summaryrefslogtreecommitdiffstats
path: root/mobile/android/base/java/org/mozilla/gecko/EditBookmarkDialog.java
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/base/java/org/mozilla/gecko/EditBookmarkDialog.java')
-rw-r--r--mobile/android/base/java/org/mozilla/gecko/EditBookmarkDialog.java252
1 files changed, 252 insertions, 0 deletions
diff --git a/mobile/android/base/java/org/mozilla/gecko/EditBookmarkDialog.java b/mobile/android/base/java/org/mozilla/gecko/EditBookmarkDialog.java
new file mode 100644
index 000000000..38c38a9eb
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/EditBookmarkDialog.java
@@ -0,0 +1,252 @@
+/* -*- 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.BrowserDB;
+import org.mozilla.gecko.db.BrowserContract.Bookmarks;
+import org.mozilla.gecko.util.ThreadUtils;
+import org.mozilla.gecko.util.UIAsyncTask;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.database.Cursor;
+import android.support.design.widget.Snackbar;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.EditText;
+
+/**
+ * A dialog that allows editing a bookmarks url, title, or keywords
+ * <p>
+ * Invoked by calling one of the {@link org.mozilla.gecko.EditBookmarkDialog#show(String)}
+ * methods.
+ */
+public class EditBookmarkDialog {
+ private final Context mContext;
+
+ public EditBookmarkDialog(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * A private struct to make it easier to pass bookmark data across threads
+ */
+ private class Bookmark {
+ final int id;
+ final String title;
+ final String url;
+ final 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 on different fields.
+ * By itself, it always enables the button.
+ *
+ * Callers can also assign 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) {
+ final ContentResolver cr = mContext.getContentResolver();
+ final BrowserDB db = BrowserDB.from(mContext);
+ (new UIAsyncTask.WithoutParams<Bookmark>(ThreadUtils.getBackgroundHandler()) {
+ @Override
+ public Bookmark doInBackground() {
+ final Cursor cursor = db.getBookmarkForUrl(cr, url);
+ if (cursor == null) {
+ return null;
+ }
+
+ Bookmark bookmark = null;
+ try {
+ cursor.moveToFirst();
+ 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)));
+ } finally {
+ 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) {
+ final Context context = mContext;
+
+ AlertDialog.Builder editPrompt = new AlertDialog.Builder(context);
+ final View editView = LayoutInflater.from(context).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);
+
+ final BrowserDB db = BrowserDB.from(mContext);
+ editPrompt.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int whichButton) {
+ (new UIAsyncTask.WithoutParams<Void>(ThreadUtils.getBackgroundHandler()) {
+ @Override
+ public Void doInBackground() {
+ String newUrl = locationText.getText().toString().trim();
+ String newKeyword = keywordText.getText().toString().trim();
+
+ db.updateBookmark(context.getContentResolver(), id, newUrl, nameText.getText().toString(), newKeyword);
+ return null;
+ }
+
+ @Override
+ public void onPostExecute(Void result) {
+ SnackbarBuilder.builder((Activity) context)
+ .message(R.string.bookmark_updated)
+ .duration(Snackbar.LENGTH_LONG)
+ .buildAndShow();
+ }
+ }).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();
+ }
+}