diff options
Diffstat (limited to 'OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java')
-rw-r--r-- | OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java | 138 |
1 files changed, 68 insertions, 70 deletions
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java index a08f4bc74..45db30fe5 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java @@ -24,7 +24,11 @@ import android.content.Intent; import android.database.Cursor; import android.graphics.Color; import android.net.Uri; -import android.os.*; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; @@ -33,22 +37,29 @@ import android.support.v4.view.MenuItemCompat; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.SearchView; import android.text.TextUtils; -import android.view.*; +import android.view.ActionMode; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; import android.view.View.OnClickListener; +import android.view.ViewGroup; import android.view.animation.AnimationUtils; -import android.widget.*; import android.widget.AbsListView.MultiChoiceModeListener; +import android.widget.AdapterView; +import android.widget.Button; +import android.widget.FrameLayout; +import android.widget.ListView; +import android.widget.TextView; import com.beardedhen.androidbootstrap.BootstrapButton; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.ExportHelper; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyTypes; -import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; -import org.sufficientlysecure.keychain.provider.KeychainDatabase; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRingData; import org.sufficientlysecure.keychain.ui.adapter.HighlightQueryCursorAdapter; import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment; import org.sufficientlysecure.keychain.util.Log; @@ -56,7 +67,6 @@ import se.emilsjolander.stickylistheaders.ApiLevelTooLowException; import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter; import se.emilsjolander.stickylistheaders.StickyListHeadersListView; -import java.util.ArrayList; import java.util.HashMap; /** @@ -142,9 +152,6 @@ public class KeyListFragment extends Fragment } catch (ApiLevelTooLowException e) { } - // this view is made visible if no data is available - mStickyList.setEmptyView(getActivity().findViewById(R.id.key_list_empty)); - /* * ActionBarSherlock does not support MultiChoiceModeListener. Thus multi-selection is only * available for Android >= 3.0 @@ -178,18 +185,15 @@ public class KeyListFragment extends Fragment break; } case R.id.menu_key_list_multi_delete: { - ids = mStickyList.getWrappedList().getCheckedItemIds(); + ids = mAdapter.getCurrentSelectedMasterKeyIds(); showDeleteKeyDialog(mode, ids); break; } case R.id.menu_key_list_multi_export: { - // todo: public/secret needs to be handled differently here - ids = mStickyList.getWrappedList().getCheckedItemIds(); + ids = mAdapter.getCurrentSelectedMasterKeyIds(); ExportHelper mExportHelper = new ExportHelper((ActionBarActivity) getActivity()); - mExportHelper - .showExportKeysDialog(ids, - Id.type.public_key, - Constants.Path.APP_DIR_FILE_PUB); + mExportHelper.showExportKeysDialog( + ids, Constants.Path.APP_DIR_FILE_PUB, mAdapter.isAnySecretSelected()); break; } case R.id.menu_key_list_multi_select_all: { @@ -243,23 +247,17 @@ public class KeyListFragment extends Fragment // These are the rows that we will retrieve. static final String[] PROJECTION = new String[]{ - KeychainContract.KeyRings._ID, - KeychainContract.KeyRings.TYPE, - KeychainContract.KeyRings.MASTER_KEY_ID, - KeychainContract.UserIds.USER_ID, - KeychainContract.Keys.IS_REVOKED + KeyRings._ID, + KeyRings.MASTER_KEY_ID, + KeyRings.USER_ID, + KeyRings.IS_REVOKED, + KeyRings.HAS_SECRET }; - static final int INDEX_TYPE = 1; - static final int INDEX_MASTER_KEY_ID = 2; - static final int INDEX_USER_ID = 3; - static final int INDEX_IS_REVOKED = 4; - - static final String SORT_ORDER = - // show secret before public key - KeychainDatabase.Tables.KEY_RINGS + "." + KeyRings.TYPE + " DESC, " - // sort by user id otherwise - + UserIds.USER_ID + " ASC"; + static final int INDEX_MASTER_KEY_ID = 1; + static final int INDEX_USER_ID = 2; + static final int INDEX_IS_REVOKED = 3; + static final int INDEX_HAS_SECRET = 4; @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { @@ -269,12 +267,12 @@ public class KeyListFragment extends Fragment String where = null; String whereArgs[] = null; if (mCurQuery != null) { - where = KeychainContract.UserIds.USER_ID + " LIKE ?"; + where = KeyRings.USER_ID + " LIKE ?"; whereArgs = new String[]{"%" + mCurQuery + "%"}; } // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. - return new CursorLoader(getActivity(), baseUri, PROJECTION, where, whereArgs, SORT_ORDER); + return new CursorLoader(getActivity(), baseUri, PROJECTION, where, whereArgs, null); } @Override @@ -286,6 +284,9 @@ public class KeyListFragment extends Fragment mStickyList.setAdapter(mAdapter); + // this view is made visible if no data is available + mStickyList.setEmptyView(getActivity().findViewById(R.id.key_list_empty)); + // NOTE: Not supported by StickyListHeader, but reimplemented here // The list should now be shown. if (isResumed()) { @@ -315,17 +316,15 @@ public class KeyListFragment extends Fragment viewIntent = new Intent(getActivity(), ViewKeyActivityJB.class); } viewIntent.setData( - KeychainContract - .KeyRings.buildPublicKeyRingsByMasterKeyIdUri( - Long.toString(mAdapter.getMasterKeyId(position)))); + KeyRings.buildGenericKeyRingUri(Long.toString(mAdapter.getMasterKeyId(position)))); startActivity(viewIntent); } @TargetApi(11) - protected void encrypt(ActionMode mode, long[] keyRingMasterKeyIds) { + protected void encrypt(ActionMode mode, long[] masterKeyIds) { Intent intent = new Intent(getActivity(), EncryptActivity.class); intent.setAction(EncryptActivity.ACTION_ENCRYPT); - intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, keyRingMasterKeyIds); + intent.putExtra(EncryptActivity.EXTRA_ENCRYPTION_KEY_IDS, masterKeyIds); // used instead of startActivity set actionbar based on callingPackage startActivityForResult(intent, 0); @@ -335,35 +334,17 @@ public class KeyListFragment extends Fragment /** * Show dialog to delete key * - * @param keyRingRowIds + * @param masterKeyIds */ @TargetApi(11) // TODO: this method needs an overhaul to handle both public and secret keys gracefully! - public void showDeleteKeyDialog(final ActionMode mode, long[] keyRingRowIds) { + public void showDeleteKeyDialog(final ActionMode mode, long[] masterKeyIds) { // Message is received after key is deleted Handler returnHandler = new Handler() { @Override public void handleMessage(Message message) { if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) { - Bundle returnData = message.getData(); - if (returnData != null - && returnData.containsKey(DeleteKeyDialogFragment.MESSAGE_NOT_DELETED)) { - ArrayList<String> notDeleted = - returnData.getStringArrayList(DeleteKeyDialogFragment.MESSAGE_NOT_DELETED); - String notDeletedMsg = ""; - for (String userId : notDeleted) { - notDeletedMsg += userId + "\n"; - } - Toast.makeText(getActivity(), - getString(R.string.error_can_not_delete_contacts, notDeletedMsg) - + getResources() - .getQuantityString( - R.plurals.error_can_not_delete_info, - notDeleted.size()), - Toast.LENGTH_LONG).show(); - - mode.finish(); - } + mode.finish(); } } }; @@ -372,7 +353,7 @@ public class KeyListFragment extends Fragment Messenger messenger = new Messenger(returnHandler); DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger, - keyRingRowIds, Id.type.public_key); + masterKeyIds); deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog"); } @@ -506,11 +487,15 @@ public class KeyListFragment extends Fragment } { // set edit button and revoked info, specific by key type + View statusDivider = (View) view.findViewById(R.id.status_divider); + FrameLayout statusLayout = (FrameLayout) view.findViewById(R.id.status_layout); Button button = (Button) view.findViewById(R.id.edit); TextView revoked = (TextView) view.findViewById(R.id.revoked); - if (cursor.getInt(KeyListFragment.INDEX_TYPE) == KeyTypes.SECRET) { + if (cursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) { // this is a secret key - show the edit button + statusDivider.setVisibility(View.VISIBLE); + statusLayout.setVisibility(View.VISIBLE); revoked.setVisibility(View.GONE); button.setVisibility(View.VISIBLE); @@ -518,26 +503,31 @@ public class KeyListFragment extends Fragment button.setOnClickListener(new OnClickListener() { public void onClick(View view) { Intent editIntent = new Intent(getActivity(), EditKeyActivity.class); - editIntent.setData( - KeychainContract.KeyRings.buildSecretKeyRingsByMasterKeyIdUri( - Long.toString(id) - ) - ); + editIntent.setData(KeyRingData.buildSecretKeyRingUri(Long.toString(id))); editIntent.setAction(EditKeyActivity.ACTION_EDIT_KEY); startActivityForResult(editIntent, 0); } }); } else { // this is a public key - hide the edit button, show if it's revoked + statusDivider.setVisibility(View.GONE); button.setVisibility(View.GONE); boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0; + statusLayout.setVisibility(isRevoked ? View.VISIBLE : View.GONE); revoked.setVisibility(isRevoked ? View.VISIBLE : View.GONE); } } } + public boolean isSecretAvailable(int id) { + if (!mCursor.moveToPosition(id)) { + throw new IllegalStateException("couldn't move cursor to position " + id); + } + + return mCursor.getInt(INDEX_HAS_SECRET) != 0; + } public long getMasterKeyId(int id) { if (!mCursor.moveToPosition(id)) { throw new IllegalStateException("couldn't move cursor to position " + id); @@ -581,7 +571,7 @@ public class KeyListFragment extends Fragment throw new IllegalStateException("couldn't move cursor to position " + position); } - if (mCursor.getInt(KeyListFragment.INDEX_TYPE) == KeyTypes.SECRET) { + if (mCursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) { { // set contact count int num = mCursor.getCount(); String contactsTotal = getResources().getQuantityString(R.plurals.n_contacts, num, num); @@ -620,7 +610,7 @@ public class KeyListFragment extends Fragment } // early breakout: all secret keys are assigned id 0 - if (mCursor.getInt(KeyListFragment.INDEX_TYPE) == KeyTypes.SECRET) { + if (mCursor.getInt(KeyListFragment.INDEX_HAS_SECRET) != 0) { return 1L; } // otherwise, return the first character of the name as ID @@ -645,6 +635,14 @@ public class KeyListFragment extends Fragment notifyDataSetChanged(); } + public boolean isAnySecretSelected() { + for (int pos : mSelection.keySet()) { + if(mAdapter.isSecretAvailable(pos)) + return true; + } + return false; + } + public long[] getCurrentSelectedMasterKeyIds() { long[] ids = new long[mSelection.size()]; int i = 0; |