Refactor: Move Editors' 'foreach_id' code into a new SpaceType callback.
Was a known pending TODO for quite some time already. This commit should have no behavior change at all.
This commit is contained in:
@@ -105,6 +105,13 @@ typedef struct SpaceType {
|
||||
/* Used when we want to replace an ID by another (or NULL). */
|
||||
void (*id_remap)(struct ScrArea *area, struct SpaceLink *sl, const struct IDRemapper *mappings);
|
||||
|
||||
/**
|
||||
* foreach_id callback to process all ID pointers of the editor. Used indirectly by lib_query's
|
||||
* #BKE_library_foreach_ID_link when #IDWALK_INCLUDE_UI bitflag is set (through WM's foreach_id
|
||||
* usage of #BKE_screen_foreach_id_screen_area).
|
||||
*/
|
||||
void (*foreach_id)(struct SpaceLink *space_link, struct LibraryForeachIDData *data);
|
||||
|
||||
int (*space_subtype_get)(struct ScrArea *area);
|
||||
void (*space_subtype_set)(struct ScrArea *area, int value);
|
||||
void (*space_subtype_item_extend)(struct bContext *C, EnumPropertyItem **item, int *totitem);
|
||||
|
||||
@@ -81,243 +81,15 @@ static void screen_free_data(ID *id)
|
||||
MEM_SAFE_FREE(screen->tool_tip);
|
||||
}
|
||||
|
||||
static void screen_foreach_id_dopesheet(LibraryForeachIDData *data, bDopeSheet *ads)
|
||||
{
|
||||
if (ads != nullptr) {
|
||||
BKE_LIB_FOREACHID_PROCESS_ID(data, ads->source, IDWALK_CB_NOP);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, ads->filter_grp, IDWALK_CB_NOP);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_screen_foreach_id_screen_area(LibraryForeachIDData *data, ScrArea *area)
|
||||
{
|
||||
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
|
||||
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
|
||||
const bool allow_pointer_access = (data_flags & IDWALK_NO_ORIG_POINTERS_ACCESS) == 0;
|
||||
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, area->full, IDWALK_CB_NOP);
|
||||
|
||||
/* TODO: this should be moved to a callback in `SpaceType`, defined in each editor's own code.
|
||||
* Will be for a later round of cleanup though... */
|
||||
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
||||
switch (sl->spacetype) {
|
||||
case SPACE_VIEW3D: {
|
||||
View3D *v3d = (View3D *)sl;
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, v3d->camera, IDWALK_CB_NOP);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, v3d->ob_center, IDWALK_CB_NOP);
|
||||
if (v3d->localvd) {
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, v3d->localvd->camera, IDWALK_CB_NOP);
|
||||
}
|
||||
BKE_viewer_path_foreach_id(data, &v3d->viewer_path);
|
||||
break;
|
||||
}
|
||||
case SPACE_GRAPH: {
|
||||
SpaceGraph *sipo = (SpaceGraph *)sl;
|
||||
BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data,
|
||||
screen_foreach_id_dopesheet(data, sipo->ads));
|
||||
SpaceType *space_type = BKE_spacetype_from_id(sl->spacetype);
|
||||
|
||||
if (!is_readonly) {
|
||||
/* Force recalc of list of channels (i.e. including calculating F-Curve colors) to
|
||||
* prevent the "black curves" problem post-undo. */
|
||||
sipo->runtime.flag |= SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPACE_PROPERTIES: {
|
||||
SpaceProperties *sbuts = (SpaceProperties *)sl;
|
||||
BKE_LIB_FOREACHID_PROCESS_ID(data, sbuts->pinid, IDWALK_CB_NOP);
|
||||
if (!is_readonly) {
|
||||
if (sbuts->pinid == nullptr) {
|
||||
sbuts->flag &= ~SB_PIN_CONTEXT;
|
||||
}
|
||||
/* NOTE: Restoring path pointers is complicated, if not impossible, because this contains
|
||||
* data pointers too, not just ID ones. See #40046. */
|
||||
MEM_SAFE_FREE(sbuts->path);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPACE_FILE: {
|
||||
if (!is_readonly) {
|
||||
SpaceFile *sfile = (SpaceFile *)sl;
|
||||
sfile->op = nullptr;
|
||||
sfile->tags = FILE_TAG_REBUILD_MAIN_FILES;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPACE_ACTION: {
|
||||
SpaceAction *saction = (SpaceAction *)sl;
|
||||
screen_foreach_id_dopesheet(data, &saction->ads);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, saction->action, IDWALK_CB_NOP);
|
||||
if (!is_readonly) {
|
||||
/* Force recalc of list of channels, potentially updating the active action while we're
|
||||
* at it (as it can only be updated that way) #28962. */
|
||||
saction->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPACE_IMAGE: {
|
||||
SpaceImage *sima = (SpaceImage *)sl;
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sima->image, IDWALK_CB_USER_ONE);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sima->iuser.scene, IDWALK_CB_NOP);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sima->mask_info.mask, IDWALK_CB_USER_ONE);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sima->gpd, IDWALK_CB_USER);
|
||||
if (!is_readonly) {
|
||||
sima->scopes.ok = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPACE_SEQ: {
|
||||
SpaceSeq *sseq = (SpaceSeq *)sl;
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sseq->gpd, IDWALK_CB_USER);
|
||||
break;
|
||||
}
|
||||
case SPACE_NLA: {
|
||||
SpaceNla *snla = (SpaceNla *)sl;
|
||||
BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(data,
|
||||
screen_foreach_id_dopesheet(data, snla->ads));
|
||||
break;
|
||||
}
|
||||
case SPACE_TEXT: {
|
||||
SpaceText *st = (SpaceText *)sl;
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, st->text, IDWALK_CB_USER_ONE);
|
||||
break;
|
||||
}
|
||||
case SPACE_SCRIPT: {
|
||||
SpaceScript *scpt = (SpaceScript *)sl;
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, scpt->script, IDWALK_CB_NOP);
|
||||
break;
|
||||
}
|
||||
case SPACE_OUTLINER: {
|
||||
SpaceOutliner *space_outliner = (SpaceOutliner *)sl;
|
||||
if (space_outliner->treestore != nullptr) {
|
||||
TreeStoreElem *tselem;
|
||||
BLI_mempool_iter iter;
|
||||
|
||||
BLI_mempool_iternew(space_outliner->treestore, &iter);
|
||||
while ((tselem = static_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) {
|
||||
/* Do not try to restore non-ID pointers (drivers/sequence/etc.). */
|
||||
if (TSE_IS_REAL_ID(tselem)) {
|
||||
const int cb_flag = (tselem->id != nullptr && allow_pointer_access &&
|
||||
(tselem->id->flag & LIB_EMBEDDED_DATA) != 0) ?
|
||||
IDWALK_CB_EMBEDDED_NOT_OWNING :
|
||||
IDWALK_CB_NOP;
|
||||
BKE_LIB_FOREACHID_PROCESS_ID(data, tselem->id, cb_flag);
|
||||
}
|
||||
else if (!is_readonly) {
|
||||
tselem->id = nullptr;
|
||||
}
|
||||
}
|
||||
if (!is_readonly) {
|
||||
/* rebuild hash table, because it depends on ids too */
|
||||
space_outliner->storeflag |= SO_TREESTORE_REBUILD;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPACE_NODE: {
|
||||
SpaceNode *snode = (SpaceNode *)sl;
|
||||
const bool is_embedded_nodetree = snode->id != nullptr && allow_pointer_access &&
|
||||
ntreeFromID(snode->id) == snode->nodetree;
|
||||
|
||||
BKE_LIB_FOREACHID_PROCESS_ID(data, snode->id, IDWALK_CB_NOP);
|
||||
BKE_LIB_FOREACHID_PROCESS_ID(data, snode->from, IDWALK_CB_NOP);
|
||||
|
||||
bNodeTreePath *path = static_cast<bNodeTreePath *>(snode->treepath.first);
|
||||
BLI_assert(path == nullptr || path->nodetree == snode->nodetree);
|
||||
|
||||
if (is_embedded_nodetree) {
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, snode->nodetree, IDWALK_CB_EMBEDDED_NOT_OWNING);
|
||||
if (path != nullptr) {
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, path->nodetree, IDWALK_CB_EMBEDDED_NOT_OWNING);
|
||||
}
|
||||
|
||||
/* Embedded ID pointers are not remapped (besides exceptions), ensure it still matches
|
||||
* actual data. Note that `snode->id` was already processed (and therefore potentially
|
||||
* remapped) above. */
|
||||
if (!is_readonly) {
|
||||
snode->nodetree = (snode->id == nullptr) ? nullptr : ntreeFromID(snode->id);
|
||||
if (path != nullptr) {
|
||||
path->nodetree = snode->nodetree;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, snode->nodetree, IDWALK_CB_USER_ONE);
|
||||
if (path != nullptr) {
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, path->nodetree, IDWALK_CB_USER_ONE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Both `snode->id` and `snode->nodetree` have been remapped now, so their data can be
|
||||
* accessed. */
|
||||
BLI_assert(snode->id == nullptr || snode->nodetree == nullptr ||
|
||||
(snode->nodetree->id.flag & LIB_EMBEDDED_DATA) == 0 ||
|
||||
snode->nodetree == ntreeFromID(snode->id));
|
||||
|
||||
if (path != nullptr) {
|
||||
for (path = path->next; path != nullptr; path = path->next) {
|
||||
BLI_assert(path->nodetree != nullptr);
|
||||
if ((data_flags & IDWALK_NO_ORIG_POINTERS_ACCESS) == 0) {
|
||||
BLI_assert((path->nodetree->id.flag & LIB_EMBEDDED_DATA) == 0);
|
||||
}
|
||||
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, path->nodetree, IDWALK_CB_USER_ONE);
|
||||
|
||||
if (path->nodetree == nullptr) {
|
||||
BLI_assert(!is_readonly);
|
||||
/* Remaining path entries are invalid, remove them. */
|
||||
for (bNodeTreePath *path_next; path; path = path_next) {
|
||||
path_next = path->next;
|
||||
BLI_remlink(&snode->treepath, path);
|
||||
MEM_freeN(path);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
BLI_assert(path == nullptr);
|
||||
|
||||
if (!is_readonly) {
|
||||
/* `edittree` is just the last in the path, set this directly since the path may have
|
||||
* been shortened above. */
|
||||
if (snode->treepath.last != nullptr) {
|
||||
path = static_cast<bNodeTreePath *>(snode->treepath.last);
|
||||
snode->edittree = path->nodetree;
|
||||
}
|
||||
else {
|
||||
snode->edittree = nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Only process this pointer in readonly case, otherwise could lead to a bad
|
||||
* double-remapping e.g. */
|
||||
if (is_embedded_nodetree && snode->edittree == snode->nodetree) {
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(
|
||||
data, snode->edittree, IDWALK_CB_EMBEDDED_NOT_OWNING);
|
||||
}
|
||||
else {
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, snode->edittree, IDWALK_CB_NOP);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPACE_CLIP: {
|
||||
SpaceClip *sclip = (SpaceClip *)sl;
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sclip->clip, IDWALK_CB_USER_ONE);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sclip->mask_info.mask, IDWALK_CB_USER_ONE);
|
||||
|
||||
if (!is_readonly) {
|
||||
sclip->scopes.ok = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPACE_SPREADSHEET: {
|
||||
SpaceSpreadsheet *sspreadsheet = (SpaceSpreadsheet *)sl;
|
||||
BKE_viewer_path_foreach_id(data, &sspreadsheet->viewer_path);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
if (space_type && space_type->foreach_id) {
|
||||
space_type->foreach_id(sl, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_remap.h"
|
||||
#include "BKE_nla.h"
|
||||
#include "BKE_screen.h"
|
||||
@@ -805,6 +806,25 @@ static void action_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemapp
|
||||
BKE_id_remapper_apply(mappings, &sact->ads.source, ID_REMAP_APPLY_DEFAULT);
|
||||
}
|
||||
|
||||
static void action_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
|
||||
{
|
||||
SpaceAction *sact = reinterpret_cast<SpaceAction *>(space_link);
|
||||
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
|
||||
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
|
||||
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sact->action, IDWALK_CB_NOP);
|
||||
|
||||
/* NOTE: Could be deduplicated with the #bDopeSheet handling of #SpaceNla and #SpaceGraph. */
|
||||
BKE_LIB_FOREACHID_PROCESS_ID(data, sact->ads.source, IDWALK_CB_NOP);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sact->ads.filter_grp, IDWALK_CB_NOP);
|
||||
|
||||
if (!is_readonly) {
|
||||
/* Force recalc of list of channels, potentially updating the active action while we're
|
||||
* at it (as it can only be updated that way) #28962. */
|
||||
sact->runtime.flag |= SACTION_RUNTIME_FLAG_NEED_CHAN_SYNC;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \note Used for splitting out a subset of modes is more involved,
|
||||
* The previous non-timeline mode is stored so switching back to the
|
||||
@@ -884,6 +904,7 @@ void ED_spacetype_action()
|
||||
st->listener = action_listener;
|
||||
st->refresh = action_refresh;
|
||||
st->id_remap = action_id_remap;
|
||||
st->foreach_id = action_foreach_id;
|
||||
st->space_subtype_item_extend = action_space_subtype_item_extend;
|
||||
st->space_subtype_get = action_space_subtype_get;
|
||||
st->space_subtype_set = action_space_subtype_set;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_gpencil_modifier_legacy.h" /* Types for registering panels. */
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_remap.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_screen.h"
|
||||
@@ -906,6 +907,23 @@ static void buttons_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemap
|
||||
}
|
||||
}
|
||||
|
||||
static void buttons_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
|
||||
{
|
||||
SpaceProperties *sbuts = reinterpret_cast<SpaceProperties *>(space_link);
|
||||
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
|
||||
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
|
||||
|
||||
BKE_LIB_FOREACHID_PROCESS_ID(data, sbuts->pinid, IDWALK_CB_NOP);
|
||||
if (!is_readonly) {
|
||||
if (sbuts->pinid == nullptr) {
|
||||
sbuts->flag &= ~SB_PIN_CONTEXT;
|
||||
}
|
||||
/* NOTE: Restoring path pointers is complicated, if not impossible, because this contains
|
||||
* data pointers too, not just ID ones. See #40046. */
|
||||
MEM_SAFE_FREE(sbuts->path);
|
||||
}
|
||||
}
|
||||
|
||||
static void buttons_space_blend_read_data(BlendDataReader * /*reader*/, SpaceLink *sl)
|
||||
{
|
||||
SpaceProperties *sbuts = (SpaceProperties *)sl;
|
||||
@@ -954,6 +972,7 @@ void ED_spacetype_buttons()
|
||||
st->listener = buttons_area_listener;
|
||||
st->context = buttons_context;
|
||||
st->id_remap = buttons_id_remap;
|
||||
st->foreach_id = buttons_foreach_id;
|
||||
st->blend_read_data = buttons_space_blend_read_data;
|
||||
st->blend_read_lib = buttons_space_blend_read_lib;
|
||||
st->blend_write = buttons_space_blend_write;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_remap.h"
|
||||
#include "BKE_movieclip.h"
|
||||
#include "BKE_screen.h"
|
||||
@@ -1162,6 +1163,20 @@ static void clip_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemapper
|
||||
BKE_id_remapper_apply(mappings, (ID **)&sclip->mask_info.mask, ID_REMAP_APPLY_ENSURE_REAL);
|
||||
}
|
||||
|
||||
static void clip_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
|
||||
{
|
||||
SpaceClip *sclip = reinterpret_cast<SpaceClip *>(space_link);
|
||||
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
|
||||
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
|
||||
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sclip->clip, IDWALK_CB_USER_ONE);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sclip->mask_info.mask, IDWALK_CB_USER_ONE);
|
||||
|
||||
if (!is_readonly) {
|
||||
sclip->scopes.ok = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void clip_space_blend_read_data(BlendDataReader * /*reader*/, SpaceLink *sl)
|
||||
{
|
||||
SpaceClip *sclip = (SpaceClip *)sl;
|
||||
@@ -1209,6 +1224,7 @@ void ED_spacetype_clip()
|
||||
st->dropboxes = clip_dropboxes;
|
||||
st->refresh = clip_refresh;
|
||||
st->id_remap = clip_id_remap;
|
||||
st->foreach_id = clip_foreach_id;
|
||||
st->blend_read_data = clip_space_blend_read_data;
|
||||
st->blend_read_lib = clip_space_blend_read_lib;
|
||||
st->blend_write = clip_space_blend_write;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "BKE_appdir.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_remap.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_report.h"
|
||||
@@ -843,6 +844,20 @@ static void file_id_remap(ScrArea *area, SpaceLink *sl, const IDRemapper * /*map
|
||||
file_reset_filelist_showing_main_data(area, sfile);
|
||||
}
|
||||
|
||||
static void file_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
|
||||
{
|
||||
SpaceFile *sfile = reinterpret_cast<SpaceFile *>(space_link);
|
||||
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
|
||||
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
|
||||
|
||||
/* TODO: investigate whether differences between this code and the one in #file_id_remap are
|
||||
* meaningful and make sense or not. */
|
||||
if (!is_readonly) {
|
||||
sfile->op = nullptr;
|
||||
sfile->tags = FILE_TAG_REBUILD_MAIN_FILES;
|
||||
}
|
||||
}
|
||||
|
||||
static void file_space_blend_read_data(BlendDataReader *reader, SpaceLink *sl)
|
||||
{
|
||||
SpaceFile *sfile = (SpaceFile *)sl;
|
||||
@@ -912,6 +927,7 @@ void ED_spacetype_file()
|
||||
st->space_subtype_set = file_space_subtype_set;
|
||||
st->context = file_context;
|
||||
st->id_remap = file_id_remap;
|
||||
st->foreach_id = file_foreach_id;
|
||||
st->blend_read_data = file_space_blend_read_data;
|
||||
st->blend_read_lib = file_space_blend_read_lib;
|
||||
st->blend_write = file_space_blend_write;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_remap.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
@@ -814,6 +815,27 @@ static void graph_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemappe
|
||||
BKE_id_remapper_apply(mappings, (ID **)&sgraph->ads->source, ID_REMAP_APPLY_DEFAULT);
|
||||
}
|
||||
|
||||
static void graph_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
|
||||
{
|
||||
SpaceGraph *sgraph = reinterpret_cast<SpaceGraph *>(space_link);
|
||||
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
|
||||
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
|
||||
|
||||
/* NOTE: Could be deduplicated with the #bDopeSheet handling of #SpaceAction and #SpaceNla. */
|
||||
if (sgraph->ads == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
BKE_LIB_FOREACHID_PROCESS_ID(data, sgraph->ads->source, IDWALK_CB_NOP);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sgraph->ads->filter_grp, IDWALK_CB_NOP);
|
||||
|
||||
if (!is_readonly) {
|
||||
/* Force recalc of list of channels (i.e. including calculating F-Curve colors) to
|
||||
* prevent the "black curves" problem post-undo. */
|
||||
sgraph->runtime.flag |= SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR;
|
||||
}
|
||||
}
|
||||
|
||||
static int graph_space_subtype_get(ScrArea *area)
|
||||
{
|
||||
SpaceGraph *sgraph = static_cast<SpaceGraph *>(area->spacedata.first);
|
||||
@@ -886,6 +908,7 @@ void ED_spacetype_ipo()
|
||||
st->listener = graph_listener;
|
||||
st->refresh = graph_refresh;
|
||||
st->id_remap = graph_id_remap;
|
||||
st->foreach_id = graph_foreach_id;
|
||||
st->space_subtype_item_extend = graph_space_subtype_item_extend;
|
||||
st->space_subtype_get = graph_space_subtype_get;
|
||||
st->space_subtype_set = graph_space_subtype_set;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "BKE_image.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_remap.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
@@ -1003,6 +1004,21 @@ static void image_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemappe
|
||||
BKE_id_remapper_apply(mappings, (ID **)&simg->mask_info.mask, ID_REMAP_APPLY_ENSURE_REAL);
|
||||
}
|
||||
|
||||
static void image_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
|
||||
{
|
||||
SpaceImage *simg = reinterpret_cast<SpaceImage *>(space_link);
|
||||
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
|
||||
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
|
||||
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, simg->image, IDWALK_CB_USER_ONE);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, simg->iuser.scene, IDWALK_CB_NOP);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, simg->mask_info.mask, IDWALK_CB_USER_ONE);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, simg->gpd, IDWALK_CB_USER);
|
||||
if (!is_readonly) {
|
||||
simg->scopes.ok = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \note Used for splitting out a subset of modes is more involved,
|
||||
* The previous non-uv-edit mode is stored so switching back to the
|
||||
@@ -1097,6 +1113,7 @@ void ED_spacetype_image()
|
||||
st->context = image_context;
|
||||
st->gizmos = image_widgets;
|
||||
st->id_remap = image_id_remap;
|
||||
st->foreach_id = image_foreach_id;
|
||||
st->space_subtype_item_extend = image_space_subtype_item_extend;
|
||||
st->space_subtype_get = image_space_subtype_get;
|
||||
st->space_subtype_set = image_space_subtype_set;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_remap.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
@@ -570,6 +571,19 @@ static void nla_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemapper
|
||||
mappings, reinterpret_cast<ID **>(&snla->ads->source), ID_REMAP_APPLY_DEFAULT);
|
||||
}
|
||||
|
||||
static void nla_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
|
||||
{
|
||||
SpaceNla *snla = reinterpret_cast<SpaceNla *>(space_link);
|
||||
|
||||
/* NOTE: Could be deduplicated with the #bDopeSheet handling of #SpaceAction and #SpaceGraph. */
|
||||
if (snla->ads == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
BKE_LIB_FOREACHID_PROCESS_ID(data, snla->ads->source, IDWALK_CB_NOP);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, snla->ads->filter_grp, IDWALK_CB_NOP);
|
||||
}
|
||||
|
||||
static void nla_space_blend_read_data(BlendDataReader *reader, SpaceLink *sl)
|
||||
{
|
||||
SpaceNla *snla = reinterpret_cast<SpaceNla *>(sl);
|
||||
@@ -613,6 +627,7 @@ void ED_spacetype_nla()
|
||||
st->listener = nla_listener;
|
||||
st->keymap = nla_keymap;
|
||||
st->id_remap = nla_id_remap;
|
||||
st->foreach_id = nla_foreach_id;
|
||||
st->blend_read_data = nla_space_blend_read_data;
|
||||
st->blend_read_lib = nla_space_blend_read_lib;
|
||||
st->blend_write = nla_space_blend_write;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_gpencil_legacy.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_remap.h"
|
||||
#include "BKE_node.hh"
|
||||
#include "BKE_node_runtime.hh"
|
||||
@@ -1029,6 +1030,96 @@ static void node_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemapper
|
||||
BKE_id_remapper_iter(mappings, node_id_remap_cb, slink);
|
||||
}
|
||||
|
||||
static void node_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
|
||||
{
|
||||
SpaceNode *snode = reinterpret_cast<SpaceNode *>(space_link);
|
||||
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
|
||||
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
|
||||
const bool allow_pointer_access = (data_flags & IDWALK_NO_ORIG_POINTERS_ACCESS) == 0;
|
||||
const bool is_embedded_nodetree = snode->id != nullptr && allow_pointer_access &&
|
||||
ntreeFromID(snode->id) == snode->nodetree;
|
||||
|
||||
BKE_LIB_FOREACHID_PROCESS_ID(data, snode->id, IDWALK_CB_NOP);
|
||||
BKE_LIB_FOREACHID_PROCESS_ID(data, snode->from, IDWALK_CB_NOP);
|
||||
|
||||
bNodeTreePath *path = static_cast<bNodeTreePath *>(snode->treepath.first);
|
||||
BLI_assert(path == nullptr || path->nodetree == snode->nodetree);
|
||||
|
||||
if (is_embedded_nodetree) {
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, snode->nodetree, IDWALK_CB_EMBEDDED_NOT_OWNING);
|
||||
if (path != nullptr) {
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, path->nodetree, IDWALK_CB_EMBEDDED_NOT_OWNING);
|
||||
}
|
||||
|
||||
/* Embedded ID pointers are not remapped (besides exceptions), ensure it still matches
|
||||
* actual data. Note that `snode->id` was already processed (and therefore potentially
|
||||
* remapped) above. */
|
||||
if (!is_readonly) {
|
||||
snode->nodetree = (snode->id == nullptr) ? nullptr : ntreeFromID(snode->id);
|
||||
if (path != nullptr) {
|
||||
path->nodetree = snode->nodetree;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, snode->nodetree, IDWALK_CB_USER_ONE);
|
||||
if (path != nullptr) {
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, path->nodetree, IDWALK_CB_USER_ONE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Both `snode->id` and `snode->nodetree` have been remapped now, so their data can be
|
||||
* accessed. */
|
||||
BLI_assert(snode->id == nullptr || snode->nodetree == nullptr ||
|
||||
(snode->nodetree->id.flag & LIB_EMBEDDED_DATA) == 0 ||
|
||||
snode->nodetree == ntreeFromID(snode->id));
|
||||
|
||||
if (path != nullptr) {
|
||||
for (path = path->next; path != nullptr; path = path->next) {
|
||||
BLI_assert(path->nodetree != nullptr);
|
||||
if ((data_flags & IDWALK_NO_ORIG_POINTERS_ACCESS) == 0) {
|
||||
BLI_assert((path->nodetree->id.flag & LIB_EMBEDDED_DATA) == 0);
|
||||
}
|
||||
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, path->nodetree, IDWALK_CB_USER_ONE);
|
||||
|
||||
if (path->nodetree == nullptr) {
|
||||
BLI_assert(!is_readonly);
|
||||
/* Remaining path entries are invalid, remove them. */
|
||||
for (bNodeTreePath *path_next; path; path = path_next) {
|
||||
path_next = path->next;
|
||||
BLI_remlink(&snode->treepath, path);
|
||||
MEM_freeN(path);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
BLI_assert(path == nullptr);
|
||||
|
||||
if (!is_readonly) {
|
||||
/* `edittree` is just the last in the path, set this directly since the path may have
|
||||
* been shortened above. */
|
||||
if (snode->treepath.last != nullptr) {
|
||||
path = static_cast<bNodeTreePath *>(snode->treepath.last);
|
||||
snode->edittree = path->nodetree;
|
||||
}
|
||||
else {
|
||||
snode->edittree = nullptr;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Only process this pointer in readonly case, otherwise could lead to a bad
|
||||
* double-remapping e.g. */
|
||||
if (is_embedded_nodetree && snode->edittree == snode->nodetree) {
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, snode->edittree, IDWALK_CB_EMBEDDED_NOT_OWNING);
|
||||
}
|
||||
else {
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, snode->edittree, IDWALK_CB_NOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int node_space_subtype_get(ScrArea *area)
|
||||
{
|
||||
SpaceNode *snode = (SpaceNode *)area->spacedata.first;
|
||||
@@ -1151,6 +1242,7 @@ void ED_spacetype_node()
|
||||
st->dropboxes = node_dropboxes;
|
||||
st->gizmos = node_widgets;
|
||||
st->id_remap = node_id_remap;
|
||||
st->foreach_id = node_foreach_id;
|
||||
st->space_subtype_item_extend = node_space_subtype_item_extend;
|
||||
st->space_subtype_get = node_space_subtype_get;
|
||||
st->space_subtype_set = node_space_subtype_set;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_remap.h"
|
||||
#include "BKE_outliner_treehash.hh"
|
||||
#include "BKE_screen.h"
|
||||
@@ -441,6 +442,38 @@ static void outliner_id_remap(ScrArea *area, SpaceLink *slink, const IDRemapper
|
||||
}
|
||||
}
|
||||
|
||||
static void outliner_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
|
||||
{
|
||||
SpaceOutliner *space_outliner = reinterpret_cast<SpaceOutliner *>(space_link);
|
||||
const int data_flags = BKE_lib_query_foreachid_process_flags_get(data);
|
||||
const bool is_readonly = (data_flags & IDWALK_READONLY) != 0;
|
||||
const bool allow_pointer_access = (data_flags & IDWALK_NO_ORIG_POINTERS_ACCESS) == 0;
|
||||
|
||||
if (space_outliner->treestore != nullptr) {
|
||||
TreeStoreElem *tselem;
|
||||
BLI_mempool_iter iter;
|
||||
|
||||
BLI_mempool_iternew(space_outliner->treestore, &iter);
|
||||
while ((tselem = static_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) {
|
||||
/* Do not try to restore non-ID pointers (drivers/sequence/etc.). */
|
||||
if (TSE_IS_REAL_ID(tselem)) {
|
||||
const int cb_flag = (tselem->id != nullptr && allow_pointer_access &&
|
||||
(tselem->id->flag & LIB_EMBEDDED_DATA) != 0) ?
|
||||
IDWALK_CB_EMBEDDED_NOT_OWNING :
|
||||
IDWALK_CB_NOP;
|
||||
BKE_LIB_FOREACHID_PROCESS_ID(data, tselem->id, cb_flag);
|
||||
}
|
||||
else if (!is_readonly) {
|
||||
tselem->id = nullptr;
|
||||
}
|
||||
}
|
||||
if (!is_readonly) {
|
||||
/* rebuild hash table, because it depends on ids too */
|
||||
space_outliner->storeflag |= SO_TREESTORE_REBUILD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void outliner_deactivate(ScrArea *area)
|
||||
{
|
||||
/* Remove hover highlights */
|
||||
@@ -583,6 +616,7 @@ void ED_spacetype_outliner()
|
||||
st->keymap = outliner_keymap;
|
||||
st->dropboxes = outliner_dropboxes;
|
||||
st->id_remap = outliner_id_remap;
|
||||
st->foreach_id = outliner_foreach_id;
|
||||
st->deactivate = outliner_deactivate;
|
||||
st->context = outliner_context;
|
||||
st->blend_read_data = outliner_space_blend_read_data;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#include "ED_screen.hh"
|
||||
@@ -147,6 +148,12 @@ static void script_main_region_listener(const wmRegionListenerParams * /*params*
|
||||
#endif
|
||||
}
|
||||
|
||||
static void script_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
|
||||
{
|
||||
SpaceScript *scpt = reinterpret_cast<SpaceScript *>(space_link);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, scpt->script, IDWALK_CB_NOP);
|
||||
}
|
||||
|
||||
static void script_space_blend_read_lib(BlendLibReader *reader, ID *parent_id, SpaceLink *sl)
|
||||
{
|
||||
SpaceScript *scpt = (SpaceScript *)sl;
|
||||
@@ -180,6 +187,7 @@ void ED_spacetype_script()
|
||||
st->duplicate = script_duplicate;
|
||||
st->operatortypes = script_operatortypes;
|
||||
st->keymap = script_keymap;
|
||||
st->foreach_id = script_foreach_id;
|
||||
st->blend_read_lib = script_space_blend_read_lib;
|
||||
st->blend_write = script_space_blend_write;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include "DNA_gpencil_legacy_types.h"
|
||||
#include "DNA_mask_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
@@ -20,6 +21,7 @@
|
||||
#include "BLI_math_base.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_remap.h"
|
||||
#include "BKE_screen.h"
|
||||
#include "BKE_sequencer_offscreen.h"
|
||||
@@ -925,6 +927,12 @@ static void sequencer_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRem
|
||||
BKE_id_remapper_apply(mappings, (ID **)&sseq->gpd, ID_REMAP_APPLY_DEFAULT);
|
||||
}
|
||||
|
||||
static void sequencer_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
|
||||
{
|
||||
SpaceSeq *sseq = reinterpret_cast<SpaceSeq *>(space_link);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, sseq->gpd, IDWALK_CB_USER);
|
||||
}
|
||||
|
||||
/* ************************************* */
|
||||
|
||||
static bool sequencer_channel_region_poll(const RegionPollParams *params)
|
||||
@@ -1012,6 +1020,7 @@ void ED_spacetype_sequencer()
|
||||
st->refresh = sequencer_refresh;
|
||||
st->listener = sequencer_listener;
|
||||
st->id_remap = sequencer_id_remap;
|
||||
st->foreach_id = sequencer_foreach_id;
|
||||
st->blend_read_data = sequencer_space_blend_read_data;
|
||||
st->blend_read_lib = sequencer_space_blend_read_lib;
|
||||
st->blend_write = sequencer_space_blend_write;
|
||||
|
||||
@@ -163,6 +163,12 @@ static void spreadsheet_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDR
|
||||
BKE_viewer_path_id_remap(&sspreadsheet->viewer_path, mappings);
|
||||
}
|
||||
|
||||
static void spreadsheet_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
|
||||
{
|
||||
SpaceSpreadsheet *sspreadsheet = reinterpret_cast<SpaceSpreadsheet *>(space_link);
|
||||
BKE_viewer_path_foreach_id(data, &sspreadsheet->viewer_path);
|
||||
}
|
||||
|
||||
static void spreadsheet_main_region_init(wmWindowManager *wm, ARegion *region)
|
||||
{
|
||||
region->v2d.scroll = V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM | V2D_SCROLL_VERTICAL_HIDE |
|
||||
@@ -721,6 +727,7 @@ void ED_spacetype_spreadsheet()
|
||||
st->operatortypes = spreadsheet_operatortypes;
|
||||
st->keymap = spreadsheet_keymap;
|
||||
st->id_remap = spreadsheet_id_remap;
|
||||
st->foreach_id = spreadsheet_foreach_id;
|
||||
st->blend_read_data = spreadsheet_blend_read_data;
|
||||
st->blend_read_lib = spreadsheet_blend_read_lib;
|
||||
st->blend_write = spreadsheet_blend_write;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_remap.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
@@ -396,6 +397,12 @@ static void text_id_remap(ScrArea * /*area*/, SpaceLink *slink, const IDRemapper
|
||||
BKE_id_remapper_apply(mappings, (ID **)&stext->text, ID_REMAP_APPLY_ENSURE_REAL);
|
||||
}
|
||||
|
||||
static void text_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
|
||||
{
|
||||
SpaceText *st = reinterpret_cast<SpaceText *>(space_link);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, st->text, IDWALK_CB_USER_ONE);
|
||||
}
|
||||
|
||||
static void text_space_blend_read_data(BlendDataReader * /*reader*/, SpaceLink *sl)
|
||||
{
|
||||
SpaceText *st = (SpaceText *)sl;
|
||||
@@ -433,6 +440,7 @@ void ED_spacetype_text()
|
||||
st->context = text_context;
|
||||
st->dropboxes = text_dropboxes;
|
||||
st->id_remap = text_id_remap;
|
||||
st->foreach_id = text_foreach_id;
|
||||
st->blend_read_data = text_space_blend_read_data;
|
||||
st->blend_read_lib = text_space_blend_read_lib;
|
||||
st->blend_write = text_space_blend_write;
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "BKE_lattice.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_lib_query.h"
|
||||
#include "BKE_lib_remap.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_mball.h"
|
||||
@@ -2092,6 +2093,18 @@ static void view3d_id_remap(ScrArea *area, SpaceLink *slink, const IDRemapper *m
|
||||
BKE_viewer_path_id_remap(&view3d->viewer_path, mappings);
|
||||
}
|
||||
|
||||
static void view3d_foreach_id(SpaceLink *space_link, LibraryForeachIDData *data)
|
||||
{
|
||||
View3D *v3d = reinterpret_cast<View3D *>(space_link);
|
||||
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, v3d->camera, IDWALK_CB_NOP);
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, v3d->ob_center, IDWALK_CB_NOP);
|
||||
if (v3d->localvd) {
|
||||
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, v3d->localvd->camera, IDWALK_CB_NOP);
|
||||
}
|
||||
BKE_viewer_path_foreach_id(data, &v3d->viewer_path);
|
||||
}
|
||||
|
||||
static void view3d_space_blend_read_data(BlendDataReader *reader, SpaceLink *sl)
|
||||
{
|
||||
View3D *v3d = (View3D *)sl;
|
||||
@@ -2166,6 +2179,7 @@ void ED_spacetype_view3d()
|
||||
st->gizmos = view3d_widgets;
|
||||
st->context = view3d_context;
|
||||
st->id_remap = view3d_id_remap;
|
||||
st->foreach_id = view3d_foreach_id;
|
||||
st->blend_read_data = view3d_space_blend_read_data;
|
||||
st->blend_read_lib = view3d_space_blend_read_lib;
|
||||
st->blend_write = view3d_space_blend_write;
|
||||
|
||||
Reference in New Issue
Block a user