Commit: 7547c6a250cd6f36c9894605b822380a1261febf Author: Bastien Montagne Date: Wed Jun 22 18:05:55 2016 +0200 Branches: master https://developer.blender.org/rB7547c6a250cd6f36c9894605b822380a1261febf
ID-Remap, step two: add some user-level tools. This commit adds operators and Outliner menu entries to reload or relocate a library, and to delete or replace a datablock. RNA ID API is also extended to allow ID deletion and remapping from python. Review task: D2027 (https://developer.blender.org/D2027). Reviewed by campbellbarton, thanks a bunch. =================================================================== M source/blender/blenloader/BLO_readfile.h M source/blender/blenloader/intern/readfile.c M source/blender/editors/space_outliner/outliner_edit.c M source/blender/editors/space_outliner/outliner_intern.h M source/blender/editors/space_outliner/outliner_ops.c M source/blender/editors/space_outliner/outliner_tools.c M source/blender/makesrna/intern/rna_ID.c M source/blender/windowmanager/intern/wm_files_link.c M source/blender/windowmanager/intern/wm_operators.c M source/blender/windowmanager/wm_files.h =================================================================== diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index bf47682..c85cf12 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -100,7 +100,8 @@ struct ID *BLO_library_link_named_part(struct Main *mainl, BlendHandle **bh, con struct ID *BLO_library_link_named_part_ex( struct Main *mainl, BlendHandle **bh, const short idcode, const char *name, const short flag, - struct Scene *scene, struct View3D *v3d); + struct Scene *scene, struct View3D *v3d, + const bool use_placeholders, const bool force_indirect); void BLO_library_link_end(struct Main *mainl, BlendHandle **bh, short flag, struct Scene *scene, struct View3D *v3d); void BLO_library_link_copypaste(struct Main *mainl, BlendHandle *bh); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index d8768f1..8e69408 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -113,6 +113,7 @@ #include "BKE_action.h" #include "BKE_armature.h" +#include "BKE_blender_version.h" #include "BKE_brush.h" #include "BKE_cloth.h" #include "BKE_constraint.h" @@ -8287,6 +8288,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) blo_do_versions_260(fd, lib, main); blo_do_versions_270(fd, lib, main); + main->versionfile = BLENDER_VERSION; + main->subversionfile = BLENDER_SUBVERSION; + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init see do_versions_userdef() above! */ @@ -9707,13 +9711,13 @@ static void give_base_to_groups( } } -static ID *create_placeholder(Main *mainvar, const char *idname, const short tag) +static ID *create_placeholder(Main *mainvar, const short idcode, const char *idname, const short tag) { - const short idcode = GS(idname); ListBase *lb = which_libbase(mainvar, idcode); ID *ph_id = BKE_libblock_alloc_notest(idcode); - memcpy(ph_id->name, idname, sizeof(ph_id->name)); + *((short *)ph_id->name) = idcode; + BLI_strncpy(ph_id->name + 2, idname, sizeof(ph_id->name) - 2); BKE_libblock_init_empty(ph_id); ph_id->lib = mainvar->curlib; ph_id->tag = tag | LIB_TAG_MISSING; @@ -9728,7 +9732,9 @@ static ID *create_placeholder(Main *mainvar, const char *idname, const short tag /* returns true if the item was found * but it may already have already been appended/linked */ -static ID *link_named_part(Main *mainl, FileData *fd, const short idcode, const char *name) +static ID *link_named_part( + Main *mainl, FileData *fd, const short idcode, const char *name, + const bool use_placeholders, const bool force_indirect) { BHead *bhead = find_bhead_from_code_name(fd, idcode, name); ID *id; @@ -9739,7 +9745,7 @@ static ID *link_named_part(Main *mainl, FileData *fd, const short idcode, const id = is_yet_read(fd, mainl, bhead); if (id == NULL) { /* not read yet */ - read_libblock(fd, mainl, bhead, LIB_TAG_TESTEXT, &id); + read_libblock(fd, mainl, bhead, force_indirect ? LIB_TAG_TESTIND : LIB_TAG_TESTEXT, &id); if (id) { /* sort by name in list */ @@ -9752,18 +9758,22 @@ static ID *link_named_part(Main *mainl, FileData *fd, const short idcode, const if (G.debug) printf("append: already linked\n"); oldnewmap_insert(fd->libmap, bhead->old, id, bhead->code); - if (id->tag & LIB_TAG_INDIRECT) { + if (!force_indirect && (id->tag & LIB_TAG_INDIRECT)) { id->tag &= ~LIB_TAG_INDIRECT; id->tag |= LIB_TAG_EXTERN; } } } + else if (use_placeholders) { + /* XXX flag part is weak! */ + id = create_placeholder(mainl, idcode, name, force_indirect ? LIB_TAG_INDIRECT : LIB_TAG_EXTERN); + } else { id = NULL; } /* if we found the id but the id is NULL, this is really bad */ - BLI_assert((bhead != NULL) == (id != NULL)); + BLI_assert(!((bhead != NULL) && (id == NULL))); return id; } @@ -9835,9 +9845,9 @@ void BLO_library_link_copypaste(Main *mainl, BlendHandle *bh) static ID *link_named_part_ex( Main *mainl, FileData *fd, const short idcode, const char *name, const short flag, - Scene *scene, View3D *v3d) + Scene *scene, View3D *v3d, const bool use_placeholders, const bool force_indirect) { - ID *id = link_named_part(mainl, fd, idcode, name); + ID *id = link_named_part(mainl, fd, idcode, name, use_placeholders, force_indirect); if (id && (GS(id->name) == ID_OB)) { /* loose object: give a base */ link_object_postprocess(id, scene, v3d, flag); @@ -9863,7 +9873,7 @@ static ID *link_named_part_ex( ID *BLO_library_link_named_part(Main *mainl, BlendHandle **bh, const short idcode, const char *name) { FileData *fd = (FileData*)(*bh); - return link_named_part(mainl, fd, idcode, name); + return link_named_part(mainl, fd, idcode, name, false, false); } /** @@ -9877,15 +9887,18 @@ ID *BLO_library_link_named_part(Main *mainl, BlendHandle **bh, const short idcod * \param flag Options for linking, used for instantiating. * \param scene The scene in which to instantiate objects/groups (if NULL, no instantiation is done). * \param v3d The active View3D (only to define active layers for instantiated objects & groups, can be NULL). + * \param use_placeholders If true, generate a placeholder (empty ID) if not found in current lib file. + * \param force_indirect If true, force loaded ID to be tagged as LIB_TAG_INDIRECT (used in reload context only). * \return the linked ID when found. */ ID *BLO_library_link_named_part_ex( Main *mainl, BlendHandle **bh, const short idcode, const char *name, const short flag, - Scene *scene, View3D *v3d) + Scene *scene, View3D *v3d, + const bool use_placeholders, const bool force_indirect) { FileData *fd = (FileData*)(*bh); - return link_named_part_ex(mainl, fd, idcode, name, flag, scene, v3d); + return link_named_part_ex(mainl, fd, idcode, name, flag, scene, v3d, use_placeholders, force_indirect); } static void link_id_part(ReportList *reports, FileData *fd, Main *mainvar, ID *id, ID **r_id) @@ -9925,7 +9938,7 @@ static void link_id_part(ReportList *reports, FileData *fd, Main *mainvar, ID *i /* Generate a placeholder for this ID (simplified version of read_libblock actually...). */ if (r_id) { - *r_id = is_valid ? create_placeholder(mainvar, id->name, id->tag) : NULL; + *r_id = is_valid ? create_placeholder(mainvar, GS(id->name), id->name + 2, id->tag) : NULL; } } } diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 8cee696..687869a 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -29,17 +29,23 @@ * \ingroup spoutliner */ +#include <string.h> + #include "MEM_guardedalloc.h" #include "DNA_anim_types.h" #include "DNA_group_types.h" +#include "DNA_ID.h" #include "DNA_scene_types.h" #include "DNA_object_types.h" #include "DNA_material_types.h" #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_path_util.h" #include "BLI_mempool.h" +#include "BLI_stack.h" +#include "BLI_string.h" #include "BLT_translation.h" @@ -47,7 +53,9 @@ #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_global.h" +#include "BKE_idcode.h" #include "BKE_library.h" +#include "BKE_library_remap.h" #include "BKE_main.h" #include "BKE_outliner_treehash.h" #include "BKE_report.h" @@ -55,6 +63,8 @@ #include "BKE_material.h" #include "BKE_group.h" +#include "../blenloader/BLO_readfile.h" + #include "ED_object.h" #include "ED_outliner.h" #include "ED_screen.h" @@ -70,6 +80,9 @@ #include "RNA_access.h" #include "RNA_define.h" +#include "RNA_enum_types.h" + +#include "GPU_material.h" #include "outliner_intern.h" @@ -291,64 +304,294 @@ void OUTLINER_OT_item_rename(wmOperatorType *ot) ot->poll = ED_operator_outliner_active; } -/* Library delete --------------------------------------------------- */ +/* ID delete --------------------------------------------------- */ -static void lib_delete(bContext *C, TreeElement *te, TreeStoreElem *tselem, ReportList *reports) +static void id_delete(bContext *C, TreeElement *te, TreeStoreElem *tselem) { - Library *lib = (Library *)tselem->id; - ListBase *lbarray[MAX_LIBARRAY]; - int a; + Main *bmain = CTX_data_main(C); + ID *id = tselem->id; - BLI_assert(te->idcode == ID_LI && lib != NULL); + BLI_assert(te->idcode != 0 && id != NULL); + BLI_assert(te->idcode != ID_LI || ((Library *)id)->parent == NULL); UNUSED_VARS_NDEBUG(te); - /* We simply set all ID from given lib (including lib itself) to zero user count. - * It is not possible to do a proper cleanup without a save/reload in current master. */ - a = set_listbasepointers(CTX_data_main(C), lbarray); - while (a--) { - ListBase *lb = lbarray[a]; - ID *id; - - for (id = lb->first; id; id = id->next) { - if (id->lib == lib) { - id_fake_user_clear(id); - id->us = 0; + BKE_libblock_delete(bmain, id); + + WM_event_add_notifier(C, NC_WINDOW, NULL); +} + +void id_delete_cb( + bContext *C, Scene *UNUSED(scene), TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, + void *UNUSED(user_data)) +{ + id_delete(C, te, tselem); +} + +static int outliner_id_delete_invoke_do(bContext *C, ReportList *reports, TreeElement *te, const float mval[2]) +{ + if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) { + TreeStoreElem *tselem = TREESTORE(te); + + if (te->idcode != 0 && tselem->id) { + if (te->idcode == ID_LI && ((Library *)tselem->id)->parent) { + BKE_reportf(reports, RPT_ERROR_INVALID_INPUT, + "Cannot delete indirectly linked library '%s'", ((Library *)tselem->id)->filepath); + return OPERATOR_CANCELLED; + } + id_delete(C, te, tselem); + return OPERATOR_FINISHED; + } + } + else { + for (te = te->subtree.first; te; te = te->next) { + int ret; + if ((ret = outliner_id_delete_invoke_do(C, reports, te, mval))) { + return ret; } } } - BKE_reportf(reports, RPT_WARNING, - "Please save and reload .b @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] https://lists.blender.org/mailman/listinfo/bf-blender-cvs
