/*
* @copyright 2010 Evan Leybourn
* @license GNU General Public License
*
* This file is part of Book Catalogue.
*
* Book Catalogue 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.
*
* Book Catalogue 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 Book Catalogue. If not, see <http://www.gnu.org/licenses/>.
*/
package com.eleybourn.bookcatalogue;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;
import com.eleybourn.bookcatalogue.booklist.BooklistStyles;
import com.eleybourn.bookcatalogue.dialogs.StandardDialogs;
import com.eleybourn.bookcatalogue.dialogs.StandardDialogs.SimpleDialogFileItem;
import com.eleybourn.bookcatalogue.dialogs.StandardDialogs.SimpleDialogItem;
import com.eleybourn.bookcatalogue.dialogs.StandardDialogs.SimpleDialogOnClickListener;
import com.eleybourn.bookcatalogue.filechooser.BackupChooser;
import com.eleybourn.bookcatalogue.goodreads.GoodreadsRegister;
import com.eleybourn.bookcatalogue.goodreads.GoodreadsUtils;
import com.eleybourn.bookcatalogue.utils.HintManager;
import com.eleybourn.bookcatalogue.utils.Logger;
import com.eleybourn.bookcatalogue.utils.StorageUtils;
import com.eleybourn.bookcatalogue.utils.Utils;
/**
*
* This is the Administration page. It contains details about the app, links
* to my website and email, functions to export and import books and functions to
* manage bookshelves.
*
* @author Evan Leybourn
*/
public class AdministrationFunctions extends ActivityWithTasks {
private static final int ACTIVITY_BOOKSHELF=1;
private static final int ACTIVITY_FIELD_VISIBILITY=2;
private CatalogueDBAdapter mDbHelper;
private boolean finish_after = false;
private boolean mExportOnStartup = false;
public static final String DOAUTO = "do_auto";
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setTitle(R.string.administration_label);
mDbHelper = new CatalogueDBAdapter(this);
mDbHelper.open();
setContentView(R.layout.administration_functions);
Bundle extras = getIntent().getExtras();
if (extras != null && extras.containsKey(DOAUTO)) {
try {
if (extras.getString(DOAUTO).equals("export")) {
finish_after = true;
mExportOnStartup = true;
} else {
throw new RuntimeException("Unsupported DOAUTO option");
}
} catch (NullPointerException e) {
Logger.logError(e);
}
}
setupAdmin();
Utils.initBackground(R.drawable.bc_background_gradient_dim, this, false);
} catch (Exception e) {
Logger.logError(e);
}
}
/**
* This function builds the Administration page in 4 sections.
* 1. The button to goto the manage bookshelves activity
* 2. The button to export the database
* 3. The button to import the exported file into the database
* 4. The application version and link details
* 5. The link to paypal for donation
*/
public void setupAdmin() {
/* Bookshelf Link */
View bookshelf = findViewById(R.id.bookshelf_label);
// Make line flash when clicked.
bookshelf.setBackgroundResource(android.R.drawable.list_selector_background);
bookshelf.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
manageBookselves();
return;
}
});
/* Manage Fields Link */
View fields = findViewById(R.id.fields_label);
// Make line flash when clicked.
fields.setBackgroundResource(android.R.drawable.list_selector_background);
fields.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
manageFields();
return;
}
});
/* Export Link */
View export = findViewById(R.id.export_label);
// Make line flash when clicked.
export.setBackgroundResource(android.R.drawable.list_selector_background);
export.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
exportData();
return;
}
});
/* Import Link */
View imports = findViewById(R.id.import_label);
// Make line flash when clicked.
imports.setBackgroundResource(android.R.drawable.list_selector_background);
imports.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// Verify - this can be a dangerous operation
AlertDialog alertDialog = new AlertDialog.Builder(AdministrationFunctions.this).setMessage(R.string.import_alert).create();
alertDialog.setTitle(R.string.import_data);
alertDialog.setIcon(android.R.drawable.ic_menu_info_details);
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, AdministrationFunctions.this.getResources().getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
importData();
//Toast.makeText(pthis, importUpdated + " Existing, " + importCreated + " Created", Toast.LENGTH_LONG).show();
return;
}
});
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, AdministrationFunctions.this.getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//do nothing
return;
}
});
alertDialog.show();
return;
}
});
/* Goodreads SYNC Link */
{
View v = findViewById(R.id.sync_with_goodreads_label);
// Make line flash when clicked.
v.setBackgroundResource(android.R.drawable.list_selector_background);
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
GoodreadsUtils.importAllFromGoodreads(AdministrationFunctions.this, true);
return;
}
});
}
/* Goodreads IMPORT Link */
{
View v = findViewById(R.id.import_all_from_goodreads_label);
// Make line flash when clicked.
v.setBackgroundResource(android.R.drawable.list_selector_background);
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
GoodreadsUtils.importAllFromGoodreads(AdministrationFunctions.this, false);
return;
}
});
}
/* Goodreads EXPORT Link */
{
View v = findViewById(R.id.send_books_to_goodreads_label);
// Make line flash when clicked.
v.setBackgroundResource(android.R.drawable.list_selector_background);
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
GoodreadsUtils.sendBooksToGoodreads(AdministrationFunctions.this);
return;
}
});
}
/* LibraryThing auth Link */
View ltAuth = findViewById(R.id.librarything_auth);
// Make line flash when clicked.
ltAuth.setBackgroundResource(android.R.drawable.list_selector_background);
ltAuth.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(AdministrationFunctions.this, AdministrationLibraryThing.class);
startActivity(i);
return;
}
});
/* Goodreads auth Link */
View grAuth = findViewById(R.id.goodreads_auth);
// Make line flash when clicked.
grAuth.setBackgroundResource(android.R.drawable.list_selector_background);
grAuth.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(AdministrationFunctions.this, GoodreadsRegister.class);
startActivity(i);
return;
}
});
/* Other Prefs Link */
View otherPrefs = findViewById(R.id.other_prefs_label);
// Make line flash when clicked.
otherPrefs.setBackgroundResource(android.R.drawable.list_selector_background);
otherPrefs.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(AdministrationFunctions.this, OtherPreferences.class);
startActivity(i);
return;
}
});
/* Book List Preferences Link */
View blPrefs = findViewById(R.id.booklist_preferences_label);
// Make line flash when clicked.
blPrefs.setBackgroundResource(android.R.drawable.list_selector_background);
blPrefs.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
BookCatalogueApp.startPreferencesActivity(AdministrationFunctions.this);
return;
}
});
// Edit Book list styles
{
View v = findViewById(R.id.edit_styles_label);
// Make line flash when clicked.
v.setBackgroundResource(android.R.drawable.list_selector_background);
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
BooklistStyles.startEditActivity(AdministrationFunctions.this);
}
});
}
{
/* Update Fields Link */
View thumb = findViewById(R.id.thumb_label);
// Make line flash when clicked.
thumb.setBackgroundResource(android.R.drawable.list_selector_background);
thumb.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
updateThumbnails();
return;
}
});
}
{
// Debug ONLY!
/* Backup Link */
View backup = findViewById(R.id.backup_label);
// Make line flash when clicked.
backup.setBackgroundResource(android.R.drawable.list_selector_background);
backup.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mDbHelper.backupDbFile();
Toast.makeText(AdministrationFunctions.this, R.string.backup_success, Toast.LENGTH_LONG).show();
return;
}
});
}
{
/* Tasks setup Link */
View v = findViewById(R.id.background_tasks_label);
// Make line flash when clicked.
v.setBackgroundResource(android.R.drawable.list_selector_background);
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
showBackgroundTasks();
return;
}
});
}
{
/* Reset Hints Link */
View hints = findViewById(R.id.reset_hints_label);
// Make line flash when clicked.
hints.setBackgroundResource(android.R.drawable.list_selector_background);
hints.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
HintManager.resetHints();
Toast.makeText(AdministrationFunctions.this, R.string.hints_have_been_reset, Toast.LENGTH_LONG).show();
return;
}
});
}
// Erase cover cache
{
View v = findViewById(R.id.erase_cover_cache_label);
// Make line flash when clicked.
v.setBackgroundResource(android.R.drawable.list_selector_background);
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Utils utils = new Utils();
try {
utils.eraseCoverCache();
} finally {
utils.close();
}
return;
}
});
}
{
/* Backup Catalogue Link */
View v = findViewById(R.id.backup_catalogue_label);
// Make line flash when clicked.
v.setBackgroundResource(android.R.drawable.list_selector_background);
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
backupCatalogue(AdministrationFunctions.this);
return;
}
});
}
{
/* Restore Catalogue Link */
View v = findViewById(R.id.restore_catalogue_label);
// Make line flash when clicked.
v.setBackgroundResource(android.R.drawable.list_selector_background);
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
restoreCatalogue();
return;
}
});
}
}
///**
// * Show the activity that displays all Event objects created by the QueueManager.
// */
//private void showEvents() {
// Intent i = new Intent(this, GoodreadsExportFailuresActivity.class);
// startActivity(i);
//}
/**
* Load the Bookshelf Activity
*/
private void manageBookselves() {
Intent i = new Intent(this, Bookshelf.class);
startActivityForResult(i, ACTIVITY_BOOKSHELF);
}
/**
* Load the Manage Field Visibility Activity
*/
private void manageFields() {
Intent i = new Intent(this, FieldVisibility.class);
startActivityForResult(i, ACTIVITY_FIELD_VISIBILITY);
}
/**
* Export all data to a CSV file
*
* return void
*/
public void exportData() {
ExportThread thread = new ExportThread(getTaskManager());
thread.start();
}
/**
* Import all data from somewhere on shared storage; ask user to disambiguate if necessary
*
* return void
*/
private void importData() {
// Find all possible files (CSV in bookCatalogue directory)
ArrayList<File> files = StorageUtils.findExportFiles();
// If none, exit with message
if (files == null || files.size() == 0) {
Toast.makeText(this, R.string.no_export_files_found, Toast.LENGTH_LONG).show();
return;
} else {
if (files.size() == 1) {
// If only 1, just use it
importData(files.get(0).getAbsolutePath());
} else {
// If more than one, ask user which file
// ENHANCE: Consider asking about importing cover images.
StandardDialogs.selectFileDialog(getLayoutInflater(), getString(R.string.more_than_one_export_file_blah), files, new SimpleDialogOnClickListener() {
@Override
public void onClick(SimpleDialogItem item) {
SimpleDialogFileItem fileItem = (SimpleDialogFileItem) item;
importData(fileItem.getFile().getAbsolutePath());
}});
}
}
}
/**
* Import all data from the passed CSV file spec
*
* return void
* @throws IOException
*/
private void importData(String filespec) {
ImportThread thread;
try {
thread = new ImportThread(getTaskManager(), filespec);
} catch (IOException e) {
Logger.logError(e);
Toast.makeText(this, getString(R.string.problem_starting_import_arg, e.getMessage()), Toast.LENGTH_LONG).show();
return;
}
thread.start();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
switch(requestCode) {
case ACTIVITY_BOOKSHELF:
case ACTIVITY_FIELD_VISIBILITY:
//do nothing (yet)
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mDbHelper.close();
}
/**
* Fix background
*/
@Override
public void onResume() {
super.onResume();
Utils.initBackground(R.drawable.bc_background_gradient_dim, this, false);
if (mExportOnStartup)
exportData();
}
/**
* Called when any background task completes
*/
@Override
public void onTaskEnded(ManagedTask task) {
// If it's an export, then handle it
if (task instanceof ExportThread) {
onExportFinished((ExportThread)task);
}
}
public void onExportFinished(ExportThread task) {
if (task.isCancelled()) {
if (finish_after)
finish();
return;
}
AlertDialog alertDialog = new AlertDialog.Builder(AdministrationFunctions.this).create();
alertDialog.setTitle(R.string.email_export);
alertDialog.setIcon(android.R.drawable.ic_menu_send);
alertDialog.setButton2(getResources().getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// setup the mail message
final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
emailIntent.setType("plain/text");
//emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, context.getString(R.string.debug_email).split(";"));
String subject = "[" + getString(R.string.app_name) + "] " + getString(R.string.export_to_csv);
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
//emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, context.getString(R.string.debug_body));
//has to be an ArrayList
ArrayList<Uri> uris = new ArrayList<Uri>();
// Find all files of interest to send
try {
File fileIn = new File(StorageUtils.getSharedStoragePath() + "/" + "export.csv");
Uri u = Uri.fromFile(fileIn);
uris.add(u);
// Send it, if there are any files to send.
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
startActivity(Intent.createChooser(emailIntent, "Send mail..."));
} catch (NullPointerException e) {
Logger.logError(e);
Toast.makeText(AdministrationFunctions.this, R.string.export_failed_sdcard, Toast.LENGTH_LONG).show();
}
dialog.dismiss();
}
});
alertDialog.setButton(getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//do nothing
dialog.dismiss();
}
});
alertDialog.setOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
if (finish_after)
finish();
}});
if (!isFinishing()) {
try {
//
// Catch errors resulting from 'back' being pressed multiple times so that the activity is destroyed
// before the dialog can be shown.
// See http://code.google.com/p/android/issues/detail?id=3953
//
alertDialog.show();
} catch (Exception e) {
Logger.logError(e);
}
}
}
/**
* Update all (non-existent) thumbnails
*
* There is a current limitation that restricts the search to only books
* with an ISBN
*/
private void updateThumbnails() {
Intent i = new Intent(this, UpdateFromInternet.class);
startActivity(i);
}
/**
* Start the activity that shows the basic details of background tasks.
*/
private void showBackgroundTasks() {
Intent i = new Intent(this, TaskListActivity.class);
startActivity(i);
}
/**
* Start the archiving activity
*/
public static void backupCatalogue(Activity a) {
Intent i = new Intent(a, BackupChooser.class);
i.putExtra(BackupChooser.EXTRA_MODE, BackupChooser.EXTRA_MODE_SAVE_AS);
a.startActivity(i);
}
/**
* Start the restore activity
*/
private void restoreCatalogue() {
Intent i = new Intent(this, BackupChooser.class);
i.putExtra(BackupChooser.EXTRA_MODE, BackupChooser.EXTRA_MODE_OPEN);
startActivity(i);
}
}