Fix T79162: 'prop_search' includes ID prefix in string properties
Regression from d6cefef98f
This also fixes an unreported issue where finding an exact match
wasn't being detected for items that contained an ID prefix.
This commit is contained in:
@@ -267,7 +267,8 @@ void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const struct ID *id, char
|
||||
void BKE_id_full_name_ui_prefix_get(char name[MAX_ID_FULL_NAME_UI],
|
||||
const struct ID *id,
|
||||
const bool add_lib_hint,
|
||||
char separator_char);
|
||||
char separator_char,
|
||||
int *r_prefix_len);
|
||||
|
||||
char *BKE_id_to_unique_string_key(const struct ID *id);
|
||||
|
||||
|
||||
@@ -2161,7 +2161,7 @@ void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const ID *id, char separa
|
||||
|
||||
/**
|
||||
* Generate full name of the data-block (without ID code, but with library if any),
|
||||
* with a 3-character prefix prepended indicating whether it comes from a library,
|
||||
* with a 2 to 3 character prefix prepended indicating whether it comes from a library,
|
||||
* is overriding, has a fake or no user, etc.
|
||||
*
|
||||
* \note Result is unique to a given ID type in a given Main database.
|
||||
@@ -2170,11 +2170,13 @@ void BKE_id_full_name_get(char name[MAX_ID_FULL_NAME], const ID *id, char separa
|
||||
* will be filled with generated string.
|
||||
* \param separator_char: Character to use for separating name and library name. Can be 0 to use
|
||||
* default (' ').
|
||||
* \param r_prefix_len: The length of the prefix added.
|
||||
*/
|
||||
void BKE_id_full_name_ui_prefix_get(char name[MAX_ID_FULL_NAME_UI],
|
||||
const ID *id,
|
||||
const bool add_lib_hint,
|
||||
char separator_char)
|
||||
char separator_char,
|
||||
int *r_prefix_len)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
@@ -2185,6 +2187,10 @@ void BKE_id_full_name_ui_prefix_get(char name[MAX_ID_FULL_NAME_UI],
|
||||
name[i++] = ' ';
|
||||
|
||||
BKE_id_full_name_get(name + i, id, separator_char);
|
||||
|
||||
if (r_prefix_len) {
|
||||
*r_prefix_len = i;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1575,7 +1575,13 @@ eAutoPropButsReturn uiDefAutoButsRNA(uiLayout *layout,
|
||||
const bool compact);
|
||||
|
||||
/* use inside searchfunc to add items */
|
||||
bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid, int state);
|
||||
bool UI_search_item_add(uiSearchItems *items,
|
||||
const char *name,
|
||||
void *poin,
|
||||
int iconid,
|
||||
int state,
|
||||
uint8_t name_prefix_offset);
|
||||
|
||||
void UI_but_func_search_set(uiBut *but,
|
||||
uiButSearchCreateFn search_create_fn,
|
||||
uiButSearchUpdateFn search_update_fn,
|
||||
|
||||
@@ -6431,7 +6431,8 @@ static void operator_enum_search_update_fn(const struct bContext *C,
|
||||
/* note: need to give the index rather than the
|
||||
* identifier because the enum can be freed */
|
||||
if (BLI_strcasestr(item->name, str)) {
|
||||
if (!UI_search_item_add(items, item->name, POINTER_FROM_INT(item->value), item->icon, 0)) {
|
||||
if (!UI_search_item_add(
|
||||
items, item->name, POINTER_FROM_INT(item->value), item->icon, 0, 0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ struct uiSearchItems {
|
||||
void **pointers;
|
||||
int *icons;
|
||||
int *states;
|
||||
uint8_t *name_prefix_offsets;
|
||||
|
||||
/** Is there any item with an icon? */
|
||||
bool has_icon;
|
||||
@@ -117,7 +118,12 @@ typedef struct uiSearchboxData {
|
||||
* typically #UI_BUT_DISABLED / #UI_BUT_INACTIVE.
|
||||
* \return false if there is nothing to add.
|
||||
*/
|
||||
bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int iconid, int state)
|
||||
bool UI_search_item_add(uiSearchItems *items,
|
||||
const char *name,
|
||||
void *poin,
|
||||
int iconid,
|
||||
int state,
|
||||
const uint8_t name_prefix_offset)
|
||||
{
|
||||
/* hijack for autocomplete */
|
||||
if (items->autocpl) {
|
||||
@@ -159,6 +165,15 @@ bool UI_search_item_add(uiSearchItems *items, const char *name, void *poin, int
|
||||
items->icons[items->totitem] = iconid;
|
||||
}
|
||||
|
||||
if (name_prefix_offset != 0) {
|
||||
/* Lazy initialize, as this isn't used often. */
|
||||
if (items->name_prefix_offsets == NULL) {
|
||||
items->name_prefix_offsets = MEM_callocN(
|
||||
items->maxitem * sizeof(*items->name_prefix_offsets), "search name prefix offsets");
|
||||
}
|
||||
items->name_prefix_offsets[items->totitem] = name_prefix_offset;
|
||||
}
|
||||
|
||||
/* Limit flags that can be set so flags such as 'UI_SELECT' aren't accidentally set
|
||||
* which will cause problems, add others as needed. */
|
||||
BLI_assert(
|
||||
@@ -184,10 +199,18 @@ int UI_searchbox_size_x(void)
|
||||
|
||||
int UI_search_items_find_index(uiSearchItems *items, const char *name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < items->totitem; i++) {
|
||||
if (STREQ(name, items->names[i])) {
|
||||
return i;
|
||||
if (items->name_prefix_offsets != NULL) {
|
||||
for (int i = 0; i < items->totitem; i++) {
|
||||
if (STREQ(name, items->names[i] + items->name_prefix_offsets[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < items->totitem; i++) {
|
||||
if (STREQ(name, items->names[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
@@ -283,7 +306,12 @@ bool ui_searchbox_apply(uiBut *but, ARegion *region)
|
||||
but->func_arg2 = NULL;
|
||||
|
||||
if (data->active != -1) {
|
||||
const char *name = data->items.names[data->active];
|
||||
const char *name = data->items.names[data->active] +
|
||||
/* Never include the prefix in the button. */
|
||||
(data->items.name_prefix_offsets ?
|
||||
data->items.name_prefix_offsets[data->active] :
|
||||
0);
|
||||
|
||||
const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
|
||||
|
||||
BLI_strncpy(but->editstr, name, name_sep ? (name_sep - name) + 1 : data->items.maxstrlen);
|
||||
@@ -472,7 +500,10 @@ void ui_searchbox_update(bContext *C, ARegion *region, uiBut *but, const bool re
|
||||
int a;
|
||||
|
||||
for (a = 0; a < data->items.totitem; a++) {
|
||||
const char *name = data->items.names[a];
|
||||
const char *name = data->items.names[a] +
|
||||
/* Never include the prefix in the button. */
|
||||
(data->items.name_prefix_offsets ? data->items.name_prefix_offsets[a] :
|
||||
0);
|
||||
const char *name_sep = data->use_sep ? strrchr(name, UI_SEP_CHAR) : NULL;
|
||||
if (STREQLEN(but->editstr, name, name_sep ? (name_sep - name) : data->items.maxstrlen)) {
|
||||
data->active = a;
|
||||
@@ -634,6 +665,10 @@ static void ui_searchbox_region_free_cb(ARegion *region)
|
||||
MEM_freeN(data->items.icons);
|
||||
MEM_freeN(data->items.states);
|
||||
|
||||
if (data->items.name_prefix_offsets != NULL) {
|
||||
MEM_freeN(data->items.name_prefix_offsets);
|
||||
}
|
||||
|
||||
MEM_freeN(data);
|
||||
region->regiondata = NULL;
|
||||
}
|
||||
@@ -802,6 +837,7 @@ ARegion *ui_searchbox_create_generic(bContext *C, ARegion *butregion, uiBut *but
|
||||
data->items.pointers = MEM_callocN(data->items.maxitem * sizeof(void *), "search pointers");
|
||||
data->items.icons = MEM_callocN(data->items.maxitem * sizeof(int), "search icons");
|
||||
data->items.states = MEM_callocN(data->items.maxitem * sizeof(int), "search flags");
|
||||
data->items.name_prefix_offsets = NULL; /* Lazy initialized as needed. */
|
||||
for (i = 0; i < data->items.maxitem; i++) {
|
||||
data->items.names[i] = MEM_callocN(but->hardmax + 1, "search pointers");
|
||||
}
|
||||
|
||||
@@ -1009,7 +1009,7 @@ static void menu_search_update_fn(const bContext *UNUSED(C),
|
||||
}
|
||||
|
||||
if (index == words_len) {
|
||||
if (!UI_search_item_add(items, item->drawwstr_full, item, item->icon, item->state)) {
|
||||
if (!UI_search_item_add(items, item->drawwstr_full, item, item->icon, item->state, 0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ static void operator_search_update_fn(const bContext *C,
|
||||
}
|
||||
}
|
||||
|
||||
if (!UI_search_item_add(items, name, ot, ICON_NONE, 0)) {
|
||||
if (!UI_search_item_add(items, name, ot, ICON_NONE, 0, 0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,13 +367,19 @@ static bool id_search_add(const bContext *C,
|
||||
|
||||
/* When using previews, the library hint (linked, overridden, missing) is added with a
|
||||
* character prefix, otherwise we can use a icon. */
|
||||
BKE_id_full_name_ui_prefix_get(name_ui, id, use_lib_prefix, UI_SEP_CHAR);
|
||||
int name_prefix_offset;
|
||||
BKE_id_full_name_ui_prefix_get(
|
||||
name_ui, id, use_lib_prefix, UI_SEP_CHAR, &name_prefix_offset);
|
||||
if (!use_lib_prefix) {
|
||||
iconid = UI_library_icon_get(id);
|
||||
}
|
||||
|
||||
if (!UI_search_item_add(
|
||||
items, name_ui, id, iconid, has_sep_char ? UI_BUT_HAS_SEP_CHAR : 0)) {
|
||||
if (!UI_search_item_add(items,
|
||||
name_ui,
|
||||
id,
|
||||
iconid,
|
||||
has_sep_char ? UI_BUT_HAS_SEP_CHAR : 0,
|
||||
name_prefix_offset)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,6 +382,7 @@ typedef struct CollItemSearch {
|
||||
int index;
|
||||
int iconid;
|
||||
bool is_id;
|
||||
int name_prefix_offset;
|
||||
uint has_sep_char : 1;
|
||||
} CollItemSearch;
|
||||
|
||||
@@ -432,6 +433,7 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
|
||||
}
|
||||
}
|
||||
|
||||
int name_prefix_offset = 0;
|
||||
int iconid = ICON_NONE;
|
||||
bool has_sep_char = false;
|
||||
bool is_id = itemptr.type && RNA_struct_is_ID(itemptr.type);
|
||||
@@ -447,7 +449,8 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
|
||||
}
|
||||
else {
|
||||
const ID *id = itemptr.data;
|
||||
BKE_id_full_name_ui_prefix_get(name_buf, itemptr.data, true, UI_SEP_CHAR);
|
||||
BKE_id_full_name_ui_prefix_get(
|
||||
name_buf, itemptr.data, true, UI_SEP_CHAR, &name_prefix_offset);
|
||||
BLI_STATIC_ASSERT(sizeof(name_buf) >= MAX_ID_FULL_NAME_UI,
|
||||
"Name string buffer should be big enough to hold full UI ID name");
|
||||
name = name_buf;
|
||||
@@ -459,13 +462,14 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
|
||||
}
|
||||
|
||||
if (name) {
|
||||
if (skip_filter || BLI_strcasestr(name, str)) {
|
||||
if (skip_filter || BLI_strcasestr(name + name_prefix_offset, str)) {
|
||||
cis = MEM_callocN(sizeof(CollItemSearch), "CollectionItemSearch");
|
||||
cis->data = itemptr.data;
|
||||
cis->name = BLI_strdup(name);
|
||||
cis->index = i;
|
||||
cis->iconid = iconid;
|
||||
cis->is_id = is_id;
|
||||
cis->name_prefix_offset = name_prefix_offset;
|
||||
cis->has_sep_char = has_sep_char;
|
||||
BLI_addtail(items_list, cis);
|
||||
}
|
||||
@@ -484,11 +488,12 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
|
||||
for (cis = items_list->first; cis; cis = cis->next) {
|
||||
/* If no item has an own icon to display, libraries can use the library icons rather than the
|
||||
* name prefix for showing the library status. */
|
||||
int name_prefix_offset = cis->name_prefix_offset;
|
||||
if (!has_id_icon && cis->is_id) {
|
||||
cis->iconid = UI_library_icon_get(cis->data);
|
||||
/* No need to re-allocate, string should be shorter than before (lib status prefix is
|
||||
* removed). */
|
||||
BKE_id_full_name_ui_prefix_get(name_buf, cis->data, false, UI_SEP_CHAR);
|
||||
BKE_id_full_name_ui_prefix_get(name_buf, cis->data, false, UI_SEP_CHAR, &name_prefix_offset);
|
||||
BLI_assert(strlen(name_buf) <= MEM_allocN_len(cis->name));
|
||||
strcpy(cis->name, name_buf);
|
||||
}
|
||||
@@ -497,7 +502,8 @@ void ui_rna_collection_search_update_fn(const struct bContext *C,
|
||||
cis->name,
|
||||
cis->data,
|
||||
cis->iconid,
|
||||
cis->has_sep_char ? UI_BUT_HAS_SEP_CHAR : 0)) {
|
||||
cis->has_sep_char ? UI_BUT_HAS_SEP_CHAR : 0,
|
||||
name_prefix_offset)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1182,7 +1182,7 @@ static void node_find_update_fn(const struct bContext *C,
|
||||
else {
|
||||
BLI_strncpy(name, node->name, 256);
|
||||
}
|
||||
if (!UI_search_item_add(items, name, node, ICON_NONE, 0)) {
|
||||
if (!UI_search_item_add(items, name, node, ICON_NONE, 0, 0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -543,7 +543,7 @@ static void merged_element_search_cb_recursive(
|
||||
|
||||
/* Don't allow duplicate named items */
|
||||
if (UI_search_items_find_index(items, name) == -1) {
|
||||
if (!UI_search_item_add(items, name, te, iconid, 0)) {
|
||||
if (!UI_search_item_add(items, name, te, iconid, 0, 0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user