FYI, the fix is to instead use
const char Toolbar5Importer::kUrlXmlTag[] = "url";

On Mon, Jan 12, 2009 at 2:11 PM, Dean McNamee <[email protected]> wrote:
>
> This added a bunch of startup time static initializers.  Specifically
> there are many things like:
>
>  const std::string Toolbar5Importer::kUrlXmlTag = "url";
>
> These all need to run the std::string constructor on startup, which
> should be considered a regression...
>
> Here is the complete list:
>
> _dynamic_initializer_for__Toolbar5Importer__kXmlApiReplyXmlTag__
> _dynamic_initializer_for__Toolbar5Importer__kBookmarksXmlTag__
> _dynamic_initializer_for__Toolbar5Importer__kBookmarkXmlTag__
> _dynamic_initializer_for__Toolbar5Importer__kTitleXmlTag__
> _dynamic_initializer_for__Toolbar5Importer__kUrlXmlTag__
> _dynamic_initializer_for__Toolbar5Importer__kTimestampXmlTag__
> _dynamic_initializer_for__Toolbar5Importer__kLabelsXmlTag__
> _dynamic_initializer_for__Toolbar5Importer__kLabelsXmlCloseTag__
> _dynamic_initializer_for__Toolbar5Importer__kLabelXmlTag__
> _dynamic_initializer_for__Toolbar5Importer__kAttributesXmlTag__
> _dynamic_initializer_for__Toolbar5Importer__kRandomNumberToken__
> _dynamic_initializer_for__Toolbar5Importer__kAuthorizationToken__
> _dynamic_initializer_for__Toolbar5Importer__kAuthorizationTokenPrefix__
> _dynamic_initializer_for__Toolbar5Importer__kAuthorizationTokenSuffix__
> _dynamic_initializer_for__Toolbar5Importer__kMaxNumToken__
> _dynamic_initializer_for__Toolbar5Importer__kMaxTimestampToken__
> _dynamic_initializer_for__Toolbar5Importer__kT5AuthorizationTokenUrl__
> _dynamic_initializer_for__Toolbar5Importer__kT5FrontEndUrlTemplate__
>
>
> On Tue, Nov 4, 2008 at 8:54 PM,  <[email protected]> wrote:
>>
>> Author: [email protected]
>> Date: Tue Nov  4 11:54:49 2008
>> New Revision: 4633
>>
>> Log:
>> Toolbar Import - Issue 8801, migrated from public tree to svn enlistment.
>>
>> Added:
>>   trunk/src/chrome/browser/importer/toolbar_importer.cc
>>   trunk/src/chrome/browser/importer/toolbar_importer.h
>> Modified:
>>   trunk/src/chrome/app/generated_resources.grd
>>   trunk/src/chrome/browser/browser.vcproj
>>   trunk/src/chrome/browser/importer/importer.cc
>>   trunk/src/chrome/browser/importer/importer.h
>>   trunk/src/chrome/browser/views/importer_view.cc
>>   trunk/src/chrome/browser/views/importer_view.h
>>
>> Modified: trunk/src/chrome/app/generated_resources.grd
>> ==============================================================================
>> --- trunk/src/chrome/app/generated_resources.grd        (original)
>> +++ trunk/src/chrome/app/generated_resources.grd        Tue Nov  4 11:54:49 
>> 2008
>> @@ -1768,6 +1768,9 @@
>>       <message name="IDS_IMPORT_FROM_FIREFOX" desc="browser combo box: 
>> Mozilla Firefox">
>>         Mozilla Firefox
>>       </message>
>> +      <message name="IDS_IMPORT_FROM_GOOGLE_TOOLBAR" desc="browser combo 
>> box: Google Toolbar">
>> +        Google Toolbar
>> +      </message>
>>       <message name="IDS_IMPORT_ITEMS_LABEL" desc="Label before item select 
>> checkboxes">
>>         Select items to import:
>>       </message>
>> @@ -1791,6 +1794,10 @@
>>         Import
>>       </message>
>>
>> +      <message name="IDS_IMPORTER_GOOGLE_LOGIN_TEXT" desc="The message to 
>> be displayed on dialog">
>> +        In order to import Toolbar bookmarks into Chrome, you must be 
>> logged into your Google account.  Please log in and try to import again.
>> +      </message>
>> +
>>       <!-- Import progress popup -->
>>       <message name="IDS_IMPORT_PROGRESS_TITLE" desc="Title for the 
>> importing progress dialog">
>>         Importing
>> @@ -2032,7 +2039,7 @@
>>       <message name="IDS_BOOKMARKS_NO_ITEMS" desc="Text shown when the user 
>> has no bookmarks">
>>         For quick access, place your bookmarks here in the bookmarks bar.
>>       </message>
>> -
>> +
>>       <!-- The location for special bookmark groups -->
>>       <message name="IDS_BOOKMARK_GROUP_FROM_IE" desc="The group name of 
>> bookmarks from Internet Explorer">
>>         Imported From IE
>> @@ -2040,11 +2047,14 @@
>>       <message name="IDS_BOOKMARK_GROUP_FROM_FIREFOX" desc="The group name 
>> of bookmarks from Firefox">
>>         Imported From Firefox
>>       </message>
>> +      <message name="IDS_BOOKMARK_GROUP_FROM_GOOGLE_TOOLBAR" desc="The 
>> group name of bookmarks from Google Toolbar">
>> +        Imported From Google Toolbar
>> +      </message>
>>       <message name="IDS_BOOKMARK_GROUP" desc="The group name of bookmarks 
>> imported from a file">
>>         Imported
>>       </message>
>>
>> -      <!-- bookmark editor messages-->
>> +  <!-- bookmark editor messages-->
>>       <message name="IDS_BOOMARK_EDITOR_NAME_LABEL" desc="Label shown before 
>> the title/name of the URL.">
>>         Name:
>>       </message>
>>
>> Modified: trunk/src/chrome/browser/browser.vcproj
>> ==============================================================================
>> --- trunk/src/chrome/browser/browser.vcproj     (original)
>> +++ trunk/src/chrome/browser/browser.vcproj     Tue Nov  4 11:54:49 2008
>> @@ -722,19 +722,19 @@
>>                        Name="Bookmarks"
>>                        >
>>                        <File
>> -                               
>> RelativePath=".\bookmarks\bookmark_context_menu.cc"
>> +                               RelativePath=".\bookmarks\bookmark_codec.cc"
>>                                >
>>                        </File>
>>                        <File
>> -                               
>> RelativePath=".\bookmarks\bookmark_context_menu.h"
>> +                               RelativePath=".\bookmarks\bookmark_codec.h"
>>                                >
>>                        </File>
>>                        <File
>> -                               RelativePath=".\bookmarks\bookmark_codec.cc"
>> +                               
>> RelativePath=".\bookmarks\bookmark_context_menu.cc"
>>                                >
>>                        </File>
>>                        <File
>> -                               RelativePath=".\bookmarks\bookmark_codec.h"
>> +                               
>> RelativePath=".\bookmarks\bookmark_context_menu.h"
>>                                >
>>                        </File>
>>                        <File
>> @@ -1577,6 +1577,14 @@
>>                                RelativePath=".\importer\mork_reader.h"
>>                                >
>>                        </File>
>> +                       <File
>> +                               RelativePath=".\importer\toolbar_importer.cc"
>> +                               >
>> +                       </File>
>> +                       <File
>> +                               RelativePath=".\importer\toolbar_importer.h"
>> +                               >
>> +                       </File>
>>                </Filter>
>>                <Filter
>>                        Name="Drag &amp; Drop"
>>
>> Modified: trunk/src/chrome/browser/importer/importer.cc
>> ==============================================================================
>> --- trunk/src/chrome/browser/importer/importer.cc       (original)
>> +++ trunk/src/chrome/browser/importer/importer.cc       Tue Nov  4 11:54:49 
>> 2008
>> @@ -11,12 +11,16 @@
>>  #include "base/gfx/png_encoder.h"
>>  #include "base/string_util.h"
>>  #include "chrome/browser/bookmarks/bookmark_model.h"
>> +#include "chrome/browser/browser.h"
>> +#include "chrome/browser/browser_list.h"
>>  #include "chrome/browser/browser_process.h"
>> +#include "chrome/browser/first_run.h"
>>  #include "chrome/browser/importer/firefox2_importer.h"
>>  #include "chrome/browser/importer/firefox3_importer.h"
>>  #include "chrome/browser/importer/firefox_importer_utils.h"
>>  #include "chrome/browser/importer/firefox_profile_lock.h"
>>  #include "chrome/browser/importer/ie_importer.h"
>> +#include "chrome/browser/importer/toolbar_importer.h"
>>  #include "chrome/browser/template_url_model.h"
>>  #include "chrome/browser/shell_integration.h"
>>  #include "chrome/browser/webdata/web_data_service.h"
>> @@ -24,6 +28,7 @@
>>  #include "chrome/common/l10n_util.h"
>>  #include "chrome/common/pref_names.h"
>>  #include "chrome/common/pref_service.h"
>> +#include "chrome/common/win_util.h"
>>  #include "chrome/views/window.h"
>>  #include "webkit/glue/image_decoder.h"
>>
>> @@ -245,7 +250,8 @@
>>     }
>>     if (t_url->url() && t_url->url()->IsValid()) {
>>       model->Add(t_url);
>> -      if (default_keyword && t_url->url() && 
>> t_url->url()->SupportsReplacement())
>> +      if (default_keyword && t_url->url() &&
>> +          t_url->url()->SupportsReplacement())
>>         model->SetDefaultSearchProvider(t_url);
>>     } else {
>>       // Don't add invalid TemplateURLs to the model.
>> @@ -327,6 +333,7 @@
>>
>>  ImporterHost::~ImporterHost() {
>>   STLDeleteContainerPointers(source_profiles_.begin(), 
>> source_profiles_.end());
>> +  if (NULL != importer_)  importer_->Release();
>>  }
>>
>>  void ImporterHost::Loaded(BookmarkModel* model) {
>> @@ -386,6 +393,7 @@
>>   // will be notified.
>>   writer_ = writer;
>>   importer_ = CreateImporterByType(profile_info.browser_type);
>> +  importer_->AddRef();
>>   importer_->set_first_run(first_run);
>>   task_ = NewRunnableMethod(importer_, &Importer::StartImport,
>>       profile_info, items, writer_.get(), this);
>> @@ -402,6 +410,27 @@
>>     }
>>   }
>>
>> +  if (profile_info.browser_type == GOOGLE_TOOLBAR5) {
>> +    if (!ToolbarImporterUtils::IsGoogleGAIACookieInstalled()) {
>> +      win_util::MessageBox(
>> +          NULL,
>> +          l10n_util::GetString(IDS_IMPORTER_GOOGLE_LOGIN_TEXT).c_str(),
>> +          L"",
>> +          MB_OK | MB_TOPMOST);
>> +
>> +      GURL url("https://www.google.com/accounts/ServiceLogin";);
>> +      BrowsingInstance* instance = new 
>> BrowsingInstance(writer_->GetProfile());
>> +      SiteInstance* site = instance->GetSiteInstanceForURL(url);
>> +      Browser* browser = BrowserList::GetLastActive();
>> +      browser->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, 
>> site);
>> +
>> +      MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
>> +        this, &ImporterHost::OnLockViewEnd, false));
>> +
>> +      is_source_readable_ = false;
>> +    }
>> +  }
>> +
>>   // BookmarkModel should be loaded before adding IE favorites. So we observe
>>   // the BookmarkModel if needed, and start the task after it has been 
>> loaded.
>>   if ((items & FAVORITES) && !writer_->BookmarkModelIsLoaded()) {
>> @@ -469,6 +498,8 @@
>>       return new Firefox2Importer();
>>     case FIREFOX3:
>>       return new Firefox3Importer();
>> +    case GOOGLE_TOOLBAR5:
>> +      return new Toolbar5Importer();
>>   }
>>   NOTREACHED();
>>   return NULL;
>> @@ -489,6 +520,8 @@
>>  }
>>
>>  void ImporterHost::DetectSourceProfiles() {
>> +  // The order in which detect is called determines the order
>> +  // in which the options appear in the dropdown combo-box
>>   if (ShellIntegration::IsFirefoxDefaultBrowser()) {
>>     DetectFirefoxProfiles();
>>     DetectIEProfiles();
>> @@ -496,6 +529,8 @@
>>     DetectIEProfiles();
>>     DetectFirefoxProfiles();
>>   }
>> +
>> +  if (!FirstRun::IsChromeFirstRun()) DetectGoogleToolbarProfiles();
>>  }
>>
>>  void ImporterHost::DetectIEProfiles() {
>> @@ -505,6 +540,8 @@
>>   ie->browser_type = MS_IE;
>>   ie->source_path.clear();
>>   ie->app_path.clear();
>> +  ie->services_supported = HISTORY | FAVORITES | COOKIES | PASSWORDS |
>> +      SEARCH_ENGINES;
>>   source_profiles_.push_back(ie);
>>  }
>>
>> @@ -568,7 +605,32 @@
>>     firefox->browser_type = firefox_type;
>>     firefox->source_path = source_path;
>>     firefox->app_path = GetFirefoxInstallPath();
>> +    firefox->services_supported = HISTORY | FAVORITES | COOKIES | PASSWORDS 
>> |
>> +        SEARCH_ENGINES;
>>     source_profiles_.push_back(firefox);
>>   }
>>  }
>>
>> +void ImporterHost::DetectGoogleToolbarProfiles() {
>> +  if (ToolbarImporterUtils::IsToolbarInstalled()) {
>> +    TOOLBAR_VERSION version = ToolbarImporterUtils::GetToolbarVersion();
>> +    if (DEPRECATED != version) {
>> +      ProfileInfo* google_toolbar = new ProfileInfo();
>> +      switch (version) {
>> +        // TODO(brg): Support other toolbar version after 1.0.
>> +        case VERSION_5:
>> +          google_toolbar->browser_type = GOOGLE_TOOLBAR5;
>> +          break;
>> +        default:
>> +          NOTREACHED() << "Supported Google Toolbar version not 
>> implemented.";
>> +          break;
>> +      }
>> +      google_toolbar->description = l10n_util::GetString(
>> +                                    IDS_IMPORT_FROM_GOOGLE_TOOLBAR);
>> +      google_toolbar->source_path.clear();
>> +      google_toolbar->app_path.clear();
>> +      google_toolbar->services_supported = FAVORITES;
>> +      source_profiles_.push_back(google_toolbar);
>> +    }
>> +  }
>> +}
>>
>> Modified: trunk/src/chrome/browser/importer/importer.h
>> ==============================================================================
>> --- trunk/src/chrome/browser/importer/importer.h        (original)
>> +++ trunk/src/chrome/browser/importer/importer.h        Tue Nov  4 11:54:49 
>> 2008
>> @@ -26,7 +26,8 @@
>>  enum ProfileType {
>>   MS_IE = 0,
>>   FIREFOX2,
>> -  FIREFOX3
>> +  FIREFOX3,
>> +  GOOGLE_TOOLBAR5
>>  };
>>
>>  // An enumeration of the type of data we want to import.
>> @@ -38,6 +39,7 @@
>>   PASSWORDS      = 0x0008,
>>   SEARCH_ENGINES = 0x0010,
>>   HOME_PAGE      = 0x0020,
>> +  ALL            = 0x003f
>>  };
>>
>>  typedef struct {
>> @@ -45,6 +47,7 @@
>>   ProfileType browser_type;
>>   std::wstring source_path;
>>   std::wstring app_path;
>> +  uint16 services_supported;  // bitmap of ImportItem
>>  } ProfileInfo;
>>
>>  class FirefoxProfileLock;
>> @@ -103,6 +106,8 @@
>>   // Shows the bookmarks toolbar.
>>   void ShowBookmarkBar();
>>
>> +  Profile* GetProfile() const { return profile_; }
>> +
>>  private:
>>   Profile* profile_;
>>
>> @@ -228,6 +233,7 @@
>>   // Helper methods for detecting available profiles.
>>   void DetectIEProfiles();
>>   void DetectFirefoxProfiles();
>> +  void DetectGoogleToolbarProfiles();
>>
>>   // The list of profiles with the default one first.
>>   std::vector<ProfileInfo*> source_profiles_;
>>
>> Added: trunk/src/chrome/browser/importer/toolbar_importer.cc
>> ==============================================================================
>> --- (empty file)
>> +++ trunk/src/chrome/browser/importer/toolbar_importer.cc       Tue Nov  4 
>> 11:54:49 2008
>> @@ -0,0 +1,578 @@
>> +// Copyright (c) 2006-2008 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/importer/toolbar_importer.h"
>> +
>> +#include <limits>
>> +#include "base/string_util.h"
>> +#include "base/rand_util.h"
>> +#include "base/registry.h"
>> +#include "chrome/common/l10n_util.h"
>> +#include "chrome/common/libxml_utils.h"
>> +#include "net/base/data_url.h"
>> +#include "net/base/cookie_monster.h"
>> +
>> +#include "generated_resources.h"
>> +
>> +
>> +//
>> +// ToolbarImporterUtils
>> +//
>> +const HKEY ToolbarImporterUtils::kToolbarInstallRegistryRoots[] =
>> +    {HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE};
>> +const TCHAR* ToolbarImporterUtils::kToolbarRootRegistryFolder =
>> +    L"Software\\Google\\Google Toolbar";
>> +const TCHAR* ToolbarImporterUtils::kToolbarVersionRegistryFolder =
>> +    L"SOFTWARE\\Google\\Google Toolbar\\Component";
>> +const TCHAR* ToolbarImporterUtils::kToolbarVersionRegistryKey =
>> +    L"CurrentVersion";
>> +
>> +
>> +bool ToolbarImporterUtils::IsToolbarInstalled() {
>> +  for (int index = 0;
>> +      index < arraysize(kToolbarInstallRegistryRoots);
>> +      ++index) {
>> +    RegKey key(kToolbarInstallRegistryRoots[index],
>> +               kToolbarRootRegistryFolder);
>> +    if (key.Valid())
>> +      return true;
>> +  }
>> +  return false;
>> +}
>> +
>> +bool ToolbarImporterUtils::IsGoogleGAIACookieInstalled() {
>> +  URLRequestContext* context = Profile::GetDefaultRequestContext();
>> +  net::CookieMonster* store= context->cookie_store();
>> +  GURL url("http://.google.com/";);
>> +  net::CookieMonster::CookieOptions options = net::CookieMonster::NORMAL;
>> +  std::string cookies = store->GetCookiesWithOptions(url, options);
>> +  std::vector<std::string> cookie_list;
>> +  SplitString(cookies, L';', &cookie_list);
>> +  for (std::vector<std::string>::iterator current = cookie_list.begin();
>> +       current != cookie_list.end();
>> +       ++current) {
>> +    size_t position = (*current).find("SID=");
>> +    if (0 == position)
>> +        return true;
>> +  }
>> +  return false;
>> +}
>> +
>> +TOOLBAR_VERSION ToolbarImporterUtils::GetToolbarVersion() {
>> +  TOOLBAR_VERSION toolbar_version = NO_VERSION;
>> +  for (int index = 0;
>> +       (index < arraysize(kToolbarInstallRegistryRoots)) &&
>> +       NO_VERSION == toolbar_version;
>> +       ++index) {
>> +    RegKey key(kToolbarInstallRegistryRoots[index],
>> +               kToolbarVersionRegistryFolder);
>> +    if (key.Valid() && key.ValueExists(kToolbarVersionRegistryKey)) {
>> +      TCHAR version_buffer[128];
>> +      DWORD version_buffer_length = sizeof(version_buffer);
>> +      if (key.ReadValue(kToolbarVersionRegistryKey,
>> +                        &version_buffer,
>> +                        &version_buffer_length)) {
>> +        int version_value = _wtoi(version_buffer);
>> +        switch (version_value) {
>> +          case 5: {
>> +            toolbar_version = VERSION_5;
>> +            break;
>> +           }
>> +          default: {
>> +            toolbar_version = DEPRECATED;
>> +            break;
>> +          }
>> +        }
>> +      }
>> +    }
>> +  }
>> +  return toolbar_version;
>> +}
>> +
>> +//
>> +// Toolbar5Importer
>> +//
>> +
>> +const std::string Toolbar5Importer::kXmlApiReplyXmlTag = "xml_api_reply";
>> +const std::string Toolbar5Importer::kBookmarksXmlTag = "bookmarks";
>> +const std::string Toolbar5Importer::kBookmarkXmlTag = "bookmark";
>> +const std::string Toolbar5Importer::kTitleXmlTag = "title";
>> +const std::string Toolbar5Importer::kUrlXmlTag = "url";
>> +const std::string Toolbar5Importer::kTimestampXmlTag = "timestamp";
>> +const std::string Toolbar5Importer::kLabelsXmlTag = "labels";
>> +const std::string Toolbar5Importer::kLabelXmlTag = "label";
>> +const std::string Toolbar5Importer::kAttributesXmlTag = "attributes";
>> +const std::string Toolbar5Importer::kAttributeXmlTag = "attribute";
>> +const std::string Toolbar5Importer::kNameXmlTag = "name";
>> +const std::string Toolbar5Importer::kValueXmlTag = "favicon";
>> +const std::string Toolbar5Importer::kFaviconAttributeXmlName = 
>> "favicon_url";
>> +
>> +const std::string Toolbar5Importer::kRandomNumberToken = "{random_number}";
>> +const std::string Toolbar5Importer::kAuthorizationToken = "{auth_token}";
>> +const std::string Toolbar5Importer::kAuthorizationTokenPrefix = "/*";
>> +const std::string Toolbar5Importer::kAuthorizationTokenSuffix = "*/";
>> +const std::string Toolbar5Importer::kMaxNumToken = "{max_num}";
>> +const std::string Toolbar5Importer::kMaxTimestampToken = "{max_timestamp}";
>> +
>> +const std::string Toolbar5Importer::kT5AuthorizationTokenUrl =
>> +    "http://www.google.com/notebook/token?zx={random_number}";;
>> +const std::string Toolbar5Importer::kT5FrontEndUrlTemplate =
>> +    "http://www.google.com/notebook/toolbar?cmd=list&tok={auth_token}&; "
>> +    "num={max_num}&min={max_timestamp}&all=0&zx={random_number}";
>> +const std::string Toolbar5Importer::kT4FrontEndUrlTemplate =
>> +    "http://www.google.com/bookmarks/?output=xml&num={max_num}&";
>> +    "min={max_timestamp}&all=0&zx={random_number}";
>> +
>> +// Importer methods.
>> +Toolbar5Importer::Toolbar5Importer() : writer_(NULL),
>> +                                       state_(NOT_USED),
>> +                                       items_to_import_(NONE),
>> +                                       token_fetcher_(NULL),
>> +                                       data_fetcher_(NULL) {
>> +}
>> +
>> +Toolbar5Importer::~Toolbar5Importer() {
>> +  DCHECK(!token_fetcher_);
>> +  DCHECK(!data_fetcher_);
>> +}
>> +
>> +void Toolbar5Importer::StartImport(ProfileInfo profile_info,
>> +                                   uint16 items,
>> +                                   ProfileWriter* writer,
>> +                                   ImporterHost* host) {
>> +  DCHECK(writer);
>> +  DCHECK(host);
>> +
>> +  importer_host_ = host;
>> +  writer_ = writer;
>> +  items_to_import_ = items;
>> +  state_ = INITIALIZED;
>> +
>> +  NotifyStarted();
>> +  ContinueImport();
>> +}
>> +
>> +void Toolbar5Importer::OnURLFetchComplete(
>> +    const URLFetcher* source,
>> +    const GURL& url,
>> +    const URLRequestStatus& status,
>> +    int response_code,
>> +    const ResponseCookies& cookies,
>> +    const std::string& data) {
>> +  if (200 != response_code) {  // HTTP/Ok
>> +    // Display to the user an error dialog and cancel the import
>> +    EndImportBookmarks(false);
>> +    return;
>> +  }
>> +
>> +  switch (state_) {
>> +    case GET_AUTHORIZATION_TOKEN:
>> +      GetBookmarkDataFromServer(data);
>> +      break;
>> +    case GET_BOOKMARKS:
>> +      GetBookmarsFromServerDataResponse(data);
>> +      break;
>> +    default:
>> +      NOTREACHED() << "Invalid state.";
>> +      EndImportBookmarks(false);
>> +      break;
>> +  }
>> +}
>> +
>> +void Toolbar5Importer::ContinueImport() {
>> +  DCHECK((items_to_import_ == FAVORITES) || (items_to_import_ == NONE)) <<
>> +      "The items requested are not supported";
>> +
>> +  // The order here is important.  Each Begin... will clear the flag
>> +  // of its item before its task finishes and re-enters this method.
>> +  if (NONE == items_to_import_) {
>> +    EndImport();
>> +  }
>> +  if ((items_to_import_ & FAVORITES) && !cancelled()) {
>> +    items_to_import_ &= ~FAVORITES;
>> +    BeginImportBookmarks();
>> +  }
>> +  // TODO(brg): Import history, autocomplete, other toolbar information
>> +  // for 2.0
>> +}
>> +
>> +void Toolbar5Importer::EndImport() {
>> +  // By spec the fetcher's must be destroyed within the same
>> +  // thread they are created.  The importer is destroyed in the ui_thread
>> +  // so when we complete in the file_thread we destroy them first.
>> +  if (NULL != token_fetcher_) {
>> +    delete token_fetcher_;
>> +    token_fetcher_ = NULL;
>> +  }
>> +
>> +  if (NULL != data_fetcher_) {
>> +    delete data_fetcher_;
>> +    data_fetcher_ = NULL;
>> +  }
>> +
>> +  NotifyEnded();
>> +}
>> +
>> +void Toolbar5Importer::BeginImportBookmarks() {
>> +  NotifyItemStarted(FAVORITES);
>> +  GetAuthenticationFromServer();
>> +}
>> +
>> +void Toolbar5Importer::EndImportBookmarks(bool success) {
>> +  NotifyItemEnded(FAVORITES);
>> +  ContinueImport();
>> +}
>> +
>> +
>> +// Notebook FE connection managers.
>> +void Toolbar5Importer::GetAuthenticationFromServer() {
>> +  // Authentication is a token string retreived from the authentication 
>> server
>> +  // To access it we call the url below with a random number replacing the
>> +  // value in the string.
>> +  state_ = GET_AUTHORIZATION_TOKEN;
>> +
>> +  // Random number construction.
>> +  int random = base::RandInt(0, std::numeric_limits<int>::max());
>> +  std::string random_string = UintToString(random);
>> +
>> +  // Retrieve authorization token from the network.
>> +  std::string url_string(kT5AuthorizationTokenUrl);
>> +  url_string.replace(url_string.find(kRandomNumberToken),
>> +                     kRandomNumberToken.size(),
>> +                     random_string);
>> +  GURL  url(url_string);
>> +
>> +  token_fetcher_ = new  URLFetcher(url, URLFetcher::GET, this);
>> +  token_fetcher_->set_request_context(Profile::GetDefaultRequestContext());
>> +  token_fetcher_->Start();
>> +}
>> +
>> +void Toolbar5Importer::GetBookmarkDataFromServer(const std::string& 
>> response) {
>> +  state_ = GET_BOOKMARKS;
>> +
>> +  // Parse and verify the authorization token from the response.
>> +  std::string token;
>> +  if (!ParseAuthenticationTokenResponse(response, &token)) {
>> +    EndImportBookmarks(false);
>> +    return;
>> +  }
>> +
>> +  // Build the Toolbar FE connection string, and call the server for
>> +  // the xml blob.  We must tag the connection string with a random number.
>> +  std::string conn_string = kT5FrontEndUrlTemplate;
>> +  int random = base::RandInt(0, std::numeric_limits<int>::max());
>> +  std::string random_string = UintToString(random);
>> +  conn_string.replace(conn_string.find(kRandomNumberToken),
>> +                      kRandomNumberToken.size(),
>> +                      random_string);
>> +  conn_string.replace(conn_string.find(kAuthorizationToken),
>> +                      kAuthorizationToken.size(),
>> +                      token);
>> +  GURL  url(conn_string);
>> +
>> +  data_fetcher_ = new URLFetcher(url, URLFetcher::GET, this);
>> +  data_fetcher_->set_request_context(Profile::GetDefaultRequestContext());
>> +  data_fetcher_->Start();
>> +}
>> +
>> +void Toolbar5Importer::GetBookmarsFromServerDataResponse(
>> +    const std::string& response) {
>> +  bool retval = false;
>> +  XmlReader reader;
>> +  if (reader.Load(response) && !cancelled()) {
>> +    // Construct Bookmarks
>> +    std::vector< ProfileWriter::BookmarkEntry > bookmarks;
>> +    std::vector< history::ImportedFavIconUsage > favicons;
>> +    retval = ParseBookmarksFromReader(&reader, &bookmarks, &favicons);
>> +    if (retval && !cancelled()) {
>> +      AddBookMarksToChrome(bookmarks, favicons);
>> +    }
>> +  }
>> +  EndImportBookmarks(retval);
>> +}
>> +
>> +bool Toolbar5Importer::ParseAuthenticationTokenResponse(
>> +    const std::string& response,
>> +    std::string* token) {
>> +  DCHECK(token);
>> +
>> +  *token = response;
>> +  size_t position = token->find(kAuthorizationTokenPrefix);
>> +  if (0 != position)
>> +    return false;
>> +  token->replace(position, kAuthorizationTokenPrefix.size(), "");
>> +
>> +  position = token->find(kAuthorizationTokenSuffix);
>> +  if (token->size() != (position + kAuthorizationTokenSuffix.size()))
>> +    return false;
>> +  token->replace(position, kAuthorizationTokenSuffix.size(), "");
>> +
>> +  return true;
>> +}
>> +
>> +// Parsing
>> +bool Toolbar5Importer::ParseBookmarksFromReader(
>> +    XmlReader* reader,
>> +    std::vector< ProfileWriter::BookmarkEntry >* bookmarks,
>> +    std::vector< history::ImportedFavIconUsage >* favicons) {
>> +  DCHECK(reader);
>> +  DCHECK(bookmarks);
>> +  DCHECK(favicons);
>> +
>> +  // The XML blob returned from the server is described in the
>> +  // Toolbar-Notebook/Bookmarks Protocol document located at
>> +  // https://docs.google.com/a/google.com/Doc?docid=cgt3m7dr_24djt62m&hl=en
>> +  // We are searching for the section with structure
>> +  // <bookmarks><bookmark>...</bookmark><bookmark>...</bookmark></bookmarks>
>> +
>> +  // Locate the |bookmarks| blob.
>> +  if (!reader->SkipToElement())
>> +    return false;
>> +
>> +  if (!LocateNextTagByName(reader, kBookmarksXmlTag))
>> +    return false;
>> +
>> +  // Parse each |bookmark| blob
>> +  while (LocateNextTagByName(reader, kBookmarkXmlTag)) {
>> +    ProfileWriter::BookmarkEntry bookmark_entry;
>> +    history::ImportedFavIconUsage favicon_entry;
>> +    if (ExtractBookmarkInformation(reader, &bookmark_entry, 
>> &favicon_entry)) {
>> +      bookmarks->push_back(bookmark_entry);
>> +      if (!favicon_entry.favicon_url.is_empty())
>> +        favicons->push_back(favicon_entry);
>> +    }
>> +  }
>> +
>> +  return true;
>> +}
>> +
>> +bool Toolbar5Importer::LocateNextTagByName(XmlReader* reader,
>> +                                           const std::string& tag) {
>> +  // Locate the |tag| blob.
>> +  while (tag != reader->NodeName()) {
>> +    if (!reader->Read())
>> +      return false;
>> +  }
>> +  return true;
>> +}
>> +
>> +bool Toolbar5Importer::ExtractBookmarkInformation(
>> +    XmlReader* reader,
>> +    ProfileWriter::BookmarkEntry* bookmark_entry,
>> +    history::ImportedFavIconUsage* favicon_entry) {
>> +  DCHECK(reader);
>> +  DCHECK(bookmark_entry);
>> +  DCHECK(favicon_entry);
>> +
>> +  // The following is a typical bookmark entry.
>> +  // The reader should be pointing to the <title> tag at the moment.
>> +  //
>> +  // <bookmark>
>> +  // <title>MyTitle</title>
>> +  // <url>http://www.sohu.com/</url>
>> +  // <timestamp>1153328691085181</timestamp>
>> +  // <id>N123nasdf239</id>
>> +  // <notebook_id>Bxxxxxxx</notebook_id> (for bookmarks, a special id is 
>> used)
>> +  // <section_id>Sxxxxxx</section_id>
>> +  // <has_highlight>0</has_highlight>
>> +  // <labels>
>> +  // <label>China</label>
>> +  // <label>^k</label> (if this special label is present, the note is 
>> deleted)
>> +  // </labels>
>> +  // <attributes>
>> +  // <attribute>
>> +  // <name>favicon_url</name>
>> +  // <value>http://www.sohu.com/favicon.ico</value>
>> +  // </attribute>
>> +  // <attribute>
>> +  // <name>favicon_timestamp</name>
>> +  // <value>1153328653</value>
>> +  // </attribute>
>> +  // <attribute>
>> +  // <name>notebook_name</name>
>> +  // <value>My notebook 0</value>
>> +  // </attribute>
>> +  // <attribute>
>> +  // <name>section_name</name>
>> +  // <value>My section 0</value>
>> +  // </attribute>
>> +  // <attribute>
>> +  // </attributes>
>> +  // </bookmark>
>> +  //
>> +  // We parse the blob in order, title->url->timestamp etc.  Any failure
>> +  // causes us to skip this bookmark.  Note Favicons are optional so failure
>> +  // to find them is not a failure to parse the blob.
>> +
>> +  if (!ExtractTitleFromXmlReader(reader, bookmark_entry))
>> +    return false;
>> +  if (!ExtractUrlFromXmlReader(reader, bookmark_entry))
>> +    return false;
>> +  if (!ExtractTimeFromXmlReader(reader, bookmark_entry))
>> +    return false;
>> +  if (!ExtractFolderFromXmlReader(reader, bookmark_entry))
>> +    return false;
>> +  ExtractFaviconFromXmlReader(reader, bookmark_entry, favicon_entry);
>> +
>> +  return true;
>> +}
>> +
>> +bool Toolbar5Importer::ExtractNamedValueFromXmlReader(XmlReader* reader,
>> +                                                      const std::string& 
>> name,
>> +                                                      std::string* buffer) {
>> +  DCHECK(reader);
>> +  DCHECK(buffer);
>> +
>> +  if (name != reader->NodeName())
>> +    return false;
>> +  if (!reader->ReadElementContent(buffer))
>> +    return false;
>> +  return true;
>> +}
>> +
>> +bool Toolbar5Importer::ExtractTitleFromXmlReader(
>> +    XmlReader* reader,
>> +    ProfileWriter::BookmarkEntry* entry) {
>> +  DCHECK(reader);
>> +  DCHECK(entry);
>> +
>> +  if (!LocateNextTagByName(reader, kTitleXmlTag))
>> +    return false;
>> +  std::string buffer;
>> +  if (!ExtractNamedValueFromXmlReader(reader, kTitleXmlTag, &buffer)) {
>> +    return false;
>> +  }
>> +  entry->title = UTF8ToWide(buffer);
>> +  return true;
>> +}
>> +
>> +bool Toolbar5Importer::ExtractUrlFromXmlReader(
>> +    XmlReader* reader,
>> +    ProfileWriter::BookmarkEntry* entry) {
>> +  DCHECK(reader);
>> +  DCHECK(entry);
>> +
>> +  if (!LocateNextTagByName(reader, kUrlXmlTag))
>> +    return false;
>> +  std::string buffer;
>> +  if (!ExtractNamedValueFromXmlReader(reader, kUrlXmlTag, &buffer)) {
>> +    return false;
>> +  }
>> +  entry->url = GURL(buffer);
>> +  return true;
>> +}
>> +
>> +bool Toolbar5Importer::ExtractTimeFromXmlReader(
>> +    XmlReader* reader,
>> +    ProfileWriter::BookmarkEntry* entry) {
>> +  DCHECK(reader);
>> +  DCHECK(entry);
>> +  if (!LocateNextTagByName(reader, kTimestampXmlTag))
>> +    return false;
>> +  std::string buffer;
>> +  if (!ExtractNamedValueFromXmlReader(reader, kTimestampXmlTag, &buffer)) {
>> +    return false;
>> +  }
>> +  int64 timestamp;
>> +  if (!StringToInt64(buffer, &timestamp)) {
>> +    return false;
>> +  }
>> +  entry->creation_time = base::Time::FromTimeT(timestamp);
>> +  return true;
>> +}
>> +
>> +bool Toolbar5Importer::ExtractFolderFromXmlReader(
>> +    XmlReader* reader,
>> +    ProfileWriter::BookmarkEntry* entry) {
>> +  DCHECK(reader);
>> +  DCHECK(entry);
>> +
>> +  if (!LocateNextTagByName(reader, kLabelsXmlTag))
>> +    return false;
>> +  if (!LocateNextTagByName(reader, kLabelXmlTag))
>> +    return false;
>> +
>> +  std::vector<std::wstring> label_vector;
>> +  std::string label_buffer;
>> +  while (kLabelXmlTag == reader->NodeName() &&
>> +         false != reader->ReadElementContent(&label_buffer)) {
>> +    label_vector.push_back(UTF8ToWide(label_buffer));
>> +  }
>> +
>> +  // if this is the first run then we place favorites with no labels
>> +  // in the title bar.  Else they are placed in the "Google Toolbar" folder.
>> +  if (first_run() && 0 == label_vector.size()) {
>> +    entry->in_toolbar = true;
>> +  } else {
>> +    entry->in_toolbar = false;
>> +    entry->path.push_back(l10n_util::GetString(
>> +                                      
>> IDS_BOOKMARK_GROUP_FROM_GOOGLE_TOOLBAR));
>> +  }
>> +
>> +  // If there is only one label and it is in the form "xxx:yyy:zzz" this
>> +  // was created from a Firefox folder.  We undo the label creation and
>> +  // recreate the correct folder.
>> +  if (1 == label_vector.size()) {
>> +    std::vector< std::wstring > folder_names;
>> +    SplitString(label_vector[0], L':', &folder_names);
>> +    entry->path.insert(entry->path.end(),
>> +                       folder_names.begin(), folder_names.end());
>> +  } else if (0 != label_vector.size()) {
>> +    std::wstring folder_name = label_vector[0];
>> +    entry->path.push_back(folder_name);
>> +  }
>> +
>> +  return true;
>> +}
>> +
>> +bool Toolbar5Importer::ExtractFaviconFromXmlReader(
>> +    XmlReader* reader,
>> +    ProfileWriter::BookmarkEntry* bookmark_entry,
>> +    history::ImportedFavIconUsage* favicon_entry) {
>> +  DCHECK(reader);
>> +  DCHECK(bookmark_entry);
>> +  DCHECK(favicon_entry);
>> +
>> +  if (!LocateNextTagByName(reader, kAttributesXmlTag))
>> +    return false;
>> +  if (!LocateNextTagByName(reader, kAttributeXmlTag))
>> +    return false;
>> +  if (!LocateNextTagByName(reader, kNameXmlTag))
>> +    return false;
>> +
>> +  // Attributes are <name>...</name><value>...</value> pairs.  The first
>> +  // attribute should be the favicon name tage, and the value is the url.
>> +  std::string buffer;
>> +  if (!ExtractNamedValueFromXmlReader(reader, kNameXmlTag, &buffer))
>> +    return false;
>> +  if (kFaviconAttributeXmlName != buffer)
>> +    return false;
>> +  if (!ExtractNamedValueFromXmlReader(reader, kValueXmlTag, &buffer))
>> +    return false;
>> +
>> +  // Validate the url
>> +  GURL favicon = GURL(buffer);
>> +  if (!favicon.is_valid())
>> +    return false;
>> +
>> +  favicon_entry->favicon_url = favicon;
>> +  favicon_entry->urls.insert(bookmark_entry->url);
>> +
>> +  return true;
>> +}
>> +
>> +// Bookmark creation
>> +void  Toolbar5Importer::AddBookMarksToChrome(
>> +    const std::vector< ProfileWriter::BookmarkEntry >& bookmarks,
>> +    const std::vector< history::ImportedFavIconUsage >& favicons) {
>> +  if (!bookmarks.empty() && !cancelled()) {
>> +      main_loop_->PostTask(FROM_HERE, NewRunnableMethod(writer_,
>> +          &ProfileWriter::AddBookmarkEntry, bookmarks));
>> +  }
>> +
>> +  if (!favicons.empty()) {
>> +    main_loop_->PostTask(FROM_HERE, NewRunnableMethod(writer_,
>> +        &ProfileWriter::AddFavicons, favicons));
>> +  }
>> +}
>>
>> Added: trunk/src/chrome/browser/importer/toolbar_importer.h
>> ==============================================================================
>> --- (empty file)
>> +++ trunk/src/chrome/browser/importer/toolbar_importer.h        Tue Nov  4 
>> 11:54:49 2008
>> @@ -0,0 +1,164 @@
>> +// Copyright (c) 2006-2008 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_IMPORTER_TOOLBAR_IMPROTER_H__
>> +#define CHROME_BROWSER_IMPORTER_TOOLBAR_IMPROTER_H__
>> +
>> +#include <string>
>> +#include <vector>
>> +
>> +#include "chrome/browser/importer/importer.h"
>> +#include "chrome/browser/url_fetcher.h"
>> +
>> +class XmlReader;
>> +
>> +enum TOOLBAR_VERSION {
>> +  NO_VERSION = -1,
>> +  DEPRECATED,
>> +  VERSION_4,
>> +  VERSION_5
>> +};
>> +
>> +class ToolbarImporterUtils {
>> + public:
>> +
>> +  static bool IsToolbarInstalled();
>> +  static bool IsGoogleGAIACookieInstalled();
>> +  static TOOLBAR_VERSION GetToolbarVersion();
>> +
>> + private:
>> +  static const HKEY kToolbarInstallRegistryRoots[2];
>> +  static const TCHAR* kToolbarRootRegistryFolder;
>> +  static const TCHAR* kToolbarVersionRegistryFolder;
>> +  static const TCHAR* kToolbarVersionRegistryKey;
>> +
>> +  ToolbarImporterUtils() {}
>> +  ~ToolbarImporterUtils() {}
>> +
>> +  DISALLOW_COPY_AND_ASSIGN(ToolbarImporterUtils);
>> +};
>> +
>> +class Toolbar5Importer : public URLFetcher::Delegate,
>> +                         public Importer {
>> + public:
>> +  Toolbar5Importer();
>> +  virtual ~Toolbar5Importer();
>> +
>> +  // Importer view calls this method to being the process.
>> +  virtual void StartImport(ProfileInfo profile_info,
>> +                           uint16 items,
>> +                           ProfileWriter* writer,
>> +                           ImporterHost* host);
>> +
>> +  // URLFetcher::Delegate method
>> +  void OnURLFetchComplete(const URLFetcher* source,
>> +                          const GURL& url,
>> +                          const URLRequestStatus& status,
>> +                          int response_code,
>> +                          const ResponseCookies& cookies,
>> +                          const std::string& data);
>> +
>> + private:
>> +  // Internal state
>> +  enum INTERNAL_STATE {
>> +    NOT_USED = -1,
>> +    INITIALIZED,
>> +    GET_AUTHORIZATION_TOKEN,
>> +    GET_BOOKMARKS,
>> +    DONE
>> +  };
>> +
>> +  // URLs for connecting to the toolbar front end
>> +  static const std::string kT5AuthorizationTokenUrl;
>> +  static const std::string kT5FrontEndUrlTemplate;
>> +  static const std::string kT4FrontEndUrlTemplate;
>> +
>> +  // Token replacement tags
>> +  static const std::string kRandomNumberToken;
>> +  static const std::string kAuthorizationToken;
>> +  static const std::string kAuthorizationTokenPrefix;
>> +  static const std::string kAuthorizationTokenSuffix;
>> +  static const std::string kMaxNumToken;
>> +  static const std::string kMaxTimestampToken;
>> +
>> +  // XML tag names
>> +  static const std::string kXmlApiReplyXmlTag;
>> +  static const std::string kBookmarksXmlTag;
>> +  static const std::string kBookmarkXmlTag;
>> +  static const std::string kTitleXmlTag;
>> +  static const std::string kUrlXmlTag;
>> +  static const std::string kTimestampXmlTag;
>> +  static const std::string kLabelsXmlTag;
>> +  static const std::string kLabelXmlTag;
>> +  static const std::string kAttributesXmlTag;
>> +  static const std::string kAttributeXmlTag;
>> +  static const std::string kNameXmlTag;
>> +  static const std::string kValueXmlTag;
>> +  static const std::string kFaviconAttributeXmlName;
>> +
>> +  // Flow control
>> +  void ContinueImport();
>> +  void EndImport();
>> +  void BeginImportBookmarks();
>> +  void EndImportBookmarks(bool success);
>> +
>> +  // Network I/O
>> +  void GetAuthenticationFromServer();
>> +  void GetBookmarkDataFromServer(const std::string& response);
>> +  void GetBookmarsFromServerDataResponse(const std::string& response);
>> +
>> +  // XML Parsing
>> +  bool ParseAuthenticationTokenResponse(const std::string& response,
>> +                                        std::string* token);
>> +  void ConstructFEConnectionString(const std::string& token,
>> +                                   std::string* conn_string);
>> +
>> +  bool ParseBookmarksFromReader(
>> +      XmlReader* reader,
>> +      std::vector< ProfileWriter::BookmarkEntry >* bookmarks,
>> +      std::vector< history::ImportedFavIconUsage >* favicons);
>> +
>> +  bool LocateNextTagByName(XmlReader* reader, const std::string& tag);
>> +
>> +  bool ExtractBookmarkInformation(XmlReader* reader,
>> +                                  ProfileWriter::BookmarkEntry* 
>> bookmark_entry,
>> +                                  history::ImportedFavIconUsage* 
>> favicon_entry);
>> +  bool ExtractNamedValueFromXmlReader(XmlReader* reader,
>> +                                      const std::string& name,
>> +                                      std::string* buffer);
>> +  bool ExtractTitleFromXmlReader(XmlReader* reader,
>> +                                 ProfileWriter::BookmarkEntry* entry);
>> +  bool ExtractUrlFromXmlReader(XmlReader* reader,
>> +                               ProfileWriter::BookmarkEntry* entry);
>> +  bool ExtractTimeFromXmlReader(XmlReader* reader,
>> +                                ProfileWriter::BookmarkEntry* entry);
>> +  bool ExtractFolderFromXmlReader(XmlReader* reader,
>> +                                  ProfileWriter::BookmarkEntry* entry);
>> +  bool ExtractFaviconFromXmlReader(
>> +      XmlReader* reader,
>> +      ProfileWriter::BookmarkEntry* bookmark_entry,
>> +      history::ImportedFavIconUsage* favicon_entry);
>> +
>> +  // Bookmark creation
>> +  void AddBookMarksToChrome(
>> +    const std::vector< ProfileWriter::BookmarkEntry >& bookmarks,
>> +    const std::vector< history::ImportedFavIconUsage >& favicons);
>> +
>> +  // Hosts the writer used in this importer.
>> +  ProfileWriter* writer_;
>> +
>> +  // Internal state
>> +  INTERNAL_STATE state_;
>> +
>> +  // Bitmask of Importer::ImportItem
>> +  uint16  items_to_import_;
>> +
>> +  // The fetchers need to be available to cancel the network call on user 
>> cancel
>> +  URLFetcher * token_fetcher_;
>> +  URLFetcher * data_fetcher_;
>> +
>> +  DISALLOW_COPY_AND_ASSIGN(Toolbar5Importer);
>> +};
>> +
>> +#endif  // CHROME_BROWSER_IMPORTER_TOOLBAR_IMPROTER_H__
>>
>> Modified: trunk/src/chrome/browser/views/importer_view.cc
>> ==============================================================================
>> --- trunk/src/chrome/browser/views/importer_view.cc     (original)
>> +++ trunk/src/chrome/browser/views/importer_view.cc     Tue Nov  4 11:54:49 
>> 2008
>> @@ -41,6 +41,7 @@
>>       new views::Label(l10n_util::GetString(IDS_IMPORT_FROM_LABEL));
>>
>>   profile_combobox_ = new views::ComboBox(this);
>> +  profile_combobox_->SetListener(this);
>>
>>   import_items_label_ =
>>       new views::Label(l10n_util::GetString(IDS_IMPORT_ITEMS_LABEL));
>> @@ -120,16 +121,7 @@
>>     return false;
>>   }
>>
>> -  uint16 items = NONE;
>> -  if (history_checkbox_->IsEnabled() && history_checkbox_->IsSelected())
>> -    items |= HISTORY;
>> -  if (favorites_checkbox_->IsEnabled() && favorites_checkbox_->IsSelected())
>> -    items |= FAVORITES;
>> -  if (passwords_checkbox_->IsEnabled() && passwords_checkbox_->IsSelected())
>> -    items |= PASSWORDS;
>> -  if (search_engines_checkbox_->IsEnabled() &&
>> -      search_engines_checkbox_->IsSelected())
>> -    items |= SEARCH_ENGINES;
>> +  uint16 items = GetCheckedItems();
>>
>>   Browser* browser = BrowserList::GetLastActive();
>>   int selected_index = profile_combobox_->GetSelectedItem();
>> @@ -149,7 +141,10 @@
>>  int ImporterView::GetItemCount(views::ComboBox* source) {
>>   DCHECK(source == profile_combobox_);
>>   DCHECK(importer_host_.get());
>> -  return importer_host_->GetAvailableProfileCount();
>> +  int item_count = importer_host_->GetAvailableProfileCount();
>> +  if (checkbox_items_.size() < static_cast<size_t>(item_count))
>> +    checkbox_items_.resize(item_count, ALL);
>> +  return item_count;
>>  }
>>
>>  std::wstring ImporterView::GetItemAt(views::ComboBox* source, int index) {
>> @@ -158,6 +153,29 @@
>>   return importer_host_->GetSourceProfileNameAt(index);
>>  }
>>
>> +void ImporterView::ItemChanged(views::ComboBox* combo_box,
>> +                               int prev_index, int new_index) {
>> +  DCHECK(combo_box);
>> +  DCHECK(checkbox_items_.size() >=
>> +      static_cast<size_t>(importer_host_->GetAvailableProfileCount()));
>> +
>> +  if (prev_index == new_index)
>> +    return;
>> +
>> +  // Save the current state
>> +  uint16 prev_items = GetCheckedItems();
>> +  checkbox_items_[prev_index] = prev_items;
>> +
>> +  // Enable/Disable the checkboxes for this Item
>> +  uint16 new_enabled_items = importer_host_->GetSourceProfileInfoAt(
>> +      new_index).services_supported;
>> +  SetCheckedItemsState(new_enabled_items);
>> +
>> +  // Set the checked items for this Item
>> +  uint16 new_items = checkbox_items_[new_index];
>> +  SetCheckedItems(new_items);
>> +}
>> +
>>  void ImporterView::ImportCanceled() {
>>   ImportComplete();
>>  }
>> @@ -174,3 +192,77 @@
>>   return checkbox;
>>  }
>>
>> +uint16 ImporterView::GetCheckedItems() {
>> +  uint16 items = NONE;
>> +  if (history_checkbox_->IsEnabled() && history_checkbox_->IsSelected())
>> +    items |= HISTORY;
>> +  if (favorites_checkbox_->IsEnabled() && favorites_checkbox_->IsSelected())
>> +    items |= FAVORITES;
>> +  if (passwords_checkbox_->IsEnabled() && passwords_checkbox_->IsSelected())
>> +    items |= PASSWORDS;
>> +  if (search_engines_checkbox_->IsEnabled() &&
>> +      search_engines_checkbox_->IsSelected())
>> +    items |= SEARCH_ENGINES;
>> +  return items;
>> +}
>> +
>> +void ImporterView::SetCheckedItemsState(uint16 items) {
>> +  if (items & HISTORY) {
>> +    history_checkbox_->SetEnabled(true);
>> +  } else {
>> +    history_checkbox_->SetEnabled(false);
>> +    history_checkbox_->SetIsSelected(false);
>> +  }
>> +  if (items & FAVORITES) {
>> +    favorites_checkbox_->SetEnabled(true);
>> +  } else {
>> +    favorites_checkbox_->SetEnabled(false);
>> +    favorites_checkbox_->SetIsSelected(false);
>> +  }
>> +  if (items & PASSWORDS) {
>> +    passwords_checkbox_->SetEnabled(true);
>> +  } else {
>> +    passwords_checkbox_->SetEnabled(false);
>> +    passwords_checkbox_->SetIsSelected(false);
>> +  }
>> +  if (items & SEARCH_ENGINES) {
>> +    search_engines_checkbox_->SetEnabled(true);
>> +  } else {
>> +    search_engines_checkbox_->SetEnabled(false);
>> +    search_engines_checkbox_->SetIsSelected(false);
>> +  }
>> +}
>> +
>> +void ImporterView::SetCheckedItems(uint16 items) {
>> +  if (history_checkbox_->IsEnabled()) {
>> +    if (items & HISTORY) {
>> +      history_checkbox_->SetIsSelected(true);
>> +    } else {
>> +      history_checkbox_->SetIsSelected(false);
>> +    }
>> +  }
>> +
>> +  if (favorites_checkbox_->IsEnabled()) {
>> +    if (items & FAVORITES) {
>> +      favorites_checkbox_->SetIsSelected(true);
>> +    } else {
>> +      favorites_checkbox_->SetIsSelected(false);
>> +    }
>> +  }
>> +
>> +  if (passwords_checkbox_->IsEnabled()) {
>> +    if (items & PASSWORDS) {
>> +      passwords_checkbox_->SetIsSelected(true);
>> +    } else {
>> +      passwords_checkbox_->SetIsSelected(false);
>> +    }
>> +  }
>> +
>> +  if (search_engines_checkbox_->IsEnabled()) {
>> +    if (items & SEARCH_ENGINES) {
>> +      search_engines_checkbox_->SetIsSelected(true);
>> +    } else {
>> +      search_engines_checkbox_->SetIsSelected(false);
>> +    }
>> +  }
>> +}
>>
>> Modified: trunk/src/chrome/browser/views/importer_view.h
>> ==============================================================================
>> --- trunk/src/chrome/browser/views/importer_view.h      (original)
>> +++ trunk/src/chrome/browser/views/importer_view.h      Tue Nov  4 11:54:49 
>> 2008
>> @@ -26,6 +26,7 @@
>>  class ImporterView : public views::View,
>>                      public views::DialogDelegate,
>>                      public views::ComboBox::Model,
>> +                     public views::ComboBox::Listener,
>>                      public ImportObserver {
>>  public:
>>   explicit ImporterView(Profile* profile);
>> @@ -46,6 +47,11 @@
>>   virtual int GetItemCount(views::ComboBox* source);
>>   virtual std::wstring GetItemAt(views::ComboBox* source, int index);
>>
>> +  // Overridden from ChromeViews::ComboBox::Listener
>> +  virtual void ItemChanged(views::ComboBox* combo_box,
>> +                           int prev_index,
>> +                           int new_index);
>> +
>>   // Overridden from ImportObserver:
>>   virtual void ImportCanceled();
>>   virtual void ImportComplete();
>> @@ -57,6 +63,15 @@
>>   // Creates and initializes a new check-box.
>>   views::CheckBox* InitCheckbox(const std::wstring& text, bool checked);
>>
>> +  // Create a bitmap from the checkboxes of the view.
>> +  uint16 GetCheckedItems();
>> +
>> +  // Enables/Disables all the checked items for the given state
>> +  void SetCheckedItemsState(uint16 items);
>> +
>> +  // Sets all checked items in the given state
>> +  void SetCheckedItems(uint16 items);
>> +
>>   views::Label* import_from_label_;
>>   views::ComboBox* profile_combobox_;
>>   views::Label* import_items_label_;
>> @@ -67,6 +82,10 @@
>>
>>   scoped_refptr<ImporterHost> importer_host_;
>>
>> +  // Stores the state of the checked items associated with the position of 
>> the
>> +  // selected item in the combo-box.
>> +  std::vector<uint16> checkbox_items_;
>> +
>>   Profile* profile_;
>>
>>   DISALLOW_EVIL_CONSTRUCTORS(ImporterView);
>>
>> >
>>
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
Chromium Developers mailing list: [email protected] 
View archives, change email options, or unsubscribe: 
    http://groups.google.com/group/chromium-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to