~ubuntu-branches/ubuntu/quantal/shotwell/quantal

« back to all changes in this revision

Viewing changes to src/data_imports/DataImportsUI.vala

  • Committer: Package Import Robot
  • Author(s): Robert Ancell
  • Date: 2012-02-21 13:52:58 UTC
  • mto: This revision was merged to the branch mainline in revision 47.
  • Revision ID: package-import@ubuntu.com-20120221135258-ao9jiib5qicomq7q
Tags: upstream-0.11.92
ImportĀ upstreamĀ versionĀ 0.11.92

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2011 Yorba Foundation
 
2
 *
 
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. 
 
5
 */
 
6
 
 
7
namespace DataImportsUI {
 
8
 
 
9
public class ConcreteDialogPane : Spit.DataImports.DialogPane, GLib.Object {
 
10
    private Gtk.VBox pane_widget;
 
11
    
 
12
    public ConcreteDialogPane() {
 
13
        pane_widget = new Gtk.VBox(false, 8);
 
14
    }
 
15
    
 
16
    public Gtk.Widget get_widget() {
 
17
        return pane_widget;
 
18
    }
 
19
 
 
20
    public Spit.DataImports.DialogPane.GeometryOptions get_preferred_geometry() {
 
21
        return Spit.DataImports.DialogPane.GeometryOptions.NONE;
 
22
    }
 
23
 
 
24
    public void on_pane_installed() {
 
25
    }
 
26
 
 
27
    public void on_pane_uninstalled() {
 
28
    }
 
29
}
 
30
 
 
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);
 
35
    }
 
36
    
 
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);
 
41
        
 
42
        (get_widget() as Gtk.Container).add(label);
 
43
    }
 
44
}
 
45
 
 
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;
 
52
    
 
53
    public LibrarySelectionPane(
 
54
        Spit.DataImports.PluginHost host,
 
55
        string welcome_message,
 
56
        Spit.DataImports.ImportableLibrary[] discovered_libraries,
 
57
        string? file_select_label
 
58
    ) {
 
59
        assert(discovered_libraries.length > 0 || on_file_selected != null);
 
60
        
 
61
        this.host = host;
 
62
        
 
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);
 
71
        
 
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;
 
77
        
 
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
 
86
                );
 
87
            }
 
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
 
92
                );
 
93
                file_radio = lib_radio;
 
94
            }
 
95
        }
 
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();
 
103
            });
 
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);
 
107
        }
 
108
        
 
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);
 
115
            else
 
116
                debug("LibrarySelectionPane: Library or file should be selected.");
 
117
        });
 
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);
 
122
        
 
123
        (get_widget() as Gtk.Container).add(content_box);
 
124
        
 
125
        set_import_button_sensitivity();
 
126
    }
 
127
    
 
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
 
131
    ) {
 
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;
 
136
        }
 
137
        button.toggled.connect (() => {
 
138
            if (button.active) {
 
139
                this.selected_library = library;
 
140
                set_import_button_sensitivity();
 
141
            }
 
142
            
 
143
        });
 
144
        button.set_margin_left(margin_left);
 
145
        button.set_margin_right(margin_right);
 
146
        box.pack_start(button, false, false, 6);
 
147
        return button;
 
148
    }
 
149
    
 
150
    private void set_import_button_sensitivity() {
 
151
        import_button.set_sensitive(selected_library != null || selected_file != null);
 
152
    }
 
153
    
 
154
    private void on_library_selected(Spit.DataImports.ImportableLibrary library) {
 
155
        host.get_data_importer().on_library_selected(library);
 
156
    }
 
157
    
 
158
    private void on_file_selected(File file) {
 
159
        host.get_data_importer().on_file_selected(file);
 
160
    }
 
161
}
 
162
 
 
163
public class ProgressPane : ConcreteDialogPane {
 
164
    private Gtk.Label message_label;
 
165
    private Gtk.Label progress_label;
 
166
    private Gtk.ProgressBar progress_bar;
 
167
    
 
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);
 
176
        
 
177
        (get_widget() as Gtk.Container).add(content_box);
 
178
    }
 
179
    
 
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);
 
184
        spin_event_loop();
 
185
    }
 
186
}
 
187
 
 
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;
 
197
 
 
198
    public const int STANDARD_CONTENT_LABEL_WIDTH = 500;
 
199
    public const int STANDARD_ACTION_BUTTON_WIDTH = 128;
 
200
 
 
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;
 
207
 
 
208
    protected DataImportsDialog() {
 
209
 
 
210
        resizable = false;
 
211
        delete_event.connect(on_window_close);
 
212
        
 
213
        string title = _("Import From Application");
 
214
        string label = _("Import media _from:");
 
215
        
 
216
        set_title(title);
 
217
 
 
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);
 
223
 
 
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();
 
226
 
 
227
        Spit.DataImports.Service[] loaded_services = Spit.DataImports.load_services();
 
228
        int ticker = 0;
 
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;
 
234
 
 
235
            service_selector_box.append_text(service.get_pluggable_name());
 
236
            ticker++;
 
237
        }
 
238
        if (last_used_index >= 0)
 
239
            service_selector_box.set_active(last_used_index);
 
240
        else
 
241
            service_selector_box.set_active(0);
 
242
 
 
243
        service_selector_box.changed.connect(on_service_changed);
 
244
 
 
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);
 
251
 
 
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);
 
256
        
 
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);
 
263
 
 
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);
 
266
        
 
267
        central_area_layouter = new Gtk.VBox(false, 0);
 
268
 
 
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);
 
271
        
 
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);
 
276
 
 
277
        set_standard_window_mode();
 
278
        
 
279
        // trigger the selected service
 
280
        on_service_changed();
 
281
        
 
282
        show_all();
 
283
    }
 
284
    
 
285
    public static DataImportsDialog get_or_create_instance() {
 
286
        if (instance == null) {
 
287
            instance = new DataImportsDialog();
 
288
        }
 
289
        return instance;   
 
290
    }
 
291
    
 
292
    public static void terminate_instance() {
 
293
        if (instance != null) {
 
294
            instance.terminate();
 
295
        }
 
296
        instance = null;
 
297
    }
 
298
    
 
299
    private bool on_window_close(Gdk.EventAny evt) {
 
300
        host.stop_importing();
 
301
        host = null;
 
302
        hide();
 
303
        destroy();
 
304
        
 
305
        return true;
 
306
    }
 
307
    
 
308
    private void on_service_changed() {
 
309
        debug("DataImportsDialog: on_service_changed invoked.");
 
310
        string service_name = service_selector_box.get_active_text();
 
311
        
 
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;
 
317
                break;
 
318
            }
 
319
        }
 
320
        assert(selected_service != null);
 
321
 
 
322
        Config.Facade.get_instance().set_last_used_dataimports_service(selected_service.get_id());
 
323
 
 
324
        host = new Spit.DataImports.ConcreteDataImportsHost(selected_service, this);
 
325
        host.start_importing();
 
326
    }
 
327
    
 
328
    private void on_close_cancel_clicked() {
 
329
        debug("DataImportsDialog: on_close_cancel_clicked( ): invoked.");
 
330
        
 
331
        terminate();
 
332
    }
 
333
    
 
334
    private void terminate() {
 
335
        debug("DataImportsDialog: terminate( ): invoked.");
 
336
        
 
337
        host.stop_importing();
 
338
        host = null;
 
339
        hide();
 
340
        destroy();
 
341
    }
 
342
    
 
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);
 
347
        resizable = false;
 
348
    }
 
349
    
 
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);
 
354
        resizable = false;
 
355
    }
 
356
 
 
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);
 
361
        resizable = false;
 
362
    }
 
363
 
 
364
    private void set_free_sizable_window_mode() {
 
365
        resizable = true;
 
366
    }
 
367
 
 
368
    private void clear_free_sizable_window_mode() {
 
369
        resizable = false;
 
370
    }
 
371
 
 
372
    public Spit.DataImports.DialogPane get_active_pane() {
 
373
        return active_pane;
 
374
    }
 
375
 
 
376
    public void set_close_button_mode() {
 
377
        close_cancel_button.set_label(_("_Close"));
 
378
        set_default(close_cancel_button);
 
379
    }
 
380
 
 
381
    public void set_cancel_button_mode() {
 
382
        close_cancel_button.set_label(_("_Cancel"));
 
383
    }
 
384
 
 
385
    public void lock_service() {
 
386
        service_selector_box.set_sensitive(false);
 
387
    }
 
388
 
 
389
    public void unlock_service() {
 
390
        service_selector_box.set_sensitive(true);
 
391
    }
 
392
    
 
393
    public void install_pane(Spit.DataImports.DialogPane pane) {
 
394
        debug("DataImportsDialog: install_pane( ): invoked.");
 
395
 
 
396
        if (active_pane != null) {
 
397
            debug("DataImportsDialog: install_pane( ): a pane is already installed; removing it.");
 
398
 
 
399
            active_pane.on_pane_uninstalled();
 
400
            central_area_layouter.remove(active_pane.get_widget());
 
401
        }
 
402
 
 
403
        central_area_layouter.add(pane.get_widget());
 
404
        show_all();
 
405
 
 
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();
 
412
        else
 
413
            set_standard_window_mode();
 
414
 
 
415
        if ((geometry_options & Spit.Publishing.DialogPane.GeometryOptions.RESIZABLE) != 0)
 
416
            set_free_sizable_window_mode();
 
417
        else
 
418
            clear_free_sizable_window_mode();
 
419
 
 
420
        active_pane = pane;
 
421
        pane.on_pane_installed();
 
422
    }
 
423
    
 
424
    private static DataImportsDialog? instance;
 
425
}
 
426
 
 
427
}
 
428