aboutsummaryrefslogtreecommitdiffstats
path: root/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2014-03-18 14:43:20 +0100
committerDominik Schürmann <dominik@dominikschuermann.de>2014-03-18 14:43:20 +0100
commit711a51f7fc72c4c13ea63bd11f7aa67a21a3307c (patch)
tree56d72b6812fc9ddb301bd9921b69823575f6f52f /OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui
parent30644b5c4f72f828ecead09fc7e2d5d4ae8e91db (diff)
parent87004fd0ca3a5178fba3050599a445ba9c64662c (diff)
downloadopen-keychain-711a51f7fc72c4c13ea63bd11f7aa67a21a3307c.tar.gz
open-keychain-711a51f7fc72c4c13ea63bd11f7aa67a21a3307c.tar.bz2
open-keychain-711a51f7fc72c4c13ea63bd11f7aa67a21a3307c.zip
Merge pull request #430 from Valodim/certify
Revamp certify dialogue
Diffstat (limited to 'OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui')
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java109
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java13
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java96
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java81
4 files changed, 220 insertions, 79 deletions
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
index 9a9911c94..d8df5ced3 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
@@ -19,11 +19,15 @@ package org.sufficientlysecure.keychain.ui;
import android.app.ProgressDialog;
import android.content.Intent;
+import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
@@ -32,26 +36,28 @@ import android.widget.*;
import android.widget.CompoundButton.OnCheckedChangeListener;
import com.beardedhen.androidbootstrap.BootstrapButton;
import org.spongycastle.openpgp.PGPPublicKeyRing;
-import org.spongycastle.openpgp.PGPSignature;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.helper.OtherHelper;
import org.sufficientlysecure.keychain.helper.Preferences;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
+import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.service.PassphraseCacheService;
+import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter;
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
import org.sufficientlysecure.keychain.util.Log;
-import java.util.Iterator;
+import java.util.ArrayList;
/**
* Signs the specified public key with the specified secret master key
*/
public class CertifyKeyActivity extends ActionBarActivity implements
- SelectSecretKeyLayoutFragment.SelectSecretKeyCallback {
+ SelectSecretKeyLayoutFragment.SelectSecretKeyCallback, LoaderManager.LoaderCallbacks<Cursor> {
private BootstrapButton mSignButton;
private CheckBox mUploadKeyCheckbox;
private Spinner mSelectKeyserverSpinner;
@@ -62,6 +68,12 @@ public class CertifyKeyActivity extends ActionBarActivity implements
private long mPubKeyId = 0;
private long mMasterKeyId = 0;
+ private ListView mUserIds;
+ private ViewKeyUserIdsAdapter mUserIdsAdapter;
+
+ private static final int LOADER_ID_KEYRING = 0;
+ private static final int LOADER_ID_USER_IDS = 1;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -125,9 +137,18 @@ public class CertifyKeyActivity extends ActionBarActivity implements
finish();
return;
}
+ Log.e(Constants.TAG, "uri: " + mDataUri);
PGPPublicKeyRing signKey = (PGPPublicKeyRing) ProviderHelper.getPGPKeyRing(this, mDataUri);
+ mUserIds = (ListView) findViewById(R.id.user_ids);
+
+ mUserIdsAdapter = new ViewKeyUserIdsAdapter(this, null, 0, true);
+ mUserIds.setAdapter(mUserIdsAdapter);
+
+ getSupportLoaderManager().initLoader(LOADER_ID_KEYRING, null, this);
+ getSupportLoaderManager().initLoader(LOADER_ID_USER_IDS, null, this);
+
if (signKey != null) {
mPubKeyId = PgpKeyHelper.getMasterKey(signKey).getKeyID();
}
@@ -138,6 +159,76 @@ public class CertifyKeyActivity extends ActionBarActivity implements
}
}
+ static final String[] KEYRING_PROJECTION =
+ new String[] {
+ KeychainContract.KeyRings._ID,
+ KeychainContract.KeyRings.MASTER_KEY_ID,
+ KeychainContract.Keys.FINGERPRINT,
+ KeychainContract.UserIds.USER_ID
+ };
+ static final int INDEX_MASTER_KEY_ID = 1;
+ static final int INDEX_FINGERPRINT = 2;
+ static final int INDEX_USER_ID = 3;
+
+ static final String[] USER_IDS_PROJECTION =
+ new String[]{
+ KeychainContract.UserIds._ID,
+ KeychainContract.UserIds.USER_ID,
+ KeychainContract.UserIds.RANK
+ };
+ static final String USER_IDS_SORT_ORDER =
+ KeychainContract.UserIds.RANK + " ASC";
+
+ @Override
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ switch(id) {
+ case LOADER_ID_KEYRING:
+ return new CursorLoader(this, mDataUri, KEYRING_PROJECTION, null, null, null);
+ case LOADER_ID_USER_IDS: {
+ Uri baseUri = KeychainContract.UserIds.buildUserIdsUri(mDataUri);
+ return new CursorLoader(this, baseUri, USER_IDS_PROJECTION, null, null, USER_IDS_SORT_ORDER);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ switch(loader.getId()) {
+ case LOADER_ID_KEYRING:
+ // the first key here is our master key
+ if (data.moveToFirst()) {
+ long keyId = data.getLong(INDEX_MASTER_KEY_ID);
+ String keyIdStr = PgpKeyHelper.convertKeyIdToHex(keyId);
+ ((TextView) findViewById(R.id.key_id)).setText(keyIdStr);
+
+ String mainUserId = data.getString(INDEX_USER_ID);
+ ((TextView) findViewById(R.id.main_user_id)).setText(mainUserId);
+
+ byte[] fingerprintBlob = data.getBlob(INDEX_FINGERPRINT);
+ if (fingerprintBlob == null) {
+ // FALLBACK for old database entries
+ fingerprintBlob = ProviderHelper.getFingerprint(this, mDataUri);
+ }
+ String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true);
+ ((TextView) findViewById(R.id.fingerprint)).setText(OtherHelper.colorizeFingerprint(fingerprint));
+ }
+ break;
+ case LOADER_ID_USER_IDS:
+ mUserIdsAdapter.swapCursor(data);
+ break;
+ }
+ }
+
+ @Override
+ public void onLoaderReset(Loader<Cursor> loader) {
+ switch(loader.getId()) {
+ case LOADER_ID_USER_IDS:
+ mUserIdsAdapter.swapCursor(null);
+ break;
+ }
+ }
+
private void showPassphraseDialog(final long secretKeyId) {
// Message is received after passphrase is cached
Handler returnHandler = new Handler() {
@@ -173,6 +264,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements
// if we have already signed this key, dont bother doing it again
boolean alreadySigned = false;
+ /* todo: reconsider this at a later point when certs are in the db
@SuppressWarnings("unchecked")
Iterator<PGPSignature> itr = pubring.getPublicKey(mPubKeyId).getSignatures();
while (itr.hasNext()) {
@@ -182,6 +274,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements
break;
}
}
+ */
if (!alreadySigned) {
/*
@@ -209,6 +302,15 @@ public class CertifyKeyActivity extends ActionBarActivity implements
* kicks off the actual signing process on a background thread
*/
private void startSigning() {
+
+ // Bail out if there is not at least one user id selected
+ ArrayList<String> userIds = mUserIdsAdapter.getSelectedUserIds();
+ if(userIds.isEmpty()) {
+ Toast.makeText(CertifyKeyActivity.this, "No User IDs to sign selected!",
+ Toast.LENGTH_SHORT).show();
+ return;
+ }
+
// Send all information needed to service to sign key in other thread
Intent intent = new Intent(this, KeychainIntentService.class);
@@ -219,6 +321,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements
data.putLong(KeychainIntentService.CERTIFY_KEY_MASTER_KEY_ID, mMasterKeyId);
data.putLong(KeychainIntentService.CERTIFY_KEY_PUB_KEY_ID, mPubKeyId);
+ data.putStringArrayList(KeychainIntentService.CERTIFY_KEY_UIDS, userIds);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java
index beff8385e..3d22ca9f6 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java
@@ -39,6 +39,7 @@ public class SelectSecretKeyLayoutFragment extends Fragment {
private TextView mKeyUserId;
private TextView mKeyUserIdRest;
private TextView mKeyMasterKeyIdHex;
+ private TextView mNoKeySelected;
private BootstrapButton mSelectKeyButton;
private Boolean mFilterCertify;
@@ -60,10 +61,10 @@ public class SelectSecretKeyLayoutFragment extends Fragment {
public void selectKey(long secretKeyId) {
if (secretKeyId == Id.key.none) {
- mKeyMasterKeyIdHex.setText(R.string.api_settings_no_key);
- mKeyUserIdRest.setText("");
+ mNoKeySelected.setVisibility(View.VISIBLE);
mKeyUserId.setVisibility(View.GONE);
mKeyUserIdRest.setVisibility(View.GONE);
+ mKeyMasterKeyIdHex.setVisibility(View.GONE);
} else {
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(
@@ -93,20 +94,25 @@ public class SelectSecretKeyLayoutFragment extends Fragment {
mKeyMasterKeyIdHex.setText(masterkeyIdHex);
mKeyUserId.setText(userName);
mKeyUserIdRest.setText(userEmail);
+ mKeyMasterKeyIdHex.setVisibility(View.VISIBLE);
mKeyUserId.setVisibility(View.VISIBLE);
mKeyUserIdRest.setVisibility(View.VISIBLE);
+ mNoKeySelected.setVisibility(View.GONE);
} else {
- mKeyMasterKeyIdHex.setText(getActivity().getResources().getString(R.string.no_key));
+ mKeyMasterKeyIdHex.setVisibility(View.GONE);
mKeyUserId.setVisibility(View.GONE);
mKeyUserIdRest.setVisibility(View.GONE);
+ mNoKeySelected.setVisibility(View.VISIBLE);
}
} else {
mKeyMasterKeyIdHex.setText(
getActivity().getResources()
.getString(R.string.no_keys_added_or_updated)
+ " for master id: " + secretKeyId);
+ mKeyMasterKeyIdHex.setVisibility(View.VISIBLE);
mKeyUserId.setVisibility(View.GONE);
mKeyUserIdRest.setVisibility(View.GONE);
+ mNoKeySelected.setVisibility(View.GONE);
}
}
@@ -124,6 +130,7 @@ public class SelectSecretKeyLayoutFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.select_secret_key_layout_fragment, container, false);
+ mNoKeySelected = (TextView) view.findViewById(R.id.no_key_selected);
mKeyUserId = (TextView) view.findViewById(R.id.select_secret_key_user_id);
mKeyUserIdRest = (TextView) view.findViewById(R.id.select_secret_key_user_id_rest);
mKeyMasterKeyIdHex = (TextView) view.findViewById(R.id.select_secret_key_master_key_hex);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
index eeb17fea2..a828a4405 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
@@ -26,10 +26,7 @@ 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.text.Spannable;
-import android.text.SpannableStringBuilder;
import android.text.format.DateFormat;
-import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -65,6 +62,7 @@ public class ViewKeyMainFragment extends Fragment implements
private TextView mSecretKey;
private BootstrapButton mActionEdit;
private BootstrapButton mActionEncrypt;
+ private BootstrapButton mActionCertify;
private ListView mUserIds;
private ListView mKeys;
@@ -95,6 +93,7 @@ public class ViewKeyMainFragment extends Fragment implements
mKeys = (ListView) view.findViewById(R.id.keys);
mActionEdit = (BootstrapButton) view.findViewById(R.id.action_edit);
mActionEncrypt = (BootstrapButton) view.findViewById(R.id.action_encrypt);
+ mActionCertify = (BootstrapButton) view.findViewById(R.id.action_certify);
return view;
}
@@ -131,6 +130,11 @@ public class ViewKeyMainFragment extends Fragment implements
mSecretKey.setTextColor(getResources().getColor(R.color.emphasis));
mSecretKey.setText(R.string.secret_key_yes);
+ // certify button
+ // TODO this button MIGHT be useful if the user wants to
+ // certify a private key with another...
+ // mActionCertify.setVisibility(View.GONE);
+
// edit button
mActionEdit.setVisibility(View.VISIBLE);
mActionEdit.setOnClickListener(new View.OnClickListener() {
@@ -147,8 +151,22 @@ public class ViewKeyMainFragment extends Fragment implements
} else {
mSecretKey.setTextColor(Color.BLACK);
mSecretKey.setText(getResources().getString(R.string.secret_key_no));
+
+ // certify button
+ mActionCertify.setVisibility(View.VISIBLE);
+ // edit button
mActionEdit.setVisibility(View.GONE);
}
+
+ // TODO see todo note above, doing this here for now
+ mActionCertify.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View view) {
+ certifyKey(KeychainContract.KeyRings.buildPublicKeyRingsByMasterKeyIdUri(
+ Long.toString(masterKeyId)
+ ));
+ }
+ });
+
}
mActionEncrypt.setOnClickListener(new View.OnClickListener() {
@@ -180,12 +198,13 @@ public class ViewKeyMainFragment extends Fragment implements
static final int KEYRING_INDEX_USER_ID = 2;
static final String[] USER_IDS_PROJECTION =
- new String[]{KeychainContract.UserIds._ID, KeychainContract.UserIds.USER_ID,
- KeychainContract.UserIds.RANK, };
- // not the main user id
- static final String USER_IDS_SELECTION = KeychainContract.UserIds.RANK + " > 0 ";
+ new String[]{
+ KeychainContract.UserIds._ID,
+ KeychainContract.UserIds.USER_ID,
+ KeychainContract.UserIds.RANK,
+ };
static final String USER_IDS_SORT_ORDER =
- KeychainContract.UserIds.USER_ID + " COLLATE LOCALIZED ASC";
+ KeychainContract.UserIds.RANK + " COLLATE LOCALIZED ASC";
static final String[] KEYS_PROJECTION =
new String[]{KeychainContract.Keys._ID, KeychainContract.Keys.KEY_ID,
@@ -221,7 +240,7 @@ public class ViewKeyMainFragment extends Fragment implements
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
- return new CursorLoader(getActivity(), baseUri, USER_IDS_PROJECTION, USER_IDS_SELECTION, null,
+ return new CursorLoader(getActivity(), baseUri, USER_IDS_PROJECTION, null, null,
USER_IDS_SORT_ORDER);
}
case LOADER_ID_KEYS: {
@@ -303,7 +322,7 @@ public class ViewKeyMainFragment extends Fragment implements
}
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true);
- mFingerprint.setText(colorizeFingerprint(fingerprint));
+ mFingerprint.setText(OtherHelper.colorizeFingerprint(fingerprint));
}
mKeysAdapter.swapCursor(data);
@@ -314,63 +333,6 @@ public class ViewKeyMainFragment extends Fragment implements
}
}
- private SpannableStringBuilder colorizeFingerprint(String fingerprint) {
- SpannableStringBuilder sb = new SpannableStringBuilder(fingerprint);
- try {
- // for each 4 characters of the fingerprint + 1 space
- for (int i = 0; i < fingerprint.length(); i += 5) {
- int spanEnd = Math.min(i + 4, fingerprint.length());
- String fourChars = fingerprint.substring(i, spanEnd);
-
- int raw = Integer.parseInt(fourChars, 16);
- byte[] bytes = {(byte) ((raw >> 8) & 0xff - 128), (byte) (raw & 0xff - 128)};
- int[] color = OtherHelper.getRgbForData(bytes);
- int r = color[0];
- int g = color[1];
- int b = color[2];
-
- // we cannot change black by multiplication, so adjust it to an almost-black grey,
- // which will then be brightened to the minimal brightness level
- if (r == 0 && g == 0 && b == 0) {
- r = 1;
- g = 1;
- b = 1;
- }
-
- // Convert rgb to brightness
- double brightness = 0.2126 * r + 0.7152 * g + 0.0722 * b;
-
- // If a color is too dark to be seen on black,
- // then brighten it up to a minimal brightness.
- if (brightness < 80) {
- double factor = 80.0 / brightness;
- r = Math.min(255, (int) (r * factor));
- g = Math.min(255, (int) (g * factor));
- b = Math.min(255, (int) (b * factor));
-
- // If it is too light, then darken it to a respective maximal brightness.
- } else if (brightness > 180) {
- double factor = 180.0 / brightness;
- r = (int) (r * factor);
- g = (int) (g * factor);
- b = (int) (b * factor);
- }
-
- // Create a foreground color with the 3 digest integers as RGB
- // and then converting that int to hex to use as a color
- sb.setSpan(new ForegroundColorSpan(Color.rgb(r, g, b)),
- i, spanEnd, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
- }
- } catch (Exception e) {
- Log.e(Constants.TAG, "Colorization failed", e);
- // if anything goes wrong, then just display the fingerprint without colour,
- // instead of partially correct colour or wrong colours
- return new SpannableStringBuilder(fingerprint);
- }
-
- return sb;
- }
-
/**
* This is called when the last Cursor provided to onLoadFinished() above is about to be closed.
* We need to make sure we are no longer using it.
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java
index 3ba291c3d..61572b9ce 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java
@@ -23,26 +23,48 @@ import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
import android.widget.TextView;
import org.sufficientlysecure.keychain.R;
+import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
+import java.util.ArrayList;
+
public class ViewKeyUserIdsAdapter extends CursorAdapter {
private LayoutInflater mInflater;
- private int mIndexUserId;
+ private int mIndexUserId, mIndexRank;
- public ViewKeyUserIdsAdapter(Context context, Cursor c, int flags) {
+ final private ArrayList<Boolean> mCheckStates;
+
+ public ViewKeyUserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes) {
super(context, c, flags);
mInflater = LayoutInflater.from(context);
+ mCheckStates = showCheckBoxes ? new ArrayList<Boolean>() : null;
+
initIndex(c);
}
+ public ViewKeyUserIdsAdapter(Context context, Cursor c, int flags) {
+ this(context, c, flags, false);
+ }
@Override
public Cursor swapCursor(Cursor newCursor) {
initIndex(newCursor);
+ if(mCheckStates != null) {
+ mCheckStates.clear();
+ if(newCursor != null) {
+ int count = newCursor.getCount();
+ mCheckStates.ensureCapacity(count);
+ // initialize to true (use case knowledge: we usually want to sign all uids)
+ for(int i = 0; i < count; i++)
+ mCheckStates.add(true);
+ }
+ }
return super.swapCursor(newCursor);
}
@@ -56,20 +78,67 @@ public class ViewKeyUserIdsAdapter extends CursorAdapter {
private void initIndex(Cursor cursor) {
if (cursor != null) {
mIndexUserId = cursor.getColumnIndexOrThrow(UserIds.USER_ID);
+ mIndexRank = cursor.getColumnIndexOrThrow(UserIds.RANK);
}
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
- String userIdStr = cursor.getString(mIndexUserId);
- TextView userId = (TextView) view.findViewById(R.id.userId);
- userId.setText(userIdStr);
+ TextView vRank = (TextView) view.findViewById(R.id.rank);
+ TextView vUserId = (TextView) view.findViewById(R.id.userId);
+ TextView vAddress = (TextView) view.findViewById(R.id.address);
+
+ vRank.setText(Integer.toString(cursor.getInt(mIndexRank)));
+
+ String[] userId = PgpKeyHelper.splitUserId(cursor.getString(mIndexUserId));
+ if (userId[0] != null) {
+ vUserId.setText(userId[0]);
+ } else {
+ vUserId.setText(R.string.user_id_no_name);
+ }
+ vAddress.setText(userId[1]);
+
+ // don't care further if checkboxes aren't shown
+ if(mCheckStates == null)
+ return;
+
+ final CheckBox vCheckBox = (CheckBox) view.findViewById(R.id.checkBox);
+ final int position = cursor.getPosition();
+ vCheckBox.setClickable(false);
+ vCheckBox.setChecked(mCheckStates.get(position));
+ vCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
+ mCheckStates.set(position, b);
+ }
+ });
+ view.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ vCheckBox.toggle();
+ }
+ });
+
+ }
+
+ public ArrayList<String> getSelectedUserIds() {
+ ArrayList<String> result = new ArrayList<String>();
+ for(int i = 0; i < mCheckStates.size(); i++) {
+ if(mCheckStates.get(i)) {
+ mCursor.moveToPosition(i);
+ result.add(mCursor.getString(mIndexUserId));
+ }
+ }
+ return result;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
- return mInflater.inflate(R.layout.view_key_userids_item, null);
+ View view = mInflater.inflate(R.layout.view_key_userids_item, null);
+ // only need to do this once ever, since mShowCheckBoxes is final
+ view.findViewById(R.id.checkBox).setVisibility(mCheckStates != null ? View.VISIBLE : View.GONE);
+ return view;
}
}