From 4704e2faf4b5c342a811a91d780c077b05c6237b Mon Sep 17 00:00:00 2001 From: Dominik Date: Sun, 28 Oct 2012 23:51:03 +0100 Subject: more work on content provider --- .../android/apg/deprecated/BaseActivity.java | 4 +- .../android/apg/deprecated/KeyListActivity.java | 767 +++++++++++++++++++++ .../thialfihar/android/apg/helper/OtherHelper.java | 20 + .../android/apg/provider/ApgProvider.java | 178 +++-- .../android/apg/provider/ProviderHelper.java | 26 +- .../thialfihar/android/apg/ui/EditKeyActivity.java | 2 +- .../thialfihar/android/apg/ui/EncryptActivity.java | 4 +- .../thialfihar/android/apg/ui/KeyListActivity.java | 418 +---------- .../android/apg/ui/KeyListActivityOld.java | 767 +++++++++++++++++++++ .../android/apg/ui/KeyListPublicActivity.java | 189 +++++ .../android/apg/ui/KeyListPublicActivityOld.java | 198 ++++++ .../android/apg/ui/KeyListPublicFragment.java | 100 +++ .../android/apg/ui/KeyListSecretActivity.java | 199 ++++++ .../android/apg/ui/KeyListSecretActivityOld.java | 210 ++++++ .../android/apg/ui/KeyListSecretFragment.java | 94 +++ .../android/apg/ui/KeyServerQueryActivity.java | 8 +- .../android/apg/ui/KeyServerUploadActivity.java | 2 +- .../thialfihar/android/apg/ui/MainActivity.java | 4 +- .../android/apg/ui/PublicKeyListActivity.java | 198 ------ .../android/apg/ui/SecretKeyListActivity.java | 210 ------ .../apg/ui/SelectPublicKeyListActivity.java | 183 +---- .../apg/ui/SelectPublicKeyListActivityOld.java | 198 ++++++ .../apg/ui/SelectPublicKeyListFragment.java | 112 +++ .../apg/ui/SelectSecretKeyListActivity.java | 130 ---- .../apg/ui/SelectSecretKeyListActivityOld.java | 130 ++++ .../thialfihar/android/apg/ui/SignKeyActivity.java | 2 +- .../apg/ui/widget/ExpandableListFragment.java | 530 ++++++++++++++ .../android/apg/ui/widget/KeyListAdapter.java | 235 +++++++ .../ui/widget/SelectPublicKeyCursorAdapter.java | 136 ++++ .../apg/ui/widget/SelectPublicKeyListAdapter.java | 217 ------ .../ui/widget/SelectPublicKeyListAdapterOld.java | 218 ++++++ .../apg/ui/widget/SelectSecretKeyListAdapter.java | 182 ----- .../ui/widget/SelectSecretKeyListAdapterOld.java | 179 +++++ 33 files changed, 4468 insertions(+), 1582 deletions(-) create mode 100644 org_apg/src/org/thialfihar/android/apg/deprecated/KeyListActivity.java create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/KeyListActivityOld.java create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/KeyListPublicActivity.java create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/KeyListPublicActivityOld.java create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/KeyListPublicFragment.java create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/KeyListSecretActivity.java create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/KeyListSecretActivityOld.java create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/KeyListSecretFragment.java delete mode 100644 org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java delete mode 100644 org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivityOld.java create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListFragment.java delete mode 100644 org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivity.java create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivityOld.java create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/widget/ExpandableListFragment.java create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/widget/KeyListAdapter.java create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyCursorAdapter.java delete mode 100644 org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyListAdapter.java create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyListAdapterOld.java delete mode 100644 org_apg/src/org/thialfihar/android/apg/ui/widget/SelectSecretKeyListAdapter.java create mode 100644 org_apg/src/org/thialfihar/android/apg/ui/widget/SelectSecretKeyListAdapterOld.java (limited to 'org_apg/src') diff --git a/org_apg/src/org/thialfihar/android/apg/deprecated/BaseActivity.java b/org_apg/src/org/thialfihar/android/apg/deprecated/BaseActivity.java index 1763384fd..507647897 100644 --- a/org_apg/src/org/thialfihar/android/apg/deprecated/BaseActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/deprecated/BaseActivity.java @@ -24,7 +24,7 @@ import org.thialfihar.android.apg.Id; import org.thialfihar.android.apg.helper.PGPMain; import org.thialfihar.android.apg.helper.Preferences; import org.thialfihar.android.apg.ui.MainActivity; -import org.thialfihar.android.apg.ui.SelectSecretKeyListActivity; +import org.thialfihar.android.apg.ui.SelectSecretKeyListActivityOld; import org.thialfihar.android.apg.util.ProgressDialogUpdater; import com.actionbarsherlock.app.ActionBar; @@ -263,7 +263,7 @@ public class BaseActivity extends SherlockFragmentActivity implements Runnable, case Id.request.secret_keys: { if (resultCode == RESULT_OK) { Bundle bundle = data.getExtras(); - setSecretKeyId(bundle.getLong(SelectSecretKeyListActivity.RESULT_EXTRA_KEY_ID)); + setSecretKeyId(bundle.getLong(SelectSecretKeyListActivityOld.RESULT_EXTRA_KEY_ID)); } else { setSecretKeyId(Id.key.none); } diff --git a/org_apg/src/org/thialfihar/android/apg/deprecated/KeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/deprecated/KeyListActivity.java new file mode 100644 index 000000000..755382bf2 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/deprecated/KeyListActivity.java @@ -0,0 +1,767 @@ +///* +// * Copyright (C) 2012 Dominik Schürmann +// * Copyright (C) 2010 Thialfihar +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +// +//package org.thialfihar.android.apg.deprecated; +// +//import org.thialfihar.android.apg.Constants; +//import org.thialfihar.android.apg.Id; +//import org.thialfihar.android.apg.helper.OtherHelper; +//import org.thialfihar.android.apg.helper.PGPHelper; +//import org.thialfihar.android.apg.helper.PGPMain; +//import org.thialfihar.android.apg.provider.KeyRings; +//import org.thialfihar.android.apg.provider.Keys; +//import org.thialfihar.android.apg.provider.UserIds; +//import org.thialfihar.android.apg.service.ApgServiceHandler; +//import org.thialfihar.android.apg.service.ApgService; +//import org.thialfihar.android.apg.ui.dialog.DeleteFileDialogFragment; +//import org.thialfihar.android.apg.ui.dialog.DeleteKeyDialogFragment; +//import org.thialfihar.android.apg.ui.dialog.FileDialogFragment; +//import org.thialfihar.android.apg.R; +// +//import com.actionbarsherlock.app.SherlockFragmentActivity; +//import com.actionbarsherlock.view.MenuItem; +// +//import android.app.AlertDialog; +//import android.app.ProgressDialog; +//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.os.Bundle; +//import android.os.Handler; +//import android.os.Message; +//import android.os.Messenger; +//import org.thialfihar.android.apg.util.Log; +//import android.view.LayoutInflater; +//import android.view.View; +//import android.view.View.OnClickListener; +//import android.view.ViewGroup; +//import android.widget.BaseExpandableListAdapter; +//import android.widget.Button; +//import android.widget.ExpandableListView; +//import android.widget.ExpandableListView.ExpandableListContextMenuInfo; +//import android.widget.ImageView; +//import android.widget.TextView; +//import android.widget.Toast; +// +//import java.util.Vector; +// +//public class KeyListActivity extends SherlockFragmentActivity { +// +// public static final String ACTION_IMPORT = Constants.INTENT_PREFIX + "IMPORT"; +// +// public static final String EXTRA_TEXT = "text"; +// +// protected ExpandableListView mList; +// protected KeyListAdapter mListAdapter; +// protected View mFilterLayout; +// protected Button mClearFilterButton; +// protected TextView mFilterInfo; +// +// protected int mSelectedItem = -1; +// protected int mTask = 0; +// +// protected String mImportFilename = Constants.path.APP_DIR + "/"; +// protected String mExportFilename = Constants.path.APP_DIR + "/"; +// +// protected String mImportData; +// protected boolean mDeleteAfterImport = false; +// +// protected int mKeyType = Id.type.public_key; +// +// FileDialogFragment mFileDialog; +// +// @Override +// public void onCreate(Bundle savedInstanceState) { +// super.onCreate(savedInstanceState); +// setContentView(R.layout.key_list); +// +// // set actionbar without home button if called from another app +// OtherHelper.setActionBarBackButton(this); +// +// setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); +// +// mList = (ExpandableListView) findViewById(R.id.list); +// registerForContextMenu(mList); +// +// mFilterLayout = findViewById(R.id.layout_filter); +// mFilterInfo = (TextView) mFilterLayout.findViewById(R.id.filterInfo); +// mClearFilterButton = (Button) mFilterLayout.findViewById(R.id.btn_clear); +// +// mClearFilterButton.setOnClickListener(new OnClickListener() { +// public void onClick(View v) { +// handleIntent(new Intent()); +// } +// }); +// +// handleIntent(getIntent()); +// } +// +// @Override +// protected void onNewIntent(Intent intent) { +// super.onNewIntent(intent); +// handleIntent(intent); +// } +// +// protected 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); +// +// // Get intent, action +// // Intent intent = getIntent(); +// String action = intent.getAction(); +// +// if (Intent.ACTION_VIEW.equals(action)) { +// // Android's Action when opening file associated to APG (see AndroidManifest.xml) +// +// handleActionImport(intent); +// } else if (ACTION_IMPORT.equals(action)) { +// // APG's own Actions +// +// handleActionImport(intent); +// } +// } +// +// /** +// * Handles import action +// * +// * @param intent +// */ +// private void handleActionImport(Intent intent) { +// if ("file".equals(intent.getScheme()) && intent.getDataString() != null) { +// mImportFilename = intent.getData().getPath(); +// } else { +// mImportData = intent.getStringExtra(EXTRA_TEXT); +// } +// importKeys(); +// } +// +// @Override +// public boolean onOptionsItemSelected(MenuItem item) { +// switch (item.getItemId()) { +// +// case android.R.id.home: +// // app icon in Action Bar clicked; go home +// Intent intent = new Intent(this, MainActivity.class); +// intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); +// startActivity(intent); +// return true; +// +// case Id.menu.option.import_keys: { +// showImportKeysDialog(); +// return true; +// } +// +// case Id.menu.option.export_keys: { +// showExportKeysDialog(false); +// return true; +// } +// +// case Id.menu.option.search: +// startSearch("", false, null, false); +// return true; +// +// default: { +// return super.onOptionsItemSelected(item); +// } +// } +// } +// +// private void showImportKeysDialog() { +// // Message is received after file is selected +// Handler returnHandler = new Handler() { +// @Override +// public void handleMessage(Message message) { +// if (message.what == FileDialogFragment.MESSAGE_OKAY) { +// Bundle data = message.getData(); +// mImportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); +// +// mDeleteAfterImport = data.getBoolean(FileDialogFragment.MESSAGE_DATA_CHECKED); +// importKeys(); +// } +// } +// }; +// +// // Create a new Messenger for the communication back +// Messenger messenger = new Messenger(returnHandler); +// +// mFileDialog = FileDialogFragment.newInstance(messenger, +// getString(R.string.title_importKeys), getString(R.string.specifyFileToImportFrom), +// mImportFilename, null, Id.request.filename); +// +// mFileDialog.show(getSupportFragmentManager(), "fileDialog"); +// } +// +// private void showExportKeysDialog(boolean singleKeyExport) { +// String title = (singleKeyExport ? getString(R.string.title_exportKey) +// : getString(R.string.title_exportKeys)); +// String message = getString(mKeyType == Id.type.public_key ? R.string.specifyFileToExportTo +// : R.string.specifyFileToExportSecretKeysTo); +// +// // Message is received after file is selected +// Handler returnHandler = new Handler() { +// @Override +// public void handleMessage(Message message) { +// if (message.what == FileDialogFragment.MESSAGE_OKAY) { +// Bundle data = message.getData(); +// mExportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); +// +// exportKeys(); +// } +// } +// }; +// +// // Create a new Messenger for the communication back +// Messenger messenger = new Messenger(returnHandler); +// +// mFileDialog = FileDialogFragment.newInstance(messenger, title, message, mExportFilename, +// null, Id.request.filename); +// +// mFileDialog.show(getSupportFragmentManager(), "fileDialog"); +// } +// +// @Override +// public boolean onContextItemSelected(android.view.MenuItem menuItem) { +// ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuItem.getMenuInfo(); +// int type = ExpandableListView.getPackedPositionType(info.packedPosition); +// int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition); +// +// if (type != ExpandableListView.PACKED_POSITION_TYPE_GROUP) { +// return super.onContextItemSelected(menuItem); +// } +// +// switch (menuItem.getItemId()) { +// case Id.menu.export: { +// mSelectedItem = groupPosition; +// showExportKeysDialog(true); +// return true; +// } +// +// case Id.menu.delete: { +// mSelectedItem = groupPosition; +// showDeleteKeyDialog(); +// return true; +// } +// +// default: { +// return super.onContextItemSelected(menuItem); +// } +// } +// } +// +// private void showDeleteKeyDialog() { +// final int keyRingId = mListAdapter.getKeyRingId(mSelectedItem); +// mSelectedItem = -1; +// +// // Message is received after key is deleted +// Handler returnHandler = new Handler() { +// @Override +// public void handleMessage(Message message) { +// if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) { +// refreshList(); +// } +// } +// }; +// +// // Create a new Messenger for the communication back +// Messenger messenger = new Messenger(returnHandler); +// +// DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger, +// keyRingId, mKeyType); +// +// deleteKeyDialog.show(getSupportFragmentManager(), "deleteKeyDialog"); +// } +// +// public void importKeys() { +// Log.d(Constants.TAG, "importKeys started"); +// +// // Send all information needed to service to import key in other thread +// Intent intent = new Intent(this, ApgService.class); +// +// intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_IMPORT_KEY); +// +// // fill values for this action +// Bundle data = new Bundle(); +// +// data.putInt(ApgService.IMPORT_KEY_TYPE, mKeyType); +// +// if (mImportData != null) { +// data.putInt(ApgService.TARGET, ApgService.TARGET_BYTES); +// data.putByteArray(ApgService.IMPORT_BYTES, mImportData.getBytes()); +// } else { +// data.putInt(ApgService.TARGET, ApgService.TARGET_FILE); +// data.putString(ApgService.IMPORT_FILENAME, mImportFilename); +// } +// +// intent.putExtra(ApgService.EXTRA_DATA, data); +// +// // Message is received after importing is done in ApgService +// ApgServiceHandler saveHandler = new ApgServiceHandler(this, R.string.progress_importing, +// ProgressDialog.STYLE_HORIZONTAL) { +// public void handleMessage(Message message) { +// // handle messages by standard ApgHandler first +// super.handleMessage(message); +// +// if (message.arg1 == ApgServiceHandler.MESSAGE_OKAY) { +// // get returned data bundle +// Bundle returnData = message.getData(); +// +// int added = returnData.getInt(ApgService.RESULT_IMPORT_ADDED); +// int updated = returnData.getInt(ApgService.RESULT_IMPORT_UPDATED); +// int bad = returnData.getInt(ApgService.RESULT_IMPORT_BAD); +// String toastMessage; +// if (added > 0 && updated > 0) { +// toastMessage = getString(R.string.keysAddedAndUpdated, added, updated); +// } else if (added > 0) { +// toastMessage = getString(R.string.keysAdded, added); +// } else if (updated > 0) { +// toastMessage = getString(R.string.keysUpdated, updated); +// } else { +// toastMessage = getString(R.string.noKeysAddedOrUpdated); +// } +// Toast.makeText(KeyListActivity.this, toastMessage, Toast.LENGTH_SHORT).show(); +// if (bad > 0) { +// AlertDialog.Builder alert = new AlertDialog.Builder(KeyListActivity.this); +// +// alert.setIcon(android.R.drawable.ic_dialog_alert); +// alert.setTitle(R.string.warning); +// alert.setMessage(KeyListActivity.this.getString( +// R.string.badKeysEncountered, bad)); +// +// alert.setPositiveButton(android.R.string.ok, +// new DialogInterface.OnClickListener() { +// public void onClick(DialogInterface dialog, int id) { +// dialog.cancel(); +// } +// }); +// alert.setCancelable(true); +// alert.create().show(); +// } else if (mDeleteAfterImport) { +// // everything went well, so now delete, if that was turned on +// DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment +// .newInstance(mImportFilename); +// deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog"); +// } +// refreshList(); +// +// } +// }; +// }; +// +// // Create a new Messenger for the communication back +// Messenger messenger = new Messenger(saveHandler); +// intent.putExtra(ApgService.EXTRA_MESSENGER, messenger); +// +// // show progress dialog +// saveHandler.showProgressDialog(this); +// +// // start service with intent +// startService(intent); +// } +// +// public void exportKeys() { +// Log.d(Constants.TAG, "exportKeys started"); +// +// // Send all information needed to service to export key in other thread +// Intent intent = new Intent(this, ApgService.class); +// +// intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_EXPORT_KEY); +// +// // fill values for this action +// Bundle data = new Bundle(); +// +// data.putString(ApgService.EXPORT_FILENAME, mExportFilename); +// data.putInt(ApgService.EXPORT_KEY_TYPE, mKeyType); +// +// if (mSelectedItem == -1) { +// data.putBoolean(ApgService.EXPORT_ALL, true); +// } else { +// int keyRingId = mListAdapter.getKeyRingId(mSelectedItem); +// data.putInt(ApgService.EXPORT_KEY_RING_ID, keyRingId); +// mSelectedItem = -1; +// } +// +// intent.putExtra(ApgService.EXTRA_DATA, data); +// +// // Message is received after exporting is done in ApgService +// ApgServiceHandler exportHandler = new ApgServiceHandler(this, R.string.progress_exporting, +// ProgressDialog.STYLE_HORIZONTAL) { +// public void handleMessage(Message message) { +// // handle messages by standard ApgHandler first +// super.handleMessage(message); +// +// if (message.arg1 == ApgServiceHandler.MESSAGE_OKAY) { +// // get returned data bundle +// Bundle returnData = message.getData(); +// +// int exported = returnData.getInt(ApgService.RESULT_EXPORT); +// String toastMessage; +// if (exported == 1) { +// toastMessage = getString(R.string.keyExported); +// } else if (exported > 0) { +// toastMessage = getString(R.string.keysExported, exported); +// } else { +// toastMessage = getString(R.string.noKeysExported); +// } +// Toast.makeText(KeyListActivity.this, toastMessage, Toast.LENGTH_SHORT).show(); +// +// } +// }; +// }; +// +// // Create a new Messenger for the communication back +// Messenger messenger = new Messenger(exportHandler); +// intent.putExtra(ApgService.EXTRA_MESSENGER, messenger); +// +// // show progress dialog +// exportHandler.showProgressDialog(this); +// +// // start service with intent +// startService(intent); +// } +// +// protected void refreshList() { +// mListAdapter.rebuild(true); +// mListAdapter.notifyDataSetChanged(); +// } +// +// protected class KeyListAdapter extends BaseExpandableListAdapter { +// private LayoutInflater mInflater; +// private Vector> mChildren; +// private SQLiteDatabase mDatabase; +// private Cursor mCursor; +// private String mSearchString; +// +// private class KeyChild { +// public static final int KEY = 0; +// public static final int USER_ID = 1; +// public static final int FINGER_PRINT = 2; +// +// public int type; +// public String userId; +// public long keyId; +// public boolean isMasterKey; +// public int algorithm; +// public int keySize; +// public boolean canSign; +// public boolean canEncrypt; +// public String fingerPrint; +// +// public KeyChild(long keyId, boolean isMasterKey, int algorithm, int keySize, +// boolean canSign, boolean canEncrypt) { +// this.type = KEY; +// this.keyId = keyId; +// this.isMasterKey = isMasterKey; +// this.algorithm = algorithm; +// this.keySize = keySize; +// this.canSign = canSign; +// this.canEncrypt = canEncrypt; +// } +// +// public KeyChild(String userId) { +// type = USER_ID; +// this.userId = userId; +// } +// +// public KeyChild(String fingerPrint, boolean isFingerPrint) { +// type = FINGER_PRINT; +// this.fingerPrint = fingerPrint; +// } +// } +// +// public KeyListAdapter(Context context, String searchString) { +// mSearchString = searchString; +// +// mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); +// mDatabase = PGPMain.getDatabase().db(); +// 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'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME + " ON " + "(" +// + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." +// + UserIds.KEY_ID + " AND " + 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 +// 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"); +// +// // 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(); +// } +// mChildren = new Vector>(); +// for (int i = 0; i < mCursor.getCount(); ++i) { +// mChildren.add(null); +// } +// } +// +// protected Vector getChildrenOfGroup(int groupPosition) { +// Vector children = mChildren.get(groupPosition); +// if (children != null) { +// return children; +// } +// +// mCursor.moveToPosition(groupPosition); +// children = new Vector(); +// Cursor c = mDatabase.query(Keys.TABLE_NAME, new String[] { Keys._ID, // 0 +// Keys.KEY_ID, // 1 +// Keys.IS_MASTER_KEY, // 2 +// Keys.ALGORITHM, // 3 +// Keys.KEY_SIZE, // 4 +// Keys.CAN_SIGN, // 5 +// Keys.CAN_ENCRYPT, // 6 +// }, Keys.KEY_RING_ID + " = ?", new String[] { mCursor.getString(0) }, null, null, +// Keys.RANK + " ASC"); +// +// int masterKeyId = -1; +// long fingerPrintId = -1; +// for (int i = 0; i < c.getCount(); ++i) { +// c.moveToPosition(i); +// children.add(new KeyChild(c.getLong(1), c.getInt(2) == 1, c.getInt(3), c.getInt(4), +// c.getInt(5) == 1, c.getInt(6) == 1)); +// if (i == 0) { +// masterKeyId = c.getInt(0); +// fingerPrintId = c.getLong(1); +// } +// } +// c.close(); +// +// if (masterKeyId != -1) { +// children.insertElementAt( +// new KeyChild(PGPHelper.getFingerPrint(KeyListActivity.this, fingerPrintId), true), 0); +// c = mDatabase.query(UserIds.TABLE_NAME, new String[] { UserIds.USER_ID, // 0 +// }, UserIds.KEY_ID + " = ? AND " + UserIds.RANK + " > 0", new String[] { "" +// + masterKeyId }, null, null, UserIds.RANK + " ASC"); +// +// for (int i = 0; i < c.getCount(); ++i) { +// c.moveToPosition(i); +// children.add(new KeyChild(c.getString(0))); +// } +// c.close(); +// } +// +// mChildren.set(groupPosition, children); +// return children; +// } +// +// public boolean hasStableIds() { +// return true; +// } +// +// public boolean isChildSelectable(int groupPosition, int childPosition) { +// return true; +// } +// +// public int getGroupCount() { +// return mCursor.getCount(); +// } +// +// public Object getChild(int groupPosition, int childPosition) { +// return null; +// } +// +// public long getChildId(int groupPosition, int childPosition) { +// return childPosition; +// } +// +// public int getChildrenCount(int groupPosition) { +// return getChildrenOfGroup(groupPosition).size(); +// } +// +// public Object getGroup(int position) { +// return position; +// } +// +// public long getGroupId(int position) { +// mCursor.moveToPosition(position); +// return mCursor.getLong(1); // MASTER_KEY_ID +// } +// +// public int getKeyRingId(int position) { +// mCursor.moveToPosition(position); +// return mCursor.getInt(0); // _ID +// } +// +// public View getGroupView(int groupPosition, boolean isExpanded, View convertView, +// ViewGroup parent) { +// mCursor.moveToPosition(groupPosition); +// +// View view = mInflater.inflate(R.layout.key_list_group_item, null); +// view.setBackgroundResource(android.R.drawable.list_selector_background); +// +// TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId); +// mainUserId.setText(""); +// TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest); +// mainUserIdRest.setText(""); +// +// String userId = mCursor.getString(2); // USER_ID +// if (userId != null) { +// String chunks[] = userId.split(" <", 2); +// userId = chunks[0]; +// if (chunks.length > 1) { +// mainUserIdRest.setText("<" + chunks[1]); +// } +// mainUserId.setText(userId); +// } +// +// if (mainUserId.getText().length() == 0) { +// mainUserId.setText(R.string.unknownUserId); +// } +// +// if (mainUserIdRest.getText().length() == 0) { +// mainUserIdRest.setVisibility(View.GONE); +// } +// return view; +// } +// +// public View getChildView(int groupPosition, int childPosition, boolean isLastChild, +// View convertView, ViewGroup parent) { +// mCursor.moveToPosition(groupPosition); +// +// Vector children = getChildrenOfGroup(groupPosition); +// +// KeyChild child = children.get(childPosition); +// View view = null; +// switch (child.type) { +// case KeyChild.KEY: { +// if (child.isMasterKey) { +// view = mInflater.inflate(R.layout.key_list_child_item_master_key, null); +// } else { +// view = mInflater.inflate(R.layout.key_list_child_item_sub_key, null); +// } +// +// TextView keyId = (TextView) view.findViewById(R.id.keyId); +// String keyIdStr = PGPHelper.getSmallFingerPrint(child.keyId); +// keyId.setText(keyIdStr); +// TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails); +// String algorithmStr = PGPHelper.getAlgorithmInfo(child.algorithm, child.keySize); +// keyDetails.setText("(" + algorithmStr + ")"); +// +// ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey); +// if (!child.canEncrypt) { +// encryptIcon.setVisibility(View.GONE); +// } +// +// ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey); +// if (!child.canSign) { +// signIcon.setVisibility(View.GONE); +// } +// break; +// } +// +// case KeyChild.USER_ID: { +// view = mInflater.inflate(R.layout.key_list_child_item_user_id, null); +// TextView userId = (TextView) view.findViewById(R.id.userId); +// userId.setText(child.userId); +// break; +// } +// +// case KeyChild.FINGER_PRINT: { +// view = mInflater.inflate(R.layout.key_list_child_item_user_id, null); +// TextView userId = (TextView) view.findViewById(R.id.userId); +// userId.setText(getString(R.string.fingerprint) + ":\n" +// + child.fingerPrint.replace(" ", "\n")); +// break; +// } +// } +// return view; +// } +// } +// +// @Override +// protected void onActivityResult(int requestCode, int resultCode, Intent data) { +// switch (requestCode) { +// case Id.request.filename: { +// if (resultCode == RESULT_OK && data != null) { +// try { +// String path = data.getData().getPath(); +// Log.d(Constants.TAG, "path=" + path); +// +// mFileDialog.setFilename(path); +// } catch (NullPointerException e) { +// Log.e(Constants.TAG, "Nullpointer while retrieving path!", e); +// } +// } +// return; +// } +// +// default: { +// break; +// } +// } +// super.onActivityResult(requestCode, resultCode, data); +// } +//} diff --git a/org_apg/src/org/thialfihar/android/apg/helper/OtherHelper.java b/org_apg/src/org/thialfihar/android/apg/helper/OtherHelper.java index 0d2f060dd..5323289bf 100644 --- a/org_apg/src/org/thialfihar/android/apg/helper/OtherHelper.java +++ b/org_apg/src/org/thialfihar/android/apg/helper/OtherHelper.java @@ -131,4 +131,24 @@ public class OtherHelper { actionBar.setHomeButtonEnabled(false); } } + + /** + * Splits userId string into naming part and email part + * + * @param userId + * @return array with naming (0) and email (1) + */ + public static String[] splitUserId(String userId) { + String[] output = new String[2]; + + String chunks[] = userId.split(" <", 2); + userId = chunks[0]; + if (chunks.length > 1) { + output[1] = "<" + chunks[1]; + } + output[0] = userId; + + return output; + } + } diff --git a/org_apg/src/org/thialfihar/android/apg/provider/ApgProvider.java b/org_apg/src/org/thialfihar/android/apg/provider/ApgProvider.java index fce03600d..bbf5de803 100644 --- a/org_apg/src/org/thialfihar/android/apg/provider/ApgProvider.java +++ b/org_apg/src/org/thialfihar/android/apg/provider/ApgProvider.java @@ -298,6 +298,29 @@ public class ApgProvider extends ContentProvider { return type; } + private SQLiteQueryBuilder buildKeyRingQuery(SQLiteQueryBuilder qb, + HashMap projectionMap, int match, String sortOrder) { + qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = "); + qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); + + qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.KEYS + " ON " + "(" + + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.KEYS + "." + + KeysColumns.KEY_RING_ROW_ID + " AND " + Tables.KEYS + "." + + KeysColumns.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + Tables.USER_IDS + + " ON " + "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + + "." + UserIdsColumns.KEY_RING_ROW_ID + " AND " + Tables.USER_IDS + "." + + UserIdsColumns.RANK + " = '0')"); + + projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS + "." + BaseColumns._ID); + projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "." + + KeyRingsColumns.MASTER_KEY_ID); + projectionMap.put(UserIdsColumns.USER_ID, Tables.USER_IDS + "." + UserIdsColumns.USER_ID); + + qb.setProjectionMap(projectionMap); + + return qb; + } + /** {@inheritDoc} */ @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, @@ -312,39 +335,34 @@ public class ApgProvider extends ContentProvider { int match = sUriMatcher.match(uri); switch (match) { + case PUBLIC_KEY_RING: + case SECRET_KEY_RING: + qb = buildKeyRingQuery(qb, projectionMap, match, sortOrder); + if (TextUtils.isEmpty(sortOrder)) { + sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; + } + + break; + case PUBLIC_KEY_RING_BY_ROW_ID: case SECRET_KEY_RING_BY_ROW_ID: - qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = " - + getKeyType(match)); + qb = buildKeyRingQuery(qb, projectionMap, match, sortOrder); - qb.appendWhere(Tables.KEY_RINGS + "." + BaseColumns._ID + " = "); + qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + BaseColumns._ID + " = "); qb.appendWhereEscapeString(uri.getLastPathSegment()); - // break omitted intentionally + if (TextUtils.isEmpty(sortOrder)) { + sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; + } + + break; case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: case SECRET_KEY_RING_BY_MASTER_KEY_ID: - qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID + " = "); - qb.appendWhereEscapeString(uri.getLastPathSegment()); - - // break omitted intentionally - - case PUBLIC_KEY_RING: - case SECRET_KEY_RING: - - qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.KEYS + " ON " + "(" - + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.KEYS + "." - + KeysColumns.KEY_RING_ROW_ID + " AND " + Tables.KEYS + "." - + KeysColumns.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " - + Tables.USER_IDS + " ON " + "(" + Tables.KEYS + "." + BaseColumns._ID + " = " - + Tables.USER_IDS + "." + UserIdsColumns.KEY_RING_ROW_ID + " AND " - + Tables.USER_IDS + "." + UserIdsColumns.RANK + " = '0') "); + qb = buildKeyRingQuery(qb, projectionMap, match, sortOrder); - projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS + "." + BaseColumns._ID); - projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "." - + KeyRingsColumns.MASTER_KEY_ID); - projectionMap.put(UserIdsColumns.USER_ID, Tables.USER_IDS + "." - + UserIdsColumns.USER_ID); + qb.appendWhere(" AND " + Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); if (TextUtils.isEmpty(sortOrder)) { sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; @@ -354,8 +372,8 @@ public class ApgProvider extends ContentProvider { case SECRET_KEY_RING_BY_KEY_ID: case PUBLIC_KEY_RING_BY_KEY_ID: - qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = " - + getKeyType(match)); + qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = "); + qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); qb.setTables(Tables.KEYS + " AS tmp INNER JOIN " + Tables.KEY_RINGS + " ON (" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + "tmp." @@ -363,9 +381,9 @@ public class ApgProvider extends ContentProvider { + "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.KEYS + "." + KeysColumns.KEY_RING_ROW_ID + " AND " + Tables.KEYS + "." + KeysColumns.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " - + Tables.USER_IDS + " ON " + "(" + Tables.KEYS + "." + BaseColumns._ID + " = " - + Tables.USER_IDS + "." + UserIdsColumns.KEY_RING_ROW_ID + " AND " - + Tables.USER_IDS + "." + UserIdsColumns.RANK + " = '0') "); + + Tables.USER_IDS + " ON " + "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + + " = " + Tables.USER_IDS + "." + UserIdsColumns.KEY_RING_ROW_ID + " AND " + + Tables.USER_IDS + "." + UserIdsColumns.RANK + " = '0')"); projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS + "." + BaseColumns._ID); projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "." @@ -373,15 +391,17 @@ public class ApgProvider extends ContentProvider { projectionMap.put(UserIdsColumns.USER_ID, Tables.USER_IDS + "." + UserIdsColumns.USER_ID); - qb.appendWhere("tmp." + KeysColumns.KEY_ID + " = "); + qb.setProjectionMap(projectionMap); + + qb.appendWhere(" AND tmp." + KeysColumns.KEY_ID + " = "); qb.appendWhereEscapeString(uri.getLastPathSegment()); break; case SECRET_KEY_RING_BY_EMAILS: case PUBLIC_KEY_RING_BY_EMAILS: - qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = " - + getKeyType(match)); + qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = "); + qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.KEYS + " ON " + "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.KEYS + "." @@ -389,7 +409,7 @@ public class ApgProvider extends ContentProvider { + KeysColumns.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " + Tables.USER_IDS + " ON " + "(" + Tables.KEYS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + "." + UserIdsColumns.KEY_RING_ROW_ID + " AND " - + Tables.USER_IDS + "." + UserIdsColumns.RANK + " = '0') "); + + Tables.USER_IDS + "." + UserIdsColumns.RANK + " = '0')"); projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS + "." + BaseColumns._ID); projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "." @@ -397,6 +417,8 @@ public class ApgProvider extends ContentProvider { projectionMap.put(UserIdsColumns.USER_ID, Tables.USER_IDS + "." + UserIdsColumns.USER_ID); + qb.setProjectionMap(projectionMap); + String emails = uri.getLastPathSegment(); String chunks[] = emails.split(" *, *"); boolean gotCondition = false; @@ -415,43 +437,55 @@ public class ApgProvider extends ContentProvider { } if (gotCondition) { - qb.appendWhere("EXISTS (SELECT tmp." + BaseColumns._ID + " FROM " + Tables.USER_IDS - + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID + " = " - + Tables.KEYS + "." + BaseColumns._ID + " AND (" + emailWhere + "))"); + qb.appendWhere(" AND EXISTS (SELECT tmp." + BaseColumns._ID + " FROM " + + Tables.USER_IDS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID + + " = " + Tables.KEYS + "." + BaseColumns._ID + " AND (" + emailWhere + + "))"); } break; - case PUBLIC_KEY_RING_KEY_BY_ROW_ID: - case SECRET_KEY_RING_KEY_BY_ROW_ID: - String keyRowId = uri.getLastPathSegment(); - qb.appendWhere(BaseColumns._ID + " = " + keyRowId); - - // break omitted intentionally - case PUBLIC_KEY_RING_KEY: case SECRET_KEY_RING_KEY: qb.setTables(Tables.KEYS); - qb.appendWhere(KeysColumns.TYPE + " = " + getKeyType(match)); + qb.appendWhere(KeysColumns.TYPE + " = "); + qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); - String foreignKeyRingRowId = uri.getPathSegments().get(2); - qb.appendWhere(KeysColumns.KEY_RING_ROW_ID + " = " + foreignKeyRingRowId); + qb.appendWhere(" AND " + KeysColumns.KEY_RING_ROW_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(2)); break; - case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: - case SECRET_KEY_RING_USER_ID_BY_ROW_ID: - String userIdRowId = uri.getLastPathSegment(); - qb.appendWhere(BaseColumns._ID + " = " + userIdRowId); + case PUBLIC_KEY_RING_KEY_BY_ROW_ID: + case SECRET_KEY_RING_KEY_BY_ROW_ID: + qb.setTables(Tables.KEYS); + qb.appendWhere(KeysColumns.TYPE + " = "); + qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); - // break omitted intentionally + qb.appendWhere(" AND " + KeysColumns.KEY_RING_ROW_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + + qb.appendWhere(" AND " + BaseColumns._ID + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); + + break; case PUBLIC_KEY_RING_USER_ID: case SECRET_KEY_RING_USER_ID: qb.setTables(Tables.USER_IDS); + qb.appendWhere(UserIdsColumns.KEY_RING_ROW_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(2)); + + break; + + case PUBLIC_KEY_RING_USER_ID_BY_ROW_ID: + case SECRET_KEY_RING_USER_ID_BY_ROW_ID: + qb.setTables(Tables.USER_IDS); + qb.appendWhere(UserIdsColumns.KEY_RING_ROW_ID + " = "); + qb.appendWhereEscapeString(uri.getPathSegments().get(2)); - String foreignKeyRowId = uri.getPathSegments().get(2); - qb.appendWhere(UserIdsColumns.KEY_RING_ROW_ID + " = " + foreignKeyRowId); + qb.appendWhere(" AND " + BaseColumns._ID + " = "); + qb.appendWhereEscapeString(uri.getLastPathSegment()); break; @@ -460,8 +494,6 @@ public class ApgProvider extends ContentProvider { } - qb.setProjectionMap(projectionMap); - // If no sort order is specified use the default String orderBy; if (TextUtils.isEmpty(sortOrder)) { @@ -474,6 +506,15 @@ public class ApgProvider extends ContentProvider { // Tell the cursor what uri to watch, so it knows when its source data changes c.setNotificationUri(getContext().getContentResolver(), uri); + + if (Constants.DEBUG) { + Log.d(Constants.TAG, + "Query: " + + qb.buildQuery(projection, selection, selectionArgs, null, null, + orderBy, null)); + Log.d(Constants.TAG, "Cursor: " + DatabaseUtils.dumpCursorToString(c)); + } + return c; } @@ -485,6 +526,7 @@ public class ApgProvider extends ContentProvider { final SQLiteDatabase db = mApgDatabase.getWritableDatabase(); Uri rowUri = null; + long rowId = -1; try { final int match = sUriMatcher.match(uri); @@ -492,41 +534,39 @@ public class ApgProvider extends ContentProvider { case PUBLIC_KEY_RING: values.put(PublicKeyRings.TYPE, KeyTypes.PUBLIC); - db.insertOrThrow(Tables.KEY_RINGS, null, values); - rowUri = PublicKeyRings.buildPublicKeyRingsUri(values - .getAsString(PublicKeyRings._ID)); + rowId = db.insertOrThrow(Tables.KEY_RINGS, null, values); + rowUri = PublicKeyRings.buildPublicKeyRingsUri(Long.toString(rowId)); break; case PUBLIC_KEY_RING_KEY: values.put(PublicKeys.TYPE, KeyTypes.PUBLIC); - db.insertOrThrow(Tables.KEYS, null, values); - rowUri = PublicKeys.buildPublicKeysUri(values.getAsString(PublicKeys._ID)); + rowId = db.insertOrThrow(Tables.KEYS, null, values); + rowUri = PublicKeys.buildPublicKeysUri(Long.toString(rowId)); break; case PUBLIC_KEY_RING_USER_ID: - db.insertOrThrow(Tables.USER_IDS, null, values); - rowUri = PublicUserIds.buildPublicUserIdsUri(values.getAsString(PublicUserIds._ID)); + rowId = db.insertOrThrow(Tables.USER_IDS, null, values); + rowUri = PublicUserIds.buildPublicUserIdsUri(Long.toString(rowId)); break; case SECRET_KEY_RING: values.put(SecretKeyRings.TYPE, KeyTypes.SECRET); - db.insertOrThrow(Tables.KEY_RINGS, null, values); - rowUri = SecretKeyRings.buildSecretKeyRingsUri(values - .getAsString(SecretKeyRings._ID)); + rowId = db.insertOrThrow(Tables.KEY_RINGS, null, values); + rowUri = SecretKeyRings.buildSecretKeyRingsUri(Long.toString(rowId)); break; case SECRET_KEY_RING_KEY: values.put(SecretKeys.TYPE, KeyTypes.SECRET); - db.insertOrThrow(Tables.KEYS, null, values); - rowUri = SecretKeys.buildSecretKeysUri(values.getAsString(SecretKeys._ID)); + rowId = db.insertOrThrow(Tables.KEYS, null, values); + rowUri = SecretKeys.buildSecretKeysUri(Long.toString(rowId)); break; case SECRET_KEY_RING_USER_ID: - db.insertOrThrow(Tables.USER_IDS, null, values); - rowUri = SecretUserIds.buildSecretUserIdsUri(values.getAsString(SecretUserIds._ID)); + rowId = db.insertOrThrow(Tables.USER_IDS, null, values); + rowUri = SecretUserIds.buildSecretUserIdsUri(Long.toString(rowId)); break; default: diff --git a/org_apg/src/org/thialfihar/android/apg/provider/ProviderHelper.java b/org_apg/src/org/thialfihar/android/apg/provider/ProviderHelper.java index e37049c7e..0bae2b782 100644 --- a/org_apg/src/org/thialfihar/android/apg/provider/ProviderHelper.java +++ b/org_apg/src/org/thialfihar/android/apg/provider/ProviderHelper.java @@ -215,17 +215,21 @@ public class ProviderHelper { // delete old version of this keyRing, which also deletes all keys and userIds on cascade Uri deleteUri = PublicKeyRings.buildPublicKeyRingsByMasterKeyIdUri(Long .toString(masterKeyId)); - context.getContentResolver().delete(deleteUri, null, null); + + try { + context.getContentResolver().delete(deleteUri, null, null); + } catch (UnsupportedOperationException e) { + Log.e(Constants.TAG, "Key could not be deleted! Maybe we are creating a new one!", e); + } ContentValues values = new ContentValues(); values.put(PublicKeyRings.MASTER_KEY_ID, masterKeyId); values.put(PublicKeyRings.KEY_RING_DATA, keyRing.getEncoded()); // insert new version of this keyRing - Uri uri = PublicKeyRings.buildPublicKeyRingsByMasterKeyIdUri(values - .getAsString(PublicKeyRings.MASTER_KEY_ID)); + Uri uri = PublicKeyRings.buildPublicKeyRingsUri(); Uri insertedUri = context.getContentResolver().insert(uri, values); - long keyRingRowId = Long.getLong(insertedUri.getLastPathSegment()); + long keyRingRowId = Long.valueOf(insertedUri.getLastPathSegment()); // save all keys and userIds included in keyRing object in database ArrayList operations = new ArrayList(); @@ -267,17 +271,21 @@ public class ProviderHelper { // delete old version of this keyRing, which also deletes all keys and userIds on cascade Uri deleteUri = SecretKeyRings.buildSecretKeyRingsByMasterKeyIdUri(Long .toString(masterKeyId)); - context.getContentResolver().delete(deleteUri, null, null); + + try { + context.getContentResolver().delete(deleteUri, null, null); + } catch (UnsupportedOperationException e) { + Log.e(Constants.TAG, "Key could not be deleted! Maybe we are creating a new one!", e); + } ContentValues values = new ContentValues(); values.put(SecretKeyRings.MASTER_KEY_ID, masterKeyId); values.put(SecretKeyRings.KEY_RING_DATA, keyRing.getEncoded()); // insert new version of this keyRing - Uri uri = SecretKeyRings.buildSecretKeyRingsByMasterKeyIdUri(values - .getAsString(SecretKeyRings.MASTER_KEY_ID)); - Uri insertedUri = context.getContentResolver().insert(uri, values); - long keyRingRowId = Long.getLong(insertedUri.getLastPathSegment()); + Uri uri = SecretKeyRings.buildSecretKeyRingsUri(); + Uri insertedUri = context.getContentResolver().insert(uri, values); + long keyRingRowId = Long.valueOf(insertedUri.getLastPathSegment()); // save all keys and userIds included in keyRing object in database ArrayList operations = new ArrayList(); diff --git a/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java index eb9b543ae..890de0ed3 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/EditKeyActivity.java @@ -111,7 +111,7 @@ public class EditKeyActivity extends SherlockFragmentActivity { case android.R.id.home: // app icon in Action Bar clicked; go home - Intent intent = new Intent(this, SecretKeyListActivity.class); + Intent intent = new Intent(this, KeyListSecretActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); return true; diff --git a/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java index 02aada874..c4382cce0 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/EncryptActivity.java @@ -1001,7 +1001,7 @@ public class EncryptActivity extends SherlockFragmentActivity { } private void selectSecretKey() { - Intent intent = new Intent(this, SelectSecretKeyListActivity.class); + Intent intent = new Intent(this, SelectSecretKeyListActivityOld.class); startActivityForResult(intent, Id.request.secret_keys); } @@ -1049,7 +1049,7 @@ public class EncryptActivity extends SherlockFragmentActivity { case Id.request.secret_keys: { if (resultCode == RESULT_OK) { Bundle bundle = data.getExtras(); - setSecretKeyId(bundle.getLong(SelectSecretKeyListActivity.RESULT_EXTRA_KEY_ID)); + setSecretKeyId(bundle.getLong(SelectSecretKeyListActivityOld.RESULT_EXTRA_KEY_ID)); } else { setSecretKeyId(Id.key.none); } diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyListActivity.java index f251608e2..11d6225a5 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/KeyListActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyListActivity.java @@ -1,67 +1,35 @@ -/* - * Copyright (C) 2012 Dominik Schürmann - * Copyright (C) 2010 Thialfihar - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package org.thialfihar.android.apg.ui; import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.helper.OtherHelper; -import org.thialfihar.android.apg.helper.PGPHelper; -import org.thialfihar.android.apg.helper.PGPMain; -import org.thialfihar.android.apg.provider.KeyRings; -import org.thialfihar.android.apg.provider.Keys; -import org.thialfihar.android.apg.provider.UserIds; -import org.thialfihar.android.apg.service.ApgServiceHandler; +import org.thialfihar.android.apg.R; import org.thialfihar.android.apg.service.ApgService; +import org.thialfihar.android.apg.service.ApgServiceHandler; +import org.thialfihar.android.apg.ui.KeyListActivityOld.KeyListAdapter; import org.thialfihar.android.apg.ui.dialog.DeleteFileDialogFragment; import org.thialfihar.android.apg.ui.dialog.DeleteKeyDialogFragment; import org.thialfihar.android.apg.ui.dialog.FileDialogFragment; -import org.thialfihar.android.apg.R; - -import com.actionbarsherlock.app.SherlockFragmentActivity; -import com.actionbarsherlock.view.MenuItem; +import org.thialfihar.android.apg.util.Log; import android.app.AlertDialog; import android.app.ProgressDialog; 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.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Messenger; -import org.thialfihar.android.apg.util.Log; -import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; -import android.view.ViewGroup; -import android.widget.BaseExpandableListAdapter; import android.widget.Button; import android.widget.ExpandableListView; -import android.widget.ExpandableListView.ExpandableListContextMenuInfo; -import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; +import android.widget.ExpandableListView.ExpandableListContextMenuInfo; -import java.util.Vector; +import com.actionbarsherlock.app.SherlockFragmentActivity; +import com.actionbarsherlock.view.MenuItem; public class KeyListActivity extends SherlockFragmentActivity { @@ -76,7 +44,7 @@ public class KeyListActivity extends SherlockFragmentActivity { protected TextView mFilterInfo; protected int mSelectedItem = -1; - protected int mTask = 0; + // protected int mTask = 0; protected String mImportFilename = Constants.path.APP_DIR + "/"; protected String mExportFilename = Constants.path.APP_DIR + "/"; @@ -91,25 +59,9 @@ public class KeyListActivity extends SherlockFragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.key_list); - // set actionbar without home button if called from another app - OtherHelper.setActionBarBackButton(this); - - setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); - - mList = (ExpandableListView) findViewById(R.id.list); - registerForContextMenu(mList); - - mFilterLayout = findViewById(R.id.layout_filter); - mFilterInfo = (TextView) mFilterLayout.findViewById(R.id.filterInfo); - mClearFilterButton = (Button) mFilterLayout.findViewById(R.id.btn_clear); - - mClearFilterButton.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - handleIntent(new Intent()); - } - }); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setHomeButtonEnabled(true); handleIntent(getIntent()); } @@ -129,18 +81,18 @@ public class KeyListActivity extends SherlockFragmentActivity { } } - 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); + // 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); // Get intent, action // Intent intent = getIntent(); @@ -192,9 +144,9 @@ public class KeyListActivity extends SherlockFragmentActivity { return true; } - case Id.menu.option.search: - startSearch("", false, null, false); - return true; +// case Id.menu.option.search: +// startSearch("", false, null, false); +// return true; default: { return super.onOptionsItemSelected(item); @@ -293,7 +245,7 @@ public class KeyListActivity extends SherlockFragmentActivity { @Override public void handleMessage(Message message) { if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) { - refreshList(); +// refreshList(); } } }; @@ -354,7 +306,8 @@ public class KeyListActivity extends SherlockFragmentActivity { } else { toastMessage = getString(R.string.noKeysAddedOrUpdated); } - Toast.makeText(KeyListActivity.this, toastMessage, Toast.LENGTH_SHORT).show(); + Toast.makeText(KeyListActivity.this, toastMessage, Toast.LENGTH_SHORT) + .show(); if (bad > 0) { AlertDialog.Builder alert = new AlertDialog.Builder(KeyListActivity.this); @@ -377,7 +330,7 @@ public class KeyListActivity extends SherlockFragmentActivity { .newInstance(mImportFilename); deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog"); } - refreshList(); +// refreshList(); } }; @@ -438,7 +391,8 @@ public class KeyListActivity extends SherlockFragmentActivity { } else { toastMessage = getString(R.string.noKeysExported); } - Toast.makeText(KeyListActivity.this, toastMessage, Toast.LENGTH_SHORT).show(); + Toast.makeText(KeyListActivity.this, toastMessage, Toast.LENGTH_SHORT) + .show(); } }; @@ -454,314 +408,4 @@ public class KeyListActivity extends SherlockFragmentActivity { // start service with intent startService(intent); } - - protected void refreshList() { - mListAdapter.rebuild(true); - mListAdapter.notifyDataSetChanged(); - } - - protected class KeyListAdapter extends BaseExpandableListAdapter { - private LayoutInflater mInflater; - private Vector> mChildren; - private SQLiteDatabase mDatabase; - private Cursor mCursor; - private String mSearchString; - - private class KeyChild { - public static final int KEY = 0; - public static final int USER_ID = 1; - public static final int FINGER_PRINT = 2; - - public int type; - public String userId; - public long keyId; - public boolean isMasterKey; - public int algorithm; - public int keySize; - public boolean canSign; - public boolean canEncrypt; - public String fingerPrint; - - public KeyChild(long keyId, boolean isMasterKey, int algorithm, int keySize, - boolean canSign, boolean canEncrypt) { - this.type = KEY; - this.keyId = keyId; - this.isMasterKey = isMasterKey; - this.algorithm = algorithm; - this.keySize = keySize; - this.canSign = canSign; - this.canEncrypt = canEncrypt; - } - - public KeyChild(String userId) { - type = USER_ID; - this.userId = userId; - } - - public KeyChild(String fingerPrint, boolean isFingerPrint) { - type = FINGER_PRINT; - this.fingerPrint = fingerPrint; - } - } - - public KeyListAdapter(Context context, String searchString) { - mSearchString = searchString; - - mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - mDatabase = PGPMain.getDatabase().db(); - 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'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME + " ON " + "(" - + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." - + UserIds.KEY_ID + " AND " + 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 - 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"); - - // 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(); - } - mChildren = new Vector>(); - for (int i = 0; i < mCursor.getCount(); ++i) { - mChildren.add(null); - } - } - - protected Vector getChildrenOfGroup(int groupPosition) { - Vector children = mChildren.get(groupPosition); - if (children != null) { - return children; - } - - mCursor.moveToPosition(groupPosition); - children = new Vector(); - Cursor c = mDatabase.query(Keys.TABLE_NAME, new String[] { Keys._ID, // 0 - Keys.KEY_ID, // 1 - Keys.IS_MASTER_KEY, // 2 - Keys.ALGORITHM, // 3 - Keys.KEY_SIZE, // 4 - Keys.CAN_SIGN, // 5 - Keys.CAN_ENCRYPT, // 6 - }, Keys.KEY_RING_ID + " = ?", new String[] { mCursor.getString(0) }, null, null, - Keys.RANK + " ASC"); - - int masterKeyId = -1; - long fingerPrintId = -1; - for (int i = 0; i < c.getCount(); ++i) { - c.moveToPosition(i); - children.add(new KeyChild(c.getLong(1), c.getInt(2) == 1, c.getInt(3), c.getInt(4), - c.getInt(5) == 1, c.getInt(6) == 1)); - if (i == 0) { - masterKeyId = c.getInt(0); - fingerPrintId = c.getLong(1); - } - } - c.close(); - - if (masterKeyId != -1) { - children.insertElementAt( - new KeyChild(PGPHelper.getFingerPrint(KeyListActivity.this, fingerPrintId), true), 0); - c = mDatabase.query(UserIds.TABLE_NAME, new String[] { UserIds.USER_ID, // 0 - }, UserIds.KEY_ID + " = ? AND " + UserIds.RANK + " > 0", new String[] { "" - + masterKeyId }, null, null, UserIds.RANK + " ASC"); - - for (int i = 0; i < c.getCount(); ++i) { - c.moveToPosition(i); - children.add(new KeyChild(c.getString(0))); - } - c.close(); - } - - mChildren.set(groupPosition, children); - return children; - } - - public boolean hasStableIds() { - return true; - } - - public boolean isChildSelectable(int groupPosition, int childPosition) { - return true; - } - - public int getGroupCount() { - return mCursor.getCount(); - } - - public Object getChild(int groupPosition, int childPosition) { - return null; - } - - public long getChildId(int groupPosition, int childPosition) { - return childPosition; - } - - public int getChildrenCount(int groupPosition) { - return getChildrenOfGroup(groupPosition).size(); - } - - public Object getGroup(int position) { - return position; - } - - public long getGroupId(int position) { - mCursor.moveToPosition(position); - return mCursor.getLong(1); // MASTER_KEY_ID - } - - public int getKeyRingId(int position) { - mCursor.moveToPosition(position); - return mCursor.getInt(0); // _ID - } - - public View getGroupView(int groupPosition, boolean isExpanded, View convertView, - ViewGroup parent) { - mCursor.moveToPosition(groupPosition); - - View view = mInflater.inflate(R.layout.key_list_group_item, null); - view.setBackgroundResource(android.R.drawable.list_selector_background); - - TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId); - mainUserId.setText(""); - TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest); - mainUserIdRest.setText(""); - - String userId = mCursor.getString(2); // USER_ID - if (userId != null) { - String chunks[] = userId.split(" <", 2); - userId = chunks[0]; - if (chunks.length > 1) { - mainUserIdRest.setText("<" + chunks[1]); - } - mainUserId.setText(userId); - } - - if (mainUserId.getText().length() == 0) { - mainUserId.setText(R.string.unknownUserId); - } - - if (mainUserIdRest.getText().length() == 0) { - mainUserIdRest.setVisibility(View.GONE); - } - return view; - } - - public View getChildView(int groupPosition, int childPosition, boolean isLastChild, - View convertView, ViewGroup parent) { - mCursor.moveToPosition(groupPosition); - - Vector children = getChildrenOfGroup(groupPosition); - - KeyChild child = children.get(childPosition); - View view = null; - switch (child.type) { - case KeyChild.KEY: { - if (child.isMasterKey) { - view = mInflater.inflate(R.layout.key_list_child_item_master_key, null); - } else { - view = mInflater.inflate(R.layout.key_list_child_item_sub_key, null); - } - - TextView keyId = (TextView) view.findViewById(R.id.keyId); - String keyIdStr = PGPHelper.getSmallFingerPrint(child.keyId); - keyId.setText(keyIdStr); - TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails); - String algorithmStr = PGPHelper.getAlgorithmInfo(child.algorithm, child.keySize); - keyDetails.setText("(" + algorithmStr + ")"); - - ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey); - if (!child.canEncrypt) { - encryptIcon.setVisibility(View.GONE); - } - - ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey); - if (!child.canSign) { - signIcon.setVisibility(View.GONE); - } - break; - } - - case KeyChild.USER_ID: { - view = mInflater.inflate(R.layout.key_list_child_item_user_id, null); - TextView userId = (TextView) view.findViewById(R.id.userId); - userId.setText(child.userId); - break; - } - - case KeyChild.FINGER_PRINT: { - view = mInflater.inflate(R.layout.key_list_child_item_user_id, null); - TextView userId = (TextView) view.findViewById(R.id.userId); - userId.setText(getString(R.string.fingerprint) + ":\n" - + child.fingerPrint.replace(" ", "\n")); - break; - } - } - return view; - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode) { - case Id.request.filename: { - if (resultCode == RESULT_OK && data != null) { - try { - String path = data.getData().getPath(); - Log.d(Constants.TAG, "path=" + path); - - mFileDialog.setFilename(path); - } catch (NullPointerException e) { - Log.e(Constants.TAG, "Nullpointer while retrieving path!", e); - } - } - return; - } - - default: { - break; - } - } - super.onActivityResult(requestCode, resultCode, data); - } } diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyListActivityOld.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyListActivityOld.java new file mode 100644 index 000000000..7037e2cb5 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyListActivityOld.java @@ -0,0 +1,767 @@ +/* + * Copyright (C) 2012 Dominik Schürmann + * Copyright (C) 2010 Thialfihar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.thialfihar.android.apg.ui; + +import org.thialfihar.android.apg.Constants; +import org.thialfihar.android.apg.Id; +import org.thialfihar.android.apg.helper.OtherHelper; +import org.thialfihar.android.apg.helper.PGPHelper; +import org.thialfihar.android.apg.helper.PGPMain; +import org.thialfihar.android.apg.service.ApgServiceHandler; +import org.thialfihar.android.apg.service.ApgService; +import org.thialfihar.android.apg.ui.dialog.DeleteFileDialogFragment; +import org.thialfihar.android.apg.ui.dialog.DeleteKeyDialogFragment; +import org.thialfihar.android.apg.ui.dialog.FileDialogFragment; +import org.thialfihar.android.apg.R; + +import com.actionbarsherlock.app.SherlockFragmentActivity; +import com.actionbarsherlock.app.SherlockListActivity; +import com.actionbarsherlock.app.SherlockListFragment; +import com.actionbarsherlock.view.MenuItem; + +import android.app.AlertDialog; +import android.app.ProgressDialog; +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.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; +import org.thialfihar.android.apg.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.BaseExpandableListAdapter; +import android.widget.Button; +import android.widget.ExpandableListView; +import android.widget.ExpandableListView.ExpandableListContextMenuInfo; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import java.util.Vector; + +public class KeyListActivityOld extends SherlockFragmentActivity { + + public static final String ACTION_IMPORT = Constants.INTENT_PREFIX + "IMPORT"; + + public static final String EXTRA_TEXT = "text"; + + protected ExpandableListView mList; + protected KeyListAdapter mListAdapter; + protected View mFilterLayout; + protected Button mClearFilterButton; + protected TextView mFilterInfo; + + protected int mSelectedItem = -1; +// protected int mTask = 0; + + protected String mImportFilename = Constants.path.APP_DIR + "/"; + protected String mExportFilename = Constants.path.APP_DIR + "/"; + + protected String mImportData; + protected boolean mDeleteAfterImport = false; + + protected int mKeyType = Id.type.public_key; + + FileDialogFragment mFileDialog; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.key_list); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setHomeButtonEnabled(true); + + setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); + + mList = (ExpandableListView) findViewById(R.id.list); + registerForContextMenu(mList); + + mFilterLayout = findViewById(R.id.layout_filter); + mFilterInfo = (TextView) mFilterLayout.findViewById(R.id.filterInfo); + mClearFilterButton = (Button) mFilterLayout.findViewById(R.id.btn_clear); + + mClearFilterButton.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + handleIntent(new Intent()); + } + }); + + handleIntent(getIntent()); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + handleIntent(intent); + } + + protected 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); + + // Get intent, action + // Intent intent = getIntent(); + String action = intent.getAction(); + + if (Intent.ACTION_VIEW.equals(action)) { + // Android's Action when opening file associated to APG (see AndroidManifest.xml) + + handleActionImport(intent); + } else if (ACTION_IMPORT.equals(action)) { + // APG's own Actions + + handleActionImport(intent); + } + } + + /** + * Handles import action + * + * @param intent + */ + private void handleActionImport(Intent intent) { + if ("file".equals(intent.getScheme()) && intent.getDataString() != null) { + mImportFilename = intent.getData().getPath(); + } else { + mImportData = intent.getStringExtra(EXTRA_TEXT); + } + importKeys(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + + case android.R.id.home: + // app icon in Action Bar clicked; go home + Intent intent = new Intent(this, MainActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + return true; + + case Id.menu.option.import_keys: { + showImportKeysDialog(); + return true; + } + + case Id.menu.option.export_keys: { + showExportKeysDialog(false); + return true; + } + + case Id.menu.option.search: + startSearch("", false, null, false); + return true; + + default: { + return super.onOptionsItemSelected(item); + } + } + } + + private void showImportKeysDialog() { + // Message is received after file is selected + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == FileDialogFragment.MESSAGE_OKAY) { + Bundle data = message.getData(); + mImportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); + + mDeleteAfterImport = data.getBoolean(FileDialogFragment.MESSAGE_DATA_CHECKED); + importKeys(); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + mFileDialog = FileDialogFragment.newInstance(messenger, + getString(R.string.title_importKeys), getString(R.string.specifyFileToImportFrom), + mImportFilename, null, Id.request.filename); + + mFileDialog.show(getSupportFragmentManager(), "fileDialog"); + } + + private void showExportKeysDialog(boolean singleKeyExport) { + String title = (singleKeyExport ? getString(R.string.title_exportKey) + : getString(R.string.title_exportKeys)); + String message = getString(mKeyType == Id.type.public_key ? R.string.specifyFileToExportTo + : R.string.specifyFileToExportSecretKeysTo); + + // Message is received after file is selected + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == FileDialogFragment.MESSAGE_OKAY) { + Bundle data = message.getData(); + mExportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME); + + exportKeys(); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + mFileDialog = FileDialogFragment.newInstance(messenger, title, message, mExportFilename, + null, Id.request.filename); + + mFileDialog.show(getSupportFragmentManager(), "fileDialog"); + } + + @Override + public boolean onContextItemSelected(android.view.MenuItem menuItem) { + ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuItem.getMenuInfo(); + int type = ExpandableListView.getPackedPositionType(info.packedPosition); + int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition); + + if (type != ExpandableListView.PACKED_POSITION_TYPE_GROUP) { + return super.onContextItemSelected(menuItem); + } + + switch (menuItem.getItemId()) { + case Id.menu.export: { + mSelectedItem = groupPosition; + showExportKeysDialog(true); + return true; + } + + case Id.menu.delete: { + mSelectedItem = groupPosition; + showDeleteKeyDialog(); + return true; + } + + default: { + return super.onContextItemSelected(menuItem); + } + } + } + + private void showDeleteKeyDialog() { + final int keyRingId = mListAdapter.getKeyRingId(mSelectedItem); + mSelectedItem = -1; + + // Message is received after key is deleted + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) { + refreshList(); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger, + keyRingId, mKeyType); + + deleteKeyDialog.show(getSupportFragmentManager(), "deleteKeyDialog"); + } + + public void importKeys() { + Log.d(Constants.TAG, "importKeys started"); + + // Send all information needed to service to import key in other thread + Intent intent = new Intent(this, ApgService.class); + + intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_IMPORT_KEY); + + // fill values for this action + Bundle data = new Bundle(); + + data.putInt(ApgService.IMPORT_KEY_TYPE, mKeyType); + + if (mImportData != null) { + data.putInt(ApgService.TARGET, ApgService.TARGET_BYTES); + data.putByteArray(ApgService.IMPORT_BYTES, mImportData.getBytes()); + } else { + data.putInt(ApgService.TARGET, ApgService.TARGET_FILE); + data.putString(ApgService.IMPORT_FILENAME, mImportFilename); + } + + intent.putExtra(ApgService.EXTRA_DATA, data); + + // Message is received after importing is done in ApgService + ApgServiceHandler saveHandler = new ApgServiceHandler(this, R.string.progress_importing, + ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard ApgHandler first + super.handleMessage(message); + + if (message.arg1 == ApgServiceHandler.MESSAGE_OKAY) { + // get returned data bundle + Bundle returnData = message.getData(); + + int added = returnData.getInt(ApgService.RESULT_IMPORT_ADDED); + int updated = returnData.getInt(ApgService.RESULT_IMPORT_UPDATED); + int bad = returnData.getInt(ApgService.RESULT_IMPORT_BAD); + String toastMessage; + if (added > 0 && updated > 0) { + toastMessage = getString(R.string.keysAddedAndUpdated, added, updated); + } else if (added > 0) { + toastMessage = getString(R.string.keysAdded, added); + } else if (updated > 0) { + toastMessage = getString(R.string.keysUpdated, updated); + } else { + toastMessage = getString(R.string.noKeysAddedOrUpdated); + } + Toast.makeText(KeyListActivityOld.this, toastMessage, Toast.LENGTH_SHORT).show(); + if (bad > 0) { + AlertDialog.Builder alert = new AlertDialog.Builder(KeyListActivityOld.this); + + alert.setIcon(android.R.drawable.ic_dialog_alert); + alert.setTitle(R.string.warning); + alert.setMessage(KeyListActivityOld.this.getString( + R.string.badKeysEncountered, bad)); + + alert.setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); + alert.setCancelable(true); + alert.create().show(); + } else if (mDeleteAfterImport) { + // everything went well, so now delete, if that was turned on + DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment + .newInstance(mImportFilename); + deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog"); + } + refreshList(); + + } + }; + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(saveHandler); + intent.putExtra(ApgService.EXTRA_MESSENGER, messenger); + + // show progress dialog + saveHandler.showProgressDialog(this); + + // start service with intent + startService(intent); + } + + public void exportKeys() { + Log.d(Constants.TAG, "exportKeys started"); + + // Send all information needed to service to export key in other thread + Intent intent = new Intent(this, ApgService.class); + + intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_EXPORT_KEY); + + // fill values for this action + Bundle data = new Bundle(); + + data.putString(ApgService.EXPORT_FILENAME, mExportFilename); + data.putInt(ApgService.EXPORT_KEY_TYPE, mKeyType); + + if (mSelectedItem == -1) { + data.putBoolean(ApgService.EXPORT_ALL, true); + } else { + int keyRingId = mListAdapter.getKeyRingId(mSelectedItem); + data.putInt(ApgService.EXPORT_KEY_RING_ID, keyRingId); + mSelectedItem = -1; + } + + intent.putExtra(ApgService.EXTRA_DATA, data); + + // Message is received after exporting is done in ApgService + ApgServiceHandler exportHandler = new ApgServiceHandler(this, R.string.progress_exporting, + ProgressDialog.STYLE_HORIZONTAL) { + public void handleMessage(Message message) { + // handle messages by standard ApgHandler first + super.handleMessage(message); + + if (message.arg1 == ApgServiceHandler.MESSAGE_OKAY) { + // get returned data bundle + Bundle returnData = message.getData(); + + int exported = returnData.getInt(ApgService.RESULT_EXPORT); + String toastMessage; + if (exported == 1) { + toastMessage = getString(R.string.keyExported); + } else if (exported > 0) { + toastMessage = getString(R.string.keysExported, exported); + } else { + toastMessage = getString(R.string.noKeysExported); + } + Toast.makeText(KeyListActivityOld.this, toastMessage, Toast.LENGTH_SHORT).show(); + + } + }; + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(exportHandler); + intent.putExtra(ApgService.EXTRA_MESSENGER, messenger); + + // show progress dialog + exportHandler.showProgressDialog(this); + + // start service with intent + startService(intent); + } + + protected void refreshList() { + mListAdapter.rebuild(true); + mListAdapter.notifyDataSetChanged(); + } + + protected class KeyListAdapter extends BaseExpandableListAdapter { + private LayoutInflater mInflater; + private Vector> mChildren; + private SQLiteDatabase mDatabase; + private Cursor mCursor; + private String mSearchString; + + private class KeyChild { + public static final int KEY = 0; + public static final int USER_ID = 1; + public static final int FINGER_PRINT = 2; + + public int type; + public String userId; + public long keyId; + public boolean isMasterKey; + public int algorithm; + public int keySize; + public boolean canSign; + public boolean canEncrypt; + public String fingerPrint; + + public KeyChild(long keyId, boolean isMasterKey, int algorithm, int keySize, + boolean canSign, boolean canEncrypt) { + this.type = KEY; + this.keyId = keyId; + this.isMasterKey = isMasterKey; + this.algorithm = algorithm; + this.keySize = keySize; + this.canSign = canSign; + this.canEncrypt = canEncrypt; + } + + public KeyChild(String userId) { + type = USER_ID; + this.userId = userId; + } + + public KeyChild(String fingerPrint, boolean isFingerPrint) { + type = FINGER_PRINT; + this.fingerPrint = fingerPrint; + } + } + + public KeyListAdapter(Context context, String searchString) { + mSearchString = searchString; + + mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); +// mDatabase = PGPMain.getDatabase().db(); +// 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'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME + " ON " + "(" +// + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." +// + UserIds.KEY_ID + " AND " + 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 +// 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"); + + // 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(); + } + mChildren = new Vector>(); + for (int i = 0; i < mCursor.getCount(); ++i) { + mChildren.add(null); + } + } + + protected Vector getChildrenOfGroup(int groupPosition) { + Vector children = mChildren.get(groupPosition); + if (children != null) { + return children; + } + + mCursor.moveToPosition(groupPosition); + children = new Vector(); +// Cursor c = mDatabase.query(Keys.TABLE_NAME, new String[] { Keys._ID, // 0 +// Keys.KEY_ID, // 1 +// Keys.IS_MASTER_KEY, // 2 +// Keys.ALGORITHM, // 3 +// Keys.KEY_SIZE, // 4 +// Keys.CAN_SIGN, // 5 +// Keys.CAN_ENCRYPT, // 6 +// }, Keys.KEY_RING_ID + " = ?", new String[] { mCursor.getString(0) }, null, null, +// Keys.RANK + " ASC"); + +// int masterKeyId = -1; +// long fingerPrintId = -1; +// for (int i = 0; i < c.getCount(); ++i) { +// c.moveToPosition(i); +// children.add(new KeyChild(c.getLong(1), c.getInt(2) == 1, c.getInt(3), c.getInt(4), +// c.getInt(5) == 1, c.getInt(6) == 1)); +// if (i == 0) { +// masterKeyId = c.getInt(0); +// fingerPrintId = c.getLong(1); +// } +// } +// c.close(); +// +// if (masterKeyId != -1) { +// children.insertElementAt( +// new KeyChild(PGPHelper.getFingerPrint(KeyListActivity.this, fingerPrintId), +// true), 0); +// c = mDatabase.query(UserIds.TABLE_NAME, new String[] { UserIds.USER_ID, // 0 +// }, UserIds.KEY_ID + " = ? AND " + UserIds.RANK + " > 0", new String[] { "" +// + masterKeyId }, null, null, UserIds.RANK + " ASC"); +// +// for (int i = 0; i < c.getCount(); ++i) { +// c.moveToPosition(i); +// children.add(new KeyChild(c.getString(0))); +// } +// c.close(); +// } + + mChildren.set(groupPosition, children); + return children; + } + + public boolean hasStableIds() { + return true; + } + + public boolean isChildSelectable(int groupPosition, int childPosition) { + return true; + } + + public int getGroupCount() { + return mCursor.getCount(); + } + + public Object getChild(int groupPosition, int childPosition) { + return null; + } + + public long getChildId(int groupPosition, int childPosition) { + return childPosition; + } + + public int getChildrenCount(int groupPosition) { + return getChildrenOfGroup(groupPosition).size(); + } + + public Object getGroup(int position) { + return position; + } + + public long getGroupId(int position) { + mCursor.moveToPosition(position); + return mCursor.getLong(1); // MASTER_KEY_ID + } + + public int getKeyRingId(int position) { + mCursor.moveToPosition(position); + return mCursor.getInt(0); // _ID + } + + public View getGroupView(int groupPosition, boolean isExpanded, View convertView, + ViewGroup parent) { + mCursor.moveToPosition(groupPosition); + + View view = mInflater.inflate(R.layout.key_list_group_item, null); + view.setBackgroundResource(android.R.drawable.list_selector_background); + + TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId); + mainUserId.setText(""); + TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest); + mainUserIdRest.setText(""); + + String userId = mCursor.getString(2); // USER_ID + if (userId != null) { + String chunks[] = userId.split(" <", 2); + userId = chunks[0]; + if (chunks.length > 1) { + mainUserIdRest.setText("<" + chunks[1]); + } + mainUserId.setText(userId); + } + + if (mainUserId.getText().length() == 0) { + mainUserId.setText(R.string.unknownUserId); + } + + if (mainUserIdRest.getText().length() == 0) { + mainUserIdRest.setVisibility(View.GONE); + } + return view; + } + + public View getChildView(int groupPosition, int childPosition, boolean isLastChild, + View convertView, ViewGroup parent) { + mCursor.moveToPosition(groupPosition); + + Vector children = getChildrenOfGroup(groupPosition); + + KeyChild child = children.get(childPosition); + View view = null; + switch (child.type) { + case KeyChild.KEY: { + if (child.isMasterKey) { + view = mInflater.inflate(R.layout.key_list_child_item_master_key, null); + } else { + view = mInflater.inflate(R.layout.key_list_child_item_sub_key, null); + } + + TextView keyId = (TextView) view.findViewById(R.id.keyId); + String keyIdStr = PGPHelper.getSmallFingerPrint(child.keyId); + keyId.setText(keyIdStr); + TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails); + String algorithmStr = PGPHelper.getAlgorithmInfo(child.algorithm, child.keySize); + keyDetails.setText("(" + algorithmStr + ")"); + + ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey); + if (!child.canEncrypt) { + encryptIcon.setVisibility(View.GONE); + } + + ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey); + if (!child.canSign) { + signIcon.setVisibility(View.GONE); + } + break; + } + + case KeyChild.USER_ID: { + view = mInflater.inflate(R.layout.key_list_child_item_user_id, null); + TextView userId = (TextView) view.findViewById(R.id.userId); + userId.setText(child.userId); + break; + } + + case KeyChild.FINGER_PRINT: { + view = mInflater.inflate(R.layout.key_list_child_item_user_id, null); + TextView userId = (TextView) view.findViewById(R.id.userId); + userId.setText(getString(R.string.fingerprint) + ":\n" + + child.fingerPrint.replace(" ", "\n")); + break; + } + } + return view; + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case Id.request.filename: { + if (resultCode == RESULT_OK && data != null) { + try { + String path = data.getData().getPath(); + Log.d(Constants.TAG, "path=" + path); + + mFileDialog.setFilename(path); + } catch (NullPointerException e) { + Log.e(Constants.TAG, "Nullpointer while retrieving path!", e); + } + } + return; + } + + default: { + break; + } + } + super.onActivityResult(requestCode, resultCode, data); + } +} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyListPublicActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyListPublicActivity.java new file mode 100644 index 000000000..b8ee2e801 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyListPublicActivity.java @@ -0,0 +1,189 @@ +package org.thialfihar.android.apg.ui; + +import org.spongycastle.openpgp.PGPPublicKeyRing; +import org.thialfihar.android.apg.Constants; +import org.thialfihar.android.apg.Id; +import org.thialfihar.android.apg.R; +import org.thialfihar.android.apg.helper.PGPHelper; +import org.thialfihar.android.apg.provider.ProviderHelper; + +import com.actionbarsherlock.app.ActionBar; +import com.actionbarsherlock.app.SherlockFragmentActivity; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuItem; + +import android.content.Intent; +import android.os.Bundle; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.View; +import android.widget.ExpandableListView; +import android.widget.ExpandableListView.ExpandableListContextMenuInfo; + +public class KeyListPublicActivity extends KeyListActivity { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.key_list_public_activity); + + mExportFilename = Constants.path.APP_DIR + "/pubexport.asc"; + mKeyType = Id.type.public_key; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.add(1, Id.menu.option.search, 0, R.string.menu_search) + .setIcon(R.drawable.ic_menu_search).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + menu.add(1, Id.menu.option.scanQRCode, 1, R.string.menu_scanQRCode) + .setIcon(R.drawable.ic_menu_scan_qrcode) + .setShowAsAction( + MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + menu.add(1, Id.menu.option.key_server, 2, R.string.menu_keyServer) + .setIcon(R.drawable.ic_menu_search_list) + .setShowAsAction( + MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + menu.add(0, Id.menu.option.import_keys, 3, R.string.menu_importKeys).setShowAsAction( + MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + menu.add(0, Id.menu.option.export_keys, 4, R.string.menu_exportKeys).setShowAsAction( + MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case Id.menu.option.key_server: { + startActivity(new Intent(this, KeyServerQueryActivity.class)); + + return true; + } + case Id.menu.option.scanQRCode: { + Intent intent = new Intent(this, ImportFromQRCodeActivity.class); + intent.setAction(ImportFromQRCodeActivity.IMPORT_FROM_QR_CODE); + startActivityForResult(intent, Id.request.import_from_qr_code); + + return true; + } + + default: { + return super.onOptionsItemSelected(item); + } + } + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo; + int type = ExpandableListView.getPackedPositionType(info.packedPosition); + + if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { + // TODO: user id? menu.setHeaderTitle("Key"); + menu.add(0, Id.menu.export, 0, R.string.menu_exportKey); + menu.add(0, Id.menu.delete, 1, R.string.menu_deleteKey); + menu.add(0, Id.menu.update, 1, R.string.menu_updateKey); + menu.add(0, Id.menu.exportToServer, 1, R.string.menu_exportKeyToServer); + menu.add(0, Id.menu.signKey, 1, R.string.menu_signKey); + } + } + + @Override + public boolean onContextItemSelected(android.view.MenuItem menuItem) { + ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuItem.getMenuInfo(); + int type = ExpandableListView.getPackedPositionType(info.packedPosition); + int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition); + + if (type != ExpandableListView.PACKED_POSITION_TYPE_GROUP) { + return super.onContextItemSelected(menuItem); + } + + switch (menuItem.getItemId()) { + case Id.menu.update: { + mSelectedItem = groupPosition; + final int keyRingId = mListAdapter.getKeyRingId(groupPosition); + long keyId = 0; + PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, + keyRingId); + if (keyRing != null) { + keyId = PGPHelper.getMasterKey((PGPPublicKeyRing) keyRing).getKeyID(); + } + if (keyId == 0) { + // this shouldn't happen + return true; + } + + Intent intent = new Intent(this, KeyServerQueryActivity.class); + intent.setAction(KeyServerQueryActivity.ACTION_LOOK_UP_KEY_ID_AND_RETURN); + intent.putExtra(KeyServerQueryActivity.EXTRA_KEY_ID, keyId); + startActivityForResult(intent, Id.request.look_up_key_id); + + return true; + } + + case Id.menu.exportToServer: { + mSelectedItem = groupPosition; + final int keyRingId = mListAdapter.getKeyRingId(groupPosition); + + Intent intent = new Intent(this, KeyServerUploadActivity.class); + intent.setAction(KeyServerUploadActivity.ACTION_EXPORT_KEY_TO_SERVER); + intent.putExtra(KeyServerUploadActivity.EXTRA_KEY_ID, keyRingId); + startActivityForResult(intent, Id.request.export_to_server); + + return true; + } + + case Id.menu.signKey: { + mSelectedItem = groupPosition; + final int keyRingId = mListAdapter.getKeyRingId(groupPosition); + long keyId = 0; + PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, + keyRingId); + if (keyRing != null) { + keyId = PGPHelper.getMasterKey((PGPPublicKeyRing) keyRing).getKeyID(); + } + + if (keyId == 0) { + // this shouldn't happen + return true; + } + + Intent intent = new Intent(this, SignKeyActivity.class); + intent.putExtra(SignKeyActivity.EXTRA_KEY_ID, keyId); + startActivity(intent); + + return true; + } + + default: { + return super.onContextItemSelected(menuItem); + } + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case Id.request.look_up_key_id: { + if (resultCode == RESULT_CANCELED || data == null + || data.getStringExtra(KeyServerQueryActivity.RESULT_EXTRA_TEXT) == null) { + return; + } + + Intent intent = new Intent(this, KeyListPublicActivity.class); + intent.setAction(KeyListPublicActivity.ACTION_IMPORT); + intent.putExtra(KeyListPublicActivity.EXTRA_TEXT, + data.getStringExtra(KeyListActivityOld.EXTRA_TEXT)); + handleIntent(intent); + break; + } + + default: { + super.onActivityResult(requestCode, resultCode, data); + break; + } + } + } +} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyListPublicActivityOld.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyListPublicActivityOld.java new file mode 100644 index 000000000..0896a92a9 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyListPublicActivityOld.java @@ -0,0 +1,198 @@ +///* +// * Copyright (C) 2010 Thialfihar +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +// +//package org.thialfihar.android.apg.ui; +// +//import org.spongycastle.openpgp.PGPPublicKeyRing; +//import org.thialfihar.android.apg.Constants; +//import org.thialfihar.android.apg.Id; +//import org.thialfihar.android.apg.R; +//import org.thialfihar.android.apg.helper.PGPHelper; +//import org.thialfihar.android.apg.helper.PGPMain; +//import org.thialfihar.android.apg.provider.ProviderHelper; +// +//import com.actionbarsherlock.view.Menu; +//import com.actionbarsherlock.view.MenuItem; +// +//import android.content.Intent; +//import android.os.Bundle; +//import android.view.ContextMenu; +//import android.view.ContextMenu.ContextMenuInfo; +//import android.view.View; +//import android.widget.ExpandableListView; +//import android.widget.ExpandableListView.ExpandableListContextMenuInfo; +// +//public class KeyListPublicActivityOld extends KeyListActivityOld { +// @Override +// public void onCreate(Bundle savedInstanceState) { +// mExportFilename = Constants.path.APP_DIR + "/pubexport.asc"; +// mKeyType = Id.type.public_key; +// super.onCreate(savedInstanceState); +// } +// +// @Override +// public boolean onCreateOptionsMenu(Menu menu) { +// menu.add(1, Id.menu.option.search, 0, R.string.menu_search) +// .setIcon(R.drawable.ic_menu_search).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); +// menu.add(1, Id.menu.option.scanQRCode, 1, R.string.menu_scanQRCode) +// .setIcon(R.drawable.ic_menu_scan_qrcode) +// .setShowAsAction( +// MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); +// menu.add(1, Id.menu.option.key_server, 2, R.string.menu_keyServer) +// .setIcon(R.drawable.ic_menu_search_list) +// .setShowAsAction( +// MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); +// menu.add(0, Id.menu.option.import_keys, 3, R.string.menu_importKeys).setShowAsAction( +// MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); +// menu.add(0, Id.menu.option.export_keys, 4, R.string.menu_exportKeys).setShowAsAction( +// MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); +// +// return true; +// } +// +// @Override +// public boolean onOptionsItemSelected(MenuItem item) { +// switch (item.getItemId()) { +// case Id.menu.option.key_server: { +// startActivity(new Intent(this, KeyServerQueryActivity.class)); +// +// return true; +// } +// case Id.menu.option.scanQRCode: { +// Intent intent = new Intent(this, ImportFromQRCodeActivity.class); +// intent.setAction(ImportFromQRCodeActivity.IMPORT_FROM_QR_CODE); +// startActivityForResult(intent, Id.request.import_from_qr_code); +// +// return true; +// } +// +// default: { +// return super.onOptionsItemSelected(item); +// } +// } +// } +// +// @Override +// public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { +// super.onCreateContextMenu(menu, v, menuInfo); +// ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo; +// int type = ExpandableListView.getPackedPositionType(info.packedPosition); +// +// if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { +// // TODO: user id? menu.setHeaderTitle("Key"); +// menu.add(0, Id.menu.export, 0, R.string.menu_exportKey); +// menu.add(0, Id.menu.delete, 1, R.string.menu_deleteKey); +// menu.add(0, Id.menu.update, 1, R.string.menu_updateKey); +// menu.add(0, Id.menu.exportToServer, 1, R.string.menu_exportKeyToServer); +// menu.add(0, Id.menu.signKey, 1, R.string.menu_signKey); +// } +// } +// +// @Override +// public boolean onContextItemSelected(android.view.MenuItem menuItem) { +// ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuItem.getMenuInfo(); +// int type = ExpandableListView.getPackedPositionType(info.packedPosition); +// int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition); +// +// if (type != ExpandableListView.PACKED_POSITION_TYPE_GROUP) { +// return super.onContextItemSelected(menuItem); +// } +// +// switch (menuItem.getItemId()) { +// case Id.menu.update: { +// mSelectedItem = groupPosition; +// final int keyRingId = mListAdapter.getKeyRingId(groupPosition); +// long keyId = 0; +// PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, keyRingId); +// if (keyRing != null) { +// keyId = PGPHelper.getMasterKey((PGPPublicKeyRing) keyRing).getKeyID(); +// } +// if (keyId == 0) { +// // this shouldn't happen +// return true; +// } +// +// Intent intent = new Intent(this, KeyServerQueryActivity.class); +// intent.setAction(KeyServerQueryActivity.ACTION_LOOK_UP_KEY_ID_AND_RETURN); +// intent.putExtra(KeyServerQueryActivity.EXTRA_KEY_ID, keyId); +// startActivityForResult(intent, Id.request.look_up_key_id); +// +// return true; +// } +// +// case Id.menu.exportToServer: { +// mSelectedItem = groupPosition; +// final int keyRingId = mListAdapter.getKeyRingId(groupPosition); +// +// Intent intent = new Intent(this, KeyServerUploadActivity.class); +// intent.setAction(KeyServerUploadActivity.ACTION_EXPORT_KEY_TO_SERVER); +// intent.putExtra(KeyServerUploadActivity.EXTRA_KEY_ID, keyRingId); +// startActivityForResult(intent, Id.request.export_to_server); +// +// return true; +// } +// +// case Id.menu.signKey: { +// mSelectedItem = groupPosition; +// final int keyRingId = mListAdapter.getKeyRingId(groupPosition); +// long keyId = 0; +// PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, keyRingId); +// if (keyRing != null) { +// keyId = PGPHelper.getMasterKey((PGPPublicKeyRing) keyRing).getKeyID(); +// } +// +// if (keyId == 0) { +// // this shouldn't happen +// return true; +// } +// +// Intent intent = new Intent(this, SignKeyActivity.class); +// intent.putExtra(SignKeyActivity.EXTRA_KEY_ID, keyId); +// startActivity(intent); +// +// return true; +// } +// +// default: { +// return super.onContextItemSelected(menuItem); +// } +// } +// } +// +// @Override +// protected void onActivityResult(int requestCode, int resultCode, Intent data) { +// switch (requestCode) { +// case Id.request.look_up_key_id: { +// if (resultCode == RESULT_CANCELED || data == null +// || data.getStringExtra(KeyServerQueryActivity.RESULT_EXTRA_TEXT) == null) { +// return; +// } +// +// Intent intent = new Intent(this, KeyListPublicActivity.class); +// intent.setAction(KeyListPublicActivity.ACTION_IMPORT); +// intent.putExtra(KeyListPublicActivity.EXTRA_TEXT, +// data.getStringExtra(KeyListActivityOld.EXTRA_TEXT)); +// handleIntent(intent); +// break; +// } +// +// default: { +// super.onActivityResult(requestCode, resultCode, data); +// break; +// } +// } +// } +//} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyListPublicFragment.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyListPublicFragment.java new file mode 100644 index 000000000..1753b0f1c --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyListPublicFragment.java @@ -0,0 +1,100 @@ +package org.thialfihar.android.apg.ui; + +import org.thialfihar.android.apg.Id; +import org.thialfihar.android.apg.R; +import org.thialfihar.android.apg.R.id; +import org.thialfihar.android.apg.provider.ApgContract.PublicKeyRings; +import org.thialfihar.android.apg.provider.ApgContract.PublicKeys; +import org.thialfihar.android.apg.provider.ApgContract.PublicUserIds; +import org.thialfihar.android.apg.ui.widget.ExpandableListFragment; +import org.thialfihar.android.apg.ui.widget.KeyListAdapter; + +import com.actionbarsherlock.app.SherlockFragmentActivity; +import com.actionbarsherlock.app.SherlockListFragment; + +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.content.CursorLoader; +import android.support.v4.content.Loader; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.LoaderManager; + +public class KeyListPublicFragment extends ExpandableListFragment implements + LoaderManager.LoaderCallbacks { + + private FragmentActivity mActivity; + private KeyListAdapter mAdapter; + + // private long mCurrentRowId; + + /** + * Define Adapter and Loader on create of Activity + */ + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + mActivity = getActivity(); + + // register long press context menu + registerForContextMenu(getListView()); + + // Give some text to display if there is no data. In a real + // application this would come from a resource. + setEmptyText("TODO empty"); + + // We have a menu item to show in action bar. + setHasOptionsMenu(true); + + mAdapter = new KeyListAdapter(mActivity, getLoaderManager(), null, Id.type.public_key); + setListAdapter(mAdapter); + + // Start out with a progress indicator. + setListShown(false); + + // Prepare the loader. Either re-connect with an existing one, + // or start a new one. + getLoaderManager().initLoader(-1, null, this); + } + + // These are the rows that we will retrieve. + static final String[] PROJECTION = new String[] { PublicKeyRings._ID, + PublicKeyRings.MASTER_KEY_ID, PublicUserIds.USER_ID }; + + static final String SORT_ORDER = PublicUserIds.USER_ID + " ASC"; + + @Override + public Loader onCreateLoader(int id, Bundle args) { + // This is called when a new Loader needs to be created. This + // sample only has one Loader, so we don't care about the ID. + Uri baseUri = PublicKeyRings.buildPublicKeyRingsUri(); + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + return new CursorLoader(getActivity(), baseUri, PROJECTION, null, null, SORT_ORDER); + } + + @Override + public void onLoadFinished(Loader loader, Cursor data) { + // Swap the new cursor in. (The framework will take care of closing the + // old cursor once we return.) + mAdapter.setGroupCursor(data); + + // The list should now be shown. + if (isResumed()) { + setListShown(true); + } else { + setListShownNoAnimation(true); + } + } + + @Override + public void onLoaderReset(Loader loader) { + // This is called when the last Cursor provided to onLoadFinished() + // above is about to be closed. We need to make sure we are no + // longer using it. + mAdapter.setGroupCursor(null); + } + +} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyListSecretActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyListSecretActivity.java new file mode 100644 index 000000000..2ac059038 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyListSecretActivity.java @@ -0,0 +1,199 @@ +package org.thialfihar.android.apg.ui; + +import org.thialfihar.android.apg.Constants; +import org.thialfihar.android.apg.Id; +import org.thialfihar.android.apg.R; +import org.thialfihar.android.apg.helper.PGPHelper; +import org.thialfihar.android.apg.helper.PGPMain; +import org.thialfihar.android.apg.service.PassphraseCacheService; +import org.thialfihar.android.apg.ui.dialog.PassphraseDialogFragment; +import org.thialfihar.android.apg.ui.widget.KeyListAdapter; +import org.thialfihar.android.apg.util.Log; + +import com.actionbarsherlock.app.ActionBar; +import com.actionbarsherlock.app.SherlockFragmentActivity; +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuItem; +import com.google.zxing.integration.android.IntentIntegrator; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.Messenger; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.View; +import android.widget.ExpandableListView; +import android.widget.ExpandableListView.ExpandableListContextMenuInfo; + +public class KeyListSecretActivity extends KeyListActivity { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.key_list_secret_activity); + + mExportFilename = Constants.path.APP_DIR + "/secexport.asc"; + mKeyType = Id.type.secret_key; + + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.add(3, Id.menu.option.search, 0, R.string.menu_search) + .setIcon(R.drawable.ic_menu_search).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); + menu.add(1, Id.menu.option.create, 1, R.string.menu_createKey).setShowAsAction( + MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + menu.add(0, Id.menu.option.import_keys, 2, R.string.menu_importKeys).setShowAsAction( + MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + menu.add(0, Id.menu.option.export_keys, 3, R.string.menu_exportKeys).setShowAsAction( + MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case Id.menu.option.create: { + createKey(); + return true; + } + + default: { + return super.onOptionsItemSelected(item); + } + } + } + + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, v, menuInfo); + ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo; + int type = ExpandableListView.getPackedPositionType(info.packedPosition); + + if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { + // TODO: user id? menu.setHeaderTitle("Key"); + menu.add(0, Id.menu.edit, 0, R.string.menu_editKey); + menu.add(0, Id.menu.export, 1, R.string.menu_exportKey); + menu.add(0, Id.menu.delete, 2, R.string.menu_deleteKey); + menu.add(0, Id.menu.share_qr_code, 2, R.string.menu_share); + } + } + + @Override + public boolean onContextItemSelected(android.view.MenuItem menuItem) { + ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuItem.getMenuInfo(); + int type = ExpandableListView.getPackedPositionType(info.packedPosition); + int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition); + + if (type != ExpandableListView.PACKED_POSITION_TYPE_GROUP) { + return super.onContextItemSelected(menuItem); + } + + switch (menuItem.getItemId()) { + case Id.menu.edit: { + mSelectedItem = groupPosition; + checkPassPhraseAndEdit(); + return true; + } + + case Id.menu.share_qr_code: { + mSelectedItem = groupPosition; + + long keyId = ((KeyListAdapter) mList.getExpandableListAdapter()) + .getGroupId(mSelectedItem); + // String msg = keyId + "," + PGPHelper.getFingerPrint(keyId); + String msg = PGPHelper.getPubkeyAsArmoredString(this, keyId); + + new IntentIntegrator(this).shareText(msg); + } + + default: { + return super.onContextItemSelected(menuItem); + } + } + } + + public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, + int childPosition, long id) { + mSelectedItem = groupPosition; + checkPassPhraseAndEdit(); + return true; + } + + public void checkPassPhraseAndEdit() { + long keyId = ((KeyListAdapter) mList.getExpandableListAdapter()).getGroupId(mSelectedItem); + String passPhrase = PassphraseCacheService.getCachedPassphrase(this, keyId); + if (passPhrase == null) { + showPassphraseDialog(keyId); + } else { + PGPMain.setEditPassPhrase(passPhrase); + editKey(); + } + } + + private void showPassphraseDialog(final long secretKeyId) { + // Message is received after passphrase is cached + Handler returnHandler = new Handler() { + @Override + public void handleMessage(Message message) { + if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { + String passPhrase = PassphraseCacheService.getCachedPassphrase( + KeyListSecretActivity.this, secretKeyId); + PGPMain.setEditPassPhrase(passPhrase); + editKey(); + } + } + }; + + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(returnHandler); + + try { + PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance( + KeyListSecretActivity.this, messenger, secretKeyId); + + passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog"); + } catch (PGPMain.ApgGeneralException e) { + Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); + // send message to handler to start encryption directly + returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); + } + } + + private void createKey() { + PGPMain.setEditPassPhrase(""); + Intent intent = new Intent(EditKeyActivity.ACTION_CREATE_KEY); + startActivityForResult(intent, Id.message.create_key); + } + + private void editKey() { + long keyId = ((KeyListAdapter) mList.getExpandableListAdapter()).getGroupId(mSelectedItem); + Intent intent = new Intent(EditKeyActivity.ACTION_EDIT_KEY); + intent.putExtra(EditKeyActivity.EXTRA_KEY_ID, keyId); + startActivityForResult(intent, Id.message.edit_key); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case Id.message.create_key: // intentionally no break + case Id.message.edit_key: { + if (resultCode == RESULT_OK) { + // refreshList(); + } + break; + } + + default: { + break; + } + } + + super.onActivityResult(requestCode, resultCode, data); + } + +} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyListSecretActivityOld.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyListSecretActivityOld.java new file mode 100644 index 000000000..adca32997 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyListSecretActivityOld.java @@ -0,0 +1,210 @@ +///* +// * Copyright (C) 2010 Thialfihar +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +// +//package org.thialfihar.android.apg.ui; +// +//import org.thialfihar.android.apg.R; +//import org.thialfihar.android.apg.Constants; +//import org.thialfihar.android.apg.Id; +//import org.thialfihar.android.apg.helper.PGPHelper; +//import org.thialfihar.android.apg.helper.PGPMain; +//import org.thialfihar.android.apg.service.PassphraseCacheService; +//import org.thialfihar.android.apg.ui.dialog.PassphraseDialogFragment; +//import org.thialfihar.android.apg.util.Log; +// +//import com.actionbarsherlock.view.Menu; +//import com.actionbarsherlock.view.MenuItem; +// +//import android.content.Intent; +//import android.os.Bundle; +//import android.os.Handler; +//import android.os.Message; +//import android.os.Messenger; +//import android.view.ContextMenu; +//import android.view.ContextMenu.ContextMenuInfo; +//import android.view.View; +//import android.widget.ExpandableListView; +//import android.widget.ExpandableListView.ExpandableListContextMenuInfo; +//import android.widget.ExpandableListView.OnChildClickListener; +// +//import com.google.zxing.integration.android.IntentIntegrator; +// +//public class KeyListSecretActivityOld extends KeyListActivityOld implements OnChildClickListener { +// +// @Override +// public void onCreate(Bundle savedInstanceState) { +// mExportFilename = Constants.path.APP_DIR + "/secexport.asc"; +// mKeyType = Id.type.secret_key; +// super.onCreate(savedInstanceState); +// mList.setOnChildClickListener(this); +// } +// +// @Override +// public boolean onCreateOptionsMenu(Menu menu) { +// menu.add(3, Id.menu.option.search, 0, R.string.menu_search) +// .setIcon(R.drawable.ic_menu_search).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); +// menu.add(1, Id.menu.option.create, 1, R.string.menu_createKey).setShowAsAction( +// MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); +// menu.add(0, Id.menu.option.import_keys, 2, R.string.menu_importKeys).setShowAsAction( +// MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); +// menu.add(0, Id.menu.option.export_keys, 3, R.string.menu_exportKeys).setShowAsAction( +// MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); +// +// return true; +// } +// +// @Override +// public boolean onOptionsItemSelected(MenuItem item) { +// switch (item.getItemId()) { +// case Id.menu.option.create: { +// createKey(); +// return true; +// } +// +// default: { +// return super.onOptionsItemSelected(item); +// } +// } +// } +// +// @Override +// public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { +// super.onCreateContextMenu(menu, v, menuInfo); +// ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo; +// int type = ExpandableListView.getPackedPositionType(info.packedPosition); +// +// if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { +// // TODO: user id? menu.setHeaderTitle("Key"); +// menu.add(0, Id.menu.edit, 0, R.string.menu_editKey); +// menu.add(0, Id.menu.export, 1, R.string.menu_exportKey); +// menu.add(0, Id.menu.delete, 2, R.string.menu_deleteKey); +// menu.add(0, Id.menu.share_qr_code, 2, R.string.menu_share); +// } +// } +// +// @Override +// public boolean onContextItemSelected(android.view.MenuItem menuItem) { +// ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuItem.getMenuInfo(); +// int type = ExpandableListView.getPackedPositionType(info.packedPosition); +// int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition); +// +// if (type != ExpandableListView.PACKED_POSITION_TYPE_GROUP) { +// return super.onContextItemSelected(menuItem); +// } +// +// switch (menuItem.getItemId()) { +// case Id.menu.edit: { +// mSelectedItem = groupPosition; +// checkPassPhraseAndEdit(); +// return true; +// } +// +// case Id.menu.share_qr_code: { +// mSelectedItem = groupPosition; +// +// long keyId = ((KeyListAdapter) mList.getExpandableListAdapter()) +// .getGroupId(mSelectedItem); +// // String msg = keyId + "," + PGPHelper.getFingerPrint(keyId); +// String msg = PGPHelper.getPubkeyAsArmoredString(this, keyId); +// +// new IntentIntegrator(this).shareText(msg); +// } +// +// default: { +// return super.onContextItemSelected(menuItem); +// } +// } +// } +// +// public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, +// int childPosition, long id) { +// mSelectedItem = groupPosition; +// checkPassPhraseAndEdit(); +// return true; +// } +// +// public void checkPassPhraseAndEdit() { +// long keyId = ((KeyListAdapter) mList.getExpandableListAdapter()).getGroupId(mSelectedItem); +// String passPhrase = PassphraseCacheService.getCachedPassphrase(this, keyId); +// if (passPhrase == null) { +// showPassphraseDialog(keyId); +// } else { +// PGPMain.setEditPassPhrase(passPhrase); +// editKey(); +// } +// } +// +// private void showPassphraseDialog(final long secretKeyId) { +// // Message is received after passphrase is cached +// Handler returnHandler = new Handler() { +// @Override +// public void handleMessage(Message message) { +// if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { +// String passPhrase = PassphraseCacheService.getCachedPassphrase( +// KeyListSecretActivity.this, secretKeyId); +// PGPMain.setEditPassPhrase(passPhrase); +// editKey(); +// } +// } +// }; +// +// // Create a new Messenger for the communication back +// Messenger messenger = new Messenger(returnHandler); +// +// try { +// PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance( +// KeyListSecretActivity.this, messenger, secretKeyId); +// +// passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog"); +// } catch (PGPMain.ApgGeneralException e) { +// Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); +// // send message to handler to start encryption directly +// returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); +// } +// } +// +// private void createKey() { +// PGPMain.setEditPassPhrase(""); +// Intent intent = new Intent(EditKeyActivity.ACTION_CREATE_KEY); +// startActivityForResult(intent, Id.message.create_key); +// } +// +// private void editKey() { +// long keyId = ((KeyListAdapter) mList.getExpandableListAdapter()).getGroupId(mSelectedItem); +// Intent intent = new Intent(EditKeyActivity.ACTION_EDIT_KEY); +// intent.putExtra(EditKeyActivity.EXTRA_KEY_ID, keyId); +// startActivityForResult(intent, Id.message.edit_key); +// } +// +// @Override +// protected void onActivityResult(int requestCode, int resultCode, Intent data) { +// switch (requestCode) { +// case Id.message.create_key: // intentionally no break +// case Id.message.edit_key: { +// if (resultCode == RESULT_OK) { +// refreshList(); +// } +// break; +// } +// +// default: { +// break; +// } +// } +// +// super.onActivityResult(requestCode, resultCode, data); +// } +//} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyListSecretFragment.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyListSecretFragment.java new file mode 100644 index 000000000..30a4b0a86 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyListSecretFragment.java @@ -0,0 +1,94 @@ +package org.thialfihar.android.apg.ui; + +import org.thialfihar.android.apg.Id; +import org.thialfihar.android.apg.provider.ApgContract.SecretKeyRings; +import org.thialfihar.android.apg.provider.ApgContract.SecretUserIds; +import org.thialfihar.android.apg.ui.widget.ExpandableListFragment; +import org.thialfihar.android.apg.ui.widget.KeyListAdapter; + +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.content.CursorLoader; +import android.support.v4.content.Loader; +import android.support.v4.app.FragmentActivity; +import android.support.v4.app.LoaderManager; + +public class KeyListSecretFragment extends ExpandableListFragment implements + LoaderManager.LoaderCallbacks { + + private FragmentActivity mActivity; + private KeyListAdapter mAdapter; + + // private long mCurrentRowId; + + /** + * Define Adapter and Loader on create of Activity + */ + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + mActivity = getActivity(); + + // register long press context menu + registerForContextMenu(getListView()); + + // Give some text to display if there is no data. In a real + // application this would come from a resource. + setEmptyText("TODO empty"); + + // We have a menu item to show in action bar. + setHasOptionsMenu(true); + + mAdapter = new KeyListAdapter(mActivity, getLoaderManager(), null, Id.type.secret_key); + setListAdapter(mAdapter); + + // Start out with a progress indicator. + setListShown(false); + + // Prepare the loader. Either re-connect with an existing one, + // or start a new one. + getLoaderManager().initLoader(-1, null, this); + } + + // These are the rows that we will retrieve. + static final String[] PROJECTION = new String[] { SecretKeyRings._ID, + SecretKeyRings.MASTER_KEY_ID, SecretUserIds.USER_ID }; + + static final String SORT_ORDER = SecretUserIds.USER_ID + " ASC"; + + @Override + public Loader onCreateLoader(int id, Bundle args) { + // This is called when a new Loader needs to be created. This + // sample only has one Loader, so we don't care about the ID. + Uri baseUri = SecretKeyRings.buildSecretKeyRingsUri(); + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + return new CursorLoader(getActivity(), baseUri, PROJECTION, null, null, SORT_ORDER); + } + + @Override + public void onLoadFinished(Loader loader, Cursor data) { + // Swap the new cursor in. (The framework will take care of closing the + // old cursor once we return.) + mAdapter.setGroupCursor(data); + + // The list should now be shown. + if (isResumed()) { + setListShown(true); + } else { + setListShownNoAnimation(true); + } + } + + @Override + public void onLoaderReset(Loader loader) { + // This is called when the last Cursor provided to onLoadFinished() + // above is about to be closed. We need to make sure we are no + // longer using it. + mAdapter.setGroupCursor(null); + } + +} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java index 268d159f8..fef8c4cf0 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java @@ -83,7 +83,7 @@ public class KeyServerQueryActivity extends SherlockFragmentActivity { case android.R.id.home: // app icon in Action Bar clicked; go home - Intent intent = new Intent(this, PublicKeyListActivity.class); + Intent intent = new Intent(this, KeyListPublicActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); return true; @@ -223,9 +223,9 @@ public class KeyServerQueryActivity extends SherlockFragmentActivity { } else { if (mKeyData != null) { Intent intent = new Intent(KeyServerQueryActivity.this, - PublicKeyListActivity.class); - intent.setAction(KeyListActivity.ACTION_IMPORT); - intent.putExtra(KeyListActivity.EXTRA_TEXT, mKeyData); + KeyListPublicActivity.class); + intent.setAction(KeyListActivityOld.ACTION_IMPORT); + intent.putExtra(KeyListActivityOld.EXTRA_TEXT, mKeyData); startActivity(intent); } } diff --git a/org_apg/src/org/thialfihar/android/apg/ui/KeyServerUploadActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/KeyServerUploadActivity.java index bc14b160a..81e513822 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/KeyServerUploadActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/KeyServerUploadActivity.java @@ -60,7 +60,7 @@ public class KeyServerUploadActivity extends SherlockFragmentActivity { case android.R.id.home: // app icon in Action Bar clicked; go home - Intent intent = new Intent(this, PublicKeyListActivity.class); + Intent intent = new Intent(this, KeyListPublicActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); return true; diff --git a/org_apg/src/org/thialfihar/android/apg/ui/MainActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/MainActivity.java index 5c9c071c9..7c25e4533 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/MainActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/MainActivity.java @@ -33,12 +33,12 @@ public class MainActivity extends SherlockActivity { public void manageKeysOnClick(View view) { // used instead of startActivity set actionbar based on callingPackage - startActivityForResult(new Intent(this, PublicKeyListActivity.class), 0); + startActivityForResult(new Intent(this, KeyListPublicActivity.class), 0); } public void myKeysOnClick(View view) { // used instead of startActivity set actionbar based on callingPackage - startActivityForResult(new Intent(this, SecretKeyListActivity.class), 0); + startActivityForResult(new Intent(this, KeyListSecretActivity.class), 0); } public void encryptOnClick(View view) { diff --git a/org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java deleted file mode 100644 index c6cc6e028..000000000 --- a/org_apg/src/org/thialfihar/android/apg/ui/PublicKeyListActivity.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2010 Thialfihar - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.thialfihar.android.apg.ui; - -import org.spongycastle.openpgp.PGPPublicKeyRing; -import org.thialfihar.android.apg.Constants; -import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.R; -import org.thialfihar.android.apg.helper.PGPHelper; -import org.thialfihar.android.apg.helper.PGPMain; -import org.thialfihar.android.apg.provider.ProviderHelper; - -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; - -import android.content.Intent; -import android.os.Bundle; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.View; -import android.widget.ExpandableListView; -import android.widget.ExpandableListView.ExpandableListContextMenuInfo; - -public class PublicKeyListActivity extends KeyListActivity { - @Override - public void onCreate(Bundle savedInstanceState) { - mExportFilename = Constants.path.APP_DIR + "/pubexport.asc"; - mKeyType = Id.type.public_key; - super.onCreate(savedInstanceState); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(1, Id.menu.option.search, 0, R.string.menu_search) - .setIcon(R.drawable.ic_menu_search).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); - menu.add(1, Id.menu.option.scanQRCode, 1, R.string.menu_scanQRCode) - .setIcon(R.drawable.ic_menu_scan_qrcode) - .setShowAsAction( - MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - menu.add(1, Id.menu.option.key_server, 2, R.string.menu_keyServer) - .setIcon(R.drawable.ic_menu_search_list) - .setShowAsAction( - MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - menu.add(0, Id.menu.option.import_keys, 3, R.string.menu_importKeys).setShowAsAction( - MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - menu.add(0, Id.menu.option.export_keys, 4, R.string.menu_exportKeys).setShowAsAction( - MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case Id.menu.option.key_server: { - startActivity(new Intent(this, KeyServerQueryActivity.class)); - - return true; - } - case Id.menu.option.scanQRCode: { - Intent intent = new Intent(this, ImportFromQRCodeActivity.class); - intent.setAction(ImportFromQRCodeActivity.IMPORT_FROM_QR_CODE); - startActivityForResult(intent, Id.request.import_from_qr_code); - - return true; - } - - default: { - return super.onOptionsItemSelected(item); - } - } - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo; - int type = ExpandableListView.getPackedPositionType(info.packedPosition); - - if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { - // TODO: user id? menu.setHeaderTitle("Key"); - menu.add(0, Id.menu.export, 0, R.string.menu_exportKey); - menu.add(0, Id.menu.delete, 1, R.string.menu_deleteKey); - menu.add(0, Id.menu.update, 1, R.string.menu_updateKey); - menu.add(0, Id.menu.exportToServer, 1, R.string.menu_exportKeyToServer); - menu.add(0, Id.menu.signKey, 1, R.string.menu_signKey); - } - } - - @Override - public boolean onContextItemSelected(android.view.MenuItem menuItem) { - ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuItem.getMenuInfo(); - int type = ExpandableListView.getPackedPositionType(info.packedPosition); - int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition); - - if (type != ExpandableListView.PACKED_POSITION_TYPE_GROUP) { - return super.onContextItemSelected(menuItem); - } - - switch (menuItem.getItemId()) { - case Id.menu.update: { - mSelectedItem = groupPosition; - final int keyRingId = mListAdapter.getKeyRingId(groupPosition); - long keyId = 0; - PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, keyRingId); - if (keyRing != null) { - keyId = PGPHelper.getMasterKey((PGPPublicKeyRing) keyRing).getKeyID(); - } - if (keyId == 0) { - // this shouldn't happen - return true; - } - - Intent intent = new Intent(this, KeyServerQueryActivity.class); - intent.setAction(KeyServerQueryActivity.ACTION_LOOK_UP_KEY_ID_AND_RETURN); - intent.putExtra(KeyServerQueryActivity.EXTRA_KEY_ID, keyId); - startActivityForResult(intent, Id.request.look_up_key_id); - - return true; - } - - case Id.menu.exportToServer: { - mSelectedItem = groupPosition; - final int keyRingId = mListAdapter.getKeyRingId(groupPosition); - - Intent intent = new Intent(this, KeyServerUploadActivity.class); - intent.setAction(KeyServerUploadActivity.ACTION_EXPORT_KEY_TO_SERVER); - intent.putExtra(KeyServerUploadActivity.EXTRA_KEY_ID, keyRingId); - startActivityForResult(intent, Id.request.export_to_server); - - return true; - } - - case Id.menu.signKey: { - mSelectedItem = groupPosition; - final int keyRingId = mListAdapter.getKeyRingId(groupPosition); - long keyId = 0; - PGPPublicKeyRing keyRing = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, keyRingId); - if (keyRing != null) { - keyId = PGPHelper.getMasterKey((PGPPublicKeyRing) keyRing).getKeyID(); - } - - if (keyId == 0) { - // this shouldn't happen - return true; - } - - Intent intent = new Intent(this, SignKeyActivity.class); - intent.putExtra(SignKeyActivity.EXTRA_KEY_ID, keyId); - startActivity(intent); - - return true; - } - - default: { - return super.onContextItemSelected(menuItem); - } - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode) { - case Id.request.look_up_key_id: { - if (resultCode == RESULT_CANCELED || data == null - || data.getStringExtra(KeyServerQueryActivity.RESULT_EXTRA_TEXT) == null) { - return; - } - - Intent intent = new Intent(this, PublicKeyListActivity.class); - intent.setAction(PublicKeyListActivity.ACTION_IMPORT); - intent.putExtra(PublicKeyListActivity.EXTRA_TEXT, - data.getStringExtra(KeyListActivity.EXTRA_TEXT)); - handleIntent(intent); - break; - } - - default: { - super.onActivityResult(requestCode, resultCode, data); - break; - } - } - } -} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java deleted file mode 100644 index c06c68943..000000000 --- a/org_apg/src/org/thialfihar/android/apg/ui/SecretKeyListActivity.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (C) 2010 Thialfihar - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.thialfihar.android.apg.ui; - -import org.thialfihar.android.apg.R; -import org.thialfihar.android.apg.Constants; -import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.helper.PGPHelper; -import org.thialfihar.android.apg.helper.PGPMain; -import org.thialfihar.android.apg.service.PassphraseCacheService; -import org.thialfihar.android.apg.ui.dialog.PassphraseDialogFragment; -import org.thialfihar.android.apg.util.Log; - -import com.actionbarsherlock.view.Menu; -import com.actionbarsherlock.view.MenuItem; - -import android.content.Intent; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.os.Messenger; -import android.view.ContextMenu; -import android.view.ContextMenu.ContextMenuInfo; -import android.view.View; -import android.widget.ExpandableListView; -import android.widget.ExpandableListView.ExpandableListContextMenuInfo; -import android.widget.ExpandableListView.OnChildClickListener; - -import com.google.zxing.integration.android.IntentIntegrator; - -public class SecretKeyListActivity extends KeyListActivity implements OnChildClickListener { - - @Override - public void onCreate(Bundle savedInstanceState) { - mExportFilename = Constants.path.APP_DIR + "/secexport.asc"; - mKeyType = Id.type.secret_key; - super.onCreate(savedInstanceState); - mList.setOnChildClickListener(this); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(3, Id.menu.option.search, 0, R.string.menu_search) - .setIcon(R.drawable.ic_menu_search).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); - menu.add(1, Id.menu.option.create, 1, R.string.menu_createKey).setShowAsAction( - MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - menu.add(0, Id.menu.option.import_keys, 2, R.string.menu_importKeys).setShowAsAction( - MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - menu.add(0, Id.menu.option.export_keys, 3, R.string.menu_exportKeys).setShowAsAction( - MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case Id.menu.option.create: { - createKey(); - return true; - } - - default: { - return super.onOptionsItemSelected(item); - } - } - } - - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, v, menuInfo); - ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo; - int type = ExpandableListView.getPackedPositionType(info.packedPosition); - - if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { - // TODO: user id? menu.setHeaderTitle("Key"); - menu.add(0, Id.menu.edit, 0, R.string.menu_editKey); - menu.add(0, Id.menu.export, 1, R.string.menu_exportKey); - menu.add(0, Id.menu.delete, 2, R.string.menu_deleteKey); - menu.add(0, Id.menu.share_qr_code, 2, R.string.menu_share); - } - } - - @Override - public boolean onContextItemSelected(android.view.MenuItem menuItem) { - ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuItem.getMenuInfo(); - int type = ExpandableListView.getPackedPositionType(info.packedPosition); - int groupPosition = ExpandableListView.getPackedPositionGroup(info.packedPosition); - - if (type != ExpandableListView.PACKED_POSITION_TYPE_GROUP) { - return super.onContextItemSelected(menuItem); - } - - switch (menuItem.getItemId()) { - case Id.menu.edit: { - mSelectedItem = groupPosition; - checkPassPhraseAndEdit(); - return true; - } - - case Id.menu.share_qr_code: { - mSelectedItem = groupPosition; - - long keyId = ((KeyListAdapter) mList.getExpandableListAdapter()) - .getGroupId(mSelectedItem); - // String msg = keyId + "," + PGPHelper.getFingerPrint(keyId); - String msg = PGPHelper.getPubkeyAsArmoredString(this, keyId); - - new IntentIntegrator(this).shareText(msg); - } - - default: { - return super.onContextItemSelected(menuItem); - } - } - } - - public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, - int childPosition, long id) { - mSelectedItem = groupPosition; - checkPassPhraseAndEdit(); - return true; - } - - public void checkPassPhraseAndEdit() { - long keyId = ((KeyListAdapter) mList.getExpandableListAdapter()).getGroupId(mSelectedItem); - String passPhrase = PassphraseCacheService.getCachedPassphrase(this, keyId); - if (passPhrase == null) { - showPassphraseDialog(keyId); - } else { - PGPMain.setEditPassPhrase(passPhrase); - editKey(); - } - } - - private void showPassphraseDialog(final long secretKeyId) { - // Message is received after passphrase is cached - Handler returnHandler = new Handler() { - @Override - public void handleMessage(Message message) { - if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { - String passPhrase = PassphraseCacheService.getCachedPassphrase( - SecretKeyListActivity.this, secretKeyId); - PGPMain.setEditPassPhrase(passPhrase); - editKey(); - } - } - }; - - // Create a new Messenger for the communication back - Messenger messenger = new Messenger(returnHandler); - - try { - PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance( - SecretKeyListActivity.this, messenger, secretKeyId); - - passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog"); - } catch (PGPMain.ApgGeneralException e) { - Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!"); - // send message to handler to start encryption directly - returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY); - } - } - - private void createKey() { - PGPMain.setEditPassPhrase(""); - Intent intent = new Intent(EditKeyActivity.ACTION_CREATE_KEY); - startActivityForResult(intent, Id.message.create_key); - } - - private void editKey() { - long keyId = ((KeyListAdapter) mList.getExpandableListAdapter()).getGroupId(mSelectedItem); - Intent intent = new Intent(EditKeyActivity.ACTION_EDIT_KEY); - intent.putExtra(EditKeyActivity.EXTRA_KEY_ID, keyId); - startActivityForResult(intent, Id.message.edit_key); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - switch (requestCode) { - case Id.message.create_key: // intentionally no break - case Id.message.edit_key: { - if (resultCode == RESULT_OK) { - refreshList(); - } - break; - } - - default: { - break; - } - } - - super.onActivityResult(requestCode, resultCode, data); - } -} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivity.java index 5d66e3e46..2b6a3967c 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivity.java @@ -1,198 +1,47 @@ -/* - * Copyright (C) 2010 Thialfihar - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package org.thialfihar.android.apg.ui; -import java.util.Vector; - -import org.thialfihar.android.apg.Constants; import org.thialfihar.android.apg.R; -import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.ui.widget.SelectPublicKeyListAdapter; import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.SherlockFragmentActivity; -import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuItem; -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 SherlockFragmentActivity { + private ActionBar mActionBar; - // Not used in sourcode, but listed in AndroidManifest! - public static final String ACTION_SELECT_PUBLIC_KEYS = Constants.INTENT_PREFIX - + "SELECT_PUBLIC_KEYS"; - + // TODO public static final String RESULT_EXTRA_SELECTION = "selection"; public static final String RESULT_EXTRA_USER_IDS = "userIds"; - protected ListView mList; - protected SelectPublicKeyListAdapter mListAdapter; - protected View mFilterLayout; - protected Button mClearFilterButton; - protected TextView mFilterInfo; - @Override - public void onCreate(Bundle savedInstanceState) { + protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - final ActionBar actionBar = getSupportActionBar(); - actionBar.setDisplayShowTitleEnabled(true); - actionBar.setDisplayHomeAsUpEnabled(false); - actionBar.setHomeButtonEnabled(false); - - setContentView(R.layout.select_public_key); - - setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); - - mList = (ListView) findViewById(R.id.list); - // needed in Android 1.5, where the XML attribute gets ignored - mList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); - - mFilterLayout = findViewById(R.id.layout_filter); - mFilterInfo = (TextView) mFilterLayout.findViewById(R.id.filterInfo); - mClearFilterButton = (Button) mFilterLayout.findViewById(R.id.btn_clear); - - mClearFilterButton.setOnClickListener(new OnClickListener() { - 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; - selectedKeyIds = intent.getLongArrayExtra(RESULT_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); + mActionBar = getSupportActionBar(); - 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; - } - } - } - } - } + setContentView(R.layout.select_public_key_activity); - private void cancelClicked() { - setResult(RESULT_CANCELED, null); - finish(); - } - - private void okClicked() { - Intent data = new Intent(); - Vector keys = new Vector(); - Vector userIds = new Vector(); - for (int i = 0; i < mList.getCount(); ++i) { - if (mList.isItemChecked(i)) { - keys.add(mList.getItemIdAtPosition(i)); - userIds.add((String) mList.getItemAtPosition(i)); - } - } - long selectedKeyIds[] = new long[keys.size()]; - for (int i = 0; i < keys.size(); ++i) { - selectedKeyIds[i] = keys.get(i); - } - String userIdArray[] = new String[0]; - data.putExtra(RESULT_EXTRA_SELECTION, selectedKeyIds); - data.putExtra(RESULT_EXTRA_USER_IDS, userIds.toArray(userIdArray)); - setResult(RESULT_OK, data); - finish(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, Id.menu.option.search, 0, R.string.menu_search).setIcon( - android.R.drawable.ic_menu_search); - menu.add(1, Id.menu.option.cancel, 0, R.string.btn_doNotSave).setShowAsAction( - MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - menu.add(1, Id.menu.option.okay, 1, R.string.btn_okay).setShowAsAction( - MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - return true; + mActionBar.setDisplayShowTitleEnabled(true); + mActionBar.setDisplayHomeAsUpEnabled(true); } + /** + * Menu Options + */ @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { - - case Id.menu.option.okay: - okClicked(); + case android.R.id.home: + // app icon in Action Bar clicked; go home + Intent intent = new Intent(this, MainActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); return true; - - case Id.menu.option.cancel: - cancelClicked(); - return true; - default: - break; - + return super.onOptionsItemSelected(item); } - return false; } } diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivityOld.java b/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivityOld.java new file mode 100644 index 000000000..c52eaf17e --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListActivityOld.java @@ -0,0 +1,198 @@ +///* +// * Copyright (C) 2010 Thialfihar +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +// +//package org.thialfihar.android.apg.ui; +// +//import java.util.Vector; +// +//import org.thialfihar.android.apg.Constants; +//import org.thialfihar.android.apg.R; +//import org.thialfihar.android.apg.Id; +//import org.thialfihar.android.apg.ui.widget.SelectPublicKeyListAdapter; +// +//import com.actionbarsherlock.app.ActionBar; +//import com.actionbarsherlock.app.SherlockFragmentActivity; +//import com.actionbarsherlock.view.Menu; +//import com.actionbarsherlock.view.MenuItem; +// +//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 SelectPublicKeyListActivityOld extends SherlockFragmentActivity { +// +// // Not used in sourcode, but listed in AndroidManifest! +// public static final String ACTION_SELECT_PUBLIC_KEYS = Constants.INTENT_PREFIX +// + "SELECT_PUBLIC_KEYS"; +// +// public static final String RESULT_EXTRA_SELECTION = "selection"; +// public static final String RESULT_EXTRA_USER_IDS = "userIds"; +// +// protected ListView mList; +// protected SelectPublicKeyListAdapter mListAdapter; +// protected View mFilterLayout; +// protected Button mClearFilterButton; +// protected TextView mFilterInfo; +// +// @Override +// public void onCreate(Bundle savedInstanceState) { +// super.onCreate(savedInstanceState); +// +// final ActionBar actionBar = getSupportActionBar(); +// actionBar.setDisplayShowTitleEnabled(true); +// actionBar.setDisplayHomeAsUpEnabled(false); +// actionBar.setHomeButtonEnabled(false); +// +// setContentView(R.layout.select_public_key); +// +// setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); +// +// mList = (ListView) findViewById(R.id.list); +// // needed in Android 1.5, where the XML attribute gets ignored +// mList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); +// +// mFilterLayout = findViewById(R.id.layout_filter); +// mFilterInfo = (TextView) mFilterLayout.findViewById(R.id.filterInfo); +// mClearFilterButton = (Button) mFilterLayout.findViewById(R.id.btn_clear); +// +// mClearFilterButton.setOnClickListener(new OnClickListener() { +// 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; +// selectedKeyIds = intent.getLongArrayExtra(RESULT_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() { +// setResult(RESULT_CANCELED, null); +// finish(); +// } +// +// private void okClicked() { +// Intent data = new Intent(); +// Vector keys = new Vector(); +// Vector userIds = new Vector(); +// for (int i = 0; i < mList.getCount(); ++i) { +// if (mList.isItemChecked(i)) { +// keys.add(mList.getItemIdAtPosition(i)); +// userIds.add((String) mList.getItemAtPosition(i)); +// } +// } +// long selectedKeyIds[] = new long[keys.size()]; +// for (int i = 0; i < keys.size(); ++i) { +// selectedKeyIds[i] = keys.get(i); +// } +// String userIdArray[] = new String[0]; +// data.putExtra(RESULT_EXTRA_SELECTION, selectedKeyIds); +// data.putExtra(RESULT_EXTRA_USER_IDS, userIds.toArray(userIdArray)); +// setResult(RESULT_OK, data); +// finish(); +// } +// +// @Override +// public boolean onCreateOptionsMenu(Menu menu) { +// menu.add(0, Id.menu.option.search, 0, R.string.menu_search).setIcon( +// android.R.drawable.ic_menu_search); +// menu.add(1, Id.menu.option.cancel, 0, R.string.btn_doNotSave).setShowAsAction( +// MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT); +// menu.add(1, Id.menu.option.okay, 1, R.string.btn_okay).setShowAsAction( +// MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT); +// return true; +// } +// +// @Override +// public boolean onOptionsItemSelected(MenuItem item) { +// switch (item.getItemId()) { +// +// case Id.menu.option.okay: +// okClicked(); +// return true; +// +// case Id.menu.option.cancel: +// cancelClicked(); +// return true; +// +// default: +// break; +// +// } +// return false; +// } +//} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListFragment.java b/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListFragment.java new file mode 100644 index 000000000..b89943d46 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/SelectPublicKeyListFragment.java @@ -0,0 +1,112 @@ +package org.thialfihar.android.apg.ui; + +import java.util.Date; + +import org.thialfihar.android.apg.R; +import org.thialfihar.android.apg.provider.ApgContract.PublicKeyRings; +import org.thialfihar.android.apg.provider.ApgContract.PublicKeys; +import org.thialfihar.android.apg.provider.ApgContract.PublicUserIds; +import org.thialfihar.android.apg.ui.widget.SelectPublicKeyCursorAdapter; + +import com.actionbarsherlock.app.SherlockFragmentActivity; +import com.actionbarsherlock.app.SherlockListActivity; +import com.actionbarsherlock.app.SherlockListFragment; + +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.content.CursorLoader; +import android.support.v4.content.Loader; +import android.support.v4.app.LoaderManager; + +public class SelectPublicKeyListFragment extends SherlockListFragment implements + LoaderManager.LoaderCallbacks { + + private SherlockFragmentActivity mActivity; + private SelectPublicKeyCursorAdapter mAdapter; + + private long mCurrentRowId; + + /** + * Define Adapter and Loader on create of Activity + */ + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + mActivity = getSherlockActivity(); + + // register long press context menu + registerForContextMenu(getListView()); + + // Give some text to display if there is no data. In a real + // application this would come from a resource. + setEmptyText("TODO empty"); + + // We have a menu item to show in action bar. + setHasOptionsMenu(true); + + mAdapter = new SelectPublicKeyCursorAdapter(mActivity, null); + + setListAdapter(mAdapter); + + // Start out with a progress indicator. + setListShown(false); + + // Prepare the loader. Either re-connect with an existing one, + // or start a new one. + getLoaderManager().initLoader(0, null, this); + } + + static final String SORT_ORDER = PublicUserIds.USER_ID + " ASC"; + + // static final String SELECTION = + + @Override + public Loader onCreateLoader(int id, Bundle args) { + // This is called when a new Loader needs to be created. This + // sample only has one Loader, so we don't care about the ID. + Uri baseUri = PublicKeyRings.buildPublicKeyRingsUri(); + + // Now create and return a CursorLoader that will take care of + // creating a Cursor for the data being displayed. + + // These are the rows that we will retrieve. + long now = new Date().getTime() / 1000; + String[] projection = new String[] { + PublicKeyRings._ID, // 0 + PublicKeyRings.MASTER_KEY_ID, // 1 + PublicUserIds.USER_ID, // 2 + "(SELECT COUNT(" + PublicKeys._ID + ") WHERE " + PublicKeys.IS_REVOKED + + " = '0' AND " + PublicKeys.CAN_ENCRYPT + " = '1')", // 3 + "(SELECT COUNT(" + PublicKeys._ID + ") WHERE " + PublicKeys.IS_REVOKED + + " = '0' AND " + PublicKeys.CAN_ENCRYPT + " = '1' AND " + + PublicKeys.CREATION + " <= '" + now + "' AND " + "(" + PublicKeys.EXPIRY + + " IS NULL OR " + PublicKeys.EXPIRY + " >= '" + now + "'))", // 4 + }; + + return new CursorLoader(getActivity(), baseUri, projection, null, null, SORT_ORDER); + } + + @Override + public void onLoadFinished(Loader loader, Cursor data) { + // Swap the new cursor in. (The framework will take care of closing the + // old cursor once we return.) + mAdapter.swapCursor(data); + + // The list should now be shown. + if (isResumed()) { + setListShown(true); + } else { + setListShownNoAnimation(true); + } + } + + @Override + public void onLoaderReset(Loader loader) { + // This is called when the last Cursor provided to onLoadFinished() + // above is about to be closed. We need to make sure we are no + // longer using it. + mAdapter.swapCursor(null); + } +} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivity.java deleted file mode 100644 index f63d84215..000000000 --- a/org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivity.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2010 Thialfihar - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.thialfihar.android.apg.ui; - -import org.thialfihar.android.apg.Constants; -import org.thialfihar.android.apg.R; -import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.ui.widget.SelectSecretKeyListAdapter; - -import com.actionbarsherlock.app.ActionBar; -import com.actionbarsherlock.app.SherlockFragmentActivity; -import com.actionbarsherlock.view.Menu; - -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.AdapterView.OnItemClickListener; -import android.widget.Button; -import android.widget.ListView; -import android.widget.TextView; - -public class SelectSecretKeyListActivity extends SherlockFragmentActivity { - - // Not used in sourcode, but listed in AndroidManifest! - public static final String ACTION_SELECT_SECRET_KEY = Constants.INTENT_PREFIX - + "SELECT_SECRET_KEY"; - - public static final String RESULT_EXTRA_USER_ID = "userId"; - public static final String RESULT_EXTRA_KEY_ID = "keyId"; - - protected ListView mList; - protected SelectSecretKeyListAdapter mListAdapter; - protected View mFilterLayout; - protected Button mClearFilterButton; - protected TextView mFilterInfo; - - protected long mSelectedKeyId = 0; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - final ActionBar actionBar = getSupportActionBar(); - actionBar.setDisplayShowTitleEnabled(true); - actionBar.setDisplayHomeAsUpEnabled(false); - actionBar.setHomeButtonEnabled(false); - - setContentView(R.layout.select_secret_key); - - setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); - - mList = (ListView) findViewById(R.id.list); - - mList.setOnItemClickListener(new OnItemClickListener() { - public void onItemClick(AdapterView adapterView, View view, int position, long id) { - Intent data = new Intent(); - data.putExtra(RESULT_EXTRA_KEY_ID, id); - data.putExtra(RESULT_EXTRA_USER_ID, (String) mList.getItemAtPosition(position)); - setResult(RESULT_OK, data); - finish(); - } - }); - - mFilterLayout = findViewById(R.id.layout_filter); - mFilterInfo = (TextView) mFilterLayout.findViewById(R.id.filterInfo); - mClearFilterButton = (Button) mFilterLayout.findViewById(R.id.btn_clear); - - mClearFilterButton.setOnClickListener(new OnClickListener() { - 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); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - menu.add(0, Id.menu.option.search, 0, R.string.menu_search).setIcon( - android.R.drawable.ic_menu_search); - return true; - } -} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivityOld.java b/org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivityOld.java new file mode 100644 index 000000000..3aaccd6b7 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/SelectSecretKeyListActivityOld.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2010 Thialfihar + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.thialfihar.android.apg.ui; + +import org.thialfihar.android.apg.Constants; +import org.thialfihar.android.apg.R; +import org.thialfihar.android.apg.Id; +import org.thialfihar.android.apg.ui.widget.SelectSecretKeyListAdapterOld; + +import com.actionbarsherlock.app.ActionBar; +import com.actionbarsherlock.app.SherlockFragmentActivity; +import com.actionbarsherlock.view.Menu; + +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.AdapterView.OnItemClickListener; +import android.widget.Button; +import android.widget.ListView; +import android.widget.TextView; + +public class SelectSecretKeyListActivityOld extends SherlockFragmentActivity { + + // Not used in sourcode, but listed in AndroidManifest! + public static final String ACTION_SELECT_SECRET_KEY = Constants.INTENT_PREFIX + + "SELECT_SECRET_KEY"; + + public static final String RESULT_EXTRA_USER_ID = "userId"; + public static final String RESULT_EXTRA_KEY_ID = "keyId"; + + protected ListView mList; + protected SelectSecretKeyListAdapterOld mListAdapter; + protected View mFilterLayout; + protected Button mClearFilterButton; + protected TextView mFilterInfo; + + protected long mSelectedKeyId = 0; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + final ActionBar actionBar = getSupportActionBar(); + actionBar.setDisplayShowTitleEnabled(true); + actionBar.setDisplayHomeAsUpEnabled(false); + actionBar.setHomeButtonEnabled(false); + + setContentView(R.layout.select_secret_key); + + setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL); + + mList = (ListView) findViewById(R.id.list); + + mList.setOnItemClickListener(new OnItemClickListener() { + public void onItemClick(AdapterView adapterView, View view, int position, long id) { + Intent data = new Intent(); + data.putExtra(RESULT_EXTRA_KEY_ID, id); + data.putExtra(RESULT_EXTRA_USER_ID, (String) mList.getItemAtPosition(position)); + setResult(RESULT_OK, data); + finish(); + } + }); + + mFilterLayout = findViewById(R.id.layout_filter); + mFilterInfo = (TextView) mFilterLayout.findViewById(R.id.filterInfo); + mClearFilterButton = (Button) mFilterLayout.findViewById(R.id.btn_clear); + + mClearFilterButton.setOnClickListener(new OnClickListener() { + 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); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + menu.add(0, Id.menu.option.search, 0, R.string.menu_search).setIcon( + android.R.drawable.ic_menu_search); + return true; + } +} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java b/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java index 4fbb621a8..a49b0aa4d 100644 --- a/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java +++ b/org_apg/src/org/thialfihar/android/apg/ui/SignKeyActivity.java @@ -120,7 +120,7 @@ public class SignKeyActivity extends SherlockFragmentActivity { } else { // kick off the SecretKey selection activity so the user chooses which key to sign with // first - Intent intent = new Intent(this, SelectSecretKeyListActivity.class); + Intent intent = new Intent(this, SelectSecretKeyListActivityOld.class); startActivityForResult(intent, Id.request.secret_keys); } } diff --git a/org_apg/src/org/thialfihar/android/apg/ui/widget/ExpandableListFragment.java b/org_apg/src/org/thialfihar/android/apg/ui/widget/ExpandableListFragment.java new file mode 100644 index 000000000..46239d560 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/widget/ExpandableListFragment.java @@ -0,0 +1,530 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.thialfihar.android.apg.ui.widget; + +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; +import android.support.v4.app.Fragment; +import android.view.ContextMenu; +import android.view.ContextMenu.ContextMenuInfo; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnCreateContextMenuListener; +import android.view.ViewGroup; +import android.view.animation.AnimationUtils; +import android.widget.AdapterView; +import android.widget.ExpandableListAdapter; +import android.widget.ExpandableListView; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.ListAdapter; +import android.widget.ProgressBar; +import android.widget.TextView; + +/** + * @author Khoa Tran + * + * @see android.support.v4.app.ListFragment + * @see android.app.ExpandableListActivity + * + * ExpandableListFragment for Android < 3.0 + * + * from + * http://stackoverflow.com/questions/6051050/expandablelistfragment-with-loadermanager-for- + * compatibility-package + * + */ +public class ExpandableListFragment extends Fragment implements OnCreateContextMenuListener, + ExpandableListView.OnChildClickListener, ExpandableListView.OnGroupCollapseListener, + ExpandableListView.OnGroupExpandListener { + + static final int INTERNAL_EMPTY_ID = 0x00ff0001; + static final int INTERNAL_PROGRESS_CONTAINER_ID = 0x00ff0002; + static final int INTERNAL_LIST_CONTAINER_ID = 0x00ff0003; + + final private Handler mHandler = new Handler(); + + final private Runnable mRequestFocus = new Runnable() { + public void run() { + mExpandableList.focusableViewAvailable(mExpandableList); + } + }; + + final private AdapterView.OnItemClickListener mOnClickListener = new AdapterView.OnItemClickListener() { + public void onItemClick(AdapterView parent, View v, int position, long id) { + onListItemClick((ExpandableListView) parent, v, position, id); + } + }; + + ExpandableListAdapter mAdapter; + ExpandableListView mExpandableList; + boolean mFinishedStart = false; + View mEmptyView; + TextView mStandardEmptyView; + View mProgressContainer; + View mExpandableListContainer; + CharSequence mEmptyText; + boolean mExpandableListShown; + + public ExpandableListFragment() { + } + + /** + * Provide default implementation to return a simple list view. Subclasses can override to + * replace with their own layout. If doing so, the returned view hierarchy must have a + * ListView whose id is {@link android.R.id#list android.R.id.list} and can optionally have a + * sibling view id {@link android.R.id#empty android.R.id.empty} that is to be shown when the + * list is empty. + * + *

+ * If you are overriding this method with your own custom content, consider including the + * standard layout {@link android.R.layout#list_content} in your layout file, so that you + * continue to retain all of the standard behavior of ListFragment. In particular, this is + * currently the only way to have the built-in indeterminant progress state be shown. + */ + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + final Context context = getActivity(); + + FrameLayout root = new FrameLayout(context); + + // ------------------------------------------------------------------ + + LinearLayout pframe = new LinearLayout(context); + pframe.setId(INTERNAL_PROGRESS_CONTAINER_ID); + pframe.setOrientation(LinearLayout.VERTICAL); + pframe.setVisibility(View.GONE); + pframe.setGravity(Gravity.CENTER); + + ProgressBar progress = new ProgressBar(context, null, android.R.attr.progressBarStyleLarge); + pframe.addView(progress, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + + root.addView(pframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, + ViewGroup.LayoutParams.FILL_PARENT)); + + // ------------------------------------------------------------------ + + FrameLayout lframe = new FrameLayout(context); + lframe.setId(INTERNAL_LIST_CONTAINER_ID); + + TextView tv = new TextView(getActivity()); + tv.setId(INTERNAL_EMPTY_ID); + tv.setGravity(Gravity.CENTER); + lframe.addView(tv, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, + ViewGroup.LayoutParams.FILL_PARENT)); + + ExpandableListView lv = new ExpandableListView(getActivity()); + lv.setId(android.R.id.list); + lv.setDrawSelectorOnTop(false); + lframe.addView(lv, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, + ViewGroup.LayoutParams.FILL_PARENT)); + + root.addView(lframe, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, + ViewGroup.LayoutParams.FILL_PARENT)); + + // ------------------------------------------------------------------ + + root.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, + ViewGroup.LayoutParams.FILL_PARENT)); + + return root; + } + + /** + * Attach to list view once the view hierarchy has been created. + */ + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + ensureList(); + } + + /** + * Detach from list view. + */ + @Override + public void onDestroyView() { + mHandler.removeCallbacks(mRequestFocus); + mExpandableList = null; + mExpandableListShown = false; + mEmptyView = mProgressContainer = mExpandableListContainer = null; + mStandardEmptyView = null; + super.onDestroyView(); + } + + /** + * This method will be called when an item in the list is selected. Subclasses should override. + * Subclasses can call getListView().getItemAtPosition(position) if they need to access the data + * associated with the selected item. + * + * @param l + * The ListView where the click happened + * @param v + * The view that was clicked within the ListView + * @param position + * The position of the view in the list + * @param id + * The row id of the item that was clicked + */ + public void onListItemClick(ExpandableListView l, View v, int position, long id) { + } + + /** + * Provide the cursor for the list view. + */ + public void setListAdapter(ExpandableListAdapter adapter) { + boolean hadAdapter = mAdapter != null; + mAdapter = adapter; + if (mExpandableList != null) { + mExpandableList.setAdapter(adapter); + if (!mExpandableListShown && !hadAdapter) { + // The list was hidden, and previously didn't have an + // adapter. It is now time to show it. + setListShown(true, getView().getWindowToken() != null); + } + } + } + + /** + * Set the currently selected list item to the specified position with the adapter's data + * + * @param position + */ + public void setSelection(int position) { + ensureList(); + mExpandableList.setSelection(position); + } + + /** + * Get the position of the currently selected list item. + */ + public int getSelectedItemPosition() { + ensureList(); + return mExpandableList.getSelectedItemPosition(); + } + + /** + * Get the cursor row ID of the currently selected list item. + */ + public long getSelectedItemId() { + ensureList(); + return mExpandableList.getSelectedItemId(); + } + + /** + * Get the activity's list view widget. + */ + public ExpandableListView getListView() { + ensureList(); + return mExpandableList; + } + + /** + * The default content for a ListFragment has a TextView that can be shown when the list is + * empty. If you would like to have it shown, call this method to supply the text it should use. + */ + public void setEmptyText(CharSequence text) { + ensureList(); + if (mStandardEmptyView == null) { + throw new IllegalStateException("Can't be used with a custom content view"); + } + mStandardEmptyView.setText(text); + if (mEmptyText == null) { + mExpandableList.setEmptyView(mStandardEmptyView); + } + mEmptyText = text; + } + + /** + * Control whether the list is being displayed. You can make it not displayed if you are waiting + * for the initial data to show in it. During this time an indeterminant progress indicator will + * be shown instead. + * + *

+ * Applications do not normally need to use this themselves. The default behavior of + * ListFragment is to start with the list not being shown, only showing it once an adapter is + * given with {@link #setListAdapter(ListAdapter)}. If the list at that point had not been + * shown, when it does get shown it will be do without the user ever seeing the hidden state. + * + * @param shown + * If true, the list view is shown; if false, the progress indicator. The initial + * value is true. + */ + public void setListShown(boolean shown) { + setListShown(shown, true); + } + + /** + * Like {@link #setListShown(boolean)}, but no animation is used when transitioning from the + * previous state. + */ + public void setListShownNoAnimation(boolean shown) { + setListShown(shown, false); + } + + /** + * Control whether the list is being displayed. You can make it not displayed if you are waiting + * for the initial data to show in it. During this time an indeterminant progress indicator will + * be shown instead. + * + * @param shown + * If true, the list view is shown; if false, the progress indicator. The initial + * value is true. + * @param animate + * If true, an animation will be used to transition to the new state. + */ + private void setListShown(boolean shown, boolean animate) { + ensureList(); + if (mProgressContainer == null) { + throw new IllegalStateException("Can't be used with a custom content view"); + } + if (mExpandableListShown == shown) { + return; + } + mExpandableListShown = shown; + if (shown) { + if (animate) { + mProgressContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), + android.R.anim.fade_out)); + mExpandableListContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), + android.R.anim.fade_in)); + } else { + mProgressContainer.clearAnimation(); + mExpandableListContainer.clearAnimation(); + } + mProgressContainer.setVisibility(View.GONE); + mExpandableListContainer.setVisibility(View.VISIBLE); + } else { + if (animate) { + mProgressContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), + android.R.anim.fade_in)); + mExpandableListContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), + android.R.anim.fade_out)); + } else { + mProgressContainer.clearAnimation(); + mExpandableListContainer.clearAnimation(); + } + mProgressContainer.setVisibility(View.VISIBLE); + mExpandableListContainer.setVisibility(View.GONE); + } + } + + /** + * Get the ListAdapter associated with this activity's ListView. + */ + public ExpandableListAdapter getListAdapter() { + return mAdapter; + } + + private void ensureList() { + if (mExpandableList != null) { + return; + } + View root = getView(); + if (root == null) { + throw new IllegalStateException("Content view not yet created"); + } + if (root instanceof ExpandableListView) { + mExpandableList = (ExpandableListView) root; + } else { + mStandardEmptyView = (TextView) root.findViewById(INTERNAL_EMPTY_ID); + if (mStandardEmptyView == null) { + mEmptyView = root.findViewById(android.R.id.empty); + } else { + mStandardEmptyView.setVisibility(View.GONE); + } + mProgressContainer = root.findViewById(INTERNAL_PROGRESS_CONTAINER_ID); + mExpandableListContainer = root.findViewById(INTERNAL_LIST_CONTAINER_ID); + View rawExpandableListView = root.findViewById(android.R.id.list); + if (!(rawExpandableListView instanceof ExpandableListView)) { + if (rawExpandableListView == null) { + throw new RuntimeException( + "Your content must have a ListView whose id attribute is " + + "'android.R.id.list'"); + } + throw new RuntimeException( + "Content has view with id attribute 'android.R.id.list' " + + "that is not a ListView class"); + } + mExpandableList = (ExpandableListView) rawExpandableListView; + if (mEmptyView != null) { + mExpandableList.setEmptyView(mEmptyView); + } else if (mEmptyText != null) { + mStandardEmptyView.setText(mEmptyText); + mExpandableList.setEmptyView(mStandardEmptyView); + } + } + mExpandableListShown = true; + mExpandableList.setOnItemClickListener(mOnClickListener); + if (mAdapter != null) { + ExpandableListAdapter adapter = mAdapter; + mAdapter = null; + setListAdapter(adapter); + } else { + // We are starting without an adapter, so assume we won't + // have our data right away and start with the progress indicator. + if (mProgressContainer != null) { + setListShown(false, false); + } + } + mHandler.post(mRequestFocus); + } + + /** + * Override this to populate the context menu when an item is long pressed. menuInfo will + * contain an {@link android.widget.ExpandableListView.ExpandableListContextMenuInfo} whose + * packedPosition is a packed position that should be used with + * {@link ExpandableListView#getPackedPositionType(long)} and the other similar methods. + *

+ * {@inheritDoc} + */ + @Override + public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { + } + + /** + * Override this for receiving callbacks when a child has been clicked. + *

+ * {@inheritDoc} + */ + public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, + int childPosition, long id) { + return false; + } + + /** + * Override this for receiving callbacks when a group has been collapsed. + */ + public void onGroupCollapse(int groupPosition) { + } + + /** + * Override this for receiving callbacks when a group has been expanded. + */ + public void onGroupExpand(int groupPosition) { + } + + // /** + // * Ensures the expandable list view has been created before Activity restores all + // * of the view states. + // * + // *@see Activity#onRestoreInstanceState(Bundle) + // */ + // @Override + // protected void onRestoreInstanceState(Bundle state) { + // ensureList(); + // super.onRestoreInstanceState(state); + // } + + /** + * Updates the screen state (current list and other views) when the content changes. + * + * @see Activity#onContentChanged() + */ + + public void onContentChanged() { + // super.onContentChanged(); + View emptyView = getView().findViewById(android.R.id.empty); + mExpandableList = (ExpandableListView) getView().findViewById(android.R.id.list); + if (mExpandableList == null) { + throw new RuntimeException( + "Your content must have a ExpandableListView whose id attribute is " + + "'android.R.id.list'"); + } + if (emptyView != null) { + mExpandableList.setEmptyView(emptyView); + } + mExpandableList.setOnChildClickListener(this); + mExpandableList.setOnGroupExpandListener(this); + mExpandableList.setOnGroupCollapseListener(this); + + if (mFinishedStart) { + setListAdapter(mAdapter); + } + mFinishedStart = true; + } + + /** + * Get the activity's expandable list view widget. This can be used to get the selection, set + * the selection, and many other useful functions. + * + * @see ExpandableListView + */ + public ExpandableListView getExpandableListView() { + ensureList(); + return mExpandableList; + } + + /** + * Get the ExpandableListAdapter associated with this activity's ExpandableListView. + */ + public ExpandableListAdapter getExpandableListAdapter() { + return mAdapter; + } + + /** + * Gets the ID of the currently selected group or child. + * + * @return The ID of the currently selected group or child. + */ + public long getSelectedId() { + return mExpandableList.getSelectedId(); + } + + /** + * Gets the position (in packed position representation) of the currently selected group or + * child. Use {@link ExpandableListView#getPackedPositionType}, + * {@link ExpandableListView#getPackedPositionGroup}, and + * {@link ExpandableListView#getPackedPositionChild} to unpack the returned packed position. + * + * @return A packed position representation containing the currently selected group or child's + * position and type. + */ + public long getSelectedPosition() { + return mExpandableList.getSelectedPosition(); + } + + /** + * Sets the selection to the specified child. If the child is in a collapsed group, the group + * will only be expanded and child subsequently selected if shouldExpandGroup is set to true, + * otherwise the method will return false. + * + * @param groupPosition + * The position of the group that contains the child. + * @param childPosition + * The position of the child within the group. + * @param shouldExpandGroup + * Whether the child's group should be expanded if it is collapsed. + * @return Whether the selection was successfully set on the child. + */ + public boolean setSelectedChild(int groupPosition, int childPosition, boolean shouldExpandGroup) { + return mExpandableList.setSelectedChild(groupPosition, childPosition, shouldExpandGroup); + } + + /** + * Sets the selection to the specified group. + * + * @param groupPosition + * The position of the group that should be selected. + */ + public void setSelectedGroup(int groupPosition) { + mExpandableList.setSelectedGroup(groupPosition); + } +} \ No newline at end of file diff --git a/org_apg/src/org/thialfihar/android/apg/ui/widget/KeyListAdapter.java b/org_apg/src/org/thialfihar/android/apg/ui/widget/KeyListAdapter.java new file mode 100644 index 000000000..b279e4e7b --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/widget/KeyListAdapter.java @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2012 Dominik Schürmann + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.thialfihar.android.apg.ui.widget; + +import org.thialfihar.android.apg.Id; +import org.thialfihar.android.apg.R; +import org.thialfihar.android.apg.helper.OtherHelper; +import org.thialfihar.android.apg.helper.PGPHelper; +import org.thialfihar.android.apg.provider.ApgContract.PublicKeys; +import org.thialfihar.android.apg.provider.ApgContract.PublicUserIds; +import org.thialfihar.android.apg.provider.ApgContract.SecretKeys; +import org.thialfihar.android.apg.provider.ApgContract.SecretUserIds; + +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.provider.BaseColumns; +import android.support.v4.app.LoaderManager; +import android.support.v4.content.CursorLoader; +import android.support.v4.content.Loader; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.SimpleCursorTreeAdapter; +import android.widget.TextView; + +public class KeyListAdapter extends SimpleCursorTreeAdapter implements + LoaderManager.LoaderCallbacks { + private Context mContext; + private LoaderManager mManager; + private LayoutInflater mInflater; + + // Id.type.public_key / Id.type.secret_key + protected int mKeyType; + + public KeyListAdapter(Context context, LoaderManager manager, Cursor groupCursor, int keyType) { + super(context, groupCursor, -1, null, null, -1, null, null); + mContext = context; + mManager = manager; + mInflater = LayoutInflater.from(context); + mKeyType = keyType; + } + + /** + * Inflate new view for group items + */ + @Override + public View newGroupView(Context context, Cursor cursor, boolean isExpanded, ViewGroup parent) { + return mInflater.inflate(R.layout.key_list_group_item, null); + } + + /** + * Binds TextViews from view to results from database group cursor. + */ + @Override + protected void bindGroupView(View view, Context context, Cursor cursor, boolean isExpanded) { + int userIdIndex; + if (mKeyType == Id.type.public_key) { + userIdIndex = cursor.getColumnIndex(PublicUserIds.USER_ID); + } else { + userIdIndex = cursor.getColumnIndex(SecretUserIds.USER_ID); + } + + TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId); + mainUserId.setText(R.string.unknownUserId); + TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest); + mainUserIdRest.setText(""); + + String userId = cursor.getString(userIdIndex); + if (userId != null) { + String[] userIdSplit = OtherHelper.splitUserId(userId); + + if (userIdSplit[1] != null) { + mainUserIdRest.setText(userIdSplit[1]); + } + mainUserId.setText(userIdSplit[0]); + } + + if (mainUserId.getText().length() == 0) { + mainUserId.setText(R.string.unknownUserId); + } + + if (mainUserIdRest.getText().length() == 0) { + mainUserIdRest.setVisibility(View.GONE); + } + } + + /** + * Inflate new view for child items + */ + @Override + public View newChildView(Context context, Cursor cursor, boolean isLastChild, ViewGroup parent) { + + return mInflater.inflate(R.layout.key_list_child_item_master_key, null); + } + + @Override + protected void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild) { + int keyIdIndex; + if (mKeyType == Id.type.public_key) { + keyIdIndex = cursor.getColumnIndex(PublicKeys.KEY_ID); + } else { + keyIdIndex = cursor.getColumnIndex(SecretKeys.KEY_ID); + } + + TextView keyId = (TextView) view.findViewById(R.id.keyId); + String keyIdStr = PGPHelper.getSmallFingerPrint(cursor.getLong(keyIdIndex)); + keyId.setText(keyIdStr); + } + + /** + * Given the group, we return a cursor for all the children within that group + */ + @Override + protected Cursor getChildrenCursor(Cursor groupCursor) { + final long idGroup = groupCursor.getLong(groupCursor.getColumnIndex(BaseColumns._ID)); + Bundle bundle = new Bundle(); + bundle.putLong("idGroup", idGroup); + int groupPos = groupCursor.getPosition(); + if (mManager.getLoader(groupPos) != null && !mManager.getLoader(groupPos).isReset()) { + mManager.restartLoader(groupPos, bundle, this); + } else { + mManager.initLoader(groupPos, bundle, this); + } + return null; + + // OLD CODE: + // Vector children = mChildren.get(groupPosition); + // if (children != null) { + // return children; + // } + + // mCursor.moveToPosition(groupPosition); + // children = new Vector(); + // Cursor c = mDatabase.query(Keys.TABLE_NAME, new String[] { Keys._ID, // 0 + // Keys.KEY_ID, // 1 + // Keys.IS_MASTER_KEY, // 2 + // Keys.ALGORITHM, // 3 + // Keys.KEY_SIZE, // 4 + // Keys.CAN_SIGN, // 5 + // Keys.CAN_ENCRYPT, // 6 + // }, Keys.KEY_RING_ID + " = ?", new String[] { mCursor.getString(0) }, null, null, + // Keys.RANK + " ASC"); + + // int masterKeyId = -1; + // long fingerPrintId = -1; + // for (int i = 0; i < c.getCount(); ++i) { + // c.moveToPosition(i); + // children.add(new KeyChild(c.getLong(1), c.getInt(2) == 1, c.getInt(3), c.getInt(4), + // c.getInt(5) == 1, c.getInt(6) == 1)); + // if (i == 0) { + // masterKeyId = c.getInt(0); + // fingerPrintId = c.getLong(1); + // } + // } + // c.close(); + // + // if (masterKeyId != -1) { + // children.insertElementAt( + // new KeyChild(PGPHelper.getFingerPrint(KeyListActivity.this, fingerPrintId), + // true), 0); + // c = mDatabase.query(UserIds.TABLE_NAME, new String[] { UserIds.USER_ID, // 0 + // }, UserIds.KEY_ID + " = ? AND " + UserIds.RANK + " > 0", new String[] { "" + // + masterKeyId }, null, null, UserIds.RANK + " ASC"); + // + // for (int i = 0; i < c.getCount(); ++i) { + // c.moveToPosition(i); + // children.add(new KeyChild(c.getString(0))); + // } + // c.close(); + // } + + // mChildren.set(groupPosition, children); + // return children; + } + + @Override + public Loader onCreateLoader(int groupPos, Bundle bundle) { + long idGroup = bundle.getLong("idGroup"); + + Uri uri = null; + String[] projection = null; + String orderBy = null; + if (mKeyType == Id.type.public_key) { + projection = new String[] { PublicKeys._ID, // 0 + PublicKeys.KEY_ID, // 1 + PublicKeys.IS_MASTER_KEY, // 2 + PublicKeys.ALGORITHM, // 3 + PublicKeys.KEY_SIZE, // 4 + PublicKeys.CAN_SIGN, // 5 + PublicKeys.CAN_ENCRYPT, // 6 + }; + orderBy = PublicKeys.RANK + " ASC"; + + uri = PublicKeys.buildPublicKeysUri(String.valueOf(idGroup)); + } else { + projection = new String[] { SecretKeys._ID, // 0 + SecretKeys.KEY_ID, // 1 + SecretKeys.IS_MASTER_KEY, // 2 + SecretKeys.ALGORITHM, // 3 + SecretKeys.KEY_SIZE, // 4 + SecretKeys.CAN_SIGN, // 5 + SecretKeys.CAN_ENCRYPT, // 6 + }; + orderBy = SecretKeys.RANK + " ASC"; + + uri = SecretKeys.buildSecretKeysUri(String.valueOf(idGroup)); + } + return new CursorLoader(mContext, uri, projection, null, null, orderBy); + } + + @Override + public void onLoadFinished(Loader loader, Cursor cursor) { + setChildrenCursor(loader.getId(), cursor); + } + + @Override + public void onLoaderReset(Loader loader) { + } +} \ No newline at end of file diff --git a/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyCursorAdapter.java b/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyCursorAdapter.java new file mode 100644 index 000000000..45b617d68 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyCursorAdapter.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2012 Dominik Schürmann + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.thialfihar.android.apg.ui.widget; + +import org.thialfihar.android.apg.R; +import org.thialfihar.android.apg.helper.OtherHelper; +import org.thialfihar.android.apg.helper.PGPHelper; + +import android.content.Context; +import android.database.Cursor; +import android.support.v4.widget.CursorAdapter; +import android.support.v4.widget.SimpleCursorAdapter; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.TextView; + +public class SelectPublicKeyCursorAdapter extends CursorAdapter { + + private LayoutInflater mInflater; +// private int mActivityIndex; +// private int mTimeIndex; +// private int mActionIndex; +// private int mAmountIndex; + + public SelectPublicKeyCursorAdapter(Context context, Cursor c) { + super(context, c); +// +// mActivityIndex = c.getColumnIndex(Notes.ACTIVITY); +// mTimeIndex = c.getColumnIndex(Notes.TIME); +// mActionIndex = c.getColumnIndex(Notes.ACTION); +// mAmountIndex = c.getColumnIndex(Notes.AMOUNT); + + mInflater = LayoutInflater.from(context); + } + + @Override + public void bindView(View view, Context context, Cursor cursor) { + // TextView activity = (TextView) view.findViewById(android.R.id.text1); + // TextView time = (TextView) view.findViewById(android.R.id.text2); + // TextView actionAndAmount = (TextView) view.findViewById(R.id.text3); + // + // activity.setText(cursor.getString(mActivityIndex)); + // + // long lTime = cursor.getLong(mTimeIndex); + // Calendar cal = Calendar.getInstance(); + // cal.setTimeInMillis(lTime); + // time.setText(cal.get(Calendar.HOUR_OF_DAY) + “:” + String.format(“%02d”, + // cal.get(Calendar.MINUTE))); + // + // String amount = cursor.getString(mAmountIndex); + // if ( amount.length() > 0){ + // actionAndAmount.setText(cursor.getString(mActionIndex) + ” (” + amount + “)”); + // } else { + // actionAndAmount.setText(cursor.getString(mActionIndex)); + // } + +// boolean enabled = isEnabled(position); + + + TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId); + mainUserId.setText(R.string.unknownUserId); + TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest); + mainUserIdRest.setText(""); + TextView keyId = (TextView) view.findViewById(R.id.keyId); + keyId.setText(R.string.noKey); + TextView status = (TextView) view.findViewById(R.id.status); + status.setText(R.string.unknownStatus); + + String userId = cursor.getString(2); // USER_ID + if (userId != null) { + String[] userIdSplit = OtherHelper.splitUserId(userId); + + if (userIdSplit[1] != null) { + mainUserIdRest.setText(userIdSplit[1]); + } + mainUserId.setText(userIdSplit[0]); + } + + long masterKeyId = cursor.getLong(1); // MASTER_KEY_ID + keyId.setText(PGPHelper.getSmallFingerPrint(masterKeyId)); + + if (mainUserIdRest.getText().length() == 0) { + mainUserIdRest.setVisibility(View.GONE); + } + +// if (enabled) { +// status.setText(R.string.canEncrypt); +// } else { + if (cursor.getInt(3) > 0) { + // has some CAN_ENCRYPT keys, but col(4) = 0, so must be revoked or expired + status.setText(R.string.expired); + } else { + status.setText(R.string.noKey); + } +// } + + status.setText(status.getText() + " "); + + CheckBox selected = (CheckBox) view.findViewById(R.id.selected); + +// if (!enabled) { +// mParent.setItemChecked(position, false); +// } + +// selected.setChecked(mParent.isItemChecked(position)); + +// view.setEnabled(enabled); +// mainUserId.setEnabled(enabled); +// mainUserIdRest.setEnabled(enabled); +// keyId.setEnabled(enabled); +// selected.setEnabled(enabled); +// status.setEnabled(enabled); + } + + @Override + public View newView(Context context, Cursor cursor, ViewGroup parent) { + return mInflater.inflate(R.layout.select_public_key, null); + } + +} \ No newline at end of file diff --git a/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyListAdapter.java b/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyListAdapter.java deleted file mode 100644 index ee78e8f88..000000000 --- a/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyListAdapter.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2010 Thialfihar - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.thialfihar.android.apg.ui.widget; - -import java.util.Date; - -import org.thialfihar.android.apg.R; -import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.helper.PGPHelper; -import org.thialfihar.android.apg.helper.PGPMain; -import org.thialfihar.android.apg.provider.KeyRings; -import org.thialfihar.android.apg.provider.Keys; -import org.thialfihar.android.apg.provider.UserIds; - -import android.app.Activity; -import android.content.Context; -import android.database.Cursor; -import android.database.DatabaseUtils; -import android.database.sqlite.SQLiteDatabase; -import android.database.sqlite.SQLiteQueryBuilder; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.CheckBox; -import android.widget.ListView; -import android.widget.TextView; - -public class SelectPublicKeyListAdapter extends BaseAdapter { - protected LayoutInflater mInflater; - protected ListView mParent; - protected SQLiteDatabase mDatabase; - protected Cursor mCursor; - protected String mSearchString; - protected Activity mActivity; - - public SelectPublicKeyListAdapter(Activity activity, ListView parent, String searchString, - long selectedKeyIds[]) { - mSearchString = searchString; - - mActivity = activity; - mParent = parent; - mDatabase = PGPMain.getDatabase().db(); - mInflater = (LayoutInflater) parent.getContext().getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - long now = new Date().getTime() / 1000; - 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'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME + " ON " + "(" - + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." - + UserIds.KEY_ID + " AND " + UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') "); - - String inIdList = null; - - if (selectedKeyIds != null && selectedKeyIds.length > 0) { - inIdList = KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID + " IN ("; - for (int i = 0; i < selectedKeyIds.length; ++i) { - if (i != 0) { - inIdList += ", "; - } - inIdList += DatabaseUtils.sqlEscapeString("" + selectedKeyIds[i]); - } - inIdList += ")"; - } - - 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 (inIdList != null) { - qb.appendWhere(" OR (" + inIdList + ")"); - } - } - - String orderBy = UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC"; - if (inIdList != null) { - orderBy = inIdList + " DESC, " + orderBy; - } - - mCursor = qb.query(mDatabase, new String[] { - KeyRings.TABLE_NAME + "." + KeyRings._ID, // 0 - KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 1 - UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 2 - "(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Keys.TABLE_NAME + " AS tmp WHERE " - + "tmp." + Keys.KEY_RING_ID + " = " + KeyRings.TABLE_NAME + "." - + KeyRings._ID + " AND " + "tmp." + Keys.IS_REVOKED + " = '0' AND " - + "tmp." + Keys.CAN_ENCRYPT + " = '1')", // 3 - "(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Keys.TABLE_NAME + " AS tmp WHERE " - + "tmp." + Keys.KEY_RING_ID + " = " + KeyRings.TABLE_NAME + "." - + KeyRings._ID + " AND " + "tmp." + Keys.IS_REVOKED + " = '0' AND " - + "tmp." + Keys.CAN_ENCRYPT + " = '1' AND " + "tmp." + Keys.CREATION - + " <= '" + now + "' AND " + "(tmp." + Keys.EXPIRY + " IS NULL OR " - + "tmp." + Keys.EXPIRY + " >= '" + now + "'))", // 4 - }, KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?", new String[] { "" - + Id.database.type_public }, null, null, orderBy); - - activity.startManagingCursor(mCursor); - } - - public void cleanup() { - if (mCursor != null) { - mActivity.stopManagingCursor(mCursor); - mCursor.close(); - } - } - - @Override - public boolean isEnabled(int position) { - mCursor.moveToPosition(position); - return mCursor.getInt(4) > 0; // valid CAN_ENCRYPT - } - - @Override - public boolean hasStableIds() { - return true; - } - - public int getCount() { - return mCursor.getCount(); - } - - public Object getItem(int position) { - mCursor.moveToPosition(position); - return mCursor.getString(2); // USER_ID - } - - public long getItemId(int position) { - mCursor.moveToPosition(position); - return mCursor.getLong(1); // MASTER_KEY_ID - } - - public View getView(int position, View convertView, ViewGroup parent) { - mCursor.moveToPosition(position); - - View view = mInflater.inflate(R.layout.select_public_key_item, null); - boolean enabled = isEnabled(position); - - TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId); - mainUserId.setText(R.string.unknownUserId); - TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest); - mainUserIdRest.setText(""); - TextView keyId = (TextView) view.findViewById(R.id.keyId); - keyId.setText(R.string.noKey); - TextView status = (TextView) view.findViewById(R.id.status); - status.setText(R.string.unknownStatus); - - String userId = mCursor.getString(2); // USER_ID - if (userId != null) { - String chunks[] = userId.split(" <", 2); - userId = chunks[0]; - if (chunks.length > 1) { - mainUserIdRest.setText("<" + chunks[1]); - } - mainUserId.setText(userId); - } - - long masterKeyId = mCursor.getLong(1); // MASTER_KEY_ID - keyId.setText(PGPHelper.getSmallFingerPrint(masterKeyId)); - - if (mainUserIdRest.getText().length() == 0) { - mainUserIdRest.setVisibility(View.GONE); - } - - if (enabled) { - status.setText(R.string.canEncrypt); - } else { - if (mCursor.getInt(3) > 0) { - // has some CAN_ENCRYPT keys, but col(4) = 0, so must be revoked or expired - status.setText(R.string.expired); - } else { - status.setText(R.string.noKey); - } - } - - status.setText(status.getText() + " "); - - CheckBox selected = (CheckBox) view.findViewById(R.id.selected); - - if (!enabled) { - mParent.setItemChecked(position, false); - } - - selected.setChecked(mParent.isItemChecked(position)); - - view.setEnabled(enabled); - mainUserId.setEnabled(enabled); - mainUserIdRest.setEnabled(enabled); - keyId.setEnabled(enabled); - selected.setEnabled(enabled); - status.setEnabled(enabled); - - return view; - } -} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyListAdapterOld.java b/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyListAdapterOld.java new file mode 100644 index 000000000..4324e36c9 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectPublicKeyListAdapterOld.java @@ -0,0 +1,218 @@ +package org.thialfihar.android.apg.ui.widget; +///* +// * Copyright (C) 2010 Thialfihar +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +// +//package org.thialfihar.android.apg.ui.widget; +// +//import java.util.Date; +// +//import org.thialfihar.android.apg.R; +//import org.thialfihar.android.apg.Id; +//import org.thialfihar.android.apg.helper.PGPHelper; +//import org.thialfihar.android.apg.helper.PGPMain; +//import org.thialfihar.android.apg.provider.KeyRings; +//import org.thialfihar.android.apg.provider.Keys; +//import org.thialfihar.android.apg.provider.UserIds; +// +//import android.app.Activity; +//import android.content.Context; +//import android.database.Cursor; +//import android.database.DatabaseUtils; +//import android.database.sqlite.SQLiteDatabase; +//import android.database.sqlite.SQLiteQueryBuilder; +//import android.view.LayoutInflater; +//import android.view.View; +//import android.view.ViewGroup; +//import android.widget.BaseAdapter; +//import android.widget.CheckBox; +//import android.widget.ListView; +//import android.widget.TextView; +// +//public class SelectPublicKeyListAdapter extends BaseAdapter { +// protected LayoutInflater mInflater; +// protected ListView mParent; +// protected SQLiteDatabase mDatabase; +// protected Cursor mCursor; +// protected String mSearchString; +// protected Activity mActivity; +// +// public SelectPublicKeyListAdapter(Activity activity, ListView parent, String searchString, +// long selectedKeyIds[]) { +// mSearchString = searchString; +// +// mActivity = activity; +// mParent = parent; +// mDatabase = PGPMain.getDatabase().db(); +// mInflater = (LayoutInflater) parent.getContext().getSystemService( +// Context.LAYOUT_INFLATER_SERVICE); +// long now = new Date().getTime() / 1000; +// 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'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME + " ON " + "(" +// + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." +// + UserIds.KEY_ID + " AND " + UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') "); +// +// String inIdList = null; +// +// if (selectedKeyIds != null && selectedKeyIds.length > 0) { +// inIdList = KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID + " IN ("; +// for (int i = 0; i < selectedKeyIds.length; ++i) { +// if (i != 0) { +// inIdList += ", "; +// } +// inIdList += DatabaseUtils.sqlEscapeString("" + selectedKeyIds[i]); +// } +// inIdList += ")"; +// } +// +// 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 (inIdList != null) { +// qb.appendWhere(" OR (" + inIdList + ")"); +// } +// } +// +// String orderBy = UserIds.TABLE_NAME + "." + UserIds.USER_ID + " ASC"; +// if (inIdList != null) { +// orderBy = inIdList + " DESC, " + orderBy; +// } +// +// mCursor = qb.query(mDatabase, new String[] { +// KeyRings.TABLE_NAME + "." + KeyRings._ID, // 0 +// KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID, // 1 +// UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 2 +// "(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Keys.TABLE_NAME + " AS tmp WHERE " +// + "tmp." + Keys.KEY_RING_ID + " = " + KeyRings.TABLE_NAME + "." +// + KeyRings._ID + " AND " + "tmp." + Keys.IS_REVOKED + " = '0' AND " +// + "tmp." + Keys.CAN_ENCRYPT + " = '1')", // 3 +// "(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Keys.TABLE_NAME + " AS tmp WHERE " +// + "tmp." + Keys.KEY_RING_ID + " = " + KeyRings.TABLE_NAME + "." +// + KeyRings._ID + " AND " + "tmp." + Keys.IS_REVOKED + " = '0' AND " +// + "tmp." + Keys.CAN_ENCRYPT + " = '1' AND " + "tmp." + Keys.CREATION +// + " <= '" + now + "' AND " + "(tmp." + Keys.EXPIRY + " IS NULL OR " +// + "tmp." + Keys.EXPIRY + " >= '" + now + "'))", // 4 +// }, KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?", new String[] { "" +// + Id.database.type_public }, null, null, orderBy); +// +// activity.startManagingCursor(mCursor); +// } +// +// public void cleanup() { +// if (mCursor != null) { +// mActivity.stopManagingCursor(mCursor); +// mCursor.close(); +// } +// } +// +// @Override +// public boolean isEnabled(int position) { +// mCursor.moveToPosition(position); +// return mCursor.getInt(4) > 0; // valid CAN_ENCRYPT +// } +// +// @Override +// public boolean hasStableIds() { +// return true; +// } +// +// public int getCount() { +// return mCursor.getCount(); +// } +// +// public Object getItem(int position) { +// mCursor.moveToPosition(position); +// return mCursor.getString(2); // USER_ID +// } +// +// public long getItemId(int position) { +// mCursor.moveToPosition(position); +// return mCursor.getLong(1); // MASTER_KEY_ID +// } +// +// public View getView(int position, View convertView, ViewGroup parent) { +// mCursor.moveToPosition(position); +// +// View view = mInflater.inflate(R.layout.select_public_key_item, null); +// boolean enabled = isEnabled(position); +// +// TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId); +// mainUserId.setText(R.string.unknownUserId); +// TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest); +// mainUserIdRest.setText(""); +// TextView keyId = (TextView) view.findViewById(R.id.keyId); +// keyId.setText(R.string.noKey); +// TextView status = (TextView) view.findViewById(R.id.status); +// status.setText(R.string.unknownStatus); +// +// String userId = mCursor.getString(2); // USER_ID +// if (userId != null) { +// String chunks[] = userId.split(" <", 2); +// userId = chunks[0]; +// if (chunks.length > 1) { +// mainUserIdRest.setText("<" + chunks[1]); +// } +// mainUserId.setText(userId); +// } +// +// long masterKeyId = mCursor.getLong(1); // MASTER_KEY_ID +// keyId.setText(PGPHelper.getSmallFingerPrint(masterKeyId)); +// +// if (mainUserIdRest.getText().length() == 0) { +// mainUserIdRest.setVisibility(View.GONE); +// } +// +// if (enabled) { +// status.setText(R.string.canEncrypt); +// } else { +// if (mCursor.getInt(3) > 0) { +// // has some CAN_ENCRYPT keys, but col(4) = 0, so must be revoked or expired +// status.setText(R.string.expired); +// } else { +// status.setText(R.string.noKey); +// } +// } +// +// status.setText(status.getText() + " "); +// +// CheckBox selected = (CheckBox) view.findViewById(R.id.selected); +// +// if (!enabled) { +// mParent.setItemChecked(position, false); +// } +// +// selected.setChecked(mParent.isItemChecked(position)); +// +// view.setEnabled(enabled); +// mainUserId.setEnabled(enabled); +// mainUserIdRest.setEnabled(enabled); +// keyId.setEnabled(enabled); +// selected.setEnabled(enabled); +// status.setEnabled(enabled); +// +// return view; +// } +//} diff --git a/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectSecretKeyListAdapter.java b/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectSecretKeyListAdapter.java deleted file mode 100644 index 2caa593ff..000000000 --- a/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectSecretKeyListAdapter.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.thialfihar.android.apg.ui.widget; - -import java.util.Date; - -import org.thialfihar.android.apg.R; -import org.thialfihar.android.apg.Id; -import org.thialfihar.android.apg.helper.PGPHelper; -import org.thialfihar.android.apg.helper.PGPMain; -import org.thialfihar.android.apg.provider.KeyRings; -import org.thialfihar.android.apg.provider.Keys; -import org.thialfihar.android.apg.provider.UserIds; - -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; -import android.widget.BaseAdapter; -import android.widget.ListView; -import android.widget.TextView; - -public class SelectSecretKeyListAdapter extends BaseAdapter { - protected LayoutInflater mInflater; - protected ListView mParent; - protected SQLiteDatabase mDatabase; - protected Cursor mCursor; - protected String mSearchString; - protected Activity mActivity; - - public SelectSecretKeyListAdapter(Activity activity, ListView parent, String searchString) { - mSearchString = searchString; - - mActivity = activity; - mParent = parent; - mDatabase = PGPMain.getDatabase().db(); - mInflater = (LayoutInflater) parent.getContext().getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - long now = new Date().getTime() / 1000; - 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'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME + " ON " + "(" - + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." - + UserIds.KEY_ID + " AND " + 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 - UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 2 - "(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Keys.TABLE_NAME + " AS tmp WHERE " - + "tmp." + Keys.KEY_RING_ID + " = " + KeyRings.TABLE_NAME + "." - + KeyRings._ID + " AND " + "tmp." + Keys.IS_REVOKED + " = '0' AND " - + "tmp." + Keys.CAN_SIGN + " = '1')", // 3, - "(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Keys.TABLE_NAME + " AS tmp WHERE " - + "tmp." + Keys.KEY_RING_ID + " = " + KeyRings.TABLE_NAME + "." - + KeyRings._ID + " AND " + "tmp." + Keys.IS_REVOKED + " = '0' AND " - + "tmp." + Keys.CAN_SIGN + " = '1' AND " + "tmp." + Keys.CREATION + " <= '" - + now + "' AND " + "(tmp." + Keys.EXPIRY + " IS NULL OR " + "tmp." - + Keys.EXPIRY + " >= '" + now + "'))", // 4 - }, KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?", new String[] { "" - + Id.database.type_secret }, null, null, UserIds.TABLE_NAME + "." + UserIds.USER_ID - + " ASC"); - - activity.startManagingCursor(mCursor); - } - - public void cleanup() { - if (mCursor != null) { - mActivity.stopManagingCursor(mCursor); - mCursor.close(); - } - } - - @Override - public boolean isEnabled(int position) { - mCursor.moveToPosition(position); - return mCursor.getInt(4) > 0; // valid CAN_SIGN - } - - @Override - public boolean hasStableIds() { - return true; - } - - public int getCount() { - return mCursor.getCount(); - } - - public Object getItem(int position) { - mCursor.moveToPosition(position); - return mCursor.getString(2); // USER_ID - } - - public long getItemId(int position) { - mCursor.moveToPosition(position); - return mCursor.getLong(1); // MASTER_KEY_ID - } - - public View getView(int position, View convertView, ViewGroup parent) { - mCursor.moveToPosition(position); - - View view = mInflater.inflate(R.layout.select_secret_key_item, null); - boolean enabled = isEnabled(position); - - TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId); - mainUserId.setText(R.string.unknownUserId); - TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest); - mainUserIdRest.setText(""); - TextView keyId = (TextView) view.findViewById(R.id.keyId); - keyId.setText(R.string.noKey); - TextView status = (TextView) view.findViewById(R.id.status); - status.setText(R.string.unknownStatus); - - String userId = mCursor.getString(2); // USER_ID - if (userId != null) { - String chunks[] = userId.split(" <", 2); - userId = chunks[0]; - if (chunks.length > 1) { - mainUserIdRest.setText("<" + chunks[1]); - } - mainUserId.setText(userId); - } - - long masterKeyId = mCursor.getLong(1); // MASTER_KEY_ID - keyId.setText(PGPHelper.getSmallFingerPrint(masterKeyId)); - - if (mainUserIdRest.getText().length() == 0) { - mainUserIdRest.setVisibility(View.GONE); - } - - if (enabled) { - status.setText(R.string.canSign); - } else { - if (mCursor.getInt(3) > 0) { - // has some CAN_SIGN keys, but col(4) = 0, so must be revoked or expired - status.setText(R.string.expired); - } else { - status.setText(R.string.noKey); - } - } - - status.setText(status.getText() + " "); - - view.setEnabled(enabled); - mainUserId.setEnabled(enabled); - mainUserIdRest.setEnabled(enabled); - keyId.setEnabled(enabled); - status.setEnabled(enabled); - - return view; - } -} \ No newline at end of file diff --git a/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectSecretKeyListAdapterOld.java b/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectSecretKeyListAdapterOld.java new file mode 100644 index 000000000..ab0aa1519 --- /dev/null +++ b/org_apg/src/org/thialfihar/android/apg/ui/widget/SelectSecretKeyListAdapterOld.java @@ -0,0 +1,179 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.thialfihar.android.apg.ui.widget; + +import java.util.Date; + +import org.thialfihar.android.apg.R; +import org.thialfihar.android.apg.Id; +import org.thialfihar.android.apg.helper.PGPHelper; +import org.thialfihar.android.apg.helper.PGPMain; + +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; +import android.widget.BaseAdapter; +import android.widget.ListView; +import android.widget.TextView; + +public class SelectSecretKeyListAdapterOld { //extends BaseAdapter { +// protected LayoutInflater mInflater; +// protected ListView mParent; +// protected SQLiteDatabase mDatabase; +// protected Cursor mCursor; +// protected String mSearchString; +// protected Activity mActivity; +// +// public SelectSecretKeyListAdapter(Activity activity, ListView parent, String searchString) { +// mSearchString = searchString; +// +// mActivity = activity; +// mParent = parent; +// mDatabase = PGPMain.getDatabase().db(); +// mInflater = (LayoutInflater) parent.getContext().getSystemService( +// Context.LAYOUT_INFLATER_SERVICE); +// long now = new Date().getTime() / 1000; +// 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'" + ") " + " INNER JOIN " + UserIds.TABLE_NAME + " ON " + "(" +// + Keys.TABLE_NAME + "." + Keys._ID + " = " + UserIds.TABLE_NAME + "." +// + UserIds.KEY_ID + " AND " + 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 +// UserIds.TABLE_NAME + "." + UserIds.USER_ID, // 2 +// "(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Keys.TABLE_NAME + " AS tmp WHERE " +// + "tmp." + Keys.KEY_RING_ID + " = " + KeyRings.TABLE_NAME + "." +// + KeyRings._ID + " AND " + "tmp." + Keys.IS_REVOKED + " = '0' AND " +// + "tmp." + Keys.CAN_SIGN + " = '1')", // 3, +// "(SELECT COUNT(tmp." + Keys._ID + ") FROM " + Keys.TABLE_NAME + " AS tmp WHERE " +// + "tmp." + Keys.KEY_RING_ID + " = " + KeyRings.TABLE_NAME + "." +// + KeyRings._ID + " AND " + "tmp." + Keys.IS_REVOKED + " = '0' AND " +// + "tmp." + Keys.CAN_SIGN + " = '1' AND " + "tmp." + Keys.CREATION + " <= '" +// + now + "' AND " + "(tmp." + Keys.EXPIRY + " IS NULL OR " + "tmp." +// + Keys.EXPIRY + " >= '" + now + "'))", // 4 +// }, KeyRings.TABLE_NAME + "." + KeyRings.TYPE + " = ?", new String[] { "" +// + Id.database.type_secret }, null, null, UserIds.TABLE_NAME + "." + UserIds.USER_ID +// + " ASC"); +// +// activity.startManagingCursor(mCursor); +// } +// +// public void cleanup() { +// if (mCursor != null) { +// mActivity.stopManagingCursor(mCursor); +// mCursor.close(); +// } +// } +// +// @Override +// public boolean isEnabled(int position) { +// mCursor.moveToPosition(position); +// return mCursor.getInt(4) > 0; // valid CAN_SIGN +// } +// +// @Override +// public boolean hasStableIds() { +// return true; +// } +// +// public int getCount() { +// return mCursor.getCount(); +// } +// +// public Object getItem(int position) { +// mCursor.moveToPosition(position); +// return mCursor.getString(2); // USER_ID +// } +// +// public long getItemId(int position) { +// mCursor.moveToPosition(position); +// return mCursor.getLong(1); // MASTER_KEY_ID +// } +// +// public View getView(int position, View convertView, ViewGroup parent) { +// mCursor.moveToPosition(position); +// +// View view = mInflater.inflate(R.layout.select_secret_key_item, null); +// boolean enabled = isEnabled(position); +// +// TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId); +// mainUserId.setText(R.string.unknownUserId); +// TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest); +// mainUserIdRest.setText(""); +// TextView keyId = (TextView) view.findViewById(R.id.keyId); +// keyId.setText(R.string.noKey); +// TextView status = (TextView) view.findViewById(R.id.status); +// status.setText(R.string.unknownStatus); +// +// String userId = mCursor.getString(2); // USER_ID +// if (userId != null) { +// String chunks[] = userId.split(" <", 2); +// userId = chunks[0]; +// if (chunks.length > 1) { +// mainUserIdRest.setText("<" + chunks[1]); +// } +// mainUserId.setText(userId); +// } +// +// long masterKeyId = mCursor.getLong(1); // MASTER_KEY_ID +// keyId.setText(PGPHelper.getSmallFingerPrint(masterKeyId)); +// +// if (mainUserIdRest.getText().length() == 0) { +// mainUserIdRest.setVisibility(View.GONE); +// } +// +// if (enabled) { +// status.setText(R.string.canSign); +// } else { +// if (mCursor.getInt(3) > 0) { +// // has some CAN_SIGN keys, but col(4) = 0, so must be revoked or expired +// status.setText(R.string.expired); +// } else { +// status.setText(R.string.noKey); +// } +// } +// +// status.setText(status.getText() + " "); +// +// view.setEnabled(enabled); +// mainUserId.setEnabled(enabled); +// mainUserIdRest.setEnabled(enabled); +// keyId.setEnabled(enabled); +// status.setEnabled(enabled); +// +// return view; +// } +} \ No newline at end of file -- cgit v1.2.3