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

Reply via email to