diff options
-rw-r--r-- | chrome/browser/browser.cc | 16 | ||||
-rw-r--r-- | chrome/browser/browser.h | 4 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_window_gtk.cc | 3 | ||||
-rw-r--r-- | chrome/browser/gtk/import_dialog_gtk.cc | 115 | ||||
-rw-r--r-- | chrome/browser/gtk/import_dialog_gtk.h | 56 | ||||
-rw-r--r-- | chrome/browser/importer/firefox_importer_utils.cc | 55 | ||||
-rw-r--r-- | chrome/browser/importer/firefox_importer_utils.h | 12 | ||||
-rw-r--r-- | chrome/browser/importer/firefox_profile_lock.cc | 8 | ||||
-rw-r--r-- | chrome/browser/importer/importer.cc | 44 | ||||
-rw-r--r-- | chrome/chrome.gyp | 2 |
10 files changed, 275 insertions, 40 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 79130d5..7de7a50 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -1117,11 +1117,6 @@ void Browser::OpenClearBrowsingDataDialog() { window_->ShowClearBrowsingDataDialog(); } -void Browser::OpenImportSettingsDialog() { - UserMetrics::RecordAction(L"Import_ShowDlg", profile_); - window_->ShowImportDialog(); -} - void Browser::OpenOptionsDialog() { UserMetrics::RecordAction(L"ShowOptions", profile_); ShowOptionsWindow(OPTIONS_PAGE_DEFAULT, OPTIONS_GROUP_NONE, profile_); @@ -1137,6 +1132,13 @@ void Browser::OpenPasswordManager() { } #endif +#if defined(OS_WIN) || defined(OS_LINUX) +void Browser::OpenImportSettingsDialog() { + UserMetrics::RecordAction(L"Import_ShowDlg", profile_); + window_->ShowImportDialog(); +} +#endif + void Browser::OpenAboutChromeDialog() { UserMetrics::RecordAction(L"AboutChrome", profile_); window_->ShowAboutChromeDialog(); @@ -1349,11 +1351,13 @@ void Browser::ExecuteCommandWithDisposition( Personalization::HandleMenuItemClick(profile()); break; #endif case IDC_CLEAR_BROWSING_DATA: OpenClearBrowsingDataDialog(); break; - case IDC_IMPORT_SETTINGS: OpenImportSettingsDialog(); break; case IDC_OPTIONS: OpenOptionsDialog(); break; case IDC_EDIT_SEARCH_ENGINES: OpenKeywordEditor(); break; case IDC_VIEW_PASSWORDS: OpenPasswordManager(); break; #endif +#if defined(OS_WIN) || defined(OS_LINUX) + case IDC_IMPORT_SETTINGS: OpenImportSettingsDialog(); break; +#endif case IDC_ABOUT: OpenAboutChromeDialog(); break; case IDC_HELP_PAGE: OpenHelpTab(); break; diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index 5b4db92..030d6b8 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -372,11 +372,13 @@ class Browser : public TabStripModelDelegate, void ShowDownloadsTab(); #if defined(OS_WIN) void OpenClearBrowsingDataDialog(); - void OpenImportSettingsDialog(); void OpenOptionsDialog(); void OpenKeywordEditor(); void OpenPasswordManager(); #endif +#if defined(OS_WIN) || defined(OS_LINUX) + void OpenImportSettingsDialog(); +#endif void OpenAboutChromeDialog(); void OpenHelpTab(); diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index 33f005a..3c40c7f 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -22,6 +22,7 @@ #include "chrome/browser/gtk/bookmark_bar_gtk.h" #include "chrome/browser/gtk/browser_toolbar_gtk.h" #include "chrome/browser/gtk/go_button_gtk.h" +#include "chrome/browser/gtk/import_dialog_gtk.h" #include "chrome/browser/gtk/infobar_container_gtk.h" #include "chrome/browser/gtk/find_bar_gtk.h" #include "chrome/browser/gtk/status_bubble_gtk.h" @@ -565,7 +566,7 @@ void BrowserWindowGtk::ShowClearBrowsingDataDialog() { } void BrowserWindowGtk::ShowImportDialog() { - NOTIMPLEMENTED(); + ImportDialogGtk::Show(window_, browser_->profile()); } void BrowserWindowGtk::ShowSearchEnginesDialog() { diff --git a/chrome/browser/gtk/import_dialog_gtk.cc b/chrome/browser/gtk/import_dialog_gtk.cc new file mode 100644 index 0000000..c0b9cbd1 --- /dev/null +++ b/chrome/browser/gtk/import_dialog_gtk.cc @@ -0,0 +1,115 @@ +// 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/gtk/import_dialog_gtk.h" + +#include <gtk/gtk.h> + +#include "app/l10n_util.h" +#include "app/resource_bundle.h" +#include "chrome/browser/profile.h" +#include "grit/generated_resources.h" + +// static +void ImportDialogGtk::Show(GtkWindow* parent, Profile* profile) { + new ImportDialogGtk(parent, profile); +} + +ImportDialogGtk::ImportDialogGtk(GtkWindow* parent, Profile* profile) : + profile_(profile), importer_host_(new ImporterHost()) { + // Build the dialog. + GtkWidget* dialog = gtk_dialog_new_with_buttons( + l10n_util::GetStringUTF8(IDS_IMPORT_SETTINGS_TITLE).c_str(), + parent, + (GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR), + l10n_util::GetStringUTF8(IDS_IMPORT_COMMIT).c_str(), + GTK_RESPONSE_ACCEPT, + l10n_util::GetStringUTF8(IDS_CANCEL).c_str(), + GTK_RESPONSE_REJECT, + NULL); + + //TODO(rahulk): find how to set size properly so that the dialog box width is + // atleast enough to display full title. + gtk_widget_set_size_request(dialog, 300, -1); + + GtkWidget* content_area = GTK_DIALOG(dialog)->vbox; + GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 0.0, 0.0); + gtk_box_pack_start(GTK_BOX(content_area), alignment, TRUE, TRUE, 0); + + GtkWidget* vbox = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(alignment), vbox); + + GtkWidget* combo_hbox = gtk_hbox_new(FALSE, 5); + GtkWidget* from = gtk_label_new( + l10n_util::GetStringUTF8(IDS_IMPORT_FROM_LABEL).c_str()); + gtk_box_pack_start(GTK_BOX(combo_hbox), from, TRUE, TRUE, 5); + + combo_ = gtk_combo_box_new_text(); + int profiles_count = importer_host_->GetAvailableProfileCount(); + for (int i = 0; i < profiles_count; i++) { + std::wstring profile = importer_host_->GetSourceProfileNameAt(i); + gtk_combo_box_append_text(GTK_COMBO_BOX(combo_), + WideToUTF8(profile).c_str()); + } + gtk_combo_box_set_active(GTK_COMBO_BOX(combo_), 0); + gtk_box_pack_start(GTK_BOX(combo_hbox), combo_, TRUE, TRUE, 5); + gtk_box_pack_start(GTK_BOX(vbox), combo_hbox, TRUE, TRUE, 5); + + GtkWidget* description = gtk_label_new( + l10n_util::GetStringUTF8(IDS_IMPORT_ITEMS_LABEL).c_str()); + gtk_box_pack_start(GTK_BOX(vbox), description, TRUE, TRUE, 5); + + GtkWidget* text_alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); + gtk_alignment_set_padding(GTK_ALIGNMENT(text_alignment), 0, 0, 25, 0); + GtkWidget* text_vbox = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(text_alignment), text_vbox); + gtk_box_pack_start(GTK_BOX(vbox), text_alignment, TRUE, TRUE, 0); + + bookmarks_ = gtk_check_button_new_with_label( + l10n_util::GetStringUTF8(IDS_IMPORT_FAVORITES_CHKBOX).c_str()); + gtk_box_pack_start(GTK_BOX(text_vbox), bookmarks_, TRUE, TRUE, 5); + + search_engines_ = gtk_check_button_new_with_label( + l10n_util::GetStringUTF8(IDS_IMPORT_SEARCH_ENGINES_CHKBOX).c_str()); + gtk_box_pack_start(GTK_BOX(text_vbox), search_engines_, TRUE, TRUE, 5); + + passwords_ = gtk_check_button_new_with_label( + l10n_util::GetStringUTF8(IDS_IMPORT_PASSWORDS_CHKBOX).c_str()); + gtk_box_pack_start(GTK_BOX(text_vbox), passwords_, TRUE, TRUE, 5); + + history_ = gtk_check_button_new_with_label( + l10n_util::GetStringUTF8(IDS_IMPORT_HISTORY_CHKBOX).c_str()); + gtk_box_pack_start(GTK_BOX(text_vbox), history_, TRUE, TRUE, 5); + + g_signal_connect(dialog, "response", + G_CALLBACK(HandleOnResponseDialog), this); + gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); + gtk_widget_show_all(dialog); +} + +void ImportDialogGtk::OnDialogResponse(GtkWidget* widget, int response) { + if (response == GTK_RESPONSE_ACCEPT) { + uint16 items = NONE; + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bookmarks_))) + items |= FAVORITES; + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(search_engines_))) + items |= SEARCH_ENGINES; + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(passwords_))) + items |= PASSWORDS; + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(history_))) + items |= HISTORY; + + const ProfileInfo& source_profile = importer_host_->GetSourceProfileInfoAt( + gtk_combo_box_get_active(GTK_COMBO_BOX(combo_))); + + // TODO(rahulk): We should not do the import on this thread. Instead + // we need to start this asynchronously and launch a UI that shows the + // progress of import. + importer_host_->StartImportSettings(source_profile, items, + new ProfileWriter(profile_), false); + } + + delete this; + gtk_widget_destroy(GTK_WIDGET(widget)); +} diff --git a/chrome/browser/gtk/import_dialog_gtk.h b/chrome/browser/gtk/import_dialog_gtk.h new file mode 100644 index 0000000..ad71b40 --- /dev/null +++ b/chrome/browser/gtk/import_dialog_gtk.h @@ -0,0 +1,56 @@ +// 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_GTK_IMPORT_DIALOG_GTK_H_ +#define CHROME_BROWSER_GTK_IMPORT_DIALOG_GTK_H_ + +#include "chrome/browser/importer/importer.h" + +#include <gtk/gtk.h> + +class Profile; +typedef struct _GtkWindow GtkWindow; + +class ImportDialogGtk { + public: + // Displays the import box to import data from another browser into |profile| + static void Show(GtkWindow* parent, Profile* profile); + + private: + ImportDialogGtk(GtkWindow* parent, Profile* profile); + ~ImportDialogGtk() { } + + static void HandleOnResponseDialog(GtkWidget* widget, + int response, + gpointer user_data) { + reinterpret_cast<ImportDialogGtk*>(user_data)->OnDialogResponse(widget, + response); + } + void OnDialogResponse(GtkWidget* widget, int response); + + // Combo box that displays list of profiles from which we can import. + GtkWidget* combo_; + + // Bookmarks/Favorites checkbox + GtkWidget* bookmarks_; + + // Search Engines checkbox + GtkWidget* search_engines_; + + // Passwords checkbox + GtkWidget* passwords_; + + // History checkbox + GtkWidget* history_; + + // Our current profile + Profile* profile_; + + // Utility class that does the actual import. + scoped_refptr<ImporterHost> importer_host_; + + DISALLOW_COPY_AND_ASSIGN(ImportDialogGtk); +}; + +#endif // CHROME_BROWSER_GTK_IMPORT_DIALOG_GTK_H_ diff --git a/chrome/browser/importer/firefox_importer_utils.cc b/chrome/browser/importer/firefox_importer_utils.cc index 1003b90..66e30b0 100644 --- a/chrome/browser/importer/firefox_importer_utils.cc +++ b/chrome/browser/importer/firefox_importer_utils.cc @@ -12,7 +12,6 @@ #include "app/win_util.h" #include "base/registry.h" #endif -#include "base/file_util.h" #include "base/logging.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" @@ -108,21 +107,61 @@ int GetCurrentFirefoxMajorVersion() { #endif } +#if defined(OS_WIN) || defined(OS_LINUX) +bool GetFirefoxVersionAndPathFromProfile(const std::wstring& profile_path, + int* version, + std::wstring* app_path) { + bool ret = false; + std::wstring compatibility_file(profile_path); + file_util::AppendToPath(&compatibility_file, L"compatibility.ini"); + std::string content; + file_util::ReadFileToString(compatibility_file, &content); + ReplaceSubstringsAfterOffset(&content, 0, "\r\n", "\n"); + std::vector<std::string> lines; + SplitString(content, '\n', &lines); + + for (size_t i = 0; i < lines.size(); ++i) { + const std::string& line = lines[i]; + if (line.empty() || line[0] == '#' || line[0] == ';') + continue; + size_t equal = line.find('='); + if (equal != std::string::npos) { + std::string key = line.substr(0, equal); + if (key == "LastVersion") { + *version = line.substr(equal + 1)[0] - '0'; + ret = true; + } else if (key == "LastAppDir") { + *app_path = UTF8ToWide(line.substr(equal + 1)); + } + } + } + return ret; +} + + +FilePath GetProfilesINI() { + FilePath ini_file; #if defined(OS_WIN) -std::wstring GetProfilesINI() { // The default location of the profile folder containing user data is // under the "Application Data" folder in Windows XP. - std::wstring ini_file; wchar_t buffer[MAX_PATH] = {0}; if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, buffer))) { - ini_file = buffer; - file_util::AppendToPath(&ini_file, L"Mozilla\\Firefox\\profiles.ini"); + ini_file = FilePath(buffer).Append(L"Mozilla\\Firefox\\profiles.ini"); } - if (!file_util::PathExists(ini_file)) - ini_file.clear(); - return ini_file; +#else + // The default location of the profile folder containing user data is + // under user HOME directory in .mozilla/firefox folder on Linux. + const char *home = getenv("HOME"); + if (home && home[0]) { + ini_file = FilePath(home).Append(".mozilla/firefox/profiles.ini"); + } +#endif + if (file_util::PathExists(ini_file)) + return ini_file; + + return FilePath(); } void ParseProfileINI(std::wstring file, DictionaryValue* root) { diff --git a/chrome/browser/importer/firefox_importer_utils.h b/chrome/browser/importer/firefox_importer_utils.h index 0f2461e..06b6063 100644 --- a/chrome/browser/importer/firefox_importer_utils.h +++ b/chrome/browser/importer/firefox_importer_utils.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_IMPORTER_FIREFOX_IMPORTER_UTILS_H_ #include "base/basictypes.h" +#include "base/file_util.h" #include "base/values.h" #include "build/build_config.h" #include "webkit/glue/password_form.h" @@ -13,17 +14,22 @@ class GURL; class TemplateURL; -// Detects which version of Firefox is installed. Returns its +// Detects which version of Firefox is installed from registry. Returns its // major version, and drops the minor version. Returns 0 if // failed. If there are indicators of both FF2 and FF3 it is // biased to return the biggest version. int GetCurrentFirefoxMajorVersion(); -#if defined(OS_WIN) +#if defined(OS_WIN) || defined(OS_LINUX) +// Detects version of Firefox and installation path from given Firefox profile +bool GetFirefoxVersionAndPathFromProfile(const std::wstring& profile_path, + int* version, + std::wstring* app_path); + // Gets the full path of the profiles.ini file. This file records // the profiles that can be used by Firefox. Returns an empty // string if failed. -std::wstring GetProfilesINI(); +FilePath GetProfilesINI(); // Parses the profile.ini file, and stores its information in |root|. // This file is a plain-text file. Key/value pairs are stored one per diff --git a/chrome/browser/importer/firefox_profile_lock.cc b/chrome/browser/importer/firefox_profile_lock.cc index d033002..f51a9f9 100644 --- a/chrome/browser/importer/firefox_profile_lock.cc +++ b/chrome/browser/importer/firefox_profile_lock.cc @@ -52,8 +52,16 @@ * ***** END LICENSE BLOCK ***** */ // static +#if defined(OS_LINUX) +// TODO(rahulk): Even though this is called OLD_LOCK_FILE_NAME in Firefox code +// http://www.google.com/codesearch/p?hl=en#e_ObwTAVPyo/profile/dirserviceprovider/src/nsProfileLock.cpp&l=433 +// this seems to work with Firefox 3.0. +const FilePath::CharType* FirefoxProfileLock::kLockFileName = + FILE_PATH_LITERAL("lock"); +#else const FilePath::CharType* FirefoxProfileLock::kLockFileName = FILE_PATH_LITERAL("parent.lock"); +#endif FirefoxProfileLock::FirefoxProfileLock(const std::wstring& path) { Init(); diff --git a/chrome/browser/importer/importer.cc b/chrome/browser/importer/importer.cc index 66aa8ed..2bfb9f6 100644 --- a/chrome/browser/importer/importer.cc +++ b/chrome/browser/importer/importer.cc @@ -515,7 +515,7 @@ void ImporterHost::StartImportSettings(const ProfileInfo& profile_info, } } - #if defined(OS_WIN) +#if defined(OS_WIN) // For google toolbar import, we need the user to log in and store their GAIA // credentials. if (profile_info.browser_type == GOOGLE_TOOLBAR5) { @@ -677,26 +677,12 @@ void ImporterHost::DetectIEProfiles() { #endif void ImporterHost::DetectFirefoxProfiles() { - // Detects which version of Firefox is installed. - int version = GetCurrentFirefoxMajorVersion(); - ProfileType firefox_type; - if (version == 2) { - firefox_type = FIREFOX2; - } else if (version == 3) { - firefox_type = FIREFOX3; - } else { - // Ignores other versions of firefox. - return; - } - +#if defined(OS_MACOSX) + NOTIMPLEMENTED(); +#else DictionaryValue root; -#if defined(OS_WIN) - std::wstring ini_file = GetProfilesINI(); + std::wstring ini_file = GetProfilesINI().ToWStringHack(); ParseProfileINI(ini_file, &root); -#else - // TODO(port): Do we need to concern ourselves with profiles on posix? - NOTIMPLEMENTED(); -#endif std::wstring source_path; for (int i = 0; ; ++i) { @@ -714,7 +700,6 @@ void ImporterHost::DetectFirefoxProfiles() { &path16, 0, ASCIIToUTF16("/"), ASCIIToUTF16("\\")); path.assign(UTF16ToWideHack(path16)); -#if defined(OS_WIN) // IsRelative=1 means the folder path would be relative to the // path of profiles.ini. IsRelative=0 refers to a custom profile // location. @@ -724,7 +709,6 @@ void ImporterHost::DetectFirefoxProfiles() { } else { profile_path = path; } -#endif // We only import the default profile when multiple profiles exist, // since the other profiles are used mostly by developers for testing. @@ -740,16 +724,34 @@ void ImporterHost::DetectFirefoxProfiles() { } } + // Detects which version of Firefox is installed. + ProfileType firefox_type; + std::wstring app_path; + int version = GetCurrentFirefoxMajorVersion(); + if (version != 2 && version != 3) + GetFirefoxVersionAndPathFromProfile(source_path, &version, &app_path); + if (version == 2) { + firefox_type = FIREFOX2; + } else if (version == 3) { + firefox_type = FIREFOX3; + } else { + // Ignores other versions of firefox. + return; + } + if (!source_path.empty()) { ProfileInfo* firefox = new ProfileInfo(); firefox->description = l10n_util::GetString(IDS_IMPORT_FROM_FIREFOX); firefox->browser_type = firefox_type; firefox->source_path = source_path; firefox->app_path = GetFirefoxInstallPath(); + if (firefox->app_path.empty()) + firefox->app_path = app_path; firefox->services_supported = HISTORY | FAVORITES | COOKIES | PASSWORDS | SEARCH_ENGINES; source_profiles_.push_back(firefox); } +#endif } void ImporterHost::DetectGoogleToolbarProfiles() { diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 87dde3d..62fcef7 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -931,6 +931,8 @@ 'browser/gtk/gtk_chrome_button.cc', 'browser/gtk/gtk_chrome_button.h', 'browser/gtk/hung_renderer_dialog_gtk.cc', + 'browser/gtk/import_dialog_gtk.cc', + 'browser/gtk/import_dialog_gtk.h', 'browser/gtk/info_bubble_gtk.cc', 'browser/gtk/info_bubble_gtk.h', 'browser/gtk/infobar_container_gtk.cc', |