From 106e1fcf0344ddf98f65b7c7adc706da19faef7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 22 Jun 2014 16:03:03 +0200 Subject: Rename adapter --- .../keychain/ui/CertifyKeyActivity.java | 8 +- .../keychain/ui/EditKeyFragment.java | 17 +- .../keychain/ui/ViewKeyKeysFragment.java | 8 +- .../keychain/ui/ViewKeyMainFragment.java | 8 +- .../keychain/ui/adapter/SubkeysAdapter.java | 211 ++++++++++++++++++ .../keychain/ui/adapter/UserIdsAdapter.java | 244 +++++++++++++++++++++ .../keychain/ui/adapter/ViewKeyKeysAdapter.java | 211 ------------------ .../keychain/ui/adapter/ViewKeyUserIdsAdapter.java | 233 -------------------- 8 files changed, 475 insertions(+), 465 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java (limited to 'OpenKeychain/src/main') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java index 6c74818a5..db00d5f69 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java @@ -53,7 +53,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; 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.adapter.UserIdsAdapter; import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment; import org.sufficientlysecure.keychain.util.Log; @@ -75,7 +75,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements private long mMasterKeyId = 0; private ListView mUserIds; - private ViewKeyUserIdsAdapter mUserIdsAdapter; + private UserIdsAdapter mUserIdsAdapter; private static final int LOADER_ID_KEYRING = 0; private static final int LOADER_ID_USER_IDS = 1; @@ -143,7 +143,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements mUserIds = (ListView) findViewById(R.id.view_key_user_ids); - mUserIdsAdapter = new ViewKeyUserIdsAdapter(this, null, 0, true); + mUserIdsAdapter = new UserIdsAdapter(this, null, 0, true); mUserIds.setAdapter(mUserIdsAdapter); mUserIds.setOnItemClickListener(mUserIdsAdapter); @@ -175,7 +175,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements case LOADER_ID_USER_IDS: { Uri uri = UserIds.buildUserIdsUri(mDataUri); return new CursorLoader(this, uri, - ViewKeyUserIdsAdapter.USER_IDS_PROJECTION, USER_IDS_SELECTION, null, null); + UserIdsAdapter.USER_IDS_PROJECTION, USER_IDS_SELECTION, null, null); } } return null; 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 9231ce142..b3516f5d6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -34,9 +34,8 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.helper.ActionBarHelper; import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; -import org.sufficientlysecure.keychain.ui.adapter.ViewKeyKeysAdapter; -import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter; +import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter; +import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter; import org.sufficientlysecure.keychain.util.Log; public class EditKeyFragment extends LoaderFragment implements @@ -50,8 +49,8 @@ public class EditKeyFragment extends LoaderFragment implements private static final int LOADER_ID_USER_IDS = 0; private static final int LOADER_ID_KEYS = 1; - private ViewKeyUserIdsAdapter mUserIdsAdapter; - private ViewKeyKeysAdapter mKeysAdapter; + private UserIdsAdapter mUserIdsAdapter; + private SubkeysAdapter mKeysAdapter; private Uri mDataUri; @@ -128,9 +127,9 @@ public class EditKeyFragment extends LoaderFragment implements // }); - mUserIdsAdapter = new ViewKeyUserIdsAdapter(getActivity(), null, 0); + mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0); mUserIds.setAdapter(mUserIdsAdapter); - mKeysAdapter = new ViewKeyKeysAdapter(getActivity(), null, 0); + mKeysAdapter = new SubkeysAdapter(getActivity(), null, 0); mKeys.setAdapter(mKeysAdapter); // Prepare the loaders. Either re-connect with an existing ones, @@ -146,13 +145,13 @@ public class EditKeyFragment extends LoaderFragment implements case LOADER_ID_USER_IDS: { Uri baseUri = KeychainContract.UserIds.buildUserIdsUri(mDataUri); return new CursorLoader(getActivity(), baseUri, - ViewKeyUserIdsAdapter.USER_IDS_PROJECTION, null, null, null); + UserIdsAdapter.USER_IDS_PROJECTION, null, null, null); } case LOADER_ID_KEYS: { Uri baseUri = KeychainContract.Keys.buildKeysUri(mDataUri); return new CursorLoader(getActivity(), baseUri, - ViewKeyKeysAdapter.KEYS_PROJECTION, null, null, null); + SubkeysAdapter.KEYS_PROJECTION, null, null, null); } default: diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyKeysFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyKeysFragment.java index e01a0140c..4be572b4e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyKeysFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyKeysFragment.java @@ -31,7 +31,7 @@ import android.widget.ListView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; -import org.sufficientlysecure.keychain.ui.adapter.ViewKeyKeysAdapter; +import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter; import org.sufficientlysecure.keychain.util.Log; @@ -42,7 +42,7 @@ public class ViewKeyKeysFragment extends LoaderFragment implements private ListView mKeys; - private ViewKeyKeysAdapter mKeysAdapter; + private SubkeysAdapter mKeysAdapter; private Uri mDataUri; @@ -75,7 +75,7 @@ public class ViewKeyKeysFragment extends LoaderFragment implements Log.i(Constants.TAG, "mDataUri: " + mDataUri.toString()); - mKeysAdapter = new ViewKeyKeysAdapter(getActivity(), null, 0); + mKeysAdapter = new SubkeysAdapter(getActivity(), null, 0); mKeys.setAdapter(mKeysAdapter); // Prepare the loaders. Either re-connect with an existing ones, @@ -87,7 +87,7 @@ public class ViewKeyKeysFragment extends LoaderFragment implements setContentShown(false); Uri baseUri = Keys.buildKeysUri(mDataUri); return new CursorLoader(getActivity(), baseUri, - ViewKeyKeysAdapter.KEYS_PROJECTION, null, null, null); + SubkeysAdapter.KEYS_PROJECTION, null, null, null); } public void onLoadFinished(Loader loader, Cursor data) { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java index bd29f3820..dd48f193c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java @@ -38,7 +38,7 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; import org.sufficientlysecure.keychain.provider.ProviderHelper; -import org.sufficientlysecure.keychain.ui.adapter.ViewKeyUserIdsAdapter; +import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter; import org.sufficientlysecure.keychain.util.Log; import java.util.Date; @@ -63,7 +63,7 @@ public class ViewKeyMainFragment extends LoaderFragment implements // conservative attitude private boolean mHasEncrypt = true; - private ViewKeyUserIdsAdapter mUserIdsAdapter; + private UserIdsAdapter mUserIdsAdapter; private Uri mDataUri; @@ -124,7 +124,7 @@ public class ViewKeyMainFragment extends LoaderFragment implements } }); - mUserIdsAdapter = new ViewKeyUserIdsAdapter(getActivity(), null, 0); + mUserIdsAdapter = new UserIdsAdapter(getActivity(), null, 0); mUserIds.setAdapter(mUserIdsAdapter); // Prepare the loaders. Either re-connect with an existing ones, @@ -154,7 +154,7 @@ public class ViewKeyMainFragment extends LoaderFragment implements case LOADER_ID_USER_IDS: { Uri baseUri = UserIds.buildUserIdsUri(mDataUri); return new CursorLoader(getActivity(), baseUri, - ViewKeyUserIdsAdapter.USER_IDS_PROJECTION, null, null, null); + UserIdsAdapter.USER_IDS_PROJECTION, null, null, null); } default: 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 new file mode 100644 index 000000000..6d8455589 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.ui.adapter; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.database.Cursor; +import android.support.v4.widget.CursorAdapter; +import android.text.format.DateFormat; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.OtherHelper; +import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; +import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; + +import java.util.Date; + +public class SubkeysAdapter extends CursorAdapter { + private LayoutInflater mInflater; + + private int mIndexKeyId; + private int mIndexAlgorithm; + private int mIndexKeySize; + private int mIndexRank; + private int mIndexCanCertify; + private int mIndexCanEncrypt; + private int mIndexCanSign; + private int mIndexHasSecret; + private int mIndexRevokedKey; + private int mIndexExpiry; + + private boolean hasAnySecret; + + private ColorStateList mDefaultTextColor; + + public static final String[] KEYS_PROJECTION = new String[] { + Keys._ID, + Keys.KEY_ID, + Keys.RANK, + Keys.ALGORITHM, + Keys.KEY_SIZE, + Keys.HAS_SECRET, + Keys.CAN_CERTIFY, + Keys.CAN_ENCRYPT, + Keys.CAN_SIGN, + Keys.IS_REVOKED, + Keys.CREATION, + Keys.EXPIRY, + Keys.FINGERPRINT + }; + + public SubkeysAdapter(Context context, Cursor c, int flags) { + super(context, c, flags); + + mInflater = LayoutInflater.from(context); + + initIndex(c); + } + + @Override + public Cursor swapCursor(Cursor newCursor) { + initIndex(newCursor); + + hasAnySecret = false; + if (newCursor != null) { + newCursor.moveToFirst(); + do { + if (newCursor.getInt(mIndexHasSecret) != 0) { + hasAnySecret = true; + break; + } + } while (newCursor.moveToNext()); + } + + return super.swapCursor(newCursor); + } + + /** + * Get column indexes for performance reasons just once in constructor and swapCursor. For a + * performance comparison see http://stackoverflow.com/a/17999582 + * + * @param cursor + */ + private void initIndex(Cursor cursor) { + if (cursor != null) { + mIndexKeyId = cursor.getColumnIndexOrThrow(Keys.KEY_ID); + mIndexAlgorithm = cursor.getColumnIndexOrThrow(Keys.ALGORITHM); + mIndexKeySize = cursor.getColumnIndexOrThrow(Keys.KEY_SIZE); + mIndexRank = cursor.getColumnIndexOrThrow(Keys.RANK); + mIndexCanCertify = cursor.getColumnIndexOrThrow(Keys.CAN_CERTIFY); + mIndexCanEncrypt = cursor.getColumnIndexOrThrow(Keys.CAN_ENCRYPT); + mIndexCanSign = cursor.getColumnIndexOrThrow(Keys.CAN_SIGN); + mIndexHasSecret = cursor.getColumnIndexOrThrow(Keys.HAS_SECRET); + mIndexRevokedKey = cursor.getColumnIndexOrThrow(Keys.IS_REVOKED); + mIndexExpiry = cursor.getColumnIndexOrThrow(Keys.EXPIRY); + } + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + TextView keyId = (TextView) view.findViewById(R.id.keyId); + TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails); + TextView keyExpiry = (TextView) view.findViewById(R.id.keyExpiry); + ImageView masterKeyIcon = (ImageView) view.findViewById(R.id.ic_masterKey); + ImageView certifyIcon = (ImageView) view.findViewById(R.id.ic_certifyKey); + ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey); + ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey); + ImageView revokedKeyIcon = (ImageView) view.findViewById(R.id.ic_revokedKey); + + String keyIdStr = PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexKeyId)); + String algorithmStr = PgpKeyHelper.getAlgorithmInfo( + context, + cursor.getInt(mIndexAlgorithm), + cursor.getInt(mIndexKeySize) + ); + + keyId.setText(keyIdStr); + // may be set with additional "stripped" later on + if (hasAnySecret && cursor.getInt(mIndexHasSecret) == 0) { + keyDetails.setText(algorithmStr + ", " + + context.getString(R.string.key_stripped)); + } else { + keyDetails.setText(algorithmStr); + } + + // Set icons according to properties + masterKeyIcon.setVisibility(cursor.getInt(mIndexRank) == 0 ? View.VISIBLE : View.INVISIBLE); + certifyIcon.setVisibility(cursor.getInt(mIndexCanCertify) != 0 ? View.VISIBLE : View.GONE); + encryptIcon.setVisibility(cursor.getInt(mIndexCanEncrypt) != 0 ? View.VISIBLE : View.GONE); + signIcon.setVisibility(cursor.getInt(mIndexCanSign) != 0 ? View.VISIBLE : View.GONE); + + boolean valid = true; + if (cursor.getInt(mIndexRevokedKey) > 0) { + revokedKeyIcon.setVisibility(View.VISIBLE); + + valid = false; + } else { + keyId.setTextColor(mDefaultTextColor); + keyDetails.setTextColor(mDefaultTextColor); + keyExpiry.setTextColor(mDefaultTextColor); + + revokedKeyIcon.setVisibility(View.GONE); + } + + if (!cursor.isNull(mIndexExpiry)) { + Date expiryDate = new Date(cursor.getLong(mIndexExpiry) * 1000); + + valid = valid && expiryDate.after(new Date()); + keyExpiry.setText( + context.getString(R.string.label_expiry) + ": " + + DateFormat.getDateFormat(context).format(expiryDate)); + } else { + keyExpiry.setText( + context.getString(R.string.label_expiry) + ": " + + context.getString(R.string.none)); + } + + // if key is expired or revoked, strike through text + if (!valid) { + keyId.setText(OtherHelper.strikeOutText(keyId.getText())); + keyDetails.setText(OtherHelper.strikeOutText(keyDetails.getText())); + keyExpiry.setText(OtherHelper.strikeOutText(keyExpiry.getText())); + } + keyId.setEnabled(valid); + keyDetails.setEnabled(valid); + keyExpiry.setEnabled(valid); + } + + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + View view = mInflater.inflate(R.layout.view_key_keys_item, null); + if (mDefaultTextColor == null) { + TextView keyId = (TextView) view.findViewById(R.id.keyId); + mDefaultTextColor = keyId.getTextColors(); + } + return view; + } + + // Disable selection of items, http://stackoverflow.com/a/4075045 + @Override + public boolean areAllItemsEnabled() { + return false; + } + + // Disable selection of items, http://stackoverflow.com/a/4075045 + @Override + public boolean isEnabled(int position) { + return false; + } + +} 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 new file mode 100644 index 000000000..77da1d0e3 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/UserIdsAdapter.java @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.sufficientlysecure.keychain.ui.adapter; + +import android.content.Context; +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.AdapterView; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.ImageView; +import android.widget.TextView; + +import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.helper.OtherHelper; +import org.sufficientlysecure.keychain.pgp.KeyRing; +import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; +import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; +import org.sufficientlysecure.keychain.service.SaveKeyringParcel; + +import java.util.ArrayList; + +public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemClickListener { + private LayoutInflater mInflater; + + private int mIndexUserId, mIndexRank; + private int mVerifiedId, mIsRevoked, mIsPrimary; + + private final ArrayList mCheckStates; + + private SaveKeyringParcel mSaveKeyringParcel; + + public static final String[] USER_IDS_PROJECTION = new String[]{ + UserIds._ID, + UserIds.USER_ID, + UserIds.RANK, + UserIds.VERIFIED, + UserIds.IS_PRIMARY, + UserIds.IS_REVOKED + }; + + public UserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes, + SaveKeyringParcel saveKeyringParcel) { + super(context, c, flags); + mInflater = LayoutInflater.from(context); + + mCheckStates = showCheckBoxes ? new ArrayList() : null; + mSaveKeyringParcel = saveKeyringParcel; + + initIndex(c); + } + + public UserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes) { + this(context, c, flags, showCheckBoxes, null); + } + + public UserIdsAdapter(Context context, Cursor c, int flags, SaveKeyringParcel saveKeyringParcel) { + this(context, c, flags, false, saveKeyringParcel); + } + + public UserIdsAdapter(Context context, Cursor c, int flags) { + this(context, c, flags, false, null); + } + + @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++) { + newCursor.moveToPosition(i); + int verified = newCursor.getInt(mVerifiedId); + mCheckStates.add(verified != Certs.VERIFIED_SECRET); + } + } + } + + return super.swapCursor(newCursor); + } + + /** + * Get column indexes for performance reasons just once in constructor and swapCursor. For a + * performance comparison see http://stackoverflow.com/a/17999582 + * + * @param cursor + */ + private void initIndex(Cursor cursor) { + if (cursor != null) { + mIndexUserId = cursor.getColumnIndexOrThrow(UserIds.USER_ID); + mIndexRank = cursor.getColumnIndexOrThrow(UserIds.RANK); + mVerifiedId = cursor.getColumnIndexOrThrow(UserIds.VERIFIED); + mIsRevoked = cursor.getColumnIndexOrThrow(UserIds.IS_REVOKED); + mIsPrimary = cursor.getColumnIndexOrThrow(UserIds.IS_PRIMARY); + } + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + TextView vName = (TextView) view.findViewById(R.id.userId); + TextView vAddress = (TextView) view.findViewById(R.id.address); + TextView vComment = (TextView) view.findViewById(R.id.comment); + ImageView vVerified = (ImageView) view.findViewById(R.id.certified); + + String[] userId = KeyRing.splitUserId(cursor.getString(mIndexUserId)); + if (userId[0] != null) { + vName.setText(userId[0]); + } else { + vName.setText(R.string.user_id_no_name); + } + if (userId[1] != null) { + vAddress.setText(userId[1]); + vAddress.setVisibility(View.VISIBLE); + } else { + vAddress.setVisibility(View.GONE); + } + if (userId[2] != null) { + vComment.setText(userId[2]); + vComment.setVisibility(View.VISIBLE); + } else { + vComment.setVisibility(View.GONE); + } + + // show small star icon for primary user ids + boolean isPrimary = cursor.getInt(mIsPrimary) != 0; + + if (cursor.getInt(mIsRevoked) > 0) { + + // set revocation icon (can this even be primary?) + vVerified.setImageResource(R.drawable.key_certify_revoke); + + // disable and strike through text for revoked user ids + vName.setEnabled(false); + vAddress.setEnabled(false); + vName.setText(OtherHelper.strikeOutText(vName.getText())); + vAddress.setText(OtherHelper.strikeOutText(vAddress.getText())); + } else { + vName.setEnabled(true); + vAddress.setEnabled(true); + + int verified = cursor.getInt(mVerifiedId); + switch (verified) { + case Certs.VERIFIED_SECRET: + vVerified.setImageResource(isPrimary + ? R.drawable.key_certify_primary_ok_depth0 + : R.drawable.key_certify_ok_depth0); + break; + case Certs.VERIFIED_SELF: + vVerified.setImageResource(isPrimary + ? R.drawable.key_certify_primary_ok_self + : R.drawable.key_certify_ok_self); + break; + default: + vVerified.setImageResource(R.drawable.key_certify_error); + break; + } + } + + // 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.setOnCheckedChangeListener(null); + vCheckBox.setChecked(mCheckStates.get(position)); + vCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + mCheckStates.set(position, b); + } + }); + vCheckBox.setClickable(false); + } + + public void onItemClick(AdapterView adapter, View view, int position, long id) { + CheckBox box = ((CheckBox) view.findViewById(R.id.checkBox)); + if (box != null) { + box.toggle(); + } + } + + public ArrayList getSelectedUserIds() { + ArrayList result = new ArrayList(); + 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) { + 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; + } + + // Disable selection of items for lists without checkboxes, http://stackoverflow.com/a/4075045 + @Override + public boolean areAllItemsEnabled() { + if (mCheckStates == null) { + return false; + } else { + return super.areAllItemsEnabled(); + } + } + + // Disable selection of items for lists without checkboxes, http://stackoverflow.com/a/4075045 + @Override + public boolean isEnabled(int position) { + if (mCheckStates == null) { + return false; + } else { + return super.isEnabled(position); + } + } + +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java deleted file mode 100644 index dae287bbc..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.sufficientlysecure.keychain.ui.adapter; - -import android.content.Context; -import android.content.res.ColorStateList; -import android.database.Cursor; -import android.support.v4.widget.CursorAdapter; -import android.text.format.DateFormat; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; - -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.helper.OtherHelper; -import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; -import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; - -import java.util.Date; - -public class ViewKeyKeysAdapter extends CursorAdapter { - private LayoutInflater mInflater; - - private int mIndexKeyId; - private int mIndexAlgorithm; - private int mIndexKeySize; - private int mIndexRank; - private int mIndexCanCertify; - private int mIndexCanEncrypt; - private int mIndexCanSign; - private int mIndexHasSecret; - private int mIndexRevokedKey; - private int mIndexExpiry; - - private boolean hasAnySecret; - - private ColorStateList mDefaultTextColor; - - public static final String[] KEYS_PROJECTION = new String[] { - Keys._ID, - Keys.KEY_ID, - Keys.RANK, - Keys.ALGORITHM, - Keys.KEY_SIZE, - Keys.HAS_SECRET, - Keys.CAN_CERTIFY, - Keys.CAN_ENCRYPT, - Keys.CAN_SIGN, - Keys.IS_REVOKED, - Keys.CREATION, - Keys.EXPIRY, - Keys.FINGERPRINT - }; - - public ViewKeyKeysAdapter(Context context, Cursor c, int flags) { - super(context, c, flags); - - mInflater = LayoutInflater.from(context); - - initIndex(c); - } - - @Override - public Cursor swapCursor(Cursor newCursor) { - initIndex(newCursor); - - hasAnySecret = false; - if (newCursor != null) { - newCursor.moveToFirst(); - do { - if (newCursor.getInt(mIndexHasSecret) != 0) { - hasAnySecret = true; - break; - } - } while (newCursor.moveToNext()); - } - - return super.swapCursor(newCursor); - } - - /** - * Get column indexes for performance reasons just once in constructor and swapCursor. For a - * performance comparison see http://stackoverflow.com/a/17999582 - * - * @param cursor - */ - private void initIndex(Cursor cursor) { - if (cursor != null) { - mIndexKeyId = cursor.getColumnIndexOrThrow(Keys.KEY_ID); - mIndexAlgorithm = cursor.getColumnIndexOrThrow(Keys.ALGORITHM); - mIndexKeySize = cursor.getColumnIndexOrThrow(Keys.KEY_SIZE); - mIndexRank = cursor.getColumnIndexOrThrow(Keys.RANK); - mIndexCanCertify = cursor.getColumnIndexOrThrow(Keys.CAN_CERTIFY); - mIndexCanEncrypt = cursor.getColumnIndexOrThrow(Keys.CAN_ENCRYPT); - mIndexCanSign = cursor.getColumnIndexOrThrow(Keys.CAN_SIGN); - mIndexHasSecret = cursor.getColumnIndexOrThrow(Keys.HAS_SECRET); - mIndexRevokedKey = cursor.getColumnIndexOrThrow(Keys.IS_REVOKED); - mIndexExpiry = cursor.getColumnIndexOrThrow(Keys.EXPIRY); - } - } - - @Override - public void bindView(View view, Context context, Cursor cursor) { - TextView keyId = (TextView) view.findViewById(R.id.keyId); - TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails); - TextView keyExpiry = (TextView) view.findViewById(R.id.keyExpiry); - ImageView masterKeyIcon = (ImageView) view.findViewById(R.id.ic_masterKey); - ImageView certifyIcon = (ImageView) view.findViewById(R.id.ic_certifyKey); - ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey); - ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey); - ImageView revokedKeyIcon = (ImageView) view.findViewById(R.id.ic_revokedKey); - - String keyIdStr = PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexKeyId)); - String algorithmStr = PgpKeyHelper.getAlgorithmInfo( - context, - cursor.getInt(mIndexAlgorithm), - cursor.getInt(mIndexKeySize) - ); - - keyId.setText(keyIdStr); - // may be set with additional "stripped" later on - if (hasAnySecret && cursor.getInt(mIndexHasSecret) == 0) { - keyDetails.setText(algorithmStr + ", " + - context.getString(R.string.key_stripped)); - } else { - keyDetails.setText(algorithmStr); - } - - // Set icons according to properties - masterKeyIcon.setVisibility(cursor.getInt(mIndexRank) == 0 ? View.VISIBLE : View.INVISIBLE); - certifyIcon.setVisibility(cursor.getInt(mIndexCanCertify) != 0 ? View.VISIBLE : View.GONE); - encryptIcon.setVisibility(cursor.getInt(mIndexCanEncrypt) != 0 ? View.VISIBLE : View.GONE); - signIcon.setVisibility(cursor.getInt(mIndexCanSign) != 0 ? View.VISIBLE : View.GONE); - - boolean valid = true; - if (cursor.getInt(mIndexRevokedKey) > 0) { - revokedKeyIcon.setVisibility(View.VISIBLE); - - valid = false; - } else { - keyId.setTextColor(mDefaultTextColor); - keyDetails.setTextColor(mDefaultTextColor); - keyExpiry.setTextColor(mDefaultTextColor); - - revokedKeyIcon.setVisibility(View.GONE); - } - - if (!cursor.isNull(mIndexExpiry)) { - Date expiryDate = new Date(cursor.getLong(mIndexExpiry) * 1000); - - valid = valid && expiryDate.after(new Date()); - keyExpiry.setText( - context.getString(R.string.label_expiry) + ": " + - DateFormat.getDateFormat(context).format(expiryDate)); - } else { - keyExpiry.setText( - context.getString(R.string.label_expiry) + ": " + - context.getString(R.string.none)); - } - - // if key is expired or revoked, strike through text - if (!valid) { - keyId.setText(OtherHelper.strikeOutText(keyId.getText())); - keyDetails.setText(OtherHelper.strikeOutText(keyDetails.getText())); - keyExpiry.setText(OtherHelper.strikeOutText(keyExpiry.getText())); - } - keyId.setEnabled(valid); - keyDetails.setEnabled(valid); - keyExpiry.setEnabled(valid); - } - - @Override - public View newView(Context context, Cursor cursor, ViewGroup parent) { - View view = mInflater.inflate(R.layout.view_key_keys_item, null); - if (mDefaultTextColor == null) { - TextView keyId = (TextView) view.findViewById(R.id.keyId); - mDefaultTextColor = keyId.getTextColors(); - } - return view; - } - - // Disable selection of items, http://stackoverflow.com/a/4075045 - @Override - public boolean areAllItemsEnabled() { - return false; - } - - // Disable selection of items, http://stackoverflow.com/a/4075045 - @Override - public boolean isEnabled(int position) { - return false; - } - -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java deleted file mode 100644 index 763752edc..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (C) 2014 Dominik Schürmann - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.sufficientlysecure.keychain.ui.adapter; - -import android.content.Context; -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.AdapterView; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.ImageView; -import android.widget.TextView; - -import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.helper.OtherHelper; -import org.sufficientlysecure.keychain.pgp.KeyRing; -import org.sufficientlysecure.keychain.provider.KeychainContract.Certs; -import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds; - -import java.util.ArrayList; - -public class ViewKeyUserIdsAdapter extends CursorAdapter implements AdapterView.OnItemClickListener { - private LayoutInflater mInflater; - - private int mIndexUserId, mIndexRank; - private int mVerifiedId, mIsRevoked, mIsPrimary; - - private final ArrayList mCheckStates; - - public static final String[] USER_IDS_PROJECTION = new String[]{ - UserIds._ID, - UserIds.USER_ID, - UserIds.RANK, - UserIds.VERIFIED, - UserIds.IS_PRIMARY, - UserIds.IS_REVOKED - }; - - public ViewKeyUserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes) { - super(context, c, flags); - - mInflater = LayoutInflater.from(context); - - mCheckStates = showCheckBoxes ? new ArrayList() : 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++) { - newCursor.moveToPosition(i); - int verified = newCursor.getInt(mVerifiedId); - mCheckStates.add(verified != Certs.VERIFIED_SECRET); - } - } - } - - return super.swapCursor(newCursor); - } - - /** - * Get column indexes for performance reasons just once in constructor and swapCursor. For a - * performance comparison see http://stackoverflow.com/a/17999582 - * - * @param cursor - */ - private void initIndex(Cursor cursor) { - if (cursor != null) { - mIndexUserId = cursor.getColumnIndexOrThrow(UserIds.USER_ID); - mIndexRank = cursor.getColumnIndexOrThrow(UserIds.RANK); - mVerifiedId = cursor.getColumnIndexOrThrow(UserIds.VERIFIED); - mIsRevoked = cursor.getColumnIndexOrThrow(UserIds.IS_REVOKED); - mIsPrimary = cursor.getColumnIndexOrThrow(UserIds.IS_PRIMARY); - } - } - - @Override - public void bindView(View view, Context context, Cursor cursor) { - TextView vName = (TextView) view.findViewById(R.id.userId); - TextView vAddress = (TextView) view.findViewById(R.id.address); - TextView vComment = (TextView) view.findViewById(R.id.comment); - ImageView vVerified = (ImageView) view.findViewById(R.id.certified); - - String[] userId = KeyRing.splitUserId(cursor.getString(mIndexUserId)); - if (userId[0] != null) { - vName.setText(userId[0]); - } else { - vName.setText(R.string.user_id_no_name); - } - if (userId[1] != null) { - vAddress.setText(userId[1]); - vAddress.setVisibility(View.VISIBLE); - } else { - vAddress.setVisibility(View.GONE); - } - if (userId[2] != null) { - vComment.setText(userId[2]); - vComment.setVisibility(View.VISIBLE); - } else { - vComment.setVisibility(View.GONE); - } - - // show small star icon for primary user ids - boolean isPrimary = cursor.getInt(mIsPrimary) != 0; - - if (cursor.getInt(mIsRevoked) > 0) { - - // set revocation icon (can this even be primary?) - vVerified.setImageResource(R.drawable.key_certify_revoke); - - // disable and strike through text for revoked user ids - vName.setEnabled(false); - vAddress.setEnabled(false); - vName.setText(OtherHelper.strikeOutText(vName.getText())); - vAddress.setText(OtherHelper.strikeOutText(vAddress.getText())); - } else { - vName.setEnabled(true); - vAddress.setEnabled(true); - - int verified = cursor.getInt(mVerifiedId); - switch (verified) { - case Certs.VERIFIED_SECRET: - vVerified.setImageResource(isPrimary - ? R.drawable.key_certify_primary_ok_depth0 - : R.drawable.key_certify_ok_depth0); - break; - case Certs.VERIFIED_SELF: - vVerified.setImageResource(isPrimary - ? R.drawable.key_certify_primary_ok_self - : R.drawable.key_certify_ok_self); - break; - default: - vVerified.setImageResource(R.drawable.key_certify_error); - break; - } - } - - // 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.setOnCheckedChangeListener(null); - vCheckBox.setChecked(mCheckStates.get(position)); - vCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean b) { - mCheckStates.set(position, b); - } - }); - vCheckBox.setClickable(false); - - } - - public void onItemClick(AdapterView adapter, View view, int position, long id) { - CheckBox box = ((CheckBox) view.findViewById(R.id.checkBox)); - if (box != null) { - box.toggle(); - } - } - - public ArrayList getSelectedUserIds() { - ArrayList result = new ArrayList(); - 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) { - 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; - } - - // Disable selection of items for lists without checkboxes, http://stackoverflow.com/a/4075045 - @Override - public boolean areAllItemsEnabled() { - if (mCheckStates == null) { - return false; - } else { - return super.areAllItemsEnabled(); - } - } - - // Disable selection of items for lists without checkboxes, http://stackoverflow.com/a/4075045 - @Override - public boolean isEnabled(int position) { - if (mCheckStates == null) { - return false; - } else { - return super.isEnabled(position); - } - } - -} -- cgit v1.2.3