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