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