Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / ash / launcher / launcher_context_menu.cc
blob9b6ac3daec606c379ebadadf0219c9be722464e7
1 // Copyright 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"
7 #include <string>
9 #include "ash/desktop_background/user_wallpaper_delegate.h"
10 #include "ash/metrics/user_metrics_recorder.h"
11 #include "ash/root_window_controller.h"
12 #include "ash/session/session_state_delegate.h"
13 #include "ash/shelf/shelf_item_delegate.h"
14 #include "ash/shelf/shelf_widget.h"
15 #include "ash/shell.h"
16 #include "base/bind.h"
17 #include "base/prefs/pref_service.h"
18 #include "chrome/browser/extensions/context_menu_matcher.h"
19 #include "chrome/browser/extensions/extension_util.h"
20 #include "chrome/browser/fullscreen.h"
21 #include "chrome/browser/prefs/incognito_mode_prefs.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/ui/ash/chrome_shell_delegate.h"
24 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
25 #include "chrome/common/extensions/extension_constants.h"
26 #include "chrome/grit/generated_resources.h"
27 #include "content/public/common/context_menu_params.h"
28 #include "grit/ash_strings.h"
29 #include "ui/base/l10n/l10n_util.h"
31 namespace {
33 bool MenuItemHasLauncherContext(const extensions::MenuItem* item) {
34 return item->contexts().Contains(extensions::MenuItem::LAUNCHER);
37 } // namespace
39 LauncherContextMenu::LauncherContextMenu(ChromeLauncherController* controller,
40 const ash::ShelfItem* item,
41 aura::Window* root)
42 : ui::SimpleMenuModel(NULL),
43 controller_(controller),
44 item_(*item),
45 shelf_alignment_menu_(root),
46 root_window_(root),
47 item_delegate_(NULL) {
48 DCHECK(item);
49 DCHECK(root_window_);
50 Init();
53 LauncherContextMenu::LauncherContextMenu(ChromeLauncherController* controller,
54 ash::ShelfItemDelegate* item_delegate,
55 ash::ShelfItem* item,
56 aura::Window* root)
57 : ui::SimpleMenuModel(NULL),
58 controller_(controller),
59 item_(*item),
60 shelf_alignment_menu_(root),
61 root_window_(root),
62 item_delegate_(item_delegate) {
63 DCHECK(item);
64 DCHECK(root_window_);
65 Init();
68 LauncherContextMenu::LauncherContextMenu(ChromeLauncherController* controller,
69 aura::Window* root)
70 : ui::SimpleMenuModel(NULL),
71 controller_(controller),
72 item_(ash::ShelfItem()),
73 shelf_alignment_menu_(root),
74 extension_items_(new extensions::ContextMenuMatcher(
75 controller->profile(), this, this,
76 base::Bind(MenuItemHasLauncherContext))),
77 root_window_(root),
78 item_delegate_(NULL) {
79 DCHECK(root_window_);
80 Init();
83 void LauncherContextMenu::Init() {
84 extension_items_.reset(new extensions::ContextMenuMatcher(
85 controller_->profile(), this, this,
86 base::Bind(MenuItemHasLauncherContext)));
87 set_delegate(this);
89 if (is_valid_item()) {
90 if (item_.type == ash::TYPE_APP_SHORTCUT ||
91 item_.type == ash::TYPE_WINDOWED_APP) {
92 // V1 apps can be started from the menu - but V2 apps should not.
93 if (!controller_->IsPlatformApp(item_.id)) {
94 AddItem(MENU_OPEN_NEW, base::string16());
95 AddSeparator(ui::NORMAL_SEPARATOR);
97 AddItem(
98 MENU_PIN,
99 l10n_util::GetStringUTF16(controller_->IsPinned(item_.id) ?
100 IDS_LAUNCHER_CONTEXT_MENU_UNPIN :
101 IDS_LAUNCHER_CONTEXT_MENU_PIN));
102 if (controller_->IsOpen(item_.id)) {
103 AddItem(MENU_CLOSE,
104 l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_CLOSE));
106 if (!controller_->IsPlatformApp(item_.id) &&
107 item_.type != ash::TYPE_WINDOWED_APP) {
108 AddSeparator(ui::NORMAL_SEPARATOR);
109 if (extensions::util::IsNewBookmarkAppsEnabled()) {
110 // With bookmark apps enabled, hosted apps launch in a window by
111 // default. This menu item is re-interpreted as a single, toggle-able
112 // option to launch the hosted app as a tab.
113 AddCheckItemWithStringId(LAUNCH_TYPE_WINDOW,
114 IDS_APP_CONTEXT_MENU_OPEN_WINDOW);
115 } else {
116 AddCheckItemWithStringId(
117 LAUNCH_TYPE_REGULAR_TAB,
118 IDS_APP_CONTEXT_MENU_OPEN_REGULAR);
119 AddCheckItemWithStringId(
120 LAUNCH_TYPE_PINNED_TAB,
121 IDS_APP_CONTEXT_MENU_OPEN_PINNED);
122 AddCheckItemWithStringId(
123 LAUNCH_TYPE_WINDOW,
124 IDS_APP_CONTEXT_MENU_OPEN_WINDOW);
125 // Even though the launch type is Full Screen it is more accurately
126 // described as Maximized in Ash.
127 AddCheckItemWithStringId(
128 LAUNCH_TYPE_FULLSCREEN,
129 IDS_APP_CONTEXT_MENU_OPEN_MAXIMIZED);
132 } else if (item_.type == ash::TYPE_BROWSER_SHORTCUT) {
133 AddItem(MENU_NEW_WINDOW,
134 l10n_util::GetStringUTF16(IDS_APP_LIST_NEW_WINDOW));
135 if (!controller_->IsLoggedInAsGuest()) {
136 AddItem(MENU_NEW_INCOGNITO_WINDOW,
137 l10n_util::GetStringUTF16(IDS_APP_LIST_NEW_INCOGNITO_WINDOW));
139 } else if (item_.type == ash::TYPE_DIALOG) {
140 AddItem(MENU_CLOSE,
141 l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_CLOSE));
142 } else {
143 if (item_.type == ash::TYPE_PLATFORM_APP) {
144 AddItem(
145 MENU_PIN,
146 l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_PIN));
148 if (controller_->IsOpen(item_.id)) {
149 AddItem(MENU_CLOSE,
150 l10n_util::GetStringUTF16(IDS_LAUNCHER_CONTEXT_MENU_CLOSE));
153 AddSeparator(ui::NORMAL_SEPARATOR);
154 if (item_.type == ash::TYPE_APP_SHORTCUT ||
155 item_.type == ash::TYPE_WINDOWED_APP ||
156 item_.type == ash::TYPE_PLATFORM_APP) {
157 const extensions::MenuItem::ExtensionKey app_key(
158 controller_->GetAppIDForShelfID(item_.id));
159 if (!app_key.empty()) {
160 int index = 0;
161 extension_items_->AppendExtensionItems(app_key,
162 base::string16(),
163 &index,
164 false); // is_action_menu
165 AddSeparator(ui::NORMAL_SEPARATOR);
169 // In fullscreen, the launcher is either hidden or autohidden depending on
170 // the type of fullscreen. Do not show the auto-hide menu item while in
171 // fullscreen because it is confusing when the preference appears not to
172 // apply.
173 if (!IsFullScreenMode() &&
174 controller_->CanUserModifyShelfAutoHideBehavior(root_window_)) {
175 AddCheckItemWithStringId(MENU_AUTO_HIDE,
176 IDS_ASH_SHELF_CONTEXT_MENU_AUTO_HIDE);
178 if (ash::ShelfWidget::ShelfAlignmentAllowed() &&
179 !ash::Shell::GetInstance()->session_state_delegate()->IsScreenLocked()) {
180 AddSubMenuWithStringId(MENU_ALIGNMENT_MENU,
181 IDS_ASH_SHELF_CONTEXT_MENU_POSITION,
182 &shelf_alignment_menu_);
184 #if defined(OS_CHROMEOS)
185 if (!controller_->IsLoggedInAsGuest()) {
186 AddItem(MENU_CHANGE_WALLPAPER,
187 l10n_util::GetStringUTF16(IDS_AURA_SET_DESKTOP_WALLPAPER));
189 #endif
192 LauncherContextMenu::~LauncherContextMenu() {
195 bool LauncherContextMenu::IsItemForCommandIdDynamic(int command_id) const {
196 return command_id == MENU_OPEN_NEW;
199 base::string16 LauncherContextMenu::GetLabelForCommandId(int command_id) const {
200 if (command_id == MENU_OPEN_NEW) {
201 if (item_.type == ash::TYPE_PLATFORM_APP) {
202 return l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_NEW_WINDOW);
204 switch (controller_->GetLaunchType(item_.id)) {
205 case extensions::LAUNCH_TYPE_PINNED:
206 case extensions::LAUNCH_TYPE_REGULAR:
207 return l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_NEW_TAB);
208 case extensions::LAUNCH_TYPE_FULLSCREEN:
209 case extensions::LAUNCH_TYPE_WINDOW:
210 return l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_NEW_WINDOW);
211 default:
212 NOTREACHED();
213 return base::string16();
216 NOTREACHED();
217 return base::string16();
220 bool LauncherContextMenu::IsCommandIdChecked(int command_id) const {
221 switch (command_id) {
222 case LAUNCH_TYPE_PINNED_TAB:
223 return controller_->GetLaunchType(item_.id) ==
224 extensions::LAUNCH_TYPE_PINNED;
225 case LAUNCH_TYPE_REGULAR_TAB:
226 return controller_->GetLaunchType(item_.id) ==
227 extensions::LAUNCH_TYPE_REGULAR;
228 case LAUNCH_TYPE_WINDOW:
229 return controller_->GetLaunchType(item_.id) ==
230 extensions::LAUNCH_TYPE_WINDOW;
231 case LAUNCH_TYPE_FULLSCREEN:
232 return controller_->GetLaunchType(item_.id) ==
233 extensions::LAUNCH_TYPE_FULLSCREEN;
234 case MENU_AUTO_HIDE:
235 return controller_->GetShelfAutoHideBehavior(root_window_) ==
236 ash::SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS;
237 default:
238 return extension_items_->IsCommandIdChecked(command_id);
242 bool LauncherContextMenu::IsCommandIdEnabled(int command_id) const {
243 switch (command_id) {
244 case MENU_PIN:
245 return controller_->IsPinnable(item_.id);
246 #if defined(OS_CHROMEOS)
247 case MENU_CHANGE_WALLPAPER:
248 return ash::Shell::GetInstance()->user_wallpaper_delegate()->
249 CanOpenSetWallpaperPage();
250 #endif
251 case MENU_NEW_WINDOW:
252 // "Normal" windows are not allowed when incognito is enforced.
253 return IncognitoModePrefs::GetAvailability(
254 controller_->profile()->GetPrefs()) != IncognitoModePrefs::FORCED;
255 case MENU_AUTO_HIDE:
256 return controller_->CanUserModifyShelfAutoHideBehavior(root_window_);
257 case MENU_NEW_INCOGNITO_WINDOW:
258 // Incognito windows are not allowed when incognito is disabled.
259 return IncognitoModePrefs::GetAvailability(
260 controller_->profile()->GetPrefs()) != IncognitoModePrefs::DISABLED;
261 default:
262 return extension_items_->IsCommandIdEnabled(command_id);
266 bool LauncherContextMenu::GetAcceleratorForCommandId(
267 int command_id,
268 ui::Accelerator* accelerator) {
269 return false;
272 void LauncherContextMenu::ExecuteCommand(int command_id, int event_flags) {
273 switch (static_cast<MenuItem>(command_id)) {
274 case MENU_OPEN_NEW:
275 controller_->Launch(item_.id, ui::EF_NONE);
276 break;
277 case MENU_CLOSE:
278 if (item_.type == ash::TYPE_DIALOG) {
279 DCHECK(item_delegate_);
280 item_delegate_->Close();
281 } else {
282 // TODO(simonhong): Use ShelfItemDelegate::Close().
283 controller_->Close(item_.id);
285 ash::Shell::GetInstance()->metrics()->RecordUserMetricsAction(
286 ash::UMA_CLOSE_THROUGH_CONTEXT_MENU);
287 break;
288 case MENU_PIN:
289 controller_->TogglePinned(item_.id);
290 break;
291 case LAUNCH_TYPE_PINNED_TAB:
292 controller_->SetLaunchType(item_.id, extensions::LAUNCH_TYPE_PINNED);
293 break;
294 case LAUNCH_TYPE_REGULAR_TAB:
295 controller_->SetLaunchType(item_.id, extensions::LAUNCH_TYPE_REGULAR);
296 break;
297 case LAUNCH_TYPE_WINDOW: {
298 extensions::LaunchType launch_type = extensions::LAUNCH_TYPE_WINDOW;
299 // With bookmark apps enabled, hosted apps can only toggle between
300 // LAUNCH_WINDOW and LAUNCH_REGULAR.
301 if (extensions::util::IsNewBookmarkAppsEnabled()) {
302 launch_type = controller_->GetLaunchType(item_.id) ==
303 extensions::LAUNCH_TYPE_WINDOW
304 ? extensions::LAUNCH_TYPE_REGULAR
305 : extensions::LAUNCH_TYPE_WINDOW;
307 controller_->SetLaunchType(item_.id, launch_type);
308 break;
310 case LAUNCH_TYPE_FULLSCREEN:
311 controller_->SetLaunchType(item_.id, extensions::LAUNCH_TYPE_FULLSCREEN);
312 break;
313 case MENU_AUTO_HIDE:
314 controller_->ToggleShelfAutoHideBehavior(root_window_);
315 break;
316 case MENU_NEW_WINDOW:
317 controller_->CreateNewWindow();
318 break;
319 case MENU_NEW_INCOGNITO_WINDOW:
320 controller_->CreateNewIncognitoWindow();
321 break;
322 case MENU_ALIGNMENT_MENU:
323 break;
324 #if defined(OS_CHROMEOS)
325 case MENU_CHANGE_WALLPAPER:
326 ash::Shell::GetInstance()->user_wallpaper_delegate()->
327 OpenSetWallpaperPage();
328 break;
329 #endif
330 default:
331 extension_items_->ExecuteCommand(command_id, NULL,
332 content::ContextMenuParams());