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