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/toolbar/wrench_menu_model.h"
10 #include "base/command_line.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "chrome/app/chrome_command_ids.h"
16 #include "chrome/browser/browser_process.h"
17 #include "chrome/browser/defaults.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/profiles/profile_manager.h"
20 #include "chrome/browser/search/search.h"
21 #include "chrome/browser/signin/signin_manager_factory.h"
22 #include "chrome/browser/signin/signin_ui_util.h"
23 #include "chrome/browser/task_manager/task_manager.h"
24 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
25 #include "chrome/browser/ui/browser.h"
26 #include "chrome/browser/ui/browser_commands.h"
27 #include "chrome/browser/ui/browser_finder.h"
28 #include "chrome/browser/ui/browser_window.h"
29 #include "chrome/browser/ui/global_error/global_error.h"
30 #include "chrome/browser/ui/global_error/global_error_service.h"
31 #include "chrome/browser/ui/global_error/global_error_service_factory.h"
32 #include "chrome/browser/ui/tabs/tab_strip_model.h"
33 #include "chrome/browser/ui/toolbar/bookmark_sub_menu_model.h"
34 #include "chrome/browser/ui/toolbar/encoding_menu_controller.h"
35 #include "chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h"
36 #include "chrome/browser/upgrade_detector.h"
37 #include "chrome/common/chrome_paths.h"
38 #include "chrome/common/chrome_switches.h"
39 #include "chrome/common/pref_names.h"
40 #include "chrome/common/profiling.h"
41 #include "components/signin/core/browser/signin_manager.h"
42 #include "content/public/browser/host_zoom_map.h"
43 #include "content/public/browser/navigation_entry.h"
44 #include "content/public/browser/notification_service.h"
45 #include "content/public/browser/notification_source.h"
46 #include "content/public/browser/notification_types.h"
47 #include "content/public/browser/user_metrics.h"
48 #include "content/public/browser/web_contents.h"
49 #include "grit/chromium_strings.h"
50 #include "grit/generated_resources.h"
51 #include "grit/theme_resources.h"
52 #include "ui/base/l10n/l10n_util.h"
53 #include "ui/base/layout.h"
54 #include "ui/base/models/button_menu_item_model.h"
55 #include "ui/base/resource/resource_bundle.h"
56 #include "ui/gfx/image/image.h"
57 #include "ui/gfx/image/image_skia.h"
59 #if defined(OS_CHROMEOS)
60 #include "chromeos/chromeos_switches.h"
64 #include "base/win/metro.h"
65 #include "base/win/windows_version.h"
66 #include "chrome/browser/enumerate_modules_model_win.h"
67 #include "chrome/browser/ui/metro_pin_tab_helper_win.h"
68 #include "content/public/browser/gpu_data_manager.h"
72 #include "ash/shell.h"
75 using base::UserMetricsAction
;
76 using content::HostZoomMap
;
77 using content::WebContents
;
80 // Conditionally return the update app menu item title based on upgrade detector
82 base::string16
GetUpgradeDialogMenuItemName() {
83 if (UpgradeDetector::GetInstance()->is_outdated_install() ||
84 UpgradeDetector::GetInstance()->is_outdated_install_no_au()) {
85 return l10n_util::GetStringUTF16(IDS_UPGRADE_BUBBLE_MENU_ITEM
);
87 return l10n_util::GetStringUTF16(IDS_UPDATE_NOW
);
93 ////////////////////////////////////////////////////////////////////////////////
96 EncodingMenuModel::EncodingMenuModel(Browser
* browser
)
97 : ui::SimpleMenuModel(this),
102 EncodingMenuModel::~EncodingMenuModel() {
105 void EncodingMenuModel::Build() {
106 EncodingMenuController::EncodingMenuItemList encoding_menu_items
;
107 EncodingMenuController encoding_menu_controller
;
108 encoding_menu_controller
.GetEncodingMenuItems(browser_
->profile(),
109 &encoding_menu_items
);
112 EncodingMenuController::EncodingMenuItemList::iterator it
=
113 encoding_menu_items
.begin();
114 for (; it
!= encoding_menu_items
.end(); ++it
) {
116 base::string16
& label
= it
->second
;
118 AddSeparator(ui::NORMAL_SEPARATOR
);
120 if (id
== IDC_ENCODING_AUTO_DETECT
) {
121 AddCheckItem(id
, label
);
123 // Use the id of the first radio command as the id of the group.
126 AddRadioItem(id
, label
, group_id
);
132 bool EncodingMenuModel::IsCommandIdChecked(int command_id
) const {
133 WebContents
* current_tab
=
134 browser_
->tab_strip_model()->GetActiveWebContents();
137 EncodingMenuController controller
;
138 return controller
.IsItemChecked(browser_
->profile(),
139 current_tab
->GetEncoding(), command_id
);
142 bool EncodingMenuModel::IsCommandIdEnabled(int command_id
) const {
143 bool enabled
= chrome::IsCommandEnabled(browser_
, command_id
);
144 // Special handling for the contents of the Encoding submenu. On Mac OS,
145 // instead of enabling/disabling the top-level menu item, the submenu's
146 // contents get disabled, per Apple's HIG.
147 #if defined(OS_MACOSX)
148 enabled
&= chrome::IsCommandEnabled(browser_
, IDC_ENCODING_MENU
);
153 bool EncodingMenuModel::GetAcceleratorForCommandId(
155 ui::Accelerator
* accelerator
) {
159 void EncodingMenuModel::ExecuteCommand(int command_id
, int event_flags
) {
160 chrome::ExecuteCommand(browser_
, command_id
);
163 ////////////////////////////////////////////////////////////////////////////////
166 ZoomMenuModel::ZoomMenuModel(ui::SimpleMenuModel::Delegate
* delegate
)
167 : SimpleMenuModel(delegate
) {
171 ZoomMenuModel::~ZoomMenuModel() {
174 void ZoomMenuModel::Build() {
175 AddItemWithStringId(IDC_ZOOM_PLUS
, IDS_ZOOM_PLUS
);
176 AddItemWithStringId(IDC_ZOOM_NORMAL
, IDS_ZOOM_NORMAL
);
177 AddItemWithStringId(IDC_ZOOM_MINUS
, IDS_ZOOM_MINUS
);
180 ////////////////////////////////////////////////////////////////////////////////
183 ToolsMenuModel::ToolsMenuModel(ui::SimpleMenuModel::Delegate
* delegate
,
185 : SimpleMenuModel(delegate
) {
189 ToolsMenuModel::~ToolsMenuModel() {}
191 void ToolsMenuModel::Build(Browser
* browser
) {
192 bool show_create_shortcuts
= true;
193 #if defined(OS_CHROMEOS) || defined(OS_MACOSX)
194 show_create_shortcuts
= false;
195 #elif defined(USE_ASH)
196 if (browser
->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH
)
197 show_create_shortcuts
= false;
200 if (CommandLine::ForCurrentProcess()->HasSwitch(
201 switches::kEnableStreamlinedHostedApps
)) {
202 AddItemWithStringId(IDC_CREATE_HOSTED_APP
, IDS_CREATE_HOSTED_APP
);
203 AddSeparator(ui::NORMAL_SEPARATOR
);
204 } else if (show_create_shortcuts
) {
205 AddItemWithStringId(IDC_CREATE_SHORTCUTS
, IDS_CREATE_SHORTCUTS
);
206 AddSeparator(ui::NORMAL_SEPARATOR
);
209 AddItemWithStringId(IDC_MANAGE_EXTENSIONS
, IDS_SHOW_EXTENSIONS
);
211 if (chrome::CanOpenTaskManager())
212 AddItemWithStringId(IDC_TASK_MANAGER
, IDS_TASK_MANAGER
);
214 AddItemWithStringId(IDC_CLEAR_BROWSING_DATA
, IDS_CLEAR_BROWSING_DATA
);
216 AddSeparator(ui::NORMAL_SEPARATOR
);
218 #if defined(GOOGLE_CHROME_BUILD)
219 #if !defined(OS_CHROMEOS)
220 // Show IDC_FEEDBACK in "Tools" menu for non-ChromeOS platforms.
221 AddItemWithStringId(IDC_FEEDBACK
, IDS_FEEDBACK
);
222 AddSeparator(ui::NORMAL_SEPARATOR
);
224 #endif // GOOGLE_CHROME_BUILD
226 encoding_menu_model_
.reset(new EncodingMenuModel(browser
));
227 AddSubMenuWithStringId(IDC_ENCODING_MENU
, IDS_ENCODING_MENU
,
228 encoding_menu_model_
.get());
229 AddItemWithStringId(IDC_VIEW_SOURCE
, IDS_VIEW_SOURCE
);
230 AddItemWithStringId(IDC_DEV_TOOLS
, IDS_DEV_TOOLS
);
231 AddItemWithStringId(IDC_DEV_TOOLS_CONSOLE
, IDS_DEV_TOOLS_CONSOLE
);
232 AddItemWithStringId(IDC_DEV_TOOLS_DEVICES
, IDS_DEV_TOOLS_DEVICES
);
234 #if defined(ENABLE_PROFILING) && !defined(NO_TCMALLOC)
235 AddSeparator(ui::NORMAL_SEPARATOR
);
236 AddCheckItemWithStringId(IDC_PROFILING_ENABLED
, IDS_PROFILING_ENABLED
);
240 ////////////////////////////////////////////////////////////////////////////////
243 WrenchMenuModel::WrenchMenuModel(ui::AcceleratorProvider
* provider
,
246 : ui::SimpleMenuModel(this),
249 tab_strip_model_(browser_
->tab_strip_model()) {
251 UpdateZoomControls();
253 zoom_subscription_
= HostZoomMap::GetForBrowserContext(
254 browser
->profile())->AddZoomLevelChangedCallback(
255 base::Bind(&WrenchMenuModel::OnZoomLevelChanged
,
256 base::Unretained(this)));
258 tab_strip_model_
->AddObserver(this);
260 registrar_
.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
261 content::NotificationService::AllSources());
264 WrenchMenuModel::~WrenchMenuModel() {
265 if (tab_strip_model_
)
266 tab_strip_model_
->RemoveObserver(this);
269 bool WrenchMenuModel::DoesCommandIdDismissMenu(int command_id
) const {
270 return command_id
!= IDC_ZOOM_MINUS
&& command_id
!= IDC_ZOOM_PLUS
;
273 bool WrenchMenuModel::IsItemForCommandIdDynamic(int command_id
) const {
274 return command_id
== IDC_ZOOM_PERCENT_DISPLAY
||
275 #if defined(OS_MACOSX)
276 command_id
== IDC_FULLSCREEN
||
277 #elif defined(OS_WIN)
278 command_id
== IDC_PIN_TO_START_SCREEN
||
280 command_id
== IDC_UPGRADE_DIALOG
||
281 command_id
== IDC_SHOW_SIGNIN
;
284 base::string16
WrenchMenuModel::GetLabelForCommandId(int command_id
) const {
285 switch (command_id
) {
286 case IDC_ZOOM_PERCENT_DISPLAY
:
288 #if defined(OS_MACOSX)
289 case IDC_FULLSCREEN
: {
290 int string_id
= IDS_ENTER_FULLSCREEN_MAC
; // Default to Enter.
291 // Note: On startup, |window()| may be NULL.
292 if (browser_
->window() && browser_
->window()->IsFullscreen())
293 string_id
= IDS_EXIT_FULLSCREEN_MAC
;
294 return l10n_util::GetStringUTF16(string_id
);
296 #elif defined(OS_WIN)
297 case IDC_PIN_TO_START_SCREEN
: {
298 int string_id
= IDS_PIN_TO_START_SCREEN
;
299 WebContents
* web_contents
=
300 browser_
->tab_strip_model()->GetActiveWebContents();
301 MetroPinTabHelper
* tab_helper
=
302 web_contents
? MetroPinTabHelper::FromWebContents(web_contents
)
304 if (tab_helper
&& tab_helper
->IsPinned())
305 string_id
= IDS_UNPIN_FROM_START_SCREEN
;
306 return l10n_util::GetStringUTF16(string_id
);
309 case IDC_UPGRADE_DIALOG
:
310 return GetUpgradeDialogMenuItemName();
311 case IDC_SHOW_SIGNIN
:
312 return signin_ui_util::GetSigninMenuLabel(
313 browser_
->profile()->GetOriginalProfile());
316 return base::string16();
320 bool WrenchMenuModel::GetIconForCommandId(int command_id
,
321 gfx::Image
* icon
) const {
322 ui::ResourceBundle
& rb
= ui::ResourceBundle::GetSharedInstance();
323 switch (command_id
) {
324 case IDC_UPGRADE_DIALOG
: {
325 if (UpgradeDetector::GetInstance()->notify_upgrade()) {
326 *icon
= rb
.GetNativeImageNamed(
327 UpgradeDetector::GetInstance()->GetIconResourceID(
328 UpgradeDetector::UPGRADE_ICON_TYPE_MENU_ICON
));
333 case IDC_SHOW_SIGNIN
: {
334 GlobalError
* error
= signin_ui_util::GetSignedInServiceError(
335 browser_
->profile()->GetOriginalProfile());
337 int icon_id
= error
->MenuItemIconResourceID();
339 *icon
= rb
.GetNativeImageNamed(icon_id
);
351 void WrenchMenuModel::ExecuteCommand(int command_id
, int event_flags
) {
352 GlobalError
* error
= GlobalErrorServiceFactory::GetForProfile(
353 browser_
->profile())->GetGlobalErrorByMenuItemCommandID(command_id
);
355 error
->ExecuteMenuItem(browser_
);
359 if (command_id
== IDC_SHOW_SIGNIN
) {
360 // If a custom error message is being shown, handle it.
361 GlobalError
* error
= signin_ui_util::GetSignedInServiceError(
362 browser_
->profile()->GetOriginalProfile());
364 error
->ExecuteMenuItem(browser_
);
369 if (command_id
== IDC_HELP_PAGE_VIA_MENU
)
370 content::RecordAction(UserMetricsAction("ShowHelpTabViaWrenchMenu"));
372 if (command_id
== IDC_FULLSCREEN
) {
373 // We issue the UMA command here and not in BrowserCommandController or even
374 // FullscreenController since we want to be able to distinguish this event
375 // and a menu which is under development.
376 content::RecordAction(UserMetricsAction("EnterFullScreenWithWrenchMenu"));
379 chrome::ExecuteCommand(browser_
, command_id
);
382 bool WrenchMenuModel::IsCommandIdChecked(int command_id
) const {
383 if (command_id
== IDC_SHOW_BOOKMARK_BAR
) {
384 return browser_
->profile()->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar
);
385 } else if (command_id
== IDC_PROFILING_ENABLED
) {
386 return Profiling::BeingProfiled();
387 } else if (command_id
== IDC_TOGGLE_REQUEST_TABLET_SITE
) {
388 return chrome::IsRequestingTabletSite(browser_
);
394 bool WrenchMenuModel::IsCommandIdEnabled(int command_id
) const {
395 GlobalError
* error
= GlobalErrorServiceFactory::GetForProfile(
396 browser_
->profile())->GetGlobalErrorByMenuItemCommandID(command_id
);
400 return chrome::IsCommandEnabled(browser_
, command_id
);
403 bool WrenchMenuModel::IsCommandIdVisible(int command_id
) const {
404 switch (command_id
) {
406 case IDC_VIEW_INCOMPATIBILITIES
: {
407 EnumerateModulesModel
* loaded_modules
=
408 EnumerateModulesModel::GetInstance();
409 if (loaded_modules
->confirmed_bad_modules_detected() <= 0)
411 // We'll leave the wrench adornment on until the user clicks the link.
412 if (loaded_modules
->modules_to_notify_about() <= 0)
413 loaded_modules
->AcknowledgeConflictNotification();
416 case IDC_PIN_TO_START_SCREEN
:
417 return base::win::IsMetroProcess();
419 case IDC_VIEW_INCOMPATIBILITIES
:
420 case IDC_PIN_TO_START_SCREEN
:
423 case IDC_UPGRADE_DIALOG
:
424 return UpgradeDetector::GetInstance()->notify_upgrade();
425 #if !defined(OS_LINUX) || defined(USE_AURA)
426 case IDC_BOOKMARK_PAGE
:
427 return !chrome::ShouldRemoveBookmarkThisPageUI(browser_
->profile());
428 case IDC_BOOKMARK_ALL_TABS
:
429 return !chrome::ShouldRemoveBookmarkOpenPagesUI(browser_
->profile());
436 bool WrenchMenuModel::GetAcceleratorForCommandId(
438 ui::Accelerator
* accelerator
) {
439 return provider_
->GetAcceleratorForCommandId(command_id
, accelerator
);
442 void WrenchMenuModel::ActiveTabChanged(WebContents
* old_contents
,
443 WebContents
* new_contents
,
446 // The user has switched between tabs and the new tab may have a different
448 UpdateZoomControls();
451 void WrenchMenuModel::TabReplacedAt(TabStripModel
* tab_strip_model
,
452 WebContents
* old_contents
,
453 WebContents
* new_contents
,
455 UpdateZoomControls();
458 void WrenchMenuModel::TabStripModelDeleted() {
459 // During views shutdown, the tabstrip model/browser is deleted first, while
460 // it is the opposite in gtk land.
461 tab_strip_model_
->RemoveObserver(this);
462 tab_strip_model_
= NULL
;
465 void WrenchMenuModel::Observe(int type
,
466 const content::NotificationSource
& source
,
467 const content::NotificationDetails
& details
) {
468 DCHECK(type
== content::NOTIFICATION_NAV_ENTRY_COMMITTED
);
469 UpdateZoomControls();
473 WrenchMenuModel::WrenchMenuModel()
474 : ui::SimpleMenuModel(this),
477 tab_strip_model_(NULL
) {
480 bool WrenchMenuModel::ShouldShowNewIncognitoWindowMenuItem() {
481 if (browser_
->profile()->IsManaged())
484 return !browser_
->profile()->IsGuestSession();
487 void WrenchMenuModel::Build(bool is_new_menu
) {
489 AddItem(IDC_VIEW_INCOMPATIBILITIES
,
490 l10n_util::GetStringUTF16(IDS_VIEW_INCOMPATIBILITIES
));
491 EnumerateModulesModel
* model
=
492 EnumerateModulesModel::GetInstance();
493 if (model
->modules_to_notify_about() > 0 ||
494 model
->confirmed_bad_modules_detected() > 0)
495 AddSeparator(ui::NORMAL_SEPARATOR
);
498 AddItemWithStringId(IDC_NEW_TAB
, IDS_NEW_TAB
);
499 AddItemWithStringId(IDC_NEW_WINDOW
, IDS_NEW_WINDOW
);
501 if (ShouldShowNewIncognitoWindowMenuItem())
502 AddItemWithStringId(IDC_NEW_INCOGNITO_WINDOW
, IDS_NEW_INCOGNITO_WINDOW
);
504 #if defined(OS_WIN) && !defined(NDEBUG) && defined(USE_ASH)
505 if (base::win::GetVersion() < base::win::VERSION_WIN8
&&
506 chrome::HOST_DESKTOP_TYPE_NATIVE
!= chrome::HOST_DESKTOP_TYPE_ASH
) {
507 AddItemWithStringId(IDC_TOGGLE_ASH_DESKTOP
,
508 ash::Shell::HasInstance() ? IDS_CLOSE_ASH_DESKTOP
:
509 IDS_OPEN_ASH_DESKTOP
);
513 bookmark_sub_menu_model_
.reset(new BookmarkSubMenuModel(this, browser_
));
514 AddSubMenuWithStringId(IDC_BOOKMARKS_MENU
, IDS_BOOKMARKS_MENU
,
515 bookmark_sub_menu_model_
.get());
517 if (chrome::IsInstantExtendedAPIEnabled()) {
518 recent_tabs_sub_menu_model_
.reset(new RecentTabsSubMenuModel(provider_
,
521 AddSubMenuWithStringId(IDC_RECENT_TABS_MENU
, IDS_RECENT_TABS_MENU
,
522 recent_tabs_sub_menu_model_
.get());
527 #if defined(USE_AURA)
528 if (base::win::GetVersion() >= base::win::VERSION_WIN8
&&
529 content::GpuDataManager::GetInstance()->CanUseGpuBrowserCompositor()) {
530 if (browser_
->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH
) {
531 // Metro mode, add the 'Relaunch Chrome in desktop mode'.
532 AddSeparator(ui::NORMAL_SEPARATOR
);
533 AddItemWithStringId(IDC_WIN8_DESKTOP_RESTART
, IDS_WIN8_DESKTOP_RESTART
);
535 // In Windows 8 desktop, add the 'Relaunch Chrome in Windows 8 mode'.
536 AddSeparator(ui::NORMAL_SEPARATOR
);
537 AddItemWithStringId(IDC_WIN8_METRO_RESTART
, IDS_WIN8_METRO_RESTART
);
541 if (base::win::IsMetroProcess()) {
542 // Metro mode, add the 'Relaunch Chrome in desktop mode'.
543 AddSeparator(ui::NORMAL_SEPARATOR
);
544 AddItemWithStringId(IDC_WIN8_DESKTOP_RESTART
, IDS_WIN8_DESKTOP_RESTART
);
546 // In Windows 8 desktop, add the 'Relaunch Chrome in Windows 8 mode'.
547 AddSeparator(ui::NORMAL_SEPARATOR
);
548 AddItemWithStringId(IDC_WIN8_METRO_RESTART
, IDS_WIN8_METRO_RESTART
);
554 // Append the full menu including separators. The final separator only gets
555 // appended when this is a touch menu - otherwise it would get added twice.
556 CreateCutCopyPasteMenu(is_new_menu
);
559 CreateZoomMenu(is_new_menu
);
561 AddItemWithStringId(IDC_SAVE_PAGE
, IDS_SAVE_PAGE
);
562 AddItemWithStringId(IDC_FIND
, IDS_FIND
);
563 AddItemWithStringId(IDC_PRINT
, IDS_PRINT
);
565 tools_menu_model_
.reset(new ToolsMenuModel(this, browser_
));
566 // In case of touch this is the last item.
568 AddSubMenuWithStringId(IDC_ZOOM_MENU
, IDS_TOOLS_MENU
,
569 tools_menu_model_
.get());
573 CreateZoomMenu(is_new_menu
);
575 AddSeparator(ui::NORMAL_SEPARATOR
);
577 AddItemWithStringId(IDC_SHOW_HISTORY
, IDS_SHOW_HISTORY
);
578 AddItemWithStringId(IDC_SHOW_DOWNLOADS
, IDS_SHOW_DOWNLOADS
);
579 AddSeparator(ui::NORMAL_SEPARATOR
);
581 #if !defined(OS_CHROMEOS)
582 // No "Sign in to Chromium..." menu item on ChromeOS.
583 SigninManager
* signin
= SigninManagerFactory::GetForProfile(
584 browser_
->profile()->GetOriginalProfile());
585 if (signin
&& signin
->IsSigninAllowed()) {
586 const base::string16 short_product_name
=
587 l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME
);
588 AddItem(IDC_SHOW_SYNC_SETUP
, l10n_util::GetStringFUTF16(
589 IDS_SYNC_MENU_PRE_SYNCED_LABEL
, short_product_name
));
590 AddSeparator(ui::NORMAL_SEPARATOR
);
594 AddItemWithStringId(IDC_OPTIONS
, IDS_SETTINGS
);
596 #if defined(OS_CHROMEOS)
597 if (CommandLine::ForCurrentProcess()->HasSwitch(
598 chromeos::switches::kEnableRequestTabletSite
))
599 AddCheckItemWithStringId(IDC_TOGGLE_REQUEST_TABLET_SITE
,
600 IDS_TOGGLE_REQUEST_TABLET_SITE
);
603 // On ChromeOS-Touch, we don't want the about menu option.
604 #if defined(OS_CHROMEOS)
608 AddItem(IDC_ABOUT
, l10n_util::GetStringUTF16(IDS_ABOUT
));
611 if (browser_defaults::kShowUpgradeMenuItem
)
612 AddItem(IDC_UPGRADE_DIALOG
, GetUpgradeDialogMenuItemName());
615 SetIcon(GetIndexOfCommandId(IDC_VIEW_INCOMPATIBILITIES
),
616 ui::ResourceBundle::GetSharedInstance().
617 GetNativeImageNamed(IDR_INPUT_ALERT_MENU
));
621 AddItemWithStringId(IDC_HELP_PAGE_VIA_MENU
, IDS_HELP_PAGE
);
623 if (browser_defaults::kShowHelpMenuItemIcon
) {
624 ui::ResourceBundle
& rb
= ResourceBundle::GetSharedInstance();
625 SetIcon(GetIndexOfCommandId(IDC_HELP_PAGE_VIA_MENU
),
626 rb
.GetNativeImageNamed(IDR_HELP_MENU
));
630 #if defined(GOOGLE_CHROME_BUILD)
631 #if defined(OS_CHROMEOS)
632 AddItemWithStringId(IDC_FEEDBACK
, IDS_FEEDBACK
);
636 AddGlobalErrorMenuItems();
639 AddSubMenuWithStringId(IDC_ZOOM_MENU
, IDS_MORE_TOOLS_MENU
,
640 tools_menu_model_
.get());
643 bool show_exit_menu
= browser_defaults::kShowExitMenuItem
;
645 if (browser_
->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH
)
646 show_exit_menu
= false;
649 if (show_exit_menu
) {
650 AddSeparator(ui::NORMAL_SEPARATOR
);
651 AddItemWithStringId(IDC_EXIT
, IDS_EXIT
);
655 void WrenchMenuModel::AddGlobalErrorMenuItems() {
656 // TODO(sail): Currently we only build the wrench menu once per browser
657 // window. This means that if a new error is added after the menu is built
658 // it won't show in the existing wrench menu. To fix this we need to some
659 // how update the menu if new errors are added.
660 ui::ResourceBundle
& rb
= ui::ResourceBundle::GetSharedInstance();
661 // GetSignedInServiceErrors() can modify the global error list, so call it
662 // before iterating through that list below.
663 std::vector
<GlobalError
*> signin_errors
=
664 signin_ui_util::GetSignedInServiceErrors(
665 browser_
->profile()->GetOriginalProfile());
666 const GlobalErrorService::GlobalErrorList
& errors
=
667 GlobalErrorServiceFactory::GetForProfile(browser_
->profile())->errors();
668 for (GlobalErrorService::GlobalErrorList::const_iterator
669 it
= errors
.begin(); it
!= errors
.end(); ++it
) {
670 GlobalError
* error
= *it
;
672 if (error
->HasMenuItem()) {
673 #if !defined(OS_CHROMEOS)
674 // Don't add a signin error if it's already being displayed elsewhere.
675 if (std::find(signin_errors
.begin(), signin_errors
.end(), error
) !=
676 signin_errors
.end()) {
677 MenuModel
* model
= this;
679 if (MenuModel::GetModelAndIndexForCommandId(
680 IDC_SHOW_SIGNIN
, &model
, &index
)) {
686 AddItem(error
->MenuItemCommandID(), error
->MenuItemLabel());
687 int icon_id
= error
->MenuItemIconResourceID();
689 const gfx::Image
& image
= rb
.GetNativeImageNamed(icon_id
);
690 SetIcon(GetIndexOfCommandId(error
->MenuItemCommandID()),
697 void WrenchMenuModel::CreateCutCopyPasteMenu(bool new_menu
) {
698 AddSeparator(new_menu
? ui::LOWER_SEPARATOR
: ui::NORMAL_SEPARATOR
);
700 #if defined(OS_POSIX) && !defined(TOOLKIT_VIEWS)
701 // WARNING: Mac does not use the ButtonMenuItemModel, but instead defines the
702 // layout for this menu item in Toolbar.xib. It does, however, use the
703 // command_id value from AddButtonItem() to identify this special item.
704 edit_menu_item_model_
.reset(new ui::ButtonMenuItemModel(IDS_EDIT
, this));
705 edit_menu_item_model_
->AddGroupItemWithStringId(IDC_CUT
, IDS_CUT
);
706 edit_menu_item_model_
->AddGroupItemWithStringId(IDC_COPY
, IDS_COPY
);
707 edit_menu_item_model_
->AddGroupItemWithStringId(IDC_PASTE
, IDS_PASTE
);
708 AddButtonItem(IDC_EDIT_MENU
, edit_menu_item_model_
.get());
710 // WARNING: views/wrench_menu assumes these items are added in this order. If
711 // you change the order you'll need to update wrench_menu as well.
712 AddItemWithStringId(IDC_CUT
, IDS_CUT
);
713 AddItemWithStringId(IDC_COPY
, IDS_COPY
);
714 AddItemWithStringId(IDC_PASTE
, IDS_PASTE
);
718 AddSeparator(ui::UPPER_SEPARATOR
);
721 void WrenchMenuModel::CreateZoomMenu(bool new_menu
) {
722 // This menu needs to be enclosed by separators.
723 AddSeparator(new_menu
? ui::LOWER_SEPARATOR
: ui::NORMAL_SEPARATOR
);
725 #if defined(OS_POSIX) && !defined(TOOLKIT_VIEWS)
726 // WARNING: Mac does not use the ButtonMenuItemModel, but instead defines the
727 // layout for this menu item in Toolbar.xib. It does, however, use the
728 // command_id value from AddButtonItem() to identify this special item.
729 zoom_menu_item_model_
.reset(
730 new ui::ButtonMenuItemModel(IDS_ZOOM_MENU
, this));
731 zoom_menu_item_model_
->AddGroupItemWithStringId(
732 IDC_ZOOM_MINUS
, IDS_ZOOM_MINUS2
);
733 zoom_menu_item_model_
->AddButtonLabel(IDC_ZOOM_PERCENT_DISPLAY
,
735 zoom_menu_item_model_
->AddGroupItemWithStringId(
736 IDC_ZOOM_PLUS
, IDS_ZOOM_PLUS2
);
737 zoom_menu_item_model_
->AddSpace();
738 zoom_menu_item_model_
->AddItemWithImage(
739 IDC_FULLSCREEN
, IDR_FULLSCREEN_MENU_BUTTON
);
740 AddButtonItem(IDC_ZOOM_MENU
, zoom_menu_item_model_
.get());
742 // WARNING: views/wrench_menu assumes these items are added in this order. If
743 // you change the order you'll need to update wrench_menu as well.
744 AddItemWithStringId(IDC_ZOOM_MINUS
, IDS_ZOOM_MINUS
);
745 AddItemWithStringId(IDC_ZOOM_PLUS
, IDS_ZOOM_PLUS
);
746 AddItemWithStringId(IDC_FULLSCREEN
, IDS_FULLSCREEN
);
749 AddSeparator(new_menu
? ui::UPPER_SEPARATOR
: ui::NORMAL_SEPARATOR
);
752 void WrenchMenuModel::UpdateZoomControls() {
753 bool enable_increment
= false;
754 bool enable_decrement
= false;
755 int zoom_percent
= 100;
756 if (browser_
->tab_strip_model()->GetActiveWebContents()) {
758 browser_
->tab_strip_model()->GetActiveWebContents()->GetZoomPercent(
759 &enable_increment
, &enable_decrement
);
761 zoom_label_
= l10n_util::GetStringFUTF16(
762 IDS_ZOOM_PERCENT
, base::IntToString16(zoom_percent
));
765 void WrenchMenuModel::OnZoomLevelChanged(
766 const content::HostZoomMap::ZoomLevelChange
& change
) {
767 UpdateZoomControls();