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 127b98a81f86ab87f1d718f329f03256111fdabd8d1Adam Powell public boolean isTitleOptional() { 128b98a81f86ab87f1d718f329f03256111fdabd8d1Adam Powell // Not only is it optional, it will *never* be shown. 129b98a81f86ab87f1d718f329f03256111fdabd8d1Adam Powell return true; 130b98a81f86ab87f1d718f329f03256111fdabd8d1Adam Powell } 131b98a81f86ab87f1d718f329f03256111fdabd8d1Adam Powell 132b98a81f86ab87f1d718f329f03256111fdabd8d1Adam Powell @Override 1335ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell public void setCustomView(View view) { 1345ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell // Custom view is not supported here. 1355ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } 1365ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell 1375ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell @Override 1385ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell public void invalidate() { 1395ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell mMenu.stopDispatchingItemsChanged(); 1405ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell try { 1415ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell mCallback.onPrepareActionMode(this, mMenu); 1425ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } finally { 1435ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell mMenu.startDispatchingItemsChanged(); 1445ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } 1455ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } 1465ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell 1475ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell public boolean dispatchOnCreate() { 1485ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell mMenu.stopDispatchingItemsChanged(); 1495ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell try { 1505ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell return mCallback.onCreateActionMode(this, mMenu); 1515ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } finally { 1525ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell mMenu.startDispatchingItemsChanged(); 1535ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } 1545ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } 1555ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell 1565ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell @Override 1575ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell public void finish() { 1585ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell if (mActionMode != this) { 1595ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell // Not the active action mode - no-op 1605ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell return; 1615ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } 1625ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell 1635ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell mCallback.onDestroyActionMode(this); 1645ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell mCallback = null; 1655ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell 1665ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell mExtractActionButton.setVisibility(VISIBLE); 1675ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell mEditButton.setVisibility(INVISIBLE); 1685ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell 16986ed436b83d6b71ff00d1c3db910f2952018489eAdam Powell sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 17086ed436b83d6b71ff00d1c3db910f2952018489eAdam Powell 1715ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell mActionMode = null; 1725ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } 1735ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell 1745ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell @Override 1755ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell public Menu getMenu() { 1765ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell return mMenu; 1775ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } 1785ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell 1795ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell @Override 1805ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell public CharSequence getTitle() { 1815ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell return null; 1825ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } 1835ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell 1845ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell @Override 1855ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell public CharSequence getSubtitle() { 1865ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell return null; 1875ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } 1885ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell 1895ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell @Override 1905ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell public View getCustomView() { 1915ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell return null; 1925ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } 1935ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell 1945ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell @Override 1955ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell public MenuInflater getMenuInflater() { 1965ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell return new MenuInflater(getContext()); 1975ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } 1985ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell 1995ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell @Override 2005ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { 201d06caed8d6a53294fe5a0fa2c7e9e394d541ed64Adam Powell if (mCallback != null) { 202d06caed8d6a53294fe5a0fa2c7e9e394d541ed64Adam Powell return mCallback.onActionItemClicked(this, item); 203d06caed8d6a53294fe5a0fa2c7e9e394d541ed64Adam Powell } 204d06caed8d6a53294fe5a0fa2c7e9e394d541ed64Adam Powell return false; 2055ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } 2065ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell 2075ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell @Override 2085ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell public void onMenuModeChange(MenuBuilder menu) { 2095ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } 2105ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell 2115ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell } 2125ee36c48be8d36c5f4025202e8ede561c9ad3abaAdam Powell} 213