1
1

Compare commits

...

1 Commits

Author SHA1 Message Date
7cdf7e992e Initial raw liboverride-dedicated view in the Outliner.
Disclaimer: this is merely a copy of the Libraries (aka blend file)
view, with some minor tweaking.
2021-03-26 12:45:47 +01:00
18 changed files with 466 additions and 28 deletions

View File

@@ -51,13 +51,13 @@ class OUTLINER_HT_header(Header):
row.prop(space, "use_sync_select", icon='UV_SYNC_SELECT', text="")
row = layout.row(align=True)
if display_mode in {'SCENES', 'VIEW_LAYER'}:
if display_mode in {'SCENES', 'VIEW_LAYER', 'LIBRARY_OVERRIDES'}:
row.popover(
panel="OUTLINER_PT_filter",
text="",
icon='FILTER',
)
elif display_mode in {'LIBRARIES', 'ORPHAN_DATA'}:
if display_mode in {'LIBRARIES', 'LIBRARY_OVERRIDES', 'ORPHAN_DATA'}:
row.prop(space, "use_filter_id_type", text="", icon='FILTER')
sub = row.row(align=True)
sub.active = space.use_filter_id_type
@@ -341,19 +341,26 @@ class OUTLINER_PT_filter(Panel):
col = layout.column(align=True)
col.prop(space, "use_sort_alpha")
row = layout.row(align=True)
row.prop(space, "use_sync_select", text="Sync Selection")
if display_mode not in {'LIBRARY_OVERRIDES'}:
row = layout.row(align=True)
row.prop(space, "use_sync_select", text="Sync Selection")
row = layout.row(align=True)
row.prop(space, "show_mode_column", text="Show Mode Column")
layout.separator()
row = layout.row(align=True)
row.prop(space, "show_mode_column", text="Show Mode Column")
layout.separator()
col = layout.column(align=True)
col.label(text="Search")
col.prop(space, "use_filter_complete", text="Exact Match")
col.prop(space, "use_filter_case_sensitive", text="Case Sensitive")
if display_mode != 'VIEW_LAYER':
if display_mode in {'LIBRARY_OVERRIDES'} and bpy.data.libraries:
col.separator()
row = col.row()
row.label(icon='LIBRARY_DATA_OVERRIDE')
row.prop(space, "use_filter_lib_override_system", text="System Overrides")
if display_mode not in {'VIEW_LAYER'}:
return
layout.separator()
@@ -405,10 +412,6 @@ class OUTLINER_PT_filter(Panel):
row = sub.row()
row.label(icon='EMPTY_DATA')
row.prop(space, "use_filter_object_empty", text="Empties")
row = sub.row()
if bpy.data.libraries:
row.label(icon='LIBRARY_DATA_OVERRIDE')
row.prop(space, "use_filter_lib_override", text="Library Overrides")
if (
bpy.data.curves or
@@ -425,6 +428,16 @@ class OUTLINER_PT_filter(Panel):
row.label(icon='BLANK1')
row.prop(space, "use_filter_object_others", text="Others")
if bpy.data.libraries:
col.separator()
row = col.row()
row.label(icon='LIBRARY_DATA_OVERRIDE')
row.prop(space, "use_filter_lib_override", text="Library Overrides")
row = col.row()
row.label(icon='LIBRARY_DATA_OVERRIDE')
row.prop(space, "use_filter_lib_override_system", text="System Overrides")
classes = (
OUTLINER_HT_header,

View File

@@ -702,6 +702,9 @@ static void lib_override_library_create_post_process(Main *bmain,
base = BKE_view_layer_base_find(view_layer, ob_new);
DEG_id_tag_update_ex(
bmain, &ob_new->id, ID_RECALC_TRANSFORM | ID_RECALC_BASE_FLAGS);
if (is_resync) {
ob_new->id.flag |= LIB_LIB_OVERRIDE_RESYNC_LEFTOVER;
}
}
if (ob_new == (Object *)ob_reference->id.newid && base != NULL) {
@@ -713,6 +716,9 @@ static void lib_override_library_create_post_process(Main *bmain,
view_layer, ob_new, is_resync)) {
BKE_collection_object_add(bmain, collection_new, ob_new);
DEG_id_tag_update_ex(bmain, &ob_new->id, ID_RECALC_TRANSFORM | ID_RECALC_BASE_FLAGS);
if (is_resync) {
ob_new->id.flag |= LIB_LIB_OVERRIDE_RESYNC_LEFTOVER;
}
}
}
}
@@ -729,6 +735,9 @@ static void lib_override_library_create_post_process(Main *bmain,
else {
BKE_collection_object_add_from(bmain, scene, (Object *)id_root, ob_new);
}
if (is_resync) {
ob_new->id.flag |= LIB_LIB_OVERRIDE_RESYNC_LEFTOVER;
}
}
break;
}
@@ -1071,6 +1080,7 @@ bool BKE_lib_override_library_resync(Main *bmain,
/* Otherwise, keep them, user needs to decide whether what to do with them. */
BLI_assert((id->tag & LIB_TAG_DOIT) == 0);
id_fake_user_set(id);
id->flag |= LIB_LIB_OVERRIDE_RESYNC_LEFTOVER;
CLOG_INFO(&LOG, 2, "Old override %s is being kept around as it was user-edited", id->name);
}
}

View File

@@ -51,6 +51,7 @@ set(SRC
tree/tree_display_data.cc
tree/tree_display_libraries.cc
tree/tree_display_orphaned.cc
tree/tree_display_override_library.cc
tree/tree_display_scenes.cc
tree/tree_display_sequencer.cc
tree/tree_display_view_layer.cc

View File

@@ -166,8 +166,11 @@ void ED_outliner_selected_objects_get(const bContext *C, ListBase *objects)
bool ED_outliner_collections_editor_poll(bContext *C)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
return (space_outliner != NULL) &&
ELEM(space_outliner->outlinevis, SO_VIEW_LAYER, SO_SCENES, SO_LIBRARIES);
return (space_outliner != NULL) && ELEM(space_outliner->outlinevis,
SO_VIEW_LAYER,
SO_SCENES,
SO_LIBRARIES,
SO_OVERRIDES_LIBRARY);
}
static bool outliner_view_layer_collections_editor_poll(bContext *C)

View File

@@ -1775,6 +1775,116 @@ static void outliner_draw_userbuts(uiBlock *block,
}
}
static bool outliner_draw_overrides_buts(uiBlock *block,
ARegion *region,
SpaceOutliner *space_outliner,
ListBase *lb,
const bool is_open)
{
bool parent_has_warnings = false;
LISTBASE_FOREACH (TreeElement *, te, lb) {
bool has_warnings = false;
const bool do_draw = (te->ys + 2 * UI_UNIT_Y >= region->v2d.cur.ymin &&
te->ys <= region->v2d.cur.ymax);
int but_flag = UI_BUT_DRAG_LOCK;
const char *tip = NULL;
TreeStoreElem *tselem = TREESTORE(te);
switch (tselem->type) {
case TSE_SOME_ID: {
#if 0
if (id->flag & LIB_FAKEUSER) {
tip = TIP_("Data-block will be retained using a fake user");
}
else {
tip = TIP_("Data-block has no users and will be deleted");
}
bt = uiDefIconButBitS(block,
UI_BTYPE_ICON_TOGGLE,
LIB_FAKEUSER,
1,
ICON_FAKE_USER_OFF,
(int)(region->v2d.cur.xmax - OL_TOG_USER_BUTS_STATUS),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
&id->flag,
0,
0,
0,
0,
tip);
UI_but_func_set(bt, restrictbutton_id_user_toggle, id, NULL);
UI_but_flag_enable(bt, but_flag);
#endif
break;
}
case TSE_LIBRARY_OVERRIDE_BASE: {
ID *id = tselem->id;
if (ID_IS_OVERRIDE_LIBRARY_REAL(id) && ID_REAL_USERS(id) == 0) {
has_warnings = true;
if (do_draw) {
tip = TIP_("This override data-block is unused");
}
}
else if (id->flag & LIB_LIB_OVERRIDE_RESYNC_LEFTOVER) {
has_warnings = true;
if (do_draw) {
tip = TIP_(
"This override data-block is not needed anymore, but was detected as user-edited");
}
}
break;
}
case TSE_LIBRARY_OVERRIDE: {
const bool is_rna_path_valid = (bool)(POINTER_AS_UINT(te->directdata));
if (!is_rna_path_valid) {
has_warnings = true;
if (do_draw) {
tip = TIP_(
"This override property does not exist in current data, it will be removed on "
"next .blend file save");
}
}
break;
}
default:
break;
}
const bool have_children_warnings = outliner_draw_overrides_buts(
block,
region,
space_outliner,
&te->subtree,
is_open && TSELEM_OPEN(tselem, space_outliner));
if (do_draw &&
(has_warnings || (have_children_warnings && !TSELEM_OPEN(tselem, space_outliner)))) {
if (tip == NULL) {
tip = TIP_("Some sub-items require attention");
}
uiBut *bt = uiDefIconBlockBut(block,
NULL,
NULL,
1,
ICON_ERROR,
(int)(region->v2d.cur.xmax - OL_TOG_USER_BUTS_STATUS),
te->ys,
UI_UNIT_X,
UI_UNIT_Y,
tip);
UI_but_flag_enable(bt, but_flag);
}
parent_has_warnings = parent_has_warnings || has_warnings || have_children_warnings;
}
return parent_has_warnings;
}
static void outliner_draw_rnacols(ARegion *region, int sizex)
{
View2D *v2d = &region->v2d;
@@ -2896,7 +3006,19 @@ static void outliner_draw_iconrow(bContext *C,
active = tree_element_type_active_state_get(C, tvc, te, tselem);
}
if (!ELEM(tselem->type, TSE_SOME_ID, TSE_LAYER_COLLECTION, TSE_R_LAYER, TSE_GP_LAYER)) {
if (!ELEM(tselem->type,
TSE_ID_BASE,
TSE_SOME_ID,
TSE_LAYER_COLLECTION,
TSE_R_LAYER,
TSE_GP_LAYER,
TSE_LIBRARY_OVERRIDE_BASE,
TSE_LIBRARY_OVERRIDE,
TSE_BONE,
TSE_EBONE,
TSE_POSE_CHANNEL,
TSE_POSEGRP,
TSE_DEFGROUP)) {
outliner_draw_iconrow_doit(block, te, fstyle, xmax, offsx, ys, alpha_fac, active, 1);
}
else {
@@ -3656,7 +3778,11 @@ void draw_outliner(const bContext *C)
}
/* Sync selection state from view layer. */
if (!ELEM(space_outliner->outlinevis, SO_LIBRARIES, SO_DATA_API, SO_ID_ORPHANS) &&
if (!ELEM(space_outliner->outlinevis,
SO_LIBRARIES,
SO_OVERRIDES_LIBRARY,
SO_DATA_API,
SO_ID_ORPHANS) &&
space_outliner->flag & SO_SYNC_SELECT) {
outliner_sync_selection(C, space_outliner);
}
@@ -3703,6 +3829,10 @@ void draw_outliner(const bContext *C)
/* draw user toggle columns */
outliner_draw_userbuts(block, region, space_outliner, &space_outliner->tree);
}
else if (space_outliner->outlinevis == SO_OVERRIDES_LIBRARY) {
/* Draw overrides status columns. */
outliner_draw_overrides_buts(block, region, space_outliner, &space_outliner->tree, true);
}
else if (restrict_column_width > 0.0f) {
/* draw restriction columns */
RestrictPropertiesActive props_active;

View File

@@ -193,7 +193,7 @@ typedef enum {
/* The outliner display modes that support the filter system.
* Note: keep it synced with space_outliner.py */
#define SUPPORT_FILTER_OUTLINER(space_outliner_) \
(ELEM((space_outliner_)->outlinevis, SO_VIEW_LAYER))
(ELEM((space_outliner_)->outlinevis, SO_VIEW_LAYER, SO_OVERRIDES_LIBRARY))
/* Outliner Searching --
*

View File

@@ -356,8 +356,11 @@ static void outliner_sync_selection_from_outliner(Scene *scene,
void ED_outliner_select_sync_from_outliner(bContext *C, SpaceOutliner *space_outliner)
{
/* Don't sync if not checked or in certain outliner display modes */
if (!(space_outliner->flag & SO_SYNC_SELECT) ||
ELEM(space_outliner->outlinevis, SO_LIBRARIES, SO_DATA_API, SO_ID_ORPHANS)) {
if (!(space_outliner->flag & SO_SYNC_SELECT) || ELEM(space_outliner->outlinevis,
SO_LIBRARIES,
SO_OVERRIDES_LIBRARY,
SO_DATA_API,
SO_ID_ORPHANS)) {
return;
}

View File

@@ -908,6 +908,11 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
BLI_assert(!"Expected this ID type to be ported to new Outliner tree-element design");
}
}
else if (ELEM(type, TSE_LIBRARY_OVERRIDE_BASE, TSE_LIBRARY_OVERRIDE)) {
if (!te->type) {
BLI_assert(!"Expected override types to be ported to new Outliner tree-element design");
}
}
else {
/* Other cases must be caught above. */
BLI_assert(TSE_IS_REAL_ID(tselem));

View File

@@ -361,6 +361,7 @@ float outliner_restrict_columns_width(const SpaceOutliner *space_outliner)
case SO_DATA_API:
case SO_SEQUENCE:
case SO_LIBRARIES:
case SO_OVERRIDES_LIBRARY:
return 0.0f;
case SO_ID_ORPHANS:
num_columns = 3;

View File

@@ -273,7 +273,7 @@ static void outliner_main_region_message_subscribe(const wmRegionMessageSubscrib
.notify = ED_region_do_msg_notify_tag_redraw,
};
if (ELEM(space_outliner->outlinevis, SO_VIEW_LAYER, SO_SCENES)) {
if (ELEM(space_outliner->outlinevis, SO_VIEW_LAYER, SO_SCENES, SO_OVERRIDES_LIBRARY)) {
WM_msg_subscribe_rna_anon_prop(mbus, Window, view_layer, &msg_sub_value_region_tag_redraw);
}
}

View File

@@ -44,6 +44,9 @@ TreeDisplay *outliner_tree_display_create(eSpaceOutliner_Mode mode, SpaceOutline
case SO_ID_ORPHANS:
tree_display = new TreeDisplayIDOrphans(*space_outliner);
break;
case SO_OVERRIDES_LIBRARY:
tree_display = new TreeDisplayOverrideLibrary(*space_outliner);
break;
case SO_VIEW_LAYER:
default:
tree_display = new TreeDisplayViewLayer(*space_outliner);

View File

@@ -110,6 +110,24 @@ class TreeDisplayLibraries final : public AbstractTreeDisplay {
short id_filter_get() const;
};
/* -------------------------------------------------------------------- */
/* Library Overrides Tree-Display. */
/**
* \brief Tree-Display for the Library Overrides display mode.
*/
class TreeDisplayOverrideLibrary final : public AbstractTreeDisplay {
public:
TreeDisplayOverrideLibrary(SpaceOutliner &space_outliner);
ListBase buildTree(const TreeSourceData &source_data) override;
private:
TreeElement *add_library_contents(Main &, ListBase &, Library *) const;
bool override_library_id_filter_poll(Library *lib, ID *id) const;
short id_filter_get() const;
};
/* -------------------------------------------------------------------- */
/* Video Sequencer Tree-Display */

View File

@@ -0,0 +1,204 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/** \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 "BLT_translation.h"
#include "../outliner_intern.h"
#include "tree_display.hh"
namespace blender::ed::outliner {
/* Convenience/readability. */
template<typename T> using List = ListBaseWrapper<T>;
TreeDisplayOverrideLibrary::TreeDisplayOverrideLibrary(SpaceOutliner &space_outliner)
: AbstractTreeDisplay(space_outliner)
{
}
ListBase TreeDisplayOverrideLibrary::buildTree(const TreeSourceData &source_data)
{
ListBase tree = {nullptr};
{
/* current file first - mainvar provides tselem with unique pointer - not used */
TreeElement *ten = add_library_contents(*source_data.bmain, tree, nullptr);
TreeStoreElem *tselem;
if (ten) {
tselem = TREESTORE(ten);
if (!tselem->used) {
tselem->flag &= ~TSE_CLOSED;
}
}
}
for (ID *id : List<ID>(source_data.bmain->libraries)) {
Library *lib = reinterpret_cast<Library *>(id);
TreeElement *ten = add_library_contents(*source_data.bmain, tree, lib);
/* NULL-check matters, due to filtering there may not be a new element. */
if (ten) {
lib->id.newid = (ID *)ten;
}
}
/* make hierarchy */
for (TreeElement *ten : List<TreeElement>(tree)) {
if (ten == tree.first) {
/* First item is main, skip. */
continue;
}
TreeStoreElem *tselem = TREESTORE(ten);
Library *lib = (Library *)tselem->id;
BLI_assert(!lib || (GS(lib->id.name) == ID_LI));
if (!lib || !lib->parent) {
continue;
}
TreeElement *parent = (TreeElement *)lib->parent->id.newid;
if (tselem->id->tag & LIB_TAG_INDIRECT) {
/* Only remove from 'first level' if lib is not also directly used. */
BLI_remlink(&tree, ten);
BLI_addtail(&parent->subtree, ten);
ten->parent = parent;
}
else {
/* Else, make a new copy of the libtree for our parent. */
TreeElement *dupten = add_library_contents(*source_data.bmain, parent->subtree, lib);
if (dupten) {
dupten->parent = parent;
}
}
}
/* restore newid pointers */
for (ID *library_id : List<ID>(source_data.bmain->libraries)) {
library_id->newid = nullptr;
}
return tree;
}
TreeElement *TreeDisplayOverrideLibrary::add_library_contents(Main &mainvar,
ListBase &lb,
Library *lib) const
{
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);
}
TreeElement *tenlib = nullptr;
for (int a = 0; a < tot; a++) {
if (!lbarray[a] || !lbarray[a]->first) {
continue;
}
ID *id = nullptr;
/* check if there's data in current lib */
for (ID *id_iter : List<ID>(lbarray[a])) {
if (id_iter->lib == lib && ID_IS_OVERRIDE_LIBRARY_REAL(id_iter)) {
id = id_iter;
break;
}
}
if (id != nullptr) {
if (!tenlib) {
/* Create library tree element on demand, depending if there are any data-blocks. */
if (lib) {
tenlib = outliner_add_element(&space_outliner_, &lb, lib, nullptr, TSE_SOME_ID, 0);
}
else {
tenlib = outliner_add_element(&space_outliner_, &lb, &mainvar, nullptr, TSE_ID_BASE, 0);
tenlib->name = IFACE_("Current File");
}
}
/* Create data-block list parent element on demand. */
if (id != nullptr) {
TreeElement *ten;
if (filter_id_type) {
ten = tenlib;
}
else {
ten = outliner_add_element(
&space_outliner_, &tenlib->subtree, lbarray[a], nullptr, TSE_ID_BASE, 0);
ten->directdata = lbarray[a];
ten->name = outliner_idcode_to_plural(GS(id->name));
}
for (ID *id : List<ID>(lbarray[a])) {
if (override_library_id_filter_poll(lib, id)) {
TreeElement *override_tree_element = outliner_add_element(
&space_outliner_, &ten->subtree, id, ten, TSE_LIBRARY_OVERRIDE_BASE, 0);
if (BLI_listbase_is_empty(&override_tree_element->subtree)) {
outliner_free_tree_element(override_tree_element, &ten->subtree);
}
}
}
}
}
}
return tenlib;
}
short TreeDisplayOverrideLibrary::id_filter_get() const
{
if (space_outliner_.filter & SO_FILTER_ID_TYPE) {
return space_outliner_.filter_id_type;
}
return 0;
}
bool TreeDisplayOverrideLibrary::override_library_id_filter_poll(Library *lib, ID *id) const
{
if (id->lib != lib) {
return false;
}
if (!ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
return false;
}
return true;
}
} // namespace blender::ed::outliner

View File

@@ -40,13 +40,24 @@ TreeElementOverridesBase::TreeElementOverridesBase(TreeElement &legacy_te, ID &i
: AbstractTreeElement(legacy_te), id_(id)
{
BLI_assert(legacy_te.store_elem->type == TSE_LIBRARY_OVERRIDE_BASE);
legacy_te.name = IFACE_("Library Overrides");
if (legacy_te.parent != nullptr &&
ELEM(legacy_te.parent->store_elem->type, TSE_SOME_ID, TSE_LAYER_COLLECTION))
{
legacy_te.name = IFACE_("Library Overrides");
}
else {
legacy_te.name = id.name + 2;
}
}
void TreeElementOverridesBase::expand(SpaceOutliner &space_outliner) const
{
BLI_assert(id_.override_library != nullptr);
const bool show_system_overrides = (SUPPORT_FILTER_OUTLINER(&space_outliner) &&
(space_outliner.filter & SO_FILTER_SHOW_SYSTEM_OVERRIDES) !=
0);
PointerRNA idpoin;
RNA_id_pointer_create(&id_, &idpoin);
@@ -56,15 +67,26 @@ void TreeElementOverridesBase::expand(SpaceOutliner &space_outliner) const
for (auto *override_prop :
ListBaseWrapper<IDOverrideLibraryProperty>(id_.override_library->properties)) {
if (!BKE_lib_override_rna_property_find(
&idpoin, override_prop, &override_rna_ptr, &override_rna_prop)) {
/* This is fine, override properties list is not always fully up-to-date with current
* RNA/IDProps etc., this gets cleaned up when re-generating the overrides rules,
* no error here. */
continue;
const bool is_rna_path_valid = BKE_lib_override_rna_property_find(
&idpoin, override_prop, &override_rna_ptr, &override_rna_prop);
if (is_rna_path_valid && !show_system_overrides &&
ELEM(override_prop->rna_prop_type, PROP_POINTER, PROP_COLLECTION) &&
RNA_struct_is_ID(RNA_property_pointer_type(&override_rna_ptr, override_rna_prop))) {
bool do_continue = true;
for (auto *override_prop_op :
ListBaseWrapper<IDOverrideLibraryPropertyOperation>(override_prop->operations)) {
if ((override_prop_op->flag & IDOVERRIDE_LIBRARY_FLAG_IDPOINTER_MATCH_REFERENCE) == 0) {
do_continue = false;
break;
}
}
if (do_continue) {
continue;
}
}
TreeElementOverridesData data = {id_, *override_prop};
TreeElementOverridesData data = {id_, *override_prop, is_rna_path_valid};
outliner_add_element(
&space_outliner, &legacy_te_.subtree, &data, &legacy_te_, TSE_LIBRARY_OVERRIDE, index++);
}
@@ -79,6 +101,9 @@ TreeElementOverridesProperty::TreeElementOverridesProperty(TreeElement &legacy_t
BLI_assert(legacy_te.store_elem->type == TSE_LIBRARY_OVERRIDE);
legacy_te.name = override_prop_.rna_path;
/* Abusing this for now, better way to do it is also pending current refacor of the whole tree
* code to use CPP... */
legacy_te.directdata = POINTER_FROM_UINT(override_data.is_rna_path_valid);
}
} // namespace blender::ed::outliner

View File

@@ -27,6 +27,7 @@ namespace blender::ed::outliner {
struct TreeElementOverridesData {
ID &id;
IDOverrideLibraryProperty &override_property;
bool is_rna_path_valid;
};
class TreeElementOverridesBase final : public AbstractTreeElement {

View File

@@ -491,6 +491,11 @@ enum {
* Note that this also applies to shapekeys, even though they are not 100% embedded data...
*/
LIB_EMBEDDED_DATA_LIB_OVERRIDE = 1 << 12,
/**
* The override data-block appears to not be needed anymore after resync with linked data, but it
* was kept around (because e.g. detected as user-edited).
*/
LIB_LIB_OVERRIDE_RESYNC_LEFTOVER = 1 << 13,
};
/**

View File

@@ -323,6 +323,8 @@ typedef enum eSpaceOutliner_Filter {
SO_FILTER_NO_CHILDREN = (1 << 4),
SO_FILTER_UNUSED_5 = (1 << 5), /* cleared */
/** Show overrides that are defined/controlled by Blender. */
SO_FILTER_SHOW_SYSTEM_OVERRIDES = SO_FILTER_UNUSED_5, /* re-use */
SO_FILTER_NO_OB_MESH = (1 << 6),
SO_FILTER_NO_OB_ARMATURE = (1 << 7),
SO_FILTER_NO_OB_EMPTY = (1 << 8),
@@ -391,6 +393,7 @@ typedef enum eSpaceOutliner_Mode {
/* SO_KEYMAP = 13, */ /* deprecated! */
SO_ID_ORPHANS = 14,
SO_VIEW_LAYER = 15,
SO_OVERRIDES_LIBRARY = 16,
} eSpaceOutliner_Mode;
/* SpaceOutliner.storeflag */

View File

@@ -3399,6 +3399,11 @@ static void rna_def_space_outliner(BlenderRNA *brna)
ICON_RNA,
"Data API",
"Display low level Blender data and its properties"},
{SO_OVERRIDES_LIBRARY,
"LIBRARY_OVERRIDES",
ICON_LIBRARY_DATA_OVERRIDE,
"Library Overrides",
"Display library overrides data-blocks"},
{SO_ID_ORPHANS,
"ORPHAN_DATA",
ICON_ORPHAN_DATA,
@@ -3588,6 +3593,14 @@ static void rna_def_space_outliner(BlenderRNA *brna)
"Show Library Overrides",
"For libraries with overrides created, show the overridden values");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
prop = RNA_def_property(srna, "use_filter_lib_override_system", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "filter", SO_FILTER_SHOW_SYSTEM_OVERRIDES);
RNA_def_property_ui_text(prop,
"Show System Overrides",
"For libraries with overrides created, show the overridden values that "
"are defined/controlled by Blender");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
}
static void rna_def_space_view3d_shading(BlenderRNA *brna)