1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)package org.chromium.content.browser;
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.ClipboardManager;
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.content.Context;
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.view.ActionMode;
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.view.Menu;
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import android.view.MenuItem;
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import org.chromium.content.R;
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * An ActionMode.Callback for in-page selection. This class handles both the editable and
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * non-editable cases.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public class SelectActionModeCallback implements ActionMode.Callback {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /**
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * An interface to retrieve information about the current selection, and also to perform
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * actions based on the selection or when the action bar is dismissed.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public interface ActionHandler {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /**
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * Perform a select all action.
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        void selectAll();
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /**
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * Perform a copy (to clipboard) action.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        void copy();
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /**
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * Perform a cut (to clipboard) action.
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        void cut();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /**
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * Perform a paste action.
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        void paste();
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /**
4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         * Perform a share action.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        void share();
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /**
5158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         * Perform a search action.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        void search();
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        /**
5658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         * @return true iff the current selection is editable (e.g. text within an input field).
5758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         */
5858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        boolean isSelectionEditable();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /**
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         * Called when the onDestroyActionMode of the SelectActionmodeCallback is called.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         */
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        void onDestroyActionMode();
6458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        /**
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         * @return Whether or not share is available.
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         */
6858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        boolean isShareAvailable();
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        /**
7158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         * @return Whether or not web search is available.
7258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)         */
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        boolean isWebSearchAvailable();
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        /**
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         * @return true if the current selection is of password type.
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)         */
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        boolean isSelectionPassword();
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    private final Context mContext;
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    private final ActionHandler mActionHandler;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private final boolean mIncognito;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private boolean mEditable;
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    private boolean mIsPasswordType;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    protected SelectActionModeCallback(
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            Context context, ActionHandler actionHandler, boolean incognito) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mContext = context;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mActionHandler = actionHandler;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mIncognito = incognito;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    protected Context getContext() {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return mContext;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Override
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
100bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch        mode.setTitle(null);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mode.setSubtitle(null);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mEditable = mActionHandler.isSelectionEditable();
103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        mIsPasswordType = mActionHandler.isSelectionPassword();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        createActionMenu(mode, menu);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Override
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        boolean isEditableNow = mActionHandler.isSelectionEditable();
111cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        boolean isPasswordNow = mActionHandler.isSelectionPassword();
112cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (mEditable != isEditableNow || mIsPasswordType != isPasswordNow) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            mEditable = isEditableNow;
114cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            mIsPasswordType = isPasswordNow;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            menu.clear();
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            createActionMenu(mode, menu);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            return true;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private void createActionMenu(ActionMode mode, Menu menu) {
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        mode.getMenuInflater().inflate(R.menu.select_action_menu, menu);
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        if (!mEditable || !canPaste()) {
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            menu.removeItem(R.id.select_action_menu_paste);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        if (!mEditable) {
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            menu.removeItem(R.id.select_action_menu_cut);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        if (mEditable || !mActionHandler.isShareAvailable()) {
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            menu.removeItem(R.id.select_action_menu_share);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        if (mEditable || mIncognito || !mActionHandler.isWebSearchAvailable()) {
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            menu.removeItem(R.id.select_action_menu_web_search);
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        }
139cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (mIsPasswordType) {
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            menu.removeItem(R.id.select_action_menu_copy);
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            menu.removeItem(R.id.select_action_menu_cut);
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Override
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        int id = item.getItemId();
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        if (id == R.id.select_action_menu_select_all) {
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            mActionHandler.selectAll();
1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        } else if (id == R.id.select_action_menu_cut) {
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            mActionHandler.cut();
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            mode.finish();
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        } else if (id == R.id.select_action_menu_copy) {
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            mActionHandler.copy();
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            mode.finish();
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        } else if (id == R.id.select_action_menu_paste) {
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            mActionHandler.paste();
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            mode.finish();
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        } else if (id == R.id.select_action_menu_share) {
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            mActionHandler.share();
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            mode.finish();
1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        } else if (id == R.id.select_action_menu_web_search) {
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            mActionHandler.search();
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            mode.finish();
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        } else {
1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            return false;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    @Override
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    public void onDestroyActionMode(ActionMode mode) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        mActionHandler.onDestroyActionMode();
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    private boolean canPaste() {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ClipboardManager clipMgr = (ClipboardManager)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                getContext().getSystemService(Context.CLIPBOARD_SERVICE);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return clipMgr.hasPrimaryClip();
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
183