Revision: 1470
          http://geeqie.svn.sourceforge.net/geeqie/?rev=1470&view=rev
Author:   nadvornik
Date:     2009-03-03 23:17:07 +0000 (Tue, 03 Mar 2009)

Log Message:
-----------
reorder exif pane entries with drag and drop

Modified Paths:
--------------
    trunk/src/bar_exif.c
    trunk/src/dnd.h

Modified: trunk/src/bar_exif.c
===================================================================
--- trunk/src/bar_exif.c        2009-03-02 22:48:04 UTC (rev 1469)
+++ trunk/src/bar_exif.c        2009-03-03 23:17:07 UTC (rev 1470)
@@ -22,6 +22,7 @@
 #include "ui_misc.h"
 #include "bar.h"
 #include "rcfile.h"
+#include "dnd.h"
 
 
 #include <math.h>
@@ -36,6 +37,7 @@
 typedef struct _ExifEntry ExifEntry;
 struct _ExifEntry
 {
+       GtkWidget *ebox;
        GtkWidget *hbox;
        GtkWidget *title_label;
        GtkWidget *value_label;
@@ -60,6 +62,7 @@
        FileData *fd;
 };
 
+static void bar_pane_exif_entry_dnd_init(GtkWidget *entry);
 static void bar_pane_exif_update_entry(PaneExifData *ped, GtkWidget *entry, 
gboolean update_title);
 
 static void bar_pane_exif_entry_destroy(GtkWidget *widget, gpointer data)
@@ -72,7 +75,7 @@
 }
 
 
-static void bar_pane_exif_add_entry(PaneExifData *ped, const gchar *key, const 
gchar *title, gint if_set)
+static GtkWidget *bar_pane_exif_add_entry(PaneExifData *ped, const gchar *key, 
const gchar *title, gint if_set)
 {
        ExifEntry *ee = g_new0(ExifEntry, 1);
        
@@ -89,11 +92,15 @@
                
        ee->if_set = if_set;
        
-       ee->hbox = gtk_hbox_new(FALSE, 0);
-       g_object_set_data(G_OBJECT(ee->hbox), "entry_data", ee);
-       g_signal_connect_after(G_OBJECT(ee->hbox), "destroy",
+       ee->ebox = gtk_event_box_new();
+       g_object_set_data(G_OBJECT(ee->ebox), "entry_data", ee);
+       g_signal_connect_after(G_OBJECT(ee->ebox), "destroy",
                               G_CALLBACK(bar_pane_exif_entry_destroy), ee);
        
+       ee->hbox = gtk_hbox_new(FALSE, 0);
+       gtk_container_add(GTK_CONTAINER(ee->ebox), ee->hbox);
+       gtk_widget_show(ee->hbox);
+
        ee->title_label = gtk_label_new(NULL);
        gtk_misc_set_alignment(GTK_MISC(ee->title_label), 1.0, 0.5);
        gtk_size_group_add_widget(ped->size_group, ee->title_label);
@@ -107,11 +114,31 @@
        gtk_misc_set_alignment(GTK_MISC(ee->value_label), 0.0, 0.5);
        gtk_box_pack_start(GTK_BOX(ee->hbox), ee->value_label, TRUE, TRUE, 1);
        gtk_widget_show(ee->value_label);
+       gtk_box_pack_start(GTK_BOX(ped->vbox), ee->ebox, TRUE, TRUE, 0);
+
+       bar_pane_exif_entry_dnd_init(ee->ebox);
        
-       gtk_box_pack_start(GTK_BOX(ped->vbox), ee->hbox, TRUE, TRUE, 0);
-       bar_pane_exif_update_entry(ped, ee->hbox, TRUE);
+       bar_pane_exif_update_entry(ped, ee->ebox, TRUE);
+       return ee->ebox;
 }
+
+static void bar_pane_exif_reparent_entry(GtkWidget *entry, GtkWidget *pane)
+{
+       GtkWidget *old_pane = entry->parent;
+       PaneExifData *ped = g_object_get_data(G_OBJECT(pane), "pane_data");
+       PaneExifData *old_ped = g_object_get_data(G_OBJECT(old_pane), 
"pane_data");
+       ExifEntry *ee = g_object_get_data(G_OBJECT(entry), "entry_data");
+       if (!ped || !old_ped || !ee) return;
        
+       g_object_ref(entry);
+       
+       gtk_size_group_remove_widget(old_ped->size_group, ee->title_label);
+       gtk_container_remove(GTK_CONTAINER(old_ped->vbox), entry);
+       
+       gtk_size_group_add_widget(ped->size_group, ee->title_label);
+       gtk_box_pack_start(GTK_BOX(ped->vbox), entry, TRUE, TRUE, 0);
+}
+
 static void bar_pane_exif_entry_update_title(ExifEntry *ee)
 {
        gchar *markup;
@@ -131,7 +158,7 @@
        if (ee->if_set && (!text || !*text))
                {
                gtk_label_set_text(GTK_LABEL(ee->value_label), NULL);
-               gtk_widget_hide(ee->hbox);
+               gtk_widget_hide(entry);
                }
        else
                {
@@ -139,7 +166,7 @@
 #if GTK_CHECK_VERSION(2,12,0)
                gtk_widget_set_tooltip_text(ee->hbox, text);
 #endif
-               gtk_widget_show(ee->hbox);
+               gtk_widget_show(entry);
                }
                
        g_free(text);
@@ -177,6 +204,7 @@
                {
                GtkWidget *entry = work->data;
                work = work->next;
+       
                
                bar_pane_exif_update_entry(ped, entry, FALSE);
                }
@@ -196,6 +224,131 @@
        bar_pane_exif_update(ped);
 }
 
+/*
+ *-------------------------------------------------------------------
+ * dnd
+ *-------------------------------------------------------------------
+ */
+
+static GtkTargetEntry bar_pane_exif_drag_types[] = {
+       { TARGET_APP_EXIF_ENTRY_STRING, GTK_TARGET_SAME_APP, 
TARGET_APP_EXIF_ENTRY },
+       { "text/plain", 0, TARGET_TEXT_PLAIN }
+};
+static gint n_exif_entry_drag_types = 2;
+
+static GtkTargetEntry bar_pane_exif_drop_types[] = {
+       { TARGET_APP_EXIF_ENTRY_STRING, GTK_TARGET_SAME_APP, 
TARGET_APP_EXIF_ENTRY },
+       { "text/plain", 0, TARGET_TEXT_PLAIN }
+};
+static gint n_exif_entry_drop_types = 2;
+
+
+static void bar_pane_exif_entry_dnd_get(GtkWidget *entry, GdkDragContext 
*context,
+                                    GtkSelectionData *selection_data, guint 
info,
+                                    guint time, gpointer data)
+{
+       ExifEntry *ee = g_object_get_data(G_OBJECT(entry), "entry_data");
+
+       switch (info)
+               {
+
+               case TARGET_APP_EXIF_ENTRY:
+                       gtk_selection_data_set(selection_data, 
selection_data->target,
+                                              8, (gpointer) &entry, 
sizeof(entry));
+                       break;
+
+               case TARGET_TEXT_PLAIN:
+               default:
+                       gtk_selection_data_set_text(selection_data, ee->key, 
-1);
+                       break;
+               }
+       
+}
+
+static void bar_pane_exif_dnd_receive(GtkWidget *pane, GdkDragContext *context,
+                                         gint x, gint y,
+                                         GtkSelectionData *selection_data, 
guint info,
+                                         guint time, gpointer data)
+{
+       PaneExifData *ped;
+       GList *work, *list;
+       gint pos;
+       GtkWidget *new_entry = NULL;
+       ped = g_object_get_data(G_OBJECT(pane), "pane_data");
+       if (!ped) return;
+
+       switch (info)
+               {
+               case TARGET_APP_EXIF_ENTRY:
+                       new_entry = *(gpointer *)selection_data->data;
+                       
+                       if (new_entry->parent && new_entry->parent != 
ped->vbox) bar_pane_exif_reparent_entry(new_entry, pane);
+                       
+                       break;
+               default:
+                       /* FIXME: this needs a check for valid exif keys */
+                       new_entry = bar_pane_exif_add_entry(ped, (gchar 
*)selection_data->data, NULL, TRUE);
+                       break;
+               }
+
+
+       list = gtk_container_get_children(GTK_CONTAINER(ped->vbox));    
+       work = list;
+       pos = 0;
+       while (work)
+               {
+               gint nx, ny;
+               GtkWidget *entry = work->data;
+               work = work->next;
+               
+               if (entry == new_entry) continue;
+               
+               if (GTK_WIDGET_DRAWABLE(entry) && 
+                   gtk_widget_translate_coordinates(pane, entry, x, y, &nx, 
&ny) &&
+                   ny < entry->allocation.height / 2) break;
+               pos++;
+               }
+       g_list_free(list);
+
+       gtk_box_reorder_child(GTK_BOX(ped->vbox), new_entry, pos);
+}
+
+static void bar_pane_exif_entry_dnd_begin(GtkWidget *widget, GdkDragContext 
*context, gpointer data)
+{
+//     gtk_drag_set_icon_default(context);
+}
+
+static void bar_pane_exif_entry_dnd_end(GtkWidget *widget, GdkDragContext 
*context, gpointer data)
+{
+}
+
+static void bar_pane_exif_entry_dnd_init(GtkWidget *entry)
+{
+       ExifEntry *ee = g_object_get_data(G_OBJECT(entry), "entry_data");
+
+       gtk_drag_source_set(entry, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
+                           bar_pane_exif_drag_types, n_exif_entry_drag_types,
+                           GDK_ACTION_COPY | GDK_ACTION_MOVE | 
GDK_ACTION_LINK);
+       g_signal_connect(G_OBJECT(entry), "drag_data_get",
+                        G_CALLBACK(bar_pane_exif_entry_dnd_get), ee);
+
+       g_signal_connect(G_OBJECT(entry), "drag_begin",
+                        G_CALLBACK(bar_pane_exif_entry_dnd_begin), ee);
+       g_signal_connect(G_OBJECT(entry), "drag_end",
+                        G_CALLBACK(bar_pane_exif_entry_dnd_end), ee);
+}
+
+static void bar_pane_exif_dnd_init(GtkWidget *pane)
+{
+       gtk_drag_dest_set(pane,
+                         GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT 
| GTK_DEST_DEFAULT_DROP,
+                         bar_pane_exif_drop_types, n_exif_entry_drop_types,
+                         GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK);
+       g_signal_connect(G_OBJECT(pane), "drag_data_received",
+                        G_CALLBACK(bar_pane_exif_dnd_receive), NULL);
+}
+
+
 static void bar_pane_exif_entry_write_config(GtkWidget *entry, GString 
*outstr, gint indent)
 {
        ExifEntry *ee = g_object_get_data(G_OBJECT(entry), "entry_data");
@@ -297,6 +450,8 @@
                         G_CALLBACK(bar_pane_exif_size_request), ped);
        g_signal_connect(G_OBJECT(ped->widget), "size-allocate",
                         G_CALLBACK(bar_pane_exif_size_allocate), ped);
+       
+       bar_pane_exif_dnd_init(ped->widget);
 
        if (populate)
                {

Modified: trunk/src/dnd.h
===================================================================
--- trunk/src/dnd.h     2009-03-02 22:48:04 UTC (rev 1469)
+++ trunk/src/dnd.h     2009-03-03 23:17:07 UTC (rev 1470)
@@ -15,9 +15,11 @@
 #define DND_H
 
 #define TARGET_APP_COLLECTION_MEMBER_STRING "application/x-" GQ_APPNAME_LC 
"-collection-member"
+#define TARGET_APP_EXIF_ENTRY_STRING "application/x-" GQ_APPNAME_LC 
"-exif-entry"
 
 enum {
        TARGET_APP_COLLECTION_MEMBER,
+       TARGET_APP_EXIF_ENTRY,
        TARGET_URI_LIST,
        TARGET_TEXT_PLAIN
 };


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Geeqie-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geeqie-svn

Reply via email to