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