Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1062)

Side by Side Diff: content/public/android/java/src/org/chromium/content/browser/SelectActionModeCallback.java

Issue 10828098: Upstreaming Select Action (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Brett's nits fixed Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/public/android/java/src/org/chromium/content/browser/ImeAdapter.java ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
5 package org.chromium.content.browser;
6
7 import android.app.SearchManager;
8 import android.content.ClipboardManager;
9 import android.content.Context;
10 import android.content.Intent;
11 import android.content.pm.PackageManager;
12 import android.content.res.TypedArray;
13 import android.provider.Browser;
14 import android.text.TextUtils;
15 import android.view.ActionMode;
16 import android.view.Menu;
17 import android.view.MenuItem;
18
19 import org.chromium.content.app.AppResource;
20
21 /**
22 * An ActionMode.Callback for in-page selection. This class handles both the edi table and
23 * non-editable cases.
24 */
25 public class SelectActionModeCallback implements ActionMode.Callback {
26 private static final int SELECT_ALL_ATTR_INDEX = 0;
27 private static final int CUT_ATTR_INDEX = 1;
28 private static final int COPY_ATTR_INDEX = 2;
29 private static final int PASTE_ATTR_INDEX = 3;
30 private static final int[] ACTION_MODE_ATTRS = {
31 android.R.attr.actionModeSelectAllDrawable,
32 android.R.attr.actionModeCutDrawable,
33 android.R.attr.actionModeCopyDrawable,
34 android.R.attr.actionModePasteDrawable,
35 };
36
37 private static final int ID_SELECTALL = 0;
38 private static final int ID_COPY = 1;
39 private static final int ID_SHARE = 2;
40 private static final int ID_SEARCH = 3;
41 private static final int ID_CUT = 4;
42 private static final int ID_PASTE = 5;
43
44 /**
45 * An interface to retrieve information about the current selection, and als o to perform
46 * actions based on the selection or when the action bar is dismissed.
47 */
48 public interface ActionHandler {
49 /**
50 * Perform a select all action.
51 * @return true iff the action was successful.
52 */
53 boolean selectAll();
54
55 /**
56 * Perform a copy (to clipboard) action.
57 * @return true iff the action was successful.
58 */
59 boolean copy();
60
61 /**
62 * Perform a cut (to clipboard) action.
63 * @return true iff the action was successful.
64 */
65 boolean cut();
66
67 /**
68 * Perform a paste action.
69 * @return true iff the action was successful.
70 */
71 boolean paste();
72
73 /**
74 * @return true iff the current selection is editable (e.g. text within an input field).
75 */
76 boolean isSelectionEditable();
77
78 /**
79 * @return the currently selected text String.
80 */
81 String getSelectedText();
82
83 /**
84 * Called when the onDestroyActionMode of the SelectActionmodeCallback i s called.
85 */
86 void onDestroyActionMode();
87 }
88
89 private Context mContext;
90 private ActionHandler mActionHandler;
91 private final boolean mIncognito;
92 private boolean mEditable;
93
94 protected SelectActionModeCallback(
95 Context context, ActionHandler actionHandler, boolean incognito) {
96 mContext = context;
97 mActionHandler = actionHandler;
98 mIncognito = incognito;
99 }
100
101 protected Context getContext() {
102 return mContext;
103 }
104
105 @Override
106 public boolean onCreateActionMode(ActionMode mode, Menu menu) {
107 mode.setSubtitle(null);
108 mEditable = mActionHandler.isSelectionEditable();
109 createActionMenu(mode, menu);
110 return true;
111 }
112
113 @Override
114 public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
115 boolean isEditableNow = mActionHandler.isSelectionEditable();
116 if (mEditable != isEditableNow) {
117 mEditable = isEditableNow;
118 menu.clear();
119 createActionMenu(mode, menu);
120 return true;
121 }
122 return false;
123 }
124
125 private void createActionMenu(ActionMode mode, Menu menu) {
126 TypedArray styledAttributes = getContext().obtainStyledAttributes(ACTION _MODE_ATTRS);
127
128 menu.add(Menu.NONE, ID_SELECTALL, Menu.NONE, android.R.string.selectAll) .
129 setAlphabeticShortcut('a').
130 setIcon(styledAttributes.getResourceId(SELECT_ALL_ATTR_INDEX, 0)).
131 setShowAsAction(
132 MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WIT H_TEXT);
133
134 if (mEditable) {
135 menu.add(Menu.NONE, ID_CUT, Menu.NONE, android.R.string.cut).
136 setIcon(styledAttributes.getResourceId(CUT_ATTR_INDEX, 0)).
137 setAlphabeticShortcut('x').
138 setShowAsAction(
139 MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WIT H_TEXT);
140 }
141
142 menu.add(Menu.NONE, ID_COPY, Menu.NONE, android.R.string.copy).
143 setIcon(styledAttributes.getResourceId(COPY_ATTR_INDEX, 0)).
144 setAlphabeticShortcut('c').
145 setShowAsAction(
146 MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WIT H_TEXT);
147
148 if (mEditable && canPaste()) {
149 menu.add(Menu.NONE, ID_PASTE, Menu.NONE, android.R.string.paste).
150 setIcon(styledAttributes.getResourceId(PASTE_ATTR_INDEX, 0)).
151 setAlphabeticShortcut('v').
152 setShowAsAction(
153 MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION _WITH_TEXT);
154 }
155
156 if (!mEditable) {
157 if (isShareHandlerAvailable()) {
158 assert AppResource.STRING_ACTION_BAR_SHARE != 0;
159 assert AppResource.DRAWABLE_ICON_ACTION_BAR_SHARE != 0;
160 menu.add(Menu.NONE, ID_SHARE, Menu.NONE, AppResource.STRING_ACTI ON_BAR_SHARE).
161 setIcon(AppResource.DRAWABLE_ICON_ACTION_BAR_SHARE).
162 setShowAsAction(
163 MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_AC TION_WITH_TEXT);
164 }
165
166 if (!mIncognito && isWebSearchAvailable()) {
167 assert AppResource.STRING_ACTION_BAR_WEB_SEARCH != 0;
168 assert AppResource.DRAWABLE_ICON_ACTION_BAR_WEB_SEARCH != 0;
169 menu.add(Menu.NONE, ID_SEARCH, Menu.NONE,
170 AppResource.STRING_ACTION_BAR_WEB_SEARCH).
171 setIcon(AppResource.DRAWABLE_ICON_ACTION_BAR_WEB_SEARCH).
172 setShowAsAction(
173 MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_AC TION_WITH_TEXT);
174 }
175 }
176
177 styledAttributes.recycle();
178 }
179
180 @Override
181 public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
182 String selection = mActionHandler.getSelectedText();
183 switch(item.getItemId()) {
184 case ID_SELECTALL:
185 mActionHandler.selectAll();
186 break;
187 case ID_CUT:
188 mActionHandler.cut();
189 break;
190 case ID_COPY:
191 mActionHandler.copy();
192 mode.finish();
193 break;
194 case ID_PASTE:
195 mActionHandler.paste();
196 break;
197 case ID_SHARE:
198 if (!TextUtils.isEmpty(selection)) {
199 Intent send = new Intent(Intent.ACTION_SEND);
200 send.setType("text/plain");
201 send.putExtra(Intent.EXTRA_TEXT, selection);
202 try {
203 assert AppResource.STRING_ACTION_BAR_SHARE != 0;
204 Intent i = Intent.createChooser(send, getContext().getSt ring(
205 AppResource.STRING_ACTION_BAR_SHARE));
206 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
207 getContext().startActivity(i);
208 } catch (android.content.ActivityNotFoundException ex) {
209 // If no app handles it, do nothing.
210 }
211 }
212 mode.finish();
213 break;
214 case ID_SEARCH:
215 if (!TextUtils.isEmpty(selection)) {
216 Intent i = new Intent(Intent.ACTION_WEB_SEARCH);
217 i.putExtra(SearchManager.EXTRA_NEW_SEARCH, true);
218 i.putExtra(SearchManager.QUERY, selection);
219 i.putExtra(Browser.EXTRA_APPLICATION_ID, getContext().getPac kageName());
220 try {
221 getContext().startActivity(i);
222 } catch (android.content.ActivityNotFoundException ex) {
223 // If no app handles it, do nothing.
224 }
225 }
226 mode.finish();
227 break;
228 default:
229 return false;
230 }
231 return true;
232 }
233
234 @Override
235 public void onDestroyActionMode(ActionMode mode) {
236 mActionHandler.onDestroyActionMode();
237 }
238
239 private boolean canPaste() {
240 ClipboardManager clipMgr = (ClipboardManager)
241 getContext().getSystemService(Context.CLIPBOARD_SERVICE);
242 return clipMgr.hasPrimaryClip();
243 }
244
245 private boolean isShareHandlerAvailable() {
246 Intent intent = new Intent(Intent.ACTION_SEND);
247 intent.setType("text/plain");
248 return getContext().getPackageManager()
249 .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY ).size() > 0;
250 }
251
252 private boolean isWebSearchAvailable() {
253 Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
254 intent.putExtra(SearchManager.EXTRA_NEW_SEARCH, true);
255 return getContext().getPackageManager()
256 .queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY ).size() > 0;
257 }
258 }
OLDNEW
« no previous file with comments | « content/public/android/java/src/org/chromium/content/browser/ImeAdapter.java ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698