michael@0: /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko; michael@0: michael@0: import org.mozilla.gecko.db.BrowserContract.Bookmarks; michael@0: import org.mozilla.gecko.db.BrowserDB; michael@0: import org.mozilla.gecko.util.ThreadUtils; michael@0: import org.mozilla.gecko.util.UiAsyncTask; michael@0: michael@0: import android.content.Context; michael@0: import android.app.AlertDialog; michael@0: import android.content.DialogInterface; michael@0: import android.database.Cursor; michael@0: import android.text.Editable; michael@0: import android.text.TextWatcher; michael@0: import android.view.LayoutInflater; michael@0: import android.view.View; michael@0: import android.widget.EditText; michael@0: import android.widget.Toast; michael@0: michael@0: /** michael@0: * A dialog that allows editing a bookmarks url, title, or keywords michael@0: *
michael@0: * Invoked by calling one of the {@link org.mozilla.gecko.EditBookmarkDialog.show}
michael@0: * methods.
michael@0: */
michael@0: public class EditBookmarkDialog {
michael@0: private static final String LOGTAG = "GeckoEditBookmarkDialog";
michael@0: private Context mContext;
michael@0:
michael@0: public EditBookmarkDialog(Context context) {
michael@0: mContext = context;
michael@0: }
michael@0:
michael@0: /**
michael@0: * A private struct to make it easier to pass bookmark data across threads
michael@0: */
michael@0: private class Bookmark {
michael@0: int id;
michael@0: String title;
michael@0: String url;
michael@0: String keyword;
michael@0:
michael@0: public Bookmark(int aId, String aTitle, String aUrl, String aKeyword) {
michael@0: id = aId;
michael@0: title = aTitle;
michael@0: url = aUrl;
michael@0: keyword = aKeyword;
michael@0: }
michael@0: }
michael@0:
michael@0: /**
michael@0: * This text watcher to enable or disable the OK button if the dialog contains
michael@0: * valid information. This class is overridden to do data checking diffferent fields.
michael@0: * By itself, it always enables the button.
michael@0: *
michael@0: * Callers can also assing a paired partner to the TextWatcher, and callers will check
michael@0: * that both are enabled before enabling the ok button.
michael@0: */
michael@0: private class EditBookmarkTextWatcher implements TextWatcher {
michael@0: // A stored reference to the dialog containing the text field being watched
michael@0: protected AlertDialog mDialog;
michael@0:
michael@0: // A stored text watcher to do the real verification of a field
michael@0: protected EditBookmarkTextWatcher mPairedTextWatcher;
michael@0:
michael@0: // Whether or not the ok button should be enabled.
michael@0: protected boolean mEnabled = true;
michael@0:
michael@0: public EditBookmarkTextWatcher(AlertDialog aDialog) {
michael@0: mDialog = aDialog;
michael@0: }
michael@0:
michael@0: public void setPairedTextWatcher(EditBookmarkTextWatcher aTextWatcher) {
michael@0: mPairedTextWatcher = aTextWatcher;
michael@0: }
michael@0:
michael@0: public boolean isEnabled() {
michael@0: return mEnabled;
michael@0: }
michael@0:
michael@0: // Textwatcher interface
michael@0: @Override
michael@0: public void onTextChanged(CharSequence s, int start, int before, int count) {
michael@0: // Disable if the we're disabled or the paired partner is disabled
michael@0: boolean enabled = mEnabled && (mPairedTextWatcher == null || mPairedTextWatcher.isEnabled());
michael@0: mDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(enabled);
michael@0: }
michael@0:
michael@0: @Override
michael@0: public void afterTextChanged(Editable s) {}
michael@0: @Override
michael@0: public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
michael@0: }
michael@0:
michael@0: /**
michael@0: * A version of the EditBookmarkTextWatcher for the url field of the dialog.
michael@0: * Only checks if the field is empty or not.
michael@0: */
michael@0: private class LocationTextWatcher extends EditBookmarkTextWatcher {
michael@0: public LocationTextWatcher(AlertDialog aDialog) {
michael@0: super(aDialog);
michael@0: }
michael@0:
michael@0: // Disables the ok button if the location field is empty.
michael@0: @Override
michael@0: public void onTextChanged(CharSequence s, int start, int before, int count) {
michael@0: mEnabled = (s.toString().trim().length() > 0);
michael@0: super.onTextChanged(s, start, before, count);
michael@0: }
michael@0: }
michael@0:
michael@0: /**
michael@0: * A version of the EditBookmarkTextWatcher for the keyword field of the dialog.
michael@0: * Checks if the field has any (non leading or trailing) spaces.
michael@0: */
michael@0: private class KeywordTextWatcher extends EditBookmarkTextWatcher {
michael@0: public KeywordTextWatcher(AlertDialog aDialog) {
michael@0: super(aDialog);
michael@0: }
michael@0:
michael@0: @Override
michael@0: public void onTextChanged(CharSequence s, int start, int before, int count) {
michael@0: // Disable if the keyword contains spaces
michael@0: mEnabled = (s.toString().trim().indexOf(' ') == -1);
michael@0: super.onTextChanged(s, start, before, count);
michael@0: }
michael@0: }
michael@0:
michael@0: /**
michael@0: * Show the Edit bookmark dialog for a particular url. If the url is bookmarked multiple times
michael@0: * this will just edit the first instance it finds.
michael@0: *
michael@0: * @param url The url of the bookmark to edit. The dialog will look up other information like the id,
michael@0: * current title, or keywords associated with this url. If the url isn't bookmarked, the
michael@0: * dialog will fail silently. If the url is bookmarked multiple times, this will only show
michael@0: * information about the first it finds.
michael@0: */
michael@0: public void show(final String url) {
michael@0: (new UiAsyncTask