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/gtk/importer/import_progress_dialog_gtk.h"
6
7#include <gtk/gtk.h>
8
9#include <string>
10
11#include "base/utf_string_conversions.h"
12#include "chrome/browser/importer/importer_host.h"
13#include "chrome/browser/importer/importer_observer.h"
14#include "chrome/browser/ui/gtk/gtk_util.h"
15#include "grit/chromium_strings.h"
16#include "grit/generated_resources.h"
17#include "ui/base/l10n/l10n_util.h"
18
19namespace {
20
21void SetItemImportStatus(GtkWidget* label, int res_id, bool is_done) {
22  std::string status = l10n_util::GetStringUTF8(res_id);
23  // Windows version of this has fancy throbbers to indicate progress. Here
24  // we rely on text until we can have something equivalent on Linux.
25  if (is_done)
26    status = "\xE2\x9C\x94 " + status;  // U+2714 HEAVY CHECK MARK
27  else
28    status.append(" ...");
29  gtk_label_set_text(GTK_LABEL(label), status.c_str());
30}
31
32}  // namespace
33
34// static
35void ImportProgressDialogGtk::StartImport(
36    GtkWindow* parent,
37    uint16 items,
38    ImporterHost* importer_host,
39    ImporterObserver* importer_observer,
40    const importer::SourceProfile& source_profile,
41    Profile* profile,
42    bool first_run) {
43  ImportProgressDialogGtk* dialog = new ImportProgressDialogGtk(
44      parent,
45      items,
46      importer_host,
47      importer_observer,
48      source_profile.importer_name,
49      source_profile.importer_type == importer::BOOKMARKS_HTML);
50
51  // In headless mode it means that we don't show the progress window, but it
52  // still need it to exist. No user interaction will be required.
53  if (!importer_host->is_headless())
54    dialog->ShowDialog();
55
56  importer_host->StartImportSettings(
57      source_profile, profile, items, new ProfileWriter(profile), first_run);
58}
59
60ImportProgressDialogGtk::ImportProgressDialogGtk(
61    GtkWindow* parent,
62    uint16 items,
63    ImporterHost* importer_host,
64    ImporterObserver* importer_observer,
65    const string16& importer_name,
66    bool bookmarks_import)
67    : parent_(parent),
68      items_(items),
69      importer_host_(importer_host),
70      importer_observer_(importer_observer),
71      importing_(true) {
72  importer_host_->SetObserver(this);
73
74  // Build the dialog.
75  dialog_ = gtk_dialog_new_with_buttons(
76      l10n_util::GetStringUTF8(IDS_IMPORT_PROGRESS_TITLE).c_str(),
77      parent_,
78      (GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
79      GTK_STOCK_CANCEL,
80      GTK_RESPONSE_REJECT,
81      NULL);
82  importer_host_->set_parent_window(GTK_WINDOW(dialog_));
83
84  GtkWidget* content_area = GTK_DIALOG(dialog_)->vbox;
85  gtk_box_set_spacing(GTK_BOX(content_area), gtk_util::kContentAreaSpacing);
86
87  GtkWidget* control_group = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
88
89  GtkWidget* import_info = gtk_label_new(
90      l10n_util::GetStringFUTF8(IDS_IMPORT_PROGRESS_INFO,
91                                importer_name).c_str());
92  gtk_util::SetLabelWidth(import_info, 400);
93  gtk_box_pack_start(GTK_BOX(control_group), import_info, FALSE, FALSE, 0);
94
95  GtkWidget* item_box = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
96
97  if (items_ & importer::HISTORY) {
98    history_ = gtk_label_new(
99        l10n_util::GetStringUTF8(IDS_IMPORT_PROGRESS_STATUS_HISTORY).c_str());
100    gtk_misc_set_alignment(GTK_MISC(history_), 0, 0.5);
101    gtk_box_pack_start(GTK_BOX(item_box), history_, FALSE, FALSE, 0);
102  }
103
104  if (items_ & importer::FAVORITES) {
105    bookmarks_ = gtk_label_new(
106        l10n_util::GetStringUTF8(IDS_IMPORT_PROGRESS_STATUS_BOOKMARKS).c_str());
107    gtk_misc_set_alignment(GTK_MISC(bookmarks_), 0, 0.5);
108    gtk_box_pack_start(GTK_BOX(item_box), bookmarks_, FALSE, FALSE, 0);
109  }
110
111  if (items_ & importer::SEARCH_ENGINES) {
112    search_engines_ = gtk_label_new(
113        l10n_util::GetStringUTF8(IDS_IMPORT_PROGRESS_STATUS_SEARCH).c_str());
114    gtk_misc_set_alignment(GTK_MISC(search_engines_), 0, 0.5);
115    gtk_box_pack_start(GTK_BOX(item_box), search_engines_, FALSE, FALSE, 0);
116  }
117
118  if (items_ & importer::PASSWORDS) {
119    passwords_ = gtk_label_new(
120        l10n_util::GetStringUTF8(IDS_IMPORT_PROGRESS_STATUS_PASSWORDS).c_str());
121    gtk_misc_set_alignment(GTK_MISC(passwords_), 0, 0.5);
122    gtk_box_pack_start(GTK_BOX(item_box), passwords_, FALSE, FALSE, 0);
123  }
124
125  gtk_box_pack_start(GTK_BOX(control_group), gtk_util::IndentWidget(item_box),
126                     FALSE, FALSE, 0);
127  gtk_box_pack_start(GTK_BOX(content_area), control_group, FALSE, FALSE, 0);
128
129  g_signal_connect(dialog_, "response",
130                   G_CALLBACK(OnResponseThunk), this);
131  gtk_window_set_resizable(GTK_WINDOW(dialog_), FALSE);
132}
133
134ImportProgressDialogGtk::~ImportProgressDialogGtk() {}
135
136void ImportProgressDialogGtk::OnResponse(GtkWidget* dialog, int response_id) {
137  if (!importing_) {
138    CloseDialog();
139    return;
140  }
141
142  // Only response to the dialog is to close it so we hide immediately.
143  gtk_widget_hide_all(dialog_);
144  if (response_id == GTK_RESPONSE_REJECT)
145    importer_host_->Cancel();
146}
147
148void ImportProgressDialogGtk::ShowDialog() {
149  gtk_widget_show_all(dialog_);
150}
151
152void ImportProgressDialogGtk::CloseDialog() {
153  gtk_widget_destroy(dialog_);
154  dialog_ = NULL;
155  delete this;
156}
157
158void ImportProgressDialogGtk::ImportStarted() {
159  importing_ = true;
160}
161
162void ImportProgressDialogGtk::ImportItemStarted(importer::ImportItem item) {
163  DCHECK(items_ & item);
164  switch (item) {
165    case importer::FAVORITES:
166      SetItemImportStatus(bookmarks_,
167                          IDS_IMPORT_PROGRESS_STATUS_BOOKMARKS, false);
168      break;
169    case importer::SEARCH_ENGINES:
170      SetItemImportStatus(search_engines_,
171                          IDS_IMPORT_PROGRESS_STATUS_SEARCH, false);
172      break;
173    case importer::PASSWORDS:
174      SetItemImportStatus(passwords_,
175                          IDS_IMPORT_PROGRESS_STATUS_PASSWORDS, false);
176      break;
177    case importer::HISTORY:
178      SetItemImportStatus(history_,
179                          IDS_IMPORT_PROGRESS_STATUS_HISTORY, false);
180      break;
181    default:
182      break;
183  }
184}
185
186void ImportProgressDialogGtk::ImportItemEnded(importer::ImportItem item) {
187  DCHECK(items_ & item);
188  switch (item) {
189    case importer::FAVORITES:
190      SetItemImportStatus(bookmarks_,
191                          IDS_IMPORT_PROGRESS_STATUS_BOOKMARKS, true);
192      break;
193    case importer::SEARCH_ENGINES:
194      SetItemImportStatus(search_engines_,
195                          IDS_IMPORT_PROGRESS_STATUS_SEARCH, true);
196      break;
197    case importer::PASSWORDS:
198      SetItemImportStatus(passwords_,
199                          IDS_IMPORT_PROGRESS_STATUS_PASSWORDS, true);
200      break;
201    case importer::HISTORY:
202      SetItemImportStatus(history_,
203                          IDS_IMPORT_PROGRESS_STATUS_HISTORY, true);
204      break;
205    default:
206      break;
207  }
208}
209
210void ImportProgressDialogGtk::ImportEnded() {
211  importing_ = false;
212  importer_host_->SetObserver(NULL);
213  if (importer_observer_)
214    importer_observer_->ImportCompleted();
215  CloseDialog();
216}
217
218namespace importer {
219
220void ShowImportProgressDialog(GtkWindow* parent,
221                              uint16 items,
222                              ImporterHost* importer_host,
223                              ImporterObserver* importer_observer,
224                              const SourceProfile& source_profile,
225                              Profile* profile,
226                              bool first_run) {
227  DCHECK_NE(0, items);
228  ImportProgressDialogGtk::StartImport(
229      parent, items, importer_host, importer_observer, source_profile, profile,
230      first_run);
231}
232
233}  // namespace importer
234