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.
This commit is contained in:
Joshua Leung 2015-02-15 21:55:49 +13:00
parent 0ff56ca2aa
commit 030b0aab43
3 changed files with 44 additions and 0 deletions

View File

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

View File

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

View File

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