Redesign Import, still some todos and regression bugs

This commit is contained in:
Dominik Schürmann 2014-06-18 00:03:06 +02:00
parent 21e9d0b7b4
commit 8c7a360d6e
34 changed files with 1204 additions and 460 deletions

View File

@ -17,6 +17,7 @@
package org.sufficientlysecure.keychain.helper;
import android.content.Context;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
@ -67,4 +68,12 @@ public class OtherHelper {
return sb;
}
public static int dpToPx(Context context, int dp) {
return (int) ((dp * context.getResources().getDisplayMetrics().density) + 0.5);
}
public static int pxToDp(Context context, int px) {
return (int) ((px / context.getResources().getDisplayMetrics().density) + 0.5);
}
}

View File

@ -32,10 +32,14 @@ import android.os.Messenger;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import com.github.johnpersano.supertoasts.SuperCardToast;
@ -45,18 +49,22 @@ import com.github.johnpersano.supertoasts.util.Style;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.OtherHelper;
import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry;
import org.sufficientlysecure.keychain.keyimport.KeybaseKeyserver;
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.service.OperationResults.ImportResult;
import org.sufficientlysecure.keychain.ui.adapter.PagerTabStripAdapter;
import org.sufficientlysecure.keychain.ui.widget.SlidingTabLayout;
import org.sufficientlysecure.keychain.util.Log;
import java.util.ArrayList;
import java.util.Locale;
public class ImportKeysActivity extends ActionBarActivity implements ActionBar.OnNavigationListener {
public class ImportKeysActivity extends ActionBarActivity {
public static final String ACTION_IMPORT_KEY = Constants.INTENT_PREFIX + "IMPORT_KEY";
public static final String ACTION_IMPORT_KEY_FROM_QR_CODE = Constants.INTENT_PREFIX
+ "IMPORT_KEY_FROM_QR_CODE";
@ -90,23 +98,18 @@ public class ImportKeysActivity extends ActionBarActivity implements ActionBar.O
private String[] mNavigationStrings;
private Fragment mCurrentFragment;
private View mImportButton;
private ViewPager mViewPager;
private SlidingTabLayout mSlidingTabLayout;
private PagerTabStripAdapter mTabsAdapter;
public static final int VIEW_PAGER_HEIGHT = 64; // dp
private static final Class[] NAVIGATION_CLASSES = new Class[]{
ImportKeysServerFragment.class,
ImportKeysFileFragment.class,
ImportKeysQrCodeFragment.class,
ImportKeysClipboardFragment.class,
ImportKeysNFCFragment.class,
ImportKeysKeybaseFragment.class
};
private static final int NAV_SERVER = 0;
private static final int NAV_FILE = 1;
private static final int NAV_QR_CODE = 2;
private static final int NAV_CLIPBOARD = 3;
private static final int NAV_NFC = 4;
private static final int NAV_KEYBASE = 5;
private static final int NAV_QR_CODE = 1;
private static final int NAV_FILE = 2;
private static final int NAV_KEYBASE = 3;
private int mCurrentNavPosition = -1;
private int mSwitchToTab = NAV_SERVER;
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -114,6 +117,9 @@ public class ImportKeysActivity extends ActionBarActivity implements ActionBar.O
setContentView(R.layout.import_keys_activity);
mViewPager = (ViewPager) findViewById(R.id.import_pager);
mSlidingTabLayout = (SlidingTabLayout) findViewById(R.id.import_sliding_tab_layout);
mImportButton = findViewById(R.id.import_import);
mImportButton.setOnClickListener(new OnClickListener() {
@Override
@ -127,18 +133,55 @@ public class ImportKeysActivity extends ActionBarActivity implements ActionBar.O
if (ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN.equals(getIntent().getAction())) {
setTitle(R.string.nav_import);
} else {
getSupportActionBar().setDisplayShowTitleEnabled(false);
// set drop down navigation
Context context = getSupportActionBar().getThemedContext();
ArrayAdapter<CharSequence> navigationAdapter = ArrayAdapter.createFromResource(context,
R.array.import_action_list, android.R.layout.simple_spinner_dropdown_item);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
getSupportActionBar().setListNavigationCallbacks(navigationAdapter, this);
initTabs();
}
handleActions(savedInstanceState, getIntent());
}
private void initTabs() {
mTabsAdapter = new PagerTabStripAdapter(this);
mViewPager.setAdapter(mTabsAdapter);
mSlidingTabLayout.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// resize view pager back to 64 if keyserver settings have been collapsed
if (getViewPagerHeight() > VIEW_PAGER_HEIGHT) {
resizeViewPager(VIEW_PAGER_HEIGHT);
}
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
Bundle serverBundle = new Bundle();
// serverBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, dataUri);
mTabsAdapter.addTab(ImportKeysServerFragment.class,
serverBundle, getString(R.string.import_tab_keyserver));
Bundle qrCodeBundle = new Bundle();
// importBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, dataUri);
mTabsAdapter.addTab(ImportKeysQrCodeFragment.class,
qrCodeBundle, getString(R.string.import_tab_qr_code));
Bundle fileBundle = new Bundle();
// importBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, dataUri);
mTabsAdapter.addTab(ImportKeysFileFragment.class,
fileBundle, getString(R.string.import_tab_direct));
Bundle keybaseBundle = new Bundle();
// keybaseBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, dataUri);
mTabsAdapter.addTab(ImportKeysKeybaseFragment.class,
keybaseBundle, getString(R.string.import_tab_keybase));
// update layout after operations
mSlidingTabLayout.setViewPager(mViewPager);
}
protected void handleActions(Bundle savedInstanceState, Intent intent) {
@ -164,7 +207,7 @@ public class ImportKeysActivity extends ActionBarActivity implements ActionBar.O
/* Keychain's own Actions */
// display file fragment
loadNavFragment(NAV_FILE, null);
mViewPager.setCurrentItem(NAV_FILE);
if (dataUri != null) {
// action: directly load data
@ -199,7 +242,9 @@ public class ImportKeysActivity extends ActionBarActivity implements ActionBar.O
// display keyserver fragment with query
Bundle args = new Bundle();
args.putString(ImportKeysServerFragment.ARG_QUERY, query);
loadNavFragment(NAV_SERVER, args);
// loadNavFragment(NAV_SERVER, args);
//TODO: load afterwards!
mSwitchToTab = NAV_SERVER;
// action: search immediately
startListFragment(savedInstanceState, null, null, query);
@ -223,9 +268,8 @@ public class ImportKeysActivity extends ActionBarActivity implements ActionBar.O
return;
}
} else if (ACTION_IMPORT_KEY_FROM_FILE.equals(action)) {
// NOTE: this only displays the appropriate fragment, no actions are taken
loadNavFragment(NAV_FILE, null);
mSwitchToTab = NAV_FILE;
// no immediate actions!
startListFragment(savedInstanceState, null, null, null);
@ -233,26 +277,28 @@ public class ImportKeysActivity extends ActionBarActivity implements ActionBar.O
// also exposed in AndroidManifest
// NOTE: this only displays the appropriate fragment, no actions are taken
loadNavFragment(NAV_QR_CODE, null);
mSwitchToTab = NAV_QR_CODE;
// no immediate actions!
startListFragment(savedInstanceState, null, null, null);
} else if (ACTION_IMPORT_KEY_FROM_NFC.equals(action)) {
// NOTE: this only displays the appropriate fragment, no actions are taken
loadNavFragment(NAV_NFC, null);
mSwitchToTab = NAV_QR_CODE;
// no immediate actions!
startListFragment(savedInstanceState, null, null, null);
} else if (ACTION_IMPORT_KEY_FROM_KEYBASE.equals(action)) {
// NOTE: this only displays the appropriate fragment, no actions are taken
loadNavFragment(NAV_KEYBASE, null);
mSwitchToTab = NAV_KEYBASE;
// no immediate actions!
startListFragment(savedInstanceState, null, null, null);
} else {
startListFragment(savedInstanceState, null, null, null);
}
mViewPager.setCurrentItem(mSwitchToTab);
}
private void startListFragment(Bundle savedInstanceState, byte[] bytes, Uri dataUri, String serverQuery) {
@ -275,54 +321,16 @@ public class ImportKeysActivity extends ActionBarActivity implements ActionBar.O
getSupportFragmentManager().executePendingTransactions();
}
/**
* "Basically, when using a list navigation, onNavigationItemSelected() is automatically
* called when your activity is created/re-created, whether you like it or not. To prevent
* your Fragment's onCreateView() from being called twice, this initial automatic call to
* onNavigationItemSelected() should check whether the Fragment is already in existence
* inside your Activity."
* <p/>
* from http://stackoverflow.com/a/14295474
* <p/>
* In our case, if we start ImportKeysActivity with parameters to directly search using a fingerprint,
* the fragment would be loaded twice resulting in the query being empty after the second load.
* <p/>
* Our solution:
* To prevent that a fragment will be loaded again even if it was already loaded loadNavFragment
* checks against mCurrentNavPosition.
*
* @param itemPosition
* @param itemId
* @return
*/
@Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
Log.d(Constants.TAG, "onNavigationItemSelected");
loadNavFragment(itemPosition, null);
return true;
public void resizeViewPager(int dp) {
ViewGroup.LayoutParams params = mViewPager.getLayoutParams();
params.height = OtherHelper.dpToPx(this, dp);
// update layout after operations
mSlidingTabLayout.setViewPager(mViewPager);
}
private void loadNavFragment(int itemPosition, Bundle args) {
if (mCurrentNavPosition != itemPosition) {
if (ActionBar.NAVIGATION_MODE_LIST == getSupportActionBar().getNavigationMode()) {
getSupportActionBar().setSelectedNavigationItem(itemPosition);
}
loadFragment(NAVIGATION_CLASSES[itemPosition], args, mNavigationStrings[itemPosition]);
mCurrentNavPosition = itemPosition;
}
}
private void loadFragment(Class<?> clss, Bundle args, String tag) {
mCurrentFragment = Fragment.instantiate(this, clss.getName(), args);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment container with this fragment
// and give the fragment a tag name equal to the string at the position selected
ft.replace(R.id.import_navigation_fragment, mCurrentFragment, tag);
// Apply changes
ft.commit();
public int getViewPagerHeight() {
ViewGroup.LayoutParams params = mViewPager.getLayoutParams();
return OtherHelper.pxToDp(this, params.height);
}
public void loadFromFingerprintUri(Bundle savedInstanceState, Uri dataUri) {
@ -349,7 +357,9 @@ public class ImportKeysActivity extends ActionBarActivity implements ActionBar.O
Bundle args = new Bundle();
args.putString(ImportKeysServerFragment.ARG_QUERY, query);
args.putBoolean(ImportKeysServerFragment.ARG_DISABLE_QUERY_EDIT, true);
loadNavFragment(NAV_SERVER, args);
// loadNavFragment(NAV_SERVER, args);
//TODO
// action: search directly
startListFragment(savedInstanceState, null, null, query);
@ -437,15 +447,16 @@ public class ImportKeysActivity extends ActionBarActivity implements ActionBar.O
toast.setButtonTextColor(getResources().getColor(R.color.black));
toast.setTextColor(getResources().getColor(R.color.black));
toast.setOnClickWrapper(new OnClickWrapper("supercardtoast",
new SuperToast.OnClickListener() {
@Override
public void onClick(View view, Parcelable token) {
Intent intent = new Intent(
ImportKeysActivity.this, LogDisplayActivity.class);
intent.putExtra(LogDisplayFragment.EXTRA_RESULT, result);
startActivity(intent);
new SuperToast.OnClickListener() {
@Override
public void onClick(View view, Parcelable token) {
Intent intent = new Intent(
ImportKeysActivity.this, LogDisplayActivity.class);
intent.putExtra(LogDisplayFragment.EXTRA_RESULT, result);
startActivity(intent);
}
}
}));
));
toast.show();
/*
@ -560,9 +571,12 @@ public class ImportKeysActivity extends ActionBarActivity implements ActionBar.O
super.onResume();
// Check to see if the Activity started due to an Android Beam
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
&& NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
handleActionNdefDiscovered(getIntent());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
handleActionNdefDiscovered(getIntent());
} else {
Log.d(Constants.TAG, "NFC: No NDEF discovered!");
}
} else {
Log.e(Constants.TAG, "Android Beam not supported by Android < 4.1");
}

View File

@ -1,88 +0,0 @@
/*
* Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import com.beardedhen.androidbootstrap.BootstrapButton;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import java.util.Locale;
public class ImportKeysClipboardFragment extends Fragment {
private ImportKeysActivity mImportActivity;
private BootstrapButton mButton;
/**
* Creates new instance of this fragment
*/
public static ImportKeysClipboardFragment newInstance() {
ImportKeysClipboardFragment frag = new ImportKeysClipboardFragment();
Bundle args = new Bundle();
frag.setArguments(args);
return frag;
}
/**
* Inflate the layout for this fragment
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.import_keys_clipboard_fragment, container, false);
mButton = (BootstrapButton) view.findViewById(R.id.import_clipboard_button);
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
CharSequence clipboardText = ClipboardReflection.getClipboardText(getActivity());
String sendText = "";
if (clipboardText != null) {
sendText = clipboardText.toString();
if (sendText.toLowerCase(Locale.ENGLISH).startsWith(Constants.FINGERPRINT_SCHEME)) {
mImportActivity.loadFromFingerprintUri(null, Uri.parse(sendText));
return;
}
}
mImportActivity.loadCallback(sendText.getBytes(), null, null, null, null);
}
});
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mImportActivity = (ImportKeysActivity) getActivity();
}
}

View File

@ -19,21 +19,24 @@ package org.sufficientlysecure.keychain.ui;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.beardedhen.androidbootstrap.BootstrapButton;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.helper.FileHelper;
import java.util.Locale;
public class ImportKeysFileFragment extends Fragment {
private ImportKeysActivity mImportActivity;
private BootstrapButton mBrowse;
private View mBrowse;
private View mClipboardButton;
public static final int REQUEST_CODE_FILE = 0x00007003;
@ -56,26 +59,45 @@ public class ImportKeysFileFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.import_keys_file_fragment, container, false);
mBrowse = (BootstrapButton) view.findViewById(R.id.import_keys_file_browse);
mBrowse = view.findViewById(R.id.import_keys_file_browse);
mBrowse.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// open .asc or .gpg files
// setting it to text/plain prevents Cynaogenmod's file manager from selecting asc
// setting it to text/plain prevents Cyanogenmod's file manager from selecting asc
// or gpg types!
FileHelper.openFile(ImportKeysFileFragment.this, Constants.Path.APP_DIR + "/",
"*/*", REQUEST_CODE_FILE);
}
});
mClipboardButton = view.findViewById(R.id.import_clipboard_button);
mClipboardButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CharSequence clipboardText = ClipboardReflection.getClipboardText(getActivity());
String sendText = "";
if (clipboardText != null) {
sendText = clipboardText.toString();
if (sendText.toLowerCase(Locale.ENGLISH).startsWith(Constants.FINGERPRINT_SCHEME)) {
mImportActivity.loadFromFingerprintUri(null, Uri.parse(sendText));
return;
}
}
mImportActivity.loadCallback(sendText.getBytes(), null, null, null, null);
}
});
return view;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
public void onAttach(Activity activity) {
super.onAttach(activity);
mImportActivity = (ImportKeysActivity) getActivity();
mImportActivity = (ImportKeysActivity) activity;
}
@Override

View File

@ -17,6 +17,7 @@
package org.sufficientlysecure.keychain.ui;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
@ -29,8 +30,6 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import com.beardedhen.androidbootstrap.BootstrapButton;
import org.sufficientlysecure.keychain.R;
/**
@ -40,7 +39,7 @@ import org.sufficientlysecure.keychain.R;
public class ImportKeysKeybaseFragment extends Fragment {
private ImportKeysActivity mImportActivity;
private BootstrapButton mSearchButton;
private View mSearchButton;
private EditText mQueryEditText;
public static final String ARG_QUERY = "query";
@ -66,7 +65,7 @@ public class ImportKeysKeybaseFragment extends Fragment {
mQueryEditText = (EditText) view.findViewById(R.id.import_keybase_query);
mSearchButton = (BootstrapButton) view.findViewById(R.id.import_keybase_search);
mSearchButton = view.findViewById(R.id.import_keybase_search);
mSearchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@ -101,8 +100,6 @@ public class ImportKeysKeybaseFragment extends Fragment {
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mImportActivity = (ImportKeysActivity) getActivity();
// set displayed values
if (getArguments() != null) {
if (getArguments().containsKey(ARG_QUERY)) {
@ -112,6 +109,13 @@ public class ImportKeysKeybaseFragment extends Fragment {
}
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mImportActivity = (ImportKeysActivity) activity;
}
private void search(String query) {
mImportActivity.loadCallback(null, null, null, null, query);
}

View File

@ -42,6 +42,7 @@ import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListLoader;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListServerLoader;
import org.sufficientlysecure.keychain.util.InputData;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Notify;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
@ -97,7 +98,7 @@ public class ImportKeysListFragment extends ListFragment implements
public ArrayList<ParcelableKeyRing> getSelectedData() {
ArrayList<ParcelableKeyRing> result = new ArrayList<ParcelableKeyRing>();
for(ImportKeysListEntry entry : getSelectedEntries()) {
for (ImportKeysListEntry entry : getSelectedEntries()) {
result.add(mCachedKeyData.get(entry.getKeyId()));
}
return result;
@ -273,17 +274,15 @@ public class ImportKeysListFragment extends ListFragment implements
// No error
mCachedKeyData = ((ImportKeysListLoader) loader).getParcelableRings();
} else if (error instanceof ImportKeysListLoader.FileHasNoContent) {
AppMsg.makeText(getActivity(), R.string.error_import_file_no_content,
AppMsg.STYLE_ALERT).show();
Notify.showNotify(getActivity(), R.string.error_import_file_no_content, Notify.Style.ERROR);
} else if (error instanceof ImportKeysListLoader.NonPgpPart) {
AppMsg.makeText(getActivity(),
Notify.showNotify(getActivity(),
((ImportKeysListLoader.NonPgpPart) error).getCount() + " " + getResources().
getQuantityString(R.plurals.error_import_non_pgp_part,
((ImportKeysListLoader.NonPgpPart) error).getCount()),
new AppMsg.Style(AppMsg.LENGTH_LONG, R.color.confirm)).show();
Notify.Style.OK);
} else {
AppMsg.makeText(getActivity(), R.string.error_generic_report_bug,
new AppMsg.Style(AppMsg.LENGTH_LONG, R.color.alert)).show();
Notify.showNotify(getActivity(), R.string.error_generic_report_bug, Notify.Style.ERROR);
}
break;
@ -292,23 +291,17 @@ public class ImportKeysListFragment extends ListFragment implements
// TODO: possibly fine-tune message building for these two cases
if (error == null) {
AppMsg.makeText(
getActivity(), getResources().getQuantityString(R.plurals.keys_found,
mAdapter.getCount(), mAdapter.getCount()),
AppMsg.STYLE_INFO
).show();
// No error
} else if (error instanceof Keyserver.QueryTooShortException) {
AppMsg.makeText(getActivity(), R.string.error_keyserver_insufficient_query,
AppMsg.STYLE_ALERT).show();
Notify.showNotify(getActivity(), R.string.error_keyserver_insufficient_query, Notify.Style.ERROR);
} else if (error instanceof Keyserver.TooManyResponsesException) {
AppMsg.makeText(getActivity(), R.string.error_keyserver_too_many_responses,
AppMsg.STYLE_ALERT).show();
Notify.showNotify(getActivity(), R.string.error_keyserver_too_many_responses, Notify.Style.ERROR);
} else if (error instanceof Keyserver.QueryFailedException) {
Log.d(Constants.TAG,
"Unrecoverable keyserver query error: " + error.getLocalizedMessage());
String alert = getActivity().getString(R.string.error_searching_keys);
alert = alert + " (" + error.getLocalizedMessage() + ")";
AppMsg.makeText(getActivity(), alert, AppMsg.STYLE_ALERT).show();
Notify.showNotify(getActivity(), alert, Notify.Style.ERROR);
}
break;

View File

@ -1,70 +0,0 @@
/*
* Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import com.beardedhen.androidbootstrap.BootstrapButton;
import org.sufficientlysecure.keychain.R;
public class ImportKeysNFCFragment extends Fragment {
private BootstrapButton mButton;
/**
* Creates new instance of this fragment
*/
public static ImportKeysNFCFragment newInstance() {
ImportKeysNFCFragment frag = new ImportKeysNFCFragment();
Bundle args = new Bundle();
frag.setArguments(args);
return frag;
}
/**
* Inflate the layout for this fragment
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.import_keys_nfc_fragment, container, false);
mButton = (BootstrapButton) view.findViewById(R.id.import_nfc_button);
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// show nfc help
Intent intent = new Intent(getActivity(), HelpActivity.class);
intent.putExtra(HelpActivity.EXTRA_SELECTED_TAB, HelpActivity.TAB_NFC);
startActivityForResult(intent, 0);
}
});
return view;
}
}

View File

@ -17,47 +17,47 @@
package org.sufficientlysecure.keychain.ui;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.beardedhen.androidbootstrap.BootstrapButton;
import com.devspark.appmsg.AppMsg;
import com.google.zxing.integration.android.IntentResult;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.util.IntentIntegratorSupportV4;
import org.sufficientlysecure.keychain.util.Log;
import org.sufficientlysecure.keychain.util.Notify;
import java.util.ArrayList;
import java.util.Locale;
public class ImportKeysQrCodeFragment extends Fragment {
private ImportKeysActivity mImportActivity;
private BootstrapButton mButton;
private TextView mText;
private ProgressBar mProgress;
private View mNfcButton;
private String[] mScannedContent;
private View mQrCodeButton;
private TextView mQrCodeText;
private ProgressBar mQrCodeProgress;
private String[] mQrCodeContent;
/**
* Creates new instance of this fragment
*/
public static ImportKeysQrCodeFragment newInstance() {
ImportKeysQrCodeFragment frag = new ImportKeysQrCodeFragment();
public static ImportKeysFileFragment newInstance() {
ImportKeysFileFragment frag = new ImportKeysFileFragment();
Bundle args = new Bundle();
frag.setArguments(args);
frag.setArguments(args);
return frag;
}
@ -68,11 +68,23 @@ public class ImportKeysQrCodeFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.import_keys_qr_code_fragment, container, false);
mButton = (BootstrapButton) view.findViewById(R.id.import_qrcode_button);
mText = (TextView) view.findViewById(R.id.import_qrcode_text);
mProgress = (ProgressBar) view.findViewById(R.id.import_qrcode_progress);
mNfcButton = view.findViewById(R.id.import_nfc_button);
mNfcButton.setOnClickListener(new View.OnClickListener() {
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// show nfc help
Intent intent = new Intent(getActivity(), HelpActivity.class);
intent.putExtra(HelpActivity.EXTRA_SELECTED_TAB, HelpActivity.TAB_NFC);
startActivityForResult(intent, 0);
}
});
mQrCodeButton = view.findViewById(R.id.import_qrcode_button);
mQrCodeText = (TextView) view.findViewById(R.id.import_qrcode_text);
mQrCodeProgress = (ProgressBar) view.findViewById(R.id.import_qrcode_progress);
mQrCodeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
@ -85,10 +97,10 @@ public class ImportKeysQrCodeFragment extends Fragment {
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
public void onAttach(Activity activity) {
super.onAttach(activity);
mImportActivity = (ImportKeysActivity) getActivity();
mImportActivity = (ImportKeysActivity) activity;
}
@Override
@ -122,8 +134,7 @@ public class ImportKeysQrCodeFragment extends Fragment {
}
// fail...
AppMsg.makeText(getActivity(), R.string.import_qr_code_wrong, AppMsg.STYLE_ALERT)
.show();
Notify.showNotify(getActivity(), R.string.import_qr_code_wrong, Notify.Style.ERROR);
}
break;
@ -136,6 +147,7 @@ public class ImportKeysQrCodeFragment extends Fragment {
}
}
public void importFingerprint(Uri dataUri) {
mImportActivity.loadFromFingerprintUri(null, dataUri);
}
@ -151,32 +163,31 @@ public class ImportKeysQrCodeFragment extends Fragment {
// first qr code -> setup
if (counter == 0) {
mScannedContent = new String[size];
mProgress.setMax(size);
mProgress.setVisibility(View.VISIBLE);
mText.setVisibility(View.VISIBLE);
mQrCodeContent = new String[size];
mQrCodeProgress.setMax(size);
mQrCodeProgress.setVisibility(View.VISIBLE);
mQrCodeText.setVisibility(View.VISIBLE);
}
if (mScannedContent == null || counter > mScannedContent.length) {
AppMsg.makeText(getActivity(), R.string.import_qr_code_start_with_one, AppMsg.STYLE_ALERT)
.show();
if (mQrCodeContent == null || counter > mQrCodeContent.length) {
Notify.showNotify(getActivity(), R.string.import_qr_code_start_with_one, Notify.Style.ERROR);
return;
}
// save scanned content
mScannedContent[counter] = content;
mQrCodeContent[counter] = content;
// get missing numbers
ArrayList<Integer> missing = new ArrayList<Integer>();
for (int i = 0; i < mScannedContent.length; i++) {
if (mScannedContent[i] == null) {
for (int i = 0; i < mQrCodeContent.length; i++) {
if (mQrCodeContent[i] == null) {
missing.add(i);
}
}
// update progress and text
int alreadyScanned = mScannedContent.length - missing.size();
mProgress.setProgress(alreadyScanned);
int alreadyScanned = mQrCodeContent.length - missing.size();
mQrCodeProgress.setProgress(alreadyScanned);
String missingString = "";
for (int m : missing) {
@ -188,17 +199,16 @@ public class ImportKeysQrCodeFragment extends Fragment {
String missingText = getResources().getQuantityString(R.plurals.import_qr_code_missing,
missing.size(), missingString);
mText.setText(missingText);
mQrCodeText.setText(missingText);
// finished!
if (missing.size() == 0) {
mText.setText(R.string.import_qr_code_finished);
mQrCodeText.setText(R.string.import_qr_code_finished);
String result = "";
for (String in : mScannedContent) {
for (String in : mQrCodeContent) {
result += in;
}
mImportActivity.loadCallback(result.getBytes(), null, null, null, null);
}
}
}

View File

@ -17,6 +17,7 @@
package org.sufficientlysecure.keychain.ui;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
@ -32,8 +33,6 @@ import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import com.beardedhen.androidbootstrap.BootstrapButton;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.Preferences;
@ -46,8 +45,10 @@ public class ImportKeysServerFragment extends Fragment {
private ImportKeysActivity mImportActivity;
private BootstrapButton mSearchButton;
private View mSearchButton;
private EditText mQueryEditText;
private View mConfigButton;
private View mConfigLayout;
private Spinner mServerSpinner;
private ArrayAdapter<String> mServerAdapter;
@ -73,14 +74,17 @@ public class ImportKeysServerFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.import_keys_server_fragment, container, false);
mSearchButton = (BootstrapButton) view.findViewById(R.id.import_server_search);
mSearchButton = view.findViewById(R.id.import_server_search);
mQueryEditText = (EditText) view.findViewById(R.id.import_server_query);
mConfigButton = view.findViewById(R.id.import_server_config_button);
mConfigLayout = view.findViewById(R.id.import_server_config);
mServerSpinner = (Spinner) view.findViewById(R.id.import_server_spinner);
// add keyservers to spinner
mServerAdapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_spinner_item, Preferences.getPreferences(getActivity())
.getKeyServers());
.getKeyServers()
);
mServerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mServerSpinner.setAdapter(mServerAdapter);
if (mServerAdapter.getCount() > 0) {
@ -118,6 +122,17 @@ public class ImportKeysServerFragment extends Fragment {
}
});
mConfigButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (mImportActivity.getViewPagerHeight() > ImportKeysActivity.VIEW_PAGER_HEIGHT) {
mImportActivity.resizeViewPager(ImportKeysActivity.VIEW_PAGER_HEIGHT);
} else {
mImportActivity.resizeViewPager(ImportKeysActivity.VIEW_PAGER_HEIGHT + 41);
}
}
});
return view;
}
@ -125,8 +140,6 @@ public class ImportKeysServerFragment extends Fragment {
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mImportActivity = (ImportKeysActivity) getActivity();
// set displayed values
if (getArguments() != null) {
if (getArguments().containsKey(ARG_QUERY)) {
@ -150,6 +163,13 @@ public class ImportKeysServerFragment extends Fragment {
}
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mImportActivity = (ImportKeysActivity) activity;
}
private void search(String query, String keyServer) {
mImportActivity.loadCallback(null, null, query, keyServer, null);
}

View File

@ -158,7 +158,7 @@ public class ViewKeyActivity extends ActionBarActivity implements
Bundle shareBundle = new Bundle();
shareBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, dataUri);
mTabsAdapter.addTab(ViewKeyShareFragment.class,
mainBundle, getString(R.string.key_view_tab_share));
shareBundle, getString(R.string.key_view_tab_share));
// update layout after operations
mSlidingTabLayout.setViewPager(mViewPager);

View File

@ -133,7 +133,7 @@ public class ImportKeysListLoader
// read all available blocks... (asc files can contain many blocks with BEGIN END)
while (bufferedInput.available() > 0) {
// todo deal with non-keyring objects?
// TODO: deal with non-keyring objects?
List<UncachedKeyRing> rings = UncachedKeyRing.fromStream(bufferedInput);
for(UncachedKeyRing key : rings) {
ImportKeysListEntry item = new ImportKeysListEntry(getContext(), key);

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 650 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -3,7 +3,7 @@
android:id="@+id/content_frame"
android:layout_marginLeft="@dimen/drawer_content_padding"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
@ -12,21 +12,38 @@
android:layout_height="wrap_content"
android:orientation="vertical" />
<FrameLayout
android:id="@+id/import_navigation_fragment"
<org.sufficientlysecure.keychain.ui.widget.SlidingTabLayout
android:id="@+id/import_sliding_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
android:layout_height="wrap_content" />
<android.support.v4.view.ViewPager
android:id="@+id/import_pager"
android:layout_width="match_parent"
android:layout_height="64dp"
android:background="@android:color/white" />
<View
android:layout_width="match_parent"
android:layout_height="2dip"
android:background="?android:attr/listDivider" />
<View
android:layout_width="match_parent"
android:layout_height="16dp" />
<View
android:layout_width="match_parent"
android:layout_height="2dip"
android:background="?android:attr/listDivider" />
<FrameLayout
android:id="@+id/import_keys_list_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:paddingTop="8dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:layout_weight="0.9" />
android:layout_weight="1"
android:background="@android:color/white" />
<LinearLayout
android:id="@+id/import_footer"
@ -34,7 +51,8 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingRight="16dp">
android:paddingRight="16dp"
android:background="@android:color/white">
<View
android:layout_width="match_parent"

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:orientation="horizontal" >
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/import_clipboard_button"
android:layout_width="match_parent"
android:layout_height="70dp"
android:text="@string/import_clipboard_button"
bootstrapbutton:bb_icon_left="fa-clipboard"
bootstrapbutton:bb_size="default"
bootstrapbutton:bb_type="default" />
</LinearLayout>

View File

@ -1,21 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:orientation="vertical">
<com.beardedhen.androidbootstrap.BootstrapButton
<LinearLayout
android:id="@+id/import_keys_file_browse"
android:paddingLeft="8dp"
android:layout_width="match_parent"
android:layout_height="70dp"
android:text="@string/filemanager_title_open"
android:contentDescription="@string/filemanager_title_open"
bootstrapbutton:bb_icon_left="fa-folder-open"
bootstrapbutton:bb_size="default"
bootstrapbutton:bb_type="default" />
android:layout_height="?android:attr/listPreferredItemHeight"
android:clickable="true"
style="@style/SelectableItem"
android:orientation="horizontal">
<TextView
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="0dip"
android:layout_height="match_parent"
android:text="@string/filemanager_title_open"
android:layout_weight="1"
android:drawableRight="@drawable/ic_action_collection"
android:drawablePadding="8dp"
android:gravity="center_vertical" />
<View
android:layout_width="1dip"
android:layout_height="match_parent"
android:gravity="right"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:background="?android:attr/listDivider" />
<ImageButton
android:id="@+id/import_clipboard_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="8dp"
android:src="@drawable/ic_action_paste"
android:layout_gravity="center_vertical"
style="@style/SelectableItem" />
</LinearLayout>
<TextView
android:id="@+id/import_qrcode_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="8dp"
android:visibility="gone" />
<ProgressBar
android:id="@+id/import_qrcode_progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:progress="0"
android:visibility="gone" />
</LinearLayout>

View File

@ -1,16 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:orientation="horizontal">
<EditText
android:id="@+id/import_keybase_query"
android:layout_marginLeft="8dp"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
@ -22,17 +18,24 @@
android:lines="1"
android:maxLines="1"
android:minLines="1"
android:layout_marginRight="8dp"
android:layout_gravity="center_vertical" />
<com.beardedhen.androidbootstrap.BootstrapButton
<View
android:layout_width="1dip"
android:layout_height="match_parent"
android:gravity="right"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:background="?android:attr/listDivider" />
<ImageButton
android:id="@+id/import_keybase_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:padding="16dp"
android:src="@drawable/ic_action_search"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dp"
bootstrapbutton:bb_icon_left="fa-search"
bootstrapbutton:bb_roundedCorners="true"
bootstrapbutton:bb_size="default"
bootstrapbutton:bb_type="default" />
style="@style/SelectableItem" />
</LinearLayout>

View File

@ -17,9 +17,13 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:orientation="horizontal"
android:paddingRight="?android:attr/scrollbarSize"
android:singleLine="true">
android:singleLine="true"
android:paddingLeft="8dp"
android:paddingRight="16dp"
android:paddingTop="4dp"
android:paddingBottom="4dp">
<CheckBox
android:id="@+id/selected"

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:orientation="horizontal">
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/import_nfc_button"
android:layout_width="wrap_content"
android:layout_height="70dp"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="8dp"
android:text="@string/import_nfc_help_button"
bootstrapbutton:bb_icon_left="fa-question"
bootstrapbutton:bb_size="default"
bootstrapbutton:bb_type="default" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/import_nfc_button"
android:text="@string/import_nfc_text" />
</RelativeLayout>

View File

@ -1,21 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:orientation="vertical">
<com.beardedhen.androidbootstrap.BootstrapButton
<LinearLayout
android:id="@+id/import_qrcode_button"
android:paddingLeft="8dp"
android:layout_width="match_parent"
android:layout_height="70dp"
android:text="@string/import_qr_scan_button"
bootstrapbutton:bb_icon_left="fa-barcode"
bootstrapbutton:bb_size="default"
bootstrapbutton:bb_type="default" />
android:layout_height="?android:attr/listPreferredItemHeight"
android:clickable="true"
style="@style/SelectableItem"
android:orientation="horizontal">
<TextView
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="0dip"
android:layout_height="match_parent"
android:text="@string/import_qr_code_button"
android:layout_weight="1"
android:drawableRight="@drawable/ic_action_qr_code"
android:drawablePadding="8dp"
android:gravity="center_vertical" />
<View
android:layout_width="1dip"
android:layout_height="match_parent"
android:gravity="right"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:background="?android:attr/listDivider" />
<Button
android:id="@+id/import_nfc_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="8dp"
android:text="NFC?"
android:layout_gravity="center_vertical"
style="@style/SelectableItem" />
</LinearLayout>
<TextView
android:id="@+id/import_qrcode_text"

View File

@ -1,20 +1,13 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="8dp"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:layout_height="wrap_content"
android:orientation="vertical">
<Spinner
android:id="@+id/import_server_spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:layout_height="?android:attr/listPreferredItemHeight"
android:orientation="horizontal">
<EditText
@ -30,18 +23,63 @@
android:lines="1"
android:maxLines="1"
android:minLines="1"
android:layout_marginRight="8dp"
android:layout_gravity="center_vertical" />
<com.beardedhen.androidbootstrap.BootstrapButton
<View
android:layout_width="1dip"
android:layout_height="match_parent"
android:gravity="right"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:background="?android:attr/listDivider" />
<ImageButton
android:id="@+id/import_server_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:padding="16dp"
android:src="@drawable/ic_action_search"
android:layout_gravity="center_vertical"
style="@style/SelectableItem" />
<View
android:layout_width="1dip"
android:layout_height="match_parent"
android:gravity="right"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:background="?android:attr/listDivider" />
<ImageButton
android:id="@+id/import_server_config_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:padding="8dp"
android:src="@drawable/ic_action_settings"
android:layout_gravity="center_vertical"
style="@style/SelectableItem" />
</LinearLayout>
<LinearLayout
android:id="@+id/import_server_config"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="1dip"
android:background="?android:attr/listDivider" />
<Spinner
android:id="@+id/import_server_spinner"
android:layout_marginLeft="8dp"
bootstrapbutton:bb_icon_left="fa-search"
bootstrapbutton:bb_roundedCorners="true"
bootstrapbutton:bb_size="default"
bootstrapbutton:bb_type="default" />
android:layout_marginRight="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>

View File

@ -24,8 +24,7 @@
<LinearLayout
android:id="@+id/view_key_action_fingerprint_share"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:layout_height="?android:attr/listPreferredItemHeight"
android:clickable="true"
style="@style/SelectableItem"
android:orientation="horizontal">
@ -63,7 +62,6 @@
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dip"
@ -90,8 +88,7 @@
<LinearLayout
android:id="@+id/view_key_action_key_share"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:layout_height="?android:attr/listPreferredItemHeight"
android:clickable="true"
style="@style/SelectableItem"
android:orientation="horizontal">
@ -135,8 +132,7 @@
<LinearLayout
android:id="@+id/view_key_action_nfc_help"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:layout_height="?android:attr/listPreferredItemHeight"
android:clickable="true"
style="@style/SelectableItem"
android:orientation="horizontal"

View File

@ -324,10 +324,8 @@
<string name="progress_verifying_integrity">Integrität wird überprüft…</string>
<string name="progress_deleting_securely">\'%s\' wird sicher gelöscht…</string>
<!--action strings-->
<string name="hint_public_keys">Öffentliche Schlüssel suchen</string>
<string name="hint_secret_keys">Private Schlüssel suchen</string>
<string name="action_share_key_with">Teile Schlüssel über…</string>
<string name="hint_keybase_search">Durchsuche Keybase.io</string>
<!--key bit length selections-->
<string name="key_size_512">512</string>
<string name="key_size_768">768</string>

View File

@ -75,16 +75,11 @@
<!-- menu -->
<string name="menu_preferences">Settings</string>
<string name="menu_help">Help</string>
<string name="menu_import_from_file">Import from file</string>
<string name="menu_import_from_qr_code">Import from QR Code</string>
<string name="menu_import_from_nfc">Import from NFC</string>
<string name="menu_export_key">Export to file</string>
<string name="menu_delete_key">Delete key</string>
<string name="menu_create_key">Create key</string>
<string name="menu_create_key_expert">Create key (expert)</string>
<string name="menu_search">Search</string>
<string name="menu_import_from_key_server">Keyserver</string>
<string name="menu_import_from_keybase">Import from Keybase.io</string>
<string name="menu_key_server">Keyserver…</string>
<string name="menu_update_key">Update from keyserver</string>
<string name="menu_export_key_to_server">Upload to key server</string>
@ -229,11 +224,6 @@
<string name="key_creation_weak_rsa_info">Note: generating RSA key with length 1024-bit and less is considered unsafe and it\'s disabled for generating new keys.</string>
<string name="key_not_found">Couldn\'t find key %08X.</string>
<plurals name="keys_found">
<item quantity="one">Found %d key.</item>
<item quantity="other">Found %d keys.</item>
</plurals>
<plurals name="bad_keys_encountered">
<item quantity="one">%d bad secret key ignored. Perhaps you exported with the option\n --export-secret-subkeys\nMake sure you export with\n --export-secret-keys\ninstead.</item>
<item quantity="other">%d bad secret keys ignored. Perhaps you exported with the option\n --export-secret-subkeys\nMake sure you export with\n --export-secret-keys\ninstead.</item>
@ -278,11 +268,11 @@
<string name="error_only_files_are_supported">Direct binary data without actual file in filesystem is not supported.</string>
<string name="error_jelly_bean_needed">You need Android 4.1 to use Android\'s NFC Beam feature!</string>
<string name="error_nfc_needed">NFC is not available on your device!</string>
<string name="error_nothing_import">Nothing to import!</string>
<string name="error_nothing_import">No keys found!</string>
<string name="error_keyserver_insufficient_query">Key search query too short</string>
<string name="error_searching_keys">Unrecoverable error searching for keys at server</string>
<string name="error_keyserver_too_many_responses">Key search query returned too many candidates; Please refine query</string>
<string name="error_import_file_no_content">File has no content</string>
<string name="error_import_file_no_content">File/Clipboard is empty</string>
<string name="error_generic_report_bug">A generic error occurred, please create a new bug report for OpenKeychain.</string>
<plurals name="error_import_non_pgp_part">
<item quantity="one">part of the loaded file is a valid OpenPGP object but not a OpenPGP key</item>
@ -339,10 +329,10 @@
<string name="progress_deleting_securely">deleting \'%s\' securely…</string>
<!-- action strings -->
<string name="hint_public_keys">Search Public Keys</string>
<string name="hint_public_keys">Name/Email/Key ID…</string>
<string name="hint_secret_keys">Search Secret Keys</string>
<string name="action_share_key_with">Share Key with…</string>
<string name="hint_keybase_search">Search Keybase.io</string>
<string name="hint_keybase_search">Name/Keybase.io username…</string>
<!-- key bit length selections -->
<string name="key_size_512">512</string>
@ -372,6 +362,10 @@
<string name="help_about_version">Version:</string>
<!-- Import -->
<string name="import_tab_keyserver">Keyserver</string>
<string name="import_tab_direct">File/Clipboard</string>
<string name="import_tab_qr_code">QR Code/NFC</string>
<string name="import_tab_keybase">Keybase.io</string>
<string name="import_import">Import selected keys</string>
<string name="import_from_clipboard">Import from clipboard</string>
@ -387,6 +381,7 @@
<string name="import_qr_scan_button">Scan QR Code with \'Barcode Scanner\'</string>
<string name="import_nfc_text">To receive keys via NFC, the device needs to be unlocked.</string>
<string name="import_nfc_help_button">Help</string>
<string name="import_qr_code_button">Scan QR Code…</string>
<string name="import_clipboard_button">Get key from clipboard</string>
<string name="import_keybase_button">Get key from Keybase.io</string>

View File

@ -227,8 +227,11 @@ Some parts and some libraries are Apache License v2, MIT X11 License (see below)
* icon.svg
modified version of kgpg_key2_kopete.svgz
* Menu icons
* Actionbar icons
http://developer.android.com/design/downloads/index.html#action-bar-icon-pack
* QR Code Actionbar icon
https://github.com/openintents/openintents/blob/master/extensions/qrcode_ext/icons/ic_menu_qr_code/ic_menu_qr_code_holo_light/ic_menu_qr_code.svg
* Purple color scheme
http://android-holo-colors.com/

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -0,0 +1,753 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Layer_1"
x="0px"
y="0px"
width="48px"
height="48px"
viewBox="0 0 48 48"
enable-background="new 0 0 48 48"
xml:space="preserve"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="ic_menu_qr_code.svg"><metadata
id="metadata231"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs229">
</defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1918"
inkscape:window-height="1179"
id="namedview227"
showgrid="false"
inkscape:zoom="8.4558186"
inkscape:cx="-17.080652"
inkscape:cy="14.446251"
inkscape:window-x="0"
inkscape:window-y="19"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" />
<rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect25"
height="5.0662165"
width="1.6889851"
y="9.6451044"
x="9.6451044" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect39"
height="5.0662165"
width="1.6889851"
y="9.6451044"
x="11.334089" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect55"
height="5.0662165"
width="1.6882463"
y="9.6451044"
x="13.023813" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect33"
height="5.0662165"
width="1.6889851"
y="33.287201"
x="9.6451044" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect49"
height="5.0662165"
width="1.6889851"
y="33.287201"
x="11.334089" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect61"
height="5.0662165"
width="1.6882463"
y="33.287201"
x="13.023813" /><rect
y="6.2678733"
x="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect5"
height="11.821418"
width="1.6882463" /><rect
y="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect13"
height="1.6882463"
width="1.6889851"
x="7.9561195" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect15"
height="1.6889851"
width="1.6889851"
y="16.400307"
x="7.9561195" /><rect
y="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect23"
height="1.6882463"
width="1.6889851"
x="9.6451044" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect27"
height="1.6889851"
width="1.6889851"
y="16.400307"
x="9.6451044" /><rect
y="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect37"
height="1.6882463"
width="1.6889851"
x="11.334089" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect41"
height="1.6889851"
width="1.6889851"
y="16.400307"
x="11.334089" /><rect
y="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect53"
height="1.6882463"
width="1.6882463"
x="13.023813" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect57"
height="1.6889851"
width="1.6882463"
y="16.400307"
x="13.023813" /><rect
y="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect65"
height="1.6882463"
width="1.6882463"
x="14.712059" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect67"
height="1.6889851"
width="1.6882463"
y="16.400307"
x="14.712059" /><rect
y="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect75"
height="11.821418"
width="1.6889851"
x="16.400307" /><rect
x="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect11"
height="11.821418"
width="1.6882463"
y="29.910709" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect19"
height="1.6882463"
width="1.6889851"
y="29.910709"
x="7.9561195" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect21"
height="1.6889851"
width="1.6889851"
y="40.04314"
x="7.9561195" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect31"
height="1.6882463"
width="1.6889851"
y="29.910709"
x="9.6451044" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect35"
height="1.6889851"
width="1.6889851"
y="40.04314"
x="9.6451044" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect47"
height="1.6882463"
width="1.6889851"
y="29.910709"
x="11.334089" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect51"
height="1.6889851"
width="1.6889851"
y="40.04314"
x="11.334089" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect59"
height="1.6882463"
width="1.6882463"
y="29.910709"
x="13.023813" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect63"
height="1.6889851"
width="1.6882463"
y="40.04314"
x="13.023813" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect71"
height="1.6882463"
width="1.6882463"
y="29.910709"
x="14.712059" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect73"
height="1.6889851"
width="1.6882463"
y="40.04314"
x="14.712059" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect83"
height="11.821418"
width="1.6889851"
y="29.910709"
x="16.400307" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect163"
height="5.0662165"
width="1.6897238"
y="9.6451044"
x="33.287201" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect177"
height="5.0662165"
width="1.6882463"
y="9.6451044"
x="34.976925" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect191"
height="5.0662165"
width="1.6897238"
y="9.6451044"
x="36.665913" /><rect
y="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect141"
height="11.821418"
width="1.6882463"
x="29.910709" /><rect
y="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect151"
height="1.6882463"
width="1.6882463"
x="31.598955" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect153"
height="1.6889851"
width="1.6882463"
y="16.400307"
x="31.598955" /><rect
y="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect161"
height="1.6882463"
width="1.6897238"
x="33.287201" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect165"
height="1.6889851"
width="1.6897238"
y="16.400307"
x="33.287201" /><rect
y="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect175"
height="1.6882463"
width="1.6882463"
x="34.976925" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect179"
height="1.6889851"
width="1.6882463"
y="16.400307"
x="34.976925" /><rect
y="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect189"
height="1.6882463"
width="1.6897238"
x="36.665913" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect193"
height="1.6889851"
width="1.6897238"
y="16.400307"
x="36.665913" /><rect
y="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect203"
height="1.6882463"
width="1.6875074"
x="38.355633" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect205"
height="1.6889851"
width="1.6875074"
y="16.400307"
x="38.355633" /><rect
y="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect217"
height="11.821418"
width="1.6889851"
x="40.04314" /><rect
x="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect7"
height="3.3779702"
width="1.6882463"
y="19.777536" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect17"
height="1.6897238"
width="1.6889851"
y="26.53274"
x="7.9561195" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect29"
height="5.0654774"
width="1.6889851"
y="21.466522"
x="9.6451044" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect43"
height="1.6889851"
width="1.6889851"
y="21.466522"
x="11.334089" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect45"
height="3.3779702"
width="1.6889851"
y="24.844492"
x="11.334089" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect69"
height="1.6889851"
width="1.6882463"
y="23.155508"
x="14.712059" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect77"
height="1.6889851"
width="1.6889851"
y="19.777536"
x="16.400307" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect79"
height="1.6889851"
width="1.6889851"
y="23.155508"
x="16.400307" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect81"
height="1.6897238"
width="1.6889851"
y="26.53274"
x="16.400307" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect85"
height="3.3779702"
width="1.6889851"
y="21.466522"
x="18.089291" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect87"
height="5.0662165"
width="1.6889851"
y="7.9561195"
x="19.778276" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect89"
height="13.510403"
width="1.6889851"
y="16.400307"
x="19.778276" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect91"
height="1.6889851"
width="1.6889851"
y="40.04314"
x="19.778276" /><rect
y="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect93"
height="1.6882463"
width="1.6882463"
x="21.467262" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect95"
height="1.6889851"
width="1.6882463"
y="13.023074"
x="21.467262" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect97"
height="5.0662165"
width="1.6882463"
y="24.844492"
x="21.467262" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect99"
height="1.6882463"
width="1.6882463"
y="31.598955"
x="21.467262" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect101"
height="6.7552013"
width="1.6882463"
y="34.976925"
x="21.467262" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect103"
height="1.6882463"
width="1.6889851"
y="11.334089"
x="23.155508" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect107"
height="5.0662165"
width="1.6889851"
y="19.777536"
x="23.155508" /><rect
y="6.2678733"
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect113"
height="1.6882463"
width="1.6882463"
x="24.844492" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect117"
height="1.6882463"
width="1.6882463"
y="18.089291"
x="24.844492" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect119"
height="1.6889851"
width="1.6882463"
y="23.155508"
x="24.844492" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect121"
height="1.6882463"
width="1.6882463"
y="28.222464"
x="24.844492" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect123"
height="1.6882463"
width="1.6882463"
y="31.598955"
x="24.844492" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect125"
height="1.6889851"
width="1.6882463"
y="40.04314"
x="24.844492" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect127"
height="3.3779702"
width="1.6889851"
y="7.9561195"
x="26.53274" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect129"
height="10.133172"
width="1.6889851"
y="13.023074"
x="26.53274" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect131"
height="8.4434481"
width="1.6889851"
y="28.222464"
x="26.53274" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect135"
height="3.3779702"
width="1.6889851"
y="26.53274"
x="28.221725" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect137"
height="1.6882463"
width="1.6889851"
y="31.598955"
x="28.221725" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect139"
height="1.6889851"
width="1.6889851"
y="40.04314"
x="28.221725" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect145"
height="1.6889851"
width="1.6882463"
y="23.155508"
x="29.910709" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect149"
height="1.6897238"
width="1.6882463"
y="36.665913"
x="29.910709" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect155"
height="5.0654774"
width="1.6882463"
y="21.466522"
x="31.598955" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect157"
height="3.3779702"
width="1.6882463"
y="31.598955"
x="31.598955" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect169"
height="1.6897238"
width="1.6897238"
y="26.53274"
x="33.287201" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect171"
height="3.3764925"
width="1.6897238"
y="29.910709"
x="33.287201" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect173"
height="6.7552013"
width="1.6897238"
y="34.976925"
x="33.287201" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect181"
height="1.6889851"
width="1.6882463"
y="19.777536"
x="34.976925" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect183"
height="3.3764925"
width="1.6882463"
y="23.155508"
x="34.976925" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect185"
height="1.6882463"
width="1.6882463"
y="31.598955"
x="34.976925" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect187"
height="1.6875074"
width="1.6882463"
y="38.355633"
x="34.976925" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect195"
height="6.7552013"
width="1.6897238"
y="19.777536"
x="36.665913" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect197"
height="1.6882463"
width="1.6897238"
y="28.222464"
x="36.665913" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect199"
height="1.6882463"
width="1.6897238"
y="31.598955"
x="36.665913" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect201"
height="5.0647388"
width="1.6897238"
y="34.976925"
x="36.665913" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect207"
height="1.6889851"
width="1.6875074"
y="19.777536"
x="38.355633" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect209"
height="5.0662165"
width="1.6875074"
y="23.155508"
x="38.355633" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect211"
height="1.6882463"
width="1.6875074"
y="29.910709"
x="38.355633" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect215"
height="1.6889851"
width="1.6875074"
y="40.04314"
x="38.355633" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect219"
height="1.6882463"
width="1.6889851"
y="24.844492"
x="40.04314" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect223"
height="3.3779702"
width="1.6889851"
y="31.598955"
x="40.04314" /><rect
style="opacity:0.6;fill:#333333;fill-opacity:1"
id="rect225"
height="1.6897238"
width="1.6889851"
y="36.665913"
x="40.04314" />
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,6 +1,6 @@
#!/bin/bash
APP_DIR=../../OpenPGP-Keychain/src/main
APP_DIR=../../OpenKeychain/src/main
LDPI_DIR=$APP_DIR/res/drawable-ldpi
MDPI_DIR=$APP_DIR/res/drawable-mdpi
HDPI_DIR=$APP_DIR/res/drawable-hdpi