aboutsummaryrefslogtreecommitdiffstats
path: root/OpenPGP-Keychain
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2014-01-06 00:58:04 +0100
committerDominik Schürmann <dominik@dominikschuermann.de>2014-01-06 00:59:02 +0100
commit708baaa68c76391a3e15cd086d3829eb058819c9 (patch)
tree575852431114003becdc608fc149f87207795ae0 /OpenPGP-Keychain
parent28d9a2f26b71158823d73451bf25e1f5cf0c5431 (diff)
downloadopen-keychain-708baaa68c76391a3e15cd086d3829eb058819c9.tar.gz
open-keychain-708baaa68c76391a3e15cd086d3829eb058819c9.tar.bz2
open-keychain-708baaa68c76391a3e15cd086d3829eb058819c9.zip
Work on multiselect in key list
Diffstat (limited to 'OpenPGP-Keychain')
-rw-r--r--OpenPGP-Keychain/res/values/strings.xml6
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListActivity.java6
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java117
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/KeyListAdapter.java273
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java53
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java5
-rw-r--r--OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java52
7 files changed, 204 insertions, 308 deletions
diff --git a/OpenPGP-Keychain/res/values/strings.xml b/OpenPGP-Keychain/res/values/strings.xml
index 0b38af7fc..6ab668934 100644
--- a/OpenPGP-Keychain/res/values/strings.xml
+++ b/OpenPGP-Keychain/res/values/strings.xml
@@ -194,6 +194,7 @@
<string name="specify_file_to_export_to">Please specify which file to export to.\nWARNING! File will be overwritten if it exists.</string>
<string name="specify_file_to_export_secret_keys_to">Please specify which file to export to.\nWARNING! You are about to export SECRET keys.\nWARNING! File will be overwritten if it exists.</string>
<string name="key_deletion_confirmation">Do you really want to delete the key \'%s\'?\nYou can\'t undo this!</string>
+ <string name="key_deletion_confirmation_multi">Do you really want to delete all selected keys?\nYou can\'t undo this!</string>
<string name="secret_key_deletion_confirmation">Do you really want to delete the SECRET key \'%s\'?\nYou can\'t undo this!</string>
<string name="keys_added_and_updated">Successfully added %1$s key(s) and updated %2$s key(s).</string>
<string name="keys_added">Successfully added %s key(s).</string>
@@ -348,4 +349,9 @@
<string name="share_qr_code_dialog_progress">QR Code %1$d of %2$d</string>
<string name="share_nfc_dialog">Share with NFC</string>
+ <plurals name="key_list_selected_keys">
+ <item quantity="one">1 key selected.</item>
+ <item quantity="other">%d keys selected.</item>
+ </plurals>
+
</resources> \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListActivity.java
index 4d1849029..5b69f9218 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListActivity.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListActivity.java
@@ -225,9 +225,9 @@ public class KeyListActivity extends SherlockFragmentActivity {
/**
* Show dialog to delete key
*
- * @param keyRingId
+ * @param keyRingIds
*/
- public void showDeleteKeyDialog(long keyRingId) {
+ public void showDeleteKeyDialog(long[] keyRingIds) {
// Message is received after key is deleted
Handler returnHandler = new Handler() {
@Override
@@ -242,7 +242,7 @@ public class KeyListActivity extends SherlockFragmentActivity {
Messenger messenger = new Messenger(returnHandler);
DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger,
- keyRingId, mKeyType);
+ keyRingIds, mKeyType);
deleteKeyDialog.show(getSupportFragmentManager(), "deleteKeyDialog");
}
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java
index 27461875a..ed8427fd0 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/KeyListPublicFragment.java
@@ -17,12 +17,16 @@
package org.sufficientlysecure.keychain.ui;
+import java.util.ArrayList;
+import java.util.Set;
+
import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
import org.sufficientlysecure.keychain.ui.adapter.KeyListPublicAdapter;
+import org.sufficientlysecure.keychain.ui.dialog.DeleteKeyDialogFragment;
import se.emilsjolander.stickylistheaders.ApiLevelTooLowException;
import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
@@ -30,23 +34,32 @@ import android.annotation.SuppressLint;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
+import android.os.Build;
import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Messenger;
+import android.provider.BaseColumns;
+import android.support.v4.app.Fragment;
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.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.AdapterView;
-
-import com.actionbarsherlock.app.SherlockFragment;
+import android.widget.ListView;
/**
* Public key list with sticky list headers. It does _not_ extend ListFragment because it uses
* StickyListHeaders library which does not extend upon ListView.
*/
-public class KeyListPublicFragment extends SherlockFragment implements
- AdapterView.OnItemClickListener, LoaderManager.LoaderCallbacks<Cursor> {
+public class KeyListPublicFragment extends Fragment implements AdapterView.OnItemClickListener,
+ LoaderManager.LoaderCallbacks<Cursor> {
private KeyListPublicActivity mKeyListPublicActivity;
private KeyListPublicAdapter mAdapter;
@@ -84,6 +97,73 @@ public class KeyListPublicFragment extends SherlockFragment implements
// this view is made visible if no data is available
mStickyList.setEmptyView(getActivity().findViewById(R.id.empty));
+ /*
+ * ActionBarSherlock does not support MultiChoiceModeListener. Thus multi-selection is only
+ * available for Android >= 3.0
+ */
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ mStickyList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+ mStickyList.getWrappedList().setMultiChoiceModeListener(new MultiChoiceModeListener() {
+
+ private int count = 0;
+
+ @Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ android.view.MenuInflater inflater = getActivity().getMenuInflater();
+ inflater.inflate(R.menu.key_list_multi_selection, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ return false;
+ }
+
+ @Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ // StringBuilder sb = new StringBuilder();
+ Set<Integer> positions = mAdapter.getCurrentCheckedPosition();
+ // for (Integer pos : positions) {
+ // sb.append(" " + pos + ",");
+ // }
+ switch (item.getItemId()) {
+ case R.id.delete_entry:
+ long[] ids = new long[positions.size()];
+ for (int i=0; i < positions.size(); i++) {
+ ids[i] = mAdapter.getItemId(positions.);
+ }
+ showDeleteKeyDialog(ids.to);
+
+ break;
+ }
+ return false;
+ }
+
+ @Override
+ public void onDestroyActionMode(ActionMode mode) {
+ count = 0;
+ mAdapter.clearSelection();
+ }
+
+ @Override
+ public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
+ boolean checked) {
+ if (checked) {
+ count++;
+ mAdapter.setNewSelection(position, checked);
+ } else {
+ count--;
+ mAdapter.removeSelection(position);
+ }
+
+ String keysSelected = getResources().getQuantityString(
+ R.plurals.key_list_selected_keys, count, count);
+ mode.setTitle(keysSelected);
+ }
+
+ });
+ }
+
// NOTE: Not supported by StickyListHeader, thus no indicator is shown while loading
// Start out with a progress indicator.
// setListShown(false);
@@ -152,4 +232,31 @@ public class KeyListPublicFragment extends SherlockFragment implements
startActivity(detailsIntent);
}
-}
+ /**
+ * Show dialog to delete key
+ *
+ * TODO: no messenger needed etc!
+ *
+ * @param keyRingRowIds
+ */
+ public void showDeleteKeyDialog(long[] keyRingRowIds) {
+ // Message is received after key is deleted
+ Handler returnHandler = new Handler() {
+ @Override
+ public void handleMessage(Message message) {
+ if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) {
+ // no further actions needed
+ }
+ }
+ };
+
+ // Create a new Messenger for the communication back
+ Messenger messenger = new Messenger(returnHandler);
+
+ DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger,
+ keyRingRowIds, Id.type.public_key);
+
+ deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog");
+ }
+
+} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/KeyListAdapter.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/KeyListAdapter.java
deleted file mode 100644
index 4719d1d1c..000000000
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/KeyListAdapter.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.sufficientlysecure.keychain.ui.adapter;
-
-import org.sufficientlysecure.keychain.Constants;
-import org.sufficientlysecure.keychain.Id;
-import org.sufficientlysecure.keychain.helper.OtherHelper;
-import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
-import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
-import org.sufficientlysecure.keychain.util.Log;
-import org.sufficientlysecure.keychain.R;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.MergeCursor;
-import android.net.Uri;
-import android.provider.BaseColumns;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.CursorTreeAdapter;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-public class KeyListAdapter extends CursorTreeAdapter {
- private Context mContext;
- private LayoutInflater mInflater;
-
- protected int mKeyType;
-
- private static final int CHILD_KEY = 0;
- private static final int CHILD_USER_ID = 1;
- private static final int CHILD_FINGERPRINT = 2;
-
- public KeyListAdapter(Context context, Cursor groupCursor, int keyType) {
- super(groupCursor, context);
- mContext = context;
- mInflater = LayoutInflater.from(context);
- mKeyType = keyType;
- }
-
- /**
- * Inflate new view for group items
- */
- @Override
- public View newGroupView(Context context, Cursor cursor, boolean isExpanded, ViewGroup parent) {
- return mInflater.inflate(R.layout.key_list_item, null);
- }
-
- /**
- * Binds TextViews from group view to results from database group cursor.
- */
- @Override
- protected void bindGroupView(View view, Context context, Cursor cursor, boolean isExpanded) {
- int userIdIndex = cursor.getColumnIndex(UserIds.USER_ID);
-
- TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId);
- mainUserId.setText(R.string.unknown_user_id);
- TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest);
- mainUserIdRest.setText("");
-
- String userId = cursor.getString(userIdIndex);
- if (userId != null) {
- String[] userIdSplit = OtherHelper.splitUserId(userId);
-
- if (userIdSplit[1] != null) {
- mainUserIdRest.setText(userIdSplit[1]);
- }
- mainUserId.setText(userIdSplit[0]);
- }
-
- if (mainUserId.getText().length() == 0) {
- mainUserId.setText(R.string.unknown_user_id);
- }
-
- if (mainUserIdRest.getText().length() == 0) {
- mainUserIdRest.setVisibility(View.GONE);
- } else {
- mainUserIdRest.setVisibility(View.VISIBLE);
- }
- }
-
- /**
- * Inflate new view for child items
- */
- @Override
- public View newChildView(Context context, Cursor cursor, boolean isLastChild, ViewGroup parent) {
- return mInflater.inflate(R.layout.key_list_child_item, null);
- }
-
- /**
- * Bind TextViews from view of childs based on query results
- */
- @Override
- protected void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild) {
- LinearLayout keyLayout = (LinearLayout) view.findViewById(R.id.keyLayout);
- LinearLayout userIdLayout = (LinearLayout) view.findViewById(R.id.userIdLayout);
-
- // first entry is fingerprint
- if (cursor.getPosition() == 0) {
- // show only userId layout
- keyLayout.setVisibility(View.GONE);
- userIdLayout.setVisibility(View.VISIBLE);
-
- String fingerprint = PgpKeyHelper.getFingerPrint(context,
- cursor.getLong(cursor.getColumnIndex(Keys.KEY_ID)));
- fingerprint = fingerprint.replace(" ", "\n");
-
- TextView userId = (TextView) view.findViewById(R.id.userId);
- if (userId == null) {
- Log.d(Constants.TAG, "userId is null!");
- }
- userId.setText(context.getString(R.string.fingerprint) + "\n" + fingerprint);
- } else {
- // differentiate between keys and userIds in MergeCursor
- if (cursor.getColumnIndex(Keys.KEY_ID) != -1) {
- keyLayout.setVisibility(View.VISIBLE);
- userIdLayout.setVisibility(View.GONE);
-
- String keyIdStr = PgpKeyHelper.convertKeyIdToHex(cursor.getLong(cursor
- .getColumnIndex(Keys.KEY_ID)));
- String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
- cursor.getInt(cursor.getColumnIndex(Keys.ALGORITHM)),
- cursor.getInt(cursor.getColumnIndex(Keys.KEY_SIZE)));
-
- TextView keyId = (TextView) view.findViewById(R.id.keyId);
- keyId.setText(keyIdStr);
-
- TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails);
- keyDetails.setText("(" + algorithmStr + ")");
-
- ImageView masterKeyIcon = (ImageView) view.findViewById(R.id.ic_masterKey);
- if (cursor.getInt(cursor.getColumnIndex(Keys.IS_MASTER_KEY)) != 1) {
- masterKeyIcon.setVisibility(View.INVISIBLE);
- } else {
- masterKeyIcon.setVisibility(View.VISIBLE);
- }
-
- ImageView certifyIcon = (ImageView) view.findViewById(R.id.ic_certifyKey);
- if (cursor.getInt(cursor.getColumnIndex(Keys.CAN_CERTIFY)) != 1) {
- certifyIcon.setVisibility(View.GONE);
- } else {
- certifyIcon.setVisibility(View.VISIBLE);
- }
-
- ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey);
- if (cursor.getInt(cursor.getColumnIndex(Keys.CAN_ENCRYPT)) != 1) {
- encryptIcon.setVisibility(View.GONE);
- } else {
- encryptIcon.setVisibility(View.VISIBLE);
- }
-
- ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey);
- if (cursor.getInt(cursor.getColumnIndex(Keys.CAN_SIGN)) != 1) {
- signIcon.setVisibility(View.GONE);
- } else {
- signIcon.setVisibility(View.VISIBLE);
- }
- } else {
- keyLayout.setVisibility(View.GONE);
- userIdLayout.setVisibility(View.VISIBLE);
-
- String userIdStr = cursor.getString(cursor.getColumnIndex(UserIds.USER_ID));
-
- TextView userId = (TextView) view.findViewById(R.id.userId);
- userId.setText(userIdStr);
- }
- }
- }
-
- /**
- * Given the group cursor, we start cursors for a fingerprint, keys, and userIds, which are
- * merged together and build the child cursor
- */
- @Override
- protected Cursor getChildrenCursor(Cursor groupCursor) {
- final long keyRingRowId = groupCursor.getLong(groupCursor.getColumnIndex(BaseColumns._ID));
-
- Cursor fingerprintCursor = getChildCursor(keyRingRowId, CHILD_FINGERPRINT);
- Cursor keyCursor = getChildCursor(keyRingRowId, CHILD_KEY);
- Cursor userIdCursor = getChildCursor(keyRingRowId, CHILD_USER_ID);
-
- MergeCursor mergeCursor = new MergeCursor(new Cursor[] { fingerprintCursor, keyCursor,
- userIdCursor });
- Log.d(Constants.TAG, "mergeCursor:" + DatabaseUtils.dumpCursorToString(mergeCursor));
-
- return mergeCursor;
- }
-
- /**
- * This builds a cursor for a specific type of children
- *
- * @param keyRingRowId
- * foreign row id of the keyRing
- * @param type
- * @return
- */
- private Cursor getChildCursor(long keyRingRowId, int type) {
- Uri uri = null;
- String[] projection = null;
- String sortOrder = null;
- String selection = null;
-
- switch (type) {
- case CHILD_FINGERPRINT:
- projection = new String[] { Keys._ID, Keys.KEY_ID, Keys.IS_MASTER_KEY, Keys.ALGORITHM,
- Keys.KEY_SIZE, Keys.CAN_CERTIFY, Keys.CAN_SIGN, Keys.CAN_ENCRYPT, };
- sortOrder = Keys.RANK + " ASC";
-
- // use only master key for fingerprint
- selection = Keys.IS_MASTER_KEY + " = 1 ";
-
- if (mKeyType == Id.type.public_key) {
- uri = Keys.buildPublicKeysUri(String.valueOf(keyRingRowId));
- } else {
- uri = Keys.buildSecretKeysUri(String.valueOf(keyRingRowId));
- }
- break;
-
- case CHILD_KEY:
- projection = new String[] { Keys._ID, Keys.KEY_ID, Keys.IS_MASTER_KEY, Keys.ALGORITHM,
- Keys.KEY_SIZE, Keys.CAN_CERTIFY, Keys.CAN_SIGN, Keys.CAN_ENCRYPT, };
- sortOrder = Keys.RANK + " ASC";
-
- if (mKeyType == Id.type.public_key) {
- uri = Keys.buildPublicKeysUri(String.valueOf(keyRingRowId));
- } else {
- uri = Keys.buildSecretKeysUri(String.valueOf(keyRingRowId));
- }
-
- break;
-
- case CHILD_USER_ID:
- projection = new String[] { UserIds._ID, UserIds.USER_ID, UserIds.RANK, };
- sortOrder = UserIds.RANK + " ASC";
-
- // not the main user id
- selection = UserIds.RANK + " > 0 ";
-
- if (mKeyType == Id.type.public_key) {
- uri = UserIds.buildPublicUserIdsUri(String.valueOf(keyRingRowId));
- } else {
- uri = UserIds.buildSecretUserIdsUri(String.valueOf(keyRingRowId));
- }
-
- break;
-
- default:
- return null;
-
- }
-
- return mContext.getContentResolver().query(uri, projection, selection, null, sortOrder);
- }
-
-}
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java
index 83c46021c..5f71c9805 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/KeyListPublicAdapter.java
@@ -17,15 +17,18 @@
package org.sufficientlysecure.keychain.ui.adapter;
+import java.util.HashMap;
+import java.util.Set;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.OtherHelper;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
import org.sufficientlysecure.keychain.util.Log;
-
import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.database.Cursor;
+import android.graphics.Color;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
@@ -39,6 +42,9 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea
private LayoutInflater mInflater;
private int mSectionColumnIndex;
+ @SuppressLint("UseSparseArrays")
+ private HashMap<Integer, Boolean> mSelection = new HashMap<Integer, Boolean>();
+
public KeyListPublicAdapter(Context context, Cursor c, int flags, int sectionColumnIndex) {
super(context, c, flags);
@@ -138,7 +144,8 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea
}
// return the first character of the name as ID because this is what
- // headers are based upon
+ // headers private HashMap<Integer, Boolean> mSelection = new HashMap<Integer,
+ // Boolean>();are based upon
return mCursor.getString(mSectionColumnIndex).subSequence(0, 1).charAt(0);
}
@@ -146,4 +153,46 @@ public class KeyListPublicAdapter extends CursorAdapter implements StickyListHea
TextView text;
}
+ /** -------------------------- MULTI-SELECTION METHODS -------------- */
+ public void setNewSelection(int position, boolean value) {
+ mSelection.put(position, value);
+ notifyDataSetChanged();
+ }
+
+ public boolean isPositionChecked(int position) {
+ Boolean result = mSelection.get(position);
+ return result == null ? false : result;
+ }
+
+ public Set<Integer> getCurrentCheckedPosition() {
+ return mSelection.keySet();
+ }
+
+ public void removeSelection(int position) {
+ mSelection.remove(position);
+ notifyDataSetChanged();
+ }
+
+ public void clearSelection() {
+ mSelection.clear();
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ // let the adapter handle setting up the row views
+ View v = super.getView(position, convertView, parent);
+
+ /**
+ * Change color for multi-selection
+ */
+ // default color
+ v.setBackgroundColor(Color.TRANSPARENT);
+ if (mSelection.get(position) != null) {
+ // this is a selected position, change color!
+ v.setBackgroundColor(parent.getResources().getColor(R.color.emphasis));
+ }
+ return v;
+ }
+
}
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java
index 6315f84fb..2fda8a9f7 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/adapter/KeyListSecretAdapter.java
@@ -19,19 +19,14 @@ package org.sufficientlysecure.keychain.ui.adapter;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.OtherHelper;
-import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.database.Cursor;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.ImageView;
import android.widget.TextView;
public class KeyListSecretAdapter extends CursorAdapter {
diff --git a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
index 638702b57..101167777 100644
--- a/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
+++ b/OpenPGP-Keychain/src/org/sufficientlysecure/keychain/ui/dialog/DeleteKeyDialogFragment.java
@@ -38,7 +38,7 @@ import android.support.v4.app.FragmentActivity;
public class DeleteKeyDialogFragment extends DialogFragment {
private static final String ARG_MESSENGER = "messenger";
- private static final String ARG_DELETE_KEY_RING_ROW_ID = "delete_file";
+ private static final String ARG_DELETE_KEY_RING_ROW_IDS = "delete_file";
private static final String ARG_KEY_TYPE = "key_type";
public static final int MESSAGE_OKAY = 1;
@@ -48,13 +48,13 @@ public class DeleteKeyDialogFragment extends DialogFragment {
/**
* Creates new instance of this delete file dialog fragment
*/
- public static DeleteKeyDialogFragment newInstance(Messenger messenger, long deleteKeyRingRowId,
+ public static DeleteKeyDialogFragment newInstance(Messenger messenger, long[] keyRingRowIds,
int keyType) {
DeleteKeyDialogFragment frag = new DeleteKeyDialogFragment();
Bundle args = new Bundle();
args.putParcelable(ARG_MESSENGER, messenger);
- args.putLong(ARG_DELETE_KEY_RING_ROW_ID, deleteKeyRingRowId);
+ args.putLongArray(ARG_DELETE_KEY_RING_ROW_IDS, keyRingRowIds);
args.putInt(ARG_KEY_TYPE, keyType);
frag.setArguments(args);
@@ -70,36 +70,48 @@ public class DeleteKeyDialogFragment extends DialogFragment {
final FragmentActivity activity = getActivity();
mMessenger = getArguments().getParcelable(ARG_MESSENGER);
- final long deleteKeyRingRowId = getArguments().getLong(ARG_DELETE_KEY_RING_ROW_ID);
+ final long[] keyRingRowIds = getArguments().getLongArray(ARG_DELETE_KEY_RING_ROW_IDS);
final int keyType = getArguments().getInt(ARG_KEY_TYPE);
- // TODO: better way to do this?
- String userId = activity.getString(R.string.unknown_user_id);
+ AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+ builder.setTitle(R.string.warning);
+
+ if (keyRingRowIds.length == 1) {
+ // TODO: better way to do this?
+ String userId = activity.getString(R.string.unknown_user_id);
+
+ if (keyType == Id.type.public_key) {
+ PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByRowId(activity,
+ keyRingRowIds[0]);
+ userId = PgpKeyHelper.getMainUserIdSafe(activity,
+ PgpKeyHelper.getMasterKey(keyRing));
+ } else {
+ PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByRowId(activity,
+ keyRingRowIds[0]);
+ userId = PgpKeyHelper.getMainUserIdSafe(activity,
+ PgpKeyHelper.getMasterKey(keyRing));
+ }
- if (keyType == Id.type.public_key) {
- PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByRowId(activity,
- deleteKeyRingRowId);
- userId = PgpKeyHelper.getMainUserIdSafe(activity, PgpKeyHelper.getMasterKey(keyRing));
+ builder.setMessage(getString(
+ keyType == Id.type.public_key ? R.string.key_deletion_confirmation
+ : R.string.secret_key_deletion_confirmation, userId));
} else {
- PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByRowId(activity,
- deleteKeyRingRowId);
- userId = PgpKeyHelper.getMainUserIdSafe(activity, PgpKeyHelper.getMasterKey(keyRing));
+ builder.setMessage(R.string.key_deletion_confirmation_multi);
}
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
- builder.setTitle(R.string.warning);
- builder.setMessage(getString(
- keyType == Id.type.public_key ? R.string.key_deletion_confirmation
- : R.string.secret_key_deletion_confirmation, userId));
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
if (keyType == Id.type.public_key) {
- ProviderHelper.deletePublicKeyRing(activity, deleteKeyRingRowId);
+ for (long keyRowId : keyRingRowIds) {
+ ProviderHelper.deletePublicKeyRing(activity, keyRowId);
+ }
} else {
- ProviderHelper.deleteSecretKeyRing(activity, deleteKeyRingRowId);
+ for (long keyRowId : keyRingRowIds) {
+ ProviderHelper.deleteSecretKeyRing(activity, keyRowId);
+ }
}
dismiss();