From b1b5d57a8c0fb1d6ca56a7023dfcd718a625c851 Mon Sep 17 00:00:00 2001 From: Ngewi Fet Date: Wed, 8 Jul 2015 11:29:25 +0200 Subject: [PATCH 1/4] Fixed: crash after exporting transactions (in some cases) Updated betterpickers library Use better dialogs for date and time when creating new transactions --- app/build.gradle | 2 +- .../android/export/ExportAsyncTask.java | 5 +- .../transaction/TransactionFormFragment.java | 75 +++++++++---------- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 5a1439113..60c1a5e91 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -154,7 +154,7 @@ dependencies { compile('com.android.support:support-v4:22.1.1', 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar', 'com.viewpagerindicator:library:2.4.1@aar', - 'com.doomonafireball.betterpickers:library:1.5.2', + 'com.doomonafireball.betterpickers:library:1.6.0', 'com.commonsware.cwac:merge:1.1.+', 'com.github.PhilJay:MPAndroidChart:v2.1.0', 'joda-time:joda-time:2.7', diff --git a/app/src/main/java/org/gnucash/android/export/ExportAsyncTask.java b/app/src/main/java/org/gnucash/android/export/ExportAsyncTask.java index ba20e610a..601070ceb 100644 --- a/app/src/main/java/org/gnucash/android/export/ExportAsyncTask.java +++ b/app/src/main/java/org/gnucash/android/export/ExportAsyncTask.java @@ -55,6 +55,7 @@ import org.gnucash.android.export.xml.GncXmlExporter; import org.gnucash.android.model.Transaction; import org.gnucash.android.ui.account.AccountsActivity; +import org.gnucash.android.ui.account.AccountsListFragment; import org.gnucash.android.ui.settings.SettingsActivity; import org.gnucash.android.ui.transaction.TransactionsActivity; @@ -233,7 +234,9 @@ protected void onPostExecute(Boolean exportResult) { //now refresh the respective views if (mContext instanceof AccountsActivity){ - ((AccountsActivity) mContext).getCurrentAccountListFragment().refresh(); + AccountsListFragment fragment = ((AccountsActivity) mContext).getCurrentAccountListFragment(); + if (fragment != null) + fragment.refresh(); } if (mContext instanceof TransactionsActivity){ ((TransactionsActivity) mContext).refresh(); diff --git a/app/src/main/java/org/gnucash/android/ui/transaction/TransactionFormFragment.java b/app/src/main/java/org/gnucash/android/ui/transaction/TransactionFormFragment.java index a387ae654..0391c1ac4 100644 --- a/app/src/main/java/org/gnucash/android/ui/transaction/TransactionFormFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/transaction/TransactionFormFragment.java @@ -16,16 +16,11 @@ package org.gnucash.android.ui.transaction; -import android.app.DatePickerDialog; -import android.app.DatePickerDialog.OnDateSetListener; -import android.app.TimePickerDialog; -import android.app.TimePickerDialog.OnTimeSetListener; import android.content.Context; import android.content.SharedPreferences; import android.database.Cursor; import android.os.Bundle; import android.preference.PreferenceManager; -import android.support.v4.app.DialogFragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v4.widget.SimpleCursorAdapter; @@ -41,12 +36,10 @@ import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.CheckBox; -import android.widget.DatePicker; import android.widget.EditText; import android.widget.FilterQueryProvider; import android.widget.Spinner; import android.widget.TextView; -import android.widget.TimePicker; import android.widget.Toast; import com.actionbarsherlock.app.ActionBar; @@ -54,6 +47,8 @@ import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuInflater; import com.actionbarsherlock.view.MenuItem; +import com.doomonafireball.betterpickers.calendardatepicker.CalendarDatePickerDialog; +import com.doomonafireball.betterpickers.radialtimepicker.RadialTimePickerDialog; import com.doomonafireball.betterpickers.recurrencepicker.EventRecurrence; import com.doomonafireball.betterpickers.recurrencepicker.EventRecurrenceFormatter; import com.doomonafireball.betterpickers.recurrencepicker.RecurrencePickerDialog; @@ -70,9 +65,7 @@ import org.gnucash.android.model.Transaction; import org.gnucash.android.model.TransactionType; import org.gnucash.android.ui.UxArgument; -import org.gnucash.android.ui.transaction.dialog.DatePickerDialogFragment; import org.gnucash.android.ui.transaction.dialog.SplitEditorDialogFragment; -import org.gnucash.android.ui.transaction.dialog.TimePickerDialogFragment; import org.gnucash.android.ui.util.AmountInputFormatter; import org.gnucash.android.ui.util.RecurrenceParser; import org.gnucash.android.ui.util.TransactionTypeToggleButton; @@ -90,14 +83,14 @@ import java.util.GregorianCalendar; import java.util.List; import java.util.Locale; -import java.util.Objects; /** * Fragment for creating or editing transactions * @author Ngewi Fet */ public class TransactionFormFragment extends SherlockFragment implements - OnDateSetListener, OnTimeSetListener, RecurrencePickerDialog.OnRecurrenceSetListener { + CalendarDatePickerDialog.OnDateSetListener, RadialTimePickerDialog.OnTimeSetListener, + RecurrencePickerDialog.OnRecurrenceSetListener { public static final String FRAGMENT_TAG_SPLITS_EDITOR = "splits_editor"; private static final String FRAGMENT_TAG_RECURRENCE_PICKER = "recurrence_picker"; @@ -570,8 +563,6 @@ public void onClick(View view) { @Override public void onClick(View v) { - FragmentTransaction ft = getFragmentManager().beginTransaction(); - long dateMillis = 0; try { Date date = DATE_FORMATTER.parse(mDateTextView.getText().toString()); @@ -579,8 +570,15 @@ public void onClick(View v) { } catch (ParseException e) { Log.e(getTag(), "Error converting input time to Date object"); } - DialogFragment newFragment = DatePickerDialogFragment.newInstance(TransactionFormFragment.this, dateMillis); - newFragment.show(ft, "date_dialog"); + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(dateMillis); + + int year = calendar.get(Calendar.YEAR); + int monthOfYear = calendar.get(Calendar.MONTH); + int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); + CalendarDatePickerDialog datePickerDialog = CalendarDatePickerDialog.newInstance(TransactionFormFragment.this, + year, monthOfYear, dayOfMonth); + datePickerDialog.show(getFragmentManager(), "date_picker_fragment"); } }); @@ -596,8 +594,14 @@ public void onClick(View v) { } catch (ParseException e) { Log.e(getTag(), "Error converting input time to Date object"); } - DialogFragment fragment = TimePickerDialogFragment.newInstance(TransactionFormFragment.this, timeMillis); - fragment.show(ft, "time_dialog"); + + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(timeMillis); + + RadialTimePickerDialog timePickerDialog = RadialTimePickerDialog.newInstance( + TransactionFormFragment.this, calendar.get(Calendar.HOUR_OF_DAY), + calendar.get(Calendar.MINUTE), true); + timePickerDialog.show(getFragmentManager(), "time_picker_dialog_fragment"); } }); @@ -894,29 +898,22 @@ private void finish() { } } - /** - * Callback when the date is set in the {@link DatePickerDialog} - */ - @Override - public void onDateSet(DatePicker view, int year, int monthOfYear, - int dayOfMonth) { - Calendar cal = new GregorianCalendar(year, monthOfYear, dayOfMonth); - mDateTextView.setText(DATE_FORMATTER.format(cal.getTime())); - mDate.set(Calendar.YEAR, year); - mDate.set(Calendar.MONTH, monthOfYear); - mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); - } + @Override + public void onDateSet(CalendarDatePickerDialog calendarDatePickerDialog, int year, int monthOfYear, int dayOfMonth) { + Calendar cal = new GregorianCalendar(year, monthOfYear, dayOfMonth); + mDateTextView.setText(DATE_FORMATTER.format(cal.getTime())); + mDate.set(Calendar.YEAR, year); + mDate.set(Calendar.MONTH, monthOfYear); + mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); + } - /** - * Callback when the time is set in the {@link TimePickerDialog} - */ - @Override - public void onTimeSet(TimePicker view, int hourOfDay, int minute) { - Calendar cal = new GregorianCalendar(0, 0, 0, hourOfDay, minute); - mTimeTextView.setText(TIME_FORMATTER.format(cal.getTime())); - mTime.set(Calendar.HOUR_OF_DAY, hourOfDay); - mTime.set(Calendar.MINUTE, minute); - } + @Override + public void onTimeSet(RadialTimePickerDialog radialTimePickerDialog, int hourOfDay, int minute) { + Calendar cal = new GregorianCalendar(0, 0, 0, hourOfDay, minute); + mTimeTextView.setText(TIME_FORMATTER.format(cal.getTime())); + mTime.set(Calendar.HOUR_OF_DAY, hourOfDay); + mTime.set(Calendar.MINUTE, minute); + } /** * Strips formatting from a currency string. From baa094ce87a350bb14f9f38c56d45e332c2ba468 Mon Sep 17 00:00:00 2001 From: Ngewi Fet Date: Wed, 8 Jul 2015 13:22:34 +0200 Subject: [PATCH 2/4] Fixed: crash when creating a sub-account and changing the type to another different from the parent Also added test case Fixed: crash when dismissing error dialog after export Fixed: crash when resuming app with passcode set and app killed --- .../android/test/ui/AccountsActivityTest.java | 31 +++++++++++++++++++ .../test/ui/TransactionsActivityTest.java | 9 ------ .../gnucash/android/db/DatabaseAdapter.java | 1 + .../android/importer/ImportAsyncTask.java | 11 +++++-- .../ui/account/AccountFormFragment.java | 20 +++++++----- .../settings/PasscodePreferenceFragment.java | 5 +++ .../res/layout/fragment_account_detail.xml | 2 +- .../res/layout/fragment_accounts_list.xml | 2 +- app/src/main/res/menu/account_actions.xml | 2 +- app/src/main/res/menu/sub_account_actions.xml | 2 +- app/src/main/res/values-de/strings.xml | 2 +- app/src/main/res/values-el/strings.xml | 2 +- app/src/main/res/values-es-rMX/strings.xml | 2 +- app/src/main/res/values-es/strings.xml | 2 +- app/src/main/res/values-fr/strings.xml | 2 +- app/src/main/res/values-hu/strings.xml | 2 +- app/src/main/res/values-it/strings.xml | 2 +- app/src/main/res/values-nb/strings.xml | 2 +- app/src/main/res/values-nl/strings.xml | 2 +- app/src/main/res/values-pt-rBR/strings.xml | 2 +- app/src/main/res/values-ru/strings.xml | 2 +- app/src/main/res/values-uk/strings.xml | 2 +- app/src/main/res/values-zh/strings.xml | 2 +- app/src/main/res/values/strings.xml | 2 +- 24 files changed, 76 insertions(+), 37 deletions(-) diff --git a/app/src/androidTest/java/org/gnucash/android/test/ui/AccountsActivityTest.java b/app/src/androidTest/java/org/gnucash/android/test/ui/AccountsActivityTest.java index 03fa31c82..618310d49 100644 --- a/app/src/androidTest/java/org/gnucash/android/test/ui/AccountsActivityTest.java +++ b/app/src/androidTest/java/org/gnucash/android/test/ui/AccountsActivityTest.java @@ -35,6 +35,7 @@ import org.gnucash.android.db.SplitsDbAdapter; import org.gnucash.android.db.TransactionsDbAdapter; import org.gnucash.android.model.Account; +import org.gnucash.android.model.AccountType; import org.gnucash.android.model.Money; import org.gnucash.android.receivers.AccountCreator; import org.gnucash.android.ui.account.AccountsActivity; @@ -47,19 +48,24 @@ import java.util.Currency; import java.util.List; +import static android.support.test.espresso.Espresso.onData; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.clearText; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.longClick; import static android.support.test.espresso.action.ViewActions.scrollTo; +import static android.support.test.espresso.action.ViewActions.swipeRight; import static android.support.test.espresso.action.ViewActions.typeText; import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.matcher.ViewMatchers.isChecked; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.isNotChecked; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; @RunWith(AndroidJUnit4.class) @@ -213,6 +219,31 @@ public void testChangeParentAccount() { assertThat(DUMMY_ACCOUNT_UID).isEqualTo(parentUID); } + /** + * When creating a sub-account (starting from within another account), if we change the account + * type to another type with no accounts of that type, then the parent account list should be hidden. + * The account which is then created is not a sub-account, but rather a top-level account + */ + @Test + public void shouldHideParentAccountViewWhenNoParentsExist(){ + onView(withText(DUMMY_ACCOUNT_NAME)).perform(click()); + onView(withId(R.id.fragment_transaction_list)).perform(swipeRight()); + onView(withText(R.string.label_create_account)).check(matches(isDisplayed())).perform(click()); + sleep(1000); + onView(withId(R.id.checkbox_parent_account)).check(matches(allOf(isChecked()))); + onView(withId(R.id.input_account_name)).perform(typeText("Trading account")); + onView(withId(R.id.input_account_type_spinner)).perform(click()); + onData(allOf(is(instanceOf(String.class)), is(AccountType.TRADING.name()))).perform(click()); + + onView(withId(R.id.layout_parent_account)).check(matches(not(isDisplayed()))); + onView(withId(R.id.menu_save)).perform(click()); + + //no sub-accounts + assertThat(mAccountsDbAdapter.getSubAccountCount(DUMMY_ACCOUNT_UID)).isEqualTo(0); + assertThat(mAccountsDbAdapter.getSubAccountCount(mAccountsDbAdapter.getOrCreateGnuCashRootAccountUID())).isEqualTo(2); + assertThat(mAccountsDbAdapter.getSimpleAccountList()).extracting("mAccountType").contains(AccountType.TRADING); + } + @Test public void testEditAccount(){ String editedAccountName = "Edited Account"; diff --git a/app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java b/app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java index 12971ed2d..f13a95fc8 100644 --- a/app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java +++ b/app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java @@ -16,7 +16,6 @@ package org.gnucash.android.test.ui; -import android.app.Fragment; import android.content.ContentValues; import android.content.Intent; import android.content.SharedPreferences; @@ -28,8 +27,6 @@ import android.support.test.runner.AndroidJUnit4; import android.test.ActivityInstrumentationTestCase2; import android.util.Log; -import android.widget.LinearLayout; -import android.widget.Spinner; import org.gnucash.android.R; import org.gnucash.android.db.AccountsDbAdapter; @@ -58,7 +55,6 @@ import java.util.List; import java.util.Locale; -import static android.support.test.espresso.Espresso.onData; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.clearText; import static android.support.test.espresso.action.ViewActions.click; @@ -69,15 +65,10 @@ import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant; import static android.support.test.espresso.matcher.ViewMatchers.isChecked; import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; -import static android.support.test.espresso.matcher.ViewMatchers.isNotChecked; -import static android.support.test.espresso.matcher.ViewMatchers.withChild; import static android.support.test.espresso.matcher.ViewMatchers.withId; -import static android.support.test.espresso.matcher.ViewMatchers.withSpinnerText; import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static org.assertj.android.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.allOf; -import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; diff --git a/app/src/main/java/org/gnucash/android/db/DatabaseAdapter.java b/app/src/main/java/org/gnucash/android/db/DatabaseAdapter.java index 13b3b08b4..5fdd2558e 100644 --- a/app/src/main/java/org/gnucash/android/db/DatabaseAdapter.java +++ b/app/src/main/java/org/gnucash/android/db/DatabaseAdapter.java @@ -286,6 +286,7 @@ public long getID(@NonNull String uid){ * Returns the string unique ID (GUID) of a record in the database * @param id long database record ID * @return GUID of the record + * @throws IllegalArgumentException if the record ID does not exist in the database */ public String getUID(long id){ Cursor cursor = mDb.query(mTableName, diff --git a/app/src/main/java/org/gnucash/android/importer/ImportAsyncTask.java b/app/src/main/java/org/gnucash/android/importer/ImportAsyncTask.java index 0546a82ce..55c6f138b 100644 --- a/app/src/main/java/org/gnucash/android/importer/ImportAsyncTask.java +++ b/app/src/main/java/org/gnucash/android/importer/ImportAsyncTask.java @@ -94,8 +94,15 @@ protected void onPostExecute(Boolean importSuccess) { if (mDelegate != null) mDelegate.onTaskComplete(); - if (progressDialog != null && progressDialog.isShowing()) - progressDialog.dismiss(); + try { + if (progressDialog != null && progressDialog.isShowing()) + progressDialog.dismiss(); + } catch (IllegalArgumentException ex){ + //TODO: This is a hack to catch "View not attached to window" exceptions + //FIXME by moving the creation and display of the progress dialog to the Fragment + } finally { + progressDialog = null; + } int message = importSuccess ? R.string.toast_success_importing_accounts : R.string.toast_error_importing_accounts; Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); diff --git a/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java b/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java index 31494c5fe..257cec3b4 100644 --- a/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java @@ -239,7 +239,7 @@ public void onCreate(Bundle savedInstanceState) { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_new_account, container, false); - getSherlockActivity().getSupportActionBar().setTitle(R.string.title_add_account); + getSherlockActivity().getSupportActionBar().setTitle(R.string.label_create_account); mCurrencySpinner = (Spinner) view.findViewById(R.id.input_currency_spinner); mNameEditText = (EditText) view.findViewById(R.id.input_account_name); //mNameEditText.requestFocus(); @@ -443,14 +443,14 @@ private void setSelectedCurrency(String currencyCode){ * @param parentAccountId Record ID of parent account to be selected */ private void setParentAccountSelection(long parentAccountId){ - if (parentAccountId > 0 && parentAccountId != mRootAccountId){ - mParentCheckBox.setChecked(true); - mParentAccountSpinner.setEnabled(true); - } else + if (parentAccountId <= 0 || parentAccountId == mRootAccountId) { return; + } for (int pos = 0; pos < mParentAccountCursorAdapter.getCount(); pos++) { if (mParentAccountCursorAdapter.getItemId(pos) == parentAccountId){ + mParentCheckBox.setChecked(true); + mParentAccountSpinner.setEnabled(true); mParentAccountSpinner.setSelection(pos, true); break; } @@ -581,11 +581,15 @@ private void loadParentAccountList(AccountType accountType){ mParentAccountCursor.close(); mParentAccountCursor = mAccountsDbAdapter.fetchAccountsOrderedByFullName(condition, null); - if (mParentAccountCursor.getCount() <= 0){ - final View view = getView(); - assert view != null; + final View view = getView(); + assert view != null; + if (mParentAccountCursor.getCount() <= 0){ + mParentCheckBox.setChecked(false); //disable before hiding, else we can still read it when saving view.findViewById(R.id.layout_parent_account).setVisibility(View.GONE); view.findViewById(R.id.label_parent_account).setVisibility(View.GONE); + } else { + view.findViewById(R.id.layout_parent_account).setVisibility(View.VISIBLE); + view.findViewById(R.id.label_parent_account).setVisibility(View.VISIBLE); } mParentAccountCursorAdapter = new QualifiedAccountNameCursorAdapter( diff --git a/app/src/main/java/org/gnucash/android/ui/settings/PasscodePreferenceFragment.java b/app/src/main/java/org/gnucash/android/ui/settings/PasscodePreferenceFragment.java index 84a4ff77a..d1662d998 100644 --- a/app/src/main/java/org/gnucash/android/ui/settings/PasscodePreferenceFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/settings/PasscodePreferenceFragment.java @@ -32,6 +32,7 @@ import com.actionbarsherlock.app.SherlockPreferenceActivity; import org.gnucash.android.R; +import org.gnucash.android.app.GnuCashApplication; import org.gnucash.android.ui.UxArgument; import org.gnucash.android.ui.passcode.PasscodeLockScreenActivity; import org.gnucash.android.ui.passcode.PasscodePreferenceActivity; @@ -108,6 +109,10 @@ public boolean onPreferenceClick(Preference preference) { public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); + if (mEditor == null){ + mEditor = PreferenceManager.getDefaultSharedPreferences(GnuCashApplication.getAppContext()).edit(); + } + switch (requestCode) { case PASSCODE_REQUEST_CODE: if (resultCode == Activity.RESULT_OK && data != null) { diff --git a/app/src/main/res/layout/fragment_account_detail.xml b/app/src/main/res/layout/fragment_account_detail.xml index d0879569a..5a4be69ef 100644 --- a/app/src/main/res/layout/fragment_account_detail.xml +++ b/app/src/main/res/layout/fragment_account_detail.xml @@ -40,6 +40,6 @@ android:id="@+id/add_preference_button" android:layout_width="match_parent" android:layout_height="wrap_content" - android:text="@string/title_add_account" /> + android:text="@string/label_create_account" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_accounts_list.xml b/app/src/main/res/layout/fragment_accounts_list.xml index 05c73ab92..07c6e8cfd 100644 --- a/app/src/main/res/layout/fragment_accounts_list.xml +++ b/app/src/main/res/layout/fragment_accounts_list.xml @@ -50,6 +50,6 @@ android:id="@+id/add_account_button" style="@style/ButtonStyle" android:onClick="onNewAccountClick" - android:text="@string/title_add_account" /> + android:text="@string/label_create_account" /> \ No newline at end of file diff --git a/app/src/main/res/menu/account_actions.xml b/app/src/main/res/menu/account_actions.xml index e43e9b1c5..17f230d23 100644 --- a/app/src/main/res/menu/account_actions.xml +++ b/app/src/main/res/menu/account_actions.xml @@ -18,7 +18,7 @@ - Neues Konto + Neues Konto Konto bearbeiten Info OFX-Datei exportieren diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index e503637a1..699b4befb 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -17,7 +17,7 @@ --> - Δημιουργία Λογαριασμού + Δημιουργία Λογαριασμού Επεξεργασία Λογαριασμού Πληροφορίες Εξαγωγή OFX diff --git a/app/src/main/res/values-es-rMX/strings.xml b/app/src/main/res/values-es-rMX/strings.xml index 67aa4efad..ecea7b875 100644 --- a/app/src/main/res/values-es-rMX/strings.xml +++ b/app/src/main/res/values-es-rMX/strings.xml @@ -17,7 +17,7 @@ --> - Crear cuenta + Crear cuenta Editar cuenta Detalles Exportar a OFX diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 2ff2c2a05..6d670d7ef 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -17,7 +17,7 @@ --> - Crear Cuenta + Crear Cuenta Editar Cuenta Info Exportar OFX diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 1eed10dcb..5d85003ba 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -17,7 +17,7 @@ --> - Créer un compte + Créer un compte Éditer le compte Informations Exporter en OFX diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index eba5056a0..213d870be 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -16,7 +16,7 @@ --> - Create Account + Create Account Edit Account Info Export OFX diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 7cb3f3aa4..17546090e 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -17,7 +17,7 @@ --> - Crea conto + Crea conto Modifica conto Informazioni Esporta OFX diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index d59e5f5eb..bd6d49d53 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -18,7 +18,7 @@ --> - Opprett konto + Opprett konto Rediger konto Informasjon Eksport OFX diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index ac4f421a3..d0f7f089c 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -17,7 +17,7 @@ --> - Nieuw rekening + Nieuw rekening Rekening bewerken Info OFX exporteren diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 8714b7c22..503cbdb27 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -16,7 +16,7 @@ limitations under the License. --> - Criar Conta + Criar Conta Editar Conta Info Exportar OFX diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 4ef43f7fc..2d2bec44e 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -17,7 +17,7 @@ --> - Создать счёт + Создать счёт Редактировать счёт Информация Экспортировать OFX diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 6edd8226f..3c6704e86 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -1,5 +1,5 @@ - Створити рахунок + Створити рахунок Редагувати рахунок Інформація Експортувати OFX diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 5aac50b60..94a123c50 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -17,7 +17,7 @@ --> - 创建科目 + 创建科目 修改科目 信息 导出OFX diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a6391dc3e..adba1a29d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -16,7 +16,7 @@ --> - Create Account + Create Account Edit Account Info Export… From 01a230101d71712f7c77e88854c9773577cb8cc5 Mon Sep 17 00:00:00 2001 From: Ngewi Fet Date: Wed, 8 Jul 2015 13:41:20 +0200 Subject: [PATCH 3/4] Fixed: crash when devices report locale as es_LG which is unsupported Fixed: crash when files in backup folder have no timestamp --- .../android/test/ui/TransactionsActivityTest.java | 14 +++++++++++++- .../gnucash/android/app/GnuCashApplication.java | 7 ++++++- .../org/gnucash/android/db/AccountsDbAdapter.java | 2 +- .../java/org/gnucash/android/export/Exporter.java | 3 +++ .../main/java/org/gnucash/android/model/Money.java | 4 +++- .../android/ui/account/AccountsActivity.java | 2 +- .../android/ui/settings/SettingsActivity.java | 5 ++++- 7 files changed, 31 insertions(+), 6 deletions(-) diff --git a/app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java b/app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java index f13a95fc8..618be35c7 100644 --- a/app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java +++ b/app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java @@ -182,7 +182,7 @@ public void testAddTransactionShouldRequireAmount(){ .perform(typeText("Lunch")); onView(withId(R.id.menu_save)).perform(click()); - + sleep(500); assertToastDisplayed(R.string.toast_transanction_amount_required); int afterCount = mTransactionsDbAdapter.getTransactionsCount(DUMMY_ACCOUNT_UID); @@ -190,6 +190,18 @@ public void testAddTransactionShouldRequireAmount(){ } + /** + * Sleep the thread for a specified period + * @param millis Duration to sleep in milliseconds + */ + private void sleep(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + /** * Checks that a specific toast message is displayed * @param toastString diff --git a/app/src/main/java/org/gnucash/android/app/GnuCashApplication.java b/app/src/main/java/org/gnucash/android/app/GnuCashApplication.java index ecfe9b0d4..247296f55 100644 --- a/app/src/main/java/org/gnucash/android/app/GnuCashApplication.java +++ b/app/src/main/java/org/gnucash/android/app/GnuCashApplication.java @@ -158,13 +158,18 @@ public static boolean shouldSaveOpeningBalances(boolean defaultValue){ * * @return Default currency code string for the application */ - public static String getDefaultCurrency(){ + public static String getDefaultCurrencyCode(){ Locale locale = Locale.getDefault(); //sometimes the locale en_UK is returned which causes a crash with Currency if (locale.getCountry().equals("UK")) { locale = new Locale(locale.getLanguage(), "GB"); } + //for unsupported locale es_LG + if (locale.getCountry().equals("LG")){ + locale = new Locale(locale.getLanguage(), "ES"); + } + String currencyCode = "USD"; //start with USD as the default SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); try { //there are some strange locales out there diff --git a/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java b/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java index 493f9f0ea..8b2d7f87f 100644 --- a/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java +++ b/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java @@ -813,7 +813,7 @@ private Money computeBalance(String accountUID, long startTimestamp, long endTim * @return the absolute balance of account list */ public Money getAccountsBalance(List accountUIDList, long startTimestamp, long endTimestamp) { - String currencyCode = GnuCashApplication.getDefaultCurrency(); + String currencyCode = GnuCashApplication.getDefaultCurrencyCode(); Money balance = Money.createZeroInstance(currencyCode); SplitsDbAdapter splitsDbAdapter = SplitsDbAdapter.getInstance(); diff --git a/app/src/main/java/org/gnucash/android/export/Exporter.java b/app/src/main/java/org/gnucash/android/export/Exporter.java index 8e9c5aa2f..29ce1e791 100644 --- a/app/src/main/java/org/gnucash/android/export/Exporter.java +++ b/app/src/main/java/org/gnucash/android/export/Exporter.java @@ -118,6 +118,9 @@ public static String buildExportFilename(ExportFormat format) { public static long getExportTime(String filename){ String[] tokens = filename.split("_"); long timeMillis = 0; + if (tokens.length < 2){ + return timeMillis; + } try { Date date = EXPORT_FILENAME_DATE_FORMAT.parse(tokens[0] + "_" + tokens[1]); timeMillis = date.getTime(); diff --git a/app/src/main/java/org/gnucash/android/model/Money.java b/app/src/main/java/org/gnucash/android/model/Money.java index 9b9a4217b..340bf5415 100644 --- a/app/src/main/java/org/gnucash/android/model/Money.java +++ b/app/src/main/java/org/gnucash/android/model/Money.java @@ -21,6 +21,8 @@ import com.crashlytics.android.Crashlytics; +import org.gnucash.android.app.GnuCashApplication; + import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; @@ -90,7 +92,7 @@ public final class Money implements Comparable{ * A zero instance with the currency of the default locale. * This can be used anywhere where a starting amount is required without having to create a new object */ - private static final Money sDefaultZero = Money.createZeroInstance(Currency.getInstance(Locale.getDefault()).getCurrencyCode()); + private static final Money sDefaultZero = Money.createZeroInstance(GnuCashApplication.getDefaultCurrencyCode()); /** * Returns a Money instance initialized to the local currency and value 0 diff --git a/app/src/main/java/org/gnucash/android/ui/account/AccountsActivity.java b/app/src/main/java/org/gnucash/android/ui/account/AccountsActivity.java index 2f7784310..f0660c74c 100644 --- a/app/src/main/java/org/gnucash/android/ui/account/AccountsActivity.java +++ b/app/src/main/java/org/gnucash/android/ui/account/AccountsActivity.java @@ -309,7 +309,7 @@ public void setTab(int index){ private void init() { PreferenceManager.setDefaultValues(this, R.xml.fragment_transaction_preferences, false); - Money.DEFAULT_CURRENCY_CODE = GnuCashApplication.getDefaultCurrency(); + Money.DEFAULT_CURRENCY_CODE = GnuCashApplication.getDefaultCurrencyCode(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); boolean firstRun = prefs.getBoolean(getString(R.string.key_first_run), true); diff --git a/app/src/main/java/org/gnucash/android/ui/settings/SettingsActivity.java b/app/src/main/java/org/gnucash/android/ui/settings/SettingsActivity.java index a4ef751e5..3aca7b379 100644 --- a/app/src/main/java/org/gnucash/android/ui/settings/SettingsActivity.java +++ b/app/src/main/java/org/gnucash/android/ui/settings/SettingsActivity.java @@ -538,7 +538,10 @@ public void restoreBackup() { final DateFormat dateFormatter = SimpleDateFormat.getDateTimeInstance(); for (File backupFile : sortedBackupFiles) { long time = Exporter.getExportTime(backupFile.getName()); - arrayAdapter.add(dateFormatter.format(new Date(time))); + if (time > 0) + arrayAdapter.add(dateFormatter.format(new Date(time))); + else //if no timestamp was found in the filename, just use the name + arrayAdapter.add(backupFile.getName()); } AlertDialog.Builder restoreDialogBuilder = new AlertDialog.Builder(this); From 55a1f50ba40b5d52f5631dea67f15a38b56f13c3 Mon Sep 17 00:00:00 2001 From: Ngewi Fet Date: Wed, 8 Jul 2015 13:52:30 +0200 Subject: [PATCH 4/4] Updated version string for v1.6.1 release Added some date/time checks to transaction tests Development build output name now includes git revision, beta builds include only build number Updated CHANGELOG --- CHANGELOG.md | 11 +++++++++++ app/build.gradle | 8 ++++---- .../android/test/ui/TransactionsActivityTest.java | 3 ++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c465db99c..9b75cde53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ Change Log =============================================================================== +Version 1.6.1 *(2015-07-08)* +---------------------------- +* Fixed: Crash when importing some scheduled transations with custom period strings +* Fixed: Crash when closing export progress dialog if an export error occurred +* Fixed: Crash when creating a sub-account and changing the account type +* Fixed: Crash when loading backup files with no timestamp in their name +* Fixed: Crash when app is run on devices with locale es_LG +* Improved: Updated betterpickers library +* Improved: New dialogs for time and date when creating transactions +* Improved: Added translation to Ukrainian + Version 1.6.0 *(2015-06-20)* ---------------------------- * Feature: Scheduled backups (QIF, OFX and XML) diff --git a/app/build.gradle b/app/build.gradle index 60c1a5e91..e13248646 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,8 +5,8 @@ apply plugin: 'crashlytics' def versionMajor = 1 def versionMinor = 6 -def versionPatch = 0 -def versionBuild = 7 +def versionPatch = 1 +def versionBuild = 0 def buildTime() { def df = new SimpleDateFormat("yyyyMMdd") @@ -100,13 +100,13 @@ android { applicationId 'org.gnucash.android.devel' testApplicationId 'org.gnucash.android.devel.test' resValue "string", "app_name", "GnuCash-devel" - versionName "${versionMajor}.${versionMinor}.${versionPatch}-dev${versionBuild}_${buildTime()}" + versionName "${versionMajor}.${versionMinor}.${versionPatch}-dev${versionBuild}_r${gitSha()}" resValue "string", "app_version_name", "${versionName}" } beta { resValue "string", "app_name", "GnuCash - beta" - versionName "${versionMajor}.${versionMinor}.${versionPatch}-beta${versionBuild}_r${gitSha()}" + versionName "${versionMajor}.${versionMinor}.${versionPatch}-beta${versionBuild}" resValue "string", "app_version_name", "${versionName}" buildConfigField "boolean", "USE_CRASHLYTICS", "true" } diff --git a/app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java b/app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java index 618be35c7..3934e6423 100644 --- a/app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java +++ b/app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java @@ -222,7 +222,8 @@ private void validateEditTransactionFields(Transaction transaction){ formatter.setMinimumFractionDigits(2); formatter.setMaximumFractionDigits(2); onView(withId(R.id.input_transaction_amount)).check(matches(withText(formatter.format(balance.asDouble())))); - + onView(withId(R.id.input_date)).check(matches(withText(TransactionFormFragment.DATE_FORMATTER.format(transaction.getTimeMillis())))); + onView(withId(R.id.input_time)).check(matches(withText(TransactionFormFragment.TIME_FORMATTER.format(transaction.getTimeMillis())))); onView(withId(R.id.input_description)).check(matches(withText(transaction.getNote()))); validateTimeInput(transaction.getTimeMillis());