changeset 1425:80462be81410

fixed keyword to mark connection
author nadvornik
date Fri, 13 Mar 2009 09:03:06 +0000
parents 0061979f7f6d
children cd88fe4e5588
files src/bar_keywords.c src/filedata.c src/filedata.h src/metadata.c src/metadata.h
diffstat 5 files changed, 147 insertions(+), 149 deletions(-) [+]
line wrap: on
line diff
--- 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();
--- 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;
 }
 
--- 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);
 
 
--- 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
--- 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);