diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java index ff2a08c8e..68555e696 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/keyimport/ImportKeysListEntry.java @@ -108,11 +108,11 @@ public class ImportKeysListEntry implements Serializable, Parcelable { return super.hashCode(); } - public boolean hasSameKeyAs(Object o) { - if (mFingerprintHex == null || o == null || !(o instanceof ImportKeysListEntry)) { + public boolean hasSameKeyAs(ImportKeysListEntry other) { + if (mFingerprintHex == null || other == null) { return false; } - return mFingerprintHex.equals(((ImportKeysListEntry) o).mFingerprintHex); + return mFingerprintHex.equals(other.mFingerprintHex); } public String getKeyIdHex() { diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java index f828d0922..dce02b105 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewCertActivity.java @@ -28,6 +28,8 @@ import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBarActivity; +import android.text.SpannableString; +import android.text.SpannableStringBuilder; import android.text.format.DateFormat; import android.view.MenuItem; import android.view.View; @@ -119,7 +121,7 @@ public class ViewCertActivity extends ActionBarActivity @Override public void onLoadFinished(Loader loader, Cursor data) { if (data.moveToFirst()) { - String signeeKey = KeyFormattingUtils.convertKeyIdToHex(data.getLong(INDEX_MASTER_KEY_ID)); + SpannableString signeeKey = KeyFormattingUtils.beautifyKeyId(data.getLong(INDEX_MASTER_KEY_ID)); mSigneeKey.setText(signeeKey); String signeeUid = data.getString(INDEX_USER_ID); @@ -129,7 +131,7 @@ public class ViewCertActivity extends ActionBarActivity mCreation.setText(DateFormat.getDateFormat(getApplicationContext()).format(creationDate)); mCertifierKeyId = data.getLong(INDEX_KEY_ID_CERTIFIER); - String certifierKey = KeyFormattingUtils.convertKeyIdToHex(mCertifierKeyId); + SpannableString certifierKey = KeyFormattingUtils.beautifyKeyId(mCertifierKeyId); mCertifierKey.setText(certifierKey); String certifierUid = data.getString(INDEX_SIGNER_UID); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java index fa20bc3bc..2bced3c8f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java @@ -470,8 +470,7 @@ public class ViewKeyActivity extends ActionBarActivity implements // get key id from MASTER_KEY_ID long masterKeyId = data.getLong(INDEX_UNIFIED_MASTER_KEY_ID); - String keyIdStr = KeyFormattingUtils.convertKeyIdToHex(masterKeyId); - getSupportActionBar().setSubtitle(keyIdStr); + getSupportActionBar().setSubtitle(KeyFormattingUtils.beautifyKeyIdWithPrefix(this, masterKeyId)); boolean isRevoked = data.getInt(INDEX_UNIFIED_IS_REVOKED) > 0; boolean isExpired = !data.isNull(INDEX_UNIFIED_EXPIRY) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java index 9edb29989..03b065ae5 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java @@ -28,6 +28,7 @@ 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.text.SpannableStringBuilder; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -219,7 +220,7 @@ public class ViewKeyCertsFragment extends LoaderFragment TextView wSignerName = (TextView) view.findViewById(R.id.signerName); TextView wSignStatus = (TextView) view.findViewById(R.id.signStatus); - String signerKeyId = KeyFormattingUtils.convertKeyIdToHex(cursor.getLong(mIndexSignerKeyId)); + SpannableStringBuilder signerKeyId = KeyFormattingUtils.beautifyKeyIdWithPrefix(getActivity(), cursor.getLong(mIndexSignerKeyId)); String[] userId = KeyRing.splitUserId(cursor.getString(mIndexSignerUserId)); if (userId[0] != null) { wSignerName.setText(userId[0]); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java index 1c929e508..377a3d66e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysAdapter.java @@ -155,7 +155,7 @@ public class ImportKeysAdapter extends ArrayAdapter { holder.mainUserIdRest.setVisibility(View.GONE); } - holder.keyId.setText(entry.getKeyIdHex()); + holder.keyId.setText(KeyFormattingUtils.beautifyKeyIdWithPrefix(getContext(), entry.getKeyIdHex())); // don't show full fingerprint on key import holder.fingerprint.setVisibility(View.GONE); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java index 99ceeb929..b377e2cc9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java @@ -145,8 +145,7 @@ public class SubkeysAdapter extends CursorAdapter { deleteImage.setVisibility(View.GONE); long keyId = cursor.getLong(INDEX_KEY_ID); - String keyIdStr = KeyFormattingUtils.convertKeyIdToHex(keyId); - vKeyId.setText(keyIdStr); + vKeyId.setText(KeyFormattingUtils.beautifyKeyId(keyId)); // may be set with additional "stripped" later on SpannableStringBuilder algorithmStr = new SpannableStringBuilder(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java index fc206aaf5..2b56dd3a7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/util/KeyFormattingUtils.java @@ -22,9 +22,13 @@ import android.content.Context; import android.database.Cursor; import android.graphics.Color; import android.graphics.PorterDuff; +import android.graphics.Typeface; import android.text.Spannable; +import android.text.SpannableString; import android.text.SpannableStringBuilder; import android.text.style.ForegroundColorSpan; +import android.text.style.StyleSpan; +import android.text.style.TypefaceSpan; import android.view.View; import android.widget.ImageView; @@ -250,6 +254,56 @@ public class KeyFormattingUtils { return hexString; } + /** + * Makes a human-readable version of a key ID, which is usually 64 bits: lower-case, no + * leading 0x, space-separated quartets (for keys whose length in hex is divisible by 4) + * + * @param idHex - the key id + * @return - the beautified form + */ + public static SpannableString beautifyKeyId(String idHex) { + if (idHex.startsWith("0x")) { + idHex = idHex.substring(2); + } + if ((idHex.length() % 4) == 0) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < idHex.length(); i += 4) { + if (i != 0) { + sb.appendCodePoint(0x2008); // U+2008 PUNCTUATION SPACE + } + sb.append(idHex.substring(i, i + 4).toLowerCase(Locale.US)); + } + idHex = sb.toString(); + } + + SpannableString ss = new SpannableString(idHex); + ss.setSpan(new TypefaceSpan("monospace"), 0, idHex.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + return ss; + } + + /** + * Makes a human-readable version of a key ID, which is usually 64 bits: lower-case, no + * leading 0x, space-separated quartets (for keys whose length in hex is divisible by 4) + * + * @param keyId - the key id + * @return - the beautified form + */ + public static SpannableString beautifyKeyId(long keyId) { + return beautifyKeyId(convertKeyIdToHex(keyId)); + } + + public static SpannableStringBuilder beautifyKeyIdWithPrefix(Context context, String idHex) { + SpannableStringBuilder ssb = new SpannableStringBuilder(); + ssb.append("ID"); + ssb.append(": "); + ssb.append(beautifyKeyId(idHex)); + return ssb; + } + + public static SpannableStringBuilder beautifyKeyIdWithPrefix(Context context, long keyId) { + return beautifyKeyIdWithPrefix(context, convertKeyIdToHex(keyId)); + } + public static SpannableStringBuilder colorizeFingerprint(String fingerprint) { // split by 4 characters fingerprint = fingerprint.replaceAll("(.{4})(?!$)", "$1 "); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java index 2d2f80e5d..30e032736 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java @@ -28,6 +28,7 @@ import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; +import android.text.SpannableStringBuilder; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; @@ -218,15 +219,15 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView { } } - public String getSecondary() { + public SpannableStringBuilder getSecondary() { if (mUserId[1] != null) { - return mUserId[1]; + return new SpannableStringBuilder(mUserId[1]); } else { return getKeyIdHex(); } } - public String getTertiary() { + public SpannableStringBuilder getTertiary() { if (mUserId[0] != null) { return getKeyIdHex(); } else { @@ -238,8 +239,8 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView { return mKeyId; } - public String getKeyIdHex() { - return KeyFormattingUtils.convertKeyIdToHex(mKeyId); + public SpannableStringBuilder getKeyIdHex() { + return KeyFormattingUtils.beautifyKeyIdWithPrefix(getContext(), mKeyId); } public String getKeyIdHexShort() { @@ -278,7 +279,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView { protected boolean keepObject(EncryptionKey obj, String mask) { String m = mask.toLowerCase(Locale.ENGLISH); return obj.getUserId().toLowerCase(Locale.ENGLISH).contains(m) || - obj.getKeyIdHex().contains(m) || + obj.getKeyIdHex().toString().contains(m) || obj.getKeyIdHexShort().startsWith(m); } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java index df8250ab6..975ea17c7 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java @@ -148,7 +148,7 @@ public abstract class KeySpinner extends Spinner implements LoaderManager.Loader String[] userId = KeyRing.splitUserId(cursor.getString(mIndexUserId)); vKeyName.setText(userId[2] == null ? userId[0] : (userId[0] + " (" + userId[2] + ")")); vKeyEmail.setText(userId[1]); - vKeyId.setText(KeyFormattingUtils.convertKeyIdToHex(cursor.getLong(mIndexKeyId))); + vKeyId.setText(KeyFormattingUtils.beautifyKeyIdWithPrefix(getContext(), cursor.getLong(mIndexKeyId))); boolean valid = setStatus(getContext(), cursor, vKeyStatus); if (valid) { diff --git a/OpenKeychain/src/main/res/layout/import_keys_list_entry.xml b/OpenKeychain/src/main/res/layout/import_keys_list_entry.xml index ddf3d1bb4..5f3319c6c 100644 --- a/OpenKeychain/src/main/res/layout/import_keys_list_entry.xml +++ b/OpenKeychain/src/main/res/layout/import_keys_list_entry.xml @@ -56,9 +56,8 @@ android:id="@+id/subkey_item_key_id" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="0xBBBBBBBBBBBBBBBB" - android:textAppearance="?android:attr/textAppearanceSmall" - android:typeface="monospace" /> + android:text="Key ID: abcd abcd abcd abcd" + android:textAppearance="?android:attr/textAppearanceSmall" /> diff --git a/OpenKeychain/src/main/res/layout/keyspinner_item.xml b/OpenKeychain/src/main/res/layout/keyspinner_item.xml index e231664f3..411ceefdf 100644 --- a/OpenKeychain/src/main/res/layout/keyspinner_item.xml +++ b/OpenKeychain/src/main/res/layout/keyspinner_item.xml @@ -44,7 +44,6 @@ android:layout_height="wrap_content" android:singleLine="true" android:ellipsize="end" - android:typeface="monospace" android:textAppearance="?android:attr/textAppearanceSmall"/> diff --git a/OpenKeychain/src/main/res/layout/view_key_subkey_item.xml b/OpenKeychain/src/main/res/layout/view_key_subkey_item.xml index af7e32039..cf4b82078 100644 --- a/OpenKeychain/src/main/res/layout/view_key_subkey_item.xml +++ b/OpenKeychain/src/main/res/layout/view_key_subkey_item.xml @@ -54,7 +54,6 @@ android:layout_height="wrap_content" android:text="0x00000000" android:textAppearance="?android:attr/textAppearanceMedium" - android:typeface="monospace" android:layout_weight="1" />