/*
* @copyright 2013 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.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.eleybourn.bookcatalogue.CatalogueDBAdapter.AnthologyTitleExistsException;
import com.eleybourn.bookcatalogue.utils.Logger;
import com.eleybourn.bookcatalogue.utils.Utils;
import com.eleybourn.bookcatalogue.widgets.SimpleListAdapter;
public class BookEditAnthology extends BookEditFragmentAbstract {
private EditText mTitleText;
private AutoCompleteTextView mAuthorText;
private String bookAuthor;
private String bookTitle;
private Button mAdd;
private CheckBox mSame;
private Integer mEditPosition = null;
int anthology_num = CatalogueDBAdapter.ANTHOLOGY_NO;
private ArrayList<AnthologyTitle> mList;
private static final int DELETE_ID = Menu.FIRST;
private static final int POPULATE = Menu.FIRST + 1;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.list_anthology, container, false);
}
/**
* Display the edit fields page
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
loadPage();
}
/**
* Display the main manage anthology page. This has three parts.
* 1. Setup the "Same Author" checkbox
* 2. Setup the "Add Title" fields
* 3. Populate the "Title List" - @see fillAnthology();
*/
public void loadPage() {
BookData book = mEditManager.getBookData();
bookAuthor = book.getString(CatalogueDBAdapter.KEY_AUTHOR_FORMATTED);
bookTitle = book.getString(CatalogueDBAdapter.KEY_TITLE);
// Setup the same author field
anthology_num = book.getInt(CatalogueDBAdapter.KEY_ANTHOLOGY_MASK);
mSame = (CheckBox) getView().findViewById(R.id.same_author);
if ((anthology_num & CatalogueDBAdapter.ANTHOLOGY_MULTIPLE_AUTHORS) != 0) {
mSame.setChecked(false);
} else {
mSame.setChecked(true);
}
mSame.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
saveState(mEditManager.getBookData());
loadPage();
}
});
ArrayAdapter<String> author_adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_dropdown_item_1line, mDbHelper.getAllAuthors());
mAuthorText = (AutoCompleteTextView) getView().findViewById(R.id.add_author);
mAuthorText.setAdapter(author_adapter);
if (mSame.isChecked()) {
mAuthorText.setVisibility(View.GONE);
} else {
mAuthorText.setVisibility(View.VISIBLE);
}
mTitleText = (EditText) getView().findViewById(R.id.add_title);
mAdd = (Button) getView().findViewById(R.id.row_add);
mAdd.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
try {
String title = mTitleText.getText().toString();
String author = mAuthorText.getText().toString();
if (mSame.isChecked()) {
author = bookAuthor;
}
AnthologyTitleListAdapter adapter = ((AnthologyTitleListAdapter)BookEditAnthology.this.getListView().getAdapter());
if (mEditPosition == null) {
AnthologyTitle anthology = new AnthologyTitle(new Author(author), title);
adapter.add(anthology);
} else {
AnthologyTitle anthology = adapter.getItem(mEditPosition);
anthology.setAuthor(new Author(author));
anthology.setTitle(title);
mEditPosition = null;
mAdd.setText(R.string.anthology_add);
}
mTitleText.setText("");
mAuthorText.setText("");
//fillAnthology(currentPosition);
mEditManager.setDirty(true);
} catch(AnthologyTitleExistsException e) {
Toast.makeText(getActivity(), R.string.the_title_already_exists, Toast.LENGTH_LONG).show();
}
}
});
fillAnthology();
// Setup the background
Utils.initBackground(R.drawable.bc_background_gradient_dim, this, false);
}
public void fillAnthology(int scroll_to_id) {
fillAnthology();
gotoTitle(scroll_to_id);
}
/**
* Populate the bookEditAnthology view
*/
public void fillAnthology() {
// Get all of the rows from the database and create the item list
mList = mEditManager.getBookData().getAnthologyTitles(); // mDbHelper.getBookAnthologyTitleList(mEditManager.getBookData().getRowId());
// Now create a simple cursor adapter and set it to display
AnthologyTitleListAdapter books = new AnthologyTitleListAdapter(getActivity(), R.layout.row_anthology, mList);
final ListView list = getListView();
list.setAdapter(books);
registerForContextMenu(list);
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mEditPosition = position;
AnthologyTitle anthology = mList.get(position);
mTitleText.setText(anthology.getTitle());
mAuthorText.setText(anthology.getAuthor().getDisplayName());
mAdd.setText(R.string.anthology_save);
}});
}
private ListView getListView() {
return (ListView) getView().findViewById(android.R.id.list);
}
public class AnthologyTitleListAdapter extends SimpleListAdapter<AnthologyTitle> {
boolean series = false;
/**
*
* Pass the parameters directly to the overridden function
*
* @param context
* @param layout
* @param cursor
* @param from
* @param to
*/
public AnthologyTitleListAdapter(Context context, int rowViewId, ArrayList<AnthologyTitle> items) {
super(context, rowViewId, items);
}
@Override
protected void onSetupView(AnthologyTitle anthology, int position, View target) {
TextView author = (TextView)target.findViewById(R.id.row_author);
author.setText(anthology.getAuthor().getDisplayName());
TextView title = (TextView)target.findViewById(R.id.row_title);
title.setText(anthology.getTitle());
}
@Override
protected void onRowClick(AnthologyTitle anthology, int position, View v) {
mEditPosition = position;
mTitleText.setText(anthology.getTitle());
mAuthorText.setText(anthology.getAuthor().getDisplayName());
mAdd.setText(R.string.anthology_save);
};
@Override
protected void onListChanged() {
mEditManager.setDirty(true);
};
}
/**
* Scroll to the current group
*/
public void gotoTitle(int id) {
try {
ListView view = this.getListView();
view.setSelection(id);
} catch (Exception e) {
Logger.logError(e);
}
return;
}
public void searchWikipedia() {
String basepath = "http://en.wikipedia.org";
String pathAuthor = bookAuthor.replace(" ", "+");
pathAuthor = pathAuthor.replace(",", "");
// Strip everything past the , from the title
String pathTitle = bookTitle;
int comma = bookTitle.indexOf(",");
if (comma > 0) {
pathTitle = pathTitle.substring(0, comma);
}
pathTitle = pathTitle.replace(" ", "+");
String path = basepath + "/w/index.php?title=Special:Search&search=%22" + pathTitle + "%22+" + pathAuthor + "";
boolean success = false;
URL url;
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser;
SearchWikipediaHandler handler = new SearchWikipediaHandler();
SearchWikipediaEntryHandler entryHandler = new SearchWikipediaEntryHandler();
try {
url = new URL(path);
parser = factory.newSAXParser();
try {
parser.parse(Utils.getInputStream(url), handler);
} catch (RuntimeException e) {
Toast.makeText(getActivity(), R.string.automatic_population_failed, Toast.LENGTH_LONG).show();
Logger.logError(e);
return;
}
String[] links = handler.getLinks();
for (int i = 0; i < links.length; i++) {
if (links[i].equals("") || success == true) {
break;
}
url = new URL(basepath + links[i]);
parser = factory.newSAXParser();
try {
parser.parse(Utils.getInputStream(url), entryHandler);
ArrayList<String> titles = entryHandler.getList();
/* Display the confirm dialog */
if (titles.size() > 0) {
success = true;
showAnthologyConfirm(titles);
}
} catch (RuntimeException e) {
Logger.logError(e);
Toast.makeText(getActivity(), R.string.automatic_population_failed, Toast.LENGTH_LONG).show();
}
}
if (success == false) {
Toast.makeText(getActivity(), R.string.automatic_population_failed, Toast.LENGTH_LONG).show();
return;
}
} catch (MalformedURLException e) {
Toast.makeText(getActivity(), R.string.automatic_population_failed, Toast.LENGTH_LONG).show();
Logger.logError(e);
} catch (ParserConfigurationException e) {
Toast.makeText(getActivity(), R.string.automatic_population_failed, Toast.LENGTH_LONG).show();
Logger.logError(e);
} catch (SAXException e) {
Toast.makeText(getActivity(), R.string.automatic_population_failed, Toast.LENGTH_LONG).show();
Logger.logError(e);
} catch (Exception e) {
Toast.makeText(getActivity(), R.string.automatic_population_failed, Toast.LENGTH_LONG).show();
Logger.logError(e);
}
fillAnthology();
return;
}
private void showAnthologyConfirm(final ArrayList<String> titles) {
String anthology_title = "";
for (int j=0; j < titles.size(); j++) {
anthology_title += "* " + titles.get(j) + "\n";
}
AlertDialog alertDialog = new AlertDialog.Builder(getActivity()).setMessage(anthology_title).create();
alertDialog.setTitle(R.string.anthology_confirm);
alertDialog.setIcon(android.R.drawable.ic_menu_info_details);
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, this.getResources().getString(R.string.ok), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
for (int j=0; j < titles.size(); j++) {
String anthology_title = titles.get(j);
anthology_title = anthology_title + ", ";
String anthology_author = bookAuthor;
// Does the string look like "Hindsight by Jack Williamson"
int pos = anthology_title.indexOf(" by ");
if (pos > 0) {
anthology_author = anthology_title.substring(pos+4);
anthology_title = anthology_title.substring(0, pos);
}
// Trim extraneous punctionaction and whitespace from the titles and authors
anthology_author = anthology_author.trim().replace("\n", " ").replaceAll("[\\,\\.\\'\\:\\;\\`\\~\\@\\#\\$\\%\\^\\&\\*\\(\\)\\-\\=\\_\\+]*$", "").trim();
anthology_title = anthology_title.trim().replace("\n", " ").replaceAll("[\\,\\.\\'\\:\\;\\`\\~\\@\\#\\$\\%\\^\\&\\*\\(\\)\\-\\=\\_\\+]*$", "").trim();
AnthologyTitle anthology = new AnthologyTitle(new Author(anthology_author), anthology_title);
mList.add(anthology);
}
AnthologyTitleListAdapter adapter = ((AnthologyTitleListAdapter)BookEditAnthology.this.getListView().getAdapter());
adapter.notifyDataSetChanged();
return;
}
});
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, this.getResources().getString(R.string.cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//do nothing
return;
}
});
alertDialog.show();
}
/**
* Run each time the menu button is pressed. This will setup the options menu
*/
@Override
public void onPrepareOptionsMenu(Menu menu) {
menu.clear();
MenuItem populate = menu.add(0, POPULATE, 0, R.string.populate_anthology_titles);
populate.setIcon(android.R.drawable.ic_menu_add);
super.onPrepareOptionsMenu(menu);
}
/**
* This will be called when a menu item is selected. A large switch statement to
* call the appropriate functions (or other activities)
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case POPULATE:
searchWikipedia();
}
return super.onOptionsItemSelected(item);
}
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, DELETE_ID, 0, R.string.menu_delete_anthology);
}
@Override
public boolean onContextItemSelected(android.view.MenuItem item) {
switch(item.getItemId()) {
case DELETE_ID:
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
AnthologyTitleListAdapter adapter = ((AnthologyTitleListAdapter)BookEditAnthology.this.getListView().getAdapter());
adapter.remove(adapter.getItem((int)info.id));
mEditManager.setDirty(true);
return true;
}
return super.onContextItemSelected(item);
}
private void saveState(BookData book) {
if (mSame.isChecked()) {
anthology_num = CatalogueDBAdapter.ANTHOLOGY_IS_ANTHOLOGY;
} else {
anthology_num = CatalogueDBAdapter.ANTHOLOGY_MULTIPLE_AUTHORS ^ CatalogueDBAdapter.ANTHOLOGY_IS_ANTHOLOGY;
}
book.setAnthologyTitles(mList);
book.putInt(CatalogueDBAdapter.KEY_ANTHOLOGY_MASK, anthology_num);
}
@Override
public void onPause() {
super.onPause();
saveState(mEditManager.getBookData());
}
@Override
protected void onLoadBookDetails(BookData book, boolean setAllDone) {
if (!setAllDone)
mFields.setAll(book);
}
@Override
protected void onSaveBookDetails(BookData book) {
super.onSaveBookDetails(book);
saveState(book);
}
}