From 3ee2c6fc6a2a5e18e333bb82f16d0efe365df2b8 Mon Sep 17 00:00:00 2001 From: vectorijk Date: Fri, 24 Apr 2015 00:00:58 -0700 Subject: Introduce and Switch to mikepenz/MaterialDrawer --- OpenKeychain/build.gradle | 10 ++ .../keychain/ui/MainActivity.java | 143 +++++++++++++++++---- OpenKeychain/src/main/res/layout/main_activity.xml | 17 +++ .../src/main/res/layout/main_drawer_header.xml | 9 ++ 4 files changed, 154 insertions(+), 25 deletions(-) create mode 100644 OpenKeychain/src/main/res/layout/main_activity.xml create mode 100644 OpenKeychain/src/main/res/layout/main_drawer_header.xml (limited to 'OpenKeychain') diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index 0f9446713..6341766f9 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -23,6 +23,11 @@ dependencies { compile "com.splitwise:tokenautocomplete:1.3.3@aar" compile 'se.emilsjolander:stickylistheaders:2.6.0' compile 'org.sufficientlysecure:html-textview:1.1' + compile 'com.mikepenz.materialdrawer:library:2.7.9@aar' + compile 'com.mikepenz.iconics:library:0.9.1@aar' + compile 'com.mikepenz.iconics:octicons-typeface:2.2.0@aar' + compile 'com.mikepenz.iconics:meteocons-typeface:1.1.1@aar' + compile 'com.mikepenz.iconics:community-material-typeface:1.0.0@aar' // libs as submodules compile project(':extern:openpgp-api-lib') @@ -56,6 +61,11 @@ dependencyVerification { 'com.splitwise:tokenautocomplete:20bee71cc59b3828eb000b684d46ddf738efd56b8fee453a509cd16fda42c8cb', 'se.emilsjolander:stickylistheaders:8c05981ec5725be33f7cee5e68c13f3db49cd5c75f1aaeb04024920b1ef96ad4', 'org.sufficientlysecure:html-textview:ca24b1522be88378634093815ce9ff1b4920c72e7513a045a7846e14069ef988', + 'com.mikepenz.materialdrawer:library:3ef80c6e1ca1b29cfcbb27fa7927c02b2246e068c17fe52283703c4897449923', + 'com.mikepenz.iconics:library:4698a36ee4c2af765d0a85779c61474d755b90d66a59020105b6760a8a909e9e', + 'com.mikepenz.iconics:octicons-typeface:67ed7d456a9ce5f5307b85f955797bfb3dd674e2f6defb31c6b8bbe2ede290be', + 'com.mikepenz.iconics:meteocons-typeface:39a8a9e70cd8287cdb119af57a672a41dd09240dba6697f5a0dbda1ccc33298b', + 'com.mikepenz.iconics:community-material-typeface:f1c5afee5f0f10d66beb3ed0df977246a02a9c46de4e05d7c0264bcde53b6b7f', // 'OpenKeychain.extern:openpgp-api-lib:f05a9215cdad3a6597e4c5ece6fcec92b178d218195a3e88d2c0937c48dd9580', // 'OpenKeychain.extern:openkeychain-api-lib:50f6ebb5452d3fdc7be137ccf857a0ff44d55539fcb7b91baef495766ed7f429', // 'com.madgag.spongycastle:core:df8fcc028a95ac5ffab3b78c9163f5cfa672e41cd50128ca55d458b6cfbacf4b', diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java index 5fa3edba4..045d1e658 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java @@ -1,6 +1,7 @@ /* * Copyright (C) 2012-2014 Dominik Schürmann * Copyright (C) 2014 Vincent Breitmoser + * Copyright (C) 2015 Kai Jiang * * 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 @@ -20,6 +21,20 @@ package org.sufficientlysecure.keychain.ui; import android.content.Intent; import android.os.Bundle; +import android.support.v7.app.ActionBarActivity; +import android.support.v7.widget.Toolbar; +import android.view.View; +import android.widget.AdapterView; +import android.widget.Toast; + +import com.mikepenz.community_material_typeface_library.CommunityMaterial; +import com.mikepenz.google_material_typeface_library.GoogleMaterial; +import com.mikepenz.iconics.typeface.FontAwesome; +import com.mikepenz.materialdrawer.Drawer; +import com.mikepenz.materialdrawer.model.DividerDrawerItem; +import com.mikepenz.materialdrawer.model.SectionDrawerItem; +import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; +import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.OperationResult; @@ -29,27 +44,78 @@ import org.sufficientlysecure.keychain.util.FabContainer; import it.neokree.materialnavigationdrawer.MaterialNavigationDrawer; -public class MainActivity extends MaterialNavigationDrawer implements FabContainer { - - @Override - public void init(Bundle savedInstanceState) { - // don't open drawer on first run - disableLearningPattern(); +public class MainActivity extends ActionBarActivity implements FabContainer { -// addMultiPaneSupport(); + public Drawer.Result result; - // set the header image - // create and set the header - setDrawerHeaderImage(R.drawable.drawer_header); +// public Drawer.Result result; + @Override + public void onCreate(Bundle savedInstanceState) { +// // don't open drawer on first run +// disableLearningPattern(); +// +//// addMultiPaneSupport(); +// +// // set the header image +// // create and set the header +// setDrawerHeaderImage(R.drawable.drawer_header); +// +// // create sections +// addSection(newSection(getString(R.string.nav_keys), R.drawable.ic_vpn_key_black_24dp, new KeyListFragment())); +// addSection(newSection(getString(R.string.nav_encrypt_decrypt), R.drawable.ic_lock_black_24dp, new EncryptDecryptOverviewFragment())); +// addSection(newSection(getString(R.string.title_api_registered_apps), R.drawable.ic_apps_black_24dp, new AppsListFragment())); +// +// // create bottom section +// addBottomSection(newSection(getString(R.string.menu_preferences), R.drawable.ic_settings_black_24dp, new Intent(this, SettingsActivity.class))); +// addBottomSection(newSection(getString(R.string.menu_help), R.drawable.ic_help_black_24dp, new Intent(this, HelpActivity.class))); + super.onCreate(savedInstanceState); + setContentView(R.layout.main_activity); - // create sections - addSection(newSection(getString(R.string.nav_keys), R.drawable.ic_vpn_key_black_24dp, new KeyListFragment())); - addSection(newSection(getString(R.string.nav_encrypt_decrypt), R.drawable.ic_lock_black_24dp, new EncryptDecryptOverviewFragment())); - addSection(newSection(getString(R.string.title_api_registered_apps), R.drawable.ic_apps_black_24dp, new AppsListFragment())); + final Toolbar toolbar = (Toolbar) findViewById(R.id.activity_main_toolbar); + toolbar.setTitle(R.string.app_name); + setSupportActionBar(toolbar); - // create bottom section - addBottomSection(newSection(getString(R.string.menu_preferences), R.drawable.ic_settings_black_24dp, new Intent(this, SettingsActivity.class))); - addBottomSection(newSection(getString(R.string.menu_help), R.drawable.ic_help_black_24dp, new Intent(this, HelpActivity.class))); + result = new Drawer() + .withActivity(this) + .withHeader(R.layout.main_drawer_header) + .withToolbar(toolbar) + .addDrawerItems( + new PrimaryDrawerItem().withName(R.string.nav_keys).withIcon(CommunityMaterial.Icon.cmd_key).withIdentifier(1).withCheckable(false), + new PrimaryDrawerItem().withName(R.string.nav_encrypt_decrypt).withIcon(FontAwesome.Icon.faw_lock).withIdentifier(2).withCheckable(false), + new PrimaryDrawerItem().withName(R.string.title_api_registered_apps).withIcon(CommunityMaterial.Icon.cmd_apps).withIdentifier(3).withCheckable(false), + new DividerDrawerItem(), + new PrimaryDrawerItem().withName(R.string.menu_preferences).withIcon(GoogleMaterial.Icon.gmd_settings).withIdentifier(4).withCheckable(false), + new PrimaryDrawerItem().withName(R.string.menu_help).withIcon(CommunityMaterial.Icon.cmd_help_circle).withIdentifier(5).withCheckable(false) + ) + .withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id, IDrawerItem drawerItem) { + if (drawerItem != null) { + Intent intent = null; + switch(drawerItem.getIdentifier()) { + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + intent = new Intent(MainActivity.this, SettingsActivity.class); + break; + case 5: + intent = new Intent(MainActivity.this, HelpActivity.class); + break; + } + if (intent != null) { + MainActivity.this.startActivity(intent); + } + } + Toast.makeText(MainActivity.this, Integer.toString(drawerItem.getIdentifier()), Toast.LENGTH_SHORT).show(); + } + }) + .withSelectedItem(-1) + .withSavedInstance(savedInstanceState) + .build(); // if this is the first time show first time activity Preferences prefs = Preferences.getPreferences(this); @@ -69,20 +135,47 @@ public class MainActivity extends MaterialNavigationDrawer implements FabContain } } +// private void onPreferenceSelected() { +// Intent intent = new Intent(this, SettingsActivity.class); +// startActivity(intent); +// } +// +// private void onHelpSelected() { +// Intent intent = new Intent(this, HelpActivity.class); +// startActivity(intent); +// } + @Override - public void fabMoveUp(int height) { - Object fragment = getCurrentSection().getTargetFragment(); - if (fragment instanceof FabContainer) { - ((FabContainer) fragment).fabMoveUp(height); + protected void onSaveInstanceState(Bundle outState) { + //add the values which need to be saved from the drawer to the bundle + outState = result.saveInstanceState(outState); + super.onSaveInstanceState(outState); + } + + @Override + public void onBackPressed(){ + //handle the back press :D close the drawer first and if the drawer is closed close the activity + if (result != null && result.isDrawerOpen()) { + result.closeDrawer(); + } else { + super.onBackPressed(); } } + @Override + public void fabMoveUp(int height) { +// Object fragment = getCurrentSection().getTargetFragment(); +// if (fragment instanceof FabContainer) { +// ((FabContainer) fragment).fabMoveUp(height); +// } + } + @Override public void fabRestorePosition() { - Object fragment = getCurrentSection().getTargetFragment(); - if (fragment instanceof FabContainer) { - ((FabContainer) fragment).fabRestorePosition(); - } +// Object fragment = getCurrentSection().getTargetFragment(); +// if (fragment instanceof FabContainer) { +// ((FabContainer) fragment).fabRestorePosition(); +// } } } diff --git a/OpenKeychain/src/main/res/layout/main_activity.xml b/OpenKeychain/src/main/res/layout/main_activity.xml new file mode 100644 index 000000000..a85c8047e --- /dev/null +++ b/OpenKeychain/src/main/res/layout/main_activity.xml @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/main_drawer_header.xml b/OpenKeychain/src/main/res/layout/main_drawer_header.xml new file mode 100644 index 000000000..bac52efb3 --- /dev/null +++ b/OpenKeychain/src/main/res/layout/main_drawer_header.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file -- cgit v1.2.3 From b323fc29c29ec2a7cba87ed19c7809b843a1fd60 Mon Sep 17 00:00:00 2001 From: vectorijk Date: Fri, 24 Apr 2015 03:21:54 -0700 Subject: Fix #1197 Switch to MaterialDrawer library --- .../keychain/ui/MainActivity.java | 129 ++++++++++++++------- OpenKeychain/src/main/res/layout/main_activity.xml | 6 +- 2 files changed, 89 insertions(+), 46 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java index 045d1e658..fa4f07d88 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java @@ -21,56 +21,48 @@ package org.sufficientlysecure.keychain.ui; import android.content.Intent; import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentTransaction; import android.support.v7.app.ActionBarActivity; import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.AdapterView; -import android.widget.Toast; import com.mikepenz.community_material_typeface_library.CommunityMaterial; import com.mikepenz.google_material_typeface_library.GoogleMaterial; import com.mikepenz.iconics.typeface.FontAwesome; import com.mikepenz.materialdrawer.Drawer; -import com.mikepenz.materialdrawer.model.DividerDrawerItem; -import com.mikepenz.materialdrawer.model.SectionDrawerItem; import com.mikepenz.materialdrawer.model.PrimaryDrawerItem; import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.remote.ui.AppsListFragment; -import org.sufficientlysecure.keychain.util.Preferences; import org.sufficientlysecure.keychain.util.FabContainer; - -import it.neokree.materialnavigationdrawer.MaterialNavigationDrawer; +import org.sufficientlysecure.keychain.util.Preferences; public class MainActivity extends ActionBarActivity implements FabContainer { public Drawer.Result result; -// public Drawer.Result result; + private KeyListFragment mKeyListFragment ; + private AppsListFragment mAppsListFragment; + private EncryptDecryptOverviewFragment mEncryptDecryptOverviewFragment; + private Fragment lastUsedFragment; + @Override public void onCreate(Bundle savedInstanceState) { -// // don't open drawer on first run -// disableLearningPattern(); -// -//// addMultiPaneSupport(); -// -// // set the header image -// // create and set the header -// setDrawerHeaderImage(R.drawable.drawer_header); -// -// // create sections -// addSection(newSection(getString(R.string.nav_keys), R.drawable.ic_vpn_key_black_24dp, new KeyListFragment())); -// addSection(newSection(getString(R.string.nav_encrypt_decrypt), R.drawable.ic_lock_black_24dp, new EncryptDecryptOverviewFragment())); -// addSection(newSection(getString(R.string.title_api_registered_apps), R.drawable.ic_apps_black_24dp, new AppsListFragment())); -// -// // create bottom section -// addBottomSection(newSection(getString(R.string.menu_preferences), R.drawable.ic_settings_black_24dp, new Intent(this, SettingsActivity.class))); -// addBottomSection(newSection(getString(R.string.menu_help), R.drawable.ic_help_black_24dp, new Intent(this, HelpActivity.class))); super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); + //initialize FragmentLayout with KeyListFragment at first + Fragment mainFragment = new KeyListFragment(); + FragmentManager fm = getSupportFragmentManager(); + FragmentTransaction transaction = fm.beginTransaction(); + transaction.replace(R.id.main_fragment_container, mainFragment); + transaction.commit(); + final Toolbar toolbar = (Toolbar) findViewById(R.id.activity_main_toolbar); toolbar.setTitle(R.string.app_name); setSupportActionBar(toolbar); @@ -82,8 +74,10 @@ public class MainActivity extends ActionBarActivity implements FabContainer { .addDrawerItems( new PrimaryDrawerItem().withName(R.string.nav_keys).withIcon(CommunityMaterial.Icon.cmd_key).withIdentifier(1).withCheckable(false), new PrimaryDrawerItem().withName(R.string.nav_encrypt_decrypt).withIcon(FontAwesome.Icon.faw_lock).withIdentifier(2).withCheckable(false), - new PrimaryDrawerItem().withName(R.string.title_api_registered_apps).withIcon(CommunityMaterial.Icon.cmd_apps).withIdentifier(3).withCheckable(false), - new DividerDrawerItem(), + new PrimaryDrawerItem().withName(R.string.title_api_registered_apps).withIcon(CommunityMaterial.Icon.cmd_apps).withIdentifier(3).withCheckable(false) + ) + .addStickyDrawerItems( + // display and stick on bottom of drawer new PrimaryDrawerItem().withName(R.string.menu_preferences).withIcon(GoogleMaterial.Icon.gmd_settings).withIdentifier(4).withCheckable(false), new PrimaryDrawerItem().withName(R.string.menu_help).withIcon(CommunityMaterial.Icon.cmd_help_circle).withIdentifier(5).withCheckable(false) ) @@ -94,10 +88,13 @@ public class MainActivity extends ActionBarActivity implements FabContainer { Intent intent = null; switch(drawerItem.getIdentifier()) { case 1: + onKeysSelected(); break; case 2: + onEnDecryptSelected(); break; case 3: + onAppsSelected(); break; case 4: intent = new Intent(MainActivity.this, SettingsActivity.class); @@ -110,7 +107,6 @@ public class MainActivity extends ActionBarActivity implements FabContainer { MainActivity.this.startActivity(intent); } } - Toast.makeText(MainActivity.this, Integer.toString(drawerItem.getIdentifier()), Toast.LENGTH_SHORT).show(); } }) .withSelectedItem(-1) @@ -135,15 +131,58 @@ public class MainActivity extends ActionBarActivity implements FabContainer { } } -// private void onPreferenceSelected() { -// Intent intent = new Intent(this, SettingsActivity.class); -// startActivity(intent); -// } -// -// private void onHelpSelected() { -// Intent intent = new Intent(this, HelpActivity.class); -// startActivity(intent); -// } + private void clearFragments() { + mKeyListFragment = null; + mAppsListFragment = null; + mEncryptDecryptOverviewFragment = null; + + getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE); + } + + private void setFragment(Fragment fragment) { + setFragment(fragment, true); + } + + private void setFragment(Fragment fragment, boolean addToBackStack) { + this.lastUsedFragment = fragment; + FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); + ft.replace(R.id.main_fragment_container, fragment); + if (addToBackStack) { + ft.addToBackStack(null); + } + ft.commit(); + } + + private boolean onKeysSelected() { + clearFragments(); + + if (mKeyListFragment == null) { + mKeyListFragment = new KeyListFragment(); + } + + setFragment(mKeyListFragment, false); + return true; + } + + private boolean onEnDecryptSelected() { + clearFragments(); + if (mEncryptDecryptOverviewFragment == null) { + mEncryptDecryptOverviewFragment = new EncryptDecryptOverviewFragment(); + } + + setFragment(mEncryptDecryptOverviewFragment); + return true; + } + + private boolean onAppsSelected() { + clearFragments(); + if (mAppsListFragment == null) { + mAppsListFragment = new AppsListFragment(); + } + + setFragment(mAppsListFragment); + return true; + } @Override protected void onSaveInstanceState(Bundle outState) { @@ -164,18 +203,20 @@ public class MainActivity extends ActionBarActivity implements FabContainer { @Override public void fabMoveUp(int height) { -// Object fragment = getCurrentSection().getTargetFragment(); -// if (fragment instanceof FabContainer) { -// ((FabContainer) fragment).fabMoveUp(height); -// } + Object fragment = getSupportFragmentManager() + .findFragmentById(R.id.main_fragment_container); + if (fragment instanceof FabContainer) { + ((FabContainer) fragment).fabMoveUp(height); + } } @Override public void fabRestorePosition() { -// Object fragment = getCurrentSection().getTargetFragment(); -// if (fragment instanceof FabContainer) { -// ((FabContainer) fragment).fabRestorePosition(); -// } + Object fragment = getSupportFragmentManager() + .findFragmentById(R.id.main_fragment_container); + if (fragment instanceof FabContainer) { + ((FabContainer) fragment).fabRestorePosition(); + } } } diff --git a/OpenKeychain/src/main/res/layout/main_activity.xml b/OpenKeychain/src/main/res/layout/main_activity.xml index a85c8047e..4a07053ea 100644 --- a/OpenKeychain/src/main/res/layout/main_activity.xml +++ b/OpenKeychain/src/main/res/layout/main_activity.xml @@ -7,11 +7,13 @@ android:id="@+id/activity_main_toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" + android:elevation="4dp" android:background="?attr/colorPrimary"/> - + \ No newline at end of file -- cgit v1.2.3 From 96853a15ee535860fd789bc5be4979f2205e959c Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 24 Apr 2015 19:00:33 +0200 Subject: revamp decrypt ui --- .../keychain/ui/DecryptFilesFragment.java | 6 +- .../keychain/ui/DecryptFragment.java | 416 +++++++++++++++------ .../keychain/ui/DecryptTextFragment.java | 74 ++-- .../src/main/res/layout/decrypt_result_include.xml | 44 +-- .../src/main/res/layout/decrypt_text_fragment.xml | 49 --- OpenKeychain/src/main/res/menu/decrypt_menu.xml | 17 + OpenKeychain/src/main/res/values/strings.xml | 15 +- 7 files changed, 391 insertions(+), 230 deletions(-) create mode 100644 OpenKeychain/src/main/res/menu/decrypt_menu.xml (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java index 766e65e8b..6c1902af1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFilesFragment.java @@ -240,7 +240,7 @@ public class DecryptFilesFragment extends DecryptFragment { } case KeychainIntentService.ACTION_DECRYPT_VERIFY: { // display signature result in activity - onResult(pgpResult); + loadVerifyResult(pgpResult); if (mDeleteAfter.isChecked()) { // Create and show dialog to delete original file @@ -308,4 +308,8 @@ public class DecryptFilesFragment extends DecryptFragment { } } + @Override + protected void onVerifyLoaded(boolean verified) { + + } } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java index 33209be86..d641f02f9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -17,26 +17,49 @@ package org.sufficientlysecure.keychain.ui; +import java.util.ArrayList; + import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; import android.os.Bundle; +import android.os.Message; +import android.os.Messenger; +import android.support.v4.app.LoaderManager; +import android.support.v4.content.CursorLoader; +import android.support.v4.content.Loader; +import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import org.openintents.openpgp.OpenPgpSignatureResult; +import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; +import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing; import org.sufficientlysecure.keychain.operations.results.DecryptVerifyResult; +import org.sufficientlysecure.keychain.operations.results.ImportKeyResult; +import org.sufficientlysecure.keychain.operations.results.OperationResult; import org.sufficientlysecure.keychain.pgp.KeyRing; +import org.sufficientlysecure.keychain.pgp.exception.PgpKeyNotFoundException; import org.sufficientlysecure.keychain.provider.KeychainContract; +import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; +import org.sufficientlysecure.keychain.provider.ProviderHelper; +import org.sufficientlysecure.keychain.service.KeychainIntentService; +import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.ui.base.CryptoOperationFragment; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils.State; +import org.sufficientlysecure.keychain.ui.util.Notify; +import org.sufficientlysecure.keychain.ui.util.Notify.Style; +import org.sufficientlysecure.keychain.util.Preferences; + -public abstract class DecryptFragment extends CryptoOperationFragment { - private static final int RESULT_CODE_LOOKUP_KEY = 0x00007006; +public abstract class DecryptFragment extends CryptoOperationFragment implements + LoaderManager.LoaderCallbacks { - protected long mSignatureKeyId = 0; + public static final int LOADER_ID_UNIFIED = 0; protected LinearLayout mResultLayout; @@ -46,155 +69,118 @@ public abstract class DecryptFragment extends CryptoOperationFragment { protected TextView mSignatureText; protected View mSignatureLayout; - protected View mSignatureDivider1; - protected View mSignatureDivider2; protected TextView mSignatureName; protected TextView mSignatureEmail; protected TextView mSignatureAction; + private OpenPgpSignatureResult mSignatureResult; + @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); - mResultLayout = (LinearLayout) getView().findViewById(R.id.result_main_layout); + mResultLayout = (LinearLayout) view.findViewById(R.id.result_main_layout); mResultLayout.setVisibility(View.GONE); - mEncryptionIcon = (ImageView) getView().findViewById(R.id.result_encryption_icon); - mEncryptionText = (TextView) getView().findViewById(R.id.result_encryption_text); - mSignatureIcon = (ImageView) getView().findViewById(R.id.result_signature_icon); - mSignatureText = (TextView) getView().findViewById(R.id.result_signature_text); - mSignatureLayout = getView().findViewById(R.id.result_signature_layout); - mSignatureDivider1 = getView().findViewById(R.id.result_signature_divider1); - mSignatureDivider2 = getView().findViewById(R.id.result_signature_divider2); - mSignatureName = (TextView) getView().findViewById(R.id.result_signature_name); - mSignatureEmail = (TextView) getView().findViewById(R.id.result_signature_email); - mSignatureAction = (TextView) getView().findViewById(R.id.result_signature_action); + mEncryptionIcon = (ImageView) view.findViewById(R.id.result_encryption_icon); + mEncryptionText = (TextView) view.findViewById(R.id.result_encryption_text); + mSignatureIcon = (ImageView) view.findViewById(R.id.result_signature_icon); + mSignatureText = (TextView) view.findViewById(R.id.result_signature_text); + mSignatureLayout = view.findViewById(R.id.result_signature_layout); + mSignatureName = (TextView) view.findViewById(R.id.result_signature_name); + mSignatureEmail = (TextView) view.findViewById(R.id.result_signature_email); + mSignatureAction = (TextView) view.findViewById(R.id.result_signature_action); } private void lookupUnknownKey(long unknownKeyId) { - Intent intent = new Intent(getActivity(), ImportKeysActivity.class); - intent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER); - intent.putExtra(ImportKeysActivity.EXTRA_KEY_ID, unknownKeyId); - startActivityForResult(intent, RESULT_CODE_LOOKUP_KEY); - } - - private void showKey(long keyId) { - Intent viewKeyIntent = new Intent(getActivity(), ViewKeyActivity.class); - viewKeyIntent.setData(KeychainContract.KeyRings - .buildGenericKeyRingUri(keyId)); - startActivity(viewKeyIntent); - } - /** - * - * @return returns false if signature is invalid, key is revoked or expired. - */ - protected boolean onResult(DecryptVerifyResult decryptVerifyResult) { - final OpenPgpSignatureResult signatureResult = decryptVerifyResult.getSignatureResult(); + // Message is received after importing is done in KeychainIntentService + ServiceProgressHandler serviceHandler = new ServiceProgressHandler(getActivity()) { + public void handleMessage(Message message) { + // handle messages by standard KeychainIntentServiceHandler first + super.handleMessage(message); - boolean valid = false; + if (message.arg1 == MessageStatus.OKAY.ordinal()) { + // get returned data bundle + Bundle returnData = message.getData(); - mSignatureKeyId = 0; - mResultLayout.setVisibility(View.VISIBLE); - if (signatureResult != null) { - mSignatureKeyId = signatureResult.getKeyId(); - - String userId = signatureResult.getPrimaryUserId(); - KeyRing.UserId userIdSplit = KeyRing.splitUserId(userId); - if (userIdSplit.name != null) { - mSignatureName.setText(userIdSplit.name); - } else { - mSignatureName.setText(R.string.user_id_no_name); - } - if (userIdSplit.email != null) { - mSignatureEmail.setText(userIdSplit.email); - } else { - mSignatureEmail.setText(KeyFormattingUtils.beautifyKeyIdWithPrefix(getActivity(), mSignatureKeyId)); - } + if (returnData == null) { + return; + } - if (signatureResult.isSignatureOnly()) { - mEncryptionText.setText(R.string.decrypt_result_not_encrypted); - KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.NOT_ENCRYPTED); - } else { - mEncryptionText.setText(R.string.decrypt_result_encrypted); - KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.ENCRYPTED); - } + final ImportKeyResult result = + returnData.getParcelable(OperationResult.EXTRA_RESULT); - switch (signatureResult.getStatus()) { - case OpenPgpSignatureResult.SIGNATURE_SUCCESS_CERTIFIED: { - mSignatureText.setText(R.string.decrypt_result_signature_certified); - KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.VERIFIED); + // if (!result.success()) { + result.createNotify(getActivity()).show(); + // } - setSignatureLayoutVisibility(View.VISIBLE); - setShowAction(mSignatureKeyId); + getLoaderManager().restartLoader(LOADER_ID_UNIFIED, null, DecryptFragment.this); - valid = true; - break; } + } + }; - case OpenPgpSignatureResult.SIGNATURE_SUCCESS_UNCERTIFIED: { - mSignatureText.setText(R.string.decrypt_result_signature_uncertified); - KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.UNVERIFIED); + // fill values for this action + Bundle data = new Bundle(); - setSignatureLayoutVisibility(View.VISIBLE); - setShowAction(mSignatureKeyId); + // search config + { + Preferences prefs = Preferences.getPreferences(getActivity()); + Preferences.CloudSearchPrefs cloudPrefs = + new Preferences.CloudSearchPrefs(true, true, prefs.getPreferredKeyserver()); + data.putString(KeychainIntentService.IMPORT_KEY_SERVER, cloudPrefs.keyserver); + } - valid = true; - break; - } + { + ParcelableKeyRing keyEntry = new ParcelableKeyRing(null, + KeyFormattingUtils.convertKeyIdToHex(unknownKeyId), null); + ArrayList selectedEntries = new ArrayList<>(); + selectedEntries.add(keyEntry); - case OpenPgpSignatureResult.SIGNATURE_KEY_MISSING: { - mSignatureText.setText(R.string.decrypt_result_signature_missing_key); - KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.UNKNOWN_KEY); - - setSignatureLayoutVisibility(View.VISIBLE); - mSignatureAction.setText(R.string.decrypt_result_action_Lookup); - mSignatureAction.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_file_download_grey_24dp, 0); - mSignatureLayout.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - lookupUnknownKey(mSignatureKeyId); - } - }); - - valid = true; - break; - } + data.putParcelableArrayList(KeychainIntentService.IMPORT_KEY_LIST, selectedEntries); + } - case OpenPgpSignatureResult.SIGNATURE_KEY_EXPIRED: { - mSignatureText.setText(R.string.decrypt_result_signature_expired_key); - KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.EXPIRED); + // Send all information needed to service to query keys in other thread + Intent intent = new Intent(getActivity(), KeychainIntentService.class); + intent.setAction(KeychainIntentService.ACTION_IMPORT_KEYRING); + intent.putExtra(KeychainIntentService.EXTRA_DATA, data); - setSignatureLayoutVisibility(View.VISIBLE); - setShowAction(mSignatureKeyId); + // Create a new Messenger for the communication back + Messenger messenger = new Messenger(serviceHandler); + intent.putExtra(KeychainIntentService.EXTRA_MESSENGER, messenger); - valid = false; - break; - } + getActivity().startService(intent); - case OpenPgpSignatureResult.SIGNATURE_KEY_REVOKED: { - mSignatureText.setText(R.string.decrypt_result_signature_revoked_key); - KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.REVOKED); + } - setSignatureLayoutVisibility(View.VISIBLE); - setShowAction(mSignatureKeyId); + private void showKey(long keyId) { + try { - valid = false; - break; - } + Intent viewKeyIntent = new Intent(getActivity(), ViewKeyActivity.class); + long masterKeyId = new ProviderHelper(getActivity()).getCachedPublicKeyRing( + KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(keyId) + ).getMasterKeyId(); + viewKeyIntent.setData(KeyRings.buildGenericKeyRingUri(masterKeyId)); + startActivity(viewKeyIntent); + + } catch (PgpKeyNotFoundException e) { + Notify.create(getActivity(), R.string.error_key_not_found, Style.ERROR); + } + } + + /** + * @return returns false if signature is invalid, key is revoked or expired. + */ + protected void loadVerifyResult(DecryptVerifyResult decryptVerifyResult) { - case OpenPgpSignatureResult.SIGNATURE_ERROR: { - mSignatureText.setText(R.string.decrypt_result_invalid_signature); - KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.INVALID); + mSignatureResult = decryptVerifyResult.getSignatureResult(); + mResultLayout.setVisibility(View.VISIBLE); - setSignatureLayoutVisibility(View.GONE); + // unsigned data + if (mSignatureResult == null) { - valid = false; - break; - } - } - } else { setSignatureLayoutVisibility(View.GONE); mSignatureText.setText(R.string.decrypt_result_no_signature); @@ -202,16 +188,27 @@ public abstract class DecryptFragment extends CryptoOperationFragment { mEncryptionText.setText(R.string.decrypt_result_encrypted); KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.ENCRYPTED); - valid = true; + getLoaderManager().destroyLoader(LOADER_ID_UNIFIED); + + onVerifyLoaded(true); + + return; + } + + if (mSignatureResult.isSignatureOnly()) { + mEncryptionText.setText(R.string.decrypt_result_not_encrypted); + KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.NOT_ENCRYPTED); + } else { + mEncryptionText.setText(R.string.decrypt_result_encrypted); + KeyFormattingUtils.setStatusImage(getActivity(), mEncryptionIcon, mEncryptionText, State.ENCRYPTED); } - return valid; + getLoaderManager().restartLoader(LOADER_ID_UNIFIED, null, this); + } private void setSignatureLayoutVisibility(int visibility) { mSignatureLayout.setVisibility(visibility); - mSignatureDivider1.setVisibility(visibility); - mSignatureDivider2.setVisibility(visibility); } private void setShowAction(final long signatureKeyId) { @@ -225,4 +222,177 @@ public abstract class DecryptFragment extends CryptoOperationFragment { }); } + // These are the rows that we will retrieve. + static final String[] UNIFIED_PROJECTION = new String[]{ + KeychainContract.KeyRings._ID, + KeychainContract.KeyRings.MASTER_KEY_ID, + KeychainContract.KeyRings.USER_ID, + KeychainContract.KeyRings.IS_REVOKED, + KeychainContract.KeyRings.IS_EXPIRED, + KeychainContract.KeyRings.VERIFIED, + }; + + @SuppressWarnings("unused") + static final int INDEX_MASTER_KEY_ID = 1; + static final int INDEX_USER_ID = 2; + static final int INDEX_IS_REVOKED = 3; + static final int INDEX_IS_EXPIRED = 4; + static final int INDEX_VERIFIED = 5; + + @Override + public Loader onCreateLoader(int id, Bundle args) { + if (id != LOADER_ID_UNIFIED) { + return null; + } + + Uri baseUri = KeychainContract.KeyRings.buildUnifiedKeyRingsFindBySubkeyUri( + mSignatureResult.getKeyId()); + return new CursorLoader(getActivity(), baseUri, UNIFIED_PROJECTION, null, null, null); + } + + @Override + public void onLoadFinished(Loader loader, Cursor data) { + + if (loader.getId() != LOADER_ID_UNIFIED) { + return; + } + + // If the key is unknown, show it as such + if (data.getCount() == 0 || !data.moveToFirst()) { + showUnknownKeyStatus(); + return; + } + + long signatureKeyId = mSignatureResult.getKeyId(); + + String userId = data.getString(INDEX_USER_ID); + KeyRing.UserId userIdSplit = KeyRing.splitUserId(userId); + if (userIdSplit.name != null) { + mSignatureName.setText(userIdSplit.name); + } else { + mSignatureName.setText(R.string.user_id_no_name); + } + if (userIdSplit.email != null) { + mSignatureEmail.setText(userIdSplit.email); + } else { + mSignatureEmail.setText(KeyFormattingUtils.beautifyKeyIdWithPrefix( + getActivity(), mSignatureResult.getKeyId())); + } + + boolean isRevoked = data.getInt(INDEX_IS_REVOKED) != 0; + boolean isExpired = data.getInt(INDEX_IS_EXPIRED) != 0; + boolean isVerified = data.getInt(INDEX_VERIFIED) > 0; + + if (isRevoked) { + mSignatureText.setText(R.string.decrypt_result_signature_revoked_key); + KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.REVOKED); + + setSignatureLayoutVisibility(View.VISIBLE); + setShowAction(signatureKeyId); + + onVerifyLoaded(false); + + } else if (isExpired) { + mSignatureText.setText(R.string.decrypt_result_signature_expired_key); + KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.EXPIRED); + + setSignatureLayoutVisibility(View.VISIBLE); + setShowAction(signatureKeyId); + + onVerifyLoaded(true); + + } else if (isVerified) { + mSignatureText.setText(R.string.decrypt_result_signature_certified); + KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.VERIFIED); + + setSignatureLayoutVisibility(View.VISIBLE); + setShowAction(signatureKeyId); + + onVerifyLoaded(true); + + } else { + mSignatureText.setText(R.string.decrypt_result_signature_uncertified); + KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.UNVERIFIED); + + setSignatureLayoutVisibility(View.VISIBLE); + setShowAction(signatureKeyId); + + onVerifyLoaded(true); + } + + } + + @Override + public void onLoaderReset(Loader loader) { + + if (loader.getId() != LOADER_ID_UNIFIED) { + return; + } + + setSignatureLayoutVisibility(View.GONE); + + } + + private void showUnknownKeyStatus() { + + final long signatureKeyId = mSignatureResult.getKeyId(); + + int result = mSignatureResult.getStatus(); + if (result != OpenPgpSignatureResult.SIGNATURE_KEY_MISSING + && result != OpenPgpSignatureResult.SIGNATURE_ERROR) { + Log.e(Constants.TAG, "got missing status for non-missing key, shouldn't happen!"); + } + + String userId = mSignatureResult.getPrimaryUserId(); + KeyRing.UserId userIdSplit = KeyRing.splitUserId(userId); + if (userIdSplit.name != null) { + mSignatureName.setText(userIdSplit.name); + } else { + mSignatureName.setText(R.string.user_id_no_name); + } + if (userIdSplit.email != null) { + mSignatureEmail.setText(userIdSplit.email); + } else { + mSignatureEmail.setText(KeyFormattingUtils.beautifyKeyIdWithPrefix( + getActivity(), mSignatureResult.getKeyId())); + } + + switch (mSignatureResult.getStatus()) { + + case OpenPgpSignatureResult.SIGNATURE_KEY_MISSING: { + mSignatureText.setText(R.string.decrypt_result_signature_missing_key); + KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.UNKNOWN_KEY); + + setSignatureLayoutVisibility(View.VISIBLE); + mSignatureAction.setText(R.string.decrypt_result_action_Lookup); + mSignatureAction + .setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_file_download_grey_24dp, 0); + mSignatureLayout.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + lookupUnknownKey(signatureKeyId); + } + }); + + onVerifyLoaded(true); + + break; + } + + case OpenPgpSignatureResult.SIGNATURE_ERROR: { + mSignatureText.setText(R.string.decrypt_result_invalid_signature); + KeyFormattingUtils.setStatusImage(getActivity(), mSignatureIcon, mSignatureText, State.INVALID); + + setSignatureLayoutVisibility(View.GONE); + + onVerifyLoaded(false); + break; + } + + } + + } + + protected abstract void onVerifyLoaded(boolean verified); + } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java index 9c6c89c43..1b9ae917f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java @@ -23,6 +23,9 @@ import android.os.Bundle; import android.os.Message; import android.os.Messenger; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.Button; @@ -39,7 +42,6 @@ import org.sufficientlysecure.keychain.service.ServiceProgressHandler; import org.sufficientlysecure.keychain.service.input.CryptoInputParcel; import org.sufficientlysecure.keychain.ui.dialog.ProgressDialogFragment; import org.sufficientlysecure.keychain.ui.util.Notify; -import org.sufficientlysecure.keychain.util.Log; import org.sufficientlysecure.keychain.util.ShareHelper; import java.io.UnsupportedEncodingException; @@ -54,6 +56,7 @@ public class DecryptTextFragment extends DecryptFragment { // model private String mCiphertext; + private boolean mShowMenuOptions = false; /** * Creates new instance of this fragment @@ -79,22 +82,6 @@ public class DecryptTextFragment extends DecryptFragment { mInvalidLayout = (LinearLayout) view.findViewById(R.id.decrypt_text_invalid); mText = (TextView) view.findViewById(R.id.decrypt_text_plaintext); - View vShareButton = view.findViewById(R.id.action_decrypt_share_plaintext); - vShareButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - startActivity(sendWithChooserExcludingEncrypt(mText.getText().toString())); - } - }); - - View vCopyButton = view.findViewById(R.id.action_decrypt_copy_plaintext); - vCopyButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - copyToClipboard(mText.getText().toString()); - } - }); - Button vInvalidButton = (Button) view.findViewById(R.id.decrypt_text_invalid_button); vInvalidButton.setOnClickListener(new View.OnClickListener() { @Override @@ -139,6 +126,8 @@ public class DecryptTextFragment extends DecryptFragment { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + String ciphertext = getArguments().getString(ARG_CIPHERTEXT); if (ciphertext != null) { mCiphertext = ciphertext; @@ -146,6 +135,33 @@ public class DecryptTextFragment extends DecryptFragment { } } + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + if (mShowMenuOptions) { + inflater.inflate(R.menu.decrypt_menu, menu); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.decrypt_share: { + startActivity(sendWithChooserExcludingEncrypt(mText.getText().toString())); + break; + } + case R.id.decrypt_copy: { + copyToClipboard(mText.getText().toString()); + break; + } + default: { + return super.onOptionsItemSelected(item); + } + } + + return true; + } + @Override protected void cryptoOperation(CryptoInputParcel cryptoInput) { // Send all information needed to service to decrypt in other thread @@ -206,15 +222,8 @@ public class DecryptTextFragment extends DecryptFragment { pgpResult.createNotify(getActivity()).show(); // display signature result in activity - boolean valid = onResult(pgpResult); + loadVerifyResult(pgpResult); - if (valid) { - mInvalidLayout.setVisibility(View.GONE); - mValidLayout.setVisibility(View.VISIBLE); - } else { - mInvalidLayout.setVisibility(View.VISIBLE); - mValidLayout.setVisibility(View.GONE); - } } else { pgpResult.createNotify(getActivity()).show(); // TODO: show also invalid layout with different text? @@ -234,4 +243,19 @@ public class DecryptTextFragment extends DecryptFragment { getActivity().startService(intent); } + @Override + protected void onVerifyLoaded(boolean verified) { + + mShowMenuOptions = verified; + getActivity().supportInvalidateOptionsMenu(); + + if (verified) { + mInvalidLayout.setVisibility(View.GONE); + mValidLayout.setVisibility(View.VISIBLE); + } else { + mInvalidLayout.setVisibility(View.VISIBLE); + mValidLayout.setVisibility(View.GONE); + } + + } } diff --git a/OpenKeychain/src/main/res/layout/decrypt_result_include.xml b/OpenKeychain/src/main/res/layout/decrypt_result_include.xml index debc1106f..f64d72987 100644 --- a/OpenKeychain/src/main/res/layout/decrypt_result_include.xml +++ b/OpenKeychain/src/main/res/layout/decrypt_result_include.xml @@ -1,10 +1,12 @@ + android:background="@color/holo_gray_bright" + tools:showIn="@layout/decrypt_text_fragment"> + android:paddingBottom="4dp" + android:animateLayoutChanges="true"> + android:layout_marginBottom="8dp" + tools:text="Encryption status text" + /> + android:layout_marginBottom="8dp" + tools:text="Signature status text" + /> - - @@ -83,6 +81,7 @@ android:layout_height="match_parent" android:layout_weight="1" android:paddingRight="4dp" + android:paddingLeft="4dp" android:gravity="center_vertical" android:orientation="vertical"> @@ -91,15 +90,16 @@ android:textAppearance="?android:attr/textAppearanceMedium" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="Alice (set in-code)" /> + tools:text="Alice" /> + android:gravity="center_vertical" + tools:text="alice@example.com" + /> @@ -114,6 +114,7 @@ + /> - - - - - - - - - - - - - - + + + + + + + \ No newline at end of file diff --git a/OpenKeychain/src/main/res/values/strings.xml b/OpenKeychain/src/main/res/values/strings.xml index df88336a1..4d92dac20 100644 --- a/OpenKeychain/src/main/res/values/strings.xml +++ b/OpenKeychain/src/main/res/values/strings.xml @@ -78,7 +78,8 @@ "View certification key" "Create key" "Add file(s)" - "Share decrypted text" + "Share decrypted text" + "Copy decrypted text" "Decrypt text from clipboard" "and verify signatures" "Decrypt files" @@ -285,16 +286,16 @@ "Not Signed" "Invalid signature!" - "Signed by (not certified!)" - "Signed by" - "Key is expired!" - "Key has been revoked!" - "Unknown public key" + "Signed by unconfirmed key" + "Signed by confirmed key" + "Signed by expired key!" + "Signed by revoked key!" + "Signed by unknown public key" "Encrypted" "Not Encrypted" "Show" "Lookup" - "Either the signature is invalid or the key has been revoked/is expired. You cannot be sure who wrote the text. Do you still want to display it?" + "Either the signature is invalid or the key has been revoked. You cannot be sure who wrote the text. Do you still want to display it?" "I understand the risks, display it!" -- cgit v1.2.3 From 9c174ff71dd5cf0bfdb1ae22d41abeda25eef913 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Fri, 24 Apr 2015 19:16:15 +0200 Subject: fix encrypt activity layout --- .../keychain/ui/widget/EncryptKeyCompletionView.java | 3 +-- OpenKeychain/src/main/res/layout/encrypt_asymmetric_fragment.xml | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java index b2dfb2493..3d2e8b9df 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EncryptKeyCompletionView.java @@ -108,9 +108,8 @@ public class EncryptKeyCompletionView extends TokenCompleteTextView protected void onAttachedToWindow() { super.onAttachedToWindow(); - mLoaderManager = ((FragmentActivity) getContext()).getSupportLoaderManager(); - if (getContext() instanceof FragmentActivity) { + mLoaderManager = ((FragmentActivity) getContext()).getSupportLoaderManager(); mLoaderManager.initLoader(hashCode(), null, this); } else { Log.e(Constants.TAG, "EncryptKeyCompletionView must be attached to a FragmentActivity, this is " + getContext().getClass()); diff --git a/OpenKeychain/src/main/res/layout/encrypt_asymmetric_fragment.xml b/OpenKeychain/src/main/res/layout/encrypt_asymmetric_fragment.xml index 51891155c..aa295050a 100644 --- a/OpenKeychain/src/main/res/layout/encrypt_asymmetric_fragment.xml +++ b/OpenKeychain/src/main/res/layout/encrypt_asymmetric_fragment.xml @@ -11,6 +11,8 @@ android:id="@+id/recipient_list" android:layout_width="match_parent" android:minHeight="56dip" + android:paddingLeft="8dp" + android:paddingRight="8dp" android:layout_height="wrap_content" /> Date: Sat, 25 Apr 2015 14:06:53 +0200 Subject: Remove old navigation drawer dependency --- OpenKeychain/build.gradle | 3 --- OpenKeychain/src/main/res/values/colors.xml | 1 + OpenKeychain/src/main/res/values/themes.xml | 9 --------- 3 files changed, 1 insertion(+), 12 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index 6341766f9..c47e650cb 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -17,7 +17,6 @@ dependencies { compile 'com.journeyapps:zxing-android-integration:2.3.0@aar' compile 'com.google.zxing:core:3.2.0' compile 'com.jpardogo.materialtabstrip:library:1.0.9' - compile 'it.neokree:MaterialNavigationDrawer:1.3.2' compile 'com.getbase:floatingactionbutton:1.9.0' compile 'org.commonjava.googlecode.markdown4j:markdown4j:2.2-cj-1.0' compile "com.splitwise:tokenautocomplete:1.3.3@aar" @@ -55,7 +54,6 @@ dependencyVerification { 'com.journeyapps:zxing-android-integration:562737821b6d34c899b6fd2234ce0a8a31e02ff1fd7c59f6211961ce9767c7c8', 'com.google.zxing:core:7fe5a8ff437635a540e56317649937b768b454795ce999ed5f244f83373dee7b', 'com.jpardogo.materialtabstrip:library:c6ef812fba4f74be7dc4a905faa4c2908cba261a94c13d4f96d5e67e4aad4aaa', - 'it.neokree:MaterialNavigationDrawer:a1221a410c5f71bf078c5c4768fdf06b402d6006c74f8e7b61199e4edc2aea57', 'com.getbase:floatingactionbutton:052aa2a94e49e5dccc97cb99f2add87e8698b84859f0e3ac181100c0bc7640ca', 'org.commonjava.googlecode.markdown4j:markdown4j:e952e825d29e1317d96f79f346bfb6786c7c5eef50bd26e54a80823704b62e13', 'com.splitwise:tokenautocomplete:20bee71cc59b3828eb000b684d46ddf738efd56b8fee453a509cd16fda42c8cb', @@ -77,7 +75,6 @@ dependencyVerification { // 'OpenKeychain.extern:safeslinger-exchange:d222721bb35408daaab9f46449364b2657112705ee571d7532f81cbeb9c4a73f', // 'OpenKeychain.extern.snackbar:lib:52357426e5275412e2063bdf6f0e6b957a3ea74da45e0aef35d22d9afc542e23', 'com.android.support:support-annotations:ab6b131ab0e1edd165d21fb4c3edadeacbee9539aa166f7f7cbae05b60dc207a', - 'com.balysv:material-ripple:b2580520bcb5e5d77bd8c42b030317accaf8f88e7e57c46a29c47c8a62d4ff45', ] } diff --git a/OpenKeychain/src/main/res/values/colors.xml b/OpenKeychain/src/main/res/values/colors.xml index 8c5358fd0..ead006a63 100644 --- a/OpenKeychain/src/main/res/values/colors.xml +++ b/OpenKeychain/src/main/res/values/colors.xml @@ -22,6 +22,7 @@ #727272 #FFFFFF #B6B6B6 + #00FFFFFF #212121 diff --git a/OpenKeychain/src/main/res/values/themes.xml b/OpenKeychain/src/main/res/values/themes.xml index c87895c01..a1644707e 100644 --- a/OpenKeychain/src/main/res/values/themes.xml +++ b/OpenKeychain/src/main/res/values/themes.xml @@ -15,19 +15,10 @@ true @style/MySearchViewStyle - - @integer/DRAWERTYPE_IMAGE @style/ThemeOverlay.AppCompat.Dark @style/ThemeOverlay.AppCompat.Light - #fafafa - false - @style/MaterialSectionTheme.Light - @style/MaterialSubheaderTheme.Light - false - false - false -- cgit v1.2.3 From f8af6e3387b46bf0be3dbef799de483e090ad850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 25 Apr 2015 14:09:55 +0200 Subject: Update lib section in about --- OpenKeychain/src/main/res/raw/help_about.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/res/raw/help_about.md b/OpenKeychain/src/main/res/raw/help_about.md index 4b51c1695..41e8d9542 100644 --- a/OpenKeychain/src/main/res/raw/help_about.md +++ b/OpenKeychain/src/main/res/raw/help_about.md @@ -39,8 +39,8 @@ License: GPLv3+ * [ZXing](https://github.com/zxing/zxing) (Apache License v2) * [ZXing Android Minimal](https://github.com/journeyapps/zxing-android-embedded) (Apache License v2) * [PagerSlidingTabStrip](https://github.com/jpardogo/PagerSlidingTabStrip) (Material Design) (Apache License v2) - * [MaterialNavigationDrawer](https://github.com/neokree/MaterialNavigationDrawer) (Apache License v2) + * [MaterialDrawer](https://github.com/mikepenz/MaterialDrawer) (Apache License v2) * [Snackbar](https://github.com/nispok/snackbar) (MIT License) * [FloatingActionButton](https://github.com/futuresimple/android-floating-action-button) (Apache License v2) - * [HtmlTextView](https://github.com/dschuermann/html-textview) (Apache License v2) + * [HtmlTextView](https://github.com/sufficientlysecure/html-textview) (Apache License v2) * [Markdown4J](https://github.com/jdcasey/markdown4j) (Apache License v2) -- cgit v1.2.3 From 28da73120145078eae9a62cb98fc9d704d5ef7a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 25 Apr 2015 14:15:38 +0200 Subject: Fix empty screen when clicking on encrypt in details view --- .../org/sufficientlysecure/keychain/ui/EncryptTextActivity.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java index 03ab48e23..dd6dd6594 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EncryptTextActivity.java @@ -98,23 +98,20 @@ public class EncryptTextActivity extends BaseActivity implements // handle like normal text encryption, override action and extras to later // executeServiceMethod ACTION_ENCRYPT_TEXT in main actions extras.putString(EXTRA_TEXT, sharedText); - action = ACTION_ENCRYPT_TEXT; } } } String textData = extras.getString(EXTRA_TEXT); - if (ACTION_ENCRYPT_TEXT.equals(action) && textData == null) { - Log.e(Constants.TAG, "Include the extra 'text' in your Intent!"); - return; + if (textData == null) { + textData = ""; } // preselect keys given by intent long mSigningKeyId = extras.getLong(EXTRA_SIGNATURE_KEY_ID); long[] mEncryptionKeyIds = extras.getLongArray(EXTRA_ENCRYPTION_KEY_IDS); - if (savedInstanceState == null) { FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); -- cgit v1.2.3 From 64ca19464b50cf14193e25724eaadd229b1a86ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 25 Apr 2015 14:37:55 +0200 Subject: Set different titles when changing in nav drawer --- .../org/sufficientlysecure/keychain/ui/MainActivity.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java index fa4f07d88..151382da3 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java @@ -49,7 +49,8 @@ public class MainActivity extends ActionBarActivity implements FabContainer { private KeyListFragment mKeyListFragment ; private AppsListFragment mAppsListFragment; private EncryptDecryptOverviewFragment mEncryptDecryptOverviewFragment; - private Fragment lastUsedFragment; + private Fragment mLastUsedFragment; + private Toolbar mToolbar; @Override public void onCreate(Bundle savedInstanceState) { @@ -63,14 +64,14 @@ public class MainActivity extends ActionBarActivity implements FabContainer { transaction.replace(R.id.main_fragment_container, mainFragment); transaction.commit(); - final Toolbar toolbar = (Toolbar) findViewById(R.id.activity_main_toolbar); - toolbar.setTitle(R.string.app_name); - setSupportActionBar(toolbar); + mToolbar = (Toolbar) findViewById(R.id.activity_main_toolbar); + mToolbar.setTitle(R.string.app_name); + setSupportActionBar(mToolbar); result = new Drawer() .withActivity(this) .withHeader(R.layout.main_drawer_header) - .withToolbar(toolbar) + .withToolbar(mToolbar) .addDrawerItems( new PrimaryDrawerItem().withName(R.string.nav_keys).withIcon(CommunityMaterial.Icon.cmd_key).withIdentifier(1).withCheckable(false), new PrimaryDrawerItem().withName(R.string.nav_encrypt_decrypt).withIcon(FontAwesome.Icon.faw_lock).withIdentifier(2).withCheckable(false), @@ -144,7 +145,7 @@ public class MainActivity extends ActionBarActivity implements FabContainer { } private void setFragment(Fragment fragment, boolean addToBackStack) { - this.lastUsedFragment = fragment; + this.mLastUsedFragment = fragment; FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); ft.replace(R.id.main_fragment_container, fragment); if (addToBackStack) { @@ -154,6 +155,7 @@ public class MainActivity extends ActionBarActivity implements FabContainer { } private boolean onKeysSelected() { + mToolbar.setTitle(R.string.app_name); clearFragments(); if (mKeyListFragment == null) { @@ -165,6 +167,7 @@ public class MainActivity extends ActionBarActivity implements FabContainer { } private boolean onEnDecryptSelected() { + mToolbar.setTitle(R.string.nav_encrypt_decrypt); clearFragments(); if (mEncryptDecryptOverviewFragment == null) { mEncryptDecryptOverviewFragment = new EncryptDecryptOverviewFragment(); @@ -175,6 +178,7 @@ public class MainActivity extends ActionBarActivity implements FabContainer { } private boolean onAppsSelected() { + mToolbar.setTitle(R.string.nav_apps); clearFragments(); if (mAppsListFragment == null) { mAppsListFragment = new AppsListFragment(); -- cgit v1.2.3 From 5d6eb2930cc785b7f1c88fa687cd5bc844c065d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 25 Apr 2015 15:10:15 +0200 Subject: Update in-app contributor list --- OpenKeychain/src/main/res/raw/help_about.md | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/res/raw/help_about.md b/OpenKeychain/src/main/res/raw/help_about.md index 41e8d9542..65a04e56e 100644 --- a/OpenKeychain/src/main/res/raw/help_about.md +++ b/OpenKeychain/src/main/res/raw/help_about.md @@ -6,8 +6,12 @@ License: GPLv3+ -## Developers +## Main Developers * Dominik Schürmann (Maintainer) + * Vincent Breitmoser + +## Contributors + * Adithya Abraham Philip * Art O Cathain * Ash Hughes * Brian C. Barnes @@ -15,18 +19,33 @@ License: GPLv3+ * Daniel Albert * Daniel Hammann * Daniel Haß + * Daniel Nelz + * Daniel Ramos * Greg Witczak + * 'iseki' + * Ishan Khanna + * 'jellysheep' + * 'Jesperbk' + * 'jkolo' + * Joey Castillo + * Kai Jiang + * Kartik Arora + * 'Kent' + * 'ligi' + * Lukas Zorich + * Manoj Khanna * 'mar-v-in' * Markus Doits * Miroojin Bakshi + * Morgan Gangwere * Nikhil Peter Raj * Paul Sarbinowski * 'Senecaso' * Signe Rüsch * Sreeram Boyapati - * Thialfihar (APG 1.x) + * 'steelman' + * 'Thialfihar' (APG developer) * Tim Bray - * Vincent Breitmoser ## Libraries * [SpongyCastle](http://rtyley.github.com/spongycastle/) (MIT X11 License) -- cgit v1.2.3 From f1f0126048a66b3e649f35f2e2768bd43fe1fad1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sat, 25 Apr 2015 23:40:26 +0200 Subject: Switch to new support lib version 22.1 --- OpenKeychain/build.gradle | 18 +- .../keychain/ui/MainActivity.java | 4 +- .../keychain/ui/adapter/PagerTabStripAdapter.java | 4 +- .../keychain/ui/adapter/TabsAdapter.java | 4 +- .../keychain/ui/base/BaseActivity.java | 4 +- .../keychain/ui/widget/EmailEditText.java | 12 +- .../keychain/ui/widget/KeySpinner.java | 6 +- .../keychain/ui/widget/NameEditText.java | 12 +- .../keychain/ui/widget/PassphraseEditText.java | 6 +- .../ui/widget/PasswordStrengthBarView.java | 114 +++++++ .../keychain/ui/widget/PasswordStrengthView.java | 361 ++++++++++++++++++++ .../PasswordStrengthBarView.java | 117 ------- .../PasswordStrengthView.java | 362 --------------------- .../main/res/layout/passphrase_repeat_dialog.xml | 2 +- OpenKeychain/src/main/res/values/themes.xml | 2 +- 15 files changed, 503 insertions(+), 525 deletions(-) create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PasswordStrengthBarView.java create mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PasswordStrengthView.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/passwordstrengthindicator/PasswordStrengthBarView.java delete mode 100644 OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/passwordstrengthindicator/PasswordStrengthView.java (limited to 'OpenKeychain') diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index c47e650cb..09f3b589e 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -6,10 +6,10 @@ dependencies { // NOTE: libraries are pinned to a specific build, see below // from local Android SDK - compile 'com.android.support:support-v4:22.0.0' - compile 'com.android.support:appcompat-v7:22.0.0' - compile 'com.android.support:recyclerview-v7:22.0.0' - compile 'com.android.support:cardview-v7:22.0.0' + compile 'com.android.support:support-v4:22.1.0' + compile 'com.android.support:appcompat-v7:22.1.0' + compile 'com.android.support:recyclerview-v7:22.1.0' + compile 'com.android.support:cardview-v7:22.1.0' // JCenter etc. compile 'com.eftimoff:android-patternview:1.0.1@aar' @@ -45,10 +45,10 @@ dependencies { // Comment out the libs referenced as git submodules! dependencyVerification { verify = [ - 'com.android.support:support-v4:355a11466727e8ba00e239416aec55ac3cd3fb4ffc9d20c4a33373085c050bd1', - 'com.android.support:appcompat-v7:40114cb756fecffa4a51c5645593cf64509c576594f77e41e801368051115c7b', - 'com.android.support:recyclerview-v7:859ed80e3761f8fc3126901260b208505120b5678bcf36ad2cfe9c453958b9c7', - 'com.android.support:cardview-v7:4c03f2acce9925aa4f8845cb8cb37b3772c712b2438ff15f76c9e3d3bc63ead7', + 'com.android.support:support-v4:74cb322740317b11a785eee1a94969426fade946123c4ae3f471276adaaaf54b', + 'com.android.support:appcompat-v7:6cc7fc2df4be0676f78ecfc5d3cda388e59890d11308811944f54efd84b047b7', + 'com.android.support:recyclerview-v7:522d323079a29bcd76173bd9bc7535223b4af3e5eefef9d9287df1f9e54d0c10', + 'com.android.support:cardview-v7:8dc99af71fec000baa4470c3907755264f15f816920861bc015b2babdbb49807', 'com.eftimoff:android-patternview:cec80e7265b8d8278b3c55b5fcdf551e4600ac2c8bf60d8dd76adca538af0b1e', 'com.journeyapps:zxing-android-embedded:702a4f58154dbd9baa80f66b6a15410f7a4d403f3e73b66537a8bfb156b4b718', 'com.journeyapps:zxing-android-integration:562737821b6d34c899b6fd2234ce0a8a31e02ff1fd7c59f6211961ce9767c7c8', @@ -74,7 +74,7 @@ dependencyVerification { // 'OpenKeychain.extern.KeybaseLib:Lib:c91cda4a75692d8664644cd17d8ac962ce5bc0e266ea26673a639805f1eccbdf', // 'OpenKeychain.extern:safeslinger-exchange:d222721bb35408daaab9f46449364b2657112705ee571d7532f81cbeb9c4a73f', // 'OpenKeychain.extern.snackbar:lib:52357426e5275412e2063bdf6f0e6b957a3ea74da45e0aef35d22d9afc542e23', - 'com.android.support:support-annotations:ab6b131ab0e1edd165d21fb4c3edadeacbee9539aa166f7f7cbae05b60dc207a', + 'com.android.support:support-annotations:9c59286413a2bb93e199c73261e58d5af32da7ae0a12cbd075f581a5de1fb446', ] } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java index 151382da3..05cf64092 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java @@ -24,7 +24,7 @@ import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; -import android.support.v7.app.ActionBarActivity; +import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.AdapterView; @@ -42,7 +42,7 @@ import org.sufficientlysecure.keychain.remote.ui.AppsListFragment; import org.sufficientlysecure.keychain.util.FabContainer; import org.sufficientlysecure.keychain.util.Preferences; -public class MainActivity extends ActionBarActivity implements FabContainer { +public class MainActivity extends AppCompatActivity implements FabContainer { public Drawer.Result result; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java index 963e77fe9..7b911da96 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/PagerTabStripAdapter.java @@ -21,7 +21,7 @@ import android.app.Activity; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentPagerAdapter; -import android.support.v7.app.ActionBarActivity; +import android.support.v7.app.AppCompatActivity; import java.util.ArrayList; @@ -41,7 +41,7 @@ public class PagerTabStripAdapter extends FragmentPagerAdapter { } } - public PagerTabStripAdapter(ActionBarActivity activity) { + public PagerTabStripAdapter(AppCompatActivity activity) { super(activity.getSupportFragmentManager()); mActivity = activity; } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java index 44afed351..a1f00599c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/TabsAdapter.java @@ -24,7 +24,7 @@ import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.app.FragmentTransaction; import android.support.v4.view.ViewPager; import android.support.v7.app.ActionBar; -import android.support.v7.app.ActionBarActivity; +import android.support.v7.app.AppCompatActivity; import java.util.ArrayList; @@ -45,7 +45,7 @@ public class TabsAdapter extends FragmentStatePagerAdapter implements ActionBar. } } - public TabsAdapter(ActionBarActivity activity, ViewPager pager) { + public TabsAdapter(AppCompatActivity activity, ViewPager pager) { super(activity.getSupportFragmentManager()); mContext = activity; mActionBar = activity.getSupportActionBar(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java index 07d2ef8c0..0e752881f 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/base/BaseActivity.java @@ -20,7 +20,7 @@ package org.sufficientlysecure.keychain.ui.base; import android.app.Activity; import android.os.Bundle; import android.support.v7.app.ActionBar; -import android.support.v7.app.ActionBarActivity; +import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.Gravity; import android.view.LayoutInflater; @@ -33,7 +33,7 @@ import org.sufficientlysecure.keychain.R; /** * Setups Toolbar */ -public abstract class BaseActivity extends ActionBarActivity { +public abstract class BaseActivity extends AppCompatActivity { protected Toolbar mToolbar; protected View mStatusBar; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EmailEditText.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EmailEditText.java index e21c5d510..e55f6b1ad 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EmailEditText.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/EmailEditText.java @@ -17,9 +17,8 @@ package org.sufficientlysecure.keychain.ui.widget; -import android.annotation.TargetApi; import android.content.Context; -import android.os.Build; +import android.support.v7.widget.AppCompatAutoCompleteTextView; import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; @@ -27,14 +26,13 @@ import android.util.AttributeSet; import android.util.Patterns; import android.view.inputmethod.EditorInfo; import android.widget.ArrayAdapter; -import android.widget.AutoCompleteTextView; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.util.ContactHelper; import java.util.regex.Matcher; -public class EmailEditText extends AutoCompleteTextView { +public class EmailEditText extends AppCompatAutoCompleteTextView { public EmailEditText(Context context) { super(context); @@ -51,12 +49,6 @@ public class EmailEditText extends AutoCompleteTextView { init(); } - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public EmailEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - init(); - } - private void init() { setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); reenableKeyboardSuggestions(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java index 2c75c3a7d..fc5ecd76a 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java @@ -24,7 +24,7 @@ import android.support.v4.app.FragmentActivity; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; import android.support.v4.widget.CursorAdapter; -import android.support.v7.internal.widget.TintSpinner; +import android.support.v7.widget.AppCompatSpinner; import android.text.format.DateFormat; import android.util.AttributeSet; import android.view.View; @@ -46,10 +46,10 @@ import java.util.Date; import java.util.TimeZone; /** - * Use TintSpinner from AppCompat lib instead of Spinner. Fixes white dropdown icon. + * Use AppCompatSpinner from AppCompat lib instead of Spinner. Fixes white dropdown icon. * Related: http://stackoverflow.com/a/27713090 */ -public abstract class KeySpinner extends TintSpinner implements LoaderManager.LoaderCallbacks { +public abstract class KeySpinner extends AppCompatSpinner implements LoaderManager.LoaderCallbacks { public interface OnKeyChangedListener { public void onKeyChanged(long masterKeyId); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NameEditText.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NameEditText.java index 153bf2ff2..1a034537c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NameEditText.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/NameEditText.java @@ -17,17 +17,15 @@ package org.sufficientlysecure.keychain.ui.widget; -import android.annotation.TargetApi; import android.content.Context; -import android.os.Build; +import android.support.v7.widget.AppCompatAutoCompleteTextView; import android.util.AttributeSet; import android.view.inputmethod.EditorInfo; import android.widget.ArrayAdapter; -import android.widget.AutoCompleteTextView; import org.sufficientlysecure.keychain.util.ContactHelper; -public class NameEditText extends AutoCompleteTextView { +public class NameEditText extends AppCompatAutoCompleteTextView { public NameEditText(Context context) { super(context); init(); @@ -43,12 +41,6 @@ public class NameEditText extends AutoCompleteTextView { init(); } - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public NameEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - init(); - } - private void init() { reenableKeyboardSuggestions(); initAdapter(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PassphraseEditText.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PassphraseEditText.java index 377f701d1..9364c5ee9 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PassphraseEditText.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PassphraseEditText.java @@ -19,15 +19,13 @@ package org.sufficientlysecure.keychain.ui.widget; import android.content.Context; import android.graphics.Canvas; +import android.support.v7.widget.AppCompatEditText; import android.text.Editable; import android.text.TextWatcher; import android.util.AttributeSet; import android.util.TypedValue; -import android.widget.EditText; -import org.sufficientlysecure.keychain.ui.widget.passwordstrengthindicator.PasswordStrengthBarView; - -public class PassphraseEditText extends EditText { +public class PassphraseEditText extends AppCompatEditText { PasswordStrengthBarView mPasswordStrengthBarView; int mPasswordBarWidth; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PasswordStrengthBarView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PasswordStrengthBarView.java new file mode 100644 index 000000000..e5886345f --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PasswordStrengthBarView.java @@ -0,0 +1,114 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2014 Matt Allen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.sufficientlysecure.keychain.ui.widget; + +import android.content.Context; +import android.graphics.Canvas; +import android.util.AttributeSet; + +/** + * Created by matt on 04/07/2014. + * https://github.com/matt-allen/android-password-strength-indicator + */ +public class PasswordStrengthBarView extends PasswordStrengthView { + + public PasswordStrengthBarView(Context context, AttributeSet attrs) { + super(context, attrs); + mMinHeight = 80; + mMinWidth = 300; + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + generateIndicatorColor(); + // Default to full width + int indWidth = mIndicatorWidth; + // If score, leave it as full - can cause it to become + // less than full width in this calculation + if (mCurrentScore < 20) indWidth = (mIndicatorWidth / 20) * mCurrentScore; + // Draw indicator + canvas.drawRect( + getPaddingLeft(), + getPaddingTop(), + indWidth, + mIndicatorHeight, + mIndicatorPaint + ); + // Draw guides if true + if (mShowGuides) { + // TODO: Try and do this with a loop, for efficiency + // Draw bottom guide border + float positionY = getHeight() - getPaddingBottom() - getPaddingTop(); + float notchHeight = (float) (positionY * 0.8); + canvas.drawLine( + getPaddingLeft(), + positionY, + getWidth() - getPaddingRight(), + positionY, + mGuidePaint); + // Show left-most notch + canvas.drawLine( + getPaddingLeft(), + positionY, + getPaddingLeft(), + notchHeight, + mGuidePaint + ); + // Show middle-left notch + canvas.drawLine( + (float) (mIndicatorWidth * 0.25) + getPaddingLeft(), + positionY, + (float) (mIndicatorWidth * 0.25) + getPaddingLeft(), + notchHeight, + mGuidePaint + ); + // Show the middle notch + canvas.drawLine( + (float) (mIndicatorWidth * 0.5) + getPaddingLeft(), + positionY, + (float) (mIndicatorWidth * 0.5) + getPaddingLeft(), + notchHeight, + mGuidePaint + ); + // Show the middle-right notch + canvas.drawLine( + (float) (mIndicatorWidth * 0.75) + getPaddingLeft(), + positionY, + (float) (mIndicatorWidth * 0.75) + getPaddingLeft(), + notchHeight, + mGuidePaint + ); + // Show the right-most notch + canvas.drawLine( + mIndicatorWidth + getPaddingLeft(), + positionY, + mIndicatorWidth + getPaddingLeft(), + notchHeight, + mGuidePaint + ); + } + } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PasswordStrengthView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PasswordStrengthView.java new file mode 100644 index 000000000..1487c3053 --- /dev/null +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/PasswordStrengthView.java @@ -0,0 +1,361 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2014 Matt Allen + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.sufficientlysecure.keychain.ui.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Color; +import android.graphics.Paint; +import android.util.AttributeSet; +import android.view.View; + +import org.sufficientlysecure.keychain.R; + +/** + * Created by Matt Allen + * 01/07/14 + * http://www.mattallensoftware.co.uk + * mattallen092@gmail.com + *

+ * https://github.com/matt-allen/android-password-strength-indicator + *

+ *

+ * This View is designed to indicate how secure a user-entered password is in a visual way to + * relay to the user if they need to make it stronger. The strength of the password can be set + * at creation (or after) which will decide whether their password is strong enough. + *

+ *

+ *

+ * The password strength is decided by an index of 20. The minimum score needed to pass is 10 + * which means the String has met the conditions imposed by the strength test, but can be improved. + * If the password scores 10-19 it is considered weak, and only if it scores 20 will it be + * considered strong. + *

+ */ +public class PasswordStrengthView extends View { + + protected int mMinWidth; + protected int mMinHeight; + + protected Paint mIndicatorPaint; + protected Paint mGuidePaint; + + protected int mIndicatorHeight; + protected int mIndicatorWidth; + protected int mCurrentScore; + + protected int mColorFail; + protected int mColorWeak; + protected int mColorStrong; + + protected boolean mShowGuides = true; + + /** + * Used to define that the indicator should only be looking + * for a weak password. The bare minimum is used here to let + * the user continue. + */ + public static final int STRENGTH_WEAK = 0; + + /** + * A fairly strict rule for generating a password. It encourages a password that is + * less easy to crack. + */ + public static final int STRENGTH_MEDIUM = 1; + + /** + * A strong algorithm that encourages very strong passwords that should be fairly long, with + * non-alphanumeric, numbers, and upper case. + */ + public static final int STRENGTH_STRONG = 2; + + private int mStrengthRequirement = -1; + protected String mPassword; + + public PasswordStrengthView(Context context, AttributeSet attrs) { + super(context, attrs); + + int COLOR_FAIL = context.getResources().getColor(R.color.android_red_light); + int COLOR_WEAK = context.getResources().getColor(R.color.android_orange_light); + int COLOR_STRONG = context.getResources().getColor(R.color.android_green_light); + + TypedArray style = context.getTheme().obtainStyledAttributes( + attrs, + R.styleable.PasswordStrengthView, + 0, 0); + + try { + mStrengthRequirement = style.getInteger(R.styleable.PasswordStrengthView_strength, + STRENGTH_MEDIUM); + mShowGuides = style.getBoolean(R.styleable.PasswordStrengthView_showGuides, true); + mColorFail = style.getColor(R.styleable.PasswordStrengthView_color_fail, COLOR_FAIL); + mColorWeak = style.getColor(R.styleable.PasswordStrengthView_color_weak, COLOR_WEAK); + mColorStrong = style.getColor(R.styleable.PasswordStrengthView_color_strong, + COLOR_STRONG); + } catch (Exception e) { + e.printStackTrace(); + } + // Create and style the paint used for drawing the guide on the indicator + mGuidePaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mGuidePaint.setStyle(Paint.Style.FILL_AND_STROKE); + mGuidePaint.setColor(Color.BLACK); + // Create and style paint for indicator + mIndicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mIndicatorPaint.setStyle(Paint.Style.FILL); + } + + /** + * This view can determine if the password entered by the user is acceptable for + * use by your use case. This is based on the strength requirement you have set. + * + * @return True if requirement has been met + */ + public boolean isStrengthRequirementMet() { + return (mCurrentScore >= 10); + } + + /** + * Change the strength requirement of the password entered by the user. This will also + * re-check the password already entered against these new requirements. + * + * @param requiredStrength Use the public constants of this class to set + */ + public void setStrengthRequirement(int requiredStrength) { + if (requiredStrength >= 0 && requiredStrength <= 2) { + mStrengthRequirement = requiredStrength; + if (mPassword != null && mPassword.length() > 0) { + generatePasswordScore(); + // Update view with new score + invalidate(); + requestLayout(); + } + } else { + throw new IndexOutOfBoundsException("Input out of expected range"); + } + } + + /** + * Update the password string to check strength of + * + * @param passwordString String representation of user-input + */ + public void setPassword(String passwordString) { + if (passwordString != null && passwordString.length() > 0) { + mPassword = passwordString; + generatePasswordScore(); + } else { + mPassword = ""; + mCurrentScore = 0; + } + + // Update view with new score + invalidate(); + requestLayout(); + } + + /** + * Private convenience method for adding to the password score + * + * @param score Amount to be added to current score + */ + protected void addToPasswordScore(int score) { + int newScore = mCurrentScore + score; + + // Limit max score + if (newScore > 20) { + mCurrentScore = 20; + } else { + mCurrentScore = newScore; + } + } + + /** + * Call this to determine the current strength requirement set on the algorithm + * + * @return Int representation of the current strength set for the indicator + */ + public int getStrengthRequirement() { + return mStrengthRequirement; + } + + /** + * Generate a score based on the password. The password will already need to be stored + * as a class member before running this. + */ + protected void generatePasswordScore() { + mCurrentScore = 0; + int upperCase = getUppercaseCount(mPassword); + int nonAlpha = getNonAlphanumericCount(mPassword); + int numbers = getNumberCount(mPassword); + switch (mStrengthRequirement) { + case STRENGTH_WEAK: + addToPasswordScore(mPassword.length() * 2); + addToPasswordScore(upperCase * 2); + addToPasswordScore(nonAlpha * 2); + addToPasswordScore(numbers * 2); + break; + + case STRENGTH_MEDIUM: + addToPasswordScore(mPassword.length()); + addToPasswordScore(upperCase); + addToPasswordScore(nonAlpha * 2); + addToPasswordScore(numbers); + break; + + case STRENGTH_STRONG: + addToPasswordScore(mPassword.length() / 2); + // Cut the score in half to make this a very high requirement + addToPasswordScore(upperCase); + addToPasswordScore(nonAlpha); + addToPasswordScore(numbers); + break; + } + } + + @Override + protected void onSizeChanged(int w, int h, int oldW, int oldH) { + super.onSizeChanged(w, h, oldW, oldH); + int paddingX = getPaddingLeft(); + int paddingY = getPaddingTop(); + mIndicatorHeight = h - paddingY; + mIndicatorWidth = w - paddingX; + } + + /** + * The standard parts of the onMeasure needed to create the password strength + * indicator. Subclasses should call super.onMeasure, but also need to set + * the minimum height and width in the constructor. + * + * @param widthMeasureSpec The measurement given by the system + * @param heightMeasureSpec The measurement given by the system + */ + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + // Set minimum space for the view to do it's thing + int minW = getPaddingLeft() + getPaddingRight() + mMinWidth; + int w = resolveSizeAndState(minW, widthMeasureSpec, 1); + // And give it enough height so it's visible + int minH = mMinHeight + getPaddingBottom() + getPaddingTop(); + int h = resolveSizeAndState(minH, heightMeasureSpec, 0); + // Feed these back into UIKit + setMeasuredDimension(w, h); + } + + /** + * Set the colour of the indicator {@code Paint} to one that is appropriate + * for the strength of the password. + */ + protected void generateIndicatorColor() { + int color = mColorFail; + if (mCurrentScore >= 18) { + color = mColorStrong; + } else if (mCurrentScore >= 10) { + color = mColorWeak; + } + mIndicatorPaint.setColor(color); + } + + /** + * Quick method to determine how many of the characters in a given string are upper case + * + * @param stringToCheck The string to examine + * @return Number of upper case characters + */ + protected int getUppercaseCount(String stringToCheck) { + int score = 0; + int loops = stringToCheck.length() - 1; + for (int i = 0; i <= loops; i++) { + if (Character.isUpperCase(stringToCheck.charAt(i))) { + score++; + } + } + return score; + } + + /** + * A convenience method to determine how many characters in the given String aren't + * letters or numbers. + * + * @param stringToCheck + * @return Number of characters that aren't numbers or letters + */ + protected int getNonAlphanumericCount(String stringToCheck) { + int score = 0; + int loops = stringToCheck.length() - 1; + for (int i = 0; i <= loops; i++) { + if (!Character.isLetter(stringToCheck.charAt(i)) && + !Character.isDigit(stringToCheck.charAt(i))) { + score++; + } + } + return score; + } + + /** + * A convenience method for returning the count of numbers in a given String. + * + * @param stringToCheck + * @return The numbers of digits in the String + */ + protected int getNumberCount(String stringToCheck) { + int score = 0; + int loops = stringToCheck.length() - 1; + for (int i = 0; i <= loops; i++) { + if (Character.isDigit(stringToCheck.charAt(i))) { + score++; + } + } + return score; + } + + /** + * Set the guides to show on the view.
+ * On the line style, the guides will show underneath
+ * On the rounded style, the guides will be shown on the outer edges.
+ * The view will be redrawn after the method is called. + * + * @param showGuides True if you want the guides to be shown + */ + public void setShowGuides(boolean showGuides) { + mShowGuides = showGuides; + if (mPassword != null && mPassword.length() > 0) { + generatePasswordScore(); + } else { + mCurrentScore = 0; + } + + invalidate(); + requestLayout(); + } + + /** + * Determine whether the view is showing the guides for the password score + * + * @return True if the guides are being shown + */ + public boolean isShowingGuides() { + return mShowGuides; + } +} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/passwordstrengthindicator/PasswordStrengthBarView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/passwordstrengthindicator/PasswordStrengthBarView.java deleted file mode 100644 index 9e06c4cce..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/passwordstrengthindicator/PasswordStrengthBarView.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Matt Allen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.sufficientlysecure.keychain.ui.widget.passwordstrengthindicator; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; -import android.util.AttributeSet; - -/** - * Created by matt on 04/07/2014. - * https://github.com/matt-allen/android-password-strength-indicator - */ -public class PasswordStrengthBarView extends PasswordStrengthView { - - public PasswordStrengthBarView(Context context, AttributeSet attrs) { - super(context, attrs); - mMinHeight = 80; - mMinWidth = 300; - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - generateIndicatorColor(); - // Default to full width - int indWidth = mIndicatorWidth; - // If score, leave it as full - can cause it to become - // less than full width in this calculation - if (mCurrentScore < 20) indWidth = (mIndicatorWidth / 20) * mCurrentScore; - // Draw indicator - canvas.drawRect( - getPaddingLeft(), - getPaddingTop(), - indWidth, - mIndicatorHeight, - mIndicatorPaint - ); - // Draw guides if true - if (mShowGuides) { - // TODO: Try and do this with a loop, for efficiency - // Draw bottom guide border - float positionY = getHeight() - getPaddingBottom() - getPaddingTop(); - float notchHeight = (float) (positionY * 0.8); - canvas.drawLine( - getPaddingLeft(), - positionY, - getWidth() - getPaddingRight(), - positionY, - mGuidePaint); - // Show left-most notch - canvas.drawLine( - getPaddingLeft(), - positionY, - getPaddingLeft(), - notchHeight, - mGuidePaint - ); - // Show middle-left notch - canvas.drawLine( - (float) (mIndicatorWidth * 0.25) + getPaddingLeft(), - positionY, - (float) (mIndicatorWidth * 0.25) + getPaddingLeft(), - notchHeight, - mGuidePaint - ); - // Show the middle notch - canvas.drawLine( - (float) (mIndicatorWidth * 0.5) + getPaddingLeft(), - positionY, - (float) (mIndicatorWidth * 0.5) + getPaddingLeft(), - notchHeight, - mGuidePaint - ); - // Show the middle-right notch - canvas.drawLine( - (float) (mIndicatorWidth * 0.75) + getPaddingLeft(), - positionY, - (float) (mIndicatorWidth * 0.75) + getPaddingLeft(), - notchHeight, - mGuidePaint - ); - // Show the right-most notch - canvas.drawLine( - mIndicatorWidth + getPaddingLeft(), - positionY, - mIndicatorWidth + getPaddingLeft(), - notchHeight, - mGuidePaint - ); - } - } -} diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/passwordstrengthindicator/PasswordStrengthView.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/passwordstrengthindicator/PasswordStrengthView.java deleted file mode 100644 index bc5018497..000000000 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/passwordstrengthindicator/PasswordStrengthView.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2014 Matt Allen - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.sufficientlysecure.keychain.ui.widget.passwordstrengthindicator; - -import android.content.Context; -import android.content.res.TypedArray; -import android.graphics.Color; -import android.graphics.Paint; -import android.util.AttributeSet; -import android.view.View; - -import org.sufficientlysecure.keychain.R; - -/** - * Created by Matt Allen - * 01/07/14 - * http://www.mattallensoftware.co.uk - * mattallen092@gmail.com - *

- * https://github.com/matt-allen/android-password-strength-indicator - *

- *

- * This View is designed to indicate how secure a user-entered password is in a visual way to - * relay to the user if they need to make it stronger. The strength of the password can be set - * at creation (or after) which will decide whether their password is strong enough. - *

- *

- *

- * The password strength is decided by an index of 20. The minimum score needed to pass is 10 - * which means the String has met the conditions imposed by the strength test, but can be improved. - * If the password scores 10-19 it is considered weak, and only if it scores 20 will it be - * considered strong. - *

- */ -public class PasswordStrengthView extends View { - - - protected int mMinWidth; - protected int mMinHeight; - - protected Paint mIndicatorPaint; - protected Paint mGuidePaint; - - protected int mIndicatorHeight; - protected int mIndicatorWidth; - protected int mCurrentScore; - - protected int mColorFail; - protected int mColorWeak; - protected int mColorStrong; - - protected boolean mShowGuides = true; - - /** - * Used to define that the indicator should only be looking - * for a weak password. The bare minimum is used here to let - * the user continue. - */ - public static final int STRENGTH_WEAK = 0; - - /** - * A fairly strict rule for generating a password. It encourages a password that is - * less easy to crack. - */ - public static final int STRENGTH_MEDIUM = 1; - - /** - * A strong algorithm that encourages very strong passwords that should be fairly long, with - * non-alphanumeric, numbers, and upper case. - */ - public static final int STRENGTH_STRONG = 2; - - private int mStrengthRequirement = -1; - protected String mPassword; - - public PasswordStrengthView(Context context, AttributeSet attrs) { - super(context, attrs); - - int COLOR_FAIL = context.getResources().getColor(R.color.android_red_light); - int COLOR_WEAK = context.getResources().getColor(R.color.android_orange_light); - int COLOR_STRONG = context.getResources().getColor(R.color.android_green_light); - - TypedArray style = context.getTheme().obtainStyledAttributes( - attrs, - R.styleable.PasswordStrengthView, - 0, 0); - - try { - mStrengthRequirement = style.getInteger(R.styleable.PasswordStrengthView_strength, - STRENGTH_MEDIUM); - mShowGuides = style.getBoolean(R.styleable.PasswordStrengthView_showGuides, true); - mColorFail = style.getColor(R.styleable.PasswordStrengthView_color_fail, COLOR_FAIL); - mColorWeak = style.getColor(R.styleable.PasswordStrengthView_color_weak, COLOR_WEAK); - mColorStrong = style.getColor(R.styleable.PasswordStrengthView_color_strong, - COLOR_STRONG); - } catch (Exception e) { - e.printStackTrace(); - } - // Create and style the paint used for drawing the guide on the indicator - mGuidePaint = new Paint(Paint.ANTI_ALIAS_FLAG); - mGuidePaint.setStyle(Paint.Style.FILL_AND_STROKE); - mGuidePaint.setColor(Color.BLACK); - // Create and style paint for indicator - mIndicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - mIndicatorPaint.setStyle(Paint.Style.FILL); - } - - /** - * This view can determine if the password entered by the user is acceptable for - * use by your use case. This is based on the strength requirement you have set. - * - * @return True if requirement has been met - */ - public boolean isStrengthRequirementMet() { - return (mCurrentScore >= 10); - } - - /** - * Change the strength requirement of the password entered by the user. This will also - * re-check the password already entered against these new requirements. - * - * @param requiredStrength Use the public constants of this class to set - */ - public void setStrengthRequirement(int requiredStrength) { - if (requiredStrength >= 0 && requiredStrength <= 2) { - mStrengthRequirement = requiredStrength; - if (mPassword != null && mPassword.length() > 0) { - generatePasswordScore(); - // Update view with new score - invalidate(); - requestLayout(); - } - } else { - throw new IndexOutOfBoundsException("Input out of expected range"); - } - } - - /** - * Update the password string to check strength of - * - * @param passwordString String representation of user-input - */ - public void setPassword(String passwordString) { - if (passwordString != null && passwordString.length() > 0) { - mPassword = passwordString; - generatePasswordScore(); - } else { - mPassword = ""; - mCurrentScore = 0; - } - - // Update view with new score - invalidate(); - requestLayout(); - } - - /** - * Private convenience method for adding to the password score - * - * @param score Amount to be added to current score - */ - protected void addToPasswordScore(int score) { - int newScore = mCurrentScore + score; - - // Limit max score - if (newScore > 20) { - mCurrentScore = 20; - } else { - mCurrentScore = newScore; - } - } - - /** - * Call this to determine the current strength requirement set on the algorithm - * - * @return Int representation of the current strength set for the indicator - */ - public int getStrengthRequirement() { - return mStrengthRequirement; - } - - /** - * Generate a score based on the password. The password will already need to be stored - * as a class member before running this. - */ - protected void generatePasswordScore() { - mCurrentScore = 0; - int upperCase = getUppercaseCount(mPassword); - int nonAlpha = getNonAlphanumericCount(mPassword); - int numbers = getNumberCount(mPassword); - switch (mStrengthRequirement) { - case STRENGTH_WEAK: - addToPasswordScore(mPassword.length() * 2); - addToPasswordScore(upperCase * 2); - addToPasswordScore(nonAlpha * 2); - addToPasswordScore(numbers * 2); - break; - - case STRENGTH_MEDIUM: - addToPasswordScore(mPassword.length()); - addToPasswordScore(upperCase); - addToPasswordScore(nonAlpha * 2); - addToPasswordScore(numbers); - break; - - case STRENGTH_STRONG: - addToPasswordScore(mPassword.length() / 2); - // Cut the score in half to make this a very high requirement - addToPasswordScore(upperCase); - addToPasswordScore(nonAlpha); - addToPasswordScore(numbers); - break; - } - } - - @Override - protected void onSizeChanged(int w, int h, int oldW, int oldH) { - super.onSizeChanged(w, h, oldW, oldH); - int paddingX = getPaddingLeft(); - int paddingY = getPaddingTop(); - mIndicatorHeight = h - paddingY; - mIndicatorWidth = w - paddingX; - } - - /** - * The standard parts of the onMeasure needed to create the password strength - * indicator. Subclasses should call super.onMeasure, but also need to set - * the minimum height and width in the constructor. - * - * @param widthMeasureSpec The measurement given by the system - * @param heightMeasureSpec The measurement given by the system - */ - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - // Set minimum space for the view to do it's thing - int minW = getPaddingLeft() + getPaddingRight() + mMinWidth; - int w = resolveSizeAndState(minW, widthMeasureSpec, 1); - // And give it enough height so it's visible - int minH = mMinHeight + getPaddingBottom() + getPaddingTop(); - int h = resolveSizeAndState(minH, heightMeasureSpec, 0); - // Feed these back into UIKit - setMeasuredDimension(w, h); - } - - /** - * Set the colour of the indicator {@code Paint} to one that is appropriate - * for the strength of the password. - */ - protected void generateIndicatorColor() { - int color = mColorFail; - if (mCurrentScore >= 18) { - color = mColorStrong; - } else if (mCurrentScore >= 10) { - color = mColorWeak; - } - mIndicatorPaint.setColor(color); - } - - /** - * Quick method to determine how many of the characters in a given string are upper case - * - * @param stringToCheck The string to examine - * @return Number of upper case characters - */ - protected int getUppercaseCount(String stringToCheck) { - int score = 0; - int loops = stringToCheck.length() - 1; - for (int i = 0; i <= loops; i++) { - if (Character.isUpperCase(stringToCheck.charAt(i))) { - score++; - } - } - return score; - } - - /** - * A convenience method to determine how many characters in the given String aren't - * letters or numbers. - * - * @param stringToCheck - * @return Number of characters that aren't numbers or letters - */ - protected int getNonAlphanumericCount(String stringToCheck) { - int score = 0; - int loops = stringToCheck.length() - 1; - for (int i = 0; i <= loops; i++) { - if (!Character.isLetter(stringToCheck.charAt(i)) && - !Character.isDigit(stringToCheck.charAt(i))) { - score++; - } - } - return score; - } - - /** - * A convenience method for returning the count of numbers in a given String. - * - * @param stringToCheck - * @return The numbers of digits in the String - */ - protected int getNumberCount(String stringToCheck) { - int score = 0; - int loops = stringToCheck.length() - 1; - for (int i = 0; i <= loops; i++) { - if (Character.isDigit(stringToCheck.charAt(i))) { - score++; - } - } - return score; - } - - /** - * Set the guides to show on the view.
- * On the line style, the guides will show underneath
- * On the rounded style, the guides will be shown on the outer edges.
- * The view will be redrawn after the method is called. - * - * @param showGuides True if you want the guides to be shown - */ - public void setShowGuides(boolean showGuides) { - mShowGuides = showGuides; - if (mPassword != null && mPassword.length() > 0) { - generatePasswordScore(); - } else { - mCurrentScore = 0; - } - - invalidate(); - requestLayout(); - } - - /** - * Determine whether the view is showing the guides for the password score - * - * @return True if the guides are being shown - */ - public boolean isShowingGuides() { - return mShowGuides; - } -} diff --git a/OpenKeychain/src/main/res/layout/passphrase_repeat_dialog.xml b/OpenKeychain/src/main/res/layout/passphrase_repeat_dialog.xml index 5f323716c..ffc5266b5 100644 --- a/OpenKeychain/src/main/res/layout/passphrase_repeat_dialog.xml +++ b/OpenKeychain/src/main/res/layout/passphrase_repeat_dialog.xml @@ -33,7 +33,7 @@ android:ems="10" android:layout_gravity="center_horizontal" /> - @color/primary_dark @color/accent - true + true false -- cgit v1.2.3 From c442d3bd0d3bac96614d3d5c0e833a42cab4706e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 26 Apr 2015 00:33:26 +0200 Subject: Put decrypt result in toolbar, some ui fixes for decrypt --- .../keychain/ui/DecryptFragment.java | 19 +-- .../keychain/ui/DecryptTextFragment.java | 6 +- .../drawable-hdpi/ic_content_copy_black_24dp.png | Bin 0 -> 284 bytes .../main/res/drawable-hdpi/ic_share_black_24dp.png | Bin 0 -> 499 bytes .../drawable-mdpi/ic_content_copy_black_24dp.png | Bin 0 -> 214 bytes .../main/res/drawable-mdpi/ic_share_black_24dp.png | Bin 0 -> 355 bytes .../drawable-xhdpi/ic_content_copy_black_24dp.png | Bin 0 -> 304 bytes .../res/drawable-xhdpi/ic_share_black_24dp.png | Bin 0 -> 614 bytes .../drawable-xxhdpi/ic_content_copy_black_24dp.png | Bin 0 -> 397 bytes .../res/drawable-xxhdpi/ic_share_black_24dp.png | Bin 0 -> 804 bytes .../ic_content_copy_black_24dp.png | Bin 0 -> 480 bytes .../res/drawable-xxxhdpi/ic_share_black_24dp.png | Bin 0 -> 1052 bytes .../src/main/res/layout/decrypt_text_activity.xml | 2 +- .../src/main/res/layout/decrypt_text_fragment.xml | 2 +- .../src/main/res/layout/toolbar_result_decrypt.xml | 145 +++++++++++++++++++++ OpenKeychain/src/main/res/menu/decrypt_menu.xml | 4 +- 16 files changed, 162 insertions(+), 16 deletions(-) create mode 100644 OpenKeychain/src/main/res/drawable-hdpi/ic_content_copy_black_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-hdpi/ic_share_black_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-mdpi/ic_content_copy_black_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-mdpi/ic_share_black_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-xhdpi/ic_content_copy_black_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-xhdpi/ic_share_black_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-xxhdpi/ic_content_copy_black_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-xxhdpi/ic_share_black_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-xxxhdpi/ic_content_copy_black_24dp.png create mode 100644 OpenKeychain/src/main/res/drawable-xxxhdpi/ic_share_black_24dp.png create mode 100644 OpenKeychain/src/main/res/layout/toolbar_result_decrypt.xml (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java index d641f02f9..651b56ab0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptFragment.java @@ -79,17 +79,18 @@ public abstract class DecryptFragment extends CryptoOperationFragment implements public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); - mResultLayout = (LinearLayout) view.findViewById(R.id.result_main_layout); + // NOTE: These views are inside the activity! + mResultLayout = (LinearLayout) getActivity().findViewById(R.id.result_main_layout); mResultLayout.setVisibility(View.GONE); - mEncryptionIcon = (ImageView) view.findViewById(R.id.result_encryption_icon); - mEncryptionText = (TextView) view.findViewById(R.id.result_encryption_text); - mSignatureIcon = (ImageView) view.findViewById(R.id.result_signature_icon); - mSignatureText = (TextView) view.findViewById(R.id.result_signature_text); - mSignatureLayout = view.findViewById(R.id.result_signature_layout); - mSignatureName = (TextView) view.findViewById(R.id.result_signature_name); - mSignatureEmail = (TextView) view.findViewById(R.id.result_signature_email); - mSignatureAction = (TextView) view.findViewById(R.id.result_signature_action); + mEncryptionIcon = (ImageView) getActivity().findViewById(R.id.result_encryption_icon); + mEncryptionText = (TextView) getActivity().findViewById(R.id.result_encryption_text); + mSignatureIcon = (ImageView) getActivity().findViewById(R.id.result_signature_icon); + mSignatureText = (TextView) getActivity().findViewById(R.id.result_signature_text); + mSignatureLayout = getActivity().findViewById(R.id.result_signature_layout); + mSignatureName = (TextView) getActivity().findViewById(R.id.result_signature_name); + mSignatureEmail = (TextView) getActivity().findViewById(R.id.result_signature_email); + mSignatureAction = (TextView) getActivity().findViewById(R.id.result_signature_action); } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java index 1b9ae917f..6f576a112 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/DecryptTextFragment.java @@ -97,9 +97,9 @@ public class DecryptTextFragment extends DecryptFragment { /** * Create Intent Chooser but exclude decrypt activites */ - private Intent sendWithChooserExcludingEncrypt(String text) { + private Intent sendWithChooserExcludingDecrypt(String text) { Intent prototype = createSendIntent(text); - String title = getString(R.string.title_share_file); + String title = getString(R.string.title_share_message); // we don't want to decrypt the decrypted, no inception ;) String[] blacklist = new String[]{ @@ -147,7 +147,7 @@ public class DecryptTextFragment extends DecryptFragment { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.decrypt_share: { - startActivity(sendWithChooserExcludingEncrypt(mText.getText().toString())); + startActivity(sendWithChooserExcludingDecrypt(mText.getText().toString())); break; } case R.id.decrypt_copy: { diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_content_copy_black_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_content_copy_black_24dp.png new file mode 100644 index 000000000..dc8c85cce Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-hdpi/ic_content_copy_black_24dp.png differ diff --git a/OpenKeychain/src/main/res/drawable-hdpi/ic_share_black_24dp.png b/OpenKeychain/src/main/res/drawable-hdpi/ic_share_black_24dp.png new file mode 100644 index 000000000..2839b1352 Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-hdpi/ic_share_black_24dp.png differ diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_content_copy_black_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_content_copy_black_24dp.png new file mode 100644 index 000000000..4ad9e552d Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-mdpi/ic_content_copy_black_24dp.png differ diff --git a/OpenKeychain/src/main/res/drawable-mdpi/ic_share_black_24dp.png b/OpenKeychain/src/main/res/drawable-mdpi/ic_share_black_24dp.png new file mode 100644 index 000000000..f0ff945b8 Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-mdpi/ic_share_black_24dp.png differ diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_content_copy_black_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_content_copy_black_24dp.png new file mode 100644 index 000000000..c6f0e6b85 Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-xhdpi/ic_content_copy_black_24dp.png differ diff --git a/OpenKeychain/src/main/res/drawable-xhdpi/ic_share_black_24dp.png b/OpenKeychain/src/main/res/drawable-xhdpi/ic_share_black_24dp.png new file mode 100644 index 000000000..4b3675766 Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-xhdpi/ic_share_black_24dp.png differ diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_content_copy_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_content_copy_black_24dp.png new file mode 100644 index 000000000..081fbec5b Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_content_copy_black_24dp.png differ diff --git a/OpenKeychain/src/main/res/drawable-xxhdpi/ic_share_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_share_black_24dp.png new file mode 100644 index 000000000..09d4df6af Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-xxhdpi/ic_share_black_24dp.png differ diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_content_copy_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_content_copy_black_24dp.png new file mode 100644 index 000000000..04c07fb56 Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_content_copy_black_24dp.png differ diff --git a/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_share_black_24dp.png b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_share_black_24dp.png new file mode 100644 index 000000000..0fe15fc05 Binary files /dev/null and b/OpenKeychain/src/main/res/drawable-xxxhdpi/ic_share_black_24dp.png differ diff --git a/OpenKeychain/src/main/res/layout/decrypt_text_activity.xml b/OpenKeychain/src/main/res/layout/decrypt_text_activity.xml index a6099e25e..41d7c5c95 100644 --- a/OpenKeychain/src/main/res/layout/decrypt_text_activity.xml +++ b/OpenKeychain/src/main/res/layout/decrypt_text_activity.xml @@ -5,7 +5,7 @@ + layout="@layout/toolbar_result_decrypt" /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenKeychain/src/main/res/menu/decrypt_menu.xml b/OpenKeychain/src/main/res/menu/decrypt_menu.xml index c0d7a519f..9e90fc9c7 100644 --- a/OpenKeychain/src/main/res/menu/decrypt_menu.xml +++ b/OpenKeychain/src/main/res/menu/decrypt_menu.xml @@ -5,13 +5,13 @@ \ No newline at end of file -- cgit v1.2.3 From d0d4149e8695b833eb12e959ebe0ea1a861dd375 Mon Sep 17 00:00:00 2001 From: vectorijk Date: Sat, 25 Apr 2015 15:33:30 -0700 Subject: update lib MaterialDrawer to latest(2.8.2) --- OpenKeychain/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index 09f3b589e..9530c3279 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -22,7 +22,7 @@ dependencies { compile "com.splitwise:tokenautocomplete:1.3.3@aar" compile 'se.emilsjolander:stickylistheaders:2.6.0' compile 'org.sufficientlysecure:html-textview:1.1' - compile 'com.mikepenz.materialdrawer:library:2.7.9@aar' + compile 'com.mikepenz.materialdrawer:library:2.8.2@aar' compile 'com.mikepenz.iconics:library:0.9.1@aar' compile 'com.mikepenz.iconics:octicons-typeface:2.2.0@aar' compile 'com.mikepenz.iconics:meteocons-typeface:1.1.1@aar' @@ -59,7 +59,7 @@ dependencyVerification { 'com.splitwise:tokenautocomplete:20bee71cc59b3828eb000b684d46ddf738efd56b8fee453a509cd16fda42c8cb', 'se.emilsjolander:stickylistheaders:8c05981ec5725be33f7cee5e68c13f3db49cd5c75f1aaeb04024920b1ef96ad4', 'org.sufficientlysecure:html-textview:ca24b1522be88378634093815ce9ff1b4920c72e7513a045a7846e14069ef988', - 'com.mikepenz.materialdrawer:library:3ef80c6e1ca1b29cfcbb27fa7927c02b2246e068c17fe52283703c4897449923', + 'com.mikepenz.materialdrawer:library:970317ed1a3cb96317f7b8d62ff592b3103eb46dfd68d9b244e7143623dc6d7a', 'com.mikepenz.iconics:library:4698a36ee4c2af765d0a85779c61474d755b90d66a59020105b6760a8a909e9e', 'com.mikepenz.iconics:octicons-typeface:67ed7d456a9ce5f5307b85f955797bfb3dd674e2f6defb31c6b8bbe2ede290be', 'com.mikepenz.iconics:meteocons-typeface:39a8a9e70cd8287cdb119af57a672a41dd09240dba6697f5a0dbda1ccc33298b', -- cgit v1.2.3 From 4732bc5744a1d1e29a4deaf7ab94e604e23da31c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 26 Apr 2015 00:36:37 +0200 Subject: Remove unused decrypt result layout --- .../src/main/res/layout/decrypt_file_fragment.xml | 2 - .../src/main/res/layout/decrypt_result_include.xml | 136 --------------------- .../src/main/res/layout/decrypt_text_fragment.xml | 2 - 3 files changed, 140 deletions(-) delete mode 100644 OpenKeychain/src/main/res/layout/decrypt_result_include.xml (limited to 'OpenKeychain') diff --git a/OpenKeychain/src/main/res/layout/decrypt_file_fragment.xml b/OpenKeychain/src/main/res/layout/decrypt_file_fragment.xml index 2ef411eaf..60673e475 100644 --- a/OpenKeychain/src/main/res/layout/decrypt_file_fragment.xml +++ b/OpenKeychain/src/main/res/layout/decrypt_file_fragment.xml @@ -9,8 +9,6 @@ android:layout_height="wrap_content" android:orientation="vertical"> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml b/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml index 37e4cd8f1..5b74905e7 100644 --- a/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml +++ b/OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml @@ -4,8 +4,6 @@ android:layout_height="match_parent" android:orientation="vertical"> - - Date: Sun, 26 Apr 2015 01:28:29 +0200 Subject: UI fixes for Android < 5 --- OpenKeychain/build.gradle | 10 +++++----- .../keychain/ui/CreateKeyEmailFragment.java | 7 +++---- .../keychain/ui/CreateKeyPassphraseFragment.java | 8 ++------ .../sufficientlysecure/keychain/ui/MainActivity.java | 2 +- OpenKeychain/src/main/res/layout/main_activity.xml | 17 ++++++++++++----- OpenKeychain/src/main/res/values/themes.xml | 7 +------ 6 files changed, 24 insertions(+), 27 deletions(-) (limited to 'OpenKeychain') diff --git a/OpenKeychain/build.gradle b/OpenKeychain/build.gradle index 09f3b589e..2d4e8a4d3 100644 --- a/OpenKeychain/build.gradle +++ b/OpenKeychain/build.gradle @@ -6,8 +6,8 @@ dependencies { // NOTE: libraries are pinned to a specific build, see below // from local Android SDK - compile 'com.android.support:support-v4:22.1.0' - compile 'com.android.support:appcompat-v7:22.1.0' + compile 'com.android.support:support-v4:22.1.1' + compile 'com.android.support:appcompat-v7:22.1.1' compile 'com.android.support:recyclerview-v7:22.1.0' compile 'com.android.support:cardview-v7:22.1.0' @@ -45,8 +45,8 @@ dependencies { // Comment out the libs referenced as git submodules! dependencyVerification { verify = [ - 'com.android.support:support-v4:74cb322740317b11a785eee1a94969426fade946123c4ae3f471276adaaaf54b', - 'com.android.support:appcompat-v7:6cc7fc2df4be0676f78ecfc5d3cda388e59890d11308811944f54efd84b047b7', + 'com.android.support:support-v4:1e2e4d35ac7fd30db5ce3bc177b92e4d5af86acef2ef93e9221599d733346f56', + 'com.android.support:appcompat-v7:9a2355537c2f01cf0b95523605c18606b8d824017e6e94a05c77b0cfc8f21c96', 'com.android.support:recyclerview-v7:522d323079a29bcd76173bd9bc7535223b4af3e5eefef9d9287df1f9e54d0c10', 'com.android.support:cardview-v7:8dc99af71fec000baa4470c3907755264f15f816920861bc015b2babdbb49807', 'com.eftimoff:android-patternview:cec80e7265b8d8278b3c55b5fcdf551e4600ac2c8bf60d8dd76adca538af0b1e', @@ -74,7 +74,7 @@ dependencyVerification { // 'OpenKeychain.extern.KeybaseLib:Lib:c91cda4a75692d8664644cd17d8ac962ce5bc0e266ea26673a639805f1eccbdf', // 'OpenKeychain.extern:safeslinger-exchange:d222721bb35408daaab9f46449364b2657112705ee571d7532f81cbeb9c4a73f', // 'OpenKeychain.extern.snackbar:lib:52357426e5275412e2063bdf6f0e6b957a3ea74da45e0aef35d22d9afc542e23', - 'com.android.support:support-annotations:9c59286413a2bb93e199c73261e58d5af32da7ae0a12cbd075f581a5de1fb446', + 'com.android.support:support-annotations:7bc07519aa613b186001160403bcfd68260fa82c61cc7e83adeedc9b862b94ae', ] } diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java index 85e2f8e9d..3d7b31905 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyEmailFragment.java @@ -125,11 +125,7 @@ public class CreateKeyEmailFragment extends Fragment { // initial values if (mAdditionalEmailModels == null) { mAdditionalEmailModels = new ArrayList<>(); - if (mCreateKeyActivity.mAdditionalEmails != null) { - mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails); - } } - if (mEmailAdapter == null) { mEmailAdapter = new EmailAdapter(mAdditionalEmailModels, new View.OnClickListener() { @Override @@ -138,6 +134,9 @@ public class CreateKeyEmailFragment extends Fragment { } }); } + if (mAdditionalEmailModels.isEmpty() && mCreateKeyActivity.mAdditionalEmails != null) { + mEmailAdapter.addAll(mCreateKeyActivity.mAdditionalEmails); + } mEmailsRecyclerView.setAdapter(mEmailAdapter); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java index 32173edf7..3379e0a6d 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateKeyPassphraseFragment.java @@ -21,7 +21,6 @@ import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; -import android.text.Editable; import android.text.method.HideReturnsTransformationMethod; import android.text.method.PasswordTransformationMethod; import android.view.LayoutInflater; @@ -37,9 +36,6 @@ import org.sufficientlysecure.keychain.ui.CreateKeyActivity.FragAction; import org.sufficientlysecure.keychain.ui.widget.PassphraseEditText; import org.sufficientlysecure.keychain.util.Passphrase; -import java.util.ArrayList; -import java.util.Arrays; - public class CreateKeyPassphraseFragment extends Fragment { // view @@ -111,8 +107,8 @@ public class CreateKeyPassphraseFragment extends Fragment { // initial values // TODO: using String here is unsafe... if (mCreateKeyActivity.mPassphrase != null) { - mPassphraseEdit.setText(Arrays.toString(mCreateKeyActivity.mPassphrase.getCharArray())); - mPassphraseEditAgain.setText(Arrays.toString(mCreateKeyActivity.mPassphrase.getCharArray())); + mPassphraseEdit.setText(new String(mCreateKeyActivity.mPassphrase.getCharArray())); + mPassphraseEditAgain.setText(new String(mCreateKeyActivity.mPassphrase.getCharArray())); } mPassphraseEdit.requestFocus(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java index 05cf64092..f571ba1e6 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/MainActivity.java @@ -64,7 +64,7 @@ public class MainActivity extends AppCompatActivity implements FabContainer { transaction.replace(R.id.main_fragment_container, mainFragment); transaction.commit(); - mToolbar = (Toolbar) findViewById(R.id.activity_main_toolbar); + mToolbar = (Toolbar) findViewById(R.id.toolbar); mToolbar.setTitle(R.string.app_name); setSupportActionBar(mToolbar); diff --git a/OpenKeychain/src/main/res/layout/main_activity.xml b/OpenKeychain/src/main/res/layout/main_activity.xml index 4a07053ea..45df0df71 100644 --- a/OpenKeychain/src/main/res/layout/main_activity.xml +++ b/OpenKeychain/src/main/res/layout/main_activity.xml @@ -1,19 +1,26 @@ + android:background="?attr/colorPrimary" + android:minHeight="?attr/actionBarSize" + app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" + app:popupTheme="@style/ThemeOverlay.AppCompat.Light" + tools:ignore="UnusedAttribute" /> + android:layout_width="match_parent" /> \ No newline at end of file diff --git a/OpenKeychain/src/main/res/values/themes.xml b/OpenKeychain/src/main/res/values/themes.xml index 96d09151d..6ac09c5d7 100644 --- a/OpenKeychain/src/main/res/values/themes.xml +++ b/OpenKeychain/src/main/res/values/themes.xml @@ -8,17 +8,12 @@ @color/primary_dark @color/accent + true - false true @style/MySearchViewStyle - - - @style/ThemeOverlay.AppCompat.Dark - - @style/ThemeOverlay.AppCompat.Light -- cgit v1.2.3