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:
2020-07-23 17:24:17 +10:00
parent 4b31f4ace7
commit 67002402bd
11 changed files with 85 additions and 23 deletions

View File

@@ -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);

View File

@@ -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;
}
}
/**

View File

@@ -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,

View File

@@ -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;
}
}

View File

@@ -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");
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}