Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2010-09-17 13:27:31 +0400
committerCampbell Barton <ideasman42@gmail.com>2010-09-17 13:27:31 +0400
commit5452f335d7fd768fda7320419e3581e5309529fe (patch)
treef80553108d8541e2d070c02fe86778494f31c188 /source
parent945ae254092dcbb284072fd4ffcc80b33bff27f6 (diff)
New optional operator function, check(), it takes the same arguments as execute().
This runs after changing a property and allows correcting incompatible options. Returning True will redraw the UI. Currently this is used for setting the write extension when saving files, so changing the image format also corrects the extension. The same is accessible from python where its used when saving SVG/EPS/PNG files. This fixes: [#23828] obj export problems, [#23760] Exporting OBJ and filetype ending also fixed document submission operator. Now the filename in the file selector is the one used for writing this means we remove the "Save Over" popup which could be overlooked too easily. Instead display the filename field with red tint, and a note in the tooltip.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/intern/exotic.c19
-rw-r--r--source/blender/editors/space_file/file_draw.c14
-rw-r--r--source/blender/editors/space_file/file_intern.h6
-rw-r--r--source/blender/editors/space_file/file_ops.c161
-rw-r--r--source/blender/editors/space_file/file_panels.c6
-rw-r--r--source/blender/editors/space_image/image_ops.c13
-rw-r--r--source/blender/makesrna/intern/rna_wm.c38
-rw-r--r--source/blender/makesrna/intern/rna_wm_api.c9
-rw-r--r--source/blender/windowmanager/WM_types.h6
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c12
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c35
11 files changed, 242 insertions, 77 deletions
diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c
index 973c18531c4..9dac409226b 100644
--- a/source/blender/blenkernel/intern/exotic.c
+++ b/source/blender/blenkernel/intern/exotic.c
@@ -577,15 +577,8 @@ void write_stl(Scene *scene, char *str)
FILE *fpSTL;
int numfacets = 0;
ReportList *reports= NULL; /* XXX */
-
- if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
- if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
- if(BLI_testextensie(str,".stl")==0) strcat(str, ".stl");
- if (BLI_exists(str)) {
- ; //XXX if(saveover(str)==0)
- //XXX return;
- }
+ /* XXX, operator needs to manage filename extension */
fpSTL= fopen(str, "wb");
@@ -872,15 +865,7 @@ void write_dxf(struct Scene *scene, char *str)
Base *base;
FILE *fp;
- if(BLI_testextensie(str,".blend")) str[ strlen(str)-6]= 0;
- if(BLI_testextensie(str,".ble")) str[ strlen(str)-4]= 0;
- if(BLI_testextensie(str,".dxf")==0) strcat(str, ".dxf");
-
-
- if (BLI_exists(str)) {
- ; //XXX if(saveover(str)==0)
- // return;
- }
+ /* XXX, operator needs to handle overwrite & rename */
fp= fopen(str, "w");
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 5f435aa0cbe..0f627bda3dc 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -172,6 +172,10 @@ void file_draw_buttons(const bContext *C, ARegion *ar)
/* Text input fields for directory and file. */
if (available_w > 0) {
+ int overwrite_alert= file_draw_check_exists(sfile);
+ /* callbacks for operator check functions */
+ uiBlockSetFunc(block, file_draw_check_cb, NULL, NULL);
+
but = uiDefBut(block, TEX, B_FS_DIRNAME, "",
min_x, line1_y, line1_w-chan_offs, btn_h,
params->dir, 0.0, (float)FILE_MAX-1, 0, 0,
@@ -182,9 +186,17 @@ void file_draw_buttons(const bContext *C, ARegion *ar)
but = uiDefBut(block, TEX, B_FS_FILENAME, "",
min_x, line2_y, line2_w-chan_offs, btn_h,
params->file, 0.0, (float)FILE_MAXFILE-1, 0, 0,
- "File name.");
+ overwrite_alert ?"File name, overwrite existing." : "File name.");
uiButSetCompleteFunc(but, autocomplete_file, NULL);
uiButSetFlag(but, UI_BUT_NO_UTF8);
+
+ /* check if this overrides a file and if the operator option is used */
+ if(overwrite_alert) {
+ uiButSetFlag(but, UI_BUT_REDALERT);
+ }
+
+ /* clear func */
+ uiBlockSetFunc(block, NULL, NULL, NULL);
}
/* Filename number increment / decrement buttons. */
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index c77379b39a0..07a24454520 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -46,6 +46,9 @@ void file_calc_previews(const bContext *C, ARegion *ar);
void file_draw_previews(const bContext *C, ARegion *ar);
void file_draw_list(const bContext *C, ARegion *ar);
+void file_draw_check_cb(bContext *C, void *arg1, void *arg2);
+int file_draw_check_exists(SpaceFile *sfile);
+
/* file_ops.h */
struct wmOperatorType;
struct wmOperator;
@@ -84,6 +87,9 @@ int file_delete_exec(bContext *C, struct wmOperator *unused);
int file_hilight_set(struct SpaceFile *sfile, struct ARegion *ar, int mx, int my);
+void file_sfile_to_operator(struct wmOperator *op, struct SpaceFile *sfile, char *filepath);
+void file_operator_to_sfile(struct SpaceFile *sfile, struct wmOperator *op);
+
/* filesel.c */
float file_string_width(const char* str);
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 2a50b505c57..c3e9e22eaad 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -206,7 +206,11 @@ static FileSelect file_select(bContext* C, const rcti* rect, short selecting, sh
}
}
- }
+ }
+
+ /* update operator for name change event */
+ file_draw_check_cb(C, NULL, NULL);
+
return retval;
}
@@ -541,6 +545,114 @@ void FILE_OT_cancel(struct wmOperatorType *ot)
ot->poll= file_operator_poll;
}
+
+void file_sfile_to_operator(wmOperator *op, SpaceFile *sfile, char *filepath)
+{
+ BLI_join_dirfile(filepath, sfile->params->dir, sfile->params->file);
+ if(RNA_struct_find_property(op->ptr, "relative_path")) {
+ if(RNA_boolean_get(op->ptr, "relative_path")) {
+ BLI_path_rel(filepath, G.sce);
+ }
+ }
+
+ if(RNA_struct_find_property(op->ptr, "filename")) {
+ RNA_string_set(op->ptr, "filename", sfile->params->file);
+ }
+ if(RNA_struct_find_property(op->ptr, "directory")) {
+ RNA_string_set(op->ptr, "directory", sfile->params->dir);
+ }
+ if(RNA_struct_find_property(op->ptr, "filepath")) {
+ RNA_string_set(op->ptr, "filepath", filepath);
+ }
+
+ /* some ops have multiple files to select */
+ {
+ PointerRNA itemptr;
+ int i, numfiles = filelist_numfiles(sfile->files);
+ struct direntry *file;
+ if(RNA_struct_find_property(op->ptr, "files")) {
+ for (i=0; i<numfiles; i++) {
+ file = filelist_file(sfile->files, i);
+ if(file->flags & ACTIVEFILE) {
+ if ((file->type & S_IFDIR)==0) {
+ RNA_collection_add(op->ptr, "files", &itemptr);
+ RNA_string_set(&itemptr, "name", file->relname);
+ }
+ }
+ }
+ }
+
+ if(RNA_struct_find_property(op->ptr, "dirs")) {
+ for (i=0; i<numfiles; i++) {
+ file = filelist_file(sfile->files, i);
+ if(file->flags & ACTIVEFILE) {
+ if ((file->type & S_IFDIR)) {
+ RNA_collection_add(op->ptr, "dirs", &itemptr);
+ RNA_string_set(&itemptr, "name", file->relname);
+ }
+ }
+ }
+ }
+ }
+}
+
+void file_operator_to_sfile(SpaceFile *sfile, wmOperator *op)
+{
+ int change= FALSE;
+ if(RNA_struct_find_property(op->ptr, "filename")) {
+ RNA_string_get(op->ptr, "filename", sfile->params->file);
+ change= TRUE;
+ }
+ if(RNA_struct_find_property(op->ptr, "directory")) {
+ RNA_string_get(op->ptr, "directory", sfile->params->dir);
+ change= TRUE;
+ }
+
+ /* If neither of the above are set, split the filepath back */
+ if(RNA_struct_find_property(op->ptr, "filepath")) {
+ if(change==FALSE) {
+ char filepath[FILE_MAX];
+ RNA_string_get(op->ptr, "filepath", filepath);
+ BLI_split_dirfile(filepath, sfile->params->dir, sfile->params->file);
+ }
+ }
+
+ /* XXX, files and dirs updates missing, not really so important though */
+}
+
+void file_draw_check_cb(bContext *C, void *dummy1, void *dummy2)
+{
+ SpaceFile *sfile= CTX_wm_space_file(C);
+ wmOperator *op= sfile->op;
+ if(op->type->check) {
+ char filepath[FILE_MAX];
+ file_sfile_to_operator(op, sfile, filepath);
+
+ /* redraw */
+ if(op->type->check(C, op)) {
+ file_operator_to_sfile(sfile, op);
+
+ /* redraw, else the changed settings wont get updated */
+ ED_area_tag_redraw(CTX_wm_area(C));
+ }
+ }
+}
+
+int file_draw_check_exists(SpaceFile *sfile)
+{
+ if(RNA_struct_find_property(sfile->op->ptr, "check_existing")) {
+ if(RNA_boolean_get(sfile->op->ptr, "check_existing")) {
+ char filepath[FILE_MAX];
+ BLI_join_dirfile(filepath, sfile->params->dir, sfile->params->file);
+ if(BLI_exists(filepath) && !BLI_is_dir(filepath)) {
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
/* sends events now, so things get handled on windowqueue level */
int file_exec(bContext *C, wmOperator *exec_op)
{
@@ -568,53 +680,8 @@ int file_exec(bContext *C, wmOperator *exec_op)
sfile->op = NULL;
- BLI_join_dirfile(filepath, sfile->params->dir, sfile->params->file);
- if(RNA_struct_find_property(op->ptr, "relative_path")) {
- if(RNA_boolean_get(op->ptr, "relative_path")) {
- BLI_path_rel(filepath, G.sce);
- }
- }
+ file_sfile_to_operator(op, sfile, filepath);
- if(RNA_struct_find_property(op->ptr, "filename")) {
- RNA_string_set(op->ptr, "filename", sfile->params->file);
- }
- if(RNA_struct_find_property(op->ptr, "directory")) {
- RNA_string_set(op->ptr, "directory", sfile->params->dir);
- }
- if(RNA_struct_find_property(op->ptr, "filepath")) {
- RNA_string_set(op->ptr, "filepath", filepath);
- }
-
- /* some ops have multiple files to select */
- {
- PointerRNA itemptr;
- int i, numfiles = filelist_numfiles(sfile->files);
- struct direntry *file;
- if(RNA_struct_find_property(op->ptr, "files")) {
- for (i=0; i<numfiles; i++) {
- file = filelist_file(sfile->files, i);
- if(file->flags & ACTIVEFILE) {
- if ((file->type & S_IFDIR)==0) {
- RNA_collection_add(op->ptr, "files", &itemptr);
- RNA_string_set(&itemptr, "name", file->relname);
- }
- }
- }
- }
-
- if(RNA_struct_find_property(op->ptr, "dirs")) {
- for (i=0; i<numfiles; i++) {
- file = filelist_file(sfile->files, i);
- if(file->flags & ACTIVEFILE) {
- if ((file->type & S_IFDIR)) {
- RNA_collection_add(op->ptr, "dirs", &itemptr);
- RNA_string_set(&itemptr, "name", file->relname);
- }
- }
- }
- }
- }
-
folderlist_free(sfile->folders_prev);
folderlist_free(sfile->folders_next);
diff --git a/source/blender/editors/space_file/file_panels.c b/source/blender/editors/space_file/file_panels.c
index 4a505bc022f..33d740e18a6 100644
--- a/source/blender/editors/space_file/file_panels.c
+++ b/source/blender/editors/space_file/file_panels.c
@@ -170,7 +170,9 @@ static void file_panel_operator(const bContext *C, Panel *pa)
SpaceFile *sfile= CTX_wm_space_file(C);
wmOperator *op= sfile->op;
int empty= 1, flag;
-
+
+ uiBlockSetFunc(uiLayoutGetBlock(pa->layout), file_draw_check_cb, NULL, NULL);
+
if(op->type->ui) {
op->layout= pa->layout;
op->type->ui((bContext*)C, op);
@@ -197,6 +199,8 @@ static void file_panel_operator(const bContext *C, Panel *pa)
if(empty)
uiItemL(pa->layout, "No properties.", 0);
}
+
+ uiBlockSetFunc(uiLayoutGetBlock(pa->layout), NULL, NULL, NULL);
}
void file_panels_register(ARegionType *art)
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 11b39af2e03..5a7e2e6fa1b 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -960,6 +960,18 @@ static int save_as_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+
+static int save_as_check(bContext *C, wmOperator *op)
+{
+ char filepath[FILE_MAX];
+ RNA_string_get(op->ptr, "filepath", filepath);
+ if(BKE_add_image_extension(filepath, RNA_enum_get(op->ptr, "file_type"))) {
+ RNA_string_set(op->ptr, "filepath", filepath);
+ return TRUE;
+ }
+ return FALSE;
+}
+
static int save_as_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
SpaceImage *sima= CTX_wm_space_image(C);
@@ -1022,6 +1034,7 @@ void IMAGE_OT_save_as(wmOperatorType *ot)
/* api callbacks */
ot->exec= save_as_exec;
+ ot->check= save_as_check;
ot->invoke= save_as_invoke;
ot->poll= space_image_buffer_exists_poll;
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 900a1fd60cf..62d0c99f6c5 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -697,7 +697,7 @@ static int operator_poll(bContext *C, wmOperatorType *ot)
return visible;
}
-static int operator_exec(bContext *C, wmOperator *op)
+static int operator_execute(bContext *C, wmOperator *op)
{
PointerRNA opr;
ParameterList list;
@@ -720,6 +720,30 @@ static int operator_exec(bContext *C, wmOperator *op)
return result;
}
+/* same as execute() but no return value */
+static int operator_check(bContext *C, wmOperator *op)
+{
+ PointerRNA opr;
+ ParameterList list;
+ FunctionRNA *func;
+ void *ret;
+ int result;
+
+ RNA_pointer_create(&CTX_wm_screen(C)->id, op->type->ext.srna, op, &opr);
+ func= RNA_struct_find_function(&opr, "check");
+
+ RNA_parameter_list_create(&list, &opr, func);
+ RNA_parameter_set_lookup(&list, "context", &C);
+ op->type->ext.call(&opr, func, &list);
+
+ RNA_parameter_get_lookup(&list, "result", &ret);
+ result= *(int*)ret;
+
+ RNA_parameter_list_free(&list);
+
+ return result;
+}
+
static int operator_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
PointerRNA opr;
@@ -796,7 +820,7 @@ static StructRNA *rna_Operator_register(const bContext *C, ReportList *reports,
wmOperatorType dummyot = {0};
wmOperator dummyop= {0};
PointerRNA dummyotr;
- int have_function[5];
+ int have_function[6];
/* setup dummy operator & operator type to store static properties in */
dummyop.type= &dummyot;
@@ -846,11 +870,11 @@ static StructRNA *rna_Operator_register(const bContext *C, ReportList *reports,
dummyot.ext.free= free;
dummyot.pyop_poll= (have_function[0])? operator_poll: NULL;
- dummyot.exec= (have_function[1])? operator_exec: NULL;
- dummyot.invoke= (have_function[2])? operator_invoke: NULL;
- dummyot.modal= (have_function[3])? operator_modal: NULL;
- dummyot.ui= (have_function[4])? operator_draw: NULL;
-
+ dummyot.exec= (have_function[1])? operator_execute: NULL;
+ dummyot.check= (have_function[2])? operator_check: NULL;
+ dummyot.invoke= (have_function[3])? operator_invoke: NULL;
+ dummyot.modal= (have_function[4])? operator_modal: NULL;
+ dummyot.ui= (have_function[5])? operator_draw: NULL;
WM_operatortype_append_ptr(operator_wrapper, (void *)&dummyot);
/* update while blender is running */
diff --git a/source/blender/makesrna/intern/rna_wm_api.c b/source/blender/makesrna/intern/rna_wm_api.c
index b13d7627a34..36dd6efc256 100644
--- a/source/blender/makesrna/intern/rna_wm_api.c
+++ b/source/blender/makesrna/intern/rna_wm_api.c
@@ -165,6 +165,15 @@ void RNA_api_operator(StructRNA *srna)
RNA_def_property_flag(parm, PROP_ENUM_FLAG);
RNA_def_function_return(func, parm);
+ /* check */
+ func= RNA_def_function(srna, "check", NULL);
+ RNA_def_function_ui_description(func, "Check the operator settings.");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
+ RNA_def_pointer(func, "context", "Context", "", "");
+
+ parm= RNA_def_boolean(func, "result", 0, "result", ""); // better name?
+ RNA_def_function_return(func, parm);
+
/* invoke */
func= RNA_def_function(srna, "invoke", NULL);
RNA_def_function_ui_description(func, "Invoke the operator.");
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 807125765f7..a732524ca03 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -385,6 +385,12 @@ typedef struct wmOperatorType {
* any interface code or input device state.
* - see defines below for return values */
int (*exec)(struct bContext *, struct wmOperator *);
+
+ /* this callback executes on a running operator whenever as property
+ * is changed. It can correct its own properties or report errors for
+ * invalid settings in exceptional cases.
+ * Boolean return value, True denotes a change has been made and to redraw */
+ int (*check)(struct bContext *, struct wmOperator *);
/* for modal temporary operators, initially invoke is called. then
* any further events are handled in modal. if the operation is
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 6e8ab87f640..c32fb372ffd 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -1241,6 +1241,8 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
/* needed for uiPupMenuReports */
if(event->val==EVT_FILESELECT_EXEC) {
+#if 0 // use REDALERT now
+
/* a bit weak, might become arg for WM_event_fileselect? */
/* XXX also extension code in image-save doesnt work for this yet */
if (RNA_struct_find_property(handler->op->ptr, "check_existing") &&
@@ -1251,7 +1253,9 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa
if(path)
MEM_freeN(path);
}
- else {
+ else
+#endif
+ {
int retval;
if(handler->op->type->flag & OPTYPE_UNDO)
@@ -1820,6 +1824,12 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op)
BLI_addhead(&win->modalhandlers, handler);
+ /* check props once before invoking if check is available
+ * ensures initial properties are valid */
+ if(op->type->check) {
+ op->type->check(C, op); /* ignore return value */
+ }
+
WM_event_fileselect_event(C, op, full?EVT_FILESELECT_FULL_OPEN:EVT_FILESELECT_OPEN);
}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 95ab84c9192..b84b7eab55f 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -928,6 +928,16 @@ static void dialog_exec_cb(bContext *C, void *arg1, void *arg2)
uiPupBlockClose(C, block);
}
+void dialog_check_cb(bContext *C, void *op_ptr, void *dummy2)
+{
+ wmOperator *op= op_ptr;
+ if(op->type->check) {
+ if(op->type->check(C, op)) {
+ /* refresh */
+ }
+ }
+}
+
/* Dialogs are popups that require user verification (click OK) before exec */
static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData)
{
@@ -953,6 +963,8 @@ static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData)
RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
layout= uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, style);
uiItemL(layout, op->type->name, 0);
+
+ uiBlockSetFunc(block, dialog_check_cb, op, NULL);
if (op->type->ui) {
op->layout= layout;
@@ -961,6 +973,8 @@ static uiBlock *wm_block_create_dialog(bContext *C, ARegion *ar, void *userData)
}
else
uiDefAutoButsRNA(C, layout, &ptr, columns);
+
+ uiBlockSetFunc(block, NULL, NULL, NULL);
/* Create OK button, the callback of which will execute op */
btn= uiDefBut(block, BUT, 0, "OK", 0, 0, 0, 20, NULL, 0, 0, 0, 0, "");
@@ -1799,6 +1813,18 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+/* function used for WM_OT_save_mainfile too */
+static int blend_save_check(bContext *C, wmOperator *op)
+{
+ char filepath[FILE_MAX];
+ RNA_string_get(op->ptr, "filepath", filepath);
+ if(BLI_replace_extension(filepath, sizeof(filepath), ".blend")) {
+ RNA_string_set(op->ptr, "filepath", filepath);
+ return TRUE;
+ }
+ return FALSE;
+}
+
static void WM_OT_save_as_mainfile(wmOperatorType *ot)
{
ot->name= "Save As Blender File";
@@ -1807,6 +1833,7 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot)
ot->invoke= wm_save_as_mainfile_invoke;
ot->exec= wm_save_as_mainfile_exec;
+ ot->check= blend_save_check;
ot->poll= WM_operator_winactive;
WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH);
@@ -1857,6 +1884,7 @@ static void WM_OT_save_mainfile(wmOperatorType *ot)
ot->invoke= wm_save_mainfile_invoke;
ot->exec= wm_save_as_mainfile_exec;
+ ot->check= blend_save_check;
ot->poll= NULL;
WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH);
@@ -1872,9 +1900,10 @@ static void WM_OT_save_mainfile(wmOperatorType *ot)
static int wm_collada_export_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
if(!RNA_property_is_set(op->ptr, "filepath")) {
- char *path = BLI_replacestr(G.sce, ".blend", ".dae");
- RNA_string_set(op->ptr, "filepath", path);
- MEM_freeN(path);
+ char *filepath[FILE_MAX];
+ BLI_strncpy(filepath, G.sce, sizeof(filepath));
+ BLI_replace_extension(filepath, sizeof(filepath), ".dae");
+ RNA_string_set(op->ptr, "filepath", filepath);
}
WM_event_add_fileselect(C, op);