inline subkey editing (wip commit)
This commit is contained in:
committed by
Dominik Schürmann
parent
fd119bda00
commit
00e97586b0
@@ -231,7 +231,8 @@ public class EditKeyFragment extends QueueingCryptoOperationFragment<SaveKeyring
|
||||
mUserIdsAddedAdapter = new UserIdsAddedAdapter(getActivity(), mSaveKeyringParcel.mAddUserIds, false);
|
||||
mUserIdsAddedList.setAdapter(mUserIdsAddedAdapter);
|
||||
|
||||
mSubkeysAdapter = new SubkeysAdapter(getActivity(), null, 0, mSaveKeyringParcel);
|
||||
mSubkeysAdapter = new SubkeysAdapter(getActivity(), null, 0);
|
||||
mSubkeysAdapter.setEditMode(mSaveKeyringParcel);
|
||||
mSubkeysList.setAdapter(mSubkeysAdapter);
|
||||
|
||||
mSubkeysAddedAdapter = new SubkeysAddedAdapter(getActivity(), mSaveKeyringParcel.mAddSubKeys, false);
|
||||
|
||||
@@ -20,30 +20,59 @@ package org.sufficientlysecure.keychain.ui;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
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.view.ActionMode;
|
||||
import android.view.ActionMode.Callback;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ViewAnimator;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.compatibility.DialogFragmentWorkaround;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedSecretKey.SecretKeyType;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
|
||||
import org.sufficientlysecure.keychain.service.SaveKeyringParcel.SubkeyChange;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.SubkeysAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.SubkeysAddedAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.adapter.UserIdsAddedAdapter;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.AddSubkeyDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.EditSubkeyDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.dialog.EditSubkeyExpiryDialogFragment;
|
||||
import org.sufficientlysecure.keychain.ui.util.Notify;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
|
||||
LoaderManager.LoaderCallbacks<Cursor> {
|
||||
|
||||
public static final String ARG_DATA_URI = "data_uri";
|
||||
public static final int LOADER_ID_SUBKEYS = 0;
|
||||
|
||||
private ListView mSubkeysList;
|
||||
private ListView mSubkeysAddedList;
|
||||
private View mSubkeysAddedLayout;
|
||||
private ViewAnimator mSubkeyAddFabLayout;
|
||||
|
||||
private SubkeysAdapter mSubkeysAdapter;
|
||||
private SubkeysAddedAdapter mSubkeysAddedAdapter;
|
||||
|
||||
private Uri mDataUriSubkeys;
|
||||
|
||||
private boolean mHasSecret;
|
||||
private SaveKeyringParcel mEditModeSaveKeyringParcel;
|
||||
|
||||
/**
|
||||
* Creates new instance of this fragment
|
||||
*/
|
||||
@@ -64,6 +93,36 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
|
||||
|
||||
mSubkeysList = (ListView) view.findViewById(R.id.keys);
|
||||
|
||||
mSubkeysList = (ListView) view.findViewById(R.id.view_key_user_ids);
|
||||
mSubkeysAddedList = (ListView) view.findViewById(R.id.view_key_user_ids_added);
|
||||
mSubkeysAddedLayout = view.findViewById(R.id.view_key_user_ids_add_layout);
|
||||
|
||||
mSubkeysList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
editSubkey(position);
|
||||
}
|
||||
});
|
||||
|
||||
View footer = new View(getActivity());
|
||||
int spacing = (int) android.util.TypedValue.applyDimension(
|
||||
android.util.TypedValue.COMPLEX_UNIT_DIP, 72, getResources().getDisplayMetrics()
|
||||
);
|
||||
android.widget.AbsListView.LayoutParams params = new android.widget.AbsListView.LayoutParams(
|
||||
android.widget.AbsListView.LayoutParams.MATCH_PARENT,
|
||||
spacing
|
||||
);
|
||||
footer.setLayoutParams(params);
|
||||
mSubkeysAddedList.addFooterView(footer, null, false);
|
||||
|
||||
mSubkeyAddFabLayout = (ViewAnimator) view.findViewById(R.id.view_key_subkey_fab_layout);
|
||||
view.findViewById(R.id.view_key_subkey_fab).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
addSubkey();
|
||||
}
|
||||
});
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
@@ -90,7 +149,7 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
|
||||
|
||||
// Prepare the loaders. Either re-connect with an existing ones,
|
||||
// or start new ones.
|
||||
getLoaderManager().initLoader(0, null, this);
|
||||
getLoaderManager().initLoader(LOADER_ID_SUBKEYS, null, this);
|
||||
}
|
||||
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
@@ -122,4 +181,215 @@ public class ViewKeyAdvSubkeysFragment extends LoaderFragment implements
|
||||
mSubkeysAdapter.swapCursor(null);
|
||||
}
|
||||
|
||||
private void enterEditMode() {
|
||||
FragmentActivity activity = getActivity();
|
||||
activity.startActionMode(new Callback() {
|
||||
@Override
|
||||
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
||||
|
||||
mEditModeSaveKeyringParcel = new SaveKeyringParcel(0L, new byte[0]);
|
||||
|
||||
mSubkeysAddedAdapter =
|
||||
new SubkeysAddedAdapter(getActivity(), mEditModeSaveKeyringParcel.mAddSubKeys, false);
|
||||
mSubkeysAddedList.setAdapter(mSubkeysAddedAdapter);
|
||||
mSubkeysAddedLayout.setVisibility(View.VISIBLE);
|
||||
mSubkeyAddFabLayout.setDisplayedChild(1);
|
||||
|
||||
mSubkeysAdapter.setEditMode(mEditModeSaveKeyringParcel);
|
||||
getLoaderManager().restartLoader(LOADER_ID_SUBKEYS, null, ViewKeyAdvSubkeysFragment.this);
|
||||
|
||||
mode.setTitle(R.string.title_edit_subkeys);
|
||||
mode.getMenuInflater().inflate(R.menu.action_edit_uids, menu);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||
mode.finish();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyActionMode(ActionMode mode) {
|
||||
mEditModeSaveKeyringParcel = null;
|
||||
mSubkeysAdapter.setEditMode(null);
|
||||
mSubkeysAddedLayout.setVisibility(View.GONE);
|
||||
mSubkeyAddFabLayout.setDisplayedChild(0);
|
||||
getLoaderManager().restartLoader(0, null, ViewKeyAdvSubkeysFragment.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.menu_edit_subkeys:
|
||||
enterEditMode();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
private void addSubkey() {
|
||||
boolean willBeMasterKey;
|
||||
if (mSubkeysAdapter != null) {
|
||||
willBeMasterKey = mSubkeysAdapter.getCount() == 0 && mSubkeysAddedAdapter.getCount() == 0;
|
||||
} else {
|
||||
willBeMasterKey = mSubkeysAddedAdapter.getCount() == 0;
|
||||
}
|
||||
|
||||
AddSubkeyDialogFragment addSubkeyDialogFragment =
|
||||
AddSubkeyDialogFragment.newInstance(willBeMasterKey);
|
||||
addSubkeyDialogFragment
|
||||
.setOnAlgorithmSelectedListener(
|
||||
new AddSubkeyDialogFragment.OnAlgorithmSelectedListener() {
|
||||
@Override
|
||||
public void onAlgorithmSelected(SaveKeyringParcel.SubkeyAdd newSubkey) {
|
||||
mSubkeysAddedAdapter.add(newSubkey);
|
||||
}
|
||||
}
|
||||
);
|
||||
addSubkeyDialogFragment.show(getActivity().getSupportFragmentManager(), "addSubkeyDialog");
|
||||
}
|
||||
|
||||
private void editSubkey(final int position) {
|
||||
final long keyId = mSubkeysAdapter.getKeyId(position);
|
||||
|
||||
Handler returnHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
switch (message.what) {
|
||||
case EditSubkeyDialogFragment.MESSAGE_CHANGE_EXPIRY:
|
||||
editSubkeyExpiry(position);
|
||||
break;
|
||||
case EditSubkeyDialogFragment.MESSAGE_REVOKE:
|
||||
// toggle
|
||||
if (mEditModeSaveKeyringParcel.mRevokeSubKeys.contains(keyId)) {
|
||||
mEditModeSaveKeyringParcel.mRevokeSubKeys.remove(keyId);
|
||||
} else {
|
||||
mEditModeSaveKeyringParcel.mRevokeSubKeys.add(keyId);
|
||||
}
|
||||
break;
|
||||
case EditSubkeyDialogFragment.MESSAGE_STRIP: {
|
||||
SecretKeyType secretKeyType = mSubkeysAdapter.getSecretKeyType(position);
|
||||
if (secretKeyType == SecretKeyType.GNU_DUMMY) {
|
||||
// Key is already stripped; this is a no-op.
|
||||
break;
|
||||
}
|
||||
|
||||
SubkeyChange change = mEditModeSaveKeyringParcel.getSubkeyChange(keyId);
|
||||
if (change == null) {
|
||||
mEditModeSaveKeyringParcel.mChangeSubKeys.add(new SubkeyChange(keyId, true, false));
|
||||
break;
|
||||
}
|
||||
// toggle
|
||||
change.mDummyStrip = !change.mDummyStrip;
|
||||
if (change.mDummyStrip && change.mMoveKeyToCard) {
|
||||
// User had chosen to divert key, but now wants to strip it instead.
|
||||
change.mMoveKeyToCard = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EditSubkeyDialogFragment.MESSAGE_MOVE_KEY_TO_CARD: {
|
||||
// TODO: enable later when Admin PIN handling is resolved
|
||||
Notify.create(getActivity(),
|
||||
"This feature will be available in an upcoming OpenKeychain version.",
|
||||
Notify.Style.WARN).show();
|
||||
break;
|
||||
|
||||
// Activity activity = EditKeyFragment.this.getActivity();
|
||||
// SecretKeyType secretKeyType = mSubkeysAdapter.getSecretKeyType(position);
|
||||
// if (secretKeyType == SecretKeyType.DIVERT_TO_CARD ||
|
||||
// secretKeyType == SecretKeyType.GNU_DUMMY) {
|
||||
// Notify.create(activity, R.string.edit_key_error_bad_nfc_stripped, Notify.Style.ERROR)
|
||||
// .show((ViewGroup) activity.findViewById(R.id.import_snackbar));
|
||||
// break;
|
||||
// }
|
||||
// int algorithm = mSubkeysAdapter.getAlgorithm(position);
|
||||
// // these are the PGP constants for RSA_GENERAL, RSA_ENCRYPT and RSA_SIGN
|
||||
// if (algorithm != 1 && algorithm != 2 && algorithm != 3) {
|
||||
// Notify.create(activity, R.string.edit_key_error_bad_nfc_algo, Notify.Style.ERROR)
|
||||
// .show((ViewGroup) activity.findViewById(R.id.import_snackbar));
|
||||
// break;
|
||||
// }
|
||||
// if (mSubkeysAdapter.getKeySize(position) != 2048) {
|
||||
// Notify.create(activity, R.string.edit_key_error_bad_nfc_size, Notify.Style.ERROR)
|
||||
// .show((ViewGroup) activity.findViewById(R.id.import_snackbar));
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// SubkeyChange change;
|
||||
// change = mSaveKeyringParcel.getSubkeyChange(keyId);
|
||||
// if (change == null) {
|
||||
// mSaveKeyringParcel.mChangeSubKeys.add(
|
||||
// new SubkeyChange(keyId, false, true)
|
||||
// );
|
||||
// break;
|
||||
// }
|
||||
// // toggle
|
||||
// change.mMoveKeyToCard = !change.mMoveKeyToCard;
|
||||
// if (change.mMoveKeyToCard && change.mDummyStrip) {
|
||||
// // User had chosen to strip key, but now wants to divert it.
|
||||
// change.mDummyStrip = false;
|
||||
// }
|
||||
// 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 editSubkeyExpiry(final int position) {
|
||||
final long keyId = mSubkeysAdapter.getKeyId(position);
|
||||
final Long creationDate = mSubkeysAdapter.getCreationDate(position);
|
||||
final Long expiryDate = mSubkeysAdapter.getExpiryDate(position);
|
||||
|
||||
Handler returnHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message message) {
|
||||
switch (message.what) {
|
||||
case EditSubkeyExpiryDialogFragment.MESSAGE_NEW_EXPIRY:
|
||||
mEditModeSaveKeyringParcel.getOrCreateSubkeyChange(keyId).mExpiry =
|
||||
(Long) message.getData().getSerializable(
|
||||
EditSubkeyExpiryDialogFragment.MESSAGE_DATA_EXPIRY);
|
||||
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() {
|
||||
EditSubkeyExpiryDialogFragment dialogFragment =
|
||||
EditSubkeyExpiryDialogFragment.newInstance(messenger, creationDate, expiryDate);
|
||||
|
||||
dialogFragment.show(getActivity().getSupportFragmentManager(), "editSubkeyExpiryDialog");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -101,8 +101,8 @@ public class ViewKeyAdvUserIdsFragment extends LoaderFragment implements
|
||||
footer.setLayoutParams(params);
|
||||
mUserIdsAddedList.addFooterView(footer, null, false);
|
||||
|
||||
mUserIdAddFabLayout = (ViewAnimator) view.findViewById(R.id.view_key_user_id_fab_layout);
|
||||
view.findViewById(R.id.view_key_user_id_fab).setOnClickListener(new View.OnClickListener() {
|
||||
mUserIdAddFabLayout = (ViewAnimator) view.findViewById(R.id.view_key_subkey_fab_layout);
|
||||
view.findViewById(R.id.view_key_subkey_fab).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
addUserId();
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.content.res.ColorStateList;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.Typeface;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.widget.CursorAdapter;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
@@ -49,7 +50,7 @@ public class SubkeysAdapter extends CursorAdapter {
|
||||
private LayoutInflater mInflater;
|
||||
private SaveKeyringParcel mSaveKeyringParcel;
|
||||
|
||||
private boolean hasAnySecret;
|
||||
private boolean mHasAnySecret;
|
||||
private ColorStateList mDefaultTextColor;
|
||||
|
||||
public static final String[] SUBKEYS_PROJECTION = new String[]{
|
||||
@@ -85,16 +86,10 @@ public class SubkeysAdapter extends CursorAdapter {
|
||||
private static final int INDEX_EXPIRY = 13;
|
||||
private static final int INDEX_FINGERPRINT = 14;
|
||||
|
||||
public SubkeysAdapter(Context context, Cursor c, int flags,
|
||||
SaveKeyringParcel saveKeyringParcel) {
|
||||
public SubkeysAdapter(Context context, Cursor c, int flags) {
|
||||
super(context, c, flags);
|
||||
|
||||
mInflater = LayoutInflater.from(context);
|
||||
mSaveKeyringParcel = saveKeyringParcel;
|
||||
}
|
||||
|
||||
public SubkeysAdapter(Context context, Cursor c, int flags) {
|
||||
this(context, c, flags, null);
|
||||
}
|
||||
|
||||
public long getKeyId(int position) {
|
||||
@@ -133,12 +128,12 @@ public class SubkeysAdapter extends CursorAdapter {
|
||||
|
||||
@Override
|
||||
public Cursor swapCursor(Cursor newCursor) {
|
||||
hasAnySecret = false;
|
||||
mHasAnySecret = false;
|
||||
if (newCursor != null && newCursor.moveToFirst()) {
|
||||
do {
|
||||
SecretKeyType hasSecret = SecretKeyType.fromNum(newCursor.getInt(INDEX_HAS_SECRET));
|
||||
if (hasSecret.isUsable()) {
|
||||
hasAnySecret = true;
|
||||
mHasAnySecret = true;
|
||||
break;
|
||||
}
|
||||
} while (newCursor.moveToNext());
|
||||
@@ -354,4 +349,18 @@ public class SubkeysAdapter extends CursorAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
/** Set this adapter into edit mode. This mode displays additional info for
|
||||
* each item from a supplied SaveKeyringParcel reference.
|
||||
*
|
||||
* Note that it is up to the caller to reload the underlying cursor after
|
||||
* updating the SaveKeyringParcel!
|
||||
*
|
||||
* @see SaveKeyringParcel
|
||||
*
|
||||
* @param saveKeyringParcel The parcel to get info from, or null to leave edit mode.
|
||||
*/
|
||||
public void setEditMode(@Nullable SaveKeyringParcel saveKeyringParcel) {
|
||||
mSaveKeyringParcel = saveKeyringParcel;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:id="@+id/view_key_user_id_fab_layout"
|
||||
android:id="@+id/view_key_subkey_fab_layout"
|
||||
android:inAnimation="@anim/fab_slide_in"
|
||||
android:outAnimation="@anim/fab_slide_down">
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/view_key_user_id_fab"
|
||||
android:id="@+id/view_key_subkey_fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="24dp"
|
||||
|
||||
@@ -1,34 +1,88 @@
|
||||
<?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_height="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:descendantFocusability="beforeDescendants"
|
||||
android:orientation="vertical">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
style="@style/SectionHeader"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:text="@string/section_keys" />
|
||||
|
||||
<FrameLayout
|
||||
<!-- focusable and related properties to workaround http://stackoverflow.com/q/16182331-->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="wrap_content"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:descendantFocusability="beforeDescendants"
|
||||
android:orientation="vertical"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp">
|
||||
|
||||
<ListView
|
||||
<TextView
|
||||
style="@style/SectionHeader"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/section_keys"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<org.sufficientlysecure.keychain.ui.widget.FixedListView
|
||||
android:id="@+id/keys"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbarStyle="outsideOverlay"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:layout_marginBottom="8dp" />
|
||||
</FrameLayout>
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_weight="1"
|
||||
android:scrollbarStyle="outsideOverlay" />
|
||||
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:id="@+id/view_key_subkeys_add_layout"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dip"
|
||||
android:background="?android:attr/listDivider" />
|
||||
|
||||
<org.sufficientlysecure.keychain.ui.widget.FixedListView
|
||||
android:id="@+id/view_key_subkeys_added"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
<ViewAnimator
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:id="@+id/view_key_subkey_fab_layout"
|
||||
android:inAnimation="@anim/fab_slide_in"
|
||||
android:outAnimation="@anim/fab_slide_down">
|
||||
|
||||
<Space
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/view_key_subkey_fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="24dp"
|
||||
android:src="@drawable/ic_person_add_grey_24dp"
|
||||
android:visibility="invisible"
|
||||
android:layout_gravity="bottom"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</ViewAnimator>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
12
OpenKeychain/src/main/res/menu/edit_subkeys.xml
Normal file
12
OpenKeychain/src/main/res/menu/edit_subkeys.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_edit_subkeys"
|
||||
android:icon="@drawable/ic_mode_edit_white_24dp"
|
||||
android:title="@string/key_view_action_edit_subkeys"
|
||||
app:showAsAction="always"
|
||||
/>
|
||||
|
||||
</menu>
|
||||
@@ -5,7 +5,7 @@
|
||||
<item
|
||||
android:id="@+id/menu_edit_user_ids"
|
||||
android:icon="@drawable/ic_mode_edit_white_24dp"
|
||||
android:title="@string/key_view_action_edit"
|
||||
android:title="@string/key_view_action_edit_ids"
|
||||
app:showAsAction="always"
|
||||
/>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
android:icon="@drawable/ic_mode_edit_white_24dp"
|
||||
android:visible="false"
|
||||
app:showAsAction="always"
|
||||
android:title="@string/key_view_action_edit" />
|
||||
android:title="@string/key_view_action_edit_ids" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_key_view_refresh"
|
||||
|
||||
@@ -385,7 +385,7 @@
|
||||
<string name="key_list_empty_text1">Žádný klíč nenalezen!</string>
|
||||
<string name="key_list_filter_show_all">Zobrazit všechny klíče</string>
|
||||
<!--Key view-->
|
||||
<string name="key_view_action_edit">Editovat klíč</string>
|
||||
<string name="key_view_action_edit_ids">Editovat klíč</string>
|
||||
<string name="key_view_action_encrypt">Zašifrovat text</string>
|
||||
<string name="key_view_action_encrypt_files">soubory</string>
|
||||
<string name="key_view_action_certify">Potvrdit klíč</string>
|
||||
|
||||
@@ -572,7 +572,7 @@
|
||||
<string name="key_list_fab_search">Schlüsselsuche</string>
|
||||
<string name="key_list_fab_import">Aus Datei importieren</string>
|
||||
<!--Key view-->
|
||||
<string name="key_view_action_edit">Schlüssel bearbeiten</string>
|
||||
<string name="key_view_action_edit_ids">Schlüssel bearbeiten</string>
|
||||
<string name="key_view_action_encrypt">Text verschlüsseln</string>
|
||||
<string name="key_view_action_encrypt_files">Dateien</string>
|
||||
<string name="key_view_action_certify">Schlüssel bestätigen</string>
|
||||
|
||||
@@ -581,7 +581,7 @@
|
||||
<string name="key_list_fab_search">Búsqueda de clave</string>
|
||||
<string name="key_list_fab_import">Importar desde fichero</string>
|
||||
<!--Key view-->
|
||||
<string name="key_view_action_edit">Editar clave</string>
|
||||
<string name="key_view_action_edit_ids">Editar clave</string>
|
||||
<string name="key_view_action_encrypt">Cifrar texto</string>
|
||||
<string name="key_view_action_encrypt_files">ficheros</string>
|
||||
<string name="key_view_action_certify">Confirmar clave</string>
|
||||
|
||||
@@ -576,7 +576,7 @@
|
||||
<string name="key_list_fab_search">Giltza Bilaketa</string>
|
||||
<string name="key_list_fab_import">Inportatu Agiritik</string>
|
||||
<!--Key view-->
|
||||
<string name="key_view_action_edit">Editatu giltza</string>
|
||||
<string name="key_view_action_edit_ids">Editatu giltza</string>
|
||||
<string name="key_view_action_encrypt">Enkriptatu idazkia</string>
|
||||
<string name="key_view_action_encrypt_files">agiriak</string>
|
||||
<string name="key_view_action_certify">Baieztatu giltza</string>
|
||||
|
||||
@@ -586,7 +586,7 @@
|
||||
<string name="key_list_fab_search">Recherche de clefs</string>
|
||||
<string name="key_list_fab_import">Importer d\'un fichier</string>
|
||||
<!--Key view-->
|
||||
<string name="key_view_action_edit">Modifier la clef</string>
|
||||
<string name="key_view_action_edit_ids">Modifier la clef</string>
|
||||
<string name="key_view_action_encrypt">Chiffrer un texte</string>
|
||||
<string name="key_view_action_encrypt_files">fichiers</string>
|
||||
<string name="key_view_action_certify">Confirmer la clef</string>
|
||||
|
||||
@@ -441,7 +441,7 @@ Permetti accesso?\n\nATTENZIONE: Se non sai perche\' questo schermata e\' appars
|
||||
<string name="key_list_empty_text1">Nessuna chiave trovata!</string>
|
||||
<string name="key_list_filter_show_all">Mostra tutte le chiavi</string>
|
||||
<!--Key view-->
|
||||
<string name="key_view_action_edit">Modifica chiave</string>
|
||||
<string name="key_view_action_edit_ids">Modifica chiave</string>
|
||||
<string name="key_view_action_encrypt">Codifica Testo</string>
|
||||
<string name="key_view_action_encrypt_files">documenti</string>
|
||||
<string name="key_view_action_update">Aggiorna dal server delle chiavi</string>
|
||||
|
||||
@@ -573,7 +573,7 @@
|
||||
<string name="key_list_fab_search">鍵の検索</string>
|
||||
<string name="key_list_fab_import">ファイルからインポート</string>
|
||||
<!--Key view-->
|
||||
<string name="key_view_action_edit">鍵の編集</string>
|
||||
<string name="key_view_action_edit_ids">鍵の編集</string>
|
||||
<string name="key_view_action_encrypt">テキスト暗号化</string>
|
||||
<string name="key_view_action_encrypt_files">ファイル</string>
|
||||
<string name="key_view_action_certify">鍵の確認</string>
|
||||
|
||||
@@ -489,7 +489,7 @@
|
||||
<string name="key_list_empty_text1">Geen sleutels gevonden!</string>
|
||||
<string name="key_list_filter_show_all">Alle sleutels weergeven</string>
|
||||
<!--Key view-->
|
||||
<string name="key_view_action_edit">Sleutel bewerken</string>
|
||||
<string name="key_view_action_edit_ids">Sleutel bewerken</string>
|
||||
<string name="key_view_action_encrypt">Versleutel tekst</string>
|
||||
<string name="key_view_action_encrypt_files">bestanden</string>
|
||||
<string name="key_view_action_certify">Sleutel bevestigen</string>
|
||||
|
||||
@@ -373,7 +373,7 @@ OSTRZEŻENIE: Jeżeli nie wiesz, czemu wyświetlił się ten komunikat, nie zezw
|
||||
<string name="key_list_empty_text1">Nie znaleziono kluczy!</string>
|
||||
<string name="key_list_filter_show_all">Pokaż wszystkie klucze</string>
|
||||
<!--Key view-->
|
||||
<string name="key_view_action_edit">Edytuj klucz</string>
|
||||
<string name="key_view_action_edit_ids">Edytuj klucz</string>
|
||||
<string name="key_view_action_encrypt">Szyfruj tekst</string>
|
||||
<string name="key_view_action_encrypt_files">pliki</string>
|
||||
<string name="key_view_action_update">Aktualizuj z serwera kluczy</string>
|
||||
|
||||
@@ -487,7 +487,7 @@
|
||||
<string name="key_list_filter_show_all">Показать все ключи</string>
|
||||
<string name="key_list_fab_search">Поиск ключа</string>
|
||||
<!--Key view-->
|
||||
<string name="key_view_action_edit">Изменить ключ</string>
|
||||
<string name="key_view_action_edit_ids">Изменить ключ</string>
|
||||
<string name="key_view_action_encrypt">Зашифровать текст</string>
|
||||
<string name="key_view_action_encrypt_files">файлы</string>
|
||||
<string name="key_view_action_certify">Подтвердить ключ</string>
|
||||
|
||||
@@ -426,7 +426,7 @@
|
||||
<string name="key_list_empty_text1">Najden ni bil noben ključ!</string>
|
||||
<string name="key_list_filter_show_all">Prikaži vse ključe</string>
|
||||
<!--Key view-->
|
||||
<string name="key_view_action_edit">Uredi ključ</string>
|
||||
<string name="key_view_action_edit_ids">Uredi ključ</string>
|
||||
<string name="key_view_action_encrypt">Šifriraj besedilo</string>
|
||||
<string name="key_view_action_encrypt_files">datoteke</string>
|
||||
<string name="key_view_action_certify">Potrdi ključ</string>
|
||||
|
||||
@@ -600,7 +600,7 @@
|
||||
<string name="key_list_fab_search">Претрага кључа</string>
|
||||
<string name="key_list_fab_import">Увези из фајла</string>
|
||||
<!--Key view-->
|
||||
<string name="key_view_action_edit">Уреди кључ</string>
|
||||
<string name="key_view_action_edit_ids">Уреди кључ</string>
|
||||
<string name="key_view_action_encrypt">Шифруј текст</string>
|
||||
<string name="key_view_action_encrypt_files">фајлови</string>
|
||||
<string name="key_view_action_certify">Потврди кључ</string>
|
||||
|
||||
@@ -476,7 +476,7 @@
|
||||
<string name="key_list_fab_search">Nyckelsökning</string>
|
||||
<string name="key_list_fab_import">Importera från fil</string>
|
||||
<!--Key view-->
|
||||
<string name="key_view_action_edit">Redigera nyckel</string>
|
||||
<string name="key_view_action_edit_ids">Redigera nyckel</string>
|
||||
<string name="key_view_action_encrypt">Kryptera text</string>
|
||||
<string name="key_view_action_encrypt_files">filer</string>
|
||||
<string name="key_view_action_certify">Bekräfta nyckel</string>
|
||||
|
||||
@@ -302,7 +302,7 @@
|
||||
</plurals>
|
||||
<string name="key_list_filter_show_all">Tüm anahtarları göster</string>
|
||||
<!--Key view-->
|
||||
<string name="key_view_action_edit">Anahtarı düzenle</string>
|
||||
<string name="key_view_action_edit_ids">Anahtarı düzenle</string>
|
||||
<string name="key_view_action_encrypt">Metni şifrele</string>
|
||||
<string name="key_view_action_encrypt_files">dosyalar</string>
|
||||
<string name="key_view_action_update">Anahtar sunucusundan güncelle</string>
|
||||
|
||||
@@ -309,7 +309,7 @@
|
||||
<string name="key_list_empty_text1">Ключ не знайдено!</string>
|
||||
<string name="key_list_filter_show_all">Показати усі ключі</string>
|
||||
<!--Key view-->
|
||||
<string name="key_view_action_edit">Редагувати ключ</string>
|
||||
<string name="key_view_action_edit_ids">Редагувати ключ</string>
|
||||
<string name="key_view_action_encrypt">Зашифрувати текст</string>
|
||||
<string name="key_view_action_encrypt_files">файли</string>
|
||||
<string name="key_view_action_update">Оновити із сервера ключів</string>
|
||||
|
||||
@@ -479,7 +479,7 @@
|
||||
<!--Key list-->
|
||||
<string name="key_list_empty_text1">找不到金鑰!</string>
|
||||
<!--Key view-->
|
||||
<string name="key_view_action_edit">編輯金鑰</string>
|
||||
<string name="key_view_action_edit_ids">編輯金鑰</string>
|
||||
<string name="key_view_action_encrypt">加密文字</string>
|
||||
<string name="key_view_action_encrypt_files">檔案</string>
|
||||
<string name="key_view_action_share_with">分享...</string>
|
||||
|
||||
@@ -666,7 +666,8 @@
|
||||
<string name="key_list_fab_import">"Import from File"</string>
|
||||
|
||||
<!-- Key view -->
|
||||
<string name="key_view_action_edit">"Edit key"</string>
|
||||
<string name="key_view_action_edit_ids">"Edit Identities"</string>
|
||||
<string name="key_view_action_edit_subkeys">"Edit Subkeys"</string>
|
||||
<string name="key_view_action_encrypt">"Encrypt text"</string>
|
||||
<string name="key_view_action_encrypt_files">"files"</string>
|
||||
<string name="key_view_action_certify">"Confirm key"</string>
|
||||
@@ -1707,5 +1708,7 @@
|
||||
<string name="menu_uids_save">Save</string>
|
||||
<string name="menu_uids_save">"Save"</string>
|
||||
<string name="title_edit_identities">"Edit Identities"</string>
|
||||
<string name="title_edit_subkeys">"Edit Subkeys"</string>
|
||||
<string name="btn_search_for_query">"Search for\n'%s'"</string>
|
||||
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user