Move Webstore URL concepts to //extensions and out
[chromium-blink-merge.git] / chrome / browser / ui / app_list / app_context_menu.cc
bloba5a67269926657f2f9129ecdbd928a30b57f77b4
1 // Copyright 2013 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/app_list/app_context_menu.h"
7 #include "base/bind.h"
8 #include "chrome/browser/extensions/context_menu_matcher.h"
9 #include "chrome/browser/extensions/extension_util.h"
10 #include "chrome/browser/extensions/menu_manager.h"
11 #include "chrome/browser/prefs/incognito_mode_prefs.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/app_list/app_context_menu_delegate.h"
14 #include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
15 #include "chrome/common/extensions/manifest_url_handler.h"
16 #include "chrome/grit/chromium_strings.h"
17 #include "chrome/grit/generated_resources.h"
18 #include "content/public/common/context_menu_params.h"
19 #include "ui/base/l10n/l10n_util.h"
21 #if defined(USE_ASH)
22 #include "ash/shell.h"
23 #endif
25 namespace app_list {
27 namespace {
29 enum CommandId {
30 LAUNCH_NEW = 100,
31 TOGGLE_PIN,
32 CREATE_SHORTCUTS,
33 SHOW_APP_INFO,
34 OPTIONS,
35 UNINSTALL,
36 REMOVE_FROM_FOLDER,
37 MENU_NEW_WINDOW,
38 MENU_NEW_INCOGNITO_WINDOW,
39 // Order matters in USE_LAUNCH_TYPE_* and must match the LaunchType enum.
40 USE_LAUNCH_TYPE_COMMAND_START = 200,
41 USE_LAUNCH_TYPE_PINNED = USE_LAUNCH_TYPE_COMMAND_START,
42 USE_LAUNCH_TYPE_REGULAR,
43 USE_LAUNCH_TYPE_FULLSCREEN,
44 USE_LAUNCH_TYPE_WINDOW,
45 USE_LAUNCH_TYPE_COMMAND_END,
48 bool MenuItemHasLauncherContext(const extensions::MenuItem* item) {
49 return item->contexts().Contains(extensions::MenuItem::LAUNCHER);
52 } // namespace
54 AppContextMenu::AppContextMenu(AppContextMenuDelegate* delegate,
55 Profile* profile,
56 const std::string& app_id,
57 AppListControllerDelegate* controller)
58 : delegate_(delegate),
59 profile_(profile),
60 app_id_(app_id),
61 controller_(controller),
62 is_platform_app_(false),
63 is_search_result_(false),
64 is_in_folder_(false) {
67 AppContextMenu::~AppContextMenu() {
70 ui::MenuModel* AppContextMenu::GetMenuModel() {
71 if (!controller_->IsExtensionInstalled(profile_, app_id_))
72 return NULL;
74 if (menu_model_.get())
75 return menu_model_.get();
77 menu_model_.reset(new ui::SimpleMenuModel(this));
79 if (app_id_ == extension_misc::kChromeAppId) {
80 menu_model_->AddItemWithStringId(
81 MENU_NEW_WINDOW,
82 IDS_APP_LIST_NEW_WINDOW);
83 if (!profile_->IsOffTheRecord()) {
84 menu_model_->AddItemWithStringId(
85 MENU_NEW_INCOGNITO_WINDOW,
86 IDS_APP_LIST_NEW_INCOGNITO_WINDOW);
88 if (controller_->CanDoShowAppInfoFlow()) {
89 menu_model_->AddItemWithStringId(SHOW_APP_INFO,
90 IDS_APP_CONTEXT_MENU_SHOW_INFO);
92 } else {
93 extension_menu_items_.reset(new extensions::ContextMenuMatcher(
94 profile_, this, menu_model_.get(),
95 base::Bind(MenuItemHasLauncherContext)));
97 // First, add the primary actions.
98 if (!is_platform_app_)
99 menu_model_->AddItem(LAUNCH_NEW, base::string16());
101 // Show Pin/Unpin option if shelf is available.
102 if (controller_->GetPinnable() != AppListControllerDelegate::NO_PIN) {
103 menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);
104 menu_model_->AddItemWithStringId(
105 TOGGLE_PIN,
106 controller_->IsAppPinned(app_id_) ?
107 IDS_APP_LIST_CONTEXT_MENU_UNPIN :
108 IDS_APP_LIST_CONTEXT_MENU_PIN);
111 if (controller_->CanDoCreateShortcutsFlow()) {
112 menu_model_->AddItemWithStringId(CREATE_SHORTCUTS,
113 IDS_NEW_TAB_APP_CREATE_SHORTCUT);
115 menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);
117 if (!is_platform_app_) {
118 // Streamlined hosted apps can only toggle between USE_LAUNCH_TYPE_WINDOW
119 // and USE_LAUNCH_TYPE_REGULAR.
120 if (extensions::util::IsStreamlinedHostedAppsEnabled()) {
121 menu_model_->AddCheckItemWithStringId(
122 USE_LAUNCH_TYPE_REGULAR,
123 IDS_APP_CONTEXT_MENU_OPEN_TAB);
124 } else {
125 menu_model_->AddCheckItemWithStringId(
126 USE_LAUNCH_TYPE_REGULAR,
127 IDS_APP_CONTEXT_MENU_OPEN_REGULAR);
128 menu_model_->AddCheckItemWithStringId(
129 USE_LAUNCH_TYPE_PINNED,
130 IDS_APP_CONTEXT_MENU_OPEN_PINNED);
131 #if defined(OS_MACOSX)
132 // Mac does not support standalone web app browser windows or maximize.
133 menu_model_->AddCheckItemWithStringId(
134 USE_LAUNCH_TYPE_FULLSCREEN,
135 IDS_APP_CONTEXT_MENU_OPEN_FULLSCREEN);
136 #else
137 menu_model_->AddCheckItemWithStringId(
138 USE_LAUNCH_TYPE_WINDOW,
139 IDS_APP_CONTEXT_MENU_OPEN_WINDOW);
140 // Even though the launch type is Full Screen it is more accurately
141 // described as Maximized in Ash.
142 menu_model_->AddCheckItemWithStringId(
143 USE_LAUNCH_TYPE_FULLSCREEN,
144 IDS_APP_CONTEXT_MENU_OPEN_MAXIMIZED);
145 #endif
147 menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);
150 // Assign unique IDs to commands added by the app itself.
151 int index = USE_LAUNCH_TYPE_COMMAND_END;
152 extension_menu_items_->AppendExtensionItems(
153 extensions::MenuItem::ExtensionKey(app_id_),
154 base::string16(),
155 &index,
156 false); // is_action_menu
158 // If at least 1 item was added, add another separator after the list.
159 if (index > USE_LAUNCH_TYPE_COMMAND_END)
160 menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);
162 if (!is_platform_app_)
163 menu_model_->AddItemWithStringId(OPTIONS, IDS_NEW_TAB_APP_OPTIONS);
165 menu_model_->AddItemWithStringId(UNINSTALL,
166 is_platform_app_
167 ? IDS_APP_LIST_UNINSTALL_ITEM
168 : IDS_APP_LIST_EXTENSIONS_UNINSTALL);
170 if (controller_->CanDoShowAppInfoFlow()) {
171 menu_model_->AddItemWithStringId(SHOW_APP_INFO,
172 IDS_APP_CONTEXT_MENU_SHOW_INFO);
176 return menu_model_.get();
179 bool AppContextMenu::IsItemForCommandIdDynamic(int command_id) const {
180 return command_id == TOGGLE_PIN || command_id == LAUNCH_NEW;
183 base::string16 AppContextMenu::GetLabelForCommandId(int command_id) const {
184 if (command_id == TOGGLE_PIN) {
185 return controller_->IsAppPinned(app_id_) ?
186 l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_UNPIN) :
187 l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_PIN);
188 } else if (command_id == LAUNCH_NEW) {
189 #if defined(OS_MACOSX)
190 // Even fullscreen windows launch in a browser tab on Mac.
191 const bool launches_in_tab = true;
192 #else
193 const bool launches_in_tab = IsCommandIdChecked(USE_LAUNCH_TYPE_PINNED) ||
194 IsCommandIdChecked(USE_LAUNCH_TYPE_REGULAR);
195 #endif
196 return launches_in_tab ?
197 l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_NEW_TAB) :
198 l10n_util::GetStringUTF16(IDS_APP_LIST_CONTEXT_MENU_NEW_WINDOW);
199 } else {
200 NOTREACHED();
201 return base::string16();
205 bool AppContextMenu::IsCommandIdChecked(int command_id) const {
206 if (command_id >= USE_LAUNCH_TYPE_COMMAND_START &&
207 command_id < USE_LAUNCH_TYPE_COMMAND_END) {
208 return static_cast<int>(controller_->GetExtensionLaunchType(
209 profile_, app_id_)) + USE_LAUNCH_TYPE_COMMAND_START == command_id;
210 } else if (extensions::ContextMenuMatcher::IsExtensionsCustomCommandId(
211 command_id)) {
212 return extension_menu_items_->IsCommandIdChecked(command_id);
214 return false;
217 bool AppContextMenu::IsCommandIdEnabled(int command_id) const {
218 if (command_id == TOGGLE_PIN) {
219 return controller_->GetPinnable() ==
220 AppListControllerDelegate::PIN_EDITABLE;
221 } else if (command_id == OPTIONS) {
222 return controller_->HasOptionsPage(profile_, app_id_);
223 } else if (command_id == UNINSTALL) {
224 return controller_->UserMayModifySettings(profile_, app_id_);
225 } else if (extensions::ContextMenuMatcher::IsExtensionsCustomCommandId(
226 command_id)) {
227 return extension_menu_items_->IsCommandIdEnabled(command_id);
228 } else if (command_id == MENU_NEW_WINDOW) {
229 // "Normal" windows are not allowed when incognito is enforced.
230 return IncognitoModePrefs::GetAvailability(profile_->GetPrefs()) !=
231 IncognitoModePrefs::FORCED;
232 } else if (command_id == MENU_NEW_INCOGNITO_WINDOW) {
233 // Incognito windows are not allowed when incognito is disabled.
234 return IncognitoModePrefs::GetAvailability(profile_->GetPrefs()) !=
235 IncognitoModePrefs::DISABLED;
237 return true;
240 bool AppContextMenu::GetAcceleratorForCommandId(
241 int command_id,
242 ui::Accelerator* acclelrator) {
243 return false;
246 void AppContextMenu::ExecuteCommand(int command_id, int event_flags) {
247 if (command_id == LAUNCH_NEW) {
248 delegate_->ExecuteLaunchCommand(event_flags);
249 } else if (command_id == TOGGLE_PIN && controller_->GetPinnable() ==
250 AppListControllerDelegate::PIN_EDITABLE) {
251 if (controller_->IsAppPinned(app_id_))
252 controller_->UnpinApp(app_id_);
253 else
254 controller_->PinApp(app_id_);
255 } else if (command_id == CREATE_SHORTCUTS) {
256 controller_->DoCreateShortcutsFlow(profile_, app_id_);
257 } else if (command_id == SHOW_APP_INFO) {
258 controller_->DoShowAppInfoFlow(profile_, app_id_);
259 } else if (command_id >= USE_LAUNCH_TYPE_COMMAND_START &&
260 command_id < USE_LAUNCH_TYPE_COMMAND_END) {
261 extensions::LaunchType launch_type = static_cast<extensions::LaunchType>(
262 command_id - USE_LAUNCH_TYPE_COMMAND_START);
263 // Streamlined hosted apps can only toggle between LAUNCH_TYPE_WINDOW and
264 // LAUNCH_TYPE_REGULAR.
265 if (extensions::util::IsStreamlinedHostedAppsEnabled()) {
266 launch_type = (controller_->GetExtensionLaunchType(profile_, app_id_) ==
267 extensions::LAUNCH_TYPE_REGULAR) ?
268 extensions::LAUNCH_TYPE_WINDOW :
269 extensions::LAUNCH_TYPE_REGULAR;
271 controller_->SetExtensionLaunchType(profile_, app_id_, launch_type);
272 } else if (command_id == OPTIONS) {
273 controller_->ShowOptionsPage(profile_, app_id_);
274 } else if (command_id == UNINSTALL) {
275 controller_->UninstallApp(profile_, app_id_);
276 } else if (extensions::ContextMenuMatcher::IsExtensionsCustomCommandId(
277 command_id)) {
278 extension_menu_items_->ExecuteCommand(command_id, NULL,
279 content::ContextMenuParams());
280 } else if (command_id == MENU_NEW_WINDOW) {
281 controller_->CreateNewWindow(profile_, false);
282 } else if (command_id == MENU_NEW_INCOGNITO_WINDOW) {
283 controller_->CreateNewWindow(profile_, true);
287 } // namespace app_list