UI: use "Save As" when saving un-saved image/text files
Now the behaviors are consistent for blend, image and text files: - If the file is not writable, will report it. - If the file is new (without a path), save as will be used. - If the file was deleted, will try to recreate it. Ref D6755
This commit is contained in:
parent
cf78053027
commit
d26b746e36
|
@ -2047,36 +2047,17 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
|
|||
/** \name Save Image Operator
|
||||
* \{ */
|
||||
|
||||
static bool image_file_path_saveable(bContext *C, Image *ima, ImageUser *iuser)
|
||||
/**
|
||||
* \param iuser: Image user or NULL when called outside the image space.
|
||||
*/
|
||||
static bool image_file_format_writable(Image *ima, ImageUser *iuser)
|
||||
{
|
||||
/* Can always repack images. */
|
||||
if (BKE_image_has_packedfile(ima)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Test for valid filepath. */
|
||||
void *lock;
|
||||
ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, &lock);
|
||||
bool ret = false;
|
||||
|
||||
if (ibuf) {
|
||||
Main *bmain = CTX_data_main(C);
|
||||
char name[FILE_MAX];
|
||||
BLI_strncpy(name, ibuf->name, FILE_MAX);
|
||||
BLI_path_abs(name, BKE_main_blendfile_path(bmain));
|
||||
|
||||
if (BLI_exists(name) == false) {
|
||||
CTX_wm_operator_poll_msg_set(C, "image file not found");
|
||||
}
|
||||
else if (!BLI_file_is_writable(name)) {
|
||||
CTX_wm_operator_poll_msg_set(C, "image path can't be written to");
|
||||
}
|
||||
else if (!BKE_image_buffer_format_writable(ibuf)) {
|
||||
CTX_wm_operator_poll_msg_set(C, "image format is read-only");
|
||||
}
|
||||
else {
|
||||
ret = true;
|
||||
}
|
||||
if (ibuf && BKE_image_buffer_format_writable(ibuf)) {
|
||||
ret = true;
|
||||
}
|
||||
|
||||
BKE_image_release_ibuf(ima, ibuf, lock);
|
||||
|
@ -2090,16 +2071,12 @@ static bool image_save_poll(bContext *C)
|
|||
return false;
|
||||
}
|
||||
|
||||
Image *ima = image_from_context(C);
|
||||
ImageUser *iuser = image_user_from_context(C);
|
||||
/* Check if there is a valid file path and image format we can write
|
||||
* outside of the 'poll' so we can show a report with a pop-up. */
|
||||
|
||||
/* Images without a filepath will go to save as. */
|
||||
if (!BKE_image_has_filepath(ima)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Check if there is a valid file path and image format we can write. */
|
||||
return image_file_path_saveable(C, ima, iuser);
|
||||
/* Can always repack images.
|
||||
* Images without a filepath will go to "Save As". */
|
||||
return true;
|
||||
}
|
||||
|
||||
static int image_save_exec(bContext *C, wmOperator *op)
|
||||
|
@ -2114,6 +2091,8 @@ static int image_save_exec(bContext *C, wmOperator *op)
|
|||
if (BKE_image_has_packedfile(image)) {
|
||||
/* Save packed files to memory. */
|
||||
BKE_image_memorypack(image);
|
||||
/* Report since this can be called from key shortcuts. */
|
||||
BKE_reportf(op->reports, RPT_INFO, "Packed to memory image \"%s\"", image->filepath);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
@ -2123,16 +2102,15 @@ static int image_save_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
image_save_options_from_op(bmain, &opts, op, NULL);
|
||||
|
||||
if (BLI_exists(opts.filepath) && BLI_file_is_writable(opts.filepath)) {
|
||||
if (save_image_op(bmain, image, iuser, op, &opts)) {
|
||||
/* report since this can be called from key-shortcuts */
|
||||
BKE_reportf(op->reports, RPT_INFO, "Saved Image '%s'", opts.filepath);
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Check if file write permission is ok. */
|
||||
if (BLI_exists(opts.filepath) && !BLI_file_is_writable(opts.filepath)) {
|
||||
BKE_reportf(
|
||||
op->reports, RPT_ERROR, "Cannot save image, path '%s' is not writable", opts.filepath);
|
||||
op->reports, RPT_ERROR, "Cannot save image, path \"%s\" is not writable", opts.filepath);
|
||||
}
|
||||
else if (save_image_op(bmain, image, iuser, op, &opts)) {
|
||||
/* Report since this can be called from key shortcuts. */
|
||||
BKE_reportf(op->reports, RPT_INFO, "Saved image \"%s\"", opts.filepath);
|
||||
ok = true;
|
||||
}
|
||||
|
||||
BKE_color_managed_view_settings_free(&opts.im_format.view_settings);
|
||||
|
@ -2147,8 +2125,11 @@ static int image_save_exec(bContext *C, wmOperator *op)
|
|||
static int image_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
Image *ima = image_from_context(C);
|
||||
ImageUser *iuser = image_user_from_context(C);
|
||||
|
||||
if (!BKE_image_has_packedfile(ima) && !BKE_image_has_filepath(ima)) {
|
||||
/* Not writable formats or images without a file-path will go to "Save As". */
|
||||
if (!BKE_image_has_packedfile(ima) &&
|
||||
(!BKE_image_has_filepath(ima) || !image_file_format_writable(ima, iuser))) {
|
||||
WM_operator_name_call(C, "IMAGE_OT_save_as", WM_OP_INVOKE_DEFAULT, NULL);
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
|
|
@ -573,17 +573,6 @@ void TEXT_OT_make_internal(wmOperatorType *ot)
|
|||
/** \name Save Operator
|
||||
* \{ */
|
||||
|
||||
static bool text_save_poll(bContext *C)
|
||||
{
|
||||
Text *text = CTX_data_edit_text(C);
|
||||
|
||||
if (!text_edit_poll(C)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (text->filepath != NULL && !(text->flags & TXT_ISMEM));
|
||||
}
|
||||
|
||||
static void txt_write_file(Main *bmain, Text *text, ReportList *reports)
|
||||
{
|
||||
FILE *fp;
|
||||
|
@ -594,6 +583,13 @@ static void txt_write_file(Main *bmain, Text *text, ReportList *reports)
|
|||
BLI_strncpy(filepath, text->filepath, FILE_MAX);
|
||||
BLI_path_abs(filepath, BKE_main_blendfile_path(bmain));
|
||||
|
||||
/* Check if file write permission is ok. */
|
||||
if (BLI_exists(filepath) && !BLI_file_is_writable(filepath)) {
|
||||
BKE_reportf(
|
||||
reports, RPT_ERROR, "Cannot save text file, path \"%s\" is not writable", filepath);
|
||||
return;
|
||||
}
|
||||
|
||||
fp = BLI_fopen(filepath, "w");
|
||||
if (fp == NULL) {
|
||||
BKE_reportf(reports,
|
||||
|
@ -616,8 +612,8 @@ static void txt_write_file(Main *bmain, Text *text, ReportList *reports)
|
|||
if (BLI_stat(filepath, &st) == 0) {
|
||||
text->mtime = st.st_mtime;
|
||||
|
||||
/* report since this can be called from key-shortcuts */
|
||||
BKE_reportf(reports, RPT_INFO, "Saved Text '%s'", filepath);
|
||||
/* Report since this can be called from key shortcuts. */
|
||||
BKE_reportf(reports, RPT_INFO, "Saved text \"%s\"", filepath);
|
||||
}
|
||||
else {
|
||||
text->mtime = 0;
|
||||
|
@ -644,6 +640,18 @@ static int text_save_exec(bContext *C, wmOperator *op)
|
|||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int text_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
Text *text = CTX_data_edit_text(C);
|
||||
|
||||
/* Internal and texts without a filepath will go to "Save As". */
|
||||
if (text->filepath == NULL || (text->flags & TXT_ISMEM)) {
|
||||
WM_operator_name_call(C, "TEXT_OT_save_as", WM_OP_INVOKE_DEFAULT, NULL);
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
return text_save_exec(C, op);
|
||||
}
|
||||
|
||||
void TEXT_OT_save(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
|
@ -653,7 +661,8 @@ void TEXT_OT_save(wmOperatorType *ot)
|
|||
|
||||
/* api callbacks */
|
||||
ot->exec = text_save_exec;
|
||||
ot->poll = text_save_poll;
|
||||
ot->invoke = text_save_invoke;
|
||||
ot->poll = text_edit_poll;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -3781,6 +3790,17 @@ static const EnumPropertyItem resolution_items[] = {
|
|||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
static bool text_resolve_conflict_poll(bContext *C)
|
||||
{
|
||||
Text *text = CTX_data_edit_text(C);
|
||||
|
||||
if (!text_edit_poll(C)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((text->filepath != NULL) && !(text->flags & TXT_ISMEM));
|
||||
}
|
||||
|
||||
static int text_resolve_conflict_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Text *text = CTX_data_edit_text(C);
|
||||
|
@ -3872,7 +3892,7 @@ void TEXT_OT_resolve_conflict(wmOperatorType *ot)
|
|||
/* api callbacks */
|
||||
ot->exec = text_resolve_conflict_exec;
|
||||
ot->invoke = text_resolve_conflict_invoke;
|
||||
ot->poll = text_save_poll;
|
||||
ot->poll = text_resolve_conflict_poll;
|
||||
|
||||
/* properties */
|
||||
RNA_def_enum(ot->srna,
|
||||
|
|
Loading…
Reference in New Issue