1
/* Copyright 2011 Yorba Foundation
3
* This software is licensed under the GNU Lesser General Public License
4
* (version 2.1 or later). See the COPYING file in this distribution.
7
namespace DataImportsUI {
9
public class ConcreteDialogPane : Spit.DataImports.DialogPane, GLib.Object {
10
private Gtk.VBox pane_widget;
12
public ConcreteDialogPane() {
13
pane_widget = new Gtk.VBox(false, 8);
16
public Gtk.Widget get_widget() {
20
public Spit.DataImports.DialogPane.GeometryOptions get_preferred_geometry() {
21
return Spit.DataImports.DialogPane.GeometryOptions.NONE;
24
public void on_pane_installed() {
27
public void on_pane_uninstalled() {
31
public class StaticMessagePane : ConcreteDialogPane {
32
public StaticMessagePane(string message_string) {
33
Gtk.Label message_label = new Gtk.Label(message_string);
34
(get_widget() as Gtk.Container).add(message_label);
37
public StaticMessagePane.with_pango(string msg) {
38
Gtk.Label label = new Gtk.Label(null);
39
label.set_markup(msg);
40
label.set_line_wrap(true);
42
(get_widget() as Gtk.Container).add(label);
46
public class LibrarySelectionPane : ConcreteDialogPane {
47
private weak Spit.DataImports.PluginHost host;
48
private Spit.DataImports.ImportableLibrary? selected_library = null;
49
private File? selected_file = null;
50
private Gtk.Button import_button;
51
private Gtk.RadioButton? file_radio = null;
53
public LibrarySelectionPane(
54
Spit.DataImports.PluginHost host,
55
string welcome_message,
56
Spit.DataImports.ImportableLibrary[] discovered_libraries,
57
string? file_select_label
59
assert(discovered_libraries.length > 0 || on_file_selected != null);
63
Gtk.Box content_box = new Gtk.VBox(false, 8);
64
content_box.set_margin_left(30);
65
content_box.set_margin_right(30);
66
Gtk.Label welcome_label = new Gtk.Label(null);
67
welcome_label.set_markup(welcome_message);
68
welcome_label.set_line_wrap(true);
69
welcome_label.set_halign(Gtk.Align.START);
70
content_box.pack_start(welcome_label, true, true, 6);
72
// margins for buttons
73
int radio_margin_left = 20;
74
int radio_margin_right = 20;
75
int chooser_margin_left = radio_margin_left;
76
int chooser_margin_right = radio_margin_right;
78
Gtk.RadioButton lib_radio = null;
79
if (discovered_libraries.length > 0) {
80
chooser_margin_left = radio_margin_left + 20;
81
foreach (Spit.DataImports.ImportableLibrary library in discovered_libraries) {
82
string lib_radio_label = library.get_display_name();
83
lib_radio = create_radio_button(
84
content_box, lib_radio, library, lib_radio_label,
85
radio_margin_left, radio_margin_right
88
if (file_select_label != null) {
89
lib_radio = create_radio_button(
90
content_box, lib_radio, null, file_select_label,
91
radio_margin_left, radio_margin_right
93
file_radio = lib_radio;
96
if (file_select_label != null) {
97
Gtk.FileChooserButton file_chooser = new Gtk.FileChooserButton(_("Database file:"), Gtk.FileChooserAction.OPEN);
98
file_chooser.selection_changed.connect(() => {
99
selected_file = file_chooser.get_file();
100
if (file_radio != null)
101
file_radio.active = true;
102
set_import_button_sensitivity();
104
file_chooser.set_margin_left(chooser_margin_left);
105
file_chooser.set_margin_right(chooser_margin_right);
106
content_box.pack_start(file_chooser, false, false, 6);
109
import_button = new Gtk.Button.with_mnemonic(_("_Import"));
110
import_button.clicked.connect(() => {
111
if (selected_library != null)
112
on_library_selected(selected_library);
113
else if (selected_file != null)
114
on_file_selected(selected_file);
116
debug("LibrarySelectionPane: Library or file should be selected.");
118
Gtk.ButtonBox button_box = new Gtk.HButtonBox();
119
button_box.layout_style = Gtk.ButtonBoxStyle.CENTER;
120
button_box.add(import_button);
121
content_box.pack_end(button_box, true, false, 6);
123
(get_widget() as Gtk.Container).add(content_box);
125
set_import_button_sensitivity();
128
private Gtk.RadioButton create_radio_button(
129
Gtk.Box box, Gtk.RadioButton? group, Spit.DataImports.ImportableLibrary? library, string label,
130
int margin_left, int margin_right
132
var button = new Gtk.RadioButton.with_label_from_widget (group, label);
133
if (group == null) { // first radio button is active
134
button.active = true;
135
selected_library = library;
137
button.toggled.connect (() => {
139
this.selected_library = library;
140
set_import_button_sensitivity();
144
button.set_margin_left(margin_left);
145
button.set_margin_right(margin_right);
146
box.pack_start(button, false, false, 6);
150
private void set_import_button_sensitivity() {
151
import_button.set_sensitive(selected_library != null || selected_file != null);
154
private void on_library_selected(Spit.DataImports.ImportableLibrary library) {
155
host.get_data_importer().on_library_selected(library);
158
private void on_file_selected(File file) {
159
host.get_data_importer().on_file_selected(file);
163
public class ProgressPane : ConcreteDialogPane {
164
private Gtk.Label message_label;
165
private Gtk.Label progress_label;
166
private Gtk.ProgressBar progress_bar;
168
public ProgressPane(string message) {
169
Gtk.Box content_box = new Gtk.VBox(false, 8);
170
message_label = new Gtk.Label(message);
171
content_box.pack_start(message_label, true, true, 6);
172
progress_bar = new Gtk.ProgressBar();
173
content_box.pack_start(progress_bar, false, true, 6);
174
progress_label = new Gtk.Label("");
175
content_box.pack_start(progress_label, false, true, 6);
177
(get_widget() as Gtk.Container).add(content_box);
180
public void update_progress(double progress, string? progress_message) {
181
progress_bar.set_fraction(progress);
182
if (progress_message != null)
183
progress_label.set_label(progress_message);
188
public class DataImportsDialog : Gtk.Dialog {
189
private const int LARGE_WINDOW_WIDTH = 860;
190
private const int LARGE_WINDOW_HEIGHT = 688;
191
private const int COLOSSAL_WINDOW_WIDTH = 1024;
192
private const int COLOSSAL_WINDOW_HEIGHT = 688;
193
private const int STANDARD_WINDOW_WIDTH = 600;
194
private const int STANDARD_WINDOW_HEIGHT = 510;
195
private const int BORDER_REGION_WIDTH = 16;
196
private const int BORDER_REGION_HEIGHT = 100;
198
public const int STANDARD_CONTENT_LABEL_WIDTH = 500;
199
public const int STANDARD_ACTION_BUTTON_WIDTH = 128;
201
private Gtk.ComboBoxText service_selector_box;
202
private Gtk.Label service_selector_box_label;
203
private Gtk.VBox central_area_layouter;
204
private Gtk.Button close_cancel_button;
205
private Spit.DataImports.DialogPane active_pane;
206
private Spit.DataImports.ConcreteDataImportsHost host;
208
protected DataImportsDialog() {
211
delete_event.connect(on_window_close);
213
string title = _("Import From Application");
214
string label = _("Import media _from:");
218
service_selector_box = new Gtk.ComboBoxText();
219
service_selector_box.set_active(0);
220
service_selector_box_label = new Gtk.Label.with_mnemonic(label);
221
service_selector_box_label.set_mnemonic_widget(service_selector_box);
222
service_selector_box_label.set_alignment(0.0f, 0.5f);
224
// get the name of the service the user last used
225
string? last_used_service = Config.Facade.get_instance().get_last_used_dataimports_service();
227
Spit.DataImports.Service[] loaded_services = Spit.DataImports.load_services();
229
int last_used_index = -1;
230
foreach (Spit.DataImports.Service service in loaded_services) {
231
string curr_service_id = service.get_id();
232
if (last_used_service != null && last_used_service == curr_service_id)
233
last_used_index = ticker;
235
service_selector_box.append_text(service.get_pluggable_name());
238
if (last_used_index >= 0)
239
service_selector_box.set_active(last_used_index);
241
service_selector_box.set_active(0);
243
service_selector_box.changed.connect(on_service_changed);
245
/* the wrapper is not an extraneous widget -- it's necessary to prevent the service
246
selection box from growing and shrinking whenever its parent's size changes.
247
When wrapped inside a Gtk.Alignment, the Alignment grows and shrinks instead of
248
the service selection box. */
249
Gtk.Alignment service_selector_box_wrapper = new Gtk.Alignment(1.0f, 0.5f, 0.0f, 0.0f);
250
service_selector_box_wrapper.add(service_selector_box);
252
Gtk.HBox service_selector_layouter = new Gtk.HBox(false, 8);
253
service_selector_layouter.set_border_width(12);
254
service_selector_layouter.add(service_selector_box_label);
255
service_selector_layouter.add(service_selector_box_wrapper);
257
/* 'service area' is the selector assembly plus the horizontal rule dividing it from the
258
rest of the dialog */
259
Gtk.VBox service_area_layouter = new Gtk.VBox(false, 0);
260
service_area_layouter.add(service_selector_layouter);
261
Gtk.HSeparator service_central_separator = new Gtk.HSeparator();
262
service_area_layouter.add(service_central_separator);
264
Gtk.Alignment service_area_wrapper = new Gtk.Alignment(0.0f, 0.0f, 1.0f, 0.0f);
265
service_area_wrapper.add(service_area_layouter);
267
central_area_layouter = new Gtk.VBox(false, 0);
269
((Gtk.Box) get_content_area()).pack_start(service_area_wrapper, false, false, 0);
270
((Gtk.Box) get_content_area()).pack_start(central_area_layouter, true, true, 0);
272
close_cancel_button = new Gtk.Button.with_mnemonic("_Cancel");
273
close_cancel_button.set_can_default(true);
274
close_cancel_button.clicked.connect(on_close_cancel_clicked);
275
((Gtk.Box) get_action_area()).add(close_cancel_button);
277
set_standard_window_mode();
279
// trigger the selected service
280
on_service_changed();
285
public static DataImportsDialog get_or_create_instance() {
286
if (instance == null) {
287
instance = new DataImportsDialog();
292
public static void terminate_instance() {
293
if (instance != null) {
294
instance.terminate();
299
private bool on_window_close(Gdk.EventAny evt) {
300
host.stop_importing();
308
private void on_service_changed() {
309
debug("DataImportsDialog: on_service_changed invoked.");
310
string service_name = service_selector_box.get_active_text();
312
Spit.DataImports.Service? selected_service = null;
313
Spit.DataImports.Service[] services = Spit.DataImports.load_all_services();
314
foreach (Spit.DataImports.Service service in services) {
315
if (service.get_pluggable_name() == service_name) {
316
selected_service = service;
320
assert(selected_service != null);
322
Config.Facade.get_instance().set_last_used_dataimports_service(selected_service.get_id());
324
host = new Spit.DataImports.ConcreteDataImportsHost(selected_service, this);
325
host.start_importing();
328
private void on_close_cancel_clicked() {
329
debug("DataImportsDialog: on_close_cancel_clicked( ): invoked.");
334
private void terminate() {
335
debug("DataImportsDialog: terminate( ): invoked.");
337
host.stop_importing();
343
private void set_large_window_mode() {
344
set_size_request(LARGE_WINDOW_WIDTH, LARGE_WINDOW_HEIGHT);
345
central_area_layouter.set_size_request(LARGE_WINDOW_WIDTH - BORDER_REGION_WIDTH,
346
LARGE_WINDOW_HEIGHT - BORDER_REGION_HEIGHT);
350
private void set_colossal_window_mode() {
351
set_size_request(COLOSSAL_WINDOW_WIDTH, COLOSSAL_WINDOW_HEIGHT);
352
central_area_layouter.set_size_request(COLOSSAL_WINDOW_WIDTH - BORDER_REGION_WIDTH,
353
COLOSSAL_WINDOW_HEIGHT - BORDER_REGION_HEIGHT);
357
private void set_standard_window_mode() {
358
set_size_request(STANDARD_WINDOW_WIDTH, STANDARD_WINDOW_HEIGHT);
359
central_area_layouter.set_size_request(STANDARD_WINDOW_WIDTH - BORDER_REGION_WIDTH,
360
STANDARD_WINDOW_HEIGHT - BORDER_REGION_HEIGHT);
364
private void set_free_sizable_window_mode() {
368
private void clear_free_sizable_window_mode() {
372
public Spit.DataImports.DialogPane get_active_pane() {
376
public void set_close_button_mode() {
377
close_cancel_button.set_label(_("_Close"));
378
set_default(close_cancel_button);
381
public void set_cancel_button_mode() {
382
close_cancel_button.set_label(_("_Cancel"));
385
public void lock_service() {
386
service_selector_box.set_sensitive(false);
389
public void unlock_service() {
390
service_selector_box.set_sensitive(true);
393
public void install_pane(Spit.DataImports.DialogPane pane) {
394
debug("DataImportsDialog: install_pane( ): invoked.");
396
if (active_pane != null) {
397
debug("DataImportsDialog: install_pane( ): a pane is already installed; removing it.");
399
active_pane.on_pane_uninstalled();
400
central_area_layouter.remove(active_pane.get_widget());
403
central_area_layouter.add(pane.get_widget());
406
Spit.DataImports.DialogPane.GeometryOptions geometry_options =
407
pane.get_preferred_geometry();
408
if ((geometry_options & Spit.Publishing.DialogPane.GeometryOptions.EXTENDED_SIZE) != 0)
409
set_large_window_mode();
410
else if ((geometry_options & Spit.Publishing.DialogPane.GeometryOptions.COLOSSAL_SIZE) != 0)
411
set_colossal_window_mode();
413
set_standard_window_mode();
415
if ((geometry_options & Spit.Publishing.DialogPane.GeometryOptions.RESIZABLE) != 0)
416
set_free_sizable_window_mode();
418
clear_free_sizable_window_mode();
421
pane.on_pane_installed();
424
private static DataImportsDialog? instance;