/*
* Copyright (C) 2012-2016 The Android Money Manager Ex Project Team
*
* 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 the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.money.manager.ex.settings;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.support.v7.preference.PreferenceScreen;
import android.text.Html;
import android.text.InputType;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog;
import com.money.manager.ex.BuildConfig;
import com.money.manager.ex.core.UIHelper;
import com.money.manager.ex.home.DatabaseMetadata;
import com.money.manager.ex.home.DatabaseMetadataFactory;
import com.money.manager.ex.MoneyManagerApplication;
import com.money.manager.ex.R;
import com.money.manager.ex.core.Core;
import com.money.manager.ex.database.DatabaseMigrator14To20;
import com.money.manager.ex.database.MmxOpenHelper;
import com.money.manager.ex.home.MainActivity;
import com.money.manager.ex.home.RecentDatabasesProvider;
import com.money.manager.ex.utils.DonateDialogUtils;
import com.money.manager.ex.utils.MmxDatabaseUtils;
import java.io.File;
import javax.inject.Inject;
import dagger.Lazy;
import timber.log.Timber;
/**
* Database preferences fragment.
*/
public class DatabaseSettingsFragment
extends PreferenceFragmentCompat {
@Inject Lazy<MmxOpenHelper> openHelper;
@Inject Lazy<RecentDatabasesProvider> mDatabases;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MoneyManagerApplication.getApp().iocComponent.inject(this);
addPreferencesFromResource(R.xml.preferences_database);
// Database path.
refreshDbPath();
initClearRecentFiles();
refreshDbVersion();
// Check schema
initDbSchemaCheckOption();
// Export database.
initExportDbOption();
//sqlite version
Preference pSQLiteVersion = findPreference(getString(PreferenceConstants.PREF_SQLITE_VERSION));
if (pSQLiteVersion != null) {
String sqliteVersion = openHelper.get().getSQLiteVersion();
if (sqliteVersion != null) pSQLiteVersion.setSummary(sqliteVersion);
}
// Check integrity
initDatabaseIntegrityOption();
// Migration of databases from version 1.4 to the location in 2.0.
setVisibilityOfMigrationButton();
// Create database
initCreateDatabaseOption();
// Fix duplicates
initFixDuplicates();
}
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
// Timber.d("creating");
}
// private
private void initClearRecentFiles() {
Preference preference = findPreference(getString(R.string.pref_clear_recent_files));
if (preference == null) return;
final RecentDatabasesProvider recents = mDatabases.get();
// show how many items are in the list.
preference.setSummary(Integer.toString(recents.map.size()));
preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
// clear recent files list
boolean success = recents.clear();
// update display value.
showNumberOfRecentFiles();
// notification
String message = success
? getString(R.string.cleared)
: getString(R.string.error);
new UIHelper(getActivity()).showToast(message);
return false;
}
});
}
private void refreshDbVersion() {
final Preference preference = findPreference(getActivity().getString(R.string.pref_database_version));
String version = "N/A";
SQLiteDatabase db = openHelper.get().getReadableDatabase();
if (db != null) {
int versionNumber = db.getVersion();
version = Integer.toString(versionNumber);
}
preference.setSummary(version);
}
private void setVisibilityOfMigrationButton() {
Preference migratePreference = findPreference(getString(R.string.pref_database_migrate_14_to_20));
if (migratePreference == null) return;
// check if there is a database at the old location.
final DatabaseMigrator14To20 migrator = new DatabaseMigrator14To20(getActivity());
boolean legacyDataExists = migrator.legacyDataExists();
// display description.
migratePreference.setSummary(getString(R.string.database_migrate_14_to_20_explanation));
// + " (" + migrator.getLegacyDbPath() + ")");
Preference.OnPreferenceClickListener migrateClicked = new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
boolean success = migrator.migrateLegacyDatabase();
if (success) {
Toast.makeText(getActivity(), R.string.database_migrate_14_to_20_success, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getActivity(), R.string.database_migrate_14_to_20_failure, Toast.LENGTH_LONG).show();
}
// The return value indicates whether to persist the preference,
// which is not used in this case.
return false;
}
};
// hide preference if there is no legacy data.
if (!legacyDataExists) {
PreferenceScreen screen = getPreferenceScreen();
screen.removePreference(migratePreference);
} else {
// enable listener for migration.
migratePreference.setOnPreferenceClickListener(migrateClicked);
}
}
private void initCreateDatabaseOption() {
Preference preference = findPreference(getString(R.string.pref_database_create));
if (preference == null) return;
preference.setSummary(getString(R.string.create_db_summary));
Preference.OnPreferenceClickListener clickListener = new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
promptForDatabaseFilename();
return false;
}
};
preference.setOnPreferenceClickListener(clickListener);
}
private void promptForDatabaseFilename() {
new MaterialDialog.Builder(getActivity())
.title(R.string.create_db)
.content(R.string.create_db_dialog_content)
.inputType(InputType.TYPE_CLASS_TEXT)
.input(getString(R.string.create_db_hint),
null, false, new MaterialDialog.InputCallback() {
@Override
public void onInput(MaterialDialog materialDialog, CharSequence charSequence) {
boolean success = createDatabase(charSequence.toString());
if (success) {
Toast.makeText(getActivity(), R.string.create_db_success,
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity(), R.string.create_db_error,
Toast.LENGTH_SHORT).show();
}
}
})
.positiveText(android.R.string.ok)
.negativeText(android.R.string.cancel)
.show();
}
private boolean createDatabase(String filename) {
// validation
if (TextUtils.isEmpty(filename)) return false;
MmxDatabaseUtils dbUtils = new MmxDatabaseUtils(getActivity());
// Create the db file. Store the path in the preferences.
String dbPath = dbUtils.createDatabase(filename);
if (TextUtils.isEmpty(dbPath)) return false;
DatabaseMetadata db = DatabaseMetadataFactory.getInstance(dbPath);
boolean isSet = dbUtils.useDatabase(db);
if (!isSet) return false;
// set main activity to reload, to open the new db file.
MainActivity.setRestartActivity(true);
// update the displayed value.
refreshDbPath();
showNumberOfRecentFiles();
return true;
}
private void refreshDbPath() {
final Preference preference = findPreference(getActivity().getString(R.string.pref_database_path));
preference.setSummary(MoneyManagerApplication.getDatabasePath(getActivity().getApplicationContext()));
}
private void initDbSchemaCheckOption() {
Preference preference = findPreference(getString(R.string.pref_db_check_schema));
if (preference == null) return;
preference.setSummary(getString(R.string.db_check_schema_summary));
Preference.OnPreferenceClickListener clickListener = new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
MmxDatabaseUtils db = new MmxDatabaseUtils(getActivity());
Timber.d("checking db schema");
boolean result = db.checkSchema();
if (result) {
showToast(R.string.db_check_schema_success, Toast.LENGTH_SHORT);
} else {
showToast(R.string.db_check_schema_error, Toast.LENGTH_SHORT);
}
return false;
}
};
preference.setOnPreferenceClickListener(clickListener);
}
private void initDatabaseIntegrityOption() {
Preference preference = findPreference(getString(R.string.pref_database_check_integrity));
if (preference == null) return;
preference.setSummary(getString(R.string.db_check_integrity_summary));
Preference.OnPreferenceClickListener clickListener = new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
MmxDatabaseUtils db = new MmxDatabaseUtils(getActivity());
boolean result;
try {
Timber.d("checking db integrity.");
result = db.checkIntegrity();
if (result) {
showToast(R.string.db_check_integrity_success, Toast.LENGTH_SHORT);
} else {
showToast(R.string.db_check_integrity_error, Toast.LENGTH_SHORT);
}
} catch (Exception ex) {
Timber.e(ex, "checking integrity");
}
return false;
}
};
preference.setOnPreferenceClickListener(clickListener);
}
private void initExportDbOption() {
final Preference pMoveDatabase = findPreference(getString(PreferenceConstants.PREF_DATABASE_BACKUP));
if (pMoveDatabase != null) {
pMoveDatabase.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
// copy files
Core core = new Core(getActivity().getApplicationContext());
File newDatabases = core.backupDatabase();
if (newDatabases != null) {
Toast.makeText(getActivity(), Html.fromHtml(getString(R.string.database_has_been_moved,
"<b>" + newDatabases.getAbsolutePath() + "</b>")), Toast.LENGTH_LONG).show();
//MainActivity.changeDatabase(newDatabases.getAbsolutePath());
// update the database file
// MoneyManagerApplication.setDatabasePath(getActivity().getApplicationContext(),
// newDatabases.getAbsolutePath());
new AppSettings(getActivity().getApplicationContext()).getDatabaseSettings()
.setDatabasePath(newDatabases.getAbsolutePath());
DonateDialogUtils.resetDonateDialog(getActivity().getApplicationContext());
// set to restart activity
MainActivity.setRestartActivity(true);
} else {
Toast.makeText(getActivity(), R.string.copy_database_on_external_storage_failed, Toast.LENGTH_LONG)
.show();
}
return false;
}
});
pMoveDatabase.setEnabled(MoneyManagerApplication.getDatabasePath(getActivity().getApplicationContext())
.startsWith("/data/"));
}
}
private void showToast(int resourceId, int duration) {
Toast.makeText(getActivity(), resourceId, duration).show();
}
private void initFixDuplicates() {
Preference preference = findPreference(getString(R.string.pref_db_fix_duplicates));
if (preference == null) return;
Preference.OnPreferenceClickListener clickListener = new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
MmxDatabaseUtils utils = new MmxDatabaseUtils(getActivity());
if (BuildConfig.DEBUG) {
Log.d(this.getClass().getSimpleName(), "fixing duplicates");
}
boolean result = utils.fixDuplicates();
if (result) {
showToast(R.string.success, Toast.LENGTH_SHORT);
} else {
showToast(R.string.error, Toast.LENGTH_SHORT);
}
return false;
}
};
preference.setOnPreferenceClickListener(clickListener);
}
private void showNumberOfRecentFiles() {
Preference preference = findPreference(getString(R.string.pref_clear_recent_files));
if (preference == null) return;
preference.setSummary(Integer.toString(mDatabases.get().count()));
}
}