aboutsummaryrefslogtreecommitdiffstats
path: root/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget
diff options
context:
space:
mode:
authorVincent Breitmoser <valodim@mugenguild.com>2015-03-30 02:42:16 +0200
committerVincent Breitmoser <valodim@mugenguild.com>2015-03-30 02:42:16 +0200
commitd27925ad19b6800658a69670ceaed261776ba6d3 (patch)
treeca83e7f27f9e5ae2718c378346c89bad1213c046 /OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget
parent01c444d63788b78781132ef5cc9998b0b4352e71 (diff)
downloadopen-keychain-d27925ad19b6800658a69670ceaed261776ba6d3.tar.gz
open-keychain-d27925ad19b6800658a69670ceaed261776ba6d3.tar.bz2
open-keychain-d27925ad19b6800658a69670ceaed261776ba6d3.zip
rewrite EncryptKeyCompletionView with generalized KeyAdapter
Diffstat (limited to 'OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget')
-rw-r--r--OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java278
1 files changed, 73 insertions, 205 deletions
diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java
index ceace1d26..b2dfb2493 100644
--- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java
+++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java
@@ -1,5 +1,6 @@
/*
- * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2014-2015 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2015 Vincent Breitmoser <v.breitmoser@mugenguild.com>
*
* 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
@@ -17,49 +18,42 @@
package org.sufficientlysecure.keychain.ui.widget;
-import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
-import android.graphics.Bitmap;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
+import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
-import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
-import android.widget.ImageView;
import android.widget.TextView;
-import com.tokenautocomplete.FilteredArrayAdapter;
import com.tokenautocomplete.TokenCompleteTextView;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
-import org.sufficientlysecure.keychain.pgp.KeyRing;
-import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException;
-import org.sufficientlysecure.keychain.provider.CachedPublicKeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
-import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
-import org.sufficientlysecure.keychain.util.ContactHelper;
+import org.sufficientlysecure.keychain.ui.adapter.KeyAdapter;
+import org.sufficientlysecure.keychain.ui.adapter.KeyAdapter.KeyItem;
import org.sufficientlysecure.keychain.util.Log;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.TimeZone;
-public class EncryptKeyCompletionView extends TokenCompleteTextView {
+public class EncryptKeyCompletionView extends TokenCompleteTextView
+ implements LoaderCallbacks<Cursor> {
+
+ public static final String ARG_QUERY = "query";
+
+ private KeyAdapter mAdapter;
+ private LoaderManager mLoaderManager;
+ private String mPrefix;
+
public EncryptKeyCompletionView(Context context) {
super(context);
initView();
@@ -76,33 +70,31 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView {
}
private void initView() {
- swapCursor(null);
setPrefix(getContext().getString(R.string.label_to) + " ");
+
allowDuplicates(false);
+ mAdapter = new KeyAdapter(getContext(), null, 0);
+ setAdapter(mAdapter);
+ }
+
+ @Override
+ public void setPrefix(String p) {
+ // this one is private in the superclass, but we need it here
+ mPrefix = p;
+ super.setPrefix(p);
}
@Override
protected View getViewForObject(Object object) {
- if (object instanceof EncryptionKey) {
- LayoutInflater l = (LayoutInflater) getContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
+ if (object instanceof KeyItem) {
+ LayoutInflater l = LayoutInflater.from(getContext());
View view = l.inflate(R.layout.recipient_box_entry, null);
- ((TextView) view.findViewById(android.R.id.text1)).setText(((EncryptionKey) object).getPrimary());
- setImageByKey((ImageView) view.findViewById(android.R.id.icon), (EncryptionKey) object);
+ ((TextView) view.findViewById(android.R.id.text1)).setText(((KeyItem) object).getReadableName());
return view;
}
return null;
}
- private void setImageByKey(ImageView view, EncryptionKey key) {
- Bitmap photo = ContactHelper.getCachedPhotoByMasterKeyId(getContext().getContentResolver(), key.getKeyId());
-
- if (photo != null) {
- view.setImageBitmap(photo);
- } else {
- view.setImageResource(R.drawable.ic_generic_man);
- }
- }
-
@Override
protected Object defaultObject(String completionText) {
// TODO: We could try to automagically download the key if it's unknown but a key id
@@ -115,196 +107,72 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView {
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
+
+ mLoaderManager = ((FragmentActivity) getContext()).getSupportLoaderManager();
+
if (getContext() instanceof FragmentActivity) {
- ((FragmentActivity) getContext()).getSupportLoaderManager().initLoader(hashCode(), null, new LoaderManager.LoaderCallbacks<Cursor>() {
- @Override
- public Loader<Cursor> onCreateLoader(int id, Bundle args) {
- // These are the rows that we will retrieve.
- Uri baseUri = KeyRings.buildUnifiedKeyRingsUri();
-
- String[] projection = new String[]{
- KeyRings._ID,
- KeyRings.MASTER_KEY_ID,
- KeyRings.KEY_ID,
- KeyRings.USER_ID,
- KeyRings.FINGERPRINT,
- KeyRings.IS_EXPIRED,
- KeyRings.HAS_ENCRYPT,
- KeyRings.HAS_DUPLICATE_USER_ID,
- KeyRings.CREATION
- };
-
- String where = KeyRings.HAS_ENCRYPT + " NOT NULL AND " + KeyRings.IS_EXPIRED + " = 0 AND "
- + Tables.KEYS + "." + KeyRings.IS_REVOKED + " = 0";
-
- return new CursorLoader(getContext(), baseUri, projection, where, null, null);
- }
-
- @Override
- public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
- swapCursor(data);
- }
-
- @Override
- public void onLoaderReset(Loader<Cursor> loader) {
- swapCursor(null);
- }
- });
+ mLoaderManager.initLoader(hashCode(), null, this);
} else {
Log.e(Constants.TAG, "EncryptKeyCompletionView must be attached to a FragmentActivity, this is " + getContext().getClass());
}
}
@Override
- public void onFocusChanged(boolean hasFocus, int direction, Rect previous) {
- super.onFocusChanged(hasFocus, direction, previous);
- if (hasFocus) {
- ((InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE))
- .showSoftInput(this, InputMethodManager.SHOW_IMPLICIT);
- }
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mLoaderManager = null;
}
- public void swapCursor(Cursor cursor) {
- if (cursor == null) {
- setAdapter(new EncryptKeyAdapter(Collections.<EncryptionKey>emptyList()));
- return;
- }
- ArrayList<EncryptionKey> keys = new ArrayList<>();
- while (cursor.moveToNext()) {
- try {
- EncryptionKey key = new EncryptionKey(cursor);
- keys.add(key);
- } catch (Exception e) {
- Log.w(Constants.TAG, e);
- return;
- }
- }
- setAdapter(new EncryptKeyAdapter(keys));
- }
-
- public class EncryptionKey {
- private String mUserIdFull;
- private KeyRing.UserId mUserId;
- private long mKeyId;
- private boolean mHasDuplicate;
- private Date mCreation;
- private String mFingerprint;
-
- public EncryptionKey(String userId, long keyId, boolean hasDuplicate, Date creation, String fingerprint) {
- mUserId = KeyRing.splitUserId(userId);
- mUserIdFull = userId;
- mKeyId = keyId;
- mHasDuplicate = hasDuplicate;
- mCreation = creation;
- mFingerprint = fingerprint;
- }
-
- public EncryptionKey(Cursor cursor) {
- this(cursor.getString(cursor.getColumnIndexOrThrow(KeyRings.USER_ID)),
- cursor.getLong(cursor.getColumnIndexOrThrow(KeyRings.KEY_ID)),
- cursor.getLong(cursor.getColumnIndexOrThrow(KeyRings.HAS_DUPLICATE_USER_ID)) > 0,
- new Date(cursor.getLong(cursor.getColumnIndexOrThrow(KeyRings.CREATION)) * 1000),
- KeyFormattingUtils.convertFingerprintToHex(
- cursor.getBlob(cursor.getColumnIndexOrThrow(KeyRings.FINGERPRINT))));
- }
-
- public EncryptionKey(CachedPublicKeyRing ring) throws PgpKeyNotFoundException {
- this(ring.getPrimaryUserId(), ring.extractOrGetMasterKeyId(), false, null,
- KeyFormattingUtils.convertFingerprintToHex(ring.getFingerprint()));
- }
-
- public String getUserId() {
- return mUserIdFull;
- }
-
- public String getFingerprint() {
- return mFingerprint;
- }
-
- public String getPrimary() {
- if (mUserId.name != null) {
- return mUserId.name;
- } else {
- return mUserId.email;
- }
- }
-
- public String getSecondary() {
- if (mUserId.email != null) {
- return mUserId.email;
- } else {
- return getCreationDate();
- }
- }
-
- public String getTertiary() {
- if (mUserId.name != null) {
- return getCreationDate();
- } else {
- return null;
- }
- }
+ @Override
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ // These are the rows that we will retrieve.
+ Uri baseUri = KeyRings.buildUnifiedKeyRingsUri();
+ String where = KeyRings.HAS_ENCRYPT + " NOT NULL AND " + KeyRings.IS_EXPIRED + " = 0 AND "
+ + Tables.KEYS + "." + KeyRings.IS_REVOKED + " = 0";
- public long getKeyId() {
- return mKeyId;
- }
+ if (args != null && args.containsKey(ARG_QUERY)) {
+ String query = args.getString(ARG_QUERY);
+ mAdapter.setSearchQuery(query);
- public String getCreationDate() {
- if (mHasDuplicate) {
- Calendar creationCal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
- creationCal.setTime(mCreation);
- // convert from UTC to time zone of device
- creationCal.setTimeZone(TimeZone.getDefault());
-
- return getContext().getString(R.string.label_creation) + ": "
- + DateFormat.getDateFormat(getContext()).format(creationCal.getTime());
- } else {
- return null;
- }
- }
+ where += " AND " + KeyRings.USER_ID + " LIKE ?";
- public String getKeyIdHex() {
- return KeyFormattingUtils.beautifyKeyIdWithPrefix(getContext(), mKeyId);
+ return new CursorLoader(getContext(), baseUri, KeyAdapter.PROJECTION, where,
+ new String[] { "%" + query + "%" }, null);
}
- public String getKeyIdHexShort() {
- return KeyFormattingUtils.convertKeyIdToHexShort(mKeyId);
- }
+ mAdapter.setSearchQuery(null);
+ return new CursorLoader(getContext(), baseUri, KeyAdapter.PROJECTION, where, null, null);
- @Override
- public String toString() {
- return Long.toString(mKeyId);
- }
}
- private class EncryptKeyAdapter extends FilteredArrayAdapter<EncryptionKey> {
+ @Override
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ mAdapter.swapCursor(data);
+ }
- public EncryptKeyAdapter(List<EncryptionKey> objs) {
- super(EncryptKeyCompletionView.this.getContext(), 0, 0, objs);
- }
+ @Override
+ public void onLoaderReset(Loader<Cursor> loader) {
+ mAdapter.swapCursor(null);
+ }
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- LayoutInflater l = (LayoutInflater) getContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
- View view;
- if (convertView != null) {
- view = convertView;
- } else {
- view = l.inflate(R.layout.recipient_selection_list_entry, null);
- }
- ((TextView) view.findViewById(android.R.id.title)).setText(getItem(position).getPrimary());
- ((TextView) view.findViewById(android.R.id.text1)).setText(getItem(position).getSecondary());
- ((TextView) view.findViewById(android.R.id.text2)).setText(getItem(position).getTertiary());
- setImageByKey((ImageView) view.findViewById(android.R.id.icon), getItem(position));
- return view;
+ @Override
+ public void onFocusChanged(boolean hasFocus, int direction, Rect previous) {
+ super.onFocusChanged(hasFocus, direction, previous);
+ if (hasFocus) {
+ ((InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE))
+ .showSoftInput(this, InputMethodManager.SHOW_IMPLICIT);
}
+ }
- @Override
- protected boolean keepObject(EncryptionKey obj, String mask) {
- String m = mask.toLowerCase(Locale.ENGLISH);
- return obj.getUserId().toLowerCase(Locale.ENGLISH).contains(m) ||
- obj.getKeyIdHex().contains(m) ||
- obj.getKeyIdHexShort().startsWith(m);
- }
+ @Override
+ protected void performFiltering(CharSequence text, int start, int end, int keyCode) {
+ super.performFiltering(text, start, end, keyCode);
+ if (start < mPrefix.length()) {
+ start = mPrefix.length();
+ }
+ Bundle args = new Bundle();
+ args.putString(ARG_QUERY, text.subSequence(start, end).toString());
+ mLoaderManager.restartLoader(hashCode(), args, this);
}
+
}