# HG changeset patch # User nadvornik # Date 1236934986 0 # Node ID 80462be81410210a930e18263913a39dfb336613 # Parent 0061979f7f6dcf053581efc5f6b3f9e5939de1dd fixed keyword to mark connection diff -r 0061979f7f6d -r 80462be81410 src/bar_keywords.c --- a/src/bar_keywords.c Thu Mar 12 22:44:21 2009 +0000 +++ b/src/bar_keywords.c Fri Mar 13 09:03:06 2009 +0000 @@ -150,26 +150,6 @@ string_list_free(list); } -static gchar *bar_pane_keywords_get_mark_text(const gchar *key) -{ - gint i; - static gchar buf[10]; - - for (i = 0; i < FILEDATA_MARKS_SIZE; i++) - { - FileDataGetMarkFunc get_mark_func; - FileDataSetMarkFunc set_mark_func; - gpointer data; - file_data_get_registered_mark_func(i, &get_mark_func, &set_mark_func, &data); - if (get_mark_func == meta_data_get_keyword_mark && strcmp(data, key) == 0) - { - g_sprintf(buf, " %d ", i + 1); - return buf; - } - } - return " ... "; -} - gboolean bar_keyword_tree_expand_if_set(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { PaneKeywordsData *pkd = data; @@ -412,52 +392,6 @@ file_data_register_notify_func(bar_pane_keywords_notify_cb, pkd, NOTIFY_PRIORITY_LOW); } -static void bar_pane_keywords_mark_edited(GtkCellRendererText *cell, const gchar *path, const gchar *text, gpointer data) -{ -/* PaneKeywordsData *pkd = data; - GtkTreeModel *store; - GtkTreeIter iter; - GtkTreePath *tpath; - gchar *key = NULL; - gint i; - FileDataGetMarkFunc get_mark_func; - FileDataSetMarkFunc set_mark_func; - gpointer mark_func_data; - - file_data_unregister_notify_func(bar_pane_keywords_notify_cb, pkd); - - store = gtk_tree_view_get_model(GTK_TREE_VIEW(pkd->keyword_treeview)); - - tpath = gtk_tree_path_new_from_string(path); - gtk_tree_model_get_iter(store, &iter, tpath); - gtk_tree_path_free(tpath); - - gtk_tree_model_get(store, &iter, FILTER_KEYWORD_COLUMN_TEXT, &key, -1); - - for (i = 0; i < FILEDATA_MARKS_SIZE; i++) - { - file_data_get_registered_mark_func(i, &get_mark_func, &set_mark_func, &mark_func_data); - if (get_mark_func == meta_data_get_keyword_mark && strcmp(mark_func_data, key) == 0) - { - g_free(mark_func_data); - file_data_register_mark_func(i, NULL, NULL, NULL); - } - } - - if (sscanf(text, " %d ", &i) &&i >=1 && i <= FILEDATA_MARKS_SIZE) - { - i--; - file_data_get_registered_mark_func(i, &get_mark_func, &set_mark_func, &mark_func_data); - if (get_mark_func == meta_data_get_keyword_mark && mark_func_data) g_free(mark_func_data); - file_data_register_mark_func(i, meta_data_get_keyword_mark, meta_data_set_keyword_mark, g_strdup(key)); - } - - g_free(key); - - file_data_register_notify_func(bar_pane_keywords_notify_cb, pkd, NOTIFY_PRIORITY_LOW); - bar_pane_keywords_update(pkd); -*/ -} /* *------------------------------------------------------------------- @@ -872,6 +806,35 @@ bar_pane_keywords_edit_dialog(pkd, FALSE); } +static void bar_pane_keywords_connect_mark_cb(GtkWidget *menu_widget, gpointer data) +{ + PaneKeywordsData *pkd = data; + + GtkTreeModel *model; + GtkTreeIter iter; + + GtkTreeModel *keyword_tree; + GtkTreeIter kw_iter; + + gint mark = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menu_widget), "mark")) - 1; + + model = gtk_tree_view_get_model(GTK_TREE_VIEW(pkd->keyword_treeview)); + keyword_tree = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model)); + + if (!pkd->click_tpath) return; + if (!gtk_tree_model_get_iter(model, &iter, pkd->click_tpath)) return; + + gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(model), &kw_iter, &iter); + + file_data_unregister_notify_func(bar_pane_keywords_notify_cb, pkd); + + meta_data_connect_mark_with_keyword(keyword_tree, &kw_iter, mark); + + file_data_register_notify_func(bar_pane_keywords_notify_cb, pkd, NOTIFY_PRIORITY_LOW); +// bar_pane_keywords_update(pkd); +} + + static void bar_pane_keywords_delete_cb(GtkWidget *menu_widget, gpointer data) { PaneKeywordsData *pkd = data; @@ -906,21 +869,51 @@ if (pkd->click_tpath) { /* for the entry */ + GtkWidget *item; + GtkWidget *submenu; + gchar *text; + gchar *mark; + gint i; + GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(pkd->keyword_treeview)); GtkTreeIter iter; gtk_tree_model_get_iter(model, &iter, pkd->click_tpath); gchar *name; - gtk_tree_model_get(model, &iter, FILTER_KEYWORD_COLUMN_NAME, &name, -1); + gtk_tree_model_get(model, &iter, FILTER_KEYWORD_COLUMN_NAME, &name, + FILTER_KEYWORD_COLUMN_MARK, &mark, -1); + + text = g_strdup_printf(_("Edit \"%s\""), name); + menu_item_add_stock(menu, text, GTK_STOCK_EDIT, G_CALLBACK(bar_pane_keywords_edit_dialog_cb), pkd); + g_free(text); + text = g_strdup_printf(_("Delete \"%s\""), name); + menu_item_add_stock(menu, text, GTK_STOCK_DELETE, G_CALLBACK(bar_pane_keywords_delete_cb), pkd); + g_free(text); - gchar *conf = g_strdup_printf(_("Edit \"%s\""), name); - gchar *del = g_strdup_printf(_("Delete \"%s\""), name); - menu_item_add_stock(menu, conf, GTK_STOCK_EDIT, G_CALLBACK(bar_pane_keywords_edit_dialog_cb), pkd); - menu_item_add_stock(menu, del, GTK_STOCK_DELETE, G_CALLBACK(bar_pane_keywords_delete_cb), pkd); + submenu = gtk_menu_new(); + for (i = 0; i < FILEDATA_MARKS_SIZE; i++) + { + text = g_strdup_printf(_("Mark %d"), i + 1); + item = menu_item_add(submenu, text, G_CALLBACK(bar_pane_keywords_connect_mark_cb), pkd); + g_object_set_data(G_OBJECT(item), "mark", GINT_TO_POINTER(i + 1)); + g_free(text); + } + + text = g_strdup_printf(_("Connect \"%s\" to mark"), name); + item = menu_item_add(menu, text, NULL, NULL); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); + g_free(text); + + if (mark && mark[0]) + { + text = g_strdup_printf(_("Disconnect \"%s\" from mark %s"), name, mark); + menu_item_add_stock(menu, text, GTK_STOCK_DELETE, G_CALLBACK(bar_pane_keywords_connect_mark_cb), pkd); + g_free(text); + } + menu_item_add_divider(menu); - g_free(conf); - g_free(del); + g_free(mark); g_free(name); } /* for the pane */ @@ -971,26 +964,6 @@ g_free(pkd); } -static GtkTreeModel *create_marks_list(void) -{ - GtkListStore *model; - GtkTreeIter iter; - gint i; - - /* create list store */ - model = gtk_list_store_new(1, G_TYPE_STRING); - for (i = 0; i < FILEDATA_MARKS_SIZE; i++) - { - gchar str[10]; - g_sprintf(str, " %d ", i + 1); - gtk_list_store_append(model, &iter); - gtk_list_store_set(model, &iter, 0, str, -1); - } - gtk_list_store_append(model, &iter); - gtk_list_store_set(model, &iter, 0, " ... ", -1); - return GTK_TREE_MODEL(model); -} - GtkWidget *bar_pane_keywords_new(const gchar *title, const gchar *key, gboolean expanded) { @@ -1070,20 +1043,13 @@ column = gtk_tree_view_column_new(); gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY); - renderer = gtk_cell_renderer_combo_new(); - g_object_set(G_OBJECT(renderer), "editable", (gboolean)TRUE, - "model", create_marks_list(), - "text-column", 0, - "has-entry", FALSE, - NULL); + renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_column_pack_start(column, renderer, TRUE); - gtk_tree_view_column_pack_start(column, renderer, TRUE); gtk_tree_view_column_add_attribute(column, renderer, "text", FILTER_KEYWORD_COLUMN_MARK); - g_signal_connect(renderer, "edited", - G_CALLBACK (bar_pane_keywords_mark_edited), pkd); + gtk_tree_view_append_column(GTK_TREE_VIEW(pkd->keyword_treeview), column); - column = gtk_tree_view_column_new(); gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE); renderer = gtk_cell_renderer_toggle_new(); diff -r 0061979f7f6d -r 80462be81410 src/filedata.c --- a/src/filedata.c Thu Mar 12 22:44:21 2009 +0000 +++ b/src/filedata.c Fri Mar 13 09:03:06 2009 +0000 @@ -1090,6 +1090,7 @@ static FileDataGetMarkFunc file_data_get_mark_func[FILEDATA_MARKS_SIZE]; static FileDataSetMarkFunc file_data_set_mark_func[FILEDATA_MARKS_SIZE]; static gpointer file_data_mark_func_data[FILEDATA_MARKS_SIZE]; +static GDestroyNotify file_data_destroy_mark_func[FILEDATA_MARKS_SIZE]; gboolean file_data_get_mark(FileData *fd, gint n) { @@ -1189,20 +1190,23 @@ file_data_send_notification(fd, NOTIFY_TYPE_INTERNAL); } -gboolean file_data_register_mark_func(gint n, FileDataGetMarkFunc get_mark_func, FileDataSetMarkFunc set_mark_func, gpointer data) +gboolean file_data_register_mark_func(gint n, FileDataGetMarkFunc get_mark_func, FileDataSetMarkFunc set_mark_func, gpointer data, GDestroyNotify notify) { if (n < 0 || n >= FILEDATA_MARKS_SIZE) return FALSE; + + if (file_data_destroy_mark_func[n]) (file_data_destroy_mark_func[n])(file_data_mark_func_data[n]); file_data_get_mark_func[n] = get_mark_func; file_data_set_mark_func[n] = set_mark_func; file_data_mark_func_data[n] = data; - + file_data_destroy_mark_func[n] = notify; + if (get_mark_func) - { - /* this effectively changes all known files */ - g_hash_table_foreach(file_data_pool, file_data_notify_mark_func, NULL); - } - + { + /* this effectively changes all known files */ + g_hash_table_foreach(file_data_pool, file_data_notify_mark_func, NULL); + } + return TRUE; } diff -r 0061979f7f6d -r 80462be81410 src/filedata.h --- a/src/filedata.h Thu Mar 12 22:44:21 2009 +0000 +++ b/src/filedata.h Fri Mar 13 09:03:06 2009 +0000 @@ -65,7 +65,7 @@ typedef gboolean (* FileDataGetMarkFunc)(FileData *fd, gint n, gpointer data); typedef gboolean (* FileDataSetMarkFunc)(FileData *fd, gint n, gboolean value, gpointer data); -gboolean file_data_register_mark_func(gint n, FileDataGetMarkFunc get_mark_func, FileDataSetMarkFunc set_mark_func, gpointer data); +gboolean file_data_register_mark_func(gint n, FileDataGetMarkFunc get_mark_func, FileDataSetMarkFunc set_mark_func, gpointer data, GDestroyNotify notify); void file_data_get_registered_mark_func(gint n, FileDataGetMarkFunc *get_mark_func, FileDataSetMarkFunc *set_mark_func, gpointer *data); diff -r 0061979f7f6d -r 80462be81410 src/metadata.c --- a/src/metadata.c Thu Mar 12 22:44:21 2009 +0000 +++ b/src/metadata.c Fri Mar 13 09:03:06 2009 +0000 @@ -627,68 +627,93 @@ gboolean meta_data_get_keyword_mark(FileData *fd, gint n, gpointer data) { + /* FIXME: do not use global keyword_tree */ + GList *path = data; GList *keywords; gboolean found = FALSE; keywords = metadata_read_list(fd, KEYWORD_KEY, METADATA_PLAIN); if (keywords) { - GList *work = keywords; + GtkTreeIter iter; + if (keyword_tree_get_iter(GTK_TREE_MODEL(keyword_tree), &iter, path) && + keyword_tree_is_set(GTK_TREE_MODEL(keyword_tree), &iter, keywords)) + found = TRUE; - while (work) - { - gchar *kw = work->data; - work = work->next; - - if (strcmp(kw, data) == 0) - { - found = TRUE; - break; - } - } - string_list_free(keywords); } return found; } gboolean meta_data_set_keyword_mark(FileData *fd, gint n, gboolean value, gpointer data) { + GList *path = data; GList *keywords = NULL; - gboolean found = FALSE; - gboolean changed = FALSE; - GList *work; + GtkTreeIter iter; + + if (!keyword_tree_get_iter(GTK_TREE_MODEL(keyword_tree), &iter, path)) return FALSE; + keywords = metadata_read_list(fd, KEYWORD_KEY, METADATA_PLAIN); - work = keywords; - - while (work) + if (!!keyword_tree_is_set(GTK_TREE_MODEL(keyword_tree), &iter, keywords) != !!value) { - gchar *kw = work->data; - - if (strcmp(kw, data) == 0) + if (value) { - found = TRUE; - if (!value) - { - changed = TRUE; - keywords = g_list_delete_link(keywords, work); - g_free(kw); - } - break; + keyword_tree_set(GTK_TREE_MODEL(keyword_tree), &iter, &keywords); } - work = work->next; + else + { + keyword_tree_reset(GTK_TREE_MODEL(keyword_tree), &iter, &keywords); + } + metadata_write_list(fd, KEYWORD_KEY, keywords); } - if (value && !found) - { - changed = TRUE; - keywords = g_list_append(keywords, g_strdup(data)); - } - - if (changed) metadata_write_list(fd, KEYWORD_KEY, keywords); string_list_free(keywords); return TRUE; } + + +void meta_data_connect_mark_with_keyword(GtkTreeModel *keyword_tree, GtkTreeIter *kw_iter, gint mark) +{ + + FileDataGetMarkFunc get_mark_func; + FileDataSetMarkFunc set_mark_func; + gpointer mark_func_data; + + gint i; + + for (i = 0; i < FILEDATA_MARKS_SIZE; i++) + { + file_data_get_registered_mark_func(i, &get_mark_func, &set_mark_func, &mark_func_data); + if (get_mark_func == meta_data_get_keyword_mark) + { + GtkTreeIter old_kw_iter; + GList *old_path = mark_func_data; + + if (keyword_tree_get_iter(keyword_tree, &old_kw_iter, old_path) && + (i == mark || /* release any previous connection of given mark */ + keyword_compare(keyword_tree, &old_kw_iter, kw_iter) == 0)) /* or given keyword */ + { + file_data_register_mark_func(i, NULL, NULL, NULL, NULL); + gtk_tree_store_set(GTK_TREE_STORE(keyword_tree), &old_kw_iter, KEYWORD_COLUMN_MARK, "", -1); + } + } + } + + + if (mark >= 0 && mark < FILEDATA_MARKS_SIZE) + { + GList *path; + gchar *mark_str; + path = keyword_tree_get_path(keyword_tree, kw_iter); + file_data_register_mark_func(mark, meta_data_get_keyword_mark, meta_data_set_keyword_mark, path, (GDestroyNotify)string_list_free); + + mark_str = g_strdup_printf("%d", mark + 1); + gtk_tree_store_set(GTK_TREE_STORE(keyword_tree), kw_iter, KEYWORD_COLUMN_MARK, mark_str, -1); + g_free(mark_str); + } +} + + /* *------------------------------------------------------------------- * keyword tree diff -r 0061979f7f6d -r 80462be81410 src/metadata.h --- a/src/metadata.h Thu Mar 12 22:44:21 2009 +0000 +++ b/src/metadata.h Fri Mar 13 09:03:06 2009 +0000 @@ -51,6 +51,9 @@ extern GtkTreeStore *keyword_tree; +void meta_data_connect_mark_with_keyword(GtkTreeModel *keyword_tree, GtkTreeIter *kw_iter, gint mark); + + gchar *keyword_get_name(GtkTreeModel *keyword_tree, GtkTreeIter *iter); gchar *keyword_get_casefold(GtkTreeModel *keyword_tree, GtkTreeIter *iter); gboolean keyword_get_is_keyword(GtkTreeModel *keyword_tree, GtkTreeIter *iter);