diff options
author | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-11 21:31:17 +0000 |
---|---|---|
committer | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-11 21:31:17 +0000 |
commit | 008b85036666ad1b49c0525682904950df3777cb (patch) | |
tree | efa76a5c06d5f566e2e9fc89c8f6fba8fa34cfe3 /chrome/browser | |
parent | 602e6865dda0510c26520bb5f86787b817d5048c (diff) | |
download | chromium_src-008b85036666ad1b49c0525682904950df3777cb.zip chromium_src-008b85036666ad1b49c0525682904950df3777cb.tar.gz chromium_src-008b85036666ad1b49c0525682904950df3777cb.tar.bz2 |
First Run Import Progress UI.
First run code needed some reworking in order to get things in order for progress notification.
BUG=18773
TEST=When importing another browser's settings, a progress dialog should be displayed.
Review URL: http://codereview.chromium.org/164290
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23080 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/cocoa/first_run_dialog.h | 2 | ||||
-rw-r--r-- | chrome/browser/cocoa/first_run_dialog.mm | 1 | ||||
-rw-r--r-- | chrome/browser/cocoa/import_progress_dialog.h | 102 | ||||
-rw-r--r-- | chrome/browser/cocoa/import_progress_dialog.mm | 176 | ||||
-rw-r--r-- | chrome/browser/first_run_mac.mm | 81 | ||||
-rw-r--r-- | chrome/browser/importer/importer.cc | 3 | ||||
-rw-r--r-- | chrome/browser/importer/importer.h | 4 |
7 files changed, 346 insertions, 23 deletions
diff --git a/chrome/browser/cocoa/first_run_dialog.h b/chrome/browser/cocoa/first_run_dialog.h index 5e5bd1e..1f10bc1 100644 --- a/chrome/browser/cocoa/first_run_dialog.h +++ b/chrome/browser/cocoa/first_run_dialog.h @@ -28,7 +28,7 @@ // Called when the "Learn More" button is pressed. - (IBAction)learnMore:(id)sender; -// Properties for bindings +// Properties for bindings. @property(assign) BOOL userDidCancel; @property(assign) BOOL statsEnabled; @property(assign) BOOL makeDefaultBrowser; diff --git a/chrome/browser/cocoa/first_run_dialog.mm b/chrome/browser/cocoa/first_run_dialog.mm index d5c9737..6fdadcb7 100644 --- a/chrome/browser/cocoa/first_run_dialog.mm +++ b/chrome/browser/cocoa/first_run_dialog.mm @@ -41,6 +41,7 @@ // Display dialog. NSWindow* win = [self window]; + [win center]; [NSApp runModalForWindow:win]; } diff --git a/chrome/browser/cocoa/import_progress_dialog.h b/chrome/browser/cocoa/import_progress_dialog.h new file mode 100644 index 0000000..0ff9dab --- /dev/null +++ b/chrome/browser/cocoa/import_progress_dialog.h @@ -0,0 +1,102 @@ +// 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_IMPORT_PROGRESS_DIALOG_H_ +#define CHROME_BROWSER_IMPORT_PROGRESS_DIALOG_H_ + +#import <Cocoa/Cocoa.h> + +#include "chrome/browser/importer/importer.h" + +class ImporterObserverBridge; + +// Class that acts as a controller for the dialog that shows progress for an +// import operation. +// Lifetime: This object is responsible for deleting itself. +@interface ImportProgressDialogController : NSWindowController { + scoped_ptr<ImporterObserverBridge> import_host_observer_bridge_; + ImporterHost* importer_host_; // (weak) + ImportObserver* observer_; // (weak) + BOOL importing_; + + // Strings bound to static labels in the UI dialog. + NSString* explanatory_text_; + NSString* favorites_status_text_; + NSString* search_status_text_; + NSString* saved_password_status_text_; + NSString* history_status_text_; + + // Bound to the color of the status text (this is the easiest way to disable + // progress items that aren't supported by the current browser we're importing + // from). + NSColor* favorites_import_enabled_; + NSColor* search_import_enabled_; + NSColor* password_import_enabled_; + NSColor* history_import_enabled_; + + // Placeholders for "Importing..." and "Done" text. + NSString* progress_text_; + NSString* done_text_; +} + +// Cancel button calls this. +- (IBAction)cancel:(id)sender; + +// Closes the dialog. +- (void)closeDialog; + +// Methods called by importer_host via ImporterObserverBridge. +- (void)ImportItemStarted:(ImportItem)item; +- (void)ImportItemEnded:(ImportItem)item; +- (void)ImportStarted; +- (void)ImportEnded; + +@property(retain) NSString* explanatoryText; +@property(retain) NSString* favoritesStatusText; +@property(retain) NSString* searchStatusText; +@property(retain) NSString* savedPasswordStatusText; +@property(retain) NSString* historyStatusText; + +@property(retain) NSColor* favoritesImportEnabled; +@property(retain) NSColor* searchImportEnabled; +@property(retain) NSColor* passwordImportEnabled; +@property(retain) NSColor* historyImportEnabled; + +@end + +// C++ -> objc bridge for import status notifications. +class ImporterObserverBridge : public ImporterHost::Observer { + public: + ImporterObserverBridge(ImportProgressDialogController* owner) + : owner_(owner) {} + virtual ~ImporterObserverBridge() {} + + // Invoked when data for the specified item is about to be collected. + virtual void ImportItemStarted(ImportItem item) { + [owner_ ImportItemStarted:item]; + } + + // Invoked when data for the specified item has been collected from the + // source profile and is now ready for further processing. + virtual void ImportItemEnded(ImportItem item) { + [owner_ ImportItemEnded:item]; + } + + // Invoked when the import begins. + virtual void ImportStarted() { + [owner_ ImportStarted]; + } + + // Invoked when the source profile has been imported. + virtual void ImportEnded() { + [owner_ ImportEnded]; + } + + private: + ImportProgressDialogController* owner_; + + DISALLOW_COPY_AND_ASSIGN(ImporterObserverBridge); +}; + +#endif // CHROME_BROWSER_IMPORT_PROGRESS_DIALOG_H_ diff --git a/chrome/browser/cocoa/import_progress_dialog.mm b/chrome/browser/cocoa/import_progress_dialog.mm new file mode 100644 index 0000000..86cd872 --- /dev/null +++ b/chrome/browser/cocoa/import_progress_dialog.mm @@ -0,0 +1,176 @@ +// 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/import_progress_dialog.h" + +#include "app/l10n_util_mac.h" +#include "base/logging.h" +#include "base/message_loop.h" +#import "base/scoped_nsobject.h" +#import "base/sys_string_conversions.h" +#include "grit/generated_resources.h" + +namespace { + +// Convert ImportItem enum into the name of the ImportProgressDialogController +// property corresponding to the text for that item, this makes the code to +// change the values for said properties much more readable. +NSString* keyForImportItem(ImportItem item) { + switch(item) { + case HISTORY: + return @"historyStatusText"; + case FAVORITES: + return @"favoritesStatusText"; + case PASSWORDS: + return @"savedPasswordStatusText"; + case SEARCH_ENGINES: + return @"searchStatusText"; + default: + DCHECK(false); + break; + } + return nil; +} + +} // namespace + +@implementation ImportProgressDialogController + +@synthesize explanatoryText = explanatory_text_; +@synthesize favoritesStatusText = favorites_status_text_; +@synthesize searchStatusText = search_status_text_; +@synthesize savedPasswordStatusText = saved_password_status_text_; +@synthesize historyStatusText = history_status_text_; + +@synthesize favoritesImportEnabled = favorites_import_enabled_; +@synthesize searchImportEnabled = search_import_enabled_; +@synthesize passwordImportEnabled = password_import_enabled_; +@synthesize historyImportEnabled = history_import_enabled_; + +- (id)initWithImporterHost:(ImporterHost*)host + browserName:(string16)browserName + observer:(ImportObserver*)observer + itemsEnabled:(int16)items; { + self = [super initWithWindowNibName:@"ImportProgressDialog"]; + if (self != nil) { + importer_host_ = host; + observer_ = observer; + import_host_observer_bridge_.reset(new ImporterObserverBridge(self)); + importer_host_->SetObserver(import_host_observer_bridge_.get()); + + NSString* explanatory_text = l10n_util::GetNSStringF( + IDS_IMPORT_PROGRESS_EXPLANATORY_TEXT_MAC, browserName); + [self setExplanatoryText:explanatory_text]; + + progress_text_ = + [l10n_util::GetNSString(IDS_IMPORT_IMPORTING_PROGRESS_TEXT_MAC) retain]; + done_text_ = + [l10n_util::GetNSString(IDS_IMPORT_IMPORTING_DONE_TEXT_MAC) retain]; + + // Enable/disable item titles. + NSColor* disabled = [NSColor disabledControlTextColor]; + NSColor* active = [NSColor textColor]; + [self setFavoritesImportEnabled:items & FAVORITES ? active : disabled]; + [self setSearchImportEnabled:items & SEARCH_ENGINES ? active : disabled]; + [self setPasswordImportEnabled:items & PASSWORDS ? active : disabled]; + [self setHistoryImportEnabled:items & HISTORY ? active : disabled]; + } + return self; +} + +- (void)dealloc { + [explanatory_text_ release]; + [favorites_status_text_ release]; + [search_status_text_ release]; + [saved_password_status_text_ release]; + [history_status_text_ release]; + + [favorites_import_enabled_ release]; + [search_import_enabled_ release]; + [password_import_enabled_ release]; + [history_import_enabled_ release]; + + [progress_text_ release]; + [done_text_ release]; + + [super dealloc]; +} + + +- (IBAction)showWindow:(id)sender { + NSWindow* win = [self window]; + [win center]; + [super showWindow:nil]; +} + +- (void)closeDialog { + if ([[self window] isVisible]) { + [[self window] close]; + } +} + +- (IBAction)cancel:(id)sender { + [self closeDialog]; + if (importing_) { + importer_host_->Cancel(); + } else { + [self release]; + } +} +- (void)ImportItemStarted:(ImportItem)item { + [self setValue:progress_text_ forKey:keyForImportItem(item)]; +} + +- (void)ImportItemEnded:(ImportItem)item { + [self setValue:done_text_ forKey:keyForImportItem(item)]; +} + +- (void)ImportStarted { + importing_ = YES; +} + +- (void)ImportEnded { + importing_ = NO; + importer_host_->SetObserver(NULL); + if (observer_) + observer_->ImportComplete(); + [self closeDialog]; + [self release]; + + MessageLoop::current()->Quit(); +} + +@end + +void StartImportingWithUI(gfx::NativeWindow parent_window, + int16 items, + ImporterHost* coordinator, + const ProfileInfo& source_profile, + Profile* target_profile, + ImportObserver* observer, + bool first_run) { + DCHECK(items != 0); + + // Retrieve name of browser we're importing from and do a little dance to + // convert wstring -> string16. + using base::SysCFStringRefToUTF16; + using base::SysWideToCFStringRef; + string16 import_browser_name = + SysCFStringRefToUTF16(SysWideToCFStringRef(source_profile.description)); + + // progress_dialog_ is responsible for deleting itself. + ImportProgressDialogController* progress_dialog_ = + [[ImportProgressDialogController alloc] + initWithImporterHost:coordinator + browserName:import_browser_name + observer:observer + itemsEnabled:items]; + // Call is async. + coordinator->StartImportSettings(source_profile, target_profile, items, + new ProfileWriter(target_profile), + first_run); + + [progress_dialog_ showWindow:nil]; + MessageLoop::current()->Run(); +} diff --git a/chrome/browser/first_run_mac.mm b/chrome/browser/first_run_mac.mm index 7242f94..cb354d4 100644 --- a/chrome/browser/first_run_mac.mm +++ b/chrome/browser/first_run_mac.mm @@ -8,6 +8,7 @@ #include "base/sys_string_conversions.h" #import "chrome/app/breakpad_mac.h" #import "chrome/browser/cocoa/first_run_dialog.h" +#import "chrome/browser/cocoa/import_progress_dialog.h" #include "chrome/browser/importer/importer.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/shell_integration.h" @@ -16,7 +17,6 @@ // static bool FirstRun::IsChromeFirstRun() { -#if defined(GOOGLE_CHROME_BUILD) // Use presence of kRegUsageStatsField key as an indicator of whether or not // this is the first run. // See chrome/browser/google_update_settings_mac.mm for details on why we use @@ -28,14 +28,63 @@ bool FirstRun::IsChromeFirstRun() { bool not_in_dict = [defaults_dict objectForKey:collect_stats_key] == nil; return not_in_dict; -#else - return false; // no first run UI for Chromium builds -#endif // defined(GOOGLE_CHROME_BUILD) } +// Class that handles conducting the first run operation. +// FirstRunController deletes itself when the first run operation ends. +class FirstRunController : public ImportObserver { + public: + explicit FirstRunController(); + virtual ~FirstRunController() {} + + // Overridden methods from ImportObserver. + virtual void ImportCanceled() { + FirstRunDone(); + } + virtual void ImportComplete() { + FirstRunDone(); + } + + // Display first run UI, start the import and return when it's all over. + bool DoFirstRun(Profile* profile, ProcessSingleton* process_singleton); + + private: + // This method closes the first run window and quits the message loop so that + // the Chrome startup can continue. This should be called when all the + // first run tasks are done. + void FirstRunDone(); + + + scoped_refptr<ImporterHost> importer_host_; + + DISALLOW_COPY_AND_ASSIGN(FirstRunController); +}; + + bool OpenFirstRunDialog(Profile* profile, ProcessSingleton* process_singleton) { // OpenFirstRunDialog is a no-op on non-branded builds. -#if defined(GOOGLE_CHROME_BUILD) + FirstRunController* controller = new FirstRunController; + return controller->DoFirstRun(profile, process_singleton); +} + +FirstRunController::FirstRunController() + : importer_host_(new ImporterHost) { +} + +void FirstRunController::FirstRunDone() { + // Set preference to show first run bubble and welcome page. + // TODO(jeremy): Implement + // FirstRun::SetShowFirstRunBubblePref(); + // FirstRun::SetShowWelcomePagePref(); + + delete this; +} + +bool FirstRunController::DoFirstRun(Profile* profile, + ProcessSingleton* process_singleton) { + // This object is responsible for deleting itself, make sure that happens. + scoped_ptr<FirstRunController> gc(this); + // Breakpad should not be enabled on first run until the user has explicitly // opted-into stats. // TODO: The behavior we probably want here is to enable Breakpad on first run @@ -47,17 +96,15 @@ bool OpenFirstRunDialog(Profile* profile, ProcessSingleton* process_singleton) { scoped_nsobject<FirstRunDialogController> dialog( [[FirstRunDialogController alloc] init]); - scoped_refptr<ImporterHost> importer_host(new ImporterHost()); - // Set list of browsers we know how to import. - ssize_t profiles_count = importer_host->GetAvailableProfileCount(); + ssize_t profiles_count = importer_host_->GetAvailableProfileCount(); // TODO(jeremy): Test on newly created account. // TODO(jeremy): Correctly handle case where no browsers to import from // are detected. NSMutableArray *browsers = [NSMutableArray arrayWithCapacity:profiles_count]; for (int i = 0; i < profiles_count; ++i) { - std::wstring profile = importer_host->GetSourceProfileNameAt(i); + std::wstring profile = importer_host_->GetSourceProfileNameAt(i); [browsers addObject:base::SysWideToNSString(profile)]; } [dialog.get() setBrowserImportList:browsers]; @@ -71,6 +118,8 @@ bool OpenFirstRunDialog(Profile* profile, ProcessSingleton* process_singleton) { return false; } +// Don't enable stats in Chromium. +#if defined(GOOGLE_CHROME_BUILD) BOOL stats_enabled = [dialog.get() statsEnabled]; // Breakpad is normally enabled very early in the startup process, @@ -82,6 +131,7 @@ bool OpenFirstRunDialog(Profile* profile, ProcessSingleton* process_singleton) { } GoogleUpdateSettings::SetCollectStatsConsent(stats_enabled); +#endif // GOOGLE_CHROME_BUILD // If selected set as default browser. BOOL make_default_browser = [dialog.get() makeDefaultBrowser]; @@ -92,15 +142,14 @@ bool OpenFirstRunDialog(Profile* profile, ProcessSingleton* process_singleton) { // Import bookmarks. if ([dialog.get() importBookmarks]) { - const ProfileInfo& source_profile = importer_host->GetSourceProfileInfoAt( + const ProfileInfo& source_profile = importer_host_->GetSourceProfileInfoAt( [dialog.get() browserImportSelectedIndex]); - int items = SEARCH_ENGINES + HISTORY + FAVORITES + HOME_PAGE + PASSWORDS; - // TODO(port): Call StartImportingWithUI here instead and launch - // a new process that does the actual import. - importer_host->StartImportSettings(source_profile, profile, items, - new ProfileWriter(profile), true); + int16 items = source_profile.services_supported; + // TODO(port): Do the actual import in a new process like Windows. + gc.release(); + StartImportingWithUI(nil, items, importer_host_.get(), + source_profile, profile, this, true); } -#endif // defined(GOOGLE_CHROME_BUILD) return true; } diff --git a/chrome/browser/importer/importer.cc b/chrome/browser/importer/importer.cc index 994ee7e..c374f26 100644 --- a/chrome/browser/importer/importer.cc +++ b/chrome/browser/importer/importer.cc @@ -824,8 +824,7 @@ void ImporterHost::DetectSafariProfiles() { safari->description = l10n_util::GetString(IDS_IMPORT_FROM_SAFARI); safari->source_path.clear(); safari->app_path.clear(); - safari->services_supported = HISTORY | FAVORITES | COOKIES | PASSWORDS | - SEARCH_ENGINES; + safari->services_supported = HISTORY | FAVORITES | HOME_PAGE; source_profiles_.push_back(safari); } #endif // OS_MACOSX diff --git a/chrome/browser/importer/importer.h b/chrome/browser/importer/importer.h index 78b2114..df8bc48 100644 --- a/chrome/browser/importer/importer.h +++ b/chrome/browser/importer/importer.h @@ -419,9 +419,6 @@ class ImportObserver { }; -#if !defined(OS_MACOSX) -// TODO(port): Make StartImportingWithUI portable. - // Shows a UI for importing and begins importing the specified items from // source_profile to target_profile. observer is notified when the process is // complete, can be NULL. parent is the window to parent the UI to, can be NULL @@ -434,6 +431,5 @@ void StartImportingWithUI(gfx::NativeWindow parent_window, Profile* target_profile, ImportObserver* observer, bool first_run); -#endif #endif // CHROME_BROWSER_IMPORTER_IMPORTER_H_ |