Beautify key id (thanks to Tim Bray)

This commit is contained in:
Dominik Schürmann 2014-09-19 13:44:17 +02:00
parent 99bf77dd84
commit 1ad36e2dbd
12 changed files with 76 additions and 23 deletions

View File

@ -108,11 +108,11 @@ public class ImportKeysListEntry implements Serializable, Parcelable {
return super.hashCode(); return super.hashCode();
} }
public boolean hasSameKeyAs(Object o) { public boolean hasSameKeyAs(ImportKeysListEntry other) {
if (mFingerprintHex == null || o == null || !(o instanceof ImportKeysListEntry)) { if (mFingerprintHex == null || other == null) {
return false; return false;
} }
return mFingerprintHex.equals(((ImportKeysListEntry) o).mFingerprintHex); return mFingerprintHex.equals(other.mFingerprintHex);
} }
public String getKeyIdHex() { public String getKeyIdHex() {

View File

@ -28,6 +28,8 @@ import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader; import android.support.v4.content.Loader;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity; import android.support.v7.app.ActionBarActivity;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.format.DateFormat; import android.text.format.DateFormat;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
@ -119,7 +121,7 @@ public class ViewCertActivity extends ActionBarActivity
@Override @Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) { public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (data.moveToFirst()) { 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); mSigneeKey.setText(signeeKey);
String signeeUid = data.getString(INDEX_USER_ID); String signeeUid = data.getString(INDEX_USER_ID);
@ -129,7 +131,7 @@ public class ViewCertActivity extends ActionBarActivity
mCreation.setText(DateFormat.getDateFormat(getApplicationContext()).format(creationDate)); mCreation.setText(DateFormat.getDateFormat(getApplicationContext()).format(creationDate));
mCertifierKeyId = data.getLong(INDEX_KEY_ID_CERTIFIER); mCertifierKeyId = data.getLong(INDEX_KEY_ID_CERTIFIER);
String certifierKey = KeyFormattingUtils.convertKeyIdToHex(mCertifierKeyId); SpannableString certifierKey = KeyFormattingUtils.beautifyKeyId(mCertifierKeyId);
mCertifierKey.setText(certifierKey); mCertifierKey.setText(certifierKey);
String certifierUid = data.getString(INDEX_SIGNER_UID); String certifierUid = data.getString(INDEX_SIGNER_UID);

View File

@ -470,8 +470,7 @@ public class ViewKeyActivity extends ActionBarActivity implements
// get key id from MASTER_KEY_ID // get key id from MASTER_KEY_ID
long masterKeyId = data.getLong(INDEX_UNIFIED_MASTER_KEY_ID); long masterKeyId = data.getLong(INDEX_UNIFIED_MASTER_KEY_ID);
String keyIdStr = KeyFormattingUtils.convertKeyIdToHex(masterKeyId); getSupportActionBar().setSubtitle(KeyFormattingUtils.beautifyKeyIdWithPrefix(this, masterKeyId));
getSupportActionBar().setSubtitle(keyIdStr);
boolean isRevoked = data.getInt(INDEX_UNIFIED_IS_REVOKED) > 0; boolean isRevoked = data.getInt(INDEX_UNIFIED_IS_REVOKED) > 0;
boolean isExpired = !data.isNull(INDEX_UNIFIED_EXPIRY) boolean isExpired = !data.isNull(INDEX_UNIFIED_EXPIRY)

View File

@ -28,6 +28,7 @@ import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader; import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader; import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter; import android.support.v4.widget.CursorAdapter;
import android.text.SpannableStringBuilder;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -219,7 +220,7 @@ public class ViewKeyCertsFragment extends LoaderFragment
TextView wSignerName = (TextView) view.findViewById(R.id.signerName); TextView wSignerName = (TextView) view.findViewById(R.id.signerName);
TextView wSignStatus = (TextView) view.findViewById(R.id.signStatus); 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)); String[] userId = KeyRing.splitUserId(cursor.getString(mIndexSignerUserId));
if (userId[0] != null) { if (userId[0] != null) {
wSignerName.setText(userId[0]); wSignerName.setText(userId[0]);

View File

@ -155,7 +155,7 @@ public class ImportKeysAdapter extends ArrayAdapter<ImportKeysListEntry> {
holder.mainUserIdRest.setVisibility(View.GONE); 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 // don't show full fingerprint on key import
holder.fingerprint.setVisibility(View.GONE); holder.fingerprint.setVisibility(View.GONE);

View File

@ -145,8 +145,7 @@ public class SubkeysAdapter extends CursorAdapter {
deleteImage.setVisibility(View.GONE); deleteImage.setVisibility(View.GONE);
long keyId = cursor.getLong(INDEX_KEY_ID); long keyId = cursor.getLong(INDEX_KEY_ID);
String keyIdStr = KeyFormattingUtils.convertKeyIdToHex(keyId); vKeyId.setText(KeyFormattingUtils.beautifyKeyId(keyId));
vKeyId.setText(keyIdStr);
// may be set with additional "stripped" later on // may be set with additional "stripped" later on
SpannableStringBuilder algorithmStr = new SpannableStringBuilder(); SpannableStringBuilder algorithmStr = new SpannableStringBuilder();

View File

@ -22,9 +22,13 @@ import android.content.Context;
import android.database.Cursor; import android.database.Cursor;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.text.Spannable; import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan; import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.text.style.TypefaceSpan;
import android.view.View; import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
@ -250,6 +254,56 @@ public class KeyFormattingUtils {
return hexString; 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) { public static SpannableStringBuilder colorizeFingerprint(String fingerprint) {
// split by 4 characters // split by 4 characters
fingerprint = fingerprint.replaceAll("(.{4})(?!$)", "$1 "); fingerprint = fingerprint.replaceAll("(.{4})(?!$)", "$1 ");

View File

@ -28,6 +28,7 @@ import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager; import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader; import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader; import android.support.v4.content.Loader;
import android.text.SpannableStringBuilder;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@ -218,15 +219,15 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView {
} }
} }
public String getSecondary() { public SpannableStringBuilder getSecondary() {
if (mUserId[1] != null) { if (mUserId[1] != null) {
return mUserId[1]; return new SpannableStringBuilder(mUserId[1]);
} else { } else {
return getKeyIdHex(); return getKeyIdHex();
} }
} }
public String getTertiary() { public SpannableStringBuilder getTertiary() {
if (mUserId[0] != null) { if (mUserId[0] != null) {
return getKeyIdHex(); return getKeyIdHex();
} else { } else {
@ -238,8 +239,8 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView {
return mKeyId; return mKeyId;
} }
public String getKeyIdHex() { public SpannableStringBuilder getKeyIdHex() {
return KeyFormattingUtils.convertKeyIdToHex(mKeyId); return KeyFormattingUtils.beautifyKeyIdWithPrefix(getContext(), mKeyId);
} }
public String getKeyIdHexShort() { public String getKeyIdHexShort() {
@ -278,7 +279,7 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView {
protected boolean keepObject(EncryptionKey obj, String mask) { protected boolean keepObject(EncryptionKey obj, String mask) {
String m = mask.toLowerCase(Locale.ENGLISH); String m = mask.toLowerCase(Locale.ENGLISH);
return obj.getUserId().toLowerCase(Locale.ENGLISH).contains(m) || return obj.getUserId().toLowerCase(Locale.ENGLISH).contains(m) ||
obj.getKeyIdHex().contains(m) || obj.getKeyIdHex().toString().contains(m) ||
obj.getKeyIdHexShort().startsWith(m); obj.getKeyIdHexShort().startsWith(m);
} }
} }

View File

@ -148,7 +148,7 @@ public abstract class KeySpinner extends Spinner implements LoaderManager.Loader
String[] userId = KeyRing.splitUserId(cursor.getString(mIndexUserId)); String[] userId = KeyRing.splitUserId(cursor.getString(mIndexUserId));
vKeyName.setText(userId[2] == null ? userId[0] : (userId[0] + " (" + userId[2] + ")")); vKeyName.setText(userId[2] == null ? userId[0] : (userId[0] + " (" + userId[2] + ")"));
vKeyEmail.setText(userId[1]); 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); boolean valid = setStatus(getContext(), cursor, vKeyStatus);
if (valid) { if (valid) {

View File

@ -56,9 +56,8 @@
android:id="@+id/subkey_item_key_id" android:id="@+id/subkey_item_key_id"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="0xBBBBBBBBBBBBBBBB" android:text="Key ID: abcd abcd abcd abcd"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall" />
android:typeface="monospace" />
</LinearLayout> </LinearLayout>

View File

@ -44,7 +44,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:singleLine="true" android:singleLine="true"
android:ellipsize="end" android:ellipsize="end"
android:typeface="monospace"
android:textAppearance="?android:attr/textAppearanceSmall"/> android:textAppearance="?android:attr/textAppearanceSmall"/>
</LinearLayout> </LinearLayout>

View File

@ -54,7 +54,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="0x00000000" android:text="0x00000000"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
android:typeface="monospace"
android:layout_weight="1" /> android:layout_weight="1" />
<ImageView <ImageView