From 8c7a360d6ed6875774c912e070cb18807e0e831d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Wed, 18 Jun 2014 00:03:06 +0200 Subject: [PATCH] Redesign Import, still some todos and regression bugs --- .../keychain/helper/OtherHelper.java | 9 + .../keychain/ui/ImportKeysActivity.java | 190 +++-- .../ui/ImportKeysClipboardFragment.java | 88 -- .../keychain/ui/ImportKeysFileFragment.java | 38 +- .../ui/ImportKeysKeybaseFragment.java | 16 +- .../keychain/ui/ImportKeysListFragment.java | 27 +- .../keychain/ui/ImportKeysNFCFragment.java | 70 -- .../keychain/ui/ImportKeysQrCodeFragment.java | 82 +- .../keychain/ui/ImportKeysServerFragment.java | 34 +- .../keychain/ui/ViewKeyActivity.java | 2 +- .../ui/adapter/ImportKeysListLoader.java | 2 +- .../drawable-hdpi/ic_action_collection.png | Bin 0 -> 422 bytes .../res/drawable-hdpi/ic_action_qr_code.png | Bin 0 -> 2680 bytes .../drawable-mdpi/ic_action_collection.png | Bin 0 -> 336 bytes .../res/drawable-mdpi/ic_action_qr_code.png | Bin 0 -> 2388 bytes .../drawable-xhdpi/ic_action_collection.png | Bin 0 -> 496 bytes .../res/drawable-xhdpi/ic_action_qr_code.png | Bin 0 -> 3339 bytes .../drawable-xxhdpi/ic_action_collection.png | Bin 0 -> 650 bytes .../res/drawable-xxhdpi/ic_action_qr_code.png | Bin 0 -> 3458 bytes .../main/res/layout/import_keys_activity.xml | 38 +- .../layout/import_keys_clipboard_fragment.xml | 20 - .../res/layout/import_keys_file_fragment.xml | 67 +- .../layout/import_keys_keybase_fragment.xml | 27 +- .../res/layout/import_keys_list_entry.xml | 8 +- .../res/layout/import_keys_nfc_fragment.xml | 30 - .../layout/import_keys_qr_code_fragment.xml | 49 +- .../layout/import_keys_server_fragment.xml | 72 +- .../res/layout/view_key_share_fragment.xml | 10 +- .../src/main/res/values-de/strings.xml | 2 - OpenKeychain/src/main/res/values/strings.xml | 23 +- README.md | 5 +- Resources/graphics/ic_action_qr_code.png | Bin 0 -> 5377 bytes Resources/graphics/ic_action_qr_code.svg | 753 ++++++++++++++++++ Resources/graphics/update-icon.sh | 2 +- 34 files changed, 1204 insertions(+), 460 deletions(-) delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java create mode 100644 OpenKeychain/src/main/res/drawable-hdpi/ic_action_collection.png create mode 100644 OpenKeychain/src/main/res/drawable-hdpi/ic_action_qr_code.png create mode 100644 OpenKeychain/src/main/res/drawable-mdpi/ic_action_collection.png create mode 100644 OpenKeychain/src/main/res/drawable-mdpi/ic_action_qr_code.png create mode 100644 OpenKeychain/src/main/res/drawable-xhdpi/ic_action_collection.png create mode 100644 OpenKeychain/src/main/res/drawable-xhdpi/ic_action_qr_code.png create mode 100644 OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_collection.png create mode 100644 OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_qr_code.png delete mode 100644 OpenKeychain/src/main/res/layout/import_keys_clipboard_fragment.xml delete mode 100644 OpenKeychain/src/main/res/layout/import_keys_nfc_fragment.xml create mode 100644 Resources/graphics/ic_action_qr_code.png create mode 100644 Resources/graphics/ic_action_qr_code.svg diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java index d64587578..f04d84315 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/helper/OtherHelper.java @@ -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); + } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java index f389726ff..54186e380 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java @@ -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 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." - *

- * from http://stackoverflow.com/a/14295474 - *

- * 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. - *

- * 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"); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java deleted file mode 100644 index f331358fa..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysClipboardFragment.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (C) 2013-2014 Dominik Schürmann - * - * 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 . - */ - -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(); - } - -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java index 51f961aab..060e9bab2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysFileFragment.java @@ -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 diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysKeybaseFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysKeybaseFragment.java index a639fe0e0..9264829ea 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysKeybaseFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysKeybaseFragment.java @@ -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); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index d91c55da3..7d8dc4a6c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -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 getSelectedData() { ArrayList result = new ArrayList(); - 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; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java deleted file mode 100644 index 45f464b1c..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysNFCFragment.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2013-2014 Dominik Schürmann - * - * 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 . - */ - -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; - } - -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java index 22b56e1ab..0cbb51c77 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysQrCodeFragment.java @@ -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 missing = new ArrayList(); - 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); } } - } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java index 9e3d88ff5..eabc8348c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysServerFragment.java @@ -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 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(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); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index 463c800d2..c3ca0334f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -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); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java index 03a82696d..c2712e89e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java @@ -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 rings = UncachedKeyRing.fromStream(bufferedInput); for(UncachedKeyRing key : rings) { ImportKeysListEntry item = new ImportKeysListEntry(getContext(), key); diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_action_collection.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_action_collection.png new file mode 100644 index 0000000000000000000000000000000000000000..8de91173c5e07ceb48cb4e722a3fc69cafeb6436 GIT binary patch literal 422 zcmV;X0a^ZuP)-QyGJs4zqzoW+)>Q>-q2H0o z-vHvhaDEwdIk5(S)KSIK5^Gop#T;nUL-l%HD&_!`;J*lbEp6fIB7o<&ef^QS4FS~N zyXXYy&i_@%07*qoM6N<$f|Sp+S^xk5 literal 0 HcmV?d00001 diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_action_qr_code.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_action_qr_code.png new file mode 100644 index 0000000000000000000000000000000000000000..e15a055db46ffba7cdfb59a2cfbc947587dacfbd GIT binary patch literal 2680 zcmZ`*i$BxrAODW2#mO=0P^M;dJ4ecWD-q{Ams7dri#Tq%voIE!+YYJeq9m88aM+Bm zP;v=Lzo^M?jbd&K)oPl{?vFM<_-$c zi*h<9l#&=27XlS<<>vvPPL_ z#P=Qh9loNx_MgNt+QxZz|HM2vw+F8={NquNiSJ=-ZjzXqHFK=jII3<&f}|}hEHoARrxAEX+q{!)0atW8y=pMs zkaZuG&oTrflK3?*OC#yah;n|cC7i;gKW|FRU>B9~HTi%r;JgJsjHN69< z8lKs$`0P!Ey}hTW=MArpt54_CW82Sl=ppY}r>7yFDFBb_WJ3L0su}Ntz3T;YlCz>1 z1ps|e;qe?2@-f(~SdYa~`BuFahfPhHPQ=|cF)@i3dT{!e+H3NCbl94`>fOtvEbrQ1h^~#*>E3oA z40m&74Vk8QUMC|kn`ro)Op-G5fe}|${95#o+EEv%<%VuAYQ61qfT)IkXe7b|^q%cO z+)BEco(f_RTIwxujA}B1jzxEF=rA-KwqVR(rknw7gHCo_^v!Z5h%p-8Hm(}?nqSqu z_44x@%FRV9&=T4^+?h9o_{lxxnO=R{&P7JG2u_qt-P7tWFl`%;)}8dEV`ua>jc;Pv zfE8e)JyahiaEAbc2}2)c^dQOH+P8+k3`Y)%DeLZ`8KIAoVro6K6=^IMtMkt`N)4kTMzs?V+WjQ!xcN z)UyxWy7LnqG9;}8ncb5HrM~4Q8ly4@cU%pKE?SrT%(p7OzXD5?XsfHMVJXH=_>p@)@@HQhchy+3DTK}&rkdql>KMo{5_N&1Hc1#`w3}@3QmdJ|S2iNa zlpX6+q}_Wp!cBRd;}a&@Tsz^=ER-XZii>l8x$fF0-3ycrh@XU%Ud(c#W0Qr1_`K!3 zW8Ky+d>ydy1D4TxGhQRNUj0op;`-ul1@CGB#erJ8#2=W}6|g@NNUo~A zyO;4#}gAPzm; z9egiaum4BX5K%w?Vlh)v#Stp%xG$(o6tbM9wH`AF*`uhdDmPP$Sw?c{Gq$vRq7B&D z*;y4a7}>pCMnGg_H=$4iqbuN#WhJ0UP zELD4x37Y;54>OVmugL5s*Jc}h)a9scvN`NxRikE;mzSq^-L4|HzIFTPMF#u_h7+}1 zq5?MFhsP-rPMUxBcQj5noCs-VfAJqB(CLa-qIo%KO9{Q_K-prG^JKUMyO*y|#Tkq7yiBlhR<<4?7~YnfnP4^2 zN9K^t^Z(^XHr?ntY^fx_4+q0B5_o?u&bVE>g=Bt*bImAK5D))Z&tCtAz_oF{=MOv+ zO$!EZu9!%JsX6LS z-W2wHCY0aeb%VM2`7>nobj4_+ZHr($wud;N?6~*v^^^HgADQU_F@<_WYy-z!EtmVt zW8t0)IYLWhK%ty=?l4pBno)X=@B*54Bu9z|1|yp~{T|1D@IAUL^oXhGg+RYOnyXxN<$P(HRs0w{bn|;#LYqgZM_7mWaTT5#nEmM@L63dbzIW9%9}tY^Rtk!g2SC zi^ueE)|=((?7a2cug_J{1a0Jhsx8+dl|Bc&-yVD|i6fcY8tg~>2EwyKyx%FPE1KL0 zf2W-)EF1pJgx8&*%h!ygM3Ht;S+|YqSh~wdrl?-lWFplIp))f%l9uWJsK;(?UxNrss^kT-8|>X4?N1V zyX6F4VkBLLCrrs~n5>4plY`F@x}5cF2Jt^IRa+cLzFPi88NKJm zlnXQiQV3>)cW@0wPm2RZo!LFg=p~qoAme|T#uYdK literal 0 HcmV?d00001 diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_action_collection.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_action_collection.png new file mode 100644 index 0000000000000000000000000000000000000000..b89ea93ff275bad1133017ea963c5cd9593fddd6 GIT binary patch literal 336 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 O0nAOU;B_V*N&f`-A1Sc_ literal 0 HcmV?d00001 diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_collection.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_action_collection.png new file mode 100644 index 0000000000000000000000000000000000000000..c41ca8c8b2450e10e653afcbbf36893883d2cdc1 GIT binary patch literal 650 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGok|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+m~=c{978H@y_vJokI7M>&EMJ8+c$gl$;L>-v=x`~zPMbi@2Gcn>i zf(fTjdCpKe(6{V|H_MHp=}F>8R2FFdV`j>U++tnGVlb`mu*#wRFVB}a28z7?ukj$e z-G_ydNq`|RzUBU%#YUh_D*TQv=ZrEjTtf=}~@0;tIvqkUF-9Pz{(!FvIKT;2I@cdIzT(ELuxZs7| z6S)|TwnhDJ$oq3<^TfPFmjfT94eL&=sNen9Xa}7nQiXpM9NJ}>cpg8$GXJ&G0fRaLfyRb~yOr#W{;{`oOgL-~k53>& cVx~VM8-xAZSn{w`TRz}&5nLU%n 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 Ty7nF6_e+44g$=sQ%r)xYNU~hq literal 0 HcmV?d00001 diff --git a/OpenKeychain/src/main/res/layout/import_keys_activity.xml b/OpenKeychain/src/main/res/layout/import_keys_activity.xml index 0486b6bd6..fc9d21e23 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_activity.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_activity.xml @@ -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"> - + android:layout_height="wrap_content" /> + + + + + + + + + android:layout_weight="1" + android:background="@android:color/white" /> + android:paddingRight="16dp" + android:background="@android:color/white"> - - - - - \ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/import_keys_file_fragment.xml b/OpenKeychain/src/main/res/layout/import_keys_file_fragment.xml index c07d2bb40..b1056dab3 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_file_fragment.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_file_fragment.xml @@ -1,21 +1,66 @@ - + android:layout_height="?android:attr/listPreferredItemHeight" + android:clickable="true" + style="@style/SelectableItem" + android:orientation="horizontal"> + + + + + + + + + + + + \ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/import_keys_keybase_fragment.xml b/OpenKeychain/src/main/res/layout/import_keys_keybase_fragment.xml index ceba0e1ce..bf00b77e7 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_keybase_fragment.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_keybase_fragment.xml @@ -1,16 +1,12 @@ - - + + + style="@style/SelectableItem" /> \ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/import_keys_list_entry.xml b/OpenKeychain/src/main/res/layout/import_keys_list_entry.xml index c91335a5b..56f34e2eb 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_list_entry.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_list_entry.xml @@ -17,9 +17,13 @@ + android:singleLine="true" + android:paddingLeft="8dp" + android:paddingRight="16dp" + android:paddingTop="4dp" + android:paddingBottom="4dp"> - - - - - - - \ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/import_keys_qr_code_fragment.xml b/OpenKeychain/src/main/res/layout/import_keys_qr_code_fragment.xml index 590f7f797..09a31b4a8 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_qr_code_fragment.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_qr_code_fragment.xml @@ -1,21 +1,48 @@ - + android:layout_height="?android:attr/listPreferredItemHeight" + android:clickable="true" + style="@style/SelectableItem" + android:orientation="horizontal"> + + + + + +