Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(496)

Side by Side Diff: chrome/browser/cocoa/preferences_window_controller.mm

Issue 391050: Implemented ShowOptionsWindow() for OS X (except the highlighting (Closed)
Patch Set: Fixed unittest. Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "chrome/browser/cocoa/preferences_window_controller.h" 5 #import "chrome/browser/cocoa/preferences_window_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include "app/l10n_util.h" 8 #include "app/l10n_util.h"
9 #include "app/l10n_util_mac.h" 9 #include "app/l10n_util_mac.h"
10 #include "base/logging.h"
10 #include "base/mac_util.h" 11 #include "base/mac_util.h"
11 #include "base/string16.h" 12 #include "base/string16.h"
12 #include "base/string_util.h" 13 #include "base/string_util.h"
13 #include "base/sys_string_conversions.h" 14 #include "base/sys_string_conversions.h"
14 #include "chrome/browser/browser.h" 15 #include "chrome/browser/browser.h"
15 #include "chrome/browser/browser_list.h" 16 #include "chrome/browser/browser_list.h"
16 #include "chrome/browser/browser_process.h" 17 #include "chrome/browser/browser_process.h"
17 #import "chrome/browser/cocoa/clear_browsing_data_controller.h" 18 #import "chrome/browser/cocoa/clear_browsing_data_controller.h"
18 #import "chrome/browser/cocoa/custom_home_pages_model.h" 19 #import "chrome/browser/cocoa/custom_home_pages_model.h"
19 #import "chrome/browser/cocoa/keyword_editor_cocoa_controller.h" 20 #import "chrome/browser/cocoa/keyword_editor_cocoa_controller.h"
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 - (void)setPasswordManagerEnabledIndex:(NSInteger)value; 371 - (void)setPasswordManagerEnabledIndex:(NSInteger)value;
371 - (void)setFormAutofillEnabledIndex:(NSInteger)value; 372 - (void)setFormAutofillEnabledIndex:(NSInteger)value;
372 - (void)setIsUsingDefaultTheme:(BOOL)value; 373 - (void)setIsUsingDefaultTheme:(BOOL)value;
373 - (void)setShowAlternateErrorPages:(BOOL)value; 374 - (void)setShowAlternateErrorPages:(BOOL)value;
374 - (void)setUseSuggest:(BOOL)value; 375 - (void)setUseSuggest:(BOOL)value;
375 - (void)setDnsPrefetch:(BOOL)value; 376 - (void)setDnsPrefetch:(BOOL)value;
376 - (void)setSafeBrowsing:(BOOL)value; 377 - (void)setSafeBrowsing:(BOOL)value;
377 - (void)setMetricsRecording:(BOOL)value; 378 - (void)setMetricsRecording:(BOOL)value;
378 - (void)setCookieBehavior:(NSInteger)value; 379 - (void)setCookieBehavior:(NSInteger)value;
379 - (void)setAskForSaveLocation:(BOOL)value; 380 - (void)setAskForSaveLocation:(BOOL)value;
380 - (void)displayPreferenceViewForToolbarItem:(NSToolbarItem*)toolbarItem 381 - (void)displayPreferenceViewForPage:(OptionsPage)page
381 animate:(BOOL)animate; 382 animate:(BOOL)animate;
382 @end 383 @end
383 384
384 // A C++ class registered for changes in preferences. Bridges the 385 // A C++ class registered for changes in preferences. Bridges the
385 // notification back to the PWC. 386 // notification back to the PWC.
386 class PrefObserverBridge : public NotificationObserver, 387 class PrefObserverBridge : public NotificationObserver,
387 public ProfileSyncServiceObserver { 388 public ProfileSyncServiceObserver {
388 public: 389 public:
389 PrefObserverBridge(PreferencesWindowController* controller) 390 PrefObserverBridge(PreferencesWindowController* controller)
390 : controller_(controller) {} 391 : controller_(controller) {}
391 392
(...skipping 11 matching lines...) Expand all
403 virtual void OnStateChanged() { 404 virtual void OnStateChanged() {
404 [controller_ syncStateChanged]; 405 [controller_ syncStateChanged];
405 } 406 }
406 407
407 private: 408 private:
408 PreferencesWindowController* controller_; // weak, owns us 409 PreferencesWindowController* controller_; // weak, owns us
409 }; 410 };
410 411
411 @implementation PreferencesWindowController 412 @implementation PreferencesWindowController
412 413
413 - (id)initWithProfile:(Profile*)profile { 414 - (id)initWithProfile:(Profile*)profile initialPage:(OptionsPage)initialPage {
414 DCHECK(profile); 415 DCHECK(profile);
415 // Use initWithWindowNibPath:: instead of initWithWindowNibName: so we 416 // Use initWithWindowNibPath:: instead of initWithWindowNibName: so we
416 // can override it in a unit test. 417 // can override it in a unit test.
417 NSString* nibPath = [mac_util::MainAppBundle() 418 NSString* nibPath = [mac_util::MainAppBundle()
418 pathForResource:@"Preferences" 419 pathForResource:@"Preferences"
419 ofType:@"nib"]; 420 ofType:@"nib"];
420 if ((self = [super initWithWindowNibPath:nibPath owner:self])) { 421 if ((self = [super initWithWindowNibPath:nibPath owner:self])) {
421 profile_ = profile; 422 profile_ = profile;
423 initialPage_ = initialPage;
422 prefs_ = profile->GetPrefs(); 424 prefs_ = profile->GetPrefs();
423 DCHECK(prefs_); 425 DCHECK(prefs_);
424 observer_.reset(new PrefObserverBridge(self)); 426 observer_.reset(new PrefObserverBridge(self));
425 427
426 // Set up the model for the custom home page table. The KVO observation 428 // Set up the model for the custom home page table. The KVO observation
427 // tells us when the number of items in the array changes. The normal 429 // tells us when the number of items in the array changes. The normal
428 // observation tells us when one of the URLs of an item changes. 430 // observation tells us when one of the URLs of an item changes.
429 customPagesSource_.reset([[CustomHomePagesModel alloc] 431 customPagesSource_.reset([[CustomHomePagesModel alloc]
430 initWithProfile:profile_]); 432 initWithProfile:profile_]);
431 const SessionStartupPref startupPref = 433 const SessionStartupPref startupPref =
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 resizeViewWithoutAutoResizingSubViews:underTheHoodContentView_ 642 resizeViewWithoutAutoResizingSubViews:underTheHoodContentView_
641 delta:NSMakeSize(0.0, verticalShift)]; 643 delta:NSMakeSize(0.0, verticalShift)];
642 underTheHoodContentSize = [underTheHoodContentView_ frame].size; 644 underTheHoodContentSize = [underTheHoodContentView_ frame].size;
643 645
644 // Put the Under the Hood content view into the scroller and scroll it to the 646 // Put the Under the Hood content view into the scroller and scroll it to the
645 // top. 647 // top.
646 [underTheHoodScroller_ setDocumentView:underTheHoodContentView_]; 648 [underTheHoodScroller_ setDocumentView:underTheHoodContentView_];
647 [underTheHoodContentView_ scrollPoint: 649 [underTheHoodContentView_ scrollPoint:
648 NSMakePoint(0, underTheHoodContentSize.height)]; 650 NSMakePoint(0, underTheHoodContentSize.height)];
649 651
650 // Get the last visited page from local state. 652 [self switchToPage:initialPage_ animate:NO];
651 OptionsPage page = static_cast<OptionsPage>(lastSelectedPage_.GetValue());
652 if (page == OPTIONS_PAGE_DEFAULT)
653 page = OPTIONS_PAGE_GENERAL;
654
655 NSUInteger pageIndex = (NSUInteger)page;
656 if (pageIndex >= [[toolbar_ items] count])
657 pageIndex = 0;
658 NSToolbarItem* firstItem = [[toolbar_ items] objectAtIndex:pageIndex];
659 [self displayPreferenceViewForToolbarItem:firstItem animate:NO];
660 [toolbar_ setSelectedItemIdentifier:[firstItem itemIdentifier]];
661 653
662 // TODO(pinkerton): save/restore position based on prefs. 654 // TODO(pinkerton): save/restore position based on prefs.
663 [[self window] center]; 655 [[self window] center];
664 } 656 }
665 657
666 - (void)dealloc { 658 - (void)dealloc {
667 if (syncService_) { 659 if (syncService_) {
668 syncService_->RemoveObserver(observer_.get()); 660 syncService_->RemoveObserver(observer_.get());
669 } 661 }
670 [customPagesSource_ removeObserver:self forKeyPath:@"customHomePages"]; 662 [customPagesSource_ removeObserver:self forKeyPath:@"customHomePages"];
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 - (IBAction)privacyLearnMore:(id)sender { 1290 - (IBAction)privacyLearnMore:(id)sender {
1299 // We open a new browser window so the Options dialog doesn't get lost 1291 // We open a new browser window so the Options dialog doesn't get lost
1300 // behind other windows. 1292 // behind other windows.
1301 Browser* browser = Browser::Create(profile_); 1293 Browser* browser = Browser::Create(profile_);
1302 browser->OpenURL(GURL(l10n_util::GetStringUTF16(IDS_LEARN_MORE_PRIVACY_URL)), 1294 browser->OpenURL(GURL(l10n_util::GetStringUTF16(IDS_LEARN_MORE_PRIVACY_URL)),
1303 GURL(), NEW_WINDOW, PageTransition::LINK); 1295 GURL(), NEW_WINDOW, PageTransition::LINK);
1304 } 1296 }
1305 1297
1306 - (IBAction)toolbarButtonSelected:(id)sender { 1298 - (IBAction)toolbarButtonSelected:(id)sender {
1307 DCHECK([sender isKindOfClass:[NSToolbarItem class]]); 1299 DCHECK([sender isKindOfClass:[NSToolbarItem class]]);
1308 [self displayPreferenceViewForToolbarItem:sender 1300 OptionsPage page = [self getPageForToolbarItem:sender];
1309 animate:YES]; 1301 [self displayPreferenceViewForPage:page animate:YES];
1310 } 1302 }
1311 1303
1312 // Helper to update the window to display a preferences view for a toolbaritem. 1304 // Helper to update the window to display a preferences view for a page.
1313 - (void)displayPreferenceViewForToolbarItem:(NSToolbarItem*)toolbarItem 1305 - (void)displayPreferenceViewForPage:(OptionsPage)page
1314 animate:(BOOL)animate { 1306 animate:(BOOL)animate {
1315 NSView* prefsView = NULL; 1307 NSWindow* prefsWindow = [self window];
1316 OptionsPage page = OPTIONS_PAGE_DEFAULT;
1317 // Tags are set in the nib file.
1318 switch ([toolbarItem tag]) {
1319 case 0: // Basics
1320 prefsView = basicsView_;
1321 page = OPTIONS_PAGE_GENERAL;
1322 break;
1323 case 1: // Personal Stuff
1324 prefsView = personalStuffView_;
1325 page = OPTIONS_PAGE_CONTENT;
1326 break;
1327 case 2: // Under the Hood
1328 prefsView = underTheHoodView_;
1329 page = OPTIONS_PAGE_ADVANCED;
1330 break;
1331 default:
1332 NOTIMPLEMENTED();
1333 }
1334 1308
1335 NSWindow* prefsWindow = [self window]; 1309 // Needs to go *after* the call to [self window], which triggers
1310 // awakeFromNib if necessary.
1311 NSView* prefsView = [self getPrefsViewForPage:page];
1336 NSView* contentView = [prefsWindow contentView]; 1312 NSView* contentView = [prefsWindow contentView];
1337 1313
1338 // Normally there is only one view, but if the user clicks really quickly, the 1314 // Normally there is only one view, but if the user clicks really quickly, the
1339 // animation could still been running, and the last view is the one that was 1315 // animation could still been running, and the last view is the one that was
1340 // animating in. 1316 // animating in.
1341 NSArray* subviews = [contentView subviews]; 1317 NSArray* subviews = [contentView subviews];
1342 NSView* currentPrefsView = nil; 1318 NSView* currentPrefsView = nil;
1343 if ([subviews count]) { 1319 if ([subviews count]) {
1344 currentPrefsView = [subviews lastObject]; 1320 currentPrefsView = [subviews lastObject];
1345 } 1321 }
(...skipping 29 matching lines...) Expand all
1375 prefsViewFrame.origin.y = 1351 prefsViewFrame.origin.y =
1376 NSHeight(contentViewFrame) - NSHeight(prefsViewFrame); 1352 NSHeight(contentViewFrame) - NSHeight(prefsViewFrame);
1377 } 1353 }
1378 [prefsView setFrame:prefsViewFrame]; 1354 [prefsView setFrame:prefsViewFrame];
1379 1355
1380 // Add the view. 1356 // Add the view.
1381 [contentView addSubview:prefsView]; 1357 [contentView addSubview:prefsView];
1382 [prefsWindow setInitialFirstResponder:prefsView]; 1358 [prefsWindow setInitialFirstResponder:prefsView];
1383 1359
1384 // Update the window title. 1360 // Update the window title.
1361 NSToolbarItem* toolbarItem = [self getToolbarItemForPage:page];
1385 [prefsWindow setTitle:[toolbarItem label]]; 1362 [prefsWindow setTitle:[toolbarItem label]];
1386 1363
1387 // Figure out the size of the window. 1364 // Figure out the size of the window.
1388 NSRect windowFrame = [prefsWindow frame]; 1365 NSRect windowFrame = [prefsWindow frame];
1389 CGFloat titleToolbarHeight = 1366 CGFloat titleToolbarHeight =
1390 NSHeight(windowFrame) - NSHeight(contentViewFrame); 1367 NSHeight(windowFrame) - NSHeight(contentViewFrame);
1391 windowFrame.size.height = 1368 windowFrame.size.height =
1392 NSHeight(prefsViewFrame) + titleToolbarHeight; 1369 NSHeight(prefsViewFrame) + titleToolbarHeight;
1393 DCHECK_GE(NSWidth(windowFrame), NSWidth(prefsViewFrame)) 1370 DCHECK_GE(NSWidth(windowFrame), NSWidth(prefsViewFrame))
1394 << "Initial width set wasn't wide enough."; 1371 << "Initial width set wasn't wide enough.";
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
1620 string16 statusLabel, linkLabel; 1597 string16 statusLabel, linkLabel;
1621 SyncStatusUIHelper::GetLabels(syncService_, &statusLabel, &linkLabel); 1598 SyncStatusUIHelper::GetLabels(syncService_, &statusLabel, &linkLabel);
1622 [syncStatus_ setStringValue:base::SysUTF16ToNSString(statusLabel)]; 1599 [syncStatus_ setStringValue:base::SysUTF16ToNSString(statusLabel)];
1623 } 1600 }
1624 1601
1625 // Show the preferences window. 1602 // Show the preferences window.
1626 - (IBAction)showPreferences:(id)sender { 1603 - (IBAction)showPreferences:(id)sender {
1627 [self showWindow:sender]; 1604 [self showWindow:sender];
1628 } 1605 }
1629 1606
1607 - (void)switchToPage:(OptionsPage)page animate:(BOOL)animate {
1608 [self displayPreferenceViewForPage:page animate:animate];
1609 NSToolbarItem* toolbarItem = [self getToolbarItemForPage:page];
1610 [toolbar_ setSelectedItemIdentifier:[toolbarItem itemIdentifier]];
1611 }
1612
1630 // Called when the window is being closed. Send out a notification that the user 1613 // Called when the window is being closed. Send out a notification that the user
1631 // is done editing preferences. Make sure there are no pending field editors 1614 // is done editing preferences. Make sure there are no pending field editors
1632 // by clearing the first responder. 1615 // by clearing the first responder.
1633 - (void)windowWillClose:(NSNotification*)notification { 1616 - (void)windowWillClose:(NSNotification*)notification {
1634 // Setting the first responder to the window ends any in-progress field 1617 // Setting the first responder to the window ends any in-progress field
1635 // editor. This will update the model appropriately so there's nothing left 1618 // editor. This will update the model appropriately so there's nothing left
1636 // to do. 1619 // to do.
1637 if (![[self window] makeFirstResponder:[self window]]) { 1620 if (![[self window] makeFirstResponder:[self window]]) {
1638 // We've hit a recalcitrant field editor, force it to go away. 1621 // We've hit a recalcitrant field editor, force it to go away.
1639 [[self window] endEditingFor:nil]; 1622 [[self window] endEditingFor:nil];
1640 } 1623 }
1641 1624
1642 [[NSNotificationCenter defaultCenter] 1625 [[NSNotificationCenter defaultCenter]
1643 postNotificationName:kUserDoneEditingPrefsNotification 1626 postNotificationName:kUserDoneEditingPrefsNotification
1644 object:self]; 1627 object:self];
1645 } 1628 }
1646 1629
1647 - (void)controlTextDidEndEditing:(NSNotification*)notification { 1630 - (void)controlTextDidEndEditing:(NSNotification*)notification {
1648 [customPagesSource_ validateURLs]; 1631 [customPagesSource_ validateURLs];
1649 } 1632 }
1650 1633
1651 @end 1634 @end
1635
1636 @implementation PreferencesWindowController(Testing)
1637
1638 - (IntegerPrefMember*)lastSelectedPage {
1639 return &lastSelectedPage_;
1640 }
1641
1642 - (NSToolbar*)toolbar {
1643 return toolbar_;
1644 }
1645
1646 - (NSView*)basicsView {
1647 return basicsView_;
1648 }
1649
1650 - (NSView*)personalStuffView {
1651 return personalStuffView_;
1652 }
1653
1654 - (NSView*)underTheHoodView {
1655 return underTheHoodView_;
1656 }
1657
1658 - (OptionsPage)normalizePage:(OptionsPage)page {
1659 if (page == OPTIONS_PAGE_DEFAULT) {
1660 // Get the last visited page from local state.
1661 page = static_cast<OptionsPage>(lastSelectedPage_.GetValue());
1662 if (page == OPTIONS_PAGE_DEFAULT) {
1663 page = OPTIONS_PAGE_GENERAL;
1664 }
1665 }
1666 return page;
1667 }
1668
1669 - (NSToolbarItem*)getToolbarItemForPage:(OptionsPage)page {
1670 NSUInteger pageIndex = (NSUInteger)[self normalizePage:page];
1671 NSArray* items = [toolbar_ items];
1672 NSUInteger itemCount = [items count];
1673 DCHECK_GE(pageIndex, 0U);
1674 if (pageIndex >= itemCount) {
1675 NOTIMPLEMENTED();
1676 pageIndex = 0;
1677 }
1678 DCHECK_GT(itemCount, 0U);
1679 return [items objectAtIndex:pageIndex];
1680 }
1681
1682 - (OptionsPage)getPageForToolbarItem:(NSToolbarItem*)toolbarItem {
1683 // Tags are set in the nib file.
1684 switch ([toolbarItem tag]) {
1685 case 0: // Basics
1686 return OPTIONS_PAGE_GENERAL;
1687 case 1: // Personal Stuff
1688 return OPTIONS_PAGE_CONTENT;
1689 case 2: // Under the Hood
1690 return OPTIONS_PAGE_ADVANCED;
1691 default:
1692 NOTIMPLEMENTED();
1693 return OPTIONS_PAGE_GENERAL;
1694 }
1695 }
1696
1697 - (NSView*)getPrefsViewForPage:(OptionsPage)page {
1698 // The views will be NULL if this is mistakenly called before awakeFromNib.
1699 DCHECK(basicsView_);
1700 DCHECK(personalStuffView_);
1701 DCHECK(underTheHoodView_);
1702 page = [self normalizePage:page];
1703 switch (page) {
1704 case OPTIONS_PAGE_GENERAL:
1705 return basicsView_;
1706 case OPTIONS_PAGE_CONTENT:
1707 return personalStuffView_;
1708 case OPTIONS_PAGE_ADVANCED:
1709 return underTheHoodView_;
1710 case OPTIONS_PAGE_DEFAULT:
1711 case OPTIONS_PAGE_COUNT:
1712 LOG(DFATAL) << "Invalid page value " << page;
1713 }
1714 return basicsView_;
1715 }
1716
1717 @end
OLDNEW
« no previous file with comments | « chrome/browser/cocoa/preferences_window_controller.h ('k') | chrome/browser/cocoa/preferences_window_controller_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698