From the long todo:
authorTon Roosendaal <ton@blender.org>
Sat, 22 Dec 2012 13:39:44 +0000 (13:39 +0000)
committerTon Roosendaal <ton@blender.org>
Sat, 22 Dec 2012 13:39:44 +0000 (13:39 +0000)
New Outliner mode: "Main Data".

This shows a flattened, non-hierarchical list of all linkable "ID" data in
your current project. It works fine on searches. Actually this is the
view on the "Main" database in Blender, the one that's saved in a .blend.

This is in general more useful than the "Datablocks" viewer,
which is not searchable, and shows every property of data as well.

source/blender/editors/space_outliner/outliner_intern.h
source/blender/editors/space_outliner/outliner_tree.c
source/blender/makesdna/DNA_space_types.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_space.c

index 65de2a27568ef821849f102da93e543bd1b7db14..f9fca378568a4f99908da225a55779eac66b23ce 100644 (file)
@@ -103,6 +103,7 @@ typedef struct TreeElement {
 #define TSE_NLA_TRACK       33
 #define TSE_KEYMAP          34
 #define TSE_KEYMAP_ITEM     35
+#define TSE_ID_BASE                    36
 
 /* button events */
 #define OL_NAMEBUTTON       1
index e6910280da470f9079efacf93070f0fba1c1a9b0..ca2168020cd5b87e34d9e851304ed6bfa56b46fa 100644 (file)
@@ -66,6 +66,7 @@
 
 #include "BKE_fcurve.h"
 #include "BKE_main.h"
+#include "BKE_library.h"
 #include "BKE_modifier.h"
 #include "BKE_sequencer.h"
 
@@ -785,6 +786,7 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor
 }
 
 // TODO: this function needs to be split up! It's getting a bit too large...
+// Note: "ID" is not always a real ID
 static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *idv, 
                                          TreeElement *parent, short type, short index)
 {
@@ -822,14 +824,20 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
        else if (type == TSE_ANIM_DATA) {
                /* pass */
        }
+       else if (type == TSE_ID_BASE) {
+               /* pass */
+       }
        else {
                te->name = id->name + 2; // default, can be overridden by Library or non-ID data
                te->idcode = GS(id->name);
        }
        
        if (type == 0) {
+               TreeStoreElem *tsepar = parent ? TREESTORE(parent) : NULL;
+               
                /* ID datablock */
-               outliner_add_id_contents(soops, te, tselem, id);
+               if (tsepar==NULL || tsepar->type != TSE_ID_BASE)
+                       outliner_add_id_contents(soops, te, tselem, id);
        }
        else if (type == TSE_ANIM_DATA) {
                IdAdtTemplate *iat = (IdAdtTemplate *)idv;
@@ -1194,8 +1202,8 @@ typedef struct tTreeSort {
        short idcode;
 } tTreeSort;
 
-/* alphabetical comparator */
-static int treesort_alpha(const void *v1, const void *v2)
+/* alphabetical comparator, tryping to put objects first */
+static int treesort_alpha_ob(const void *v1, const void *v2)
 {
        const tTreeSort *x1 = v1, *x2 = v2;
        int comp;
@@ -1216,6 +1224,20 @@ static int treesort_alpha(const void *v1, const void *v2)
        return 0;
 }
 
+/* alphabetical comparator */
+static int treesort_alpha(const void *v1, const void *v2)
+{
+       const tTreeSort *x1 = v1, *x2 = v2;
+       int comp;
+       
+       comp = strcmp(x1->name, x2->name);
+       
+       if (comp > 0) return 1;
+       else if (comp < 0) return -1;
+       return 0;
+}
+
+
 /* this is nice option for later? doesnt look too useful... */
 #if 0
 static int treesort_obtype_alpha(const void *v1, const void *v2)
@@ -1254,8 +1276,8 @@ static void outliner_sort(SpaceOops *soops, ListBase *lb)
        if (te == NULL) return;
        tselem = TREESTORE(te);
        
-       /* sorting rules; only object lists or deformgroups */
-       if ((tselem->type == TSE_DEFGROUP) || (tselem->type == 0 && te->idcode == ID_OB)) {
+       /* sorting rules; only object lists, ID lists, or deformgroups */
+       if ( ELEM(tselem->type, TSE_DEFGROUP, TSE_ID_BASE) || (tselem->type == 0 && te->idcode == ID_OB)) {
                
                /* count first */
                for (te = lb->first; te; te = te->next) totelem++;
@@ -1270,15 +1292,27 @@ static void outliner_sort(SpaceOops *soops, ListBase *lb)
                                tp->te = te;
                                tp->name = te->name;
                                tp->idcode = te->idcode;
-                               if (tselem->type && tselem->type != TSE_DEFGROUP) tp->idcode = 0;  // don't sort this
+                               
+                               if (tselem->type && tselem->type != TSE_DEFGROUP)
+                                       tp->idcode = 0;  // don't sort this
+                               if (tselem->type == TSE_ID_BASE)
+                                       tp->idcode = 1; // do sort this
+                               
                                tp->id = tselem->id;
                        }
-                       /* keep beginning of list */
-                       for (tp = tear, skip = 0; skip < totelem; skip++, tp++)
-                               if (tp->idcode) break;
                        
-                       if (skip < totelem)
-                               qsort(tear + skip, totelem - skip, sizeof(tTreeSort), treesort_alpha);
+                       /* just sort alphabetically */
+                       if (tear->idcode == 1) {
+                               qsort(tear, totelem, sizeof(tTreeSort), treesort_alpha);
+                       }
+                       else {
+                               /* keep beginning of list */
+                               for (tp = tear, skip = 0; skip < totelem; skip++, tp++)
+                                       if (tp->idcode) break;
+                               
+                               if (skip < totelem)
+                                       qsort(tear + skip, totelem - skip, sizeof(tTreeSort), treesort_alpha_ob);
+                       }
                        
                        lb->first = lb->last = NULL;
                        tp = tear;
@@ -1552,6 +1586,27 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
                        tselem->flag &= ~TSE_CLOSED;
                }
        }
+       else if (soops->outlinevis == SO_DATAMAIN) {
+               ListBase *lbarray[MAX_LIBARRAY];
+               int a, tot;
+               
+               tot = set_listbasepointers(mainvar, lbarray);
+               for (a = 0; a < tot; a++) {
+                       if (lbarray[a]->first) {
+                               ID *id = lbarray[a]->first;
+                               
+                               ten = outliner_add_element(soops, &soops->tree, (void *)lbarray[a], NULL, TSE_ID_BASE, 0);
+                               ten->directdata = lbarray[a];
+                               
+                               ten->name = (char *)RNA_ID_type_name(GS(id->name));
+                               
+                               for (; id; id = id->next) {
+                                       outliner_add_element(soops, &ten->subtree, id, ten, 0, 0);
+                               }
+                       }
+               }
+               
+       }
        else if (soops->outlinevis == SO_USERDEF) {
                PointerRNA userdefptr;
 
index d632a8861305fc9601532c194e527ad49305fd68..ff775d75bc8cfd563793f44cfee68ebf3c0f9a38 100644 (file)
@@ -270,6 +270,7 @@ typedef enum eSpaceOutliner_Mode {
        SO_DATABLOCKS = 11,
        SO_USERDEF = 12,
        SO_KEYMAP = 13,
+       SO_DATAMAIN = 9,
 } eSpaceOutliner_Mode;
 
 /* SpaceOops->storeflag */
index 5f4e4ce4259424a785280d3afb0b13e4ca1a3bd3..d7dad1757f0f20b95e43661e7274bbf0fe064880 100644 (file)
@@ -1039,6 +1039,8 @@ int RNA_function_call_direct_va_lookup(struct bContext *C, struct ReportList *re
 short RNA_type_to_ID_code(StructRNA *type);
 StructRNA *ID_code_to_RNA_type(short idcode);
 
+const char *RNA_ID_type_name(short type);
+
 
 #define RNA_POINTER_INVALIDATE(ptr) {                                         \
        /* this is checked for validity */                                        \
index cc74fce1733a1890433bf701b8e834a7fd6d1cc2..fac330fc243617c40061cc44473f6064e478f976 100644 (file)
@@ -198,6 +198,15 @@ static Object *rna_Main_objects_new(Main *UNUSED(bmain), ReportList *reports, co
        return ob;
 }
 
+/* exported for non-rna use cases */
+const char *RNA_ID_type_name(short type)
+{
+       const char *idname;
+       if (RNA_enum_id_from_value(id_type_items, type, &idname) == 0)
+               idname = "UNKNOWN";
+       return idname;
+}
+
 static void rna_Main_objects_remove(Main *bmain, ReportList *reports, PointerRNA *object_ptr)
 {
        Object *object = object_ptr->data;
index 034ac544300e3bd1f2f73d9a37b156eb086dd446..3e32cbc280847c5579806a5ac196a50754eab287 100644 (file)
@@ -1255,7 +1255,8 @@ static void rna_def_space_outliner(BlenderRNA *brna)
                {SO_GROUPS, "GROUPS", 0, "Groups", "Display groups and their datablocks"},
                {SO_LIBRARIES, "LIBRARIES", 0, "Libraries", "Display libraries"},
                {SO_SEQUENCE, "SEQUENCE", 0, "Sequence", "Display sequence datablocks"},
-               {SO_DATABLOCKS, "DATABLOCKS", 0, "Datablocks", "Display raw datablocks"},
+               {SO_DATAMAIN, "DATAMAIN", 0, "Main Data", "Displays all Main (relinkable) datablocks"},
+               {SO_DATABLOCKS, "DATABLOCKS", 0, "Datablocks", "Display all raw datablocks"},
                {SO_USERDEF, "USER_PREFERENCES", 0, "User Preferences", "Display the user preference datablocks"},
                {SO_KEYMAP, "KEYMAPS", 0, "Key Maps", "Display keymap datablocks"},
                {0, NULL, 0, NULL, NULL}