Actually save key in identity select dialog, and some more design updates

This commit is contained in:
Vincent Breitmoser
2018-03-30 22:20:44 +02:00
parent b92ff86988
commit 336c43cfde
6 changed files with 286 additions and 57 deletions

View File

@@ -31,6 +31,7 @@ import android.content.res.Resources;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable.ConstantState; import android.graphics.drawable.Drawable.ConstantState;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.transition.Fade; import android.support.transition.Fade;
import android.support.transition.Transition; import android.support.transition.Transition;
@@ -50,18 +51,26 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnDismissListener;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import com.mikepenz.materialdrawer.util.KeyboardUtil; import com.mikepenz.materialdrawer.util.KeyboardUtil;
import org.openintents.openpgp.util.OpenPgpApi; import org.openintents.openpgp.util.OpenPgpApi;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.livedata.KeyInfoInteractor.KeyInfo; import org.sufficientlysecure.keychain.livedata.KeyInfoInteractor.KeyInfo;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.remote.ui.dialog.RemoteSelectIdentityKeyPresenter.RemoteSelectIdentityKeyView; import org.sufficientlysecure.keychain.remote.ui.dialog.RemoteSelectIdentityKeyPresenter.RemoteSelectIdentityKeyView;
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper.AbstractCallback;
import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder; import org.sufficientlysecure.keychain.ui.dialog.CustomAlertDialogBuilder;
import org.sufficientlysecure.keychain.ui.util.ThemeChanger; import org.sufficientlysecure.keychain.ui.util.ThemeChanger;
import org.sufficientlysecure.keychain.ui.util.recyclerview.DividerItemDecoration; import org.sufficientlysecure.keychain.ui.util.recyclerview.DividerItemDecoration;
import org.sufficientlysecure.keychain.ui.util.recyclerview.RecyclerItemClickListener; import org.sufficientlysecure.keychain.ui.util.recyclerview.RecyclerItemClickListener;
import org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator; import org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator;
import timber.log.Timber;
public class RemoteSelectIdKeyActivity extends FragmentActivity { public class RemoteSelectIdKeyActivity extends FragmentActivity {
@@ -71,6 +80,7 @@ public class RemoteSelectIdKeyActivity extends FragmentActivity {
private RemoteSelectIdentityKeyPresenter presenter; private RemoteSelectIdentityKeyPresenter presenter;
private Parcelable currentlyImportingParcel;
@Override @Override
@@ -115,6 +125,7 @@ public class RemoteSelectIdKeyActivity extends FragmentActivity {
private View buttonNoKeysCancel; private View buttonNoKeysCancel;
private View buttonNoKeysExisting; private View buttonNoKeysExisting;
private View buttonKeyListOther; private View buttonKeyListOther;
private View buttonOverflow;
@NonNull @NonNull
@Override @Override
@@ -129,6 +140,8 @@ public class RemoteSelectIdKeyActivity extends FragmentActivity {
ViewGroup view = (ViewGroup) layoutInflater.inflate(R.layout.api_select_identity_key, null, false); ViewGroup view = (ViewGroup) layoutInflater.inflate(R.layout.api_select_identity_key, null, false);
alert.setView(view); alert.setView(view);
buttonOverflow = view.findViewById(R.id.overflow_menu);
buttonKeyListCancel = view.findViewById(R.id.button_key_list_cancel); buttonKeyListCancel = view.findViewById(R.id.button_key_list_cancel);
buttonKeyListOther = view.findViewById(R.id.button_key_list_other); buttonKeyListOther = view.findViewById(R.id.button_key_list_other);
@@ -182,7 +195,7 @@ public class RemoteSelectIdKeyActivity extends FragmentActivity {
@NonNull @NonNull
private RemoteSelectIdentityKeyView createMvpView(final ViewGroup rootView, LayoutInflater layoutInflater) { private RemoteSelectIdentityKeyView createMvpView(final ViewGroup rootView, LayoutInflater layoutInflater) {
final ImageView iconClientApp = rootView.findViewById(R.id.icon_client_app); // final ImageView iconClientApp = rootView.findViewById(R.id.icon_client_app);
final KeyChoiceAdapter keyChoiceAdapter = new KeyChoiceAdapter(layoutInflater, getResources()); final KeyChoiceAdapter keyChoiceAdapter = new KeyChoiceAdapter(layoutInflater, getResources());
final TextView titleText = rootView.findViewById(R.id.text_title_select_key); final TextView titleText = rootView.findViewById(R.id.text_title_select_key);
final TextView addressText = rootView.findViewById(R.id.text_user_id); final TextView addressText = rootView.findViewById(R.id.text_user_id);
@@ -217,7 +230,7 @@ public class RemoteSelectIdKeyActivity extends FragmentActivity {
@Override @Override
public void setTitleClientIconAndName(Drawable drawable, CharSequence name) { public void setTitleClientIconAndName(Drawable drawable, CharSequence name) {
titleText.setText(getString(R.string.title_select_key, name)); titleText.setText(getString(R.string.title_select_key, name));
iconClientApp.setImageDrawable(drawable); // iconClientApp.setImageDrawable(drawable);
setSelectionIcons(drawable); setSelectionIcons(drawable);
} }
@@ -270,6 +283,11 @@ public class RemoteSelectIdKeyActivity extends FragmentActivity {
layoutAnimator.setDisplayedChildId(R.id.select_key_layout_generate_ok); layoutAnimator.setDisplayedChildId(R.id.select_key_layout_generate_ok);
} }
@Override
public void showLayoutGenerateSave() {
layoutAnimator.setDisplayedChildId(R.id.select_key_layout_generate_save);
}
@Override @Override
public void setKeyListData(List<KeyInfo> data) { public void setKeyListData(List<KeyInfo> data) {
keyChoiceAdapter.setData(data); keyChoiceAdapter.setData(data);
@@ -292,10 +310,26 @@ public class RemoteSelectIdKeyActivity extends FragmentActivity {
buttonKeyListCancel.setVisibility(View.INVISIBLE); buttonKeyListCancel.setVisibility(View.INVISIBLE);
keyChoiceAdapter.setActiveItem(position); keyChoiceAdapter.setActiveItem(position);
} }
@Override
public void showImportInternalError() {
Toast.makeText(getContext(), R.string.error_save_key_internal, Toast.LENGTH_LONG).show();
}
@Override
public void launchImportOperation(ImportKeyringParcel importKeyringParcel) {
RemoteSelectIdKeyActivity activity = (RemoteSelectIdKeyActivity) getActivity();
if (activity == null) {
return;
}
activity.launchImportOperation(importKeyringParcel);
}
}; };
} }
private void setupListenersForPresenter() { private void setupListenersForPresenter() {
buttonOverflow.setOnClickListener(this::showContextMenu);
buttonKeyListOther.setOnClickListener(view -> presenter.onClickKeyListOther()); buttonKeyListOther.setOnClickListener(view -> presenter.onClickKeyListOther());
buttonKeyListCancel.setOnClickListener(view -> presenter.onClickKeyListCancel()); buttonKeyListCancel.setOnClickListener(view -> presenter.onClickKeyListCancel());
@@ -312,6 +346,23 @@ public class RemoteSelectIdKeyActivity extends FragmentActivity {
keyChoiceList.addOnItemTouchListener(new RecyclerItemClickListener(getContext(), keyChoiceList.addOnItemTouchListener(new RecyclerItemClickListener(getContext(),
(view, position) -> presenter.onKeyItemClick(position))); (view, position) -> presenter.onKeyItemClick(position)));
} }
private void showContextMenu(View view) {
PopupMenu menu = new PopupMenu(getActivity(), view);
menu.inflate(R.menu.identity_context_menu);
// menu.setOnMenuItemClickListener(DecryptListFragment.this);
menu.show();
}
}
private void launchImportOperation(ImportKeyringParcel importKeyringParcel) {
if (currentlyImportingParcel != null) {
Timber.e("Starting import while already running? Inconsistent state!");
return;
}
currentlyImportingParcel = importKeyringParcel;
importOpHelper.cryptoOperation();
} }
private static class KeyChoiceAdapter extends Adapter<KeyChoiceViewHolder> { private static class KeyChoiceAdapter extends Adapter<KeyChoiceViewHolder> {
@@ -333,21 +384,21 @@ public class RemoteSelectIdKeyActivity extends FragmentActivity {
return new KeyChoiceViewHolder(keyChoiceItemView); return new KeyChoiceViewHolder(keyChoiceItemView);
} }
public void setActiveItem(Integer activeItem) { void setActiveItem(Integer activeItem) {
if (this.activeItem != null) {
notifyItemChanged(activeItem);
}
this.activeItem = activeItem; this.activeItem = activeItem;
if (this.activeItem != null) { notifyDataSetChanged();
notifyItemChanged(activeItem);
}
} }
@Override @Override
public void onBindViewHolder(KeyChoiceViewHolder holder, int position) { public void onBindViewHolder(KeyChoiceViewHolder holder, int position) {
KeyInfo keyInfo = data.get(position); KeyInfo keyInfo = data.get(position);
Drawable icon = (activeItem != null && position == activeItem) ? iconSelected : iconUnselected; boolean hasActiveItem = activeItem != null;
boolean isActiveItem = hasActiveItem && position == activeItem;
Drawable icon = isActiveItem ? iconSelected : iconUnselected;
holder.bind(keyInfo, icon); holder.bind(keyInfo, icon);
holder.itemView.setVisibility(!hasActiveItem || isActiveItem ? View.VISIBLE : View.INVISIBLE);
} }
@Override @Override
@@ -400,4 +451,34 @@ public class RemoteSelectIdKeyActivity extends FragmentActivity {
} }
} }
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (importOpHelper.handleActivityResult(requestCode, resultCode, data)) {
return;
}
super.onActivityResult(requestCode, resultCode, data);
}
private CryptoOperationHelper<Parcelable, ImportKeyResult> importOpHelper =
new CryptoOperationHelper<>(0, this,
new AbstractCallback<Parcelable, ImportKeyResult>() {
@Override
public Parcelable createOperationInput() {
return currentlyImportingParcel;
}
@Override
public void onCryptoOperationError(ImportKeyResult result) {
currentlyImportingParcel = null;
presenter.onImportOpError();
}
@Override
public void onCryptoOperationSuccess(ImportKeyResult result) {
currentlyImportingParcel = null;
presenter.onImportOpSuccess(result);
}
}, null);
} }

View File

@@ -12,7 +12,6 @@ public class RemoteSelectIdViewModel extends ViewModel {
private KeyInfoLiveData keyInfo; private KeyInfoLiveData keyInfo;
private PgpKeyGenerationLiveData keyGenerationData; private PgpKeyGenerationLiveData keyGenerationData;
public long selectedMasterKeyId;
public KeyInfoLiveData getKeyInfo(Context context) { public KeyInfoLiveData getKeyInfo(Context context) {
if (keyInfo == null) { if (keyInfo == null) {

View File

@@ -18,6 +18,7 @@
package org.sufficientlysecure.keychain.remote.ui.dialog; package org.sufficientlysecure.keychain.remote.ui.dialog;
import java.io.IOException;
import java.util.List; import java.util.List;
import android.arch.lifecycle.LifecycleOwner; import android.arch.lifecycle.LifecycleOwner;
@@ -32,9 +33,13 @@ import org.openintents.openpgp.util.OpenPgpUtils.UserId;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.livedata.KeyInfoInteractor.KeyInfo; import org.sufficientlysecure.keychain.livedata.KeyInfoInteractor.KeyInfo;
import org.sufficientlysecure.keychain.livedata.KeyInfoInteractor.KeySelector; import org.sufficientlysecure.keychain.livedata.KeyInfoInteractor.KeySelector;
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult; import org.sufficientlysecure.keychain.operations.results.PgpEditKeyResult;
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings;
import org.sufficientlysecure.keychain.service.ImportKeyringParcel;
import org.sufficientlysecure.keychain.service.SaveKeyringParcel; import org.sufficientlysecure.keychain.service.SaveKeyringParcel;
import org.sufficientlysecure.keychain.ui.base.CryptoOperationHelper;
import timber.log.Timber; import timber.log.Timber;
@@ -44,11 +49,12 @@ class RemoteSelectIdentityKeyPresenter {
private final RemoteSelectIdViewModel viewModel; private final RemoteSelectIdViewModel viewModel;
private UserId userId;
private RemoteSelectIdentityKeyView view; private RemoteSelectIdentityKeyView view;
private List<KeyInfo> keyInfoData; private List<KeyInfo> keyInfoData;
private long masterKeyId;
private UserId userId;
private long selectedMasterKeyId;
private byte[] generatedKeyData;
RemoteSelectIdentityKeyPresenter(Context context, RemoteSelectIdViewModel viewModel, LifecycleOwner lifecycleOwner) { RemoteSelectIdentityKeyPresenter(Context context, RemoteSelectIdViewModel viewModel, LifecycleOwner lifecycleOwner) {
@@ -106,11 +112,18 @@ class RemoteSelectIdentityKeyPresenter {
} }
private void onChangeKeyGeneration(PgpEditKeyResult pgpEditKeyResult) { private void onChangeKeyGeneration(PgpEditKeyResult pgpEditKeyResult) {
viewModel.getKeyGenerationLiveData(context).setSaveKeyringParcel(null);
if (pgpEditKeyResult == null) { if (pgpEditKeyResult == null) {
return; return;
} }
try {
UncachedKeyRing generatedRing = pgpEditKeyResult.getRing();
this.generatedKeyData = generatedRing.getEncoded();
} catch (IOException e) {
throw new AssertionError("Newly generated key ring must be encodable!");
}
viewModel.getKeyGenerationLiveData(context).setSaveKeyringParcel(null);
view.showLayoutGenerateOk(); view.showLayoutGenerateOk();
} }
@@ -145,7 +158,7 @@ class RemoteSelectIdentityKeyPresenter {
} }
void onKeyItemClick(int position) { void onKeyItemClick(int position) {
viewModel.selectedMasterKeyId = keyInfoData.get(position).getMasterKeyId(); selectedMasterKeyId = keyInfoData.get(position).getMasterKeyId();
view.highlightKey(position); view.highlightKey(position);
} }
@@ -162,12 +175,28 @@ class RemoteSelectIdentityKeyPresenter {
} }
void onClickGenerateOkFinish() { void onClickGenerateOkFinish() {
// saveKey if (generatedKeyData == null) {
// view.finishAndReturn return;
}
ImportKeyringParcel importKeyringParcel = ImportKeyringParcel.createFromBytes(generatedKeyData);
generatedKeyData = null;
view.launchImportOperation(importKeyringParcel);
view.showLayoutGenerateSave();
} }
void onHighlightFinished() { void onHighlightFinished() {
view.finishAndReturn(viewModel.selectedMasterKeyId); view.finishAndReturn(selectedMasterKeyId);
}
void onImportOpSuccess(ImportKeyResult result) {
long importedMasterKeyId = result.getImportedMasterKeyIds()[0];
view.finishAndReturn(importedMasterKeyId);
}
void onImportOpError() {
view.showImportInternalError();
} }
interface RemoteSelectIdentityKeyView { interface RemoteSelectIdentityKeyView {
@@ -183,9 +212,14 @@ class RemoteSelectIdentityKeyPresenter {
void showLayoutImportExplanation(); void showLayoutImportExplanation();
void showLayoutGenerateProgress(); void showLayoutGenerateProgress();
void showLayoutGenerateOk(); void showLayoutGenerateOk();
void showLayoutGenerateSave();
void setKeyListData(List<KeyInfo> data); void setKeyListData(List<KeyInfo> data);
void highlightKey(int position); void highlightKey(int position);
void launchImportOperation(ImportKeyringParcel importKeyringParcel);
void showImportInternalError();
} }
} }

View File

@@ -50,6 +50,11 @@ public abstract class ImportKeyringParcel implements Parcelable {
return new AutoValue_ImportKeyringParcel(Collections.singletonList(key), null, false); return new AutoValue_ImportKeyringParcel(Collections.singletonList(key), null, false);
} }
public static ImportKeyringParcel createFromBytes(byte[] keyData) {
ParcelableKeyRing keyRing = ParcelableKeyRing.createFromEncodedBytes(keyData);
return new AutoValue_ImportKeyringParcel(Collections.singletonList(keyRing), null, false);
}
public static ImportKeyringParcel createFromFileCacheWithSkipSave() { public static ImportKeyringParcel createFromFileCacheWithSkipSave() {
return new AutoValue_ImportKeyringParcel(null, null, true); return new AutoValue_ImportKeyringParcel(null, null, true);
} }

View File

@@ -2,8 +2,8 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto" xmlns:custom="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"
tools:layout_marginTop="24dp" tools:layout_marginTop="24dp"
> >
@@ -13,30 +13,37 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?attr/colorPrimary" android:background="?attr/colorPrimary"
android:elevation="4dp" android:elevation="4dp"
android:gravity="center_horizontal"
android:padding="16dp" android:padding="16dp"
android:gravity="center_vertical"
tools:targetApi="lollipop"> tools:targetApi="lollipop">
<ImageView <ImageView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:src="@mipmap/ic_launcher" android:src="@mipmap/ic_launcher"
/> />
<ImageView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_marginLeft="16dp"
android:layout_marginLeft="24dp" android:text="OpenKeychain"
android:layout_marginRight="24dp" style="?android:textAppearanceLarge"
android:src="@drawable/link_24dp" />
<Space
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
/> />
<ImageView <ImageView
android:id="@+id/icon_client_app"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:src="@drawable/apps_k9" android:src="@drawable/ic_more_vert_black_24dp"
android:background="?selectableItemBackground"
android:id="@+id/overflow_menu"
/> />
</LinearLayout> </LinearLayout>
@@ -69,8 +76,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:inAnimation="@anim/fade_in" android:inAnimation="@anim/fade_in"
android:outAnimation="@anim/fade_out" android:outAnimation="@anim/fade_out"
android:measureAllChildren="true" android:measureAllChildren="false"
custom:initialView="05"> custom:initialView="04">
<Space <Space
android:layout_width="wrap_content" android:layout_width="wrap_content"
@@ -138,7 +145,7 @@
android:layout_height="24dp" android:layout_height="24dp"
android:layout_marginLeft="16dp" android:layout_marginLeft="16dp"
android:layout_marginRight="16dp" android:layout_marginRight="16dp"
android:src="@drawable/ic_save_black_24dp" android:src="@drawable/ic_help_black_24dp"
android:tint="@color/md_grey_600" android:tint="@color/md_grey_600"
/> />
@@ -231,7 +238,7 @@
android:layout_height="24dp" android:layout_height="24dp"
android:layout_marginLeft="16dp" android:layout_marginLeft="16dp"
android:layout_marginRight="16dp" android:layout_marginRight="16dp"
android:src="@drawable/ic_save_black_24dp" android:src="@drawable/ic_help_black_24dp"
android:tint="@color/md_grey_600" android:tint="@color/md_grey_600"
/> />
@@ -285,7 +292,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="16dp" android:layout_marginLeft="16dp"
android:layout_marginRight="16dp" android:layout_marginRight="16dp"
android:text="To use an existing end-to-end key, you can either:\n\n① Open Autocrypt Setup Message from another e-mail app in K-9 Mail\n\n② Manually manage keys in OpenKeychain" android:text="To import your key, you can either:\n\n① Open Autocrypt Setup Message from another e-mail app in K-9 Mail\n\n② Manually manage keys in OpenKeychain"
android:textAppearance="?android:attr/textAppearanceMedium" android:textAppearance="?android:attr/textAppearanceMedium"
/> />
@@ -330,35 +337,71 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="?listPreferredItemHeight" android:minHeight="?listPreferredItemHeight"
android:orientation="horizontal" android:orientation="vertical"
android:id="@+id/select_key_layout_generate_progress"
android:layout_marginTop="36dp"
android:paddingLeft="16dp" android:paddingLeft="16dp"
android:paddingRight="16dp"> android:paddingRight="16dp"
android:id="@+id/select_key_layout_generate_progress">
<ProgressBar <LinearLayout
android:layout_width="24dp" android:layout_width="match_parent"
android:layout_height="24dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_gravity="center_vertical"
android:indeterminate="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:minHeight="?listPreferredItemHeight">
android:text="Generating end-to-end key…"
android:textAppearance="?android:attr/textAppearanceMedium" <ProgressBar
/> android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_gravity="center_vertical"
android:indeterminate="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="Please wait…"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?listPreferredItemHeight"
android:background="?selectableItemBackground"
android:orientation="horizontal"
style="?buttonBarStyle">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:text="Back"
style="?buttonBarButtonStyle"
/>
<Space
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:text="Finish"
style="?buttonBarButtonStyle"
/>
</LinearLayout>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="36dp"
android:orientation="vertical" android:orientation="vertical"
android:id="@+id/select_key_layout_generate_ok" android:id="@+id/select_key_layout_generate_ok"
android:paddingLeft="16dp" android:paddingLeft="16dp"
@@ -395,8 +438,7 @@
android:id="@+id/button_gen_back" android:id="@+id/button_gen_back"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom" android:minHeight="?listPreferredItemHeight"
android:layout_marginBottom="8dp"
android:background="?selectableItemBackground" android:background="?selectableItemBackground"
android:orientation="horizontal" android:orientation="horizontal"
style="?buttonBarStyle"> style="?buttonBarStyle">
@@ -426,6 +468,73 @@
</LinearLayout> </LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/select_key_layout_generate_save"
android:paddingLeft="16dp"
android:paddingRight="16dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?listPreferredItemHeight"
android:gravity="center_vertical"
android:orientation="horizontal">
<ProgressBar
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:indeterminate="true"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="Finishing setup…"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?listPreferredItemHeight"
android:background="?selectableItemBackground"
android:orientation="horizontal"
style="?buttonBarStyle">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:text="Back"
style="?buttonBarButtonStyle"
/>
<Space
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="false"
android:text="Finish"
style="?buttonBarButtonStyle"
/>
</LinearLayout>
</LinearLayout>
</org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator> </org.sufficientlysecure.keychain.ui.widget.ToolableViewAnimator>
</LinearLayout> </LinearLayout>

View File

@@ -1991,7 +1991,8 @@
<string name="use_key">Use key: %s</string> <string name="use_key">Use key: %s</string>
<string name="use_key_no_name">Use key: <![CDATA[<no name>]]></string> <string name="use_key_no_name">Use key: <![CDATA[<no name>]]></string>
<string name="title_select_key">%s wants to end-to-end encrypt with this address:</string> <string name="title_select_key">%s wants to set up end-to-end encryption for this address:</string>
<string name="select_identity_cancel">Cancel</string> <string name="select_identity_cancel">Cancel</string>
<string name="select_identity_create">Create a key for me</string> <string name="select_identity_create">Create a key for me</string>
<string name="error_save_key_internal">"Internal error saving key!"</string>
</resources> </resources>