diff options
author | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-24 00:55:35 +0000 |
---|---|---|
committer | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-24 00:55:35 +0000 |
commit | f9bc9b9ca68926b2687ae073941c8186aa3aed0d (patch) | |
tree | a15d6b735ca16d4739d1ce435512fe311bf8ef1a /chrome | |
parent | 6b5cc7aeca6761c88c0f98b0e54990becbe32177 (diff) | |
download | chromium_src-f9bc9b9ca68926b2687ae073941c8186aa3aed0d.zip chromium_src-f9bc9b9ca68926b2687ae073941c8186aa3aed0d.tar.gz chromium_src-f9bc9b9ca68926b2687ae073941c8186aa3aed0d.tar.bz2 |
Added main menu item for Sync in OS X. (Right below "Preferences..."). Made it work without a browser window being present.
Moved menu verification code into sync_status_ui_helper_mac{.h,.mm,_unittest.mm}.
BUG=27995
TEST=tested that the main menu item worked with or without a browser window. tested that the main menu item didn't show up unless --enable-sync was passed in.
Review URL: http://codereview.chromium.org/423004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@32892 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/app/nibs/MainMenu.xib | 54 | ||||
-rw-r--r-- | chrome/browser/app_controller_mac.mm | 15 | ||||
-rw-r--r-- | chrome/browser/browser.cc | 3 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller.h | 6 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller.mm | 69 | ||||
-rw-r--r-- | chrome/browser/cocoa/browser_window_controller_unittest.mm | 71 | ||||
-rw-r--r-- | chrome/browser/cocoa/html_dialog_window_controller.mm | 8 | ||||
-rw-r--r-- | chrome/browser/cocoa/html_dialog_window_controller_cppsafe.h | 25 | ||||
-rw-r--r-- | chrome/browser/sync/sync_setup_flow.cc | 24 | ||||
-rw-r--r-- | chrome/browser/sync/sync_status_ui_helper_mac.h | 28 | ||||
-rw-r--r-- | chrome/browser/sync/sync_status_ui_helper_mac.mm | 75 | ||||
-rw-r--r-- | chrome/browser/sync/sync_status_ui_helper_mac_unittest.mm | 110 | ||||
-rwxr-xr-x | chrome/chrome.gyp | 4 |
13 files changed, 340 insertions, 152 deletions
diff --git a/chrome/app/nibs/MainMenu.xib b/chrome/app/nibs/MainMenu.xib index efc2e26..5b58035 100644 --- a/chrome/app/nibs/MainMenu.xib +++ b/chrome/app/nibs/MainMenu.xib @@ -96,6 +96,28 @@ <reference key="NSOnImage" ref="353210768"/> <reference key="NSMixedImage" ref="549394948"/> </object> + <object class="NSMenuItem" id="214319129"> + <reference key="NSMenu" ref="110575045"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsHidden">YES</bool> + <string key="NSTitle">^IDS_SYNC_START_SYNC_BUTTON_LABEL</string> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + <int key="NSTag">41108</int> + </object> + <object class="NSMenuItem" id="784044270"> + <reference key="NSMenu" ref="110575045"/> + <bool key="NSIsDisabled">YES</bool> + <bool key="NSIsSeparator">YES</bool> + <bool key="NSIsHidden">YES</bool> + <string key="NSTitle"/> + <string key="NSKeyEquiv"/> + <int key="NSMnemonicLoc">2147483647</int> + <reference key="NSOnImage" ref="353210768"/> + <reference key="NSMixedImage" ref="549394948"/> + </object> <object class="NSMenuItem" id="52470633"> <reference key="NSMenu" ref="110575045"/> <string key="NSTitle">^IDS_CLEAR_BROWSING_DATA_MAC</string> @@ -1631,6 +1653,14 @@ </object> <int key="connectionID">663</int> </object> + <object class="IBConnectionRecord"> + <object class="IBActionConnection" key="connection"> + <string key="label">commandDispatch:</string> + <reference key="source" ref="1014"/> + <reference key="destination" ref="214319129"/> + </object> + <int key="connectionID">666</int> + </object> </object> <object class="IBMutableOrderedSet" key="objectRecords"> <object class="NSArray" key="orderedObjects"> @@ -1967,6 +1997,8 @@ <reference ref="52470633"/> <reference ref="198763083"/> <reference ref="198763083"/> + <reference ref="214319129"/> + <reference ref="784044270"/> </object> <reference key="parent" ref="694149608"/> </object> @@ -2451,6 +2483,16 @@ <reference key="object" ref="198763083"/> <reference key="parent" ref="110575045"/> </object> + <object class="IBObjectRecord"> + <int key="objectID">664</int> + <reference key="object" ref="214319129"/> + <reference key="parent" ref="110575045"/> + </object> + <object class="IBObjectRecord"> + <int key="objectID">665</int> + <reference key="object" ref="784044270"/> + <reference key="parent" ref="110575045"/> + </object> </object> </object> <object class="NSMutableDictionary" key="flattenedProperties"> @@ -2639,7 +2681,10 @@ <string>658.IBPluginDependency</string> <string>658.ImportedFromIB2</string> <string>660.IBPluginDependency</string> + <string>662.IBPluginDependency</string> <string>662.IBShouldRemoveOnLegacySave</string> + <string>664.IBPluginDependency</string> + <string>665.IBPluginDependency</string> <string>72.IBPluginDependency</string> <string>72.ImportedFromIB2</string> <string>73.IBPluginDependency</string> @@ -2764,7 +2809,7 @@ <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <reference ref="9"/> <string>{{525, 802}, {197, 73}}</string> - <string>{{38, 600}, {1578, 20}}</string> + <string>{{401, 784}, {1578, 20}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <reference ref="9"/> <string>{74, 862}</string> @@ -2829,7 +2874,7 @@ <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <reference ref="9"/> - <string>{{50, 367}, {385, 233}}</string> + <string>{{413, 521}, {385, 263}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <reference ref="9"/> <string>{{23, 794}, {245, 183}}</string> @@ -2849,8 +2894,11 @@ <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <reference ref="9"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <boolean value="YES"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <reference ref="9"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <reference ref="9"/> @@ -2896,7 +2944,7 @@ </object> </object> <nil key="sourceID"/> - <int key="maxID">663</int> + <int key="maxID">666</int> </object> <object class="IBClassDescriber" key="IBDocument.Classes"> <object class="NSMutableArray" key="referencedPartialClassDescriptions"> diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm index e313130..ba41a4d 100644 --- a/chrome/browser/app_controller_mac.mm +++ b/chrome/browser/app_controller_mac.mm @@ -33,6 +33,9 @@ #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/options_window.h" #include "chrome/browser/sessions/tab_restore_service.h" +#include "chrome/browser/sync/profile_sync_service.h" +#include "chrome/browser/sync/sync_status_ui_helper.h" +#include "chrome/browser/sync/sync_status_ui_helper_mac.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/notification_service.h" @@ -484,6 +487,10 @@ static bool g_is_opening_new_window = false; case IDC_NEW_TAB: enable = [self keyWindowIsMissingOrBlocked]; break; + case IDC_SYNC_BOOKMARKS: + enable = ProfileSyncService::IsSyncEnabled(); + browser_sync::UpdateSyncItem(item, enable, [self defaultProfile]); + break; default: enable = menuState_->IsCommandEnabled(tag) ? YES : NO; } @@ -566,6 +573,12 @@ static bool g_is_opening_new_window = false; [controller runModalDialog]; break; } + case IDC_SYNC_BOOKMARKS: + // TODO(akalin): Add a constant to denote starting sync from the + // main menu and use that instead of START_FROM_WRENCH. + SyncStatusUIHelper::OpenSyncMyBookmarksDialog( + defaultProfile, ProfileSyncService::START_FROM_WRENCH); + break; }; } @@ -604,6 +617,8 @@ static bool g_is_opening_new_window = false; menuState_->UpdateCommandEnabled(IDC_HELP_PAGE, true); menuState_->UpdateCommandEnabled(IDC_IMPORT_SETTINGS, true); menuState_->UpdateCommandEnabled(IDC_REPORT_BUG, true); + menuState_->UpdateCommandEnabled(IDC_SYNC_BOOKMARKS, + ProfileSyncService::IsSyncEnabled()); // TODO(pinkerton): ...more to come... } diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index c423e8c..602f5f5 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -704,8 +704,7 @@ void Browser::UpdateCommandsForFullscreenMode(bool is_fullscreen) { command_updater_.UpdateCommandEnabled(IDC_SHOW_BOOKMARK_BAR, show_main_ui); command_updater_.UpdateCommandEnabled(IDC_IMPORT_SETTINGS, show_main_ui); command_updater_.UpdateCommandEnabled( - IDC_SYNC_BOOKMARKS, show_main_ui && - profile_->GetOriginalProfile()->GetProfileSyncService() != NULL); + IDC_SYNC_BOOKMARKS, show_main_ui && ProfileSyncService::IsSyncEnabled()); command_updater_.UpdateCommandEnabled(IDC_OPTIONS, show_main_ui); command_updater_.UpdateCommandEnabled(IDC_EDIT_SEARCH_ENGINES, show_main_ui); command_updater_.UpdateCommandEnabled(IDC_VIEW_PASSWORDS, show_main_ui); diff --git a/chrome/browser/cocoa/browser_window_controller.h b/chrome/browser/cocoa/browser_window_controller.h index c410592..38f76fc 100644 --- a/chrome/browser/cocoa/browser_window_controller.h +++ b/chrome/browser/cocoa/browser_window_controller.h @@ -202,12 +202,6 @@ class TabStripModelObserverBridge; // Return a point suitable for the topLeft for a bookmark bubble. - (NSPoint)topLeftForBubble; -// Updates a bookmark sync UI item (expected to be a menu item). This is -// called every time the menu containing the sync UI item is displayed. -- (void)updateSyncItem:(id)syncItem - syncEnabled:(BOOL)syncEnabled - status:(SyncStatusUIHelper::MessageType)status; - @end // BrowserWindowController(TestingAPI) #endif // CHROME_BROWSER_COCOA_BROWSER_WINDOW_CONTROLLER_H_ diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm index a58ad28..3b4620f 100644 --- a/chrome/browser/cocoa/browser_window_controller.mm +++ b/chrome/browser/cocoa/browser_window_controller.mm @@ -41,7 +41,8 @@ #import "chrome/browser/cocoa/tab_view.h" #import "chrome/browser/cocoa/toolbar_controller.h" #import "chrome/browser/browser_theme_provider.h" -#include "chrome/browser/sync/sync_status_ui_helper.h" +#include "chrome/browser/sync/profile_sync_service.h" +#include "chrome/browser/sync/sync_status_ui_helper_mac.h" #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" #import "chrome/browser/cocoa/background_gradient_view.h" @@ -661,17 +662,8 @@ willPositionSheet:(NSWindow*)sheet enable &= [self supportsFullscreen]; break; case IDC_SYNC_BOOKMARKS: - { - Profile* profile = browser_->profile()->GetOriginalProfile(); - ProfileSyncService* syncService = profile->GetProfileSyncService(); - // TODO(timsteele): Need a ui helper method to just get the type - // without needing labels. - string16 label, link; - SyncStatusUIHelper::MessageType status = - SyncStatusUIHelper::GetLabels(syncService, &label, &link); - enable &= (syncService != NULL); - [self updateSyncItem:item syncEnabled:enable status:status]; - } + enable &= ProfileSyncService::IsSyncEnabled(); + browser_sync::UpdateSyncItem(item, enable, browser_->profile()); break; default: // Special handling for the contents of the Text Encoding submenu. On @@ -693,59 +685,6 @@ willPositionSheet:(NSWindow*)sheet return enable; } -// TODO(akalin): We need to add a menu item to the main Chrome menu (near -// "Clear browsing data..."). However, this is tricky as no browsers may -// actually be open. Refactor the sync UI code so that it doesn't depend -// on a browser being present. - -- (void)updateSyncItem:(id)syncItem - syncEnabled:(BOOL)syncEnabled - status:(SyncStatusUIHelper::MessageType)status { - DCHECK([syncItem isKindOfClass:[NSMenuItem class]]); - NSMenuItem* syncMenuItem = (NSMenuItem*)syncItem; - // Look for a separator immediately after the menu item. - NSMenuItem* followingSeparator = nil; - NSMenu* menu = [syncItem menu]; - if (menu) { - NSInteger syncItemIndex = [menu indexOfItem:syncMenuItem]; - DCHECK_NE(syncItemIndex, -1); - if ((syncItemIndex + 1) < [menu numberOfItems]) { - NSMenuItem* menuItem = [menu itemAtIndex:(syncItemIndex + 1)]; - if ([menuItem isSeparatorItem]) { - followingSeparator = menuItem; - } - } - } - - // TODO(akalin): consolidate this code with the equivalent Windows code in - // chrome/browser/views/toolbar_view.cc. - int titleId; - switch (status) { - case SyncStatusUIHelper::SYNCED: - titleId = IDS_SYNC_MENU_BOOKMARKS_SYNCED_LABEL; - break; - case SyncStatusUIHelper::SYNC_ERROR: - titleId = IDS_SYNC_MENU_BOOKMARK_SYNC_ERROR_LABEL; - break; - case SyncStatusUIHelper::PRE_SYNCED: - titleId = IDS_SYNC_START_SYNC_BUTTON_LABEL; - break; - default: - NOTREACHED(); - // Needed to prevent release-mode warnings. - titleId = IDS_SYNC_START_SYNC_BUTTON_LABEL; - break; - } - NSString* title = l10n_util::GetNSStringWithFixup(titleId); - [syncMenuItem setTitle:title]; - - // If we don't have a sync service, hide any sync-related menu - // items. However, sync_menu_item is enabled/disabled outside of this - // function so we don't touch it here, and separators are always disabled. - [syncMenuItem setHidden:!syncEnabled]; - [followingSeparator setHidden:!syncEnabled]; -} - // Called when the user picks a menu or toolbar item when this window is key. // Calls through to the browser object to execute the command. This assumes that // the command is supported and doesn't check, otherwise it would have been diff --git a/chrome/browser/cocoa/browser_window_controller_unittest.mm b/chrome/browser/cocoa/browser_window_controller_unittest.mm index 81cccc9..857cbd9 100644 --- a/chrome/browser/cocoa/browser_window_controller_unittest.mm +++ b/chrome/browser/cocoa/browser_window_controller_unittest.mm @@ -492,77 +492,6 @@ TEST_F(BrowserWindowControllerTest, TestFindBarOnTop) { EXPECT_GT(findBar_index, bookmark_index); } -TEST_F(BrowserWindowControllerTest, TestSyncMenuItem) { - scoped_nsobject<NSMenuItem> syncMenuItem( - [[NSMenuItem alloc] initWithTitle:@"" - action:@selector(commandDispatch) - keyEquivalent:@""]); - [syncMenuItem setTag:IDC_SYNC_BOOKMARKS]; - - NSString* bookmarksSynced = - l10n_util::GetNSStringWithFixup(IDS_SYNC_MENU_BOOKMARKS_SYNCED_LABEL); - NSString* bookmarkSyncError = - l10n_util::GetNSStringWithFixup(IDS_SYNC_MENU_BOOKMARK_SYNC_ERROR_LABEL); - NSString* startSync = - l10n_util::GetNSStringWithFixup(IDS_SYNC_START_SYNC_BUTTON_LABEL); - - [syncMenuItem setTitle:@""]; - [syncMenuItem setHidden:NO]; - [controller_ updateSyncItem:syncMenuItem - syncEnabled:NO - status:SyncStatusUIHelper::PRE_SYNCED]; - EXPECT_TRUE([[syncMenuItem title] isEqualTo:startSync]); - EXPECT_TRUE([syncMenuItem isHidden]); - - [syncMenuItem setTitle:@""]; - [syncMenuItem setHidden:YES]; - [controller_ updateSyncItem:syncMenuItem - syncEnabled:YES - status:SyncStatusUIHelper::SYNC_ERROR]; - EXPECT_TRUE([[syncMenuItem title] isEqualTo:bookmarkSyncError]); - EXPECT_FALSE([syncMenuItem isHidden]); - - [syncMenuItem setTitle:@""]; - [syncMenuItem setHidden:NO]; - [controller_ updateSyncItem:syncMenuItem - syncEnabled:NO - status:SyncStatusUIHelper::SYNCED]; - EXPECT_TRUE([[syncMenuItem title] isEqualTo:bookmarksSynced]); - EXPECT_TRUE([syncMenuItem isHidden]); -} - -TEST_F(BrowserWindowControllerTest, TestSyncMenuItemWithSeparator) { - scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@""]); - NSMenuItem* syncMenuItem = - [menu addItemWithTitle:@"" - action:@selector(commandDispatch) - keyEquivalent:@""]; - [syncMenuItem setTag:IDC_SYNC_BOOKMARKS]; - NSMenuItem* following_separator = [NSMenuItem separatorItem]; - [menu addItem:following_separator]; - - const SyncStatusUIHelper::MessageType kStatus = - SyncStatusUIHelper::PRE_SYNCED; - - [syncMenuItem setHidden:NO]; - [following_separator setHidden:NO]; - [controller_ updateSyncItem:syncMenuItem - syncEnabled:NO - status:kStatus]; - EXPECT_FALSE([following_separator isEnabled]); - EXPECT_TRUE([syncMenuItem isHidden]); - EXPECT_TRUE([following_separator isHidden]); - - [syncMenuItem setHidden:YES]; - [following_separator setHidden:YES]; - [controller_ updateSyncItem:syncMenuItem - syncEnabled:YES - status:kStatus]; - EXPECT_FALSE([following_separator isEnabled]); - EXPECT_FALSE([syncMenuItem isHidden]); - EXPECT_FALSE([following_separator isHidden]); -} - @interface BrowserWindowControllerFakeFullscreen : BrowserWindowController { @private // We release the window ourselves, so we don't have to rely on the unittest diff --git a/chrome/browser/cocoa/html_dialog_window_controller.mm b/chrome/browser/cocoa/html_dialog_window_controller.mm index b9f045e..c82aca3 100644 --- a/chrome/browser/cocoa/html_dialog_window_controller.mm +++ b/chrome/browser/cocoa/html_dialog_window_controller.mm @@ -95,6 +95,14 @@ private: @end +namespace html_dialog_window_controller { + +void ShowHtmlDialog(HtmlDialogUIDelegate* delegate, Profile* profile) { + [HtmlDialogWindowController showHtmlDialog:delegate profile:profile]; +} + +} // namespace html_dialog_window_controller + HtmlDialogWindowDelegateBridge::HtmlDialogWindowDelegateBridge( HtmlDialogWindowController* controller, HtmlDialogUIDelegate* delegate) : controller_(controller), delegate_(delegate) { diff --git a/chrome/browser/cocoa/html_dialog_window_controller_cppsafe.h b/chrome/browser/cocoa/html_dialog_window_controller_cppsafe.h new file mode 100644 index 0000000..15c4576 --- /dev/null +++ b/chrome/browser/cocoa/html_dialog_window_controller_cppsafe.h @@ -0,0 +1,25 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_COCOA_HTML_DIALOG_WINDOW_CONTROLLER_CPPSAFE_H_ +#define CHROME_BROWSER_COCOA_HTML_DIALOG_WINDOW_CONTROLLER_CPPSAFE_H_ + +// We declare this in a separate file that is safe for including in C++ code. + +// TODO(akalin): It would be nice if there were a platform-agnostic way to +// create a browser-independent HTML dialog. However, this would require +// some invasive changes on the Windows/Linux side. Remove this file once +// We have this platform-agnostic API. + +namespace html_dialog_window_controller { + +// Creates and shows an HtmlDialogWindowController with the given +// delegate and profile. The window is automatically destroyed when it is +// closed. +void ShowHtmlDialog(HtmlDialogUIDelegate* delegate, Profile* profile); + +} // namespace html_dialog_window_controller + +#endif // CHROME_BROWSER_COCOA_HTML_DIALOG_WINDOW_CONTROLLER_CPPSAFE_H_ + diff --git a/chrome/browser/sync/sync_setup_flow.cc b/chrome/browser/sync/sync_setup_flow.cc index f5cdb84..610527e 100644 --- a/chrome/browser/sync/sync_setup_flow.cc +++ b/chrome/browser/sync/sync_setup_flow.cc @@ -14,6 +14,9 @@ #include "base/values.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" +#if defined(OS_MACOSX) +#include "chrome/browser/cocoa/html_dialog_window_controller_cppsafe.h" +#endif #include "chrome/browser/google_service_auth_error.h" #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/sync/profile_sync_service.h" @@ -324,12 +327,23 @@ SyncSetupFlow* SyncSetupFlow::Run(ProfileSyncService* service, std::string json_args; base::JSONWriter::Write(&args, false, &json_args); - Browser* b = BrowserList::GetLastActive(); - if (!b) - return NULL; - SyncSetupFlow* flow = new SyncSetupFlow(start, end, json_args, container, service); - b->BrowserShowHtmlDialog(flow, NULL); + Browser* b = BrowserList::GetLastActive(); + if (b) { + b->BrowserShowHtmlDialog(flow, NULL); + } else { + // TODO(akalin): Figure out a cleaner way to do this than to have this + // gross per-OS behavior, i.e. have a cross-platform ShowHtmlDialog() + // function that is not tied to a browser instance. Note that if we do + // that, we'll have to fix sync_setup_wizard_unittest.cc as it relies on + // being able to intercept ShowHtmlDialog() calls. +#if defined(OS_MACOSX) + html_dialog_window_controller::ShowHtmlDialog(flow, service->profile()); +#else + delete flow; + return NULL; +#endif + } return flow; } diff --git a/chrome/browser/sync/sync_status_ui_helper_mac.h b/chrome/browser/sync/sync_status_ui_helper_mac.h new file mode 100644 index 0000000..36b9bb3 --- /dev/null +++ b/chrome/browser/sync/sync_status_ui_helper_mac.h @@ -0,0 +1,28 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_SYNC_SYNC_STATUS_UI_HELPER_MAC_H_ +#define CHROME_BROWSER_SYNC_SYNC_STATUS_UI_HELPER_MAC_H_ + +#include "chrome/browser/sync/sync_status_ui_helper.h" + +#import <Cocoa/Cocoa.h> + +class Profile; + +namespace browser_sync { + +// Updates a bookmark sync UI item (expected to be a menu item). This is +// called every time a menu containing a sync UI item is displayed. +void UpdateSyncItem(id syncItem, BOOL syncEnabled, Profile* profile); + +// This function (used by UpdateSyncItem) is only exposed for testing. +// Just use UpdateSyncItem() instead. +void UpdateSyncItemForStatus(id syncItem, BOOL syncEnabled, + SyncStatusUIHelper::MessageType status); + +} // namespace browser_sync + +#endif // CHROME_BROWSER_SYNC_SYNC_STATUS_UI_HELPER_H_ + diff --git a/chrome/browser/sync/sync_status_ui_helper_mac.mm b/chrome/browser/sync/sync_status_ui_helper_mac.mm new file mode 100644 index 0000000..75d199f --- /dev/null +++ b/chrome/browser/sync/sync_status_ui_helper_mac.mm @@ -0,0 +1,75 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/sync/sync_status_ui_helper_mac.h" + +#import <Cocoa/Cocoa.h> + +#include "app/l10n_util_mac.h" +#include "base/logging.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/sync/sync_status_ui_helper.h" +#include "grit/generated_resources.h" + +namespace browser_sync { + +void UpdateSyncItem(id syncItem, BOOL syncEnabled, Profile* profile) { + ProfileSyncService* syncService = + profile->GetOriginalProfile()->GetProfileSyncService(); + // TODO(timsteele): Need a ui helper method to just get the type + // without needing labels. + string16 label, link; + SyncStatusUIHelper::MessageType status = + SyncStatusUIHelper::GetLabels(syncService, &label, &link); + UpdateSyncItemForStatus(syncItem, syncEnabled, status); +} + +void UpdateSyncItemForStatus(id syncItem, BOOL syncEnabled, + SyncStatusUIHelper::MessageType status) { + DCHECK([syncItem isKindOfClass:[NSMenuItem class]]); + NSMenuItem* syncMenuItem = static_cast<NSMenuItem*>(syncItem); + // Look for a separator immediately after the menu item. + NSMenuItem* followingSeparator = nil; + NSMenu* menu = [syncItem menu]; + if (menu) { + NSInteger syncItemIndex = [menu indexOfItem:syncMenuItem]; + DCHECK_NE(syncItemIndex, -1); + if ((syncItemIndex + 1) < [menu numberOfItems]) { + NSMenuItem* menuItem = [menu itemAtIndex:(syncItemIndex + 1)]; + if ([menuItem isSeparatorItem]) { + followingSeparator = menuItem; + } + } + } + + // TODO(akalin): consolidate this code with the equivalent Windows code in + // chrome/browser/views/toolbar_view.cc. + int titleId; + switch (status) { + case SyncStatusUIHelper::SYNCED: + titleId = IDS_SYNC_MENU_BOOKMARKS_SYNCED_LABEL; + break; + case SyncStatusUIHelper::SYNC_ERROR: + titleId = IDS_SYNC_MENU_BOOKMARK_SYNC_ERROR_LABEL; + break; + case SyncStatusUIHelper::PRE_SYNCED: + titleId = IDS_SYNC_START_SYNC_BUTTON_LABEL; + break; + default: + NOTREACHED(); + // Needed to prevent release-mode warnings. + titleId = IDS_SYNC_START_SYNC_BUTTON_LABEL; + break; + } + NSString* title = l10n_util::GetNSStringWithFixup(titleId); + [syncMenuItem setTitle:title]; + + // If we don't have a sync service, hide any sync-related menu + // items. However, sync_menu_item is enabled/disabled outside of this + // function so we don't touch it here, and separators are always disabled. + [syncMenuItem setHidden:!syncEnabled]; + [followingSeparator setHidden:!syncEnabled]; +} + +} // namespace browser_sync diff --git a/chrome/browser/sync/sync_status_ui_helper_mac_unittest.mm b/chrome/browser/sync/sync_status_ui_helper_mac_unittest.mm new file mode 100644 index 0000000..e5418e1 --- /dev/null +++ b/chrome/browser/sync/sync_status_ui_helper_mac_unittest.mm @@ -0,0 +1,110 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/sync/sync_status_ui_helper_mac.h" + +#import <Cocoa/Cocoa.h> + +#include "app/l10n_util_mac.h" +#include "base/scoped_nsobject.h" +#include "chrome/app/chrome_dll_resource.h" +#include "chrome/browser/cocoa/cocoa_test_helper.h" +#include "grit/generated_resources.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class SyncStatusUIHelperMacTest : public CocoaTest { +}; + +TEST_F(SyncStatusUIHelperMacTest, UpdateSyncItem) { + scoped_nsobject<NSMenuItem> syncMenuItem( + [[NSMenuItem alloc] initWithTitle:@"" + action:@selector(commandDispatch) + keyEquivalent:@""]); + [syncMenuItem setTag:IDC_SYNC_BOOKMARKS]; + + NSString* bookmarksSynced = + l10n_util::GetNSStringWithFixup(IDS_SYNC_MENU_BOOKMARKS_SYNCED_LABEL); + NSString* bookmarkSyncError = + l10n_util::GetNSStringWithFixup(IDS_SYNC_MENU_BOOKMARK_SYNC_ERROR_LABEL); + NSString* startSync = + l10n_util::GetNSStringWithFixup(IDS_SYNC_START_SYNC_BUTTON_LABEL); + + [syncMenuItem setTitle:@""]; + [syncMenuItem setHidden:NO]; + + browser_sync::UpdateSyncItemForStatus(syncMenuItem, NO, + SyncStatusUIHelper::PRE_SYNCED); + EXPECT_TRUE([[syncMenuItem title] isEqualTo:startSync]); + EXPECT_TRUE([syncMenuItem isHidden]); + + [syncMenuItem setTitle:@""]; + [syncMenuItem setHidden:YES]; + browser_sync::UpdateSyncItemForStatus(syncMenuItem, YES, + SyncStatusUIHelper::SYNC_ERROR); + EXPECT_TRUE([[syncMenuItem title] isEqualTo:bookmarkSyncError]); + EXPECT_FALSE([syncMenuItem isHidden]); + + [syncMenuItem setTitle:@""]; + [syncMenuItem setHidden:NO]; + browser_sync::UpdateSyncItemForStatus(syncMenuItem, NO, + SyncStatusUIHelper::SYNCED); + EXPECT_TRUE([[syncMenuItem title] isEqualTo:bookmarksSynced]); + EXPECT_TRUE([syncMenuItem isHidden]); +} + +TEST_F(SyncStatusUIHelperMacTest, UpdateSyncItemWithSeparator) { + scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@""]); + NSMenuItem* syncMenuItem = + [menu addItemWithTitle:@"" + action:@selector(commandDispatch) + keyEquivalent:@""]; + [syncMenuItem setTag:IDC_SYNC_BOOKMARKS]; + NSMenuItem* followingSeparator = [NSMenuItem separatorItem]; + [menu addItem:followingSeparator]; + + const SyncStatusUIHelper::MessageType kStatus = + SyncStatusUIHelper::PRE_SYNCED; + + [syncMenuItem setHidden:NO]; + [followingSeparator setHidden:NO]; + browser_sync::UpdateSyncItemForStatus(syncMenuItem, NO, kStatus); + EXPECT_FALSE([followingSeparator isEnabled]); + EXPECT_TRUE([syncMenuItem isHidden]); + EXPECT_TRUE([followingSeparator isHidden]); + + [syncMenuItem setHidden:YES]; + [followingSeparator setHidden:YES]; + browser_sync::UpdateSyncItemForStatus(syncMenuItem, YES, kStatus); + EXPECT_FALSE([followingSeparator isEnabled]); + EXPECT_FALSE([syncMenuItem isHidden]); + EXPECT_FALSE([followingSeparator isHidden]); +} + +TEST_F(SyncStatusUIHelperMacTest, UpdateSyncItemWithNonSeparator) { + scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@""]); + NSMenuItem* syncMenuItem = + [menu addItemWithTitle:@"" + action:@selector(commandDispatch) + keyEquivalent:@""]; + [syncMenuItem setTag:IDC_SYNC_BOOKMARKS]; + NSMenuItem* followingNonSeparator = + [menu addItemWithTitle:@"" + action:@selector(commandDispatch) + keyEquivalent:@""]; + + const SyncStatusUIHelper::MessageType kStatus = + SyncStatusUIHelper::PRE_SYNCED; + + browser_sync::UpdateSyncItemForStatus(syncMenuItem, NO, kStatus); + EXPECT_TRUE([followingNonSeparator isEnabled]); + EXPECT_FALSE([followingNonSeparator isHidden]); + + browser_sync::UpdateSyncItemForStatus(syncMenuItem, YES, kStatus); + EXPECT_TRUE([followingNonSeparator isEnabled]); + EXPECT_FALSE([followingNonSeparator isHidden]); +} + +} // namespace diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 820e670..aaf0bf6 100755 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -1193,6 +1193,7 @@ 'browser/cocoa/history_menu_cocoa_controller.h', 'browser/cocoa/history_menu_cocoa_controller.mm', 'browser/cocoa/html_dialog_window_controller.h', + 'browser/cocoa/html_dialog_window_controller_cppsafe.h', 'browser/cocoa/html_dialog_window_controller.mm', 'browser/cocoa/hyperlink_button_cell.h', 'browser/cocoa/hyperlink_button_cell.mm', @@ -2191,6 +2192,8 @@ 'browser/sync/sync_setup_wizard.h', 'browser/sync/sync_status_ui_helper.cc', 'browser/sync/sync_status_ui_helper.h', + 'browser/sync/sync_status_ui_helper_mac.mm', + 'browser/sync/sync_status_ui_helper_mac.h', 'browser/state_tracker.cc', 'browser/state_tracker.h', 'browser/tab_contents/constrained_window.h', @@ -4749,6 +4752,7 @@ 'browser/sync/glue/http_bridge_unittest.cc', 'browser/sync/profile_sync_service_unittest.cc', 'browser/sync/sync_setup_wizard_unittest.cc', + 'browser/sync/sync_status_ui_helper_mac_unittest.mm', 'browser/tab_contents/navigation_controller_unittest.cc', 'browser/tab_contents/navigation_entry_unittest.cc', 'browser/tab_contents/render_view_host_manager_unittest.cc', |