diff options
Diffstat (limited to 'src/library/ImportQueuePage.vala')
-rw-r--r-- | src/library/ImportQueuePage.vala | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/src/library/ImportQueuePage.vala b/src/library/ImportQueuePage.vala new file mode 100644 index 0000000..5ace1d8 --- /dev/null +++ b/src/library/ImportQueuePage.vala @@ -0,0 +1,208 @@ +/* Copyright 2009-2014 Yorba Foundation + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later). See the COPYING file in this distribution. + */ + +public class ImportQueuePage : SinglePhotoPage { + public const string NAME = _("Importing..."); + + private Gee.ArrayList<BatchImport> queue = new Gee.ArrayList<BatchImport>(); + private Gee.HashSet<BatchImport> cancel_unallowed = new Gee.HashSet<BatchImport>(); + private BatchImport current_batch = null; + private Gtk.ProgressBar progress_bar = new Gtk.ProgressBar(); + private bool stopped = false; + +#if UNITY_SUPPORT + UnityProgressBar uniprobar = UnityProgressBar.get_instance(); +#endif + + public signal void batch_added(BatchImport batch_import); + + public signal void batch_removed(BatchImport batch_import); + + public ImportQueuePage() { + base (NAME, false); + + // Set up toolbar + Gtk.Toolbar toolbar = get_toolbar(); + + // Stop button + Gtk.ToolButton stop_button = new Gtk.ToolButton.from_stock(Gtk.Stock.STOP); + stop_button.set_related_action(get_action("Stop")); + + toolbar.insert(stop_button, -1); + + // separator to force progress bar to right side of toolbar + Gtk.SeparatorToolItem separator = new Gtk.SeparatorToolItem(); + separator.set_draw(false); + + toolbar.insert(separator, -1); + + // Progress bar + Gtk.ToolItem progress_item = new Gtk.ToolItem(); + progress_item.set_expand(true); + progress_item.add(progress_bar); + progress_bar.set_show_text(true); + + toolbar.insert(progress_item, -1); +#if UNITY_SUPPORT + //UnityProgressBar: try to draw progress bar + uniprobar.set_visible(true); +#endif + } + + protected override void init_collect_ui_filenames(Gee.List<string> ui_filenames) { + ui_filenames.add("import_queue.ui"); + + base.init_collect_ui_filenames(ui_filenames); + } + + protected override Gtk.ActionEntry[] init_collect_action_entries() { + Gtk.ActionEntry[] actions = base.init_collect_action_entries(); + + Gtk.ActionEntry stop = { "Stop", Gtk.Stock.STOP, TRANSLATABLE, null, TRANSLATABLE, + on_stop }; + stop.label = _("_Stop Import"); + stop.tooltip = _("Stop importing photos"); + actions += stop; + + return actions; + } + + public void enqueue_and_schedule(BatchImport batch_import, bool allow_user_cancel) { + assert(!queue.contains(batch_import)); + + batch_import.starting.connect(on_starting); + batch_import.preparing.connect(on_preparing); + batch_import.progress.connect(on_progress); + batch_import.imported.connect(on_imported); + batch_import.import_complete.connect(on_import_complete); + batch_import.fatal_error.connect(on_fatal_error); + + if (!allow_user_cancel) + cancel_unallowed.add(batch_import); + + queue.add(batch_import); + batch_added(batch_import); + + if (queue.size == 1) + batch_import.schedule(); + + update_stop_action(); + } + + public int get_batch_count() { + return queue.size; + } + + private void update_stop_action() { + set_action_sensitive("Stop", !cancel_unallowed.contains(current_batch) && queue.size > 0); + } + + private void on_stop() { + update_stop_action(); + + if (queue.size == 0) + return; + + AppWindow.get_instance().set_busy_cursor(); + stopped = true; + + // mark all as halted and let each signal failure + foreach (BatchImport batch_import in queue) + batch_import.user_halt(); + } + + private void on_starting(BatchImport batch_import) { + update_stop_action(); + current_batch = batch_import; + } + + private void on_preparing() { + progress_bar.set_text(_("Preparing to import...")); + progress_bar.pulse(); + } + + private void on_progress(uint64 completed_bytes, uint64 total_bytes) { + double pct = (completed_bytes <= total_bytes) ? (double) completed_bytes / (double) total_bytes + : 0.0; + progress_bar.set_fraction(pct); +#if UNITY_SUPPORT + //UnityProgressBar: set progress + uniprobar.set_progress(pct); +#endif + } + + private void on_imported(ThumbnailSource source, Gdk.Pixbuf pixbuf, int to_follow) { + // only interested in updating the display for the last of the bunch + if (to_follow > 0 || !is_in_view()) + return; + + set_pixbuf(pixbuf, Dimensions.for_pixbuf(pixbuf)); + + // set the singleton collection to this item + get_view().clear(); + (source is LibraryPhoto) ? get_view().add(new PhotoView(source as LibraryPhoto)) : + get_view().add(new VideoView(source as Video)); + + progress_bar.set_ellipsize(Pango.EllipsizeMode.MIDDLE); + progress_bar.set_text(_("Imported %s").printf(source.get_name())); + } + + private void on_import_complete(BatchImport batch_import, ImportManifest manifest, + BatchImportRoll import_roll) { + assert(batch_import == current_batch); + current_batch = null; + + assert(queue.size > 0); + assert(queue.get(0) == batch_import); + + bool removed = queue.remove(batch_import); + assert(removed); + + // fail quietly if cancel was allowed + cancel_unallowed.remove(batch_import); + + // strip signal handlers + batch_import.starting.disconnect(on_starting); + batch_import.preparing.disconnect(on_preparing); + batch_import.progress.disconnect(on_progress); + batch_import.imported.disconnect(on_imported); + batch_import.import_complete.disconnect(on_import_complete); + batch_import.fatal_error.disconnect(on_fatal_error); + + // schedule next if available + if (queue.size > 0) { + queue.get(0).schedule(); + } else { + // reset UI + progress_bar.set_ellipsize(Pango.EllipsizeMode.NONE); + progress_bar.set_text(""); + progress_bar.set_fraction(0.0); +#if UNITY_SUPPORT + //UnityProgressBar: reset + uniprobar.reset(); +#endif + + // blank the display + blank_display(); + + // reset cursor if cancelled + if (stopped) + AppWindow.get_instance().set_normal_cursor(); + + stopped = false; + } + + update_stop_action(); + + // report the batch has been removed from the queue after everything else is set + batch_removed(batch_import); + } + + private void on_fatal_error(ImportResult result, string message) { + AppWindow.error_message(message); + } +} + |