1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup spoutliner
*/
#include "BLI_listbase.h"
#include "BLI_listbase_wrapper.hh"
#include "BKE_collection.h"
#include "BKE_main.h"
#include "DNA_collection_types.h"
#include "DNA_space_types.h"
#include "BLT_translation.h"
#include "../outliner_intern.hh"
#include "common.hh"
#include "tree_display.hh"
#include "tree_element.hh"
namespace blender::ed::outliner {
/* Convenience/readability. */
template<typename T> using List = ListBaseWrapper<T>;
TreeDisplayOverrideLibraryProperties::TreeDisplayOverrideLibraryProperties(SpaceOutliner &space_outliner)
: AbstractTreeDisplay(space_outliner)
{
}
ListBase TreeDisplayOverrideLibraryProperties::buildTree(const TreeSourceData &source_data)
{
ListBase tree = add_library_contents(*source_data.bmain);
for (TreeElement *top_level_te : List<TreeElement>(tree)) {
TreeStoreElem *tselem = TREESTORE(top_level_te);
if (!tselem->used) {
tselem->flag &= ~TSE_CLOSED;
}
}
return tree;
}
ListBase TreeDisplayOverrideLibraryProperties::add_library_contents(Main &mainvar)
{
ListBase tree = {nullptr};
const short filter_id_type = id_filter_get();
ListBase *lbarray[INDEX_ID_MAX];
int tot;
if (filter_id_type) {
lbarray[0] = which_libbase(&mainvar, space_outliner_.filter_id_type);
tot = 1;
}
else {
tot = set_listbasepointers(&mainvar, lbarray);
}
for (int a = 0; a < tot; a++) {
if (!lbarray[a] || !lbarray[a]->first) {
continue;
}
ID *id = nullptr;
/* check if there's data in current id list */
for (ID *id_iter : List<ID>(lbarray[a])) {
if (ID_IS_OVERRIDE_LIBRARY_REAL(id_iter) && !ID_IS_LINKED(id_iter)) {
id = id_iter;
break;
}
}
if (id == nullptr) {
continue;
}
/* Create data-block list parent element on demand. */
TreeElement *id_base_te = nullptr;
ListBase *lb_to_expand = &tree;
if (!filter_id_type) {
id_base_te = outliner_add_element(
&space_outliner_, &tree, lbarray[a], nullptr, TSE_ID_BASE, 0);
id_base_te->directdata = lbarray[a];
id_base_te->name = outliner_idcode_to_plural(GS(id->name));
lb_to_expand = &id_base_te->subtree;
}
for (ID *id : List<ID>(lbarray[a])) {
if (ID_IS_OVERRIDE_LIBRARY_REAL(id) && !ID_IS_LINKED(id)) {
TreeElement *override_tree_element = outliner_add_element(
&space_outliner_, lb_to_expand, id, id_base_te, TSE_LIBRARY_OVERRIDE_BASE, 0);
if (BLI_listbase_is_empty(&override_tree_element->subtree)) {
outliner_free_tree_element(override_tree_element, lb_to_expand);
}
}
}
}
/* Remove ID base elements that turn out to be empty. */
LISTBASE_FOREACH_MUTABLE (TreeElement *, te, &tree) {
if (BLI_listbase_is_empty(&te->subtree)) {
outliner_free_tree_element(te, &tree);
}
}
return tree;
}
short TreeDisplayOverrideLibraryProperties::id_filter_get() const
{
if (space_outliner_.filter & SO_FILTER_ID_TYPE) {
return space_outliner_.filter_id_type;
}
return 0;
}
} // namespace blender::ed::outliner
|