Mercurial > geeqie
diff src/metadata.c @ 1391:9e0df7903581
implemented keywords editor as described at
http://geeqie.wiki.sourceforge.net/keywords
keyword tree is hardcoded for now
TODO: configuration
author | nadvornik |
---|---|
date | Sat, 07 Mar 2009 17:02:59 +0000 |
parents | 79937bc55f3a |
children | d1b32a69b40a |
line wrap: on
line diff
--- a/src/metadata.c Sat Mar 07 10:32:04 2009 +0000 +++ b/src/metadata.c Sat Mar 07 17:02:59 2009 +0000 @@ -688,5 +688,243 @@ return TRUE; } +/* + *------------------------------------------------------------------- + * keyword tree + *------------------------------------------------------------------- + */ + + + +GtkTreeStore *keyword_tree; + +gchar *keyword_get_name(GtkTreeModel *keyword_tree, GtkTreeIter *iter) +{ + gchar *name; + gtk_tree_model_get(keyword_tree, iter, KEYWORD_COLUMN_NAME, &name, -1); + return name; +} + +gchar *keyword_get_casefold(GtkTreeModel *keyword_tree, GtkTreeIter *iter) +{ + gchar *casefold; + gtk_tree_model_get(keyword_tree, iter, KEYWORD_COLUMN_CASEFOLD, &casefold, -1); + return casefold; +} + +gboolean keyword_get_is_keyword(GtkTreeModel *keyword_tree, GtkTreeIter *iter) +{ + gboolean is_keyword; + gtk_tree_model_get(keyword_tree, iter, KEYWORD_COLUMN_IS_KEYWORD, &is_keyword, -1); + return is_keyword; +} + +void keyword_set(GtkTreeStore *keyword_tree, GtkTreeIter *iter, const gchar *name, gboolean is_keyword) +{ + gchar *casefold = g_utf8_casefold(name, -1); + gtk_tree_store_set(keyword_tree, iter, KEYWORD_COLUMN_MARK, "", + KEYWORD_COLUMN_NAME, name, + KEYWORD_COLUMN_CASEFOLD, casefold, + KEYWORD_COLUMN_IS_KEYWORD, is_keyword, -1); + g_free(casefold); +} + +static gboolean keyword_tree_is_set_casefold(GtkTreeModel *keyword_tree, GtkTreeIter iter, GList *casefold_list) +{ + if (!casefold_list) return FALSE; + + while (TRUE) + { + GtkTreeIter parent; + + if (keyword_get_is_keyword(keyword_tree, &iter)) + { + GList *work = casefold_list; + gboolean found = FALSE; + gchar *iter_casefold = keyword_get_casefold(keyword_tree, &iter); + while (work) + { + const gchar *casefold = work->data; + work = work->next; + + if (strcmp(iter_casefold, casefold) == 0) + { + found = TRUE; + break; + } + } + g_free(iter_casefold); + if (!found) return FALSE; + } + + if (!gtk_tree_model_iter_parent(keyword_tree, &parent, &iter)) return TRUE; + iter = parent; + } +} + +gboolean keyword_tree_is_set(GtkTreeModel *keyword_tree, GtkTreeIter *iter, GList *kw_list) +{ + gboolean ret; + GList *casefold_list = NULL; + GList *work; + + if (!keyword_get_is_keyword(keyword_tree, iter)) return FALSE; + + work = kw_list; + while (work) + { + const gchar *kw = work->data; + work = work->next; + + casefold_list = g_list_prepend(casefold_list, g_utf8_casefold(kw, -1)); + } + + ret = keyword_tree_is_set_casefold(keyword_tree, *iter, casefold_list); + + string_list_free(casefold_list); + return ret; +} + +void keyword_tree_set(GtkTreeModel *keyword_tree, GtkTreeIter *iter_ptr, GList **kw_list) +{ + GtkTreeIter iter = *iter_ptr; + while (TRUE) + { + GtkTreeIter parent; + + if (keyword_get_is_keyword(keyword_tree, &iter)) + { + gchar *name = keyword_get_name(keyword_tree, &iter); + if (!find_string_in_list_utf8nocase(*kw_list, name)) + { + *kw_list = g_list_append(*kw_list, name); + printf("set %s\n", name); + } + else + { + g_free(name); + } + } + + if (!gtk_tree_model_iter_parent(keyword_tree, &parent, &iter)) return; + iter = parent; + } +} + +static void keyword_tree_reset1(GtkTreeModel *keyword_tree, GtkTreeIter *iter, GList **kw_list) +{ + gchar *found; + gchar *name; + if (!keyword_get_is_keyword(keyword_tree, iter)) return; + + name = keyword_get_name(keyword_tree, iter); + found = find_string_in_list_utf8nocase(*kw_list, name); + + if (found) + { + *kw_list = g_list_remove(*kw_list, found); + printf("remove %s\n", found); + g_free(found); + } + g_free(name); +} + +static void keyword_tree_reset_recursive(GtkTreeModel *keyword_tree, GtkTreeIter *iter, GList **kw_list) +{ + GtkTreeIter child; + keyword_tree_reset1(keyword_tree, iter, kw_list); + + if (!gtk_tree_model_iter_children(keyword_tree, &child, iter)) return; + + while (TRUE) + { + keyword_tree_reset_recursive(keyword_tree, &child, kw_list); + if (!gtk_tree_model_iter_next(keyword_tree, &child)) return; + } +} + +static gboolean keyword_tree_check_empty_children(GtkTreeModel *keyword_tree, GtkTreeIter *parent, GList *kw_list) +{ + GtkTreeIter iter; + + if (!gtk_tree_model_iter_children(keyword_tree, &iter, parent)) + return TRUE; /* this should happen only on empty helpers */ + + while (TRUE) + { + if (keyword_get_is_keyword(keyword_tree, &iter)) + { + if (keyword_tree_is_set(keyword_tree, &iter, kw_list)) return FALSE; + } + else + { + /* for helpers we have to check recursively */ + if (!keyword_tree_check_empty_children(keyword_tree, &iter, kw_list)) return FALSE; + } + + if (!gtk_tree_model_iter_next(keyword_tree, &iter)) + { + return TRUE; + } + } +} + +void keyword_tree_reset(GtkTreeModel *keyword_tree, GtkTreeIter *iter_ptr, GList **kw_list) +{ + GtkTreeIter iter = *iter_ptr; + GtkTreeIter parent; + keyword_tree_reset_recursive(keyword_tree, &iter, kw_list); + + if (!gtk_tree_model_iter_parent(keyword_tree, &parent, &iter)) return; + iter = parent; + + while (keyword_tree_check_empty_children(keyword_tree, &iter, *kw_list)) + { + GtkTreeIter parent; + keyword_tree_reset1(keyword_tree, &iter, kw_list); + if (!gtk_tree_model_iter_parent(keyword_tree, &parent, &iter)) return; + iter = parent; + } +} + + +void keyword_tree_new_default(void) +{ + keyword_tree = gtk_tree_store_new(KEYWORD_COLUMN_COUNT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN); + + GtkTreeIter i1, i2, i3; + + gtk_tree_store_append(keyword_tree, &i1, NULL); + keyword_set(keyword_tree, &i1, "animal", TRUE); + + gtk_tree_store_append(keyword_tree, &i2, &i1); + keyword_set(keyword_tree, &i2, "mammal", TRUE); + + gtk_tree_store_append(keyword_tree, &i3, &i2); + keyword_set(keyword_tree, &i3, "dog", TRUE); + + gtk_tree_store_append(keyword_tree, &i3, &i2); + keyword_set(keyword_tree, &i3, "cat", TRUE); + + gtk_tree_store_append(keyword_tree, &i2, &i1); + keyword_set(keyword_tree, &i2, "insect", TRUE); + + gtk_tree_store_append(keyword_tree, &i3, &i2); + keyword_set(keyword_tree, &i3, "fly", TRUE); + + gtk_tree_store_append(keyword_tree, &i3, &i2); + keyword_set(keyword_tree, &i3, "dragonfly", TRUE); + + gtk_tree_store_append(keyword_tree, &i1, NULL); + keyword_set(keyword_tree, &i1, "daytime", FALSE); + + gtk_tree_store_append(keyword_tree, &i2, &i1); + keyword_set(keyword_tree, &i2, "morning", TRUE); + + gtk_tree_store_append(keyword_tree, &i2, &i1); + keyword_set(keyword_tree, &i2, "noon", TRUE); + +} + /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */