blob: 70e71f00affdd908c574f96213415a41e634f1ea [file] [log] [blame]
// Copyright (c) 2010 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/views/importing_progress_view.h"
#include "app/l10n_util.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/locale_settings.h"
#include "views/grid_layout.h"
#include "views/controls/label.h"
#include "views/controls/throbber.h"
#include "views/standard_layout.h"
#include "views/window/window.h"
////////////////////////////////////////////////////////////////////////////////
// ImportingProgressView, public:
ImportingProgressView::ImportingProgressView(const std::wstring& source_name,
int16 items,
ImporterHost* coordinator,
ImportObserver* observer,
HWND parent_window,
bool bookmarks_import)
: state_bookmarks_(new views::CheckmarkThrobber),
state_searches_(new views::CheckmarkThrobber),
state_passwords_(new views::CheckmarkThrobber),
state_history_(new views::CheckmarkThrobber),
state_cookies_(new views::CheckmarkThrobber),
label_bookmarks_(new views::Label(
l10n_util::GetString(IDS_IMPORT_PROGRESS_STATUS_BOOKMARKS))),
label_searches_(new views::Label(
l10n_util::GetString(IDS_IMPORT_PROGRESS_STATUS_SEARCH))),
label_passwords_(new views::Label(
l10n_util::GetString(IDS_IMPORT_PROGRESS_STATUS_PASSWORDS))),
label_history_(new views::Label(
l10n_util::GetString(IDS_IMPORT_PROGRESS_STATUS_HISTORY))),
label_cookies_(new views::Label(
l10n_util::GetString(IDS_IMPORT_PROGRESS_STATUS_COOKIES))),
parent_window_(parent_window),
coordinator_(coordinator),
import_observer_(observer),
items_(items),
importing_(true),
bookmarks_import_(bookmarks_import) {
std::wstring info_text = bookmarks_import ?
l10n_util::GetString(IDS_IMPORT_BOOKMARKS) :
l10n_util::GetStringF(IDS_IMPORT_PROGRESS_INFO, source_name);
label_info_ = new views::Label(info_text);
coordinator_->SetObserver(this);
label_info_->SetMultiLine(true);
label_info_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
label_bookmarks_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
label_searches_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
label_passwords_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
label_history_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
label_cookies_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
// These are scoped pointers, so we don't need the parent to delete them.
state_bookmarks_->set_parent_owned(false);
state_searches_->set_parent_owned(false);
state_passwords_->set_parent_owned(false);
state_history_->set_parent_owned(false);
state_cookies_->set_parent_owned(false);
label_bookmarks_->set_parent_owned(false);
label_searches_->set_parent_owned(false);
label_passwords_->set_parent_owned(false);
label_history_->set_parent_owned(false);
label_cookies_->set_parent_owned(false);
}
ImportingProgressView::~ImportingProgressView() {
RemoveChildView(state_bookmarks_.get());
RemoveChildView(state_searches_.get());
RemoveChildView(state_passwords_.get());
RemoveChildView(state_history_.get());
RemoveChildView(state_cookies_.get());
RemoveChildView(label_bookmarks_.get());
RemoveChildView(label_searches_.get());
RemoveChildView(label_passwords_.get());
RemoveChildView(label_history_.get());
RemoveChildView(label_cookies_.get());
if (importing_) {
// We're being deleted while importing, clean up state so that the importer
// doesn't have a reference to us and cancel the import. We can get here
// if our parent window is closed, which closes our window and deletes us.
importing_ = false;
coordinator_->SetObserver(NULL);
coordinator_->Cancel();
if (import_observer_)
import_observer_->ImportComplete();
}
}
////////////////////////////////////////////////////////////////////////////////
// ImportingProgressView, ImporterObserver implementation:
void ImportingProgressView::ImportItemStarted(importer::ImportItem item) {
DCHECK(items_ & item);
switch (item) {
case importer::FAVORITES:
state_bookmarks_->Start();
break;
case importer::SEARCH_ENGINES:
state_searches_->Start();
break;
case importer::PASSWORDS:
state_passwords_->Start();
break;
case importer::HISTORY:
state_history_->Start();
break;
case importer::COOKIES:
state_cookies_->Start();
break;
}
}
void ImportingProgressView::ImportItemEnded(importer::ImportItem item) {
DCHECK(items_ & item);
switch (item) {
case importer::FAVORITES:
state_bookmarks_->Stop();
state_bookmarks_->SetChecked(true);
break;
case importer::SEARCH_ENGINES:
state_searches_->Stop();
state_searches_->SetChecked(true);
break;
case importer::PASSWORDS:
state_passwords_->Stop();
state_passwords_->SetChecked(true);
break;
case importer::HISTORY:
state_history_->Stop();
state_history_->SetChecked(true);
break;
case importer::COOKIES:
state_cookies_->Stop();
state_cookies_->SetChecked(true);
break;
}
}
void ImportingProgressView::ImportStarted() {
importing_ = true;
}
void ImportingProgressView::ImportEnded() {
// This can happen because:
// - the import completed successfully.
// - the import was canceled by the user.
// - the user chose to skip the import because they didn't want to shut down
// Firefox.
// In every case, we need to close the UI now.
importing_ = false;
coordinator_->SetObserver(NULL);
window()->Close();
if (import_observer_)
import_observer_->ImportComplete();
}
////////////////////////////////////////////////////////////////////////////////
// ImportingProgressView, views::View overrides:
gfx::Size ImportingProgressView::GetPreferredSize() {
return gfx::Size(views::Window::GetLocalizedContentsSize(
IDS_IMPORTPROGRESS_DIALOG_WIDTH_CHARS,
IDS_IMPORTPROGRESS_DIALOG_HEIGHT_LINES));
}
void ImportingProgressView::ViewHierarchyChanged(bool is_add,
views::View* parent,
views::View* child) {
if (is_add && child == this)
InitControlLayout();
}
////////////////////////////////////////////////////////////////////////////////
// ImportingProgressView, views::DialogDelegate implementation:
int ImportingProgressView::GetDialogButtons() const {
return MessageBoxFlags::DIALOGBUTTON_CANCEL;
}
std::wstring ImportingProgressView::GetDialogButtonLabel(
MessageBoxFlags::DialogButton button) const {
DCHECK(button == MessageBoxFlags::DIALOGBUTTON_CANCEL);
return l10n_util::GetString(IDS_IMPORT_PROGRESS_STATUS_CANCEL);
}
bool ImportingProgressView::IsModal() const {
return parent_window_ != NULL;
}
std::wstring ImportingProgressView::GetWindowTitle() const {
return l10n_util::GetString(IDS_IMPORT_PROGRESS_TITLE);
}
bool ImportingProgressView::Cancel() {
// When the user cancels the import, we need to tell the coordinator to stop
// importing and return false so that the window lives long enough to receive
// ImportEnded, which will close the window. Closing the window results in
// another call to this function and at that point we must return true to
// allow the window to close.
if (!importing_)
return true; // We have received ImportEnded, so we can close.
// Cancel the import and wait for further instructions.
coordinator_->Cancel();
return false;
}
views::View* ImportingProgressView::GetContentsView() {
return this;
}
////////////////////////////////////////////////////////////////////////////////
// ImportingProgressView, private:
void ImportingProgressView::InitControlLayout() {
using views::GridLayout;
using views::ColumnSet;
GridLayout* layout = CreatePanelGridLayout(this);
SetLayoutManager(layout);
gfx::Size ps = state_history_->GetPreferredSize();
const int single_column_view_set_id = 0;
ColumnSet* column_set = layout->AddColumnSet(single_column_view_set_id);
if (bookmarks_import_) {
column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
GridLayout::FIXED, ps.width(), 0);
column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
}
column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
GridLayout::USE_PREF, 0, 0);
const int double_column_view_set_id = 1;
column_set = layout->AddColumnSet(double_column_view_set_id);
column_set->AddPaddingColumn(0, kUnrelatedControlLargeHorizontalSpacing);
column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 0,
GridLayout::FIXED, ps.width(), 0);
column_set->AddPaddingColumn(0, kRelatedControlHorizontalSpacing);
column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
GridLayout::USE_PREF, 0, 0);
column_set->AddPaddingColumn(0, kUnrelatedControlLargeHorizontalSpacing);
layout->StartRow(0, single_column_view_set_id);
if (bookmarks_import_)
layout->AddView(state_bookmarks_.get());
layout->AddView(label_info_);
layout->AddPaddingRow(0, kUnrelatedControlVerticalSpacing);
if (items_ & importer::HISTORY) {
layout->StartRow(0, double_column_view_set_id);
layout->AddView(state_history_.get());
layout->AddView(label_history_.get());
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
}
if (items_ & importer::FAVORITES && !bookmarks_import_) {
layout->StartRow(0, double_column_view_set_id);
layout->AddView(state_bookmarks_.get());
layout->AddView(label_bookmarks_.get());
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
}
if (items_ & importer::SEARCH_ENGINES) {
layout->StartRow(0, double_column_view_set_id);
layout->AddView(state_searches_.get());
layout->AddView(label_searches_.get());
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
}
if (items_ & importer::PASSWORDS) {
layout->StartRow(0, double_column_view_set_id);
layout->AddView(state_passwords_.get());
layout->AddView(label_passwords_.get());
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
}
if (items_ & importer::COOKIES) {
layout->StartRow(0, double_column_view_set_id);
layout->AddView(state_cookies_.get());
layout->AddView(label_cookies_.get());
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
}
}
////////////////////////////////////////////////////////////////////////////////
// StartImportingWithUI
void StartImportingWithUI(HWND parent_window,
int16 items,
ImporterHost* coordinator,
const ProfileInfo& source_profile,
Profile* target_profile,
ImportObserver* observer,
bool first_run) {
DCHECK(items != 0);
ImportingProgressView* v = new ImportingProgressView(
source_profile.description, items, coordinator, observer, parent_window,
source_profile.browser_type == importer::BOOKMARKS_HTML);
views::Window* window =
views::Window::CreateChromeWindow(parent_window, gfx::Rect(), v);
// In headless mode it means that we don't show the progress window, but it
// still need it to exist. No user interaction will be required.
if (!coordinator->is_headless())
window->Show();
coordinator->StartImportSettings(source_profile, target_profile, items,
new ProfileWriter(target_profile),
first_run);
}