aboutsummaryrefslogtreecommitdiffstats
path: root/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui
diff options
context:
space:
mode:
Diffstat (limited to 'OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui')
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java8
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java63
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java57
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java95
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java13
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java86
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java29
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java211
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java300
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java8
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java180
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java86
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java4
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java10
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java27
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/HighlightQueryCursorAdapter.java66
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java65
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java5
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java39
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java11
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java2
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java3
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java9
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java1
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java12
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java23
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java10
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java1
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java52
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java111
-rw-r--r--OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java17
33 files changed, 1160 insertions, 452 deletions
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
index aab6b81d9..029dda1a0 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/CertifyKeyActivity.java
@@ -230,7 +230,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements
// Message is received after signing is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- R.string.progress_signing, ProgressDialog.STYLE_SPINNER) {
+ getString(R.string.progress_signing), ProgressDialog.STYLE_SPINNER) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
@@ -249,7 +249,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements
finish();
}
}
- };
+ }
};
// Create a new Messenger for the communication back
@@ -283,7 +283,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements
// Message is received after uploading is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- R.string.progress_exporting, ProgressDialog.STYLE_HORIZONTAL) {
+ getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
@@ -295,7 +295,7 @@ public class CertifyKeyActivity extends ActionBarActivity implements
setResult(RESULT_OK);
finish();
}
- };
+ }
};
// Create a new Messenger for the communication back
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
index 9bb675db0..38d763ce4 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptActivity.java
@@ -25,6 +25,7 @@ import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.regex.Matcher;
+import org.openintents.openpgp.OpenPgpSignatureResult;
import org.spongycastle.openpgp.PGPPublicKeyRing;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
@@ -32,6 +33,7 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.compatibility.ClipboardReflection;
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
import org.sufficientlysecure.keychain.helper.FileHelper;
+import org.sufficientlysecure.keychain.pgp.PgpDecryptVerifyResult;
import org.sufficientlysecure.keychain.pgp.PgpHelper;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.pgp.PgpDecryptVerify;
@@ -528,6 +530,10 @@ public class DecryptActivity extends DrawerActivity {
Log.e(Constants.TAG, "File not found!", e);
AppMsg.makeText(this, getString(R.string.error_file_not_found, e.getMessage()),
AppMsg.STYLE_ALERT).show();
+ } finally {
+ try {
+ if (inStream != null) inStream.close();
+ } catch (Exception e){ }
}
} else {
inStream = new ByteArrayInputStream(mMessage.getText().toString().getBytes());
@@ -644,7 +650,7 @@ public class DecryptActivity extends DrawerActivity {
// Message is received after encrypting is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- R.string.progress_decrypting, ProgressDialog.STYLE_HORIZONTAL) {
+ getString(R.string.progress_decrypting), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
@@ -690,11 +696,15 @@ public class DecryptActivity extends DrawerActivity {
}
- if (returnData.getBoolean(KeychainIntentService.RESULT_SIGNATURE)) {
- String userId = returnData
- .getString(KeychainIntentService.RESULT_SIGNATURE_USER_ID);
- mSignatureKeyId = returnData
- .getLong(KeychainIntentService.RESULT_SIGNATURE_KEY_ID);
+ PgpDecryptVerifyResult decryptVerifyResult =
+ returnData.getParcelable(KeychainIntentService.RESULT_DECRYPT_VERIFY_RESULT);
+
+ OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult();
+
+ if (signatureResult != null) {
+
+ String userId = signatureResult.getUserId();
+ mSignatureKeyId = signatureResult.getKeyId();
mUserIdRest.setText("id: "
+ PgpKeyHelper.convertKeyIdToHex(mSignatureKeyId));
if (userId == null) {
@@ -707,26 +717,37 @@ public class DecryptActivity extends DrawerActivity {
}
mUserId.setText(userId);
- if (returnData.getBoolean(KeychainIntentService.RESULT_SIGNATURE_SUCCESS)) {
- mSignatureStatusImage.setImageResource(R.drawable.overlay_ok);
- mLookupKey.setVisibility(View.GONE);
- } else if (returnData
- .getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN)) {
- mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
- mLookupKey.setVisibility(View.VISIBLE);
- AppMsg.makeText(DecryptActivity.this,
- R.string.unknown_signature,
- AppMsg.STYLE_ALERT).show();
- } else {
- mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
- mLookupKey.setVisibility(View.GONE);
+ switch (signatureResult.getStatus()) {
+ case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: {
+ mSignatureStatusImage.setImageResource(R.drawable.overlay_ok);
+ mLookupKey.setVisibility(View.GONE);
+ break;
+ }
+
+ // TODO!
+// case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: {
+// break;
+// }
+
+ case OpenPgpSignatureResult.SIGNATURE_UNKNOWN_PUB_KEY: {
+ mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
+ mLookupKey.setVisibility(View.VISIBLE);
+ AppMsg.makeText(DecryptActivity.this,
+ R.string.unknown_signature,
+ AppMsg.STYLE_ALERT).show();
+ break;
+ }
+
+ default: {
+ mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
+ mLookupKey.setVisibility(View.GONE);
+ break;
+ }
}
mSignatureLayout.setVisibility(View.VISIBLE);
}
}
}
-
- ;
};
// Create a new Messenger for the communication back
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
index e2822c898..0c35bb2b1 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyActivity.java
@@ -92,12 +92,12 @@ public class EditKeyActivity extends ActionBarActivity {
private SectionView mUserIdsView;
private SectionView mKeysView;
- private String mCurrentPassPhrase = null;
+ private String mCurrentPassphrase = null;
private String mNewPassPhrase = null;
private String mSavedNewPassPhrase = null;
private boolean mIsPassPhraseSet;
- private BootstrapButton mChangePassPhrase;
+ private BootstrapButton mChangePassphrase;
private CheckBox mNoPassphrase;
@@ -134,14 +134,14 @@ public class EditKeyActivity extends ActionBarActivity {
* @param intent
*/
private void handleActionCreateKey(Intent intent) {
- // Inflate a "Done"/"Cancel" custom action bar
- ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.btn_save,
+ // Inflate a "Save"/"Cancel" custom action bar
+ ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.btn_save, R.drawable.ic_action_save,
new View.OnClickListener() {
@Override
public void onClick(View v) {
saveClicked();
}
- }, R.string.btn_do_not_save, new View.OnClickListener() {
+ }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() {
@Override
public void onClick(View v) {
cancelClicked();
@@ -150,7 +150,7 @@ public class EditKeyActivity extends ActionBarActivity {
Bundle extras = intent.getExtras();
- mCurrentPassPhrase = "";
+ mCurrentPassphrase = "";
if (extras != null) {
// if userId is given, prefill the fields
@@ -165,7 +165,7 @@ public class EditKeyActivity extends ActionBarActivity {
if (noPassphrase) {
// check "no passphrase" checkbox and remove button
mNoPassphrase.setChecked(true);
- mChangePassPhrase.setVisibility(View.GONE);
+ mChangePassphrase.setVisibility(View.GONE);
}
}
@@ -181,13 +181,14 @@ public class EditKeyActivity extends ActionBarActivity {
// fill values for this action
Bundle data = new Bundle();
data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE,
- mCurrentPassPhrase);
+ mCurrentPassphrase);
serviceIntent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// Message is received after generating is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
- this, R.string.progress_generating, ProgressDialog.STYLE_SPINNER, true,
+ this, getResources().getQuantityString(R.plurals.progress_generating, 1),
+ ProgressDialog.STYLE_HORIZONTAL, true,
new DialogInterface.OnCancelListener() {
@Override
@@ -224,7 +225,7 @@ public class EditKeyActivity extends ActionBarActivity {
buildLayout();
}
- };
+ }
};
// Create a new Messenger for the communication back
@@ -248,8 +249,8 @@ public class EditKeyActivity extends ActionBarActivity {
* @param intent
*/
private void handleActionEditKey(Intent intent) {
- // Inflate a "Done"/"Cancel" custom action bar
- ActionBarHelper.setDoneView(getSupportActionBar(), R.string.btn_save,
+ // Inflate a "Save"/"Cancel" custom action bar
+ ActionBarHelper.setOneButtonView(getSupportActionBar(), R.string.btn_save, R.drawable.ic_action_save,
new View.OnClickListener() {
@Override
public void onClick(View v) {
@@ -279,9 +280,9 @@ public class EditKeyActivity extends ActionBarActivity {
@Override
public void handleMessage(Message message) {
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
- String passPhrase = PassphraseCacheService.getCachedPassphrase(
+ String passphrase = PassphraseCacheService.getCachedPassphrase(
EditKeyActivity.this, masterKeyId);
- mCurrentPassPhrase = passPhrase;
+ mCurrentPassphrase = passphrase;
finallySaveClicked();
}
}
@@ -326,8 +327,8 @@ public class EditKeyActivity extends ActionBarActivity {
cancelClicked();
return true;
case R.id.menu_key_edit_export_file:
- mExportHelper.showExportKeysDialog(mDataUri, Id.type.secret_key, Constants.path.APP_DIR
- + "/secexport.asc");
+ long[] ids = new long[]{Long.valueOf(mDataUri.getLastPathSegment())};
+ mExportHelper.showExportKeysDialog(ids, Id.type.secret_key, Constants.path.APP_DIR_FILE_SEC);
return true;
case R.id.menu_key_edit_delete: {
// Message is received after key is deleted
@@ -371,14 +372,14 @@ public class EditKeyActivity extends ActionBarActivity {
}
}
- mCurrentPassPhrase = "";
+ mCurrentPassphrase = "";
buildLayout();
mIsPassPhraseSet = PassphraseCacheService.hasPassphrase(this, masterKeyId);
if (!mIsPassPhraseSet) {
// check "no passphrase" checkbox and remove button
mNoPassphrase.setChecked(true);
- mChangePassPhrase.setVisibility(View.GONE);
+ mChangePassphrase.setVisibility(View.GONE);
}
}
@@ -408,7 +409,7 @@ public class EditKeyActivity extends ActionBarActivity {
// set title based on isPassphraseSet()
int title = -1;
if (isPassphraseSet()) {
- title = R.string.title_change_pass_phrase;
+ title = R.string.title_change_passphrase;
} else {
title = R.string.title_set_passphrase;
}
@@ -427,7 +428,7 @@ public class EditKeyActivity extends ActionBarActivity {
setContentView(R.layout.edit_key_activity);
// find views
- mChangePassPhrase = (BootstrapButton) findViewById(R.id.edit_key_btn_change_pass_phrase);
+ mChangePassphrase = (BootstrapButton) findViewById(R.id.edit_key_btn_change_passphrase);
mNoPassphrase = (CheckBox) findViewById(R.id.edit_key_no_passphrase);
// Build layout based on given userIds and keys
@@ -447,7 +448,7 @@ public class EditKeyActivity extends ActionBarActivity {
updatePassPhraseButtonText();
- mChangePassPhrase.setOnClickListener(new OnClickListener() {
+ mChangePassphrase.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
showSetPassphraseDialog();
}
@@ -462,10 +463,10 @@ public class EditKeyActivity extends ActionBarActivity {
// remove passphrase
mSavedNewPassPhrase = mNewPassPhrase;
mNewPassPhrase = "";
- mChangePassPhrase.setVisibility(View.GONE);
+ mChangePassphrase.setVisibility(View.GONE);
} else {
mNewPassPhrase = mSavedNewPassPhrase;
- mChangePassPhrase.setVisibility(View.VISIBLE);
+ mChangePassphrase.setVisibility(View.VISIBLE);
}
}
});
@@ -504,7 +505,7 @@ public class EditKeyActivity extends ActionBarActivity {
if (passphrase == null) {
showPassphraseDialog(masterKeyId, masterCanSign);
} else {
- mCurrentPassPhrase = passphrase;
+ mCurrentPassphrase = passphrase;
finallySaveClicked();
}
} catch (PgpGeneralException e) {
@@ -523,7 +524,7 @@ public class EditKeyActivity extends ActionBarActivity {
// fill values for this action
Bundle data = new Bundle();
data.putString(KeychainIntentService.SAVE_KEYRING_CURRENT_PASSPHRASE,
- mCurrentPassPhrase);
+ mCurrentPassphrase);
data.putString(KeychainIntentService.SAVE_KEYRING_NEW_PASSPHRASE, mNewPassPhrase);
data.putStringArrayList(KeychainIntentService.SAVE_KEYRING_USER_IDS,
getUserIds(mUserIdsView));
@@ -541,7 +542,7 @@ public class EditKeyActivity extends ActionBarActivity {
// Message is received after saving is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- R.string.progress_saving, ProgressDialog.STYLE_HORIZONTAL) {
+ getString(R.string.progress_saving), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
@@ -559,7 +560,7 @@ public class EditKeyActivity extends ActionBarActivity {
setResult(RESULT_OK, data);
finish();
}
- };
+ }
};
// Create a new Messenger for the communication back
@@ -694,7 +695,7 @@ public class EditKeyActivity extends ActionBarActivity {
}
private void updatePassPhraseButtonText() {
- mChangePassPhrase.setText(isPassphraseSet() ? getString(R.string.btn_change_passphrase)
+ mChangePassphrase.setText(isPassphraseSet() ? getString(R.string.btn_change_passphrase)
: getString(R.string.btn_set_passphrase));
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
index 9da6c1b9f..8f8952763 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptActivity.java
@@ -52,17 +52,21 @@ import android.os.Message;
import android.os.Messenger;
import android.view.View;
import android.view.View.OnClickListener;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;
import com.beardedhen.androidbootstrap.BootstrapButton;
+import com.beardedhen.androidbootstrap.FontAwesomeText;
import com.devspark.appmsg.AppMsg;
public class EncryptActivity extends DrawerActivity {
@@ -101,18 +105,24 @@ public class EncryptActivity extends DrawerActivity {
private int mEncryptTarget;
- private EditText mPassPhrase = null;
- private EditText mPassPhraseAgain = null;
+ private EditText mPassphrase = null;
+ private EditText mPassphraseAgain = null;
private CheckBox mAsciiArmor = null;
private Spinner mFileCompression = null;
private EditText mFilename = null;
private CheckBox mDeleteAfter = null;
+ private CheckBox mShareAfter = null;
private BootstrapButton mBrowse = null;
private String mInputFilename = null;
private String mOutputFilename = null;
+ private Integer mShortAnimationDuration = null;
+ private boolean mFileAdvancedSettingsVisible = false;
+ private TextView mFileAdvancedSettings = null;
+ private LinearLayout mFileAdvancedSettingsContainer = null;
+ private FontAwesomeText mAdvancedSettingsIcon;
private boolean mAsciiArmorDemand = false;
private boolean mOverrideAsciiArmor = false;
@@ -147,6 +157,9 @@ public class EncryptActivity extends DrawerActivity {
updateMode();
updateActionBarButtons();
+
+ // retrieve and cache the system's short animation time
+ mShortAnimationDuration = getResources().getInteger(android.R.integer.config_shortAnimTime);
}
/**
@@ -436,14 +449,14 @@ public class EncryptActivity extends DrawerActivity {
// symmetric encryption
if (mMode.getCurrentView().getId() == R.id.modeSymmetric) {
boolean gotPassPhrase = false;
- String passPhrase = mPassPhrase.getText().toString();
- String passPhraseAgain = mPassPhraseAgain.getText().toString();
- if (!passPhrase.equals(passPhraseAgain)) {
+ String passphrase = mPassphrase.getText().toString();
+ String passphraseAgain = mPassphraseAgain.getText().toString();
+ if (!passphrase.equals(passphraseAgain)) {
AppMsg.makeText(this, R.string.passphrases_do_not_match, AppMsg.STYLE_ALERT).show();
return;
}
- gotPassPhrase = (passPhrase.length() != 0);
+ gotPassPhrase = (passphrase.length() != 0);
if (!gotPassPhrase) {
AppMsg.makeText(this, R.string.passphrase_must_not_be_empty, AppMsg.STYLE_ALERT)
.show();
@@ -550,11 +563,11 @@ public class EncryptActivity extends DrawerActivity {
if (mMode.getCurrentView().getId() == R.id.modeSymmetric) {
Log.d(Constants.TAG, "Symmetric encryption enabled!");
- String passPhrase = mPassPhrase.getText().toString();
- if (passPhrase.length() == 0) {
- passPhrase = null;
+ String passphrase = mPassphrase.getText().toString();
+ if (passphrase.length() == 0) {
+ passphrase = null;
}
- data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passPhrase);
+ data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passphrase);
} else {
mSecretKeyIdToPass = mSecretKeyId;
encryptionKeyIds = mEncryptionKeyIds;
@@ -604,7 +617,7 @@ public class EncryptActivity extends DrawerActivity {
// Message is received after encrypting is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- R.string.progress_encrypting, ProgressDialog.STYLE_HORIZONTAL) {
+ getString(R.string.progress_encrypting), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
@@ -650,6 +663,15 @@ public class EncryptActivity extends DrawerActivity {
.newInstance(mInputFilename);
deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog");
}
+
+ if (mShareAfter.isChecked()) {
+ // Share encrypted file
+ Intent sendFileIntent = new Intent(Intent.ACTION_SEND);
+ sendFileIntent.setType("*/*");
+ sendFileIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(mOutputFilename));
+ startActivity(Intent.createChooser(sendFileIntent,
+ getString(R.string.title_send_file)));
+ }
break;
default:
@@ -659,8 +681,6 @@ public class EncryptActivity extends DrawerActivity {
}
}
}
-
- ;
};
// Create a new Messenger for the communication back
@@ -766,8 +786,8 @@ public class EncryptActivity extends DrawerActivity {
mMainUserId = (TextView) findViewById(R.id.mainUserId);
mMainUserIdRest = (TextView) findViewById(R.id.mainUserIdRest);
- mPassPhrase = (EditText) findViewById(R.id.passPhrase);
- mPassPhraseAgain = (EditText) findViewById(R.id.passPhraseAgain);
+ mPassphrase = (EditText) findViewById(R.id.passphrase);
+ mPassphraseAgain = (EditText) findViewById(R.id.passphraseAgain);
// measure the height of the source_file view and set the message view's min height to that,
// so it fills mSource fully... bit of a hack.
@@ -785,6 +805,50 @@ public class EncryptActivity extends DrawerActivity {
}
});
+ mAdvancedSettingsIcon = (FontAwesomeText) findViewById(R.id.advancedSettingsIcon);
+ mFileAdvancedSettingsContainer = (LinearLayout) findViewById(R.id.fileAdvancedSettingsContainer);
+ mFileAdvancedSettings = (TextView) findViewById(R.id.advancedSettings);
+
+ LinearLayout advancedSettingsControl = (LinearLayout) findViewById(R.id.advancedSettingsControl);
+ advancedSettingsControl.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ mFileAdvancedSettingsVisible = !mFileAdvancedSettingsVisible;
+ if (mFileAdvancedSettingsVisible) {
+ mAdvancedSettingsIcon.setIcon("fa-chevron-down");
+ mFileAdvancedSettingsContainer.setVisibility(View.VISIBLE);
+ AlphaAnimation animation = new AlphaAnimation(0f, 1f);
+ animation.setDuration(mShortAnimationDuration);
+ mFileAdvancedSettingsContainer.startAnimation(animation);
+ mFileAdvancedSettings.setText(R.string.btn_encryption_advanced_settings_hide);
+
+ } else {
+ mAdvancedSettingsIcon.setIcon("fa-chevron-right");
+ AlphaAnimation animation = new AlphaAnimation(1f, 0f);
+ animation.setDuration(mShortAnimationDuration);
+ animation.setAnimationListener(new Animation.AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) {
+ // do nothing
+ }
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ // making sure that at the end the container is completely removed from view
+ mFileAdvancedSettingsContainer.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) {
+ // do nothing
+ }
+ });
+ mFileAdvancedSettingsContainer.startAnimation(animation);
+ mFileAdvancedSettings.setText(R.string.btn_encryption_advanced_settings_show);
+ }
+ }
+ });
+
mFileCompression = (Spinner) findViewById(R.id.fileCompression);
Choice[] choices = new Choice[]{
new Choice(Id.choice.compression.none, getString(R.string.choice_none) + " ("
@@ -809,6 +873,7 @@ public class EncryptActivity extends DrawerActivity {
}
mDeleteAfter = (CheckBox) findViewById(R.id.deleteAfterEncryption);
+ mShareAfter = (CheckBox) findViewById(R.id.shareAfterEncryption);
mAsciiArmor = (CheckBox) findViewById(R.id.asciiArmour);
mAsciiArmor.setChecked(Preferences.getPreferences(this).getDefaultAsciiArmour());
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
index 9ccd7e088..ac8250bef 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/HelpActivity.java
@@ -22,16 +22,11 @@ import java.util.ArrayList;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.adapter.TabsAdapter;
-import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentStatePagerAdapter;
-import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
-import android.widget.TextView;
public class HelpActivity extends ActionBarActivity {
public static final String EXTRA_SELECTED_TAB = "selectedTab";
@@ -64,19 +59,19 @@ public class HelpActivity extends ActionBarActivity {
Bundle startBundle = new Bundle();
startBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_start);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_start)),
- HelpHtmlFragment.class, startBundle, (selectedTab == 0 ? true : false));
+ HelpHtmlFragment.class, startBundle, (selectedTab == 0) );
Bundle nfcBundle = new Bundle();
nfcBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_nfc_beam);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_nfc_beam)),
- HelpHtmlFragment.class, nfcBundle, (selectedTab == 1 ? true : false));
+ HelpHtmlFragment.class, nfcBundle, (selectedTab == 1) );
Bundle changelogBundle = new Bundle();
changelogBundle.putInt(HelpHtmlFragment.ARG_HTML_FILE, R.raw.help_changelog);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_changelog)),
- HelpHtmlFragment.class, changelogBundle, (selectedTab == 2 ? true : false));
+ HelpHtmlFragment.class, changelogBundle, (selectedTab == 2) );
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.help_tab_about)),
- HelpAboutFragment.class, null, (selectedTab == 3 ? true : false));
+ HelpAboutFragment.class, null, (selectedTab == 3) );
}
} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
index 5ac421a44..f04a0e227 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysActivity.java
@@ -161,7 +161,7 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
} else if (extras.containsKey(EXTRA_KEY_ID)) {
long keyId = intent.getLongExtra(EXTRA_KEY_ID, 0);
if (keyId != 0) {
- query = "0x" + PgpKeyHelper.convertKeyToHex(keyId);
+ query = PgpKeyHelper.convertKeyIdToHex(keyId);
}
} else if (extras.containsKey(EXTRA_FINGERPRINT)) {
String fingerprint = intent.getStringExtra(EXTRA_FINGERPRINT);
@@ -360,51 +360,53 @@ public class ImportKeysActivity extends DrawerActivity implements ActionBar.OnNa
// }
- // Message is received after importing is done in ApgService
- KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(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 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
- // get returned data bundle
- Bundle returnData = message.getData();
-
- int added = returnData.getInt(KeychainIntentService.RESULT_IMPORT_ADDED);
- int updated = returnData
- .getInt(KeychainIntentService.RESULT_IMPORT_UPDATED);
- int bad = returnData.getInt(KeychainIntentService.RESULT_IMPORT_BAD);
- String toastMessage;
- if (added > 0 && updated > 0) {
- String addedStr = getResources().getQuantityString(
- R.plurals.keys_added_and_updated_1, added, added);
- String updatedStr = getResources().getQuantityString(
- R.plurals.keys_added_and_updated_2, updated, updated);
- toastMessage = addedStr + updatedStr;
- } else if (added > 0) {
- toastMessage = getResources().getQuantityString(R.plurals.keys_added,
- added, added);
- } else if (updated > 0) {
- toastMessage = getResources().getQuantityString(R.plurals.keys_updated,
- updated, updated);
- } else {
- toastMessage = getString(R.string.no_keys_added_or_updated);
- }
- AppMsg.makeText(ImportKeysActivity.this, toastMessage, AppMsg.STYLE_INFO)
- .show();
- if (bad > 0) {
- BadImportKeyDialogFragment badImportKeyDialogFragment = BadImportKeyDialogFragment.newInstance(bad);
- badImportKeyDialogFragment.show(getSupportFragmentManager(), "badKeyDialog");
- }
- }
- }
- };
-
/**
* Import keys with mImportData
*/
public void importKeys() {
+ // Message is received after importing is done in ApgService
+ KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(
+ this,
+ getString(R.string.progress_importing),
+ ProgressDialog.STYLE_HORIZONTAL) {
+ public void handleMessage(Message message) {
+ // handle messages by standard KeychainIntentServiceHandler first
+ super.handleMessage(message);
+
+ if (message.arg1 == KeychainIntentServiceHandler.MESSAGE_OKAY) {
+ // get returned data bundle
+ Bundle returnData = message.getData();
+
+ int added = returnData.getInt(KeychainIntentService.RESULT_IMPORT_ADDED);
+ int updated = returnData
+ .getInt(KeychainIntentService.RESULT_IMPORT_UPDATED);
+ int bad = returnData.getInt(KeychainIntentService.RESULT_IMPORT_BAD);
+ String toastMessage;
+ if (added > 0 && updated > 0) {
+ String addedStr = getResources().getQuantityString(
+ R.plurals.keys_added_and_updated_1, added, added);
+ String updatedStr = getResources().getQuantityString(
+ R.plurals.keys_added_and_updated_2, updated, updated);
+ toastMessage = addedStr + updatedStr;
+ } else if (added > 0) {
+ toastMessage = getResources().getQuantityString(R.plurals.keys_added,
+ added, added);
+ } else if (updated > 0) {
+ toastMessage = getResources().getQuantityString(R.plurals.keys_updated,
+ updated, updated);
+ } else {
+ toastMessage = getString(R.string.no_keys_added_or_updated);
+ }
+ AppMsg.makeText(ImportKeysActivity.this, toastMessage, AppMsg.STYLE_INFO)
+ .show();
+ if (bad > 0) {
+ BadImportKeyDialogFragment badImportKeyDialogFragment = BadImportKeyDialogFragment.newInstance(bad);
+ badImportKeyDialogFragment.show(getSupportFragmentManager(), "badKeyDialog");
+ }
+ }
+ }
+ };
+
if (mListFragment.getKeyBytes() != null || mListFragment.getDataUri() != null) {
Log.d(Constants.TAG, "importKeys started");
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
index 1118f0264..a6917d6f4 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java
@@ -219,27 +219,44 @@ public class ImportKeysListFragment extends ListFragment implements
} else {
setListShownNoAnimation(true);
}
+
+ Exception error = data.getError();
+
switch (loader.getId()) {
case LOADER_ID_BYTES:
+
+ if(error == null){
+ // No error
+ } else if(error instanceof ImportKeysListLoader.FileHasNoContent) {
+ AppMsg.makeText(getActivity(), R.string.error_import_file_no_content,
+ AppMsg.STYLE_ALERT).show();
+ } else if(error instanceof ImportKeysListLoader.NonPgpPart) {
+ AppMsg.makeText(getActivity(),
+ ((ImportKeysListLoader.NonPgpPart) error).getCount() + " " + getResources().
+ getQuantityString(R.plurals.error_import_non_pgp_part,
+ ((ImportKeysListLoader.NonPgpPart) error).getCount()),
+ new AppMsg.Style(AppMsg.LENGTH_LONG, R.color.confirm)).show();
+ } else {
+ AppMsg.makeText(getActivity(), R.string.error_generic_report_bug,
+ new AppMsg.Style(AppMsg.LENGTH_LONG, R.color.alert)).show();
+ }
break;
case LOADER_ID_SERVER_QUERY:
- Exception error = data.getError();
-
- if(error == null){
+ if(error == null) {
AppMsg.makeText(
getActivity(), getResources().getQuantityString(R.plurals.keys_found,
mAdapter.getCount(), mAdapter.getCount()),
AppMsg.STYLE_INFO
).show();
- } else if(error instanceof KeyServer.InsufficientQuery){
+ } else if(error instanceof KeyServer.InsufficientQuery) {
AppMsg.makeText(getActivity(), R.string.error_keyserver_insufficient_query,
AppMsg.STYLE_ALERT).show();
- }else if(error instanceof KeyServer.QueryException){
+ } else if(error instanceof KeyServer.QueryException) {
AppMsg.makeText(getActivity(), R.string.error_keyserver_query,
AppMsg.STYLE_ALERT).show();
- }else if(error instanceof KeyServer.TooManyResponses){
+ } else if(error instanceof KeyServer.TooManyResponses) {
AppMsg.makeText(getActivity(), R.string.error_keyserver_too_many_responses,
AppMsg.STYLE_ALERT).show();
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
index 0bbe2edb1..9eebbed64 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListActivity.java
@@ -59,8 +59,8 @@ public class KeyListActivity extends DrawerActivity {
return true;
case R.id.menu_key_list_export:
- mExportHelper.showExportKeysDialog(null, Id.type.public_key, Constants.path.APP_DIR
- + "/pubexport.asc");
+ // TODO fix this for unified keylist
+ mExportHelper.showExportKeysDialog(null, Id.type.public_key, Constants.path.APP_DIR_FILE_PUB);
return true;
default:
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
index ea37677d1..c4a694bba 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java
@@ -19,11 +19,14 @@ package org.sufficientlysecure.keychain.ui;
import java.util.HashMap;
import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
+import org.sufficientlysecure.keychain.helper.ExportHelper;
import org.sufficientlysecure.keychain.provider.KeychainContract;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyTypes;
@@ -53,13 +56,21 @@ import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
+import android.support.v4.view.MenuItemCompat;
+import android.support.v7.app.ActionBarActivity;
+import android.support.v7.widget.SearchView;
+import android.text.Spannable;
+import android.text.TextUtils;
+import android.text.style.ForegroundColorSpan;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
+import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
+import android.view.animation.AnimationUtils;
import android.widget.AbsListView.MultiChoiceModeListener;
import android.widget.AdapterView;
import android.widget.Button;
@@ -73,24 +84,37 @@ import com.beardedhen.androidbootstrap.BootstrapButton;
* Public key list with sticky list headers. It does _not_ extend ListFragment because it uses
* StickyListHeaders library which does not extend upon ListView.
*/
-public class KeyListFragment extends Fragment implements AdapterView.OnItemClickListener,
+public class KeyListFragment extends Fragment implements SearchView.OnQueryTextListener, AdapterView.OnItemClickListener,
LoaderManager.LoaderCallbacks<Cursor> {
private KeyListAdapter mAdapter;
private StickyListHeadersListView mStickyList;
+ // rebuild functionality of ListFragment, http://stackoverflow.com/a/12504097
+ boolean mListShown;
+ View mProgressContainer;
+ View mListContainer;
+
+ private String mCurQuery;
+ private SearchView mSearchView;
// empty list layout
private BootstrapButton mButtonEmptyCreate;
private BootstrapButton mButtonEmptyImport;
+
/**
* Load custom layout with StickyListView from library
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.key_list_fragment, container, false);
+ View root = inflater.inflate(R.layout.key_list_fragment, container, false);
+
+ mStickyList = (StickyListHeadersListView) root.findViewById(R.id.key_list_list);
+ mStickyList.setOnItemClickListener(this);
- mButtonEmptyCreate = (BootstrapButton) view.findViewById(R.id.key_list_empty_button_create);
+
+ // empty view
+ mButtonEmptyCreate = (BootstrapButton) root.findViewById(R.id.key_list_empty_button_create);
mButtonEmptyCreate.setOnClickListener(new OnClickListener() {
@Override
@@ -102,8 +126,7 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
startActivityForResult(intent, 0);
}
});
-
- mButtonEmptyImport = (BootstrapButton) view.findViewById(R.id.key_list_empty_button_import);
+ mButtonEmptyImport = (BootstrapButton) root.findViewById(R.id.key_list_empty_button_import);
mButtonEmptyImport.setOnClickListener(new OnClickListener() {
@Override
@@ -114,7 +137,12 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
}
});
- return view;
+ // rebuild functionality of ListFragment, http://stackoverflow.com/a/12504097
+ mListContainer = root.findViewById(R.id.key_list_list_container);
+ mProgressContainer = root.findViewById(R.id.key_list_progress_container);
+ mListShown = true;
+
+ return root;
}
/**
@@ -125,8 +153,6 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- mStickyList = (StickyListHeadersListView) getActivity().findViewById(R.id.list);
-
mStickyList.setOnItemClickListener(this);
mStickyList.setAreHeadersSticky(true);
mStickyList.setDrawingListUnderStickyHeader(false);
@@ -137,7 +163,7 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
}
// this view is made visible if no data is available
- mStickyList.setEmptyView(getActivity().findViewById(R.id.empty));
+ mStickyList.setEmptyView(getActivity().findViewById(R.id.key_list_empty));
/*
* ActionBarSherlock does not support MultiChoiceModeListener. Thus multi-selection is only
@@ -147,8 +173,6 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
mStickyList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mStickyList.getWrappedList().setMultiChoiceModeListener(new MultiChoiceModeListener() {
- private int count = 0;
-
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
android.view.MenuInflater inflater = getActivity().getMenuInflater();
@@ -174,7 +198,7 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
break;
}
case R.id.menu_key_list_multi_delete: {
- ids = mAdapter.getCurrentSelectedItemIds();
+ ids = mStickyList.getWrappedList().getCheckedItemIds();
showDeleteKeyDialog(mode, ids);
break;
}
@@ -184,7 +208,6 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
@Override
public void onDestroyActionMode(ActionMode mode) {
- count = 0;
mAdapter.clearSelection();
}
@@ -192,13 +215,11 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
boolean checked) {
if (checked) {
- count++;
mAdapter.setNewSelection(position, checked);
} else {
- count--;
mAdapter.removeSelection(position);
}
-
+ int count = mStickyList.getCheckedItemCount();
String keysSelected = getResources().getQuantityString(
R.plurals.key_list_selected_keys, count, count);
mode.setTitle(keysSelected);
@@ -207,9 +228,12 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
});
}
- // NOTE: Not supported by StickyListHeader, thus no indicator is shown while loading
+ // We have a menu item to show in action bar.
+ setHasOptionsMenu(true);
+
+ // NOTE: Not supported by StickyListHeader, but reimplemented here
// Start out with a progress indicator.
- // setListShown(false);
+ setListShown(false);
// Create an empty adapter we will use to display the loaded data.
mAdapter = new KeyListAdapter(getActivity(), null, Id.type.public_key);
@@ -238,27 +262,33 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
// 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 = KeyRings.buildUnifiedKeyRingsUri();
-
+ String where = null;
+ String whereArgs[] = null;
+ if (mCurQuery != null) {
+ where = KeychainContract.UserIds.USER_ID + " LIKE ?";
+ whereArgs = new String[]{"%" + mCurQuery + "%"};
+ }
// 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);
+ return new CursorLoader(getActivity(), baseUri, PROJECTION, where, whereArgs, SORT_ORDER);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
+ mAdapter.setSearchQuery(mCurQuery);
mAdapter.swapCursor(data);
mStickyList.setAdapter(mAdapter);
- // NOTE: Not supported by StickyListHeader, thus no indicator is shown while loading
+ // NOTE: Not supported by StickyListHeader, but reimplemented here
// The list should now be shown.
- // if (isResumed()) {
- // setListShown(true);
- // } else {
- // setListShownNoAnimation(true);
- // }
+ if (isResumed()) {
+ setListShown(true);
+ } else {
+ setListShownNoAnimation(true);
+ }
}
@Override
@@ -338,6 +368,87 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
deleteKeyDialog.show(getActivity().getSupportFragmentManager(), "deleteKeyDialog");
}
+
+ @Override
+ public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
+ // Get the searchview
+ MenuItem searchItem = menu.findItem(R.id.menu_key_list_search);
+ mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
+
+ // Execute this when searching
+ mSearchView.setOnQueryTextListener(this);
+
+ // Erase search result without focus
+ MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() {
+ @Override
+ public boolean onMenuItemActionExpand(MenuItem item) {
+ return true;
+ }
+
+ @Override
+ public boolean onMenuItemActionCollapse(MenuItem item) {
+ mCurQuery = null;
+ mSearchView.setQuery("", true);
+ getLoaderManager().restartLoader(0, null, KeyListFragment.this);
+ return true;
+ }
+ });
+
+ super.onCreateOptionsMenu(menu, inflater);
+ }
+
+ @Override
+ public boolean onQueryTextSubmit(String s) {
+ return true;
+ }
+
+ @Override
+ public boolean onQueryTextChange(String s) {
+ // Called when the action bar search text has changed. Update
+ // the search filter, and restart the loader to do a new query
+ // with this filter.
+ mCurQuery = !TextUtils.isEmpty(s) ? s : null;
+ getLoaderManager().restartLoader(0, null, this);
+ return true;
+ }
+
+ // rebuild functionality of ListFragment, http://stackoverflow.com/a/12504097
+ public void setListShown(boolean shown, boolean animate) {
+ if (mListShown == shown) {
+ return;
+ }
+ mListShown = shown;
+ if (shown) {
+ if (animate) {
+ mProgressContainer.startAnimation(AnimationUtils.loadAnimation(
+ getActivity(), android.R.anim.fade_out));
+ mListContainer.startAnimation(AnimationUtils.loadAnimation(
+ getActivity(), android.R.anim.fade_in));
+ }
+ mProgressContainer.setVisibility(View.GONE);
+ mListContainer.setVisibility(View.VISIBLE);
+ } else {
+ if (animate) {
+ mProgressContainer.startAnimation(AnimationUtils.loadAnimation(
+ getActivity(), android.R.anim.fade_in));
+ mListContainer.startAnimation(AnimationUtils.loadAnimation(
+ getActivity(), android.R.anim.fade_out));
+ }
+ mProgressContainer.setVisibility(View.VISIBLE);
+ mListContainer.setVisibility(View.INVISIBLE);
+ }
+ }
+
+ // rebuild functionality of ListFragment, http://stackoverflow.com/a/12504097
+ public void setListShown(boolean shown) {
+ setListShown(shown, true);
+ }
+
+ // rebuild functionality of ListFragment, http://stackoverflow.com/a/12504097
+ public void setListShownNoAnimation(boolean shown) {
+ setListShown(shown, false);
+ }
+
/**
* Implements StickyListHeadersAdapter from library
*/
@@ -347,6 +458,8 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
private int mIndexIsRevoked;
private int mMasterKeyId;
+ private String mCurQuery;
+
@SuppressLint("UseSparseArrays")
private HashMap<Integer, Boolean> mSelection = new HashMap<Integer, Boolean>();
@@ -394,12 +507,12 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
String userId = cursor.getString(mIndexUserId);
String[] userIdSplit = PgpKeyHelper.splitUserId(userId);
if (userIdSplit[0] != null) {
- mainUserId.setText(userIdSplit[0]);
+ mainUserId.setText(highlightSearchQuery(userIdSplit[0]));
} else {
mainUserId.setText(R.string.user_id_no_name);
}
if (userIdSplit[1] != null) {
- mainUserIdRest.setText(userIdSplit[1]);
+ mainUserIdRest.setText(highlightSearchQuery(userIdSplit[1]));
mainUserIdRest.setVisibility(View.VISIBLE);
} else {
mainUserIdRest.setVisibility(View.GONE);
@@ -558,20 +671,6 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
notifyDataSetChanged();
}
- public boolean isPositionChecked(int position) {
- Boolean result = mSelection.get(position);
- return result == null ? false : result;
- }
-
- public long[] getCurrentSelectedItemIds() {
- long[] ids = new long[mSelection.size()];
- int i = 0;
- // get master key ids
- for (int pos : mSelection.keySet())
- ids[i++] = mAdapter.getItemId(pos);
- return ids;
- }
-
public long[] getCurrentSelectedMasterKeyIds() {
long[] ids = new long[mSelection.size()];
int i = 0;
@@ -608,6 +707,34 @@ public class KeyListFragment extends Fragment implements AdapterView.OnItemClick
return v;
}
+ // search highlight methods
+
+ public void setSearchQuery(String searchQuery) {
+ mCurQuery = searchQuery;
+ }
+
+ public String getSearchQuery() {
+ return mCurQuery;
+ }
+
+ protected Spannable highlightSearchQuery(String text) {
+ Spannable highlight = Spannable.Factory.getInstance().newSpannable(text);
+
+ if (mCurQuery != null) {
+ Pattern pattern = Pattern.compile("(?i)" + mCurQuery);
+ Matcher matcher = pattern.matcher(text);
+ if (matcher.find()) {
+ highlight.setSpan(
+ new ForegroundColorSpan(mContext.getResources().getColor(R.color.emphasis)),
+ matcher.start(),
+ matcher.end(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ return highlight;
+ } else {
+ return highlight;
+ }
+ }
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java
index b38beebd1..2e8f25890 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesActivity.java
@@ -24,24 +24,27 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.Preferences;
import org.sufficientlysecure.keychain.ui.widget.IntegerListPreference;
+import android.annotation.SuppressLint;
import android.content.Intent;
+import android.os.Build;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
+import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
import android.support.v7.app.ActionBarActivity;
+import java.util.List;
+
+@SuppressLint("NewApi")
public class PreferencesActivity extends PreferenceActivity {
- private IntegerListPreference mPassPhraseCacheTtl = null;
- private IntegerListPreference mEncryptionAlgorithm = null;
- private IntegerListPreference mHashAlgorithm = null;
- private IntegerListPreference mMessageCompression = null;
- private IntegerListPreference mFileCompression = null;
- private CheckBoxPreference mAsciiArmour = null;
- private CheckBoxPreference mForceV3Signatures = null;
+
+ public final static String ACTION_PREFS_GEN = "org.sufficientlysecure.keychain.ui.PREFS_GEN";
+ public final static String ACTION_PREFS_ADV = "org.sufficientlysecure.keychain.ui.PREFS_ADV";
+
private PreferenceScreen mKeyServerPreference = null;
- private Preferences mPreferences;
+ private static Preferences mPreferences;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -53,22 +56,218 @@ public class PreferencesActivity extends PreferenceActivity {
// actionBar.setDisplayHomeAsUpEnabled(false);
// actionBar.setHomeButtonEnabled(false);
- addPreferencesFromResource(R.xml.preferences);
+ String action = getIntent().getAction();
+
+ if (action != null && action.equals(ACTION_PREFS_GEN)) {
+ addPreferencesFromResource(R.xml.gen_preferences);
+
+ initializePassPassPhraceCacheTtl(
+ (IntegerListPreference) findPreference(Constants.pref.PASS_PHRASE_CACHE_TTL));
+
+ mKeyServerPreference = (PreferenceScreen) findPreference(Constants.pref.KEY_SERVERS);
+ String servers[] = mPreferences.getKeyServers();
+ mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers,
+ servers.length, servers.length));
+ mKeyServerPreference
+ .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ public boolean onPreferenceClick(Preference preference) {
+ Intent intent = new Intent(PreferencesActivity.this,
+ PreferencesKeyServerActivity.class);
+ intent.putExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS,
+ mPreferences.getKeyServers());
+ startActivityForResult(intent, Id.request.key_server_preference);
+ return false;
+ }
+ });
+
+ } else if (action != null && action.equals(ACTION_PREFS_ADV)) {
+ addPreferencesFromResource(R.xml.adv_preferences);
+
+ initializeEncryptionAlgorithm(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM));
+
+ int[] valueIds = new int[] { Id.choice.compression.none, Id.choice.compression.zip,
+ Id.choice.compression.zlib, Id.choice.compression.bzip2, };
+ String[] entries = new String[] {
+ getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
+ "ZIP (" + getString(R.string.compression_fast) + ")",
+ "ZLIB (" + getString(R.string.compression_fast) + ")",
+ "BZIP2 (" + getString(R.string.compression_very_slow) + ")", };
+ String[] values = new String[valueIds.length];
+ for (int i = 0; i < values.length; ++i) {
+ values[i] = "" + valueIds[i];
+ }
+
+ initializeHashAlgorithm(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_HASH_ALGORITHM),
+ valueIds, entries, values);
+
+ initializeMessageCompression(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_MESSAGE_COMPRESSION),
+ valueIds, entries, values);
+
+ initializeFileCompression(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_FILE_COMPRESSION),
+ entries, values);
+
+ initializeAsciiArmour((CheckBoxPreference) findPreference(Constants.pref.DEFAULT_ASCII_ARMOUR));
+
+ initializeForceV3Signatures((CheckBoxPreference) findPreference(Constants.pref.FORCE_V3_SIGNATURES));
+
+ } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
+ // Load the legacy preferences headers
+ addPreferencesFromResource(R.xml.preference_headers_legacy);
+ }
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case Id.request.key_server_preference: {
+ if (resultCode == RESULT_CANCELED || data == null) {
+ return;
+ }
+ String servers[] = data
+ .getStringArrayExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS);
+ mPreferences.setKeyServers(servers);
+ mKeyServerPreference.setSummary(getResources().getQuantityString(
+ R.plurals.n_key_servers, servers.length, servers.length));
+ break;
+ }
+
+ default: {
+ super.onActivityResult(requestCode, resultCode, data);
+ break;
+ }
+ }
+ }
+
+ /* Called only on Honeycomb and later */
+ @Override
+ public void onBuildHeaders(List<Header> target) {
+ super.onBuildHeaders(target);
+ loadHeadersFromResource(R.xml.preference_headers, target);
+ }
+
+ /** This fragment shows the general preferences in android 3.0+ */
+ public static class GeneralPrefsFragment extends PreferenceFragment {
+
+ private PreferenceScreen mKeyServerPreference = null;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Load the preferences from an XML resource
+ addPreferencesFromResource(R.xml.gen_preferences);
+
+ initializePassPassPhraceCacheTtl(
+ (IntegerListPreference) findPreference(Constants.pref.PASS_PHRASE_CACHE_TTL));
+
+ mKeyServerPreference = (PreferenceScreen) findPreference(Constants.pref.KEY_SERVERS);
+ String servers[] = mPreferences.getKeyServers();
+ mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers,
+ servers.length, servers.length));
+ mKeyServerPreference
+ .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ public boolean onPreferenceClick(Preference preference) {
+ Intent intent = new Intent(getActivity(),
+ PreferencesKeyServerActivity.class);
+ intent.putExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS,
+ mPreferences.getKeyServers());
+ startActivityForResult(intent, Id.request.key_server_preference);
+ return false;
+ }
+ });
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case Id.request.key_server_preference: {
+ if (resultCode == RESULT_CANCELED || data == null) {
+ return;
+ }
+ String servers[] = data
+ .getStringArrayExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS);
+ mPreferences.setKeyServers(servers);
+ mKeyServerPreference.setSummary(getResources().getQuantityString(
+ R.plurals.n_key_servers, servers.length, servers.length));
+ break;
+ }
+
+ default: {
+ super.onActivityResult(requestCode, resultCode, data);
+ break;
+ }
+ }
+ }
+ }
+
+ /** This fragment shows the advanced preferences in android 3.0+ */
+ public static class AdvancedPrefsFragment extends PreferenceFragment {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Load the preferences from an XML resource
+ addPreferencesFromResource(R.xml.adv_preferences);
+
+ initializeEncryptionAlgorithm(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM));
+
+ int[] valueIds = new int[] { Id.choice.compression.none, Id.choice.compression.zip,
+ Id.choice.compression.zlib, Id.choice.compression.bzip2, };
+ String[] entries = new String[] {
+ getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
+ "ZIP (" + getString(R.string.compression_fast) + ")",
+ "ZLIB (" + getString(R.string.compression_fast) + ")",
+ "BZIP2 (" + getString(R.string.compression_very_slow) + ")", };
+ String[] values = new String[valueIds.length];
+ for (int i = 0; i < values.length; ++i) {
+ values[i] = "" + valueIds[i];
+ }
+
+ initializeHashAlgorithm(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_HASH_ALGORITHM),
+ valueIds, entries, values);
+
+ initializeMessageCompression(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_MESSAGE_COMPRESSION),
+ valueIds, entries, values);
+
+ initializeFileCompression(
+ (IntegerListPreference) findPreference(Constants.pref.DEFAULT_FILE_COMPRESSION),
+ entries, values);
- mPassPhraseCacheTtl = (IntegerListPreference) findPreference(Constants.pref.PASS_PHRASE_CACHE_TTL);
- mPassPhraseCacheTtl.setValue("" + mPreferences.getPassPhraseCacheTtl());
- mPassPhraseCacheTtl.setSummary(mPassPhraseCacheTtl.getEntry());
- mPassPhraseCacheTtl
+ initializeAsciiArmour((CheckBoxPreference) findPreference(Constants.pref.DEFAULT_ASCII_ARMOUR));
+
+ initializeForceV3Signatures((CheckBoxPreference) findPreference(Constants.pref.FORCE_V3_SIGNATURES));
+ }
+ }
+
+ protected boolean isValidFragment (String fragmentName) {
+ return AdvancedPrefsFragment.class.getName().equals(fragmentName)
+ || GeneralPrefsFragment.class.getName().equals(fragmentName)
+ || super.isValidFragment(fragmentName);
+ }
+
+ private static void initializePassPassPhraceCacheTtl(final IntegerListPreference mPassphraseCacheTtl) {
+ mPassphraseCacheTtl.setValue("" + mPreferences.getPassPhraseCacheTtl());
+ mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry());
+ mPassphraseCacheTtl
.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
- mPassPhraseCacheTtl.setValue(newValue.toString());
- mPassPhraseCacheTtl.setSummary(mPassPhraseCacheTtl.getEntry());
+ mPassphraseCacheTtl.setValue(newValue.toString());
+ mPassphraseCacheTtl.setSummary(mPassphraseCacheTtl.getEntry());
mPreferences.setPassPhraseCacheTtl(Integer.parseInt(newValue.toString()));
return false;
}
});
+ }
- mEncryptionAlgorithm = (IntegerListPreference) findPreference(Constants.pref.DEFAULT_ENCRYPTION_ALGORITHM);
+ private static void initializeEncryptionAlgorithm(final IntegerListPreference mEncryptionAlgorithm) {
int valueIds[] = { PGPEncryptedData.AES_128, PGPEncryptedData.AES_192,
PGPEncryptedData.AES_256, PGPEncryptedData.BLOWFISH, PGPEncryptedData.TWOFISH,
PGPEncryptedData.CAST5, PGPEncryptedData.DES, PGPEncryptedData.TRIPLE_DES,
@@ -93,8 +292,10 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
+ }
- mHashAlgorithm = (IntegerListPreference) findPreference(Constants.pref.DEFAULT_HASH_ALGORITHM);
+ private static void initializeHashAlgorithm
+ (final IntegerListPreference mHashAlgorithm, int[] valueIds, String[] entries, String[] values) {
valueIds = new int[] { HashAlgorithmTags.MD5, HashAlgorithmTags.RIPEMD160,
HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA224, HashAlgorithmTags.SHA256,
HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA512, };
@@ -116,19 +317,10 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
+ }
- mMessageCompression = (IntegerListPreference) findPreference(Constants.pref.DEFAULT_MESSAGE_COMPRESSION);
- valueIds = new int[] { Id.choice.compression.none, Id.choice.compression.zip,
- Id.choice.compression.zlib, Id.choice.compression.bzip2, };
- entries = new String[] {
- getString(R.string.choice_none) + " (" + getString(R.string.compression_fast) + ")",
- "ZIP (" + getString(R.string.compression_fast) + ")",
- "ZLIB (" + getString(R.string.compression_fast) + ")",
- "BZIP2 (" + getString(R.string.compression_very_slow) + ")", };
- values = new String[valueIds.length];
- for (int i = 0; i < values.length; ++i) {
- values[i] = "" + valueIds[i];
- }
+ private static void initializeMessageCompression
+ (final IntegerListPreference mMessageCompression, int[] valueIds, String[] entries, String[] values) {
mMessageCompression.setEntries(entries);
mMessageCompression.setEntryValues(values);
mMessageCompression.setValue("" + mPreferences.getDefaultMessageCompression());
@@ -143,8 +335,10 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
+ }
- mFileCompression = (IntegerListPreference) findPreference(Constants.pref.DEFAULT_FILE_COMPRESSION);
+ private static void initializeFileCompression
+ (final IntegerListPreference mFileCompression, String[] entries, String[] values) {
mFileCompression.setEntries(entries);
mFileCompression.setEntryValues(values);
mFileCompression.setValue("" + mPreferences.getDefaultFileCompression());
@@ -157,8 +351,9 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
+ }
- mAsciiArmour = (CheckBoxPreference) findPreference(Constants.pref.DEFAULT_ASCII_ARMOUR);
+ private static void initializeAsciiArmour(final CheckBoxPreference mAsciiArmour) {
mAsciiArmour.setChecked(mPreferences.getDefaultAsciiArmour());
mAsciiArmour.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
@@ -167,8 +362,9 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
+ }
- mForceV3Signatures = (CheckBoxPreference) findPreference(Constants.pref.FORCE_V3_SIGNATURES);
+ private static void initializeForceV3Signatures(final CheckBoxPreference mForceV3Signatures) {
mForceV3Signatures.setChecked(mPreferences.getForceV3Signatures());
mForceV3Signatures
.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@@ -178,43 +374,5 @@ public class PreferencesActivity extends PreferenceActivity {
return false;
}
});
-
- mKeyServerPreference = (PreferenceScreen) findPreference(Constants.pref.KEY_SERVERS);
- String servers[] = mPreferences.getKeyServers();
- mKeyServerPreference.setSummary(getResources().getQuantityString(R.plurals.n_key_servers,
- servers.length, servers.length));
- mKeyServerPreference
- .setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
- public boolean onPreferenceClick(Preference preference) {
- Intent intent = new Intent(PreferencesActivity.this,
- PreferencesKeyServerActivity.class);
- intent.putExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS,
- mPreferences.getKeyServers());
- startActivityForResult(intent, Id.request.key_server_preference);
- return false;
- }
- });
- }
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case Id.request.key_server_preference: {
- if (resultCode == RESULT_CANCELED || data == null) {
- return;
- }
- String servers[] = data
- .getStringArrayExtra(PreferencesKeyServerActivity.EXTRA_KEY_SERVERS);
- mPreferences.setKeyServers(servers);
- mKeyServerPreference.setSummary(getResources().getQuantityString(
- R.plurals.n_key_servers, servers.length, servers.length));
- break;
- }
-
- default: {
- super.onActivityResult(requestCode, resultCode, data);
- break;
- }
- }
}
-}
+} \ No newline at end of file
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java
index b5ac739ae..50fec1ffc 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/PreferencesKeyServerActivity.java
@@ -50,14 +50,14 @@ public class PreferencesKeyServerActivity extends ActionBarActivity implements O
super.onCreate(savedInstanceState);
// Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.btn_okay,
+ ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.btn_okay, R.drawable.ic_action_done,
new View.OnClickListener() {
@Override
public void onClick(View v) {
// ok
okClicked();
}
- }, R.string.btn_do_not_save, new View.OnClickListener() {
+ }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() {
@Override
public void onClick(View v) {
// cancel
@@ -81,11 +81,11 @@ public class PreferencesKeyServerActivity extends ActionBarActivity implements O
Intent intent = getIntent();
String servers[] = intent.getStringArrayExtra(EXTRA_KEY_SERVERS);
if (servers != null) {
- for (int i = 0; i < servers.length; ++i) {
+ for (String serv : servers) {
KeyServerEditor view = (KeyServerEditor) mInflater.inflate(
R.layout.key_server_editor, mEditors, false);
view.setEditorListener(this);
- view.setValue(servers[i]);
+ view.setValue(serv);
mEditors.addView(view);
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java
index 86ae0073f..3c63628f7 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyActivity.java
@@ -46,14 +46,14 @@ public class SelectPublicKeyActivity extends ActionBarActivity {
super.onCreate(savedInstanceState);
// Inflate a "Done"/"Cancel" custom action bar view
- ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.btn_okay,
+ ActionBarHelper.setTwoButtonView(getSupportActionBar(), R.string.btn_okay, R.drawable.ic_action_done,
new View.OnClickListener() {
@Override
public void onClick(View v) {
// ok
okClicked();
}
- }, R.string.btn_do_not_save, new View.OnClickListener() {
+ }, R.string.btn_do_not_save, R.drawable.ic_action_cancel, new View.OnClickListener() {
@Override
public void onClick(View v) {
// cancel
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
index 59b46dd00..d320af451 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectPublicKeyFragment.java
@@ -30,7 +30,7 @@ import org.sufficientlysecure.keychain.provider.KeychainDatabase;
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
import org.sufficientlysecure.keychain.ui.adapter.SelectKeyCursorAdapter;
-import android.app.Activity;
+import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.net.Uri;
@@ -38,17 +38,35 @@ import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
+import android.text.Editable;
+import android.text.TextUtils;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.EditText;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
import android.widget.ListView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
-public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
+public class SelectPublicKeyFragment extends ListFragmentWorkaround implements TextWatcher,
LoaderManager.LoaderCallbacks<Cursor> {
public static final String ARG_PRESELECTED_KEY_IDS = "preselected_key_ids";
- private Activity mActivity;
private SelectKeyCursorAdapter mAdapter;
- private ListView mListView;
-
+ private EditText mSearchView;
private long mSelectedMasterKeyIds[];
+ private String mCurQuery;
+
+ // copied from ListFragment
+ static final int INTERNAL_EMPTY_ID = 0x00ff0001;
+ static final int INTERNAL_PROGRESS_CONTAINER_ID = 0x00ff0002;
+ static final int INTERNAL_LIST_CONTAINER_ID = 0x00ff0003;
+ // added for search view
+ static final int SEARCH_ID = 0x00ff0004;
/**
* Creates new instance of this fragment
@@ -67,27 +85,100 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
mSelectedMasterKeyIds = getArguments().getLongArray(ARG_PRESELECTED_KEY_IDS);
}
/**
+ * Copied from ListFragment and added EditText for search on top of list.
+ * We do not use a custom layout here, because this breaks the progress bar functionality
+ * of ListFragment.
+ *
+ * @param inflater
+ * @param container
+ * @param savedInstanceState
+ * @return
+ */
+ @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));
+
+ // Added for search view: linearLayout, mSearchView
+ LinearLayout linearLayout = new LinearLayout(context);
+ linearLayout.setOrientation(LinearLayout.VERTICAL);
+
+ mSearchView = new EditText(context);
+ mSearchView.setId(SEARCH_ID);
+ mSearchView.setHint(R.string.menu_search);
+ mSearchView.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.ic_action_search), null, null, null);
+
+ linearLayout.addView(mSearchView, new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+
+ ListView lv = new ListView(getActivity());
+ lv.setId(android.R.id.list);
+ lv.setDrawSelectorOnTop(false);
+ linearLayout.addView(lv, new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
+
+ lframe.addView(linearLayout, 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;
+ }
+
+ /**
* Define Adapter and Loader on create of Activity
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
- mActivity = getActivity();
- mListView = getListView();
-
- mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
+ getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
// Give some text to display if there is no data. In a real
// application this would come from a resource.
setEmptyText(getString(R.string.list_empty));
- mAdapter = new SelectKeyCursorAdapter(mActivity, null, 0, mListView, Id.type.public_key);
+ mSearchView.addTextChangedListener(this);
+
+ mAdapter = new SelectKeyCursorAdapter(getActivity(), null, 0, getListView(), Id.type.public_key);
setListAdapter(mAdapter);
@@ -101,16 +192,16 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
/**
* Selects items based on master key ids in list view
- *
+ *
* @param masterKeyIds
*/
private void preselectMasterKeyIds(long[] masterKeyIds) {
if (masterKeyIds != null) {
- for (int i = 0; i < mListView.getCount(); ++i) {
+ for (int i = 0; i < getListView().getCount(); ++i) {
long keyId = mAdapter.getMasterKeyId(i);
- for (int j = 0; j < masterKeyIds.length; ++j) {
- if (keyId == masterKeyIds[j]) {
- mListView.setItemChecked(i, true);
+ for (long masterKeyId : masterKeyIds) {
+ if (keyId == masterKeyId) {
+ getListView().setItemChecked(i, true);
break;
}
}
@@ -120,15 +211,15 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
/**
* Returns all selected master key ids
- *
+ *
* @return
*/
public long[] getSelectedMasterKeyIds() {
// mListView.getCheckedItemIds() would give the row ids of the KeyRings not the master key
// ids!
Vector<Long> vector = new Vector<Long>();
- for (int i = 0; i < mListView.getCount(); ++i) {
- if (mListView.isItemChecked(i)) {
+ for (int i = 0; i < getListView().getCount(); ++i) {
+ if (getListView().isItemChecked(i)) {
vector.add(mAdapter.getMasterKeyId(i));
}
}
@@ -144,13 +235,13 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
/**
* Returns all selected user ids
- *
+ *
* @return
*/
public String[] getSelectedUserIds() {
Vector<String> userIds = new Vector<String>();
- for (int i = 0; i < mListView.getCount(); ++i) {
- if (mListView.isItemChecked(i)) {
+ for (int i = 0; i < getListView().getCount(); ++i) {
+ if (getListView().isItemChecked(i)) {
userIds.add((String) mAdapter.getUserId(i));
}
}
@@ -168,7 +259,7 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
// These are the rows that we will retrieve.
long now = new Date().getTime() / 1000;
- String[] projection = new String[] {
+ String[] projection = new String[]{
KeyRings._ID,
KeyRings.MASTER_KEY_ID,
UserIds.USER_ID,
@@ -185,7 +276,7 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
+ Keys.CAN_ENCRYPT + " = '1' AND valid_keys." + Keys.CREATION + " <= '"
+ now + "' AND " + "(valid_keys." + Keys.EXPIRY + " IS NULL OR valid_keys."
+ Keys.EXPIRY + " >= '" + now + "')) AS "
- + SelectKeyCursorAdapter.PROJECTION_ROW_VALID, };
+ + SelectKeyCursorAdapter.PROJECTION_ROW_VALID,};
String inMasterKeyList = null;
if (mSelectedMasterKeyIds != null && mSelectedMasterKeyIds.length > 0) {
@@ -199,37 +290,28 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
inMasterKeyList += ")";
}
- // 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.USER_ID + " ASC";
if (inMasterKeyList != null) {
// sort by selected master keys
orderBy = inMasterKeyList + " DESC, " + orderBy;
}
+ String where = null;
+ String whereArgs[] = null;
+ if (mCurQuery != null) {
+ where = UserIds.USER_ID + " LIKE ?";
+ whereArgs = new String[]{"%" + mCurQuery + "%"};
+ }
// 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, orderBy);
+ return new CursorLoader(getActivity(), baseUri, projection, where, whereArgs, orderBy);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
+ mAdapter.setSearchQuery(mCurQuery);
mAdapter.swapCursor(data);
// The list should now be shown.
@@ -250,4 +332,20 @@ public class SelectPublicKeyFragment extends ListFragmentWorkaround implements
// longer using it.
mAdapter.swapCursor(null);
}
+
+ @Override
+ public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
+
+ }
+
+ @Override
+ public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
+
+ }
+
+ @Override
+ public void afterTextChanged(Editable editable) {
+ mCurQuery = !TextUtils.isEmpty(editable.toString()) ? editable.toString() : null;
+ getLoaderManager().restartLoader(0, null, this);
+ }
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java
index 6bcb84f46..c9129285e 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/SelectSecretKeyLayoutFragment.java
@@ -24,10 +24,13 @@ import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
import org.sufficientlysecure.keychain.provider.ProviderHelper;
+import android.Manifest;
import android.app.Activity;
+import android.app.ActivityOptions;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@@ -40,6 +43,7 @@ public class SelectSecretKeyLayoutFragment extends Fragment {
private TextView mKeyUserId;
private TextView mKeyUserIdRest;
+ private TextView mKeyMasterKeyIdHex;
private BootstrapButton mSelectKeyButton;
private Boolean mFilterCertify;
@@ -61,26 +65,52 @@ public class SelectSecretKeyLayoutFragment extends Fragment {
public void selectKey(long secretKeyId) {
if (secretKeyId == Id.key.none) {
- mKeyUserId.setText(R.string.api_settings_no_key);
+ mKeyMasterKeyIdHex.setText(R.string.api_settings_no_key);
mKeyUserIdRest.setText("");
+ mKeyUserId.setVisibility(View.GONE);
+ mKeyUserIdRest.setVisibility(View.GONE);
+
} else {
- String uid = getResources().getString(R.string.user_id_no_name);
- String uidExtra = "";
PGPSecretKeyRing keyRing = ProviderHelper.getPGPSecretKeyRingByMasterKeyId(
getActivity(), secretKeyId);
if (keyRing != null) {
PGPSecretKey key = PgpKeyHelper.getMasterKey(keyRing);
+ String masterkeyIdHex = PgpKeyHelper.convertKeyIdToHex(secretKeyId);
+
if (key != null) {
String userId = PgpKeyHelper.getMainUserIdSafe(getActivity(), key);
- String chunks[] = userId.split(" <", 2);
- uid = chunks[0];
- if (chunks.length > 1) {
- uidExtra = "<" + chunks[1];
+
+ String[] userIdSplit = PgpKeyHelper.splitUserId(userId);
+ String userName, userEmail;
+
+ if (userIdSplit[0] != null) {
+ userName = userIdSplit[0];
+ } else {
+ userName = getActivity().getResources().getString(R.string.user_id_no_name);
}
+
+ if (userIdSplit[1] != null) {
+ userEmail = userIdSplit[1];
+ } else {
+ userEmail = getActivity().getResources().getString(R.string.error_user_id_no_email);
+ }
+
+ mKeyMasterKeyIdHex.setText(masterkeyIdHex);
+ mKeyUserId.setText(userName);
+ mKeyUserIdRest.setText(userEmail);
+ mKeyUserId.setVisibility(View.VISIBLE);
+ mKeyUserIdRest.setVisibility(View.VISIBLE);
+ } else {
+ mKeyMasterKeyIdHex.setText(getActivity().getResources().getString(R.string.no_key));
+ mKeyUserId.setVisibility(View.GONE);
+ mKeyUserIdRest.setVisibility(View.GONE);
}
+ } else {
+ mKeyMasterKeyIdHex.setText(getActivity().getResources().getString(R.string.no_keys_added_or_updated) + " for master id: " + secretKeyId);
+ mKeyUserId.setVisibility(View.GONE);
+ mKeyUserIdRest.setVisibility(View.GONE);
}
- mKeyUserId.setText(uid);
- mKeyUserIdRest.setText(uidExtra);
+
}
}
@@ -98,6 +128,7 @@ public class SelectSecretKeyLayoutFragment extends Fragment {
mKeyUserId = (TextView) view.findViewById(R.id.select_secret_key_user_id);
mKeyUserIdRest = (TextView) view.findViewById(R.id.select_secret_key_user_id_rest);
+ mKeyMasterKeyIdHex = (TextView) view.findViewById(R.id.select_secret_key_master_key_hex);
mSelectKeyButton = (BootstrapButton) view
.findViewById(R.id.select_secret_key_select_key_button);
mFilterCertify = false;
@@ -117,30 +148,31 @@ public class SelectSecretKeyLayoutFragment extends Fragment {
startActivityForResult(intent, REQUEST_CODE_SELECT_KEY);
}
+ // Select Secret Key Activity delivers the intent which was sent by it using interface to Select
+ // Secret Key Fragment.Intent contains Master Key Id, User Email, User Name, Master Key Id Hex.
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode & 0xFFFF) {
- case REQUEST_CODE_SELECT_KEY: {
- long secretKeyId;
- if (resultCode == Activity.RESULT_OK) {
- Bundle bundle = data.getExtras();
- secretKeyId = bundle.getLong(SelectSecretKeyActivity.RESULT_EXTRA_MASTER_KEY_ID);
-
- selectKey(secretKeyId);
-
- // remove displayed errors
- mKeyUserId.setError(null);
-
- // give value back to callback
- mCallback.onKeySelected(secretKeyId);
+ case REQUEST_CODE_SELECT_KEY: {
+ long secretKeyId;
+ if (resultCode == Activity.RESULT_OK) {
+ Bundle bundle = data.getExtras();
+ secretKeyId = bundle.getLong(SelectSecretKeyActivity.RESULT_EXTRA_MASTER_KEY_ID);
+ selectKey(secretKeyId);
+
+ // remove displayed errors
+ mKeyUserId.setError(null);
+
+ // give value back to callback
+ mCallback.onKeySelected(secretKeyId);
+ }
+ break;
}
- break;
- }
- default:
- super.onActivityResult(requestCode, resultCode, data);
+ default:
+ super.onActivityResult(requestCode, resultCode, data);
- break;
+ break;
}
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
index 550d3047d..6f0aaa0f0 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/UploadKeyActivity.java
@@ -102,7 +102,7 @@ public class UploadKeyActivity extends ActionBarActivity {
// Message is received after uploading is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(this,
- R.string.progress_exporting, ProgressDialog.STYLE_HORIZONTAL) {
+ getString(R.string.progress_exporting), ProgressDialog.STYLE_HORIZONTAL) {
public void handleMessage(Message message) {
// handle messages by standard ApgHandler first
super.handleMessage(message);
@@ -113,7 +113,7 @@ public class UploadKeyActivity extends ActionBarActivity {
Toast.LENGTH_SHORT).show();
finish();
}
- };
+ }
};
// Create a new Messenger for the communication back
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
index 055203c0f..01a2740b1 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java
@@ -93,12 +93,12 @@ public class ViewKeyActivity extends ActionBarActivity {
Bundle mainBundle = new Bundle();
mainBundle.putParcelable(ViewKeyMainFragment.ARG_DATA_URI, mDataUri);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.key_view_tab_main)),
- ViewKeyMainFragment.class, mainBundle, (selectedTab == 0 ? true : false));
+ ViewKeyMainFragment.class, mainBundle, (selectedTab == 0));
Bundle certBundle = new Bundle();
certBundle.putLong(ViewKeyCertsFragment.ARG_KEYRING_ROW_ID, rowId);
mTabsAdapter.addTab(actionBar.newTab().setText(getString(R.string.key_view_tab_certs)),
- ViewKeyCertsFragment.class, certBundle, (selectedTab == 1 ? true : false));
+ ViewKeyCertsFragment.class, certBundle, (selectedTab == 1));
}
@Override
@@ -123,8 +123,8 @@ public class ViewKeyActivity extends ActionBarActivity {
uploadToKeyserver(mDataUri);
return true;
case R.id.menu_key_view_export_file:
- mExportHelper.showExportKeysDialog(mDataUri, Id.type.public_key, Constants.path.APP_DIR
- + "/pubexport.asc");
+ long[] ids = new long[]{Long.valueOf(mDataUri.getLastPathSegment())};
+ mExportHelper.showExportKeysDialog(ids, Id.type.public_key, Constants.path.APP_DIR_FILE_PUB);
return true;
case R.id.menu_key_view_share_default_fingerprint:
shareKey(mDataUri, true);
@@ -159,7 +159,7 @@ public class ViewKeyActivity extends ActionBarActivity {
}
private void updateFromKeyserver(Uri dataUri) {
- long updateKeyId = ProviderHelper.getMasterKeyId(ViewKeyActivity.this, mDataUri);
+ long updateKeyId = ProviderHelper.getMasterKeyId(ViewKeyActivity.this, dataUri);
if (updateKeyId == 0) {
Log.e(Constants.TAG, "this shouldn't happen. KeyId == 0!");
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
index 00ca0d1f4..c898a06ea 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyMainFragment.java
@@ -26,7 +26,10 @@ import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
import android.text.format.DateFormat;
+import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -273,7 +276,7 @@ public class ViewKeyMainFragment extends Fragment implements
// get key id from MASTER_KEY_ID
long keyId = data.getLong(KEYS_INDEX_KEY_ID);
- String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId);
+ String keyIdStr = PgpKeyHelper.convertKeyIdToHex(keyId);
mKeyId.setText(keyIdStr);
// get creation date from CREATION
@@ -306,9 +309,8 @@ public class ViewKeyMainFragment extends Fragment implements
fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), mDataUri);
}
String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true);
- fingerprint = fingerprint.replace(" ", "\n");
- mFingerprint.setText(fingerprint);
+ mFingerprint.setText(colorizeFingerprint(fingerprint));
}
mKeysAdapter.swapCursor(data);
@@ -319,6 +321,25 @@ public class ViewKeyMainFragment extends Fragment implements
}
}
+ private SpannableStringBuilder colorizeFingerprint(String fingerprint) {
+ SpannableStringBuilder sb = new SpannableStringBuilder(fingerprint);
+ ForegroundColorSpan fcs = new ForegroundColorSpan(Color.BLACK);
+
+ // for each 4 characters of the fingerprint + 1 space
+ for (int i = 0; i < fingerprint.length(); i += 5) {
+ int minFingLength = Math.min(i + 4, fingerprint.length());
+ String fourChars = fingerprint.substring(i, minFingLength);
+
+ // Create a foreground color by converting the 4 fingerprint chars to an int hashcode
+ // and then converting that int to hex to use as a color
+ fcs = new ForegroundColorSpan(
+ Color.parseColor(String.format("#%06X", (0xFFFFFF & fourChars.hashCode()))));
+ sb.setSpan(fcs, i, minFingLength, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+ }
+
+ return sb;
+ }
+
/**
* 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.
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/HighlightQueryCursorAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/HighlightQueryCursorAdapter.java
new file mode 100644
index 000000000..fd7a2dc30
--- /dev/null
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/HighlightQueryCursorAdapter.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.sufficientlysecure.keychain.ui.adapter;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.support.v4.widget.CursorAdapter;
+import android.text.Spannable;
+import android.text.style.ForegroundColorSpan;
+
+import org.sufficientlysecure.keychain.R;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public abstract class HighlightQueryCursorAdapter extends CursorAdapter {
+
+ private String mCurQuery;
+
+ public HighlightQueryCursorAdapter(Context context, Cursor c, int flags) {
+ super(context, c, flags);
+ mCurQuery = null;
+ }
+
+ public void setSearchQuery(String searchQuery) {
+ mCurQuery = searchQuery;
+ }
+
+ public String getSearchQuery() {
+ return mCurQuery;
+ }
+
+ protected Spannable highlightSearchQuery(String text) {
+ Spannable highlight = Spannable.Factory.getInstance().newSpannable(text);
+
+ if (mCurQuery != null) {
+ Pattern pattern = Pattern.compile("(?i)" + mCurQuery);
+ Matcher matcher = pattern.matcher(text);
+ if (matcher.find()) {
+ highlight.setSpan(
+ new ForegroundColorSpan(mContext.getResources().getColor(R.color.emphasis)),
+ matcher.start(),
+ matcher.end(),
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+ return highlight;
+ } else {
+ return highlight;
+ }
+ }
+}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
index 52186b662..4f7623bce 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java
@@ -42,7 +42,15 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
protected Activity mActivity;
protected List<ImportKeysListEntry> data;
+ static class ViewHolder{
+ private TextView mainUserId;
+ private TextView mainUserIdRest;
+ private TextView keyId;
+ private TextView fingerprint;
+ private TextView algorithm;
+ private TextView status;
+ }
public ImportKeysAdapter(Activity activity) {
super(activity, -1);
mActivity = activity;
@@ -86,16 +94,21 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
public View getView(int position, View convertView, ViewGroup parent) {
ImportKeysListEntry entry = data.get(position);
-
- View view = mInflater.inflate(R.layout.import_keys_list_entry, null);
-
- TextView mainUserId = (TextView) view.findViewById(R.id.mainUserId);
- TextView mainUserIdRest = (TextView) view.findViewById(R.id.mainUserIdRest);
- TextView keyId = (TextView) view.findViewById(R.id.keyId);
- TextView fingerprint = (TextView) view.findViewById(R.id.fingerprint);
- TextView algorithm = (TextView) view.findViewById(R.id.algorithm);
- TextView status = (TextView) view.findViewById(R.id.status);
-
+ ViewHolder holder;
+ if(convertView == null) {
+ holder = new ViewHolder();
+ convertView = mInflater.inflate(R.layout.import_keys_list_entry, null);
+ holder.mainUserId = (TextView) convertView.findViewById(R.id.mainUserId);
+ holder.mainUserIdRest = (TextView) convertView.findViewById(R.id.mainUserIdRest);
+ holder.keyId = (TextView) convertView.findViewById(R.id.keyId);
+ holder.fingerprint = (TextView) convertView.findViewById(R.id.fingerprint);
+ holder.algorithm = (TextView) convertView.findViewById(R.id.algorithm);
+ holder.status = (TextView) convertView.findViewById(R.id.status);
+ convertView.setTag(holder);
+ }
+ else{
+ holder = (ViewHolder)convertView.getTag();
+ }
// main user id
String userId = entry.userIds.get(0);
String[] userIdSplit = PgpKeyHelper.splitUserId(userId);
@@ -105,39 +118,39 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
// show red user id if it is a secret key
if (entry.secretKey) {
userIdSplit[0] = mActivity.getString(R.string.secret_key) + " " + userIdSplit[0];
- mainUserId.setTextColor(Color.RED);
+ holder.mainUserId.setTextColor(Color.RED);
}
- mainUserId.setText(userIdSplit[0]);
+ holder.mainUserId.setText(userIdSplit[0]);
} else {
- mainUserId.setText(R.string.user_id_no_name);
+ holder.mainUserId.setText(R.string.user_id_no_name);
}
// email
if (userIdSplit[1] != null) {
- mainUserIdRest.setText(userIdSplit[1]);
- mainUserIdRest.setVisibility(View.VISIBLE);
+ holder.mainUserIdRest.setText(userIdSplit[1]);
+ holder.mainUserIdRest.setVisibility(View.VISIBLE);
} else {
- mainUserIdRest.setVisibility(View.GONE);
+ holder.mainUserIdRest.setVisibility(View.GONE);
}
- keyId.setText(entry.hexKeyId);
+ holder.keyId.setText(entry.hexKeyId);
if (entry.fingerPrint != null) {
- fingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrint);
- fingerprint.setVisibility(View.VISIBLE);
+ holder.fingerprint.setText(mActivity.getString(R.string.fingerprint) + " " + entry.fingerPrint);
+ holder.fingerprint.setVisibility(View.VISIBLE);
} else {
- fingerprint.setVisibility(View.GONE);
+ holder.fingerprint.setVisibility(View.GONE);
}
- algorithm.setText("" + entry.bitStrength + "/" + entry.algorithm);
+ holder.algorithm.setText("" + entry.bitStrength + "/" + entry.algorithm);
if (entry.revoked) {
- status.setText(R.string.revoked);
+ holder.status.setText(R.string.revoked);
} else {
- status.setVisibility(View.GONE);
+ holder.status.setVisibility(View.GONE);
}
- LinearLayout ll = (LinearLayout) view.findViewById(R.id.list);
+ LinearLayout ll = (LinearLayout) convertView.findViewById(R.id.list);
if (entry.userIds.size() == 1) {
ll.setVisibility(View.GONE);
} else {
@@ -162,10 +175,10 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
}
}
- CheckBox cBox = (CheckBox) view.findViewById(R.id.selected);
+ CheckBox cBox = (CheckBox) convertView.findViewById(R.id.selected);
cBox.setChecked(entry.isSelected());
- return view;
+ return convertView;
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java
index 4a7a9c93a..a52e9b447 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListEntry.java
@@ -125,7 +125,10 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
* Constructor for later querying from keyserver
*/
public ImportKeysListEntry() {
+ // keys from keyserver are always public keys
secretKey = false;
+ // do not select by default
+ selected = false;
userIds = new ArrayList<String>();
}
@@ -167,7 +170,7 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
this.revoked = pgpKeyRing.getPublicKey().isRevoked();
this.fingerPrint = PgpKeyHelper.convertFingerprintToHex(pgpKeyRing.getPublicKey()
.getFingerprint(), true);
- this.hexKeyId = "0x" + PgpKeyHelper.convertKeyIdToHex(keyId);
+ this.hexKeyId = PgpKeyHelper.convertKeyIdToHex(keyId);
this.bitStrength = pgpKeyRing.getPublicKey().getBitStrength();
int algorithm = pgpKeyRing.getPublicKey().getAlgorithm();
if (algorithm == PGPPublicKey.RSA_ENCRYPT || algorithm == PGPPublicKey.RSA_GENERAL
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
index 29e418db7..3eca99f15 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java
@@ -20,7 +20,6 @@ package org.sufficientlysecure.keychain.ui.adapter;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.List;
import org.spongycastle.openpgp.PGPKeyRing;
import org.spongycastle.openpgp.PGPObjectFactory;
@@ -34,6 +33,21 @@ import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
public class ImportKeysListLoader extends AsyncTaskLoader<AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>> {
+
+ public static class FileHasNoContent extends Exception {
+
+ }
+
+ public static class NonPgpPart extends Exception {
+ private int count;
+ public NonPgpPart(int count) {
+ this.count = count;
+ }
+ public int getCount() {
+ return count;
+ }
+ }
+
Context mContext;
InputData mInputData;
@@ -88,21 +102,26 @@ public class ImportKeysListLoader extends AsyncTaskLoader<AsyncTaskResultWrapper
/**
* Reads all PGPKeyRing objects from input
*
- * @param keyringBytes
+ * @param inputData
* @return
*/
private void generateListOfKeyrings(InputData inputData) {
+
+ boolean isEmpty = true;
+ int nonPgpCounter = 0;
+
PositionAwareInputStream progressIn = new PositionAwareInputStream(
inputData.getInputStream());
// need to have access to the bufferedInput, so we can reuse it for the possible
// PGPObject chunks after the first one, e.g. files with several consecutive ASCII
- // armour blocks
+ // armor blocks
BufferedInputStream bufferedInput = new BufferedInputStream(progressIn);
try {
// read all available blocks... (asc files can contain many blocks with BEGIN END)
while (bufferedInput.available() > 0) {
+ isEmpty = false;
InputStream in = PGPUtil.getDecoderStream(bufferedInput);
PGPObjectFactory objectFactory = new PGPObjectFactory(in);
@@ -116,11 +135,25 @@ public class ImportKeysListLoader extends AsyncTaskLoader<AsyncTaskResultWrapper
addToData(newKeyring);
} else {
Log.e(Constants.TAG, "Object not recognized as PGPKeyRing!");
+ nonPgpCounter++;
}
}
}
} catch (Exception e) {
Log.e(Constants.TAG, "Exception on parsing key file!", e);
+ entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>(data, e);
+ nonPgpCounter = 0;
+ }
+
+ if(isEmpty) {
+ Log.e(Constants.TAG, "File has no content!", new FileHasNoContent());
+ entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>
+ (data, new FileHasNoContent());
+ }
+
+ if(nonPgpCounter > 0) {
+ entryListWrapper = new AsyncTaskResultWrapper<ArrayList<ImportKeysListEntry>>
+ (data, new NonPgpPart(nonPgpCounter));
}
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
index d44dd5890..6d67a0e65 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SelectKeyCursorAdapter.java
@@ -25,7 +25,6 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.UserIds;
import android.content.Context;
import android.database.Cursor;
-import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -33,7 +32,9 @@ import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
-public class SelectKeyCursorAdapter extends CursorAdapter {
+
+
+public class SelectKeyCursorAdapter extends HighlightQueryCursorAdapter {
protected int mKeyType;
@@ -55,7 +56,6 @@ public class SelectKeyCursorAdapter extends CursorAdapter {
mInflater = LayoutInflater.from(context);
mListView = listView;
mKeyType = keyType;
-
initIndex(c);
}
@@ -104,12 +104,12 @@ public class SelectKeyCursorAdapter extends CursorAdapter {
String[] userIdSplit = PgpKeyHelper.splitUserId(userId);
if (userIdSplit[0] != null) {
- mainUserId.setText(userIdSplit[0]);
+ mainUserId.setText(highlightSearchQuery(userIdSplit[0]));
} else {
mainUserId.setText(R.string.user_id_no_name);
}
if (userIdSplit[1] != null) {
- mainUserIdRest.setText(userIdSplit[1]);
+ mainUserIdRest.setText(highlightSearchQuery(userIdSplit[1]));
} else {
mainUserIdRest.setText("");
}
@@ -164,5 +164,4 @@ public class SelectKeyCursorAdapter extends CursorAdapter {
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return mInflater.inflate(R.layout.select_key_item, null);
}
-
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java
index 54c7eb60e..046a98883 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyKeysAdapter.java
@@ -83,7 +83,7 @@ public class ViewKeyKeysAdapter extends CursorAdapter {
ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey);
ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey);
- String keyIdStr = "0x" + PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexKeyId));
+ String keyIdStr = PgpKeyHelper.convertKeyIdToHex(cursor.getLong(mIndexKeyId));
String algorithmStr = PgpKeyHelper.getAlgorithmInfo(cursor.getInt(mIndexAlgorithm),
cursor.getInt(mIndexKeySize));
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java
index 98b677511..a47601c9b 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/CreateKeyDialogFragment.java
@@ -32,6 +32,7 @@ import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.util.Choice;
+import java.util.ArrayList;
import java.util.Vector;
public class CreateKeyDialogFragment extends DialogFragment {
@@ -78,7 +79,7 @@ public class CreateKeyDialogFragment extends DialogFragment {
boolean wouldBeMasterKey = (childCount == 0);
final Spinner algorithm = (Spinner) view.findViewById(R.id.create_key_algorithm);
- Vector<Choice> choices = new Vector<Choice>();
+ ArrayList<Choice> choices = new ArrayList<Choice>();
choices.add(new Choice(Id.choice.algorithm.dsa, getResources().getString(
R.string.dsa)));
if (!wouldBeMasterKey) {
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
index cd8bc79a9..162bf32fd 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/DeleteFileDialogFragment.java
@@ -67,7 +67,7 @@ public class DeleteFileDialogFragment extends DialogFragment {
alert.setMessage(this.getString(R.string.file_delete_confirmation, deleteFile));
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-
+
@Override
public void onClick(DialogInterface dialog, int id) {
dismiss();
@@ -83,7 +83,10 @@ public class DeleteFileDialogFragment extends DialogFragment {
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
ProgressDialogFragment deletingDialog = ProgressDialogFragment.newInstance(
- R.string.progress_deleting_securely, ProgressDialog.STYLE_HORIZONTAL, false, null);
+ getString(R.string.progress_deleting_securely),
+ ProgressDialog.STYLE_HORIZONTAL,
+ false,
+ null);
// Message is received after deleting is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(activity, deletingDialog) {
@@ -95,7 +98,7 @@ public class DeleteFileDialogFragment extends DialogFragment {
Toast.makeText(activity, R.string.file_delete_successful,
Toast.LENGTH_SHORT).show();
}
- };
+ }
};
// Create a new Messenger for the communication back
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java
index 39ce63b5f..2a3a7508d 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/FileDialogFragment.java
@@ -33,7 +33,6 @@ import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.support.v4.app.DialogFragment;
-import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
index e88271240..afa05cc91 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/PassphraseDialogFragment.java
@@ -153,17 +153,17 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
dismiss();
long curKeyIndex = 1;
boolean keyOK = true;
- String passPhrase = mPassphraseEditText.getText().toString();
+ String passphrase = mPassphraseEditText.getText().toString();
long keyId;
PGPSecretKey clickSecretKey = secretKey;
if (clickSecretKey != null) {
- while (keyOK == true) {
+ while (keyOK) {
if (clickSecretKey != null) { // check again for loop
try {
PBESecretKeyDecryptor keyDecryptor = new JcePBESecretKeyDecryptorBuilder()
.setProvider(Constants.BOUNCY_CASTLE_PROVIDER_NAME).build(
- passPhrase.toCharArray());
+ passphrase.toCharArray());
PGPPrivateKey testKey = clickSecretKey
.extractPrivateKey(keyDecryptor);
if (testKey == null) {
@@ -206,10 +206,10 @@ public class PassphraseDialogFragment extends DialogFragment implements OnEditor
// cache the new passphrase
Log.d(Constants.TAG, "Everything okay! Caching entered passphrase");
- PassphraseCacheService.addCachedPassphrase(activity, keyId, passPhrase);
- if (keyOK == false && clickSecretKey.getKeyID() != keyId) {
+ PassphraseCacheService.addCachedPassphrase(activity, keyId, passphrase);
+ if ( !keyOK && clickSecretKey.getKeyID() != keyId) {
PassphraseCacheService.addCachedPassphrase(activity, clickSecretKey.getKeyID(),
- passPhrase);
+ passphrase);
}
sendMessageToHandler(MESSAGE_OKAY);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java
index 6c62d14e0..b7a1882ef 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ProgressDialogFragment.java
@@ -30,7 +30,7 @@ import android.view.KeyEvent;
import org.sufficientlysecure.keychain.R;
public class ProgressDialogFragment extends DialogFragment {
- private static final String ARG_MESSAGE_ID = "message_id";
+ private static final String ARG_MESSAGE = "message";
private static final String ARG_STYLE = "style";
private static final String ARG_CANCELABLE = "cancelable";
@@ -39,16 +39,16 @@ public class ProgressDialogFragment extends DialogFragment {
/**
* Creates new instance of this fragment
*
- * @param messageId
+ * @param message
* @param style
* @param cancelable
* @return
*/
- public static ProgressDialogFragment newInstance(int messageId, int style, boolean cancelable,
+ public static ProgressDialogFragment newInstance(String message, int style, boolean cancelable,
OnCancelListener onCancelListener) {
ProgressDialogFragment frag = new ProgressDialogFragment();
Bundle args = new Bundle();
- args.putInt(ARG_MESSAGE_ID, messageId);
+ args.putString(ARG_MESSAGE, message);
args.putInt(ARG_STYLE, style);
args.putBoolean(ARG_CANCELABLE, cancelable);
@@ -117,22 +117,22 @@ public class ProgressDialogFragment extends DialogFragment {
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
- int messageId = getArguments().getInt(ARG_MESSAGE_ID);
+ String message = getArguments().getString(ARG_MESSAGE);
int style = getArguments().getInt(ARG_STYLE);
boolean cancelable = getArguments().getBoolean(ARG_CANCELABLE);
- dialog.setMessage(getString(messageId));
+ dialog.setMessage(message);
dialog.setProgressStyle(style);
if (cancelable) {
dialog.setButton(DialogInterface.BUTTON_NEGATIVE,
activity.getString(R.string.progress_cancel),
new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.cancel();
- }
- });
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.cancel();
+ }
+ });
}
// Disable the back button
@@ -140,7 +140,6 @@ public class ProgressDialogFragment extends DialogFragment {
@Override
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
-
if (keyCode == KeyEvent.KEYCODE_BACK) {
return true;
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
index 50e72dfba..e406547b3 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/SetPassphraseDialogFragment.java
@@ -101,9 +101,9 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
public void onClick(DialogInterface dialog, int id) {
dismiss();
- String passPhrase1 = mPassphraseEditText.getText().toString();
- String passPhrase2 = mPassphraseAgainEditText.getText().toString();
- if (!passPhrase1.equals(passPhrase2)) {
+ String passphrase1 = mPassphraseEditText.getText().toString();
+ String passphrase2 = mPassphraseAgainEditText.getText().toString();
+ if (!passphrase1.equals(passphrase2)) {
Toast.makeText(
activity,
getString(R.string.error_message,
@@ -112,7 +112,7 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
return;
}
- if (passPhrase1.equals("")) {
+ if (passphrase1.equals("")) {
Toast.makeText(
activity,
getString(R.string.error_message,
@@ -123,7 +123,7 @@ public class SetPassphraseDialogFragment extends DialogFragment implements OnEdi
// return resulting data back to activity
Bundle data = new Bundle();
- data.putString(MESSAGE_NEW_PASSPHRASE, passPhrase1);
+ data.putString(MESSAGE_NEW_PASSPHRASE, passphrase1);
sendMessageToHandler(MESSAGE_OKAY, data);
}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java
index 03e09cdcb..b850638a6 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/ShareNfcDialogFragment.java
@@ -53,7 +53,6 @@ public class ShareNfcDialogFragment extends DialogFragment {
AlertDialog.Builder alert = new AlertDialog.Builder(activity);
- alert.setIcon(android.R.drawable.ic_dialog_info);
alert.setTitle(R.string.share_nfc_dialog);
alert.setCancelable(true);
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java
index 6c265057e..65461cb4f 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeyEditor.java
@@ -34,6 +34,7 @@ import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
+import android.text.format.DateUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
@@ -58,6 +59,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
Spinner mUsage;
TextView mCreationDate;
BootstrapButton mExpiryDateButton;
+ GregorianCalendar mCreatedDate;
GregorianCalendar mExpiryDate;
private int mDatePickerResultCount = 0;
@@ -113,8 +115,12 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
if (date == null) {
date = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
}
-
- DatePickerDialog dialog = new DatePickerDialog(getContext(),
+ /*
+ * Using custom DatePickerDialog which overrides the setTitle because
+ * the DatePickerDialog title is buggy (unix warparound bug).
+ * See: https://code.google.com/p/android/issues/detail?id=49066
+ */
+ DatePickerDialog dialog = new ExpiryDatePickerDialog(getContext(),
mExpiryDateSetListener, date.get(Calendar.YEAR), date.get(Calendar.MONTH),
date.get(Calendar.DAY_OF_MONTH));
mDatePickerResultCount = 0;
@@ -129,6 +135,21 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
}
}
});
+
+ // setCalendarViewShown() is supported from API 11 onwards.
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB)
+ // Hide calendarView in tablets because of the unix warparound bug.
+ dialog.getDatePicker().setCalendarViewShown(false);
+
+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
+ if ( dialog != null && mCreatedDate != null ) {
+ dialog.getDatePicker().setMinDate(mCreatedDate.getTime().getTime()+ DateUtils.DAY_IN_MILLIS);
+ } else {
+ //When created date isn't available
+ dialog.getDatePicker().setMinDate(date.getTime().getTime()+ DateUtils.DAY_IN_MILLIS);
+ }
+ }
+
dialog.show();
}
});
@@ -153,9 +174,8 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
}
mAlgorithm.setText(PgpKeyHelper.getAlgorithmInfo(key));
- String keyId1Str = PgpKeyHelper.convertKeyIdToHex(key.getKeyID());
- String keyId2Str = PgpKeyHelper.convertKeyIdToHex(key.getKeyID() >> 32);
- mKeyId.setText(keyId1Str + " " + keyId2Str);
+ String keyIdStr = PgpKeyHelper.convertKeyIdToHex(key.getKeyID());
+ mKeyId.setText(keyIdStr);
Vector<Choice> choices = new Vector<Choice>();
boolean isElGamalKey = (key.getPublicKey().getAlgorithm() == PGPPublicKey.ELGAMAL_ENCRYPT);
@@ -205,7 +225,7 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
cal.setTime(PgpKeyHelper.getCreationDate(key));
- mCreationDate.setText(DateFormat.getDateInstance().format(cal.getTime()));
+ setCreatedDate(cal);
cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
Date expiryDate = PgpKeyHelper.getExpiryDate(key);
if (expiryDate == null) {
@@ -235,6 +255,15 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
mEditorListener = listener;
}
+ private void setCreatedDate(GregorianCalendar date) {
+ mCreatedDate = date;
+ if (date == null) {
+ mCreationDate.setText(getContext().getString(R.string.none));
+ } else {
+ mCreationDate.setText(DateFormat.getDateInstance().format(date.getTime()));
+ }
+ }
+
private void setExpiryDate(GregorianCalendar date) {
mExpiryDate = date;
if (date == null) {
@@ -253,3 +282,14 @@ public class KeyEditor extends LinearLayout implements Editor, OnClickListener {
}
}
+
+class ExpiryDatePickerDialog extends DatePickerDialog {
+
+ public ExpiryDatePickerDialog(Context context, OnDateSetListener callBack, int year, int monthOfYear, int dayOfMonth) {
+ super(context, callBack, year, monthOfYear, dayOfMonth);
+ }
+ //Set permanent title.
+ public void setTitle(CharSequence title) {
+ super.setTitle(getContext().getString(R.string.expiry_date_dialog_title));
+ }
+}
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java
index a95d80a4e..0acfe13bc 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/SectionView.java
@@ -80,19 +80,19 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
public void setType(int type) {
mType = type;
switch (type) {
- case Id.type.user_id: {
- mTitle.setText(R.string.section_user_ids);
- break;
- }
+ case Id.type.user_id: {
+ mTitle.setText(R.string.section_user_ids);
+ break;
+ }
- case Id.type.key: {
- mTitle.setText(R.string.section_keys);
- break;
- }
+ case Id.type.key: {
+ mTitle.setText(R.string.section_keys);
+ break;
+ }
- default: {
- break;
- }
+ default: {
+ break;
+ }
}
}
@@ -103,7 +103,9 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
}
}
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ */
@Override
protected void onFinishInflate() {
mInflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
@@ -121,7 +123,9 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
super.onFinishInflate();
}
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ */
public void onDeleted(Editor editor) {
this.updateEditorsVisible();
}
@@ -131,38 +135,40 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
mEditors.setVisibility(hasChildren ? View.VISIBLE : View.GONE);
}
- /** {@inheritDoc} */
+ /**
+ * {@inheritDoc}
+ */
public void onClick(View v) {
if (canEdit) {
switch (mType) {
- case Id.type.user_id: {
- UserIdEditor view = (UserIdEditor) mInflater.inflate(
- R.layout.edit_key_user_id_item, mEditors, false);
- view.setEditorListener(this);
- if (mEditors.getChildCount() == 0) {
- view.setIsMainUserId(true);
+ case Id.type.user_id: {
+ UserIdEditor view = (UserIdEditor) mInflater.inflate(
+ R.layout.edit_key_user_id_item, mEditors, false);
+ view.setEditorListener(this);
+ if (mEditors.getChildCount() == 0) {
+ view.setIsMainUserId(true);
+ }
+ mEditors.addView(view);
+ break;
}
- mEditors.addView(view);
- break;
- }
- case Id.type.key: {
- CreateKeyDialogFragment mCreateKeyDialogFragment = CreateKeyDialogFragment.newInstance(mEditors.getChildCount());
- mCreateKeyDialogFragment.setOnAlgorithmSelectedListener(new CreateKeyDialogFragment.OnAlgorithmSelectedListener() {
- @Override
- public void onAlgorithmSelected(Choice algorithmChoice, int keySize) {
- mNewKeyAlgorithmChoice = algorithmChoice;
- mNewKeySize = keySize;
- createKey();
- }
- });
- mCreateKeyDialogFragment.show(mActivity.getSupportFragmentManager(), "createKeyDialog");
- break;
- }
+ case Id.type.key: {
+ CreateKeyDialogFragment mCreateKeyDialogFragment = CreateKeyDialogFragment.newInstance(mEditors.getChildCount());
+ mCreateKeyDialogFragment.setOnAlgorithmSelectedListener(new CreateKeyDialogFragment.OnAlgorithmSelectedListener() {
+ @Override
+ public void onAlgorithmSelected(Choice algorithmChoice, int keySize) {
+ mNewKeyAlgorithmChoice = algorithmChoice;
+ mNewKeySize = keySize;
+ createKey();
+ }
+ });
+ mCreateKeyDialogFragment.show(mActivity.getSupportFragmentManager(), "createKeyDialog");
+ break;
+ }
- default: {
- break;
- }
+ default: {
+ break;
+ }
}
this.updateEditorsVisible();
}
@@ -220,31 +226,34 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
Bundle data = new Bundle();
Boolean isMasterKey;
- String passPhrase;
+ String passphrase;
if (mEditors.getChildCount() > 0) {
PGPSecretKey masterKey = ((KeyEditor) mEditors.getChildAt(0)).getValue();
- passPhrase = PassphraseCacheService
+ passphrase = PassphraseCacheService
.getCachedPassphrase(mActivity, masterKey.getKeyID());
isMasterKey = false;
} else {
- passPhrase = "";
+ passphrase = "";
isMasterKey = true;
}
data.putBoolean(KeychainIntentService.GENERATE_KEY_MASTER_KEY, isMasterKey);
- data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passPhrase);
+ data.putString(KeychainIntentService.GENERATE_KEY_SYMMETRIC_PASSPHRASE, passphrase);
data.putInt(KeychainIntentService.GENERATE_KEY_ALGORITHM, mNewKeyAlgorithmChoice.getId());
data.putInt(KeychainIntentService.GENERATE_KEY_KEY_SIZE, mNewKeySize);
intent.putExtra(KeychainIntentService.EXTRA_DATA, data);
// show progress dialog
- mGeneratingDialog = ProgressDialogFragment.newInstance(R.string.progress_generating,
- ProgressDialog.STYLE_SPINNER, true, new DialogInterface.OnCancelListener() {
- @Override
- public void onCancel(DialogInterface dialog) {
- mActivity.stopService(intent);
- }
- });
+ mGeneratingDialog = ProgressDialogFragment.newInstance(
+ getResources().getQuantityString(R.plurals.progress_generating, 1),
+ ProgressDialog.STYLE_SPINNER,
+ true,
+ new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ mActivity.stopService(intent);
+ }
+ });
// Message is received after generating is done in ApgService
KeychainIntentServiceHandler saveHandler = new KeychainIntentServiceHandler(mActivity,
@@ -261,7 +270,7 @@ public class SectionView extends LinearLayout implements OnClickListener, Editor
.getByteArray(KeychainIntentService.RESULT_NEW_KEY));
addGeneratedKeyToView(newKey);
}
- };
+ }
};
// Create a new Messenger for the communication back
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java
index 5428b626e..71cd89ae8 100644
--- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java
+++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/UserIdEditor.java
@@ -19,6 +19,7 @@ package org.sufficientlysecure.keychain.ui.widget;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import android.widget.*;
import org.sufficientlysecure.keychain.R;
import android.content.Context;
@@ -26,11 +27,9 @@ import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.RadioButton;
import com.beardedhen.androidbootstrap.BootstrapButton;
+import org.sufficientlysecure.keychain.helper.ContactHelper;
public class UserIdEditor extends LinearLayout implements Editor, OnClickListener {
private EditorListener mEditorListener = null;
@@ -38,7 +37,7 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene
private BootstrapButton mDeleteButton;
private RadioButton mIsMainUserId;
private EditText mName;
- private EditText mEmail;
+ private AutoCompleteTextView mEmail;
private EditText mComment;
// see http://www.regular-expressions.info/email.html
@@ -102,9 +101,17 @@ public class UserIdEditor extends LinearLayout implements Editor, OnClickListene
mIsMainUserId.setOnClickListener(this);
mName = (EditText) findViewById(R.id.name);
- mEmail = (EditText) findViewById(R.id.email);
+ mEmail = (AutoCompleteTextView) findViewById(R.id.email);
mComment = (EditText) findViewById(R.id.comment);
+
+ mEmail.setThreshold(1); // Start working from first character
+ mEmail.setAdapter(
+ new ArrayAdapter<String>
+ (this.getContext(), android.R.layout.simple_dropdown_item_1line,
+ ContactHelper.getMailAccounts(getContext())
+ ));
+
super.onFinishInflate();
}