From the long todo:

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.
This commit is contained in:
Ton Roosendaal 2012-12-22 13:39:44 +00:00
parent 6a57420b52
commit c5cb2c8b33
6 changed files with 81 additions and 12 deletions

@ -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

@ -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;

@ -270,6 +270,7 @@ typedef enum eSpaceOutliner_Mode {
SO_DATABLOCKS = 11,
SO_USERDEF = 12,
SO_KEYMAP = 13,
SO_DATAMAIN = 9,
} eSpaceOutliner_Mode;
/* SpaceOops->storeflag */

@ -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 */ \

@ -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;

@ -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}