[shotwell/wip/gtk4: 53/88] Fix import reporting




commit 3415e4528ab62f035c4752f646e978ccbb3fec8e
Author: Jens Georg <mail jensge org>
Date:   Wed Apr 13 20:15:07 2022 +0200

    Fix import reporting

 src/Dialogs.vala               | 93 ++++++++++++++++++++++--------------------
 src/camera/ImportPage.vala     | 55 +++++++++++++------------
 src/library/LibraryBranch.vala | 10 ++---
 src/library/LibraryWindow.vala | 47 ++++++++-------------
 src/main.vala                  |  2 +-
 5 files changed, 102 insertions(+), 105 deletions(-)
---
diff --git a/src/Dialogs.vala b/src/Dialogs.vala
index 24a0e736..bf4d3c11 100644
--- a/src/Dialogs.vala
+++ b/src/Dialogs.vala
@@ -226,7 +226,7 @@ public string create_result_report_from_manifest(ImportManifest manifest) {
     StringBuilder builder = new StringBuilder();
     
     string header = _("Import Results Report") + " (Shotwell " + Resources.APP_VERSION + " @ " +
-        TimeVal().to_iso8601() + ")\n\n";
+        new DateTime.now_local().format_iso8601() + ")\n\n";
     builder.append(header);
     
     string subhead = (ngettext("Attempted to import %d file.", "Attempted to import %d files.",
@@ -349,7 +349,7 @@ public string create_result_report_from_manifest(ImportManifest manifest) {
 
 // Summarizes the contents of an import manifest in an on-screen message window. Returns
 // true if the user selected the yes action, false otherwise.
-public bool report_manifest(ImportManifest manifest, bool show_dest_id, 
+public async bool report_manifest(ImportManifest manifest, bool show_dest_id, 
     QuestionParams? question = null) {
     string message = "";
     
@@ -543,70 +543,75 @@ public bool report_manifest(ImportManifest manifest, bool show_dest_id,
         message += _("No photos or videos imported.\n");
     
     Gtk.MessageDialog dialog = null;
-    int dialog_response = Gtk.ResponseType.NONE;
+    dialog = new Gtk.MessageDialog(AppWindow.get_instance(), Gtk.DialogFlags.MODAL,
+    Gtk.MessageType.QUESTION, Gtk.ButtonsType.NONE, "%s", message);
+    dialog.title = _("Import Complete");
+    Gtk.Widget save_results_button = dialog.add_button(ImportUI.SAVE_RESULTS_BUTTON_NAME,
+    ImportUI.SAVE_RESULTS_RESPONSE_ID);
+    save_results_button.set_visible(manifest.success.size < manifest.all.size);
+    Gtk.Window dialog_parent = (Gtk.Window) dialog.get_parent();
+    dialog.set_transient_for(AppWindow.get_instance());
+
     if (question == null) {
-        dialog = new Gtk.MessageDialog(AppWindow.get_instance(), Gtk.DialogFlags.MODAL,
-            Gtk.MessageType.INFO, Gtk.ButtonsType.NONE, "%s", message);
-        dialog.title = _("Import Complete");
-        Gtk.Widget save_results_button = dialog.add_button(ImportUI.SAVE_RESULTS_BUTTON_NAME,
-            ImportUI.SAVE_RESULTS_RESPONSE_ID);
-        save_results_button.set_visible(manifest.success.size < manifest.all.size);
-        Gtk.Widget ok_button = dialog.add_button(Resources.OK_LABEL, Gtk.ResponseType.OK);
+        var ok_button = dialog.add_button(Resources.OK_LABEL, Gtk.ResponseType.OK);
         dialog.set_default_widget(ok_button);
-        
-        Gtk.Window dialog_parent = (Gtk.Window) dialog.get_parent();
-        dialog_response = 0; // TODO dialog.run();
-        dialog.destroy();
-        
-        if (dialog_response == ImportUI.SAVE_RESULTS_RESPONSE_ID)
-            save_import_results(dialog_parent, create_result_report_from_manifest(manifest));
-
     } else {
         message += ("\n" + question.question);
         
-        dialog = new Gtk.MessageDialog(AppWindow.get_instance(), Gtk.DialogFlags.MODAL,
-            Gtk.MessageType.QUESTION, Gtk.ButtonsType.NONE, "%s", message);
-        dialog.title = _("Import Complete");
-        Gtk.Widget save_results_button = dialog.add_button(ImportUI.SAVE_RESULTS_BUTTON_NAME,
-            ImportUI.SAVE_RESULTS_RESPONSE_ID);
-        save_results_button.set_visible(manifest.success.size < manifest.all.size);
-        Gtk.Widget no_button = dialog.add_button(question.no_button, Gtk.ResponseType.NO);
+        var no_button = dialog.add_button(question.no_button, Gtk.ResponseType.NO);
         dialog.add_button(question.yes_button, Gtk.ResponseType.YES);
-        dialog.set_default_widget(no_button);
-        
-        dialog_response = 0; //TODO dialog.run();
-        while (dialog_response == ImportUI.SAVE_RESULTS_RESPONSE_ID) {
-            save_import_results(dialog, create_result_report_from_manifest(manifest));
-            dialog_response = 0;  // TODO dialog.run();
-        }
-        
-        dialog.hide();
-        dialog.destroy();
+        dialog.set_default_widget(no_button);        
     }
+    dialog.text = message;
+    dialog.show();
+    SourceFunc async_cb = report_manifest.callback;
+    bool result = false;
+    dialog.response.connect((source, res) => {
+        if (res == ImportUI.SAVE_RESULTS_RESPONSE_ID) {
+            save_import_results.begin(dialog, create_result_report_from_manifest(manifest));
+        }
+
+        result = res == Gtk.ResponseType.YES;
+        if (res != ImportUI.SAVE_RESULTS_RESPONSE_ID || question == null) {
+            async_cb();
+        }
+    });
+
+    yield;
+    dialog.destroy();
     
-    return (dialog_response == Gtk.ResponseType.YES);
+    return result;
 }
 
-internal void save_import_results(Gtk.Window? chooser_dialog_parent, string results_log) {
+internal async void save_import_results(Gtk.Window? chooser_dialog_parent, string results_log) {
     var chooser_dialog = new Gtk.FileChooserNative(
         ImportUI.SAVE_RESULTS_FILE_CHOOSER_TITLE, chooser_dialog_parent, Gtk.FileChooserAction.SAVE,
         Resources.SAVE_AS_LABEL, Resources.CANCEL_LABEL);
-        try {
-    chooser_dialog.set_current_folder(File.new_for_commandline_arg (Environment.get_home_dir()));
+    try {
+        chooser_dialog.set_current_folder(File.new_for_commandline_arg (Environment.get_home_dir()));
     } catch (Error err) {
     }
     chooser_dialog.set_current_name("Shotwell Import Log.txt");
+    chooser_dialog.set_transient_for(chooser_dialog_parent);
+    
+    int dialog_result =  0;
+    chooser_dialog.show();
+    SourceFunc continue_cb = save_import_results.callback;
+    chooser_dialog.response.connect((source, res) => {
+        chooser_dialog.hide();
+        dialog_result = res;
+        continue_cb();
+    });
+    yield;
     
-    int dialog_result = 0; // TODOchooser_dialog.run();
     File? chosen_file = chooser_dialog.get_file();
-    chooser_dialog.hide();
     chooser_dialog.destroy();
     
     if (dialog_result == Gtk.ResponseType.ACCEPT && chosen_file != null) {
         try {
-            FileOutputStream outstream = chosen_file.replace(null, false, FileCreateFlags.NONE);
-            outstream.write(results_log.data);
-            outstream.close();
+            FileOutputStream outstream = yield chosen_file.replace_async(null, false, FileCreateFlags.NONE);
+            yield outstream.write_async(results_log.data);
+            yield outstream.close_async();
         } catch (Error err) {
             critical("couldn't save import results to log file %s: %s", chosen_file.get_path(),
                 err.message);
diff --git a/src/camera/ImportPage.vala b/src/camera/ImportPage.vala
index b1a1f7b9..724dcc45 100644
--- a/src/camera/ImportPage.vala
+++ b/src/camera/ImportPage.vala
@@ -1697,34 +1697,39 @@ public class ImportPage : CheckerboardPage {
         // until this function returns (at any time)
         ImportPage? local_ref = this.local_ref;
         this.local_ref = null;
-        
-        if (manifest.success.size > 0) {
-            string photos_string = (ngettext("Delete this photo from camera?",
-                "Delete these %d photos from camera?", 
-                manifest.success.size)).printf(manifest.success.size);
-            string videos_string = (ngettext("Delete this video from camera?",
-                "Delete these %d videos from camera?", 
-                manifest.success.size)).printf(manifest.success.size);
-            string both_string = (ngettext("Delete this photo/video from camera?",
-                "Delete these %d photos/videos from camera?", 
-                manifest.success.size)).printf(manifest.success.size);
-            string neither_string = (ngettext("Delete these files from camera?",
-                "Delete these %d files from camera?", 
-                manifest.success.size)).printf(manifest.success.size);
-
-            string question_string = ImportUI.get_media_specific_string(manifest.success,
-                photos_string, videos_string, both_string, neither_string);
-
-            ImportUI.QuestionParams question = new ImportUI.QuestionParams(
-                question_string, Resources.DELETE_LABEL, _("_Keep"));
-        
-            if (!ImportUI.report_manifest(manifest, false, question))
-                return;
-        } else {
-            ImportUI.report_manifest(manifest, false, null);
+
+        if (manifest.success.size <= 0) {
+            ImportUI.report_manifest.begin(manifest, false, null);
             return;
         }
         
+        string photos_string = (ngettext("Delete this photo from camera?",
+            "Delete these %d photos from camera?", 
+            manifest.success.size)).printf(manifest.success.size);
+        string videos_string = (ngettext("Delete this video from camera?",
+            "Delete these %d videos from camera?", 
+            manifest.success.size)).printf(manifest.success.size);
+        string both_string = (ngettext("Delete this photo/video from camera?",
+            "Delete these %d photos/videos from camera?", 
+            manifest.success.size)).printf(manifest.success.size);
+        string neither_string = (ngettext("Delete these files from camera?",
+            "Delete these %d files from camera?", 
+            manifest.success.size)).printf(manifest.success.size);
+
+        string question_string = ImportUI.get_media_specific_string(manifest.success,
+            photos_string, videos_string, both_string, neither_string);
+
+        ImportUI.QuestionParams question = new ImportUI.QuestionParams(
+            question_string, Resources.DELETE_LABEL, _("_Keep"));
+
+        ImportUI.report_manifest.begin(manifest, false, question, (source, res) => {
+            if (ImportUI.report_manifest.end(res)) {
+                delete_from_camera(manifest);
+            }
+        });
+    }
+
+    void delete_from_camera(ImportManifest manifest) {
         // delete the photos from the camera and the SourceCollection... for now, this is an 
         // all-or-nothing deal
         Marker marker = import_sources.start_marking();
diff --git a/src/library/LibraryBranch.vala b/src/library/LibraryBranch.vala
index 7ecd00d6..5160114f 100644
--- a/src/library/LibraryBranch.vala
+++ b/src/library/LibraryBranch.vala
@@ -12,8 +12,8 @@ public class Library.Branch : Sidebar.Branch {
     public Library.FlaggedSidebarEntry flagged_entry { get; private set; }
     #endif
     public Library.LastImportSidebarEntry last_imported_entry { get; private set; }
-    #if 0
     public Library.ImportQueueSidebarEntry import_queue_entry { get; private set; }
+    #if 0
     public Library.OfflineSidebarEntry offline_entry { get; private set; }
     #endif
     public Library.TrashSidebarEntry trash_entry { get; private set; }
@@ -40,8 +40,8 @@ public class Library.Branch : Sidebar.Branch {
         #if 0
         flagged_entry = new Library.FlaggedSidebarEntry();
         offline_entry = new Library.OfflineSidebarEntry();
-        import_queue_entry = new Library.ImportQueueSidebarEntry();
         #endif
+        import_queue_entry = new Library.ImportQueueSidebarEntry();
 
         insert(photos_entry, EntryPosition.PHOTOS);
         insert(trash_entry, EntryPosition.TRASH);
@@ -52,8 +52,8 @@ public class Library.Branch : Sidebar.Branch {
         last_imported_entry.visibility_changed.connect(on_last_imported_visibility_changed);
         on_last_imported_visibility_changed();
 
-        //import_queue_entry.visibility_changed.connect(on_import_queue_visibility_changed);
-        //on_import_queue_visibility_changed();
+        import_queue_entry.visibility_changed.connect(on_import_queue_visibility_changed);
+        on_import_queue_visibility_changed();
 
         //offline_entry.visibility_changed.connect(on_offline_visibility_changed);
         //on_offline_visibility_changed();
@@ -73,7 +73,7 @@ public class Library.Branch : Sidebar.Branch {
     }
 
     private void on_import_queue_visibility_changed() {
-        //update_entry_visibility(import_queue_entry, EntryPosition.IMPORT_QUEUE);
+        update_entry_visibility(import_queue_entry, EntryPosition.IMPORT_QUEUE);
     }
 
     private void on_offline_visibility_changed() {
diff --git a/src/library/LibraryWindow.vala b/src/library/LibraryWindow.vala
index 9fc4bca0..5357367c 100644
--- a/src/library/LibraryWindow.vala
+++ b/src/library/LibraryWindow.vala
@@ -515,6 +515,14 @@ public class LibraryWindow : AppWindow {
         go_fullscreen(fs_photo);
     }
 
+    async void do_file_import(ListModel files, bool recursive) {
+        var result = yield copy_files_dialog();
+        if (result != Gtk.ResponseType.CANCEL) {
+            dispatch_import_jobs(files, "folders",
+                result == Gtk.ResponseType.ACCEPT, recursive);
+        }
+    }
+
     private void on_file_import() {
         var import_dialog = new Gtk.FileChooserNative(_("Import From Folder"), null,
             Gtk.FileChooserAction.SELECT_FOLDER, Resources.OK_LABEL, Resources.CANCEL_LABEL);
@@ -533,31 +541,10 @@ public class LibraryWindow : AppWindow {
         import_dialog.show();
         import_dialog.response.connect((dialog, response) => {
             import_dir = import_dialog.get_current_folder();
+            import_recursive = bool.parse(import_dialog.get_choice("recursive-import"));
+            do_file_import.begin(import_dialog.get_files(), import_recursive);
             import_dialog.destroy();
         });
-#if 0        
-        int response = 0; //import_dialog.run();
-        
-        if (response == Gtk.ResponseType.ACCEPT) {
-            import_dialog.hide();
-            // force file linking if directory is inside current library directory
-            Gtk.ResponseType copy_files_response =
-                AppDirs.is_in_import_dir(import_dialog.get_file())
-                    ? Gtk.ResponseType.REJECT : copy_files_dialog();
-            
-            if (copy_files_response != Gtk.ResponseType.CANCEL) {
-            // TODO
-            #if 0
-                dispatch_import_jobs(import_dialog.get_uris(), "folders",
-                    copy_files_response == Gtk.ResponseType.ACCEPT, recursive.active);
-                    #endif
-            }
-        }
-        
-        import_dir = import_dialog.get_current_folder().get_path();
-        import_recursive = recursive.active;
-        import_dialog.destroy();
- #endif
     }
     
     private void on_external_library_import() {
@@ -774,14 +761,14 @@ public class LibraryWindow : AppWindow {
     }
 
     public void enqueue_batch_import(BatchImport batch_import, bool allow_user_cancel) {
-        //library_branch.import_queue_entry.enqueue_and_schedule(batch_import, allow_user_cancel);
+        library_branch.import_queue_entry.enqueue_and_schedule(batch_import, allow_user_cancel);
     }
     
     private void import_reporter(ImportManifest manifest) {
-        ImportUI.report_manifest(manifest, true);
+        ImportUI.report_manifest.begin(manifest, true);
     }
     
-    private void dispatch_import_jobs(GLib.SList<string> uris, string job_name, bool copy_to_library, bool 
recurse) {
+    private void dispatch_import_jobs(ListModel uris, string job_name, bool copy_to_library, bool recurse) {
         if (AppDirs.get_import_dir().get_path() == Environment.get_home_dir() && notify_library_is_home_dir) 
{
             Gtk.ResponseType response = AppWindow.affirm_cancel_question(
                 _("Shotwell is configured to import photos to your home directory.\n" + 
@@ -796,8 +783,8 @@ public class LibraryWindow : AppWindow {
         }
         
         Gee.ArrayList<FileImportJob> jobs = new Gee.ArrayList<FileImportJob>();
-        foreach (string uri in uris) {
-            File file_or_dir = File.new_for_uri(uri);
+        for (var i = 0; i < uris.get_n_items(); i++) {
+            var file_or_dir = (File) uris.get_item(i);
             if (file_or_dir.get_path() == null) {
                 // TODO: Specify which directory/file.
                 AppWindow.error_message(_("Photos cannot be imported from this directory."));
@@ -805,7 +792,7 @@ public class LibraryWindow : AppWindow {
                 continue;
             }
 
-            jobs.add(new FileImportJob(file_or_dir, copy_to_library, recurse));
+            jobs.add(new FileImportJob(file_or_dir, copy_to_library && 
!AppDirs.is_in_import_dir(file_or_dir), recurse));
         }
         
         if (jobs.size > 0) {
@@ -960,7 +947,7 @@ public class LibraryWindow : AppWindow {
     }
     
     public void switch_to_import_queue_page() {
-        //switch_to_page(library_branch.import_queue_entry.get_page());
+        switch_to_page(library_branch.import_queue_entry.get_page());
     }
     
     private void on_camera_added(DiscoveredCamera camera) {
diff --git a/src/main.vala b/src/main.vala
index 9c25cf34..d261d173 100644
--- a/src/main.vala
+++ b/src/main.vala
@@ -260,7 +260,7 @@ private void report_system_pictures_import(ImportManifest manifest, BatchImportR
     if (do_external_import && (manifest.all.size == 0))
         return;
 
-    ImportUI.report_manifest(manifest, true);
+    ImportUI.report_manifest.begin(manifest, true);
 }
 
 void dump_tags (GExiv2.Metadata metadata, string[] tags) throws Error {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]