From 0599f0dd4e83e20ddf234d1c1ef1f897b8305b02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 4 Oct 2014 21:09:32 +0200 Subject: Workings on new parcel for key downloads --- .../keychain/service/results/GetKeyResult.java | 64 +++++++++++++++++++ .../keychain/service/results/OperationResult.java | 12 +++- .../keychain/ui/AddKeysActivity.java | 72 +++++++++++++--------- .../keychain/ui/ImportKeysListFragment.java | 65 +++++++++++-------- .../ui/adapter/AsyncTaskResultWrapper.java | 12 ++-- .../ui/adapter/ImportKeysListCloudLoader.java | 32 ++++++++-- .../keychain/ui/adapter/ImportKeysListLoader.java | 18 +++--- OpenKeychain/src/main/res/values/strings.xml | 23 ++++--- 8 files changed, 212 insertions(+), 86 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/GetKeyResult.java (limited to 'OpenKeychain/src') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/GetKeyResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/GetKeyResult.java new file mode 100644 index 000000000..e76d1bd41 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/GetKeyResult.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2014 Dominik Schürmann + * Copyright (C) 2014 Vincent Breitmoser + * + * 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 . + */ + +package org.sufficientlysecure.keychain.service.results; + +import android.os.Parcel; + +public class GetKeyResult extends OperationResult { + + public int mNonPgpPartsCount; + + public int getNonPgpPartsCount() { + return mNonPgpPartsCount; + } + + public void setNonPgpPartsCount(int nonPgpPartsCount) { + mNonPgpPartsCount = nonPgpPartsCount; + } + + public GetKeyResult(int result, OperationLog log) { + super(result, log); + } + + public static final int RESULT_ERROR_NO_VALID_KEYS = RESULT_ERROR + 8; + public static final int RESULT_ERROR_NO_PGP_PARTS = RESULT_ERROR + 16; + public static final int RESULT_ERROR_QUERY_TOO_SHORT = RESULT_ERROR + 32; + public static final int RESULT_ERROR_TOO_MANY_RESPONSES = RESULT_ERROR + 64; + public static final int RESULT_ERROR_TOO_SHORT_OR_TOO_MANY_RESPONSES = RESULT_ERROR + 128; + public static final int RESULT_ERROR_QUERY_FAILED = RESULT_ERROR + 256; + + public GetKeyResult(Parcel source) { + super(source); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + } + + public static Creator CREATOR = new Creator() { + public GetKeyResult createFromParcel(final Parcel source) { + return new GetKeyResult(source); + } + + public GetKeyResult[] newArray(final int size) { + return new GetKeyResult[size]; + } + }; +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/OperationResult.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/OperationResult.java index 5613aa794..c8963bb38 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/OperationResult.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/results/OperationResult.java @@ -538,8 +538,16 @@ public abstract class OperationResult implements Parcelable { MSG_ACC_SAVED (LogLevel.INFO, R.string.api_settings_save_msg), - MSG_NO_VALID_ENC (LogLevel.ERROR, R.string.error_invalid_data) - + MSG_NO_VALID_ENC (LogLevel.ERROR, R.string.error_invalid_data), + + // get key + MSG_GET_SUCCESS(LogLevel.OK, R.string.msg_download_success), + MSG_GET_NO_VALID_KEYS(LogLevel.ERROR, R.string.msg_download_no_valid_keys), + MSG_GET_NO_PGP_PARTS(LogLevel.ERROR, R.string.msg_download_no_pgp_parts), + MSG_GET_QUERY_TOO_SHORT(LogLevel.ERROR, R.string.msg_download_query_too_short), + MSG_GET_TOO_MANY_RESPONSES(LogLevel.ERROR, R.string.msg_download_too_many_responses), + MSG_GET_QUERY_TOO_SHORT_OR_TOO_MANY_RESPONSES(LogLevel.ERROR, R.string.msg_download_query_too_short_or_too_many_responses), + MSG_GET_QUERY_FAILED(LogLevel.ERROR, R.string.msg_download_query_failed) ; public final int mMsgId; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/AddKeysActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/AddKeysActivity.java index 436ed050f..8dd5d3c13 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/AddKeysActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/AddKeysActivity.java @@ -43,10 +43,10 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.ProviderHelper; import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; +import org.sufficientlysecure.keychain.service.results.GetKeyResult; import org.sufficientlysecure.keychain.service.results.ImportKeyResult; import org.sufficientlysecure.keychain.service.results.OperationResult; import org.sufficientlysecure.keychain.ui.adapter.AsyncTaskResultWrapper; -import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListCloudLoader; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListLoader; import org.sufficientlysecure.keychain.ui.util.Notify; import org.sufficientlysecure.keychain.ui.widget.ExchangeKeySpinner; @@ -61,7 +61,6 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.ArrayList; -import java.util.Iterator; import java.util.Locale; import edu.cmu.cylab.starslinger.exchange.ExchangeActivity; @@ -306,7 +305,9 @@ public class AddKeysActivity extends ActionBarActivity implements AsyncTaskResultWrapper> data) { Log.d(Constants.TAG, "data: " + data.getResult()); - Exception error = data.getError(); +// Exception error = data.getError(); + + GetKeyResult getKeyResult = (GetKeyResult) data.getOperationResult(); LongSparseArray cachedKeyData = null; @@ -314,42 +315,55 @@ public class AddKeysActivity extends ActionBarActivity implements switch (loader.getId()) { case LOADER_ID_BYTES: - if (error == null) { + if (getKeyResult.success()) { // No error cachedKeyData = ((ImportKeysListLoader) loader).getParcelableRings(); - Log.d(Constants.TAG, "no error!:" + cachedKeyData); - - } else if (error instanceof ImportKeysListLoader.NoValidKeysException) { - Notify.showNotify(this, R.string.error_import_no_valid_keys, Notify.Style.ERROR); - } else if (error instanceof ImportKeysListLoader.NonPgpPartException) { - Notify.showNotify(this, - ((ImportKeysListLoader.NonPgpPartException) error).getCount() + " " + getResources(). - getQuantityString(R.plurals.error_import_non_pgp_part, - ((ImportKeysListLoader.NonPgpPartException) error).getCount()), - Notify.Style.OK - ); } else { - Notify.showNotify(this, R.string.error_generic_report_bug, Notify.Style.ERROR); + getKeyResult.createNotify(this).show(); } + +// if (error == null) { +// // No error +// cachedKeyData = ((ImportKeysListLoader) loader).getParcelableRings(); +// Log.d(Constants.TAG, "no error!:" + cachedKeyData); +// +// } else if (error instanceof ImportKeysListLoader.NoValidKeysException) { +// Notify.showNotify(this, R.string.error_import_no_valid_keys, Notify.Style.ERROR); +// } else if (error instanceof ImportKeysListLoader.NonPgpPartException) { +// Notify.showNotify(this, +// ((ImportKeysListLoader.NonPgpPartException) error).getCount() + " " + getResources(). +// getQuantityString(R.plurals.error_import_non_pgp_part, +// ((ImportKeysListLoader.NonPgpPartException) error).getCount()), +// Notify.Style.OK +// ); +// } else { +// Notify.showNotify(this, R.string.error_generic_report_bug, Notify.Style.ERROR); +// } break; case LOADER_ID_CLOUD: - if (error == null) { + if (getKeyResult.success()) { // No error - } else if (error instanceof Keyserver.QueryTooShortException) { - Notify.showNotify(this, R.string.error_query_too_short, Notify.Style.ERROR); - } else if (error instanceof Keyserver.TooManyResponsesException) { - Notify.showNotify(this, R.string.error_too_many_responses, Notify.Style.ERROR); - } else if (error instanceof Keyserver.QueryTooShortOrTooManyResponsesException) { - Notify.showNotify(this, R.string.error_too_short_or_too_many_responses, Notify.Style.ERROR); - } else if (error instanceof Keyserver.QueryFailedException) { - Log.d(Constants.TAG, - "Unrecoverable keyserver query error: " + error.getLocalizedMessage()); - String alert = this.getString(R.string.error_searching_keys); - alert = alert + " (" + error.getLocalizedMessage() + ")"; - Notify.showNotify(this, alert, Notify.Style.ERROR); + } else { + getKeyResult.createNotify(this).show(); } + +// if (error == null) { +// // No error +// } else if (error instanceof Keyserver.QueryTooShortException) { +// Notify.showNotify(this, R.string.error_query_too_short, Notify.Style.ERROR); +// } else if (error instanceof Keyserver.TooManyResponsesException) { +// Notify.showNotify(this, R.string.error_too_many_responses, Notify.Style.ERROR); +// } else if (error instanceof Keyserver.QueryTooShortOrTooManyResponsesException) { +// Notify.showNotify(this, R.string.error_too_short_or_too_many_responses, Notify.Style.ERROR); +// } else if (error instanceof Keyserver.QueryFailedException) { +// Log.d(Constants.TAG, +// "Unrecoverable keyserver query error: " + error.getLocalizedMessage()); +// String alert = this.getString(R.string.error_searching_keys); +// alert = alert + " (" + error.getLocalizedMessage() + ")"; +// Notify.showNotify(this, alert, Notify.Style.ERROR); +// } break; default: diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java index 16ebd6aca..ad50ecd3d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ImportKeysListFragment.java @@ -31,6 +31,7 @@ import android.widget.ListView; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.service.results.GetKeyResult; import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize; import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; @@ -285,48 +286,60 @@ public class ImportKeysListFragment extends ListFragment implements setListShownNoAnimation(true); } - Exception error = data.getError(); - // free old cached key data mCachedKeyData = null; + GetKeyResult getKeyResult = (GetKeyResult) data.getOperationResult(); switch (loader.getId()) { case LOADER_ID_BYTES: - if (error == null) { + if (getKeyResult.success()) { // No error mCachedKeyData = ((ImportKeysListLoader) loader).getParcelableRings(); - } else if (error instanceof ImportKeysListLoader.NoValidKeysException) { - Notify.showNotify(getActivity(), R.string.error_import_no_valid_keys, Notify.Style.ERROR); - } else if (error instanceof ImportKeysListLoader.NonPgpPartException) { - Notify.showNotify(getActivity(), - ((ImportKeysListLoader.NonPgpPartException) error).getCount() + " " + getResources(). - getQuantityString(R.plurals.error_import_non_pgp_part, - ((ImportKeysListLoader.NonPgpPartException) error).getCount()), - Notify.Style.OK - ); } else { - Notify.showNotify(getActivity(), R.string.error_generic_report_bug, Notify.Style.ERROR); + getKeyResult.createNotify(getActivity()).show(); } +// if (error == null) { +// // No error +// mCachedKeyData = ((ImportKeysListLoader) loader).getParcelableRings(); +// } else if (error instanceof ImportKeysListLoader.NoValidKeysException) { +// Notify.showNotify(getActivity(), R.string.error_import_no_valid_keys, Notify.Style.ERROR); +// } else if (error instanceof ImportKeysListLoader.NonPgpPartException) { +// Notify.showNotify(getActivity(), +// ((ImportKeysListLoader.NonPgpPartException) error).getCount() + " " + getResources(). +// getQuantityString(R.plurals.error_import_non_pgp_part, +// ((ImportKeysListLoader.NonPgpPartException) error).getCount()), +// Notify.Style.OK +// ); +// } else { +// Notify.showNotify(getActivity(), R.string.error_generic_report_bug, Notify.Style.ERROR); +// } break; case LOADER_ID_CLOUD: - if (error == null) { + if (getKeyResult.success()) { // No error - } else if (error instanceof Keyserver.QueryTooShortException) { - Notify.showNotify(getActivity(), R.string.error_query_too_short, Notify.Style.ERROR); - } else if (error instanceof Keyserver.TooManyResponsesException) { - Notify.showNotify(getActivity(), R.string.error_too_many_responses, Notify.Style.ERROR); - } else if (error instanceof Keyserver.QueryTooShortOrTooManyResponsesException) { - Notify.showNotify(getActivity(), R.string.error_too_short_or_too_many_responses, Notify.Style.ERROR); - } else if (error instanceof Keyserver.QueryFailedException) { - Log.d(Constants.TAG, - "Unrecoverable keyserver query error: " + error.getLocalizedMessage()); - String alert = getActivity().getString(R.string.error_searching_keys); - alert = alert + " (" + error.getLocalizedMessage() + ")"; - Notify.showNotify(getActivity(), alert, Notify.Style.ERROR); + } else { + getKeyResult.createNotify(getActivity()).show(); } + + +// if (error == null) { +// // No error +// } else if (error instanceof Keyserver.QueryTooShortException) { +// Notify.showNotify(getActivity(), R.string.error_query_too_short, Notify.Style.ERROR); +// } else if (error instanceof Keyserver.TooManyResponsesException) { +// Notify.showNotify(getActivity(), R.string.error_too_many_responses, Notify.Style.ERROR); +// } else if (error instanceof Keyserver.QueryTooShortOrTooManyResponsesException) { +// Notify.showNotify(getActivity(), R.string.error_too_short_or_too_many_responses, Notify.Style.ERROR); +// } else if (error instanceof Keyserver.QueryFailedException) { +// Log.d(Constants.TAG, +// "Unrecoverable keyserver query error: " + error.getLocalizedMessage()); +// String alert = getActivity().getString(R.string.error_searching_keys); +// alert = alert + " (" + error.getLocalizedMessage() + ")"; +// Notify.showNotify(getActivity(), alert, Notify.Style.ERROR); +// } break; default: diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/AsyncTaskResultWrapper.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/AsyncTaskResultWrapper.java index 5f2aec4fe..dc0c5846a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/AsyncTaskResultWrapper.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/AsyncTaskResultWrapper.java @@ -17,6 +17,8 @@ package org.sufficientlysecure.keychain.ui.adapter; +import org.sufficientlysecure.keychain.service.results.OperationResult; + /** * The AsyncTaskResultWrapper is used to wrap a result from a AsyncTask (for example: Loader). * You can pass the result and an exception in it if an error occurred. @@ -28,19 +30,19 @@ package org.sufficientlysecure.keychain.ui.adapter; public class AsyncTaskResultWrapper { private final T mResult; - private final Exception mError; + private final OperationResult mOperationResult; - public AsyncTaskResultWrapper(T result, Exception error) { + public AsyncTaskResultWrapper(T result, OperationResult operationResult) { this.mResult = result; - this.mError = error; + this.mOperationResult = operationResult; } public T getResult() { return mResult; } - public Exception getError() { - return mError; + public OperationResult getOperationResult() { + return mOperationResult; } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListCloudLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListCloudLoader.java index 0332e8882..cb51a15a9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListCloudLoader.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListCloudLoader.java @@ -21,6 +21,9 @@ import android.content.Context; import android.support.v4.content.AsyncTaskLoader; import org.sufficientlysecure.keychain.Constants; +import org.sufficientlysecure.keychain.keyimport.Keyserver; +import org.sufficientlysecure.keychain.service.results.GetKeyResult; +import org.sufficientlysecure.keychain.service.results.OperationResult; import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.keyimport.CloudSearch; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; @@ -93,7 +96,8 @@ public class ImportKeysListCloudLoader */ private void queryServer(boolean enforceFingerprint) { try { - ArrayList searchResult = CloudSearch.search(mServerQuery, mCloudPrefs); + ArrayList searchResult + = CloudSearch.search(mServerQuery, mCloudPrefs); mEntryList.clear(); // add result to data @@ -114,9 +118,29 @@ public class ImportKeysListCloudLoader } else { mEntryList.addAll(searchResult); } - mEntryListWrapper = new AsyncTaskResultWrapper>(mEntryList, null); - } catch (Exception e) { - mEntryListWrapper = new AsyncTaskResultWrapper>(mEntryList, e); + GetKeyResult getKeyResult = new GetKeyResult(GetKeyResult.RESULT_OK, null); + mEntryListWrapper = new AsyncTaskResultWrapper>(mEntryList, getKeyResult); + } catch (Keyserver.CloudSearchFailureException e) { + // convert exception to result parcel + int error = GetKeyResult.RESULT_ERROR; + OperationResult.LogType logType = null; + if (e instanceof Keyserver.QueryFailedException) { + error = GetKeyResult.RESULT_ERROR_QUERY_FAILED; + logType = OperationResult.LogType.MSG_GET_QUERY_FAILED; + } else if (e instanceof Keyserver.TooManyResponsesException) { + error = GetKeyResult.RESULT_ERROR_TOO_MANY_RESPONSES; + logType = OperationResult.LogType.MSG_GET_TOO_MANY_RESPONSES; + } else if (e instanceof Keyserver.QueryTooShortException) { + error = GetKeyResult.RESULT_ERROR_QUERY_TOO_SHORT; + logType = OperationResult.LogType.MSG_GET_QUERY_TOO_SHORT; + } else if (e instanceof Keyserver.QueryTooShortOrTooManyResponsesException) { + error = GetKeyResult.RESULT_ERROR_TOO_SHORT_OR_TOO_MANY_RESPONSES; + logType = OperationResult.LogType.MSG_GET_QUERY_TOO_SHORT_OR_TOO_MANY_RESPONSES; + } + OperationResult.OperationLog log = new OperationResult.OperationLog(); + log.add(logType, 0); + GetKeyResult getKeyResult = new GetKeyResult(error, log); + mEntryListWrapper = new AsyncTaskResultWrapper>(mEntryList, getKeyResult); } } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java index 04947da93..6664cb61a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ImportKeysListLoader.java @@ -25,6 +25,8 @@ import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.keyimport.ImportKeysListEntry; import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.pgp.UncachedKeyRing; +import org.sufficientlysecure.keychain.service.results.GetKeyResult; +import org.sufficientlysecure.keychain.service.results.OperationResult; import org.sufficientlysecure.keychain.util.InputData; import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.PositionAwareInputStream; @@ -37,9 +39,6 @@ import java.util.Iterator; public class ImportKeysListLoader extends AsyncTaskLoader>> { - public static class NoValidKeysException extends Exception { - } - public static class NonPgpPartException extends Exception { private int mCount; @@ -72,7 +71,8 @@ public class ImportKeysListLoader return mEntryListWrapper; } - mEntryListWrapper = new AsyncTaskResultWrapper>(mData, null); + GetKeyResult getKeyResult = new GetKeyResult(GetKeyResult.RESULT_OK, null); + mEntryListWrapper = new AsyncTaskResultWrapper>(mData, getKeyResult); if (mInputData == null) { Log.e(Constants.TAG, "Input data is null!"); @@ -136,13 +136,11 @@ public class ImportKeysListLoader } } catch (IOException e) { Log.e(Constants.TAG, "IOException on parsing key file! Return NoValidKeysException!", e); - - NoValidKeysException e1 = new NoValidKeysException(); + OperationResult.OperationLog log = new OperationResult.OperationLog(); + log.add(OperationResult.LogType.MSG_GET_NO_VALID_KEYS, 0); + GetKeyResult getKeyResult = new GetKeyResult(GetKeyResult.RESULT_ERROR_NO_VALID_KEYS, log); mEntryListWrapper = new AsyncTaskResultWrapper> - (mData, e1); - } catch (Exception e) { - Log.e(Constants.TAG, "Other Exception on parsing key file!", e); - mEntryListWrapper = new AsyncTaskResultWrapper>(mData, e); + (mData, getKeyResult); } } diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index ac594065f..58740109d 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -261,18 +261,8 @@ "You need Android 4.1 to use Android's NFC Beam feature!" "NFC is not available on your device!" "No keys found!" - "Search query too short. Please refine your query!" - "An error occurred when searching for keys." - "Key search query returned too many candidates. Please refine your query!" - "Either no keys or too many have been found. Please improve your query!" "Retrieving the key ID from contacts failed!" - - "No valid keys found in File/Clipboard!" "A generic error occurred, please create a new bug report for OpenKeychain." - - "part of the loaded file is a valid OpenPGP object but not a OpenPGP key" - "parts of the loaded file are valid OpenPGP objects but not OpenPGP keys" - "Invalid signature!" @@ -928,6 +918,19 @@ "Account saved" + "Downloaded successfully!" + "No valid keys found in File/Clipboard!" + "TODO: plurals!" + + "part of the loaded file is a valid OpenPGP object but not a OpenPGP key" + "parts of the loaded file are valid OpenPGP objects but not OpenPGP keys" + + "Search query too short. Please refine your query!" + "Key search query returned too many candidates. Please refine your query!" + "Either no keys or too many have been found. Please improve your query!" + + "An error occurred when searching for keys." + "Click to clear cached passphrases" "OpenKeychain has cached %d passphrases" -- cgit v1.2.3