From 84d00abea113c6561519c2481245eff0253b15a2 Mon Sep 17 00:00:00 2001 From: Thialfihar Date: Sat, 5 Jun 2010 21:47:16 +0000 Subject: added search feature for key management and select Activities --- src/org/thialfihar/android/apg/Apg.java | 14 +++ .../thialfihar/android/apg/GeneralActivity.java | 4 +- .../thialfihar/android/apg/KeyListActivity.java | 110 +++++++++++++++++++-- .../android/apg/SelectPublicKeyListActivity.java | 104 ++++++++++++++----- .../android/apg/SelectPublicKeyListAdapter.java | 51 +++++++++- .../android/apg/SelectSecretKeyListActivity.java | 52 +++++++++- .../android/apg/SelectSecretKeyListAdapter.java | 36 ++++++- .../android/apg/provider/DataProvider.java | 40 ++++---- 8 files changed, 346 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/org/thialfihar/android/apg/Apg.java b/src/org/thialfihar/android/apg/Apg.java index 3c35064a4..744bb736c 100644 --- a/src/org/thialfihar/android/apg/Apg.java +++ b/src/org/thialfihar/android/apg/Apg.java @@ -79,6 +79,7 @@ import org.bouncycastle2.openpgp.PGPSignatureList; import org.bouncycastle2.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle2.openpgp.PGPSignatureSubpacketVector; import org.bouncycastle2.openpgp.PGPUtil; +import org.thialfihar.android.apg.provider.DataProvider; import org.thialfihar.android.apg.provider.Database; import org.thialfihar.android.apg.provider.KeyRings; import org.thialfihar.android.apg.provider.Keys; @@ -92,6 +93,7 @@ import android.app.Activity; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; +import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.view.ViewGroup; @@ -130,6 +132,18 @@ public class Apg { public static final String EXTRA_MAX = "max"; public static final String EXTRA_ACCOUNT = "account"; + public static final String AUTHORITY = DataProvider.AUTHORITY; + + public static final Uri CONTENT_URI_SECRET_KEY_RINGS = + Uri.parse("content://" + AUTHORITY + "/key_rings/secret/"); + public static final Uri CONTENT_URI_SECRET_KEY_RING_BY_KEY_ID = + Uri.parse("content://" + AUTHORITY + "/key_rings/secret/key_id/"); + + public static final Uri CONTENT_URI_PUBLIC_KEY_RINGS = + Uri.parse("content://" + AUTHORITY + "/key_rings/public/"); + public static final Uri CONTENT_URI_PUBLIC_KEY_RING_BY_KEY_ID = + Uri.parse("content://" + AUTHORITY + "/key_rings/public/key_id/"); + public static String VERSION = "1.0.1"; public static String FULL_VERSION = "APG v" + VERSION; diff --git a/src/org/thialfihar/android/apg/GeneralActivity.java b/src/org/thialfihar/android/apg/GeneralActivity.java index 1a80368aa..af919bb48 100644 --- a/src/org/thialfihar/android/apg/GeneralActivity.java +++ b/src/org/thialfihar/android/apg/GeneralActivity.java @@ -66,8 +66,8 @@ public class GeneralActivity extends BaseActivity { Vector choices = new Vector(); if (containsKeys) { - choices.add(new Choice(Id.choice.action.import_public, getString(R.string.action_import_public))); - choices.add(new Choice(Id.choice.action.import_secret, getString(R.string.action_import_secret))); + choices.add(new Choice(Id.choice.action.import_public, getString(R.string.action_importPublic))); + choices.add(new Choice(Id.choice.action.import_secret, getString(R.string.action_importSecret))); } if (isEncrypted) { diff --git a/src/org/thialfihar/android/apg/KeyListActivity.java b/src/org/thialfihar/android/apg/KeyListActivity.java index 7e86504b3..f09a74384 100644 --- a/src/org/thialfihar/android/apg/KeyListActivity.java +++ b/src/org/thialfihar/android/apg/KeyListActivity.java @@ -29,11 +29,13 @@ import org.thialfihar.android.apg.provider.UserIds; import android.app.AlertDialog; import android.app.Dialog; +import android.app.SearchManager; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.os.Bundle; import android.os.Message; @@ -41,7 +43,9 @@ import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.view.View.OnClickListener; import android.widget.BaseExpandableListAdapter; +import android.widget.Button; import android.widget.ExpandableListView; import android.widget.ImageView; import android.widget.TextView; @@ -51,6 +55,9 @@ import android.widget.ExpandableListView.ExpandableListContextMenuInfo; public class KeyListActivity extends BaseActivity { protected ExpandableListView mList; protected KeyListAdapter mListAdapter; + protected View mFilterLayout; + protected Button mClearFilterButton; + protected TextView mFilterInfo; protected int mSelectedItem = -1; protected int mTask = 0; @@ -66,9 +73,49 @@ public class KeyListActivity extends BaseActivity { setContentView(R.layout.key_list); mList = (ExpandableListView) findViewById(R.id.list); - mListAdapter = new KeyListAdapter(this); - mList.setAdapter(mListAdapter); registerForContextMenu(mList); + + mFilterLayout = (View) findViewById(R.id.layout_filter); + mFilterInfo = (TextView) mFilterLayout.findViewById(R.id.filterInfo); + mClearFilterButton = (Button) mFilterLayout.findViewById(R.id.btn_clear); + + mClearFilterButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + handleIntent(new Intent()); + } + }); + + handleIntent(getIntent()); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + handleIntent(intent); + } + + private void handleIntent(Intent intent) { + String searchString = null; + if (Intent.ACTION_SEARCH.equals(intent.getAction())) { + searchString = intent.getStringExtra(SearchManager.QUERY); + if (searchString != null && searchString.trim().length() == 0) { + searchString = null; + } + } + + if (searchString == null) { + mFilterLayout.setVisibility(View.GONE); + } else { + mFilterLayout.setVisibility(View.VISIBLE); + mFilterInfo.setText(getString(R.string.filterInfo, searchString)); + } + + if (mListAdapter != null) { + mListAdapter.cleanup(); + } + mListAdapter = new KeyListAdapter(this, searchString); + mList.setAdapter(mListAdapter); } @Override @@ -371,6 +418,7 @@ public class KeyListActivity extends BaseActivity { private Vector> mChildren; private SQLiteDatabase mDatabase; private Cursor mCursor; + private String mSearchString; private class KeyChild { public static final int KEY = 0; @@ -401,11 +449,13 @@ public class KeyListActivity extends BaseActivity { } } - public KeyListAdapter(Context context) { + public KeyListAdapter(Context context, String searchString) { + mSearchString = searchString; + mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); mDatabase = Apg.getDatabase().db(); - mCursor = mDatabase.query( - KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + + SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); + qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + " AND " + Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" + @@ -413,7 +463,32 @@ public class KeyListActivity extends BaseActivity { " INNER JOIN " + UserIds.TABLE_NAME + " ON " + "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " + - UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') ", + UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0')"); + + if (searchString != null && searchString.trim().length() > 0) { + String[] chunks = searchString.trim().split(" +"); + qb.appendWhere("EXISTS (SELECT tmp." + UserIds._ID + " FROM " + + UserIds.TABLE_NAME + " AS tmp WHERE " + + "tmp." + UserIds.KEY_ID + " = " + + Keys.TABLE_NAME + "." + Keys._ID); + for (int i = 0; i < chunks.length; ++i) { + qb.appendWhere(" AND tmp." + UserIds.USER_ID + " LIKE "); + qb.appendWhereEscapeString("%" + chunks[i] + "%"); + } + qb.appendWhere(")"); + } + + String query = qb.buildQuery(new String[] { + KeyRings.TABLE_NAME + "." + KeyRings._ID, // 0 + KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 1 + UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 2 + }, + KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?", + new String[] { "" + (mKeyType == Id.type.public_key ? + Id.database.type_public : Id.database.type_secret) }, + null, null, UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC", null); + + mCursor = qb.query(mDatabase, new String[] { KeyRings.TABLE_NAME + "." + KeyRings._ID, // 0 KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 1 @@ -424,10 +499,33 @@ public class KeyListActivity extends BaseActivity { Id.database.type_public : Id.database.type_secret) }, null, null, UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC"); + // content provider way for reference, might have to go back to it sometime: + /*Uri contentUri = null; + if (mKeyType == Id.type.secret_key) { + contentUri = Apg.CONTENT_URI_SECRET_KEY_RINGS; + } else { + contentUri = Apg.CONTENT_URI_PUBLIC_KEY_RINGS; + } + mCursor = getContentResolver().query( + contentUri, + new String[] { + DataProvider._ID, // 0 + DataProvider.MASTER_KEY_ID, // 1 + DataProvider.USER_ID, // 2 + }, + null, null, null);*/ + startManagingCursor(mCursor); rebuild(false); } + public void cleanup() { + if (mCursor != null) { + stopManagingCursor(mCursor); + mCursor.close(); + } + } + public void rebuild(boolean requery) { if (requery) { mCursor.requery(); diff --git a/src/org/thialfihar/android/apg/SelectPublicKeyListActivity.java b/src/org/thialfihar/android/apg/SelectPublicKeyListActivity.java index aeb6d59a3..d9d9864c4 100644 --- a/src/org/thialfihar/android/apg/SelectPublicKeyListActivity.java +++ b/src/org/thialfihar/android/apg/SelectPublicKeyListActivity.java @@ -18,50 +18,32 @@ package org.thialfihar.android.apg; import java.util.Vector; +import android.app.SearchManager; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ListView; +import android.widget.TextView; public class SelectPublicKeyListActivity extends BaseActivity { - protected Intent mIntent; protected ListView mList; + protected SelectPublicKeyListAdapter mListAdapter; + protected View mFilterLayout; + protected Button mClearFilterButton; + protected TextView mFilterInfo; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.select_public_key); - // fill things - mIntent = getIntent(); - long selectedKeyIds[] = null; - if (mIntent.getExtras() != null) { - selectedKeyIds = mIntent.getExtras().getLongArray(Apg.EXTRA_SELECTION); - } - mList = (ListView) findViewById(R.id.list); // needed in Android 1.5, where the XML attribute gets ignored mList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); - SelectPublicKeyListAdapter adapter = new SelectPublicKeyListAdapter(this, mList); - mList.setAdapter(adapter); - - if (selectedKeyIds != null) { - for (int i = 0; i < adapter.getCount(); ++i) { - long keyId = adapter.getItemId(i); - for (int j = 0; j < selectedKeyIds.length; ++j) { - if (keyId == selectedKeyIds[j]) { - mList.setItemChecked(i, true); - break; - } - } - } - } - Button okButton = (Button) findViewById(R.id.btn_ok); - okButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { @@ -70,13 +52,85 @@ public class SelectPublicKeyListActivity extends BaseActivity { }); Button cancelButton = (Button) findViewById(R.id.btn_cancel); - cancelButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { cancelClicked(); } }); + + mFilterLayout = (View) findViewById(R.id.layout_filter); + mFilterInfo = (TextView) mFilterLayout.findViewById(R.id.filterInfo); + mClearFilterButton = (Button) mFilterLayout.findViewById(R.id.btn_clear); + + mClearFilterButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + handleIntent(new Intent()); + } + }); + + handleIntent(getIntent()); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + handleIntent(intent); + } + + private void handleIntent(Intent intent) { + String searchString = null; + if (Intent.ACTION_SEARCH.equals(intent.getAction())) { + searchString = intent.getStringExtra(SearchManager.QUERY); + if (searchString != null && searchString.trim().length() == 0) { + searchString = null; + } + } + + long selectedKeyIds[] = null; + if (getIntent().getExtras() != null) { + selectedKeyIds = getIntent().getExtras().getLongArray(Apg.EXTRA_SELECTION); + } + + if (selectedKeyIds == null) { + Vector vector = new Vector(); + for (int i = 0; i < mList.getCount(); ++i) { + if (mList.isItemChecked(i)) { + vector.add(mList.getItemIdAtPosition(i)); + } + } + selectedKeyIds = new long[vector.size()]; + for (int i = 0; i < vector.size(); ++i) { + selectedKeyIds[i] = vector.get(i); + } + } + + if (searchString == null) { + mFilterLayout.setVisibility(View.GONE); + } else { + mFilterLayout.setVisibility(View.VISIBLE); + mFilterInfo.setText(getString(R.string.filterInfo, searchString)); + } + + if (mListAdapter != null) { + mListAdapter.cleanup(); + } + + mListAdapter = new SelectPublicKeyListAdapter(this, mList, searchString, selectedKeyIds); + mList.setAdapter(mListAdapter); + + if (selectedKeyIds != null) { + for (int i = 0; i < mListAdapter.getCount(); ++i) { + long keyId = mListAdapter.getItemId(i); + for (int j = 0; j < selectedKeyIds.length; ++j) { + if (keyId == selectedKeyIds[j]) { + mList.setItemChecked(i, true); + break; + } + } + } + } } private void cancelClicked() { diff --git a/src/org/thialfihar/android/apg/SelectPublicKeyListAdapter.java b/src/org/thialfihar/android/apg/SelectPublicKeyListAdapter.java index ffc344ead..1b5a20d31 100644 --- a/src/org/thialfihar/android/apg/SelectPublicKeyListAdapter.java +++ b/src/org/thialfihar/android/apg/SelectPublicKeyListAdapter.java @@ -26,6 +26,7 @@ import android.app.Activity; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteQueryBuilder; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -39,14 +40,20 @@ public class SelectPublicKeyListAdapter extends BaseAdapter { protected ListView mParent; protected SQLiteDatabase mDatabase; protected Cursor mCursor; + protected String mSearchString; + protected Activity mActivity; - public SelectPublicKeyListAdapter(Activity activity, ListView parent) { + public SelectPublicKeyListAdapter(Activity activity, ListView parent, + String searchString, long selectedKeyIds[]) { + mSearchString = searchString; + + mActivity = activity; mParent = parent; mDatabase = Apg.getDatabase().db(); mInflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); long now = new Date().getTime() / 1000; - mCursor = mDatabase.query( - KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + + SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); + qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + " AND " + Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" + @@ -54,7 +61,36 @@ public class SelectPublicKeyListAdapter extends BaseAdapter { " INNER JOIN " + UserIds.TABLE_NAME + " ON " + "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " + - UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') ", + UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') "); + + if (searchString != null && searchString.trim().length() > 0) { + String[] chunks = searchString.trim().split(" +"); + qb.appendWhere("(EXISTS (SELECT tmp." + UserIds._ID + " FROM " + + UserIds.TABLE_NAME + " AS tmp WHERE " + + "tmp." + UserIds.KEY_ID + " = " + + Keys.TABLE_NAME + "." + Keys._ID); + for (int i = 0; i < chunks.length; ++i) { + qb.appendWhere(" AND tmp." + UserIds.USER_ID + " LIKE "); + qb.appendWhereEscapeString("%" + chunks[i] + "%"); + } + qb.appendWhere("))"); + + if (selectedKeyIds != null && selectedKeyIds.length > 0) { + qb.appendWhere(" OR "); + + qb.appendWhere("(" + KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID + + " IN ("); + for (int i = 0; i < selectedKeyIds.length; ++i) { + if (i != 0) { + qb.appendWhere(", "); + } + qb.appendWhereEscapeString("" + selectedKeyIds[i]); + } + qb.appendWhere("))"); + } + } + + mCursor = qb.query(mDatabase, new String[] { KeyRings.TABLE_NAME + "." + KeyRings._ID, // 0 KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 1 @@ -80,6 +116,13 @@ public class SelectPublicKeyListAdapter extends BaseAdapter { activity.startManagingCursor(mCursor); } + public void cleanup() { + if (mCursor != null) { + mActivity.stopManagingCursor(mCursor); + mCursor.close(); + } + } + @Override public boolean isEnabled(int position) { mCursor.moveToPosition(position); diff --git a/src/org/thialfihar/android/apg/SelectSecretKeyListActivity.java b/src/org/thialfihar/android/apg/SelectSecretKeyListActivity.java index cd87a94b6..be00e18f4 100644 --- a/src/org/thialfihar/android/apg/SelectSecretKeyListActivity.java +++ b/src/org/thialfihar/android/apg/SelectSecretKeyListActivity.java @@ -16,16 +16,23 @@ package org.thialfihar.android.apg; +import android.app.SearchManager; import android.content.Intent; import android.os.Bundle; import android.view.View; +import android.view.View.OnClickListener; import android.widget.AdapterView; +import android.widget.Button; import android.widget.ListView; +import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener; public class SelectSecretKeyListActivity extends BaseActivity { protected ListView mList; protected SelectSecretKeyListAdapter mListAdapter; + protected View mFilterLayout; + protected Button mClearFilterButton; + protected TextView mFilterInfo; protected long mSelectedKeyId = 0; @@ -36,8 +43,6 @@ public class SelectSecretKeyListActivity extends BaseActivity { setContentView(R.layout.select_secret_key); mList = (ListView) findViewById(R.id.list); - mListAdapter = new SelectSecretKeyListAdapter(this, mList); - mList.setAdapter(mListAdapter); mList.setOnItemClickListener(new OnItemClickListener() { @Override @@ -48,5 +53,48 @@ public class SelectSecretKeyListActivity extends BaseActivity { finish(); } }); + + mFilterLayout = (View) findViewById(R.id.layout_filter); + mFilterInfo = (TextView) mFilterLayout.findViewById(R.id.filterInfo); + mClearFilterButton = (Button) mFilterLayout.findViewById(R.id.btn_clear); + + mClearFilterButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + handleIntent(new Intent()); + } + }); + + handleIntent(getIntent()); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + handleIntent(intent); + } + + private void handleIntent(Intent intent) { + String searchString = null; + if (Intent.ACTION_SEARCH.equals(intent.getAction())) { + searchString = intent.getStringExtra(SearchManager.QUERY); + if (searchString != null && searchString.trim().length() == 0) { + searchString = null; + } + } + + if (searchString == null) { + mFilterLayout.setVisibility(View.GONE); + } else { + mFilterLayout.setVisibility(View.VISIBLE); + mFilterInfo.setText(getString(R.string.filterInfo, searchString)); + } + + if (mListAdapter != null) { + mListAdapter.cleanup(); + } + + mListAdapter = new SelectSecretKeyListAdapter(this, mList, searchString); + mList.setAdapter(mListAdapter); } } diff --git a/src/org/thialfihar/android/apg/SelectSecretKeyListAdapter.java b/src/org/thialfihar/android/apg/SelectSecretKeyListAdapter.java index 33cd15b40..d83c2aca6 100644 --- a/src/org/thialfihar/android/apg/SelectSecretKeyListAdapter.java +++ b/src/org/thialfihar/android/apg/SelectSecretKeyListAdapter.java @@ -10,6 +10,7 @@ import android.app.Activity; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteQueryBuilder; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -22,14 +23,19 @@ public class SelectSecretKeyListAdapter extends BaseAdapter { protected ListView mParent; protected SQLiteDatabase mDatabase; protected Cursor mCursor; + protected String mSearchString; + protected Activity mActivity; - public SelectSecretKeyListAdapter(Activity activity, ListView parent) { + public SelectSecretKeyListAdapter(Activity activity, ListView parent, String searchString) { + mSearchString = searchString; + + mActivity = activity; mParent = parent; mDatabase = Apg.getDatabase().db(); mInflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); long now = new Date().getTime() / 1000; - mCursor = mDatabase.query( - KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + + SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); + qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + " AND " + Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" + @@ -37,7 +43,22 @@ public class SelectSecretKeyListAdapter extends BaseAdapter { " INNER JOIN " + UserIds.TABLE_NAME + " ON " + "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " + - UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') ", + UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') "); + + if (searchString != null && searchString.trim().length() > 0) { + String[] chunks = searchString.trim().split(" +"); + qb.appendWhere("EXISTS (SELECT tmp." + UserIds._ID + " FROM " + + UserIds.TABLE_NAME + " AS tmp WHERE " + + "tmp." + UserIds.KEY_ID + " = " + + Keys.TABLE_NAME + "." + Keys._ID); + for (int i = 0; i < chunks.length; ++i) { + qb.appendWhere(" AND tmp." + UserIds.USER_ID + " LIKE "); + qb.appendWhereEscapeString("%" + chunks[i] + "%"); + } + qb.appendWhere(")"); + } + + mCursor = qb.query(mDatabase, new String[] { KeyRings.TABLE_NAME + "." + KeyRings._ID, // 0 KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 1 @@ -63,6 +84,13 @@ public class SelectSecretKeyListAdapter extends BaseAdapter { activity.startManagingCursor(mCursor); } + public void cleanup() { + if (mCursor != null) { + mActivity.stopManagingCursor(mCursor); + mCursor.close(); + } + } + @Override public boolean isEnabled(int position) { mCursor.moveToPosition(position); diff --git a/src/org/thialfihar/android/apg/provider/DataProvider.java b/src/org/thialfihar/android/apg/provider/DataProvider.java index 8a3fefdff..0667d82dd 100644 --- a/src/org/thialfihar/android/apg/provider/DataProvider.java +++ b/src/org/thialfihar/android/apg/provider/DataProvider.java @@ -72,6 +72,7 @@ public class DataProvider extends ContentProvider { private static final String USER_ID_CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.user_id"; + public static final String _ID = "_id"; public static final String MASTER_KEY_ID = "master_key_id"; public static final String KEY_ID = "key_id"; public static final String USER_ID = "user_id"; @@ -117,6 +118,7 @@ public class DataProvider extends ContentProvider { // TODO: implement the others, then use them for the lists SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); HashMap projectionMap = new HashMap(); + int match = mUriMatcher.match(uri); int type; switch (match) { @@ -148,28 +150,17 @@ public class DataProvider extends ContentProvider { qb.appendWhere(KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = " + type); switch (match) { - case PUBLIC_KEY_RINGS: - case SECRET_KEY_RINGS: { - qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + - "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + - Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + " AND " + - Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" + - ") " + - " INNER JOIN " + UserIds.TABLE_NAME + " ON " + - "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " + - UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " + - UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') "); - - projectionMap.put(MASTER_KEY_ID, - KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID); - projectionMap.put(USER_ID, - UserIds.TABLE_NAME + "." + UserIds.USER_ID); + case PUBLIC_KEY_RING_ID: + case SECRET_KEY_RING_ID: { + qb.appendWhere(" AND " + + KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(2)); - break; + // break omitted intentionally } - case PUBLIC_KEY_RING_ID: - case SECRET_KEY_RING_ID: { + case PUBLIC_KEY_RINGS: + case SECRET_KEY_RINGS: { qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + " AND " + @@ -180,14 +171,17 @@ public class DataProvider extends ContentProvider { UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " + UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') "); + projectionMap.put(_ID, + KeyRings.TABLE_NAME + "." + KeyRings._ID); projectionMap.put(MASTER_KEY_ID, KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID); projectionMap.put(USER_ID, UserIds.TABLE_NAME + "." + UserIds.USER_ID); - qb.appendWhere(" AND " + - KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID + " = "); - qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + if (TextUtils.isEmpty(sortOrder)) { + sortOrder = UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC"; + } + break; } @@ -207,6 +201,8 @@ public class DataProvider extends ContentProvider { UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " + UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') "); + projectionMap.put(_ID, + KeyRings.TABLE_NAME + "." + KeyRings._ID); projectionMap.put(MASTER_KEY_ID, KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID); projectionMap.put(USER_ID, -- cgit v1.2.3