diff options
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java')
-rw-r--r-- | OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java | 136 |
1 files changed, 100 insertions, 36 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java index 3dbae09b6..56d273c7c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java @@ -18,6 +18,11 @@ package org.sufficientlysecure.keychain.ui.adapter; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; import java.util.Date; import android.content.Context; @@ -27,6 +32,7 @@ import android.support.v4.widget.CursorAdapter; import android.text.format.DateUtils; import android.view.LayoutInflater; import android.view.View; +import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.ImageView; @@ -38,6 +44,7 @@ import org.sufficientlysecure.keychain.pgp.CanonicalizedPublicKeyRing; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.ui.util.Highlighter; +import org.sufficientlysecure.keychain.ui.util.FormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State; @@ -45,6 +52,7 @@ public class KeyAdapter extends CursorAdapter { protected String mQuery; protected LayoutInflater mInflater; + protected Context mContext; // These are the rows that we will retrieve. public static final String[] PROJECTION = new String[]{ @@ -56,7 +64,6 @@ public class KeyAdapter extends CursorAdapter { KeyRings.VERIFIED, KeyRings.HAS_ANY_SECRET, KeyRings.HAS_DUPLICATE_USER_ID, - KeyRings.HAS_ENCRYPT, KeyRings.FINGERPRINT, KeyRings.CREATION, }; @@ -68,13 +75,13 @@ public class KeyAdapter extends CursorAdapter { public static final int INDEX_VERIFIED = 5; public static final int INDEX_HAS_ANY_SECRET = 6; public static final int INDEX_HAS_DUPLICATE_USER_ID = 7; - public static final int INDEX_HAS_ENCRYPT = 8; - public static final int INDEX_FINGERPRINT = 9; - public static final int INDEX_CREATION = 10; + public static final int INDEX_FINGERPRINT = 8; + public static final int INDEX_CREATION = 9; public KeyAdapter(Context context, Cursor c, int flags) { super(context, c, flags); + mContext = context; mInflater = LayoutInflater.from(context); } @@ -83,6 +90,9 @@ public class KeyAdapter extends CursorAdapter { } public static class KeyItemViewHolder { + public View mView; + public View mLayoutDummy; + public View mLayoutData; public Long mMasterKeyId; public TextView mMainUserId; public TextView mMainUserIdRest; @@ -91,7 +101,12 @@ public class KeyAdapter extends CursorAdapter { public View mSlinger; public ImageButton mSlingerButton; + public KeyItem mDisplayedItem; + public KeyItemViewHolder(View view) { + mView = view; + mLayoutData = view.findViewById(R.id.key_list_item_data); + mLayoutDummy = view.findViewById(R.id.key_list_item_dummy); mMainUserId = (TextView) view.findViewById(R.id.key_list_item_name); mMainUserIdRest = (TextView) view.findViewById(R.id.key_list_item_email); mStatus = (ImageView) view.findViewById(R.id.key_list_item_status_icon); @@ -100,11 +115,15 @@ public class KeyAdapter extends CursorAdapter { mCreationDate = (TextView) view.findViewById(R.id.key_list_item_creation); } - public void setData(Context context, Cursor cursor, Highlighter highlighter) { + public void setData(Context context, KeyItem item, Highlighter highlighter, boolean enabled) { + + mLayoutData.setVisibility(View.VISIBLE); + mLayoutDummy.setVisibility(View.GONE); + + mDisplayedItem = item; { // set name and stuff, common to both key types - String userId = cursor.getString(INDEX_USER_ID); - KeyRing.UserId userIdSplit = KeyRing.splitUserId(userId); + KeyRing.UserId userIdSplit = item.mUserId; if (userIdSplit.name != null) { mMainUserId.setText(highlighter.highlight(userIdSplit.name)); } else { @@ -118,43 +137,42 @@ public class KeyAdapter extends CursorAdapter { } } + // sort of a hack: if this item isn't enabled, we make it clickable + // to intercept its click events. either way, no listener! + mView.setClickable(!enabled); + { // set edit button and status, specific by key type - long masterKeyId = cursor.getLong(INDEX_MASTER_KEY_ID); - boolean isSecret = cursor.getInt(INDEX_HAS_ANY_SECRET) != 0; - boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0; - boolean isExpired = cursor.getInt(INDEX_IS_EXPIRED) != 0; - boolean isVerified = cursor.getInt(INDEX_VERIFIED) > 0; - boolean hasDuplicate = cursor.getInt(INDEX_HAS_DUPLICATE_USER_ID) != 0; + mMasterKeyId = item.mKeyId; - mMasterKeyId = masterKeyId; + int textColor; // Note: order is important! - if (isRevoked) { + if (item.mIsRevoked) { KeyFormattingUtils - .setStatusImage(context, mStatus, null, State.REVOKED, R.color.bg_gray); + .setStatusImage(context, mStatus, null, State.REVOKED, R.color.key_flag_gray); mStatus.setVisibility(View.VISIBLE); mSlinger.setVisibility(View.GONE); - mMainUserId.setTextColor(context.getResources().getColor(R.color.bg_gray)); - mMainUserIdRest.setTextColor(context.getResources().getColor(R.color.bg_gray)); - } else if (isExpired) { - KeyFormattingUtils.setStatusImage(context, mStatus, null, State.EXPIRED, R.color.bg_gray); + textColor = context.getResources().getColor(R.color.key_flag_gray); + } else if (item.mIsExpired) { + KeyFormattingUtils.setStatusImage(context, mStatus, null, State.EXPIRED, R.color.key_flag_gray); mStatus.setVisibility(View.VISIBLE); mSlinger.setVisibility(View.GONE); - mMainUserId.setTextColor(context.getResources().getColor(R.color.bg_gray)); - mMainUserIdRest.setTextColor(context.getResources().getColor(R.color.bg_gray)); - } else if (isSecret) { + textColor = context.getResources().getColor(R.color.key_flag_gray); + } else if (item.mIsSecret) { mStatus.setVisibility(View.GONE); if (mSlingerButton.hasOnClickListeners()) { + mSlingerButton.setColorFilter( + FormattingUtils.getColorFromAttr(context, R.attr.colorTertiaryText), + PorterDuff.Mode.SRC_IN); mSlinger.setVisibility(View.VISIBLE); } else { mSlinger.setVisibility(View.GONE); } - mMainUserId.setTextColor(context.getResources().getColor(R.color.black)); - mMainUserIdRest.setTextColor(context.getResources().getColor(R.color.black)); + textColor = FormattingUtils.getColorFromAttr(context, R.attr.colorText); } else { // this is a public key - show if it's verified - if (isVerified) { + if (item.mIsVerified) { KeyFormattingUtils.setStatusImage(context, mStatus, State.VERIFIED); mStatus.setVisibility(View.VISIBLE); } else { @@ -162,19 +180,26 @@ public class KeyAdapter extends CursorAdapter { mStatus.setVisibility(View.VISIBLE); } mSlinger.setVisibility(View.GONE); - mMainUserId.setTextColor(context.getResources().getColor(R.color.black)); - mMainUserIdRest.setTextColor(context.getResources().getColor(R.color.black)); + textColor = FormattingUtils.getColorFromAttr(context, R.attr.colorText); } - if (hasDuplicate) { + if (!enabled) { + textColor = context.getResources().getColor(R.color.key_flag_gray); + } + + mMainUserId.setTextColor(textColor); + mMainUserIdRest.setTextColor(textColor); + + if (item.mHasDuplicate) { String dateTime = DateUtils.formatDateTime(context, - cursor.getLong(INDEX_CREATION) * 1000, + item.mCreation.getTime(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_ABBREV_MONTH); mCreationDate.setText(context.getString(R.string.label_key_created, - dateTime)); + dateTime)); + mCreationDate.setTextColor(textColor); mCreationDate.setVisibility(View.VISIBLE); } else { mCreationDate.setVisibility(View.GONE); @@ -184,6 +209,24 @@ public class KeyAdapter extends CursorAdapter { } + /** Shows the "you have no keys yet" dummy view, and sets an OnClickListener. */ + public void setDummy(OnClickListener listener) { + + // just reset everything to display the dummy layout + mLayoutDummy.setVisibility(View.VISIBLE); + mLayoutData.setVisibility(View.GONE); + mSlinger.setVisibility(View.GONE); + mStatus.setVisibility(View.GONE); + mView.setClickable(false); + + mLayoutDummy.setOnClickListener(listener); + + } + + } + + public boolean isEnabled(Cursor cursor) { + return true; } @Override @@ -191,16 +234,17 @@ public class KeyAdapter extends CursorAdapter { View view = mInflater.inflate(R.layout.key_list_item, parent, false); KeyItemViewHolder holder = new KeyItemViewHolder(view); view.setTag(holder); - holder.mSlingerButton.setColorFilter(context.getResources().getColor(R.color.tertiary_text_light), - PorterDuff.Mode.SRC_IN); return view; } @Override public void bindView(View view, Context context, Cursor cursor) { Highlighter highlighter = new Highlighter(context, mQuery); + KeyItem item = new KeyItem(cursor); + boolean isEnabled = isEnabled(cursor); + KeyItemViewHolder h = (KeyItemViewHolder) view.getTag(); - h.setData(context, cursor, highlighter); + h.setData(context, item, highlighter, isEnabled); } public boolean isSecretAvailable(int id) { @@ -230,14 +274,16 @@ public class KeyAdapter extends CursorAdapter { @Override public long getItemId(int position) { + Cursor cursor = getCursor(); // prevent a crash on rapid cursor changes - if (getCursor().isClosed()) { + if (cursor != null && getCursor().isClosed()) { return 0L; } return super.getItemId(position); } - public static class KeyItem { + // must be serializable for TokenCompleTextView state + public static class KeyItem implements Serializable { public final String mUserIdFull; public final KeyRing.UserId mUserId; @@ -245,6 +291,7 @@ public class KeyAdapter extends CursorAdapter { public final boolean mHasDuplicate; public final Date mCreation; public final String mFingerprint; + public final boolean mIsSecret, mIsRevoked, mIsExpired, mIsVerified; private KeyItem(Cursor cursor) { String userId = cursor.getString(INDEX_USER_ID); @@ -255,6 +302,10 @@ public class KeyAdapter extends CursorAdapter { mCreation = new Date(cursor.getLong(INDEX_CREATION) * 1000); mFingerprint = KeyFormattingUtils.convertFingerprintToHex( cursor.getBlob(INDEX_FINGERPRINT)); + mIsSecret = cursor.getInt(INDEX_HAS_ANY_SECRET) != 0; + mIsRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0; + mIsExpired = cursor.getInt(INDEX_IS_EXPIRED) > 0; + mIsVerified = cursor.getInt(INDEX_VERIFIED) > 0; } public KeyItem(CanonicalizedPublicKeyRing ring) { @@ -267,6 +318,12 @@ public class KeyAdapter extends CursorAdapter { mCreation = key.getCreationTime(); mFingerprint = KeyFormattingUtils.convertFingerprintToHex( ring.getFingerprint()); + mIsRevoked = key.isRevoked(); + mIsExpired = key.isExpired(); + + // these two are actually "don't know"s + mIsSecret = false; + mIsVerified = false; } public String getReadableName() { @@ -279,4 +336,11 @@ public class KeyAdapter extends CursorAdapter { } + public static String[] getProjectionWith(String[] projection) { + List<String> list = new ArrayList<>(); + list.addAll(Arrays.asList(PROJECTION)); + list.addAll(Arrays.asList(projection)); + return list.toArray(new String[list.size()]); + } + } |