diff options
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java')
-rw-r--r-- | OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java | 170 |
1 files changed, 49 insertions, 121 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java index ad1a14a33..5050c01af 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java @@ -17,33 +17,30 @@ package org.sufficientlysecure.keychain.ui.widget; -import android.annotation.SuppressLint; + import android.content.Context; import android.database.Cursor; -import android.graphics.Color; import android.os.Bundle; import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; -import android.support.v4.widget.CursorAdapter; import android.support.v7.widget.AppCompatSpinner; -import android.text.format.DateUtils; import android.util.AttributeSet; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; -import android.widget.ImageView; import android.widget.SpinnerAdapter; -import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; -import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.provider.KeychainContract; -import org.sufficientlysecure.keychain.util.Log; +import org.sufficientlysecure.keychain.ui.adapter.KeyAdapter; +import org.sufficientlysecure.keychain.ui.adapter.KeyAdapter.KeyItem; + /** * Use AppCompatSpinner from AppCompat lib instead of Spinner. Fixes white dropdown icon. @@ -119,7 +116,8 @@ public abstract class KeySpinner extends AppCompatSpinner implements if (getContext() instanceof FragmentActivity) { ((FragmentActivity) getContext()).getSupportLoaderManager().restartLoader(LOADER_ID, null, this); } else { - Log.e(Constants.TAG, "KeySpinner must be attached to FragmentActivity, this is " + getContext().getClass()); + throw new AssertionError("KeySpinner must be attached to FragmentActivity, this is " + + getContext().getClass()); } } @@ -138,7 +136,11 @@ public abstract class KeySpinner extends AppCompatSpinner implements } public long getSelectedKeyId() { - return getSelectedItemId(); + Object item = getSelectedItem(); + if (item instanceof KeyItem) { + return ((KeyItem) item).mKeyId; + } + return Constants.key.none; } public void setPreSelectedKeyId(long selectedKeyId) { @@ -146,161 +148,87 @@ public abstract class KeySpinner extends AppCompatSpinner implements } protected class SelectKeyAdapter extends BaseAdapter implements SpinnerAdapter { - private CursorAdapter inner; - private int mIndexUserId; - private int mIndexDuplicate; + private KeyAdapter inner; private int mIndexMasterKeyId; - private int mIndexCreationDate; public SelectKeyAdapter() { - inner = new CursorAdapter(getContext(), null, 0) { - @Override - public View newView(Context context, Cursor cursor, ViewGroup parent) { - return View.inflate(getContext(), R.layout.keyspinner_item, null); - } + inner = new KeyAdapter(getContext(), null, 0) { @Override - public void bindView(View view, Context context, Cursor cursor) { - TextView vKeyName = (TextView) view.findViewById(R.id.keyspinner_key_name); - ImageView vKeyStatus = (ImageView) view.findViewById(R.id.keyspinner_key_status); - TextView vKeyEmail = (TextView) view.findViewById(R.id.keyspinner_key_email); - TextView vDuplicate = (TextView) view.findViewById(R.id.keyspinner_duplicate); - - KeyRing.UserId userId = KeyRing.splitUserId(cursor.getString(mIndexUserId)); - vKeyName.setText(userId.name); - vKeyEmail.setText(userId.email); - - boolean duplicate = cursor.getLong(mIndexDuplicate) > 0; - if (duplicate) { - String dateTime = DateUtils.formatDateTime(context, - cursor.getLong(mIndexCreationDate) * 1000, - DateUtils.FORMAT_SHOW_DATE - | DateUtils.FORMAT_SHOW_YEAR - | DateUtils.FORMAT_ABBREV_MONTH); - - vDuplicate.setText(context.getString(R.string.label_key_created, dateTime)); - vDuplicate.setVisibility(View.VISIBLE); - } else { - vDuplicate.setVisibility(View.GONE); - } - - boolean valid = setStatus(getContext(), cursor, vKeyStatus); - setItemEnabled(view, valid); + public boolean isEnabled(Cursor cursor) { + return KeySpinner.this.isItemEnabled(cursor); } - @Override - public long getItemId(int position) { - try { - return ((Cursor) getItem(position)).getLong(mIndexMasterKeyId); - } catch (Exception e) { - // This can happen on concurrent modification :( - return Constants.key.none; - } - } }; } - private void setItemEnabled(View view, boolean enabled) { - TextView vKeyName = (TextView) view.findViewById(R.id.keyspinner_key_name); - ImageView vKeyStatus = (ImageView) view.findViewById(R.id.keyspinner_key_status); - TextView vKeyEmail = (TextView) view.findViewById(R.id.keyspinner_key_email); - TextView vKeyDuplicate = (TextView) view.findViewById(R.id.keyspinner_duplicate); - - if (enabled) { - vKeyName.setTextColor(Color.BLACK); - vKeyEmail.setTextColor(Color.BLACK); - vKeyDuplicate.setTextColor(Color.BLACK); - vKeyStatus.setVisibility(View.GONE); - view.setClickable(false); - } else { - vKeyName.setTextColor(Color.GRAY); - vKeyEmail.setTextColor(Color.GRAY); - vKeyDuplicate.setTextColor(Color.GRAY); - vKeyStatus.setVisibility(View.VISIBLE); - // this is a HACK. the trick is, if the element itself is clickable, the - // click is not passed on to the view list - view.setClickable(true); - } - } - public Cursor swapCursor(Cursor newCursor) { if (newCursor == null) return inner.swapCursor(null); - mIndexDuplicate = newCursor.getColumnIndex(KeychainContract.KeyRings.HAS_DUPLICATE_USER_ID); - mIndexUserId = newCursor.getColumnIndex(KeychainContract.KeyRings.USER_ID); mIndexMasterKeyId = newCursor.getColumnIndex(KeychainContract.KeyRings.MASTER_KEY_ID); - mIndexCreationDate = newCursor.getColumnIndex(KeychainContract.KeyRings.CREATION); + + Cursor oldCursor = inner.swapCursor(newCursor); // pre-select key if mPreSelectedKeyId is given if (mPreSelectedKeyId != Constants.key.none && newCursor.moveToFirst()) { do { if (newCursor.getLong(mIndexMasterKeyId) == mPreSelectedKeyId) { - setSelection(newCursor.getPosition() + 1); + setSelection(newCursor.getPosition() +1); } } while (newCursor.moveToNext()); } - return inner.swapCursor(newCursor); + return oldCursor; } @Override public int getCount() { - return inner.getCount() + 1; + return inner.getCount() +1; } @Override public Object getItem(int position) { - if (position == 0) return null; - return inner.getItem(position - 1); + if (position == 0) { + return null; + } + return inner.getItem(position -1); } @Override public long getItemId(int position) { - if (position == 0) return Constants.key.none; - return inner.getItemId(position - 1); + if (position == 0) { + return Constants.key.none; + } + return inner.getItemId(position -1); } - @SuppressLint("ViewHolder") // inflate call is for the preview only @Override public View getView(int position, View convertView, ViewGroup parent) { - try { - View v = getDropDownView(position, convertView, parent); - v.findViewById(R.id.keyspinner_key_email).setVisibility(View.GONE); - return v; - } catch (NullPointerException e) { - // This is for the preview... - return View.inflate(getContext(), android.R.layout.simple_list_item_1, null); - } - } - @Override - public View getDropDownView(int position, View convertView, ViewGroup parent) { - View view; - if (position == 0) { - if (convertView == null) { - view = inner.newView(null, null, parent); - } else { - view = convertView; + // Unfortunately, SpinnerAdapter does not support multiple view + // types. For this reason, we throw away convertViews of a bad + // type. This is sort of a hack, but since the number of elements + // we deal with in KeySpinners is usually very small (number of + // secret keys), this is the easiest solution. (I'm sorry.) + if (convertView != null) { + // This assumes that the inner view has non-null tags on its views! + boolean isWrongType = (convertView.getTag() == null) != (position == 0); + if (isWrongType) { + convertView = null; } - TextView vKeyName = (TextView) view.findViewById(R.id.keyspinner_key_name); - ImageView vKeyStatus = (ImageView) view.findViewById(R.id.keyspinner_key_status); - TextView vKeyEmail = (TextView) view.findViewById(R.id.keyspinner_key_email); - TextView vKeyDuplicate = (TextView) view.findViewById(R.id.keyspinner_duplicate); - - vKeyName.setText(R.string.choice_none); - vKeyEmail.setVisibility(View.GONE); - vKeyDuplicate.setVisibility(View.GONE); - vKeyStatus.setVisibility(View.GONE); - setItemEnabled(view, true); - } else { - view = inner.getView(position - 1, convertView, parent); - TextView vKeyEmail = (TextView) view.findViewById(R.id.keyspinner_key_email); - vKeyEmail.setVisibility(View.VISIBLE); } - return view; + + if (position > 0) { + return inner.getView(position -1, convertView, parent); + } + + return convertView != null ? convertView : + LayoutInflater.from(getContext()).inflate( + R.layout.keyspinner_item_none, parent, false); } + } - boolean setStatus(Context context, Cursor cursor, ImageView statusView) { + boolean isItemEnabled(Cursor cursor) { return true; } |