mobile/android/base/EditBookmarkDialog.java

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/base/EditBookmarkDialog.java	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,241 @@
     1.4 +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
     1.5 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +package org.mozilla.gecko;
    1.10 +
    1.11 +import org.mozilla.gecko.db.BrowserContract.Bookmarks;
    1.12 +import org.mozilla.gecko.db.BrowserDB;
    1.13 +import org.mozilla.gecko.util.ThreadUtils;
    1.14 +import org.mozilla.gecko.util.UiAsyncTask;
    1.15 +
    1.16 +import android.content.Context;
    1.17 +import android.app.AlertDialog;
    1.18 +import android.content.DialogInterface;
    1.19 +import android.database.Cursor;
    1.20 +import android.text.Editable;
    1.21 +import android.text.TextWatcher;
    1.22 +import android.view.LayoutInflater;
    1.23 +import android.view.View;
    1.24 +import android.widget.EditText;
    1.25 +import android.widget.Toast;
    1.26 +
    1.27 +/**
    1.28 + * A dialog that allows editing a bookmarks url, title, or keywords
    1.29 + * <p>
    1.30 + * Invoked by calling one of the {@link org.mozilla.gecko.EditBookmarkDialog.show}
    1.31 + * methods.
    1.32 + */
    1.33 +public class EditBookmarkDialog {
    1.34 +    private static final String LOGTAG = "GeckoEditBookmarkDialog";
    1.35 +    private Context mContext;
    1.36 +
    1.37 +    public EditBookmarkDialog(Context context) {
    1.38 +        mContext = context;
    1.39 +    }
    1.40 +
    1.41 +    /**
    1.42 +     * A private struct to make it easier to pass bookmark data across threads
    1.43 +     */
    1.44 +    private class Bookmark {
    1.45 +        int id;
    1.46 +        String title;
    1.47 +        String url;
    1.48 +        String keyword;
    1.49 +
    1.50 +        public Bookmark(int aId, String aTitle, String aUrl, String aKeyword) {
    1.51 +            id = aId;
    1.52 +            title = aTitle;
    1.53 +            url = aUrl;
    1.54 +            keyword = aKeyword;
    1.55 +        }
    1.56 +    }
    1.57 +
    1.58 +    /**
    1.59 +     * This text watcher to enable or disable the OK button if the dialog contains
    1.60 +     * valid information. This class is overridden to do data checking diffferent fields.
    1.61 +     * By itself, it always enables the button.
    1.62 +     *
    1.63 +     * Callers can also assing a paired partner to the TextWatcher, and callers will check
    1.64 +     * that both are enabled before enabling the ok button.
    1.65 +     */
    1.66 +    private class EditBookmarkTextWatcher implements TextWatcher {
    1.67 +        // A stored reference to the dialog containing the text field being watched
    1.68 +        protected AlertDialog mDialog;
    1.69 +
    1.70 +        // A stored text watcher to do the real verification of a field
    1.71 +        protected EditBookmarkTextWatcher mPairedTextWatcher;
    1.72 +
    1.73 +        // Whether or not the ok button should be enabled.
    1.74 +        protected boolean mEnabled = true;
    1.75 +
    1.76 +        public EditBookmarkTextWatcher(AlertDialog aDialog) {
    1.77 +            mDialog = aDialog;
    1.78 +        }
    1.79 +
    1.80 +        public void setPairedTextWatcher(EditBookmarkTextWatcher aTextWatcher) {
    1.81 +            mPairedTextWatcher = aTextWatcher;
    1.82 +        }
    1.83 +
    1.84 +        public boolean isEnabled() {
    1.85 +            return mEnabled;
    1.86 +        }
    1.87 +
    1.88 +        // Textwatcher interface
    1.89 +        @Override
    1.90 +        public void onTextChanged(CharSequence s, int start, int before, int count) {
    1.91 +            // Disable if the we're disabled or the paired partner is disabled
    1.92 +            boolean enabled = mEnabled && (mPairedTextWatcher == null || mPairedTextWatcher.isEnabled());
    1.93 +            mDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(enabled);
    1.94 +        }
    1.95 +
    1.96 +        @Override
    1.97 +        public void afterTextChanged(Editable s) {}
    1.98 +        @Override
    1.99 +        public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
   1.100 +    }
   1.101 +
   1.102 +    /**
   1.103 +     * A version of the EditBookmarkTextWatcher for the url field of the dialog.
   1.104 +     * Only checks if the field is empty or not.
   1.105 +     */
   1.106 +    private class LocationTextWatcher extends EditBookmarkTextWatcher {
   1.107 +        public LocationTextWatcher(AlertDialog aDialog) {
   1.108 +            super(aDialog);
   1.109 +        }
   1.110 +
   1.111 +        // Disables the ok button if the location field is empty.
   1.112 +        @Override
   1.113 +        public void onTextChanged(CharSequence s, int start, int before, int count) {
   1.114 +            mEnabled = (s.toString().trim().length() > 0);
   1.115 +            super.onTextChanged(s, start, before, count);
   1.116 +        }
   1.117 +    }
   1.118 +
   1.119 +    /**
   1.120 +     * A version of the EditBookmarkTextWatcher for the keyword field of the dialog.
   1.121 +     * Checks if the field has any (non leading or trailing) spaces.
   1.122 +     */
   1.123 +    private class KeywordTextWatcher extends EditBookmarkTextWatcher {
   1.124 +        public KeywordTextWatcher(AlertDialog aDialog) {
   1.125 +            super(aDialog);
   1.126 +        }
   1.127 +
   1.128 +        @Override
   1.129 +        public void onTextChanged(CharSequence s, int start, int before, int count) {
   1.130 +            // Disable if the keyword contains spaces
   1.131 +            mEnabled = (s.toString().trim().indexOf(' ') == -1);
   1.132 +            super.onTextChanged(s, start, before, count);
   1.133 +       }
   1.134 +    }
   1.135 +
   1.136 +    /**
   1.137 +     * Show the Edit bookmark dialog for a particular url. If the url is bookmarked multiple times
   1.138 +     * this will just edit the first instance it finds.
   1.139 +     *
   1.140 +     * @param url The url of the bookmark to edit. The dialog will look up other information like the id,
   1.141 +     *            current title, or keywords associated with this url. If the url isn't bookmarked, the
   1.142 +     *            dialog will fail silently. If the url is bookmarked multiple times, this will only show
   1.143 +     *            information about the first it finds.
   1.144 +     */
   1.145 +    public void show(final String url) {
   1.146 +        (new UiAsyncTask<Void, Void, Bookmark>(ThreadUtils.getBackgroundHandler()) {
   1.147 +            @Override
   1.148 +            public Bookmark doInBackground(Void... params) {
   1.149 +                Cursor cursor = BrowserDB.getBookmarkForUrl(mContext.getContentResolver(), url);
   1.150 +                if (cursor == null) {
   1.151 +                    return null;
   1.152 +                }
   1.153 +
   1.154 +                Bookmark bookmark = null;
   1.155 +                try {
   1.156 +                    cursor.moveToFirst();
   1.157 +                    bookmark = new Bookmark(cursor.getInt(cursor.getColumnIndexOrThrow(Bookmarks._ID)),
   1.158 +                                                          cursor.getString(cursor.getColumnIndexOrThrow(Bookmarks.TITLE)),
   1.159 +                                                          cursor.getString(cursor.getColumnIndexOrThrow(Bookmarks.URL)),
   1.160 +                                                          cursor.getString(cursor.getColumnIndexOrThrow(Bookmarks.KEYWORD)));
   1.161 +                } finally {
   1.162 +                    cursor.close();
   1.163 +                }
   1.164 +                return bookmark;
   1.165 +            }
   1.166 +
   1.167 +            @Override
   1.168 +            public void onPostExecute(Bookmark bookmark) {
   1.169 +                if (bookmark == null)
   1.170 +                    return;
   1.171 +
   1.172 +                show(bookmark.id, bookmark.title, bookmark.url, bookmark.keyword);
   1.173 +            }
   1.174 +        }).execute();
   1.175 +    }
   1.176 +
   1.177 +    /**
   1.178 +     * Show the Edit bookmark dialog for a set of data. This will show the dialog whether
   1.179 +     * a bookmark with this url exists or not, but the results will NOT be saved if the id
   1.180 +     * is not a valid bookmark id.
   1.181 +     *
   1.182 +     * @param id The id of the bookmark to change. If there is no bookmark with this ID, the dialog
   1.183 +     *           will fail silently.
   1.184 +     * @param title The initial title to show in the dialog
   1.185 +     * @param url The initial url to show in the dialog
   1.186 +     * @param keyword The initial keyword to show in the dialog
   1.187 +     */
   1.188 +    public void show(final int id, final String title, final String url, final String keyword) {
   1.189 +        AlertDialog.Builder editPrompt = new AlertDialog.Builder(mContext);
   1.190 +        final View editView = LayoutInflater.from(mContext).inflate(R.layout.bookmark_edit, null);
   1.191 +        editPrompt.setTitle(R.string.bookmark_edit_title);
   1.192 +        editPrompt.setView(editView);
   1.193 +
   1.194 +        final EditText nameText = ((EditText) editView.findViewById(R.id.edit_bookmark_name));
   1.195 +        final EditText locationText = ((EditText) editView.findViewById(R.id.edit_bookmark_location));
   1.196 +        final EditText keywordText = ((EditText) editView.findViewById(R.id.edit_bookmark_keyword));
   1.197 +        nameText.setText(title);
   1.198 +        locationText.setText(url);
   1.199 +        keywordText.setText(keyword);
   1.200 +
   1.201 +        editPrompt.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
   1.202 +            @Override
   1.203 +            public void onClick(DialogInterface dialog, int whichButton) {
   1.204 +                (new UiAsyncTask<Void, Void, Void>(ThreadUtils.getBackgroundHandler()) {
   1.205 +                    @Override
   1.206 +                    public Void doInBackground(Void... params) {
   1.207 +                        String newUrl = locationText.getText().toString().trim();
   1.208 +                        String newKeyword = keywordText.getText().toString().trim();
   1.209 +                        BrowserDB.updateBookmark(mContext.getContentResolver(), id, newUrl, nameText.getText().toString(), newKeyword);
   1.210 +                        return null;
   1.211 +                    }
   1.212 +
   1.213 +                    @Override
   1.214 +                    public void onPostExecute(Void result) {
   1.215 +                        Toast.makeText(mContext, R.string.bookmark_updated, Toast.LENGTH_SHORT).show();
   1.216 +                    }
   1.217 +                }).execute();
   1.218 +            }
   1.219 +        });
   1.220 +
   1.221 +        editPrompt.setNegativeButton(R.string.button_cancel, new DialogInterface.OnClickListener() {
   1.222 +            @Override
   1.223 +            public void onClick(DialogInterface dialog, int whichButton) {
   1.224 +                  // do nothing
   1.225 +              }
   1.226 +        });
   1.227 +
   1.228 +        final AlertDialog dialog = editPrompt.create();
   1.229 +
   1.230 +        // Create our TextWatchers
   1.231 +        LocationTextWatcher locationTextWatcher = new LocationTextWatcher(dialog);
   1.232 +        KeywordTextWatcher keywordTextWatcher = new KeywordTextWatcher(dialog);
   1.233 +
   1.234 +        // Cross reference the TextWatchers
   1.235 +        locationTextWatcher.setPairedTextWatcher(keywordTextWatcher);
   1.236 +        keywordTextWatcher.setPairedTextWatcher(locationTextWatcher);
   1.237 +
   1.238 +        // Add the TextWatcher Listeners
   1.239 +        locationText.addTextChangedListener(locationTextWatcher);
   1.240 +        keywordText.addTextChangedListener(keywordTextWatcher);
   1.241 +
   1.242 +        dialog.show();
   1.243 +    }
   1.244 +}

mercurial