| // Copyright 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package org.chromium.content.browser; |
| |
| import android.content.ClipboardManager; |
| import android.content.Context; |
| import android.view.ActionMode; |
| import android.view.Menu; |
| import android.view.MenuItem; |
| |
| import org.chromium.content.R; |
| |
| /** |
| * An ActionMode.Callback for in-page selection. This class handles both the editable and |
| * non-editable cases. |
| */ |
| public class SelectActionModeCallback implements ActionMode.Callback { |
| /** |
| * An interface to retrieve information about the current selection, and also to perform |
| * actions based on the selection or when the action bar is dismissed. |
| */ |
| public interface ActionHandler { |
| /** |
| * Perform a select all action. |
| */ |
| void selectAll(); |
| |
| /** |
| * Perform a copy (to clipboard) action. |
| */ |
| void copy(); |
| |
| /** |
| * Perform a cut (to clipboard) action. |
| */ |
| void cut(); |
| |
| /** |
| * Perform a paste action. |
| */ |
| void paste(); |
| |
| /** |
| * Perform a share action. |
| */ |
| void share(); |
| |
| /** |
| * Perform a search action. |
| */ |
| void search(); |
| |
| /** |
| * @return true iff the current selection is editable (e.g. text within an input field). |
| */ |
| boolean isSelectionEditable(); |
| |
| /** |
| * Called when the onDestroyActionMode of the SelectActionmodeCallback is called. |
| */ |
| void onDestroyActionMode(); |
| |
| /** |
| * @return Whether or not share is available. |
| */ |
| boolean isShareAvailable(); |
| |
| /** |
| * @return Whether or not web search is available. |
| */ |
| boolean isWebSearchAvailable(); |
| |
| /** |
| * @return true if the current selection is of password type. |
| */ |
| boolean isSelectionPassword(); |
| } |
| |
| private final Context mContext; |
| private final ActionHandler mActionHandler; |
| private final boolean mIncognito; |
| private boolean mEditable; |
| private boolean mIsPasswordType; |
| |
| protected SelectActionModeCallback( |
| Context context, ActionHandler actionHandler, boolean incognito) { |
| mContext = context; |
| mActionHandler = actionHandler; |
| mIncognito = incognito; |
| } |
| |
| protected Context getContext() { |
| return mContext; |
| } |
| |
| @Override |
| public boolean onCreateActionMode(ActionMode mode, Menu menu) { |
| mode.setTitle(null); |
| mode.setSubtitle(null); |
| mEditable = mActionHandler.isSelectionEditable(); |
| mIsPasswordType = mActionHandler.isSelectionPassword(); |
| createActionMenu(mode, menu); |
| return true; |
| } |
| |
| @Override |
| public boolean onPrepareActionMode(ActionMode mode, Menu menu) { |
| boolean isEditableNow = mActionHandler.isSelectionEditable(); |
| boolean isPasswordNow = mActionHandler.isSelectionPassword(); |
| if (mEditable != isEditableNow || mIsPasswordType != isPasswordNow) { |
| mEditable = isEditableNow; |
| mIsPasswordType = isPasswordNow; |
| menu.clear(); |
| createActionMenu(mode, menu); |
| return true; |
| } |
| return false; |
| } |
| |
| private void createActionMenu(ActionMode mode, Menu menu) { |
| mode.getMenuInflater().inflate(R.menu.select_action_menu, menu); |
| if (!mEditable || !canPaste()) { |
| menu.removeItem(R.id.select_action_menu_paste); |
| } |
| |
| if (!mEditable) { |
| menu.removeItem(R.id.select_action_menu_cut); |
| } |
| |
| if (mEditable || !mActionHandler.isShareAvailable()) { |
| menu.removeItem(R.id.select_action_menu_share); |
| } |
| |
| if (mEditable || mIncognito || !mActionHandler.isWebSearchAvailable()) { |
| menu.removeItem(R.id.select_action_menu_web_search); |
| } |
| if (mIsPasswordType) { |
| menu.removeItem(R.id.select_action_menu_copy); |
| menu.removeItem(R.id.select_action_menu_cut); |
| } |
| } |
| |
| @Override |
| public boolean onActionItemClicked(ActionMode mode, MenuItem item) { |
| int id = item.getItemId(); |
| |
| if (id == R.id.select_action_menu_select_all) { |
| mActionHandler.selectAll(); |
| } else if (id == R.id.select_action_menu_cut) { |
| mActionHandler.cut(); |
| } else if (id == R.id.select_action_menu_copy) { |
| mActionHandler.copy(); |
| mode.finish(); |
| } else if (id == R.id.select_action_menu_paste) { |
| mActionHandler.paste(); |
| } else if (id == R.id.select_action_menu_share) { |
| mActionHandler.share(); |
| mode.finish(); |
| } else if (id == R.id.select_action_menu_web_search) { |
| mActionHandler.search(); |
| mode.finish(); |
| } else { |
| return false; |
| } |
| return true; |
| } |
| |
| @Override |
| public void onDestroyActionMode(ActionMode mode) { |
| mActionHandler.onDestroyActionMode(); |
| } |
| |
| private boolean canPaste() { |
| ClipboardManager clipMgr = (ClipboardManager) |
| getContext().getSystemService(Context.CLIPBOARD_SERVICE); |
| return clipMgr.hasPrimaryClip(); |
| } |
| } |