mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-27 11:12:15 -05:00
Merge remote-tracking branch 'origin/master' into external-test
Conflicts: OpenKeychain-Test/src/test/resources/extern/OpenPGP-Haskell OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/OperationResultParcel.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java
This commit is contained in:
commit
54bc874ce5
@ -53,6 +53,12 @@ import java.util.Set;
|
|||||||
|
|
||||||
public class OpenPgpService extends RemoteService {
|
public class OpenPgpService extends RemoteService {
|
||||||
|
|
||||||
|
static final String[] KEYRING_PROJECTION =
|
||||||
|
new String[]{
|
||||||
|
KeyRings._ID,
|
||||||
|
KeyRings.MASTER_KEY_ID,
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search database for key ids based on emails.
|
* Search database for key ids based on emails.
|
||||||
*
|
*
|
||||||
@ -70,7 +76,7 @@ public class OpenPgpService extends RemoteService {
|
|||||||
|
|
||||||
for (String email : encryptionUserIds) {
|
for (String email : encryptionUserIds) {
|
||||||
Uri uri = KeyRings.buildUnifiedKeyRingsFindByEmailUri(email);
|
Uri uri = KeyRings.buildUnifiedKeyRingsFindByEmailUri(email);
|
||||||
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
|
Cursor cursor = getContentResolver().query(uri, KEYRING_PROJECTION, null, null, null);
|
||||||
try {
|
try {
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
long id = cursor.getLong(cursor.getColumnIndex(KeyRings.MASTER_KEY_ID));
|
long id = cursor.getLong(cursor.getColumnIndex(KeyRings.MASTER_KEY_ID));
|
||||||
|
@ -317,21 +317,21 @@ public class OperationResultParcel implements Parcelable {
|
|||||||
|
|
||||||
public static class OperationLog implements Iterable<LogEntryParcel> {
|
public static class OperationLog implements Iterable<LogEntryParcel> {
|
||||||
|
|
||||||
private final List<LogEntryParcel> parcels = new ArrayList<LogEntryParcel>();
|
private final List<LogEntryParcel> mParcels = new ArrayList<LogEntryParcel>();
|
||||||
|
|
||||||
/// Simple convenience method
|
/// Simple convenience method
|
||||||
public void add(LogLevel level, LogType type, int indent, Object... parameters) {
|
public void add(LogLevel level, LogType type, int indent, Object... parameters) {
|
||||||
Log.d(Constants.TAG, type.toString());
|
Log.d(Constants.TAG, type.toString());
|
||||||
parcels.add(new OperationResultParcel.LogEntryParcel(level, type, indent, parameters));
|
mParcels.add(new OperationResultParcel.LogEntryParcel(level, type, indent, parameters));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(LogLevel level, LogType type, int indent) {
|
public void add(LogLevel level, LogType type, int indent) {
|
||||||
Log.d(Constants.TAG, type.toString());
|
Log.d(Constants.TAG, type.toString());
|
||||||
parcels.add(new OperationResultParcel.LogEntryParcel(level, type, indent, (Object[]) null));
|
mParcels.add(new OperationResultParcel.LogEntryParcel(level, type, indent, (Object[]) null));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean containsWarnings() {
|
public boolean containsWarnings() {
|
||||||
for(LogEntryParcel entry : new IterableIterator<LogEntryParcel>(parcels.iterator())) {
|
for(LogEntryParcel entry : new IterableIterator<LogEntryParcel>(mParcels.iterator())) {
|
||||||
if (entry.mLevel == LogLevel.WARN || entry.mLevel == LogLevel.ERROR) {
|
if (entry.mLevel == LogLevel.WARN || entry.mLevel == LogLevel.ERROR) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -340,20 +340,20 @@ public class OperationResultParcel implements Parcelable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addAll(List<LogEntryParcel> parcels) {
|
public void addAll(List<LogEntryParcel> parcels) {
|
||||||
parcels.addAll(parcels);
|
mParcels.addAll(parcels);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<LogEntryParcel> toList() {
|
public List<LogEntryParcel> toList() {
|
||||||
return parcels;
|
return mParcels;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return parcels.isEmpty();
|
return mParcels.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<LogEntryParcel> iterator() {
|
public Iterator<LogEntryParcel> iterator() {
|
||||||
return parcels.iterator();
|
return mParcels.iterator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter;
|
|||||||
import org.sufficientlysecure.keychain.ui.adapter.SubkeysAddedAdapter;
|
import org.sufficientlysecure.keychain.ui.adapter.SubkeysAddedAdapter;
|
||||||
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
|
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAdapter;
|
||||||
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAddedAdapter;
|
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAddedAdapter;
|
||||||
|
import org.sufficientlysecure.keychain.ui.dialog.EditSubkeyDialogFragment;
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.EditUserIdDialogFragment;
|
import org.sufficientlysecure.keychain.ui.dialog.EditUserIdDialogFragment;
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
|
import org.sufficientlysecure.keychain.ui.dialog.PassphraseDialogFragment;
|
||||||
import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment;
|
import org.sufficientlysecure.keychain.ui.dialog.SetPassphraseDialogFragment;
|
||||||
@ -214,9 +215,17 @@ public class EditKeyFragment extends LoaderFragment implements
|
|||||||
mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mUserIdsAddedData);
|
mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mUserIdsAddedData);
|
||||||
mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter);
|
mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter);
|
||||||
|
|
||||||
mSubkeysAdapter = new SubkeysAdapter(getActivity(), null, 0);
|
mSubkeysAdapter = new SubkeysAdapter(getActivity(), null, 0, mSaveKeyringParcel);
|
||||||
mSubkeysList.setAdapter(mSubkeysAdapter);
|
mSubkeysList.setAdapter(mSubkeysAdapter);
|
||||||
|
|
||||||
|
mSubkeysList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||||
|
long keyId = mSubkeysAdapter.getKeyId(position);
|
||||||
|
editSubkey(keyId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
mSubkeysAddedAdapter = new SubkeysAddedAdapter(getActivity(), mSaveKeyringParcel.mAddSubKeys);
|
mSubkeysAddedAdapter = new SubkeysAddedAdapter(getActivity(), mSaveKeyringParcel.mAddSubKeys);
|
||||||
mSubkeysAddedList.setAdapter(mSubkeysAddedAdapter);
|
mSubkeysAddedList.setAdapter(mSubkeysAddedAdapter);
|
||||||
|
|
||||||
@ -342,6 +351,46 @@ public class EditKeyFragment extends LoaderFragment implements
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void editSubkey(final long keyId) {
|
||||||
|
Handler returnHandler = new Handler() {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message message) {
|
||||||
|
switch (message.what) {
|
||||||
|
case EditSubkeyDialogFragment.MESSAGE_CHANGE_EXPIRY:
|
||||||
|
// toggle
|
||||||
|
// if (mSaveKeyringParcel.changePrimaryUserId != null
|
||||||
|
// && mSaveKeyringParcel.changePrimaryUserId.equals(userId)) {
|
||||||
|
// mSaveKeyringParcel.changePrimaryUserId = null;
|
||||||
|
// } else {
|
||||||
|
// mSaveKeyringParcel.changePrimaryUserId = userId;
|
||||||
|
// }
|
||||||
|
break;
|
||||||
|
case EditSubkeyDialogFragment.MESSAGE_REVOKE:
|
||||||
|
// toggle
|
||||||
|
if (mSaveKeyringParcel.mRevokeSubKeys.contains(keyId)) {
|
||||||
|
mSaveKeyringParcel.mRevokeSubKeys.remove(keyId);
|
||||||
|
} else {
|
||||||
|
mSaveKeyringParcel.mRevokeSubKeys.add(keyId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
getLoaderManager().getLoader(LOADER_ID_SUBKEYS).forceLoad();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a new Messenger for the communication back
|
||||||
|
final Messenger messenger = new Messenger(returnHandler);
|
||||||
|
|
||||||
|
DialogFragmentWorkaround.INTERFACE.runnableRunDelayed(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
EditSubkeyDialogFragment dialogFragment =
|
||||||
|
EditSubkeyDialogFragment.newInstance(messenger);
|
||||||
|
|
||||||
|
dialogFragment.show(getActivity().getSupportFragmentManager(), "editSubkeyDialog");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void addUserId() {
|
private void addUserId() {
|
||||||
mUserIdsAddedAdapter.add(new UserIdsAddedAdapter.UserIdModel());
|
mUserIdsAddedAdapter.add(new UserIdsAddedAdapter.UserIdModel());
|
||||||
}
|
}
|
||||||
@ -432,4 +481,4 @@ public class EditKeyFragment extends LoaderFragment implements
|
|||||||
// start service with intent
|
// start service with intent
|
||||||
getActivity().startService(intent);
|
getActivity().startService(intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,14 +32,15 @@ import org.sufficientlysecure.keychain.R;
|
|||||||
import org.sufficientlysecure.keychain.helper.OtherHelper;
|
import org.sufficientlysecure.keychain.helper.OtherHelper;
|
||||||
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
import org.sufficientlysecure.keychain.pgp.PgpKeyHelper;
|
||||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
|
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
|
||||||
|
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
public class SubkeysAdapter extends CursorAdapter {
|
public class SubkeysAdapter extends CursorAdapter {
|
||||||
private LayoutInflater mInflater;
|
private LayoutInflater mInflater;
|
||||||
|
private SaveKeyringParcel mSaveKeyringParcel;
|
||||||
|
|
||||||
private boolean hasAnySecret;
|
private boolean hasAnySecret;
|
||||||
|
|
||||||
private ColorStateList mDefaultTextColor;
|
private ColorStateList mDefaultTextColor;
|
||||||
|
|
||||||
public static final String[] SUBKEYS_PROJECTION = new String[]{
|
public static final String[] SUBKEYS_PROJECTION = new String[]{
|
||||||
@ -71,10 +72,21 @@ public class SubkeysAdapter extends CursorAdapter {
|
|||||||
private static final int INDEX_EXPIRY = 11;
|
private static final int INDEX_EXPIRY = 11;
|
||||||
private static final int INDEX_FINGERPRINT = 12;
|
private static final int INDEX_FINGERPRINT = 12;
|
||||||
|
|
||||||
public SubkeysAdapter(Context context, Cursor c, int flags) {
|
public SubkeysAdapter(Context context, Cursor c, int flags,
|
||||||
|
SaveKeyringParcel saveKeyringParcel) {
|
||||||
super(context, c, flags);
|
super(context, c, flags);
|
||||||
|
|
||||||
mInflater = LayoutInflater.from(context);
|
mInflater = LayoutInflater.from(context);
|
||||||
|
mSaveKeyringParcel = saveKeyringParcel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubkeysAdapter(Context context, Cursor c, int flags) {
|
||||||
|
this(context, c, flags, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getKeyId(int position) {
|
||||||
|
mCursor.moveToPosition(position);
|
||||||
|
return mCursor.getLong(INDEX_KEY_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -94,79 +106,94 @@ public class SubkeysAdapter extends CursorAdapter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bindView(View view, Context context, Cursor cursor) {
|
public void bindView(View view, Context context, Cursor cursor) {
|
||||||
TextView keyId = (TextView) view.findViewById(R.id.keyId);
|
TextView vKeyId = (TextView) view.findViewById(R.id.keyId);
|
||||||
TextView keyDetails = (TextView) view.findViewById(R.id.keyDetails);
|
TextView vKeyDetails = (TextView) view.findViewById(R.id.keyDetails);
|
||||||
TextView keyExpiry = (TextView) view.findViewById(R.id.keyExpiry);
|
TextView vKeyExpiry = (TextView) view.findViewById(R.id.keyExpiry);
|
||||||
ImageView masterKeyIcon = (ImageView) view.findViewById(R.id.ic_masterKey);
|
ImageView vMasterKeyIcon = (ImageView) view.findViewById(R.id.ic_masterKey);
|
||||||
ImageView certifyIcon = (ImageView) view.findViewById(R.id.ic_certifyKey);
|
ImageView vCertifyIcon = (ImageView) view.findViewById(R.id.ic_certifyKey);
|
||||||
ImageView encryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey);
|
ImageView vEncryptIcon = (ImageView) view.findViewById(R.id.ic_encryptKey);
|
||||||
ImageView signIcon = (ImageView) view.findViewById(R.id.ic_signKey);
|
ImageView vSignIcon = (ImageView) view.findViewById(R.id.ic_signKey);
|
||||||
ImageView revokedKeyIcon = (ImageView) view.findViewById(R.id.ic_revokedKey);
|
ImageView vRevokedKeyIcon = (ImageView) view.findViewById(R.id.ic_revokedKey);
|
||||||
|
ImageView vEditImage = (ImageView) view.findViewById(R.id.edit_image);
|
||||||
|
|
||||||
String keyIdStr = PgpKeyHelper.convertKeyIdToHex(cursor.getLong(INDEX_KEY_ID));
|
long keyId = cursor.getLong(INDEX_KEY_ID);
|
||||||
|
String keyIdStr = PgpKeyHelper.convertKeyIdToHex(keyId);
|
||||||
String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
|
String algorithmStr = PgpKeyHelper.getAlgorithmInfo(
|
||||||
context,
|
context,
|
||||||
cursor.getInt(INDEX_ALGORITHM),
|
cursor.getInt(INDEX_ALGORITHM),
|
||||||
cursor.getInt(INDEX_KEY_SIZE)
|
cursor.getInt(INDEX_KEY_SIZE)
|
||||||
);
|
);
|
||||||
|
|
||||||
keyId.setText(keyIdStr);
|
vKeyId.setText(keyIdStr);
|
||||||
// may be set with additional "stripped" later on
|
// may be set with additional "stripped" later on
|
||||||
if (hasAnySecret && cursor.getInt(INDEX_HAS_SECRET) == 0) {
|
if (hasAnySecret && cursor.getInt(INDEX_HAS_SECRET) == 0) {
|
||||||
keyDetails.setText(algorithmStr + ", " +
|
vKeyDetails.setText(algorithmStr + ", " +
|
||||||
context.getString(R.string.key_stripped));
|
context.getString(R.string.key_stripped));
|
||||||
} else {
|
} else {
|
||||||
keyDetails.setText(algorithmStr);
|
vKeyDetails.setText(algorithmStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set icons according to properties
|
// Set icons according to properties
|
||||||
masterKeyIcon.setVisibility(cursor.getInt(INDEX_RANK) == 0 ? View.VISIBLE : View.INVISIBLE);
|
vMasterKeyIcon.setVisibility(cursor.getInt(INDEX_RANK) == 0 ? View.VISIBLE : View.INVISIBLE);
|
||||||
certifyIcon.setVisibility(cursor.getInt(INDEX_CAN_CERTIFY) != 0 ? View.VISIBLE : View.GONE);
|
vCertifyIcon.setVisibility(cursor.getInt(INDEX_CAN_CERTIFY) != 0 ? View.VISIBLE : View.GONE);
|
||||||
encryptIcon.setVisibility(cursor.getInt(INDEX_CAN_ENCRYPT) != 0 ? View.VISIBLE : View.GONE);
|
vEncryptIcon.setVisibility(cursor.getInt(INDEX_CAN_ENCRYPT) != 0 ? View.VISIBLE : View.GONE);
|
||||||
signIcon.setVisibility(cursor.getInt(INDEX_CAN_SIGN) != 0 ? View.VISIBLE : View.GONE);
|
vSignIcon.setVisibility(cursor.getInt(INDEX_CAN_SIGN) != 0 ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
boolean valid = true;
|
boolean isRevoked = cursor.getInt(INDEX_IS_REVOKED) > 0;
|
||||||
if (cursor.getInt(INDEX_IS_REVOKED) > 0) {
|
|
||||||
revokedKeyIcon.setVisibility(View.VISIBLE);
|
|
||||||
|
|
||||||
valid = false;
|
// for edit key
|
||||||
|
if (mSaveKeyringParcel != null) {
|
||||||
|
boolean revokeThisSubkey = (mSaveKeyringParcel.mRevokeSubKeys.contains(keyId));
|
||||||
|
|
||||||
|
if (revokeThisSubkey) {
|
||||||
|
if (!isRevoked) {
|
||||||
|
isRevoked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vEditImage.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
keyId.setTextColor(mDefaultTextColor);
|
vEditImage.setVisibility(View.GONE);
|
||||||
keyDetails.setTextColor(mDefaultTextColor);
|
|
||||||
keyExpiry.setTextColor(mDefaultTextColor);
|
|
||||||
|
|
||||||
revokedKeyIcon.setVisibility(View.GONE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isRevoked) {
|
||||||
|
vRevokedKeyIcon.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
vKeyId.setTextColor(mDefaultTextColor);
|
||||||
|
vKeyDetails.setTextColor(mDefaultTextColor);
|
||||||
|
vKeyExpiry.setTextColor(mDefaultTextColor);
|
||||||
|
|
||||||
|
vRevokedKeyIcon.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isExpired;
|
||||||
if (!cursor.isNull(INDEX_EXPIRY)) {
|
if (!cursor.isNull(INDEX_EXPIRY)) {
|
||||||
Date expiryDate = new Date(cursor.getLong(INDEX_EXPIRY) * 1000);
|
Date expiryDate = new Date(cursor.getLong(INDEX_EXPIRY) * 1000);
|
||||||
|
isExpired = expiryDate.before(new Date());
|
||||||
|
|
||||||
valid = valid && expiryDate.after(new Date());
|
vKeyExpiry.setText(context.getString(R.string.label_expiry) + ": "
|
||||||
keyExpiry.setText(
|
+ DateFormat.getDateFormat(context).format(expiryDate));
|
||||||
context.getString(R.string.label_expiry) + ": " +
|
|
||||||
DateFormat.getDateFormat(context).format(expiryDate)
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
keyExpiry.setText(
|
isExpired = false;
|
||||||
context.getString(R.string.label_expiry) + ": " +
|
|
||||||
context.getString(R.string.none)
|
vKeyExpiry.setText(context.getString(R.string.label_expiry) + ": " + context.getString(R.string.none));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if key is expired or revoked, strike through text
|
// if key is expired or revoked, strike through text
|
||||||
if (!valid) {
|
boolean isInvalid = isRevoked || isExpired;
|
||||||
keyId.setText(OtherHelper.strikeOutText(keyId.getText()));
|
if (isInvalid) {
|
||||||
keyDetails.setText(OtherHelper.strikeOutText(keyDetails.getText()));
|
vKeyId.setText(OtherHelper.strikeOutText(vKeyId.getText()));
|
||||||
keyExpiry.setText(OtherHelper.strikeOutText(keyExpiry.getText()));
|
vKeyDetails.setText(OtherHelper.strikeOutText(vKeyDetails.getText()));
|
||||||
|
vKeyExpiry.setText(OtherHelper.strikeOutText(vKeyExpiry.getText()));
|
||||||
}
|
}
|
||||||
keyId.setEnabled(valid);
|
vKeyId.setEnabled(!isInvalid);
|
||||||
keyDetails.setEnabled(valid);
|
vKeyDetails.setEnabled(!isInvalid);
|
||||||
keyExpiry.setEnabled(valid);
|
vKeyExpiry.setEnabled(!isInvalid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View newView(Context context, Cursor cursor, ViewGroup parent) {
|
public View newView(Context context, Cursor cursor, ViewGroup parent) {
|
||||||
View view = mInflater.inflate(R.layout.view_key_keys_item, null);
|
View view = mInflater.inflate(R.layout.view_key_subkey_item, null);
|
||||||
if (mDefaultTextColor == null) {
|
if (mDefaultTextColor == null) {
|
||||||
TextView keyId = (TextView) view.findViewById(R.id.keyId);
|
TextView keyId = (TextView) view.findViewById(R.id.keyId);
|
||||||
mDefaultTextColor = keyId.getTextColors();
|
mDefaultTextColor = keyId.getTextColors();
|
||||||
@ -177,13 +204,21 @@ public class SubkeysAdapter extends CursorAdapter {
|
|||||||
// Disable selection of items, http://stackoverflow.com/a/4075045
|
// Disable selection of items, http://stackoverflow.com/a/4075045
|
||||||
@Override
|
@Override
|
||||||
public boolean areAllItemsEnabled() {
|
public boolean areAllItemsEnabled() {
|
||||||
return false;
|
if (mSaveKeyringParcel == null) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return super.areAllItemsEnabled();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable selection of items, http://stackoverflow.com/a/4075045
|
// Disable selection of items, http://stackoverflow.com/a/4075045
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled(int position) {
|
public boolean isEnabled(int position) {
|
||||||
return false;
|
if (mSaveKeyringParcel == null) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return super.isEnabled(position);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,9 +40,7 @@ import java.util.ArrayList;
|
|||||||
|
|
||||||
public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemClickListener {
|
public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemClickListener {
|
||||||
private LayoutInflater mInflater;
|
private LayoutInflater mInflater;
|
||||||
|
|
||||||
private final ArrayList<Boolean> mCheckStates;
|
private final ArrayList<Boolean> mCheckStates;
|
||||||
|
|
||||||
private SaveKeyringParcel mSaveKeyringParcel;
|
private SaveKeyringParcel mSaveKeyringParcel;
|
||||||
|
|
||||||
public static final String[] USER_IDS_PROJECTION = new String[]{
|
public static final String[] USER_IDS_PROJECTION = new String[]{
|
||||||
@ -60,7 +58,6 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
|
|||||||
private static final int INDEX_IS_PRIMARY = 4;
|
private static final int INDEX_IS_PRIMARY = 4;
|
||||||
private static final int INDEX_IS_REVOKED = 5;
|
private static final int INDEX_IS_REVOKED = 5;
|
||||||
|
|
||||||
|
|
||||||
public UserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes,
|
public UserIdsAdapter(Context context, Cursor c, int flags, boolean showCheckBoxes,
|
||||||
SaveKeyringParcel saveKeyringParcel) {
|
SaveKeyringParcel saveKeyringParcel) {
|
||||||
super(context, c, flags);
|
super(context, c, flags);
|
||||||
@ -139,10 +136,13 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
|
|||||||
&& mSaveKeyringParcel.mChangePrimaryUserId.equals(userId));
|
&& mSaveKeyringParcel.mChangePrimaryUserId.equals(userId));
|
||||||
boolean revokeThisUserId = (mSaveKeyringParcel.mRevokeUserIds.contains(userId));
|
boolean revokeThisUserId = (mSaveKeyringParcel.mRevokeUserIds.contains(userId));
|
||||||
|
|
||||||
|
// only if primary user id will be changed
|
||||||
|
// (this is not triggered if the user id is currently the primary one)
|
||||||
if (changeAnyPrimaryUserId) {
|
if (changeAnyPrimaryUserId) {
|
||||||
// change all user ids, only this one should be primary
|
// change _all_ primary user ids and set new one to true
|
||||||
isPrimary = changeThisPrimaryUserId;
|
isPrimary = changeThisPrimaryUserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (revokeThisUserId) {
|
if (revokeThisUserId) {
|
||||||
if (!isRevoked) {
|
if (!isRevoked) {
|
||||||
isRevoked = true;
|
isRevoked = true;
|
||||||
@ -233,7 +233,7 @@ public class UserIdsAdapter extends CursorAdapter implements AdapterView.OnItemC
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View newView(Context context, Cursor cursor, ViewGroup parent) {
|
public View newView(Context context, Cursor cursor, ViewGroup parent) {
|
||||||
View view = mInflater.inflate(R.layout.view_key_userids_item, null);
|
View view = mInflater.inflate(R.layout.view_key_user_id_item, null);
|
||||||
// only need to do this once ever, since mShowCheckBoxes is final
|
// only need to do this once ever, since mShowCheckBoxes is final
|
||||||
view.findViewById(R.id.checkBox).setVisibility(mCheckStates != null ? View.VISIBLE : View.GONE);
|
view.findViewById(R.id.checkBox).setVisibility(mCheckStates != null ? View.VISIBLE : View.GONE);
|
||||||
return view;
|
return view;
|
||||||
|
@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* 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.dialog;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.Messenger;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.support.v4.app.DialogFragment;
|
||||||
|
|
||||||
|
import org.sufficientlysecure.keychain.Constants;
|
||||||
|
import org.sufficientlysecure.keychain.R;
|
||||||
|
import org.sufficientlysecure.keychain.util.Log;
|
||||||
|
|
||||||
|
public class EditSubkeyDialogFragment extends DialogFragment {
|
||||||
|
private static final String ARG_MESSENGER = "messenger";
|
||||||
|
|
||||||
|
public static final int MESSAGE_CHANGE_EXPIRY = 1;
|
||||||
|
public static final int MESSAGE_REVOKE = 2;
|
||||||
|
|
||||||
|
private Messenger mMessenger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new instance of this dialog fragment
|
||||||
|
*/
|
||||||
|
public static EditSubkeyDialogFragment newInstance(Messenger messenger) {
|
||||||
|
EditSubkeyDialogFragment frag = new EditSubkeyDialogFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putParcelable(ARG_MESSENGER, messenger);
|
||||||
|
|
||||||
|
frag.setArguments(args);
|
||||||
|
|
||||||
|
return frag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates dialog
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
mMessenger = getArguments().getParcelable(ARG_MESSENGER);
|
||||||
|
|
||||||
|
CustomAlertDialogBuilder builder = new CustomAlertDialogBuilder(getActivity());
|
||||||
|
CharSequence[] array = getResources().getStringArray(R.array.edit_key_edit_subkey);
|
||||||
|
|
||||||
|
builder.setTitle(R.string.edit_key_edit_subkey_title);
|
||||||
|
builder.setItems(array, new DialogInterface.OnClickListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
switch (which) {
|
||||||
|
case 0:
|
||||||
|
sendMessageToHandler(MESSAGE_CHANGE_EXPIRY, null);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
sendMessageToHandler(MESSAGE_REVOKE, null);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return builder.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send message back to handler which is initialized in a activity
|
||||||
|
*
|
||||||
|
* @param what Message integer you want to send
|
||||||
|
*/
|
||||||
|
private void sendMessageToHandler(Integer what, Bundle data) {
|
||||||
|
Message msg = Message.obtain();
|
||||||
|
msg.what = what;
|
||||||
|
if (data != null) {
|
||||||
|
msg.setData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
mMessenger.send(msg);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
Log.w(Constants.TAG, "Messenger is null!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingRight="3dip"
|
|
||||||
android:singleLine="true">
|
android:singleLine="true">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
@ -13,28 +12,44 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
android:src="@drawable/key_small"
|
android:src="@drawable/key_small"
|
||||||
android:layout_marginLeft="8dp" />
|
android:padding="8dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_alignParentLeft="true"
|
||||||
|
android:layout_alignParentStart="true" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/edit_image"
|
||||||
|
android:src="@drawable/ic_action_edit"
|
||||||
|
android:padding="8dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_alignParentEnd="true" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="fill_parent"
|
android:layout_toRightOf="@id/ic_masterKey"
|
||||||
|
android:layout_toLeftOf="@id/edit_image"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_marginRight="8dp"
|
||||||
android:layout_marginLeft="8dp"
|
android:id="@+id/linearLayout">
|
||||||
android:layout_marginRight="8dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingBottom="2dip"
|
android:paddingBottom="2dip"
|
||||||
android:paddingTop="2dip">
|
android:paddingTop="2dip">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/keyId"
|
android:id="@+id/keyId"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/label_key_id"
|
android:text="0x00000000"
|
||||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
android:typeface="monospace"
|
android:typeface="monospace"
|
||||||
android:layout_weight="1" />
|
android:layout_weight="1" />
|
||||||
@ -75,8 +90,8 @@
|
|||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="fill_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/keyDetails"
|
android:id="@+id/keyDetails"
|
||||||
@ -94,8 +109,9 @@
|
|||||||
android:text="Expiry: 4/7/2016"
|
android:text="Expiry: 4/7/2016"
|
||||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||||
android:layout_gravity="right" />
|
android:layout_gravity="right" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</RelativeLayout>
|
@ -63,7 +63,6 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
@ -480,6 +480,11 @@
|
|||||||
<item>Change to Primary Identity</item>
|
<item>Change to Primary Identity</item>
|
||||||
<item>Revoke Identity</item>
|
<item>Revoke Identity</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
<string name="edit_key_edit_subkey_title">Select an action!</string>
|
||||||
|
<string-array name="edit_key_edit_subkey">
|
||||||
|
<item>Change Expiry</item>
|
||||||
|
<item>Revoke Subkey</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
<!-- Navigation Drawer -->
|
<!-- Navigation Drawer -->
|
||||||
<string name="nav_keys">Keys</string>
|
<string name="nav_keys">Keys</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user