Scenes: forbid deleting last local scene

Previously, it was only forbidden to delete the last scene. This can
lead to the situation where a .blend file only contains linked scenes.
This is problematic, because linked data might not always be available
or can be removed from a .blend file without having an additional check
for remaining scenes.

Now there always has to be at least one local scene.

Reviewers: mont29

Differential Revision: https://developer.blender.org/D10049
This commit is contained in:
Jacques Lucke 2021-01-08 16:30:44 +01:00
parent 2d3f96cace
commit bc788929aa
4 changed files with 25 additions and 5 deletions

View File

@ -110,6 +110,8 @@ void BKE_toolsettings_free(struct ToolSettings *toolsettings);
struct Scene *BKE_scene_duplicate(struct Main *bmain, struct Scene *sce, eSceneCopyMethod type);
void BKE_scene_groups_relink(struct Scene *sce);
bool BKE_scene_can_be_removed(const struct Main *bmain, const struct Scene *scene);
bool BKE_scene_has_view_layer(const struct Scene *scene, const struct ViewLayer *layer);
struct Scene *BKE_scene_find_from_collection(const struct Main *bmain,
const struct Collection *collection);

View File

@ -2032,6 +2032,21 @@ void BKE_scene_groups_relink(Scene *sce)
}
}
bool BKE_scene_can_be_removed(const Main *bmain, const Scene *scene)
{
/* Linked scenes can always be removed. */
if (ID_IS_LINKED(scene)) {
return true;
}
/* Local scenes can only be removed, when there is at least one local scene left. */
LISTBASE_FOREACH (Scene *, other_scene, &bmain->scenes) {
if (other_scene != scene && !ID_IS_LINKED(other_scene)) {
return true;
}
}
return false;
}
Scene *BKE_scene_add(Main *bmain, const char *name)
{
Scene *sce;

View File

@ -240,8 +240,9 @@ static void SCENE_OT_new(wmOperatorType *ot)
static bool scene_delete_poll(bContext *C)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
return (scene->id.prev || scene->id.next);
return BKE_scene_can_be_removed(bmain, scene);
}
static int scene_delete_exec(bContext *C, wmOperator *UNUSED(op))

View File

@ -194,9 +194,9 @@ static void rna_Main_scenes_remove(
{
/* don't call BKE_id_free(...) directly */
Scene *scene = scene_ptr->data;
Scene *scene_new;
if ((scene_new = scene->id.prev) || (scene_new = scene->id.next)) {
if (BKE_scene_can_be_removed(bmain, scene)) {
Scene *scene_new = scene->id.prev ? scene->id.prev : scene->id.next;
if (do_unlink) {
wmWindow *win = CTX_wm_window(C);
@ -216,8 +216,10 @@ static void rna_Main_scenes_remove(
rna_Main_ID_remove(bmain, reports, scene_ptr, do_unlink, true, true);
}
else {
BKE_reportf(
reports, RPT_ERROR, "Scene '%s' is the last, cannot be removed", scene->id.name + 2);
BKE_reportf(reports,
RPT_ERROR,
"Scene '%s' is the last local one, cannot be removed",
scene->id.name + 2);
}
}