diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2016-04-19 18:08:31 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2016-04-19 23:53:18 +0300 |
commit | 52e09ed4f93b21aee8643de2f8b53e9fa7c99543 (patch) | |
tree | a711758277e06071c69abd1c92f24fa540269cd3 /source/blender/windowmanager/intern/wm_operators.c | |
parent | dd423a6818cc8132ba073dfbeb66cb40d3f09611 (diff) |
Cleanup: move operators & related code of files & append/link to relevant dedicated source files.
This commit adds a new `wm_files_link.c` which contains everything related to append/link code,
moved from `wm_operators.c` (rather small currently, but will expand quite a bit with future reload & asset works).
It also moves all load/save .bland files (and related userpref/startup stuff) from `wm_operators.c`
to `wm_files.c` (some helper funcs were already there).
This also makes `wm_operators.c` significantly lighter.
Diffstat (limited to 'source/blender/windowmanager/intern/wm_operators.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 1020 |
1 files changed, 0 insertions, 1020 deletions
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index b5ad027148a..fdb6db66577 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -52,7 +52,6 @@ #include "DNA_scene_types.h" #include "DNA_userdef_types.h" #include "DNA_windowmanager_types.h" -#include "DNA_mesh_types.h" /* only for USE_BMESH_SAVE_AS_COMPAT */ #include "BLT_translation.h" @@ -2073,1025 +2072,6 @@ static void WM_OT_window_duplicate(wmOperatorType *ot) ot->poll = wm_operator_winactive_normal; } -static void WM_OT_save_homefile(wmOperatorType *ot) -{ - ot->name = "Save Startup File"; - ot->idname = "WM_OT_save_homefile"; - ot->description = "Make the current file the default .blend file, includes preferences"; - - ot->invoke = WM_operator_confirm; - ot->exec = wm_homefile_write_exec; -} - -static int wm_userpref_autoexec_add_exec(bContext *UNUSED(C), wmOperator *UNUSED(op)) -{ - bPathCompare *path_cmp = MEM_callocN(sizeof(bPathCompare), "bPathCompare"); - BLI_addtail(&U.autoexec_paths, path_cmp); - return OPERATOR_FINISHED; -} - -static void WM_OT_userpref_autoexec_path_add(wmOperatorType *ot) -{ - ot->name = "Add Autoexec Path"; - ot->idname = "WM_OT_userpref_autoexec_path_add"; - ot->description = "Add path to exclude from autoexecution"; - - ot->exec = wm_userpref_autoexec_add_exec; - - ot->flag = OPTYPE_INTERNAL; -} - -static int wm_userpref_autoexec_remove_exec(bContext *UNUSED(C), wmOperator *op) -{ - const int index = RNA_int_get(op->ptr, "index"); - bPathCompare *path_cmp = BLI_findlink(&U.autoexec_paths, index); - if (path_cmp) { - BLI_freelinkN(&U.autoexec_paths, path_cmp); - } - return OPERATOR_FINISHED; -} - -static void WM_OT_userpref_autoexec_path_remove(wmOperatorType *ot) -{ - ot->name = "Remove Autoexec Path"; - ot->idname = "WM_OT_userpref_autoexec_path_remove"; - ot->description = "Remove path to exclude from autoexecution"; - - ot->exec = wm_userpref_autoexec_remove_exec; - - ot->flag = OPTYPE_INTERNAL; - - RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "", 0, 1000); -} - -static void WM_OT_save_userpref(wmOperatorType *ot) -{ - ot->name = "Save User Settings"; - ot->idname = "WM_OT_save_userpref"; - ot->description = "Save user preferences separately, overrides startup file preferences"; - - ot->invoke = WM_operator_confirm; - ot->exec = wm_userpref_write_exec; -} - -static void WM_OT_read_history(wmOperatorType *ot) -{ - ot->name = "Reload History File"; - ot->idname = "WM_OT_read_history"; - ot->description = "Reloads history and bookmarks"; - - ot->invoke = WM_operator_confirm; - ot->exec = wm_history_file_read_exec; - - /* this operator is only used for loading settings from a previous blender install */ - ot->flag = OPTYPE_INTERNAL; -} - -static void WM_OT_read_homefile(wmOperatorType *ot) -{ - PropertyRNA *prop; - ot->name = "Reload Start-Up File"; - ot->idname = "WM_OT_read_homefile"; - ot->description = "Open the default file (doesn't save the current file)"; - - ot->invoke = WM_operator_confirm; - ot->exec = wm_homefile_read_exec; - - prop = RNA_def_string_file_path(ot->srna, "filepath", NULL, - FILE_MAX, "File Path", - "Path to an alternative start-up file"); - RNA_def_property_flag(prop, PROP_HIDDEN); - - /* So scripts can use an alternative start-up file without the UI */ - prop = RNA_def_boolean(ot->srna, "load_ui", true, "Load UI", - "Load user interface setup from the .blend file"); - RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); - - /* omit poll to run in background mode */ -} - -static void WM_OT_read_factory_settings(wmOperatorType *ot) -{ - ot->name = "Load Factory Settings"; - ot->idname = "WM_OT_read_factory_settings"; - ot->description = "Load default file and user preferences"; - - ot->invoke = WM_operator_confirm; - ot->exec = wm_homefile_read_exec; - /* omit poll to run in background mode */ -} - -/* *************** open file **************** */ - -/** - * Wrap #WM_file_read, shared by file reading operators. - */ -static bool wm_file_read_opwrap(bContext *C, const char *filepath, ReportList *reports, - const bool autoexec_init) -{ - bool success; - - /* XXX wm in context is not set correctly after WM_file_read -> crash */ - /* do it before for now, but is this correct with multiple windows? */ - WM_event_add_notifier(C, NC_WINDOW, NULL); - - if (autoexec_init) { - WM_file_autoexec_init(filepath); - } - - success = WM_file_read(C, filepath, reports); - - return success; -} - -/* currently fits in a pointer */ -struct FileRuntime { - bool is_untrusted; -}; - -static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - const char *openname = G.main->name; - - if (CTX_wm_window(C) == NULL) { - /* in rare cases this could happen, when trying to invoke in background - * mode on load for example. Don't use poll for this because exec() - * can still run without a window */ - BKE_report(op->reports, RPT_ERROR, "Context window not set"); - return OPERATOR_CANCELLED; - } - - /* if possible, get the name of the most recently used .blend file */ - if (G.recent_files.first) { - struct RecentFile *recent = G.recent_files.first; - openname = recent->filepath; - } - - RNA_string_set(op->ptr, "filepath", openname); - wm_open_init_load_ui(op, true); - wm_open_init_use_scripts(op, true); - op->customdata = NULL; - - WM_event_add_fileselect(C, op); - - return OPERATOR_RUNNING_MODAL; -} - -static int wm_open_mainfile_exec(bContext *C, wmOperator *op) -{ - char filepath[FILE_MAX]; - bool success; - - RNA_string_get(op->ptr, "filepath", filepath); - - /* re-use last loaded setting so we can reload a file without changing */ - wm_open_init_load_ui(op, false); - wm_open_init_use_scripts(op, false); - - if (RNA_boolean_get(op->ptr, "load_ui")) - G.fileflags &= ~G_FILE_NO_UI; - else - G.fileflags |= G_FILE_NO_UI; - - if (RNA_boolean_get(op->ptr, "use_scripts")) - G.f |= G_SCRIPT_AUTOEXEC; - else - G.f &= ~G_SCRIPT_AUTOEXEC; - - success = wm_file_read_opwrap(C, filepath, op->reports, !(G.f & G_SCRIPT_AUTOEXEC)); - - /* for file open also popup for warnings, not only errors */ - BKE_report_print_level_set(op->reports, RPT_WARNING); - - if (success) { - return OPERATOR_FINISHED; - } - else { - return OPERATOR_CANCELLED; - } -} - -static bool wm_open_mainfile_check(bContext *UNUSED(C), wmOperator *op) -{ - struct FileRuntime *file_info = (struct FileRuntime *)&op->customdata; - PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_scripts"); - bool is_untrusted = false; - char path[FILE_MAX]; - char *lslash; - - RNA_string_get(op->ptr, "filepath", path); - - /* get the dir */ - lslash = (char *)BLI_last_slash(path); - if (lslash) *(lslash + 1) = '\0'; - - if ((U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0) { - if (BKE_autoexec_match(path) == true) { - RNA_property_boolean_set(op->ptr, prop, false); - is_untrusted = true; - } - } - - if (file_info) { - file_info->is_untrusted = is_untrusted; - } - - return is_untrusted; -} - -static void wm_open_mainfile_ui(bContext *UNUSED(C), wmOperator *op) -{ - struct FileRuntime *file_info = (struct FileRuntime *)&op->customdata; - uiLayout *layout = op->layout; - uiLayout *col = op->layout; - const char *autoexec_text; - - uiItemR(layout, op->ptr, "load_ui", 0, NULL, ICON_NONE); - - col = uiLayoutColumn(layout, false); - if (file_info->is_untrusted) { - autoexec_text = IFACE_("Trusted Source [Untrusted Path]"); - uiLayoutSetActive(col, false); - uiLayoutSetEnabled(col, false); - } - else { - autoexec_text = IFACE_("Trusted Source"); - } - - uiItemR(col, op->ptr, "use_scripts", 0, autoexec_text, ICON_NONE); -} - -static void WM_OT_open_mainfile(wmOperatorType *ot) -{ - ot->name = "Open Blender File"; - ot->idname = "WM_OT_open_mainfile"; - ot->description = "Open a Blender file"; - - ot->invoke = wm_open_mainfile_invoke; - ot->exec = wm_open_mainfile_exec; - ot->check = wm_open_mainfile_check; - ot->ui = wm_open_mainfile_ui; - /* omit window poll so this can work in background mode */ - - WM_operator_properties_filesel( - ot, FILE_TYPE_FOLDER | FILE_TYPE_BLENDER, FILE_BLENDER, FILE_OPENFILE, - WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA); - - RNA_def_boolean(ot->srna, "load_ui", true, "Load UI", "Load user interface setup in the .blend file"); - RNA_def_boolean(ot->srna, "use_scripts", true, "Trusted Source", - "Allow .blend file to execute scripts automatically, default available from system preferences"); -} - - -/* *************** revert file **************** */ - -static int wm_revert_mainfile_exec(bContext *C, wmOperator *op) -{ - bool success; - - wm_open_init_use_scripts(op, false); - - if (RNA_boolean_get(op->ptr, "use_scripts")) - G.f |= G_SCRIPT_AUTOEXEC; - else - G.f &= ~G_SCRIPT_AUTOEXEC; - - success = wm_file_read_opwrap(C, G.main->name, op->reports, !(G.f & G_SCRIPT_AUTOEXEC)); - - if (success) { - return OPERATOR_FINISHED; - } - else { - return OPERATOR_CANCELLED; - } -} - -static int wm_revert_mainfile_poll(bContext *UNUSED(C)) -{ - return G.relbase_valid; -} - -static void WM_OT_revert_mainfile(wmOperatorType *ot) -{ - ot->name = "Revert"; - ot->idname = "WM_OT_revert_mainfile"; - ot->description = "Reload the saved file"; - ot->invoke = WM_operator_confirm; - - RNA_def_boolean(ot->srna, "use_scripts", true, "Trusted Source", - "Allow .blend file to execute scripts automatically, default available from system preferences"); - - ot->exec = wm_revert_mainfile_exec; - ot->poll = wm_revert_mainfile_poll; -} - -/* **************** link/append *************** */ - -static int wm_link_append_poll(bContext *C) -{ - if (WM_operator_winactive(C)) { - /* linking changes active object which is pretty useful in general, - * but which totally confuses edit mode (i.e. it becoming not so obvious - * to leave from edit mode and invalid tools in toolbar might be displayed) - * so disable link/append when in edit mode (sergey) */ - if (CTX_data_edit_object(C)) - return 0; - - return 1; - } - - return 0; -} - -static int wm_link_append_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - if (RNA_struct_property_is_set(op->ptr, "filepath")) { - return WM_operator_call_notest(C, op); - } - else { - /* XXX TODO solve where to get last linked library from */ - if (G.lib[0] != '\0') { - RNA_string_set(op->ptr, "filepath", G.lib); - } - else if (G.relbase_valid) { - char path[FILE_MAX]; - BLI_strncpy(path, G.main->name, sizeof(G.main->name)); - BLI_parent_dir(path); - RNA_string_set(op->ptr, "filepath", path); - } - WM_event_add_fileselect(C, op); - return OPERATOR_RUNNING_MODAL; - } -} - -static short wm_link_append_flag(wmOperator *op) -{ - PropertyRNA *prop; - short flag = 0; - - if (RNA_boolean_get(op->ptr, "autoselect")) - flag |= FILE_AUTOSELECT; - if (RNA_boolean_get(op->ptr, "active_layer")) - flag |= FILE_ACTIVELAY; - if ((prop = RNA_struct_find_property(op->ptr, "relative_path")) && RNA_property_boolean_get(op->ptr, prop)) - flag |= FILE_RELPATH; - if (RNA_boolean_get(op->ptr, "link")) - flag |= FILE_LINK; - if (RNA_boolean_get(op->ptr, "instance_groups")) - flag |= FILE_GROUP_INSTANCE; - - return flag; -} - -typedef struct WMLinkAppendDataItem { - char *name; - BLI_bitmap *libraries; /* All libs (from WMLinkAppendData.libraries) to try to load this ID from. */ - short idcode; - - ID *new_id; - void *customdata; -} WMLinkAppendDataItem; - -typedef struct WMLinkAppendData { - LinkNodePair libraries; - LinkNodePair items; - int num_libraries; - int num_items; - short flag; - - /* Internal 'private' data */ - MemArena *memarena; -} WMLinkAppendData; - -static WMLinkAppendData *wm_link_append_data_new(const int flag) -{ - MemArena *ma = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__); - WMLinkAppendData *lapp_data = BLI_memarena_calloc(ma, sizeof(*lapp_data)); - - lapp_data->flag = flag; - lapp_data->memarena = ma; - - return lapp_data; -} - -static void wm_link_append_data_free(WMLinkAppendData *lapp_data) -{ - BLI_memarena_free(lapp_data->memarena); -} - -/* WARNING! *Never* call wm_link_append_data_library_add() after having added some items! */ - -static void wm_link_append_data_library_add(WMLinkAppendData *lapp_data, const char *libname) -{ - size_t len = strlen(libname) + 1; - char *libpath = BLI_memarena_alloc(lapp_data->memarena, len); - - BLI_strncpy(libpath, libname, len); - BLI_linklist_append_arena(&lapp_data->libraries, libpath, lapp_data->memarena); - lapp_data->num_libraries++; -} - -static WMLinkAppendDataItem *wm_link_append_data_item_add( - WMLinkAppendData *lapp_data, const char *idname, const short idcode, void *customdata) -{ - WMLinkAppendDataItem *item = BLI_memarena_alloc(lapp_data->memarena, sizeof(*item)); - size_t len = strlen(idname) + 1; - - item->name = BLI_memarena_alloc(lapp_data->memarena, len); - BLI_strncpy(item->name, idname, len); - item->idcode = idcode; - item->libraries = BLI_BITMAP_NEW_MEMARENA(lapp_data->memarena, lapp_data->num_libraries); - - item->new_id = NULL; - item->customdata = customdata; - - BLI_linklist_append_arena(&lapp_data->items, item, lapp_data->memarena); - lapp_data->num_items++; - - return item; -} - -static void wm_link_do( - WMLinkAppendData *lapp_data, ReportList *reports, Main *bmain, Scene *scene, View3D *v3d) -{ - Main *mainl; - BlendHandle *bh; - Library *lib; - - const int flag = lapp_data->flag; - - LinkNode *liblink, *itemlink; - int lib_idx, item_idx; - - BLI_assert(lapp_data->num_items && lapp_data->num_libraries); - - for (lib_idx = 0, liblink = lapp_data->libraries.list; liblink; lib_idx++, liblink = liblink->next) { - char *libname = liblink->link; - - bh = BLO_blendhandle_from_file(libname, reports); - - if (bh == NULL) { - /* Unlikely since we just browsed it, but possible - * Error reports will have been made by BLO_blendhandle_from_file() */ - continue; - } - - /* here appending/linking starts */ - mainl = BLO_library_link_begin(bmain, &bh, libname); - lib = mainl->curlib; - BLI_assert(lib); - UNUSED_VARS_NDEBUG(lib); - - if (mainl->versionfile < 250) { - BKE_reportf(reports, RPT_WARNING, - "Linking or appending from a very old .blend file format (%d.%d), no animation conversion will " - "be done! You may want to re-save your lib file with current Blender", - mainl->versionfile, mainl->subversionfile); - } - - /* For each lib file, we try to link all items belonging to that lib, - * and tag those successful to not try to load them again with the other libs. */ - for (item_idx = 0, itemlink = lapp_data->items.list; itemlink; item_idx++, itemlink = itemlink->next) { - WMLinkAppendDataItem *item = itemlink->link; - ID *new_id; - - if (!BLI_BITMAP_TEST(item->libraries, lib_idx)) { - continue; - } - - new_id = BLO_library_link_named_part_ex(mainl, &bh, item->idcode, item->name, flag, scene, v3d); - if (new_id) { - /* If the link is sucessful, clear item's libs 'todo' flags. - * This avoids trying to link same item with other libraries to come. */ - BLI_BITMAP_SET_ALL(item->libraries, false, lapp_data->num_libraries); - item->new_id = new_id; - } - } - - BLO_library_link_end(mainl, &bh, flag, scene, v3d); - BLO_blendhandle_close(bh); - } -} - -static int wm_link_append_exec(bContext *C, wmOperator *op) -{ - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - PropertyRNA *prop; - WMLinkAppendData *lapp_data; - char path[FILE_MAX_LIBEXTRA], root[FILE_MAXDIR], libname[FILE_MAX], relname[FILE_MAX]; - char *group, *name; - int totfiles = 0; - short flag; - - RNA_string_get(op->ptr, "filename", relname); - RNA_string_get(op->ptr, "directory", root); - - BLI_join_dirfile(path, sizeof(path), root, relname); - - /* test if we have a valid data */ - if (!BLO_library_path_explode(path, libname, &group, &name)) { - BKE_reportf(op->reports, RPT_ERROR, "'%s': not a library", path); - return OPERATOR_CANCELLED; - } - else if (!group) { - BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", path); - return OPERATOR_CANCELLED; - } - else if (BLI_path_cmp(bmain->name, libname) == 0) { - BKE_reportf(op->reports, RPT_ERROR, "'%s': cannot use current file as library", path); - return OPERATOR_CANCELLED; - } - - /* check if something is indicated for append/link */ - prop = RNA_struct_find_property(op->ptr, "files"); - if (prop) { - totfiles = RNA_property_collection_length(op->ptr, prop); - if (totfiles == 0) { - if (!name) { - BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", path); - return OPERATOR_CANCELLED; - } - } - } - else if (!name) { - BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", path); - return OPERATOR_CANCELLED; - } - - flag = wm_link_append_flag(op); - - /* sanity checks for flag */ - if (scene && scene->id.lib) { - BKE_reportf(op->reports, RPT_WARNING, - "Scene '%s' is linked, instantiation of objects & groups is disabled", scene->id.name + 2); - flag &= ~FILE_GROUP_INSTANCE; - scene = NULL; - } - - /* from here down, no error returns */ - - if (scene && RNA_boolean_get(op->ptr, "autoselect")) { - BKE_scene_base_deselect_all(scene); - } - - /* tag everything, all untagged data can be made local - * its also generally useful to know what is new - * - * take extra care BKE_main_id_flag_all(bmain, LIB_TAG_PRE_EXISTING, false) is called after! */ - BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true); - - /* We define our working data... - * Note that here, each item 'uses' one library, and only one. */ - lapp_data = wm_link_append_data_new(flag); - if (totfiles != 0) { - GHash *libraries = BLI_ghash_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, __func__); - int lib_idx = 0; - - RNA_BEGIN (op->ptr, itemptr, "files") - { - RNA_string_get(&itemptr, "name", relname); - - BLI_join_dirfile(path, sizeof(path), root, relname); - - if (BLO_library_path_explode(path, libname, &group, &name)) { - if (!group || !name) { - continue; - } - - if (!BLI_ghash_haskey(libraries, libname)) { - BLI_ghash_insert(libraries, BLI_strdup(libname), SET_INT_IN_POINTER(lib_idx)); - lib_idx++; - wm_link_append_data_library_add(lapp_data, libname); - } - } - } - RNA_END; - - RNA_BEGIN (op->ptr, itemptr, "files") - { - RNA_string_get(&itemptr, "name", relname); - - BLI_join_dirfile(path, sizeof(path), root, relname); - - if (BLO_library_path_explode(path, libname, &group, &name)) { - WMLinkAppendDataItem *item; - if (!group || !name) { - printf("skipping %s\n", path); - continue; - } - - lib_idx = GET_INT_FROM_POINTER(BLI_ghash_lookup(libraries, libname)); - - item = wm_link_append_data_item_add(lapp_data, name, BKE_idcode_from_name(group), NULL); - BLI_BITMAP_ENABLE(item->libraries, lib_idx); - } - } - RNA_END; - - BLI_ghash_free(libraries, MEM_freeN, NULL); - } - else { - WMLinkAppendDataItem *item; - - wm_link_append_data_library_add(lapp_data, libname); - item = wm_link_append_data_item_add(lapp_data, name, BKE_idcode_from_name(group), NULL); - BLI_BITMAP_ENABLE(item->libraries, 0); - } - - /* XXX We'd need re-entrant locking on Main for this to work... */ - /* BKE_main_lock(bmain); */ - - wm_link_do(lapp_data, op->reports, bmain, scene, CTX_wm_view3d(C)); - - /* BKE_main_unlock(bmain); */ - - wm_link_append_data_free(lapp_data); - - /* mark all library linked objects to be updated */ - BKE_main_lib_objects_recalc_all(bmain); - IMB_colormanagement_check_file_config(bmain); - - /* append, rather than linking */ - if ((flag & FILE_LINK) == 0) { - bool set_fake = RNA_boolean_get(op->ptr, "set_fake"); - BKE_library_make_local(bmain, NULL, true, set_fake); - } - - /* important we unset, otherwise these object wont - * link into other scenes from this blend file */ - BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false); - - /* recreate dependency graph to include new objects */ - DAG_scene_relations_rebuild(bmain, scene); - - /* free gpu materials, some materials depend on existing objects, such as lamps so freeing correctly refreshes */ - GPU_materials_free(); - - /* XXX TODO: align G.lib with other directory storage (like last opened image etc...) */ - BLI_strncpy(G.lib, root, FILE_MAX); - - WM_event_add_notifier(C, NC_WINDOW, NULL); - - return OPERATOR_FINISHED; -} - -static void wm_link_append_properties_common(wmOperatorType *ot, bool is_link) -{ - PropertyRNA *prop; - - /* better not save _any_ settings for this operator */ - /* properties */ - prop = RNA_def_boolean(ot->srna, "link", is_link, - "Link", "Link the objects or datablocks rather than appending"); - RNA_def_property_flag(prop, PROP_SKIP_SAVE | PROP_HIDDEN); - prop = RNA_def_boolean(ot->srna, "autoselect", true, - "Select", "Select new objects"); - RNA_def_property_flag(prop, PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "active_layer", true, - "Active Layer", "Put new objects on the active layer"); - RNA_def_property_flag(prop, PROP_SKIP_SAVE); - prop = RNA_def_boolean(ot->srna, "instance_groups", is_link, - "Instance Groups", "Create Dupli-Group instances for each group"); - RNA_def_property_flag(prop, PROP_SKIP_SAVE); -} - -static void WM_OT_link(wmOperatorType *ot) -{ - ot->name = "Link from Library"; - ot->idname = "WM_OT_link"; - ot->description = "Link from a Library .blend file"; - - ot->invoke = wm_link_append_invoke; - ot->exec = wm_link_append_exec; - ot->poll = wm_link_append_poll; - - ot->flag |= OPTYPE_UNDO; - - WM_operator_properties_filesel( - ot, FILE_TYPE_FOLDER | FILE_TYPE_BLENDER | FILE_TYPE_BLENDERLIB, FILE_LOADLIB, FILE_OPENFILE, - WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILENAME | WM_FILESEL_RELPATH | WM_FILESEL_FILES, - FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA); - - wm_link_append_properties_common(ot, true); -} - -static void WM_OT_append(wmOperatorType *ot) -{ - ot->name = "Append from Library"; - ot->idname = "WM_OT_append"; - ot->description = "Append from a Library .blend file"; - - ot->invoke = wm_link_append_invoke; - ot->exec = wm_link_append_exec; - ot->poll = wm_link_append_poll; - - ot->flag |= OPTYPE_UNDO; - - WM_operator_properties_filesel( - ot, FILE_TYPE_FOLDER | FILE_TYPE_BLENDER | FILE_TYPE_BLENDERLIB, FILE_LOADLIB, FILE_OPENFILE, - WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILENAME | WM_FILESEL_FILES, - FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA); - - wm_link_append_properties_common(ot, false); - RNA_def_boolean(ot->srna, "set_fake", false, "Fake User", "Set Fake User for appended items (except Objects and Groups)"); -} - -/* *************** recover last session **************** */ - -void WM_recover_last_session(bContext *C, ReportList *reports) -{ - char filepath[FILE_MAX]; - - BLI_make_file_string("/", filepath, BKE_tempdir_base(), BLENDER_QUIT_FILE); - /* if reports==NULL, it's called directly without operator, we add a quick check here */ - if (reports || BLI_exists(filepath)) { - G.fileflags |= G_FILE_RECOVER; - - wm_file_read_opwrap(C, filepath, reports, true); - - G.fileflags &= ~G_FILE_RECOVER; - - /* XXX bad global... fixme */ - if (G.main->name[0]) - G.file_loaded = 1; /* prevents splash to show */ - else { - G.relbase_valid = 0; - G.save_over = 0; /* start with save preference untitled.blend */ - } - - } -} - -static int wm_recover_last_session_exec(bContext *C, wmOperator *op) -{ - WM_recover_last_session(C, op->reports); - return OPERATOR_FINISHED; -} - -static void WM_OT_recover_last_session(wmOperatorType *ot) -{ - ot->name = "Recover Last Session"; - ot->idname = "WM_OT_recover_last_session"; - ot->description = "Open the last closed file (\"" BLENDER_QUIT_FILE "\")"; - ot->invoke = WM_operator_confirm; - - ot->exec = wm_recover_last_session_exec; -} - -/* *************** recover auto save **************** */ - -static int wm_recover_auto_save_exec(bContext *C, wmOperator *op) -{ - char filepath[FILE_MAX]; - bool success; - - RNA_string_get(op->ptr, "filepath", filepath); - - G.fileflags |= G_FILE_RECOVER; - - success = wm_file_read_opwrap(C, filepath, op->reports, true); - - G.fileflags &= ~G_FILE_RECOVER; - - if (success) { - return OPERATOR_FINISHED; - } - else { - return OPERATOR_CANCELLED; - } -} - -static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - char filename[FILE_MAX]; - - wm_autosave_location(filename); - RNA_string_set(op->ptr, "filepath", filename); - WM_event_add_fileselect(C, op); - - return OPERATOR_RUNNING_MODAL; -} - -static void WM_OT_recover_auto_save(wmOperatorType *ot) -{ - ot->name = "Recover Auto Save"; - ot->idname = "WM_OT_recover_auto_save"; - ot->description = "Open an automatically saved file to recover it"; - - ot->exec = wm_recover_auto_save_exec; - ot->invoke = wm_recover_auto_save_invoke; - - WM_operator_properties_filesel( - ot, FILE_TYPE_BLENDER, FILE_BLENDER, FILE_OPENFILE, - WM_FILESEL_FILEPATH, FILE_LONGDISPLAY, FILE_SORT_TIME); -} - -/* *************** save file as **************** */ - -static void wm_filepath_default(char *filepath) -{ - if (G.save_over == false) { - BLI_ensure_filename(filepath, FILE_MAX, "untitled.blend"); - } -} - -static void save_set_compress(wmOperator *op) -{ - PropertyRNA *prop; - - prop = RNA_struct_find_property(op->ptr, "compress"); - if (!RNA_property_is_set(op->ptr, prop)) { - if (G.save_over) { /* keep flag for existing file */ - RNA_property_boolean_set(op->ptr, prop, (G.fileflags & G_FILE_COMPRESS) != 0); - } - else { /* use userdef for new file */ - RNA_property_boolean_set(op->ptr, prop, (U.flag & USER_FILECOMPRESS) != 0); - } - } -} - -static void save_set_filepath(wmOperator *op) -{ - PropertyRNA *prop; - char name[FILE_MAX]; - - prop = RNA_struct_find_property(op->ptr, "filepath"); - if (!RNA_property_is_set(op->ptr, prop)) { - /* if not saved before, get the name of the most recently used .blend file */ - if (G.main->name[0] == 0 && G.recent_files.first) { - struct RecentFile *recent = G.recent_files.first; - BLI_strncpy(name, recent->filepath, FILE_MAX); - } - else { - BLI_strncpy(name, G.main->name, FILE_MAX); - } - - wm_filepath_default(name); - RNA_property_string_set(op->ptr, prop, name); - } -} - -static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - - save_set_compress(op); - save_set_filepath(op); - - WM_event_add_fileselect(C, op); - - return OPERATOR_RUNNING_MODAL; -} - -/* function used for WM_OT_save_mainfile too */ -static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op) -{ - char path[FILE_MAX]; - int fileflags; - - save_set_compress(op); - - if (RNA_struct_property_is_set(op->ptr, "filepath")) { - RNA_string_get(op->ptr, "filepath", path); - } - else { - BLI_strncpy(path, G.main->name, FILE_MAX); - wm_filepath_default(path); - } - - fileflags = G.fileflags & ~G_FILE_USERPREFS; - - /* set compression flag */ - BKE_BIT_TEST_SET(fileflags, RNA_boolean_get(op->ptr, "compress"), - G_FILE_COMPRESS); - BKE_BIT_TEST_SET(fileflags, RNA_boolean_get(op->ptr, "relative_remap"), - G_FILE_RELATIVE_REMAP); - BKE_BIT_TEST_SET(fileflags, - (RNA_struct_property_is_set(op->ptr, "copy") && - RNA_boolean_get(op->ptr, "copy")), - G_FILE_SAVE_COPY); - -#ifdef USE_BMESH_SAVE_AS_COMPAT - BKE_BIT_TEST_SET(fileflags, - (RNA_struct_find_property(op->ptr, "use_mesh_compat") && - RNA_boolean_get(op->ptr, "use_mesh_compat")), - G_FILE_MESH_COMPAT); -#else -# error "don't remove by accident" -#endif - - if (wm_file_write(C, path, fileflags, op->reports) != 0) - return OPERATOR_CANCELLED; - - WM_event_add_notifier(C, NC_WM | ND_FILESAVE, NULL); - - return OPERATOR_FINISHED; -} - -/* function used for WM_OT_save_mainfile too */ -static bool blend_save_check(bContext *UNUSED(C), wmOperator *op) -{ - char filepath[FILE_MAX]; - RNA_string_get(op->ptr, "filepath", filepath); - if (!BLO_has_bfile_extension(filepath)) { - /* some users would prefer BLI_replace_extension(), - * we keep getting nitpicking bug reports about this - campbell */ - BLI_ensure_extension(filepath, FILE_MAX, ".blend"); - RNA_string_set(op->ptr, "filepath", filepath); - return true; - } - return false; -} - -static void WM_OT_save_as_mainfile(wmOperatorType *ot) -{ - PropertyRNA *prop; - - ot->name = "Save As Blender File"; - ot->idname = "WM_OT_save_as_mainfile"; - ot->description = "Save the current file in the desired location"; - - ot->invoke = wm_save_as_mainfile_invoke; - ot->exec = wm_save_as_mainfile_exec; - ot->check = blend_save_check; - /* omit window poll so this can work in background mode */ - - WM_operator_properties_filesel( - ot, FILE_TYPE_FOLDER | FILE_TYPE_BLENDER, FILE_BLENDER, FILE_SAVE, - WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA); - RNA_def_boolean(ot->srna, "compress", false, "Compress", "Write compressed .blend file"); - RNA_def_boolean(ot->srna, "relative_remap", true, "Remap Relative", - "Remap relative paths when saving in a different directory"); - prop = RNA_def_boolean(ot->srna, "copy", false, "Save Copy", - "Save a copy of the actual working state but does not make saved file active"); - RNA_def_property_flag(prop, PROP_SKIP_SAVE); -#ifdef USE_BMESH_SAVE_AS_COMPAT - RNA_def_boolean(ot->srna, "use_mesh_compat", false, "Legacy Mesh Format", - "Save using legacy mesh format (no ngons) - WARNING: only saves tris and quads, other ngons will " - "be lost (no implicit triangulation)"); -#endif -} - -/* *************** save file directly ******** */ - -static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - int ret; - - /* cancel if no active window */ - if (CTX_wm_window(C) == NULL) - return OPERATOR_CANCELLED; - - save_set_compress(op); - save_set_filepath(op); - - /* if we're saving for the first time and prefer relative paths - any existing paths will be absolute, - * enable the option to remap paths to avoid confusion [#37240] */ - if ((G.relbase_valid == false) && (U.flag & USER_RELPATHS)) { - PropertyRNA *prop = RNA_struct_find_property(op->ptr, "relative_remap"); - if (!RNA_property_is_set(op->ptr, prop)) { - RNA_property_boolean_set(op->ptr, prop, true); - } - } - - if (G.save_over) { - char path[FILE_MAX]; - - RNA_string_get(op->ptr, "filepath", path); - if (BLI_exists(path)) { - ret = WM_operator_confirm_message_ex(C, op, IFACE_("Save Over?"), ICON_QUESTION, path); - } - else { - ret = wm_save_as_mainfile_exec(C, op); - } - } - else { - WM_event_add_fileselect(C, op); - ret = OPERATOR_RUNNING_MODAL; - } - - return ret; -} - -static void WM_OT_save_mainfile(wmOperatorType *ot) -{ - ot->name = "Save Blender File"; - ot->idname = "WM_OT_save_mainfile"; - ot->description = "Save the current Blender file"; - - ot->invoke = wm_save_mainfile_invoke; - ot->exec = wm_save_as_mainfile_exec; - ot->check = blend_save_check; - /* omit window poll so this can work in background mode */ - - WM_operator_properties_filesel( - ot, FILE_TYPE_FOLDER | FILE_TYPE_BLENDER, FILE_BLENDER, FILE_SAVE, - WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA); - RNA_def_boolean(ot->srna, "compress", false, "Compress", "Write compressed .blend file"); - RNA_def_boolean(ot->srna, "relative_remap", false, "Remap Relative", - "Remap relative paths when saving in a different directory"); -} - static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot) { ot->name = "Toggle Window Fullscreen"; |