From 3e7ce0008fde176634980a31f61052052698ff93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Mon, 18 Aug 2014 11:02:41 +0200 Subject: Fixes for expiry UI --- .../keychain/ui/EditKeyFragment.java | 4 +- .../keychain/ui/adapter/SubkeysAdapter.java | 8 +- .../keychain/ui/adapter/SubkeysAddedAdapter.java | 8 +- .../ui/dialog/AddSubkeyDialogFragment.java | 5 +- .../ui/dialog/EditSubkeyExpiryDialogFragment.java | 145 ++++++++++++--------- .../main/res/layout/edit_subkey_expiry_dialog.xml | 10 ++ 6 files changed, 111 insertions(+), 69 deletions(-) diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java index 409953ad5..f2d6d4c13 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/EditKeyFragment.java @@ -406,10 +406,10 @@ public class EditKeyFragment extends LoaderFragment implements @Override public void handleMessage(Message message) { switch (message.what) { - case EditSubkeyExpiryDialogFragment.MESSAGE_NEW_EXPIRY_DATE: + case EditSubkeyExpiryDialogFragment.MESSAGE_NEW_EXPIRY: mSaveKeyringParcel.getOrCreateSubkeyChange(keyId).mExpiry = (Long) message.getData().getSerializable( - EditSubkeyExpiryDialogFragment.MESSAGE_DATA_EXPIRY_DATE); + EditSubkeyExpiryDialogFragment.MESSAGE_DATA_EXPIRY); break; } getLoaderManager().getLoader(LOADER_ID_SUBKEYS).forceLoad(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java index 6df84a056..9958b33a1 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAdapter.java @@ -35,7 +35,9 @@ import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.provider.KeychainContract.Keys; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import java.util.Calendar; import java.util.Date; +import java.util.TimeZone; public class SubkeysAdapter extends CursorAdapter { private LayoutInflater mInflater; @@ -198,9 +200,13 @@ public class SubkeysAdapter extends CursorAdapter { boolean isExpired; if (expiryDate != null) { isExpired = expiryDate.before(new Date()); + Calendar expiryCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + expiryCal.setTime(expiryDate); + // convert from UTC to time zone of device + expiryCal.setTimeZone(TimeZone.getDefault()); vKeyExpiry.setText(context.getString(R.string.label_expiry) + ": " - + DateFormat.getDateFormat(context).format(expiryDate)); + + DateFormat.getDateFormat(context).format(expiryCal.getTime())); } else { isExpired = false; diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java index 7e0027ddc..a1dfeb10c 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/SubkeysAddedAdapter.java @@ -33,8 +33,10 @@ import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.PgpKeyHelper; import org.sufficientlysecure.keychain.service.SaveKeyringParcel; +import java.util.Calendar; import java.util.Date; import java.util.List; +import java.util.TimeZone; public class SubkeysAddedAdapter extends ArrayAdapter { private LayoutInflater mInflater; @@ -108,9 +110,13 @@ public class SubkeysAddedAdapter extends ArrayAdapter= android.os.Build.VERSION_CODES.HONEYCOMB) { - mExpiryDatePicker.setMinDate(new Date().getTime() + DateUtils.DAY_IN_MILLIS); + // date picker works based on default time zone + Calendar minDateCal = Calendar.getInstance(TimeZone.getDefault()); + minDateCal.add(Calendar.DAY_OF_YEAR, 1); // at least one day after creation (today) + mExpiryDatePicker.setMinDate(minDateCal.getTime().getTime()); } ArrayList choices = new ArrayList(); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java index fde8a3477..f46e253c0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/dialog/EditSubkeyExpiryDialogFragment.java @@ -25,9 +25,10 @@ import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.support.v4.app.DialogFragment; -import android.text.format.DateUtils; import android.view.LayoutInflater; import android.view.View; +import android.widget.CheckBox; +import android.widget.CompoundButton; import android.widget.DatePicker; import org.sufficientlysecure.keychain.Constants; @@ -40,17 +41,15 @@ import java.util.TimeZone; public class EditSubkeyExpiryDialogFragment extends DialogFragment { private static final String ARG_MESSENGER = "messenger"; - private static final String ARG_CREATION_DATE = "creation_date"; - private static final String ARG_EXPIRY_DATE = "expiry_date"; + private static final String ARG_CREATION = "creation"; + private static final String ARG_EXPIRY = "expiry"; - public static final int MESSAGE_NEW_EXPIRY_DATE = 1; + public static final int MESSAGE_NEW_EXPIRY = 1; public static final int MESSAGE_CANCEL = 2; - public static final String MESSAGE_DATA_EXPIRY_DATE = "expiry_date"; + public static final String MESSAGE_DATA_EXPIRY = "expiry"; private Messenger mMessenger; - private DatePicker mDatePicker; - /** * Creates new instance of this dialog fragment */ @@ -59,8 +58,8 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { EditSubkeyExpiryDialogFragment frag = new EditSubkeyExpiryDialogFragment(); Bundle args = new Bundle(); args.putParcelable(ARG_MESSENGER, messenger); - args.putSerializable(ARG_CREATION_DATE, creationDate); - args.putSerializable(ARG_EXPIRY_DATE, expiryDate); + args.putSerializable(ARG_CREATION, creationDate); + args.putSerializable(ARG_EXPIRY, expiryDate); frag.setArguments(args); @@ -74,13 +73,13 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { public Dialog onCreateDialog(Bundle savedInstanceState) { final Activity activity = getActivity(); mMessenger = getArguments().getParcelable(ARG_MESSENGER); - long creationDate = getArguments().getLong(ARG_CREATION_DATE); - long expiryDate = getArguments().getLong(ARG_EXPIRY_DATE); + long creation = getArguments().getLong(ARG_CREATION); + long expiry = getArguments().getLong(ARG_EXPIRY); Calendar creationCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - creationCal.setTime(new Date(creationDate * 1000)); + creationCal.setTime(new Date(creation * 1000)); final Calendar expiryCal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - expiryCal.setTime(new Date(expiryDate * 1000)); + expiryCal.setTime(new Date(expiry * 1000)); // date picker works with default time zone, we need to convert from UTC to default timezone creationCal.setTimeZone(TimeZone.getDefault()); @@ -96,44 +95,64 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { View view = inflater.inflate(R.layout.edit_subkey_expiry_dialog, null); alert.setView(view); - mDatePicker = (DatePicker) view.findViewById(R.id.edit_subkey_expiry_date_picker); + final CheckBox noExpiry = (CheckBox) view.findViewById(R.id.edit_subkey_expiry_no_expiry); + final DatePicker datePicker = (DatePicker) view.findViewById(R.id.edit_subkey_expiry_date_picker); - // set default date - if (expiryDate == 0L) { - // if key has no expiry, set it to creation date +1 day + noExpiry.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) { + datePicker.setVisibility(View.GONE); + } else { + datePicker.setVisibility(View.VISIBLE); + } + } + }); - Calendar creationCalPlusOne = (Calendar) creationCal.clone(); - creationCalPlusOne.add(Calendar.DAY_OF_MONTH, 1); - mDatePicker.init( - creationCalPlusOne.get(Calendar.YEAR), - creationCalPlusOne.get(Calendar.MONTH), - creationCalPlusOne.get(Calendar.DAY_OF_MONTH), - null - ); + // init date picker with default selected date + if (expiry == 0L) { + noExpiry.setChecked(true); + datePicker.setVisibility(View.GONE); + + Calendar todayCal = Calendar.getInstance(TimeZone.getDefault()); + if (creationCal.after(todayCal)) { + // Note: This is just for the rare cases where creation is _after_ today + + // set it to creation date +1 day (don't set it to creationCal, it would break crash + // datePicker.setMinDate() execution with IllegalArgumentException + Calendar creationCalPlusOne = (Calendar) creationCal.clone(); + creationCalPlusOne.add(Calendar.DAY_OF_YEAR, 1); + datePicker.init( + creationCalPlusOne.get(Calendar.YEAR), + creationCalPlusOne.get(Calendar.MONTH), + creationCalPlusOne.get(Calendar.DAY_OF_MONTH), + null + ); + + } else { + // normally, just init with today + datePicker.init( + todayCal.get(Calendar.YEAR), + todayCal.get(Calendar.MONTH), + todayCal.get(Calendar.DAY_OF_MONTH), + null + ); + } } else { - // set date picker to current expiry date +1 day - - Calendar expiryCalPlusOne = (Calendar) expiryCal.clone(); - expiryCalPlusOne.add(Calendar.DAY_OF_MONTH, 1); - mDatePicker.init( - expiryCalPlusOne.get(Calendar.YEAR), - expiryCalPlusOne.get(Calendar.MONTH), - expiryCalPlusOne.get(Calendar.DAY_OF_MONTH), + noExpiry.setChecked(false); + datePicker.setVisibility(View.VISIBLE); + + // set date picker to current expiry + datePicker.init( + expiryCal.get(Calendar.YEAR), + expiryCal.get(Calendar.MONTH), + expiryCal.get(Calendar.DAY_OF_MONTH), null ); } if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { - // will crash with IllegalArgumentException if we set a min date - // that is before creation date - if (expiryDate == 0L || creationCal.before(expiryCal)) { - mDatePicker.setMinDate(creationCal.getTime().getTime() - + DateUtils.DAY_IN_MILLIS); - } else { - // set min to expiry date - mDatePicker.setMinDate(expiryCal.getTime().getTime() - + DateUtils.DAY_IN_MILLIS); - } + datePicker.setMinDate(creationCal.getTime().getTime()); } alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @@ -141,30 +160,28 @@ public class EditSubkeyExpiryDialogFragment extends DialogFragment { public void onClick(DialogInterface dialog, int id) { dismiss(); - Calendar selectedCal = Calendar.getInstance(TimeZone.getDefault()); - //noinspection ResourceType - selectedCal.set(mDatePicker.getYear(), mDatePicker.getMonth(), mDatePicker.getDayOfMonth()); - // date picker uses default time zone, we need to convert to UTC - selectedCal.setTimeZone(TimeZone.getTimeZone("UTC")); - - long numDays = (selectedCal.getTimeInMillis() / 86400000) - - (expiryCal.getTimeInMillis() / 86400000); - if (numDays > 0) { - Bundle data = new Bundle(); - data.putSerializable(MESSAGE_DATA_EXPIRY_DATE, selectedCal.getTime().getTime() / 1000); - sendMessageToHandler(MESSAGE_NEW_EXPIRY_DATE, data); + long expiry; + if (noExpiry.isChecked()) { + expiry = 0L; + } else { + Calendar selectedCal = Calendar.getInstance(TimeZone.getDefault()); + //noinspection ResourceType + selectedCal.set(datePicker.getYear(), datePicker.getMonth(), datePicker.getDayOfMonth()); + // date picker uses default time zone, we need to convert to UTC + selectedCal.setTimeZone(TimeZone.getTimeZone("UTC")); + + long numDays = (selectedCal.getTimeInMillis() / 86400000) + - (expiryCal.getTimeInMillis() / 86400000); + if (numDays <= 0) { + Log.e(Constants.TAG, "Should not happen! Expiry num of days <= 0!"); + throw new RuntimeException(); + } + expiry = selectedCal.getTime().getTime() / 1000; } - } - }); - - alert.setNeutralButton(R.string.btn_no_date, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - dismiss(); Bundle data = new Bundle(); - data.putSerializable(MESSAGE_DATA_EXPIRY_DATE, 0L); - sendMessageToHandler(MESSAGE_NEW_EXPIRY_DATE, data); + data.putSerializable(MESSAGE_DATA_EXPIRY, expiry); + sendMessageToHandler(MESSAGE_NEW_EXPIRY, data); } }); diff --git a/OpenKeychain/src/main/res/layout/edit_subkey_expiry_dialog.xml b/OpenKeychain/src/main/res/layout/edit_subkey_expiry_dialog.xml index 062f07863..8a713115e 100644 --- a/OpenKeychain/src/main/res/layout/edit_subkey_expiry_dialog.xml +++ b/OpenKeychain/src/main/res/layout/edit_subkey_expiry_dialog.xml @@ -4,6 +4,16 @@ android:layout_width="match_parent" android:layout_height="match_parent"> + +