From 50248bd570f1de019b18a467e5181c4d14a772f6 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 2 Nov 2015 21:29:53 +0100 Subject: extended: init tabs with loader info --- .../keychain/ui/ViewKeyAdvActivity.java | 20 +++++++++++--------- .../keychain/ui/ViewKeyAdvUserIdsFragment.java | 5 +++-- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java index 94a171f14..e676b441f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java @@ -78,9 +78,6 @@ public class ViewKeyAdvActivity extends BaseActivity implements mViewPager = (ViewPager) findViewById(R.id.pager); mSlidingTabLayout = (PagerSlidingTabStrip) findViewById(R.id.sliding_tab_layout); - Intent intent = getIntent(); - int switchToTab = intent.getIntExtra(EXTRA_SELECTED_TAB, TAB_SHARE); - mDataUri = getIntent().getData(); if (mDataUri == null) { Log.e(Constants.TAG, "Data missing. Should be uri of key!"); @@ -101,10 +98,6 @@ public class ViewKeyAdvActivity extends BaseActivity implements // or start new ones. getSupportLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this); - initTabs(mDataUri); - - // switch to tab selected by extra - mViewPager.setCurrentItem(switchToTab); } @Override @@ -112,17 +105,18 @@ public class ViewKeyAdvActivity extends BaseActivity implements setContentView(R.layout.view_key_adv_activity); } - private void initTabs(Uri dataUri) { + private void initTabs(Uri dataUri, boolean hasSecret) { PagerTabStripAdapter adapter = new PagerTabStripAdapter(this); mViewPager.setAdapter(adapter); Bundle shareBundle = new Bundle(); - shareBundle.putParcelable(ViewKeyAdvUserIdsFragment.ARG_DATA_URI, dataUri); + shareBundle.putParcelable(ViewKeyAdvShareFragment.ARG_DATA_URI, dataUri); adapter.addTab(ViewKeyAdvShareFragment.class, shareBundle, getString(R.string.key_view_tab_share)); Bundle userIdsBundle = new Bundle(); userIdsBundle.putParcelable(ViewKeyAdvUserIdsFragment.ARG_DATA_URI, dataUri); + userIdsBundle.putBoolean(ViewKeyAdvUserIdsFragment.ARG_HAS_SECRET, hasSecret); adapter.addTab(ViewKeyAdvUserIdsFragment.class, userIdsBundle, getString(R.string.section_user_ids)); @@ -138,6 +132,12 @@ public class ViewKeyAdvActivity extends BaseActivity implements // update layout after operations mSlidingTabLayout.setViewPager(mViewPager); + + // switch to tab selected by extra + Intent intent = getIntent(); + int switchToTab = intent.getIntExtra(EXTRA_SELECTED_TAB, TAB_SHARE); + mViewPager.setCurrentItem(switchToTab); + } // These are the rows that we will retrieve. @@ -216,6 +216,8 @@ public class ViewKeyAdvActivity extends BaseActivity implements mStatusBar.setBackgroundColor(ViewKeyActivity.getStatusBarBackgroundColor(color)); mSlidingTabLayout.setBackgroundColor(color); + initTabs(mDataUri, isSecret); + break; } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java index ad437f924..386a26ae2 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java @@ -43,15 +43,16 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements LoaderManager.LoaderCallbacks { public static final String ARG_DATA_URI = "uri"; + public static final String ARG_HAS_SECRET = "has_secret"; private ListView mUserIds; - private static final int LOADER_ID_UNIFIED = 0; - private static final int LOADER_ID_USER_IDS = 1; + private static final int LOADER_ID_USER_IDS = 0; private UserIdsAdapter mUserIdsAdapter; private Uri mDataUri; + private boolean mHasSecret; @Override public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) { -- cgit v1.2.3 From 5b6bc24a0c87162609d1c2b60ac8c13144641680 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 2 Nov 2015 21:30:41 +0100 Subject: extend-uid: add option icon for edit action mode --- .../keychain/ui/ViewKeyAdvActivity.java | 4 + .../keychain/ui/ViewKeyAdvUserIdsFragment.java | 127 +++++++++++++-------- .../keychain/ui/adapter/UserIdsAdapter.java | 18 ++- .../keychain/ui/adapter/UserIdsAddedAdapter.java | 2 +- .../main/res/layout/view_key_adv_user_id_item.xml | 29 ++--- .../src/main/res/menu/action_edit_uids.xml | 10 ++ OpenKeychain/src/main/res/menu/edit_user_id.xml | 12 ++ OpenKeychain/src/main/res/values/strings.xml | 1 + 8 files changed, 131 insertions(+), 72 deletions(-) create mode 100644 OpenKeychain/src/main/res/menu/action_edit_uids.xml create mode 100644 OpenKeychain/src/main/res/menu/edit_user_id.xml diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java index e676b441f..dc66e52ed 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java @@ -26,6 +26,10 @@ import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v4.view.ViewPager; +import android.support.v7.view.ActionMode; +import android.support.v7.view.ActionMode.Callback; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.widget.Toast; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java index 386a26ae2..2afb7d216 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java @@ -21,10 +21,16 @@ package org.sufficientlysecure.keychain.ui; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; +import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; +import android.view.ActionMode; +import android.view.ActionMode.Callback; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; @@ -33,8 +39,8 @@ import android.widget.ListView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter; import org.sufficientlysecure.keychain.ui.dialog.UserIdInfoDialogFragment; import org.sufficientlysecure.keychain.util.Log; @@ -95,54 +101,44 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements getActivity().finish(); return; } + boolean hasSecret = getArguments().getBoolean(ARG_HAS_SECRET); - loadData(dataUri); + loadData(dataUri, hasSecret); } - private void loadData(Uri dataUri) { + private void loadData(Uri dataUri, boolean hasSecret) { mDataUri = dataUri; + mHasSecret = hasSecret; - Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString()); + Log.i(Constants.TAG, "mDataUri: " + mDataUri); mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0); mUserIds.setAdapter(mUserIdsAdapter); + setHasOptionsMenu(hasSecret); + // Prepare the loaders. Either re-connect with an existing ones, // or start new ones. - getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this); getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this); } - static final String[] UNIFIED_PROJECTION = new String[]{ - KeyRings._ID, KeyRings.MASTER_KEY_ID, - KeyRings.HAS_ANY_SECRET, KeyRings.IS_REVOKED, KeyRings.IS_EXPIRED, KeyRings.HAS_ENCRYPT - }; - static final int INDEX_UNIFIED_MASTER_KEY_ID = 1; - static final int INDEX_UNIFIED_HAS_ANY_SECRET = 2; - static final int INDEX_UNIFIED_IS_REVOKED = 3; - static final int INDEX_UNIFIED_IS_EXPIRED = 4; - static final int INDEX_UNIFIED_HAS_ENCRYPT = 5; - public Loader onCreateLoader(int id, Bundle args) { setContentShown(false); - switch (id) { - case LOADER_ID_UNIFIED: { - Uri baseUri = KeyRings.buildUnifiedKeyRingUri(mDataUri); - return new CursorLoader(getActivity(), baseUri, UNIFIED_PROJECTION, null, null, null); - } - case LOADER_ID_USER_IDS: { - Uri baseUri = UserPackets.buildUserIdsUri(mDataUri); - return new CursorLoader(getActivity(), baseUri, - UserIdsAdapter.USER_PACKETS_PROJECTION, null, null, null); - } - - default: - return null; + if (id != LOADER_ID_USER_IDS) { + return null; } + + Uri baseUri = UserPackets.buildUserIdsUri(mDataUri); + return new CursorLoader(getActivity(), baseUri, + UserIdsAdapter.USER_PACKETS_PROJECTION, null, null, null); } public void onLoadFinished(Loader loader, Cursor data) { + if (loader.getId() != LOADER_ID_USER_IDS) { + return; + } + /* TODO better error handling? May cause problems when a key is deleted, * because the notification triggers faster than the activity closes. */ @@ -150,23 +146,8 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements if (data.getCount() == 0) { return; } - // Swap the new cursor in. (The framework will take care of closing the - // old cursor once we return.) - switch (loader.getId()) { - case LOADER_ID_UNIFIED: { - if (data.moveToFirst()) { - - break; - } - } - - case LOADER_ID_USER_IDS: { - mUserIdsAdapter.swapCursor(data); - break; - } - - } + mUserIdsAdapter.swapCursor(data); setContentShown(true); } @@ -175,11 +156,61 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements * We need to make sure we are no longer using it. */ public void onLoaderReset(Loader loader) { - switch (loader.getId()) { - case LOADER_ID_USER_IDS: - mUserIdsAdapter.swapCursor(null); - break; + if (loader.getId() != LOADER_ID_USER_IDS) { + return; } + mUserIdsAdapter.swapCursor(null); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.edit_user_id, menu); + MenuItem vEditUserIds = menu.findItem(R.id.menu_edit_user_ids); + vEditUserIds.setVisible(mHasSecret); } + public void enterEditMode() { + FragmentActivity activity = getActivity(); + activity.startActionMode(new Callback() { + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + mUserIdsAdapter.setEditMode(new SaveKeyringParcel(0L, new byte[0])); + getLoaderManager().restartLoader(LOADER_ID_USER_IDS, null, ViewKeyAdvUserIdsFragment.this); + + mode.setTitle("Edit User Ids"); + mode.getMenuInflater().inflate(R.menu.action_edit_uids, menu); + + return true; + } + + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return false; + } + + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + mode.finish(); + return true; + } + + @Override + public void onDestroyActionMode(ActionMode mode) { + mUserIdsAdapter.setEditMode(null); + getLoaderManager().restartLoader(LOADER_ID_USER_IDS, null, ViewKeyAdvUserIdsFragment.this); + } + }); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_edit_user_ids: + enterEditMode(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java index 0f4312dad..d5a9f551d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java @@ -29,6 +29,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; +import android.widget.ViewAnimator; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.KeyRing; @@ -66,7 +67,7 @@ public class UserIdsAdapter extends UserAttributesAdapter { TextView vAddress = (TextView) view.findViewById(R.id.user_id_item_address); TextView vComment = (TextView) view.findViewById(R.id.user_id_item_comment); ImageView vVerified = (ImageView) view.findViewById(R.id.user_id_item_certified); - View vVerifiedLayout = view.findViewById(R.id.user_id_item_certified_layout); + ViewAnimator vVerifiedLayout = (ViewAnimator) view.findViewById(R.id.user_id_icon_animator); ImageView vEditImage = (ImageView) view.findViewById(R.id.user_id_item_edit_image); ImageView vDeleteButton = (ImageView) view.findViewById(R.id.user_id_item_delete_button); vDeleteButton.setVisibility(View.GONE); // not used @@ -114,16 +115,9 @@ public class UserIdsAdapter extends UserAttributesAdapter { } } - vEditImage.setVisibility(View.VISIBLE); - vVerifiedLayout.setVisibility(View.GONE); + vVerifiedLayout.setDisplayedChild(2); } else { - vEditImage.setVisibility(View.GONE); - - if (mShowStatusImages) { - vVerifiedLayout.setVisibility(View.VISIBLE); - } else { - vVerifiedLayout.setVisibility(View.GONE); - } + vVerifiedLayout.setDisplayedChild(mShowStatusImages ? 1 : 0); } if (isRevoked) { @@ -177,6 +171,10 @@ public class UserIdsAdapter extends UserAttributesAdapter { return isRevokedPending; } + public void setEditMode(SaveKeyringParcel saveKeyringParcel) { + mSaveKeyringParcel = saveKeyringParcel; + } + @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { return mInflater.inflate(R.layout.view_key_adv_user_id_item, null); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAddedAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAddedAdapter.java index c7197b46d..b1892b27e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAddedAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAddedAdapter.java @@ -72,7 +72,7 @@ public class UserIdsAddedAdapter extends ArrayAdapter { holder.vDelete.setVisibility(View.VISIBLE); // always visible // not used: - View certifiedLayout = convertView.findViewById(R.id.user_id_item_certified_layout); + View certifiedLayout = convertView.findViewById(R.id.user_id_icon_animator); ImageView editImage = (ImageView) convertView.findViewById(R.id.user_id_item_edit_image); certifiedLayout.setVisibility(View.GONE); editImage.setVisibility(View.GONE); diff --git a/OpenKeychain/src/main/res/layout/view_key_adv_user_id_item.xml b/OpenKeychain/src/main/res/layout/view_key_adv_user_id_item.xml index a9ebe43d3..e2899f806 100644 --- a/OpenKeychain/src/main/res/layout/view_key_adv_user_id_item.xml +++ b/OpenKeychain/src/main/res/layout/view_key_adv_user_id_item.xml @@ -2,6 +2,7 @@ @@ -40,16 +41,19 @@ - - + android:orientation="vertical" + custom:initialView="1"> + + - + - + + + + + + \ No newline at end of file diff --git a/OpenKeychain/src/main/res/menu/edit_user_id.xml b/OpenKeychain/src/main/res/menu/edit_user_id.xml new file mode 100644 index 000000000..d1f856fd2 --- /dev/null +++ b/OpenKeychain/src/main/res/menu/edit_user_id.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index eb6dab882..33babe763 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -1704,5 +1704,6 @@ "Wrong data type, text was expected!" "No text in shared data!" "Search for\n'%s'" + Save -- cgit v1.2.3 From a041acab65b916e3727ec679edc0f5583847a96c Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 2 Nov 2015 21:59:31 +0100 Subject: extend-uid: allow changes to user ids in edit mode --- .../keychain/ui/EditKeyFragment.java | 3 +- .../keychain/ui/ViewKeyAdvActivity.java | 6 +- .../keychain/ui/ViewKeyAdvUserIdsFragment.java | 70 +++++++++++++++++++++- .../keychain/ui/adapter/UserAttributesAdapter.java | 1 + .../keychain/ui/adapter/UserIdsAdapter.java | 17 ++++-- .../ui/adapter/UserIdsSelectableAdapter.java | 4 +- OpenKeychain/src/main/res/values/strings.xml | 2 + 7 files changed, 87 insertions(+), 16 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index 07b0a12d3..fa0edec48 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -223,7 +223,8 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment parent, View view, int position, long id) { - showUserIdInfo(position); + showOrEditUserIdInfo(position); } }); return root; } + private void showOrEditUserIdInfo(final int position) { + if (mEditModeSaveKeyringParcel != null) { + editUserId(position); + } else { + showUserIdInfo(position); + } + } + + private void editUserId(final int position) { + final String userId = mUserIdsAdapter.getUserId(position); + final boolean isRevoked = mUserIdsAdapter.getIsRevoked(position); + final boolean isRevokedPending = mUserIdsAdapter.getIsRevokedPending(position); + + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + switch (message.what) { + case EditUserIdDialogFragment.MESSAGE_CHANGE_PRIMARY_USER_ID: + // toggle + if (mEditModeSaveKeyringParcel.mChangePrimaryUserId != null + && mEditModeSaveKeyringParcel.mChangePrimaryUserId.equals(userId)) { + mEditModeSaveKeyringParcel.mChangePrimaryUserId = null; + } else { + mEditModeSaveKeyringParcel.mChangePrimaryUserId = userId; + } + break; + case EditUserIdDialogFragment.MESSAGE_REVOKE: + // toggle + if (mEditModeSaveKeyringParcel.mRevokeUserIds.contains(userId)) { + mEditModeSaveKeyringParcel.mRevokeUserIds.remove(userId); + } else { + mEditModeSaveKeyringParcel.mRevokeUserIds.add(userId); + // not possible to revoke and change to primary user id + if (mEditModeSaveKeyringParcel.mChangePrimaryUserId != null + && mEditModeSaveKeyringParcel.mChangePrimaryUserId.equals(userId)) { + mEditModeSaveKeyringParcel.mChangePrimaryUserId = null; + } + } + break; + } + getLoaderManager().getLoader(LOADER_ID_USER_IDS).forceLoad(); + } + }; + + // Create a new Messenger for the communication back + final Messenger messenger = new Messenger(returnHandler); + + DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() { + public void run() { + EditUserIdDialogFragment dialogFragment = + EditUserIdDialogFragment.newInstance(messenger, isRevoked, isRevokedPending); + dialogFragment.show(getActivity().getSupportFragmentManager(), "editUserIdDialog"); + } + }); + } + private void showUserIdInfo(final int position) { + final boolean isRevoked = mUserIdsAdapter.getIsRevoked(position); final int isVerified = mUserIdsAdapter.getIsVerified(position); @@ -175,10 +237,11 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements activity.startActionMode(new Callback() { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { - mUserIdsAdapter.setEditMode(new SaveKeyringParcel(0L, new byte[0])); + mEditModeSaveKeyringParcel = new SaveKeyringParcel(0L, new byte[0]); + mUserIdsAdapter.setEditMode(mEditModeSaveKeyringParcel); getLoaderManager().restartLoader(LOADER_ID_USER_IDS, null, ViewKeyAdvUserIdsFragment.this); - mode.setTitle("Edit User Ids"); + mode.setTitle(R.string.title_edit_identities); mode.getMenuInflater().inflate(R.menu.action_edit_uids, menu); return true; @@ -197,6 +260,7 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements @Override public void onDestroyActionMode(ActionMode mode) { + mEditModeSaveKeyringParcel = null; mUserIdsAdapter.setEditMode(null); getLoaderManager().restartLoader(LOADER_ID_USER_IDS, null, ViewKeyAdvUserIdsFragment.this); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserAttributesAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserAttributesAdapter.java index e0abaf4b0..31f8513fa 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserAttributesAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserAttributesAdapter.java @@ -1,5 +1,6 @@ package org.sufficientlysecure.keychain.ui.adapter; + import android.content.Context; import android.database.Cursor; import android.support.v4.widget.CursorAdapter; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java index d5a9f551d..7dee90b4e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java @@ -23,6 +23,7 @@ import android.content.Context; import android.database.Cursor; import android.graphics.Typeface; import android.net.Uri; +import android.support.annotation.Nullable; import android.support.v4.content.CursorLoader; import android.view.LayoutInflater; import android.view.View; @@ -53,10 +54,6 @@ public class UserIdsAdapter extends UserAttributesAdapter { mShowStatusImages = showStatusImages; } - public UserIdsAdapter(Context context, Cursor c, int flags, SaveKeyringParcel saveKeyringParcel) { - this(context, c, flags, true, saveKeyringParcel); - } - public UserIdsAdapter(Context context, Cursor c, int flags) { this(context, c, flags, true, null); } @@ -171,7 +168,17 @@ public class UserIdsAdapter extends UserAttributesAdapter { return isRevokedPending; } - public void setEditMode(SaveKeyringParcel saveKeyringParcel) { + /** Set this adapter into edit mode. This mode displays additional info for + * each item from a supplied SaveKeyringParcel reference. + * + * Note that it is up to the caller to reload the underlying cursor after + * updating the SaveKeyringParcel! + * + * @see SaveKeyringParcel + * + * @param saveKeyringParcel The parcel to get info from, or null to leave edit mode. + */ + public void setEditMode(@Nullable SaveKeyringParcel saveKeyringParcel) { mSaveKeyringParcel = saveKeyringParcel; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsSelectableAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsSelectableAdapter.java index 947d911c3..3cc2e2044 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsSelectableAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsSelectableAdapter.java @@ -18,8 +18,8 @@ public class UserIdsSelectableAdapter extends UserIdsAdapter implements AdapterV private final ArrayList mCheckStates; - public UserIdsSelectableAdapter(Context context, Cursor c, int flags, SaveKeyringParcel saveKeyringParcel) { - super(context, c, flags, saveKeyringParcel); + public UserIdsSelectableAdapter(Context context, Cursor c, int flags) { + super(context, c, flags); mCheckStates = new ArrayList(); } diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 33babe763..78d4e03ee 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -1705,5 +1705,7 @@ "No text in shared data!" "Search for\n'%s'" Save + "Save" + "Edit Identities" -- cgit v1.2.3 From 4ec51fcd9fc1a0871436cdb3d44428d6af23afac Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 2 Nov 2015 22:14:21 +0100 Subject: extend-uid: button and list to add user ids --- .../keychain/ui/ViewKeyAdvUserIdsFragment.java | 51 +++++++++++++++++++++- .../main/res/layout/view_key_adv_main_fragment.xml | 43 +++++++++++++++++- 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java index fdaf188ca..6186e1440 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java @@ -18,6 +18,7 @@ package org.sufficientlysecure.keychain.ui; + import android.database.Cursor; import android.net.Uri; import android.os.Bundle; @@ -45,7 +46,10 @@ import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter; +import org.sufficientlysecure.keychain.ui.adapter.UserIdsAddedAdapter; +import org.sufficientlysecure.keychain.ui.dialog.AddUserIdDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.EditUserIdDialogFragment; +import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.UserIdInfoDialogFragment; import org.sufficientlysecure.keychain.util.Log; @@ -55,11 +59,14 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements public static final String ARG_DATA_URI = "uri"; public static final String ARG_HAS_SECRET = "has_secret"; - private ListView mUserIds; - private static final int LOADER_ID_USER_IDS = 0; + private ListView mUserIds; + private ListView mUserIdsAddedList; + private View mUserIdsAddedLayout; + private UserIdsAdapter mUserIdsAdapter; + private UserIdsAddedAdapter mUserIdsAddedAdapter; private Uri mDataUri; private boolean mHasSecret; @@ -71,6 +78,8 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements View view = inflater.inflate(R.layout.view_key_adv_main_fragment, getContainer()); mUserIds = (ListView) view.findViewById(R.id.view_key_user_ids); + mUserIdsAddedList = (ListView) view.findViewById(R.id.view_key_user_ids_added); + mUserIdsAddedLayout = view.findViewById(R.id.view_key_user_ids_add_layout); mUserIds.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override @@ -79,6 +88,13 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements } }); + view.findViewById(R.id.view_key_action_add_user_id).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + addUserId(); + } + }); + return root; } @@ -153,6 +169,29 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements }); } + private void addUserId() { + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == SetPassphraseDialogFragment.MESSAGE_OKAY) { + Bundle data = message.getData(); + + // add new user id + mUserIdsAddedAdapter.add(data + .getString(AddUserIdDialogFragment.MESSAGE_DATA_USER_ID)); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + // pre-fill out primary name + AddUserIdDialogFragment addUserIdDialog = AddUserIdDialogFragment.newInstance(messenger, ""); + + addUserIdDialog.show(getActivity().getSupportFragmentManager(), "addUserIdDialog"); + } + @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); @@ -237,7 +276,14 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements activity.startActionMode(new Callback() { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { + mEditModeSaveKeyringParcel = new SaveKeyringParcel(0L, new byte[0]); + + mUserIdsAddedAdapter = + new UserIdsAddedAdapter(getActivity(), mEditModeSaveKeyringParcel.mAddUserIds, false); + mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter); + mUserIdsAddedLayout.setVisibility(View.VISIBLE); + mUserIdsAdapter.setEditMode(mEditModeSaveKeyringParcel); getLoaderManager().restartLoader(LOADER_ID_USER_IDS, null, ViewKeyAdvUserIdsFragment.this); @@ -262,6 +308,7 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements public void onDestroyActionMode(ActionMode mode) { mEditModeSaveKeyringParcel = null; mUserIdsAdapter.setEditMode(null); + mUserIdsAddedLayout.setVisibility(View.GONE); getLoaderManager().restartLoader(LOADER_ID_USER_IDS, null, ViewKeyAdvUserIdsFragment.this); } }); diff --git a/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml index 3347a514c..d36c09ea1 100644 --- a/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml +++ b/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml @@ -1,6 +1,7 @@ + android:layout_height="match_parent" + xmlns:tools="http://schemas.android.com/tools"> + + + + + + + + + + + + -- cgit v1.2.3 From 312c245de10ef39a45cfdd832634017a4a1bb79f Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 2 Nov 2015 23:05:20 +0100 Subject: extended-share: move qr code resizing into onLayoutChangeListener (+performance, -recreation crash) --- .../keychain/ui/ViewKeyAdvShareFragment.java | 47 ++++++++++++++++++---- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java index c5e575e32..ce2f2def8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvShareFragment.java @@ -44,6 +44,7 @@ import android.support.v4.content.Loader; import android.support.v7.widget.CardView; import android.view.LayoutInflater; import android.view.View; +import android.view.View.OnLayoutChangeListener; import android.view.ViewGroup; import android.view.animation.AlphaAnimation; import android.widget.ImageButton; @@ -85,6 +86,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements private byte[] mFingerprint; private String mUserId; + private Bitmap mQrCodeBitmapCache; @Override public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) { @@ -96,6 +98,34 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements mFingerprintView = (TextView) view.findViewById(R.id.view_key_fingerprint); mQrCode = (ImageView) view.findViewById(R.id.view_key_qr_code); + + // We cache the QR code bitmap in its smallest possible size, then scale + // it manually for the correct size whenever the layout of the ImageView + // changes. The fingerprint qr code loader which runs in the background + // just calls requestLayout when it is finished, this way the loader and + // background task are disconnected from any layouting the ImageView may + // undergo. Please note how these six lines are perfectly right-aligned. + mQrCode.addOnLayoutChangeListener(new OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, + int oldRight, + int oldBottom) { + // bitmap scaling is expensive, avoid doing it if we already have the correct size! + int mCurrentWidth = 0, mCurrentHeight = 0; + if (mQrCodeBitmapCache != null) { + if (mCurrentWidth == mQrCode.getWidth() && mCurrentHeight == mQrCode.getHeight()) { + return; + } + mCurrentWidth = mQrCode.getWidth(); + mCurrentHeight = mQrCode.getHeight(); + // scale the image up to our actual size. we do this in code rather + // than let the ImageView do this because we don't require filtering. + Bitmap scaled = Bitmap.createScaledBitmap(mQrCodeBitmapCache, + mCurrentWidth, mCurrentHeight, false); + mQrCode.setImageBitmap(scaled); + } + } + }); mQrCodeLayout = (CardView) view.findViewById(R.id.view_key_qr_code_layout); mQrCodeLayout.setOnClickListener(new View.OnClickListener() { @Override @@ -379,6 +409,7 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements */ public void onLoaderReset(Loader loader) { mFingerprint = null; + mQrCodeBitmapCache = null; } /** @@ -390,6 +421,10 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements final String fingerprint = KeyFormattingUtils.convertFingerprintToHex(fingerprintBlob); mFingerprintView.setText(KeyFormattingUtils.colorizeFingerprint(fingerprint)); + if (mQrCodeBitmapCache != null) { + return; + } + AsyncTask loadTask = new AsyncTask() { protected Bitmap doInBackground(Void... unused) { @@ -402,15 +437,11 @@ public class ViewKeyAdvShareFragment extends LoaderFragment implements } protected void onPostExecute(Bitmap qrCode) { - // only change view, if fragment is attached to activity - if (ViewKeyAdvShareFragment.this.isAdded()) { + // cache for later, and if we are attached request re-layout + mQrCodeBitmapCache = qrCode; - // scale the image up to our actual size. we do this in code rather - // than let the ImageView do this because we don't require filtering. - Bitmap scaled = Bitmap.createScaledBitmap(qrCode, - mQrCode.getHeight(), mQrCode.getHeight(), - false); - mQrCode.setImageBitmap(scaled); + if (ViewKeyAdvShareFragment.this.isAdded()) { + mQrCode.requestLayout(); // simple fade-in animation AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f); -- cgit v1.2.3 From 54cc08c2917e2872cb79e56410b7c305dcebfef6 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 2 Nov 2015 23:06:35 +0100 Subject: extended: leave ActionMode on page change --- .../keychain/ui/ViewKeyAdvActivity.java | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java index a27bb3ad3..3db6bf4ae 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java @@ -27,6 +27,8 @@ import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v4.view.ViewPager; +import android.support.v4.view.ViewPager.SimpleOnPageChangeListener; +import android.view.ActionMode; import android.view.View; import android.widget.Toast; @@ -239,4 +241,23 @@ public class ViewKeyAdvActivity extends BaseActivity implements super.onActivityResult(requestCode, resultCode, data); } } + + @Override + public void onActionModeStarted(final ActionMode mode) { + super.onActionModeStarted(mode); + // Leave whatever action mode we are in when we change the page + mSlidingTabLayout.setOnPageChangeListener(new SimpleOnPageChangeListener() { + @Override + public void onPageSelected(int position) { + super.onPageSelected(position); + mode.finish(); + } + }); + } + + @Override + public void onActionModeFinished(ActionMode mode) { + super.onActionModeFinished(mode); + mSlidingTabLayout.setOnPageChangeListener(null); + } } -- cgit v1.2.3 From fd119bda00bac1cfe6dbcafa2736c65e3624c083 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Tue, 3 Nov 2015 00:30:12 +0100 Subject: extend-uid: use FAB instead of extra list item --- .../keychain/ui/ViewKeyAdvActivity.java | 2 + .../keychain/ui/ViewKeyAdvUserIdsFragment.java | 20 +++- OpenKeychain/src/main/res/anim/fab_slide_down.xml | 6 + OpenKeychain/src/main/res/anim/fab_slide_in.xml | 7 ++ .../main/res/layout/view_key_adv_main_fragment.xml | 122 +++++++++++---------- 5 files changed, 100 insertions(+), 57 deletions(-) create mode 100644 OpenKeychain/src/main/res/anim/fab_slide_down.xml create mode 100644 OpenKeychain/src/main/res/anim/fab_slide_in.xml diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java index 3db6bf4ae..01dc10d28 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java @@ -29,6 +29,7 @@ import android.support.v4.content.Loader; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.SimpleOnPageChangeListener; import android.view.ActionMode; +import android.view.Menu; import android.view.View; import android.widget.Toast; @@ -260,4 +261,5 @@ public class ViewKeyAdvActivity extends BaseActivity implements super.onActionModeFinished(mode); mSlidingTabLayout.setOnPageChangeListener(null); } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java index 6186e1440..e98970754 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java @@ -39,6 +39,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ListView; +import android.widget.ViewAnimator; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; @@ -64,6 +65,7 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements private ListView mUserIds; private ListView mUserIdsAddedList; private View mUserIdsAddedLayout; + private ViewAnimator mUserIdAddFabLayout; private UserIdsAdapter mUserIdsAdapter; private UserIdsAddedAdapter mUserIdsAddedAdapter; @@ -88,7 +90,19 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements } }); - view.findViewById(R.id.view_key_action_add_user_id).setOnClickListener(new View.OnClickListener() { + View footer = new View(getActivity()); + int spacing = (int) android.util.TypedValue.applyDimension( + android.util.TypedValue.COMPLEX_UNIT_DIP, 72, getResources().getDisplayMetrics() + ); + android.widget.AbsListView.LayoutParams params = new android.widget.AbsListView.LayoutParams( + android.widget.AbsListView.LayoutParams.MATCH_PARENT, + spacing + ); + footer.setLayoutParams(params); + mUserIdsAddedList.addFooterView(footer, null, false); + + mUserIdAddFabLayout = (ViewAnimator) view.findViewById(R.id.view_key_user_id_fab_layout); + view.findViewById(R.id.view_key_user_id_fab).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { addUserId(); @@ -271,7 +285,7 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements vEditUserIds.setVisible(mHasSecret); } - public void enterEditMode() { + private void enterEditMode() { FragmentActivity activity = getActivity(); activity.startActionMode(new Callback() { @Override @@ -283,6 +297,7 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements new UserIdsAddedAdapter(getActivity(), mEditModeSaveKeyringParcel.mAddUserIds, false); mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter); mUserIdsAddedLayout.setVisibility(View.VISIBLE); + mUserIdAddFabLayout.setDisplayedChild(1); mUserIdsAdapter.setEditMode(mEditModeSaveKeyringParcel); getLoaderManager().restartLoader(LOADER_ID_USER_IDS, null, ViewKeyAdvUserIdsFragment.this); @@ -309,6 +324,7 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements mEditModeSaveKeyringParcel = null; mUserIdsAdapter.setEditMode(null); mUserIdsAddedLayout.setVisibility(View.GONE); + mUserIdAddFabLayout.setDisplayedChild(0); getLoaderManager().restartLoader(LOADER_ID_USER_IDS, null, ViewKeyAdvUserIdsFragment.this); } }); diff --git a/OpenKeychain/src/main/res/anim/fab_slide_down.xml b/OpenKeychain/src/main/res/anim/fab_slide_down.xml new file mode 100644 index 000000000..e51ac0cb9 --- /dev/null +++ b/OpenKeychain/src/main/res/anim/fab_slide_down.xml @@ -0,0 +1,6 @@ + + diff --git a/OpenKeychain/src/main/res/anim/fab_slide_in.xml b/OpenKeychain/src/main/res/anim/fab_slide_in.xml new file mode 100644 index 000000000..cb38f81e8 --- /dev/null +++ b/OpenKeychain/src/main/res/anim/fab_slide_in.xml @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml index d36c09ea1..ab0c59865 100644 --- a/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml +++ b/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml @@ -1,74 +1,86 @@ - - - - - - - + android:layout_height="match_parent"> + + android:paddingLeft="16dp" + android:paddingRight="16dp"> - + + android:layout_height="0dp" + android:layout_marginBottom="4dp" + android:layout_weight="1" /> - + - + + + + + - + + + + + + + + + - + -- cgit v1.2.3 From 00e97586b06e5e61f6639b75423f9ec3edba47a0 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sat, 14 Nov 2015 03:24:07 +0100 Subject: inline subkey editing (wip commit) --- .../keychain/ui/EditKeyFragment.java | 3 +- .../keychain/ui/ViewKeyAdvSubkeysFragment.java | 272 ++++++++++++++++++++- .../keychain/ui/ViewKeyAdvUserIdsFragment.java | 4 +- .../keychain/ui/adapter/SubkeysAdapter.java | 29 ++- .../main/res/layout/view_key_adv_main_fragment.xml | 4 +- .../res/layout/view_key_adv_subkeys_fragment.xml | 104 ++++++-- OpenKeychain/src/main/res/menu/edit_subkeys.xml | 12 + OpenKeychain/src/main/res/menu/edit_user_id.xml | 2 +- OpenKeychain/src/main/res/menu/key_view.xml | 2 +- OpenKeychain/src/main/res/values-cs/strings.xml | 2 +- OpenKeychain/src/main/res/values-de/strings.xml | 2 +- OpenKeychain/src/main/res/values-es/strings.xml | 2 +- OpenKeychain/src/main/res/values-eu/strings.xml | 2 +- OpenKeychain/src/main/res/values-fr/strings.xml | 2 +- OpenKeychain/src/main/res/values-it/strings.xml | 2 +- OpenKeychain/src/main/res/values-ja/strings.xml | 2 +- OpenKeychain/src/main/res/values-nl/strings.xml | 2 +- OpenKeychain/src/main/res/values-pl/strings.xml | 2 +- OpenKeychain/src/main/res/values-ru/strings.xml | 2 +- OpenKeychain/src/main/res/values-sl/strings.xml | 2 +- OpenKeychain/src/main/res/values-sr/strings.xml | 2 +- OpenKeychain/src/main/res/values-sv/strings.xml | 2 +- OpenKeychain/src/main/res/values-tr/strings.xml | 2 +- OpenKeychain/src/main/res/values-uk/strings.xml | 2 +- .../src/main/res/values-zh-rTW/strings.xml | 2 +- OpenKeychain/src/main/res/values/strings.xml | 5 +- 26 files changed, 409 insertions(+), 60 deletions(-) create mode 100644 OpenKeychain/src/main/res/menu/edit_subkeys.xml diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index fa0edec48..969a84f14 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -231,7 +231,8 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment { public static final String ARG_DATA_URI = "data_uri"; + public static final int LOADER_ID_SUBKEYS = 0; private ListView mSubkeysList; + private ListView mSubkeysAddedList; + private View mSubkeysAddedLayout; + private ViewAnimator mSubkeyAddFabLayout; + private SubkeysAdapter mSubkeysAdapter; + private SubkeysAddedAdapter mSubkeysAddedAdapter; private Uri mDataUriSubkeys; + private boolean mHasSecret; + private SaveKeyringParcel mEditModeSaveKeyringParcel; + /** * Creates new instance of this fragment */ @@ -64,6 +93,36 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements mSubkeysList = (ListView) view.findViewById(R.id.keys); + mSubkeysList = (ListView) view.findViewById(R.id.view_key_user_ids); + mSubkeysAddedList = (ListView) view.findViewById(R.id.view_key_user_ids_added); + mSubkeysAddedLayout = view.findViewById(R.id.view_key_user_ids_add_layout); + + mSubkeysList.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + editSubkey(position); + } + }); + + View footer = new View(getActivity()); + int spacing = (int) android.util.TypedValue.applyDimension( + android.util.TypedValue.COMPLEX_UNIT_DIP, 72, getResources().getDisplayMetrics() + ); + android.widget.AbsListView.LayoutParams params = new android.widget.AbsListView.LayoutParams( + android.widget.AbsListView.LayoutParams.MATCH_PARENT, + spacing + ); + footer.setLayoutParams(params); + mSubkeysAddedList.addFooterView(footer, null, false); + + mSubkeyAddFabLayout = (ViewAnimator) view.findViewById(R.id.view_key_subkey_fab_layout); + view.findViewById(R.id.view_key_subkey_fab).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + addSubkey(); + } + }); + return root; } @@ -90,7 +149,7 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements // Prepare the loaders. Either re-connect with an existing ones, // or start new ones. - getLoaderManager().initLoader(0, null, this); + getLoaderManager().initLoader(LOADER_ID_SUBKEYS, null, this); } public Loader onCreateLoader(int id, Bundle args) { @@ -122,4 +181,215 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements mSubkeysAdapter.swapCursor(null); } + private void enterEditMode() { + FragmentActivity activity = getActivity(); + activity.startActionMode(new Callback() { + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + + mEditModeSaveKeyringParcel = new SaveKeyringParcel(0L, new byte[0]); + + mSubkeysAddedAdapter = + new SubkeysAddedAdapter(getActivity(), mEditModeSaveKeyringParcel.mAddSubKeys, false); + mSubkeysAddedList.setAdapter(mSubkeysAddedAdapter); + mSubkeysAddedLayout.setVisibility(View.VISIBLE); + mSubkeyAddFabLayout.setDisplayedChild(1); + + mSubkeysAdapter.setEditMode(mEditModeSaveKeyringParcel); + getLoaderManager().restartLoader(LOADER_ID_SUBKEYS, null, ViewKeyAdvSubkeysFragment.this); + + mode.setTitle(R.string.title_edit_subkeys); + mode.getMenuInflater().inflate(R.menu.action_edit_uids, menu); + + return true; + } + + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return false; + } + + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + mode.finish(); + return true; + } + + @Override + public void onDestroyActionMode(ActionMode mode) { + mEditModeSaveKeyringParcel = null; + mSubkeysAdapter.setEditMode(null); + mSubkeysAddedLayout.setVisibility(View.GONE); + mSubkeyAddFabLayout.setDisplayedChild(0); + getLoaderManager().restartLoader(0, null, ViewKeyAdvSubkeysFragment.this); + } + }); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_edit_subkeys: + enterEditMode(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + private void addSubkey() { + boolean willBeMasterKey; + if (mSubkeysAdapter != null) { + willBeMasterKey = mSubkeysAdapter.getCount() == 0 && mSubkeysAddedAdapter.getCount() == 0; + } else { + willBeMasterKey = mSubkeysAddedAdapter.getCount() == 0; + } + + AddSubkeyDialogFragment addSubkeyDialogFragment = + AddSubkeyDialogFragment.newInstance(willBeMasterKey); + addSubkeyDialogFragment + .setOnAlgorithmSelectedListener( + new AddSubkeyDialogFragment.OnAlgorithmSelectedListener() { + @Override + public void onAlgorithmSelected(SaveKeyringParcel.SubkeyAdd newSubkey) { + mSubkeysAddedAdapter.add(newSubkey); + } + } + ); + addSubkeyDialogFragment.show(getActivity().getSupportFragmentManager(), "addSubkeyDialog"); + } + + private void editSubkey(final int position) { + final long keyId = mSubkeysAdapter.getKeyId(position); + + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + switch (message.what) { + case EditSubkeyDialogFragment.MESSAGE_CHANGE_EXPIRY: + editSubkeyExpiry(position); + break; + case EditSubkeyDialogFragment.MESSAGE_REVOKE: + // toggle + if (mEditModeSaveKeyringParcel.mRevokeSubKeys.contains(keyId)) { + mEditModeSaveKeyringParcel.mRevokeSubKeys.remove(keyId); + } else { + mEditModeSaveKeyringParcel.mRevokeSubKeys.add(keyId); + } + break; + case EditSubkeyDialogFragment.MESSAGE_STRIP: { + SecretKeyType secretKeyType = mSubkeysAdapter.getSecretKeyType(position); + if (secretKeyType == SecretKeyType.GNU_DUMMY) { + // Key is already stripped; this is a no-op. + break; + } + + SubkeyChange change = mEditModeSaveKeyringParcel.getSubkeyChange(keyId); + if (change == null) { + mEditModeSaveKeyringParcel.mChangeSubKeys.add(new SubkeyChange(keyId, true, false)); + break; + } + // toggle + change.mDummyStrip = !change.mDummyStrip; + if (change.mDummyStrip && change.mMoveKeyToCard) { + // User had chosen to divert key, but now wants to strip it instead. + change.mMoveKeyToCard = false; + } + break; + } + case EditSubkeyDialogFragment.MESSAGE_MOVE_KEY_TO_CARD: { + // TODO: enable later when Admin PIN handling is resolved + Notify.create(getActivity(), + "This feature will be available in an upcoming OpenKeychain version.", + Notify.Style.WARN).show(); + break; + +// Activity activity = EditKeyFragment.this.getActivity(); +// SecretKeyType secretKeyType = mSubkeysAdapter.getSecretKeyType(position); +// if (secretKeyType == SecretKeyType.DIVERT_TO_CARD || +// secretKeyType == SecretKeyType.GNU_DUMMY) { +// Notify.create(activity, R.string.edit_key_error_bad_nfc_stripped, Notify.Style.ERROR) +// .show((ViewGroup) activity.findViewById(R.id.import_snackbar)); +// break; +// } +// int algorithm = mSubkeysAdapter.getAlgorithm(position); +// // these are the PGP constants for RSA_GENERAL, RSA_ENCRYPT and RSA_SIGN +// if (algorithm != 1 && algorithm != 2 && algorithm != 3) { +// Notify.create(activity, R.string.edit_key_error_bad_nfc_algo, Notify.Style.ERROR) +// .show((ViewGroup) activity.findViewById(R.id.import_snackbar)); +// break; +// } +// if (mSubkeysAdapter.getKeySize(position) != 2048) { +// Notify.create(activity, R.string.edit_key_error_bad_nfc_size, Notify.Style.ERROR) +// .show((ViewGroup) activity.findViewById(R.id.import_snackbar)); +// break; +// } +// +// +// SubkeyChange change; +// change = mSaveKeyringParcel.getSubkeyChange(keyId); +// if (change == null) { +// mSaveKeyringParcel.mChangeSubKeys.add( +// new SubkeyChange(keyId, false, true) +// ); +// break; +// } +// // toggle +// change.mMoveKeyToCard = !change.mMoveKeyToCard; +// if (change.mMoveKeyToCard && change.mDummyStrip) { +// // User had chosen to strip key, but now wants to divert it. +// change.mDummyStrip = false; +// } +// break; + } + } + getLoaderManager().getLoader(LOADER_ID_SUBKEYS).forceLoad(); + } + }; + + // Create a new Messenger for the communication back + final Messenger messenger = new Messenger(returnHandler); + + DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() { + public void run() { + EditSubkeyDialogFragment dialogFragment = + EditSubkeyDialogFragment.newInstance(messenger); + + dialogFragment.show(getActivity().getSupportFragmentManager(), "editSubkeyDialog"); + } + }); + } + + private void editSubkeyExpiry(final int position) { + final long keyId = mSubkeysAdapter.getKeyId(position); + final Long creationDate = mSubkeysAdapter.getCreationDate(position); + final Long expiryDate = mSubkeysAdapter.getExpiryDate(position); + + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + switch (message.what) { + case EditSubkeyExpiryDialogFragment.MESSAGE_NEW_EXPIRY: + mEditModeSaveKeyringParcel.getOrCreateSubkeyChange(keyId).mExpiry = + (Long) message.getData().getSerializable( + EditSubkeyExpiryDialogFragment.MESSAGE_DATA_EXPIRY); + break; + } + getLoaderManager().getLoader(LOADER_ID_SUBKEYS).forceLoad(); + } + }; + + // Create a new Messenger for the communication back + final Messenger messenger = new Messenger(returnHandler); + + DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() { + public void run() { + EditSubkeyExpiryDialogFragment dialogFragment = + EditSubkeyExpiryDialogFragment.newInstance(messenger, creationDate, expiryDate); + + dialogFragment.show(getActivity().getSupportFragmentManager(), "editSubkeyExpiryDialog"); + } + }); + } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java index e98970754..c8e892276 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java @@ -101,8 +101,8 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements footer.setLayoutParams(params); mUserIdsAddedList.addFooterView(footer, null, false); - mUserIdAddFabLayout = (ViewAnimator) view.findViewById(R.id.view_key_user_id_fab_layout); - view.findViewById(R.id.view_key_user_id_fab).setOnClickListener(new View.OnClickListener() { + mUserIdAddFabLayout = (ViewAnimator) view.findViewById(R.id.view_key_subkey_fab_layout); + view.findViewById(R.id.view_key_subkey_fab).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { addUserId(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java index 24f5f04a1..84608f2dc 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java @@ -22,6 +22,7 @@ import android.content.res.ColorStateList; import android.database.Cursor; import android.graphics.PorterDuff; import android.graphics.Typeface; +import android.support.annotation.Nullable; import android.support.v4.widget.CursorAdapter; import android.text.Spannable; import android.text.SpannableString; @@ -49,7 +50,7 @@ public class SubkeysAdapter extends CursorAdapter { private LayoutInflater mInflater; private SaveKeyringParcel mSaveKeyringParcel; - private boolean hasAnySecret; + private boolean mHasAnySecret; private ColorStateList mDefaultTextColor; public static final String[] SUBKEYS_PROJECTION = new String[]{ @@ -85,16 +86,10 @@ public class SubkeysAdapter extends CursorAdapter { private static final int INDEX_EXPIRY = 13; private static final int INDEX_FINGERPRINT = 14; - public SubkeysAdapter(Context context, Cursor c, int flags, - SaveKeyringParcel saveKeyringParcel) { + public SubkeysAdapter(Context context, Cursor c, int flags) { super(context, c, flags); mInflater = LayoutInflater.from(context); - mSaveKeyringParcel = saveKeyringParcel; - } - - public SubkeysAdapter(Context context, Cursor c, int flags) { - this(context, c, flags, null); } public long getKeyId(int position) { @@ -133,12 +128,12 @@ public class SubkeysAdapter extends CursorAdapter { @Override public Cursor swapCursor(Cursor newCursor) { - hasAnySecret = false; + mHasAnySecret = false; if (newCursor != null && newCursor.moveToFirst()) { do { SecretKeyType hasSecret = SecretKeyType.fromNum(newCursor.getInt(INDEX_HAS_SECRET)); if (hasSecret.isUsable()) { - hasAnySecret = true; + mHasAnySecret = true; break; } } while (newCursor.moveToNext()); @@ -354,4 +349,18 @@ public class SubkeysAdapter extends CursorAdapter { } } + /** Set this adapter into edit mode. This mode displays additional info for + * each item from a supplied SaveKeyringParcel reference. + * + * Note that it is up to the caller to reload the underlying cursor after + * updating the SaveKeyringParcel! + * + * @see SaveKeyringParcel + * + * @param saveKeyringParcel The parcel to get info from, or null to leave edit mode. + */ + public void setEditMode(@Nullable SaveKeyringParcel saveKeyringParcel) { + mSaveKeyringParcel = saveKeyringParcel; + } + } diff --git a/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml index ab0c59865..98ee2d492 100644 --- a/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml +++ b/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml @@ -63,7 +63,7 @@ android:layout_alignParentRight="true" android:layout_alignParentEnd="true" android:layout_alignParentBottom="true" - android:id="@+id/view_key_user_id_fab_layout" + android:id="@+id/view_key_subkey_fab_layout" android:inAnimation="@anim/fab_slide_in" android:outAnimation="@anim/fab_slide_down"> @@ -72,7 +72,7 @@ android:layout_height="wrap_content" /> - + + - - + android:layout_height="match_parent"> - + + android:layout_height="wrap_content" + android:focusable="true" + android:focusableInTouchMode="true" + android:descendantFocusability="beforeDescendants" + android:orientation="vertical" + android:paddingLeft="16dp" + android:paddingRight="16dp"> + + - + + - + android:orientation="vertical" + android:id="@+id/view_key_subkeys_add_layout" + android:visibility="gone" + tools:visibility="visible"> + + + + + + + + + + + + + + + + + + - \ No newline at end of file + diff --git a/OpenKeychain/src/main/res/menu/edit_subkeys.xml b/OpenKeychain/src/main/res/menu/edit_subkeys.xml new file mode 100644 index 000000000..f9f75ebbb --- /dev/null +++ b/OpenKeychain/src/main/res/menu/edit_subkeys.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/OpenKeychain/src/main/res/menu/edit_user_id.xml b/OpenKeychain/src/main/res/menu/edit_user_id.xml index d1f856fd2..617dae841 100644 --- a/OpenKeychain/src/main/res/menu/edit_user_id.xml +++ b/OpenKeychain/src/main/res/menu/edit_user_id.xml @@ -5,7 +5,7 @@ diff --git a/OpenKeychain/src/main/res/menu/key_view.xml b/OpenKeychain/src/main/res/menu/key_view.xml index c0adfcd6f..a3de4efed 100644 --- a/OpenKeychain/src/main/res/menu/key_view.xml +++ b/OpenKeychain/src/main/res/menu/key_view.xml @@ -7,7 +7,7 @@ android:icon="@drawable/ic_mode_edit_white_24dp" android:visible="false" app:showAsAction="always" - android:title="@string/key_view_action_edit" /> + android:title="@string/key_view_action_edit_ids" /> Žádný klíč nenalezen! Zobrazit všechny klíče - Editovat klíč + Editovat klíč Zašifrovat text soubory Potvrdit klíč diff --git a/OpenKeychain/src/main/res/values-de/strings.xml b/OpenKeychain/src/main/res/values-de/strings.xml index 6f4b8d1d5..6a29c338f 100644 --- a/OpenKeychain/src/main/res/values-de/strings.xml +++ b/OpenKeychain/src/main/res/values-de/strings.xml @@ -572,7 +572,7 @@ Schlüsselsuche Aus Datei importieren - Schlüssel bearbeiten + Schlüssel bearbeiten Text verschlüsseln Dateien Schlüssel bestätigen diff --git a/OpenKeychain/src/main/res/values-es/strings.xml b/OpenKeychain/src/main/res/values-es/strings.xml index b39ccac5c..b895ced33 100644 --- a/OpenKeychain/src/main/res/values-es/strings.xml +++ b/OpenKeychain/src/main/res/values-es/strings.xml @@ -581,7 +581,7 @@ Búsqueda de clave Importar desde fichero - Editar clave + Editar clave Cifrar texto ficheros Confirmar clave diff --git a/OpenKeychain/src/main/res/values-eu/strings.xml b/OpenKeychain/src/main/res/values-eu/strings.xml index 3d2ba88d8..b26be00ce 100644 --- a/OpenKeychain/src/main/res/values-eu/strings.xml +++ b/OpenKeychain/src/main/res/values-eu/strings.xml @@ -576,7 +576,7 @@ Giltza Bilaketa Inportatu Agiritik - Editatu giltza + Editatu giltza Enkriptatu idazkia agiriak Baieztatu giltza diff --git a/OpenKeychain/src/main/res/values-fr/strings.xml b/OpenKeychain/src/main/res/values-fr/strings.xml index d80ff8988..506cf2af9 100644 --- a/OpenKeychain/src/main/res/values-fr/strings.xml +++ b/OpenKeychain/src/main/res/values-fr/strings.xml @@ -586,7 +586,7 @@ Recherche de clefs Importer d\'un fichier - Modifier la clef + Modifier la clef Chiffrer un texte fichiers Confirmer la clef diff --git a/OpenKeychain/src/main/res/values-it/strings.xml b/OpenKeychain/src/main/res/values-it/strings.xml index 42478af12..8a9fc394f 100644 --- a/OpenKeychain/src/main/res/values-it/strings.xml +++ b/OpenKeychain/src/main/res/values-it/strings.xml @@ -441,7 +441,7 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars Nessuna chiave trovata! Mostra tutte le chiavi - Modifica chiave + Modifica chiave Codifica Testo documenti Aggiorna dal server delle chiavi diff --git a/OpenKeychain/src/main/res/values-ja/strings.xml b/OpenKeychain/src/main/res/values-ja/strings.xml index 82a4c8f33..5b1b3e9ef 100644 --- a/OpenKeychain/src/main/res/values-ja/strings.xml +++ b/OpenKeychain/src/main/res/values-ja/strings.xml @@ -573,7 +573,7 @@ 鍵の検索 ファイルからインポート - 鍵の編集 + 鍵の編集 テキスト暗号化 ファイル 鍵の確認 diff --git a/OpenKeychain/src/main/res/values-nl/strings.xml b/OpenKeychain/src/main/res/values-nl/strings.xml index 04fac67f2..932832f60 100644 --- a/OpenKeychain/src/main/res/values-nl/strings.xml +++ b/OpenKeychain/src/main/res/values-nl/strings.xml @@ -489,7 +489,7 @@ Geen sleutels gevonden! Alle sleutels weergeven - Sleutel bewerken + Sleutel bewerken Versleutel tekst bestanden Sleutel bevestigen diff --git a/OpenKeychain/src/main/res/values-pl/strings.xml b/OpenKeychain/src/main/res/values-pl/strings.xml index 5c80bf161..adb3cf49f 100644 --- a/OpenKeychain/src/main/res/values-pl/strings.xml +++ b/OpenKeychain/src/main/res/values-pl/strings.xml @@ -373,7 +373,7 @@ OSTRZEŻENIE: Jeżeli nie wiesz, czemu wyświetlił się ten komunikat, nie zezw Nie znaleziono kluczy! Pokaż wszystkie klucze - Edytuj klucz + Edytuj klucz Szyfruj tekst pliki Aktualizuj z serwera kluczy diff --git a/OpenKeychain/src/main/res/values-ru/strings.xml b/OpenKeychain/src/main/res/values-ru/strings.xml index c1710c063..10dd79cba 100644 --- a/OpenKeychain/src/main/res/values-ru/strings.xml +++ b/OpenKeychain/src/main/res/values-ru/strings.xml @@ -487,7 +487,7 @@ Показать все ключи Поиск ключа - Изменить ключ + Изменить ключ Зашифровать текст файлы Подтвердить ключ diff --git a/OpenKeychain/src/main/res/values-sl/strings.xml b/OpenKeychain/src/main/res/values-sl/strings.xml index d7db38ccf..697de0984 100644 --- a/OpenKeychain/src/main/res/values-sl/strings.xml +++ b/OpenKeychain/src/main/res/values-sl/strings.xml @@ -426,7 +426,7 @@ Najden ni bil noben ključ! Prikaži vse ključe - Uredi ključ + Uredi ključ Šifriraj besedilo datoteke Potrdi ključ diff --git a/OpenKeychain/src/main/res/values-sr/strings.xml b/OpenKeychain/src/main/res/values-sr/strings.xml index f19f92087..8ff26f896 100644 --- a/OpenKeychain/src/main/res/values-sr/strings.xml +++ b/OpenKeychain/src/main/res/values-sr/strings.xml @@ -600,7 +600,7 @@ Претрага кључа Увези из фајла - Уреди кључ + Уреди кључ Шифруј текст фајлови Потврди кључ diff --git a/OpenKeychain/src/main/res/values-sv/strings.xml b/OpenKeychain/src/main/res/values-sv/strings.xml index 23d7e6908..f3a818ecf 100644 --- a/OpenKeychain/src/main/res/values-sv/strings.xml +++ b/OpenKeychain/src/main/res/values-sv/strings.xml @@ -476,7 +476,7 @@ Nyckelsökning Importera från fil - Redigera nyckel + Redigera nyckel Kryptera text filer Bekräfta nyckel diff --git a/OpenKeychain/src/main/res/values-tr/strings.xml b/OpenKeychain/src/main/res/values-tr/strings.xml index 22cd4e361..b6088a954 100644 --- a/OpenKeychain/src/main/res/values-tr/strings.xml +++ b/OpenKeychain/src/main/res/values-tr/strings.xml @@ -302,7 +302,7 @@ Tüm anahtarları göster - Anahtarı düzenle + Anahtarı düzenle Metni şifrele dosyalar Anahtar sunucusundan güncelle diff --git a/OpenKeychain/src/main/res/values-uk/strings.xml b/OpenKeychain/src/main/res/values-uk/strings.xml index 0613819e9..97f9ec391 100644 --- a/OpenKeychain/src/main/res/values-uk/strings.xml +++ b/OpenKeychain/src/main/res/values-uk/strings.xml @@ -309,7 +309,7 @@ Ключ не знайдено! Показати усі ключі - Редагувати ключ + Редагувати ключ Зашифрувати текст файли Оновити із сервера ключів diff --git a/OpenKeychain/src/main/res/values-zh-rTW/strings.xml b/OpenKeychain/src/main/res/values-zh-rTW/strings.xml index 81b3bf126..cb4ebf002 100644 --- a/OpenKeychain/src/main/res/values-zh-rTW/strings.xml +++ b/OpenKeychain/src/main/res/values-zh-rTW/strings.xml @@ -479,7 +479,7 @@ 找不到金鑰! - 編輯金鑰 + 編輯金鑰 加密文字 檔案 分享... diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 78d4e03ee..ee498b969 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -666,7 +666,8 @@ "Import from File" - "Edit key" + "Edit Identities" + "Edit Subkeys" "Encrypt text" "files" "Confirm key" @@ -1707,5 +1708,7 @@ Save "Save" "Edit Identities" + "Edit Subkeys" + "Search for\n'%s'" -- cgit v1.2.3 From 69220cb4c0466112426e7d10f865da834b464d90 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Sun, 15 Nov 2015 20:19:24 +0100 Subject: inline subkey editing, fixed --- .../keychain/ui/ViewKeyAdvActivity.java | 1 + .../keychain/ui/ViewKeyAdvSubkeysFragment.java | 25 ++++++++++++++++------ .../keychain/ui/ViewKeyAdvUserIdsFragment.java | 4 ++-- .../res/layout/view_key_adv_subkeys_fragment.xml | 2 +- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java index 01dc10d28..86cabaf96 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java @@ -125,6 +125,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements Bundle keysBundle = new Bundle(); keysBundle.putParcelable(ViewKeyAdvSubkeysFragment.ARG_DATA_URI, dataUri); + keysBundle.putBoolean(ViewKeyAdvSubkeysFragment.ARG_HAS_SECRET, hasSecret); adapter.addTab(ViewKeyAdvSubkeysFragment.class, keysBundle, getString(R.string.key_view_tab_keys)); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java index ce68bfab1..048dd4f77 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java @@ -47,7 +47,6 @@ import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange; import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter; import org.sufficientlysecure.keychain.ui.adapter.SubkeysAddedAdapter; -import org.sufficientlysecure.keychain.ui.adapter.UserIdsAddedAdapter; import org.sufficientlysecure.keychain.ui.dialog.AddSubkeyDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.EditSubkeyDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.EditSubkeyExpiryDialogFragment; @@ -58,6 +57,8 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements LoaderManager.LoaderCallbacks { public static final String ARG_DATA_URI = "data_uri"; + public static final String ARG_HAS_SECRET = "has_secret"; + public static final int LOADER_ID_SUBKEYS = 0; private ListView mSubkeysList; @@ -76,11 +77,12 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements /** * Creates new instance of this fragment */ - public static ViewKeyAdvSubkeysFragment newInstance(Uri dataUri) { + public static ViewKeyAdvSubkeysFragment newInstance(Uri dataUri, boolean hasSecret) { ViewKeyAdvSubkeysFragment frag = new ViewKeyAdvSubkeysFragment(); Bundle args = new Bundle(); args.putParcelable(ARG_DATA_URI, dataUri); + args.putBoolean(ARG_HAS_SECRET, hasSecret); frag.setArguments(args); return frag; @@ -91,11 +93,9 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements View root = super.onCreateView(inflater, superContainer, savedInstanceState); View view = inflater.inflate(R.layout.view_key_adv_subkeys_fragment, getContainer()); - mSubkeysList = (ListView) view.findViewById(R.id.keys); - - mSubkeysList = (ListView) view.findViewById(R.id.view_key_user_ids); - mSubkeysAddedList = (ListView) view.findViewById(R.id.view_key_user_ids_added); - mSubkeysAddedLayout = view.findViewById(R.id.view_key_user_ids_add_layout); + mSubkeysList = (ListView) view.findViewById(R.id.view_key_subkeys); + mSubkeysAddedList = (ListView) view.findViewById(R.id.view_key_subkeys_added); + mSubkeysAddedLayout = view.findViewById(R.id.view_key_subkeys_add_layout); mSubkeysList.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override @@ -136,6 +136,9 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements getActivity().finish(); return; } + mHasSecret = getArguments().getBoolean(ARG_HAS_SECRET); + + setHasOptionsMenu(true); loadData(dataUri); } @@ -226,6 +229,14 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements }); } + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + inflater.inflate(R.menu.edit_subkeys, menu); + final MenuItem vEditSubkeys = menu.findItem(R.id.menu_edit_subkeys); + vEditSubkeys.setVisible(mHasSecret); + } + @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java index c8e892276..49c0184c7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java @@ -218,6 +218,8 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements } boolean hasSecret = getArguments().getBoolean(ARG_HAS_SECRET); + setHasOptionsMenu(true); + loadData(dataUri, hasSecret); } @@ -230,8 +232,6 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0); mUserIds.setAdapter(mUserIdsAdapter); - setHasOptionsMenu(hasSecret); - // Prepare the loaders. Either re-connect with an existing ones, // or start new ones. getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this); diff --git a/OpenKeychain/src/main/res/layout/view_key_adv_subkeys_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_adv_subkeys_fragment.xml index c86b32349..001078b76 100644 --- a/OpenKeychain/src/main/res/layout/view_key_adv_subkeys_fragment.xml +++ b/OpenKeychain/src/main/res/layout/view_key_adv_subkeys_fragment.xml @@ -28,7 +28,7 @@ xmlns:tools="http://schemas.android.com/tools"> android:layout_weight="1" /> Date: Sun, 15 Nov 2015 23:24:20 +0100 Subject: inline-edit: move action mode menu handling int activity --- .../keychain/ui/ViewKeyAdvActivity.java | 118 ++++++++++++++++++--- .../keychain/ui/ViewKeyAdvSubkeysFragment.java | 43 ++++---- .../keychain/ui/ViewKeyAdvUserIdsFragment.java | 36 +++---- OpenKeychain/src/main/res/layout/edit_icon.xml | 9 ++ .../src/main/res/menu/action_mode_edit.xml | 12 +++ OpenKeychain/src/main/res/menu/edit_subkeys.xml | 12 --- OpenKeychain/src/main/res/menu/edit_user_id.xml | 12 --- OpenKeychain/src/main/res/values/strings.xml | 3 +- 8 files changed, 157 insertions(+), 88 deletions(-) create mode 100644 OpenKeychain/src/main/res/layout/edit_icon.xml create mode 100644 OpenKeychain/src/main/res/menu/action_mode_edit.xml delete mode 100644 OpenKeychain/src/main/res/menu/edit_subkeys.xml delete mode 100644 OpenKeychain/src/main/res/menu/edit_user_id.xml diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java index 86cabaf96..fe4135cd8 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java @@ -18,19 +18,26 @@ package org.sufficientlysecure.keychain.ui; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract; -import android.support.v4.app.LoaderManager; +import android.support.v4.app.Fragment; +import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v4.view.ViewPager; -import android.support.v4.view.ViewPager.SimpleOnPageChangeListener; +import android.support.v4.view.ViewPager.OnPageChangeListener; import android.view.ActionMode; +import android.view.LayoutInflater; import android.view.Menu; +import android.view.MenuItem; import android.view.View; +import android.view.ViewPropertyAnimator; +import android.view.animation.OvershootInterpolator; import android.widget.Toast; import com.astuetz.PagerSlidingTabStrip; @@ -47,7 +54,7 @@ import org.sufficientlysecure.keychain.util.ContactHelper; import org.sufficientlysecure.keychain.util.Log; public class ViewKeyAdvActivity extends BaseActivity implements - LoaderManager.LoaderCallbacks { + LoaderCallbacks, OnPageChangeListener { ProviderHelper mProviderHelper; @@ -64,6 +71,11 @@ public class ViewKeyAdvActivity extends BaseActivity implements private PagerSlidingTabStrip mSlidingTabLayout; private static final int LOADER_ID_UNIFIED = 0; + private ActionMode mActionMode; + private boolean mHasSecret; + private PagerTabStripAdapter mTabAdapter; + private boolean mActionIconShown; + private boolean[] mTabsWithActionMode; @Override protected void onCreate(Bundle savedInstanceState) { @@ -109,33 +121,44 @@ public class ViewKeyAdvActivity extends BaseActivity implements } private void initTabs(Uri dataUri, boolean hasSecret) { - PagerTabStripAdapter adapter = new PagerTabStripAdapter(this); - mViewPager.setAdapter(adapter); + + mHasSecret = hasSecret; + + mTabAdapter = new PagerTabStripAdapter(this); + mViewPager.setAdapter(mTabAdapter); + + // keep track which of these are action mode enabled! + mTabsWithActionMode = new boolean[4]; Bundle shareBundle = new Bundle(); shareBundle.putParcelable(ViewKeyAdvShareFragment.ARG_DATA_URI, dataUri); - adapter.addTab(ViewKeyAdvShareFragment.class, + mTabAdapter.addTab(ViewKeyAdvShareFragment.class, shareBundle, getString(R.string.key_view_tab_share)); + mTabsWithActionMode[0] = false; Bundle userIdsBundle = new Bundle(); userIdsBundle.putParcelable(ViewKeyAdvUserIdsFragment.ARG_DATA_URI, dataUri); userIdsBundle.putBoolean(ViewKeyAdvUserIdsFragment.ARG_HAS_SECRET, hasSecret); - adapter.addTab(ViewKeyAdvUserIdsFragment.class, + mTabAdapter.addTab(ViewKeyAdvUserIdsFragment.class, userIdsBundle, getString(R.string.section_user_ids)); + mTabsWithActionMode[1] = true; Bundle keysBundle = new Bundle(); keysBundle.putParcelable(ViewKeyAdvSubkeysFragment.ARG_DATA_URI, dataUri); keysBundle.putBoolean(ViewKeyAdvSubkeysFragment.ARG_HAS_SECRET, hasSecret); - adapter.addTab(ViewKeyAdvSubkeysFragment.class, + mTabAdapter.addTab(ViewKeyAdvSubkeysFragment.class, keysBundle, getString(R.string.key_view_tab_keys)); + mTabsWithActionMode[2] = true; Bundle certsBundle = new Bundle(); certsBundle.putParcelable(ViewKeyAdvCertsFragment.ARG_DATA_URI, dataUri); - adapter.addTab(ViewKeyAdvCertsFragment.class, + mTabAdapter.addTab(ViewKeyAdvCertsFragment.class, certsBundle, getString(R.string.key_view_tab_certs)); + mTabsWithActionMode[3] = false; // update layout after operations mSlidingTabLayout.setViewPager(mViewPager); + mSlidingTabLayout.setOnPageChangeListener(this); // switch to tab selected by extra Intent intent = getIntent(); @@ -245,22 +268,83 @@ public class ViewKeyAdvActivity extends BaseActivity implements } @Override - public void onActionModeStarted(final ActionMode mode) { - super.onActionModeStarted(mode); - // Leave whatever action mode we are in when we change the page - mSlidingTabLayout.setOnPageChangeListener(new SimpleOnPageChangeListener() { + public boolean onCreateOptionsMenu(Menu menu) { + + if (!mHasSecret) { + return false; + } + + // always add the item, switch its visibility depending on fragment + getMenuInflater().inflate(R.menu.action_mode_edit, menu); + final MenuItem vActionModeItem = menu.findItem(R.id.menu_action_mode_edit); + + boolean isCurrentActionFragment = mTabsWithActionMode[mViewPager.getCurrentItem()]; + + // if the state is as it should be, never mind + if (isCurrentActionFragment == mActionIconShown) { + return isCurrentActionFragment; + } + + // show or hide accordingly + mActionIconShown = isCurrentActionFragment; + vActionModeItem.setEnabled(isCurrentActionFragment); + animateMenuItem(vActionModeItem, isCurrentActionFragment); + + return true; + } + + private void animateMenuItem(final MenuItem vEditSubkeys, final boolean animateShow) { + + View actionView = LayoutInflater.from(this).inflate(R.layout.edit_icon, null); + vEditSubkeys.setActionView(actionView); + actionView.setTranslationX(animateShow ? 150 : 0); + + ViewPropertyAnimator animator = actionView.animate(); + animator.translationX(animateShow ? 0 : 150); + animator.setDuration(300); + animator.setInterpolator(new OvershootInterpolator(1.5f)); + animator.setListener(new AnimatorListenerAdapter() { @Override - public void onPageSelected(int position) { - super.onPageSelected(position); - mode.finish(); + public void onAnimationEnd(Animator animation) { + if (!animateShow) { + vEditSubkeys.setVisible(false); + } + vEditSubkeys.setActionView(null); } }); + animator.start(); + + } + + @Override + public void onActionModeStarted(final ActionMode mode) { + super.onActionModeStarted(mode); + mActionMode = mode; } @Override public void onActionModeFinished(ActionMode mode) { super.onActionModeFinished(mode); - mSlidingTabLayout.setOnPageChangeListener(null); + mActionMode = null; + } + + @Override + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { + + } + + @Override + public void onPageSelected(int position) { + if (mActionMode != null) { + mActionMode.finish(); + mActionMode = null; + } + invalidateOptionsMenu(); + } + + @Override + public void onPageScrollStateChanged(int state) { + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java index 048dd4f77..b93eccb92 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java @@ -17,6 +17,7 @@ package org.sufficientlysecure.keychain.ui; + import android.database.Cursor; import android.net.Uri; import android.os.Bundle; @@ -28,7 +29,6 @@ import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.view.ActionMode; -import android.view.ActionMode.Callback; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; @@ -123,6 +123,8 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements } }); + setHasOptionsMenu(true); + return root; } @@ -138,8 +140,6 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements } mHasSecret = getArguments().getBoolean(ARG_HAS_SECRET); - setHasOptionsMenu(true); - loadData(dataUri); } @@ -184,9 +184,23 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements mSubkeysAdapter.swapCursor(null); } - private void enterEditMode() { + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_action_mode_edit: + enterEditMode(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + public void enterEditMode() { FragmentActivity activity = getActivity(); - activity.startActionMode(new Callback() { + if (activity == null) { + return; + } + activity.startActionMode(new ActionMode.Callback() { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { @@ -229,25 +243,6 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements }); } - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.edit_subkeys, menu); - final MenuItem vEditSubkeys = menu.findItem(R.id.menu_edit_subkeys); - vEditSubkeys.setVisible(mHasSecret); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.menu_edit_subkeys: - enterEditMode(); - return true; - default: - return super.onOptionsItemSelected(item); - } - } - private void addSubkey() { boolean willBeMasterKey; if (mSubkeysAdapter != null) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java index 49c0184c7..1e38a823a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java @@ -30,10 +30,8 @@ import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.view.ActionMode; -import android.view.ActionMode.Callback; import android.view.LayoutInflater; import android.view.Menu; -import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; @@ -109,6 +107,8 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements } }); + setHasOptionsMenu(true); + return root; } @@ -218,8 +218,6 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements } boolean hasSecret = getArguments().getBoolean(ARG_HAS_SECRET); - setHasOptionsMenu(true); - loadData(dataUri, hasSecret); } @@ -278,16 +276,22 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements } @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { - super.onCreateOptionsMenu(menu, inflater); - inflater.inflate(R.menu.edit_user_id, menu); - MenuItem vEditUserIds = menu.findItem(R.id.menu_edit_user_ids); - vEditUserIds.setVisible(mHasSecret); + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_action_mode_edit: + enterEditMode(); + return true; + default: + return super.onOptionsItemSelected(item); + } } - private void enterEditMode() { + public void enterEditMode() { FragmentActivity activity = getActivity(); - activity.startActionMode(new Callback() { + if (activity == null) { + return; + } + activity.startActionMode(new ActionMode.Callback() { @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { @@ -330,14 +334,4 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements }); } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.menu_edit_user_ids: - enterEditMode(); - return true; - default: - return super.onOptionsItemSelected(item); - } - } } diff --git a/OpenKeychain/src/main/res/layout/edit_icon.xml b/OpenKeychain/src/main/res/layout/edit_icon.xml new file mode 100644 index 000000000..f3af5a3dc --- /dev/null +++ b/OpenKeychain/src/main/res/layout/edit_icon.xml @@ -0,0 +1,9 @@ + + + diff --git a/OpenKeychain/src/main/res/menu/action_mode_edit.xml b/OpenKeychain/src/main/res/menu/action_mode_edit.xml new file mode 100644 index 000000000..edbebac8b --- /dev/null +++ b/OpenKeychain/src/main/res/menu/action_mode_edit.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/OpenKeychain/src/main/res/menu/edit_subkeys.xml b/OpenKeychain/src/main/res/menu/edit_subkeys.xml deleted file mode 100644 index f9f75ebbb..000000000 --- a/OpenKeychain/src/main/res/menu/edit_subkeys.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/OpenKeychain/src/main/res/menu/edit_user_id.xml b/OpenKeychain/src/main/res/menu/edit_user_id.xml deleted file mode 100644 index 617dae841..000000000 --- a/OpenKeychain/src/main/res/menu/edit_user_id.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index ee498b969..9962888cd 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -666,8 +666,7 @@ "Import from File" - "Edit Identities" - "Edit Subkeys" + "Edit" "Encrypt text" "files" "Confirm key" -- cgit v1.2.3 From 09410e7f697395b1764e5f8e56581fe1d93be1fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 27 Dec 2015 15:06:02 +0100 Subject: Fix merge conflicts --- OpenKeychain/src/main/res/values/strings.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index 9962888cd..e18884008 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -1703,8 +1703,6 @@ "Cancel" "Wrong data type, text was expected!" "No text in shared data!" - "Search for\n'%s'" - Save "Save" "Edit Identities" "Edit Subkeys" -- cgit v1.2.3 From 1dea4ef19f594f3562e31f104abc77958f6edb59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 27 Dec 2015 15:45:08 +0100 Subject: Pass trough masterKeyId and fingerprint to advanced key edit fragments --- .../keychain/ui/ViewKeyAdvActivity.java | 14 +++++++++++--- .../keychain/ui/ViewKeyAdvSubkeysFragment.java | 22 +++++++--------------- .../keychain/ui/ViewKeyAdvUserIdsFragment.java | 16 +++++++++++----- 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java index fe4135cd8..c2f63fa4e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java @@ -120,7 +120,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements setContentView(R.layout.view_key_adv_activity); } - private void initTabs(Uri dataUri, boolean hasSecret) { + private void initTabs(Uri dataUri, boolean hasSecret, long masterKeyId, byte[] fingerprint) { mHasSecret = hasSecret; @@ -139,6 +139,8 @@ public class ViewKeyAdvActivity extends BaseActivity implements Bundle userIdsBundle = new Bundle(); userIdsBundle.putParcelable(ViewKeyAdvUserIdsFragment.ARG_DATA_URI, dataUri); userIdsBundle.putBoolean(ViewKeyAdvUserIdsFragment.ARG_HAS_SECRET, hasSecret); + userIdsBundle.putLong(ViewKeyAdvUserIdsFragment.ARG_MASTER_KEY_ID, masterKeyId); + userIdsBundle.putByteArray(ViewKeyAdvUserIdsFragment.ARG_FINGERPRINT, fingerprint); mTabAdapter.addTab(ViewKeyAdvUserIdsFragment.class, userIdsBundle, getString(R.string.section_user_ids)); mTabsWithActionMode[1] = true; @@ -146,6 +148,8 @@ public class ViewKeyAdvActivity extends BaseActivity implements Bundle keysBundle = new Bundle(); keysBundle.putParcelable(ViewKeyAdvSubkeysFragment.ARG_DATA_URI, dataUri); keysBundle.putBoolean(ViewKeyAdvSubkeysFragment.ARG_HAS_SECRET, hasSecret); + keysBundle.putLong(ViewKeyAdvSubkeysFragment.ARG_MASTER_KEY_ID, masterKeyId); + keysBundle.putByteArray(ViewKeyAdvSubkeysFragment.ARG_FINGERPRINT, fingerprint); mTabAdapter.addTab(ViewKeyAdvSubkeysFragment.class, keysBundle, getString(R.string.key_view_tab_keys)); mTabsWithActionMode[2] = true; @@ -175,7 +179,8 @@ public class ViewKeyAdvActivity extends BaseActivity implements KeychainContract.KeyRings.IS_REVOKED, KeychainContract.KeyRings.IS_EXPIRED, KeychainContract.KeyRings.VERIFIED, - KeychainContract.KeyRings.HAS_ANY_SECRET + KeychainContract.KeyRings.HAS_ANY_SECRET, + KeychainContract.KeyRings.FINGERPRINT, }; static final int INDEX_MASTER_KEY_ID = 1; @@ -184,6 +189,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements static final int INDEX_IS_EXPIRED = 4; static final int INDEX_VERIFIED = 5; static final int INDEX_HAS_ANY_SECRET = 6; + static final int INDEX_FINGERPRINT = 7; @Override public Loader onCreateLoader(int id, Bundle args) { @@ -217,6 +223,8 @@ public class ViewKeyAdvActivity extends BaseActivity implements setTitle(R.string.user_id_no_name); } + byte[] fingerprint = data.getBlob(INDEX_FINGERPRINT); + // get key id from MASTER_KEY_ID long masterKeyId = data.getLong(INDEX_MASTER_KEY_ID); getSupportActionBar().setSubtitle(KeyFormattingUtils.beautifyKeyIdWithPrefix(this, masterKeyId)); @@ -243,7 +251,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements mStatusBar.setBackgroundColor(ViewKeyActivity.getStatusBarBackgroundColor(color)); mSlidingTabLayout.setBackgroundColor(color); - initTabs(mDataUri, isSecret); + initTabs(mDataUri, isSecret, masterKeyId, fingerprint); break; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java index b93eccb92..923a1e61c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java @@ -58,6 +58,8 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements public static final String ARG_DATA_URI = "data_uri"; public static final String ARG_HAS_SECRET = "has_secret"; + public static final String ARG_MASTER_KEY_ID = "master_key_id"; + public static final String ARG_FINGERPRINT = "fingerprint"; public static final int LOADER_ID_SUBKEYS = 0; @@ -71,23 +73,11 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements private Uri mDataUriSubkeys; + private long mMasterKeyId; + private byte[] mFingerprint; private boolean mHasSecret; private SaveKeyringParcel mEditModeSaveKeyringParcel; - /** - * Creates new instance of this fragment - */ - public static ViewKeyAdvSubkeysFragment newInstance(Uri dataUri, boolean hasSecret) { - ViewKeyAdvSubkeysFragment frag = new ViewKeyAdvSubkeysFragment(); - - Bundle args = new Bundle(); - args.putParcelable(ARG_DATA_URI, dataUri); - args.putBoolean(ARG_HAS_SECRET, hasSecret); - - frag.setArguments(args); - return frag; - } - @Override public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) { View root = super.onCreateView(inflater, superContainer, savedInstanceState); @@ -139,6 +129,8 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements return; } mHasSecret = getArguments().getBoolean(ARG_HAS_SECRET); + mMasterKeyId = getArguments().getLong(ARG_MASTER_KEY_ID); + mFingerprint = getArguments().getByteArray(ARG_FINGERPRINT); loadData(dataUri); } @@ -204,7 +196,7 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { - mEditModeSaveKeyringParcel = new SaveKeyringParcel(0L, new byte[0]); + mEditModeSaveKeyringParcel = new SaveKeyringParcel(mMasterKeyId, mFingerprint); mSubkeysAddedAdapter = new SubkeysAddedAdapter(getActivity(), mEditModeSaveKeyringParcel.mAddSubKeys, false); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java index 1e38a823a..a44d4da5e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java @@ -57,6 +57,8 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements public static final String ARG_DATA_URI = "uri"; public static final String ARG_HAS_SECRET = "has_secret"; + public static final String ARG_MASTER_KEY_ID = "master_key_id"; + public static final String ARG_FINGERPRINT = "fingerprint"; private static final int LOADER_ID_USER_IDS = 0; @@ -69,6 +71,9 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements private UserIdsAddedAdapter mUserIdsAddedAdapter; private Uri mDataUri; + + private long mMasterKeyId; + private byte[] mFingerprint; private boolean mHasSecret; private SaveKeyringParcel mEditModeSaveKeyringParcel; @@ -216,14 +221,15 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements getActivity().finish(); return; } - boolean hasSecret = getArguments().getBoolean(ARG_HAS_SECRET); + mHasSecret = getArguments().getBoolean(ARG_HAS_SECRET); + mMasterKeyId = getArguments().getLong(ARG_MASTER_KEY_ID); + mFingerprint = getArguments().getByteArray(ARG_FINGERPRINT); - loadData(dataUri, hasSecret); + loadData(dataUri); } - private void loadData(Uri dataUri, boolean hasSecret) { + private void loadData(Uri dataUri) { mDataUri = dataUri; - mHasSecret = hasSecret; Log.i(Constants.TAG, "mDataUri: " + mDataUri); @@ -295,7 +301,7 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { - mEditModeSaveKeyringParcel = new SaveKeyringParcel(0L, new byte[0]); + mEditModeSaveKeyringParcel = new SaveKeyringParcel(mMasterKeyId, mFingerprint); mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mEditModeSaveKeyringParcel.mAddUserIds, false); -- cgit v1.2.3 From 9887e8b42ad2e6fddb1f3be4c0c315724c4d5c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 28 Dec 2015 15:38:16 +0100 Subject: Advanced screen: edited key saved --- .../keychain/ui/ViewKeyAdvSubkeysFragment.java | 51 +++++++++++++++++++++- .../keychain/ui/ViewKeyAdvUserIdsFragment.java | 50 ++++++++++++++++++++- 2 files changed, 99 insertions(+), 2 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java index 923a1e61c..5a0b1b393 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java @@ -18,6 +18,7 @@ package org.sufficientlysecure.keychain.ui; +import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; @@ -41,12 +42,14 @@ import android.widget.ViewAnimator; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; +import org.sufficientlysecure.keychain.operations.results.EditKeyResult; import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange; import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter; import org.sufficientlysecure.keychain.ui.adapter.SubkeysAddedAdapter; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.dialog.AddSubkeyDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.EditSubkeyDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.EditSubkeyExpiryDialogFragment; @@ -71,6 +74,8 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements private SubkeysAdapter mSubkeysAdapter; private SubkeysAddedAdapter mSubkeysAddedAdapter; + private CryptoOperationHelper mEditKeyHelper; + private Uri mDataUriSubkeys; private long mMasterKeyId; @@ -135,6 +140,15 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements loadData(dataUri); } + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (mEditKeyHelper != null) { + mEditKeyHelper.handleActivityResult(requestCode, resultCode, data); + } + + super.onActivityResult(requestCode, resultCode, data); + } + private void loadData(Uri dataUri) { mDataUriSubkeys = KeychainContract.Keys.buildKeysUri(dataUri); @@ -220,7 +234,7 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - mode.finish(); + editKey(mode); return true; } @@ -390,4 +404,39 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements }); } + + private void editKey(final ActionMode mode) { + CryptoOperationHelper.Callback editKeyCallback + = new CryptoOperationHelper.Callback() { + + @Override + public SaveKeyringParcel createOperationInput() { + return mEditModeSaveKeyringParcel; + } + + @Override + public void onCryptoOperationSuccess(EditKeyResult result) { + mode.finish(); + result.createNotify(getActivity()).show(); + } + + @Override + public void onCryptoOperationCancelled() { + + } + + @Override + public void onCryptoOperationError(EditKeyResult result) { + + } + + @Override + public boolean onCryptoSetProgress(String msg, int progress, int max) { + return false; + } + }; + mEditKeyHelper = new CryptoOperationHelper<>(1, this, editKeyCallback, R.string.progress_saving); + mEditKeyHelper.cryptoOperation(); + } + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java index a44d4da5e..176eb6ca0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java @@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.ui; +import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; @@ -42,10 +43,12 @@ import android.widget.ViewAnimator; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; +import org.sufficientlysecure.keychain.operations.results.EditKeyResult; import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAddedAdapter; +import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper; import org.sufficientlysecure.keychain.ui.dialog.AddUserIdDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.EditUserIdDialogFragment; import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment; @@ -70,6 +73,8 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements private UserIdsAdapter mUserIdsAdapter; private UserIdsAddedAdapter mUserIdsAddedAdapter; + private CryptoOperationHelper mEditKeyHelper; + private Uri mDataUri; private long mMasterKeyId; @@ -228,6 +233,15 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements loadData(dataUri); } + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (mEditKeyHelper != null) { + mEditKeyHelper.handleActivityResult(requestCode, resultCode, data); + } + + super.onActivityResult(requestCode, resultCode, data); + } + private void loadData(Uri dataUri) { mDataUri = dataUri; @@ -325,7 +339,7 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - mode.finish(); + editKey(mode); return true; } @@ -340,4 +354,38 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements }); } + private void editKey(final ActionMode mode) { + CryptoOperationHelper.Callback editKeyCallback + = new CryptoOperationHelper.Callback() { + + @Override + public SaveKeyringParcel createOperationInput() { + return mEditModeSaveKeyringParcel; + } + + @Override + public void onCryptoOperationSuccess(EditKeyResult result) { + mode.finish(); + result.createNotify(getActivity()).show(); + } + + @Override + public void onCryptoOperationCancelled() { + + } + + @Override + public void onCryptoOperationError(EditKeyResult result) { + + } + + @Override + public boolean onCryptoSetProgress(String msg, int progress, int max) { + return false; + } + }; + mEditKeyHelper = new CryptoOperationHelper<>(1, this, editKeyCallback, R.string.progress_saving); + mEditKeyHelper.cryptoOperation(); + } + } -- cgit v1.2.3 From ea3b25846946e96e124cd5635e710f8ece77eceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 28 Dec 2015 15:41:36 +0100 Subject: use correct white add icon --- .../keychain/ui/ViewKeyAdvUserIdsFragment.java | 2 +- .../main/res/layout/view_key_adv_main_fragment.xml | 86 ---------------------- .../res/layout/view_key_adv_subkeys_fragment.xml | 2 +- .../res/layout/view_key_adv_user_ids_fragment.xml | 86 ++++++++++++++++++++++ 4 files changed, 88 insertions(+), 88 deletions(-) delete mode 100644 OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml create mode 100644 OpenKeychain/src/main/res/layout/view_key_adv_user_ids_fragment.xml diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java index 176eb6ca0..3e165a77e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java @@ -85,7 +85,7 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements @Override public View onCreateView(LayoutInflater inflater, ViewGroup superContainer, Bundle savedInstanceState) { View root = super.onCreateView(inflater, superContainer, savedInstanceState); - View view = inflater.inflate(R.layout.view_key_adv_main_fragment, getContainer()); + View view = inflater.inflate(R.layout.view_key_adv_user_ids_fragment, getContainer()); mUserIds = (ListView) view.findViewById(R.id.view_key_user_ids); mUserIdsAddedList = (ListView) view.findViewById(R.id.view_key_user_ids_added); diff --git a/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml deleted file mode 100644 index 98ee2d492..000000000 --- a/OpenKeychain/src/main/res/layout/view_key_adv_main_fragment.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/OpenKeychain/src/main/res/layout/view_key_adv_subkeys_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_adv_subkeys_fragment.xml index 001078b76..4679d5be9 100644 --- a/OpenKeychain/src/main/res/layout/view_key_adv_subkeys_fragment.xml +++ b/OpenKeychain/src/main/res/layout/view_key_adv_subkeys_fragment.xml @@ -78,7 +78,7 @@ xmlns:tools="http://schemas.android.com/tools"> android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="24dp" - android:src="@drawable/ic_person_add_grey_24dp" + android:src="@drawable/ic_add_white_24dp" android:visibility="invisible" android:layout_gravity="bottom" tools:visibility="visible" /> diff --git a/OpenKeychain/src/main/res/layout/view_key_adv_user_ids_fragment.xml b/OpenKeychain/src/main/res/layout/view_key_adv_user_ids_fragment.xml new file mode 100644 index 000000000..b6399b057 --- /dev/null +++ b/OpenKeychain/src/main/res/layout/view_key_adv_user_ids_fragment.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From 621f8c2c70183bdb44c4adb6f6a507a192af58a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 29 Dec 2015 19:57:01 +0100 Subject: Load key data in tabs independently from advanced activity. This decouples the fragments from the activity and allows to init the tabs before loading key data in the advanced activity. Fixes switching to the first tab when key has been edited. --- .../keychain/ui/ViewKeyAdvActivity.java | 22 ++---- .../keychain/ui/ViewKeyAdvSubkeysFragment.java | 78 +++++++++++++++------ .../keychain/ui/ViewKeyAdvUserIdsFragment.java | 80 +++++++++++++++------- 3 files changed, 118 insertions(+), 62 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java index c2f63fa4e..b10e5f8d4 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvActivity.java @@ -25,7 +25,6 @@ import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract; -import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager.LoaderCallbacks; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; @@ -41,6 +40,7 @@ import android.view.animation.OvershootInterpolator; import android.widget.Toast; import com.astuetz.PagerSlidingTabStrip; + import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.OperationResult; @@ -113,6 +113,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements // or start new ones. getSupportLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this); + initTabs(mDataUri); } @Override @@ -120,10 +121,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements setContentView(R.layout.view_key_adv_activity); } - private void initTabs(Uri dataUri, boolean hasSecret, long masterKeyId, byte[] fingerprint) { - - mHasSecret = hasSecret; - + private void initTabs(Uri dataUri) { mTabAdapter = new PagerTabStripAdapter(this); mViewPager.setAdapter(mTabAdapter); @@ -138,18 +136,12 @@ public class ViewKeyAdvActivity extends BaseActivity implements Bundle userIdsBundle = new Bundle(); userIdsBundle.putParcelable(ViewKeyAdvUserIdsFragment.ARG_DATA_URI, dataUri); - userIdsBundle.putBoolean(ViewKeyAdvUserIdsFragment.ARG_HAS_SECRET, hasSecret); - userIdsBundle.putLong(ViewKeyAdvUserIdsFragment.ARG_MASTER_KEY_ID, masterKeyId); - userIdsBundle.putByteArray(ViewKeyAdvUserIdsFragment.ARG_FINGERPRINT, fingerprint); mTabAdapter.addTab(ViewKeyAdvUserIdsFragment.class, userIdsBundle, getString(R.string.section_user_ids)); mTabsWithActionMode[1] = true; Bundle keysBundle = new Bundle(); keysBundle.putParcelable(ViewKeyAdvSubkeysFragment.ARG_DATA_URI, dataUri); - keysBundle.putBoolean(ViewKeyAdvSubkeysFragment.ARG_HAS_SECRET, hasSecret); - keysBundle.putLong(ViewKeyAdvSubkeysFragment.ARG_MASTER_KEY_ID, masterKeyId); - keysBundle.putByteArray(ViewKeyAdvSubkeysFragment.ARG_FINGERPRINT, fingerprint); mTabAdapter.addTab(ViewKeyAdvSubkeysFragment.class, keysBundle, getString(R.string.key_view_tab_keys)); mTabsWithActionMode[2] = true; @@ -229,7 +221,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements long masterKeyId = data.getLong(INDEX_MASTER_KEY_ID); getSupportActionBar().setSubtitle(KeyFormattingUtils.beautifyKeyIdWithPrefix(this, masterKeyId)); - boolean isSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0; + mHasSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0; boolean isRevoked = data.getInt(INDEX_IS_REVOKED) > 0; boolean isExpired = data.getInt(INDEX_IS_EXPIRED) != 0; boolean isVerified = data.getInt(INDEX_VERIFIED) > 0; @@ -238,7 +230,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements int color; if (isRevoked || isExpired) { color = getResources().getColor(R.color.key_flag_red); - } else if (isSecret) { + } else if (mHasSecret) { color = getResources().getColor(R.color.android_green_light); } else { if (isVerified) { @@ -251,8 +243,6 @@ public class ViewKeyAdvActivity extends BaseActivity implements mStatusBar.setBackgroundColor(ViewKeyActivity.getStatusBarBackgroundColor(color)); mSlidingTabLayout.setBackgroundColor(color); - initTabs(mDataUri, isSecret, masterKeyId, fingerprint); - break; } } @@ -284,7 +274,7 @@ public class ViewKeyAdvActivity extends BaseActivity implements // always add the item, switch its visibility depending on fragment getMenuInflater().inflate(R.menu.action_mode_edit, menu); - final MenuItem vActionModeItem = menu.findItem(R.id.menu_action_mode_edit); + final MenuItem vActionModeItem = menu.findItem(R.id.menu_action_mode_edit); boolean isCurrentActionFragment = mTabsWithActionMode[mViewPager.getCurrentItem()]; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java index 5a0b1b393..4308983ce 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java @@ -60,11 +60,9 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements LoaderManager.LoaderCallbacks { public static final String ARG_DATA_URI = "data_uri"; - public static final String ARG_HAS_SECRET = "has_secret"; - public static final String ARG_MASTER_KEY_ID = "master_key_id"; - public static final String ARG_FINGERPRINT = "fingerprint"; - public static final int LOADER_ID_SUBKEYS = 0; + private static final int LOADER_ID_UNIFIED = 0; + private static final int LOADER_ID_SUBKEYS = 1; private ListView mSubkeysList; private ListView mSubkeysAddedList; @@ -76,7 +74,7 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements private CryptoOperationHelper mEditKeyHelper; - private Uri mDataUriSubkeys; + private Uri mDataUri; private long mMasterKeyId; private byte[] mFingerprint; @@ -133,9 +131,6 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements getActivity().finish(); return; } - mHasSecret = getArguments().getBoolean(ARG_HAS_SECRET); - mMasterKeyId = getArguments().getLong(ARG_MASTER_KEY_ID); - mFingerprint = getArguments().getByteArray(ARG_FINGERPRINT); loadData(dataUri); } @@ -150,7 +145,7 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements } private void loadData(Uri dataUri) { - mDataUriSubkeys = KeychainContract.Keys.buildKeysUri(dataUri); + mDataUri = dataUri; // Create an empty adapter we will use to display the loaded data. mSubkeysAdapter = new SubkeysAdapter(getActivity(), null, 0); @@ -158,14 +153,42 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements // Prepare the loaders. Either re-connect with an existing ones, // or start new ones. + getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this); getLoaderManager().initLoader(LOADER_ID_SUBKEYS, null, this); } + // These are the rows that we will retrieve. + static final String[] PROJECTION = new String[]{ + KeychainContract.KeyRings._ID, + KeychainContract.KeyRings.MASTER_KEY_ID, + KeychainContract.KeyRings.HAS_ANY_SECRET, + KeychainContract.KeyRings.FINGERPRINT, + }; + + static final int INDEX_MASTER_KEY_ID = 1; + static final int INDEX_HAS_ANY_SECRET = 2; + static final int INDEX_FINGERPRINT = 3; + + @Override public Loader onCreateLoader(int id, Bundle args) { - setContentShown(false); + switch (id) { + case LOADER_ID_UNIFIED: { + Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mDataUri); + return new CursorLoader(getActivity(), baseUri, + PROJECTION, null, null, null); + } + + case LOADER_ID_SUBKEYS: { + setContentShown(false); - return new CursorLoader(getActivity(), mDataUriSubkeys, - SubkeysAdapter.SUBKEYS_PROJECTION, null, null, null); + Uri subkeysUri = KeychainContract.Keys.buildKeysUri(mDataUri); + return new CursorLoader(getActivity(), subkeysUri, + SubkeysAdapter.SUBKEYS_PROJECTION, null, null, null); + } + + default: + return null; + } } public void onLoadFinished(Loader loader, Cursor data) { @@ -174,12 +197,26 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements return; } - // Swap the new cursor in. (The framework will take care of closing the - // old cursor once we return.) - mSubkeysAdapter.swapCursor(data); + switch (loader.getId()) { + case LOADER_ID_UNIFIED: { + data.moveToFirst(); + + mMasterKeyId = data.getLong(INDEX_MASTER_KEY_ID); + mHasSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0; + mFingerprint = data.getBlob(INDEX_FINGERPRINT); + break; + } + case LOADER_ID_SUBKEYS: { + // Swap the new cursor in. (The framework will take care of closing the + // old cursor once we return.) + mSubkeysAdapter.swapCursor(data); + + // TODO: maybe show not before both are loaded! + setContentShown(true); + break; + } + } - // TODO: maybe show not before both are loaded! - setContentShown(true); } /** @@ -244,7 +281,7 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements mSubkeysAdapter.setEditMode(null); mSubkeysAddedLayout.setVisibility(View.GONE); mSubkeyAddFabLayout.setDisplayedChild(0); - getLoaderManager().restartLoader(0, null, ViewKeyAdvSubkeysFragment.this); + getLoaderManager().restartLoader(LOADER_ID_SUBKEYS, null, ViewKeyAdvSubkeysFragment.this); } }); } @@ -422,12 +459,13 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements @Override public void onCryptoOperationCancelled() { - + mode.finish(); } @Override public void onCryptoOperationError(EditKeyResult result) { - + mode.finish(); + result.createNotify(getActivity()).show(); } @Override diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java index 3e165a77e..ae1dd51d0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvUserIdsFragment.java @@ -44,6 +44,7 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround; import org.sufficientlysecure.keychain.operations.results.EditKeyResult; +import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter; @@ -59,11 +60,9 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements LoaderManager.LoaderCallbacks { public static final String ARG_DATA_URI = "uri"; - public static final String ARG_HAS_SECRET = "has_secret"; - public static final String ARG_MASTER_KEY_ID = "master_key_id"; - public static final String ARG_FINGERPRINT = "fingerprint"; - private static final int LOADER_ID_USER_IDS = 0; + private static final int LOADER_ID_UNIFIED = 0; + private static final int LOADER_ID_USER_IDS = 1; private ListView mUserIds; private ListView mUserIdsAddedList; @@ -226,9 +225,6 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements getActivity().finish(); return; } - mHasSecret = getArguments().getBoolean(ARG_HAS_SECRET); - mMasterKeyId = getArguments().getLong(ARG_MASTER_KEY_ID); - mFingerprint = getArguments().getByteArray(ARG_FINGERPRINT); loadData(dataUri); } @@ -252,36 +248,67 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements // Prepare the loaders. Either re-connect with an existing ones, // or start new ones. + getLoaderManager().initLoader(LOADER_ID_UNIFIED, null, this); getLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this); } + // These are the rows that we will retrieve. + static final String[] PROJECTION = new String[]{ + KeychainContract.KeyRings._ID, + KeychainContract.KeyRings.MASTER_KEY_ID, + KeychainContract.KeyRings.HAS_ANY_SECRET, + KeychainContract.KeyRings.FINGERPRINT, + }; + + static final int INDEX_MASTER_KEY_ID = 1; + static final int INDEX_HAS_ANY_SECRET = 2; + static final int INDEX_FINGERPRINT = 3; + public Loader onCreateLoader(int id, Bundle args) { - setContentShown(false); + switch (id) { + case LOADER_ID_UNIFIED: { + Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingUri(mDataUri); + return new CursorLoader(getActivity(), baseUri, + PROJECTION, null, null, null); + } - if (id != LOADER_ID_USER_IDS) { - return null; - } + case LOADER_ID_USER_IDS: { + setContentShown(false); - Uri baseUri = UserPackets.buildUserIdsUri(mDataUri); - return new CursorLoader(getActivity(), baseUri, - UserIdsAdapter.USER_PACKETS_PROJECTION, null, null, null); - } + Uri userIdUri = UserPackets.buildUserIdsUri(mDataUri); + return new CursorLoader(getActivity(), userIdUri, + UserIdsAdapter.USER_PACKETS_PROJECTION, null, null, null); + } - public void onLoadFinished(Loader loader, Cursor data) { - if (loader.getId() != LOADER_ID_USER_IDS) { - return; + default: + return null; } + } - /* TODO better error handling? May cause problems when a key is deleted, - * because the notification triggers faster than the activity closes. - */ - // Avoid NullPointerExceptions... + public void onLoadFinished(Loader loader, Cursor data) { + // Avoid NullPointerExceptions, if we get an empty result set. if (data.getCount() == 0) { return; } - mUserIdsAdapter.swapCursor(data); - setContentShown(true); + switch (loader.getId()) { + case LOADER_ID_UNIFIED: { + data.moveToFirst(); + + mMasterKeyId = data.getLong(INDEX_MASTER_KEY_ID); + mHasSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0; + mFingerprint = data.getBlob(INDEX_FINGERPRINT); + break; + } + case LOADER_ID_USER_IDS: { + // Swap the new cursor in. (The framework will take care of closing the + // old cursor once we return.) + mUserIdsAdapter.swapCursor(data); + + setContentShown(true); + break; + } + } } /** @@ -371,12 +398,13 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements @Override public void onCryptoOperationCancelled() { - + mode.finish(); } @Override public void onCryptoOperationError(EditKeyResult result) { - + mode.finish(); + result.createNotify(getActivity()).show(); } @Override -- cgit v1.2.3 From 3f705117080def34b7793f6935e6ec7b6109d741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Tue, 29 Dec 2015 21:21:11 +0100 Subject: Add edit action to user id card, left align card actions per material design guidelines --- .../keychain/ui/ViewKeyActivity.java | 7 +-- .../keychain/ui/ViewKeyAdvSubkeysFragment.java | 2 +- .../keychain/ui/ViewKeyFragment.java | 11 +++- .../keychain/ui/util/ContentDescriptionHint.java | 9 ++- .../main/res/layout/linked_id_view_fragment.xml | 10 +-- .../src/main/res/layout/view_key_fragment.xml | 72 +++++++++++++++------- .../src/main/res/layout/view_key_yubikey.xml | 2 +- OpenKeychain/src/main/res/values/colors.xml | 2 +- 8 files changed, 75 insertions(+), 40 deletions(-) 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 35e00ff21..1eb16b3c3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -391,11 +391,11 @@ public class ViewKeyActivity extends BaseNfcActivity implements return true; } case R.id.menu_key_view_certify_fingerprint: { - certifyFingeprint(mDataUri, false); + certifyFingerprint(mDataUri, false); return true; } case R.id.menu_key_view_certify_fingerprint_word: { - certifyFingeprint(mDataUri, true); + certifyFingerprint(mDataUri, true); return true; } } @@ -423,14 +423,13 @@ public class ViewKeyActivity extends BaseNfcActivity implements return true; } - private void scanQrCode() { Intent scanQrCode = new Intent(this, ImportKeysProxyActivity.class); scanQrCode.setAction(ImportKeysProxyActivity.ACTION_SCAN_WITH_RESULT); startActivityForResult(scanQrCode, REQUEST_QR_FINGERPRINT); } - private void certifyFingeprint(Uri dataUri, boolean enableWordConfirm) { + private void certifyFingerprint(Uri dataUri, boolean enableWordConfirm) { Intent intent = new Intent(this, CertifyFingerprintActivity.class); intent.setData(dataUri); intent.putExtra(CertifyFingerprintActivity.EXTRA_ENABLE_WORD_CONFIRM, enableWordConfirm); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java index 4308983ce..14477723e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyAdvSubkeysFragment.java @@ -200,7 +200,7 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements switch (loader.getId()) { case LOADER_ID_UNIFIED: { data.moveToFirst(); - + mMasterKeyId = data.getLong(INDEX_MASTER_KEY_ID); mHasSecret = data.getInt(INDEX_HAS_ANY_SECRET) != 0; mFingerprint = data.getBlob(INDEX_FINGERPRINT); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java index f75012731..b8edb9b1c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyFragment.java @@ -162,7 +162,7 @@ public class ViewKeyFragment extends LoaderFragment implements try { frag = mLinkedIdsAdapter.getLinkedIdFragment(mDataUri, position, mFingerprint); } catch (IOException e) { - e.printStackTrace(); + Log.e(Constants.TAG, "IOException", e); return; } @@ -429,8 +429,17 @@ public class ViewKeyFragment extends LoaderFragment implements } case LOADER_ID_USER_IDS: { + LinearLayout editButtonsLayout = + (LinearLayout) getActivity().findViewById(R.id.view_key_card_user_ids_buttons); + if (mIsSecret) { + editButtonsLayout.setVisibility(View.VISIBLE); + } else { + editButtonsLayout.setVisibility(View.GONE); + } + setContentShown(true, false); mUserIdsAdapter.swapCursor(data); + break; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/ContentDescriptionHint.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/ContentDescriptionHint.java index 8e45a20e9..758e63eb1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/ContentDescriptionHint.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/ContentDescriptionHint.java @@ -1,8 +1,3 @@ -package org.sufficientlysecure.keychain.ui.util; - -/** - * Created by rohan on 20/9/15. - */ /* * Copyright 2012 Google Inc. * @@ -19,14 +14,18 @@ package org.sufficientlysecure.keychain.ui.util; * limitations under the License. */ +package org.sufficientlysecure.keychain.ui.util; + import android.content.Context; import android.graphics.Rect; import android.text.TextUtils; import android.view.Gravity; import android.view.View; import android.widget.Toast; + public class ContentDescriptionHint { private static final int ESTIMATED_TOAST_HEIGHT_DIPS = 48; + public static void setup(View view) { view.setOnLongClickListener(new View.OnLongClickListener() { @Override diff --git a/OpenKeychain/src/main/res/layout/linked_id_view_fragment.xml b/OpenKeychain/src/main/res/layout/linked_id_view_fragment.xml index 8b275fcef..14db368bf 100644 --- a/OpenKeychain/src/main/res/layout/linked_id_view_fragment.xml +++ b/OpenKeychain/src/main/res/layout/linked_id_view_fragment.xml @@ -144,14 +144,14 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" - android:gravity="right|end"> + android:gravity="left|start">