[Bf-blender-cvs] [5ce3f69da43] master: UI: File Close Dialog

Jacques Lucke noreply at git.blender.org
Fri May 17 17:44:09 CEST 2019


Commit: 5ce3f69da438bf2bd58d5039f8a4165f31262e1e
Author: Jacques Lucke
Date:   Fri May 17 17:31:26 2019 +0200
Branches: master
https://developer.blender.org/rB5ce3f69da438bf2bd58d5039f8a4165f31262e1e

UI: File Close Dialog

This adds a new dialog that is shown whenever a file is closed.
So, either when a new file is opened, or when Blender quits.
The dialog allows to save unsaved changes. Furthermore it also
allows saving images that have been modified in Blender, but are
not saved yet.

Known limitations:
* Images that have no file path and have not been packed before,
  are not saved.
* On MacOS the old dialog is shown when Blender quits.

Reviewers: brecht, billreynish

Differential Revision: https://developer.blender.org/D4860

===================================================================

M	source/blender/editors/include/ED_image.h
M	source/blender/editors/space_image/image_ops.c
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/intern/wm_event_system.c
M	source/blender/windowmanager/intern/wm_files.c
M	source/blender/windowmanager/intern/wm_window.c
M	source/blender/windowmanager/wm_files.h

===================================================================

diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h
index affe98e10f8..a09e1d579fd 100644
--- a/source/blender/editors/include/ED_image.h
+++ b/source/blender/editors/include/ED_image.h
@@ -111,6 +111,7 @@ void ED_image_draw_info(struct Scene *scene,
 
 bool ED_space_image_show_cache(struct SpaceImage *sima);
 
+bool ED_image_should_save_modified(const struct bContext *C);
 int ED_image_save_all_modified_info(const struct bContext *C, struct ReportList *reports);
 bool ED_image_save_all_modified(const struct bContext *C, struct ReportList *reports);
 
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index b49fd92beb3..533e39a27bc 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -2161,126 +2161,117 @@ void IMAGE_OT_save_sequence(wmOperatorType *ot)
 
 /********************** save all operator **********************/
 
-static int image_save_all_modified(const bContext *C,
-                                   ReportList *reports,
-                                   int *num_files,
-                                   const bool dry_run,
-                                   const bool ignore_dry_run_warnings)
+static bool image_should_be_saved_when_modified(Image *ima)
+{
+  return !ELEM(ima->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE);
+}
+
+static bool image_should_be_saved(Image *ima)
+{
+  if (BKE_image_is_dirty(ima) && (ima->source == IMA_SRC_FILE)) {
+    return image_should_be_saved_when_modified(ima);
+  }
+  else {
+    return false;
+  }
+}
+
+static bool image_has_valid_path(Image *ima)
+{
+  return strchr(ima->name, '\\') || strchr(ima->name, '/');
+}
+
+bool ED_image_should_save_modified(const bContext *C)
+{
+  return ED_image_save_all_modified_info(C, NULL) > 0;
+}
+
+int ED_image_save_all_modified_info(const bContext *C, ReportList *reports)
 {
   Main *bmain = CTX_data_main(C);
-  Scene *scene = CTX_data_scene(C);
   GSet *unique_paths = BLI_gset_str_new(__func__);
-  bool ok = true;
 
-  if (num_files) {
-    *num_files = 0;
-  }
+  int num_saveable_images = 0;
 
   for (Image *ima = bmain->images.first; ima; ima = ima->id.next) {
-    if (ELEM(ima->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)) {
-      /* Don't save render results automatically. */
-    }
-    else if (BKE_image_is_dirty(ima) && (ima->source == IMA_SRC_FILE)) {
+    if (image_should_be_saved(ima)) {
       if (BKE_image_has_packedfile(ima)) {
         if (ima->id.lib == NULL) {
-          /* Re-pack. */
-          if (!dry_run) {
-            BKE_image_memorypack(ima);
-          }
-
-          if (num_files) {
-            (*num_files)++;
-          }
+          num_saveable_images++;
         }
-        else if (!ignore_dry_run_warnings) {
-          /* Can't pack to library data. */
+        else {
           BKE_reportf(reports,
                       RPT_WARNING,
                       "Packed library image: %s from library %s can't be saved",
                       ima->id.name,
                       ima->id.lib->name);
-          ok = false;
         }
       }
       else {
-        /* Save to file. */
-        const bool valid_path = strchr(ima->name, '\\') || strchr(ima->name, '/');
-
-        if (valid_path) {
-          ImageSaveOptions opts;
-
-          BKE_image_save_options_init(&opts, bmain, scene);
-
-          if (image_save_options_init(bmain, &opts, ima, NULL, false, false)) {
-            if (!BLI_gset_haskey(unique_paths, opts.filepath)) {
-              if (!dry_run) {
-                const bool save_ok = BKE_image_save(reports, bmain, ima, NULL, &opts);
-
-                if (save_ok) {
-                  BLI_gset_insert(unique_paths, BLI_strdup(opts.filepath));
-                }
-
-                ok = ok && save_ok;
-              }
-
-              if (num_files) {
-                (*num_files)++;
-              }
-            }
-            else if (!ignore_dry_run_warnings) {
-              BKE_reportf(reports,
-                          RPT_WARNING,
-                          "File path used by more than one saved image: %s",
-                          opts.filepath);
-              ok = false;
-            }
+        if (image_has_valid_path(ima)) {
+          num_saveable_images++;
+          if (BLI_gset_haskey(unique_paths, ima->name)) {
+            BKE_reportf(reports,
+                        RPT_WARNING,
+                        "File path used by more than one saved image: %s",
+                        ima->name);
+          }
+          else {
+            BLI_gset_insert(unique_paths, BLI_strdup(ima->name));
           }
         }
-        else if (!ignore_dry_run_warnings) {
+        else {
           BKE_reportf(reports,
                       RPT_WARNING,
                       "Image %s can't be saved, no valid file path: %s",
                       ima->id.name,
                       ima->name);
-          ok = false;
         }
       }
     }
   }
 
   BLI_gset_free(unique_paths, MEM_freeN);
-
-  return ok;
-}
-
-int ED_image_save_all_modified_info(const bContext *C, ReportList *reports)
-{
-  /* Dry run to get number of files, and any warnings we can detect in advance. */
-  int num_files;
-  image_save_all_modified(C, reports, &num_files, true, false);
-  return num_files;
+  return num_saveable_images;
 }
 
 bool ED_image_save_all_modified(const bContext *C, ReportList *reports)
 {
-  /* Save, and ignore any warnings that we already detected in
-   * ED_image_save_all_modified_info. */
-  return image_save_all_modified(C, reports, NULL, false, true);
+  ED_image_save_all_modified_info(C, reports);
+
+  Main *bmain = CTX_data_main(C);
+  bool ok = true;
+
+  for (Image *ima = bmain->images.first; ima; ima = ima->id.next) {
+    if (image_should_be_saved(ima)) {
+      if (BKE_image_has_packedfile(ima)) {
+        BKE_image_memorypack(ima);
+      }
+      else {
+        if (image_has_valid_path(ima)) {
+          ImageSaveOptions opts;
+          Scene *scene = CTX_data_scene(C);
+          BKE_image_save_options_init(&opts, bmain, scene);
+          if (image_save_options_init(bmain, &opts, ima, NULL, false, false)) {
+            bool saved_successfully = BKE_image_save(reports, bmain, ima, NULL, &opts);
+            ok = ok && saved_successfully;
+          }
+        }
+      }
+    }
+  }
+  return ok;
 }
 
 static bool image_save_all_modified_poll(bContext *C)
 {
-  /* Let operator run if there are any files to saved, or any warnings to
-   * report about files that we can't save. */
-  int num_files;
-  bool ok = image_save_all_modified(C, NULL, &num_files, true, false);
-  return (num_files > 0) || !ok;
+  int num_files = ED_image_save_all_modified_info(C, NULL);
+  return num_files > 0;
 }
 
 static int image_save_all_modified_exec(bContext *C, wmOperator *op)
 {
-  /* Save, and show all warnings. */
-  image_save_all_modified(C, op->reports, NULL, false, false);
+  ED_image_save_all_modified(C, op->reports);
   return OPERATOR_FINISHED;
 }
 
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index bd02a1e13c1..70f986732ad 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -401,6 +401,10 @@ int WM_operator_name_call(struct bContext *C,
                           const char *opstring,
                           short context,
                           struct PointerRNA *properties);
+int WM_operator_name_call_with_properties(struct bContext *C,
+                                          const char *opstring,
+                                          short context,
+                                          struct IDProperty *properties);
 int WM_operator_call_py(struct bContext *C,
                         struct wmOperatorType *ot,
                         short context,
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 8ad23af446d..6683085e6d3 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -1678,6 +1678,17 @@ int WM_operator_name_call(bContext *C, const char *opstring, short context, Poin
   return 0;
 }
 
+int WM_operator_name_call_with_properties(struct bContext *C,
+                                          const char *opstring,
+                                          short context,
+                                          struct IDProperty *properties)
+{
+  PointerRNA props_ptr;
+  wmOperatorType *ot = WM_operatortype_find(opstring, false);
+  RNA_pointer_create(NULL, ot->srna, properties, &props_ptr);
+  return WM_operator_name_call_ptr(C, ot, context, &props_ptr);
+}
+
 /**
  * Call an existent menu. The menu can be created in C or Python.
  */
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 329763a17fd..fabdd71fc5c 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -76,6 +76,7 @@
 #include "BKE_blender_undo.h"
 #include "BKE_context.h"
 #include "BKE_global.h"
+#include "BKE_idprop.h"
 #include "BKE_main.h"
 #include "BKE_packedFile.h"
 #include "BKE_report.h"
@@ -98,6 +99,7 @@
 
 #include "ED_datafiles.h"
 #include "ED_fileselect.h"
+#include "ED_image.h"
 #include "ED_screen.h"
 #include "ED_view3d.h"
 #include "ED_util.h"
@@ -1922,11 +1924,27 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op)
   return OPERATOR_FINISHED;
 }
 
+static void wm_homefile_read_after_dialog_callback(bContext *C, void *user_data)
+{
+  WM_operator_name_call_with_properties(
+      C, "WM_OT_read_homefile", WM_OP_EXEC_DEFAULT, (IDProperty *)user_data);
+}
+
+static void wm_free_operator_properties_callback(void *user_data)
+{
+  IDProperty *properties = (IDProperty *)user_data;
+  IDP_FreeProperty(properties);
+}
+
 static int wm_homefile_read_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
 {
-  wmWindowManager *wm = CTX_wm_manager(C);
-  if (U.uiflag & USER_SAVE_PROMPT && !wm->file_saved) {
-    return WM_operator_confirm_messa

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list