Mercurial > geeqie.yaz
diff src/bar_keywords.c @ 1392:d1b32a69b40a
dnd in keywords tree
improved dnd in advanced exif
author | nadvornik |
---|---|
date | Sun, 08 Mar 2009 09:56:40 +0000 |
parents | 9e0df7903581 |
children | 79b32088ecc4 |
line wrap: on
line diff
--- a/src/bar_keywords.c Sat Mar 07 17:02:59 2009 +0000 +++ b/src/bar_keywords.c Sun Mar 08 09:56:40 2009 +0000 @@ -27,6 +27,7 @@ #include "ui_menu.h" #include "rcfile.h" #include "layout.h" +#include "dnd.h" static const gchar *keyword_favorite_defaults[] = { N_("Favorite"), @@ -285,7 +286,10 @@ keyword_list_push(pkd->keyword_view, list); string_list_free(list); + /* + keyword_list_push triggers bar_pane_keywords_change which calls bar_keyword_tree_sync, no need to do it again bar_keyword_tree_sync(pkd); + */ } void bar_pane_keywords_filter_modify(GtkTreeModel *model, GtkTreeIter *iter, GValue *value, gint column, gpointer data) @@ -293,7 +297,7 @@ PaneKeywordsData *pkd = data; GtkTreeModel *keyword_tree = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model)); GtkTreeIter child_iter; - + gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(model), &child_iter, iter); memset(value, 0, sizeof (GValue)); @@ -440,6 +444,180 @@ */ } + +static GtkTargetEntry bar_pane_keywords_drag_types[] = { + { TARGET_APP_KEYWORD_PATH_STRING, GTK_TARGET_SAME_WIDGET, TARGET_APP_KEYWORD_PATH }, + { "text/plain", 0, TARGET_TEXT_PLAIN } +}; +static gint n_keywords_drag_types = 2; + + +static GtkTargetEntry bar_pane_keywords_drop_types[] = { + { TARGET_APP_KEYWORD_PATH_STRING, GTK_TARGET_SAME_WIDGET, TARGET_APP_KEYWORD_PATH }, + { "text/plain", 0, TARGET_TEXT_PLAIN } +}; +static gint n_keywords_drop_types = 2; + + +static void bar_pane_keywords_dnd_get(GtkWidget *tree_view, GdkDragContext *context, + GtkSelectionData *selection_data, guint info, + guint time, gpointer data) +{ + GtkTreeIter iter; + GtkTreeModel *model; + GtkTreeIter child_iter; + GtkTreeModel *keyword_tree; + + GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view)); + + if (!gtk_tree_selection_get_selected(sel, &model, &iter)) return; + + keyword_tree = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model)); + gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(model), &child_iter, &iter); + + switch (info) + { + case TARGET_APP_KEYWORD_PATH: + { + GList *path = keyword_tree_get_path(keyword_tree, &child_iter); + gtk_selection_data_set(selection_data, selection_data->target, + 8, (gpointer) &path, sizeof(path)); + break; + } + + case TARGET_TEXT_PLAIN: + default: + { + gchar *name = keyword_get_name(keyword_tree, &child_iter); + gtk_selection_data_set_text(selection_data, name, -1); +printf("name %s\n", name); + g_free(name); + } + break; + } +} + +static void bar_pane_keywords_dnd_begin(GtkWidget *treeview, GdkDragContext *context, gpointer data) +{ +} + +static void bar_pane_keywords_dnd_end(GtkWidget *widget, GdkDragContext *context, gpointer data) +{ +} + +static void bar_pane_keywords_dnd_receive(GtkWidget *tree_view, GdkDragContext *context, + gint x, gint y, + GtkSelectionData *selection_data, guint info, + guint time, gpointer data) +{ + GtkTreePath *tpath = NULL; + GtkTreeViewDropPosition pos; + GtkTreeModel *model; + + GtkTreeModel *keyword_tree; + gboolean src_valid = FALSE; + gchar *new_keyword = NULL; + + /* iterators for keyword_tree */ + GtkTreeIter src_kw_iter; + GtkTreeIter dest_kw_iter; + GtkTreeIter new_kw_iter; + + g_signal_stop_emission_by_name(tree_view, "drag_data_received"); + + gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(tree_view), NULL, pos); + + model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view)); + keyword_tree = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model)); + + gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(tree_view), x, y, &tpath, &pos); + + + switch (info) + { + case TARGET_APP_KEYWORD_PATH: + { + GList *path = *(gpointer *)selection_data->data; + src_valid = keyword_tree_get_iter(keyword_tree, &src_kw_iter, path); + string_list_free(path); + break; + } + default: + new_keyword = (gchar *)selection_data->data; + break; + } + + if (tpath) + { + GtkTreeIter dest_iter; + gtk_tree_model_get_iter(model, &dest_iter, tpath); + gtk_tree_path_free(tpath); + gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(model), &dest_kw_iter, &dest_iter); + + + if ((pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE || pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER) && + !gtk_tree_model_iter_has_child(keyword_tree, &dest_kw_iter)) + { + gtk_tree_store_append(GTK_TREE_STORE(keyword_tree), &new_kw_iter, &dest_kw_iter); + } + else + { + switch (pos) + { + case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE: + case GTK_TREE_VIEW_DROP_BEFORE: + gtk_tree_store_insert_before(GTK_TREE_STORE(keyword_tree), &new_kw_iter, NULL, &dest_kw_iter); + break; + case GTK_TREE_VIEW_DROP_INTO_OR_AFTER: + case GTK_TREE_VIEW_DROP_AFTER: + gtk_tree_store_insert_after(GTK_TREE_STORE(keyword_tree), &new_kw_iter, NULL, &dest_kw_iter); + break; + } + } + } + else + { + gtk_tree_store_append(GTK_TREE_STORE(keyword_tree), &new_kw_iter, NULL); + } + + + if (src_valid) + { + keyword_move_recursive(GTK_TREE_STORE(keyword_tree), &new_kw_iter, &src_kw_iter); + } + + if (new_keyword) + { + keyword_set(GTK_TREE_STORE(keyword_tree), &new_kw_iter, new_keyword, TRUE); + } +} + +static gint bar_pane_keywords_dnd_motion(GtkWidget *tree_view, GdkDragContext *context, + gint x, gint y, guint time, gpointer data) +{ + GtkTreePath *tpath = NULL; + GtkTreeViewDropPosition pos; + gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(tree_view), x, y, &tpath, &pos); + if (tpath) + { + GtkTreeModel *model; + GtkTreeIter dest_iter; + model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree_view)); + gtk_tree_model_get_iter(model, &dest_iter, tpath); + if (pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE && gtk_tree_model_iter_has_child(model, &dest_iter)) + pos = GTK_TREE_VIEW_DROP_BEFORE; + + if (pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER && gtk_tree_model_iter_has_child(model, &dest_iter)) + pos = GTK_TREE_VIEW_DROP_AFTER; + } + + gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(tree_view), tpath, pos); + gtk_tree_path_free(tpath); + gdk_drag_status(context, GDK_ACTION_COPY, time); + return TRUE; +} + + void bar_pane_keywords_close(GtkWidget *bar) { PaneKeywordsData *pkd; @@ -591,6 +769,30 @@ gtk_tree_view_append_column(GTK_TREE_VIEW(pkd->keyword_treeview), column); gtk_tree_view_set_expander_column(GTK_TREE_VIEW(pkd->keyword_treeview), column); + gtk_drag_source_set(pkd->keyword_treeview, + GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, + bar_pane_keywords_drag_types, n_keywords_drag_types, + GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK); + + g_signal_connect(G_OBJECT(pkd->keyword_treeview), "drag_data_get", + G_CALLBACK(bar_pane_keywords_dnd_get), pkd); + + g_signal_connect(G_OBJECT(pkd->keyword_treeview), "drag_begin", + G_CALLBACK(bar_pane_keywords_dnd_begin), pkd); + g_signal_connect(G_OBJECT(pkd->keyword_treeview), "drag_end", + G_CALLBACK(bar_pane_keywords_dnd_end), pkd); + + gtk_drag_dest_set(pkd->keyword_treeview, + GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, + bar_pane_keywords_drop_types, n_keywords_drop_types, + GDK_ACTION_COPY | GDK_ACTION_MOVE); + + g_signal_connect(G_OBJECT(pkd->keyword_treeview), "drag_data_received", + G_CALLBACK(bar_pane_keywords_dnd_receive), pkd); + + g_signal_connect(G_OBJECT(pkd->keyword_treeview), "drag_motion", + G_CALLBACK(bar_pane_keywords_dnd_motion), pkd); + gtk_container_add(GTK_CONTAINER(scrolled), pkd->keyword_treeview); gtk_widget_show(pkd->keyword_treeview);