1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.view.menu; 18 19 import java.util.ArrayList; 20 import java.util.List; 21 22 import android.content.ComponentName; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.content.pm.PackageManager; 26 import android.content.pm.ResolveInfo; 27 import android.view.KeyEvent; 28 import android.view.Menu; 29 import android.view.MenuItem; 30 import android.view.SubMenu; 31 32 /** 33 * @hide 34 */ 35 public class ActionMenu implements Menu { 36 private Context mContext; 37 38 private boolean mIsQwerty; 39 40 private ArrayList<ActionMenuItem> mItems; 41 42 public ActionMenu(Context context) { 43 mContext = context; 44 mItems = new ArrayList<ActionMenuItem>(); 45 } 46 47 public Context getContext() { 48 return mContext; 49 } 50 51 public MenuItem add(CharSequence title) { 52 return add(0, 0, 0, title); 53 } 54 55 public MenuItem add(int titleRes) { 56 return add(0, 0, 0, titleRes); 57 } 58 59 public MenuItem add(int groupId, int itemId, int order, int titleRes) { 60 return add(groupId, itemId, order, mContext.getResources().getString(titleRes)); 61 } 62 63 public MenuItem add(int groupId, int itemId, int order, CharSequence title) { 64 ActionMenuItem item = new ActionMenuItem(getContext(), 65 groupId, itemId, 0, order, title); 66 mItems.add(order, item); 67 return item; 68 } 69 70 public int addIntentOptions(int groupId, int itemId, int order, 71 ComponentName caller, Intent[] specifics, Intent intent, int flags, 72 MenuItem[] outSpecificItems) { 73 PackageManager pm = mContext.getPackageManager(); 74 final List<ResolveInfo> lri = 75 pm.queryIntentActivityOptions(caller, specifics, intent, 0); 76 final int N = lri != null ? lri.size() : 0; 77 78 if ((flags & FLAG_APPEND_TO_GROUP) == 0) { 79 removeGroup(groupId); 80 } 81 82 for (int i=0; i<N; i++) { 83 final ResolveInfo ri = lri.get(i); 84 Intent rintent = new Intent( 85 ri.specificIndex < 0 ? intent : specifics[ri.specificIndex]); 86 rintent.setComponent(new ComponentName( 87 ri.activityInfo.applicationInfo.packageName, 88 ri.activityInfo.name)); 89 final MenuItem item = add(groupId, itemId, order, ri.loadLabel(pm)) 90 .setIcon(ri.loadIcon(pm)) 91 .setIntent(rintent); 92 if (outSpecificItems != null && ri.specificIndex >= 0) { 93 outSpecificItems[ri.specificIndex] = item; 94 } 95 } 96 97 return N; 98 } 99 100 public SubMenu addSubMenu(CharSequence title) { 101 // TODO Implement submenus 102 return null; 103 } 104 105 public SubMenu addSubMenu(int titleRes) { 106 // TODO Implement submenus 107 return null; 108 } 109 110 public SubMenu addSubMenu(int groupId, int itemId, int order, 111 CharSequence title) { 112 // TODO Implement submenus 113 return null; 114 } 115 116 public SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes) { 117 // TODO Implement submenus 118 return null; 119 } 120 121 public void clear() { 122 mItems.clear(); 123 } 124 125 public void close() { 126 } 127 128 private int findItemIndex(int id) { 129 final ArrayList<ActionMenuItem> items = mItems; 130 final int itemCount = items.size(); 131 for (int i = 0; i < itemCount; i++) { 132 if (items.get(i).getItemId() == id) { 133 return i; 134 } 135 } 136 137 return -1; 138 } 139 140 public MenuItem findItem(int id) { 141 return mItems.get(findItemIndex(id)); 142 } 143 144 public MenuItem getItem(int index) { 145 return mItems.get(index); 146 } 147 148 public boolean hasVisibleItems() { 149 final ArrayList<ActionMenuItem> items = mItems; 150 final int itemCount = items.size(); 151 152 for (int i = 0; i < itemCount; i++) { 153 if (items.get(i).isVisible()) { 154 return true; 155 } 156 } 157 158 return false; 159 } 160 161 private ActionMenuItem findItemWithShortcut(int keyCode, KeyEvent event) { 162 // TODO Make this smarter. 163 final boolean qwerty = mIsQwerty; 164 final ArrayList<ActionMenuItem> items = mItems; 165 final int itemCount = items.size(); 166 final int modifierState = event.getModifiers(); 167 for (int i = 0; i < itemCount; i++) { 168 ActionMenuItem item = items.get(i); 169 final char shortcut = qwerty ? item.getAlphabeticShortcut() : 170 item.getNumericShortcut(); 171 final int shortcutModifiers = 172 qwerty ? item.getAlphabeticModifiers() : item.getNumericModifiers(); 173 final boolean is_modifiers_exact_match = (modifierState & SUPPORTED_MODIFIERS_MASK) 174 == (shortcutModifiers & SUPPORTED_MODIFIERS_MASK); 175 if ((keyCode == shortcut) && is_modifiers_exact_match) { 176 return item; 177 } 178 } 179 return null; 180 } 181 182 public boolean isShortcutKey(int keyCode, KeyEvent event) { 183 return findItemWithShortcut(keyCode, event) != null; 184 } 185 186 public boolean performIdentifierAction(int id, int flags) { 187 final int index = findItemIndex(id); 188 if (index < 0) { 189 return false; 190 } 191 192 return mItems.get(index).invoke(); 193 } 194 195 public boolean performShortcut(int keyCode, KeyEvent event, int flags) { 196 ActionMenuItem item = findItemWithShortcut(keyCode, event); 197 if (item == null) { 198 return false; 199 } 200 201 return item.invoke(); 202 } 203 204 public void removeGroup(int groupId) { 205 final ArrayList<ActionMenuItem> items = mItems; 206 int itemCount = items.size(); 207 int i = 0; 208 while (i < itemCount) { 209 if (items.get(i).getGroupId() == groupId) { 210 items.remove(i); 211 itemCount--; 212 } else { 213 i++; 214 } 215 } 216 } 217 218 public void removeItem(int id) { 219 mItems.remove(findItemIndex(id)); 220 } 221 222 public void setGroupCheckable(int group, boolean checkable, 223 boolean exclusive) { 224 final ArrayList<ActionMenuItem> items = mItems; 225 final int itemCount = items.size(); 226 227 for (int i = 0; i < itemCount; i++) { 228 ActionMenuItem item = items.get(i); 229 if (item.getGroupId() == group) { 230 item.setCheckable(checkable); 231 item.setExclusiveCheckable(exclusive); 232 } 233 } 234 } 235 236 public void setGroupEnabled(int group, boolean enabled) { 237 final ArrayList<ActionMenuItem> items = mItems; 238 final int itemCount = items.size(); 239 240 for (int i = 0; i < itemCount; i++) { 241 ActionMenuItem item = items.get(i); 242 if (item.getGroupId() == group) { 243 item.setEnabled(enabled); 244 } 245 } 246 } 247 248 public void setGroupVisible(int group, boolean visible) { 249 final ArrayList<ActionMenuItem> items = mItems; 250 final int itemCount = items.size(); 251 252 for (int i = 0; i < itemCount; i++) { 253 ActionMenuItem item = items.get(i); 254 if (item.getGroupId() == group) { 255 item.setVisible(visible); 256 } 257 } 258 } 259 260 public void setQwertyMode(boolean isQwerty) { 261 mIsQwerty = isQwerty; 262 } 263 264 public int size() { 265 return mItems.size(); 266 } 267 } 268