summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorjeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-11 21:31:17 +0000
committerjeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-11 21:31:17 +0000
commit008b85036666ad1b49c0525682904950df3777cb (patch)
treeefa76a5c06d5f566e2e9fc89c8f6fba8fa34cfe3 /chrome/browser
parent602e6865dda0510c26520bb5f86787b817d5048c (diff)
downloadchromium_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.h2
-rw-r--r--chrome/browser/cocoa/first_run_dialog.mm1
-rw-r--r--chrome/browser/cocoa/import_progress_dialog.h102
-rw-r--r--chrome/browser/cocoa/import_progress_dialog.mm176
-rw-r--r--chrome/browser/first_run_mac.mm81
-rw-r--r--chrome/browser/importer/importer.cc3
-rw-r--r--chrome/browser/importer/importer.h4
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_