/******************************************************************************* * Copyright (c) 2010 Denis Solonenko. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v2.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Contributors: * Denis Solonenko - initial API and implementation ******************************************************************************/ package ru.orangesoftware.financisto2.activity; import android.app.AlertDialog; import android.app.ProgressDialog; import android.app.TabActivity; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.Window; import android.widget.ListAdapter; import android.widget.TabHost; import android.widget.Toast; import ru.orangesoftware.financisto2.R; import ru.orangesoftware.financisto2.db.DatabaseAdapter; import ru.orangesoftware.financisto2.db.DatabaseAdapter_; import ru.orangesoftware.financisto2.export.csv.CsvExportOptions; import ru.orangesoftware.financisto2.export.csv.CsvExportTask; import ru.orangesoftware.financisto2.export.csv.CsvImportOptions; import ru.orangesoftware.financisto2.export.csv.CsvImportTask; import ru.orangesoftware.financisto2.export.qif.QifExportOptions; import ru.orangesoftware.financisto2.export.qif.QifExportTask; import ru.orangesoftware.financisto2.export.qif.QifImportOptions; import ru.orangesoftware.financisto2.export.qif.QifImportTask; import ru.orangesoftware.financisto2.utils.EntityEnum; import ru.orangesoftware.financisto2.utils.EnumUtils; import ru.orangesoftware.financisto2.utils.ExecutableEntityEnum; import ru.orangesoftware.financisto2.utils.IntegrityFix; import ru.orangesoftware.financisto2.utils.MyPreferences; import static ru.orangesoftware.financisto2.service.DailyAutoBackupScheduler.scheduleNextAutoBackup; import static ru.orangesoftware.financisto2.utils.EnumUtils.showPickOneDialog; public class MainActivity extends TabActivity implements TabHost.OnTabChangeListener { private static final int ACTIVITY_CSV_EXPORT = 2; private static final int ACTIVITY_QIF_EXPORT = 3; private static final int ACTIVITY_CSV_IMPORT = 4; private static final int ACTIVITY_QIF_IMPORT = 5; private static final int CHANGE_PREFERENCES = 6; private static final int MENU_PREFERENCES = Menu.FIRST + 1; private static final int MENU_ABOUT = Menu.FIRST + 2; private static final int MENU_BACKUP = Menu.FIRST + 3; private static final int MENU_RESTORE = Menu.FIRST + 4; private static final int MENU_SCHEDULED_TRANSACTIONS = Menu.FIRST + 5; private static final int MENU_ENTITIES = Menu.FIRST + 8; private static final int MENU_MASS_OP = Menu.FIRST + 9; private static final int MENU_DONATE = Menu.FIRST + 10; private static final int MENU_IMPORT_EXPORT = Menu.FIRST + 11; private static final int MENU_BACKUP_TO = Menu.FIRST + 12; private static final int MENU_INTEGRITY_FIX = Menu.FIRST + 13; private static final int MENU_PLANNER = Menu.FIRST + 14; private static final int MENU_BACKUP_RESTORE_ONLINE = Menu.FIRST + 15; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); final TabHost tabHost = getTabHost(); setupAccountsTab(tabHost); setupBlotterTab(tabHost); setupBudgetsTab(tabHost); setupReportsTab(tabHost); MyPreferences.StartupScreen screen = MyPreferences.getStartupScreen(this); tabHost.setCurrentTabByTag(screen.tag); tabHost.setOnTabChangedListener(this); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == ACTIVITY_CSV_EXPORT) { if (resultCode == RESULT_OK) { CsvExportOptions options = CsvExportOptions.fromIntent(data); doCsvExport(options); } } else if (requestCode == ACTIVITY_QIF_EXPORT) { if (resultCode == RESULT_OK) { QifExportOptions options = QifExportOptions.fromIntent(data); doQifExport(options); } } else if (requestCode == ACTIVITY_CSV_IMPORT) { if (resultCode == RESULT_OK) { CsvImportOptions options = CsvImportOptions.fromIntent(data); doCsvImport(options); } } else if (requestCode == ACTIVITY_QIF_IMPORT) { if (resultCode == RESULT_OK) { QifImportOptions options = QifImportOptions.fromIntent(data); doQifImport(options); } } else if (requestCode == CHANGE_PREFERENCES) { scheduleNextAutoBackup(this); } } @Override public void onTabChanged(String tabId) { Log.d("Financisto", "About to update tab " + tabId); long t0 = System.currentTimeMillis(); refreshCurrentTab(); long t1 = System.currentTimeMillis(); Log.d("Financisto", "Tab " + tabId + " updated in " + (t1 - t0) + "ms"); } private void refreshCurrentTab() { Context c = getTabHost().getCurrentView().getContext(); if (c instanceof RefreshSupportedActivity) { RefreshSupportedActivity activity = (RefreshSupportedActivity) c; activity.recreateCursor(); activity.integrityCheck(); } } private void setupAccountsTab(TabHost tabHost) { tabHost.addTab(tabHost.newTabSpec("accounts") .setIndicator(getString(R.string.accounts), getResources().getDrawable(R.drawable.ic_tab_accounts)) .setContent(new Intent(this, AccountListActivity.class))); } private void setupBlotterTab(TabHost tabHost) { Intent intent = new Intent(this, BlotterActivity.class); intent.putExtra(BlotterActivity.SAVE_FILTER, true); intent.putExtra(BlotterActivity.EXTRA_FILTER_ACCOUNTS, true); tabHost.addTab(tabHost.newTabSpec("blotter") .setIndicator(getString(R.string.blotter), getResources().getDrawable(R.drawable.ic_tab_blotter)) .setContent(intent)); } private void setupBudgetsTab(TabHost tabHost) { tabHost.addTab(tabHost.newTabSpec("budgets") .setIndicator(getString(R.string.budgets), getResources().getDrawable(R.drawable.ic_tab_budgets)) .setContent(new Intent(this, BudgetListActivity.class))); } private void setupReportsTab(TabHost tabHost) { tabHost.addTab(tabHost.newTabSpec("reports") .setIndicator(getString(R.string.reports), getResources().getDrawable(R.drawable.ic_tab_reports)) .setContent(new Intent(this, ReportsListActivity.class))); } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); MenuItem menuItem = menu.add(0, MENU_ENTITIES, 0, R.string.entities); menuItem.setIcon(R.drawable.menu_entities); menuItem = menu.add(0, MENU_SCHEDULED_TRANSACTIONS, 0, R.string.scheduled_transactions); menuItem.setIcon(R.drawable.ic_menu_today); menuItem = menu.add(0, MENU_MASS_OP, 0, R.string.mass_operations); menuItem.setIcon(R.drawable.ic_menu_agenda); menuItem = menu.add(0, MENU_BACKUP, 0, R.string.backup_database); menuItem.setIcon(R.drawable.ic_menu_upload); menuItem.setIcon(android.R.drawable.ic_menu_preferences); menu.addSubMenu(0, MENU_PLANNER, 0, R.string.planner); menu.addSubMenu(0, MENU_PREFERENCES, 0, R.string.preferences); menu.addSubMenu(0, MENU_RESTORE, 0, R.string.restore_database); menu.addSubMenu(0, MENU_BACKUP_RESTORE_ONLINE, 0, R.string.backup_restore_database_online); menu.addSubMenu(0, MENU_IMPORT_EXPORT, 0, R.string.import_export); menu.addSubMenu(0, MENU_BACKUP_TO, 0, R.string.backup_database_to); menu.addSubMenu(0, MENU_INTEGRITY_FIX, 0, R.string.integrity_fix); menu.addSubMenu(0, MENU_DONATE, 0, R.string.donate); menu.addSubMenu(0, MENU_ABOUT, 0, R.string.about); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { super.onOptionsItemSelected(item); switch (item.getItemId()) { case MENU_ENTITIES: final MenuEntities[] entities = MenuEntities.values(); ListAdapter adapter = EnumUtils.createEntityEnumAdapter(this, entities); final AlertDialog d = new AlertDialog.Builder(this) .setAdapter(adapter, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); MenuEntities e = entities[which]; startActivity(new Intent(MainActivity.this, e.getActivityClass())); } }) .create(); d.setTitle(R.string.entities); d.show(); break; case MENU_PREFERENCES: startActivityForResult(new Intent(this, PreferencesActivity.class), CHANGE_PREFERENCES); break; case MENU_SCHEDULED_TRANSACTIONS: startActivity(new Intent(this, ScheduledListActivity.class)); break; case MENU_MASS_OP: startActivity(new Intent(this, MassOpActivity.class)); break; case MENU_PLANNER: startActivity(new Intent(this, PlannerActivity.class)); break; case MENU_ABOUT: startActivity(new Intent(this, AboutActivity.class)); break; case MENU_DONATE: openBrowser("market://search?q=pname:ru.orangesoftware.financisto2.support"); break; case MENU_IMPORT_EXPORT: showPickOneDialog(this, R.string.import_export, ImportExportEntities.values(), this); break; case MENU_INTEGRITY_FIX: doIntegrityFix(); break; } return false; } private void doIntegrityFix() { new IntegrityFixTask().execute(); } private void openBrowser(String url) { try { Intent browserIntent = new Intent("android.intent.action.VIEW", Uri.parse(url)); startActivity(browserIntent); } catch (Exception ex) { //eventually market is not available Toast.makeText(this, R.string.donate_error, Toast.LENGTH_LONG).show(); } } /** * Treat asynchronous requests to popup error messages */ private Handler handler = new Handler() { /** * Schedule the popup of the given error message * @param msg The message to display **/ @Override public void handleMessage(Message msg) { showErrorPopup(MainActivity.this, msg.what); } }; public void showErrorPopup(Context context, int message) { new AlertDialog.Builder(context) .setMessage(message) .setTitle(R.string.error) .setPositiveButton(R.string.ok, null) .setCancelable(true) .create() .show(); } private void doCsvExport(CsvExportOptions options) { ProgressDialog progressDialog = ProgressDialog.show(this, null, getString(R.string.csv_export_inprogress), true); new CsvExportTask(this, progressDialog, options).execute(); } private void doCsvImport(CsvImportOptions options) { ProgressDialog progressDialog = ProgressDialog.show(this, null, getString(R.string.csv_import_inprogress), true); new CsvImportTask(this, handler, progressDialog, options).execute(); } private void doQifExport(QifExportOptions options) { ProgressDialog progressDialog = ProgressDialog.show(this, null, getString(R.string.qif_export_inprogress), true); new QifExportTask(this, progressDialog, options).execute(); } private void doQifImport(QifImportOptions options) { ProgressDialog progressDialog = ProgressDialog.show(this, null, getString(R.string.qif_import_inprogress), true); new QifImportTask(this, handler, progressDialog, options).execute(); } private void doCsvExport() { Intent intent = new Intent(this, CsvExportActivity.class); startActivityForResult(intent, ACTIVITY_CSV_EXPORT); } private void doCsvImport() { Intent intent = new Intent(this, CsvImportActivity.class); startActivityForResult(intent, ACTIVITY_CSV_IMPORT); } private void doQifExport() { Intent intent = new Intent(this, QifExportActivity.class); startActivityForResult(intent, ACTIVITY_QIF_EXPORT); } private void doQifImport() { Intent intent = new Intent(this, QifImportActivity.class); startActivityForResult(intent, ACTIVITY_QIF_IMPORT); } private enum MenuEntities implements EntityEnum { CURRENCIES(R.string.currencies, R.drawable.menu_entities_currencies, CurrencyListActivity.class), EXCHANGE_RATES(R.string.exchange_rates, R.drawable.menu_entities_exchange_rates, ExchangeRatesListActivity.class), CATEGORIES(R.string.categories, R.drawable.menu_entities_categories, CategoryListActivity2.class), PAYEES(R.string.payees, R.drawable.menu_entities_payees, PayeeListActivity.class), PROJECTS(R.string.projects, R.drawable.menu_entities_projects, ProjectListActivity.class); private final int titleId; private final int iconId; private final Class<?> actitivyClass; MenuEntities(int titleId, int iconId, Class<?> activityClass) { this.titleId = titleId; this.iconId = iconId; this.actitivyClass = activityClass; } @Override public int getTitleId() { return titleId; } @Override public int getIconId() { return iconId; } public Class<?> getActivityClass() { return actitivyClass; } } private enum ImportExportEntities implements ExecutableEntityEnum<MainActivity> { CSV_EXPORT(R.string.csv_export, R.drawable.ic_menu_back) { @Override public void execute(MainActivity mainActivity) { mainActivity.doCsvExport(); } }, CSV_IMPORT(R.string.csv_import, R.drawable.ic_menu_forward) { @Override public void execute(MainActivity mainActivity) { mainActivity.doCsvImport(); } }, QIF_EXPORT(R.string.qif_export, R.drawable.ic_menu_back) { @Override public void execute(MainActivity mainActivity) { mainActivity.doQifExport(); } }, QIF_IMPORT(R.string.qif_import, R.drawable.ic_menu_forward) { @Override public void execute(MainActivity mainActivity) { mainActivity.doQifImport(); } }; private final int titleId; private final int iconId; ImportExportEntities(int titleId, int iconId) { this.titleId = titleId; this.iconId = iconId; } @Override public int getTitleId() { return titleId; } @Override public int getIconId() { return iconId; } } private class IntegrityFixTask extends AsyncTask<Void, Void, Void> { ProgressDialog progressDialog; @Override protected void onPreExecute() { progressDialog = ProgressDialog.show(MainActivity.this, null, getString(R.string.integrity_fix_in_progress), true); progressDialog.show(); } @Override protected void onPostExecute(Void o) { refreshCurrentTab(); progressDialog.dismiss(); } @Override protected Void doInBackground(Void... objects) { DatabaseAdapter db = DatabaseAdapter_.getInstance_(MainActivity.this); new IntegrityFix(db).fix(); return null; } } }