ID Management: Allow unique name check for linked IDs too.

This is mandatory for liboverride resync, since this feature may imply
we have to create linked overrides in libraries, and there may be
several copies of those.

This is also a first step to a more general support of IDmanagement-editing
library data.

Note that this commit should have absolutely no effect on current code,
as the only function allowed to check unique names for linked IDs
currently is `BKE_libblock_management_main_add`, which is unused.

This commit also adds some basic testing for `BKE_id_new_name_validate`.
This commit is contained in:
2021-06-01 11:39:28 +02:00
parent 27910ccce6
commit db15c9d1bd
4 changed files with 81 additions and 14 deletions

View File

@@ -164,7 +164,7 @@ static void lib_id_clear_library_data_ex(Main *bmain, ID *id)
id->tag &= ~(LIB_TAG_INDIRECT | LIB_TAG_EXTERN);
id->flag &= ~LIB_INDIRECT_WEAK_LINK;
if (id_in_mainlist) {
if (BKE_id_new_name_validate(which_libbase(bmain, GS(id->name)), id, NULL)) {
if (BKE_id_new_name_validate(which_libbase(bmain, GS(id->name)), id, NULL, false)) {
bmain->is_memfile_undo_written = false;
}
}
@@ -833,7 +833,9 @@ void BKE_libblock_management_main_add(Main *bmain, void *idv)
ListBase *lb = which_libbase(bmain, GS(id->name));
BKE_main_lock(bmain);
BLI_addtail(lb, id);
BKE_id_new_name_validate(lb, id, NULL);
/* We need to allow adding extra datablocks into libraries too, e.g. to support generating new
* overrides for recursive resync. */
BKE_id_new_name_validate(lb, id, NULL, true);
/* alphabetic insertion: is in new_id */
id->tag &= ~(LIB_TAG_NO_MAIN | LIB_TAG_NO_USER_REFCOUNT);
bmain->is_memfile_undo_written = false;
@@ -989,7 +991,7 @@ void BKE_main_id_repair_duplicate_names_listbase(ListBase *lb)
}
for (i = 0; i < lb_len; i++) {
if (!BLI_gset_add(gset, id_array[i]->name + 2)) {
BKE_id_new_name_validate(lb, id_array[i], NULL);
BKE_id_new_name_validate(lb, id_array[i], NULL, false);
}
}
BLI_gset_free(gset, NULL);
@@ -1092,7 +1094,7 @@ void *BKE_libblock_alloc(Main *bmain, short type, const char *name, const int fl
BKE_main_lock(bmain);
BLI_addtail(lb, id);
BKE_id_new_name_validate(lb, id, name);
BKE_id_new_name_validate(lb, id, name, false);
bmain->is_memfile_undo_written = false;
/* alphabetic insertion: is in new_id */
BKE_main_unlock(bmain);
@@ -1557,7 +1559,7 @@ static bool check_for_dupid(ListBase *lb, ID *id, char *name, ID **r_id_sorting_
* and that current one is not. */
bool is_valid = false;
for (id_test = lb->first; id_test; id_test = id_test->next) {
if (id != id_test && !ID_IS_LINKED(id_test)) {
if (id != id_test && id_test->lib == id->lib) {
if (id_test->name[2] == final_name[0] && STREQ(final_name, id_test->name + 2)) {
/* We expect final_name to not be already used, so this is a failure. */
is_valid = false;
@@ -1613,7 +1615,7 @@ static bool check_for_dupid(ListBase *lb, ID *id, char *name, ID **r_id_sorting_
for (id_test = lb->first; id_test; id_test = id_test->next) {
char base_name_test[MAX_ID_NAME - 2];
int number_test;
if ((id != id_test) && !ID_IS_LINKED(id_test) && (name[0] == id_test->name[2]) &&
if ((id != id_test) && (id_test->lib == id->lib) && (name[0] == id_test->name[2]) &&
(ELEM(id_test->name[base_name_len + 2], '.', '\0')) &&
STREQLEN(name, id_test->name + 2, base_name_len) &&
(BLI_split_name_num(base_name_test, &number_test, id_test->name + 2, '.') ==
@@ -1702,15 +1704,18 @@ static bool check_for_dupid(ListBase *lb, ID *id, char *name, ID **r_id_sorting_
*
* Only for local IDs (linked ones already have a unique ID in their library).
*
* \param do_linked_data if true, also ensure a unique name in case the given \a id is linked
* (otherwise, just ensure that it is properly sorted).
*
* \return true if a new name had to be created.
*/
bool BKE_id_new_name_validate(ListBase *lb, ID *id, const char *tname)
bool BKE_id_new_name_validate(ListBase *lb, ID *id, const char *tname, const bool do_linked_data)
{
bool result = false;
char name[MAX_ID_NAME - 2];
/* If library, don't rename, but do ensure proper sorting. */
if (ID_IS_LINKED(id)) {
/* If library, don't rename (unless explicitely required), but do ensure proper sorting. */
if (!do_linked_data && ID_IS_LINKED(id)) {
id_sort_by_name(lb, id, NULL);
return result;
@@ -2195,7 +2200,7 @@ void BLI_libblock_ensure_unique_name(Main *bmain, const char *name)
idtest = BLI_findstring(lb, name + 2, offsetof(ID, name) + 2);
if (idtest != NULL) {
/* BKE_id_new_name_validate also takes care of sorting. */
BKE_id_new_name_validate(lb, idtest, NULL);
BKE_id_new_name_validate(lb, idtest, NULL, false);
bmain->is_memfile_undo_written = false;
}
}
@@ -2206,7 +2211,7 @@ void BLI_libblock_ensure_unique_name(Main *bmain, const char *name)
void BKE_libblock_rename(Main *bmain, ID *id, const char *name)
{
ListBase *lb = which_libbase(bmain, GS(id->name));
if (BKE_id_new_name_validate(lb, id, name)) {
if (BKE_id_new_name_validate(lb, id, name, false)) {
bmain->is_memfile_undo_written = false;
}
}