[libgda] Added copy possibility, and corrected saving images bug



commit 1274c896522b2d97bd85f49ce2029168aa37d2c4
Author: Vivien Malerba <malerba gnome-db org>
Date:   Tue Jun 7 18:42:34 2011 +0200

    Added copy possibility, and corrected saving images bug

 libgda-ui/data-entries/plugins/common-pict.c       |   60 +++++++++++-
 libgda-ui/data-entries/plugins/common-pict.h       |    5 +-
 .../plugins/gdaui-data-cell-renderer-pict.c        |   16 ++--
 libgda-ui/data-entries/plugins/gdaui-entry-pict.c  |   24 +++--
 libgda-ui/gdaui-raw-grid.c                         |  106 +++++++++++++++++++-
 5 files changed, 189 insertions(+), 22 deletions(-)
---
diff --git a/libgda-ui/data-entries/plugins/common-pict.c b/libgda-ui/data-entries/plugins/common-pict.c
index 1c3defd..1114532 100644
--- a/libgda-ui/data-entries/plugins/common-pict.c
+++ b/libgda-ui/data-entries/plugins/common-pict.c
@@ -283,6 +283,17 @@ typedef struct {
 } PictMenuData;
 static void file_load_cb (GtkWidget *button, PictMenuData *menudata);
 static void file_save_cb (GtkWidget *button, PictMenuData *menudata);
+static void copy_cb (GtkWidget *button, PictMenuData *menudata);
+
+static void
+menudata_free (PictMenuData *menudata)
+{
+	if (menudata->bindata) {
+		g_free (menudata->bindata->data);
+		g_free (menudata->bindata);
+	}
+	g_free (menudata);
+}
 
 void
 common_pict_create_menu (PictMenu *pictmenu, GtkWidget *attach_to, PictBinData *bindata, PictOptions *options,
@@ -292,7 +303,9 @@ common_pict_create_menu (PictMenu *pictmenu, GtkWidget *attach_to, PictBinData *
 	PictMenuData *menudata;
 	
 	menudata = g_new (PictMenuData, 1);
-	menudata->bindata = bindata;
+	menudata->bindata = g_new (PictBinData, 1);
+	menudata->bindata->data = g_memdup (bindata->data, bindata->data_length);
+	menudata->bindata->data_length = bindata->data_length;
 	menudata->options = options;
 	menudata->callback = callback;
 	menudata->data = data;
@@ -302,7 +315,15 @@ common_pict_create_menu (PictMenu *pictmenu, GtkWidget *attach_to, PictBinData *
 	g_signal_connect (menu, "deactivate", 
 			  G_CALLBACK (gtk_widget_hide), NULL);
 	pictmenu->menu = menu;
-		
+
+	mitem = gtk_menu_item_new_with_mnemonic (_("_Copy image"));
+	gtk_widget_show (mitem);
+	gtk_container_add (GTK_CONTAINER (menu), mitem);
+	g_signal_connect (mitem, "activate",
+			  G_CALLBACK (copy_cb), menudata);
+	gtk_widget_set_sensitive (mitem, bindata->data ? TRUE : FALSE);
+	pictmenu->copy_mitem = mitem;
+
 	mitem = gtk_menu_item_new_with_mnemonic (_("_Load image from file"));
 	gtk_widget_show (mitem);
 	gtk_container_add (GTK_CONTAINER (menu), mitem);
@@ -458,7 +479,7 @@ file_save_cb (GtkWidget *button, PictMenuData *menudata)
 					   GTK_WINDOW (gtk_widget_get_toplevel (button)),
 					   GTK_FILE_CHOOSER_ACTION_SAVE, 
 					   GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-					   GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+					   GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
 					   NULL);
 	gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dlg),
 					     gdaui_get_default_path ());
@@ -522,6 +543,38 @@ file_save_cb (GtkWidget *button, PictMenuData *menudata)
 	g_slist_free (pictformat.formats);
 }
 
+static void
+copy_cb (GtkWidget *button, PictMenuData *menudata)
+{
+	GtkClipboard *cp;
+	cp = gtk_clipboard_get (gdk_atom_intern_static_string ("CLIPBOARD"));
+	if (!cp)
+		return;
+
+	GdkPixbufLoader *loader;
+	GdkPixbuf *pixbuf = NULL;
+	loader = gdk_pixbuf_loader_new ();
+	if (gdk_pixbuf_loader_write (loader, menudata->bindata->data,
+				     menudata->bindata->data_length, NULL)) {
+		if (gdk_pixbuf_loader_close (loader, NULL)) {
+			pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+			g_object_ref (pixbuf);
+		}
+		else
+			gdk_pixbuf_loader_close (loader, NULL);
+	}
+	else
+		gdk_pixbuf_loader_close (loader, NULL);
+	g_object_unref (loader);
+	
+	if (pixbuf) {
+		gtk_clipboard_set_image (cp, pixbuf);
+		g_object_unref (pixbuf);
+	}
+	else
+		gtk_clipboard_set_image (cp, NULL);
+}
+
 /* 
  * adjust the sensitiveness of the menu items in the popup menu
  */
@@ -532,6 +585,7 @@ common_pict_adjust_menu_sensitiveness (PictMenu *pictmenu, gboolean editable, Pi
 		return;
 	gtk_widget_set_sensitive (pictmenu->load_mitem, editable);
 	gtk_widget_set_sensitive (pictmenu->save_mitem, bindata->data ? TRUE : FALSE);
+	gtk_widget_set_sensitive (pictmenu->copy_mitem, bindata->data ? TRUE : FALSE);
 }
 
 /*
diff --git a/libgda-ui/data-entries/plugins/common-pict.h b/libgda-ui/data-entries/plugins/common-pict.h
index 165dbf6..555c0f0 100644
--- a/libgda-ui/data-entries/plugins/common-pict.h
+++ b/libgda-ui/data-entries/plugins/common-pict.h
@@ -1,5 +1,5 @@
-/* common-pict.h
- * Copyright (C) 2006  Vivien Malerba <malerba gnome-db org>
+/*
+ * Copyright (C) 2006 - 2011 Vivien Malerba <malerba gnome-db org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -52,6 +52,7 @@ typedef struct {
 	GtkWidget    *menu; /* popup menu */
 	GtkWidget    *load_mitem;
 	GtkWidget    *save_mitem;
+	GtkWidget    *copy_mitem;
 } PictMenu;
 
 void         common_pict_parse_options (PictOptions *options, const gchar *options_str);
diff --git a/libgda-ui/data-entries/plugins/gdaui-data-cell-renderer-pict.c b/libgda-ui/data-entries/plugins/gdaui-data-cell-renderer-pict.c
index a524bdb..f8fbd0f 100644
--- a/libgda-ui/data-entries/plugins/gdaui-data-cell-renderer-pict.c
+++ b/libgda-ui/data-entries/plugins/gdaui-data-cell-renderer-pict.c
@@ -1,6 +1,5 @@
-/* gdaui-data-cell-renderer-pict.c
- *
- * Copyright (C) 2006 - 2010 Vivien Malerba <malerba gdaui org>
+/*
+ * Copyright (C) 2006 - 2011 Vivien Malerba <malerba gdaui org>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -451,10 +450,13 @@ gdaui_data_cell_renderer_pict_activate  (GtkCellRenderer            *cell,
 		int event_time;
 
 		g_object_set_data_full (G_OBJECT (pictcell), "last-path", g_strdup (path), g_free);
-		if (!pictcell->priv->popup_menu.menu)
-			common_pict_create_menu (&(pictcell->priv->popup_menu), widget, &(pictcell->priv->bindata),
-						 &(pictcell->priv->options),
-						 (PictCallback) pict_data_changed_cb, pictcell);
+		if (pictcell->priv->popup_menu.menu) {
+			gtk_widget_destroy (pictcell->priv->popup_menu.menu);
+			pictcell->priv->popup_menu.menu = NULL;
+		}
+		common_pict_create_menu (&(pictcell->priv->popup_menu), widget, &(pictcell->priv->bindata),
+					 &(pictcell->priv->options),
+					 (PictCallback) pict_data_changed_cb, pictcell);
 
 		common_pict_adjust_menu_sensitiveness (&(pictcell->priv->popup_menu), pictcell->priv->editable,
 						       &(pictcell->priv->bindata));
diff --git a/libgda-ui/data-entries/plugins/gdaui-entry-pict.c b/libgda-ui/data-entries/plugins/gdaui-entry-pict.c
index 0fa2d09..def9209 100644
--- a/libgda-ui/data-entries/plugins/gdaui-entry-pict.c
+++ b/libgda-ui/data-entries/plugins/gdaui-entry-pict.c
@@ -289,10 +289,13 @@ do_popup_menu (GtkWidget *widget, GdkEventButton *event, GdauiEntryPict *mgpict)
 {
 	int button, event_time;
 	
-	if (!mgpict->priv->popup_menu.menu)
-		common_pict_create_menu (&(mgpict->priv->popup_menu), widget, &(mgpict->priv->bindata), 
-					 &(mgpict->priv->options), 
-					 (PictCallback) pict_data_changed_cb, mgpict);
+	if (mgpict->priv->popup_menu.menu) {
+		gtk_widget_destroy (mgpict->priv->popup_menu.menu);
+		mgpict->priv->popup_menu.menu = NULL;
+	}
+	common_pict_create_menu (&(mgpict->priv->popup_menu), widget, &(mgpict->priv->bindata), 
+				 &(mgpict->priv->options), 
+				 (PictCallback) pict_data_changed_cb, mgpict);
 
 	common_pict_adjust_menu_sensitiveness (&(mgpict->priv->popup_menu), mgpict->priv->editable, 
 						       &(mgpict->priv->bindata));
@@ -325,11 +328,14 @@ event_cb (GtkWidget *widget, GdkEvent *event, GdauiEntryPict *mgpict)
 	}
 	if ((event->type == GDK_2BUTTON_PRESS) && (((GdkEventButton *) event)->button == 1)) {
 		if (mgpict->priv->editable) {
-			if (!mgpict->priv->popup_menu.menu) 
-				common_pict_create_menu (&(mgpict->priv->popup_menu), widget, &(mgpict->priv->bindata), 
-							 &(mgpict->priv->options), 
-							 (PictCallback) pict_data_changed_cb, mgpict);
-
+			if (mgpict->priv->popup_menu.menu) {
+				gtk_widget_destroy (mgpict->priv->popup_menu.menu);
+				mgpict->priv->popup_menu.menu = NULL;
+			}
+			common_pict_create_menu (&(mgpict->priv->popup_menu), widget, &(mgpict->priv->bindata), 
+						 &(mgpict->priv->options), 
+						 (PictCallback) pict_data_changed_cb, mgpict);
+			
 			common_pict_adjust_menu_sensitiveness (&(mgpict->priv->popup_menu), mgpict->priv->editable, 
 							       &(mgpict->priv->bindata));
 			
diff --git a/libgda-ui/gdaui-raw-grid.c b/libgda-ui/gdaui-raw-grid.c
index 38f8819..f61267d 100644
--- a/libgda-ui/gdaui-raw-grid.c
+++ b/libgda-ui/gdaui-raw-grid.c
@@ -22,6 +22,7 @@
 #include <glib/gi18n-lib.h>
 #include <libgda/libgda.h>
 #include <libgda-ui.h>
+#include <libgda/gda-blob-op.h>
 #include "internal/utility.h"
 #include "marshallers/gdaui-marshal.h"
 #include "data-entries/gdaui-data-cell-renderer-combo.h"
@@ -123,6 +124,10 @@ struct _GdauiRawGridPriv
 
 	GtkWidget                  *filter;
 	GtkWidget                  *filter_window;
+
+	/* store the position of the mouse for popup menu on button press event */
+	gint                        bin_x;
+	gint                        bin_y;
 };
 
 /* get a pointer to the parents to be able to call their destructor */
@@ -1738,6 +1743,7 @@ static void menu_show_columns_cb (GtkWidget *widget, GdauiRawGrid *grid);
 static void menu_save_as_cb (GtkWidget *widget, GdauiRawGrid *grid);
 static void menu_set_filter_cb (GtkWidget *widget, GdauiRawGrid *grid);
 static void menu_unset_filter_cb (GtkWidget *widget, GdauiRawGrid *grid);
+static void menu_copy_row_cb (GtkWidget *widget, GdauiRawGrid *grid);
 static GtkWidget *new_menu_item (const gchar *label,
 				 gboolean pixmap,
 				 GCallback cb_func,
@@ -1758,7 +1764,7 @@ hidden_column_mitem_toggled_cb (GtkCheckMenuItem *check, G_GNUC_UNUSED GdauiRawG
 	gtk_tree_view_column_set_visible (cdata->column, act);
 }
 
-static gint
+static gboolean
 tree_view_popup_button_pressed_cb (G_GNUC_UNUSED GtkWidget *widget, GdkEventButton *event, GdauiRawGrid *grid)
 {
 	GtkWidget *menu, *submenu;
@@ -1772,9 +1778,15 @@ tree_view_popup_button_pressed_cb (G_GNUC_UNUSED GtkWidget *widget, GdkEventButt
 		return FALSE;
 
 	tree_view = GTK_TREE_VIEW (grid);
+	if (event->window != gtk_tree_view_get_bin_window (tree_view))
+		return FALSE;
+
 	selection = gtk_tree_view_get_selection (tree_view);
 	sel_mode = gtk_tree_selection_get_mode (selection);
 
+	grid->priv->bin_x = (gint) event->x;
+	grid->priv->bin_y = (gint) event->y;
+
 	/* create the menu */
 	menu = gtk_menu_new ();
 	mitem = gtk_menu_item_new_with_label (_("Shown columns"));
@@ -1802,6 +1814,11 @@ tree_view_popup_button_pressed_cb (G_GNUC_UNUSED GtkWidget *widget, GdkEventButt
 				  G_CALLBACK (hidden_column_mitem_toggled_cb), grid);
 	}
 
+	gtk_menu_shell_append (GTK_MENU_SHELL (menu),
+			       new_menu_item (GTK_STOCK_COPY, TRUE,
+					      G_CALLBACK (menu_copy_row_cb), grid));
+	
+
 	if (sel_mode == GTK_SELECTION_MULTIPLE)
 		gtk_menu_shell_append (GTK_MENU_SHELL (menu),
 				       new_menu_item (_("Select _All"), FALSE,
@@ -1893,6 +1910,93 @@ menu_unselect_all_cb (G_GNUC_UNUSED GtkWidget *widget, GdauiRawGrid *grid)
 }
 
 static void
+menu_copy_row_cb (GtkWidget *widget, GdauiRawGrid *grid)
+{
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	GtkTreePath *path;
+	GtkClipboard *cp;
+	GtkTreeViewColumn *column;
+	GList *columns;
+	cp = gtk_clipboard_get (gdk_atom_intern_static_string ("CLIPBOARD"));
+	if (!cp)
+		return;
+
+	if (! gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (grid),
+					     grid->priv->bin_x, grid->priv->bin_y, &path,
+					     &column, NULL, NULL))
+		return;
+
+	model = GTK_TREE_MODEL (grid->priv->store);
+	if (! gtk_tree_model_get_iter (model, &iter, path)) {
+		gtk_tree_path_free (path);
+		return;
+	}
+	gtk_tree_path_free (path);
+
+	columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (grid));
+	const GValue *cvalue;
+	gboolean cpset = TRUE;
+	gtk_tree_model_get (model, &iter, g_list_index (columns, column), &cvalue, -1);
+	g_list_free (columns);
+	if (G_VALUE_TYPE (cvalue) == GDA_TYPE_NULL)
+		gtk_clipboard_set_text (cp, "", -1);
+	else if ((G_VALUE_TYPE (cvalue) == GDA_TYPE_BINARY) ||
+		 (G_VALUE_TYPE (cvalue) == GDA_TYPE_BLOB)) {
+		const GdaBinary *bin;
+		
+		cpset = FALSE;
+		if (G_VALUE_TYPE (cvalue) == GDA_TYPE_BINARY)
+			bin = gda_value_get_binary (cvalue);
+		else {
+			GdaBlob *blob;
+			blob = (GdaBlob *) gda_value_get_blob ((GValue *) cvalue);
+			g_assert (blob);
+			bin = (GdaBinary *) blob;
+			if (blob->op &&
+			    (bin->binary_length != gda_blob_op_get_length (blob->op)))
+				gda_blob_op_read_all (blob->op, blob);
+		}
+		if (bin) {
+			GdkPixbufLoader *loader;
+			GdkPixbuf *pixbuf = NULL;
+			loader = gdk_pixbuf_loader_new ();
+			if (gdk_pixbuf_loader_write (loader, bin->data, bin->binary_length, NULL)) {
+				if (gdk_pixbuf_loader_close (loader, NULL)) {
+					pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+					g_object_ref (pixbuf);
+				}
+				else
+					gdk_pixbuf_loader_close (loader, NULL);
+			}
+			else
+				gdk_pixbuf_loader_close (loader, NULL);
+			g_object_unref (loader);
+			
+			if (pixbuf) {
+				gtk_clipboard_set_image (cp, pixbuf);
+				g_object_unref (pixbuf);
+				cpset = TRUE;
+			}
+		}
+	}
+	else
+		cpset = FALSE;
+
+	if (!cpset) {
+		gchar *str;
+		GdaDataHandler *dh;
+		dh = gda_data_handler_get_default (G_VALUE_TYPE (cvalue));
+		if (dh)
+			str = gda_data_handler_get_str_from_value (dh, cvalue);
+		else
+			str = gda_value_stringify (cvalue);
+		gtk_clipboard_set_text (cp, str, -1);
+		g_free (str);
+	}
+}
+
+static void
 menu_show_columns_cb (GtkWidget *widget, GdauiRawGrid *grid)
 {
 	GtkCheckMenuItem *item;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]