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:
parent
c1ec6f00f2
commit
aac95aa1e9
|
@ -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,
|
||||
)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue