• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
5 package org.chromium.content.browser;
6 
7 import android.content.ClipboardManager;
8 import android.content.Context;
9 import android.view.ActionMode;
10 import android.view.Menu;
11 import android.view.MenuItem;
12 
13 import 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  */
19 public 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          */
selectAll()28         void selectAll();
29 
30         /**
31          * Perform a copy (to clipboard) action.
32          */
copy()33         void copy();
34 
35         /**
36          * Perform a cut (to clipboard) action.
37          */
cut()38         void cut();
39 
40         /**
41          * Perform a paste action.
42          */
paste()43         void paste();
44 
45         /**
46          * Perform a share action.
47          */
share()48         void share();
49 
50         /**
51          * Perform a search action.
52          */
search()53         void search();
54 
55         /**
56          * @return true iff the current selection is editable (e.g. text within an input field).
57          */
isSelectionEditable()58         boolean isSelectionEditable();
59 
60         /**
61          * Called when the onDestroyActionMode of the SelectActionmodeCallback is called.
62          */
onDestroyActionMode()63         void onDestroyActionMode();
64 
65         /**
66          * @return Whether or not share is available.
67          */
isShareAvailable()68         boolean isShareAvailable();
69 
70         /**
71          * @return Whether or not web search is available.
72          */
isWebSearchAvailable()73         boolean isWebSearchAvailable();
74 
75         /**
76          * @return true if the current selection is of password type.
77          */
isSelectionPassword()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 
SelectActionModeCallback( Context context, ActionHandler actionHandler, boolean incognito)87     protected SelectActionModeCallback(
88             Context context, ActionHandler actionHandler, boolean incognito) {
89         mContext = context;
90         mActionHandler = actionHandler;
91         mIncognito = incognito;
92     }
93 
getContext()94     protected Context getContext() {
95         return mContext;
96     }
97 
98     @Override
onCreateActionMode(ActionMode mode, Menu menu)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
onPrepareActionMode(ActionMode mode, Menu menu)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 
createActionMenu(ActionMode mode, Menu menu)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
onActionItemClicked(ActionMode mode, MenuItem item)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
onDestroyActionMode(ActionMode mode)171     public void onDestroyActionMode(ActionMode mode) {
172         mActionHandler.onDestroyActionMode();
173     }
174 
canPaste()175     private boolean canPaste() {
176         ClipboardManager clipMgr = (ClipboardManager)
177                 getContext().getSystemService(Context.CLIPBOARD_SERVICE);
178         return clipMgr.hasPrimaryClip();
179     }
180 }
181