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/browser_command_controller.h" 6 7 #include "base/command_line.h" 8 #include "base/prefs/pref_service.h" 9 #include "chrome/app/chrome_command_ids.h" 10 #include "chrome/browser/browser_process.h" 11 #include "chrome/browser/chrome_notification_types.h" 12 #include "chrome/browser/defaults.h" 13 #include "chrome/browser/extensions/extension_service.h" 14 #include "chrome/browser/extensions/extension_util.h" 15 #include "chrome/browser/lifetime/application_lifetime.h" 16 #include "chrome/browser/prefs/incognito_mode_prefs.h" 17 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile_manager.h" 19 #include "chrome/browser/sessions/tab_restore_service.h" 20 #include "chrome/browser/sessions/tab_restore_service_factory.h" 21 #include "chrome/browser/shell_integration.h" 22 #include "chrome/browser/signin/signin_promo.h" 23 #include "chrome/browser/sync/profile_sync_service.h" 24 #include "chrome/browser/sync/profile_sync_service_factory.h" 25 #include "chrome/browser/ui/bookmarks/bookmark_tab_helper.h" 26 #include "chrome/browser/ui/browser.h" 27 #include "chrome/browser/ui/browser_commands.h" 28 #include "chrome/browser/ui/browser_window.h" 29 #include "chrome/browser/ui/chrome_pages.h" 30 #include "chrome/browser/ui/tabs/tab_strip_model.h" 31 #include "chrome/browser/ui/tabs/tab_strip_model_utils.h" 32 #include "chrome/browser/ui/webui/inspect_ui.h" 33 #include "chrome/common/chrome_switches.h" 34 #include "chrome/common/content_restriction.h" 35 #include "chrome/common/pref_names.h" 36 #include "chrome/common/profiling.h" 37 #include "content/public/browser/native_web_keyboard_event.h" 38 #include "content/public/browser/navigation_controller.h" 39 #include "content/public/browser/navigation_entry.h" 40 #include "content/public/browser/user_metrics.h" 41 #include "content/public/browser/web_contents.h" 42 #include "content/public/browser/web_contents_observer.h" 43 #include "content/public/common/url_constants.h" 44 #include "extensions/browser/extension_system.h" 45 #include "ui/events/keycodes/keyboard_codes.h" 46 47 #if defined(OS_MACOSX) 48 #include "chrome/browser/ui/browser_commands_mac.h" 49 #endif 50 51 #if defined(OS_WIN) 52 #include "base/win/metro.h" 53 #include "base/win/windows_version.h" 54 #include "chrome/browser/ui/apps/apps_metro_handler_win.h" 55 #include "content/public/browser/gpu_data_manager.h" 56 #endif 57 58 #if defined(USE_ASH) 59 #include "ash/accelerators/accelerator_commands.h" 60 #include "chrome/browser/ui/ash/ash_util.h" 61 #endif 62 63 #if defined(OS_CHROMEOS) 64 #include "ash/multi_profile_uma.h" 65 #include "ash/session/session_state_delegate.h" 66 #include "ash/shell.h" 67 #include "chrome/browser/ui/ash/multi_user/multi_user_context_menu.h" 68 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" 69 #include "chrome/browser/ui/browser_commands_chromeos.h" 70 #endif 71 72 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 73 #include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h" 74 #endif 75 76 using content::NavigationEntry; 77 using content::NavigationController; 78 using content::WebContents; 79 80 namespace { 81 82 enum WindowState { 83 // Not in fullscreen mode. 84 WINDOW_STATE_NOT_FULLSCREEN, 85 86 // Fullscreen mode, occupying the whole screen. 87 WINDOW_STATE_FULLSCREEN, 88 89 // Fullscreen mode for metro snap, occupying the full height and 20% of 90 // the screen width. 91 WINDOW_STATE_METRO_SNAP, 92 }; 93 94 // Returns |true| if entry has an internal chrome:// URL, |false| otherwise. 95 bool HasInternalURL(const NavigationEntry* entry) { 96 if (!entry) 97 return false; 98 99 // Check the |virtual_url()| first. This catches regular chrome:// URLs 100 // including URLs that were rewritten (such as chrome://bookmarks). 101 if (entry->GetVirtualURL().SchemeIs(content::kChromeUIScheme)) 102 return true; 103 104 // If the |virtual_url()| isn't a chrome:// URL, check if it's actually 105 // view-source: of a chrome:// URL. 106 if (entry->GetVirtualURL().SchemeIs(content::kViewSourceScheme)) 107 return entry->GetURL().SchemeIs(content::kChromeUIScheme); 108 109 return false; 110 } 111 112 #if defined(OS_WIN) 113 // Windows 8 specific helper class to manage DefaultBrowserWorker. It does the 114 // following asynchronous actions in order: 115 // 1- Check that chrome is the default browser 116 // 2- If we are the default, restart chrome in metro and exit 117 // 3- If not the default browser show the 'select default browser' system dialog 118 // 4- When dialog dismisses check again who got made the default 119 // 5- If we are the default then restart chrome in metro and exit 120 // 6- If we are not the default exit. 121 // 122 // Note: this class deletes itself. 123 class SwitchToMetroUIHandler 124 : public ShellIntegration::DefaultWebClientObserver { 125 public: 126 SwitchToMetroUIHandler() 127 : default_browser_worker_( 128 new ShellIntegration::DefaultBrowserWorker(this)), 129 first_check_(true) { 130 default_browser_worker_->StartCheckIsDefault(); 131 } 132 133 virtual ~SwitchToMetroUIHandler() { 134 default_browser_worker_->ObserverDestroyed(); 135 } 136 137 private: 138 virtual void SetDefaultWebClientUIState( 139 ShellIntegration::DefaultWebClientUIState state) OVERRIDE { 140 switch (state) { 141 case ShellIntegration::STATE_PROCESSING: 142 return; 143 case ShellIntegration::STATE_UNKNOWN : 144 break; 145 case ShellIntegration::STATE_IS_DEFAULT: 146 chrome::AttemptRestartToMetroMode(); 147 break; 148 case ShellIntegration::STATE_NOT_DEFAULT: 149 if (first_check_) { 150 default_browser_worker_->StartSetAsDefault(); 151 return; 152 } 153 break; 154 default: 155 NOTREACHED(); 156 } 157 delete this; 158 } 159 160 virtual void OnSetAsDefaultConcluded(bool success) OVERRIDE { 161 if (!success) { 162 delete this; 163 return; 164 } 165 first_check_ = false; 166 default_browser_worker_->StartCheckIsDefault(); 167 } 168 169 virtual bool IsInteractiveSetDefaultPermitted() OVERRIDE { 170 return true; 171 } 172 173 scoped_refptr<ShellIntegration::DefaultBrowserWorker> default_browser_worker_; 174 bool first_check_; 175 176 DISALLOW_COPY_AND_ASSIGN(SwitchToMetroUIHandler); 177 }; 178 #endif // defined(OS_WIN) 179 180 } // namespace 181 182 namespace chrome { 183 184 /////////////////////////////////////////////////////////////////////////////// 185 // BrowserCommandController, public: 186 187 BrowserCommandController::BrowserCommandController(Browser* browser) 188 : browser_(browser), 189 command_updater_(this), 190 block_command_execution_(false), 191 last_blocked_command_id_(-1), 192 last_blocked_command_disposition_(CURRENT_TAB) { 193 browser_->tab_strip_model()->AddObserver(this); 194 PrefService* local_state = g_browser_process->local_state(); 195 if (local_state) { 196 local_pref_registrar_.Init(local_state); 197 local_pref_registrar_.Add( 198 prefs::kAllowFileSelectionDialogs, 199 base::Bind( 200 &BrowserCommandController::UpdateCommandsForFileSelectionDialogs, 201 base::Unretained(this))); 202 } 203 204 profile_pref_registrar_.Init(profile()->GetPrefs()); 205 profile_pref_registrar_.Add( 206 prefs::kDevToolsDisabled, 207 base::Bind(&BrowserCommandController::UpdateCommandsForDevTools, 208 base::Unretained(this))); 209 profile_pref_registrar_.Add( 210 bookmarks::prefs::kEditBookmarksEnabled, 211 base::Bind(&BrowserCommandController::UpdateCommandsForBookmarkEditing, 212 base::Unretained(this))); 213 profile_pref_registrar_.Add( 214 bookmarks::prefs::kShowBookmarkBar, 215 base::Bind(&BrowserCommandController::UpdateCommandsForBookmarkBar, 216 base::Unretained(this))); 217 profile_pref_registrar_.Add( 218 prefs::kIncognitoModeAvailability, 219 base::Bind( 220 &BrowserCommandController::UpdateCommandsForIncognitoAvailability, 221 base::Unretained(this))); 222 profile_pref_registrar_.Add( 223 prefs::kPrintingEnabled, 224 base::Bind(&BrowserCommandController::UpdatePrintingState, 225 base::Unretained(this))); 226 #if !defined(OS_MACOSX) 227 profile_pref_registrar_.Add( 228 prefs::kFullscreenAllowed, 229 base::Bind(&BrowserCommandController::UpdateCommandsForFullscreenMode, 230 base::Unretained(this))); 231 #endif 232 pref_signin_allowed_.Init( 233 prefs::kSigninAllowed, 234 profile()->GetOriginalProfile()->GetPrefs(), 235 base::Bind(&BrowserCommandController::OnSigninAllowedPrefChange, 236 base::Unretained(this))); 237 238 InitCommandState(); 239 240 TabRestoreService* tab_restore_service = 241 TabRestoreServiceFactory::GetForProfile(profile()); 242 if (tab_restore_service) { 243 tab_restore_service->AddObserver(this); 244 TabRestoreServiceChanged(tab_restore_service); 245 } 246 } 247 248 BrowserCommandController::~BrowserCommandController() { 249 // TabRestoreService may have been shutdown by the time we get here. Don't 250 // trigger creating it. 251 TabRestoreService* tab_restore_service = 252 TabRestoreServiceFactory::GetForProfileIfExisting(profile()); 253 if (tab_restore_service) 254 tab_restore_service->RemoveObserver(this); 255 profile_pref_registrar_.RemoveAll(); 256 local_pref_registrar_.RemoveAll(); 257 browser_->tab_strip_model()->RemoveObserver(this); 258 } 259 260 bool BrowserCommandController::IsReservedCommandOrKey( 261 int command_id, 262 const content::NativeWebKeyboardEvent& event) { 263 // In Apps mode, no keys are reserved. 264 if (browser_->is_app()) 265 return false; 266 267 #if defined(OS_CHROMEOS) 268 // On Chrome OS, the top row of keys are mapped to browser actions like 269 // back/forward or refresh. We don't want web pages to be able to change the 270 // behavior of these keys. Ash handles F4 and up; this leaves us needing to 271 // reserve browser back/forward and refresh here. 272 ui::KeyboardCode key_code = 273 static_cast<ui::KeyboardCode>(event.windowsKeyCode); 274 if ((key_code == ui::VKEY_BROWSER_BACK && command_id == IDC_BACK) || 275 (key_code == ui::VKEY_BROWSER_FORWARD && command_id == IDC_FORWARD) || 276 (key_code == ui::VKEY_BROWSER_REFRESH && command_id == IDC_RELOAD)) { 277 return true; 278 } 279 #endif 280 281 if (window()->IsFullscreen() && command_id == IDC_FULLSCREEN) 282 return true; 283 284 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 285 // If this key was registered by the user as a content editing hotkey, then 286 // it is not reserved. 287 ui::TextEditKeyBindingsDelegateAuraLinux* delegate = 288 ui::GetTextEditKeyBindingsDelegate(); 289 if (delegate && event.os_event && delegate->MatchEvent(*event.os_event, NULL)) 290 return false; 291 #endif 292 293 return command_id == IDC_CLOSE_TAB || 294 command_id == IDC_CLOSE_WINDOW || 295 command_id == IDC_NEW_INCOGNITO_WINDOW || 296 command_id == IDC_NEW_TAB || 297 command_id == IDC_NEW_WINDOW || 298 command_id == IDC_RESTORE_TAB || 299 command_id == IDC_SELECT_NEXT_TAB || 300 command_id == IDC_SELECT_PREVIOUS_TAB || 301 command_id == IDC_EXIT; 302 } 303 304 void BrowserCommandController::SetBlockCommandExecution(bool block) { 305 block_command_execution_ = block; 306 if (block) { 307 last_blocked_command_id_ = -1; 308 last_blocked_command_disposition_ = CURRENT_TAB; 309 } 310 } 311 312 int BrowserCommandController::GetLastBlockedCommand( 313 WindowOpenDisposition* disposition) { 314 if (disposition) 315 *disposition = last_blocked_command_disposition_; 316 return last_blocked_command_id_; 317 } 318 319 void BrowserCommandController::TabStateChanged() { 320 UpdateCommandsForTabState(); 321 } 322 323 void BrowserCommandController::ZoomStateChanged() { 324 UpdateCommandsForZoomState(); 325 } 326 327 void BrowserCommandController::ContentRestrictionsChanged() { 328 UpdateCommandsForContentRestrictionState(); 329 } 330 331 void BrowserCommandController::FullscreenStateChanged() { 332 UpdateCommandsForFullscreenMode(); 333 } 334 335 void BrowserCommandController::PrintingStateChanged() { 336 UpdatePrintingState(); 337 } 338 339 void BrowserCommandController::LoadingStateChanged(bool is_loading, 340 bool force) { 341 UpdateReloadStopState(is_loading, force); 342 } 343 344 //////////////////////////////////////////////////////////////////////////////// 345 // BrowserCommandController, CommandUpdaterDelegate implementation: 346 347 void BrowserCommandController::ExecuteCommandWithDisposition( 348 int id, 349 WindowOpenDisposition disposition) { 350 // No commands are enabled if there is not yet any selected tab. 351 // TODO(pkasting): It seems like we should not need this, because either 352 // most/all commands should not have been enabled yet anyway or the ones that 353 // are enabled should be global, or safe themselves against having no selected 354 // tab. However, Ben says he tried removing this before and got lots of 355 // crashes, e.g. from Windows sending WM_COMMANDs at random times during 356 // window construction. This probably could use closer examination someday. 357 if (browser_->tab_strip_model()->active_index() == TabStripModel::kNoTab) 358 return; 359 360 DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command " 361 << id; 362 363 // If command execution is blocked then just record the command and return. 364 if (block_command_execution_) { 365 // We actually only allow no more than one blocked command, otherwise some 366 // commands maybe lost. 367 DCHECK_EQ(last_blocked_command_id_, -1); 368 last_blocked_command_id_ = id; 369 last_blocked_command_disposition_ = disposition; 370 return; 371 } 372 373 // The order of commands in this switch statement must match the function 374 // declaration order in browser.h! 375 switch (id) { 376 // Navigation commands 377 case IDC_BACK: 378 GoBack(browser_, disposition); 379 break; 380 case IDC_FORWARD: 381 GoForward(browser_, disposition); 382 break; 383 case IDC_RELOAD: 384 Reload(browser_, disposition); 385 break; 386 case IDC_RELOAD_CLEARING_CACHE: 387 ClearCache(browser_); 388 // FALL THROUGH 389 case IDC_RELOAD_IGNORING_CACHE: 390 ReloadIgnoringCache(browser_, disposition); 391 break; 392 case IDC_HOME: 393 Home(browser_, disposition); 394 break; 395 case IDC_OPEN_CURRENT_URL: 396 OpenCurrentURL(browser_); 397 break; 398 case IDC_STOP: 399 Stop(browser_); 400 break; 401 402 // Window management commands 403 case IDC_NEW_WINDOW: 404 NewWindow(browser_); 405 break; 406 case IDC_NEW_INCOGNITO_WINDOW: 407 NewIncognitoWindow(browser_); 408 break; 409 case IDC_CLOSE_WINDOW: 410 content::RecordAction(base::UserMetricsAction("CloseWindowByKey")); 411 CloseWindow(browser_); 412 break; 413 case IDC_NEW_TAB: 414 NewTab(browser_); 415 break; 416 case IDC_CLOSE_TAB: 417 content::RecordAction(base::UserMetricsAction("CloseTabByKey")); 418 CloseTab(browser_); 419 break; 420 case IDC_SELECT_NEXT_TAB: 421 content::RecordAction(base::UserMetricsAction("Accel_SelectNextTab")); 422 SelectNextTab(browser_); 423 break; 424 case IDC_SELECT_PREVIOUS_TAB: 425 content::RecordAction( 426 base::UserMetricsAction("Accel_SelectPreviousTab")); 427 SelectPreviousTab(browser_); 428 break; 429 case IDC_MOVE_TAB_NEXT: 430 MoveTabNext(browser_); 431 break; 432 case IDC_MOVE_TAB_PREVIOUS: 433 MoveTabPrevious(browser_); 434 break; 435 case IDC_SELECT_TAB_0: 436 case IDC_SELECT_TAB_1: 437 case IDC_SELECT_TAB_2: 438 case IDC_SELECT_TAB_3: 439 case IDC_SELECT_TAB_4: 440 case IDC_SELECT_TAB_5: 441 case IDC_SELECT_TAB_6: 442 case IDC_SELECT_TAB_7: 443 SelectNumberedTab(browser_, id - IDC_SELECT_TAB_0); 444 break; 445 case IDC_SELECT_LAST_TAB: 446 SelectLastTab(browser_); 447 break; 448 case IDC_DUPLICATE_TAB: 449 DuplicateTab(browser_); 450 break; 451 case IDC_RESTORE_TAB: 452 RestoreTab(browser_); 453 break; 454 case IDC_SHOW_AS_TAB: 455 ConvertPopupToTabbedBrowser(browser_); 456 break; 457 case IDC_FULLSCREEN: 458 #if defined(OS_MACOSX) 459 chrome::ToggleFullscreenWithChromeOrFallback(browser_); 460 #else 461 chrome::ToggleFullscreenMode(browser_); 462 #endif 463 break; 464 465 #if defined(OS_CHROMEOS) 466 case IDC_VISIT_DESKTOP_OF_LRU_USER_2: 467 case IDC_VISIT_DESKTOP_OF_LRU_USER_3: 468 ExecuteVisitDesktopCommand(id, browser_->window()->GetNativeWindow()); 469 break; 470 #endif 471 472 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 473 case IDC_USE_SYSTEM_TITLE_BAR: { 474 PrefService* prefs = browser_->profile()->GetPrefs(); 475 prefs->SetBoolean(prefs::kUseCustomChromeFrame, 476 !prefs->GetBoolean(prefs::kUseCustomChromeFrame)); 477 break; 478 } 479 #endif 480 481 #if defined(OS_WIN) 482 // Windows 8 specific commands. 483 case IDC_METRO_SNAP_ENABLE: 484 browser_->SetMetroSnapMode(true); 485 break; 486 case IDC_METRO_SNAP_DISABLE: 487 browser_->SetMetroSnapMode(false); 488 break; 489 case IDC_WIN_DESKTOP_RESTART: 490 if (!VerifyASHSwitchForApps(window()->GetNativeWindow(), id)) 491 break; 492 493 chrome::AttemptRestartToDesktopMode(); 494 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { 495 content::RecordAction(base::UserMetricsAction("Win8DesktopRestart")); 496 } else { 497 content::RecordAction(base::UserMetricsAction("Win7DesktopRestart")); 498 } 499 break; 500 case IDC_WIN8_METRO_RESTART: 501 case IDC_WIN_CHROMEOS_RESTART: 502 if (!VerifyASHSwitchForApps(window()->GetNativeWindow(), id)) 503 break; 504 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { 505 // SwitchToMetroUIHandler deletes itself. 506 new SwitchToMetroUIHandler; 507 content::RecordAction(base::UserMetricsAction("Win8MetroRestart")); 508 } else { 509 content::RecordAction(base::UserMetricsAction("Win7ASHRestart")); 510 chrome::AttemptRestartToMetroMode(); 511 } 512 break; 513 #endif 514 515 #if defined(OS_MACOSX) 516 case IDC_PRESENTATION_MODE: 517 chrome::ToggleFullscreenMode(browser_); 518 break; 519 #endif 520 case IDC_EXIT: 521 Exit(); 522 break; 523 524 // Page-related commands 525 case IDC_SAVE_PAGE: 526 SavePage(browser_); 527 break; 528 case IDC_BOOKMARK_PAGE: 529 BookmarkCurrentPage(browser_); 530 break; 531 case IDC_PIN_TO_START_SCREEN: 532 TogglePagePinnedToStartScreen(browser_); 533 break; 534 case IDC_BOOKMARK_ALL_TABS: 535 BookmarkAllTabs(browser_); 536 break; 537 case IDC_VIEW_SOURCE: 538 ViewSelectedSource(browser_); 539 break; 540 case IDC_EMAIL_PAGE_LOCATION: 541 EmailPageLocation(browser_); 542 break; 543 case IDC_PRINT: 544 Print(browser_); 545 break; 546 #if !defined(DISABLE_BASIC_PRINTING) 547 case IDC_BASIC_PRINT: 548 content::RecordAction(base::UserMetricsAction("Accel_Advanced_Print")); 549 BasicPrint(browser_); 550 break; 551 #endif // !DISABLE_BASIC_PRINTING 552 case IDC_TRANSLATE_PAGE: 553 Translate(browser_); 554 break; 555 case IDC_MANAGE_PASSWORDS_FOR_PAGE: 556 ManagePasswordsForPage(browser_); 557 break; 558 559 // Page encoding commands 560 case IDC_ENCODING_AUTO_DETECT: 561 browser_->ToggleEncodingAutoDetect(); 562 break; 563 case IDC_ENCODING_UTF8: 564 case IDC_ENCODING_UTF16LE: 565 case IDC_ENCODING_ISO88591: 566 case IDC_ENCODING_WINDOWS1252: 567 case IDC_ENCODING_GBK: 568 case IDC_ENCODING_GB18030: 569 case IDC_ENCODING_BIG5HKSCS: 570 case IDC_ENCODING_BIG5: 571 case IDC_ENCODING_KOREAN: 572 case IDC_ENCODING_SHIFTJIS: 573 case IDC_ENCODING_ISO2022JP: 574 case IDC_ENCODING_EUCJP: 575 case IDC_ENCODING_THAI: 576 case IDC_ENCODING_ISO885915: 577 case IDC_ENCODING_MACINTOSH: 578 case IDC_ENCODING_ISO88592: 579 case IDC_ENCODING_WINDOWS1250: 580 case IDC_ENCODING_ISO88595: 581 case IDC_ENCODING_WINDOWS1251: 582 case IDC_ENCODING_KOI8R: 583 case IDC_ENCODING_KOI8U: 584 case IDC_ENCODING_ISO88597: 585 case IDC_ENCODING_WINDOWS1253: 586 case IDC_ENCODING_ISO88594: 587 case IDC_ENCODING_ISO885913: 588 case IDC_ENCODING_WINDOWS1257: 589 case IDC_ENCODING_ISO88593: 590 case IDC_ENCODING_ISO885910: 591 case IDC_ENCODING_ISO885914: 592 case IDC_ENCODING_ISO885916: 593 case IDC_ENCODING_WINDOWS1254: 594 case IDC_ENCODING_ISO88596: 595 case IDC_ENCODING_WINDOWS1256: 596 case IDC_ENCODING_ISO88598: 597 case IDC_ENCODING_ISO88598I: 598 case IDC_ENCODING_WINDOWS1255: 599 case IDC_ENCODING_WINDOWS1258: 600 browser_->OverrideEncoding(id); 601 break; 602 603 // Clipboard commands 604 case IDC_CUT: 605 Cut(browser_); 606 break; 607 case IDC_COPY: 608 Copy(browser_); 609 break; 610 case IDC_PASTE: 611 Paste(browser_); 612 break; 613 614 // Find-in-page 615 case IDC_FIND: 616 Find(browser_); 617 break; 618 case IDC_FIND_NEXT: 619 FindNext(browser_); 620 break; 621 case IDC_FIND_PREVIOUS: 622 FindPrevious(browser_); 623 break; 624 625 // Zoom 626 case IDC_ZOOM_PLUS: 627 Zoom(browser_, content::PAGE_ZOOM_IN); 628 break; 629 case IDC_ZOOM_NORMAL: 630 Zoom(browser_, content::PAGE_ZOOM_RESET); 631 break; 632 case IDC_ZOOM_MINUS: 633 Zoom(browser_, content::PAGE_ZOOM_OUT); 634 break; 635 636 // Focus various bits of UI 637 case IDC_FOCUS_TOOLBAR: 638 content::RecordAction(base::UserMetricsAction("Accel_Focus_Toolbar")); 639 FocusToolbar(browser_); 640 break; 641 case IDC_FOCUS_LOCATION: 642 content::RecordAction(base::UserMetricsAction("Accel_Focus_Location")); 643 FocusLocationBar(browser_); 644 break; 645 case IDC_FOCUS_SEARCH: 646 content::RecordAction(base::UserMetricsAction("Accel_Focus_Search")); 647 FocusSearch(browser_); 648 break; 649 case IDC_FOCUS_MENU_BAR: 650 FocusAppMenu(browser_); 651 break; 652 case IDC_FOCUS_BOOKMARKS: 653 content::RecordAction( 654 base::UserMetricsAction("Accel_Focus_Bookmarks")); 655 FocusBookmarksToolbar(browser_); 656 break; 657 case IDC_FOCUS_INFOBARS: 658 FocusInfobars(browser_); 659 break; 660 case IDC_FOCUS_NEXT_PANE: 661 FocusNextPane(browser_); 662 break; 663 case IDC_FOCUS_PREVIOUS_PANE: 664 FocusPreviousPane(browser_); 665 break; 666 667 // Show various bits of UI 668 case IDC_OPEN_FILE: 669 browser_->OpenFile(); 670 break; 671 case IDC_CREATE_SHORTCUTS: 672 CreateApplicationShortcuts(browser_); 673 break; 674 case IDC_CREATE_HOSTED_APP: 675 CreateBookmarkAppFromCurrentWebContents(browser_); 676 break; 677 case IDC_DEV_TOOLS: 678 ToggleDevToolsWindow(browser_, DevToolsToggleAction::Show()); 679 break; 680 case IDC_DEV_TOOLS_CONSOLE: 681 ToggleDevToolsWindow(browser_, DevToolsToggleAction::ShowConsole()); 682 break; 683 case IDC_DEV_TOOLS_DEVICES: 684 InspectUI::InspectDevices(browser_); 685 break; 686 case IDC_DEV_TOOLS_INSPECT: 687 ToggleDevToolsWindow(browser_, DevToolsToggleAction::Inspect()); 688 break; 689 case IDC_DEV_TOOLS_TOGGLE: 690 ToggleDevToolsWindow(browser_, DevToolsToggleAction::Toggle()); 691 break; 692 case IDC_TASK_MANAGER: 693 OpenTaskManager(browser_); 694 break; 695 #if defined(OS_CHROMEOS) 696 case IDC_TAKE_SCREENSHOT: 697 TakeScreenshot(); 698 break; 699 #endif 700 #if defined(GOOGLE_CHROME_BUILD) 701 case IDC_FEEDBACK: 702 OpenFeedbackDialog(browser_); 703 break; 704 #endif 705 case IDC_SHOW_BOOKMARK_BAR: 706 ToggleBookmarkBar(browser_); 707 break; 708 case IDC_PROFILING_ENABLED: 709 Profiling::Toggle(); 710 break; 711 712 case IDC_SHOW_BOOKMARK_MANAGER: 713 ShowBookmarkManager(browser_); 714 break; 715 case IDC_SHOW_APP_MENU: 716 content::RecordAction(base::UserMetricsAction("Accel_Show_App_Menu")); 717 ShowAppMenu(browser_); 718 break; 719 case IDC_SHOW_AVATAR_MENU: 720 ShowAvatarMenu(browser_); 721 break; 722 case IDC_SHOW_HISTORY: 723 ShowHistory(browser_); 724 break; 725 case IDC_SHOW_DOWNLOADS: 726 ShowDownloads(browser_); 727 break; 728 case IDC_MANAGE_EXTENSIONS: 729 ShowExtensions(browser_, std::string()); 730 break; 731 case IDC_OPTIONS: 732 ShowSettings(browser_); 733 break; 734 case IDC_EDIT_SEARCH_ENGINES: 735 ShowSearchEngineSettings(browser_); 736 break; 737 case IDC_VIEW_PASSWORDS: 738 ShowPasswordManager(browser_); 739 break; 740 case IDC_CLEAR_BROWSING_DATA: 741 ShowClearBrowsingDataDialog(browser_); 742 break; 743 case IDC_IMPORT_SETTINGS: 744 ShowImportDialog(browser_); 745 break; 746 case IDC_TOGGLE_REQUEST_TABLET_SITE: 747 ToggleRequestTabletSite(browser_); 748 break; 749 case IDC_ABOUT: 750 ShowAboutChrome(browser_); 751 break; 752 case IDC_UPGRADE_DIALOG: 753 OpenUpdateChromeDialog(browser_); 754 break; 755 case IDC_VIEW_INCOMPATIBILITIES: 756 ShowConflicts(browser_); 757 break; 758 case IDC_HELP_PAGE_VIA_KEYBOARD: 759 ShowHelp(browser_, HELP_SOURCE_KEYBOARD); 760 break; 761 case IDC_HELP_PAGE_VIA_MENU: 762 ShowHelp(browser_, HELP_SOURCE_MENU); 763 break; 764 case IDC_SHOW_SIGNIN: 765 ShowBrowserSignin(browser_, signin::SOURCE_MENU); 766 break; 767 case IDC_TOGGLE_SPEECH_INPUT: 768 ToggleSpeechInput(browser_); 769 break; 770 case IDC_DISTILL_PAGE: 771 DistillCurrentPage(browser_); 772 break; 773 774 default: 775 LOG(WARNING) << "Received Unimplemented Command: " << id; 776 break; 777 } 778 } 779 780 //////////////////////////////////////////////////////////////////////////////// 781 // BrowserCommandController, SigninPrefObserver implementation: 782 783 void BrowserCommandController::OnSigninAllowedPrefChange() { 784 // For unit tests, we don't have a window. 785 if (!window()) 786 return; 787 UpdateShowSyncState(IsShowingMainUI()); 788 } 789 790 // BrowserCommandController, TabStripModelObserver implementation: 791 792 void BrowserCommandController::TabInsertedAt(WebContents* contents, 793 int index, 794 bool foreground) { 795 AddInterstitialObservers(contents); 796 } 797 798 void BrowserCommandController::TabDetachedAt(WebContents* contents, int index) { 799 RemoveInterstitialObservers(contents); 800 } 801 802 void BrowserCommandController::TabReplacedAt(TabStripModel* tab_strip_model, 803 WebContents* old_contents, 804 WebContents* new_contents, 805 int index) { 806 RemoveInterstitialObservers(old_contents); 807 AddInterstitialObservers(new_contents); 808 } 809 810 void BrowserCommandController::TabBlockedStateChanged( 811 content::WebContents* contents, 812 int index) { 813 PrintingStateChanged(); 814 FullscreenStateChanged(); 815 UpdateCommandsForFind(); 816 } 817 818 //////////////////////////////////////////////////////////////////////////////// 819 // BrowserCommandController, TabRestoreServiceObserver implementation: 820 821 void BrowserCommandController::TabRestoreServiceChanged( 822 TabRestoreService* service) { 823 UpdateTabRestoreCommandState(); 824 } 825 826 void BrowserCommandController::TabRestoreServiceDestroyed( 827 TabRestoreService* service) { 828 service->RemoveObserver(this); 829 } 830 831 void BrowserCommandController::TabRestoreServiceLoaded( 832 TabRestoreService* service) { 833 UpdateTabRestoreCommandState(); 834 } 835 836 //////////////////////////////////////////////////////////////////////////////// 837 // BrowserCommandController, private: 838 839 class BrowserCommandController::InterstitialObserver 840 : public content::WebContentsObserver { 841 public: 842 InterstitialObserver(BrowserCommandController* controller, 843 content::WebContents* web_contents) 844 : WebContentsObserver(web_contents), 845 controller_(controller) { 846 } 847 848 virtual void DidAttachInterstitialPage() OVERRIDE { 849 controller_->UpdateCommandsForTabState(); 850 } 851 852 virtual void DidDetachInterstitialPage() OVERRIDE { 853 controller_->UpdateCommandsForTabState(); 854 } 855 856 private: 857 BrowserCommandController* controller_; 858 859 DISALLOW_COPY_AND_ASSIGN(InterstitialObserver); 860 }; 861 862 bool BrowserCommandController::IsShowingMainUI() { 863 bool should_hide_ui = window() && window()->ShouldHideUIForFullscreen(); 864 return browser_->is_type_tabbed() && !should_hide_ui; 865 } 866 867 void BrowserCommandController::InitCommandState() { 868 // All browser commands whose state isn't set automagically some other way 869 // (like Back & Forward with initial page load) must have their state 870 // initialized here, otherwise they will be forever disabled. 871 872 // Navigation commands 873 command_updater_.UpdateCommandEnabled(IDC_RELOAD, true); 874 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, true); 875 command_updater_.UpdateCommandEnabled(IDC_RELOAD_CLEARING_CACHE, true); 876 877 // Window management commands 878 command_updater_.UpdateCommandEnabled(IDC_CLOSE_WINDOW, true); 879 command_updater_.UpdateCommandEnabled(IDC_NEW_TAB, true); 880 command_updater_.UpdateCommandEnabled(IDC_CLOSE_TAB, true); 881 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, true); 882 UpdateTabRestoreCommandState(); 883 #if defined(OS_WIN) && defined(USE_ASH) 884 if (browser_->host_desktop_type() != chrome::HOST_DESKTOP_TYPE_ASH) 885 command_updater_.UpdateCommandEnabled(IDC_EXIT, true); 886 #else 887 command_updater_.UpdateCommandEnabled(IDC_EXIT, true); 888 #endif 889 command_updater_.UpdateCommandEnabled(IDC_DEBUG_FRAME_TOGGLE, true); 890 #if defined(USE_ASH) 891 command_updater_.UpdateCommandEnabled(IDC_MINIMIZE_WINDOW, true); 892 #endif 893 #if defined(OS_CHROMEOS) 894 command_updater_.UpdateCommandEnabled(IDC_VISIT_DESKTOP_OF_LRU_USER_2, true); 895 command_updater_.UpdateCommandEnabled(IDC_VISIT_DESKTOP_OF_LRU_USER_3, true); 896 #endif 897 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 898 command_updater_.UpdateCommandEnabled(IDC_USE_SYSTEM_TITLE_BAR, true); 899 #endif 900 901 // Page-related commands 902 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, true); 903 command_updater_.UpdateCommandEnabled(IDC_MANAGE_PASSWORDS_FOR_PAGE, true); 904 command_updater_.UpdateCommandEnabled(IDC_ENCODING_AUTO_DETECT, true); 905 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF8, true); 906 command_updater_.UpdateCommandEnabled(IDC_ENCODING_UTF16LE, true); 907 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88591, true); 908 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1252, true); 909 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GBK, true); 910 command_updater_.UpdateCommandEnabled(IDC_ENCODING_GB18030, true); 911 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5HKSCS, true); 912 command_updater_.UpdateCommandEnabled(IDC_ENCODING_BIG5, true); 913 command_updater_.UpdateCommandEnabled(IDC_ENCODING_THAI, true); 914 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOREAN, true); 915 command_updater_.UpdateCommandEnabled(IDC_ENCODING_SHIFTJIS, true); 916 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO2022JP, true); 917 command_updater_.UpdateCommandEnabled(IDC_ENCODING_EUCJP, true); 918 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885915, true); 919 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MACINTOSH, true); 920 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88592, true); 921 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1250, true); 922 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88595, true); 923 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1251, true); 924 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8R, true); 925 command_updater_.UpdateCommandEnabled(IDC_ENCODING_KOI8U, true); 926 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88597, true); 927 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1253, true); 928 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88594, true); 929 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885913, true); 930 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1257, true); 931 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88593, true); 932 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885910, true); 933 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885914, true); 934 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO885916, true); 935 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1254, true); 936 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88596, true); 937 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1256, true); 938 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598, true); 939 command_updater_.UpdateCommandEnabled(IDC_ENCODING_ISO88598I, true); 940 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1255, true); 941 command_updater_.UpdateCommandEnabled(IDC_ENCODING_WINDOWS1258, true); 942 943 // Zoom 944 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MENU, true); 945 command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, true); 946 command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, false); 947 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true); 948 949 // Show various bits of UI 950 const bool guest_session = profile()->IsGuestSession(); 951 const bool normal_window = browser_->is_type_tabbed(); 952 UpdateOpenFileState(&command_updater_); 953 command_updater_.UpdateCommandEnabled(IDC_CREATE_SHORTCUTS, false); 954 UpdateCommandsForDevTools(); 955 command_updater_.UpdateCommandEnabled(IDC_TASK_MANAGER, CanOpenTaskManager()); 956 command_updater_.UpdateCommandEnabled(IDC_SHOW_HISTORY, !guest_session); 957 command_updater_.UpdateCommandEnabled(IDC_SHOW_DOWNLOADS, true); 958 command_updater_.UpdateCommandEnabled(IDC_HELP_MENU, true); 959 command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_KEYBOARD, true); 960 command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_MENU, true); 961 command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU, !guest_session); 962 command_updater_.UpdateCommandEnabled(IDC_RECENT_TABS_MENU, 963 !guest_session && 964 !profile()->IsOffTheRecord()); 965 command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, normal_window); 966 #if defined(OS_CHROMEOS) 967 command_updater_.UpdateCommandEnabled(IDC_TAKE_SCREENSHOT, true); 968 #else 969 // Chrome OS uses the system tray menu to handle multi-profiles. 970 if (normal_window && (guest_session || !profile()->IsOffTheRecord())) 971 command_updater_.UpdateCommandEnabled(IDC_SHOW_AVATAR_MENU, true); 972 #endif 973 974 UpdateShowSyncState(true); 975 976 // Navigation commands 977 command_updater_.UpdateCommandEnabled( 978 IDC_HOME, 979 normal_window || (extensions::util::IsStreamlinedHostedAppsEnabled() && 980 browser_->is_app())); 981 982 // Window management commands 983 command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window); 984 command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB, 985 normal_window); 986 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, normal_window); 987 command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, normal_window); 988 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, normal_window); 989 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_1, normal_window); 990 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_2, normal_window); 991 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_3, normal_window); 992 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_4, normal_window); 993 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_5, normal_window); 994 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_6, normal_window); 995 command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_7, normal_window); 996 command_updater_.UpdateCommandEnabled(IDC_SELECT_LAST_TAB, normal_window); 997 #if defined(OS_WIN) 998 bool metro = browser_->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH; 999 command_updater_.UpdateCommandEnabled(IDC_METRO_SNAP_ENABLE, metro); 1000 command_updater_.UpdateCommandEnabled(IDC_METRO_SNAP_DISABLE, metro); 1001 int restart_mode = metro ? IDC_WIN_DESKTOP_RESTART : 1002 (base::win::GetVersion() >= base::win::VERSION_WIN8 ? 1003 IDC_WIN8_METRO_RESTART : IDC_WIN_CHROMEOS_RESTART); 1004 command_updater_.UpdateCommandEnabled(restart_mode, normal_window); 1005 #endif 1006 1007 // These are always enabled; the menu determines their menu item visibility. 1008 command_updater_.UpdateCommandEnabled(IDC_UPGRADE_DIALOG, true); 1009 command_updater_.UpdateCommandEnabled(IDC_VIEW_INCOMPATIBILITIES, true); 1010 1011 // Toggle speech input 1012 command_updater_.UpdateCommandEnabled(IDC_TOGGLE_SPEECH_INPUT, true); 1013 1014 // Distill current page. 1015 command_updater_.UpdateCommandEnabled( 1016 IDC_DISTILL_PAGE, 1017 CommandLine::ForCurrentProcess()->HasSwitch( 1018 switches::kEnableDomDistiller)); 1019 1020 // Initialize other commands whose state changes based on various conditions. 1021 UpdateCommandsForFullscreenMode(); 1022 UpdateCommandsForContentRestrictionState(); 1023 UpdateCommandsForBookmarkEditing(); 1024 UpdateCommandsForIncognitoAvailability(); 1025 } 1026 1027 // static 1028 void BrowserCommandController::UpdateSharedCommandsForIncognitoAvailability( 1029 CommandUpdater* command_updater, 1030 Profile* profile) { 1031 const bool guest_session = profile->IsGuestSession(); 1032 // TODO(mlerman): Make GetAvailability account for profile->IsGuestSession(). 1033 IncognitoModePrefs::Availability incognito_availability = 1034 IncognitoModePrefs::GetAvailability(profile->GetPrefs()); 1035 command_updater->UpdateCommandEnabled( 1036 IDC_NEW_WINDOW, 1037 incognito_availability != IncognitoModePrefs::FORCED); 1038 command_updater->UpdateCommandEnabled( 1039 IDC_NEW_INCOGNITO_WINDOW, 1040 incognito_availability != IncognitoModePrefs::DISABLED && !guest_session); 1041 1042 const bool forced_incognito = 1043 incognito_availability == IncognitoModePrefs::FORCED || 1044 guest_session; // Guest always runs in Incognito mode. 1045 command_updater->UpdateCommandEnabled( 1046 IDC_SHOW_BOOKMARK_MANAGER, 1047 browser_defaults::bookmarks_enabled && !forced_incognito); 1048 ExtensionService* extension_service = 1049 extensions::ExtensionSystem::Get(profile)->extension_service(); 1050 const bool enable_extensions = 1051 extension_service && extension_service->extensions_enabled(); 1052 1053 // Bookmark manager and settings page/subpages are forced to open in normal 1054 // mode. For this reason we disable these commands when incognito is forced. 1055 command_updater->UpdateCommandEnabled(IDC_MANAGE_EXTENSIONS, 1056 enable_extensions && !forced_incognito); 1057 1058 command_updater->UpdateCommandEnabled(IDC_IMPORT_SETTINGS, !forced_incognito); 1059 command_updater->UpdateCommandEnabled(IDC_OPTIONS, 1060 !forced_incognito || guest_session); 1061 command_updater->UpdateCommandEnabled(IDC_SHOW_SIGNIN, !forced_incognito); 1062 } 1063 1064 void BrowserCommandController::UpdateCommandsForIncognitoAvailability() { 1065 UpdateSharedCommandsForIncognitoAvailability(&command_updater_, profile()); 1066 1067 if (!IsShowingMainUI()) { 1068 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, false); 1069 command_updater_.UpdateCommandEnabled(IDC_OPTIONS, false); 1070 } 1071 } 1072 1073 void BrowserCommandController::UpdateCommandsForTabState() { 1074 WebContents* current_web_contents = 1075 browser_->tab_strip_model()->GetActiveWebContents(); 1076 if (!current_web_contents) // May be NULL during tab restore. 1077 return; 1078 1079 // Navigation commands 1080 command_updater_.UpdateCommandEnabled(IDC_BACK, CanGoBack(browser_)); 1081 command_updater_.UpdateCommandEnabled(IDC_FORWARD, CanGoForward(browser_)); 1082 command_updater_.UpdateCommandEnabled(IDC_RELOAD, CanReload(browser_)); 1083 command_updater_.UpdateCommandEnabled(IDC_RELOAD_IGNORING_CACHE, 1084 CanReload(browser_)); 1085 command_updater_.UpdateCommandEnabled(IDC_RELOAD_CLEARING_CACHE, 1086 CanReload(browser_)); 1087 1088 // Window management commands 1089 command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, 1090 !browser_->is_app() && CanDuplicateTab(browser_)); 1091 1092 // Page-related commands 1093 window()->SetStarredState( 1094 BookmarkTabHelper::FromWebContents(current_web_contents)->is_starred()); 1095 window()->ZoomChangedForActiveTab(false); 1096 command_updater_.UpdateCommandEnabled(IDC_VIEW_SOURCE, 1097 CanViewSource(browser_)); 1098 command_updater_.UpdateCommandEnabled(IDC_EMAIL_PAGE_LOCATION, 1099 CanEmailPageLocation(browser_)); 1100 if (browser_->is_devtools()) 1101 command_updater_.UpdateCommandEnabled(IDC_OPEN_FILE, false); 1102 1103 // Changing the encoding is not possible on Chrome-internal webpages. 1104 NavigationController& nc = current_web_contents->GetController(); 1105 bool is_chrome_internal = HasInternalURL(nc.GetLastCommittedEntry()) || 1106 current_web_contents->ShowingInterstitialPage(); 1107 command_updater_.UpdateCommandEnabled(IDC_ENCODING_MENU, 1108 !is_chrome_internal && current_web_contents->IsSavable()); 1109 1110 // Show various bits of UI 1111 // TODO(pinkerton): Disable app-mode in the model until we implement it 1112 // on the Mac. Be sure to remove both ifdefs. http://crbug.com/13148 1113 #if !defined(OS_MACOSX) 1114 command_updater_.UpdateCommandEnabled( 1115 IDC_CREATE_SHORTCUTS, 1116 CanCreateApplicationShortcuts(browser_)); 1117 command_updater_.UpdateCommandEnabled(IDC_CREATE_HOSTED_APP, 1118 CanCreateBookmarkApp(browser_)); 1119 #endif 1120 1121 command_updater_.UpdateCommandEnabled( 1122 IDC_TOGGLE_REQUEST_TABLET_SITE, 1123 CanRequestTabletSite(current_web_contents)); 1124 1125 UpdateCommandsForContentRestrictionState(); 1126 UpdateCommandsForBookmarkEditing(); 1127 UpdateCommandsForFind(); 1128 // Update the zoom commands when an active tab is selected. 1129 UpdateCommandsForZoomState(); 1130 } 1131 1132 void BrowserCommandController::UpdateCommandsForZoomState() { 1133 WebContents* contents = 1134 browser_->tab_strip_model()->GetActiveWebContents(); 1135 if (!contents) 1136 return; 1137 command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, CanZoomIn(contents)); 1138 command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, ActualSize(contents)); 1139 command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, CanZoomOut(contents)); 1140 } 1141 1142 void BrowserCommandController::UpdateCommandsForContentRestrictionState() { 1143 int restrictions = GetContentRestrictions(browser_); 1144 1145 command_updater_.UpdateCommandEnabled( 1146 IDC_COPY, !(restrictions & CONTENT_RESTRICTION_COPY)); 1147 command_updater_.UpdateCommandEnabled( 1148 IDC_CUT, !(restrictions & CONTENT_RESTRICTION_CUT)); 1149 command_updater_.UpdateCommandEnabled( 1150 IDC_PASTE, !(restrictions & CONTENT_RESTRICTION_PASTE)); 1151 UpdateSaveAsState(); 1152 UpdatePrintingState(); 1153 } 1154 1155 void BrowserCommandController::UpdateCommandsForDevTools() { 1156 bool dev_tools_enabled = 1157 !profile()->GetPrefs()->GetBoolean(prefs::kDevToolsDisabled); 1158 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS, 1159 dev_tools_enabled); 1160 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE, 1161 dev_tools_enabled); 1162 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_DEVICES, 1163 dev_tools_enabled); 1164 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_INSPECT, 1165 dev_tools_enabled); 1166 command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_TOGGLE, 1167 dev_tools_enabled); 1168 } 1169 1170 void BrowserCommandController::UpdateCommandsForBookmarkEditing() { 1171 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_PAGE, 1172 CanBookmarkCurrentPage(browser_)); 1173 command_updater_.UpdateCommandEnabled(IDC_BOOKMARK_ALL_TABS, 1174 CanBookmarkAllTabs(browser_)); 1175 command_updater_.UpdateCommandEnabled(IDC_PIN_TO_START_SCREEN, 1176 true); 1177 } 1178 1179 void BrowserCommandController::UpdateCommandsForBookmarkBar() { 1180 command_updater_.UpdateCommandEnabled( 1181 IDC_SHOW_BOOKMARK_BAR, 1182 browser_defaults::bookmarks_enabled && !profile()->IsGuestSession() && 1183 !profile()->GetPrefs()->IsManagedPreference( 1184 bookmarks::prefs::kShowBookmarkBar) && 1185 IsShowingMainUI()); 1186 } 1187 1188 void BrowserCommandController::UpdateCommandsForFileSelectionDialogs() { 1189 UpdateSaveAsState(); 1190 UpdateOpenFileState(&command_updater_); 1191 } 1192 1193 void BrowserCommandController::UpdateCommandsForFullscreenMode() { 1194 WindowState window_state = WINDOW_STATE_NOT_FULLSCREEN; 1195 if (window() && window()->IsFullscreen()) { 1196 window_state = WINDOW_STATE_FULLSCREEN; 1197 #if defined(OS_WIN) 1198 if (window()->IsInMetroSnapMode()) 1199 window_state = WINDOW_STATE_METRO_SNAP; 1200 #endif 1201 } 1202 bool show_main_ui = IsShowingMainUI(); 1203 bool main_not_fullscreen = 1204 show_main_ui && window_state == WINDOW_STATE_NOT_FULLSCREEN; 1205 1206 // Navigation commands 1207 command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, show_main_ui); 1208 1209 // Window management commands 1210 command_updater_.UpdateCommandEnabled( 1211 IDC_SHOW_AS_TAB, 1212 !browser_->is_type_tabbed() && 1213 window_state == WINDOW_STATE_NOT_FULLSCREEN); 1214 1215 // Focus various bits of UI 1216 command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui); 1217 command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_main_ui); 1218 command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui); 1219 command_updater_.UpdateCommandEnabled( 1220 IDC_FOCUS_MENU_BAR, main_not_fullscreen); 1221 command_updater_.UpdateCommandEnabled( 1222 IDC_FOCUS_NEXT_PANE, main_not_fullscreen); 1223 command_updater_.UpdateCommandEnabled( 1224 IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen); 1225 command_updater_.UpdateCommandEnabled( 1226 IDC_FOCUS_BOOKMARKS, main_not_fullscreen); 1227 command_updater_.UpdateCommandEnabled( 1228 IDC_FOCUS_INFOBARS, main_not_fullscreen); 1229 1230 // Show various bits of UI 1231 command_updater_.UpdateCommandEnabled(IDC_DEVELOPER_MENU, show_main_ui); 1232 #if defined(GOOGLE_CHROME_BUILD) 1233 command_updater_.UpdateCommandEnabled(IDC_FEEDBACK, show_main_ui); 1234 #endif 1235 UpdateShowSyncState(show_main_ui); 1236 1237 // Settings page/subpages are forced to open in normal mode. We disable these 1238 // commands for guest sessions and when incognito is forced. 1239 const bool options_enabled = show_main_ui && 1240 IncognitoModePrefs::GetAvailability( 1241 profile()->GetPrefs()) != IncognitoModePrefs::FORCED; 1242 const bool guest_session = profile()->IsGuestSession(); 1243 command_updater_.UpdateCommandEnabled(IDC_OPTIONS, options_enabled); 1244 command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, 1245 options_enabled && !guest_session); 1246 1247 command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui); 1248 command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui); 1249 command_updater_.UpdateCommandEnabled(IDC_ABOUT, show_main_ui); 1250 command_updater_.UpdateCommandEnabled(IDC_SHOW_APP_MENU, show_main_ui); 1251 #if defined (ENABLE_PROFILING) && !defined(NO_TCMALLOC) 1252 command_updater_.UpdateCommandEnabled(IDC_PROFILING_ENABLED, show_main_ui); 1253 #endif 1254 1255 // Disable explicit fullscreen toggling when in metro snap mode. 1256 bool fullscreen_enabled = window_state != WINDOW_STATE_METRO_SNAP; 1257 #if !defined(OS_MACOSX) 1258 if (window_state == WINDOW_STATE_NOT_FULLSCREEN && 1259 !profile()->GetPrefs()->GetBoolean(prefs::kFullscreenAllowed)) { 1260 // Disable toggling into fullscreen mode if disallowed by pref. 1261 fullscreen_enabled = false; 1262 } 1263 #endif 1264 1265 command_updater_.UpdateCommandEnabled(IDC_FULLSCREEN, fullscreen_enabled); 1266 command_updater_.UpdateCommandEnabled(IDC_PRESENTATION_MODE, 1267 fullscreen_enabled); 1268 1269 UpdateCommandsForBookmarkBar(); 1270 } 1271 1272 void BrowserCommandController::UpdatePrintingState() { 1273 bool print_enabled = CanPrint(browser_); 1274 command_updater_.UpdateCommandEnabled(IDC_PRINT, print_enabled); 1275 #if !defined(DISABLE_BASIC_PRINTING) 1276 command_updater_.UpdateCommandEnabled(IDC_BASIC_PRINT, 1277 CanBasicPrint(browser_)); 1278 #endif // !DISABLE_BASIC_PRINTING 1279 } 1280 1281 void BrowserCommandController::UpdateSaveAsState() { 1282 command_updater_.UpdateCommandEnabled(IDC_SAVE_PAGE, CanSavePage(browser_)); 1283 } 1284 1285 void BrowserCommandController::UpdateShowSyncState(bool show_main_ui) { 1286 command_updater_.UpdateCommandEnabled( 1287 IDC_SHOW_SYNC_SETUP, show_main_ui && pref_signin_allowed_.GetValue()); 1288 } 1289 1290 // static 1291 void BrowserCommandController::UpdateOpenFileState( 1292 CommandUpdater* command_updater) { 1293 bool enabled = true; 1294 PrefService* local_state = g_browser_process->local_state(); 1295 if (local_state) 1296 enabled = local_state->GetBoolean(prefs::kAllowFileSelectionDialogs); 1297 1298 command_updater->UpdateCommandEnabled(IDC_OPEN_FILE, enabled); 1299 } 1300 1301 void BrowserCommandController::UpdateReloadStopState(bool is_loading, 1302 bool force) { 1303 window()->UpdateReloadStopState(is_loading, force); 1304 command_updater_.UpdateCommandEnabled(IDC_STOP, is_loading); 1305 } 1306 1307 void BrowserCommandController::UpdateTabRestoreCommandState() { 1308 TabRestoreService* tab_restore_service = 1309 TabRestoreServiceFactory::GetForProfile(profile()); 1310 // The command is enabled if the service hasn't loaded yet to trigger loading. 1311 // The command is updated once the load completes. 1312 command_updater_.UpdateCommandEnabled( 1313 IDC_RESTORE_TAB, 1314 tab_restore_service && 1315 (!tab_restore_service->IsLoaded() || 1316 GetRestoreTabType(browser_) != TabStripModelDelegate::RESTORE_NONE)); 1317 } 1318 1319 void BrowserCommandController::UpdateCommandsForFind() { 1320 TabStripModel* model = browser_->tab_strip_model(); 1321 bool enabled = !model->IsTabBlocked(model->active_index()) && 1322 !browser_->is_devtools(); 1323 1324 command_updater_.UpdateCommandEnabled(IDC_FIND, enabled); 1325 command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, enabled); 1326 command_updater_.UpdateCommandEnabled(IDC_FIND_PREVIOUS, enabled); 1327 } 1328 1329 void BrowserCommandController::AddInterstitialObservers(WebContents* contents) { 1330 interstitial_observers_.push_back(new InterstitialObserver(this, contents)); 1331 } 1332 1333 void BrowserCommandController::RemoveInterstitialObservers( 1334 WebContents* contents) { 1335 for (size_t i = 0; i < interstitial_observers_.size(); i++) { 1336 if (interstitial_observers_[i]->web_contents() != contents) 1337 continue; 1338 1339 delete interstitial_observers_[i]; 1340 interstitial_observers_.erase(interstitial_observers_.begin() + i); 1341 return; 1342 } 1343 } 1344 1345 BrowserWindow* BrowserCommandController::window() { 1346 return browser_->window(); 1347 } 1348 1349 Profile* BrowserCommandController::profile() { 1350 return browser_->profile(); 1351 } 1352 1353 } // namespace chrome 1354