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
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2016-04-19 18:08:31 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2016-04-19 23:53:18 +0300
commit52e09ed4f93b21aee8643de2f8b53e9fa7c99543 (patch)
treea711758277e06071c69abd1c92f24fa540269cd3 /source/blender/windowmanager/intern/wm_operators.c
parentdd423a6818cc8132ba073dfbeb66cb40d3f09611 (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.c1020
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";