Home | History | Annotate | Download | only in importer
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/ui/views/importer/import_progress_dialog_view.h"
      6 
      7 #include "base/utf_string_conversions.h"
      8 #include "chrome/browser/importer/importer_host.h"
      9 #include "chrome/browser/importer/importer_observer.h"
     10 #include "chrome/browser/importer/importer_progress_dialog.h"
     11 #include "grit/chromium_strings.h"
     12 #include "grit/generated_resources.h"
     13 #include "grit/locale_settings.h"
     14 #include "ui/base/l10n/l10n_util.h"
     15 #include "views/controls/label.h"
     16 #include "views/controls/throbber.h"
     17 #include "views/layout/grid_layout.h"
     18 #include "views/layout/layout_constants.h"
     19 #include "views/window/window.h"
     20 
     21 ImportProgressDialogView::ImportProgressDialogView(
     22     HWND parent_window,
     23     uint16 items,
     24     ImporterHost* importer_host,
     25     ImporterObserver* importer_observer,
     26     const string16& importer_name,
     27     bool bookmarks_import)
     28     : state_bookmarks_(new views::CheckmarkThrobber),
     29       state_searches_(new views::CheckmarkThrobber),
     30       state_passwords_(new views::CheckmarkThrobber),
     31       state_history_(new views::CheckmarkThrobber),
     32       state_cookies_(new views::CheckmarkThrobber),
     33       label_bookmarks_(new views::Label(UTF16ToWide(
     34           l10n_util::GetStringUTF16(IDS_IMPORT_PROGRESS_STATUS_BOOKMARKS)))),
     35       label_searches_(new views::Label(UTF16ToWide(
     36           l10n_util::GetStringUTF16(IDS_IMPORT_PROGRESS_STATUS_SEARCH)))),
     37       label_passwords_(new views::Label(UTF16ToWide(
     38           l10n_util::GetStringUTF16(IDS_IMPORT_PROGRESS_STATUS_PASSWORDS)))),
     39       label_history_(new views::Label(UTF16ToWide(
     40           l10n_util::GetStringUTF16(IDS_IMPORT_PROGRESS_STATUS_HISTORY)))),
     41       label_cookies_(new views::Label(UTF16ToWide(
     42           l10n_util::GetStringUTF16(IDS_IMPORT_PROGRESS_STATUS_COOKIES)))),
     43       parent_window_(parent_window),
     44       items_(items),
     45       importer_host_(importer_host),
     46       importer_observer_(importer_observer),
     47       importing_(true),
     48       bookmarks_import_(bookmarks_import) {
     49   std::wstring info_text = bookmarks_import ?
     50       UTF16ToWide(l10n_util::GetStringUTF16(IDS_IMPORT_BOOKMARKS)) :
     51       UTF16ToWide(l10n_util::GetStringFUTF16(
     52           IDS_IMPORT_PROGRESS_INFO, importer_name));
     53   label_info_ = new views::Label(info_text);
     54   importer_host_->SetObserver(this);
     55   label_info_->SetMultiLine(true);
     56   label_info_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
     57   label_bookmarks_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
     58   label_searches_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
     59   label_passwords_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
     60   label_history_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
     61   label_cookies_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
     62 
     63   // These are scoped pointers, so we don't need the parent to delete them.
     64   state_bookmarks_->set_parent_owned(false);
     65   state_searches_->set_parent_owned(false);
     66   state_passwords_->set_parent_owned(false);
     67   state_history_->set_parent_owned(false);
     68   state_cookies_->set_parent_owned(false);
     69   label_bookmarks_->set_parent_owned(false);
     70   label_searches_->set_parent_owned(false);
     71   label_passwords_->set_parent_owned(false);
     72   label_history_->set_parent_owned(false);
     73   label_cookies_->set_parent_owned(false);
     74 }
     75 
     76 ImportProgressDialogView::~ImportProgressDialogView() {
     77   RemoveChildView(state_bookmarks_.get());
     78   RemoveChildView(state_searches_.get());
     79   RemoveChildView(state_passwords_.get());
     80   RemoveChildView(state_history_.get());
     81   RemoveChildView(state_cookies_.get());
     82   RemoveChildView(label_bookmarks_.get());
     83   RemoveChildView(label_searches_.get());
     84   RemoveChildView(label_passwords_.get());
     85   RemoveChildView(label_history_.get());
     86   RemoveChildView(label_cookies_.get());
     87 
     88   if (importing_) {
     89     // We're being deleted while importing, clean up state so that the importer
     90     // doesn't have a reference to us and cancel the import. We can get here
     91     // if our parent window is closed, which closes our window and deletes us.
     92     importing_ = false;
     93     importer_host_->SetObserver(NULL);
     94     importer_host_->Cancel();
     95     if (importer_observer_)
     96       importer_observer_->ImportCompleted();
     97   }
     98 }
     99 
    100 gfx::Size ImportProgressDialogView::GetPreferredSize() {
    101   return gfx::Size(views::Window::GetLocalizedContentsSize(
    102       IDS_IMPORTPROGRESS_DIALOG_WIDTH_CHARS,
    103       IDS_IMPORTPROGRESS_DIALOG_HEIGHT_LINES));
    104 }
    105 
    106 void ImportProgressDialogView::ViewHierarchyChanged(bool is_add,
    107                                                     views::View* parent,
    108                                                     views::View* child) {
    109   if (is_add && child == this)
    110     InitControlLayout();
    111 }
    112 
    113 int ImportProgressDialogView::GetDialogButtons() const {
    114   return MessageBoxFlags::DIALOGBUTTON_CANCEL;
    115 }
    116 
    117 std::wstring ImportProgressDialogView::GetDialogButtonLabel(
    118     MessageBoxFlags::DialogButton button) const {
    119   DCHECK(button == MessageBoxFlags::DIALOGBUTTON_CANCEL);
    120   return UTF16ToWide(
    121       l10n_util::GetStringUTF16(IDS_IMPORT_PROGRESS_STATUS_CANCEL));
    122 }
    123 
    124 bool ImportProgressDialogView::IsModal() const {
    125   return parent_window_ != NULL;
    126 }
    127 
    128 std::wstring ImportProgressDialogView::GetWindowTitle() const {
    129   return UTF16ToWide(l10n_util::GetStringUTF16(IDS_IMPORT_PROGRESS_TITLE));
    130 }
    131 
    132 bool ImportProgressDialogView::Cancel() {
    133   // When the user cancels the import, we need to tell the importer_host to stop
    134   // importing and return false so that the window lives long enough to receive
    135   // ImportEnded, which will close the window. Closing the window results in
    136   // another call to this function and at that point we must return true to
    137   // allow the window to close.
    138   if (!importing_)
    139     return true;  // We have received ImportEnded, so we can close.
    140 
    141   // Cancel the import and wait for further instructions.
    142   importer_host_->Cancel();
    143   return false;
    144 }
    145 
    146 views::View* ImportProgressDialogView::GetContentsView() {
    147   return this;
    148 }
    149 
    150 void ImportProgressDialogView::InitControlLayout() {
    151   using views::GridLayout;
    152   using views::ColumnSet;
    153 
    154   GridLayout* layout = GridLayout::CreatePanel(this);
    155   SetLayoutManager(layout);
    156 
    157   gfx::Size ps = state_history_->GetPreferredSize();
    158 
    159   const int single_column_view_set_id = 0;
    160   ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id);
    161   if (bookmarks_import_) {
    162     column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
    163                           GridLayout::FIXED, ps.width(), 0);
    164     column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
    165   }
    166   column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
    167                         GridLayout::USE_PREF, 0, 0);
    168   const int double_column_view_set_id = 1;
    169   column_set = layout->AddColumnSet(double_column_view_set_id);
    170   column_set->AddPaddingColumn(
    171       0, views::kUnrelatedControlLargeHorizontalSpacing);
    172   column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
    173                         GridLayout::FIXED, ps.width(), 0);
    174   column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
    175   column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
    176                         GridLayout::USE_PREF, 0, 0);
    177   column_set->AddPaddingColumn(
    178       0, views::kUnrelatedControlLargeHorizontalSpacing);
    179 
    180   layout->StartRow(0, single_column_view_set_id);
    181   if (bookmarks_import_)
    182     layout->AddView(state_bookmarks_.get());
    183   layout->AddView(label_info_);
    184   layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
    185 
    186   if (items_ & importer::HISTORY) {
    187     layout->StartRow(0, double_column_view_set_id);
    188     layout->AddView(state_history_.get());
    189     layout->AddView(label_history_.get());
    190     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    191   }
    192   if (items_ & importer::FAVORITES && !bookmarks_import_) {
    193     layout->StartRow(0, double_column_view_set_id);
    194     layout->AddView(state_bookmarks_.get());
    195     layout->AddView(label_bookmarks_.get());
    196     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    197   }
    198   if (items_ & importer::SEARCH_ENGINES) {
    199     layout->StartRow(0, double_column_view_set_id);
    200     layout->AddView(state_searches_.get());
    201     layout->AddView(label_searches_.get());
    202     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    203   }
    204   if (items_ & importer::PASSWORDS) {
    205     layout->StartRow(0, double_column_view_set_id);
    206     layout->AddView(state_passwords_.get());
    207     layout->AddView(label_passwords_.get());
    208     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    209   }
    210   if (items_ & importer::COOKIES) {
    211     layout->StartRow(0, double_column_view_set_id);
    212     layout->AddView(state_cookies_.get());
    213     layout->AddView(label_cookies_.get());
    214     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    215   }
    216 }
    217 
    218 void ImportProgressDialogView::ImportStarted() {
    219   importing_ = true;
    220 }
    221 
    222 void ImportProgressDialogView::ImportItemStarted(importer::ImportItem item) {
    223   DCHECK(items_ & item);
    224   switch (item) {
    225     case importer::FAVORITES:
    226       state_bookmarks_->Start();
    227       break;
    228     case importer::SEARCH_ENGINES:
    229       state_searches_->Start();
    230       break;
    231     case importer::PASSWORDS:
    232       state_passwords_->Start();
    233       break;
    234     case importer::HISTORY:
    235       state_history_->Start();
    236       break;
    237     case importer::COOKIES:
    238       state_cookies_->Start();
    239       break;
    240   }
    241 }
    242 
    243 void ImportProgressDialogView::ImportItemEnded(importer::ImportItem item) {
    244   DCHECK(items_ & item);
    245   switch (item) {
    246     case importer::FAVORITES:
    247       state_bookmarks_->Stop();
    248       state_bookmarks_->SetChecked(true);
    249       break;
    250     case importer::SEARCH_ENGINES:
    251       state_searches_->Stop();
    252       state_searches_->SetChecked(true);
    253       break;
    254     case importer::PASSWORDS:
    255       state_passwords_->Stop();
    256       state_passwords_->SetChecked(true);
    257       break;
    258     case importer::HISTORY:
    259       state_history_->Stop();
    260       state_history_->SetChecked(true);
    261       break;
    262     case importer::COOKIES:
    263       state_cookies_->Stop();
    264       state_cookies_->SetChecked(true);
    265       break;
    266   }
    267 }
    268 
    269 void ImportProgressDialogView::ImportEnded() {
    270   // This can happen because:
    271   // - the import completed successfully.
    272   // - the import was canceled by the user.
    273   // - the user chose to skip the import because they didn't want to shut down
    274   //   Firefox.
    275   // In every case, we need to close the UI now.
    276   importing_ = false;
    277   importer_host_->SetObserver(NULL);
    278   window()->CloseWindow();
    279   if (importer_observer_)
    280     importer_observer_->ImportCompleted();
    281 }
    282 
    283 namespace importer {
    284 
    285 void ShowImportProgressDialog(HWND parent_window,
    286                               uint16 items,
    287                               ImporterHost* importer_host,
    288                               ImporterObserver* importer_observer,
    289                               const SourceProfile& source_profile,
    290                               Profile* target_profile,
    291                               bool first_run) {
    292   DCHECK(items != 0);
    293   ImportProgressDialogView* progress_view = new ImportProgressDialogView(
    294       parent_window,
    295       items,
    296       importer_host,
    297       importer_observer,
    298       source_profile.importer_name,
    299       source_profile.importer_type == importer::BOOKMARKS_HTML);
    300 
    301   views::Window* window = views::Window::CreateChromeWindow(
    302       parent_window, gfx::Rect(), progress_view);
    303 
    304   if (!importer_host->is_headless() && !first_run)
    305     window->Show();
    306 
    307   importer_host->StartImportSettings(
    308       source_profile, target_profile, items, new ProfileWriter(target_profile),
    309       first_run);
    310 }
    311 
    312 }  // namespace importer
    313