Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <bastien@blender.org>2022-03-09 14:47:24 +0300
committerFabian Schempp <fabianschempp@googlemail.com>2022-04-11 01:30:37 +0300
commit27cf0ad4231a3c6ba9b13c030cf502c27ab2afa0 (patch)
treee43e1ca939711a39a903ef7784a88a38928db958 /source/blender/editors/space_outliner
parentdb72a95723d7a5a71a6e56b299109d508299afbb (diff)
LibOverride/Outliner: Restrict further operations over liboverrides.
Restrict a lot deletion/moving around of liboverride objects and collections in the Outliner. While some of those operations may be valid in some specific cases, in the vast majority of cases they would just end up breaking override hierarchies/relationships. Part of T95708/T95707.
Diffstat (limited to 'source/blender/editors/space_outliner')
-rw-r--r--source/blender/editors/space_outliner/outliner_collections.cc64
-rw-r--r--source/blender/editors/space_outliner/outliner_intern.hh2
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.cc11
3 files changed, 60 insertions, 17 deletions
diff --git a/source/blender/editors/space_outliner/outliner_collections.cc b/source/blender/editors/space_outliner/outliner_collections.cc
index f38f6c2855d..7c0ccd7b14c 100644
--- a/source/blender/editors/space_outliner/outliner_collections.cc
+++ b/source/blender/editors/space_outliner/outliner_collections.cc
@@ -9,6 +9,7 @@
#include "BLI_listbase.h"
#include "BLI_utildefines.h"
+#include "DNA_ID.h"
#include "DNA_collection_types.h"
#include "DNA_object_types.h"
@@ -275,6 +276,12 @@ struct CollectionEditData {
Scene *scene;
SpaceOutliner *space_outliner;
GSet *collections_to_edit;
+
+ /* Whether the processed operation should be allowed on liboverride collections, or not. */
+ bool is_liboverride_allowed;
+ /* Whether the processed operation should be allowed on hierarchy roots of liboverride
+ * collections, or not. */
+ bool is_liboverride_hierarchy_root_allowed;
};
static TreeTraversalAction collection_find_data_to_edit(TreeElement *te, void *customdata)
@@ -287,27 +294,40 @@ static TreeTraversalAction collection_find_data_to_edit(TreeElement *te, void *c
}
if (collection->flag & COLLECTION_IS_MASTER) {
- /* skip - showing warning/error message might be misleading
- * when deleting multiple collections, so just do nothing */
+ /* Skip - showing warning/error message might be misleading
+ * when deleting multiple collections, so just do nothing. */
+ return TRAVERSE_CONTINUE;
}
- else {
- /* Delete, duplicate and link don't edit children, those will come along
- * with the parents. */
- BLI_gset_add(data->collections_to_edit, collection);
- return TRAVERSE_SKIP_CHILDS;
+
+ if (ID_IS_OVERRIDE_LIBRARY_REAL(collection)) {
+ if (ID_IS_OVERRIDE_LIBRARY_HIERARCHY_ROOT(collection)) {
+ if (!data->is_liboverride_hierarchy_root_allowed) {
+ return TRAVERSE_SKIP_CHILDS;
+ }
+ }
+ else {
+ if (!data->is_liboverride_allowed) {
+ return TRAVERSE_SKIP_CHILDS;
+ }
+ }
}
- return TRAVERSE_CONTINUE;
+ /* Delete, duplicate and link don't edit children, those will come along
+ * with the parents. */
+ BLI_gset_add(data->collections_to_edit, collection);
+ return TRAVERSE_SKIP_CHILDS;
}
void outliner_collection_delete(
- bContext *C, Main *bmain, Scene *scene, ReportList *reports, bool hierarchy)
+ bContext *C, Main *bmain, Scene *scene, ReportList *reports, bool do_hierarchy)
{
SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
CollectionEditData data{};
data.scene = scene;
data.space_outliner = space_outliner;
+ data.is_liboverride_allowed = false;
+ data.is_liboverride_hierarchy_root_allowed = do_hierarchy;
data.collections_to_edit = BLI_gset_ptr_new(__func__);
@@ -356,14 +376,14 @@ void outliner_collection_delete(
}
if (!skip) {
- BKE_collection_delete(bmain, collection, hierarchy);
+ BKE_collection_delete(bmain, collection, do_hierarchy);
}
else {
- BKE_reportf(
- reports,
- RPT_WARNING,
- "Cannot delete linked collection '%s', it is used by other linked scenes/collections",
- collection->id.name + 2);
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Cannot delete collection '%s', it is either a linked one used by other "
+ "linked scenes/collections, or a library override one",
+ collection->id.name + 2);
}
}
}
@@ -662,6 +682,8 @@ static int collection_link_exec(bContext *C, wmOperator *op)
CollectionEditData data{};
data.scene = scene;
data.space_outliner = space_outliner;
+ data.is_liboverride_allowed = false; /* No linking of non-root collections. */
+ data.is_liboverride_hierarchy_root_allowed = true;
if ((ID_IS_LINKED(active_collection) || ID_IS_OVERRIDE_LIBRARY(active_collection)) ||
((active_collection->flag & COLLECTION_IS_MASTER) &&
@@ -726,6 +748,8 @@ static int collection_instance_exec(bContext *C, wmOperator *UNUSED(op))
CollectionEditData data{};
data.scene = scene;
data.space_outliner = space_outliner;
+ data.is_liboverride_allowed = false; /* No instancing of non-root collections. */
+ data.is_liboverride_hierarchy_root_allowed = true;
data.collections_to_edit = BLI_gset_ptr_new(__func__);
@@ -825,6 +849,8 @@ static bool collections_view_layer_poll(bContext *C, bool clear, int flag)
CollectionEditData data{};
data.scene = scene;
data.space_outliner = space_outliner;
+ data.is_liboverride_allowed = true;
+ data.is_liboverride_hierarchy_root_allowed = true;
data.collections_to_edit = BLI_gset_ptr_new(__func__);
bool result = false;
@@ -891,6 +917,8 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op)
CollectionEditData data{};
data.scene = scene;
data.space_outliner = space_outliner;
+ data.is_liboverride_allowed = true;
+ data.is_liboverride_hierarchy_root_allowed = true;
bool clear = strstr(op->idname, "clear") != nullptr;
int flag = strstr(op->idname, "holdout") ? LAYER_COLLECTION_HOLDOUT :
strstr(op->idname, "indirect_only") ? LAYER_COLLECTION_INDIRECT_ONLY :
@@ -1029,6 +1057,8 @@ static int collection_isolate_exec(bContext *C, wmOperator *op)
CollectionEditData data{};
data.scene = scene;
data.space_outliner = space_outliner;
+ data.is_liboverride_allowed = true;
+ data.is_liboverride_hierarchy_root_allowed = true;
data.collections_to_edit = BLI_gset_ptr_new(__func__);
outliner_tree_traverse(space_outliner,
&space_outliner->tree,
@@ -1126,6 +1156,8 @@ static int collection_visibility_exec(bContext *C, wmOperator *op)
CollectionEditData data{};
data.scene = scene;
data.space_outliner = space_outliner;
+ data.is_liboverride_allowed = true;
+ data.is_liboverride_hierarchy_root_allowed = true;
data.collections_to_edit = BLI_gset_ptr_new(__func__);
outliner_tree_traverse(space_outliner,
@@ -1273,6 +1305,8 @@ static int collection_flag_exec(bContext *C, wmOperator *op)
CollectionEditData data{};
data.scene = scene;
data.space_outliner = space_outliner;
+ data.is_liboverride_allowed = true;
+ data.is_liboverride_hierarchy_root_allowed = true;
data.collections_to_edit = BLI_gset_ptr_new(__func__);
const bool has_layer_collection = space_outliner->outlinevis == SO_VIEW_LAYER;
diff --git a/source/blender/editors/space_outliner/outliner_intern.hh b/source/blender/editors/space_outliner/outliner_intern.hh
index 0516758e887..7a45531c608 100644
--- a/source/blender/editors/space_outliner/outliner_intern.hh
+++ b/source/blender/editors/space_outliner/outliner_intern.hh
@@ -545,7 +545,7 @@ void outliner_collection_delete(struct bContext *C,
struct Main *bmain,
struct Scene *scene,
struct ReportList *reports,
- bool hierarchy);
+ bool do_hierarchy);
void OUTLINER_OT_collection_new(struct wmOperatorType *ot);
void OUTLINER_OT_collection_duplicate_linked(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_outliner/outliner_tools.cc b/source/blender/editors/space_outliner/outliner_tools.cc
index a931f65ad08..71a22d76f15 100644
--- a/source/blender/editors/space_outliner/outliner_tools.cc
+++ b/source/blender/editors/space_outliner/outliner_tools.cc
@@ -1698,7 +1698,16 @@ static TreeTraversalAction outliner_find_objects_to_delete(TreeElement *te, void
return TRAVERSE_SKIP_CHILDS;
}
- BLI_gset_add(objects_to_delete, tselem->id);
+ ID *id = tselem->id;
+
+ if (ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
+ if (!ID_IS_OVERRIDE_LIBRARY_HIERARCHY_ROOT(id)) {
+ /* Only allow deletion of liboverride objects if they are root overrides. */
+ return TRAVERSE_SKIP_CHILDS;
+ }
+ }
+
+ BLI_gset_add(objects_to_delete, id);
return TRAVERSE_CONTINUE;
}