From 030b0aab430d1fa660d7e3330ecd83caca487b99 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 15 Feb 2015 21:55:49 +1300 Subject: Outliner: Added new mode for displaying "orphaned" datablocks Orphaned datablocks are those which have either: * 0 users * A "fake" user only In the case of the former, they will be quietly discarded from the file on the next save + reload. Hence, it is helpful to have a view where you can confirm which ones fall into this category and might be worth saving. We also include datablocks with a fake user only so that datablocks given a user above can have that easily turned off again (in case the user makes a mistake). Another benefit of showing these is that it become easier to remove fake users from datablocks you no longer want retained without having to hunt for them. --- .../blender/editors/space_outliner/outliner_tree.c | 41 ++++++++++++++++++++++ source/blender/makesdna/DNA_space_types.h | 1 + source/blender/makesrna/intern/rna_space.c | 2 ++ 3 files changed, 44 insertions(+) (limited to 'source') diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index c956d77d64a..d176fd29867 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -1474,6 +1474,7 @@ static int outliner_filter_tree(SpaceOops *soops, ListBase *lb) return (BLI_listbase_is_empty(lb) == false); } +// XXX: move this above all the filters? static void outliner_add_library_contents(Main *mainvar, SpaceOops *soops, TreeElement *te, Library *lib) { TreeElement *ten; @@ -1509,6 +1510,43 @@ static void outliner_add_library_contents(Main *mainvar, SpaceOops *soops, TreeE } +// XXX: move this above all the filters? +static void outliner_add_orphaned_datablocks(Main *mainvar, SpaceOops *soops) +{ + TreeElement *ten; + 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; + + /* check if there are any datablocks of this type which are orphans */ + for (; id; id = id->next) { + if (ID_REAL_USERS(id) <= 0) + break; + } + + if (id) { + /* header for this type of datablock */ + ten = outliner_add_element(soops, &soops->tree, (void *)lbarray[a], NULL, TSE_ID_BASE, 0); + ten->directdata = lbarray[a]; + + ten->name = (char *)BKE_idcode_to_name_plural(GS(id->name)); + if (ten->name == NULL) + ten->name = "UNKNOWN"; + + /* add the orphaned datablocks - these will not be added with any subtrees attached */ + for (id = lbarray[a]->first; id; id = id->next) { + if (ID_REAL_USERS(id) <= 0) + outliner_add_element(soops, &ten->subtree, id, ten, 0, 0); + } + } + } + } +} + /* ======================================================= */ /* Main Tree Building API */ @@ -1713,6 +1751,9 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops) tselem->flag &= ~TSE_CLOSED; } } + else if (soops->outlinevis == SO_ID_ORPHANS) { + outliner_add_orphaned_datablocks(mainvar, soops); + } else { ten = outliner_add_element(soops, &soops->tree, OBACT, NULL, 0, 0); if (ten) ten->directdata = BASACT; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index f41de65f68e..41fbb26c50c 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -292,6 +292,7 @@ typedef enum eSpaceOutliner_Mode { SO_DATABLOCKS = 11, SO_USERDEF = 12, /* SO_KEYMAP = 13, */ /* deprecated! */ + SO_ID_ORPHANS = 14, } eSpaceOutliner_Mode; /* SpaceOops->storeflag */ diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 816d4acd729..ef5a6c2a51c 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1841,6 +1841,8 @@ static void rna_def_space_outliner(BlenderRNA *brna) {SO_LIBRARIES, "LIBRARIES", 0, "Blender File", "Display data of current file and linked libraries"}, {SO_DATABLOCKS, "DATABLOCKS", 0, "Datablocks", "Display all raw datablocks"}, {SO_USERDEF, "USER_PREFERENCES", 0, "User Preferences", "Display the user preference datablocks"}, + {SO_ID_ORPHANS, "ORPHANED_DATABLOCKS", 0, "Orphaned Datablocks", + "Display datablocks which are unused and/or will be lost when the file is reloaded"}, {0, NULL, 0, NULL, NULL} }; -- cgit v1.2.3