diff --git a/app/src/main/java/org/gnucash/android/ui/settings/BookManagerFragment.java b/app/src/main/java/org/gnucash/android/ui/settings/BookManagerFragment.java index a1fb72d82..ae87a7034 100644 --- a/app/src/main/java/org/gnucash/android/ui/settings/BookManagerFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/settings/BookManagerFragment.java @@ -54,6 +54,7 @@ import org.gnucash.android.db.adapter.TransactionsDbAdapter; import org.gnucash.android.ui.account.AccountsActivity; import org.gnucash.android.ui.common.Refreshable; +import org.gnucash.android.ui.settings.dialog.DeleteBookConfirmationDialog; import org.gnucash.android.util.BookUtils; import org.gnucash.android.util.PreferencesHelper; @@ -199,30 +200,8 @@ public boolean onMenuItemClick(MenuItem item) { case R.id.ctx_menu_sync_book: //TODO implement sync return false; - case R.id.ctx_menu_delete_book: { - AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getActivity()); - dialogBuilder.setTitle(getString(R.string.title_confirm_delete_book)) - .setIcon(R.drawable.ic_close_black_24dp) - .setMessage(getString(R.string.msg_all_book_data_will_be_deleted)); - dialogBuilder.setPositiveButton(getString(R.string.btn_delete_book), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - BooksDbAdapter.getInstance().deleteBook(bookUID); - refresh(); - } - }); - dialogBuilder.setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - } - }); - AlertDialog dialog = dialogBuilder.create(); - dialog.show(); //must be called before you can access buttons - dialog.getButton(AlertDialog.BUTTON_POSITIVE) - .setTextColor(ContextCompat.getColor(context, R.color.account_red)); - } - return true; + case R.id.ctx_menu_delete_book: + return handleMenuDeleteBook(bookUID); default: return true; } @@ -238,6 +217,13 @@ public void onClick(DialogInterface dialog, int which) { }); } + private boolean handleMenuDeleteBook(final String bookUID) { + DeleteBookConfirmationDialog dialog = DeleteBookConfirmationDialog.newInstance(bookUID); + dialog.show(getFragmentManager(), "delete_book"); + dialog.setTargetFragment(BookManagerFragment.this, 0); + return true; + } + /** * Opens a dialog for renaming a book * @param bookName Current name of the book diff --git a/app/src/main/java/org/gnucash/android/ui/settings/dialog/DeleteAllAccountsConfirmationDialog.java b/app/src/main/java/org/gnucash/android/ui/settings/dialog/DeleteAllAccountsConfirmationDialog.java index 58c4cd93f..d45dfffcf 100644 --- a/app/src/main/java/org/gnucash/android/ui/settings/dialog/DeleteAllAccountsConfirmationDialog.java +++ b/app/src/main/java/org/gnucash/android/ui/settings/dialog/DeleteAllAccountsConfirmationDialog.java @@ -16,13 +16,10 @@ package org.gnucash.android.ui.settings.dialog; -import android.annotation.TargetApi; -import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; -import android.support.v4.app.DialogFragment; import android.widget.Toast; import org.gnucash.android.R; @@ -36,7 +33,7 @@ * * @author Ngewi Fet */ -public class DeleteAllAccountsConfirmationDialog extends DialogFragment { +public class DeleteAllAccountsConfirmationDialog extends DoubleConfirmationDialog { public static DeleteAllAccountsConfirmationDialog newInstance() { DeleteAllAccountsConfirmationDialog frag = new DeleteAllAccountsConfirmationDialog(); @@ -45,7 +42,7 @@ public static DeleteAllAccountsConfirmationDialog newInstance() { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { - return new AlertDialog.Builder(getActivity()) + return getDialogBuilder() .setIcon(android.R.drawable.ic_delete) .setTitle(R.string.title_confirm_delete).setMessage(R.string.confirm_delete_all_accounts) .setPositiveButton(R.string.alert_dialog_ok_delete, @@ -59,13 +56,6 @@ public void onClick(DialogInterface dialog, int whichButton) { } } ) - .setNegativeButton(R.string.alert_dialog_cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - dismiss(); - } - } - ) .create(); } } diff --git a/app/src/main/java/org/gnucash/android/ui/settings/dialog/DeleteAllTransactionsConfirmationDialog.java b/app/src/main/java/org/gnucash/android/ui/settings/dialog/DeleteAllTransactionsConfirmationDialog.java index 6b41f7a8b..0b37f0bd6 100644 --- a/app/src/main/java/org/gnucash/android/ui/settings/dialog/DeleteAllTransactionsConfirmationDialog.java +++ b/app/src/main/java/org/gnucash/android/ui/settings/dialog/DeleteAllTransactionsConfirmationDialog.java @@ -16,13 +16,11 @@ */ package org.gnucash.android.ui.settings.dialog; -import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.os.Bundle; import android.support.annotation.NonNull; -import android.support.v4.app.DialogFragment; import android.util.Log; import android.widget.Toast; @@ -44,7 +42,7 @@ * @author ngewif * @author Yongxin Wang */ -public class DeleteAllTransactionsConfirmationDialog extends DialogFragment { +public class DeleteAllTransactionsConfirmationDialog extends DoubleConfirmationDialog { public static DeleteAllTransactionsConfirmationDialog newInstance() { DeleteAllTransactionsConfirmationDialog frag = new DeleteAllTransactionsConfirmationDialog(); @@ -53,7 +51,7 @@ public static DeleteAllTransactionsConfirmationDialog newInstance() { @Override @NonNull public Dialog onCreateDialog(Bundle savedInstanceState) { - return new AlertDialog.Builder(getActivity()) + return getDialogBuilder() .setIcon(android.R.drawable.ic_delete) .setTitle(R.string.title_confirm_delete).setMessage(R.string.msg_delete_all_transactions_confirmation) .setPositiveButton(R.string.alert_dialog_ok_delete, @@ -80,19 +78,6 @@ public void onClick(DialogInterface dialog, int whichButton) { } } - ) - . - - setNegativeButton(R.string.alert_dialog_cancel, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) { - dismiss(); - } - } - - ) - . - - create(); + ).create(); } } diff --git a/app/src/main/java/org/gnucash/android/ui/settings/dialog/DeleteBookConfirmationDialog.java b/app/src/main/java/org/gnucash/android/ui/settings/dialog/DeleteBookConfirmationDialog.java new file mode 100644 index 000000000..fe5dfccf9 --- /dev/null +++ b/app/src/main/java/org/gnucash/android/ui/settings/dialog/DeleteBookConfirmationDialog.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2017 Àlex Magaz Graça + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gnucash.android.ui.settings.dialog; + +import android.app.Dialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.support.annotation.NonNull; + +import org.gnucash.android.R; +import org.gnucash.android.db.adapter.BooksDbAdapter; +import org.gnucash.android.ui.common.Refreshable; + +/** + * Confirmation dialog for deleting a book. + * + * @author Àlex Magaz + */ +public class DeleteBookConfirmationDialog extends DoubleConfirmationDialog { + @NonNull + public static DeleteBookConfirmationDialog newInstance(String bookUID) { + DeleteBookConfirmationDialog frag = new DeleteBookConfirmationDialog(); + Bundle args = new Bundle(); + args.putString("bookUID", bookUID); + frag.setArguments(args); + return frag; + } + + @NonNull + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + return getDialogBuilder() + .setTitle(R.string.title_confirm_delete_book) + .setIcon(R.drawable.ic_close_black_24dp) + .setMessage(R.string.msg_all_book_data_will_be_deleted) + .setPositiveButton(R.string.btn_delete_book, new DialogInterface.OnClickListener() { + @SuppressWarnings("ConstantConditions") + @Override + public void onClick(DialogInterface dialogInterface, int which) { + final String bookUID = getArguments().getString("bookUID"); + BooksDbAdapter.getInstance().deleteBook(bookUID); + ((Refreshable) getTargetFragment()).refresh(); + } + }) + .create(); + } +} diff --git a/app/src/main/java/org/gnucash/android/ui/settings/dialog/DoubleConfirmationDialog.java b/app/src/main/java/org/gnucash/android/ui/settings/dialog/DoubleConfirmationDialog.java new file mode 100644 index 000000000..6475f343a --- /dev/null +++ b/app/src/main/java/org/gnucash/android/ui/settings/dialog/DoubleConfirmationDialog.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2017 Àlex Magaz Graça + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gnucash.android.ui.settings.dialog; + +import android.content.DialogInterface; +import android.support.annotation.NonNull; +import android.support.v4.app.DialogFragment; +import android.support.v7.app.AlertDialog; +import android.widget.CheckBox; +import android.widget.CompoundButton; + +import org.gnucash.android.R; + +/** + * Confirmation dialog with additional checkbox to confirm the action. + * + *

It's meant to avoid the user confirming irreversible actions by + * mistake. The positive button to confirm the action is only enabled + * when the checkbox is checked.

+ * + *

Extend this class and override onCreateDialog to finish setting + * up the dialog. See getDialogBuilder().

+ * + * @author Àlex Magaz + */ +public abstract class DoubleConfirmationDialog extends DialogFragment { + /** + * Returns the dialog builder with the defaults for a double confirmation + * dialog already set up. + * + *

Call it from onCreateDialog to finish setting up the dialog. + * At least the following should be set:

+ * + *
    + *
  • The title.
  • + *
  • The positive button.
  • + *
+ * + * @return AlertDialog.Builder with the defaults for a double confirmation + * dialog already set up. + */ + @NonNull + protected AlertDialog.Builder getDialogBuilder() { + return new AlertDialog.Builder(getActivity()) + .setView(R.layout.dialog_double_confirm) + .setNegativeButton(R.string.btn_cancel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + onNegativeButton(); + } + }); + } + + @Override + public void onStart() { + super.onStart(); + if (getDialog() != null) { + ((AlertDialog) getDialog()).getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false); + setUpConfirmCheckBox(); + } + } + + @SuppressWarnings("ConstantConditions") + private void setUpConfirmCheckBox() { + final AlertDialog dialog = (AlertDialog) getDialog(); + CheckBox confirmCheckBox = dialog.findViewById(R.id.checkbox_confirm); + confirmCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(b); + } + }); + } + + /** + * Called when the negative button is pressed. + * + *

By default it just dismisses the dialog.

+ */ + protected void onNegativeButton() { + getDialog().dismiss(); + } +} diff --git a/app/src/main/res/layout/dialog_double_confirm.xml b/app/src/main/res/layout/dialog_double_confirm.xml new file mode 100644 index 000000000..fdb85836f --- /dev/null +++ b/app/src/main/res/layout/dialog_double_confirm.xml @@ -0,0 +1,29 @@ + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 624257895..bbd535f73 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -462,4 +462,5 @@ Select the destination after export is complete Export to \'/Apps/GnuCash Android/\' folder on Dropbox Preferences + Yes, I\'m sure diff --git a/app/src/test/java/org/gnucash/android/test/unit/model/TransactionTest.java b/app/src/test/java/org/gnucash/android/test/unit/model/TransactionTest.java index 383d5fb92..c5285833f 100644 --- a/app/src/test/java/org/gnucash/android/test/unit/model/TransactionTest.java +++ b/app/src/test/java/org/gnucash/android/test/unit/model/TransactionTest.java @@ -80,6 +80,7 @@ public void settingUID_shouldSetTransactionUidOfSplits(){ @Test public void testCreateAutoBalanceSplit() { Transaction transactionCredit = new Transaction("Transaction with more credit"); + transactionCredit.setCommodity(Commodity.getInstance("EUR")); Split creditSplit = new Split(new Money("1", "EUR"), "test-account"); creditSplit.setType(TransactionType.CREDIT); transactionCredit.addSplit(creditSplit); @@ -93,6 +94,7 @@ public void testCreateAutoBalanceSplit() { Transaction transactionDebit = new Transaction("Transaction with more debit"); + transactionDebit.setCommodity(Commodity.getInstance("EUR")); Split debitSplit = new Split(new Money("1", "EUR"), "test-account"); debitSplit.setType(TransactionType.DEBIT); transactionDebit.addSplit(debitSplit);