| OLD | NEW |
| (Empty) |
| 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/toolbar/wrench_menu_model.h" | |
| 6 | |
| 7 #include <algorithm> | |
| 8 #include <cmath> | |
| 9 | |
| 10 #include "base/command_line.h" | |
| 11 #include "base/metrics/histogram.h" | |
| 12 #include "base/prefs/pref_service.h" | |
| 13 #include "base/strings/string_number_conversions.h" | |
| 14 #include "base/strings/string_util.h" | |
| 15 #include "base/strings/utf_string_conversions.h" | |
| 16 #include "chrome/app/chrome_command_ids.h" | |
| 17 #include "chrome/browser/browser_process.h" | |
| 18 #include "chrome/browser/defaults.h" | |
| 19 #include "chrome/browser/extensions/extension_util.h" | |
| 20 #include "chrome/browser/prefs/incognito_mode_prefs.h" | |
| 21 #include "chrome/browser/profiles/profile.h" | |
| 22 #include "chrome/browser/profiles/profile_manager.h" | |
| 23 #include "chrome/browser/search/search.h" | |
| 24 #include "chrome/browser/signin/signin_manager_factory.h" | |
| 25 #include "chrome/browser/signin/signin_ui_util.h" | |
| 26 #include "chrome/browser/task_manager/task_manager.h" | |
| 27 #include "chrome/browser/ui/bookmarks/bookmark_utils.h" | |
| 28 #include "chrome/browser/ui/browser.h" | |
| 29 #include "chrome/browser/ui/browser_commands.h" | |
| 30 #include "chrome/browser/ui/browser_finder.h" | |
| 31 #include "chrome/browser/ui/browser_window.h" | |
| 32 #include "chrome/browser/ui/global_error/global_error.h" | |
| 33 #include "chrome/browser/ui/global_error/global_error_service.h" | |
| 34 #include "chrome/browser/ui/global_error/global_error_service_factory.h" | |
| 35 #include "chrome/browser/ui/tabs/tab_strip_model.h" | |
| 36 #include "chrome/browser/ui/toolbar/bookmark_sub_menu_model.h" | |
| 37 #include "chrome/browser/ui/toolbar/encoding_menu_controller.h" | |
| 38 #include "chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h" | |
| 39 #include "chrome/browser/ui/toolbar/toolbar_actions_bar.h" | |
| 40 #include "chrome/browser/upgrade_detector.h" | |
| 41 #include "chrome/common/chrome_paths.h" | |
| 42 #include "chrome/common/chrome_switches.h" | |
| 43 #include "chrome/common/profiling.h" | |
| 44 #include "chrome/grit/chromium_strings.h" | |
| 45 #include "chrome/grit/generated_resources.h" | |
| 46 #include "components/bookmarks/common/bookmark_pref_names.h" | |
| 47 #include "components/dom_distiller/core/dom_distiller_switches.h" | |
| 48 #include "components/signin/core/browser/signin_manager.h" | |
| 49 #include "components/signin/core/common/profile_management_switches.h" | |
| 50 #include "components/ui/zoom/zoom_controller.h" | |
| 51 #include "components/ui/zoom/zoom_event_manager.h" | |
| 52 #include "content/public/browser/host_zoom_map.h" | |
| 53 #include "content/public/browser/navigation_entry.h" | |
| 54 #include "content/public/browser/notification_service.h" | |
| 55 #include "content/public/browser/notification_source.h" | |
| 56 #include "content/public/browser/notification_types.h" | |
| 57 #include "content/public/browser/user_metrics.h" | |
| 58 #include "content/public/browser/web_contents.h" | |
| 59 #include "extensions/common/feature_switch.h" | |
| 60 #include "grit/theme_resources.h" | |
| 61 #include "ui/base/l10n/l10n_util.h" | |
| 62 #include "ui/base/layout.h" | |
| 63 #include "ui/base/models/button_menu_item_model.h" | |
| 64 #include "ui/base/resource/resource_bundle.h" | |
| 65 #include "ui/gfx/image/image.h" | |
| 66 #include "ui/gfx/image/image_skia.h" | |
| 67 | |
| 68 #if defined(OS_CHROMEOS) | |
| 69 #include "chromeos/chromeos_switches.h" | |
| 70 #endif | |
| 71 | |
| 72 #if defined(OS_WIN) | |
| 73 #include "base/win/metro.h" | |
| 74 #include "base/win/windows_version.h" | |
| 75 #include "chrome/browser/enumerate_modules_model_win.h" | |
| 76 #include "chrome/browser/ui/metro_pin_tab_helper_win.h" | |
| 77 #include "content/public/browser/gpu_data_manager.h" | |
| 78 #endif | |
| 79 | |
| 80 #if defined(USE_ASH) | |
| 81 #include "ash/shell.h" | |
| 82 #endif | |
| 83 | |
| 84 using base::UserMetricsAction; | |
| 85 using content::WebContents; | |
| 86 | |
| 87 namespace { | |
| 88 | |
| 89 #if defined(OS_MACOSX) | |
| 90 // An empty command used because of a bug in AppKit menus. | |
| 91 // See comment in CreateActionToolbarOverflowMenu(). | |
| 92 const int kEmptyMenuItemCommand = 0; | |
| 93 #endif | |
| 94 | |
| 95 // Conditionally return the update app menu item title based on upgrade detector | |
| 96 // state. | |
| 97 base::string16 GetUpgradeDialogMenuItemName() { | |
| 98 if (UpgradeDetector::GetInstance()->is_outdated_install() || | |
| 99 UpgradeDetector::GetInstance()->is_outdated_install_no_au()) { | |
| 100 return l10n_util::GetStringUTF16(IDS_UPGRADE_BUBBLE_MENU_ITEM); | |
| 101 } else { | |
| 102 return l10n_util::GetStringUTF16(IDS_UPDATE_NOW); | |
| 103 } | |
| 104 } | |
| 105 | |
| 106 #if defined(OS_WIN) | |
| 107 bool GetRestartMenuItemIfRequired(const chrome::HostDesktopType& desktop_type, | |
| 108 int* command_id, | |
| 109 int* string_id) { | |
| 110 if (base::win::GetVersion() == base::win::VERSION_WIN8 || | |
| 111 base::win::GetVersion() == base::win::VERSION_WIN8_1) { | |
| 112 if (desktop_type != chrome::HOST_DESKTOP_TYPE_ASH) { | |
| 113 *command_id = IDC_WIN8_METRO_RESTART; | |
| 114 *string_id = IDS_WIN8_METRO_RESTART; | |
| 115 } else { | |
| 116 *command_id = IDC_WIN_DESKTOP_RESTART; | |
| 117 *string_id = IDS_WIN_DESKTOP_RESTART; | |
| 118 } | |
| 119 return true; | |
| 120 } | |
| 121 | |
| 122 // Windows 7 ASH mode is only supported in DEBUG for now. | |
| 123 #if !defined(NDEBUG) | |
| 124 // Windows 8 can support ASH mode using WARP, but Windows 7 requires a working | |
| 125 // GPU compositor. | |
| 126 if (base::win::GetVersion() == base::win::VERSION_WIN7 && | |
| 127 content::GpuDataManager::GetInstance()->CanUseGpuBrowserCompositor()) { | |
| 128 if (desktop_type != chrome::HOST_DESKTOP_TYPE_ASH) { | |
| 129 *command_id = IDC_WIN_CHROMEOS_RESTART; | |
| 130 *string_id = IDS_WIN_CHROMEOS_RESTART; | |
| 131 } else { | |
| 132 *command_id = IDC_WIN_DESKTOP_RESTART; | |
| 133 *string_id = IDS_WIN_DESKTOP_RESTART; | |
| 134 } | |
| 135 return true; | |
| 136 } | |
| 137 #endif | |
| 138 return false; | |
| 139 } | |
| 140 #endif | |
| 141 | |
| 142 } // namespace | |
| 143 | |
| 144 //////////////////////////////////////////////////////////////////////////////// | |
| 145 // EncodingMenuModel | |
| 146 | |
| 147 EncodingMenuModel::EncodingMenuModel(Browser* browser) | |
| 148 : ui::SimpleMenuModel(this), | |
| 149 browser_(browser) { | |
| 150 Build(); | |
| 151 } | |
| 152 | |
| 153 EncodingMenuModel::~EncodingMenuModel() { | |
| 154 } | |
| 155 | |
| 156 void EncodingMenuModel::Build() { | |
| 157 EncodingMenuController::EncodingMenuItemList encoding_menu_items; | |
| 158 EncodingMenuController encoding_menu_controller; | |
| 159 encoding_menu_controller.GetEncodingMenuItems(browser_->profile(), | |
| 160 &encoding_menu_items); | |
| 161 | |
| 162 int group_id = 0; | |
| 163 EncodingMenuController::EncodingMenuItemList::iterator it = | |
| 164 encoding_menu_items.begin(); | |
| 165 for (; it != encoding_menu_items.end(); ++it) { | |
| 166 int id = it->first; | |
| 167 base::string16& label = it->second; | |
| 168 if (id == 0) { | |
| 169 AddSeparator(ui::NORMAL_SEPARATOR); | |
| 170 } else { | |
| 171 if (id == IDC_ENCODING_AUTO_DETECT) { | |
| 172 AddCheckItem(id, label); | |
| 173 } else { | |
| 174 // Use the id of the first radio command as the id of the group. | |
| 175 if (group_id <= 0) | |
| 176 group_id = id; | |
| 177 AddRadioItem(id, label, group_id); | |
| 178 } | |
| 179 } | |
| 180 } | |
| 181 } | |
| 182 | |
| 183 bool EncodingMenuModel::IsCommandIdChecked(int command_id) const { | |
| 184 WebContents* current_tab = | |
| 185 browser_->tab_strip_model()->GetActiveWebContents(); | |
| 186 if (!current_tab) | |
| 187 return false; | |
| 188 EncodingMenuController controller; | |
| 189 return controller.IsItemChecked(browser_->profile(), | |
| 190 current_tab->GetEncoding(), command_id); | |
| 191 } | |
| 192 | |
| 193 bool EncodingMenuModel::IsCommandIdEnabled(int command_id) const { | |
| 194 bool enabled = chrome::IsCommandEnabled(browser_, command_id); | |
| 195 // Special handling for the contents of the Encoding submenu. On Mac OS, | |
| 196 // instead of enabling/disabling the top-level menu item, the submenu's | |
| 197 // contents get disabled, per Apple's HIG. | |
| 198 #if defined(OS_MACOSX) | |
| 199 enabled &= chrome::IsCommandEnabled(browser_, IDC_ENCODING_MENU); | |
| 200 #endif | |
| 201 return enabled; | |
| 202 } | |
| 203 | |
| 204 bool EncodingMenuModel::GetAcceleratorForCommandId( | |
| 205 int command_id, | |
| 206 ui::Accelerator* accelerator) { | |
| 207 return false; | |
| 208 } | |
| 209 | |
| 210 void EncodingMenuModel::ExecuteCommand(int command_id, int event_flags) { | |
| 211 chrome::ExecuteCommand(browser_, command_id); | |
| 212 } | |
| 213 | |
| 214 //////////////////////////////////////////////////////////////////////////////// | |
| 215 // ZoomMenuModel | |
| 216 | |
| 217 ZoomMenuModel::ZoomMenuModel(ui::SimpleMenuModel::Delegate* delegate) | |
| 218 : SimpleMenuModel(delegate) { | |
| 219 Build(); | |
| 220 } | |
| 221 | |
| 222 ZoomMenuModel::~ZoomMenuModel() { | |
| 223 } | |
| 224 | |
| 225 void ZoomMenuModel::Build() { | |
| 226 AddItemWithStringId(IDC_ZOOM_PLUS, IDS_ZOOM_PLUS); | |
| 227 AddItemWithStringId(IDC_ZOOM_NORMAL, IDS_ZOOM_NORMAL); | |
| 228 AddItemWithStringId(IDC_ZOOM_MINUS, IDS_ZOOM_MINUS); | |
| 229 } | |
| 230 | |
| 231 //////////////////////////////////////////////////////////////////////////////// | |
| 232 // HelpMenuModel | |
| 233 | |
| 234 #if defined(GOOGLE_CHROME_BUILD) | |
| 235 | |
| 236 class WrenchMenuModel::HelpMenuModel : public ui::SimpleMenuModel { | |
| 237 public: | |
| 238 HelpMenuModel(ui::SimpleMenuModel::Delegate* delegate, | |
| 239 Browser* browser) | |
| 240 : SimpleMenuModel(delegate) { | |
| 241 Build(browser); | |
| 242 } | |
| 243 | |
| 244 private: | |
| 245 void Build(Browser* browser) { | |
| 246 #if defined(OS_CHROMEOS) && defined(OFFICIAL_BUILD) | |
| 247 int help_string_id = IDS_GET_HELP; | |
| 248 #else | |
| 249 int help_string_id = IDS_HELP_PAGE; | |
| 250 #endif | |
| 251 AddItem(IDC_ABOUT, l10n_util::GetStringUTF16(IDS_ABOUT)); | |
| 252 AddItemWithStringId(IDC_HELP_PAGE_VIA_MENU, help_string_id); | |
| 253 if (browser_defaults::kShowHelpMenuItemIcon) { | |
| 254 ui::ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | |
| 255 SetIcon(GetIndexOfCommandId(IDC_HELP_PAGE_VIA_MENU), | |
| 256 rb.GetNativeImageNamed(IDR_HELP_MENU)); | |
| 257 } | |
| 258 AddItemWithStringId(IDC_FEEDBACK, IDS_FEEDBACK); | |
| 259 } | |
| 260 | |
| 261 DISALLOW_COPY_AND_ASSIGN(HelpMenuModel); | |
| 262 }; | |
| 263 | |
| 264 #endif // defined(GOOGLE_CHROME_BUILD) | |
| 265 | |
| 266 //////////////////////////////////////////////////////////////////////////////// | |
| 267 // ToolsMenuModel | |
| 268 | |
| 269 ToolsMenuModel::ToolsMenuModel(ui::SimpleMenuModel::Delegate* delegate, | |
| 270 Browser* browser) | |
| 271 : SimpleMenuModel(delegate) { | |
| 272 Build(browser); | |
| 273 } | |
| 274 | |
| 275 ToolsMenuModel::~ToolsMenuModel() {} | |
| 276 | |
| 277 // More tools submenu is constructed as follows: | |
| 278 // - Page specific actions overflow (save page, adding to taskbar). | |
| 279 // - Browser / OS level tools (extensions, task manager). | |
| 280 // - Developer tools. | |
| 281 // - Option to enable profiling. | |
| 282 void ToolsMenuModel::Build(Browser* browser) { | |
| 283 bool show_create_shortcuts = true; | |
| 284 #if defined(OS_CHROMEOS) || defined(OS_MACOSX) | |
| 285 show_create_shortcuts = false; | |
| 286 #elif defined(USE_ASH) | |
| 287 if (browser->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH) | |
| 288 show_create_shortcuts = false; | |
| 289 #endif | |
| 290 AddItemWithStringId(IDC_SAVE_PAGE, IDS_SAVE_PAGE); | |
| 291 if (extensions::util::IsNewBookmarkAppsEnabled()) { | |
| 292 #if defined(OS_MACOSX) | |
| 293 int string_id = IDS_ADD_TO_APPLICATIONS; | |
| 294 #elif defined(OS_WIN) | |
| 295 int string_id = IDS_ADD_TO_TASKBAR; | |
| 296 if (base::win::GetVersion() >= base::win::VERSION_WIN10) { | |
| 297 // This is currently non-functional on Win10 and above so change it to be | |
| 298 // a link to the generic "create shortcuts" dialog which will allow for | |
| 299 // a desktop shortcut. | |
| 300 AddItemWithStringId(IDC_CREATE_SHORTCUTS, IDS_CREATE_SHORTCUTS); | |
| 301 string_id = 0; // Avoids AddItemWithStringId below. | |
| 302 } | |
| 303 #else | |
| 304 int string_id = IDS_ADD_TO_DESKTOP; | |
| 305 #endif | |
| 306 #if defined(USE_ASH) | |
| 307 if (browser->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH) | |
| 308 string_id = IDS_ADD_TO_SHELF; | |
| 309 #endif | |
| 310 if (string_id) | |
| 311 AddItemWithStringId(IDC_CREATE_HOSTED_APP, string_id); | |
| 312 } else if (show_create_shortcuts) { | |
| 313 AddItemWithStringId(IDC_CREATE_SHORTCUTS, IDS_CREATE_SHORTCUTS); | |
| 314 } | |
| 315 | |
| 316 AddSeparator(ui::NORMAL_SEPARATOR); | |
| 317 AddItemWithStringId(IDC_CLEAR_BROWSING_DATA, IDS_CLEAR_BROWSING_DATA); | |
| 318 AddItemWithStringId(IDC_MANAGE_EXTENSIONS, IDS_SHOW_EXTENSIONS); | |
| 319 if (chrome::CanOpenTaskManager()) | |
| 320 AddItemWithStringId(IDC_TASK_MANAGER, IDS_TASK_MANAGER); | |
| 321 #if defined(OS_CHROMEOS) | |
| 322 AddItemWithStringId(IDC_TAKE_SCREENSHOT, IDS_TAKE_SCREENSHOT); | |
| 323 #endif | |
| 324 encoding_menu_model_.reset(new EncodingMenuModel(browser)); | |
| 325 AddSubMenuWithStringId(IDC_ENCODING_MENU, IDS_ENCODING_MENU, | |
| 326 encoding_menu_model_.get()); | |
| 327 | |
| 328 AddSeparator(ui::NORMAL_SEPARATOR); | |
| 329 AddItemWithStringId(IDC_DEV_TOOLS, IDS_DEV_TOOLS); | |
| 330 | |
| 331 #if defined(ENABLE_PROFILING) && !defined(NO_TCMALLOC) | |
| 332 AddSeparator(ui::NORMAL_SEPARATOR); | |
| 333 AddCheckItemWithStringId(IDC_PROFILING_ENABLED, IDS_PROFILING_ENABLED); | |
| 334 #endif | |
| 335 } | |
| 336 | |
| 337 //////////////////////////////////////////////////////////////////////////////// | |
| 338 // WrenchMenuModel | |
| 339 | |
| 340 WrenchMenuModel::WrenchMenuModel(ui::AcceleratorProvider* provider, | |
| 341 Browser* browser) | |
| 342 : ui::SimpleMenuModel(this), | |
| 343 uma_action_recorded_(false), | |
| 344 provider_(provider), | |
| 345 browser_(browser) { | |
| 346 Build(); | |
| 347 UpdateZoomControls(); | |
| 348 | |
| 349 browser_zoom_subscription_ = | |
| 350 ui_zoom::ZoomEventManager::GetForBrowserContext(browser->profile()) | |
| 351 ->AddZoomLevelChangedCallback(base::Bind( | |
| 352 &WrenchMenuModel::OnZoomLevelChanged, base::Unretained(this))); | |
| 353 | |
| 354 browser_->tab_strip_model()->AddObserver(this); | |
| 355 | |
| 356 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | |
| 357 content::NotificationService::AllSources()); | |
| 358 } | |
| 359 | |
| 360 WrenchMenuModel::~WrenchMenuModel() { | |
| 361 if (browser_) // Null in tests. | |
| 362 browser_->tab_strip_model()->RemoveObserver(this); | |
| 363 } | |
| 364 | |
| 365 bool WrenchMenuModel::DoesCommandIdDismissMenu(int command_id) const { | |
| 366 return command_id != IDC_ZOOM_MINUS && command_id != IDC_ZOOM_PLUS; | |
| 367 } | |
| 368 | |
| 369 bool WrenchMenuModel::IsItemForCommandIdDynamic(int command_id) const { | |
| 370 return command_id == IDC_ZOOM_PERCENT_DISPLAY || | |
| 371 #if defined(OS_MACOSX) | |
| 372 command_id == IDC_FULLSCREEN || | |
| 373 #elif defined(OS_WIN) | |
| 374 command_id == IDC_PIN_TO_START_SCREEN || | |
| 375 #endif | |
| 376 command_id == IDC_UPGRADE_DIALOG; | |
| 377 } | |
| 378 | |
| 379 base::string16 WrenchMenuModel::GetLabelForCommandId(int command_id) const { | |
| 380 switch (command_id) { | |
| 381 case IDC_ZOOM_PERCENT_DISPLAY: | |
| 382 return zoom_label_; | |
| 383 #if defined(OS_MACOSX) | |
| 384 case IDC_FULLSCREEN: { | |
| 385 int string_id = IDS_ENTER_FULLSCREEN_MAC; // Default to Enter. | |
| 386 // Note: On startup, |window()| may be NULL. | |
| 387 if (browser_->window() && browser_->window()->IsFullscreen()) | |
| 388 string_id = IDS_EXIT_FULLSCREEN_MAC; | |
| 389 return l10n_util::GetStringUTF16(string_id); | |
| 390 } | |
| 391 #elif defined(OS_WIN) | |
| 392 case IDC_PIN_TO_START_SCREEN: { | |
| 393 int string_id = IDS_PIN_TO_START_SCREEN; | |
| 394 WebContents* web_contents = | |
| 395 browser_->tab_strip_model()->GetActiveWebContents(); | |
| 396 MetroPinTabHelper* tab_helper = | |
| 397 web_contents ? MetroPinTabHelper::FromWebContents(web_contents) | |
| 398 : NULL; | |
| 399 if (tab_helper && tab_helper->IsPinned()) | |
| 400 string_id = IDS_UNPIN_FROM_START_SCREEN; | |
| 401 return l10n_util::GetStringUTF16(string_id); | |
| 402 } | |
| 403 #endif | |
| 404 case IDC_UPGRADE_DIALOG: | |
| 405 return GetUpgradeDialogMenuItemName(); | |
| 406 default: | |
| 407 NOTREACHED(); | |
| 408 return base::string16(); | |
| 409 } | |
| 410 } | |
| 411 | |
| 412 bool WrenchMenuModel::GetIconForCommandId(int command_id, | |
| 413 gfx::Image* icon) const { | |
| 414 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | |
| 415 switch (command_id) { | |
| 416 case IDC_UPGRADE_DIALOG: { | |
| 417 if (UpgradeDetector::GetInstance()->notify_upgrade()) { | |
| 418 *icon = rb.GetNativeImageNamed( | |
| 419 UpgradeDetector::GetInstance()->GetIconResourceID()); | |
| 420 return true; | |
| 421 } | |
| 422 return false; | |
| 423 } | |
| 424 default: | |
| 425 break; | |
| 426 } | |
| 427 return false; | |
| 428 } | |
| 429 | |
| 430 void WrenchMenuModel::ExecuteCommand(int command_id, int event_flags) { | |
| 431 GlobalError* error = GlobalErrorServiceFactory::GetForProfile( | |
| 432 browser_->profile())->GetGlobalErrorByMenuItemCommandID(command_id); | |
| 433 if (error) { | |
| 434 error->ExecuteMenuItem(browser_); | |
| 435 return; | |
| 436 } | |
| 437 | |
| 438 LogMenuMetrics(command_id); | |
| 439 chrome::ExecuteCommand(browser_, command_id); | |
| 440 } | |
| 441 | |
| 442 void WrenchMenuModel::LogMenuMetrics(int command_id) { | |
| 443 base::TimeDelta delta = timer_.Elapsed(); | |
| 444 | |
| 445 switch (command_id) { | |
| 446 case IDC_NEW_TAB: | |
| 447 if (!uma_action_recorded_) | |
| 448 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.NewTab", delta); | |
| 449 LogMenuAction(MENU_ACTION_NEW_TAB); | |
| 450 break; | |
| 451 case IDC_NEW_WINDOW: | |
| 452 if (!uma_action_recorded_) | |
| 453 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.NewWindow", delta); | |
| 454 LogMenuAction(MENU_ACTION_NEW_WINDOW); | |
| 455 break; | |
| 456 case IDC_NEW_INCOGNITO_WINDOW: | |
| 457 if (!uma_action_recorded_) { | |
| 458 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.NewIncognitoWindow", | |
| 459 delta); | |
| 460 } | |
| 461 LogMenuAction(MENU_ACTION_NEW_INCOGNITO_WINDOW); | |
| 462 break; | |
| 463 | |
| 464 // Bookmarks sub menu. | |
| 465 case IDC_SHOW_BOOKMARK_BAR: | |
| 466 if (!uma_action_recorded_) { | |
| 467 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ShowBookmarkBar", | |
| 468 delta); | |
| 469 } | |
| 470 LogMenuAction(MENU_ACTION_SHOW_BOOKMARK_BAR); | |
| 471 break; | |
| 472 case IDC_SHOW_BOOKMARK_MANAGER: | |
| 473 if (!uma_action_recorded_) { | |
| 474 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ShowBookmarkMgr", | |
| 475 delta); | |
| 476 } | |
| 477 LogMenuAction(MENU_ACTION_SHOW_BOOKMARK_MANAGER); | |
| 478 break; | |
| 479 case IDC_IMPORT_SETTINGS: | |
| 480 if (!uma_action_recorded_) { | |
| 481 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ImportSettings", | |
| 482 delta); | |
| 483 } | |
| 484 LogMenuAction(MENU_ACTION_IMPORT_SETTINGS); | |
| 485 break; | |
| 486 case IDC_BOOKMARK_PAGE: | |
| 487 if (!uma_action_recorded_) { | |
| 488 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.BookmarkPage", | |
| 489 delta); | |
| 490 } | |
| 491 LogMenuAction(MENU_ACTION_BOOKMARK_PAGE); | |
| 492 break; | |
| 493 case IDC_BOOKMARK_ALL_TABS: | |
| 494 if (!uma_action_recorded_) { | |
| 495 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.BookmarkAllTabs", | |
| 496 delta); | |
| 497 } | |
| 498 LogMenuAction(MENU_ACTION_BOOKMARK_ALL_TABS); | |
| 499 break; | |
| 500 case IDC_PIN_TO_START_SCREEN: | |
| 501 if (!uma_action_recorded_) { | |
| 502 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.PinToStartScreen", | |
| 503 delta); | |
| 504 } | |
| 505 LogMenuAction(MENU_ACTION_PIN_TO_START_SCREEN); | |
| 506 break; | |
| 507 | |
| 508 // Recent tabs menu. | |
| 509 case IDC_RESTORE_TAB: | |
| 510 if (!uma_action_recorded_) | |
| 511 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.RestoreTab", delta); | |
| 512 LogMenuAction(MENU_ACTION_RESTORE_TAB); | |
| 513 break; | |
| 514 | |
| 515 // Windows. | |
| 516 case IDC_WIN_DESKTOP_RESTART: | |
| 517 if (!uma_action_recorded_) { | |
| 518 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.WinDesktopRestart", | |
| 519 delta); | |
| 520 } | |
| 521 LogMenuAction(MENU_ACTION_WIN_DESKTOP_RESTART); | |
| 522 break; | |
| 523 case IDC_WIN8_METRO_RESTART: | |
| 524 if (!uma_action_recorded_) { | |
| 525 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Win8MetroRestart", | |
| 526 delta); | |
| 527 } | |
| 528 LogMenuAction(MENU_ACTION_WIN8_METRO_RESTART); | |
| 529 break; | |
| 530 | |
| 531 case IDC_WIN_CHROMEOS_RESTART: | |
| 532 if (!uma_action_recorded_) { | |
| 533 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ChromeOSRestart", | |
| 534 delta); | |
| 535 } | |
| 536 LogMenuAction(MENU_ACTION_WIN_CHROMEOS_RESTART); | |
| 537 break; | |
| 538 case IDC_DISTILL_PAGE: | |
| 539 if (!uma_action_recorded_) { | |
| 540 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.DistillPage", | |
| 541 delta); | |
| 542 } | |
| 543 LogMenuAction(MENU_ACTION_DISTILL_PAGE); | |
| 544 break; | |
| 545 case IDC_SAVE_PAGE: | |
| 546 if (!uma_action_recorded_) | |
| 547 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.SavePage", delta); | |
| 548 LogMenuAction(MENU_ACTION_SAVE_PAGE); | |
| 549 break; | |
| 550 case IDC_FIND: | |
| 551 if (!uma_action_recorded_) | |
| 552 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Find", delta); | |
| 553 LogMenuAction(MENU_ACTION_FIND); | |
| 554 break; | |
| 555 case IDC_PRINT: | |
| 556 if (!uma_action_recorded_) | |
| 557 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Print", delta); | |
| 558 LogMenuAction(MENU_ACTION_PRINT); | |
| 559 break; | |
| 560 | |
| 561 // Edit menu. | |
| 562 case IDC_CUT: | |
| 563 if (!uma_action_recorded_) | |
| 564 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Cut", delta); | |
| 565 LogMenuAction(MENU_ACTION_CUT); | |
| 566 break; | |
| 567 case IDC_COPY: | |
| 568 if (!uma_action_recorded_) | |
| 569 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Copy", delta); | |
| 570 LogMenuAction(MENU_ACTION_COPY); | |
| 571 break; | |
| 572 case IDC_PASTE: | |
| 573 if (!uma_action_recorded_) | |
| 574 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Paste", delta); | |
| 575 LogMenuAction(MENU_ACTION_PASTE); | |
| 576 break; | |
| 577 | |
| 578 // Tools menu. | |
| 579 case IDC_CREATE_HOSTED_APP: | |
| 580 if (!uma_action_recorded_) { | |
| 581 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.CreateHostedApp", | |
| 582 delta); | |
| 583 } | |
| 584 LogMenuAction(MENU_ACTION_CREATE_HOSTED_APP); | |
| 585 break; | |
| 586 case IDC_CREATE_SHORTCUTS: | |
| 587 if (!uma_action_recorded_) | |
| 588 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.CreateShortcuts", | |
| 589 delta); | |
| 590 LogMenuAction(MENU_ACTION_CREATE_SHORTCUTS); | |
| 591 break; | |
| 592 case IDC_MANAGE_EXTENSIONS: | |
| 593 if (!uma_action_recorded_) { | |
| 594 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ManageExtensions", | |
| 595 delta); | |
| 596 } | |
| 597 LogMenuAction(MENU_ACTION_MANAGE_EXTENSIONS); | |
| 598 break; | |
| 599 case IDC_TASK_MANAGER: | |
| 600 if (!uma_action_recorded_) { | |
| 601 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.TaskManager", | |
| 602 delta); | |
| 603 } | |
| 604 LogMenuAction(MENU_ACTION_TASK_MANAGER); | |
| 605 break; | |
| 606 case IDC_CLEAR_BROWSING_DATA: | |
| 607 if (!uma_action_recorded_) { | |
| 608 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ClearBrowsingData", | |
| 609 delta); | |
| 610 } | |
| 611 LogMenuAction(MENU_ACTION_CLEAR_BROWSING_DATA); | |
| 612 break; | |
| 613 case IDC_VIEW_SOURCE: | |
| 614 if (!uma_action_recorded_) | |
| 615 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ViewSource", delta); | |
| 616 LogMenuAction(MENU_ACTION_VIEW_SOURCE); | |
| 617 break; | |
| 618 case IDC_DEV_TOOLS: | |
| 619 if (!uma_action_recorded_) | |
| 620 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.DevTools", delta); | |
| 621 LogMenuAction(MENU_ACTION_DEV_TOOLS); | |
| 622 break; | |
| 623 case IDC_DEV_TOOLS_CONSOLE: | |
| 624 if (!uma_action_recorded_) { | |
| 625 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.DevToolsConsole", | |
| 626 delta); | |
| 627 } | |
| 628 LogMenuAction(MENU_ACTION_DEV_TOOLS_CONSOLE); | |
| 629 break; | |
| 630 case IDC_DEV_TOOLS_DEVICES: | |
| 631 if (!uma_action_recorded_) { | |
| 632 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.DevToolsDevices", | |
| 633 delta); | |
| 634 } | |
| 635 LogMenuAction(MENU_ACTION_DEV_TOOLS_DEVICES); | |
| 636 break; | |
| 637 case IDC_PROFILING_ENABLED: | |
| 638 if (!uma_action_recorded_) { | |
| 639 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ProfilingEnabled", | |
| 640 delta); | |
| 641 } | |
| 642 LogMenuAction(MENU_ACTION_PROFILING_ENABLED); | |
| 643 break; | |
| 644 | |
| 645 // Zoom menu | |
| 646 case IDC_ZOOM_MINUS: | |
| 647 if (!uma_action_recorded_) { | |
| 648 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ZoomMinus", delta); | |
| 649 LogMenuAction(MENU_ACTION_ZOOM_MINUS); | |
| 650 } | |
| 651 break; | |
| 652 case IDC_ZOOM_PLUS: | |
| 653 if (!uma_action_recorded_) { | |
| 654 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ZoomPlus", delta); | |
| 655 LogMenuAction(MENU_ACTION_ZOOM_PLUS); | |
| 656 } | |
| 657 break; | |
| 658 case IDC_FULLSCREEN: | |
| 659 content::RecordAction(UserMetricsAction("EnterFullScreenWithWrenchMenu")); | |
| 660 | |
| 661 if (!uma_action_recorded_) { | |
| 662 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.EnterFullScreen", | |
| 663 delta); | |
| 664 } | |
| 665 LogMenuAction(MENU_ACTION_FULLSCREEN); | |
| 666 break; | |
| 667 | |
| 668 case IDC_SHOW_HISTORY: | |
| 669 if (!uma_action_recorded_) { | |
| 670 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ShowHistory", | |
| 671 delta); | |
| 672 } | |
| 673 LogMenuAction(MENU_ACTION_SHOW_HISTORY); | |
| 674 break; | |
| 675 case IDC_SHOW_DOWNLOADS: | |
| 676 if (!uma_action_recorded_) { | |
| 677 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ShowDownloads", | |
| 678 delta); | |
| 679 } | |
| 680 LogMenuAction(MENU_ACTION_SHOW_DOWNLOADS); | |
| 681 break; | |
| 682 case IDC_SHOW_SYNC_SETUP: | |
| 683 if (!uma_action_recorded_) { | |
| 684 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.ShowSyncSetup", | |
| 685 delta); | |
| 686 } | |
| 687 LogMenuAction(MENU_ACTION_SHOW_SYNC_SETUP); | |
| 688 break; | |
| 689 case IDC_OPTIONS: | |
| 690 if (!uma_action_recorded_) | |
| 691 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Settings", delta); | |
| 692 LogMenuAction(MENU_ACTION_OPTIONS); | |
| 693 break; | |
| 694 case IDC_ABOUT: | |
| 695 if (!uma_action_recorded_) | |
| 696 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.About", delta); | |
| 697 LogMenuAction(MENU_ACTION_ABOUT); | |
| 698 break; | |
| 699 | |
| 700 // Help menu. | |
| 701 case IDC_HELP_PAGE_VIA_MENU: | |
| 702 content::RecordAction(UserMetricsAction("ShowHelpTabViaWrenchMenu")); | |
| 703 | |
| 704 if (!uma_action_recorded_) | |
| 705 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.HelpPage", delta); | |
| 706 LogMenuAction(MENU_ACTION_HELP_PAGE_VIA_MENU); | |
| 707 break; | |
| 708 #if defined(GOOGLE_CHROME_BUILD) | |
| 709 case IDC_FEEDBACK: | |
| 710 if (!uma_action_recorded_) | |
| 711 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Feedback", delta); | |
| 712 LogMenuAction(MENU_ACTION_FEEDBACK); | |
| 713 break; | |
| 714 #endif | |
| 715 | |
| 716 case IDC_TOGGLE_REQUEST_TABLET_SITE: | |
| 717 if (!uma_action_recorded_) { | |
| 718 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.RequestTabletSite", | |
| 719 delta); | |
| 720 } | |
| 721 LogMenuAction(MENU_ACTION_TOGGLE_REQUEST_TABLET_SITE); | |
| 722 break; | |
| 723 case IDC_EXIT: | |
| 724 if (!uma_action_recorded_) | |
| 725 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction.Exit", delta); | |
| 726 LogMenuAction(MENU_ACTION_EXIT); | |
| 727 break; | |
| 728 } | |
| 729 | |
| 730 if (!uma_action_recorded_) { | |
| 731 UMA_HISTOGRAM_MEDIUM_TIMES("WrenchMenu.TimeToAction", delta); | |
| 732 uma_action_recorded_ = true; | |
| 733 } | |
| 734 } | |
| 735 | |
| 736 void WrenchMenuModel::LogMenuAction(int action_id) { | |
| 737 UMA_HISTOGRAM_ENUMERATION("WrenchMenu.MenuAction", action_id, | |
| 738 LIMIT_MENU_ACTION); | |
| 739 } | |
| 740 | |
| 741 bool WrenchMenuModel::IsCommandIdChecked(int command_id) const { | |
| 742 if (command_id == IDC_SHOW_BOOKMARK_BAR) { | |
| 743 return browser_->profile()->GetPrefs()->GetBoolean( | |
| 744 bookmarks::prefs::kShowBookmarkBar); | |
| 745 } else if (command_id == IDC_PROFILING_ENABLED) { | |
| 746 return Profiling::BeingProfiled(); | |
| 747 } else if (command_id == IDC_TOGGLE_REQUEST_TABLET_SITE) { | |
| 748 return chrome::IsRequestingTabletSite(browser_); | |
| 749 } | |
| 750 | |
| 751 return false; | |
| 752 } | |
| 753 | |
| 754 bool WrenchMenuModel::IsCommandIdEnabled(int command_id) const { | |
| 755 GlobalError* error = GlobalErrorServiceFactory::GetForProfile( | |
| 756 browser_->profile())->GetGlobalErrorByMenuItemCommandID(command_id); | |
| 757 if (error) | |
| 758 return true; | |
| 759 | |
| 760 return chrome::IsCommandEnabled(browser_, command_id); | |
| 761 } | |
| 762 | |
| 763 bool WrenchMenuModel::IsCommandIdVisible(int command_id) const { | |
| 764 switch (command_id) { | |
| 765 #if defined(OS_MACOSX) | |
| 766 case kEmptyMenuItemCommand: | |
| 767 return false; // Always hidden (see CreateActionToolbarOverflowMenu). | |
| 768 #endif | |
| 769 #if defined(OS_WIN) | |
| 770 case IDC_VIEW_INCOMPATIBILITIES: { | |
| 771 EnumerateModulesModel* loaded_modules = | |
| 772 EnumerateModulesModel::GetInstance(); | |
| 773 if (loaded_modules->confirmed_bad_modules_detected() <= 0) | |
| 774 return false; | |
| 775 // We'll leave the wrench adornment on until the user clicks the link. | |
| 776 if (loaded_modules->modules_to_notify_about() <= 0) | |
| 777 loaded_modules->AcknowledgeConflictNotification(); | |
| 778 return true; | |
| 779 } | |
| 780 case IDC_PIN_TO_START_SCREEN: | |
| 781 return base::win::IsMetroProcess(); | |
| 782 #else | |
| 783 case IDC_VIEW_INCOMPATIBILITIES: | |
| 784 case IDC_PIN_TO_START_SCREEN: | |
| 785 return false; | |
| 786 #endif | |
| 787 case IDC_UPGRADE_DIALOG: | |
| 788 return browser_defaults::kShowUpgradeMenuItem && | |
| 789 UpgradeDetector::GetInstance()->notify_upgrade(); | |
| 790 #if !defined(OS_LINUX) || defined(USE_AURA) | |
| 791 case IDC_BOOKMARK_PAGE: | |
| 792 return !chrome::ShouldRemoveBookmarkThisPageUI(browser_->profile()); | |
| 793 case IDC_BOOKMARK_ALL_TABS: | |
| 794 return !chrome::ShouldRemoveBookmarkOpenPagesUI(browser_->profile()); | |
| 795 #endif | |
| 796 default: | |
| 797 return true; | |
| 798 } | |
| 799 } | |
| 800 | |
| 801 bool WrenchMenuModel::GetAcceleratorForCommandId( | |
| 802 int command_id, | |
| 803 ui::Accelerator* accelerator) { | |
| 804 return provider_->GetAcceleratorForCommandId(command_id, accelerator); | |
| 805 } | |
| 806 | |
| 807 void WrenchMenuModel::ActiveTabChanged(WebContents* old_contents, | |
| 808 WebContents* new_contents, | |
| 809 int index, | |
| 810 int reason) { | |
| 811 // The user has switched between tabs and the new tab may have a different | |
| 812 // zoom setting. | |
| 813 UpdateZoomControls(); | |
| 814 } | |
| 815 | |
| 816 void WrenchMenuModel::TabReplacedAt(TabStripModel* tab_strip_model, | |
| 817 WebContents* old_contents, | |
| 818 WebContents* new_contents, | |
| 819 int index) { | |
| 820 UpdateZoomControls(); | |
| 821 } | |
| 822 | |
| 823 void WrenchMenuModel::Observe(int type, | |
| 824 const content::NotificationSource& source, | |
| 825 const content::NotificationDetails& details) { | |
| 826 DCHECK(type == content::NOTIFICATION_NAV_ENTRY_COMMITTED); | |
| 827 UpdateZoomControls(); | |
| 828 } | |
| 829 | |
| 830 // For testing. | |
| 831 WrenchMenuModel::WrenchMenuModel() | |
| 832 : ui::SimpleMenuModel(this), | |
| 833 uma_action_recorded_(false), | |
| 834 provider_(nullptr), | |
| 835 browser_(nullptr) {} | |
| 836 | |
| 837 bool WrenchMenuModel::ShouldShowNewIncognitoWindowMenuItem() { | |
| 838 if (browser_->profile()->IsGuestSession()) | |
| 839 return false; | |
| 840 | |
| 841 return IncognitoModePrefs::GetAvailability(browser_->profile()->GetPrefs()) != | |
| 842 IncognitoModePrefs::DISABLED; | |
| 843 } | |
| 844 | |
| 845 // Note: When adding new menu items please place under an appropriate section. | |
| 846 // Menu is organised as follows: | |
| 847 // - Extension toolbar overflow. | |
| 848 // - Global browser errors and warnings. | |
| 849 // - Tabs and windows. | |
| 850 // - Places previously been e.g. History, bookmarks, recent tabs. | |
| 851 // - Page actions e.g. zoom, edit, find, print. | |
| 852 // - Learn about the browser and global customisation e.g. settings, help. | |
| 853 // - Browser relaunch, quit. | |
| 854 void WrenchMenuModel::Build() { | |
| 855 if (extensions::FeatureSwitch::extension_action_redesign()->IsEnabled()) | |
| 856 CreateActionToolbarOverflowMenu(); | |
| 857 | |
| 858 AddItem(IDC_VIEW_INCOMPATIBILITIES, | |
| 859 l10n_util::GetStringUTF16(IDS_VIEW_INCOMPATIBILITIES)); | |
| 860 SetIcon(GetIndexOfCommandId(IDC_VIEW_INCOMPATIBILITIES), | |
| 861 ui::ResourceBundle::GetSharedInstance(). | |
| 862 GetNativeImageNamed(IDR_INPUT_ALERT_MENU)); | |
| 863 if (IsCommandIdVisible(IDC_UPGRADE_DIALOG)) | |
| 864 AddItem(IDC_UPGRADE_DIALOG, GetUpgradeDialogMenuItemName()); | |
| 865 if (AddGlobalErrorMenuItems() || | |
| 866 IsCommandIdVisible(IDC_VIEW_INCOMPATIBILITIES) || | |
| 867 IsCommandIdVisible(IDC_UPGRADE_DIALOG)) | |
| 868 AddSeparator(ui::NORMAL_SEPARATOR); | |
| 869 | |
| 870 AddItemWithStringId(IDC_NEW_TAB, IDS_NEW_TAB); | |
| 871 AddItemWithStringId(IDC_NEW_WINDOW, IDS_NEW_WINDOW); | |
| 872 if (ShouldShowNewIncognitoWindowMenuItem()) | |
| 873 AddItemWithStringId(IDC_NEW_INCOGNITO_WINDOW, IDS_NEW_INCOGNITO_WINDOW); | |
| 874 AddSeparator(ui::NORMAL_SEPARATOR); | |
| 875 | |
| 876 if (!browser_->profile()->IsOffTheRecord()) { | |
| 877 recent_tabs_sub_menu_model_.reset(new RecentTabsSubMenuModel(provider_, | |
| 878 browser_, | |
| 879 NULL)); | |
| 880 AddSubMenuWithStringId(IDC_RECENT_TABS_MENU, IDS_HISTORY_MENU, | |
| 881 recent_tabs_sub_menu_model_.get()); | |
| 882 } | |
| 883 AddItemWithStringId(IDC_SHOW_DOWNLOADS, IDS_SHOW_DOWNLOADS); | |
| 884 if (!browser_->profile()->IsGuestSession()) { | |
| 885 bookmark_sub_menu_model_.reset(new BookmarkSubMenuModel(this, browser_)); | |
| 886 AddSubMenuWithStringId(IDC_BOOKMARKS_MENU, IDS_BOOKMARKS_MENU, | |
| 887 bookmark_sub_menu_model_.get()); | |
| 888 } | |
| 889 | |
| 890 CreateZoomMenu(); | |
| 891 AddItemWithStringId(IDC_PRINT, IDS_PRINT); | |
| 892 if (switches::MediaRouterEnabled() && !browser()->profile()->IsOffTheRecord()) | |
| 893 AddItemWithStringId(IDC_ROUTE_MEDIA, IDS_MEDIA_ROUTER_MENU_ITEM_TITLE); | |
| 894 AddItemWithStringId(IDC_FIND, IDS_FIND); | |
| 895 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 896 switches::kEnableDomDistiller)) | |
| 897 AddItemWithStringId(IDC_DISTILL_PAGE, IDS_DISTILL_PAGE); | |
| 898 tools_menu_model_.reset(new ToolsMenuModel(this, browser_)); | |
| 899 AddSubMenuWithStringId( | |
| 900 IDC_MORE_TOOLS_MENU, IDS_MORE_TOOLS_MENU, tools_menu_model_.get()); | |
| 901 // Append the full menu including separators. The final separator only gets | |
| 902 // appended when this is a touch menu - otherwise it would get added twice. | |
| 903 CreateCutCopyPasteMenu(); | |
| 904 | |
| 905 AddItemWithStringId(IDC_OPTIONS, IDS_SETTINGS); | |
| 906 // The help submenu is only displayed on official Chrome builds. As the | |
| 907 // 'About' item has been moved to this submenu, it's reinstated here for | |
| 908 // Chromium builds. | |
| 909 #if defined(GOOGLE_CHROME_BUILD) | |
| 910 help_menu_model_.reset(new HelpMenuModel(this, browser_)); | |
| 911 AddSubMenuWithStringId(IDC_HELP_MENU, IDS_HELP_MENU, | |
| 912 help_menu_model_.get()); | |
| 913 #else | |
| 914 AddItem(IDC_ABOUT, l10n_util::GetStringUTF16(IDS_ABOUT)); | |
| 915 #endif | |
| 916 #if defined(OS_CHROMEOS) | |
| 917 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 918 chromeos::switches::kEnableRequestTabletSite)) | |
| 919 AddCheckItemWithStringId(IDC_TOGGLE_REQUEST_TABLET_SITE, | |
| 920 IDS_TOGGLE_REQUEST_TABLET_SITE); | |
| 921 #endif | |
| 922 | |
| 923 #if defined(OS_WIN) | |
| 924 int command_id = IDC_WIN_DESKTOP_RESTART; | |
| 925 int string_id = IDS_WIN_DESKTOP_RESTART; | |
| 926 if (GetRestartMenuItemIfRequired(browser_->host_desktop_type(), | |
| 927 &command_id, | |
| 928 &string_id)) { | |
| 929 AddSeparator(ui::NORMAL_SEPARATOR); | |
| 930 AddItemWithStringId(command_id, string_id); | |
| 931 } | |
| 932 #endif | |
| 933 bool show_exit_menu = browser_defaults::kShowExitMenuItem; | |
| 934 #if defined(OS_WIN) | |
| 935 if (browser_->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH) | |
| 936 show_exit_menu = false; | |
| 937 #endif | |
| 938 if (show_exit_menu) { | |
| 939 AddSeparator(ui::NORMAL_SEPARATOR); | |
| 940 AddItemWithStringId(IDC_EXIT, IDS_EXIT); | |
| 941 } | |
| 942 uma_action_recorded_ = false; | |
| 943 } | |
| 944 | |
| 945 bool WrenchMenuModel::AddGlobalErrorMenuItems() { | |
| 946 // TODO(sail): Currently we only build the wrench menu once per browser | |
| 947 // window. This means that if a new error is added after the menu is built | |
| 948 // it won't show in the existing wrench menu. To fix this we need to some | |
| 949 // how update the menu if new errors are added. | |
| 950 const GlobalErrorService::GlobalErrorList& errors = | |
| 951 GlobalErrorServiceFactory::GetForProfile(browser_->profile())->errors(); | |
| 952 bool menu_items_added = false; | |
| 953 for (GlobalErrorService::GlobalErrorList::const_iterator | |
| 954 it = errors.begin(); it != errors.end(); ++it) { | |
| 955 GlobalError* error = *it; | |
| 956 DCHECK(error); | |
| 957 if (error->HasMenuItem()) { | |
| 958 AddItem(error->MenuItemCommandID(), error->MenuItemLabel()); | |
| 959 SetIcon(GetIndexOfCommandId(error->MenuItemCommandID()), | |
| 960 error->MenuItemIcon()); | |
| 961 menu_items_added = true; | |
| 962 } | |
| 963 } | |
| 964 return menu_items_added; | |
| 965 } | |
| 966 | |
| 967 void WrenchMenuModel::CreateActionToolbarOverflowMenu() { | |
| 968 // We only add the extensions overflow container if there are any icons that | |
| 969 // aren't shown in the main container. | |
| 970 // browser_->window() can return null during startup. | |
| 971 if (browser_->window() && | |
| 972 browser_->window()->GetToolbarActionsBar()->NeedsOverflow()) { | |
| 973 #if defined(OS_MACOSX) | |
| 974 // There's a bug in AppKit menus, where if a menu item with a custom view | |
| 975 // (like the extensions overflow menu) is the first menu item, it is not | |
| 976 // highlightable or keyboard-selectable. | |
| 977 // Adding any menu item before it (even one which is never visible) prevents | |
| 978 // it, so add a bogus item here that will always be hidden. | |
| 979 AddItem(kEmptyMenuItemCommand, base::string16()); | |
| 980 #endif | |
| 981 AddItem(IDC_EXTENSIONS_OVERFLOW_MENU, base::string16()); | |
| 982 AddSeparator(ui::UPPER_SEPARATOR); | |
| 983 } | |
| 984 } | |
| 985 | |
| 986 void WrenchMenuModel::CreateCutCopyPasteMenu() { | |
| 987 AddSeparator(ui::LOWER_SEPARATOR); | |
| 988 | |
| 989 // WARNING: Mac does not use the ButtonMenuItemModel, but instead defines the | |
| 990 // layout for this menu item in WrenchMenu.xib. It does, however, use the | |
| 991 // command_id value from AddButtonItem() to identify this special item. | |
| 992 edit_menu_item_model_.reset(new ui::ButtonMenuItemModel(IDS_EDIT, this)); | |
| 993 edit_menu_item_model_->AddGroupItemWithStringId(IDC_CUT, IDS_CUT); | |
| 994 edit_menu_item_model_->AddGroupItemWithStringId(IDC_COPY, IDS_COPY); | |
| 995 edit_menu_item_model_->AddGroupItemWithStringId(IDC_PASTE, IDS_PASTE); | |
| 996 AddButtonItem(IDC_EDIT_MENU, edit_menu_item_model_.get()); | |
| 997 | |
| 998 AddSeparator(ui::UPPER_SEPARATOR); | |
| 999 } | |
| 1000 | |
| 1001 void WrenchMenuModel::CreateZoomMenu() { | |
| 1002 // This menu needs to be enclosed by separators. | |
| 1003 AddSeparator(ui::LOWER_SEPARATOR); | |
| 1004 | |
| 1005 // WARNING: Mac does not use the ButtonMenuItemModel, but instead defines the | |
| 1006 // layout for this menu item in WrenchMenu.xib. It does, however, use the | |
| 1007 // command_id value from AddButtonItem() to identify this special item. | |
| 1008 zoom_menu_item_model_.reset( | |
| 1009 new ui::ButtonMenuItemModel(IDS_ZOOM_MENU, this)); | |
| 1010 zoom_menu_item_model_->AddGroupItemWithStringId(IDC_ZOOM_MINUS, | |
| 1011 IDS_ZOOM_MINUS2); | |
| 1012 zoom_menu_item_model_->AddGroupItemWithStringId(IDC_ZOOM_PLUS, | |
| 1013 IDS_ZOOM_PLUS2); | |
| 1014 zoom_menu_item_model_->AddItemWithImage(IDC_FULLSCREEN, | |
| 1015 IDR_FULLSCREEN_MENU_BUTTON); | |
| 1016 AddButtonItem(IDC_ZOOM_MENU, zoom_menu_item_model_.get()); | |
| 1017 | |
| 1018 AddSeparator(ui::UPPER_SEPARATOR); | |
| 1019 } | |
| 1020 | |
| 1021 void WrenchMenuModel::UpdateZoomControls() { | |
| 1022 int zoom_percent = 100; | |
| 1023 if (browser_->tab_strip_model() && | |
| 1024 browser_->tab_strip_model()->GetActiveWebContents()) { | |
| 1025 zoom_percent = ui_zoom::ZoomController::FromWebContents( | |
| 1026 browser_->tab_strip_model()->GetActiveWebContents()) | |
| 1027 ->GetZoomPercent(); | |
| 1028 } | |
| 1029 zoom_label_ = l10n_util::GetStringFUTF16( | |
| 1030 IDS_ZOOM_PERCENT, base::IntToString16(zoom_percent)); | |
| 1031 } | |
| 1032 | |
| 1033 void WrenchMenuModel::OnZoomLevelChanged( | |
| 1034 const content::HostZoomMap::ZoomLevelChange& change) { | |
| 1035 UpdateZoomControls(); | |
| 1036 } | |
| OLD | NEW |