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.
5 #include "chrome/browser/ui/ash/launcher/launcher_context_menu.h"
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"
32 bool MenuItemHasLauncherContext(const extensions::MenuItem* item) {
33 return item->contexts().Contains(extensions::MenuItem::LAUNCHER);
38 LauncherContextMenu::LauncherContextMenu(ChromeLauncherController* controller,
39 const ash::LauncherItem* item,
41 : ui::SimpleMenuModel(NULL),
42 controller_(controller),
44 shelf_alignment_menu_(root),
51 LauncherContextMenu::LauncherContextMenu(ChromeLauncherController* controller,
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))),
65 void LauncherContextMenu::Init() {
66 extension_items_.reset(new extensions::ContextMenuMatcher(
67 controller_->profile(), this, this,
68 base::Bind(MenuItemHasLauncherContext)));
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);
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)) {
86 l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_CLOSE));
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(
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);
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));
114 if (item_.type == ash::TYPE_PLATFORM_APP) {
117 l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_PIN));
119 if (controller_->IsOpen(item_.id)) {
121 l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_CLOSE));
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()) {
131 extension_items_->AppendExtensionItems(
132 app_id, string16(), &index);
133 AddSeparator(ui::NORMAL_SEPARATOR);
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
141 if (!IsFullScreenMode()) {
142 AddCheckItemWithStringId(MENU_AUTO_HIDE,
143 IDS_ASH_SHELF_CONTEXT_MENU_AUTO_HIDE);
145 if (ash::ShelfWidget::ShelfAlignmentAllowed()) {
146 AddSubMenuWithStringId(MENU_ALIGNMENT_MENU,
147 IDS_ASH_SHELF_CONTEXT_MENU_POSITION,
148 &shelf_alignment_menu_);
150 #if defined(OS_CHROMEOS)
151 AddItem(MENU_CHANGE_WALLPAPER,
152 l10n_util::GetStringUTF16(IDS_AURA_SET_DESKTOP_WALLPAPER));
156 LauncherContextMenu::~LauncherContextMenu() {
159 bool LauncherContextMenu::IsItemForCommandIdDynamic(int command_id) const {
160 return command_id == MENU_OPEN_NEW;
163 string16 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);
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);
181 bool 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;
196 return controller_->GetShelfAutoHideBehavior(root_window_) ==
197 ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS;
199 return extension_items_->IsCommandIdChecked(command_id);
203 bool LauncherContextMenu::IsCommandIdEnabled(int command_id) const {
204 switch (command_id) {
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();
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;
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;
223 return extension_items_->IsCommandIdEnabled(command_id);
227 bool LauncherContextMenu::GetAcceleratorForCommandId(
229 ui::Accelerator* accelerator) {
233 void LauncherContextMenu::ExecuteCommand(int command_id, int event_flags) {
234 switch (static_cast<MenuItem>(command_id)) {
236 controller_->Launch(item_.id, ui::EF_NONE);
239 controller_->Close(item_.id);
240 ChromeShellDelegate::instance()->RecordUserMetricsAction(
241 ash::UMA_CLOSE_THROUGH_CONTEXT_MENU);
244 controller_->TogglePinned(item_.id);
246 case LAUNCH_TYPE_PINNED_TAB:
247 controller_->SetLaunchType(item_.id,
248 extensions::ExtensionPrefs::LAUNCH_PINNED);
250 case LAUNCH_TYPE_REGULAR_TAB:
251 controller_->SetLaunchType(item_.id,
252 extensions::ExtensionPrefs::LAUNCH_REGULAR);
254 case LAUNCH_TYPE_WINDOW:
255 controller_->SetLaunchType(item_.id,
256 extensions::ExtensionPrefs::LAUNCH_WINDOW);
258 case LAUNCH_TYPE_FULLSCREEN:
259 controller_->SetLaunchType(item_.id,
260 extensions::ExtensionPrefs::LAUNCH_FULLSCREEN);
263 controller_->ToggleShelfAutoHideBehavior(root_window_);
265 case MENU_NEW_WINDOW:
266 controller_->CreateNewWindow();
268 case MENU_NEW_INCOGNITO_WINDOW:
269 controller_->CreateNewIncognitoWindow();
271 case MENU_ALIGNMENT_MENU:
273 #if defined(OS_CHROMEOS)
274 case MENU_CHANGE_WALLPAPER:
275 ash::Shell::GetInstance()->user_wallpaper_delegate()->
276 OpenSetWallpaperPage();
280 extension_items_->ExecuteCommand(command_id, NULL,
281 content::ContextMenuParams());