Images: move save modified images operator from Python to C

We will use this for saving images along with the .blend file.

Ref D4861
This commit is contained in:
Brecht Van Lommel 2019-05-16 16:01:11 +02:00
parent c1ec6f00f2
commit aac95aa1e9
7 changed files with 127 additions and 37 deletions

View File

@ -115,39 +115,6 @@ class EditExternally(Operator):
return {'FINISHED'}
class SaveDirty(Operator):
"""Save all modified textures"""
bl_idname = "image.save_dirty"
bl_label = "Save Dirty"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, _context):
unique_paths = set()
for image in bpy.data.images:
if image.is_dirty:
if image.packed_file:
if image.library:
self.report({'WARNING'},
"Packed library image: %r from library %r"
" can't be re-packed" %
(image.name, image.library.filepath))
else:
image.pack()
else:
filepath = bpy.path.abspath(image.filepath,
library=image.library)
if "\\" not in filepath and "/" not in filepath:
self.report({'WARNING'}, "Invalid path: " + filepath)
elif filepath in unique_paths:
self.report({'WARNING'},
"Path used by more than one image: %r" %
filepath)
else:
unique_paths.add(filepath)
image.save()
return {'FINISHED'}
class ProjectEdit(Operator):
"""Edit a snapshot of the view-port in an external image editor"""
bl_idname = "image.project_edit"
@ -248,5 +215,4 @@ classes = (
EditExternally,
ProjectApply,
ProjectEdit,
SaveDirty,
)

View File

@ -230,7 +230,7 @@ class IMAGE_MT_image(Menu):
if ima and ima.source == 'SEQUENCE':
layout.operator("image.save_sequence")
layout.operator("image.save_dirty", text="Save All Images")
layout.operator("image.save_all_modified", text="Save All Images")
if ima:
layout.separator()

View File

@ -645,7 +645,7 @@ class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
split.operator("paint.add_simple_uvs", icon='ADD', text="Add Simple UVs")
elif have_image:
layout.separator()
layout.operator("image.save_dirty", text="Save All Images", icon='FILE_TICK')
layout.operator("image.save_all_modified", text="Save All Images", icon='FILE_TICK')
# TODO, move to space_view3d.py

View File

@ -28,6 +28,7 @@ struct ARegion;
struct ImBuf;
struct Image;
struct ImageUser;
struct ReportList;
struct Scene;
struct SpaceImage;
struct ToolSettings;
@ -110,4 +111,7 @@ void ED_image_draw_info(struct Scene *scene,
bool ED_space_image_show_cache(struct SpaceImage *sima);
int ED_image_save_all_modified_count(const struct bContext *C);
bool ED_image_save_all_modified(const struct bContext *C, struct ReportList *reports);
#endif /* __ED_IMAGE_H__ */

View File

@ -66,6 +66,7 @@ void IMAGE_OT_reload(struct wmOperatorType *ot);
void IMAGE_OT_save(struct wmOperatorType *ot);
void IMAGE_OT_save_as(struct wmOperatorType *ot);
void IMAGE_OT_save_sequence(struct wmOperatorType *ot);
void IMAGE_OT_save_all_modified(struct wmOperatorType *ot);
void IMAGE_OT_pack(struct wmOperatorType *ot);
void IMAGE_OT_unpack(struct wmOperatorType *ot);

View File

@ -34,8 +34,10 @@
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
@ -2157,6 +2159,122 @@ void IMAGE_OT_save_sequence(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/********************** save all operator **********************/
int ED_image_save_all_modified_count(const bContext *C)
{
Main *bmain = CTX_data_main(C);
int num_files = 0;
for (Image *ima = bmain->images.first; ima; ima = ima->id.next) {
if (ELEM(ima->type, IMA_TYPE_R_RESULT, IMA_TYPE_COMPOSITE)) {
continue;
}
else if (BKE_image_is_dirty(ima)) {
if (ima->source == IMA_SRC_FILE && !BKE_image_has_packedfile(ima)) {
num_files++;
}
}
}
return num_files;
}
bool ED_image_save_all_modified(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;
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 (BKE_image_has_packedfile(ima)) {
if (ima->id.lib == NULL) {
/* Re-pack. */
BKE_image_memorypack(ima);
}
else {
/* Can't pack to library data. */
BKE_reportf(reports,
RPT_ERROR,
"Packed library image: %s from library %s can't be saved",
ima->id.name,
ima->id.lib->name);
}
}
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)) {
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;
}
else {
BKE_reportf(reports,
RPT_WARNING,
"File path used by more than one saved image: %s",
opts.filepath);
}
}
}
else {
BKE_reportf(reports,
RPT_ERROR,
"Image %s can't be saved, no valid file path: %s",
ima->id.name,
ima->name);
}
}
}
}
BLI_gset_free(unique_paths, MEM_freeN);
return ok;
}
static int image_save_all_modified_exec(bContext *C, wmOperator *op)
{
ED_image_save_all_modified(C, op->reports);
return OPERATOR_FINISHED;
}
static bool image_save_all_modified_poll(bContext *C)
{
return (ED_image_save_all_modified_count(C) > 0);
}
void IMAGE_OT_save_all_modified(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Save All Modified";
ot->idname = "IMAGE_OT_save_all_modified";
ot->description = "Save all modified images";
/* api callbacks */
ot->exec = image_save_all_modified_exec;
ot->poll = image_save_all_modified_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/******************** reload image operator ********************/
static int image_reload_exec(bContext *C, wmOperator *UNUSED(op))

View File

@ -224,6 +224,7 @@ static void image_operatortypes(void)
WM_operatortype_append(IMAGE_OT_save);
WM_operatortype_append(IMAGE_OT_save_as);
WM_operatortype_append(IMAGE_OT_save_sequence);
WM_operatortype_append(IMAGE_OT_save_all_modified);
WM_operatortype_append(IMAGE_OT_pack);
WM_operatortype_append(IMAGE_OT_unpack);