diff options
author | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-19 16:14:47 +0000 |
---|---|---|
committer | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-19 16:14:47 +0000 |
commit | e90fa89d1e52b1b081c42267cdf1bb76c8f9a0db (patch) | |
tree | c571c898d7dcbc53d3bb289fa93d29a67c84df0b | |
parent | 652725dca523e36d14e6cf98d6e9fcf3a1db822c (diff) | |
download | chromium_src-e90fa89d1e52b1b081c42267cdf1bb76c8f9a0db.zip chromium_src-e90fa89d1e52b1b081c42267cdf1bb76c8f9a0db.tar.gz chromium_src-e90fa89d1e52b1b081c42267cdf1bb76c8f9a0db.tar.bz2 |
[Mac] Implement the update available notification in the wrench menu.
The changes to restart_browser.mm also affect the sheet displayed in the About
window. Note that the badge on the wrench menu looks bad.
BUG=45147
TEST=difficult
Review URL: http://codereview.chromium.org/2856042
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52911 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/generated_resources.grd | 22 | ||||
-rw-r--r-- | chrome/browser/browser_shutdown.cc | 13 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_cocoa.mm | 3 | ||||
-rw-r--r-- | chrome/browser/cocoa/menu_controller.mm | 12 | ||||
-rw-r--r-- | chrome/browser/cocoa/restart_browser.mm | 30 | ||||
-rw-r--r-- | chrome/browser/cocoa/toolbar_controller.h | 4 | ||||
-rw-r--r-- | chrome/browser/cocoa/toolbar_controller.mm | 58 | ||||
-rw-r--r-- | chrome/browser/wrench_menu_model.cc | 5 |
8 files changed, 120 insertions, 27 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 085a381..e4bb86a 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -7532,12 +7532,22 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_UPDATE_RECOMMENDED" desc="The main text of the Update Recommended dialog."> Old school's not cool. <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> is woefully out of date because it hasn't crashed or restarted in a while. Restart to apply update. </message> - <message name="IDS_RESTART_AND_UPDATE" desc="The button label for restarting and updating Chrome."> - Restart and update - </message> - <message name="IDS_NOT_NOW" desc="The button label for delaying the restart and updating Chrome."> - Not now - </message> + <if expr="not pp_ifdef('use_titlecase')"> + <message name="IDS_RESTART_AND_UPDATE" desc="The button label for restarting and updating Chrome."> + Restart and update + </message> + <message name="IDS_NOT_NOW" desc="The button label for delaying the restart and updating Chrome."> + Not now + </message> + </if> + <if expr="pp_ifdef('use_titlecase')"> + <message name="IDS_RESTART_AND_UPDATE" desc="In Tile Case: The button label for restarting and updating Chrome."> + Update and Restart + </message> + <message name="IDS_NOT_NOW" desc="In Tile Case: The button label for delaying the restart and updating Chrome."> + Not Now + </message> + </if> <!-- Extra Mac UI Strings --> <if expr="os == 'darwin'"> diff --git a/chrome/browser/browser_shutdown.cc b/chrome/browser/browser_shutdown.cc index f49f844..dd541ef 100644 --- a/chrome/browser/browser_shutdown.cc +++ b/chrome/browser/browser_shutdown.cc @@ -11,6 +11,7 @@ #include "base/file_util.h" #include "base/histogram.h" #include "base/path_service.h" +#include "base/process_util.h" #include "base/string_util.h" #include "base/thread.h" #include "base/time.h" @@ -164,16 +165,24 @@ void Shutdown() { #endif if (restart_last_session) { -#if (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) +#if !defined(OS_CHROMEOS) // Make sure to relaunch the browser with the same command line and add // Restore Last Session flag if session restore is not set. CommandLine command_line(*CommandLine::ForCurrentProcess()); if (!command_line.HasSwitch(switches::kRestoreLastSession)) command_line.AppendSwitch(switches::kRestoreLastSession); +#if defined(OS_WIN) || defined(OS_LINUX) Upgrade::RelaunchChromeBrowser(command_line); +#endif // defined(OS_WIN) || defined(OS_LINUX) + +#if defined(OS_MACOSX) + command_line.AppendSwitch(switches::kActivateOnLaunch); + base::LaunchApp(command_line, false, false, NULL); +#endif // defined(OS_MACOSX) + #else NOTIMPLEMENTED(); -#endif +#endif // !defined(OS_CHROMEOS) } if (shutdown_type_ > NOT_VALID && shutdown_num_processes_ > 0) { diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm index a0961e3..de83bbb 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/cocoa/browser_window_cocoa.mm @@ -28,6 +28,7 @@ #import "chrome/browser/cocoa/nsmenuitem_additions.h" #include "chrome/browser/cocoa/page_info_window_mac.h" #include "chrome/browser/cocoa/repost_form_warning_mac.h" +#include "chrome/browser/cocoa/restart_browser.h" #include "chrome/browser/cocoa/status_bubble_mac.h" #include "chrome/browser/cocoa/task_manager_mac.h" #import "chrome/browser/cocoa/theme_install_bubble_view.h" @@ -285,7 +286,7 @@ views::Window* BrowserWindowCocoa::ShowAboutChromeDialog() { } void BrowserWindowCocoa::ShowUpdateChromeDialog() { - NOTIMPLEMENTED(); + restart_browser::RequestRestart(nil); } void BrowserWindowCocoa::ShowTaskManager() { diff --git a/chrome/browser/cocoa/menu_controller.mm b/chrome/browser/cocoa/menu_controller.mm index 047c8dd..a5b8256 100644 --- a/chrome/browser/cocoa/menu_controller.mm +++ b/chrome/browser/cocoa/menu_controller.mm @@ -9,6 +9,8 @@ #include "app/menus/simple_menu_model.h" #include "base/logging.h" #include "base/sys_string_conversions.h" +#include "skia/ext/skia_utils_mac.h" +#include "third_party/skia/include/core/SkBitmap.h" @interface MenuController (Private) - (NSMenu*)menuFromModel:(menus::MenuModel*)model; @@ -86,6 +88,16 @@ [[NSMenuItem alloc] initWithTitle:label action:@selector(itemSelected:) keyEquivalent:@""]); + + // If the menu item has an icon, set it. + SkBitmap skiaIcon; + if (model->GetIconAt(modelIndex, &skiaIcon) && !skiaIcon.isNull()) { + NSImage* icon = gfx::SkBitmapToNSImage(skiaIcon); + if (icon) { + [item setImage:icon]; + } + } + menus::MenuModel::ItemType type = model->GetTypeAt(modelIndex); if (type == menus::MenuModel::TYPE_SUBMENU) { // Recursively build a submenu from the sub-model at this index. diff --git a/chrome/browser/cocoa/restart_browser.mm b/chrome/browser/cocoa/restart_browser.mm index 726fe65..d3747d60 100644 --- a/chrome/browser/cocoa/restart_browser.mm +++ b/chrome/browser/cocoa/restart_browser.mm @@ -2,8 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "app/l10n_util_mac.h" #import "chrome/browser/cocoa/restart_browser.h" + +#include "app/l10n_util_mac.h" +#include "chrome/browser/browser_list.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/pref_service.h" +#include "chrome/common/pref_names.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" #include "grit/app_strings.h" @@ -34,7 +39,16 @@ - (void)alertDidEnd:(NSAlert*)alert returnCode:(int)returnCode contextInfo:(void*)contextInfo { - // Nothing to do, just clean up + if (returnCode == NSAlertFirstButtonReturn) { + // Nothing to do. User will restart later. + } else if (returnCode == NSAlertSecondButtonReturn) { + // Set the flag to restore state after the restart. + PrefService* pref_service = g_browser_process->local_state(); + pref_service->SetBoolean(prefs::kRestartLastSessionOnShutdown, true); + BrowserList::CloseAllBrowsersAndExit(); + } else { + NOTREACHED(); + } [self autorelease]; } @@ -45,10 +59,13 @@ namespace restart_browser { void RequestRestart(NSWindow* parent) { NSString* title = l10n_util::GetNSStringFWithFixup(IDS_PLEASE_RESTART_BROWSER, - l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); + l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); NSString* text = - l10n_util::GetNSStringWithFixup(IDS_OPTIONS_RESTART_REQUIRED); - NSString* okBtn = l10n_util::GetNSStringWithFixup(IDS_APP_OK); + l10n_util::GetNSStringFWithFixup(IDS_UPDATE_RECOMMENDED, + l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); + NSString* notNowButtin = l10n_util::GetNSStringWithFixup(IDS_NOT_NOW); + NSString* restartButton = + l10n_util::GetNSStringWithFixup(IDS_RESTART_AND_UPDATE); RestartHelper* helper = [[RestartHelper alloc] init]; @@ -56,7 +73,8 @@ void RequestRestart(NSWindow* parent) { [alert setAlertStyle:NSInformationalAlertStyle]; [alert setMessageText:title]; [alert setInformativeText:text]; - [alert addButtonWithTitle:okBtn]; + [alert addButtonWithTitle:notNowButtin]; + [alert addButtonWithTitle:restartButton]; [alert beginSheetModalForWindow:parent modalDelegate:helper diff --git a/chrome/browser/cocoa/toolbar_controller.h b/chrome/browser/cocoa/toolbar_controller.h index 9d3ad48..458401a 100644 --- a/chrome/browser/cocoa/toolbar_controller.h +++ b/chrome/browser/cocoa/toolbar_controller.h @@ -28,7 +28,7 @@ class LocationBarViewMac; @class MenuButton; namespace ToolbarControllerInternal { class MenuDelegate; -class PrefObserverBridge; +class NotificationBridge; } // namespace ToolbarControllerInternal class Profile; @class ReloadButton; @@ -77,7 +77,7 @@ class WrenchMenuModel; scoped_ptr<WrenchMenuModel> wrenchMenuModel_; // Used for monitoring the optional toolbar button prefs. - scoped_ptr<ToolbarControllerInternal::PrefObserverBridge> prefObserver_; + scoped_ptr<ToolbarControllerInternal::NotificationBridge> notificationBridge_; BooleanPrefMember showHomeButton_; BooleanPrefMember showPageOptionButtons_; BOOL hasToolbar_; // If NO, we may have only the location bar. diff --git a/chrome/browser/cocoa/toolbar_controller.mm b/chrome/browser/cocoa/toolbar_controller.mm index cfa75f9..66010bd 100644 --- a/chrome/browser/cocoa/toolbar_controller.mm +++ b/chrome/browser/cocoa/toolbar_controller.mm @@ -17,6 +17,7 @@ #include "chrome/app/chrome_dll_resource.h" #include "chrome/browser/autocomplete/autocomplete_edit_view.h" #include "chrome/browser/browser.h" +#include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/browser_window.h" #import "chrome/browser/cocoa/accelerators_cocoa.h" #import "chrome/browser/cocoa/back_forward_menu_controller.h" @@ -39,14 +40,17 @@ #include "chrome/browser/search_engines/template_url_model.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/toolbar_model.h" +#include "chrome/browser/upgrade_detector.h" #include "chrome/browser/wrench_menu_model.h" #include "chrome/common/notification_details.h" #include "chrome/common/notification_observer.h" +#include "chrome/common/notification_service.h" #include "chrome/common/notification_type.h" #include "chrome/common/pref_names.h" #include "gfx/rect.h" #include "grit/chromium_strings.h" #include "grit/generated_resources.h" +#include "grit/theme_resources.h" namespace { @@ -85,6 +89,7 @@ const CGFloat kWrenchMenuLeftPadding = 3.0; - (void)browserActionsContainerDragFinished:(NSNotification*)notification; - (void)browserActionsVisibilityChanged:(NSNotification*)notification; - (void)adjustLocationSizeBy:(CGFloat)dX animate:(BOOL)animate; +- (void)badgeWrenchMenu; @end namespace ToolbarControllerInternal { @@ -144,21 +149,31 @@ class MenuDelegate : public menus::SimpleMenuModel::Delegate { Browser* browser_; }; -// A C++ class registered for changes in preferences. Bridges the -// notification back to the ToolbarController. -class PrefObserverBridge : public NotificationObserver { +// A class registered for C++ notifications. This is used to detect changes in +// preferences and upgrade available notifications. Bridges the notification +// back to the ToolbarController. +class NotificationBridge : public NotificationObserver { public: - explicit PrefObserverBridge(ToolbarController* controller) - : controller_(controller) { } + explicit NotificationBridge(ToolbarController* controller) + : controller_(controller) { + registrar_.Add(this, NotificationType::UPGRADE_RECOMMENDED, + NotificationService::AllSources()); + } + // Overridden from NotificationObserver: virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { if (type == NotificationType::PREF_CHANGED) [controller_ prefChanged:Details<std::wstring>(details).ptr()]; + else if (type == NotificationType::UPGRADE_RECOMMENDED) + [controller_ badgeWrenchMenu]; } + private: ToolbarController* controller_; // weak, owns us + + NotificationRegistrar registrar_; }; } // namespace ToolbarControllerInternal @@ -235,7 +250,13 @@ class PrefObserverBridge : public NotificationObserver { [reloadButton_ setImage:nsimage_cache::ImageNamed(kReloadButtonReloadImageName)]; [homeButton_ setImage:nsimage_cache::ImageNamed(kHomeButtonImageName)]; - [wrenchButton_ setImage:nsimage_cache::ImageNamed(kWrenchButtonImageName)]; + + if (Singleton<UpgradeDetector>::get()->notify_upgrade()) { + [self badgeWrenchMenu]; + } else { + NSImage* wrenchImage = nsimage_cache::ImageNamed(kWrenchButtonImageName); + [wrenchButton_ setImage:wrenchImage]; + } [backButton_ setShowsBorderOnlyWhileMouseInside:YES]; [forwardButton_ setShowsBorderOnlyWhileMouseInside:YES]; @@ -250,11 +271,13 @@ class PrefObserverBridge : public NotificationObserver { [locationBar_ setFont:[NSFont systemFontOfSize:[NSFont systemFontSize]]]; // Register pref observers for the optional home and page/options buttons // and then add them to the toolbar based on those prefs. - prefObserver_.reset(new ToolbarControllerInternal::PrefObserverBridge(self)); + notificationBridge_.reset( + new ToolbarControllerInternal::NotificationBridge(self)); PrefService* prefs = profile_->GetPrefs(); - showHomeButton_.Init(prefs::kShowHomeButton, prefs, prefObserver_.get()); + showHomeButton_.Init(prefs::kShowHomeButton, prefs, + notificationBridge_.get()); showPageOptionButtons_.Init(prefs::kShowPageOptionsButtons, prefs, - prefObserver_.get()); + notificationBridge_.get()); [self showOptionalHomeButton]; [self installWrenchMenu]; @@ -524,6 +547,23 @@ class PrefObserverBridge : public NotificationObserver { return wrenchMenuController_; } +- (void)badgeWrenchMenu { + // The wrench menu gets an upgrade dot. Currently, it's ugly. + // http://crbug.com/49370 + NSImage* wrenchImage = nsimage_cache::ImageNamed(kWrenchButtonImageName); + ThemeProvider* theme_provider = profile_->GetThemeProvider(); + NSImage* badge = theme_provider->GetNSImageNamed(IDR_UPGRADE_DOT_ACTIVE, + true); + [wrenchImage lockFocus]; + [badge drawAtPoint:NSMakePoint(1, 1) + fromRect:NSZeroRect + operation:NSCompositeSourceOver + fraction:1.0]; + [wrenchImage unlockFocus]; + [wrenchButton_ setImage:wrenchImage]; + [wrenchButton_ setNeedsDisplay:YES]; +} + - (void)prefChanged:(std::wstring*)prefName { if (!prefName) return; if (*prefName == prefs::kShowHomeButton) { diff --git a/chrome/browser/wrench_menu_model.cc b/chrome/browser/wrench_menu_model.cc index 637ab57..dd427023 100644 --- a/chrome/browser/wrench_menu_model.cc +++ b/chrome/browser/wrench_menu_model.cc @@ -255,7 +255,10 @@ void WrenchMenuModel::Build() { AddItemWithStringId(IDC_OPTIONS, IDS_OPTIONS); #endif - if (browser_defaults::kShowAboutMenuItem) { + // On Mac, there is no About item unless it is replaced with the update + // available notification. + if (browser_defaults::kShowAboutMenuItem || + Singleton<UpgradeDetector>::get()->notify_upgrade()) { AddItem(IDC_ABOUT, l10n_util::GetStringFUTF16( IDS_ABOUT, |