launcher_context_menu.cc revision 4e180b6a0b4720a9b8e9e959a882386f690f08ff
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/ui/ash/launcher/launcher_context_menu.h" 6 7#include <string> 8 9#include "ash/desktop_background/user_wallpaper_delegate.h" 10#include "ash/root_window_controller.h" 11#include "ash/shelf/shelf_widget.h" 12#include "ash/shell.h" 13#include "ash/shell_delegate.h" 14#include "base/bind.h" 15#include "base/command_line.h" 16#include "base/prefs/pref_service.h" 17#include "chrome/browser/extensions/context_menu_matcher.h" 18#include "chrome/browser/extensions/extension_prefs.h" 19#include "chrome/browser/fullscreen.h" 20#include "chrome/browser/prefs/incognito_mode_prefs.h" 21#include "chrome/browser/profiles/profile.h" 22#include "chrome/browser/ui/ash/chrome_shell_delegate.h" 23#include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h" 24#include "chrome/common/chrome_switches.h" 25#include "content/public/common/context_menu_params.h" 26#include "grit/ash_strings.h" 27#include "grit/generated_resources.h" 28#include "ui/base/l10n/l10n_util.h" 29 30namespace { 31 32bool MenuItemHasLauncherContext(const extensions::MenuItem* item) { 33 return item->contexts().Contains(extensions::MenuItem::LAUNCHER); 34} 35 36} // namespace 37 38LauncherContextMenu::LauncherContextMenu(ChromeLauncherController* controller, 39 const ash::LauncherItem* item, 40 aura::RootWindow* root) 41 : ui::SimpleMenuModel(NULL), 42 controller_(controller), 43 item_(*item), 44 shelf_alignment_menu_(root), 45 root_window_(root) { 46 DCHECK(item); 47 DCHECK(root_window_); 48 Init(); 49} 50 51LauncherContextMenu::LauncherContextMenu(ChromeLauncherController* controller, 52 aura::RootWindow* root) 53 : ui::SimpleMenuModel(NULL), 54 controller_(controller), 55 item_(ash::LauncherItem()), 56 shelf_alignment_menu_(root), 57 extension_items_(new extensions::ContextMenuMatcher( 58 controller->profile(), this, this, 59 base::Bind(MenuItemHasLauncherContext))), 60 root_window_(root) { 61 DCHECK(root_window_); 62 Init(); 63} 64 65void LauncherContextMenu::Init() { 66 extension_items_.reset(new extensions::ContextMenuMatcher( 67 controller_->profile(), this, this, 68 base::Bind(MenuItemHasLauncherContext))); 69 set_delegate(this); 70 71 if (is_valid_item()) { 72 if (item_.type == ash::TYPE_APP_SHORTCUT || 73 item_.type == ash::TYPE_WINDOWED_APP) { 74 // V1 apps can be started from the menu - but V2 apps should not. 75 if (!controller_->IsPlatformApp(item_.id)) { 76 AddItem(MENU_OPEN_NEW, string16()); 77 AddSeparator(ui::NORMAL_SEPARATOR); 78 } 79 AddItem( 80 MENU_PIN, 81 l10n_util::GetStringUTF16(controller_->IsPinned(item_.id) ? 82 IDS_LAUNCHER_CONTEXT_MENU_UNPIN : 83 IDS_LAUNCHER_CONTEXT_MENU_PIN)); 84 if (controller_->IsOpen(item_.id)) { 85 AddItem(MENU_CLOSE, 86 l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_CLOSE)); 87 } 88 if (!controller_->IsPlatformApp(item_.id) && 89 item_.type != ash::TYPE_WINDOWED_APP) { 90 AddSeparator(ui::NORMAL_SEPARATOR); 91 AddCheckItemWithStringId( 92 LAUNCH_TYPE_REGULAR_TAB, 93 IDS_APP_CONTEXT_MENU_OPEN_REGULAR); 94 AddCheckItemWithStringId( 95 LAUNCH_TYPE_PINNED_TAB, 96 IDS_APP_CONTEXT_MENU_OPEN_PINNED); 97 AddCheckItemWithStringId( 98 LAUNCH_TYPE_WINDOW, 99 IDS_APP_CONTEXT_MENU_OPEN_WINDOW); 100 // Even though the launch type is Full Screen it is more accurately 101 // described as Maximized in Ash. 102 AddCheckItemWithStringId( 103 LAUNCH_TYPE_FULLSCREEN, 104 IDS_APP_CONTEXT_MENU_OPEN_MAXIMIZED); 105 } 106 } else if (item_.type == ash::TYPE_BROWSER_SHORTCUT) { 107 AddItem(MENU_NEW_WINDOW, 108 l10n_util::GetStringUTF16(IDS_LAUNCHER_NEW_WINDOW)); 109 if (!controller_->IsLoggedInAsGuest()) { 110 AddItem(MENU_NEW_INCOGNITO_WINDOW, 111 l10n_util::GetStringUTF16(IDS_LAUNCHER_NEW_INCOGNITO_WINDOW)); 112 } 113 } else { 114 if (item_.type == ash::TYPE_PLATFORM_APP) { 115 AddItem( 116 MENU_PIN, 117 l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_PIN)); 118 } 119 if (controller_->IsOpen(item_.id)) { 120 AddItem(MENU_CLOSE, 121 l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_CLOSE)); 122 } 123 } 124 AddSeparator(ui::NORMAL_SEPARATOR); 125 if (item_.type == ash::TYPE_APP_SHORTCUT || 126 item_.type == ash::TYPE_WINDOWED_APP || 127 item_.type == ash::TYPE_PLATFORM_APP) { 128 std::string app_id = controller_->GetAppIDForLauncherID(item_.id); 129 if (!app_id.empty()) { 130 int index = 0; 131 extension_items_->AppendExtensionItems( 132 app_id, string16(), &index); 133 AddSeparator(ui::NORMAL_SEPARATOR); 134 } 135 } 136 } 137 // In fullscreen, the launcher is either hidden or autohidden depending on 138 // the type of fullscreen. Do not show the auto-hide menu item while in 139 // fullscreen because it is confusing when the preference appears not to 140 // apply. 141 if (!IsFullScreenMode()) { 142 AddCheckItemWithStringId(MENU_AUTO_HIDE, 143 IDS_ASH_SHELF_CONTEXT_MENU_AUTO_HIDE); 144 } 145 if (ash::ShelfWidget::ShelfAlignmentAllowed()) { 146 AddSubMenuWithStringId(MENU_ALIGNMENT_MENU, 147 IDS_ASH_SHELF_CONTEXT_MENU_POSITION, 148 &shelf_alignment_menu_); 149 } 150#if defined(OS_CHROMEOS) 151 AddItem(MENU_CHANGE_WALLPAPER, 152 l10n_util::GetStringUTF16(IDS_AURA_SET_DESKTOP_WALLPAPER)); 153#endif 154} 155 156LauncherContextMenu::~LauncherContextMenu() { 157} 158 159bool LauncherContextMenu::IsItemForCommandIdDynamic(int command_id) const { 160 return command_id == MENU_OPEN_NEW; 161} 162 163string16 LauncherContextMenu::GetLabelForCommandId(int command_id) const { 164 if (command_id == MENU_OPEN_NEW) { 165 if (item_.type == ash::TYPE_PLATFORM_APP) { 166 return l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_NEW_WINDOW); 167 } 168 switch (controller_->GetLaunchType(item_.id)) { 169 case extensions::ExtensionPrefs::LAUNCH_PINNED: 170 case extensions::ExtensionPrefs::LAUNCH_REGULAR: 171 return l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_NEW_TAB); 172 case extensions::ExtensionPrefs::LAUNCH_FULLSCREEN: 173 case extensions::ExtensionPrefs::LAUNCH_WINDOW: 174 return l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_NEW_WINDOW); 175 } 176 } 177 NOTREACHED(); 178 return string16(); 179} 180 181bool LauncherContextMenu::IsCommandIdChecked(int command_id) const { 182 switch (command_id) { 183 case LAUNCH_TYPE_PINNED_TAB: 184 return controller_->GetLaunchType(item_.id) == 185 extensions::ExtensionPrefs::LAUNCH_PINNED; 186 case LAUNCH_TYPE_REGULAR_TAB: 187 return controller_->GetLaunchType(item_.id) == 188 extensions::ExtensionPrefs::LAUNCH_REGULAR; 189 case LAUNCH_TYPE_WINDOW: 190 return controller_->GetLaunchType(item_.id) == 191 extensions::ExtensionPrefs::LAUNCH_WINDOW; 192 case LAUNCH_TYPE_FULLSCREEN: 193 return controller_->GetLaunchType(item_.id) == 194 extensions::ExtensionPrefs::LAUNCH_FULLSCREEN; 195 case MENU_AUTO_HIDE: 196 return controller_->GetShelfAutoHideBehavior(root_window_) == 197 ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS; 198 default: 199 return extension_items_->IsCommandIdChecked(command_id); 200 } 201} 202 203bool LauncherContextMenu::IsCommandIdEnabled(int command_id) const { 204 switch (command_id) { 205 case MENU_PIN: 206 return controller_->IsPinnable(item_.id); 207#if defined(OS_CHROMEOS) 208 case MENU_CHANGE_WALLPAPER: 209 return ash::Shell::GetInstance()->user_wallpaper_delegate()-> 210 CanOpenSetWallpaperPage(); 211#endif 212 case MENU_NEW_WINDOW: 213 // "Normal" windows are not allowed when incognito is enforced. 214 return IncognitoModePrefs::GetAvailability( 215 controller_->profile()->GetPrefs()) != IncognitoModePrefs::FORCED; 216 case MENU_AUTO_HIDE: 217 return controller_->CanUserModifyShelfAutoHideBehavior(root_window_); 218 case MENU_NEW_INCOGNITO_WINDOW: 219 // Incognito windows are not allowed when incognito is disabled. 220 return IncognitoModePrefs::GetAvailability( 221 controller_->profile()->GetPrefs()) != IncognitoModePrefs::DISABLED; 222 default: 223 return extension_items_->IsCommandIdEnabled(command_id); 224 } 225} 226 227bool LauncherContextMenu::GetAcceleratorForCommandId( 228 int command_id, 229 ui::Accelerator* accelerator) { 230 return false; 231} 232 233void LauncherContextMenu::ExecuteCommand(int command_id, int event_flags) { 234 switch (static_cast<MenuItem>(command_id)) { 235 case MENU_OPEN_NEW: 236 controller_->Launch(item_.id, ui::EF_NONE); 237 break; 238 case MENU_CLOSE: 239 controller_->Close(item_.id); 240 ChromeShellDelegate::instance()->RecordUserMetricsAction( 241 ash::UMA_CLOSE_THROUGH_CONTEXT_MENU); 242 break; 243 case MENU_PIN: 244 controller_->TogglePinned(item_.id); 245 break; 246 case LAUNCH_TYPE_PINNED_TAB: 247 controller_->SetLaunchType(item_.id, 248 extensions::ExtensionPrefs::LAUNCH_PINNED); 249 break; 250 case LAUNCH_TYPE_REGULAR_TAB: 251 controller_->SetLaunchType(item_.id, 252 extensions::ExtensionPrefs::LAUNCH_REGULAR); 253 break; 254 case LAUNCH_TYPE_WINDOW: 255 controller_->SetLaunchType(item_.id, 256 extensions::ExtensionPrefs::LAUNCH_WINDOW); 257 break; 258 case LAUNCH_TYPE_FULLSCREEN: 259 controller_->SetLaunchType(item_.id, 260 extensions::ExtensionPrefs::LAUNCH_FULLSCREEN); 261 break; 262 case MENU_AUTO_HIDE: 263 controller_->ToggleShelfAutoHideBehavior(root_window_); 264 break; 265 case MENU_NEW_WINDOW: 266 controller_->CreateNewWindow(); 267 break; 268 case MENU_NEW_INCOGNITO_WINDOW: 269 controller_->CreateNewIncognitoWindow(); 270 break; 271 case MENU_ALIGNMENT_MENU: 272 break; 273#if defined(OS_CHROMEOS) 274 case MENU_CHANGE_WALLPAPER: 275 ash::Shell::GetInstance()->user_wallpaper_delegate()-> 276 OpenSetWallpaperPage(); 277 break; 278#endif 279 default: 280 extension_items_->ExecuteCommand(command_id, NULL, 281 content::ContextMenuParams()); 282 } 283} 284