/* * @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 . */ package com.eleybourn.bookcatalogue; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Calendar; import android.app.Activity; import android.app.DatePickerDialog; import android.app.Dialog; import android.app.TabActivity; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Resources; import android.database.Cursor; import android.database.SQLException; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.Matrix; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup.LayoutParams; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.CheckBox; import android.widget.DatePicker; import android.widget.EditText; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.Spinner; import android.widget.TabHost; import android.widget.TextView; import android.widget.Toast; public class BookEditFields extends Activity { private AutoCompleteTextView mAuthorText; private EditText mTitleText; private EditText mIsbnText; private AutoCompleteTextView mPublisherText; private TextView mDate_publishedText; private Button mBookshelfButton; private TextView mBookshelfText; private AutoCompleteTextView mSeriesText; private EditText mSeriesNumText; private EditText mListPriceText; private EditText mPagesText; private CheckBox mAnthologyCheckBox; private Spinner mFormatText; private EditText mDescriptionText; private EditText mGenreText; private ArrayList formats = new ArrayList(); private ArrayAdapter spinnerAdapter; private Button mConfirmButton; private Button mCancelButton; private Long mRowId; private CatalogueDBAdapter mDbHelper; private Integer mThumbEditSize; private Integer mThumbZoomSize; private ImageView mImageView; private Float rating = Float.parseFloat("0"); private boolean read = false; private int anthology_num = CatalogueDBAdapter.ANTHOLOGY_NO; private String notes = ""; private String location = ""; private String read_start = ""; private String read_end = ""; private boolean signed = false; private String added_genre = ""; private String added_series = ""; private String added_title = ""; private String added_author = ""; public static String ADDED_GENRE = "ADDED_GENRE"; public static String ADDED_SERIES = "ADDED_SERIES"; public static String ADDED_TITLE = "ADDED_TITLE"; public static String ADDED_AUTHOR = "ADDED_AUTHOR"; // Target size of a thumbnail in edit dialog and zoom dialog (bbox dim) private static final int MAX_EDIT_THUMBNAIL_SIZE=256; private static final int MAX_ZOOM_THUMBNAIL_SIZE=1024; private static final int DELETE_ID = 1; private static final int ADD_PHOTO = 2; private static final int ROTATE_THUMB_SUBMENU = 3; private static final int ROTATE_THUMB_CW = 31; private static final int ROTATE_THUMB_CCW = 32; private static final int ROTATE_THUMB_180 = 33; private static final int ADD_GALLERY = 4; private static final int ZOOM_THUMB = 5; private static final int GONE = 8; private static final int DATE_DIALOG_ID = 1; private static final int ZOOM_THUMB_DIALOG_ID = 2; public static final String BOOKSHELF_SEPERATOR = ", "; protected void getRowId() { /* Get any information from the extras bundle */ Bundle extras = getIntent().getExtras(); mRowId = extras != null ? extras.getLong(CatalogueDBAdapter.KEY_ROWID) : null; } protected ArrayList getAuthors() { ArrayList author_list = new ArrayList(); Cursor author_cur = mDbHelper.fetchAllAuthorsIgnoreBooks(); startManagingCursor(author_cur); while (author_cur.moveToNext()) { String name = author_cur.getString(author_cur.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_AUTHOR_FORMATTED)); author_list.add(name); } author_cur.close(); return author_list; } protected ArrayList getSeries() { ArrayList series_list = new ArrayList(); Cursor series_cur = mDbHelper.fetchAllSeries(); startManagingCursor(series_cur); while (series_cur.moveToNext()) { String series = series_cur.getString(series_cur.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_SERIES)); series_list.add(series); } series_cur.close(); return series_list; } protected ArrayList getPublishers() { ArrayList publisher_list = new ArrayList(); Cursor publisher_cur = mDbHelper.fetchAllPublishers(); startManagingCursor(publisher_cur); while (publisher_cur.moveToNext()) { String publisher = publisher_cur.getString(publisher_cur.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_PUBLISHER)); publisher_list.add(publisher); } publisher_cur.close(); return publisher_list; } /** * Display the edit fields page */ @Override protected void onCreate(Bundle savedInstanceState) { SharedPreferences mPrefs = getSharedPreferences("bookCatalogue", MODE_PRIVATE); String visibility_prefix = FieldVisibility.prefix; boolean field_visibility = true; try { mRowId = savedInstanceState != null ? savedInstanceState.getLong(CatalogueDBAdapter.KEY_ROWID) : null; if (mRowId == null) { getRowId(); } super.onCreate(savedInstanceState); mDbHelper = new CatalogueDBAdapter(this); mDbHelper.open(); // See how big the display is and use that to set bitmap sizes android.util.DisplayMetrics metrics = new android.util.DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); // Minimum of MAX_EDIT_THUMBNAIL_SIZE and 1/3rd of largest screen dimension mThumbEditSize = Math.min(MAX_EDIT_THUMBNAIL_SIZE, Math.max(metrics.widthPixels, metrics.heightPixels)/3); // Zoom size is minimum of MAX_ZOOM_THUMBNAIL_SIZE and largest screen dimension. mThumbZoomSize = Math.min(MAX_ZOOM_THUMBNAIL_SIZE, Math.max(metrics.widthPixels, metrics.heightPixels)); setContentView(R.layout.edit_book); ArrayAdapter author_adapter = new ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, getAuthors()); mAuthorText = (AutoCompleteTextView) findViewById(R.id.author); mAuthorText.setAdapter(author_adapter); field_visibility = mPrefs.getBoolean(visibility_prefix + CatalogueDBAdapter.KEY_AUTHOR, true); if (field_visibility == false) { mAuthorText.setVisibility(GONE); } mTitleText = (EditText) findViewById(R.id.title); field_visibility = mPrefs.getBoolean(visibility_prefix + CatalogueDBAdapter.KEY_TITLE, true); if (field_visibility == false) { mTitleText.setVisibility(GONE); } mIsbnText = (EditText) findViewById(R.id.isbn); field_visibility = mPrefs.getBoolean(visibility_prefix + CatalogueDBAdapter.KEY_ISBN, true); if (field_visibility == false) { mIsbnText.setVisibility(GONE); } ArrayAdapter publisher_adapter = new ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, getPublishers()); mPublisherText = (AutoCompleteTextView) findViewById(R.id.publisher); mPublisherText.setAdapter(publisher_adapter); field_visibility = mPrefs.getBoolean(visibility_prefix + CatalogueDBAdapter.KEY_PUBLISHER, true); if (field_visibility == false) { mPublisherText.setVisibility(GONE); } Button mDate_publishedButton = (Button) findViewById(R.id.date_published_button); mDate_publishedButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { showDialog(DATE_DIALOG_ID); } }); mDate_publishedText = (TextView) findViewById(R.id.date_published); field_visibility = mPrefs.getBoolean(visibility_prefix + "date_published", true); if (field_visibility == false) { mDate_publishedButton.setVisibility(GONE); mDate_publishedText.setVisibility(GONE); } ArrayAdapter series_adapter = new ArrayAdapter(this, android.R.layout.simple_dropdown_item_1line, getSeries()); mSeriesText = (AutoCompleteTextView) findViewById(R.id.series); mSeriesText.setAdapter(series_adapter); field_visibility = mPrefs.getBoolean(visibility_prefix + "series", true); if (field_visibility == false) { mSeriesText.setVisibility(GONE); } mSeriesNumText = (EditText) findViewById(R.id.series_num); field_visibility = mPrefs.getBoolean(visibility_prefix + "series_num", true); if (field_visibility == false) { mSeriesNumText.setVisibility(GONE); } mListPriceText = (EditText) findViewById(R.id.list_price); field_visibility = mPrefs.getBoolean(visibility_prefix + "list_price", true); if (field_visibility == false) { mListPriceText.setVisibility(GONE); } mPagesText = (EditText) findViewById(R.id.pages); field_visibility = mPrefs.getBoolean(visibility_prefix + "pages", true); if (field_visibility == false) { mPagesText.setVisibility(GONE); } mAnthologyCheckBox = (CheckBox) findViewById(R.id.anthology); field_visibility = mPrefs.getBoolean(visibility_prefix + "anthology", true); if (field_visibility == false) { mAnthologyCheckBox.setVisibility(GONE); } mDescriptionText = (EditText) findViewById(R.id.description); field_visibility = mPrefs.getBoolean(visibility_prefix + CatalogueDBAdapter.KEY_DESCRIPTION, true); if (field_visibility == false) { mDescriptionText.setVisibility(GONE); } mGenreText = (EditText) findViewById(R.id.genre); field_visibility = mPrefs.getBoolean(visibility_prefix + CatalogueDBAdapter.KEY_GENRE, true); if (field_visibility == false) { mGenreText.setVisibility(GONE); } mFormatText = (Spinner) findViewById(R.id.format); spinnerAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item); spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mFormatText.setAdapter(spinnerAdapter); formats.add(getString(R.string.format1)); formats.add(getString(R.string.format2)); formats.add(getString(R.string.format3)); formats.add(getString(R.string.format4)); formats.add(getString(R.string.format5)); for (int i=0; i -1) { checked = true; } cb.setChecked(checked); cb.setHintTextColor(Color.WHITE); cb.setHint(db_bookshelf); cb.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { String name = cb.getHint() + BOOKSHELF_SEPERATOR; if (cb.isChecked()) { mBookshelfText.setText(mBookshelfText.getText().toString() + name); } else { String text = mBookshelfText.getText().toString(); int index = text.indexOf(name); if (index > -1) { text = text.substring(0, index) + text.substring(index + name.length()); } mBookshelfText.setText(text); } return; } }); root.addView(cb, root.getChildCount()-1); } while (bookshelves_for_book.moveToNext()); } bookshelves_for_book.close(); dialog.show(); //while (bookshelves_for_book2.moveToNext()) { //new ArrayAdapter(this, android.R.layout.simple_list_item_1, new String[] { "Apple", "Peach","Banane" }); //root.addView(child); //} /* AlertDialog.Builder builder = new AlertDialog.Builder(BookEditFields.this); builder.setTitle(R.string.bookshelf_label); builder.setMultiChoiceItems(bookshelves_for_book2, CatalogueDBAdapter.KEY_BOOK, CatalogueDBAdapter.KEY_BOOKSHELF, new OnMultiChoiceClickListener() { public void onClick(DialogInterface dialog, int item, boolean isChecked) { ((AlertDialog) dialog).getListView().setItemChecked(item, isChecked); bookshelves_for_book2.moveToPosition(item); String bookshelf = bookshelves_for_book2.getString(bookshelves_for_book2.getColumnIndex(CatalogueDBAdapter.KEY_BOOKSHELF)); //String bookshelf = "foo"; Toast.makeText(BookEditFields.this, item + " " + bookshelf, Toast.LENGTH_SHORT).show(); mBookshelfText.setText(mBookshelfText.getText().toString() + bookshelf + "\n"); } }); AlertDialog alertDialog = builder.create(); alertDialog.setButton(BookEditFields.this.getResources().getString(R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { return; } }); alertDialog.show(); */ } }); //spinnerAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item); //spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); //mBookshelfText.setAdapter(spinnerAdapter); //if (bookshelves.moveToFirst()) { // do { // spinnerAdapter.add(bookshelves.getString(1)); // } // while (bookshelves.moveToNext()); //} //bookshelves.close(); // close the cursor field_visibility = mPrefs.getBoolean(visibility_prefix + "bookshelf", true); if (field_visibility == false) { mBookshelfText.setVisibility(GONE); } populateFields(); mImageView.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() { @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { MenuItem delete = menu.add(0, DELETE_ID, 0, R.string.menu_delete_thumb); delete.setIcon(android.R.drawable.ic_menu_delete); MenuItem add_photo = menu.add(0, ADD_PHOTO, 1, R.string.menu_add_thumb_photo); add_photo.setIcon(android.R.drawable.ic_menu_camera); MenuItem add_gallery = menu.add(0, ADD_GALLERY, 2, R.string.menu_add_thumb_gallery); add_gallery.setIcon(android.R.drawable.ic_menu_gallery); // Submenu for rotate android.view.SubMenu submenu = menu.addSubMenu(0, ROTATE_THUMB_SUBMENU, 3, R.string.menu_rotate_thumb); add_gallery.setIcon(android.R.drawable.ic_menu_rotate); MenuItem rotate_photo_cw = submenu.add(0, ROTATE_THUMB_CW, 1, R.string.menu_rotate_thumb_cw); rotate_photo_cw.setIcon(android.R.drawable.ic_menu_rotate); MenuItem rotate_photo_ccw = submenu.add(0, ROTATE_THUMB_CCW, 2, R.string.menu_rotate_thumb_ccw); rotate_photo_ccw.setIcon(android.R.drawable.ic_menu_rotate); MenuItem rotate_photo_180 = submenu.add(0, ROTATE_THUMB_180, 3, R.string.menu_rotate_thumb_180); rotate_photo_180.setIcon(android.R.drawable.ic_menu_rotate); MenuItem zoom_thumb = menu.add(0, ZOOM_THUMB, 4, R.string.menu_zoom_thumb); zoom_thumb.setIcon(android.R.drawable.ic_menu_zoom); } }); // mConfirmButton.setOnClickListener - This is set in populate fields. The behaviour changes depending on if it is adding or saving mCancelButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { setResult(RESULT_OK); finish(); } }); } catch (SQLException e) { //Log.e("Book Catalogue", "Unknown error " + e.toString()); } } @Override protected Dialog onCreateDialog(int id) { Dialog dialog; switch (id) { case DATE_DIALOG_ID: try { String dateString = (String) mDate_publishedText.getText(); // get the current date final Calendar c = Calendar.getInstance(); int yyyy = c.get(Calendar.YEAR); int mm = c.get(Calendar.MONTH); int dd = c.get(Calendar.DAY_OF_MONTH); try { String[] date = dateString.split("-"); yyyy = Integer.parseInt(date[0]); mm = Integer.parseInt(date[1])-1; dd = Integer.parseInt(date[2]); } catch (Exception e) { //do nothing } dialog = new DatePickerDialog(this, mDateSetListener, yyyy, mm, dd); } catch (Exception e) { // use the default date dialog = null; } break; case ZOOM_THUMB_DIALOG_ID: // Create dialog and set layout dialog = new Dialog(BookEditFields.this); dialog.setContentView(R.layout.zoom_thumb_dialog); // Check if we have a file and/or it is valid String filename = CatalogueDBAdapter.fetchThumbnailFilename(mRowId, false); if (filename == null) { dialog.setTitle("Cover is not set"); } else { BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inJustDecodeBounds = true; BitmapFactory.decodeFile( filename, opt ); // If no size info, assume file bad and return appropriate icon if ( opt.outHeight <= 0 || opt.outWidth <= 0 ) { dialog.setTitle("Cover corrupt"); } else { dialog.setTitle("Cover Detail"); ImageView cover = new ImageView(this); CatalogueDBAdapter.fetchThumbnailIntoImageView(mRowId, cover, mThumbZoomSize, mThumbZoomSize, true); cover.setAdjustViewBounds(true); LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); dialog.addContentView(cover, lp); } } break; default: dialog = null; } return dialog; } // the callback received when the user "sets" the date in the dialog private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() { public void onDateSet(DatePicker view, int year, int month, int day) { month = month + 1; String mm = month + ""; if (mm.length() == 1) { mm = "0" + mm; } String dd = day + ""; if (dd.length() == 1) { dd = "0" + dd; } mDate_publishedText.setText(year + "-" + mm + "-" + dd); } }; @Override public boolean onContextItemSelected(MenuItem item) { switch(item.getItemId()) { case DELETE_ID: deleteThumbnail(mRowId); populateFields(); return true; case ROTATE_THUMB_SUBMENU: // Just a submenu; skip return true; case ROTATE_THUMB_CW: rotateThumbnail(mRowId, 90); populateFields(); return true; case ROTATE_THUMB_CCW: rotateThumbnail(mRowId, -90); populateFields(); return true; case ROTATE_THUMB_180: rotateThumbnail(mRowId, 180); populateFields(); return true; case ADD_PHOTO: Intent pintent = null; pintent = new Intent("android.media.action.IMAGE_CAPTURE"); startActivityForResult(pintent, ADD_PHOTO); return true; case ADD_GALLERY: Intent gintent = new Intent(); gintent.setType("image/*"); gintent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(gintent, "Select Picture"), ADD_GALLERY); return true; case ZOOM_THUMB: showDialog(ZOOM_THUMB_DIALOG_ID); return true; } return super.onContextItemSelected(item); } /** * Delete the provided thumbnail from the sdcard * * @param id The id of the book (and thumbnail) to delete */ private void deleteThumbnail(long id) { try { File thumb = CatalogueDBAdapter.fetchThumbnail(id); thumb.delete(); thumb = CatalogueDBAdapter.fetchThumbnail(id); thumb.delete(); } catch (Exception e) { // something has gone wrong. } } /** * Rotate the thumbnail a specified amount * * @param id */ private void rotateThumbnail(long id, long angle) { Bitmap bm = CatalogueDBAdapter.fetchThumbnailIntoImageView(mRowId, null, mThumbZoomSize*2, mThumbZoomSize*2, true); if (bm == null) return; Matrix m = new Matrix(); m.postRotate(angle); bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), m, true); /* Create a file to copy the thumbnail into */ FileOutputStream f = null; try { String filename = CatalogueDBAdapter.fetchThumbnailFilename(mRowId, false); f = new FileOutputStream(filename); } catch (FileNotFoundException e) { //Log.e("Book Catalogue", "Thumbnail cannot be written"); return; } bm.compress(Bitmap.CompressFormat.PNG, 100, f); } /** * This function will populate the forms elements in three different ways * 1. If a valid rowId exists it will populate the fields from the database * 2. If fields have been passed from another activity (e.g. ISBNSearch) it will populate the fields from the bundle * 3. It will leave the fields blank for new books. */ private void populateFields() { Bundle extras = getIntent().getExtras(); if (mRowId == null) { getRowId(); } if (mRowId != null && mRowId > 0) { // From the database (edit) Cursor book = mDbHelper.fetchBookById(mRowId); startManagingCursor(book); if (book != null) { book.moveToFirst(); } String title = book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_TITLE)); getParent().setTitle(this.getResources().getString(R.string.app_name) + ": " + title); mAuthorText.setText(book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_AUTHOR_FORMATTED))); mTitleText.setText(title); mIsbnText.setText(book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_ISBN))); mPublisherText.setText(book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_PUBLISHER))); String[] date = book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_DATE_PUBLISHED)).split("-"); try { String yyyy = date[0]; int month = Integer.parseInt(date[1]); month = month + 1; String mm = month + ""; if (mm.length() == 1) { mm = "0" + mm; } String dd = date[2]; if (dd.length() == 1) { dd = "0" + dd; } mDate_publishedText.setText(yyyy + "-" + mm + "-" + dd); } catch (Exception e) { } //Display the selected bookshelves Cursor bookshelves = mDbHelper.fetchAllBookshelvesByBook(mRowId); String bookshelves_text = ""; while (bookshelves.moveToNext()) { bookshelves_text += bookshelves.getString(bookshelves.getColumnIndex(CatalogueDBAdapter.KEY_BOOKSHELF)) + BOOKSHELF_SEPERATOR; } mBookshelfText.setText(bookshelves_text); bookshelves.close(); mSeriesText.setText(book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_SERIES))); mSeriesNumText.setText(book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_SERIES_NUM))); mListPriceText.setText(book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_LIST_PRICE))); mPagesText.setText(book.getString(book.getColumnIndexOrThrow(CatalogueDBAdapter.KEY_PAGES))); String format = book.getString(book.getColumnIndex(CatalogueDBAdapter.KEY_FORMAT)); for (int i=0; i