[libgda] GdaUI: better handle binary data and blobs



commit c9618780b00dc32214225ebf31bb79955e7c9b1f
Author: Vivien Malerba <malerba gnome-db org>
Date:   Thu Sep 10 21:32:23 2009 +0200

    GdaUI: better handle binary data and blobs
    
    created a GdaDataEntry and a cell renderer to allow one to
    load and save binary from and to a file

 libgda-ui/data-entries/Makefile.am                 |    7 +
 libgda-ui/data-entries/common-bin.c                |  221 +++++++++++
 libgda-ui/data-entries/common-bin.h                |   42 ++
 .../data-entries/gdaui-data-cell-renderer-bin.c    |  404 ++++++++++++++++++++
 .../data-entries/gdaui-data-cell-renderer-bin.h    |   61 +++
 libgda-ui/data-entries/gdaui-entry-bin.c           |  320 ++++++++++++++++
 libgda-ui/data-entries/gdaui-entry-bin.h           |   60 +++
 libgda-ui/gdaui-init.c                             |   45 ++-
 8 files changed, 1154 insertions(+), 6 deletions(-)
---
diff --git a/libgda-ui/data-entries/Makefile.am b/libgda-ui/data-entries/Makefile.am
index 57b6a2d..2a004ae 100644
--- a/libgda-ui/data-entries/Makefile.am
+++ b/libgda-ui/data-entries/Makefile.am
@@ -7,16 +7,19 @@ AM_CPPFLAGS = \
         -I$(top_builddir) -I$(top_builddir)/libgda-ui \
         $(LIBGDA_CFLAGS) \
         $(GTK_CFLAGS) \
+	$(GIO_CFLAGS) \
         -DPREFIX=\""$(prefix)"\" \
         -DSYSCONFDIR=\""$(sysconfdir)"\" \
         -DDATADIR=\""$(datadir)"\" \
         -DLIBDIR=\""$(libdir)"\"
 
 libgda_ui_data_entries_headers = \
+	gdaui-data-cell-renderer-bin.h \
 	gdaui-data-cell-renderer-boolean.h \
 	gdaui-data-cell-renderer-combo.h \
 	gdaui-data-cell-renderer-info.h \
 	gdaui-data-cell-renderer-textual.h \
+	gdaui-entry-bin.h \
 	gdaui-entry-boolean.h \
 	gdaui-entry-combo.h \
 	gdaui-entry-none.h \
@@ -31,10 +34,14 @@ libgda_ui_data_entries_headers = \
 
 libgda_ui_data_entries_la_SOURCES = \
 	$(libgda_ui_data_entries_headers) \
+	common-bin.c \
+	common-bin.h \
+	gdaui-data-cell-renderer-bin.c \
 	gdaui-data-cell-renderer-boolean.c \
 	gdaui-data-cell-renderer-combo.c \
 	gdaui-data-cell-renderer-info.c \
 	gdaui-data-cell-renderer-textual.c \
+	gdaui-entry-bin.c \
 	gdaui-entry-boolean.c \
 	gdaui-entry-combo.c \
 	gdaui-entry-none.c \
diff --git a/libgda-ui/data-entries/common-bin.c b/libgda-ui/data-entries/common-bin.c
new file mode 100644
index 0000000..7b72f1c
--- /dev/null
+++ b/libgda-ui/data-entries/common-bin.c
@@ -0,0 +1,221 @@
+/* common-pict.c
+ * Copyright (C) 2009 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <libgda/gda-value.h>
+#include "common-bin.h"
+#include <string.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n-lib.h>
+#include <libgda/gda-blob-op.h>
+
+#ifdef HAVE_GIO
+#include <gio/gio.h>
+#endif
+
+static void
+file_load_cb (GtkWidget *button, BinMenu *menu)
+{
+	GtkWidget *dlg;
+
+        dlg = gtk_file_chooser_dialog_new (_("Select file to load"),
+                                           GTK_WINDOW (gtk_widget_get_toplevel (button)),
+                                           GTK_FILE_CHOOSER_ACTION_OPEN,
+                                           GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                           GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+                                           NULL);
+	if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_ACCEPT) {
+                char *filename;
+                gsize length;
+                GError *error = NULL;
+                gchar *data;
+
+                filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
+
+		if (menu->entry_type == GDA_TYPE_BLOB) {
+			menu->loaded_value_cb (menu->loaded_value_cb_data,
+					       gda_value_new_blob_from_file (filename));
+		}
+		else if (menu->entry_type == GDA_TYPE_BINARY) {
+			if (g_file_get_contents (filename, &data, &length, &error)) {
+				GdaBinary *bin;
+				GValue *nvalue;
+				bin = g_new0 (GdaBinary, 1);
+				bin->data = data;
+				bin->binary_length = length;
+				nvalue = gda_value_new (GDA_TYPE_BINARY);
+				gda_value_take_binary (nvalue, bin);
+
+				menu->loaded_value_cb (menu->loaded_value_cb_data, nvalue);
+
+#ifdef HAVE_GIO
+				/* Open with... using GIO */
+				gchar *tmp;
+				tmp = g_content_type_guess (NULL, bin->data, (gsize) bin->binary_length, NULL);
+				g_print ("Content type: %s\n", tmp);
+
+				GList *list;
+				list = g_app_info_get_all_for_type (tmp);
+				for (; list; list = list->next) {
+					GAppInfo *ai;
+					ai = (GAppInfo*) list->data;
+					g_print ("\t open with %s (%s)\n", g_app_info_get_name (ai),
+						 g_app_info_get_executable (ai));
+				}
+				g_free (tmp);
+#endif
+			}
+			else {
+				GtkWidget *msg;
+				
+				msg = gtk_message_dialog_new_with_markup (GTK_WINDOW (gtk_widget_get_toplevel (button)),
+						   GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
+						   GTK_BUTTONS_CLOSE,
+						   _("Could not load the contents of '%s':\n %s"),
+						   filename,
+						   error && error->message ? error->message : _("No detail"));
+				if (error)
+					g_error_free (error);
+				gtk_widget_destroy (dlg);
+				dlg = NULL;
+				
+				gtk_dialog_run (GTK_DIALOG (msg));
+				gtk_widget_destroy (msg);
+			}
+		}
+		else
+			g_assert_not_reached ();
+
+                g_free (filename);
+        }
+
+        if (dlg)
+                gtk_widget_destroy (dlg);
+}
+
+static void
+file_save_cb (GtkWidget *button, BinMenu *menu)
+{
+	GtkWidget *dlg;
+
+        dlg = gtk_file_chooser_dialog_new (_("Select a file to save data to"),
+                                           GTK_WINDOW (gtk_widget_get_toplevel (button)),
+                                           GTK_FILE_CHOOSER_ACTION_SAVE,
+                                           GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                           GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+                                           NULL);
+
+        if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_ACCEPT) {
+                char *filename;
+                gboolean allok = TRUE;
+                GError *error = NULL;
+
+                filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg));
+		if (menu->entry_type == GDA_TYPE_BINARY) {
+			const GdaBinary *bin;
+			bin = gda_value_get_binary (menu->tmpvalue);
+			allok = g_file_set_contents (filename, (gchar *) bin->data,
+						     bin->binary_length, &error);
+		}
+		else if (menu->entry_type == GDA_TYPE_BLOB) {
+			GdaBlob *blob;
+			blob = (GdaBlob*) gda_value_get_blob (menu->tmpvalue);
+			if (blob->op) {
+			       
+				GValue *dest_value;
+				GdaBlob *dest_blob;
+
+				dest_value = gda_value_new_blob_from_file (filename);
+				dest_blob = (GdaBlob*) gda_value_get_blob (dest_value);
+				allok = gda_blob_op_write_all (dest_blob->op, (GdaBlob*) blob);
+				gda_value_free (dest_value);
+			}
+			else
+				allok = g_file_set_contents (filename, (gchar *) ((GdaBinary*)blob)->data,
+							     ((GdaBinary*)blob)->binary_length, &error);
+		}
+		else
+			g_assert_not_reached ();
+                if (!allok) {
+                        GtkWidget *msg;
+			msg = gtk_message_dialog_new_with_markup (GTK_WINDOW (gtk_widget_get_toplevel (button)),
+                                                                  GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
+                                                                  GTK_BUTTONS_CLOSE,
+                                                                  _("Could not save data to '%s':\n %s"),
+                                                                  filename,
+                                                                  error && error->message ? error->message : _("No detail"));
+                        if (error)
+                                g_error_free (error);
+                        gtk_widget_destroy (dlg);
+                        dlg = NULL;
+
+                        gtk_dialog_run (GTK_DIALOG (msg));
+                        gtk_widget_destroy (msg);
+                }
+                g_free (filename);
+        }
+
+        if (dlg)
+                gtk_widget_destroy (dlg);
+}
+
+void
+common_bin_create_menu (BinMenu *binmenu, GtkWidget *attach_to, GType entry_type,
+			BinCallback loaded_value_cb, gpointer loaded_value_cb_data)
+{
+	GtkWidget *menu, *mitem;
+
+	binmenu->entry_type = entry_type;
+	binmenu->loaded_value_cb = loaded_value_cb;
+	binmenu->loaded_value_cb_data = loaded_value_cb_data;
+	
+	menu = gtk_menu_new ();
+	g_signal_connect (menu, "deactivate", 
+			  G_CALLBACK (gtk_widget_hide), NULL);
+	binmenu->menu = menu;
+	
+	mitem = gtk_menu_item_new_with_mnemonic (_("_Load from file"));
+	gtk_container_add (GTK_CONTAINER (menu), mitem);
+	g_signal_connect (mitem, "activate",
+			  G_CALLBACK (file_load_cb), binmenu);
+	binmenu->load_mitem = mitem;
+	
+	mitem = gtk_menu_item_new_with_mnemonic (_("_Save to file"));
+	gtk_container_add (GTK_CONTAINER (menu), mitem);
+	g_signal_connect (mitem, "activate",
+			  G_CALLBACK (file_save_cb), binmenu);
+	binmenu->save_mitem = mitem;
+	
+	gtk_menu_attach_to_widget (GTK_MENU (menu), attach_to, NULL);
+	gtk_widget_show_all (menu);
+}
+
+/* 
+ * adjust the sensitiveness of the menu items in the popup menu
+ */
+void
+common_bin_adjust_menu (BinMenu *binmenu, gboolean editable, const GValue *value)
+{
+	if (!binmenu || !binmenu->menu)
+		return;
+
+	binmenu->tmpvalue = value;
+	gtk_widget_set_sensitive (binmenu->load_mitem, editable);
+	gtk_widget_set_sensitive (binmenu->save_mitem, (value && !gda_value_is_null (value)) ? TRUE : FALSE);
+}
+
diff --git a/libgda-ui/data-entries/common-bin.h b/libgda-ui/data-entries/common-bin.h
new file mode 100644
index 0000000..5c721ef
--- /dev/null
+++ b/libgda-ui/data-entries/common-bin.h
@@ -0,0 +1,42 @@
+/* common-bin.h
+ * Copyright (C) 2009  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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __COMMON_BIN_H__
+#define __COMMON_BIN_H__
+
+#include <gtk/gtk.h>
+
+typedef void (*BinCallback) (gpointer, GValue *);
+typedef struct {
+        GtkWidget    *menu; /* popup menu */
+        GtkWidget    *load_mitem;
+        GtkWidget    *save_mitem;
+
+	GType         entry_type;
+	const GValue *tmpvalue;
+
+	BinCallback   loaded_value_cb;
+	gpointer      loaded_value_cb_data;
+} BinMenu;
+
+
+void         common_bin_create_menu (BinMenu *binmenu, GtkWidget *attach_to, GType entry_type, BinCallback loaded_value_cb, gpointer loaded_value_cb_data);
+void         common_bin_adjust_menu (BinMenu *binmenu, gboolean editable, const GValue *value);
+
+#endif
diff --git a/libgda-ui/data-entries/gdaui-data-cell-renderer-bin.c b/libgda-ui/data-entries/gdaui-data-cell-renderer-bin.c
new file mode 100644
index 0000000..a12818a
--- /dev/null
+++ b/libgda-ui/data-entries/gdaui-data-cell-renderer-bin.c
@@ -0,0 +1,404 @@
+/* gdaui-data-cell-renderer-bin.c
+ *
+ * Copyright (C) 2009 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdlib.h>
+#include <libgda/libgda.h>
+#include <glib/gi18n-lib.h>
+#include <libgda/gda-enum-types.h>
+#include "gdaui-data-cell-renderer-bin.h"
+#include "marshallers/gdaui-custom-marshal.h"
+#include "common-bin.h"
+
+
+static void gdaui_data_cell_renderer_bin_get_property  (GObject *object,
+							guint param_id,
+							GValue *value,
+							GParamSpec *pspec);
+static void gdaui_data_cell_renderer_bin_set_property  (GObject *object,
+							guint param_id,
+							const GValue *value,
+							GParamSpec *pspec);
+static void gdaui_data_cell_renderer_bin_init       (GdauiDataCellRendererBin      *celltext);
+static void gdaui_data_cell_renderer_bin_class_init (GdauiDataCellRendererBinClass *class);
+static void gdaui_data_cell_renderer_bin_dispose    (GObject *object);
+static void gdaui_data_cell_renderer_bin_finalize   (GObject *object);
+static void gdaui_data_cell_renderer_bin_render     (GtkCellRenderer            *cell,
+						     GdkWindow                  *window,
+						     GtkWidget                  *widget,
+						     GdkRectangle               *background_area,
+						     GdkRectangle               *cell_area,
+						     GdkRectangle               *expose_area,
+						     GtkCellRendererState        flags);
+static void gdaui_data_cell_renderer_bin_get_size   (GtkCellRenderer            *cell,
+						     GtkWidget                  *widget,
+						     GdkRectangle               *cell_area,
+						     gint                       *x_offset,
+						     gint                       *y_offset,
+						     gint                       *width,
+						     gint                       *height);
+static gboolean gdaui_data_cell_renderer_bin_activate  (GtkCellRenderer            *cell,
+							GdkEvent                   *event,
+							GtkWidget                  *widget,
+							const gchar                *path,
+							GdkRectangle               *background_area,
+							GdkRectangle               *cell_area,
+							GtkCellRendererState        flags);
+
+enum {
+	CHANGED,
+	LAST_SIGNAL
+};
+
+
+struct _GdauiDataCellRendererBinPrivate 
+{
+	GdaDataHandler       *dh;
+	BinMenu               menu;
+        GType                 type;
+	gboolean              to_be_deleted;
+
+	gboolean              editable;
+	gboolean              active;
+	gboolean              null;
+};
+
+enum {
+	PROP_0,
+	PROP_VALUE,
+	PROP_VALUE_ATTRIBUTES,
+	PROP_EDITABLE,
+	PROP_TO_BE_DELETED,
+	PROP_DATA_HANDLER,
+	PROP_TYPE
+};
+
+static GObjectClass *parent_class = NULL;
+static guint bin_cell_signals[LAST_SIGNAL] = { 0 };
+
+
+GType
+gdaui_data_cell_renderer_bin_get_type (void)
+{
+	static GType cell_type = 0;
+
+	if (!cell_type) {
+		static const GTypeInfo cell_info = {
+			sizeof (GdauiDataCellRendererBinClass),
+			NULL,		/* base_init */
+			NULL,		/* base_finalize */
+			(GClassInitFunc) gdaui_data_cell_renderer_bin_class_init,
+			NULL,		/* class_finalize */
+			NULL,		/* class_data */
+			sizeof (GdauiDataCellRendererBin),
+			0,              /* n_preallocs */
+			(GInstanceInitFunc) gdaui_data_cell_renderer_bin_init,
+		};
+		
+		cell_type =
+			g_type_register_static (GTK_TYPE_CELL_RENDERER_TEXT, "GdauiDataCellRendererBin",
+						&cell_info, 0);
+	}
+
+	return cell_type;
+}
+
+static void
+gdaui_data_cell_renderer_bin_init (GdauiDataCellRendererBin *cell)
+{
+	cell->priv = g_new0 (GdauiDataCellRendererBinPrivate, 1);
+	cell->priv->dh = NULL;
+	cell->priv->type = GDA_TYPE_BLOB;
+	cell->priv->editable = FALSE;
+	GTK_CELL_RENDERER (cell)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
+	GTK_CELL_RENDERER (cell)->xpad = 2;
+	GTK_CELL_RENDERER (cell)->ypad = 2;
+}
+
+static void
+gdaui_data_cell_renderer_bin_class_init (GdauiDataCellRendererBinClass *class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (class);
+	GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
+
+	parent_class = g_type_class_peek_parent (class);
+
+	object_class->dispose = gdaui_data_cell_renderer_bin_dispose;
+	object_class->finalize = gdaui_data_cell_renderer_bin_finalize;
+
+	object_class->get_property = gdaui_data_cell_renderer_bin_get_property;
+	object_class->set_property = gdaui_data_cell_renderer_bin_set_property;
+
+	cell_class->get_size = gdaui_data_cell_renderer_bin_get_size;
+	cell_class->render = gdaui_data_cell_renderer_bin_render;
+	cell_class->activate = gdaui_data_cell_renderer_bin_activate;
+	cell_class->start_editing = NULL;
+  
+	g_object_class_install_property (object_class,
+					 PROP_VALUE,
+					 g_param_spec_boxed ("value",
+							     _("Value"),
+							     _("GValue to render"),
+							     G_TYPE_VALUE,
+							     G_PARAM_READWRITE));
+  
+	g_object_class_install_property (object_class,
+					 PROP_VALUE_ATTRIBUTES,
+					 g_param_spec_flags ("value_attributes", NULL, NULL, GDA_TYPE_VALUE_ATTRIBUTE,
+							     GDA_VALUE_ATTR_NONE, G_PARAM_READWRITE));
+
+	g_object_class_install_property (object_class,
+					 PROP_EDITABLE,
+					 g_param_spec_boolean ("editable",
+							       _("Editable"),
+							       NULL,
+							       TRUE,
+							       G_PARAM_READABLE |
+							       G_PARAM_WRITABLE));
+
+	g_object_class_install_property (object_class,
+					 PROP_TO_BE_DELETED,
+					 g_param_spec_boolean ("to_be_deleted", NULL, NULL, FALSE,
+							   G_PARAM_WRITABLE));
+	g_object_class_install_property(object_class,
+					PROP_DATA_HANDLER,
+					g_param_spec_object("data_handler", NULL, NULL, GDA_TYPE_DATA_HANDLER,
+							    G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY));
+	g_object_class_install_property(object_class,
+					PROP_TYPE,
+					g_param_spec_gtype("type", NULL, NULL, G_TYPE_NONE,
+							   G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY));
+  
+
+	bin_cell_signals[CHANGED] =
+		g_signal_new ("changed",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (GdauiDataCellRendererBinClass, changed),
+			      NULL, NULL,
+			      _gdaui_marshal_VOID__STRING_VALUE,
+			      G_TYPE_NONE, 2,
+			      G_TYPE_STRING,
+			      G_TYPE_VALUE);
+}
+
+static void
+gdaui_data_cell_renderer_bin_dispose (GObject *object)
+{
+	GdauiDataCellRendererBin *datacell = GDAUI_DATA_CELL_RENDERER_BIN (object);
+
+	if (datacell->priv->dh) {
+		g_object_unref (G_OBJECT (datacell->priv->dh));
+		datacell->priv->dh = NULL;
+	}
+
+	/* parent class */
+	parent_class->dispose (object);
+}
+
+static void
+gdaui_data_cell_renderer_bin_finalize (GObject *object)
+{
+	GdauiDataCellRendererBin *datacell = GDAUI_DATA_CELL_RENDERER_BIN (object);
+
+	if (datacell->priv) {
+		g_free (datacell->priv);
+		datacell->priv = NULL;
+	}
+
+	/* parent class */
+	parent_class->finalize (object);
+}
+
+static void
+gdaui_data_cell_renderer_bin_get_property (GObject *object,
+					   guint param_id,
+					   GValue *value,
+					   GParamSpec *pspec)
+{
+	GdauiDataCellRendererBin *cell = GDAUI_DATA_CELL_RENDERER_BIN (object);
+  
+	switch (param_id) {
+	case PROP_VALUE:
+		break;
+	case PROP_VALUE_ATTRIBUTES:
+		break;
+	case PROP_EDITABLE:
+		g_value_set_boolean (value, cell->priv->editable);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+
+static void
+gdaui_data_cell_renderer_bin_set_property (GObject *object,
+					   guint param_id,
+					   const GValue *value,
+					   GParamSpec *pspec)
+{
+	GdauiDataCellRendererBin *cell = GDAUI_DATA_CELL_RENDERER_BIN (object);
+  
+	switch (param_id) {
+	case PROP_VALUE:
+		/* Because we don't have a copy of the value, we MUST NOT free it! */
+		if (value) {			
+                        GValue *gval = g_value_get_boxed (value);
+                }
+		break;
+	case PROP_VALUE_ATTRIBUTES:
+		break;
+	case PROP_EDITABLE:
+		cell->priv->editable = g_value_get_boolean (value);
+		break;
+	case PROP_TO_BE_DELETED:
+		cell->priv->to_be_deleted = g_value_get_boolean (value);
+		break;
+	case PROP_DATA_HANDLER:
+		if(cell->priv->dh)
+			g_object_unref (G_OBJECT(cell->priv->dh));
+
+		cell->priv->dh = GDA_DATA_HANDLER(g_value_get_object(value));
+		if(cell->priv->dh)
+			g_object_ref (G_OBJECT (cell->priv->dh));
+		break;
+	case PROP_TYPE:
+		cell->priv->type = g_value_get_gtype (value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+/**
+ * gdaui_data_cell_renderer_bin_new:
+ * @dh: a #GdaDataHandler object
+ * @type:
+ * 
+ * Creates a new #GdauiDataCellRendererBin. Adjust rendering
+ * parameters using object properties. Object properties can be set
+ * globally (with g_object_set()). Also, with #GtkTreeViewColumn, you
+ * can bind a property to a value in a #GtkTreeModel. For example, you
+ * can bind the "active" property on the cell renderer to a bin value
+ * in the model, thus causing the check button to reflect the state of
+ * the model.
+ * 
+ * Return value: the new cell renderer
+ */
+GtkCellRenderer *
+gdaui_data_cell_renderer_bin_new (GdaDataHandler *dh, GType type)
+{
+	GObject *obj;
+
+        g_return_val_if_fail (dh && GDA_IS_DATA_HANDLER (dh), NULL);
+        obj = g_object_new (GDAUI_TYPE_DATA_CELL_RENDERER_BIN, "type", type, 
+                            "data_handler", dh, 
+			    "editable", FALSE,
+			    "text", _("Attachment"), NULL);
+        	
+        return GTK_CELL_RENDERER (obj);
+}
+
+static void
+gdaui_data_cell_renderer_bin_get_size (GtkCellRenderer *cell,
+				       GtkWidget       *widget,
+				       GdkRectangle    *cell_area,
+				       gint            *x_offset,
+				       gint            *y_offset,
+				       gint            *width,
+				       gint            *height)
+{
+	GtkCellRendererClass *text_class = g_type_class_peek (GTK_TYPE_CELL_RENDERER_TEXT);
+
+	(text_class->get_size) (cell, widget, cell_area, x_offset, y_offset, width, height);
+}
+
+static void
+gdaui_data_cell_renderer_bin_render (GtkCellRenderer      *cell,
+				     GdkWindow            *window,
+				     GtkWidget            *widget,
+				     GdkRectangle         *background_area,
+				     GdkRectangle         *cell_area,
+				     GdkRectangle         *expose_area,
+				     GtkCellRendererState  flags)
+{
+	GtkCellRendererClass *text_class = g_type_class_peek (GTK_TYPE_CELL_RENDERER_TEXT);
+
+	(text_class->render) (cell, window, widget, background_area, cell_area, expose_area, flags);
+
+	if (GDAUI_DATA_CELL_RENDERER_BIN (cell)->priv->to_be_deleted)
+		gtk_paint_hline (widget->style,
+				 window, GTK_STATE_SELECTED,
+				 cell_area, 
+				 widget,
+				 "hline",
+				 cell_area->x + cell->xpad, cell_area->x + cell_area->width - cell->xpad,
+				 cell_area->y + cell_area->height / 2.);
+
+}
+
+static void
+bin_data_changed_cb (GdauiDataCellRendererBin *bincell, GValue *value)
+{
+        g_signal_emit (G_OBJECT (bincell), bin_cell_signals[CHANGED], 0,
+                       g_object_get_data (G_OBJECT (bincell), "last_path"), value);
+        gda_value_free (value);
+}
+
+static gboolean
+gdaui_data_cell_renderer_bin_activate  (GtkCellRenderer            *cell,
+					GdkEvent                   *event,
+					GtkWidget                  *widget,
+					const gchar                *path,
+					GdkRectangle               *background_area,
+					GdkRectangle               *cell_area,
+					GtkCellRendererState        flags)
+{
+	GdauiDataCellRendererBin *bincell;
+	GtkTreeModel *model;
+	GtkTreePath *tpath;
+	GtkTreeIter iter;
+
+        bincell = GDAUI_DATA_CELL_RENDERER_BIN (cell);
+	int event_time;
+	
+	g_object_set_data_full (G_OBJECT (bincell), "last_path", g_strdup (path), g_free);
+	if (!bincell->priv->menu.menu)
+		common_bin_create_menu (&(bincell->priv->menu), widget, bincell->priv->type,
+					(BinCallback) bin_data_changed_cb, bincell);
+	
+	model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget));
+	tpath = gtk_tree_path_new_from_string (path);
+	if (gtk_tree_model_get_iter (model, &iter, tpath)) {
+		/* FIXME: get the real GValue */
+		/*common_bin_adjust_menu (&(bincell->priv->menu), bincell->priv->editable,
+		  bincell->priv->value);*/
+		event_time = gtk_get_current_event_time ();
+		gtk_menu_popup (GTK_MENU (bincell->priv->menu.menu), NULL, NULL, NULL, NULL,
+				0, event_time);
+	}
+	gtk_tree_path_free (tpath);
+
+        return FALSE;
+}
+
+
diff --git a/libgda-ui/data-entries/gdaui-data-cell-renderer-bin.h b/libgda-ui/data-entries/gdaui-data-cell-renderer-bin.h
new file mode 100644
index 0000000..7c5674b
--- /dev/null
+++ b/libgda-ui/data-entries/gdaui-data-cell-renderer-bin.h
@@ -0,0 +1,61 @@
+/* gdaui-data-cell-renderer-bin.h
+ *
+ * Copyright (C) 2009 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
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GDAUI_DATA_CELL_RENDERER_BIN_H__
+#define __GDAUI_DATA_CELL_RENDERER_BIN_H__
+
+#include <gtk/gtk.h>
+#include <libgda/gda-data-handler.h>
+
+G_BEGIN_DECLS
+
+#define GDAUI_TYPE_DATA_CELL_RENDERER_BIN		(gdaui_data_cell_renderer_bin_get_type ())
+#define GDAUI_DATA_CELL_RENDERER_BIN(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), GDAUI_TYPE_DATA_CELL_RENDERER_BIN, GdauiDataCellRendererBin))
+#define GDAUI_DATA_CELL_RENDERER_BIN_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), GDAUI_TYPE_DATA_CELL_RENDERER_BIN, GdauiDataCellRendererBinClass))
+#define GDAUI_IS_DATA_CELL_RENDERER_BIN(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDAUI_TYPE_DATA_CELL_RENDERER_BIN))
+#define GDAUI_IS_DATA_CELL_RENDERER_BIN_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), GDAUI_TYPE_DATA_CELL_RENDERER_BIN))
+#define GDAUI_DATA_CELL_RENDERER_BIN_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GDAUI_TYPE_DATA_CELL_RENDERER_BIN, GdauiDataCellRendererBinClass))
+
+typedef struct _GdauiDataCellRendererBin GdauiDataCellRendererBin;
+typedef struct _GdauiDataCellRendererBinClass GdauiDataCellRendererBinClass;
+typedef struct _GdauiDataCellRendererBinPrivate GdauiDataCellRendererBinPrivate;
+
+struct _GdauiDataCellRendererBin
+{
+	GtkCellRendererText             parent;
+	
+	GdauiDataCellRendererBinPrivate *priv;
+};
+
+struct _GdauiDataCellRendererBinClass
+{
+	GtkCellRendererTextClass  parent_class;
+	
+	void (* changed) (GdauiDataCellRendererBin *cell_renderer,
+			  const gchar              *path,
+			  const GValue             *new_value);
+};
+
+GType            gdaui_data_cell_renderer_bin_get_type  (void) G_GNUC_CONST;
+GtkCellRenderer *gdaui_data_cell_renderer_bin_new       (GdaDataHandler *dh, GType type);
+
+G_END_DECLS
+
+#endif
diff --git a/libgda-ui/data-entries/gdaui-entry-bin.c b/libgda-ui/data-entries/gdaui-entry-bin.c
new file mode 100644
index 0000000..63e0fc0
--- /dev/null
+++ b/libgda-ui/data-entries/gdaui-entry-bin.c
@@ -0,0 +1,320 @@
+/* gdaui-entry-bin.c
+ *
+ * Copyright (C) 2009 Vivien Malerba
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include <glib/gi18n-lib.h>
+#include "gdaui-entry-bin.h"
+#include "common-bin.h"
+
+/* 
+ * Main static functions 
+ */
+static void gdaui_entry_bin_class_init (GdauiEntryBinClass * class);
+static void gdaui_entry_bin_init (GdauiEntryBin * srv);
+static void gdaui_entry_bin_dispose (GObject   * object);
+static void gdaui_entry_bin_finalize (GObject   * object);
+
+/* virtual functions */
+static GtkWidget *create_entry (GdauiEntryWrapper *mgwrap);
+static void       real_set_value (GdauiEntryWrapper *mgwrap, const GValue *value);
+static GValue    *real_get_value (GdauiEntryWrapper *mgwrap);
+static void       connect_signals(GdauiEntryWrapper *mgwrap, GCallback modify_cb, GCallback activate_cb);
+static gboolean   expand_in_layout (GdauiEntryWrapper *mgwrap);
+static void       set_editable (GdauiEntryWrapper *mgwrap, gboolean editable);
+static void       grab_focus (GdauiEntryWrapper *mgwrap);
+
+/* get a pointer to the parents to be able to call their destructor */
+static GObjectClass  *parent_class = NULL;
+
+/* private structure */
+struct _GdauiEntryBinPrivate
+{
+	GtkWidget *button;
+
+	BinMenu    menu;
+	gboolean   editable;
+
+	GValue    *current_data;
+};
+
+
+GType
+gdaui_entry_bin_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0)) {
+		static const GTypeInfo info = {
+			sizeof (GdauiEntryBinClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) gdaui_entry_bin_class_init,
+			NULL,
+			NULL,
+			sizeof (GdauiEntryBin),
+			0,
+			(GInstanceInitFunc) gdaui_entry_bin_init
+		};
+		
+		type = g_type_register_static (GDAUI_TYPE_ENTRY_WRAPPER, "GdauiEntryBin", &info, 0);
+	}
+	return type;
+}
+
+static void
+gdaui_entry_bin_class_init (GdauiEntryBinClass * class)
+{
+	GObjectClass   *object_class = G_OBJECT_CLASS (class);
+
+	parent_class = g_type_class_peek_parent (class);
+
+	object_class->dispose = gdaui_entry_bin_dispose;
+	object_class->finalize = gdaui_entry_bin_finalize;
+
+	GDAUI_ENTRY_WRAPPER_CLASS (class)->create_entry = create_entry;
+	GDAUI_ENTRY_WRAPPER_CLASS (class)->real_set_value = real_set_value;
+	GDAUI_ENTRY_WRAPPER_CLASS (class)->real_get_value = real_get_value;
+	GDAUI_ENTRY_WRAPPER_CLASS (class)->connect_signals = connect_signals;
+	GDAUI_ENTRY_WRAPPER_CLASS (class)->expand_in_layout = expand_in_layout;
+	GDAUI_ENTRY_WRAPPER_CLASS (class)->set_editable = set_editable;
+	GDAUI_ENTRY_WRAPPER_CLASS (class)->grab_focus = grab_focus;
+}
+
+static void
+gdaui_entry_bin_init (GdauiEntryBin * gdaui_entry_bin)
+{
+	gdaui_entry_bin->priv = g_new0 (GdauiEntryBinPrivate, 1);
+	gdaui_entry_bin->priv->button = NULL;
+	gdaui_entry_bin->priv->current_data = NULL;
+	gdaui_entry_bin->priv->editable = TRUE;
+}
+
+/**
+ * gdaui_entry_bin_new
+ * @dh: the data handler to be used by the new widget
+ * @type: the requested data type (compatible with @dh)
+ *
+ * Creates a new widget which is mainly a GtkEntry
+ *
+ * Returns: the new widget
+ */
+GtkWidget *
+gdaui_entry_bin_new (GdaDataHandler *dh, GType type)
+{
+	GObject *obj;
+	GdauiEntryBin *dbin;
+
+	g_return_val_if_fail (GDA_IS_DATA_HANDLER (dh), NULL);
+	g_return_val_if_fail (type != G_TYPE_INVALID, NULL);
+	g_return_val_if_fail (gda_data_handler_accepts_g_type (dh, type), NULL);
+
+	obj = g_object_new (GDAUI_TYPE_ENTRY_BIN, "handler", dh, NULL);
+	dbin = GDAUI_ENTRY_BIN (obj);
+	gdaui_data_entry_set_value_type (GDAUI_DATA_ENTRY (dbin), type);
+
+	return GTK_WIDGET (obj);
+}
+
+
+static void
+gdaui_entry_bin_dispose (GObject   * object)
+{
+	GdauiEntryBin *gdaui_entry_bin;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GDAUI_IS_ENTRY_BIN (object));
+
+	gdaui_entry_bin = GDAUI_ENTRY_BIN (object);
+	if (gdaui_entry_bin->priv) {
+		if (gdaui_entry_bin->priv->current_data) {
+			gda_value_free (gdaui_entry_bin->priv->current_data);
+			gdaui_entry_bin->priv->current_data = NULL;
+		}
+		if (gdaui_entry_bin->priv->menu.menu) {
+			gtk_widget_destroy (gdaui_entry_bin->priv->menu.menu);
+			gdaui_entry_bin->priv->menu.menu = NULL;
+		}
+	}
+
+	/* parent class */
+	parent_class->dispose (object);
+}
+
+static void
+gdaui_entry_bin_finalize (GObject   * object)
+{
+	GdauiEntryBin *gdaui_entry_bin;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GDAUI_IS_ENTRY_BIN (object));
+
+	gdaui_entry_bin = GDAUI_ENTRY_BIN (object);
+	if (gdaui_entry_bin->priv) {
+
+		g_free (gdaui_entry_bin->priv);
+		gdaui_entry_bin->priv = NULL;
+	}
+
+	/* parent class */
+	parent_class->finalize (object);
+}
+
+static GtkWidget *
+create_entry (GdauiEntryWrapper *mgwrap)
+{
+	GtkWidget *button, *arrow, *label;
+	GdauiEntryBin *dbin;
+	GtkWidget *hbox;
+
+	g_return_val_if_fail (GDAUI_IS_ENTRY_BIN (mgwrap), NULL);
+	dbin = GDAUI_ENTRY_BIN (mgwrap);
+	g_return_val_if_fail (dbin->priv, NULL);
+
+	button = gtk_button_new ();
+	dbin->priv->button = button;
+
+	hbox = gtk_hbox_new (FALSE, 0);
+        gtk_container_add (GTK_CONTAINER (button), hbox);
+
+	label = gtk_label_new (_("Attachement"));
+	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+        arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
+	gtk_misc_set_alignment (GTK_MISC (arrow), 1.0, -1);
+	gtk_box_pack_start (GTK_BOX (hbox), arrow, TRUE, TRUE, 0);
+
+        gtk_widget_show_all (hbox);
+
+	return button;
+}
+
+/*
+ * WARNING:
+ * Does NOT emit any signal 
+ */
+static void
+take_current_value (GdauiEntryBin *dbin, GValue *value)
+{
+	if (dbin->priv->current_data) {
+		gda_value_free (dbin->priv->current_data);
+		dbin->priv->current_data = NULL;
+	}
+
+	dbin->priv->current_data = value;
+	common_bin_adjust_menu (&(dbin->priv->menu), dbin->priv->editable, value);
+}
+
+static void
+real_set_value (GdauiEntryWrapper *mgwrap, const GValue *value)
+{
+	GdauiEntryBin *dbin;
+
+	g_return_if_fail (GDAUI_IS_ENTRY_BIN (mgwrap));
+	dbin = GDAUI_ENTRY_BIN (mgwrap);
+	g_return_if_fail (dbin->priv);
+
+	take_current_value (dbin, value ? gda_value_copy (value) : NULL);
+}
+
+static GValue *
+real_get_value (GdauiEntryWrapper *mgwrap)
+{
+	GdauiEntryBin *dbin;
+
+	g_return_val_if_fail (GDAUI_IS_ENTRY_BIN (mgwrap), NULL);
+	dbin = GDAUI_ENTRY_BIN (mgwrap);
+	g_return_val_if_fail (dbin->priv, NULL);
+
+	if (dbin->priv->current_data)
+		return gda_value_copy (dbin->priv->current_data);
+	else
+		return gda_value_new_null ();
+}
+
+
+static void
+value_loaded_cb (GdauiEntryBin *dbin, GValue *new_value)
+{
+	take_current_value (dbin, new_value);
+
+	/* signal changes */
+	gdaui_entry_wrapper_contents_changed (GDAUI_ENTRY_WRAPPER (dbin));
+	gdaui_entry_wrapper_contents_activated (GDAUI_ENTRY_WRAPPER (dbin));
+}
+
+static void
+button_clicked_cb (GtkWidget *button, GdauiEntryBin *dbin)
+{
+	if (!dbin->priv->menu.menu)
+		common_bin_create_menu (&(dbin->priv->menu), button,
+					gdaui_data_entry_get_value_type (GDAUI_DATA_ENTRY (dbin)),
+					(BinCallback) value_loaded_cb, dbin);
+
+	common_bin_adjust_menu (&(dbin->priv->menu), dbin->priv->editable, dbin->priv->current_data);
+
+	int event_time;
+	event_time = gtk_get_current_event_time ();
+	gtk_menu_popup (GTK_MENU (dbin->priv->menu.menu), NULL, NULL, NULL, NULL,
+                        0, event_time);
+}
+
+static void
+connect_signals (GdauiEntryWrapper *mgwrap, GCallback modify_cb, GCallback activate_cb)
+{
+	GdauiEntryBin *dbin;
+
+	g_return_if_fail (GDAUI_IS_ENTRY_BIN (mgwrap));
+	dbin = GDAUI_ENTRY_BIN (mgwrap);
+	g_return_if_fail (dbin->priv);
+
+	g_signal_connect (G_OBJECT (dbin->priv->button), "clicked",
+			  G_CALLBACK (button_clicked_cb), dbin);
+}
+
+static gboolean
+expand_in_layout (GdauiEntryWrapper *mgwrap)
+{
+	return FALSE;
+}
+
+static void
+set_editable (GdauiEntryWrapper *mgwrap, gboolean editable)
+{
+	GdauiEntryBin *dbin;
+
+	g_return_if_fail (GDAUI_IS_ENTRY_BIN (mgwrap));
+	dbin = GDAUI_ENTRY_BIN (mgwrap);
+	g_return_if_fail (dbin->priv);
+
+	dbin->priv->editable = editable;
+	if (dbin->priv->menu.load_mitem)
+		gtk_widget_set_sensitive (dbin->priv->menu.load_mitem, dbin->priv->editable);
+}
+
+static void
+grab_focus (GdauiEntryWrapper *mgwrap)
+{
+	GdauiEntryBin *dbin;
+
+	g_return_if_fail (GDAUI_IS_ENTRY_BIN (mgwrap));
+	dbin = GDAUI_ENTRY_BIN (mgwrap);
+	g_return_if_fail (dbin->priv);
+
+	gtk_widget_grab_focus (dbin->priv->button);
+}
diff --git a/libgda-ui/data-entries/gdaui-entry-bin.h b/libgda-ui/data-entries/gdaui-entry-bin.h
new file mode 100644
index 0000000..15853c4
--- /dev/null
+++ b/libgda-ui/data-entries/gdaui-entry-bin.h
@@ -0,0 +1,60 @@
+/* gdaui-entry-bin.h
+ *
+ * Copyright (C) 2009 Vivien Malerba
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+
+#ifndef __GDAUI_ENTRY_BIN_H_
+#define __GDAUI_ENTRY_BIN_H_
+
+#include "gdaui-entry-wrapper.h"
+#include <libgda/gda-data-handler.h>
+
+G_BEGIN_DECLS
+
+#define GDAUI_TYPE_ENTRY_BIN          (gdaui_entry_bin_get_type())
+#define GDAUI_ENTRY_BIN(obj)          G_TYPE_CHECK_INSTANCE_CAST (obj, gdaui_entry_bin_get_type(), GdauiEntryBin)
+#define GDAUI_ENTRY_BIN_CLASS(klass)  G_TYPE_CHECK_CLASS_CAST (klass, gdaui_entry_bin_get_type (), GdauiEntryBinClass)
+#define GDAUI_IS_ENTRY_BIN(obj)       G_TYPE_CHECK_INSTANCE_TYPE (obj, gdaui_entry_bin_get_type ())
+
+
+typedef struct _GdauiEntryBin GdauiEntryBin;
+typedef struct _GdauiEntryBinClass GdauiEntryBinClass;
+typedef struct _GdauiEntryBinPrivate GdauiEntryBinPrivate;
+
+
+/* struct for the object's data */
+struct _GdauiEntryBin
+{
+	GdauiEntryWrapper           object;
+	GdauiEntryBinPrivate       *priv;
+};
+
+/* struct for the object's class */
+struct _GdauiEntryBinClass
+{
+	GdauiEntryWrapperClass      parent_class;
+};
+
+GType        gdaui_entry_bin_get_type        (void) G_GNUC_CONST;
+GtkWidget   *gdaui_entry_bin_new             (GdaDataHandler *dh, GType type);
+
+
+G_END_DECLS
+
+#endif
diff --git a/libgda-ui/gdaui-init.c b/libgda-ui/gdaui-init.c
index e2dc27b..f1f9ff4 100644
--- a/libgda-ui/gdaui-init.c
+++ b/libgda-ui/gdaui-init.c
@@ -29,6 +29,7 @@
 #include <libgda-ui/gdaui-plugin.h>
 #include <libgda/binreloc/gda-binreloc.h>
 #include "data-entries/gdaui-entry-boolean.h"
+#include "data-entries/gdaui-entry-bin.h"
 #include "data-entries/gdaui-entry-string.h"
 #include "data-entries/gdaui-entry-time.h"
 #include "data-entries/gdaui-entry-date.h"
@@ -36,6 +37,7 @@
 #include "data-entries/gdaui-entry-none.h"
 #include "data-entries/gdaui-data-cell-renderer-textual.h"
 #include "data-entries/gdaui-data-cell-renderer-boolean.h"
+#include "data-entries/gdaui-data-cell-renderer-bin.h"
 
 /* plugins list */
 
@@ -125,7 +127,6 @@ gdaui_new_data_entry (GType type, const gchar *plugin_name)
 			entry = (GdauiDataEntry *) gdaui_entry_none_new (GDA_TYPE_NULL);
 		else if ((type == G_TYPE_INT64) ||
 			 (type == G_TYPE_UINT64) ||
-			 (type == GDA_TYPE_BINARY) ||
 			 (type == G_TYPE_DOUBLE) ||
 			 (type == G_TYPE_INT) ||
 			 (type == GDA_TYPE_NUMERIC) ||
@@ -140,9 +141,11 @@ gdaui_new_data_entry (GType type, const gchar *plugin_name)
 			entry = (GdauiDataEntry *) gdaui_entry_string_new (dh, type, spec_options);
 		else if (type == G_TYPE_BOOLEAN)
 			entry = (GdauiDataEntry *) gdaui_entry_boolean_new (dh, G_TYPE_BOOLEAN);
+		else if ((type == GDA_TYPE_BLOB) ||
+			 (type == GDA_TYPE_BINARY))
+			entry = (GdauiDataEntry *) gdaui_entry_bin_new (dh, type);
 		else if	((type == GDA_TYPE_GEOMETRIC_POINT) ||
 			 (type == G_TYPE_OBJECT) ||
-			 (type == GDA_TYPE_BLOB) ||
 			 (type == GDA_TYPE_LIST))
 			entry = (GdauiDataEntry *) gdaui_entry_none_new (type);
 		else if	(type == GDA_TYPE_TIME)
@@ -159,8 +162,8 @@ gdaui_new_data_entry (GType type, const gchar *plugin_name)
 	return entry;
 }
 
-/**
- * gdaui_new_cell_renderer
+/*
+ * _gdaui_new_cell_renderer
  * @type: a #GType
  * @plugin_name: the name of an entry plugin, or %NULL
  *
@@ -176,7 +179,7 @@ gdaui_new_data_entry (GType type, const gchar *plugin_name)
  * Returns: a new #GtkCellRenderer object, _NEVER_ %NULL
  */
 GtkCellRenderer *
-gdaui_new_cell_renderer (GType type, const gchar *plugin_name)
+_gdaui_new_cell_renderer (GType type, const gchar *plugin_name)
 {
 	GdaDataHandler *dh;
 	GtkCellRenderer *cell = NULL;
@@ -208,6 +211,9 @@ gdaui_new_cell_renderer (GType type, const gchar *plugin_name)
 			cell = gdaui_data_cell_renderer_textual_new (NULL, GDA_TYPE_NULL, NULL);
 		else if (type == G_TYPE_BOOLEAN)
 			cell = gdaui_data_cell_renderer_boolean_new (dh, G_TYPE_BOOLEAN);
+		else if ((type == GDA_TYPE_BLOB) ||
+			 (type == GDA_TYPE_BINARY))
+			cell = gdaui_data_cell_renderer_bin_new (dh, type);
 		else
 			cell = gdaui_data_cell_renderer_textual_new (dh, type, NULL);
 	}
@@ -217,6 +223,7 @@ gdaui_new_cell_renderer (GType type, const gchar *plugin_name)
 
 static GdauiDataEntry *entry_none_create_func (GdaDataHandler *handler, GType type, const gchar *options);
 static GdauiDataEntry *entry_boolean_create_func (GdaDataHandler *handler, GType type, const gchar *options);
+static GdauiDataEntry *entry_bin_create_func (GdaDataHandler *handler, GType type, const gchar *options);
 static GdauiDataEntry *entry_string_create_func (GdaDataHandler *handler, GType type, const gchar *options);
 static GdauiDataEntry *entry_time_create_func (GdaDataHandler *handler, GType type, const gchar *options);
 static GdauiDataEntry *entry_timestamp_create_func (GdaDataHandler *handler, GType type, const gchar *options);
@@ -224,6 +231,7 @@ static GdauiDataEntry *entry_date_create_func (GdaDataHandler *handler, GType ty
 
 static GtkCellRenderer *cell_textual_create_func (GdaDataHandler *handler, GType type, const gchar *options);
 static GtkCellRenderer *cell_boolean_create_func (GdaDataHandler *handler, GType type, const gchar *options);
+static GtkCellRenderer *cell_bin_create_func (GdaDataHandler *handler, GType type, const gchar *options);
 
 static xmlChar *get_spec_with_isocodes (const gchar *file);
 
@@ -257,7 +265,20 @@ init_plugins_hash (void)
 	plugin->valid_g_types [0] = G_TYPE_BOOLEAN;
 	plugin->options_xml_spec = NULL;
 	plugin->entry_create_func = entry_boolean_create_func;
-	plugin->cell_create_func =cell_boolean_create_func;
+	plugin->cell_create_func = cell_boolean_create_func;
+	g_hash_table_insert (hash, plugin->plugin_name, plugin);
+
+	plugin = g_new0 (GdauiPlugin, 1);
+	plugin->plugin_name = "binary";
+	plugin->plugin_descr = "Binary data entry";
+	plugin->plugin_file = NULL;
+	plugin->nb_g_types = 2;
+	plugin->valid_g_types = g_new (GType, plugin->nb_g_types);
+	plugin->valid_g_types [0] = GDA_TYPE_BLOB;
+	plugin->valid_g_types [1] = GDA_TYPE_BINARY;
+	plugin->options_xml_spec = NULL;
+	plugin->entry_create_func = entry_bin_create_func;
+	plugin->cell_create_func = cell_bin_create_func;
 	g_hash_table_insert (hash, plugin->plugin_name, plugin);
        
 	plugin = g_new0 (GdauiPlugin, 1);
@@ -451,6 +472,12 @@ entry_boolean_create_func (GdaDataHandler *handler, GType type, const gchar *opt
 }
 
 static GdauiDataEntry *
+entry_bin_create_func (GdaDataHandler *handler, GType type, const gchar *options)
+{
+	return (GdauiDataEntry *) gdaui_entry_bin_new (handler, type);
+}
+
+static GdauiDataEntry *
 entry_string_create_func (GdaDataHandler *handler, GType type, const gchar *options)
 {
 	return (GdauiDataEntry *) gdaui_entry_string_new (handler, type, options);
@@ -486,6 +513,12 @@ cell_boolean_create_func (GdaDataHandler *handler, GType type, const gchar *opti
 	return gdaui_data_cell_renderer_boolean_new (handler, G_TYPE_BOOLEAN);
 }
 
+static GtkCellRenderer *
+cell_bin_create_func (GdaDataHandler *handler, GType type, const gchar *options)
+{
+	return gdaui_data_cell_renderer_bin_new (handler, type);
+}
+
 static xmlNodePtr
 find_child_node_from_name (xmlNodePtr parent, const gchar *name, const gchar *attr_name, const gchar *attr_value)
 {



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