Bug 872388 - Move EditBookmark dialog into its own class. r=bnicholson

This commit is contained in:
Wes Johnston 2013-05-30 17:03:18 -07:00
parent 5f85a25cda
commit 4efe423c34
5 changed files with 264 additions and 112 deletions

View File

@ -15,9 +15,7 @@ import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.util.UiAsyncTask;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
@ -555,62 +553,6 @@ public class AwesomeBar extends GeckoActivity
mContextMenuSubject = tab.getSubject(menu, view, menuInfo);
}
private abstract class EditBookmarkTextWatcher implements TextWatcher {
protected AlertDialog mDialog;
protected EditBookmarkTextWatcher mPairedTextWatcher;
protected boolean mEnabled = true;
public EditBookmarkTextWatcher(AlertDialog aDialog) {
mDialog = aDialog;
}
public void setPairedTextWatcher(EditBookmarkTextWatcher aTextWatcher) {
mPairedTextWatcher = aTextWatcher;
}
public boolean isEnabled() {
return mEnabled;
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Disable if the we're disabled or paired partner is disabled
boolean enabled = mEnabled && (mPairedTextWatcher == null || mPairedTextWatcher.isEnabled());
mDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(enabled);
}
@Override
public void afterTextChanged(Editable s) {}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
}
private class LocationTextWatcher extends EditBookmarkTextWatcher implements TextWatcher {
public LocationTextWatcher(AlertDialog aDialog) {
super(aDialog);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Disable if the location is empty
mEnabled = (s.toString().trim().length() > 0);
super.onTextChanged(s, start, before, count);
}
}
private class KeywordTextWatcher extends EditBookmarkTextWatcher implements TextWatcher {
public KeywordTextWatcher(AlertDialog aDialog) {
super(aDialog);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Disable if the keyword contains spaces
mEnabled = (s.toString().trim().indexOf(' ') == -1);
super.onTextChanged(s, start, before, count);
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
if (mContextMenuSubject == null)
@ -653,60 +595,7 @@ public class AwesomeBar extends GeckoActivity
break;
}
case R.id.edit_bookmark: {
AlertDialog.Builder editPrompt = new AlertDialog.Builder(this);
final View editView = getLayoutInflater().inflate(R.layout.bookmark_edit, null);
editPrompt.setTitle(R.string.bookmark_edit_title);
editPrompt.setView(editView);
final EditText nameText = ((EditText) editView.findViewById(R.id.edit_bookmark_name));
final EditText locationText = ((EditText) editView.findViewById(R.id.edit_bookmark_location));
final EditText keywordText = ((EditText) editView.findViewById(R.id.edit_bookmark_keyword));
nameText.setText(title);
locationText.setText(url);
keywordText.setText(keyword);
editPrompt.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
(new UiAsyncTask<Void, Void, Void>(ThreadUtils.getBackgroundHandler()) {
@Override
public Void doInBackground(Void... params) {
String newUrl = locationText.getText().toString().trim();
String newKeyword = keywordText.getText().toString().trim();
BrowserDB.updateBookmark(getContentResolver(), id, newUrl, nameText.getText().toString(), newKeyword);
return null;
}
@Override
public void onPostExecute(Void result) {
Toast.makeText(AwesomeBar.this, R.string.bookmark_updated, Toast.LENGTH_SHORT).show();
}
}).execute();
}
});
editPrompt.setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
// do nothing
}
});
final AlertDialog dialog = editPrompt.create();
// Create our TextWatchers
LocationTextWatcher locationTextWatcher = new LocationTextWatcher(dialog);
KeywordTextWatcher keywordTextWatcher = new KeywordTextWatcher(dialog);
// Cross reference the TextWatchers
locationTextWatcher.setPairedTextWatcher(keywordTextWatcher);
keywordTextWatcher.setPairedTextWatcher(locationTextWatcher);
// Add the TextWatcher Listeners
locationText.addTextChangedListener(locationTextWatcher);
keywordText.addTextChangedListener(keywordTextWatcher);
dialog.show();
new EditBookmarkDialog(this).show(id, title, url, keyword);
break;
}
case R.id.remove_bookmark: {

View File

@ -0,0 +1,237 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko;
import org.mozilla.gecko.db.BrowserContract.Bookmarks;
import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.gecko.util.UiAsyncTask;
import android.content.Context;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.database.Cursor;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
/**
* A dialog that allows editing a bookmarks url, title, or keywords
* <p>
* Invoked by calling one of the {@link org.mozilla.gecko.EditBookmarkDialog.show}
* methods.
*/
public class EditBookmarkDialog {
private static final String LOGTAG = "GeckoEditBookmarkDialog";
private Context mContext;
public EditBookmarkDialog(Context activity) {
mContext = activity;
}
/**
* A private struct to make it easier to pass bookmark data across threads
*/
private class Bookmark {
int id;
String title;
String url;
String keyword;
public Bookmark(int aId, String aTitle, String aUrl, String aKeyword) {
id = aId;
title = aTitle;
url = aUrl;
keyword = aKeyword;
}
}
/**
* This text watcher to enable or disable the OK button if the dialog contains
* valid information. This class is overridden to do data checking diffferent fields.
* By itself, it always enables the button.
*
* Callers can also assing a paired partner to the TextWatcher, and callers will check
* that both are enabled before enabling the ok button.
*/
private class EditBookmarkTextWatcher implements TextWatcher {
// A stored reference to the dialog containing the text field being watched
protected AlertDialog mDialog;
// A stored text watcher to do the real verification of a field
protected EditBookmarkTextWatcher mPairedTextWatcher;
// Whether or not the ok button should be enabled.
protected boolean mEnabled = true;
public EditBookmarkTextWatcher(AlertDialog aDialog) {
mDialog = aDialog;
}
public void setPairedTextWatcher(EditBookmarkTextWatcher aTextWatcher) {
mPairedTextWatcher = aTextWatcher;
}
public boolean isEnabled() {
return mEnabled;
}
// Textwatcher interface
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Disable if the we're disabled or the paired partner is disabled
boolean enabled = mEnabled && (mPairedTextWatcher == null || mPairedTextWatcher.isEnabled());
mDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(enabled);
}
@Override
public void afterTextChanged(Editable s) {}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
}
/**
* A version of the EditBookmarkTextWatcher for the url field of the dialog.
* Only checks if the field is empty or not.
*/
private class LocationTextWatcher extends EditBookmarkTextWatcher {
public LocationTextWatcher(AlertDialog aDialog) {
super(aDialog);
}
// Disables the ok button if the location field is empty.
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mEnabled = (s.toString().trim().length() > 0);
super.onTextChanged(s, start, before, count);
}
}
/**
* A version of the EditBookmarkTextWatcher for the keyword field of the dialog.
* Checks if the field has any (non leading or trailing) spaces.
*/
private class KeywordTextWatcher extends EditBookmarkTextWatcher {
public KeywordTextWatcher(AlertDialog aDialog) {
super(aDialog);
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Disable if the keyword contains spaces
mEnabled = (s.toString().trim().indexOf(' ') == -1);
super.onTextChanged(s, start, before, count);
}
}
/**
* Show the Edit bookmark dialog for a particular url. If the url is bookmarked multiple times
* this will just edit the first instance it finds.
*
* @param url The url of the bookmark to edit. The dialog will look up other information like the id,
* current title, or keywords associated with this url. If the url isn't bookmarked, the
* dialog will fail silently. If the url is bookmarked multiple times, this will only show
* information about the first it finds.
*/
public void show(final String url) {
(new UiAsyncTask<Void, Void, Bookmark>(ThreadUtils.getBackgroundHandler()) {
@Override
public Bookmark doInBackground(Void... params) {
Cursor cursor = BrowserDB.getBookmarkForUrl(mContext.getContentResolver(), url);
if (cursor == null) {
return null;
}
cursor.moveToFirst();
Bookmark bookmark = new Bookmark(cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks._ID)),
cursor.getString(cursor.getColumnIndexOrThrow(Bookmarks.TITLE)),
cursor.getString(cursor.getColumnIndexOrThrow(Bookmarks.URL)),
cursor.getString(cursor.getColumnIndexOrThrow(Bookmarks.KEYWORD)));
cursor.close();
return bookmark;
}
@Override
public void onPostExecute(Bookmark bookmark) {
if (bookmark == null)
return;
show(bookmark.id, bookmark.title, bookmark.url, bookmark.keyword);
}
}).execute();
}
/**
* Show the Edit bookmark dialog for a set of data. This will show the dialog whether
* a bookmark with this url exists or not, but the results will NOT be saved if the id
* is not a valid bookmark id.
*
* @param id The id of the bookmark to change. If there is no bookmark with this ID, the dialog
* will fail silently.
* @param title The initial title to show in the dialog
* @param url The initial url to show in the dialog
* @param keyword The initial keyword to show in the dialog
*/
public void show(final int id, final String title, final String url, final String keyword) {
AlertDialog.Builder editPrompt = new AlertDialog.Builder(mContext);
final View editView = LayoutInflater.from(mContext).inflate(R.layout.bookmark_edit, null);
editPrompt.setTitle(R.string.bookmark_edit_title);
editPrompt.setView(editView);
final EditText nameText = ((EditText) editView.findViewById(R.id.edit_bookmark_name));
final EditText locationText = ((EditText) editView.findViewById(R.id.edit_bookmark_location));
final EditText keywordText = ((EditText) editView.findViewById(R.id.edit_bookmark_keyword));
nameText.setText(title);
locationText.setText(url);
keywordText.setText(keyword);
editPrompt.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
(new UiAsyncTask<Void, Void, Void>(ThreadUtils.getBackgroundHandler()) {
@Override
public Void doInBackground(Void... params) {
String newUrl = locationText.getText().toString().trim();
String newKeyword = keywordText.getText().toString().trim();
BrowserDB.updateBookmark(mContext.getContentResolver(), id, newUrl, nameText.getText().toString(), newKeyword);
return null;
}
@Override
public void onPostExecute(Void result) {
Toast.makeText(mContext, R.string.bookmark_updated, Toast.LENGTH_SHORT).show();
}
}).execute();
}
});
editPrompt.setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int whichButton) {
// do nothing
}
});
final AlertDialog dialog = editPrompt.create();
// Create our TextWatchers
LocationTextWatcher locationTextWatcher = new LocationTextWatcher(dialog);
KeywordTextWatcher keywordTextWatcher = new KeywordTextWatcher(dialog);
// Cross reference the TextWatchers
locationTextWatcher.setPairedTextWatcher(keywordTextWatcher);
keywordTextWatcher.setPairedTextWatcher(locationTextWatcher);
// Add the TextWatcher Listeners
locationText.addTextChangedListener(locationTextWatcher);
keywordText.addTextChangedListener(keywordTextWatcher);
dialog.show();
}
}

View File

@ -83,6 +83,7 @@ FENNEC_JAVA_FILES = \
Distribution.java \
DoorHanger.java \
DoorHangerPopup.java \
EditBookmarkDialog.java \
Favicons.java \
FilePickerResultHandler.java \
FilePickerResultHandlerSync.java \

View File

@ -114,6 +114,8 @@ public class BrowserDB {
public void unpinAllSites(ContentResolver cr);
public Cursor getPinnedSites(ContentResolver cr, int limit);
public Cursor getBookmarkForUrl(ContentResolver cr, String url);
}
static {
@ -295,6 +297,10 @@ public class BrowserDB {
return sDb.getPinnedSites(cr, limit);
}
public static Cursor getBookmarkForUrl(ContentResolver cr, String url) {
return sDb.getBookmarkForUrl(cr, url);
}
public static class PinnedSite {
public String title = "";
public String url = "";

View File

@ -1242,4 +1242,23 @@ public class LocalBrowserDB implements BrowserDB.BrowserDBIface {
return (count > 0);
}
public Cursor getBookmarkForUrl(ContentResolver cr, String url) {
Cursor c = cr.query(bookmarksUriWithLimit(1),
new String[] { Bookmarks._ID,
Bookmarks.URL,
Bookmarks.TITLE,
Bookmarks.KEYWORD },
Bookmarks.URL + " = ?",
new String[] { url },
null);
if (c == null) {
return c;
} else if (c.getCount() == 0) {
c.close();
c = null;
}
return c;
}
}