Fix: properly implement the 'only append' execption case for WorkSpaces.

Add needed extra flag and utils to IDType to mark and check an ID type
as only appendable.

Note that this is only a loose user-level enforcement currently, in any
case you need to be able to link an ID to append it currently, so for
low-level code this does not really matter.

Currently only WorkSpace and Screen ID types are marked with the new
`IDTYPE_FLAGS_ONLY_APPEND` flag.
This commit is contained in:
Bastien Montagne 2021-09-16 14:26:49 +02:00
parent 3deb56424f
commit e97653ccf3
5 changed files with 30 additions and 8 deletions

View File

@ -45,6 +45,10 @@ enum {
IDTYPE_FLAGS_NO_COPY = 1 << 0,
/** Indicates that the given IDType does not support linking/appending from a library file. */
IDTYPE_FLAGS_NO_LIBLINKING = 1 << 1,
/** Indicates that the given IDType should not be directly linked from a library file, but may be
* appended.
* NOTE: Mutually exclusive with `IDTYPE_FLAGS_NO_LIBLINKING`. */
IDTYPE_FLAGS_ONLY_APPEND = 1 << 2,
/** Indicates that the given IDType does not have animation data. */
IDTYPE_FLAGS_NO_ANIMDATA = 1 << 3,
};
@ -285,6 +289,7 @@ const char *BKE_idtype_idcode_to_translation_context(const short idcode);
bool BKE_idtype_idcode_is_valid(const short idcode);
bool BKE_idtype_idcode_is_linkable(const short idcode);
bool BKE_idtype_idcode_is_only_appendable(const short idcode);
/* Macro currently, since any linkable IDtype should be localizable. */
#define BKE_idtype_idcode_is_localizable BKE_idtype_idcode_is_linkable

View File

@ -224,10 +224,10 @@ bool BKE_idtype_idcode_is_valid(const short idcode)
}
/**
* Return non-zero when an ID type is linkable.
* Check if an ID type is linkable.
*
* \param idcode: The code to check.
* \return Boolean, 0 when non linkable.
* \param idcode: The IDType code to check.
* \return Boolean, false when non linkable, true otherwise.
*/
bool BKE_idtype_idcode_is_linkable(const short idcode)
{
@ -236,6 +236,24 @@ bool BKE_idtype_idcode_is_linkable(const short idcode)
return id_type != NULL ? (id_type->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0 : false;
}
/**
* Check if an ID type is only appendable.
*
* \param idcode: The IDType code to check.
* \return Boolean, false when also linkable, true when only appendable.
*/
bool BKE_idtype_idcode_is_only_appendable(const short idcode)
{
const IDTypeInfo *id_type = BKE_idtype_get_info_from_idcode(idcode);
BLI_assert(id_type != NULL);
if (id_type != NULL && (id_type->flags & IDTYPE_FLAGS_ONLY_APPEND) != 0) {
/* Only appendable ID types should also always be linkable. */
BLI_assert((id_type->flags & IDTYPE_FLAGS_NO_LIBLINKING) == 0);
return true;
}
return false;
}
/**
* Convert an \a idcode into an \a idfilter (e.g. ID_OB -> FILTER_ID_OB).
*/

View File

@ -312,7 +312,7 @@ IDTypeInfo IDType_ID_SCR = {
.name = "Screen",
.name_plural = "screens",
.translation_context = BLT_I18NCONTEXT_ID_SCREEN,
.flags = IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_NO_ANIMDATA,
.flags = IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_ONLY_APPEND | IDTYPE_FLAGS_NO_ANIMDATA,
.init_data = NULL,
.copy_data = NULL,

View File

@ -186,7 +186,7 @@ IDTypeInfo IDType_ID_WS = {
.name = "WorkSpace",
.name_plural = "workspaces",
.translation_context = BLT_I18NCONTEXT_ID_WORKSPACE,
.flags = IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_NO_ANIMDATA,
.flags = IDTYPE_FLAGS_NO_COPY | IDTYPE_FLAGS_ONLY_APPEND | IDTYPE_FLAGS_NO_ANIMDATA,
.init_data = workspace_init_data,
.copy_data = NULL,

View File

@ -944,9 +944,8 @@ static bool wm_link_append_item_poll(ReportList *reports,
idcode = BKE_idtype_idcode_from_name(group);
/* XXX For now, we do a nasty exception for workspace, forbid linking them.
* Not nice, ultimately should be solved! */
if (!BKE_idtype_idcode_is_linkable(idcode) && (do_append || idcode != ID_WS)) {
if (!BKE_idtype_idcode_is_linkable(idcode) ||
(!do_append && BKE_idtype_idcode_is_only_appendable(idcode))) {
if (reports) {
if (do_append) {
BKE_reportf(reports,