SelectActionModeCallback.java revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
1// Copyright (c) 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.app.Activity;
8import android.app.SearchManager;
9import android.content.ClipboardManager;
10import android.content.Context;
11import android.content.Intent;
12import android.content.pm.PackageManager;
13import android.provider.Browser;
14import android.text.TextUtils;
15import android.view.ActionMode;
16import android.view.Menu;
17import android.view.MenuItem;
18
19import org.chromium.content.R;
20
21/**
22 * An ActionMode.Callback for in-page selection. This class handles both the editable and
23 * non-editable cases.
24 */
25public class SelectActionModeCallback implements ActionMode.Callback {
26    /**
27     * An interface to retrieve information about the current selection, and also to perform
28     * actions based on the selection or when the action bar is dismissed.
29     */
30    public interface ActionHandler {
31        /**
32         * Perform a select all action.
33         */
34        void selectAll();
35
36        /**
37         * Perform a copy (to clipboard) action.
38         */
39        void copy();
40
41        /**
42         * Perform a cut (to clipboard) action.
43         */
44        void cut();
45
46        /**
47         * Perform a paste action.
48         */
49        void paste();
50
51        /**
52         * Perform a share action.
53         */
54        void share();
55
56        /**
57         * Perform a search action.
58         */
59        void search();
60
61        /**
62         * @return true iff the current selection is editable (e.g. text within an input field).
63         */
64        boolean isSelectionEditable();
65
66        /**
67         * Called when the onDestroyActionMode of the SelectActionmodeCallback is called.
68         */
69        void onDestroyActionMode();
70
71        /**
72         * @return Whether or not share is available.
73         */
74        boolean isShareAvailable();
75
76        /**
77         * @return Whether or not web search is available.
78         */
79        boolean isWebSearchAvailable();
80    }
81
82    private Context mContext;
83    private ActionHandler mActionHandler;
84    private final boolean mIncognito;
85    private boolean mEditable;
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        createActionMenu(mode, menu);
104        return true;
105    }
106
107    @Override
108    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
109        boolean isEditableNow = mActionHandler.isSelectionEditable();
110        if (mEditable != isEditableNow) {
111            mEditable = isEditableNow;
112            menu.clear();
113            createActionMenu(mode, menu);
114            return true;
115        }
116        return false;
117    }
118
119    private void createActionMenu(ActionMode mode, Menu menu) {
120        mode.getMenuInflater().inflate(R.menu.select_action_menu, menu);
121        if (!mEditable || !canPaste()) {
122            menu.removeItem(R.id.select_action_menu_paste);
123        }
124
125        if (!mEditable) {
126            menu.removeItem(R.id.select_action_menu_cut);
127        }
128
129        if (mEditable || !mActionHandler.isShareAvailable()) {
130            menu.removeItem(R.id.select_action_menu_share);
131        }
132
133        if (mEditable || mIncognito || !mActionHandler.isWebSearchAvailable()) {
134            menu.removeItem(R.id.select_action_menu_web_search);
135        }
136    }
137
138    @Override
139    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
140        int id = item.getItemId();
141
142        if (id == R.id.select_action_menu_select_all) {
143            mActionHandler.selectAll();
144        } else if (id == R.id.select_action_menu_cut) {
145            mActionHandler.cut();
146        } else if (id == R.id.select_action_menu_copy) {
147            mActionHandler.copy();
148            mode.finish();
149        } else if (id == R.id.select_action_menu_paste) {
150            mActionHandler.paste();
151        } else if (id == R.id.select_action_menu_share) {
152            mActionHandler.share();
153            mode.finish();
154        } else if (id == R.id.select_action_menu_web_search) {
155            mActionHandler.search();
156            mode.finish();
157        } else {
158            return false;
159        }
160        return true;
161    }
162
163    @Override
164    public void onDestroyActionMode(ActionMode mode) {
165        mActionHandler.onDestroyActionMode();
166    }
167
168    private boolean canPaste() {
169        ClipboardManager clipMgr = (ClipboardManager)
170                getContext().getSystemService(Context.CLIPBOARD_SERVICE);
171        return clipMgr.hasPrimaryClip();
172    }
173}
174