15ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell/*
25ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell * Copyright (C) 2011 The Android Open Source Project
35ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell *
45ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell * Licensed under the Apache License, Version 2.0 (the "License");
55ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell * you may not use this file except in compliance with the License.
65ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell * You may obtain a copy of the License at
75ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell *
85ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell *      http://www.apache.org/licenses/LICENSE-2.0
95ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell *
105ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell * Unless required by applicable law or agreed to in writing, software
115ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell * distributed under the License is distributed on an "AS IS" BASIS,
125ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell * See the License for the specific language governing permissions and
145ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell * limitations under the License.
155ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell */
165ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
175ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powellpackage android.inputmethodservice;
185ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1986ed436b83d6b71ff00d1c3db910f2952018489eAdam Powellimport com.android.internal.view.menu.MenuBuilder;
2086ed436b83d6b71ff00d1c3db910f2952018489eAdam Powellimport com.android.internal.view.menu.MenuPopupHelper;
2186ed436b83d6b71ff00d1c3db910f2952018489eAdam Powell
225ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powellimport android.content.Context;
235ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powellimport android.util.AttributeSet;
245ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powellimport android.view.ActionMode;
255ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powellimport android.view.Menu;
265ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powellimport android.view.MenuInflater;
275ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powellimport android.view.MenuItem;
285ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powellimport android.view.View;
2986ed436b83d6b71ff00d1c3db910f2952018489eAdam Powellimport android.view.accessibility.AccessibilityEvent;
305ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powellimport android.widget.Button;
315ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powellimport android.widget.LinearLayout;
325ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
335ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell/**
345ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell * ExtractEditLayout provides an ActionMode presentation for the
355ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell * limited screen real estate in extract mode.
365ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell *
375ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell * @hide
385ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell */
395ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powellpublic class ExtractEditLayout extends LinearLayout {
405ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell    ExtractActionMode mActionMode;
415ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell    Button mExtractActionButton;
425ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell    Button mEditButton;
435ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
445ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell    public ExtractEditLayout(Context context) {
455ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        super(context);
465ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell    }
475ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
485ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell    public ExtractEditLayout(Context context, AttributeSet attrs) {
495ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        super(context, attrs);
505ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell    }
515ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
525ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell    @Override
535ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell    public ActionMode startActionModeForChild(View sourceView, ActionMode.Callback cb) {
545ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        final ExtractActionMode mode = new ExtractActionMode(cb);
555ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        if (mode.dispatchOnCreate()) {
565ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            mode.invalidate();
575ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            mExtractActionButton.setVisibility(INVISIBLE);
585ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            mEditButton.setVisibility(VISIBLE);
595ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            mActionMode = mode;
6086ed436b83d6b71ff00d1c3db910f2952018489eAdam Powell            sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
615ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            return mode;
625ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
635ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        return null;
645ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell    }
655ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
6634703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne    /**
6734703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne     * @return true if an action mode is currently active.
6834703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne     */
6934703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne    public boolean isActionModeStarted() {
7034703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne        return mActionMode != null;
7134703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne    }
7234703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne
7334703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne    /**
7434703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne     * Finishes a possibly started action mode.
7534703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne     */
7634703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne    public void finishActionMode() {
7734703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne        if (mActionMode != null) {
7834703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne            mActionMode.finish();
7934703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne        }
8034703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne    }
8134703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne
825ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell    @Override
835ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell    public void onFinishInflate() {
845ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        super.onFinishInflate();
855ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        mExtractActionButton = (Button) findViewById(com.android.internal.R.id.inputExtractAction);
865ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        mEditButton = (Button) findViewById(com.android.internal.R.id.inputExtractEditButton);
875ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        mEditButton.setOnClickListener(new OnClickListener() {
885ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            public void onClick(View clicked) {
895ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell                if (mActionMode != null) {
905ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell                    new MenuPopupHelper(getContext(), mActionMode.mMenu, clicked).show();
915ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell                }
925ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            }
935ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        });
945ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell    }
955ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
965ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell    private class ExtractActionMode extends ActionMode implements MenuBuilder.Callback {
975ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        private ActionMode.Callback mCallback;
985ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        MenuBuilder mMenu;
995ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1005ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        public ExtractActionMode(Callback cb) {
1015ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            mMenu = new MenuBuilder(getContext());
1025ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            mMenu.setCallback(this);
1035ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            mCallback = cb;
1045ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
1055ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1065ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        @Override
1075ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        public void setTitle(CharSequence title) {
1085ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            // Title will not be shown.
1095ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
1105ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1115ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        @Override
1125ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        public void setTitle(int resId) {
11334703b6d304c2bc6f4a39583931c7582d0455b0cGilles Debunne            // Title will not be shown.
1145ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
1155ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1165ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        @Override
1175ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        public void setSubtitle(CharSequence subtitle) {
1185ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            // Subtitle will not be shown.
1195ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
1205ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1215ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        @Override
1225ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        public void setSubtitle(int resId) {
1235ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            // Subtitle will not be shown.
1245ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
1255ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1265ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        @Override
1275ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        public void setCustomView(View view) {
1285ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            // Custom view is not supported here.
1295ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
1305ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1315ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        @Override
1325ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        public void invalidate() {
1335ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            mMenu.stopDispatchingItemsChanged();
1345ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            try {
1355ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell                mCallback.onPrepareActionMode(this, mMenu);
1365ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            } finally {
1375ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell                mMenu.startDispatchingItemsChanged();
1385ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            }
1395ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
1405ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1415ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        public boolean dispatchOnCreate() {
1425ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            mMenu.stopDispatchingItemsChanged();
1435ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            try {
1445ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell                return mCallback.onCreateActionMode(this, mMenu);
1455ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            } finally {
1465ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell                mMenu.startDispatchingItemsChanged();
1475ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            }
1485ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
1495ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1505ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        @Override
1515ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        public void finish() {
1525ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            if (mActionMode != this) {
1535ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell                // Not the active action mode - no-op
1545ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell                return;
1555ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            }
1565ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1575ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            mCallback.onDestroyActionMode(this);
1585ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            mCallback = null;
1595ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1605ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            mExtractActionButton.setVisibility(VISIBLE);
1615ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            mEditButton.setVisibility(INVISIBLE);
1625ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
16386ed436b83d6b71ff00d1c3db910f2952018489eAdam Powell            sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
16486ed436b83d6b71ff00d1c3db910f2952018489eAdam Powell
1655ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            mActionMode = null;
1665ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
1675ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1685ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        @Override
1695ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        public Menu getMenu() {
1705ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            return mMenu;
1715ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
1725ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1735ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        @Override
1745ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        public CharSequence getTitle() {
1755ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            return null;
1765ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
1775ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1785ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        @Override
1795ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        public CharSequence getSubtitle() {
1805ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            return null;
1815ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
1825ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1835ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        @Override
1845ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        public View getCustomView() {
1855ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            return null;
1865ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
1875ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1885ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        @Override
1895ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        public MenuInflater getMenuInflater() {
1905ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell            return new MenuInflater(getContext());
1915ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
1925ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
1935ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        @Override
1945ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) {
195d06caed8d6a53294fe5a0fa2c7e9e394d541ed64Adam Powell            if (mCallback != null) {
196d06caed8d6a53294fe5a0fa2c7e9e394d541ed64Adam Powell                return mCallback.onActionItemClicked(this, item);
197d06caed8d6a53294fe5a0fa2c7e9e394d541ed64Adam Powell            }
198d06caed8d6a53294fe5a0fa2c7e9e394d541ed64Adam Powell            return false;
1995ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
2005ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
2015ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        @Override
2025ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        public void onMenuModeChange(MenuBuilder menu) {
2035ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell        }
2045ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell
2055ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell    }
2065ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell}
207