SelectActionModeCallback.java revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1// Copyright 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.content.browser;
6
7import android.content.ClipboardManager;
8import android.content.Context;
9import android.view.ActionMode;
10import android.view.Menu;
11import android.view.MenuItem;
12
13import org.chromium.content.R;
14
15/**
16 * An ActionMode.Callback for in-page selection. This class handles both the editable and
17 * non-editable cases.
18 */
19public class SelectActionModeCallback implements ActionMode.Callback {
20    /**
21     * An interface to retrieve information about the current selection, and also to perform
22     * actions based on the selection or when the action bar is dismissed.
23     */
24    public interface ActionHandler {
25        /**
26         * Perform a select all action.
27         */
28        void selectAll();
29
30        /**
31         * Perform a copy (to clipboard) action.
32         */
33        void copy();
34
35        /**
36         * Perform a cut (to clipboard) action.
37         */
38        void cut();
39
40        /**
41         * Perform a paste action.
42         */
43        void paste();
44
45        /**
46         * Perform a share action.
47         */
48        void share();
49
50        /**
51         * Perform a search action.
52         */
53        void search();
54
55        /**
56         * @return true iff the current selection is editable (e.g. text within an input field).
57         */
58        boolean isSelectionEditable();
59
60        /**
61         * Called when the onDestroyActionMode of the SelectActionmodeCallback is called.
62         */
63        void onDestroyActionMode();
64
65        /**
66         * @return Whether or not share is available.
67         */
68        boolean isShareAvailable();
69
70        /**
71         * @return Whether or not web search is available.
72         */
73        boolean isWebSearchAvailable();
74
75        /**
76         * @return true if the current selection is of password type.
77         */
78        boolean isSelectionPassword();
79    }
80
81    private final Context mContext;
82    private final ActionHandler mActionHandler;
83    private final boolean mIncognito;
84    private boolean mEditable;
85    private boolean mIsPasswordType;
86
87    protected SelectActionModeCallback(
88            Context context, ActionHandler actionHandler, boolean incognito) {
89        mContext = context;
90        mActionHandler = actionHandler;
91        mIncognito = incognito;
92    }
93
94    protected Context getContext() {
95        return mContext;
96    }
97
98    @Override
99    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
100        mode.setTitle(null);
101        mode.setSubtitle(null);
102        mEditable = mActionHandler.isSelectionEditable();
103        mIsPasswordType = mActionHandler.isSelectionPassword();
104        createActionMenu(mode, menu);
105        return true;
106    }
107
108    @Override
109    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
110        boolean isEditableNow = mActionHandler.isSelectionEditable();
111        boolean isPasswordNow = mActionHandler.isSelectionPassword();
112        if (mEditable != isEditableNow || mIsPasswordType != isPasswordNow) {
113            mEditable = isEditableNow;
114            mIsPasswordType = isPasswordNow;
115            menu.clear();
116            createActionMenu(mode, menu);
117            return true;
118        }
119        return false;
120    }
121
122    private void createActionMenu(ActionMode mode, Menu menu) {
123        mode.getMenuInflater().inflate(R.menu.select_action_menu, menu);
124        if (!mEditable || !canPaste()) {
125            menu.removeItem(R.id.select_action_menu_paste);
126        }
127
128        if (!mEditable) {
129            menu.removeItem(R.id.select_action_menu_cut);
130        }
131
132        if (mEditable || !mActionHandler.isShareAvailable()) {
133            menu.removeItem(R.id.select_action_menu_share);
134        }
135
136        if (mEditable || mIncognito || !mActionHandler.isWebSearchAvailable()) {
137            menu.removeItem(R.id.select_action_menu_web_search);
138        }
139        if (mIsPasswordType) {
140            menu.removeItem(R.id.select_action_menu_copy);
141            menu.removeItem(R.id.select_action_menu_cut);
142        }
143    }
144
145    @Override
146    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
147        int id = item.getItemId();
148
149        if (id == R.id.select_action_menu_select_all) {
150            mActionHandler.selectAll();
151        } else if (id == R.id.select_action_menu_cut) {
152            mActionHandler.cut();
153        } else if (id == R.id.select_action_menu_copy) {
154            mActionHandler.copy();
155            mode.finish();
156        } else if (id == R.id.select_action_menu_paste) {
157            mActionHandler.paste();
158        } else if (id == R.id.select_action_menu_share) {
159            mActionHandler.share();
160            mode.finish();
161        } else if (id == R.id.select_action_menu_web_search) {
162            mActionHandler.search();
163            mode.finish();
164        } else {
165            return false;
166        }
167        return true;
168    }
169
170    @Override
171    public void onDestroyActionMode(ActionMode mode) {
172        mActionHandler.onDestroyActionMode();
173    }
174
175    private boolean canPaste() {
176        ClipboardManager clipMgr = (ClipboardManager)
177                getContext().getSystemService(Context.CLIPBOARD_SERVICE);
178        return clipMgr.hasPrimaryClip();
179    }
180}
181