app: fix UI tag matching to always work case-insensitively

Add gimp_tag_has_prefix() and use it in GimpTagEntry when completing
patrially entered tag names, and fix two uses of strcmp() in
GimpTagPopup to use gimp_tag_compare_with_string().
This commit is contained in:
Michael Natterer
2012-05-05 18:58:04 +02:00
parent ec516f1062
commit 30b4fe8510
4 changed files with 56 additions and 25 deletions

View File

@ -246,7 +246,7 @@ gimp_tag_compare_func (const void *p1,
/** /**
* gimp_tag_compare_with_string: * gimp_tag_compare_with_string:
* @tag: a #GimpTag object. * @tag: a #GimpTag object.
* @tag_string: pointer to right-hand #GimpTag object. * @tag_string: the string to compare to.
* *
* Compares tag and a string according to tag comparison rules. Similar to * Compares tag and a string according to tag comparison rules. Similar to
* gimp_tag_compare_func(), but can be used without creating temporary tag * gimp_tag_compare_func(), but can be used without creating temporary tag
@ -276,6 +276,42 @@ gimp_tag_compare_with_string (GimpTag *tag,
return result; return result;
} }
/**
* gimp_tag_has_prefix:
* @tag: a #GimpTag object.
* @prefix_string: the prefix to compare to.
*
* Compares tag and a prefix according to tag comparison rules. Similar to
* gimp_tag_compare_with_string(), but does not work on the collate key
* because that can't be matched partially.
*
* Return value: wheher #tag starts with @prefix_string.
**/
gboolean
gimp_tag_has_prefix (GimpTag *tag,
const gchar *prefix_string)
{
gchar *case_folded1;
gchar *case_folded2;
gboolean has_prefix;
g_return_val_if_fail (GIMP_IS_TAG (tag), FALSE);
g_return_val_if_fail (prefix_string != NULL, FALSE);
case_folded1 = g_utf8_casefold (g_quark_to_string (tag->tag), -1);
case_folded2 = g_utf8_casefold (prefix_string, -1);
has_prefix = g_str_has_prefix (case_folded1, case_folded2);
g_free (case_folded1);
g_free (case_folded2);
g_printerr ("'%s' has prefix '%s': %d\n",
g_quark_to_string (tag->tag), prefix_string, has_prefix);
return has_prefix;
}
/** /**
* gimp_tag_string_make_valid: * gimp_tag_string_make_valid:
* @tag_string: a text string. * @tag_string: a text string.

View File

@ -68,6 +68,8 @@ gint gimp_tag_compare_func (const void *p1,
const void *p2); const void *p2);
gint gimp_tag_compare_with_string (GimpTag *tag, gint gimp_tag_compare_with_string (GimpTag *tag,
const gchar *tag_string); const gchar *tag_string);
gboolean gimp_tag_has_prefix (GimpTag *tag,
const gchar *prefix_string);
gchar * gimp_tag_string_make_valid (const gchar *tag_string); gchar * gimp_tag_string_make_valid (const gchar *tag_string);
gboolean gimp_tag_is_tag_separator (gunichar c); gboolean gimp_tag_is_tag_separator (gunichar c);

View File

@ -1047,8 +1047,6 @@ gimp_tag_entry_get_completion_candidates (GimpTagEntry *tag_entry,
GList *candidates = NULL; GList *candidates = NULL;
GList *all_tags; GList *all_tags;
GList *list; GList *list;
const gchar *tag_name;
gint i;
gint length; gint length;
gchar *prefix; gchar *prefix;
@ -1066,10 +1064,10 @@ gimp_tag_entry_get_completion_candidates (GimpTagEntry *tag_entry,
{ {
GimpTag *tag = list->data; GimpTag *tag = list->data;
tag_name = gimp_tag_get_name (tag); if (gimp_tag_has_prefix (tag, prefix))
if (g_str_has_prefix (tag_name, prefix))
{ {
gint i;
/* check if tag is not already entered */ /* check if tag is not already entered */
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
{ {

View File

@ -210,12 +210,10 @@ gimp_tag_popup_constructed (GObject *object)
GList *tag_list; GList *tag_list;
GList *tag_iterator; GList *tag_iterator;
gint i; gint i;
gint j;
gint max_height; gint max_height;
gint screen_height; gint screen_height;
gchar **current_tags; gchar **current_tags;
gint current_count; gint current_count;
const gchar *list_tag;
GdkRectangle popup_rects[2]; /* variants of popup placement */ GdkRectangle popup_rects[2]; /* variants of popup placement */
GdkRectangle popup_rect; /* best popup rect in screen coordinates */ GdkRectangle popup_rect; /* best popup rect in screen coordinates */
@ -255,15 +253,14 @@ gimp_tag_popup_constructed (GObject *object)
i++, tag_iterator = g_list_next (tag_iterator)) i++, tag_iterator = g_list_next (tag_iterator))
{ {
PopupTagData *tag_data = &popup->tag_data[i]; PopupTagData *tag_data = &popup->tag_data[i];
gint j;
tag_data->tag = tag_iterator->data; tag_data->tag = tag_iterator->data;
tag_data->state = GTK_STATE_NORMAL; tag_data->state = GTK_STATE_NORMAL;
list_tag = gimp_tag_get_name (tag_data->tag);
for (j = 0; j < current_count; j++) for (j = 0; j < current_count; j++)
{ {
if (! strcmp (current_tags[j], list_tag)) if (! gimp_tag_compare_with_string (tag_data->tag, current_tags[j]))
{ {
tag_data->state = GTK_STATE_SELECTED; tag_data->state = GTK_STATE_SELECTED;
break; break;
@ -968,7 +965,6 @@ gimp_tag_popup_toggle_tag (GimpTagPopup *popup,
{ {
gchar **current_tags; gchar **current_tags;
GString *tag_str; GString *tag_str;
const gchar *tag;
gint length; gint length;
gint i; gint i;
gboolean tag_toggled_off = FALSE; gboolean tag_toggled_off = FALSE;
@ -986,13 +982,12 @@ gimp_tag_popup_toggle_tag (GimpTagPopup *popup,
return; return;
} }
tag = gimp_tag_get_name (tag_data->tag);
current_tags = gimp_tag_entry_parse_tags (GIMP_TAG_ENTRY (popup->combo_entry)); current_tags = gimp_tag_entry_parse_tags (GIMP_TAG_ENTRY (popup->combo_entry));
tag_str = g_string_new (""); tag_str = g_string_new ("");
length = g_strv_length (current_tags); length = g_strv_length (current_tags);
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
{ {
if (! strcmp (current_tags[i], tag)) if (! gimp_tag_compare_with_string (tag_data->tag, current_tags[i]))
{ {
tag_toggled_off = TRUE; tag_toggled_off = TRUE;
} }
@ -1018,7 +1013,7 @@ gimp_tag_popup_toggle_tag (GimpTagPopup *popup,
g_string_append_c (tag_str, ' '); g_string_append_c (tag_str, ' ');
} }
g_string_append (tag_str, tag); g_string_append (tag_str, gimp_tag_get_name (tag_data->tag));
} }
gimp_tag_entry_set_tag_string (GIMP_TAG_ENTRY (popup->combo_entry), gimp_tag_entry_set_tag_string (GIMP_TAG_ENTRY (popup->combo_entry),