Changeset View
Changeset View
Standalone View
Standalone View
source/blender/windowmanager/intern/wm_files_link.c
| Show First 20 Lines • Show All 272 Lines • ▼ Show 20 Lines | for (item_idx = 0, itemlink = lapp_data->items.list; itemlink; item_idx++, itemlink = itemlink->next) { | ||||
| } | } | ||||
| } | } | ||||
| BLO_library_link_end(mainl, &bh, flag, scene, sl); | BLO_library_link_end(mainl, &bh, flag, scene, sl); | ||||
| BLO_blendhandle_close(bh); | BLO_blendhandle_close(bh); | ||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * Check if an item defined by \a name and \a group can be appended/linked. | |||||
| * | |||||
| * \param reports: Optionally report an error when an item can't be appended/linked. | |||||
| */ | |||||
| static bool wm_link_append_item_poll( | |||||
| ReportList *reports, const char *path, const char *group, const char *name, const bool do_append) | |||||
| { | |||||
| short idcode; | |||||
| if (!group || !name) { | |||||
| printf("skipping %s\n", path); | |||||
| return false; | |||||
| } | |||||
| idcode = BKE_idcode_from_name(group); | |||||
| /* XXX For now, we do a nasty exception for workspace, forbid linking them. | |||||
| * Not nice, ultimately should be solved! */ | |||||
| if (!BKE_idcode_is_linkable(idcode) && (do_append || idcode != ID_WS)) { | |||||
| if (reports) { | |||||
| if (do_append) { | |||||
| BKE_reportf(reports, RPT_ERROR_INVALID_INPUT, "Can't append data-block '%s' of type '%s'", name, group); | |||||
| } | |||||
| else { | |||||
| BKE_reportf(reports, RPT_ERROR_INVALID_INPUT, "Can't link data-block '%s' of type '%s'", name, group); | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| return true; | |||||
| } | |||||
| static int wm_link_append_exec(bContext *C, wmOperator *op) | static int wm_link_append_exec(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| Main *bmain = CTX_data_main(C); | Main *bmain = CTX_data_main(C); | ||||
| Scene *scene = CTX_data_scene(C); | Scene *scene = CTX_data_scene(C); | ||||
| SceneLayer *sl = CTX_data_scene_layer(C); | SceneLayer *sl = CTX_data_scene_layer(C); | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| WMLinkAppendData *lapp_data; | WMLinkAppendData *lapp_data; | ||||
| char path[FILE_MAX_LIBEXTRA], root[FILE_MAXDIR], libname[FILE_MAX], relname[FILE_MAX]; | char path[FILE_MAX_LIBEXTRA], root[FILE_MAXDIR], libname[FILE_MAX], relname[FILE_MAX]; | ||||
| char *group, *name; | char *group, *name; | ||||
| int totfiles = 0; | int totfiles = 0; | ||||
| short flag; | short flag; | ||||
| bool has_item = false; | |||||
| bool do_append; | |||||
| RNA_string_get(op->ptr, "filename", relname); | RNA_string_get(op->ptr, "filename", relname); | ||||
| RNA_string_get(op->ptr, "directory", root); | RNA_string_get(op->ptr, "directory", root); | ||||
| BLI_join_dirfile(path, sizeof(path), root, relname); | BLI_join_dirfile(path, sizeof(path), root, relname); | ||||
| /* test if we have a valid data */ | /* test if we have a valid data */ | ||||
| if (!BLO_library_path_explode(path, libname, &group, &name)) { | if (!BLO_library_path_explode(path, libname, &group, &name)) { | ||||
| Show All 21 Lines | if (prop) { | ||||
| } | } | ||||
| } | } | ||||
| else if (!name) { | else if (!name) { | ||||
| BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", path); | BKE_reportf(op->reports, RPT_ERROR, "'%s': nothing indicated", path); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| flag = wm_link_append_flag(op); | flag = wm_link_append_flag(op); | ||||
| do_append = (flag & FILE_LINK) == 0; | |||||
| /* sanity checks for flag */ | /* sanity checks for flag */ | ||||
| if (scene && scene->id.lib) { | if (scene && scene->id.lib) { | ||||
| BKE_reportf(op->reports, RPT_WARNING, | BKE_reportf(op->reports, RPT_WARNING, | ||||
| "Scene '%s' is linked, instantiation of objects & groups is disabled", scene->id.name + 2); | "Scene '%s' is linked, instantiation of objects & groups is disabled", scene->id.name + 2); | ||||
| flag &= ~FILE_GROUP_INSTANCE; | flag &= ~FILE_GROUP_INSTANCE; | ||||
| scene = NULL; | scene = NULL; | ||||
| } | } | ||||
| Show All 19 Lines | if (totfiles != 0) { | ||||
| RNA_BEGIN (op->ptr, itemptr, "files") | RNA_BEGIN (op->ptr, itemptr, "files") | ||||
| { | { | ||||
| RNA_string_get(&itemptr, "name", relname); | RNA_string_get(&itemptr, "name", relname); | ||||
| BLI_join_dirfile(path, sizeof(path), root, relname); | BLI_join_dirfile(path, sizeof(path), root, relname); | ||||
| if (BLO_library_path_explode(path, libname, &group, &name)) { | if (BLO_library_path_explode(path, libname, &group, &name)) { | ||||
| if (!group || !name) { | if (!wm_link_append_item_poll(NULL, path, group, name, do_append)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (!BLI_ghash_haskey(libraries, libname)) { | if (!BLI_ghash_haskey(libraries, libname)) { | ||||
| BLI_ghash_insert(libraries, BLI_strdup(libname), SET_INT_IN_POINTER(lib_idx)); | BLI_ghash_insert(libraries, BLI_strdup(libname), SET_INT_IN_POINTER(lib_idx)); | ||||
| lib_idx++; | lib_idx++; | ||||
| wm_link_append_data_library_add(lapp_data, libname); | wm_link_append_data_library_add(lapp_data, libname); | ||||
| has_item = true; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| RNA_END; | RNA_END; | ||||
| RNA_BEGIN (op->ptr, itemptr, "files") | RNA_BEGIN (op->ptr, itemptr, "files") | ||||
| { | { | ||||
| RNA_string_get(&itemptr, "name", relname); | RNA_string_get(&itemptr, "name", relname); | ||||
| BLI_join_dirfile(path, sizeof(path), root, relname); | BLI_join_dirfile(path, sizeof(path), root, relname); | ||||
| if (BLO_library_path_explode(path, libname, &group, &name)) { | if (BLO_library_path_explode(path, libname, &group, &name)) { | ||||
| WMLinkAppendDataItem *item; | WMLinkAppendDataItem *item; | ||||
| if (!group || !name) { | |||||
| printf("skipping %s\n", path); | if (!wm_link_append_item_poll(op->reports, path, group, name, do_append)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| lib_idx = GET_INT_FROM_POINTER(BLI_ghash_lookup(libraries, libname)); | 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); | item = wm_link_append_data_item_add(lapp_data, name, BKE_idcode_from_name(group), NULL); | ||||
| BLI_BITMAP_ENABLE(item->libraries, lib_idx); | BLI_BITMAP_ENABLE(item->libraries, lib_idx); | ||||
| has_item = true; | |||||
| } | } | ||||
| } | } | ||||
| RNA_END; | RNA_END; | ||||
| BLI_ghash_free(libraries, MEM_freeN, NULL); | BLI_ghash_free(libraries, MEM_freeN, NULL); | ||||
| } | } | ||||
| else { | else { | ||||
| WMLinkAppendDataItem *item; | WMLinkAppendDataItem *item; | ||||
| wm_link_append_data_library_add(lapp_data, libname); | 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); | item = wm_link_append_data_item_add(lapp_data, name, BKE_idcode_from_name(group), NULL); | ||||
| BLI_BITMAP_ENABLE(item->libraries, 0); | BLI_BITMAP_ENABLE(item->libraries, 0); | ||||
| has_item = true; | |||||
| } | |||||
| if (!has_item) { | |||||
| wm_link_append_data_free(lapp_data); | |||||
| return OPERATOR_CANCELLED; | |||||
| } | } | ||||
| /* XXX We'd need re-entrant locking on Main for this to work... */ | /* XXX We'd need re-entrant locking on Main for this to work... */ | ||||
| /* BKE_main_lock(bmain); */ | /* BKE_main_lock(bmain); */ | ||||
| wm_link_do(lapp_data, op->reports, bmain, scene, sl, false, false); | wm_link_do(lapp_data, op->reports, bmain, scene, sl, false, false); | ||||
| /* BKE_main_unlock(bmain); */ | /* BKE_main_unlock(bmain); */ | ||||
| /* mark all library linked objects to be updated */ | /* mark all library linked objects to be updated */ | ||||
| BKE_main_lib_objects_recalc_all(bmain); | BKE_main_lib_objects_recalc_all(bmain); | ||||
| IMB_colormanagement_check_file_config(bmain); | IMB_colormanagement_check_file_config(bmain); | ||||
| /* append, rather than linking */ | /* append, rather than linking */ | ||||
| if ((flag & FILE_LINK) == 0) { | if (do_append) { | ||||
| const bool set_fake = RNA_boolean_get(op->ptr, "set_fake"); | const bool set_fake = RNA_boolean_get(op->ptr, "set_fake"); | ||||
| const bool use_recursive = RNA_boolean_get(op->ptr, "use_recursive"); | const bool use_recursive = RNA_boolean_get(op->ptr, "use_recursive"); | ||||
| if (use_recursive) { | if (use_recursive) { | ||||
| BKE_library_make_local(bmain, NULL, NULL, true, set_fake); | BKE_library_make_local(bmain, NULL, NULL, true, set_fake); | ||||
| } | } | ||||
| else { | else { | ||||
| LinkNode *itemlink; | LinkNode *itemlink; | ||||
| ▲ Show 20 Lines • Show All 138 Lines • ▼ Show 20 Lines | static void lib_relocate_do( | ||||
| Main *bmain, Scene *scene, | Main *bmain, Scene *scene, | ||||
| Library *library, WMLinkAppendData *lapp_data, ReportList *reports, const bool do_reload) | Library *library, WMLinkAppendData *lapp_data, ReportList *reports, const bool do_reload) | ||||
| { | { | ||||
| ListBase *lbarray[MAX_LIBARRAY]; | ListBase *lbarray[MAX_LIBARRAY]; | ||||
| int lba_idx; | int lba_idx; | ||||
| LinkNode *itemlink; | LinkNode *itemlink; | ||||
| int item_idx; | int item_idx; | ||||
| bool has_item = false; | |||||
| /* Remove all IDs to be reloaded from Main. */ | /* Remove all IDs to be reloaded from Main. */ | ||||
| lba_idx = set_listbasepointers(bmain, lbarray); | lba_idx = set_listbasepointers(bmain, lbarray); | ||||
| while (lba_idx--) { | while (lba_idx--) { | ||||
| ID *id = lbarray[lba_idx]->first; | ID *id = lbarray[lba_idx]->first; | ||||
| const short idcode = id ? GS(id->name) : 0; | const short idcode = id ? GS(id->name) : 0; | ||||
| if (!id || !BKE_idcode_is_linkable(idcode)) { | if (!id || !BKE_idcode_is_linkable(idcode)) { | ||||
| /* No need to reload non-linkable datatypes, those will get relinked with their 'users ID'. */ | /* No need to reload non-linkable datatypes, those will get relinked with their 'users ID'. */ | ||||
| continue; | continue; | ||||
| } | } | ||||
| for (; id; id = id->next) { | for (; id; id = id->next) { | ||||
| if (id->lib == library) { | if (id->lib == library) { | ||||
| WMLinkAppendDataItem *item; | WMLinkAppendDataItem *item; | ||||
| /* We remove it from current Main, and add it to items to link... */ | /* We remove it from current Main, and add it to items to link... */ | ||||
| /* Note that non-linkable IDs (like e.g. shapekeys) are also explicitly linked here... */ | /* Note that non-linkable IDs (like e.g. shapekeys) are also explicitly linked here... */ | ||||
| BLI_remlink(lbarray[lba_idx], id); | BLI_remlink(lbarray[lba_idx], id); | ||||
| item = wm_link_append_data_item_add(lapp_data, id->name + 2, idcode, id); | item = wm_link_append_data_item_add(lapp_data, id->name + 2, idcode, id); | ||||
| BLI_BITMAP_SET_ALL(item->libraries, true, lapp_data->num_libraries); | BLI_BITMAP_SET_ALL(item->libraries, true, lapp_data->num_libraries); | ||||
| has_item = true; | |||||
| #ifdef PRINT_DEBUG | #ifdef PRINT_DEBUG | ||||
| printf("\tdatablock to seek for: %s\n", id->name); | printf("\tdatablock to seek for: %s\n", id->name); | ||||
| #endif | #endif | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (!has_item) { | |||||
| /* nothing to relocate */ | |||||
| return; | |||||
| } | |||||
| BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true); | BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true); | ||||
| /* We do not want any instanciation here! */ | /* We do not want any instanciation here! */ | ||||
| wm_link_do(lapp_data, reports, bmain, NULL, NULL, do_reload, do_reload); | wm_link_do(lapp_data, reports, bmain, NULL, NULL, do_reload, do_reload); | ||||
| BKE_main_lock(bmain); | BKE_main_lock(bmain); | ||||
| /* We add back old id to bmain. | /* We add back old id to bmain. | ||||
| ▲ Show 20 Lines • Show All 338 Lines • Show Last 20 Lines | |||||