summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa
diff options
context:
space:
mode:
authorpinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-05 18:19:10 +0000
committerpinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-05 18:19:10 +0000
commitd2123de693b44900b587ef1955af5e5217d68c42 (patch)
tree4e970debf26f143250a52d89b5f897362565ab77 /chrome/browser/cocoa
parent376883a4ccd8f92817de1355317adea570a730ce (diff)
downloadchromium_src-d2123de693b44900b587ef1955af5e5217d68c42.zip
chromium_src-d2123de693b44900b587ef1955af5e5217d68c42.tar.gz
chromium_src-d2123de693b44900b587ef1955af5e5217d68c42.tar.bz2
Implement table for custom home pages at startup on Mac.
BUG=13151 TEST=custom home pages table. adding to it, removing. use current. enabling and disabling when applicable. Review URL: http://codereview.chromium.org/119242 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17740 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa')
-rw-r--r--chrome/browser/cocoa/custom_home_pages_model.h52
-rw-r--r--chrome/browser/cocoa/custom_home_pages_model.mm119
-rw-r--r--chrome/browser/cocoa/custom_home_pages_model_unittest.mm141
-rw-r--r--chrome/browser/cocoa/preferences_window_controller.h15
-rw-r--r--chrome/browser/cocoa/preferences_window_controller.mm168
5 files changed, 458 insertions, 37 deletions
diff --git a/chrome/browser/cocoa/custom_home_pages_model.h b/chrome/browser/cocoa/custom_home_pages_model.h
new file mode 100644
index 0000000..ba56e5f
--- /dev/null
+++ b/chrome/browser/cocoa/custom_home_pages_model.h
@@ -0,0 +1,52 @@
+// 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_CUSTOM_HOME_PAGES_MODEL_H_
+#define CHROME_BROWSER_COCOA_CUSTOM_HOME_PAGES_MODEL_H_
+
+#import <Cocoa/Cocoa.h>
+
+#include <vector>
+#include "base/scoped_nsobject.h"
+#include "googleurl/src/gurl.h"
+
+class Profile;
+
+// The model for the "custom home pages" table in preferences. Contains a list
+// of CustomHomePageEntry objects. This is intended to be used with Cocoa
+// bindings.
+//
+// The supported binding is |customHomePages|, a to-many relationship which
+// can be observed with an array controller.
+
+@interface CustomHomePagesModel : NSObject {
+ @private
+ scoped_nsobject<NSArray> entries_;
+ Profile* profile_; // weak, used for loading favicons
+}
+
+// Initialize with |profile|, which must not be NULL. The profile is used for
+// loading favicons for urls.
+- (id)initWithProfile:(Profile*)profile;
+
+// Get/set the urls the model currently contains as a group. Only one change
+// notification will be sent.
+- (std::vector<GURL>)URLs;
+- (void)setURLs:(const std::vector<GURL>&)urls;
+
+// For binding |customHomePages| to a mutable array controller.
+- (NSUInteger)countOfCustomHomePages;
+- (id)objectInCustomHomePagesAtIndex:(NSUInteger)index;
+- (void)insertObject:(id)object inCustomHomePagesAtIndex:(NSUInteger)index;
+- (void)removeObjectFromCustomHomePagesAtIndex:(NSUInteger)index;
+@end
+
+// A notification that fires when the URL of one of the entries changes.
+// Prevents interested parties from having to observe all model objects in order
+// to persist changes to a single entry. Changes to the number of items in the
+// model can be observed by watching |customHomePages| via KVO so an additional
+// notification is not sent.
+extern NSString* const kHomepageEntryChangedNotification;
+
+#endif // CHROME_BROWSER_COCOA_CUSTOM_HOME_PAGES_MODEL_H_
diff --git a/chrome/browser/cocoa/custom_home_pages_model.mm b/chrome/browser/cocoa/custom_home_pages_model.mm
new file mode 100644
index 0000000..1204ac6
--- /dev/null
+++ b/chrome/browser/cocoa/custom_home_pages_model.mm
@@ -0,0 +1,119 @@
+// 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.
+
+#import "chrome/browser/cocoa/custom_home_pages_model.h"
+
+#include "base/sys_string_conversions.h"
+#include "chrome/browser/history/history.h"
+#include "chrome/browser/net/url_fixer_upper.h"
+
+NSString* const kHomepageEntryChangedNotification =
+ @"kHomepageEntryChangedNotification";
+
+// An entry representing a single item in the custom home page model. Stores
+// a url and a favicon.
+@interface CustomHomePageEntry : NSObject {
+ @private
+ scoped_nsobject<NSString> url_;
+ scoped_nsobject<NSImage> icon_;
+
+ // If non-zero, indicates we're loading the favicon for the page.
+ HistoryService::Handle icon_handle_;
+}
+@property(nonatomic, copy) NSString* URL;
+@property(nonatomic, retain) NSImage* image;
+@end
+
+//----------------------------------------------------------------------------
+
+
+@implementation CustomHomePagesModel
+
+- (id)initWithProfile:(Profile*)profile {
+ if ((self = [super init])) {
+ profile_ = profile;
+ entries_.reset([[NSMutableArray alloc] init]);
+ }
+ return self;
+}
+
+- (NSUInteger)countOfCustomHomePages {
+ return [entries_ count];
+}
+
+- (id)objectInCustomHomePagesAtIndex:(NSUInteger)index {
+ return [entries_ objectAtIndex:index];
+}
+
+- (void)insertObject:(id)object inCustomHomePagesAtIndex:(NSUInteger)index {
+ [entries_ insertObject:object atIndex:index];
+}
+
+- (void)removeObjectFromCustomHomePagesAtIndex:(NSUInteger)index {
+ [entries_ removeObjectAtIndex:index];
+}
+
+// Get/set the urls the model currently contains as a group. These will weed
+// out any URLs that are empty and not add them to the model. As a result,
+// the next time they're persisted to the prefs backend, they'll disappear.
+
+- (std::vector<GURL>)URLs {
+ std::vector<GURL> urls;
+ for (CustomHomePageEntry* entry in entries_.get()) {
+ const char* urlString = [[entry URL] UTF8String];
+ if (urlString && std::strlen(urlString)) {
+ urls.push_back(GURL(std::string(urlString)));
+ }
+ }
+ return urls;
+}
+
+- (void)setURLs:(const std::vector<GURL>&)urls {
+ [self willChangeValueForKey:@"customHomePages"];
+ [entries_ removeAllObjects];
+ for (size_t i = 0; i < urls.size(); ++i) {
+ scoped_nsobject<CustomHomePageEntry> entry(
+ [[CustomHomePageEntry alloc] init]);
+ const char* urlString = urls[i].spec().c_str();
+ if (urlString && std::strlen(urlString)) {
+ [entry setURL:[NSString stringWithCString:urlString
+ encoding:NSUTF8StringEncoding]];
+ [entries_ addObject:entry];
+ }
+ }
+ [self didChangeValueForKey:@"customHomePages"];
+}
+
+@end
+
+//---------------------------------------------------------------------------
+
+@implementation CustomHomePageEntry
+
+- (void)setURL:(NSString*)url {
+ // Make sure the url is valid before setting it by fixing it up.
+ std::string urlToFix(base::SysNSStringToUTF8(url));
+ urlToFix = URLFixerUpper::FixupURL(urlToFix, "");
+ url_.reset([base::SysUTF8ToNSString(urlToFix) retain]);
+
+ // Broadcast that an individual item has changed.
+ [[NSNotificationCenter defaultCenter]
+ postNotificationName:kHomepageEntryChangedNotification object:nil];
+
+ // TODO(pinkerton): fetch favicon, convert to NSImage
+}
+
+- (NSString*)URL {
+ return url_.get();
+}
+
+- (void)setImage:(NSImage*)image {
+ icon_.reset(image);
+}
+
+- (NSImage*)image {
+ return icon_.get();
+}
+
+@end
diff --git a/chrome/browser/cocoa/custom_home_pages_model_unittest.mm b/chrome/browser/cocoa/custom_home_pages_model_unittest.mm
new file mode 100644
index 0000000..7ca6402
--- /dev/null
+++ b/chrome/browser/cocoa/custom_home_pages_model_unittest.mm
@@ -0,0 +1,141 @@
+// 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 "base/scoped_nsobject.h"
+#include "chrome/browser/cocoa/browser_test_helper.h"
+#import "chrome/browser/cocoa/custom_home_pages_model.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+// A helper for KVO and NSNotifications. Makes a note that it's been called
+// back.
+@interface CustomHomePageHelper : NSObject {
+ @public
+ BOOL sawNotification_;
+}
+@end
+
+@implementation CustomHomePageHelper
+- (void)observeValueForKeyPath:(NSString*)keyPath
+ ofObject:(id)object
+ change:(NSDictionary*)change
+ context:(void*)context {
+ sawNotification_ = YES;
+}
+
+- (void)entryChanged:(NSNotification*)notify {
+ sawNotification_ = YES;
+}
+@end
+
+class CustomHomePagesModelTest : public testing::Test {
+ public:
+ CustomHomePagesModelTest() {
+ model_.reset([[CustomHomePagesModel alloc]
+ initWithProfile:helper_.profile()]);
+ }
+ ~CustomHomePagesModelTest() { }
+
+ BrowserTestHelper helper_;
+ scoped_nsobject<CustomHomePagesModel> model_;
+};
+
+TEST_F(CustomHomePagesModelTest, Init) {
+ scoped_nsobject<CustomHomePagesModel> model(
+ [[CustomHomePagesModel alloc] initWithProfile:helper_.profile()]);
+}
+
+TEST_F(CustomHomePagesModelTest, GetSetURLs) {
+ // Basic test.
+ std::vector<GURL> urls;
+ urls.push_back(GURL("http://www.google.com"));
+ [model_ setURLs:urls];
+ std::vector<GURL> received_urls = [model_.get() URLs];
+ EXPECT_EQ(received_urls.size(), 1U);
+ EXPECT_TRUE(urls[0] == received_urls[0]);
+
+ // Set an empty list, make sure we get back an empty list.
+ std::vector<GURL> empty;
+ [model_ setURLs:empty];
+ received_urls = [model_.get() URLs];
+ EXPECT_EQ(received_urls.size(), 0U);
+
+ // Give it a list with not well-formed URLs and make sure we get back.
+ // only the good ones.
+ std::vector<GURL> poorly_formed;
+ poorly_formed.push_back(GURL("http://www.google.com")); // good
+ poorly_formed.push_back(GURL("www.google.com")); // bad
+ poorly_formed.push_back(GURL("www.yahoo.")); // bad
+ poorly_formed.push_back(GURL("http://www.yahoo.com")); // good
+ [model_ setURLs:poorly_formed];
+ received_urls = [model_.get() URLs];
+ EXPECT_EQ(received_urls.size(), 2U);
+}
+
+// Test that we get a KVO notification when called setURLs.
+TEST_F(CustomHomePagesModelTest, KVOObserveWhenListChanges) {
+ scoped_nsobject<CustomHomePageHelper> kvo_helper(
+ [[CustomHomePageHelper alloc] init]);
+ [model_ addObserver:kvo_helper
+ forKeyPath:@"customHomePages"
+ options:0L
+ context:NULL];
+ EXPECT_FALSE(kvo_helper.get()->sawNotification_);
+
+ std::vector<GURL> urls;
+ urls.push_back(GURL("http://www.google.com"));
+ [model_ setURLs:urls]; // Should send kvo change notification.
+ EXPECT_TRUE(kvo_helper.get()->sawNotification_);
+}
+
+// Test the KVO "to-many" bindings for |customHomePages| and the KVO
+// notifiation when items are added to and removed from the list.
+TEST_F(CustomHomePagesModelTest, KVO) {
+ EXPECT_EQ([model_ countOfCustomHomePages], 0U);
+
+ scoped_nsobject<CustomHomePageHelper> kvo_helper(
+ [[CustomHomePageHelper alloc] init]);
+ [model_ addObserver:kvo_helper
+ forKeyPath:@"customHomePages"
+ options:0L
+ context:NULL];
+ EXPECT_FALSE(kvo_helper.get()->sawNotification_);
+
+ // Cheat and insert NSString objects into the array. As long as we don't
+ // call -URLs, we'll be ok.
+ [model_ insertObject:@"www.google.com" inCustomHomePagesAtIndex:0];
+ EXPECT_TRUE(kvo_helper.get()->sawNotification_);
+ [model_ insertObject:@"www.yahoo.com" inCustomHomePagesAtIndex:1];
+ [model_ insertObject:@"dev.chromium.org" inCustomHomePagesAtIndex:2];
+ EXPECT_EQ([model_ countOfCustomHomePages], 3U);
+
+ EXPECT_TRUE([[model_ objectInCustomHomePagesAtIndex:1]
+ isEqualToString:@"www.yahoo.com"]);
+
+ kvo_helper.get()->sawNotification_ = NO;
+ [model_ removeObjectFromCustomHomePagesAtIndex:1];
+ EXPECT_TRUE(kvo_helper.get()->sawNotification_);
+ EXPECT_EQ([model_ countOfCustomHomePages], 2U);
+ EXPECT_TRUE([[model_ objectInCustomHomePagesAtIndex:1]
+ isEqualToString:@"dev.chromium.org"]);
+ EXPECT_TRUE([[model_ objectInCustomHomePagesAtIndex:0]
+ isEqualToString:@"www.google.com"]);
+}
+
+// Test that when individual items are changed that they broadcast a message.
+TEST_F(CustomHomePagesModelTest, ModelChangedNotification) {
+ scoped_nsobject<CustomHomePageHelper> kvo_helper(
+ [[CustomHomePageHelper alloc] init]);
+ [[NSNotificationCenter defaultCenter]
+ addObserver:kvo_helper
+ selector:@selector(entryChanged:)
+ name:kHomepageEntryChangedNotification
+ object:nil];
+
+ std::vector<GURL> urls;
+ urls.push_back(GURL("http://www.google.com"));
+ [model_ setURLs:urls];
+ id entry = [model_ objectInCustomHomePagesAtIndex:0];
+ [entry setURL:@"http://www.foo.bar"];
+ EXPECT_TRUE(kvo_helper.get()->sawNotification_);
+}
diff --git a/chrome/browser/cocoa/preferences_window_controller.h b/chrome/browser/cocoa/preferences_window_controller.h
index 57ff985..e7f7734 100644
--- a/chrome/browser/cocoa/preferences_window_controller.h
+++ b/chrome/browser/cocoa/preferences_window_controller.h
@@ -8,10 +8,10 @@
#include "base/scoped_nsobject.h"
#include "chrome/common/pref_member.h"
+@class CustomHomePagesModel;
class PrefObserverBridge;
class PrefService;
class Profile;
-@class StartupURLDataSource;
// A window controller that handles the preferences window. The bulk of the
// work is handled via Cocoa Bindings and getter/setter methods that wrap
@@ -31,14 +31,17 @@ class Profile;
PrefService* prefs_; // weak ref - Obtained from profile_ for convenience.
scoped_ptr<PrefObserverBridge> observer_; // Watches for pref changes.
IBOutlet NSTabView* tabView_;
+ IBOutlet NSArrayController* customPagesArrayController_;
// Basics panel
IntegerPrefMember restoreOnStartup_;
- scoped_nsobject<StartupURLDataSource> customPagesSource_;
+ scoped_nsobject<CustomHomePagesModel> customPagesSource_;
BooleanPrefMember newTabPageIsHomePage_;
StringPrefMember homepage_;
BooleanPrefMember showHomeButton_;
BooleanPrefMember showPageOptionButtons_;
+ // Used when creating a new home page url to make the new cell editable.
+ BOOL pendingSelectForEdit_;
// User Data panel
BooleanPrefMember askSavePasswords_;
@@ -59,6 +62,9 @@ class Profile;
// Basics panel
- (IBAction)makeDefaultBrowser:(id)sender;
+- (IBAction)addHomepage:(id)sender;
+- (IBAction)removeSelectedHomepages:(id)sender;
+- (IBAction)useCurrentPagesAsHomepage:(id)sender;
// User Data panel
- (IBAction)showSavedPasswords:(id)sender;
@@ -66,7 +72,10 @@ class Profile;
- (IBAction)clearData:(id)sender;
- (IBAction)resetTheme:(id)sender;
-@end
+// Usable from cocoa bindings to hook up the custom home pages table.
+@property(readonly) CustomHomePagesModel* customPagesSource;
// NSNotification sent when the prefs window is closed.
extern NSString* const kUserDoneEditingPrefsNotification;
+
+@end
diff --git a/chrome/browser/cocoa/preferences_window_controller.mm b/chrome/browser/cocoa/preferences_window_controller.mm
index ef5c207..cd800cb 100644
--- a/chrome/browser/cocoa/preferences_window_controller.mm
+++ b/chrome/browser/cocoa/preferences_window_controller.mm
@@ -8,7 +8,10 @@
#include "base/mac_util.h"
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
#import "chrome/browser/cocoa/clear_browsing_data_controller.h"
+#import "chrome/browser/cocoa/custom_home_pages_model.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/browser/net/url_fixer_upper.h"
#include "chrome/browser/profile.h"
@@ -33,24 +36,6 @@ std::wstring GetNewTabUIURLString() {
}
} // namespace
-// A data source object for the "startup urls" table.
-// TODO(pinkerton): hook this up to bindings.
-@interface StartupURLDataSource : NSObject {
- @private
- Profile* profile_; // weak, used to load icons
-}
-- (id)initWithProfile:(Profile*)profile;
-@end
-
-@implementation StartupURLDataSource
-- (id)initWithProfile:(Profile*)profile {
- if ((self = [super init])) {
- profile_ = profile;
- }
- return self;
-}
-@end
-
//-------------------------------------------------------------------------
@interface PreferencesWindowController(Private)
@@ -62,6 +47,8 @@ std::wstring GetNewTabUIURLString() {
- (void)registerPrefObservers;
- (void)unregisterPrefObservers;
+- (void)customHomePagesChanged;
+
// KVC setter methods.
- (void)setNewTabPageIsHomePageIndex:(NSInteger)val;
- (void)setHomepageURL:(NSString*)urlString;
@@ -104,8 +91,25 @@ class PrefObserverBridge : public NotificationObserver {
prefs_ = profile->GetPrefs();
DCHECK(prefs_);
observer_.reset(new PrefObserverBridge(self));
- customPagesSource_.reset([[StartupURLDataSource alloc]
+
+ // Set up the model for the custom home page table. The KVO observation
+ // tells us when the number of items in the array changes. The normal
+ // observation tells us when one of the URLs of an item changes.
+ customPagesSource_.reset([[CustomHomePagesModel alloc]
initWithProfile:profile_]);
+ const SessionStartupPref startupPref =
+ SessionStartupPref::GetStartupPref(prefs_);
+ [customPagesSource_ setURLs:startupPref.urls];
+ [customPagesSource_ addObserver:self
+ forKeyPath:@"customHomePages"
+ options:0L
+ context:NULL];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(homepageEntryChanged:)
+ name:kHomepageEntryChangedNotification
+ object:nil];
+
// This needs to be done before awakeFromNib: because the bindings set up
// in the nib rely on it.
[self registerPrefObservers];
@@ -128,6 +132,8 @@ class PrefObserverBridge : public NotificationObserver {
}
- (void)dealloc {
+ [customPagesSource_ removeObserver:self forKeyPath:@"customHomePages"];
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
[self unregisterPrefObservers];
[super dealloc];
}
@@ -149,7 +155,7 @@ class PrefObserverBridge : public NotificationObserver {
// TODO(pinkerton): Register Default search.
// UserData panel
- askSavePasswords_.Init(prefs::kPasswordManagerEnabled,
+ askSavePasswords_.Init(prefs::kPasswordManagerEnabled,
prefs_, observer_.get());
formAutofill_.Init(prefs::kFormAutofillEnabled, prefs_, observer_.get());
@@ -166,10 +172,25 @@ class PrefObserverBridge : public NotificationObserver {
// User Data panel
// Nothing to do here.
-
+
// TODO(pinkerton): do other panels...
}
+// Called when a key we're observing via KVO changes.
+- (void)observeValueForKeyPath:(NSString*)keyPath
+ ofObject:(id)object
+ change:(NSDictionary*)change
+ context:(void*)context {
+ if ([keyPath isEqualToString:@"customHomePages"]) {
+ [self customHomePagesChanged];
+ return;
+ }
+ [super observeValueForKeyPath:keyPath
+ ofObject:object
+ change:change
+ context:context];
+}
+
// Record the user performed a certain action and save the preferences.
- (void)recordUserAction:(const wchar_t*)action {
UserMetrics::RecordComputedAction(action, profile_);
@@ -228,15 +249,14 @@ class PrefObserverBridge : public NotificationObserver {
// TODO(beng): Note that the kURLsToRestoreOnStartup pref is a mutable list,
// and changes to mutable lists aren't broadcast through the
- // observer system, so the second half of this condition will
+ // observer system, so this condition will
// never match. Once support for broadcasting such updates is
// added, this will automagically start to work, and this comment
// can be removed.
if (*prefName == prefs::kURLsToRestoreOnStartup) {
const SessionStartupPref startupPref =
SessionStartupPref::GetStartupPref(prefs_);
- // Set table model.
- NOTIMPLEMENTED();
+ [customPagesSource_ setURLs:startupPref.urls];
}
if (*prefName == prefs::kHomePageIsNewTabPage) {
@@ -261,18 +281,39 @@ class PrefObserverBridge : public NotificationObserver {
// on the "restore on startup" pref. The ordering of the cells is in the
// same order as the pref.
- (NSInteger)restoreOnStartupIndex {
- const SessionStartupPref startupPref =
- SessionStartupPref::GetStartupPref(prefs_);
- return startupPref.type;
+ const SessionStartupPref pref = SessionStartupPref::GetStartupPref(prefs_);
+ return pref.type;
+}
+
+// A helper function that takes the startup session type, grabs the URLs to
+// restore, and saves it all in prefs.
+- (void)saveSessionStartupWithType:(SessionStartupPref::Type)type {
+ SessionStartupPref pref;
+ pref.type = type;
+ pref.urls = [customPagesSource_.get() URLs];
+ SessionStartupPref::SetStartupPref(prefs_, pref);
+}
+
+// Called when the custom home pages array changes. Force a save to prefs, but
+// in order to save it, we have to look up what the current radio button
+// setting is (since they're set together). What a pain.
+- (void)customHomePagesChanged {
+ const SessionStartupPref pref = SessionStartupPref::GetStartupPref(prefs_);
+ [self saveSessionStartupWithType:pref.type];
+}
+
+// Called when an entry in the custom home page array changes URLs. Force
+// a save to prefs.
+- (void)homepageEntryChanged:(NSNotification*)notify {
+ [self customHomePagesChanged];
}
// Sets the pref based on the index of the selected cell in the matrix and
// marks the appropriate user metric.
- (void)setRestoreOnStartupIndex:(NSInteger)type {
- SessionStartupPref pref;
- pref.type = static_cast<SessionStartupPref::Type>(type);
- // TODO(pinkerton): list of pages in |pref.urls|
- switch (pref.type) {
+ SessionStartupPref::Type startupType =
+ static_cast<SessionStartupPref::Type>(type);
+ switch (startupType) {
case SessionStartupPref::DEFAULT:
[self recordUserAction:L"Options_Startup_Homepage"];
break;
@@ -285,7 +326,7 @@ class PrefObserverBridge : public NotificationObserver {
default:
NOTREACHED();
}
- SessionStartupPref::SetStartupPref(prefs_, pref);
+ [self saveSessionStartupWithType:startupType];
}
// Returns whether or not the +/-/Current buttons should be enabled, based on
@@ -294,6 +335,65 @@ class PrefObserverBridge : public NotificationObserver {
return [self restoreOnStartupIndex] == SessionStartupPref::URLS;
}
+// Getter for the |customPagesSource| property for bindings.
+- (id)customPagesSource {
+ return customPagesSource_.get();
+}
+
+// Called when the selection in the table changes. If a flag is set indicating
+// that we're waiting for a special select message, edit the cell. Otherwise
+// just ignore it, we don't normally care.
+- (void)tableViewSelectionDidChange:(NSNotification *)aNotification {
+ if (pendingSelectForEdit_) {
+ NSTableView* table = [aNotification object];
+ NSUInteger selectedRow = [table selectedRow];
+ [table editColumn:0 row:selectedRow withEvent:nil select:YES];
+ pendingSelectForEdit_ = NO;
+ }
+}
+
+// Called when the user hits the (+) button for adding a new homepage to the
+// list. This will also attempt to make the new item editable so the user can
+// just start typing.
+- (IBAction)addHomepage:(id)sender {
+ [customPagesArrayController_ add:sender];
+
+ // When the new item is added to the model, the array controller will select
+ // it. We'll watch for that notification (because we are the table view's
+ // delegate) and then make the cell editable. Note that this can't be
+ // accomplished simply by subclassing the array controller's add method (I
+ // did try). The update of the table is asynchronous with the controller
+ // updating the model.
+ pendingSelectForEdit_ = YES;
+}
+
+// Called when the user hits the (-) button for removing the selected items in
+// the homepage table. The controller does all the work.
+- (IBAction)removeSelectedHomepages:(id)sender {
+ [customPagesArrayController_ remove:sender];
+}
+
+// Add all entries for all open browsers with our profile.
+- (IBAction)useCurrentPagesAsHomepage:(id)sender {
+ std::vector<GURL> urls;
+ for (BrowserList::const_iterator browserIter = BrowserList::begin();
+ browserIter != BrowserList::end(); ++browserIter) {
+ Browser* browser = *browserIter;
+ if (browser->profile() != profile_)
+ continue; // Only want entries for open profile.
+
+ for (int tabIndex = 0; tabIndex < browser->tab_count(); ++tabIndex) {
+ TabContents* tab = browser->GetTabContentsAt(tabIndex);
+ if (tab->ShouldDisplayURL()) {
+ const GURL url = browser->GetTabContentsAt(tabIndex)->GetURL();
+ if (!url.is_empty())
+ urls.push_back(url);
+ }
+ }
+ }
+ [customPagesSource_ setURLs:urls];
+}
+
enum { kHomepageNewTabPage, kHomepageURL };
// Returns the index of the selected cell in the "home page" marix based on
@@ -441,9 +541,9 @@ const int kDisabledIndex = 1;
- (IBAction)showSavedPasswords:(id)sender {
NSString* const kKeychainBundleId = @"com.apple.keychainaccess";
[self recordUserAction:L"Options_ShowPasswordsExceptions"];
- [[NSWorkspace sharedWorkspace]
+ [[NSWorkspace sharedWorkspace]
launchAppWithBundleIdentifier:kKeychainBundleId
- options:0L
+ options:0L
additionalEventParamDescriptor:nil
launchIdentifier:nil];
}