diff --git a/app/src/main/java/org/gnucash/android/db/DatabaseHelper.java b/app/src/main/java/org/gnucash/android/db/DatabaseHelper.java index 5af6e0e97..440e5c7e5 100644 --- a/app/src/main/java/org/gnucash/android/db/DatabaseHelper.java +++ b/app/src/main/java/org/gnucash/android/db/DatabaseHelper.java @@ -212,8 +212,8 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){ /* * NOTE: In order to modify the database, create a new static method in the MigrationHelper class * called upgradeDbToVersion<#>, e.g. int upgradeDbToVersion10(SQLiteDatabase) in order to upgrade to version 10. - * The upgrade method should return the current database version as the return value. - * Then all you need to do is incremend the DatabaseSchema.DATABASE_VERSION to the appropriate number. + * The upgrade method should return the upgraded database version as the return value. + * Then all you need to do is increment the DatabaseSchema.DATABASE_VERSION to the appropriate number. */ if (oldVersion > newVersion) { throw new IllegalArgumentException("Database downgrades are not supported at the moment"); diff --git a/app/src/main/java/org/gnucash/android/db/DatabaseSchema.java b/app/src/main/java/org/gnucash/android/db/DatabaseSchema.java index 463c9e064..15d7870cc 100644 --- a/app/src/main/java/org/gnucash/android/db/DatabaseSchema.java +++ b/app/src/main/java/org/gnucash/android/db/DatabaseSchema.java @@ -28,7 +28,7 @@ public class DatabaseSchema { * Database version. * With any change to the database schema, this number must increase */ - public static final int DATABASE_VERSION = 10; + public static final int DATABASE_VERSION = 11; /** * Database version where Splits were introduced diff --git a/app/src/main/java/org/gnucash/android/db/MigrationHelper.java b/app/src/main/java/org/gnucash/android/db/MigrationHelper.java index 9040e2d22..f8d91f088 100644 --- a/app/src/main/java/org/gnucash/android/db/MigrationHelper.java +++ b/app/src/main/java/org/gnucash/android/db/MigrationHelper.java @@ -56,7 +56,9 @@ import java.nio.channels.FileChannel; import java.sql.Timestamp; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; @@ -1068,7 +1070,7 @@ static int upgradeDbToVersion9(SQLiteDatabase db){ *

This method converts all saved scheduled export parameters to the new format using the * timestamp of last export

* @param db SQLite database - * @return New version number + * @return 10 if upgrade was successful, 9 otherwise */ static int upgradeDbToVersion10(SQLiteDatabase db){ Log.i(DatabaseHelper.LOG_TAG, "Upgrading database to version 9"); @@ -1107,6 +1109,8 @@ static int upgradeDbToVersion10(SQLiteDatabase db){ db.insert(ScheduledActionEntry.TABLE_NAME, null, contentValues); } + cursor.close(); + db.setTransactionSuccessful(); oldVersion = 10; } finally { @@ -1114,4 +1118,56 @@ static int upgradeDbToVersion10(SQLiteDatabase db){ } return oldVersion; } + + /** + * Upgrade database to version 11 + *

+ * Migrate scheduled backups and update export parameters to the new format + *

+ * @param db SQLite database + * @return 11 if upgrade was successful, 10 otherwise + */ + static int upgradeDbToVersion11(SQLiteDatabase db){ + Log.i(DatabaseHelper.LOG_TAG, "Upgrading database to version 9"); + int oldVersion = 10; + + db.beginTransaction(); + try { + Cursor cursor = db.query(ScheduledActionEntry.TABLE_NAME, null, + ScheduledActionEntry.COLUMN_TYPE + "= ?", + new String[]{ScheduledAction.ActionType.BACKUP.name()}, null, null, null); + + Map uidToTagMap = new HashMap<>(); + while (cursor.moveToNext()) { + String uid = cursor.getString(cursor.getColumnIndexOrThrow(ScheduledActionEntry.COLUMN_UID)); + String tag = cursor.getString(cursor.getColumnIndexOrThrow(ScheduledActionEntry.COLUMN_TAG)); + String[] tokens = tag.split(";"); + try { + Timestamp timestamp = Timestamp.valueOf(tokens[2]); + } catch (IllegalArgumentException ex) { + tokens[2] = PreferenceManager.getDefaultSharedPreferences(GnuCashApplication.getAppContext()) + .getString(Exporter.PREF_LAST_EXPORT_TIME, Exporter.TIMESTAMP_ZERO); + } finally { + tag = TextUtils.join(";", tokens); + } + uidToTagMap.put(uid, tag); + } + + cursor.close(); + + ContentValues contentValues = new ContentValues(); + for (Map.Entry entry : uidToTagMap.entrySet()) { + contentValues.clear(); + contentValues.put(ScheduledActionEntry.COLUMN_TAG, entry.getValue()); + db.update(ScheduledActionEntry.TABLE_NAME, contentValues, + ScheduledActionEntry.COLUMN_UID + " = ?", new String[]{entry.getKey()}); + } + + db.setTransactionSuccessful(); + oldVersion = 11; + } finally { + db.endTransaction(); + } + return oldVersion; + } } diff --git a/app/src/main/java/org/gnucash/android/export/ExportParams.java b/app/src/main/java/org/gnucash/android/export/ExportParams.java index 04d860e0c..97232940e 100644 --- a/app/src/main/java/org/gnucash/android/export/ExportParams.java +++ b/app/src/main/java/org/gnucash/android/export/ExportParams.java @@ -16,6 +16,11 @@ package org.gnucash.android.export; +import android.preference.PreferenceManager; + +import org.gnucash.android.BuildConfig; +import org.gnucash.android.R; +import org.gnucash.android.app.GnuCashApplication; import org.gnucash.android.ui.export.ExportFormFragment; import java.sql.Timestamp; 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 a0232003a..8619362db 100644 --- a/app/src/main/java/org/gnucash/android/importer/ImportAsyncTask.java +++ b/app/src/main/java/org/gnucash/android/importer/ImportAsyncTask.java @@ -18,6 +18,7 @@ import android.annotation.TargetApi; import android.app.Activity; import android.app.ProgressDialog; +import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.util.Log; @@ -35,17 +36,17 @@ * Imports a GnuCash (desktop) account file and displays a progress dialog. * The AccountsActivity is opened when importing is done. */ -public class ImportAsyncTask extends AsyncTask { - private final Activity context; +public class ImportAsyncTask extends AsyncTask { + private final Activity mContext; private TaskDelegate mDelegate; - private ProgressDialog progressDialog; + private ProgressDialog mProgressDialog; public ImportAsyncTask(Activity context){ - this.context = context; + this.mContext = context; } public ImportAsyncTask(Activity context, TaskDelegate delegate){ - this.context = context; + this.mContext = context; this.mDelegate = delegate; } @@ -53,34 +54,36 @@ public ImportAsyncTask(Activity context, TaskDelegate delegate){ @Override protected void onPreExecute() { super.onPreExecute(); - progressDialog = new ProgressDialog(context); - progressDialog.setTitle(R.string.title_progress_importing_accounts); - progressDialog.setIndeterminate(true); - progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); - progressDialog.show(); + mProgressDialog = new ProgressDialog(mContext); + mProgressDialog.setTitle(R.string.title_progress_importing_accounts); + mProgressDialog.setIndeterminate(true); + mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); + mProgressDialog.show(); if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB){ //these methods must be called after progressDialog.show() - progressDialog.setProgressNumberFormat(null); - progressDialog.setProgressPercentFormat(null); + mProgressDialog.setProgressNumberFormat(null); + mProgressDialog.setProgressPercentFormat(null); } } @Override - protected Boolean doInBackground(InputStream... inputStreams) { + protected Boolean doInBackground(Uri... uris) { try { - GncXmlImporter.parse(inputStreams[0]); + InputStream accountInputStream = mContext.getContentResolver().openInputStream(uris[0]); + GncXmlImporter.parse(accountInputStream); } catch (Exception exception){ Log.e(ImportAsyncTask.class.getName(), "" + exception.getMessage()); Crashlytics.logException(exception); exception.printStackTrace(); final String err_msg = exception.getLocalizedMessage(); - context.runOnUiThread(new Runnable() { + Crashlytics.log(err_msg); + mContext.runOnUiThread(new Runnable() { @Override public void run() { - Toast.makeText(context, - context.getString(R.string.toast_error_importing_accounts) + "\n" + err_msg, + Toast.makeText(mContext, + mContext.getString(R.string.toast_error_importing_accounts) + "\n" + err_msg, Toast.LENGTH_LONG).show(); } }); @@ -96,18 +99,18 @@ protected void onPostExecute(Boolean importSuccess) { mDelegate.onTaskComplete(); try { - if (progressDialog != null && progressDialog.isShowing()) - progressDialog.dismiss(); + if (mProgressDialog != null && mProgressDialog.isShowing()) + mProgressDialog.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; + mProgressDialog = null; } int message = importSuccess ? R.string.toast_success_importing_accounts : R.string.toast_error_importing_accounts; - Toast.makeText(context, message, Toast.LENGTH_SHORT).show(); + Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show(); - AccountsActivity.start(context); + AccountsActivity.start(mContext); } } 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 9bca152c6..494d817ba 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 @@ -295,18 +295,9 @@ private void handleOpenFileIntent(Intent intent) { Uri data = intent.getData(); if (data != null){ GncXmlExporter.createBackup(); - intent.setData(null); - InputStream accountInputStream = null; - try { - accountInputStream = getContentResolver().openInputStream(data); - new ImportAsyncTask(this).execute(accountInputStream); - } catch (FileNotFoundException e) { - Crashlytics.logException(e); - Log.e(LOG_TAG, "Error opening file for import - " + e.getMessage()); - } finally { - removeFirstRunFlag(); - } + new ImportAsyncTask(this).execute(data); + removeFirstRunFlag(); } } @@ -496,8 +487,8 @@ public void onTaskComplete() { }; } - InputStream accountFileInputStream = activity.getResources().openRawResource(R.raw.default_accounts); - new ImportAsyncTask(activity, delegate).execute(accountFileInputStream); + Uri uri = Uri.parse("android.resource://" + BuildConfig.APPLICATION_ID + "/" + R.raw.default_accounts); + new ImportAsyncTask(activity, delegate).execute(uri); } /** @@ -536,14 +527,8 @@ public static void startXmlFileChooser(Activity activity) { * @param data Intent data containing the XML uri */ public static void importXmlFileFromIntent(Activity context, Intent data) { - try { - GncXmlExporter.createBackup(); - InputStream accountInputStream = context.getContentResolver().openInputStream(data.getData()); - new ImportAsyncTask(context).execute(accountInputStream); - } catch (FileNotFoundException e) { - Crashlytics.logException(e); - Toast.makeText(context, R.string.toast_error_importing_accounts, Toast.LENGTH_SHORT).show(); - } + GncXmlExporter.createBackup(); + new ImportAsyncTask(context).execute(data.getData()); } /** 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 21dc8fcc3..250a799c0 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 @@ -27,6 +27,7 @@ import android.content.IntentSender; import android.content.SharedPreferences; import android.database.Cursor; +import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.preference.CheckBoxPreference; @@ -565,15 +566,7 @@ public void onClick(DialogInterface dialog, int which) { @Override public void onClick(DialogInterface dialog, int which) { File backupFile = sortedBackupFiles[which]; - - try { - FileInputStream inputStream = new FileInputStream(backupFile); - new ImportAsyncTask(SettingsActivity.this).execute(inputStream); - } catch (FileNotFoundException e) { - Crashlytics.logException(e); - Log.e(LOG_TAG, "Error restoring backup: " + backupFile.getName()); - Toast.makeText(SettingsActivity.this, R.string.toast_error_importing_accounts, Toast.LENGTH_LONG).show(); - } + new ImportAsyncTask(SettingsActivity.this).execute(Uri.fromFile(backupFile)); } }); diff --git a/app/src/main/res/layout/activity_transaction_detail.xml b/app/src/main/res/layout/activity_transaction_detail.xml index 695f3bb56..f04f239a8 100644 --- a/app/src/main/res/layout/activity_transaction_detail.xml +++ b/app/src/main/res/layout/activity_transaction_detail.xml @@ -133,27 +133,25 @@ style="@style/TransactionInfo" /> - - + android:src="@drawable/ic_action_sort_by_size"/> - - - + + android:src="@drawable/ic_action_rotate_right"/> - - \ No newline at end of file