[libgda] UI extension: API cleanups, bug fixes and doc improvements



commit 30b6b8f060ecbb743b4fac2f9adfe78e585a0e24
Author: Vivien Malerba <malerba gnome-db org>
Date:   Tue Dec 22 21:09:50 2009 +0100

    UI extension: API cleanups, bug fixes and doc improvements

 control-center/dsn-config.c                        |   32 +-
 control-center/gdaui-dsn-assistant.c               |    2 +-
 control-center/main.c                              |    9 +-
 control-center/provider-config.c                   |    4 +-
 doc/C/Makefile.am                                  |    3 +-
 doc/C/libgda-4.0-docs.sgml                         |   27 +-
 doc/C/libgda-ui-sections.txt                       |  131 ++--
 doc/C/libgda-ui.types                              |    8 +-
 doc/C/tmpl/gdaui-basic-form.sgml                   |   41 +-
 doc/C/tmpl/gdaui-cloud.sgml                        |   39 +-
 doc/C/tmpl/gdaui-combo.sgml                        |   61 +--
 doc/C/tmpl/gdaui-data-entry.sgml                   |   15 +
 doc/C/tmpl/gdaui-data-filter.sgml                  |   40 +
 doc/C/tmpl/gdaui-data-proxy-info.sgml              |   61 ++
 doc/C/tmpl/gdaui-data-proxy.sgml                   |  146 ++++
 doc/C/tmpl/gdaui-data-selector.sgml                |  107 +++
 doc/C/tmpl/gdaui-form.sgml                         |   15 +-
 doc/C/tmpl/gdaui-grid.sgml                         |   20 +-
 doc/C/tmpl/gdaui-plugins.sgml                      |   63 ++
 doc/C/tmpl/gdaui-raw-form.sgml                     |    5 +-
 doc/C/tmpl/gdaui-raw-grid.sgml                     |   18 +-
 doc/C/tmpl/gdaui-server-operation.sgml             |   11 +-
 doc/C/tmpl/gdaui-tree-store.sgml                   |    5 +-
 doc/C/vi-cloud.png                                 |  Bin 0 -> 8341 bytes
 doc/C/vi-filter.png                                |  Bin 0 -> 7926 bytes
 doc/C/vi-info.png                                  |  Bin 0 -> 6004 bytes
 doc/C/vi-provider-selector.png                     |  Bin 0 -> 4354 bytes
 doc/C/vi-raw-grid.png                              |  Bin 0 -> 25914 bytes
 doc/C/vi-server-op.png                             |  Bin 0 -> 17977 bytes
 doc/C/visual_index.xml                             |   18 +
 libgda-ui/Makefile.am                              |   16 +-
 .../data-entries/gdaui-data-cell-renderer-combo.c  |   10 +-
 libgda-ui/data-entries/gdaui-entry-combo.c         |   10 +-
 libgda-ui/data-entries/gdaui-entry-wrapper.c       |    5 +-
 libgda-ui/data-entries/plugins/gdaui-entry-cgrid.c |    6 +-
 libgda-ui/demos/Makefile.am                        |    4 +-
 libgda-ui/demos/cloud.c                            |   89 ++-
 libgda-ui/demos/combo.c                            |  216 +++++
 libgda-ui/demos/data_model_dir.c                   |   14 +-
 libgda-ui/demos/ddl_queries.c                      |   23 +-
 libgda-ui/demos/form_data_layout.c                 |    8 +-
 libgda-ui/demos/form_pict.c                        |   11 +-
 libgda-ui/demos/form_rw.c                          |    4 +
 libgda-ui/demos/grid.c                             |    3 +
 libgda-ui/demos/grid_data_layout.c                 |    9 +-
 libgda-ui/demos/grid_pict.c                        |    7 +-
 libgda-ui/demos/grid_rw.c                          |    2 +
 libgda-ui/demos/linked_grid_form.c                 |   18 +-
 libgda-ui/demos/login.c                            |    2 +-
 libgda-ui/demos/main.c                             |    2 +-
 libgda-ui/demos/provider_sel.c                     |   64 ++
 libgda-ui/gdaui-basic-form.c                       |  367 +++++---
 libgda-ui/gdaui-basic-form.h                       |    4 +
 libgda-ui/gdaui-cloud.c                            |  258 +++++-
 libgda-ui/gdaui-cloud.h                            |    2 -
 libgda-ui/gdaui-combo.c                            |  415 ++++++++--
 libgda-ui/gdaui-combo.h                            |   16 +-
 libgda-ui/gdaui-data-entry.c                       |   98 ++-
 ...ui-data-widget-filter.c => gdaui-data-filter.c} |  145 ++--
 libgda-ui/gdaui-data-filter.h                      |   66 ++
 ...-data-widget-info.c => gdaui-data-proxy-info.c} |  362 ++++----
 libgda-ui/gdaui-data-proxy-info.h                  |   75 ++
 libgda-ui/gdaui-data-proxy.c                       |  293 +++++++
 libgda-ui/gdaui-data-proxy.h                       |   76 ++
 libgda-ui/gdaui-data-selector.c                    |  224 +++++
 libgda-ui/gdaui-data-selector.h                    |   70 ++
 libgda-ui/gdaui-data-store.c                       |  112 ++-
 libgda-ui/gdaui-data-widget-filter.h               |   66 --
 libgda-ui/gdaui-data-widget-info.h                 |   76 --
 libgda-ui/gdaui-data-widget.c                      |  463 ----------
 libgda-ui/gdaui-data-widget.h                      |   93 --
 libgda-ui/gdaui-decl.h                             |    4 +-
 libgda-ui/gdaui-form.c                             |  264 +++++-
 libgda-ui/gdaui-grid.c                             |  245 +++++--
 libgda-ui/gdaui-grid.h                             |    1 -
 libgda-ui/gdaui-provider-selector.c                |   27 +-
 libgda-ui/gdaui-raw-form.c                         |  399 +++++----
 libgda-ui/gdaui-raw-grid.c                         |  891 +++++++++++---------
 libgda-ui/gdaui-raw-grid.h                         |   12 +-
 libgda-ui/gdaui-server-operation.c                 |  311 ++++----
 libgda-ui/gdaui-set.c                              |   10 +-
 libgda-ui/gdaui-set.h                              |   12 +-
 libgda-ui/internal/gdaui-dsn-selector.c            |    4 +-
 libgda-ui/internal/utility.c                       |    6 +-
 libgda-ui/internal/utility.h                       |    8 +-
 libgda-ui/libgda-ui.h                              |   10 +-
 libgda-ui/libgda-ui.symbols                        |   11 +-
 libgda/gda-data-model-iter.c                       |   32 +-
 libgda/gda-data-model.c                            |    3 +-
 po/POTFILES.in                                     |    4 +-
 providers/web/gda-web-recordset.c                  |    3 +-
 testing/gdaui-test-data-entries.c                  |   14 +-
 tools/browser/common/gdaui-data-import.c           |   32 +-
 tools/browser/query-exec/query-result.c            |    3 +
 94 files changed, 4506 insertions(+), 2485 deletions(-)
---
diff --git a/control-center/dsn-config.c b/control-center/dsn-config.c
index 78d6252..3b75ed2 100644
--- a/control-center/dsn-config.c
+++ b/control-center/dsn-config.c
@@ -70,7 +70,7 @@ list_popup_cb (GdauiRawGrid *grid, GtkMenu *menu, gpointer user_data)
 {
 	GtkWidget *item_delete, *item_properties;
 	gboolean ok;
-	GList *list;
+	GArray *selection;
 
 	item_delete = cc_new_menu_item (GTK_STOCK_DELETE,
 					      TRUE,
@@ -81,10 +81,10 @@ list_popup_cb (GdauiRawGrid *grid, GtkMenu *menu, gpointer user_data)
 						  G_CALLBACK (list_popup_properties_cb),
 						  user_data);
 
-	list = gdaui_raw_grid_get_selection (grid);
-	ok = list != NULL;
-	if (list)
-		g_list_free (list);
+	selection = gdaui_data_selector_get_selected_rows (GDAUI_DATA_SELECTOR (grid));
+	ok = (selection != NULL);
+	if (selection)
+		g_array_free (selection, TRUE);
 	gtk_widget_set_sensitive (item_delete, ok);
 	gtk_widget_set_sensitive (item_properties, ok);
 
@@ -154,9 +154,9 @@ dsn_config_new (void)
 
 	g_object_unref (model);
 	g_object_set_data (G_OBJECT (dsn), "grid", priv->dsn_list);
- 	gdaui_data_widget_column_set_editable (GDAUI_DATA_WIDGET (priv->dsn_list), 0, FALSE);
- 	gdaui_data_widget_column_hide (GDAUI_DATA_WIDGET (priv->dsn_list), 3);
- 	gdaui_data_widget_column_hide (GDAUI_DATA_WIDGET (priv->dsn_list), 4);
+ 	gdaui_data_proxy_column_set_editable (GDAUI_DATA_PROXY (priv->dsn_list), 0, FALSE);
+ 	gdaui_data_selector_set_column_visible (GDAUI_DATA_SELECTOR (priv->dsn_list), 3, FALSE);
+ 	gdaui_data_selector_set_column_visible (GDAUI_DATA_SELECTOR (priv->dsn_list), 4, FALSE);
 	g_object_set (priv->dsn_list, "info_cell_visible", FALSE, NULL);
 
 	gtk_container_add (GTK_CONTAINER (sw), priv->dsn_list);
@@ -199,28 +199,30 @@ dsn_config_edit_properties (GtkWidget *dsn)
 {
 	DsnConfigPrivate *priv;
 	GdaDataModel *model;
-	GList *selection;
+	GArray *selection;
 	gchar *str;
 	const GValue *cvalue;
 
 	priv = g_object_get_data (G_OBJECT (dsn), DSN_CONFIG_DATA);
 	
-	selection = gdaui_raw_grid_get_selection (GDAUI_RAW_GRID (priv->dsn_list));
+	selection = gdaui_data_selector_get_selected_rows (GDAUI_DATA_SELECTOR (priv->dsn_list));
 	if (!selection)
 		return;
 
-	model = gdaui_data_widget_get_gda_model (GDAUI_DATA_WIDGET (priv->dsn_list));
-	if (!GDA_IS_DATA_MODEL (model))
+	model = gdaui_data_selector_get_model (GDAUI_DATA_SELECTOR (priv->dsn_list));
+	if (!GDA_IS_DATA_MODEL (model)) {
+		g_array_free (selection, TRUE);
 		return;
+	}
 
-	cvalue = gda_data_model_get_value_at (model, 0, GPOINTER_TO_INT (selection->data), NULL);
+	cvalue = gda_data_model_get_value_at (model, 0, g_array_index (selection, gint, 0), NULL);
+	g_array_free (selection, TRUE);
 	if (!cvalue) 
 		return;
 
 	str = gda_value_stringify ((GValue *) cvalue);
 	dsn_properties_dialog (GTK_WINDOW (gtk_widget_get_toplevel (dsn)), str);
 
-	g_list_free (selection);
 	g_free (str);
 }
 
@@ -237,7 +239,7 @@ dsn_config_delete (GtkWidget *dsn)
 
 	sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->dsn_list));
 	sel_rows = gtk_tree_selection_get_selected_rows (sel, NULL);
-	model = gdaui_data_widget_get_gda_model (GDAUI_DATA_WIDGET (priv->dsn_list));
+	model = gdaui_data_selector_get_model (GDAUI_DATA_SELECTOR (priv->dsn_list));
 	g_assert (GDA_IS_DATA_MODEL (model));
 
 	/* make a list of DSN to remove */
diff --git a/control-center/gdaui-dsn-assistant.c b/control-center/gdaui-dsn-assistant.c
index 326b497..b532eea 100644
--- a/control-center/gdaui-dsn-assistant.c
+++ b/control-center/gdaui-dsn-assistant.c
@@ -254,7 +254,7 @@ provider_changed_cb (GtkWidget *combo, GdauiDsnAssistant *assistant)
 	op = get_specs_database_creation (assistant);
 	if (op) {
 		assistant->priv->newdb_params = g_object_new (GDAUI_TYPE_SERVER_OPERATION, 
-							      "opt_header", TRUE, "server_operation", op, NULL);
+							      "hide-single-header", TRUE, "server_operation", op, NULL);
 		gtk_widget_show (assistant->priv->newdb_params);
 		gtk_container_add (GTK_CONTAINER (assistant->priv->newdb_box), 
 				   assistant->priv->newdb_params);
diff --git a/control-center/main.c b/control-center/main.c
index 157ce84..9077bda 100644
--- a/control-center/main.c
+++ b/control-center/main.c
@@ -374,15 +374,16 @@ static void
 dsn_selection_changed_cb (GdauiRawGrid *dbrawgrid, gboolean row_selected, gpointer data)
 {
 	GtkAction *action;
-	GList *sel;
+	GArray *selection;
 
 	action = gtk_action_group_get_action (actions, "DatabaseProperties");
 	g_object_set (G_OBJECT (action), "sensitive", row_selected, NULL);
 
-	sel = gdaui_raw_grid_get_selection (dbrawgrid);
+	selection = gdaui_data_selector_get_selected_rows (GDAUI_DATA_SELECTOR (dbrawgrid));
 	action = gtk_action_group_get_action (actions, "DatabaseDelete");
-	g_object_set (G_OBJECT (action), "sensitive", sel ? TRUE : FALSE, NULL);
-	g_list_free (sel);
+	g_object_set (G_OBJECT (action), "sensitive", selection ? TRUE : FALSE, NULL);
+	if (selection)
+		g_array_free (selection, TRUE);
 }
 
 static void
diff --git a/control-center/provider-config.c b/control-center/provider-config.c
index 15dc299..faf66a7 100644
--- a/control-center/provider-config.c
+++ b/control-center/provider-config.c
@@ -94,8 +94,8 @@ provider_config_new (void)
 	model = gda_config_list_providers ();
 	priv->provider_list = gdaui_raw_grid_new (model);
 	g_object_unref (model);
-	gdaui_data_widget_column_set_editable (GDAUI_DATA_WIDGET (priv->provider_list), 0, FALSE);
-	gdaui_data_widget_column_hide (GDAUI_DATA_WIDGET (priv->provider_list), 2);
+	gdaui_data_proxy_column_set_editable (GDAUI_DATA_PROXY (priv->provider_list), 0, FALSE);
+	gdaui_data_selector_set_column_visible (GDAUI_DATA_SELECTOR (priv->provider_list), 2, FALSE);
 	g_object_set (G_OBJECT (priv->provider_list), "info_cell_visible", FALSE, NULL);
 	gtk_container_add (GTK_CONTAINER (sw), priv->provider_list);
 	
diff --git a/doc/C/Makefile.am b/doc/C/Makefile.am
index f6c48c4..f0c865e 100644
--- a/doc/C/Makefile.am
+++ b/doc/C/Makefile.am
@@ -66,7 +66,8 @@ HTML_IMAGES = DataModels.png \
 	tree-overview.png tree-overview2.png \
 	SqlIdentifiers.png thread-wrapper.png \
 	vi-basic-form.png vi-combo.png vi-data-entry.png \
-	vi-login.png
+	vi-login.png vi-cloud.png vi-provider-selector.png vi-raw-grid.png \
+	vi-info.png vi-filter.png vi-server-op.png
 
 # Extra options to supply to gtkdoc-fixref
 FIXXREF_OPTIONS=
diff --git a/doc/C/libgda-4.0-docs.sgml b/doc/C/libgda-4.0-docs.sgml
index eb59c06..91ab87d 100644
--- a/doc/C/libgda-4.0-docs.sgml
+++ b/doc/C/libgda-4.0-docs.sgml
@@ -137,9 +137,9 @@
 <!ENTITY libgdaui-gdaui-easy SYSTEM "xml/gdaui-easy.xml">
 <!ENTITY libgdaui-gdaui-plugins SYSTEM "xml/gdaui-plugins.xml">
 <!ENTITY libgdaui-GdauiDataStore SYSTEM "xml/gdaui-data-store.xml">
-<!ENTITY libgdaui-GdauiDataWidgetFilter SYSTEM "xml/gdaui-data-widget-filter.xml">
-<!ENTITY libgdaui-GdauiDataWidget SYSTEM "xml/gdaui-data-widget.xml">
-<!ENTITY libgdaui-GdauiDataWidgetInfo SYSTEM "xml/gdaui-data-widget-info.xml">
+<!ENTITY libgdaui-GdauiDataFilter SYSTEM "xml/gdaui-data-filter.xml">
+<!ENTITY libgdaui-GdauiDataProxy SYSTEM "xml/gdaui-data-proxy.xml">
+<!ENTITY libgdaui-GdauiDataProxyInfo SYSTEM "xml/gdaui-data-proxy-info.xml">
 <!ENTITY libgdaui-GdauiForm SYSTEM "xml/gdaui-form.xml">
 <!ENTITY libgdaui-GdauiGrid SYSTEM "xml/gdaui-grid.xml">
 <!ENTITY libgdaui-GdauiLogin SYSTEM "xml/gdaui-login.xml">
@@ -147,9 +147,9 @@
 <!ENTITY libgdaui-GdauiRawForm SYSTEM "xml/gdaui-raw-form.xml">
 <!ENTITY libgdaui-GdauiRawGrid SYSTEM "xml/gdaui-raw-grid.xml">
 <!ENTITY libgdaui-GdauiServerOperation SYSTEM "xml/gdaui-server-operation.xml">
-<!ENTITY libgdaui-GdauiSet SYSTEM "xml/gdaui-set.xml">
 <!ENTITY libgdaui-GdauiTreeStore SYSTEM "xml/gdaui-tree-store.xml">
 <!ENTITY libgdaui-GdauiCloud SYSTEM "xml/gdaui-cloud.xml">
+<!ENTITY libgdaui-GdauiDataSelector SYSTEM "xml/gdaui-data-selector.xml">
 ]>
 
 <book id="index">
@@ -1246,29 +1246,30 @@ g_object_unref (store);
     <chapter>
       <title>User interface API reference</title>
       &visual-index;
-      &libgdaui-gdaui-easy;
 
       &libgdaui-GdauiLogin;
       &libgdaui-GdauiProviderSelector;
 
+      &libgdaui-GdauiDataSelector;
+      &libgdaui-GdauiDataProxy;
       &libgdaui-GdauiBasicForm;
-      &libgdaui-gdaui-plugins;
       &libgdaui-GdauiForm;
+      &libgdaui-GdauiRawForm;
       &libgdaui-GdauiGrid;
+      &libgdaui-GdauiRawGrid;
+      &libgdaui-GdauiCombo;
       &libgdaui-GdauiCloud;
 
-      &libgdaui-GdauiRawForm;
-      &libgdaui-GdauiRawGrid;
+      &libgdaui-gdaui-plugins;
 
-      &libgdaui-GdauiCombo;
       &libgdaui-GdauiDataEntry;
       &libgdaui-GdauiDataStore;
-      &libgdaui-GdauiDataWidgetFilter;
-      &libgdaui-GdauiDataWidget;
-      &libgdaui-GdauiDataWidgetInfo;
+      &libgdaui-GdauiDataFilter;
+      &libgdaui-GdauiDataProxyInfo;
       &libgdaui-GdauiServerOperation;
-      &libgdaui-GdauiSet;
       &libgdaui-GdauiTreeStore;
+
+      &libgdaui-gdaui-easy;
     </chapter>
 
     <chapter id="multi-threading">
diff --git a/doc/C/libgda-ui-sections.txt b/doc/C/libgda-ui-sections.txt
index a27218a..113db04 100644
--- a/doc/C/libgda-ui-sections.txt
+++ b/doc/C/libgda-ui-sections.txt
@@ -30,6 +30,7 @@ gdaui_basic_form_entry_set_editable
 gdaui_basic_form_set_entries_to_default
 gdaui_basic_form_get_entry_widget
 gdaui_basic_form_get_label_widget
+gdaui_basic_form_set_data_layout_from_file
 <SUBSECTION Standard>
 GDAUI_BASIC_FORM
 GDAUI_BASIC_FORM_CLASS
@@ -46,13 +47,8 @@ GdauiCombo
 gdaui_combo_new
 gdaui_combo_new_with_model
 gdaui_combo_set_model
-gdaui_combo_get_model
-gdaui_combo_add_undef_choice
-gdaui_combo_set_values
-gdaui_combo_get_values
-gdaui_combo_undef_selected
-gdaui_combo_set_values_ext
-gdaui_combo_get_values_ext
+gdaui_combo_add_null
+gdaui_combo_is_null_selected
 <SUBSECTION Standard>
 GDAUI_COMBO
 GDAUI_COMBO_CLASS
@@ -111,58 +107,53 @@ gdaui_data_store_get_type
 </SECTION>
 
 <SECTION>
-<FILE>gdaui-data-widget-filter</FILE>
-<TITLE>GdauiDataWidgetFilter</TITLE>
-GdauiDataWidgetFilter
-gdaui_data_widget_filter_new
+<FILE>gdaui-data-filter</FILE>
+<TITLE>GdauiDataFilter</TITLE>
+GdauiDataFilter
+gdaui_data_filter_new
 <SUBSECTION Standard>
-GDAUI_DATA_WIDGET_FILTER
-GDAUI_IS_DATA_WIDGET_FILTER
-GDAUI_DATA_WIDGET_FILTER_CLASS
-GDAUI_TYPE_DATA_WIDGET_FILTER
-gdaui_data_widget_filter_get_type
+GDAUI_DATA_FILTER
+GDAUI_IS_DATA_FILTER
+GDAUI_DATA_FILTER_CLASS
+GDAUI_TYPE_DATA_FILTER
+gdaui_data_filter_get_type
 </SECTION>
 
 <SECTION>
-<FILE>gdaui-data-widget</FILE>
-<TITLE>GdauiDataWidget</TITLE>
-GdauiDataWidget
-GdauiDataWidgetIface
-gdaui_data_widget_new
-gdaui_data_widget_get_proxy
-gdaui_data_widget_get_actions_group
-gdaui_data_widget_perform_action
-gdaui_data_widget_column_show
-gdaui_data_widget_column_hide
-gdaui_data_widget_column_set_editable
-gdaui_data_widget_column_show_actions
-gdaui_data_widget_get_gda_model
-gdaui_data_widget_set_gda_model
-gdaui_data_widget_get_current_data
-GdauiDataWidgetWriteMode
-gdaui_data_widget_set_write_mode
-gdaui_data_widget_get_write_mode
-gdaui_data_widget_set_data_layout_from_file
+<FILE>gdaui-data-proxy</FILE>
+<TITLE>GdauiDataProxy</TITLE>
+GdauiDataProxy
+GdauiDataProxyIface
+gdaui_data_proxy_new
+gdaui_data_proxy_get_proxy
+gdaui_data_proxy_get_actions_group
+GdauiAction
+gdaui_data_proxy_perform_action
+gdaui_data_proxy_column_set_editable
+gdaui_data_proxy_column_show_actions
+GdauiDataProxyWriteMode
+gdaui_data_proxy_set_write_mode
+gdaui_data_proxy_get_write_mode
 <SUBSECTION Standard>
-GDAUI_DATA_WIDGET
-GDAUI_IS_DATA_WIDGET
-GDAUI_DATA_WIDGET_CLASS
-GDAUI_TYPE_DATA_WIDGET
-gdaui_data_widget_get_type
+GDAUI_DATA_PROXY
+GDAUI_IS_DATA_PROXY
+GDAUI_DATA_PROXY_CLASS
+GDAUI_TYPE_DATA_PROXY
+gdaui_data_proxy_get_type
 </SECTION>
 
 <SECTION>
-<FILE>gdaui-data-widget-info</FILE>
-<TITLE>GdauiDataWidgetInfo</TITLE>
-GdauiDataWidgetInfo
-GdauiDataWidgetInfoFlag
-gdaui_data_widget_info_new
+<FILE>gdaui-data-proxy-info</FILE>
+<TITLE>GdauiDataProxyInfo</TITLE>
+GdauiDataProxyInfo
+GdauiDataProxyInfoFlag
+gdaui_data_proxy_info_new
 <SUBSECTION Standard>
-GDAUI_DATA_WIDGET_INFO
-GDAUI_IS_DATA_WIDGET_INFO
-GDAUI_DATA_WIDGET_INFO_CLASS
-GDAUI_TYPE_DATA_WIDGET_INFO
-gdaui_data_widget_info_get_type
+GDAUI_DATA_PROXY_INFO
+GDAUI_IS_DATA_PROXY_INFO
+GDAUI_DATA_PROXY_INFO_CLASS
+GDAUI_TYPE_DATA_PROXY_INFO
+gdaui_data_proxy_info_get_type
 </SECTION>
 
 <SECTION>
@@ -184,7 +175,6 @@ gdaui_form_get_type
 <TITLE>GdauiGrid</TITLE>
 GdauiGrid
 gdaui_grid_new
-gdaui_grid_get_selection
 gdaui_grid_set_sample_size
 <SUBSECTION Standard>
 GDAUI_GRID
@@ -250,7 +240,7 @@ GdauiRawGrid
 gdaui_raw_grid_new
 gdaui_raw_grid_set_sample_size
 gdaui_raw_grid_set_sample_start
-gdaui_raw_grid_get_selection
+gdaui_raw_grid_set_data_layout_from_file
 <SUBSECTION Standard>
 GDAUI_RAW_GRID
 GDAUI_IS_RAW_GRID
@@ -274,22 +264,6 @@ gdaui_server_operation_get_type
 </SECTION>
 
 <SECTION>
-<FILE>gdaui-set</FILE>
-<TITLE>GdauiSet</TITLE>
-GdauiSet
-gdaui_set_new
-GdauiSetGroup
-GdauiSetSource
-<SUBSECTION Standard>
-GDAUI_SET
-GDAUI_SET_CLASS
-GDAUI_IS_SET
-GDAUI_IS_SET_CLASS
-GDAUI_TYPE_SET
-gdaui_set_get_type
-</SECTION>
-
-<SECTION>
 <FILE>gdaui-tree-store</FILE>
 <TITLE>GdauiTreeStore</TITLE>
 GdauiTreeStore
@@ -312,6 +286,8 @@ gdaui_cloud_set_selection_mode
 gdaui_cloud_get_selection
 gdaui_cloud_filter
 gdaui_cloud_create_filter_widget
+GdauiCloudWeightFunc
+gdaui_cloud_set_weight_func
 <SUBSECTION Standard>
 GDAUI_CLOUD
 GDAUI_CLOUD_CLASS
@@ -320,3 +296,22 @@ GDAUI_IS_CLOUD_CLASS
 GDAUI_TYPE_CLOUD
 gdaui_cloud_get_type
 </SECTION>
+
+<SECTION>
+<FILE>gdaui-data-selector</FILE>
+<TITLE>GdauiDataSelector</TITLE>
+GdauiDataSelector
+gdaui_data_selector_get_model
+gdaui_data_selector_set_model
+gdaui_data_selector_get_selected_rows
+gdaui_data_selector_get_data_set
+gdaui_data_selector_select_row
+gdaui_data_selector_unselect_row
+gdaui_data_selector_set_column_visible
+<SUBSECTION Standard>
+GDAUI_DATA_SELECTOR
+GDAUI_DATA_SELECTOR_GET_IFACE
+GDAUI_IS_DATA_SELECTOR
+GDAUI_TYPE_DATA_SELECTOR
+gdaui_data_selector_get_type
+</SECTION>
diff --git a/doc/C/libgda-ui.types b/doc/C/libgda-ui.types
index c74b3fc..e2bec78 100644
--- a/doc/C/libgda-ui.types
+++ b/doc/C/libgda-ui.types
@@ -3,9 +3,10 @@ gdaui_basic_form_get_type
 gdaui_combo_get_type
 gdaui_data_entry_get_type
 gdaui_data_store_get_type
-gdaui_data_widget_filter_get_type
-gdaui_data_widget_get_type
-gdaui_data_widget_info_get_type
+gdaui_data_filter_get_type
+gdaui_data_proxy_get_type
+gdaui_data_proxy_info_get_type
+gdaui_data_selector_get_type
 gdaui_form_get_type
 gdaui_grid_get_type
 gdaui_login_get_type
@@ -13,6 +14,5 @@ gdaui_provider_selector_get_type
 gdaui_raw_form_get_type
 gdaui_raw_grid_get_type
 gdaui_server_operation_get_type
-gdaui_set_get_type
 gdaui_tree_store_get_type
 gdaui_cloud_get_type
diff --git a/doc/C/tmpl/gdaui-basic-form.sgml b/doc/C/tmpl/gdaui-basic-form.sgml
index b580874..de4dc4a 100644
--- a/doc/C/tmpl/gdaui-basic-form.sgml
+++ b/doc/C/tmpl/gdaui-basic-form.sgml
@@ -6,7 +6,29 @@ Form widget mapping the values contained in a #GdaSet
 
 <!-- ##### SECTION Long_Description ##### -->
 <para>
-
+  The #GdauiBasicForm widget is a form containing an entry for each #GdaHolder object
+  contained in a #GdaSet (specified when the form is created). A typical usage is when the
+  user is requested to enter a value which will be used in a statement (without any error checking for clarity):
+  <programlisting>
+GdaStatement *stmt;
+GdaSet *params;
+stmt = gda_sql_parser_parse_string (parser, "SELECT * FROM customers where name LIKE ##name::string", NULL, NULL);
+gda_statement_get_parameters (stmt, &amp;params, NULL);
+
+GtkWidget *form;
+gint result;
+form = gdaui_basic_form_new_in_dialog (params, NULL, "Customer search", "Enter Customer search expression");
+result = gtk_dialog_run (GTK_DIALOG (form));
+gtk_widget_destroy (form);
+if (result == GTK_RESPONSE_ACCEPT) {
+    /* execute statement */
+    GdaDataModel *model;
+    model = gda_connection_statement_execute_select (cnc, stmt, params, NULL);
+    [...]
+}
+g_object_unref (params);
+g_object_unref (stmt);
+  </programlisting>
 </para>
 
 <!-- ##### SECTION See_Also ##### -->
@@ -39,6 +61,13 @@ Form widget mapping the values contained in a #GdaSet
 @arg1: 
 @arg2: 
 
+<!-- ##### SIGNAL GdauiBasicForm::layout-changed ##### -->
+<para>
+
+</para>
+
+ gdauibasicform: the object which received the signal.
+
 <!-- ##### ARG GdauiBasicForm:can-expand ##### -->
 <para>
 
@@ -190,3 +219,13 @@ Form widget mapping the values contained in a #GdaSet
 @Returns: 
 
 
+<!-- ##### FUNCTION gdaui_basic_form_set_data_layout_from_file ##### -->
+<para>
+
+</para>
+
+ form: 
+ file_name: 
+ parent_table: 
+
+
diff --git a/doc/C/tmpl/gdaui-cloud.sgml b/doc/C/tmpl/gdaui-cloud.sgml
index 266ff61..3bec60b 100644
--- a/doc/C/tmpl/gdaui-cloud.sgml
+++ b/doc/C/tmpl/gdaui-cloud.sgml
@@ -6,7 +6,13 @@ Cloud widget
 
 <!-- ##### SECTION Long_Description ##### -->
 <para>
-
+  The #GdauiCloud widget displays a string for each row in a #GdaDataModel for which the size
+  is variable (determined either by some data in the data model, or by a function provided by
+  the programmer).
+</para>
+<para>
+  Depending on the selection mode of the widget, each string can be selected by the user and
+  the "selection-changed" signal is emitted.
 </para>
 
 <!-- ##### SECTION See_Also ##### -->
@@ -31,13 +37,6 @@ Cloud widget
 @gdauicloud: the object which received the signal.
 @arg1: 
 
-<!-- ##### SIGNAL GdauiCloud::selection-changed ##### -->
-<para>
-
-</para>
-
- gdauicloud: the object which received the signal.
-
 <!-- ##### ARG GdauiCloud:label-column ##### -->
 <para>
 
@@ -83,30 +82,42 @@ Cloud widget
 @mode: 
 
 
-<!-- ##### FUNCTION gdaui_cloud_get_selection ##### -->
+<!-- ##### FUNCTION gdaui_cloud_filter ##### -->
 <para>
 
 </para>
 
 @cloud: 
- Returns: 
+ filter: 
 
 
-<!-- ##### FUNCTION gdaui_cloud_filter ##### -->
+<!-- ##### FUNCTION gdaui_cloud_create_filter_widget ##### -->
 <para>
 
 </para>
 
 @cloud: 
- filter: 
+ Returns: 
 
 
-<!-- ##### FUNCTION gdaui_cloud_create_filter_widget ##### -->
+<!-- ##### USER_FUNCTION GdauiCloudWeightFunc ##### -->
 <para>
 
 </para>
 
- cloud: 
+ model: 
+ row: 
+ data: 
 @Returns: 
 
 
+<!-- ##### FUNCTION gdaui_cloud_set_weight_func ##### -->
+<para>
+
+</para>
+
+ cloud: 
+ func: 
+ data: 
+
+
diff --git a/doc/C/tmpl/gdaui-combo.sgml b/doc/C/tmpl/gdaui-combo.sgml
index dd4f48a..348cdf0 100644
--- a/doc/C/tmpl/gdaui-combo.sgml
+++ b/doc/C/tmpl/gdaui-combo.sgml
@@ -23,6 +23,11 @@ Combo box to choose from the contents of a #GdaDataModel
 </para>
 
 
+<!-- ##### ARG GdauiCombo:as-list ##### -->
+<para>
+
+</para>
+
 <!-- ##### ARG GdauiCombo:model ##### -->
 <para>
 
@@ -58,71 +63,21 @@ Combo box to choose from the contents of a #GdaDataModel
 @cols_index: 
 
 
-<!-- ##### FUNCTION gdaui_combo_get_model ##### -->
-<para>
-
-</para>
-
- combo: 
- Returns: 
-
-
-<!-- ##### FUNCTION gdaui_combo_add_undef_choice ##### -->
+<!-- ##### FUNCTION gdaui_combo_add_null ##### -->
 <para>
 
 </para>
 
 @combo: 
- add_undef_choice: 
+ add_null: 
 
 
-<!-- ##### FUNCTION gdaui_combo_set_values ##### -->
+<!-- ##### FUNCTION gdaui_combo_is_null_selected ##### -->
 <para>
 
 </para>
 
 @combo: 
- values: 
- Returns: 
-
-
-<!-- ##### FUNCTION gdaui_combo_get_values ##### -->
-<para>
-
-</para>
-
- combo: 
- Returns: 
-
-
-<!-- ##### FUNCTION gdaui_combo_undef_selected ##### -->
-<para>
-
-</para>
-
- combo: 
- Returns: 
-
-
-<!-- ##### FUNCTION gdaui_combo_set_values_ext ##### -->
-<para>
-
-</para>
-
- combo: 
- values: 
- cols_index: 
- Returns: 
-
-
-<!-- ##### FUNCTION gdaui_combo_get_values_ext ##### -->
-<para>
-
-</para>
-
- combo: 
- n_cols: 
- cols_index: 
 @Returns: 
 
 
diff --git a/doc/C/tmpl/gdaui-data-entry.sgml b/doc/C/tmpl/gdaui-data-entry.sgml
index 8949f90..b37266b 100644
--- a/doc/C/tmpl/gdaui-data-entry.sgml
+++ b/doc/C/tmpl/gdaui-data-entry.sgml
@@ -10,6 +10,21 @@ Data entry widget
   which lets the user view and/or modify a #GValue.
 </para>
 <para>
+  This interface is implemented by widgets which feature data editing (usually composed of an editing
+  area and a button to have some more control on the value being edited).
+  The interface allows to control how the widget works and to query the value and the attributes
+  of the data held by the widget.
+</para>
+<para>
+  The widget can store the original value (to be able to tell if the value has been changed
+  by the user) and a default value (which will be returned if the user explicitly forces the widget
+  to be set to the default value).
+  Control methods allow to set the type of value to be edited (the requested type must be
+  compatible with what the widget can handle), set the value (which replaces the currently edited
+  value), set the value and the original value (the value passed as argument is set and is also
+  considered to be the original value).
+</para>
+<para>
   #GdaUiDataEntry widgets are normally created using the gdaui_new_data_entry() function.
 </para>
 
diff --git a/doc/C/tmpl/gdaui-data-filter.sgml b/doc/C/tmpl/gdaui-data-filter.sgml
new file mode 100644
index 0000000..76655cc
--- /dev/null
+++ b/doc/C/tmpl/gdaui-data-filter.sgml
@@ -0,0 +1,40 @@
+<!-- ##### SECTION Title ##### -->
+GdauiDataFilter
+
+<!-- ##### SECTION Short_Description ##### -->
+Entrer rules to filter the rows in a #GdauiDataProxy
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+  The #GdauiDataFilter widget can be used as a standalone widget, but is also
+  used internally by the #GdauiDataProxyInfo widget for its search option.
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT GdauiDataFilter ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG GdauiDataFilter:data-widget ##### -->
+<para>
+
+</para>
+
+<!-- ##### FUNCTION gdaui_data_filter_new ##### -->
+<para>
+
+</para>
+
+ data_widget: 
+ Returns: 
+
+
diff --git a/doc/C/tmpl/gdaui-data-proxy-info.sgml b/doc/C/tmpl/gdaui-data-proxy-info.sgml
new file mode 100644
index 0000000..12c5a83
--- /dev/null
+++ b/doc/C/tmpl/gdaui-data-proxy-info.sgml
@@ -0,0 +1,61 @@
+<!-- ##### SECTION Title ##### -->
+GdauiDataProxyInfo
+
+<!-- ##### SECTION Short_Description ##### -->
+Shows information &amp; actions about a #GdauiDataProxy widget
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+  The #GdauiDataProxyInfo widget is a container widget which, depending on how it is configured:
+  <itemizedlist>
+    <listitem><para>proposes action buttons to change the currently displayed row, add new row, ...</para></listitem>
+    <listitem><para>displays information about the number of rows in a #GdauiDataProxy</para></listitem>
+  </itemizedlist>
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT GdauiDataProxyInfo ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### ARG GdauiDataProxyInfo:data-proxy ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GdauiDataProxyInfo:flags ##### -->
+<para>
+
+</para>
+
+<!-- ##### ENUM GdauiDataProxyInfoFlag ##### -->
+<para>
+
+</para>
+
+ GDAUI_DATA_PROXY_INFO_NONE: 
+ GDAUI_DATA_PROXY_INFO_CURRENT_ROW: 
+ GDAUI_DATA_PROXY_INFO_ROW_MODIFY_BUTTONS: 
+ GDAUI_DATA_PROXY_INFO_ROW_MOVE_BUTTONS: 
+ GDAUI_DATA_PROXY_INFO_CHUNCK_CHANGE_BUTTONS: 
+ GDAUI_DATA_PROXY_INFO_NO_FILTER: 
+
+<!-- ##### FUNCTION gdaui_data_proxy_info_new ##### -->
+<para>
+
+</para>
+
+ data_proxy: 
+ flags: 
+ Returns: 
+
+
diff --git a/doc/C/tmpl/gdaui-data-proxy.sgml b/doc/C/tmpl/gdaui-data-proxy.sgml
new file mode 100644
index 0000000..3229aa5
--- /dev/null
+++ b/doc/C/tmpl/gdaui-data-proxy.sgml
@@ -0,0 +1,146 @@
+<!-- ##### SECTION Title ##### -->
+GdauiDataProxy
+
+<!-- ##### SECTION Short_Description ##### -->
+Modifying data in a #GdaDataModel
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+  The #GdauiDataProxy interface is implemented by widgets which allow modifications
+  to a #GdaDataModel (through a #GdaDataProxy to actually proxy the changes before they
+  are written to the data model).
+  
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+  The #GdauiDataSelector interface which is usually also implemented by the widgets
+  which implement the #GdauiDataProxy interface.
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT GdauiDataProxy ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SIGNAL GdauiDataProxy::proxy-changed ##### -->
+<para>
+
+</para>
+
+ gdauidataproxy: the object which received the signal.
+ arg1: 
+
+<!-- ##### STRUCT GdauiDataProxyIface ##### -->
+<para>
+
+</para>
+
+ g_iface: 
+ get_proxy: 
+ set_column_editable: 
+ show_column_actions: 
+ get_actions_group: 
+ set_write_mode: 
+ get_write_mode: 
+ proxy_changed: 
+
+<!-- ##### FUNCTION gdaui_data_proxy_get_proxy ##### -->
+<para>
+
+</para>
+
+ iface: 
+ Returns: 
+
+
+<!-- ##### FUNCTION gdaui_data_proxy_get_actions_group ##### -->
+<para>
+
+</para>
+
+ iface: 
+ Returns: 
+
+
+<!-- ##### ENUM GdauiAction ##### -->
+<para>
+
+</para>
+
+ GDAUI_ACTION_NEW_DATA: 
+ GDAUI_ACTION_WRITE_MODIFIED_DATA: 
+ GDAUI_ACTION_DELETE_SELECTED_DATA: 
+ GDAUI_ACTION_UNDELETE_SELECTED_DATA: 
+ GDAUI_ACTION_RESET_DATA: 
+ GDAUI_ACTION_MOVE_FIRST_RECORD: 
+ GDAUI_ACTION_MOVE_PREV_RECORD: 
+ GDAUI_ACTION_MOVE_NEXT_RECORD: 
+ GDAUI_ACTION_MOVE_LAST_RECORD: 
+ GDAUI_ACTION_MOVE_FIRST_CHUNCK: 
+ GDAUI_ACTION_MOVE_PREV_CHUNCK: 
+ GDAUI_ACTION_MOVE_NEXT_CHUNCK: 
+ GDAUI_ACTION_MOVE_LAST_CHUNCK: 
+
+<!-- ##### FUNCTION gdaui_data_proxy_perform_action ##### -->
+<para>
+
+</para>
+
+ iface: 
+ action: 
+
+
+<!-- ##### FUNCTION gdaui_data_proxy_column_set_editable ##### -->
+<para>
+
+</para>
+
+ iface: 
+ column: 
+ editable: 
+
+
+<!-- ##### FUNCTION gdaui_data_proxy_column_show_actions ##### -->
+<para>
+
+</para>
+
+ iface: 
+ column: 
+ show_actions: 
+
+
+<!-- ##### ENUM GdauiDataProxyWriteMode ##### -->
+<para>
+
+</para>
+
+ GDAUI_DATA_PROXY_WRITE_ON_DEMAND: 
+ GDAUI_DATA_PROXY_WRITE_ON_ROW_CHANGE: 
+ GDAUI_DATA_PROXY_WRITE_ON_VALUE_ACTIVATED: 
+ GDAUI_DATA_PROXY_WRITE_ON_VALUE_CHANGE: 
+
+<!-- ##### FUNCTION gdaui_data_proxy_set_write_mode ##### -->
+<para>
+
+</para>
+
+ iface: 
+ mode: 
+ Returns: 
+
+
+<!-- ##### FUNCTION gdaui_data_proxy_get_write_mode ##### -->
+<para>
+
+</para>
+
+ iface: 
+ Returns: 
+
+
diff --git a/doc/C/tmpl/gdaui-data-selector.sgml b/doc/C/tmpl/gdaui-data-selector.sgml
new file mode 100644
index 0000000..6012391
--- /dev/null
+++ b/doc/C/tmpl/gdaui-data-selector.sgml
@@ -0,0 +1,107 @@
+<!-- ##### SECTION Title ##### -->
+GdauiDataSelector
+
+<!-- ##### SECTION Short_Description ##### -->
+Selecting data in a #GdaDataModel
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+  The #GdauiDataSelector interface is implemented by widgets which allow the user
+  to select some data from a #GdaDataModel. Depending on the actual widget, the selection
+  can be a single row or more than one row.
+</para>
+<para>
+  This interface allows one to set and get the #GdaDataModel from which data is to be selected
+  and offers a few other common behaviours.
+</para>
+<para>
+  Please note that any row number in this interface is in reference to the #GdaDataModel returned by
+  the gdaui_data_selector_get_model() method.
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### STRUCT GdauiDataSelector ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SIGNAL GdauiDataSelector::selection-changed ##### -->
+<para>
+
+</para>
+
+ gdauidataselector: the object which received the signal.
+
+<!-- ##### FUNCTION gdaui_data_selector_get_model ##### -->
+<para>
+
+</para>
+
+ iface: 
+ Returns: 
+
+
+<!-- ##### FUNCTION gdaui_data_selector_set_model ##### -->
+<para>
+
+</para>
+
+ iface: 
+ model: 
+
+
+<!-- ##### FUNCTION gdaui_data_selector_get_selected_rows ##### -->
+<para>
+
+</para>
+
+ iface: 
+ Returns: 
+
+
+<!-- ##### FUNCTION gdaui_data_selector_get_data_set ##### -->
+<para>
+
+</para>
+
+ iface: 
+ Returns: 
+
+
+<!-- ##### FUNCTION gdaui_data_selector_select_row ##### -->
+<para>
+
+</para>
+
+ iface: 
+ row: 
+ Returns: 
+
+
+<!-- ##### FUNCTION gdaui_data_selector_unselect_row ##### -->
+<para>
+
+</para>
+
+ iface: 
+ row: 
+
+
+<!-- ##### FUNCTION gdaui_data_selector_set_column_visible ##### -->
+<para>
+
+</para>
+
+ iface: 
+ column: 
+ visible: 
+
+
diff --git a/doc/C/tmpl/gdaui-form.sgml b/doc/C/tmpl/gdaui-form.sgml
index af8d08e..ddbee7f 100644
--- a/doc/C/tmpl/gdaui-form.sgml
+++ b/doc/C/tmpl/gdaui-form.sgml
@@ -2,7 +2,7 @@
 GdauiForm
 
 <!-- ##### SECTION Short_Description ##### -->
-
+Form widget to manipulate data in a #GdaDataModel, with decorations
 
 <!-- ##### SECTION Long_Description ##### -->
 <para>
@@ -11,7 +11,7 @@ GdauiForm
 
 <!-- ##### SECTION See_Also ##### -->
 <para>
-
+  The #GdauiRawForm widget which is used by the #GdaForm widget.
 </para>
 
 <!-- ##### SECTION Stability_Level ##### -->
@@ -23,17 +23,22 @@ GdauiForm
 </para>
 
 
-<!-- ##### ARG GdauiForm:model ##### -->
+<!-- ##### ARG GdauiForm:info ##### -->
 <para>
 
 </para>
 
-<!-- ##### ARG GdauiForm:raw-form ##### -->
+<!-- ##### ARG GdauiForm:info-flags ##### -->
+<para>
+
+</para>
+
+<!-- ##### ARG GdauiForm:model ##### -->
 <para>
 
 </para>
 
-<!-- ##### ARG GdauiForm:widget-info ##### -->
+<!-- ##### ARG GdauiForm:raw-form ##### -->
 <para>
 
 </para>
diff --git a/doc/C/tmpl/gdaui-grid.sgml b/doc/C/tmpl/gdaui-grid.sgml
index 12dfb1b..821328b 100644
--- a/doc/C/tmpl/gdaui-grid.sgml
+++ b/doc/C/tmpl/gdaui-grid.sgml
@@ -2,7 +2,7 @@
 GdauiGrid
 
 <!-- ##### SECTION Short_Description ##### -->
-
+Grid widget to manipulate data in a #GdaDataModel, with decorations
 
 <!-- ##### SECTION Long_Description ##### -->
 <para>
@@ -11,7 +11,7 @@ GdauiGrid
 
 <!-- ##### SECTION See_Also ##### -->
 <para>
-
+  The #GdauiRawGrid widget which is used by the #GdaGrid widget.
 </para>
 
 <!-- ##### SECTION Stability_Level ##### -->
@@ -23,36 +23,32 @@ GdauiGrid
 </para>
 
 
-<!-- ##### ARG GdauiGrid:model ##### -->
+<!-- ##### ARG GdauiGrid:info ##### -->
 <para>
 
 </para>
 
-<!-- ##### ARG GdauiGrid:raw-grid ##### -->
+<!-- ##### ARG GdauiGrid:info-flags ##### -->
 <para>
 
 </para>
 
-<!-- ##### ARG GdauiGrid:widget-info ##### -->
+<!-- ##### ARG GdauiGrid:model ##### -->
 <para>
 
 </para>
 
-<!-- ##### FUNCTION gdaui_grid_new ##### -->
+<!-- ##### ARG GdauiGrid:raw-grid ##### -->
 <para>
 
 </para>
 
- model: 
- Returns: 
-
-
-<!-- ##### FUNCTION gdaui_grid_get_selection ##### -->
+<!-- ##### FUNCTION gdaui_grid_new ##### -->
 <para>
 
 </para>
 
- grid: 
+ model: 
 @Returns: 
 
 
diff --git a/doc/C/tmpl/gdaui-plugins.sgml b/doc/C/tmpl/gdaui-plugins.sgml
new file mode 100644
index 0000000..da94a2b
--- /dev/null
+++ b/doc/C/tmpl/gdaui-plugins.sgml
@@ -0,0 +1,63 @@
+<!-- ##### SECTION Title ##### -->
+UI plugins
+
+<!-- ##### SECTION Short_Description ##### -->
+
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### SECTION Stability_Level ##### -->
+
+
+<!-- ##### USER_FUNCTION GdauiEntryCreateFunc ##### -->
+<para>
+
+</para>
+
+ Param1: 
+ Param2: 
+ Param3: 
+ Returns: 
+
+
+<!-- ##### USER_FUNCTION GdauiCellCreateFunc ##### -->
+<para>
+
+</para>
+
+ Param1: 
+ Param2: 
+ Param3: 
+ Returns: 
+
+
+<!-- ##### STRUCT GdauiPlugin ##### -->
+<para>
+
+</para>
+
+ plugin_name: 
+ plugin_descr: 
+ plugin_file: 
+ nb_g_types: 
+ valid_g_types: 
+ options_xml_spec: 
+ entry_create_func: 
+ cell_create_func: 
+
+<!-- ##### FUNCTION gdaui_plugin_declare ##### -->
+<para>
+
+</para>
+
+ plugin: 
+
+
diff --git a/doc/C/tmpl/gdaui-raw-form.sgml b/doc/C/tmpl/gdaui-raw-form.sgml
index 849961f..54c7552 100644
--- a/doc/C/tmpl/gdaui-raw-form.sgml
+++ b/doc/C/tmpl/gdaui-raw-form.sgml
@@ -2,7 +2,7 @@
 GdauiRawForm
 
 <!-- ##### SECTION Short_Description ##### -->
-
+Form widget to manipulate data in a #GdaDataModel
 
 <!-- ##### SECTION Long_Description ##### -->
 <para>
@@ -11,7 +11,8 @@ GdauiRawForm
 
 <!-- ##### SECTION See_Also ##### -->
 <para>
-
+  The #GdauiForm widget which uses the #GdauiRawForm and adds decorations such as
+  information about data model size, and features searching.
 </para>
 
 <!-- ##### SECTION Stability_Level ##### -->
diff --git a/doc/C/tmpl/gdaui-raw-grid.sgml b/doc/C/tmpl/gdaui-raw-grid.sgml
index 302a57c..3fe4842 100644
--- a/doc/C/tmpl/gdaui-raw-grid.sgml
+++ b/doc/C/tmpl/gdaui-raw-grid.sgml
@@ -2,7 +2,7 @@
 GdauiRawGrid
 
 <!-- ##### SECTION Short_Description ##### -->
-
+Grid widget to manipulate data in a #GdaDataModel
 
 <!-- ##### SECTION Long_Description ##### -->
 <para>
@@ -11,7 +11,8 @@ GdauiRawGrid
 
 <!-- ##### SECTION See_Also ##### -->
 <para>
-
+  The #GdauiGrid widget which uses the #GdauiRawGrid and adds decorations such as
+  information about data model size, and features searching.
 </para>
 
 <!-- ##### SECTION Stability_Level ##### -->
@@ -39,14 +40,6 @@ GdauiRawGrid
 @gdauirawgrid: the object which received the signal.
 @arg1: 
 
-<!-- ##### SIGNAL GdauiRawGrid::selection-changed ##### -->
-<para>
-
-</para>
-
- gdauirawgrid: the object which received the signal.
- arg1: 
-
 <!-- ##### ARG GdauiRawGrid:data-layout ##### -->
 <para>
 
@@ -94,12 +87,13 @@ GdauiRawGrid
 @sample_start: 
 
 
-<!-- ##### FUNCTION gdaui_raw_grid_get_selection ##### -->
+<!-- ##### FUNCTION gdaui_raw_grid_set_data_layout_from_file ##### -->
 <para>
 
 </para>
 
 @grid: 
- Returns: 
+ file_name: 
+ parent_table: 
 
 
diff --git a/doc/C/tmpl/gdaui-server-operation.sgml b/doc/C/tmpl/gdaui-server-operation.sgml
index 930c5d1..1970a30 100644
--- a/doc/C/tmpl/gdaui-server-operation.sgml
+++ b/doc/C/tmpl/gdaui-server-operation.sgml
@@ -2,16 +2,19 @@
 GdauiServerOperation
 
 <!-- ##### SECTION Short_Description ##### -->
-
+Enter information to perform a DDL query
 
 <!-- ##### SECTION Long_Description ##### -->
 <para>
-
+  The #GdauiServerOperation widget allows the user to enter information to perform
+  Data Definition queries (all queries which are not SELECT, INSERT, UPDATE or DELETE).
+  For example the figure shows a #GdauiServerOperation widget set to create an index in an
+  SQLite database.
 </para>
 
 <!-- ##### SECTION See_Also ##### -->
 <para>
-
+  See the #GdaServerOperation which actually holds the information to perform the query.
 </para>
 
 <!-- ##### SECTION Stability_Level ##### -->
@@ -23,7 +26,7 @@ GdauiServerOperation
 </para>
 
 
-<!-- ##### ARG GdauiServerOperation:opt-header ##### -->
+<!-- ##### ARG GdauiServerOperation:hide-single-header ##### -->
 <para>
 
 </para>
diff --git a/doc/C/tmpl/gdaui-tree-store.sgml b/doc/C/tmpl/gdaui-tree-store.sgml
index 5a0c766..51bb8ec 100644
--- a/doc/C/tmpl/gdaui-tree-store.sgml
+++ b/doc/C/tmpl/gdaui-tree-store.sgml
@@ -2,11 +2,12 @@
 GdauiTreeStore
 
 <!-- ##### SECTION Short_Description ##### -->
-
+Bridge between a GdaTree and a GtkTreeModel
 
 <!-- ##### SECTION Long_Description ##### -->
 <para>
-
+  The #GdauiTreeStore implements the #GtkTreeModel interface required
+  to display data from a #GdaTree in a #GtkTreeView widget.
 </para>
 
 <!-- ##### SECTION See_Also ##### -->
diff --git a/doc/C/vi-cloud.png b/doc/C/vi-cloud.png
new file mode 100644
index 0000000..8c7a4bf
Binary files /dev/null and b/doc/C/vi-cloud.png differ
diff --git a/doc/C/vi-filter.png b/doc/C/vi-filter.png
new file mode 100644
index 0000000..a25ee77
Binary files /dev/null and b/doc/C/vi-filter.png differ
diff --git a/doc/C/vi-info.png b/doc/C/vi-info.png
new file mode 100644
index 0000000..ea7c21e
Binary files /dev/null and b/doc/C/vi-info.png differ
diff --git a/doc/C/vi-provider-selector.png b/doc/C/vi-provider-selector.png
new file mode 100644
index 0000000..967c30b
Binary files /dev/null and b/doc/C/vi-provider-selector.png differ
diff --git a/doc/C/vi-raw-grid.png b/doc/C/vi-raw-grid.png
new file mode 100644
index 0000000..f902993
Binary files /dev/null and b/doc/C/vi-raw-grid.png differ
diff --git a/doc/C/vi-server-op.png b/doc/C/vi-server-op.png
new file mode 100644
index 0000000..6f32897
Binary files /dev/null and b/doc/C/vi-server-op.png differ
diff --git a/doc/C/visual_index.xml b/doc/C/visual_index.xml
index bd76fa1..ee6e903 100644
--- a/doc/C/visual_index.xml
+++ b/doc/C/visual_index.xml
@@ -11,4 +11,22 @@
   <link linkend="GdauiLogin">
     <inlinegraphic fileref="vi-login.png" format="PNG"></inlinegraphic>
   </link>
+  <link linkend="GdauiProviderSelector">
+    <inlinegraphic fileref="vi-provider-selector.png" format="PNG"></inlinegraphic>
+  </link>
+  <link linkend="GdauiCloud">
+    <inlinegraphic fileref="vi-cloud.png" format="PNG"></inlinegraphic>
+  </link>
+  <link linkend="GdauiRawGrid">
+    <inlinegraphic fileref="vi-raw-grid.png" format="PNG"></inlinegraphic>
+  </link>
+  <link linkend="GdauiDataProxyInfo">
+    <inlinegraphic fileref="vi-info.png" format="PNG"></inlinegraphic>
+  </link>
+  <link linkend="GdauiDataFilter">
+    <inlinegraphic fileref="vi-filter.png" format="PNG"></inlinegraphic>
+  </link>
+  <link linkend="GdauiServerOperation">
+    <inlinegraphic fileref="vi-server-op.png" format="PNG"></inlinegraphic>
+  </link>
 </para>
diff --git a/libgda-ui/Makefile.am b/libgda-ui/Makefile.am
index 531dccf..93dc834 100644
--- a/libgda-ui/Makefile.am
+++ b/libgda-ui/Makefile.am
@@ -19,9 +19,10 @@ ui_headers = \
 	gdaui-combo.h \
 	gdaui-data-entry.h \
 	gdaui-data-store.h \
-	gdaui-data-widget.h \
-	gdaui-data-widget-filter.h \
-	gdaui-data-widget-info.h \
+	gdaui-data-filter.h \
+	gdaui-data-selector.h \
+	gdaui-data-proxy.h \
+	gdaui-data-proxy-info.h \
 	gdaui-decl.h \
 	gdaui-easy.h \
 	gdaui-enums.h \
@@ -33,7 +34,6 @@ ui_headers = \
 	gdaui-raw-form.h \
 	gdaui-raw-grid.h \
 	gdaui-server-operation.h \
-	gdaui-set.h \
 	gdaui-tree-store.h \
 	gdaui-plugin.h
 
@@ -44,9 +44,10 @@ libgda_ui_4_0_la_SOURCES = \
 	gdaui-combo.c \
 	gdaui-data-entry.c \
 	gdaui-data-store.c \
-	gdaui-data-widget.c \
-	gdaui-data-widget-filter.c \
-	gdaui-data-widget-info.c \
+	gdaui-data-filter.c \
+	gdaui-data-selector.c \
+	gdaui-data-proxy.c \
+	gdaui-data-proxy-info.c \
 	gdaui-form.c \
 	gdaui-grid.c \
 	gdaui-cloud.c \
@@ -55,6 +56,7 @@ libgda_ui_4_0_la_SOURCES = \
 	gdaui-raw-form.c \
 	gdaui-raw-grid.c \
 	gdaui-server-operation.c \
+	gdaui-set.h \
 	gdaui-set.c \
 	gdaui-tree-store.c \
 	gdaui-init.c
diff --git a/libgda-ui/data-entries/gdaui-data-cell-renderer-combo.c b/libgda-ui/data-entries/gdaui-data-cell-renderer-combo.c
index b05c746..6fc6e0d 100644
--- a/libgda-ui/data-entries/gdaui-data-cell-renderer-combo.c
+++ b/libgda-ui/data-entries/gdaui-data-cell-renderer-combo.c
@@ -583,7 +583,7 @@ gdaui_data_cell_renderer_combo_start_editing (GtkCellRenderer     *cell,
 	g_object_set_data_full (G_OBJECT (combo),
 				GDAUI_DATA_CELL_RENDERER_COMBO_PATH,
 				g_strdup (path), g_free);
-	gdaui_combo_add_undef_choice (GDAUI_COMBO (combo),
+	gdaui_combo_add_null (GDAUI_COMBO (combo),
 				      (datacell->priv->attributes & GDA_VALUE_ATTR_CAN_BE_NULL) ? TRUE : FALSE);
 	gtk_widget_show (combo);
 
@@ -615,10 +615,10 @@ gdaui_data_cell_renderer_combo_editing_done (GtkCellEditable *combo, GdauiDataCe
 	if (canceled)
 		return;
 	
-	list = gdaui_combo_get_values_ext (GDAUI_COMBO (combo), 
-					   datacell->priv->source->ref_n_cols, 
-					   datacell->priv->source->ref_cols_index);
-	list_all = gdaui_combo_get_values_ext (GDAUI_COMBO (combo), 0, NULL);
+	list = _gdaui_combo_get_selected_ext (GDAUI_COMBO (combo), 
+					      datacell->priv->source->ref_n_cols, 
+					      datacell->priv->source->ref_cols_index);
+	list_all = _gdaui_combo_get_selected_ext (GDAUI_COMBO (combo), 0, NULL);
 
 	path = g_object_get_data (G_OBJECT (combo), GDAUI_DATA_CELL_RENDERER_COMBO_PATH);
 	g_signal_emit (datacell, text_cell_renderer_combo_signals [CHANGED], 0, path, list, list_all);
diff --git a/libgda-ui/data-entries/gdaui-entry-combo.c b/libgda-ui/data-entries/gdaui-entry-combo.c
index e85e6db..451ba64 100644
--- a/libgda-ui/data-entries/gdaui-entry-combo.c
+++ b/libgda-ui/data-entries/gdaui-entry-combo.c
@@ -294,9 +294,9 @@ void _gdaui_entry_combo_construct (GdauiEntryCombo* combo, GdauiSet *paramlist,
 	gtk_widget_show (entry);
 	combo->priv->combo_entry = entry;
 
-	gdaui_combo_set_values_ext (GDAUI_COMBO (entry), values, NULL);
+	_gdaui_combo_set_selected_ext (GDAUI_COMBO (entry), values, NULL);
 	g_slist_free (values);
-	gdaui_combo_add_undef_choice (GDAUI_COMBO (entry), combo->priv->null_possible);
+	gdaui_combo_add_null (GDAUI_COMBO (entry), combo->priv->null_possible);
 }
 
 static void
@@ -392,7 +392,7 @@ gdaui_entry_combo_get_property (GObject *object,
 static void
 combo_contents_changed_cb (GdauiCombo *entry, GdauiEntryCombo *combo)
 {
-	if (gdaui_combo_undef_selected (GDAUI_COMBO (combo->priv->combo_entry))) /* Set to NULL? */ {
+	if (gdaui_combo_is_null_selected (GDAUI_COMBO (combo->priv->combo_entry))) /* Set to NULL? */ {
 		gdaui_entry_combo_set_values (combo, NULL);
 		gdaui_entry_combo_emit_signal (combo);
 	}
@@ -567,7 +567,7 @@ gdaui_entry_combo_get_all_values (GdauiEntryCombo *combo)
 	g_return_val_if_fail (combo && GDAUI_IS_ENTRY_COMBO (combo), NULL);
 	g_return_val_if_fail (combo->priv, NULL);
 
-	return gdaui_combo_get_values_ext (GDAUI_COMBO (combo->priv->combo_entry), 0, NULL);
+	return _gdaui_combo_get_selected_ext (GDAUI_COMBO (combo->priv->combo_entry), 0, NULL);
 }
 
 /**
@@ -822,7 +822,7 @@ gdaui_entry_combo_set_attributes (GdauiDataEntry *iface, guint attrs, guint mask
 	if (mask & GDA_VALUE_ATTR_CAN_BE_NULL)
 		if (combo->priv->null_possible != (attrs & GDA_VALUE_ATTR_CAN_BE_NULL) ? TRUE : FALSE) {
 			combo->priv->null_possible = (attrs & GDA_VALUE_ATTR_CAN_BE_NULL) ? TRUE : FALSE;
-			gdaui_combo_add_undef_choice (GDAUI_COMBO (combo->priv->combo_entry),
+			gdaui_combo_add_null (GDAUI_COMBO (combo->priv->combo_entry),
 						      combo->priv->null_possible);		 
 		}
 
diff --git a/libgda-ui/data-entries/gdaui-entry-wrapper.c b/libgda-ui/data-entries/gdaui-entry-wrapper.c
index 7fb7887..ae5315e 100644
--- a/libgda-ui/data-entries/gdaui-entry-wrapper.c
+++ b/libgda-ui/data-entries/gdaui-entry-wrapper.c
@@ -529,7 +529,10 @@ gdaui_entry_wrapper_set_value_orig (GdauiDataEntry *iface, const GValue *value)
 		changed = ! mgwrap->priv->real_class->value_is_equal_to (mgwrap, value);
 	else {
 		evalue = gdaui_entry_wrapper_get_value (iface);
-		if (! gda_value_differ ((GValue *) value, evalue))
+		if ((!value || (G_VALUE_TYPE (value) == GDA_TYPE_NULL)) &&
+		    (!evalue || (G_VALUE_TYPE (evalue) == GDA_TYPE_NULL)))
+			changed = FALSE;
+		else if (!gda_value_differ ((GValue *) value, evalue))
 			changed = FALSE;
 		if (evalue)
 			gda_value_free (evalue);
diff --git a/libgda-ui/data-entries/plugins/gdaui-entry-cgrid.c b/libgda-ui/data-entries/plugins/gdaui-entry-cgrid.c
index 18540aa..77455ef 100644
--- a/libgda-ui/data-entries/plugins/gdaui-entry-cgrid.c
+++ b/libgda-ui/data-entries/plugins/gdaui-entry-cgrid.c
@@ -26,7 +26,7 @@
 
 #include <libgda/gda-data-model.h>
 #include <libgda-ui/gdaui-raw-grid.h>
-#include <libgda-ui/gdaui-data-widget.h>
+#include <libgda-ui/gdaui-data-proxy.h>
 
 #include "gdaui-entry-cgrid.h"
 
@@ -574,8 +574,8 @@ gdaui_entry_cgrid_set_model (GdauiEntryCGrid   *cgrid,
 
 	guint i;
 	for (i = 0; i < list_length; ++i) 
-		gdaui_data_widget_column_set_editable (GDAUI_DATA_WIDGET (cgrid->priv->tree_view),
-							  i, FALSE);
+		gdaui_data_proxy_column_set_editable (GDAUI_DATA_PROXY (cgrid->priv->tree_view),
+						      i, FALSE);
 
 	gint grid_height = gda_data_model_get_n_rows ((GdaDataModel  *) model) * get_row_height (cgrid)
 		+ get_header_height (cgrid);
diff --git a/libgda-ui/demos/Makefile.am b/libgda-ui/demos/Makefile.am
index afc8eb3..5074db4 100644
--- a/libgda-ui/demos/Makefile.am
+++ b/libgda-ui/demos/Makefile.am
@@ -24,8 +24,10 @@ demos =						\
 	linked_model_param.c \
 	ddl_queries.c \
 	login.c \
+	provider_sel.c \
 	tree.c \
-	cloud.c
+	cloud.c \
+	combo.c
 
 demofiles = demo_db.db example_automatic_layout.xml
 
diff --git a/libgda-ui/demos/cloud.c b/libgda-ui/demos/cloud.c
index 7acbb64..f3cd3ba 100644
--- a/libgda-ui/demos/cloud.c
+++ b/libgda-ui/demos/cloud.c
@@ -1,4 +1,4 @@
-/* Widgets/Cloud widget
+/* Selector widgets/Cloud widget
  *
  * The GdauiCloud widget displays data stored in a GdaDataModel in a cloud fashion
  */
@@ -20,6 +20,49 @@ mode_changed_cb (GtkToggleButton *button, GdauiCloud *cloud)
 	}
 }
 
+static void
+selection_changed_cb (GdauiDataSelector *selector, gpointer data)
+{
+	GString *string = NULL;
+	GArray *sel;
+	gint i;
+
+	sel = gdaui_data_selector_get_selected_rows (selector);
+	if (sel) {
+		for (i = 0; i < sel->len; i++) {
+			if (!string)
+				string = g_string_new ("");
+			else
+				g_string_append (string, ", ");
+			g_string_append_printf (string, "%d", g_array_index (sel, gint, i));
+		}
+		g_array_free (sel, TRUE);
+	}
+	g_print ("Selection changed: %s\n", string ? string->str: "none");
+}
+
+static void
+force_select (GtkButton *button, GdauiCloud *cloud)
+{
+	GtkEntry *entry;
+	gint row;
+	entry = g_object_get_data (G_OBJECT (button), "entry");
+	row = atoi (gtk_entry_get_text (GTK_ENTRY (entry)));
+	g_print ("Row %d selected: %s\n", row, 
+		 gdaui_data_selector_select_row (GDAUI_DATA_SELECTOR (cloud), row) ? "OK": "Error");
+}
+
+static void
+force_unselect (GtkButton *button, GdauiCloud *cloud)
+{
+	GtkEntry *entry;
+	gint row;
+	entry = g_object_get_data (G_OBJECT (button), "entry");
+	row = atoi (gtk_entry_get_text (GTK_ENTRY (entry)));
+	gdaui_data_selector_unselect_row (GDAUI_DATA_SELECTOR (cloud), row);
+	g_print ("Row %d UNselected\n", row);
+}
+
 GtkWidget *
 do_cloud (GtkWidget *do_widget)
 {  
@@ -52,11 +95,11 @@ do_cloud (GtkWidget *do_widget)
 		gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
 		
 		label = gtk_label_new ("The following GdauiCloud widget displays customers,\n"
-				       "appearing bigger if they made more purshases.");
+				       "appearing bigger if they made more purchases.");
 		gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
 		
 		/* Create the demo widget */
-		stmt = gda_sql_parser_parse_string (demo_parser, "select c.id, c.name, count (o.id) from customers c left join orders o on (c.id=o.customer) group by c.name order by c.name", NULL, NULL);
+		stmt = gda_sql_parser_parse_string (demo_parser, "select c.id, c.name, count (o.id) as weight from customers c left join orders o on (c.id=o.customer) group by c.name order by c.name", NULL, NULL);
 		model = gda_connection_statement_execute_select (demo_cnc, stmt, NULL, NULL);
 		g_object_unref (stmt);
 		cloud = gdaui_cloud_new (model, 1, 2);
@@ -98,6 +141,44 @@ do_cloud (GtkWidget *do_widget)
 		g_object_set_data (G_OBJECT (rb),"mode", GINT_TO_POINTER (GTK_SELECTION_MULTIPLE));
 		g_signal_connect (rb, "toggled",
 				  G_CALLBACK (mode_changed_cb), cloud);
+
+		/* selection */
+		GdaDataModelIter *sel;
+		GtkWidget *form;
+		label = gtk_label_new ("Current selection is:");
+		gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+		sel = gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (cloud));
+		form = gdaui_basic_form_new (GDA_SET (sel));
+		gtk_box_pack_start (GTK_BOX (vbox), form, FALSE, FALSE, 0);
+
+		g_signal_connect (cloud, "selection-changed",
+				  G_CALLBACK (selection_changed_cb), NULL);
+
+		/* force selection */
+		GtkWidget *hbox, *entry, *button;
+		label = gtk_label_new ("Selection forcing:");
+		gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+		hbox = gtk_hbox_new (FALSE, 0);
+		gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+		label = gtk_label_new ("row number:");
+		gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+		entry = gtk_entry_new ();
+		gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
+
+		hbox = gtk_hbox_new (FALSE, 0);
+		gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);		
+		button = gtk_button_new_with_label ("Force select");
+		gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+		g_object_set_data (G_OBJECT (button), "entry", entry);
+		g_signal_connect (button, "clicked",
+				  G_CALLBACK (force_select), cloud);
+		button = gtk_button_new_with_label ("Force UNselect");
+		gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+		g_object_set_data (G_OBJECT (button), "entry", entry);
+		g_signal_connect (button, "clicked",
+				  G_CALLBACK (force_unselect), cloud);
 	}
 
 	gboolean visible;
@@ -111,5 +192,3 @@ do_cloud (GtkWidget *do_widget)
 
 	return window;
 }
-
-
diff --git a/libgda-ui/demos/combo.c b/libgda-ui/demos/combo.c
new file mode 100644
index 0000000..5b40ec0
--- /dev/null
+++ b/libgda-ui/demos/combo.c
@@ -0,0 +1,216 @@
+/* Selector widgets/Combo widget
+ *
+ * The GdauiCombo widget displays data stored in a GdaDataModel in a GtkComboBox
+ */
+
+#include <libgda-ui/libgda-ui.h>
+#include <sql-parser/gda-sql-parser.h>
+
+extern GdaConnection *demo_cnc;
+extern GdaSqlParser *demo_parser;
+static GtkWidget *window = NULL;
+
+static void
+null_entry_changed_cb (GtkCheckButton *cbutton, GdauiCombo *combo)
+{
+	gdaui_combo_add_null (combo, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cbutton)));
+}
+
+static void
+popup_as_list_changed_cb (GtkCheckButton *cbutton, GdauiCombo *combo)
+{
+	g_object_set ((GObject*) combo, "as-list", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cbutton)), NULL);
+}
+
+static void
+column_show_changed_cb (GtkCheckButton *cbutton, GdauiCombo *combo)
+{
+	gint column;
+	column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cbutton), "column"));
+	gdaui_data_selector_set_column_visible (GDAUI_DATA_SELECTOR (combo), column,
+						gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cbutton)));
+	g_print ("Column %d %s\n", column,
+		 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cbutton)) ? "visible" : "invisible");
+}
+
+static void
+selection_changed_cb (GdauiDataSelector *selector, gpointer data)
+{
+	GString *string = NULL;
+	GArray *sel;
+	gint i;
+
+	sel = gdaui_data_selector_get_selected_rows (selector);
+	if (sel) {
+		for (i = 0; i < sel->len; i++) {
+			if (!string)
+				string = g_string_new ("");
+			else
+				g_string_append (string, ", ");
+			g_string_append_printf (string, "%d", g_array_index (sel, gint, i));
+		}
+		g_array_free (sel, TRUE);
+	}
+	g_print ("Selection changed: %s\n", string ? string->str: "none");
+}
+
+static void
+force_select (GtkButton *button, GdauiCombo *combo)
+{
+	GtkEntry *entry;
+	gint row;
+	entry = g_object_get_data (G_OBJECT (button), "entry");
+	row = atoi (gtk_entry_get_text (GTK_ENTRY (entry)));
+	g_print ("Row %d selected: %s\n", row, 
+		 gdaui_data_selector_select_row (GDAUI_DATA_SELECTOR (combo), row) ? "OK": "Error");
+}
+
+static void
+force_unselect (GtkButton *button, GdauiCombo *combo)
+{
+	GtkEntry *entry;
+	gint row;
+	entry = g_object_get_data (G_OBJECT (button), "entry");
+	row = atoi (gtk_entry_get_text (GTK_ENTRY (entry)));
+	gdaui_data_selector_unselect_row (GDAUI_DATA_SELECTOR (combo), row);
+	g_print ("Row %d UNselected\n", row);
+}
+
+GtkWidget *
+do_combo (GtkWidget *do_widget)
+{  
+	if (!window) {
+                GdaStatement *stmt;
+		GtkWidget *vbox;
+		GtkWidget *label;
+		GdaDataModel *model;
+		GtkWidget *combo;
+		
+		window = gtk_dialog_new_with_buttons ("GdauiCombo",
+						      GTK_WINDOW (do_widget),
+						      0,
+						      GTK_STOCK_CLOSE,
+						      GTK_RESPONSE_NONE,
+						      NULL);
+		
+		g_signal_connect (window, "response",
+				  G_CALLBACK (gtk_widget_destroy), NULL);
+		g_signal_connect (window, "destroy",
+				  G_CALLBACK (gtk_widget_destroyed), &window);
+		
+		vbox = gtk_vbox_new (FALSE, 5);
+#if GTK_CHECK_VERSION(2,18,0)
+		gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (window))),
+				    vbox, TRUE, TRUE, 0);
+#else
+		gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), vbox, TRUE, TRUE, 0);
+#endif
+		gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
+		
+		label = gtk_label_new ("The following GdauiCombo widget displays customers");
+		gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+		
+		/* Create the demo widget */
+		gint cols_index[] = {1};
+		stmt = gda_sql_parser_parse_string (demo_parser, "select c.id, c.name, count (o.id) as weight from customers c left join orders o on (c.id=o.customer) group by c.name order by c.name", NULL, NULL);
+		model = gda_connection_statement_execute_select (demo_cnc, stmt, NULL, NULL);
+		g_object_unref (stmt);
+		combo = gdaui_combo_new_with_model (model, 1, cols_index);
+		g_object_unref (model);
+
+		gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
+
+		/* options */
+		GtkWidget *option;
+
+		label = gtk_label_new ("");
+		gtk_label_set_markup (GTK_LABEL (label), "<b>Options:</b>");
+		gtk_misc_set_alignment (GTK_MISC (label), 0., -1);
+		gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+		option = gtk_check_button_new_with_label ("Add NULL entry");
+		gtk_box_pack_start (GTK_BOX (vbox), option, FALSE, FALSE, 0);
+		g_signal_connect (option, "toggled",
+				  G_CALLBACK (null_entry_changed_cb), combo);
+		
+		option = gtk_check_button_new_with_label ("Popup as list");
+		gtk_box_pack_start (GTK_BOX (vbox), option, FALSE, FALSE, 0);
+		g_signal_connect (option, "toggled",
+				  G_CALLBACK (popup_as_list_changed_cb), combo);
+		
+
+		/* selection */
+		GdaDataModelIter *sel;
+		GtkWidget *form;
+		label = gtk_label_new ("");
+		gtk_label_set_markup (GTK_LABEL (label), "<b>Current selection is:</b>");
+		gtk_misc_set_alignment (GTK_MISC (label), 0., -1);
+		gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+		sel = gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (combo));
+		form = gdaui_basic_form_new (GDA_SET (sel));
+		gtk_box_pack_start (GTK_BOX (vbox), form, FALSE, FALSE, 0);
+
+		g_signal_connect (combo, "selection-changed",
+				  G_CALLBACK (selection_changed_cb), NULL);
+
+		/* force selection */
+		GtkWidget *hbox, *entry, *button;
+		label = gtk_label_new ("");
+		gtk_label_set_markup (GTK_LABEL (label), "<b>Selection forcing:</b>");
+		gtk_misc_set_alignment (GTK_MISC (label), 0., -1);
+		gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+		hbox = gtk_hbox_new (FALSE, 0);
+		gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+		label = gtk_label_new ("row number:");
+		gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+		entry = gtk_entry_new ();
+		gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
+
+		hbox = gtk_hbox_new (FALSE, 0);
+		gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);		
+		button = gtk_button_new_with_label ("Force select");
+		gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+		g_object_set_data (G_OBJECT (button), "entry", entry);
+		g_signal_connect (button, "clicked",
+				  G_CALLBACK (force_select), combo);
+		button = gtk_button_new_with_label ("Force UNselect");
+		gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+		g_object_set_data (G_OBJECT (button), "entry", entry);
+		g_signal_connect (button, "clicked",
+				  G_CALLBACK (force_unselect), combo);
+
+		/* show/hide columns */
+		gint i, ncols;
+		label = gtk_label_new ("");
+		gtk_label_set_markup (GTK_LABEL (label), "<b>Show columns:</b>");
+		gtk_misc_set_alignment (GTK_MISC (label), 0., -1);
+		gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+		ncols = gda_data_model_get_n_columns (model);
+		for (i = 0; i < ncols; i++) {
+			gchar *str;
+			str = g_strdup_printf ("Column %d", i);
+			option = gtk_check_button_new_with_label (str);
+			g_free (str);
+			gtk_box_pack_start (GTK_BOX (vbox), option, FALSE, FALSE, 0);
+			g_object_set_data (G_OBJECT (option), "column", GINT_TO_POINTER (i));
+			if (i == 1)
+				gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (option), TRUE);
+			g_signal_connect (option, "toggled",
+					  G_CALLBACK (column_show_changed_cb), combo);
+		}
+	}
+
+	gboolean visible;
+	g_object_get (G_OBJECT (window), "visible", &visible, NULL);
+	if (!visible)
+		gtk_widget_show_all (window);
+	else {
+		gtk_widget_destroy (window);
+		window = NULL;
+	}
+
+	return window;
+}
+
diff --git a/libgda-ui/demos/data_model_dir.c b/libgda-ui/demos/data_model_dir.c
index 579db9e..8aba369 100644
--- a/libgda-ui/demos/data_model_dir.c
+++ b/libgda-ui/demos/data_model_dir.c
@@ -43,7 +43,6 @@ do_data_model_dir (GtkWidget *do_widget)
 		GtkWidget *label;
 		GdaDataModel *model;
 		GtkWidget *form, *grid, *nb;
-		GdauiRawForm *raw;
 		GdaSet *data_set;
 		GdaHolder *param;
 		gchar *path;
@@ -93,21 +92,12 @@ do_data_model_dir (GtkWidget *do_widget)
 		g_object_unref (model);
 
 		/* specify that we want to use the 'picture' plugin */
-		g_object_get (G_OBJECT (form), "raw_form", &raw, NULL);
-		data_set = gdaui_basic_form_get_data_set (GDAUI_BASIC_FORM (raw));
+		data_set = GDA_SET (gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (grid)));
 		param = gda_set_get_holder (data_set, "data");
 
 		value = gda_value_new_from_string ("picture", G_TYPE_STRING);
 		gda_holder_set_attribute_static (param, GDAUI_ATTRIBUTE_PLUGIN, value);
-		gdaui_data_widget_column_show_actions (GDAUI_DATA_WIDGET (raw), -1, TRUE);
-
-		g_object_get (G_OBJECT (grid), "raw_grid", &raw, NULL);
-		data_set = GDA_SET (gdaui_data_widget_get_current_data (GDAUI_DATA_WIDGET (raw)));
-		param = gda_set_get_holder (data_set, "data");
-
-		gda_holder_set_attribute_static (param, GDAUI_ATTRIBUTE_PLUGIN, value);
-		gdaui_data_widget_column_show_actions (GDAUI_DATA_WIDGET (raw), -1, TRUE);
-
+		gdaui_data_proxy_column_show_actions (GDAUI_DATA_PROXY (grid), -1, TRUE);
 		gda_value_free (value);
 	}
 
diff --git a/libgda-ui/demos/ddl_queries.c b/libgda-ui/demos/ddl_queries.c
index dd99b09..90788c8 100644
--- a/libgda-ui/demos/ddl_queries.c
+++ b/libgda-ui/demos/ddl_queries.c
@@ -1,4 +1,4 @@
-/* DDL queries
+/* Widgets/DDL queries
  *
  * A DDL query is a query defining or modifying a database structure and properties.
  * In Libgda, each type of DDL query corresponds to an "operation".
@@ -175,7 +175,7 @@ update_possible_operations (DemoData *data)
 	GdaServerOperationType type;
 	GdaDataModel *model;
 	
-	model = gdaui_combo_get_model (GDAUI_COMBO (data->op_combo));
+	model = gdaui_data_selector_get_model (GDAUI_DATA_SELECTOR (data->op_combo));
 	if (!model) {
 		gint columns[] = {1};
 		model = gda_data_model_array_new_with_g_types (2, G_TYPE_INT, G_TYPE_STRING);
@@ -230,8 +230,8 @@ tested_operation_changed_cb (GdauiCombo *combo, DemoData *data)
 	GdaServerProvider *prov = NULL;
 	GdaServerOperationType type;
 	GError *error = NULL;
-	GSList *combo_values;
-	gint columns[] = {0};
+	GdaDataModelIter *iter;
+	const GValue *cvalue = NULL;
 
 	if (data->op) {
 		g_object_unref (data->op);
@@ -243,8 +243,10 @@ tested_operation_changed_cb (GdauiCombo *combo, DemoData *data)
 	gtk_widget_set_sensitive (data->show_button, FALSE);
 	gtk_widget_set_sensitive (data->sql_button, FALSE);
 
-	combo_values = gdaui_combo_get_values_ext (GDAUI_COMBO (data->op_combo), 1, columns);
-	if (!combo_values || !gda_value_isa ((GValue *) (combo_values->data), G_TYPE_INT)) {
+	iter = gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (data->op_combo));
+	if (iter)
+		cvalue = gda_data_model_iter_get_value_at (iter, 0);
+	if (!cvalue || !gda_value_isa ((GValue *) cvalue, G_TYPE_INT)) {
 		GtkWidget *label;
 
 		label = gtk_label_new ("Select an operation to perform");
@@ -253,8 +255,7 @@ tested_operation_changed_cb (GdauiCombo *combo, DemoData *data)
 		gtk_widget_show (data->op_form);
 		return;
 	}
-	type = g_value_get_int ((GValue *) (combo_values->data));
-	g_slist_free (combo_values);
+	type = g_value_get_int ((GValue *) cvalue);
 	
 	prov = get_provider_obj (data);
 	if (prov)
@@ -418,9 +419,9 @@ show_named_parameters (GtkButton *button, DemoData *data)
 	gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
 #if GTK_CHECK_VERSION(2,18,0)
 		gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
-				    label, TRUE, TRUE, 0);
+				    label, FALSE, FALSE, 0);
 #else
-		gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), label, TRUE, TRUE, 0);
+		gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), label, FALSE, FALSE, 0);
 #endif
 	gtk_widget_show (label);
 	
@@ -488,7 +489,7 @@ show_sql (GtkButton *button, DemoData *data)
 
 		dlg = gtk_message_dialog_new_with_markup (GTK_WINDOW (data->top_window),
 							  GTK_DIALOG_MODAL,
-							  msg_type, GTK_BUTTONS_CLOSE, "%s", msg);
+							  msg_type, GTK_BUTTONS_CLOSE, msg);
 		g_free (sql);
 		g_free (msg);
 
diff --git a/libgda-ui/demos/form_data_layout.c b/libgda-ui/demos/form_data_layout.c
index 326c518..c58cda8 100644
--- a/libgda-ui/demos/form_data_layout.c
+++ b/libgda-ui/demos/form_data_layout.c
@@ -22,9 +22,6 @@ do_form_data_layout (GtkWidget *do_widget)
 		GdaDataModel *model;
 		GtkWidget *form;
 		GdauiRawForm *raw_form;
-		GdaSet *data_set;
-		GdaHolder *param;
-		GValue *value;
 		
 		window = gtk_dialog_new_with_buttons ("Form with automatic 'data_layout'",
 						      GTK_WINDOW (do_widget),
@@ -66,11 +63,10 @@ do_form_data_layout (GtkWidget *do_widget)
 		form = gdaui_form_new (model);
 		g_object_unref (model);
 
-		g_object_get (G_OBJECT (form), "raw_form", &raw_form, NULL);
+		g_object_get (G_OBJECT (form), "raw-form", &raw_form, NULL);
 		gchar *filename;
 		filename = demo_find_file ("example_automatic_layout.xml", NULL);
-		gdaui_data_widget_set_data_layout_from_file (GDAUI_DATA_WIDGET (raw_form),
-							     filename, "products");
+		gdaui_basic_form_set_data_layout_from_file (GDAUI_BASIC_FORM (raw_form), filename, "products");
 		g_free (filename);
 
 		gtk_box_pack_start (GTK_BOX (vbox), form, TRUE, TRUE, 0);
diff --git a/libgda-ui/demos/form_pict.c b/libgda-ui/demos/form_pict.c
index 8070cb8..e4cc1f2 100644
--- a/libgda-ui/demos/form_pict.c
+++ b/libgda-ui/demos/form_pict.c
@@ -20,7 +20,6 @@ do_form_pict (GtkWidget *do_widget)
 		GtkWidget *label;
 		GdaDataModel *model;
 		GtkWidget *form;
-		GdauiRawForm *raw_form;
 		GdaSet *data_set;
 		GdaHolder *param;
 		GValue *value;
@@ -59,19 +58,19 @@ do_form_pict (GtkWidget *do_widget)
 		gda_data_select_compute_modification_statements (GDA_DATA_SELECT (model), NULL);
 		form = gdaui_form_new (model);
 		g_object_unref (model);
+		g_object_set (G_OBJECT (form), "info-flags",
+			      GDAUI_DATA_PROXY_INFO_CURRENT_ROW |
+			      GDAUI_DATA_PROXY_INFO_ROW_MOVE_BUTTONS |
+			      GDAUI_DATA_PROXY_INFO_ROW_MODIFY_BUTTONS, NULL);
 
 		/* specify that we want to use the 'picture' plugin */
-		g_object_get (G_OBJECT (form), "raw_form", &raw_form, NULL);
-		data_set = gdaui_basic_form_get_data_set (GDAUI_BASIC_FORM (raw_form));
+		data_set = GDA_SET (gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (form)));
 		param = gda_set_get_holder (data_set, "pict");
-
 		value = gda_value_new_from_string ("picture", G_TYPE_STRING);
 		gda_holder_set_attribute_static (param, GDAUI_ATTRIBUTE_PLUGIN, value);
 		gda_value_free (value);
 
 		gtk_box_pack_start (GTK_BOX (vbox), form, TRUE, TRUE, 0);
-
-		gtk_widget_set_size_request (window, 500, 500);
 	}
 
 	gboolean visible;
diff --git a/libgda-ui/demos/form_rw.c b/libgda-ui/demos/form_rw.c
index 858f0b1..aa15f9c 100644
--- a/libgda-ui/demos/form_rw.c
+++ b/libgda-ui/demos/form_rw.c
@@ -58,6 +58,10 @@ do_form_rw (GtkWidget *do_widget)
 		}
 		form = gdaui_form_new (model);
 		g_object_unref (model);
+		g_object_set (G_OBJECT (form), "info-flags",
+			      GDAUI_DATA_PROXY_INFO_CURRENT_ROW |
+			      GDAUI_DATA_PROXY_INFO_ROW_MOVE_BUTTONS |
+			      GDAUI_DATA_PROXY_INFO_ROW_MODIFY_BUTTONS, NULL);
 
 		gtk_box_pack_start (GTK_BOX (vbox), form, TRUE, TRUE, 0);
 	}
diff --git a/libgda-ui/demos/grid.c b/libgda-ui/demos/grid.c
index 2fa6418..69fe21f 100644
--- a/libgda-ui/demos/grid.c
+++ b/libgda-ui/demos/grid.c
@@ -51,6 +51,9 @@ do_grid (GtkWidget *do_widget)
 		g_object_unref (stmt);
 		grid = gdaui_grid_new (model);
 		g_object_unref (model);
+		gdaui_grid_set_sample_size (GDAUI_GRID (grid), 100);
+		g_object_set (G_OBJECT (grid), "info-flags",
+			      GDAUI_DATA_PROXY_INFO_CURRENT_ROW | GDAUI_DATA_PROXY_INFO_CHUNCK_CHANGE_BUTTONS, NULL);
 
 		gtk_box_pack_start (GTK_BOX (vbox), grid, TRUE, TRUE, 0);
 	}
diff --git a/libgda-ui/demos/grid_data_layout.c b/libgda-ui/demos/grid_data_layout.c
index bb40140..c8f0891 100644
--- a/libgda-ui/demos/grid_data_layout.c
+++ b/libgda-ui/demos/grid_data_layout.c
@@ -22,9 +22,6 @@ do_grid_data_layout (GtkWidget *do_widget)
 		GdaDataModel *model;
 		GtkWidget *grid;
 		GdauiRawGrid *raw_grid;
-		GdaSet *data_set;
-		GdaHolder *param;
-		GValue *value;
 		
 		window = gtk_dialog_new_with_buttons ("Grid with the automatic 'data_layout'",
 						      GTK_WINDOW (do_widget),
@@ -63,7 +60,7 @@ do_grid_data_layout (GtkWidget *do_widget)
 		g_object_unref (model);
 
 		/* specify that we want to use the 'data_layout' plugin */
-		g_object_get (G_OBJECT (grid), "raw_grid", &raw_grid, NULL);
+		g_object_get (G_OBJECT (grid), "raw-grid", &raw_grid, NULL);
 		/* data_set = GDA_SET (gdaui_data_widget_get_current_data (GDAUI_DATA_WIDGET (raw_grid))); */
 		/* param = gda_set_get_holder (data_set, "pict"); */
 
@@ -79,10 +76,8 @@ do_grid_data_layout (GtkWidget *do_widget)
 		//
 		gchar *filename;
 		filename = demo_find_file ("example_automatic_layout.xml", NULL);
-		gdaui_data_widget_set_data_layout_from_file (GDAUI_DATA_WIDGET (raw_grid),
-							     filename, "products");
+		gdaui_raw_grid_set_data_layout_from_file (GDAUI_RAW_GRID (raw_grid), filename, "products");
 		g_free (filename);
-		//
 
 		gtk_box_pack_start (GTK_BOX (vbox), grid, TRUE, TRUE, 0);
 
diff --git a/libgda-ui/demos/grid_pict.c b/libgda-ui/demos/grid_pict.c
index 4b77a45..3eb305b 100644
--- a/libgda-ui/demos/grid_pict.c
+++ b/libgda-ui/demos/grid_pict.c
@@ -20,7 +20,6 @@ do_grid_pict (GtkWidget *do_widget)
 		GtkWidget *label;
 		GdaDataModel *model;
 		GtkWidget *grid;
-		GdauiRawGrid *raw_grid;
 		GdaSet *data_set;
 		GdaHolder *param;
 		GValue *value;
@@ -59,12 +58,12 @@ do_grid_pict (GtkWidget *do_widget)
                 gda_data_select_compute_modification_statements (GDA_DATA_SELECT (model), NULL);
 		grid = gdaui_grid_new (model);
 		g_object_unref (model);
+		g_object_set (G_OBJECT (grid), "info-flags",
+			      GDAUI_DATA_PROXY_INFO_CURRENT_ROW | GDAUI_DATA_PROXY_INFO_ROW_MODIFY_BUTTONS, NULL);
 
 		/* specify that we want to use the 'picture' plugin */
-		g_object_get (G_OBJECT (grid), "raw_grid", &raw_grid, NULL);
-		data_set = GDA_SET (gdaui_data_widget_get_current_data (GDAUI_DATA_WIDGET (raw_grid)));
+		data_set = GDA_SET (gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (grid)));
 		param = gda_set_get_holder (data_set, "pict");
-
 		value = gda_value_new_from_string ("picture", G_TYPE_STRING);
 		gda_holder_set_attribute_static (param, GDAUI_ATTRIBUTE_PLUGIN, value);
 		gda_value_free (value);
diff --git a/libgda-ui/demos/grid_rw.c b/libgda-ui/demos/grid_rw.c
index 9303957..459d417 100644
--- a/libgda-ui/demos/grid_rw.c
+++ b/libgda-ui/demos/grid_rw.c
@@ -53,6 +53,8 @@ do_grid_rw (GtkWidget *do_widget)
 		gda_data_select_compute_modification_statements (GDA_DATA_SELECT (model), NULL);
 		grid = gdaui_grid_new (model);
 		g_object_unref (model);
+		g_object_set (G_OBJECT (grid), "info-flags",
+			      GDAUI_DATA_PROXY_INFO_CURRENT_ROW | GDAUI_DATA_PROXY_INFO_ROW_MODIFY_BUTTONS, NULL);
 
 		gtk_box_pack_start (GTK_BOX (vbox), grid, TRUE, TRUE, 0);
 	}
diff --git a/libgda-ui/demos/linked_grid_form.c b/libgda-ui/demos/linked_grid_form.c
index e15886e..df1eb8f 100644
--- a/libgda-ui/demos/linked_grid_form.c
+++ b/libgda-ui/demos/linked_grid_form.c
@@ -18,12 +18,12 @@ typedef struct {
 } DemoData;
 
 static void
-restrict_default_served_by_field (GdauiDataWidget *data_widget, GdaDataModel *restrict_with, gint restrict_col)
+restrict_default_served_by_field (GdauiDataSelector *selector, GdaDataModel *restrict_with, gint restrict_col)
 {
 	GdaDataModelIter *iter;
 	GdaHolder *param;
 
-	iter = gdaui_data_widget_get_current_data (data_widget);
+	iter = gdaui_data_selector_get_data_set (selector);
 	param = GDA_HOLDER (g_slist_nth_data (GDA_SET (iter)->holders, 2));
 
 	g_assert (gda_holder_set_source_model (param, restrict_with, restrict_col, NULL));
@@ -71,8 +71,6 @@ do_linked_grid_form (GtkWidget *do_widget)
 		GtkWidget *cb;		
 		GdaDataModel *cust_model, *sr_model;
 		GtkWidget *form, *grid;
-		GdauiRawGrid *raw_grid;
-		GdauiRawForm *raw_form;
 		GdaDataProxy *proxy;
 		DemoData *data;
 
@@ -130,9 +128,8 @@ do_linked_grid_form (GtkWidget *do_widget)
 		gtk_widget_show (grid);
 
 		/* restrict the c.default_served_by field in the grid to be within the sr_model */
-		g_object_get (G_OBJECT (grid), "raw_grid", &raw_grid, NULL);
-		restrict_default_served_by_field (GDAUI_DATA_WIDGET (raw_grid), sr_model, 0);
-		data->grid_iter = gdaui_data_widget_get_current_data (GDAUI_DATA_WIDGET (raw_grid));
+		restrict_default_served_by_field (GDAUI_DATA_SELECTOR (grid), sr_model, 0);
+		data->grid_iter = gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (grid));
 		g_signal_connect (data->grid_iter, "row_changed",
 				  G_CALLBACK (iter_row_changed_cb), data);
 
@@ -143,15 +140,14 @@ do_linked_grid_form (GtkWidget *do_widget)
 		gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
 		gtk_widget_show (label);
 
-		proxy = gdaui_data_widget_get_proxy (GDAUI_DATA_WIDGET (raw_grid));
+		proxy = gdaui_data_proxy_get_proxy (GDAUI_DATA_PROXY (grid));
 		form = gdaui_form_new (GDA_DATA_MODEL (proxy));
 		gtk_box_pack_start (GTK_BOX (vbox), form, TRUE, TRUE, 0);
 		gtk_widget_show (form);
 
 		/* restrict the c.default_served_by field in the form to be within the sr_model */
-		g_object_get (G_OBJECT (form), "raw_form", &raw_form, NULL);
-		restrict_default_served_by_field (GDAUI_DATA_WIDGET (raw_form), sr_model, 0);
-		data->form_iter = gdaui_data_widget_get_current_data (GDAUI_DATA_WIDGET (raw_form));
+		restrict_default_served_by_field (GDAUI_DATA_SELECTOR (form), sr_model, 0);
+		data->form_iter = gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (form));
 		g_signal_connect (data->form_iter, "row_changed",
 				  G_CALLBACK (iter_row_changed_cb), data);
 
diff --git a/libgda-ui/demos/login.c b/libgda-ui/demos/login.c
index 9a78001..d52eb96 100644
--- a/libgda-ui/demos/login.c
+++ b/libgda-ui/demos/login.c
@@ -1,4 +1,4 @@
-/* Widgets/Login widget
+/* Widgets/Login
  *
  * The GdauiLogin widget displays information required to open a connection
  */
diff --git a/libgda-ui/demos/main.c b/libgda-ui/demos/main.c
index 423a1b2..7fea550 100644
--- a/libgda-ui/demos/main.c
+++ b/libgda-ui/demos/main.c
@@ -795,7 +795,7 @@ main (int argc, char **argv)
 		demo_parser = gda_sql_parser_new ();
 
 	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-	gtk_window_set_title (GTK_WINDOW (window), _("Gnome-Db Code Demos"));
+	gtk_window_set_title (GTK_WINDOW (window), _("Libgda-ui Code Demos"));
 	g_signal_connect (window, "destroy",
 			  G_CALLBACK (gtk_main_quit), NULL);
 
diff --git a/libgda-ui/demos/provider_sel.c b/libgda-ui/demos/provider_sel.c
new file mode 100644
index 0000000..5a9d5fd
--- /dev/null
+++ b/libgda-ui/demos/provider_sel.c
@@ -0,0 +1,64 @@
+/* Widgets/Provider selector
+ *
+ * The GdauiProviderSelector widget allows the user to select a database pvodier
+ * among the ones detected when Libgda has been initialized
+ */
+
+#include <libgda-ui/libgda-ui.h>
+
+static GtkWidget *window = NULL;
+
+static void
+selection_changed_cb (GdauiProviderSelector *psel, gpointer data)
+{
+	g_print ("Provider selected: %s\n", gdaui_provider_selector_get_provider (psel));
+}
+
+GtkWidget *
+do_provider_sel (GtkWidget *do_widget)
+{  
+	if (!window) {
+		GtkWidget *vbox, *psel, *label;
+
+		window = gtk_dialog_new_with_buttons ("GdauiProviderSelector",
+						      GTK_WINDOW (do_widget),
+						      0,
+						      GTK_STOCK_CLOSE,
+						      GTK_RESPONSE_NONE,
+						      NULL);
+		gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
+		g_signal_connect (window, "response",
+				  G_CALLBACK (gtk_widget_destroy), NULL);
+		g_signal_connect (window, "destroy",
+				  G_CALLBACK (gtk_widget_destroyed), &window);
+		
+
+#if GTK_CHECK_VERSION(2,18,0)
+		vbox = gtk_dialog_get_content_area (GTK_DIALOG (window));
+#else
+		vbox = GTK_DIALOG (window)->vbox;
+#endif
+
+		/* Create the widget */
+		label = gtk_label_new ("Provider selector:");
+		gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+		psel = gdaui_provider_selector_new ();
+		gtk_box_pack_start (GTK_BOX (vbox), psel, FALSE, FALSE, 0);
+		g_signal_connect (psel, "selection-changed",
+				  G_CALLBACK (selection_changed_cb), NULL);
+	}
+
+	gboolean visible;
+	g_object_get (G_OBJECT (window), "visible", &visible, NULL);
+	if (!visible)
+		gtk_widget_show_all (window);
+	else {
+		gtk_widget_destroy (window);
+		window = NULL;
+	}
+
+	return window;
+}
+
+
diff --git a/libgda-ui/gdaui-basic-form.c b/libgda-ui/gdaui-basic-form.c
index 9d3d5f3..8abaa02 100644
--- a/libgda-ui/gdaui-basic-form.c
+++ b/libgda-ui/gdaui-basic-form.c
@@ -27,9 +27,11 @@
 #include "internal/utility.h"
 #include "gdaui-data-entry.h"
 #include <libgda-ui/data-entries/gdaui-entry-combo.h>
-#include <libgda-ui/gdaui-data-widget.h>
+#include <libgda-ui/gdaui-data-proxy.h>
+#include <libgda-ui/gdaui-data-selector.h>
 #include <libgda-ui/gdaui-raw-form.h>
 #include <libgda-ui/gdaui-easy.h>
+#include <libgda/binreloc/gda-binreloc.h>
 
 static void gdaui_basic_form_class_init (GdauiBasicFormClass * class);
 static void gdaui_basic_form_init (GdauiBasicForm *wid);
@@ -51,7 +53,7 @@ static void gdaui_basic_form_set_entries_auto_default (GdauiBasicForm *form, gbo
 
 static void get_rid_of_set (GdaSet *paramlist, GdauiBasicForm *form);
 static void paramlist_public_data_changed_cb (GdauiSet *paramlist, GdauiBasicForm *form);
-static void paramlist_param_attr_changed_cb (GdaSet *paramlist, GdaHolder *param, 
+static void paramlist_param_attr_changed_cb (GdaSet *paramlist, GdaHolder *param,
 					     const gchar *att_name, const GValue *att_value, GdauiBasicForm *form);
 
 static void entry_contents_modified (GdauiDataEntry *entry, GdauiBasicForm *form);
@@ -62,6 +64,7 @@ static void mark_not_null_entry_labels (GdauiBasicForm *form, gboolean show_mark
 enum {
 	HOLDER_CHANGED,
 	ACTIVATED,
+	LAYOUT_CHANGED,
 	LAST_SIGNAL
 };
 
@@ -124,8 +127,8 @@ gdaui_basic_form_get_type (void)
 			sizeof (GdauiBasicForm),
 			0,
 			(GInstanceInitFunc) gdaui_basic_form_init
-		};		
-		
+		};
+
 		type = g_type_register_static (GTK_TYPE_VBOX, "GdauiBasicForm", &info, 0);
 	}
 
@@ -136,7 +139,7 @@ static void
 gdaui_basic_form_class_init (GdauiBasicFormClass * class)
 {
 	GObjectClass   *object_class = G_OBJECT_CLASS (class);
-	
+
 	parent_class = g_type_class_peek_parent (class);
 
 	/* signals */
@@ -171,40 +174,55 @@ gdaui_basic_form_class_init (GdauiBasicFormClass * class)
 			      NULL, NULL,
 			      _gdaui_marshal_VOID__VOID, G_TYPE_NONE, 0);
 
+	/**
+	 * GdauiBasicForm::layout-changed:
+	 * @form: GdauiBasicForm
+	 *
+	 * Emitted when the form's layout changes
+	 */
+	gdaui_basic_form_signals[LAYOUT_CHANGED] =
+		g_signal_new ("layout-changed",
+			      G_TYPE_FROM_CLASS (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (GdauiBasicFormClass, layout_changed),
+			      NULL, NULL,
+			      _gdaui_marshal_VOID__VOID, G_TYPE_NONE, 0);
+
 	class->holder_changed = NULL;
 	class->activated = NULL;
+	class->layout_changed = NULL;
 	object_class->dispose = gdaui_basic_form_dispose;
 
 	/* Properties */
         object_class->set_property = gdaui_basic_form_set_property;
         object_class->get_property = gdaui_basic_form_get_property;
-	
+
 	g_object_class_install_property (object_class, PROP_DATA_LAYOUT,
-					 g_param_spec_pointer ("data-layout", 
+					 g_param_spec_pointer ("data-layout",
 							       _("Pointer to an XML data layout specification"), NULL,
 							       G_PARAM_WRITABLE));
 	g_object_class_install_property (object_class, PROP_PARAMLIST,
-					 g_param_spec_pointer ("paramlist", 
+					 g_param_spec_pointer ("paramlist",
 							       _("List of parameters to show in the form"), NULL,
                                                                G_PARAM_READABLE | G_PARAM_WRITABLE));
 	g_object_class_install_property (object_class, PROP_HEADERS_SENSITIVE,
 					 g_param_spec_boolean ("headers-sensitive",
-							       _("Entry headers are sensitive"), 
+							       _("Entry headers are sensitive"),
 							       NULL, FALSE,
 							       G_PARAM_READABLE | G_PARAM_WRITABLE));
 	g_object_class_install_property (object_class, PROP_SHOW_ACTIONS,
 					 g_param_spec_boolean ("show-actions",
-							       _("Show Entry actions"), 
+							       _("Show Entry actions"),
 							       NULL, FALSE,
 							       G_PARAM_READABLE | G_PARAM_WRITABLE));
 	g_object_class_install_property (object_class, PROP_ENTRIES_AUTO_DEFAULT,
 					 g_param_spec_boolean ("entries-auto-default",
-							       _("Entries Auto-default"), 
+							       _("Entries Auto-default"),
 							       NULL, FALSE,
 							       G_PARAM_READABLE | G_PARAM_WRITABLE));
 	g_object_class_install_property (object_class, PROP_CAN_EXPAND,
 					 g_param_spec_boolean ("can-expand",
-							       _("TRUE if expanding the form makes sense"), 
+							       _("TRUE if expanding the form makes sense"),
 							       NULL, FALSE,
 							       G_PARAM_READABLE));
 
@@ -263,7 +281,7 @@ widget_shown_cb (GtkWidget *wid, GdauiBasicForm *form)
 			gint row = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (wid), "row_no"));
 			gtk_table_set_row_spacing (GTK_TABLE (form->priv->entries_table), row, 0);
 		}
-		
+
 		gtk_widget_hide (wid);
 	}
 }
@@ -310,10 +328,11 @@ paramlist_public_data_changed_cb (GdauiSet *paramlist, GdauiBasicForm *form)
 	/* here we want to re-define all the data entry widgets */
 	gdaui_basic_form_clean (form);
 	gdaui_basic_form_fill (form);
+	g_signal_emit (G_OBJECT (form), gdaui_basic_form_signals[LAYOUT_CHANGED], 0);
 }
 
 static void
-paramlist_param_attr_changed_cb (GdaSet *paramlist, GdaHolder *param, 
+paramlist_param_attr_changed_cb (GdaSet *paramlist, GdaHolder *param,
 				 const gchar *att_name, const GValue *att_value, GdauiBasicForm *form)
 {
 	GtkWidget *entry;
@@ -325,21 +344,21 @@ paramlist_param_attr_changed_cb (GdaSet *paramlist, GdaHolder *param,
 			guint mask = 0;
 			const GValue *defv;
 			gboolean toset;
-			
+
 			defv = gda_holder_get_default_value (param);
 			attrs |= defv ? GDA_VALUE_ATTR_CAN_BE_DEFAULT : 0;
 			mask |= GDA_VALUE_ATTR_CAN_BE_DEFAULT;
-			
+
 			toset = gda_holder_get_not_null (param);
 			attrs |= toset ? 0 : GDA_VALUE_ATTR_CAN_BE_NULL;
 			mask |= GDA_VALUE_ATTR_CAN_BE_NULL;
-			
+
 			defv = gda_holder_get_attribute (param, GDA_ATTRIBUTE_IS_DEFAULT);
 			if (defv && (G_VALUE_TYPE (defv) == G_TYPE_BOOLEAN) && g_value_get_boolean (defv)) {
 				attrs |= GDA_VALUE_ATTR_IS_DEFAULT;
 				mask |= GDA_VALUE_ATTR_IS_DEFAULT;
 			}
-			
+
 			g_signal_handlers_block_by_func (G_OBJECT (entry),
 							 G_CALLBACK (entry_contents_modified), form);
 			gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (entry), attrs, mask);
@@ -368,7 +387,7 @@ paramlist_param_attr_changed_cb (GdaSet *paramlist, GdaHolder *param,
 		paramlist_public_data_changed_cb (form->priv->set_info, form);
 
 		/* hide entries which were hidden */
-		for (list = hidden_params; list; list = list->next) 
+		for (list = hidden_params; list; list = list->next)
 			gdaui_basic_form_entry_set_visible (form, GDA_HOLDER (list->data), FALSE);
 		g_slist_free (hidden_params);
 	}
@@ -385,7 +404,7 @@ gdaui_basic_form_dispose (GObject *object)
 
 	if (form->priv) {
 		/* paramlist */
-		if (form->priv->set) 
+		if (form->priv->set)
 			get_rid_of_set (form->priv->set, form);
 
 		gdaui_basic_form_clean (form);
@@ -544,8 +563,8 @@ load_xml_data_layout_item (GdauiBasicForm  *form,
 	/* else */
 	/* 	text = id; */
 	const gchar *text = NULL;
-	if (GDAUI_IS_RAW_FORM (form)) {
-		GdaDataModel *model = gdaui_data_widget_get_gda_model (GDAUI_DATA_WIDGET (form));
+	if (GDAUI_IS_DATA_SELECTOR (form)) {
+		GdaDataModel *model = gdaui_data_selector_get_model (GDAUI_DATA_SELECTOR (form));
 		if (model && GDA_IS_DATA_SELECT (model))
 			text = gda_utility_data_model_find_column_description (GDA_DATA_SELECT (model), name);
 	}
@@ -560,20 +579,20 @@ load_xml_data_layout_item (GdauiBasicForm  *form,
 			  (GtkAttachOptions) (GTK_FILL|GTK_EXPAND), 0, 0);
 	gtk_misc_set_alignment (GTK_MISC(label), 0, /* 0 */ 0.5);
 
-	GtkAlignment *alignment = GTK_ALIGNMENT(gtk_alignment_new (0.5, 0.5, 1, 1));
-	gtk_widget_show (GTK_WIDGET(alignment));
-	gtk_table_attach (GTK_TABLE(data), GTK_WIDGET(alignment),
+	GtkAlignment *alignment = GTK_ALIGNMENT (gtk_alignment_new (0.5, 0.5, 1, 1));
+	gtk_widget_show (GTK_WIDGET (alignment));
+	gtk_table_attach (GTK_TABLE (data), GTK_WIDGET (alignment),
 			  col + 1, col + 2, row, row + 1,
 			  (GtkAttachOptions) (GTK_EXPAND|GTK_FILL),
 			  (GtkAttachOptions) (GTK_EXPAND|GTK_FILL), 0, 0);
 	gtk_alignment_set_padding (GTK_ALIGNMENT(alignment), 0, 0, 12, 0);
 
-	GtkHBox *hbox = GTK_HBOX(gtk_hbox_new (FALSE, /* 0 */ 6));
-	gtk_widget_show (GTK_WIDGET(hbox));
-	gtk_container_add (GTK_CONTAINER(alignment), GTK_WIDGET(hbox));
+	GtkHBox *hbox = GTK_HBOX (gtk_hbox_new (FALSE, /* 0 */ 6));
+	gtk_widget_show (GTK_WIDGET (hbox));
+	gtk_container_add (GTK_CONTAINER (alignment), GTK_WIDGET (hbox));
 
 	// name hbox (both name and id are equals)
-	gtk_widget_set_name (GTK_WIDGET(hbox), name);
+	gtk_widget_set_name (GTK_WIDGET (hbox), name);
 
 	g_free (name);
 
@@ -939,7 +958,7 @@ load_xml_data_layout_group (GdauiBasicForm  *form,
 							    (GTK_NOTEBOOK(data), sequence - 1),
 							    GTK_WIDGET(label));
 			}
-	
+
 	xmlNodePtr child;
 	for (child = node->children; child != NULL; child = child->next) {
 
@@ -1161,28 +1180,27 @@ gdaui_basic_form_set_property (GObject *object,
         form = GDAUI_BASIC_FORM (object);
         if (form->priv) {
                 switch (param_id) {
-		case PROP_DATA_LAYOUT:
-			{
-				xmlNodePtr node = g_value_get_pointer (value);
-
-				gdaui_basic_form_clean (form);
-
-				xmlNodePtr child;
-				for (child = node->children; child != NULL; child = child->next) {
-
-					if (child->type == XML_ELEMENT_NODE &&
-					    !xmlStrcmp (child->name, BAD_CAST "data_layout_groups")) {
-						load_xml_data_layout_groups (form, child, NULL);
-					}
-				}
-
-				if (form->priv->scrolled_window != NULL) {
-					g_print ("Loaded XML file, reinit interface\n");
+		case PROP_DATA_LAYOUT: {
+			xmlNodePtr node = g_value_get_pointer (value);
+			
+			gdaui_basic_form_clean (form);
+			
+			xmlNodePtr child;
+			for (child = node->children; child != NULL; child = child->next) {
+				
+				if (child->type == XML_ELEMENT_NODE &&
+				    !xmlStrcmp (child->name, BAD_CAST "data_layout_groups")) {
+					load_xml_data_layout_groups (form, child, NULL);
 				}
-				gdaui_basic_form_fill (form);
-	
 			}
+			
+			if (form->priv->scrolled_window != NULL) {
+				g_print ("Loaded XML file, reinit interface\n");
+			}
+			gdaui_basic_form_fill (form);
+			g_signal_emit (G_OBJECT (form), gdaui_basic_form_signals[LAYOUT_CHANGED], 0);
 			break;
+		}
 		case PROP_PARAMLIST:
 			if (form->priv->set) {
 				get_rid_of_set (form->priv->set, form);
@@ -1192,9 +1210,9 @@ gdaui_basic_form_set_property (GObject *object,
 			form->priv->set = g_value_get_pointer (value);
 			if (form->priv->set) {
 				g_return_if_fail (GDA_IS_SET (form->priv->set));
-								
+
 				g_object_ref (form->priv->set);
-				form->priv->set_info = gdaui_set_new (GDA_SET (form->priv->set));
+				form->priv->set_info = _gdaui_set_new (GDA_SET (form->priv->set));
 
 				g_signal_connect (form->priv->set_info, "public_data_changed",
 						  G_CALLBACK (paramlist_public_data_changed_cb), form);
@@ -1202,6 +1220,7 @@ gdaui_basic_form_set_property (GObject *object,
 						  G_CALLBACK (paramlist_param_attr_changed_cb), form);
 
 				gdaui_basic_form_fill (form);
+				g_signal_emit (G_OBJECT (form), gdaui_basic_form_signals[LAYOUT_CHANGED], 0);
 			}
 			break;
 		case PROP_HEADERS_SENSITIVE:
@@ -1250,7 +1269,7 @@ gdaui_basic_form_get_property (GObject *object,
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 			break;
                 }
-        }	
+        }
 }
 
 static void
@@ -1280,7 +1299,7 @@ gdaui_basic_form_clean (GdauiBasicForm *form)
 		gtk_widget_destroy (form->priv->entries_glade);
 		form->priv->entries_glade = NULL;
 	}
-	
+
 	g_slist_free (form->priv->not_null_labels);
 	form->priv->not_null_labels = NULL;
 
@@ -1316,12 +1335,12 @@ find_hbox (GtkWidget  *widget,
 /*
  * create the entries in the widget
  */
-static void 
+static void
 gdaui_basic_form_fill (GdauiBasicForm *form)
 {
 	GSList *list;
 	gboolean form_expand = FALSE;
-	
+
 	/* parameters list management */
 	if (!form->priv->set || !form->priv->set_info->groups_list)
 		/* nothing to do */
@@ -1337,7 +1356,7 @@ gdaui_basic_form_fill (GdauiBasicForm *form)
 		GtkWidget *entry = NULL;
 
 		group = GDAUI_SET_GROUP (list->data);
-		if (! group->group->nodes_source) { 
+		if (! group->group->nodes_source) {
 			/* there is only one non-constrained parameter */
 			GdaHolder *param;
 			GType type;
@@ -1357,10 +1376,10 @@ gdaui_basic_form_fill (GdauiBasicForm *form)
 			/* determine initial value */
 			type = gda_holder_get_g_type (param);
 			value = val;
-			if (!value && default_val && 
+			if (!value && default_val &&
 			    (G_VALUE_TYPE ((GValue *) default_val) == type))
 				value = default_val;
-			
+
 			/* create entry */
 			plugin_val = gda_holder_get_attribute (param, GDAUI_ATTRIBUTE_PLUGIN);
 			if (plugin_val) {
@@ -1376,10 +1395,10 @@ gdaui_basic_form_fill (GdauiBasicForm *form)
 			gdaui_data_entry_set_value (GDAUI_DATA_ENTRY (entry), val);
 
 			if (!nnul ||
-			    (nnul && value && 
+			    (nnul && value &&
 			     (G_VALUE_TYPE ((GValue *) value) != GDA_TYPE_NULL)))
 				gdaui_data_entry_set_original_value (GDAUI_DATA_ENTRY (entry), value);
-			
+
 			if (default_val) {
 				gdaui_data_entry_set_value_default (GDAUI_DATA_ENTRY (entry), default_val);
 				gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (entry),
@@ -1390,7 +1409,7 @@ gdaui_basic_form_fill (GdauiBasicForm *form)
 			gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (entry),
 							 nnul ? 0 : GDA_VALUE_ATTR_CAN_BE_NULL,
 							 GDA_VALUE_ATTR_CAN_BE_NULL);
-			    
+
 			g_object_set_data (G_OBJECT (entry), "param", param);
 			g_object_set_data (G_OBJECT (entry), "form", form);
 			form->priv->entries = g_slist_append (form->priv->entries, entry);
@@ -1400,11 +1419,11 @@ gdaui_basic_form_fill (GdauiBasicForm *form)
 			SignalData sd;
 			sd.holder = g_object_ref (param);
 			sd.signal_id = g_signal_connect (G_OBJECT (param), "changed",
-							 G_CALLBACK (parameter_changed_cb), 
+							 G_CALLBACK (parameter_changed_cb),
 							 entry);
 			g_array_prepend_val (form->priv->signal_data, sd);
 		}
-		else { 
+		else {
 			/* several parameters depending on the values of a GdaDataModel object */
 			GSList *plist;
 			gboolean nnul = TRUE;
@@ -1426,7 +1445,7 @@ gdaui_basic_form_fill (GdauiBasicForm *form)
 				SignalData sd;
 				sd.holder = g_object_ref (param);
 				sd.signal_id = g_signal_connect (G_OBJECT (param), "changed",
-								 G_CALLBACK (parameter_changed_cb), 
+								 G_CALLBACK (parameter_changed_cb),
 								 entry);
 				g_array_prepend_val (form->priv->signal_data, sd);
 			}
@@ -1486,7 +1505,7 @@ gdaui_basic_form_fill (GdauiBasicForm *form)
 		gtk_widget_show (GTK_WIDGET(form->priv->scrolled_window));
 	}
 
-	/* 
+	/*
 	 * There is no layout spec (or the provided one could not be used),
 	 * so use the default tables arrangment
 	 */
@@ -1506,7 +1525,7 @@ gdaui_basic_form_fill (GdauiBasicForm *form)
 			gboolean expand;
 			GtkWidget *entry_label;
 			GdaHolder *param;
-			
+
 			/* label for the entry */
 			param = g_object_get_data (G_OBJECT (list->data), "param");
 			if (param) {
@@ -1520,17 +1539,17 @@ gdaui_basic_form_fill (GdauiBasicForm *form)
 				label = gtk_label_new (str);
 				g_free (str);
 				g_object_set_data_full (G_OBJECT (label), "_gda_title", title, g_free);
-				if (gda_holder_get_not_null (param)) 
+				if (gda_holder_get_not_null (param))
 					form->priv->not_null_labels = g_slist_prepend (form->priv->not_null_labels,
 										       label);
 
 				gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
-				
+
 				gtk_table_attach (GTK_TABLE (table), label, 0, 1, i, i+1,
 						  GTK_FILL | GTK_SHRINK, GTK_SHRINK, 0, 0);
 				gtk_widget_show (label);
 				entry_label = label;
-				
+
 				g_object_get (G_OBJECT (param), "description", &title, NULL);
 				if (title && *title)
 					gtk_widget_set_tooltip_text (label, title);
@@ -1549,12 +1568,12 @@ gdaui_basic_form_fill (GdauiBasicForm *form)
 					if (nullok && gda_holder_get_not_null (GDA_SET_NODE (params->data)->holder))
 						nullok = FALSE;
 					if (!title)
-						g_object_get (G_OBJECT (GDA_SET_NODE (params->data)->holder), 
+						g_object_get (G_OBJECT (GDA_SET_NODE (params->data)->holder),
 							      "name", &title, NULL);
 				}
-				
+
 				if (!title) {
-					str = g_object_get_data (G_OBJECT (group->group->nodes_source->data_model), 
+					str = g_object_get_data (G_OBJECT (group->group->nodes_source->data_model),
 								 "name");
 					if (str)
 						title = g_strdup (str);
@@ -1565,15 +1584,15 @@ gdaui_basic_form_fill (GdauiBasicForm *form)
 				label = gtk_label_new (str);
 				g_free (str);
 				g_object_set_data_full (G_OBJECT (label), "_gda_title", title, g_free);
-				if (!nullok) 
+				if (!nullok)
 					form->priv->not_null_labels = g_slist_prepend (form->priv->not_null_labels, label);
 				gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
-				
+
 				gtk_table_attach (GTK_TABLE (table), label, 0, 1, i, i+1,
 						  GTK_FILL | GTK_SHRINK, GTK_SHRINK, 0, 0);
 				gtk_widget_show (label);
 				entry_label = label;
-				
+
 				title = g_object_get_data (G_OBJECT (group->group->nodes_source->data_model),
 							   "descr");
 				if (title && *title)
@@ -1584,7 +1603,7 @@ gdaui_basic_form_fill (GdauiBasicForm *form)
 			expand = gdaui_data_entry_expand_in_layout (GDAUI_DATA_ENTRY (list->data));
 			form_expand = form_expand || expand;
 			gtk_table_attach (GTK_TABLE (table), GTK_WIDGET (list->data), 1, 2, i, i+1,
-					  GTK_FILL | GTK_EXPAND, 
+					  GTK_FILL | GTK_EXPAND,
 					  expand ? (GTK_FILL | GTK_EXPAND) : GTK_SHRINK, 0, 0);
 			gtk_widget_show (GTK_WIDGET (list->data));
 			g_object_set_data (G_OBJECT (list->data), "entry_label", entry_label);
@@ -1600,7 +1619,7 @@ gdaui_basic_form_fill (GdauiBasicForm *form)
 	}
 
 	form->priv->can_expand = form_expand;
-	
+
 	/* Set the Show actions in the entries */
 	gdaui_basic_form_show_entry_actions (form, form->priv->show_actions);
 	/* Set the Auto entries default in the entries */
@@ -1638,7 +1657,7 @@ label_destroyed_cb (GtkWidget *label, GdauiBasicForm *form)
 }
 
 /*
- * if @show_mark is TRUE, display the label as bold 
+ * if @show_mark is TRUE, display the label as bold
  */
 static void
 mark_not_null_entry_labels (GdauiBasicForm *form, gboolean show_mark)
@@ -1651,9 +1670,9 @@ mark_not_null_entry_labels (GdauiBasicForm *form, gboolean show_mark)
 
 		title = g_object_get_data (G_OBJECT (list->data), "_gda_title");
 		str = _gdaui_utility_markup_title (title, !show_mark);
-		if (show_mark) 
+		if (show_mark)
 			gtk_label_set_markup (GTK_LABEL (list->data), str);
-		else 
+		else
 			gtk_label_set_text (GTK_LABEL (list->data), str);
 		g_free (str);
 	}
@@ -1681,7 +1700,7 @@ entry_contents_modified (GdauiDataEntry *entry, GdauiBasicForm *form)
 	param = g_object_get_data (G_OBJECT (entry), "param");
 	if (param) { /* single parameter */
 		GValue *value;
-		
+
 		form->priv->forward_param_updates = FALSE;
 
 		/* parameter's value */
@@ -1713,13 +1732,13 @@ entry_contents_modified (GdauiDataEntry *entry, GdauiBasicForm *form)
 		g_assert (g_slist_length (params) == g_slist_length (values));
 
 		for (list = values; list; list = list->next, params = params->next) {
-			/* REM: if there is more than one value in 'params', then a 
-			 * signal is emitted for each param that is changed, 
+			/* REM: if there is more than one value in 'params', then a
+			 * signal is emitted for each param that is changed,
 			 * and there is no way for the listener of that signal to know if it
 			 * the end of the "holder-changed" sequence. What could be done is:
-			 * - adding another boolean to tell if that signal is the 
+			 * - adding another boolean to tell if that signal is the
 			 *   last one in the "holder-changed" sequence, or
-			 * - modify the signal to add a list of parameters which are changed 
+			 * - modify the signal to add a list of parameters which are changed
 			 *   and emit only one signal.
 			 */
 			GdaHolder *param;
@@ -1728,7 +1747,7 @@ entry_contents_modified (GdauiDataEntry *entry, GdauiBasicForm *form)
 			/* parameter's value */
 			param = GDA_SET_NODE (params->data)->holder;
 			gda_holder_set_value (param, (GValue *)(list->data), NULL);
-			g_signal_emit (G_OBJECT (form), gdaui_basic_form_signals[HOLDER_CHANGED], 
+			g_signal_emit (G_OBJECT (form), gdaui_basic_form_signals[HOLDER_CHANGED],
 				       0, param, TRUE);
 			form->priv->forward_param_updates = TRUE;
 		}
@@ -1739,7 +1758,7 @@ entry_contents_modified (GdauiDataEntry *entry, GdauiBasicForm *form)
 		if (GDA_IS_DATA_MODEL_ITER (form->priv->set)) {
 			GdaDataProxy *proxy;
 			gint proxy_row;
-			
+
 			proxy_row = gda_data_model_iter_get_row ((GdaDataModelIter *) form->priv->set);
 
 			g_object_get (G_OBJECT (form->priv->set), "data_model", &proxy, NULL);
@@ -1750,10 +1769,10 @@ entry_contents_modified (GdauiDataEntry *entry, GdauiBasicForm *form)
 				all_new_values = gdaui_entry_combo_get_all_values (GDAUI_ENTRY_COMBO (entry));
 				for (i = 0; i < group->nodes_source->shown_n_cols; i++) {
 					GValue *value;
-					
+
 					col = group->nodes_source->shown_cols_index[i];
 					value = (GValue *) g_slist_nth_data (all_new_values, col);
-					gda_data_proxy_set_model_row_value (proxy, 
+					gda_data_proxy_set_model_row_value (proxy,
 									    group->nodes_source->data_model,
 									    proxy_row, col, value);
 				}
@@ -1770,7 +1789,7 @@ entry_contents_modified (GdauiDataEntry *entry, GdauiBasicForm *form)
  * Called when a parameter changes
  * We emit a "holder-changed" signal only if the 'form->priv->forward_param_updates' is TRUE, which means
  * the param change does not come from a GdauiDataEntry change.
- */ 
+ */
 static void
 parameter_changed_cb (GdaHolder *param, GdauiDataEntry *entry)
 {
@@ -1785,7 +1804,7 @@ parameter_changed_cb (GdaHolder *param, GdauiDataEntry *entry)
 		/* There can be a feedback from the entry if the param is invalid and "set_default_if_invalid"
 		   exists and is TRUE */
 		param_valid = gda_holder_is_valid (param);
-		if (!param_valid) 
+		if (!param_valid)
 			if (g_object_class_find_property (G_OBJECT_GET_CLASS (entry), "set_default_if_invalid"))
 				g_object_get (G_OBJECT (entry), "set_default_if_invalid", &default_if_invalid, NULL);
 
@@ -1805,16 +1824,16 @@ parameter_changed_cb (GdaHolder *param, GdauiDataEntry *entry)
 				const GValue *pvalue;
 				pvalue = gda_holder_get_value (GDA_SET_NODE (list->data)->holder);
 				values = g_slist_append (values, (GValue *) pvalue);
-				if (allnull && pvalue && 
+				if (allnull && pvalue &&
 				    (G_VALUE_TYPE ((GValue *) pvalue) != GDA_TYPE_NULL))
 					allnull = FALSE;
 
 				list = g_slist_next (list);
 			}
-			
-			if (!allnull) 
+
+			if (!allnull)
 				gdaui_entry_combo_set_values (GDAUI_ENTRY_COMBO (entry), values);
-			else 
+			else
 				gdaui_entry_combo_set_values (GDAUI_ENTRY_COMBO (entry), NULL);
 
 			g_slist_free (values);
@@ -1862,23 +1881,23 @@ gdaui_basic_form_set_as_reference (GdauiBasicForm *form)
 			GSList *values = NULL;
 			GSList *params = group->group->nodes;
 			gboolean allnull = TRUE;
-			
+
 			while (params) {
 				const GValue *pvalue;
 				pvalue = gda_holder_get_value (GDA_SET_NODE (params->data)->holder);
 				values = g_slist_append (values, (GValue *) pvalue);
-				if (allnull && pvalue && 
+				if (allnull && pvalue &&
 				    (G_VALUE_TYPE ((GValue *) pvalue) != GDA_TYPE_NULL))
 					allnull = FALSE;
-				
+
 				params = g_slist_next (params);
 			}
-			
-			if (!allnull) 
+
+			if (!allnull)
 				gdaui_entry_combo_set_values_orig (GDAUI_ENTRY_COMBO (list->data), values);
-			else 
+			else
 				gdaui_entry_combo_set_values_orig (GDAUI_ENTRY_COMBO (list->data), NULL);
-			
+
 			g_slist_free (values);
 		}
 		else {
@@ -1894,7 +1913,7 @@ gdaui_basic_form_set_as_reference (GdauiBasicForm *form)
 }
 
 /**
- * gdaui_basic_form_is_valid 
+ * gdaui_basic_form_is_valid
  * @form: a #GdauiBasicForm widget
  *
  * Tells if the form can be used as-is (if all the parameters do have some valid values)
@@ -1947,7 +1966,7 @@ gdaui_basic_form_has_changed (GdauiBasicForm *form)
 	GSList *list;
 
 	g_return_val_if_fail (GDAUI_IS_BASIC_FORM (form), FALSE);
-	
+
 	for (list = form->priv->entries; list; list = list->next)
 		if (! (gdaui_data_entry_get_attributes (GDAUI_DATA_ENTRY (list->data)) &
 		       GDA_VALUE_ATTR_IS_UNCHANGED))
@@ -1968,14 +1987,14 @@ gdaui_basic_form_show_entry_actions (GdauiBasicForm *form, gboolean show_actions
 {
 	GSList *entries;
 	guint show;
-	
+
 	g_return_if_fail (GDAUI_IS_BASIC_FORM (form));
 
 	show = show_actions ? GDA_VALUE_ATTR_ACTIONS_SHOWN : 0;
 	form->priv->show_actions = show_actions;
 
-	for (entries = form->priv->entries; entries; entries = entries->next) 
-		gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (entries->data), show, 
+	for (entries = form->priv->entries; entries; entries = entries->next)
+		gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (entries->data), show,
 						 GDA_VALUE_ATTR_ACTIONS_SHOWN);
 	/* mark_not_null_entry_labels (form, show_actions); */
 }
@@ -1995,7 +2014,7 @@ gdaui_basic_form_reset (GdauiBasicForm *form)
 	GSList *list;
 
 	g_return_if_fail (GDAUI_IS_BASIC_FORM (form));
-	
+
 	list = form->priv->entries;
 	while (list) {
 		GdaSetNode *node = g_object_get_data (G_OBJECT (list->data), "node");
@@ -2043,43 +2062,43 @@ gdaui_basic_form_entry_set_visible (GdauiBasicForm *form, GdaHolder *param, gboo
 	if (entry) {
 		gint row = -1;
 		GtkWidget *entry_label = g_object_get_data (G_OBJECT (entry), "entry_label");
-		
+
 		if (form->priv->entries_table)
 			row = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (entry), "row_no"));
-		
+
 		if (show) {
 			if (g_slist_find (form->priv->hidden_entries, entry)) {
 				form->priv->hidden_entries = g_slist_remove (form->priv->hidden_entries, entry);
-				g_signal_handlers_disconnect_by_func (G_OBJECT (entry), 
+				g_signal_handlers_disconnect_by_func (G_OBJECT (entry),
 								      G_CALLBACK (widget_shown_cb), form);
 			}
 			gtk_widget_show (entry);
-			
+
 			if (entry_label) {
 				if (g_slist_find (form->priv->hidden_entries, entry_label)) {
-					form->priv->hidden_entries = g_slist_remove (form->priv->hidden_entries, 
+					form->priv->hidden_entries = g_slist_remove (form->priv->hidden_entries,
 										     entry_label);
-					g_signal_handlers_disconnect_by_func (G_OBJECT (entry_label), 
+					g_signal_handlers_disconnect_by_func (G_OBJECT (entry_label),
 									      G_CALLBACK (widget_shown_cb), form);
 				}
 				gtk_widget_show (entry_label);
 			}
-			if (row > -1) 
+			if (row > -1)
 				gtk_table_set_row_spacing (GTK_TABLE (form->priv->entries_table), row, 5);
 		}
 		else {
 			if (!g_slist_find (form->priv->hidden_entries, entry)) {
 				form->priv->hidden_entries = g_slist_append (form->priv->hidden_entries, entry);
-				g_signal_connect_after (G_OBJECT (entry), "show", 
+				g_signal_connect_after (G_OBJECT (entry), "show",
 							G_CALLBACK (widget_shown_cb), form);
 			}
 			gtk_widget_hide (entry);
-			
+
 			if (entry_label) {
 				if (!g_slist_find (form->priv->hidden_entries, entry_label)) {
-					form->priv->hidden_entries = g_slist_append (form->priv->hidden_entries, 
+					form->priv->hidden_entries = g_slist_append (form->priv->hidden_entries,
 										     entry_label);
-					g_signal_connect_after (G_OBJECT (entry_label), "show", 
+					g_signal_connect_after (G_OBJECT (entry_label), "show",
 								G_CALLBACK (widget_shown_cb), form);
 				}
 				gtk_widget_hide (entry_label);
@@ -2094,7 +2113,7 @@ gdaui_basic_form_entry_set_visible (GdauiBasicForm *form, GdaHolder *param, gboo
  * gdaui_basic_form_entry_grab_focus
  * @form: a #GdauiBasicForm widget
  * @param: a #GdaHolder object
- * 
+ *
  * Makes the data entry corresponding to @param grab the focus for the window it's in
  *
  * Since: 4.2
@@ -2135,7 +2154,7 @@ gdaui_basic_form_entry_set_editable (GdauiBasicForm *form, GdaHolder *param, gbo
 		entry = gdaui_basic_form_get_entry_widget (form, param);
 		if (entry) {
 			/* GtkWidget *entry_label = g_object_get_data (G_OBJECT (entry), "entry_label"); */
-			
+
 			gdaui_data_entry_set_editable (GDAUI_DATA_ENTRY (entry), editable);
 			/*if (entry_label)
 			  gtk_widget_set_sensitive (entry_label, editable || !form->priv->headers_sensitive);*/
@@ -2167,12 +2186,12 @@ gdaui_basic_form_set_entries_auto_default (GdauiBasicForm *form, gboolean auto_d
 	GSList *entries;
 
 	g_return_if_fail (GDAUI_IS_BASIC_FORM (form));
-	
+
 	form->priv->entries_auto_default = auto_default;
 	for (entries = form->priv->entries; entries; entries = entries->next) {
 		if (g_object_class_find_property (G_OBJECT_GET_CLASS (entries->data), "set_default_if_invalid"))
 			g_object_set (G_OBJECT (entries->data), "set_default_if_invalid", auto_default, NULL);
-	}	
+	}
 }
 
 /**
@@ -2194,7 +2213,7 @@ gdaui_basic_form_set_entries_to_default (GdauiBasicForm *form)
 	for (entries = form->priv->entries; entries; entries = entries->next) {
 		attrs = gdaui_data_entry_get_attributes (GDAUI_DATA_ENTRY (entries->data));
 		if (attrs & GDA_VALUE_ATTR_CAN_BE_DEFAULT)
-			gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (entries->data), 
+			gdaui_data_entry_set_attributes (GDAUI_DATA_ENTRY (entries->data),
 							 GDA_VALUE_ATTR_IS_DEFAULT, GDA_VALUE_ATTR_IS_DEFAULT);
 	}
 }
@@ -2264,7 +2283,7 @@ gdaui_basic_form_get_label_widget (GdauiBasicForm *form, GdaHolder *param)
 	g_return_val_if_fail (GDAUI_IS_BASIC_FORM (form), NULL);
 
 	entry = gdaui_basic_form_get_entry_widget (form, param);
-	if (entry) 
+	if (entry)
 		return g_object_get_data (G_OBJECT (entry), "entry_label");
 	else
 		return NULL;
@@ -2298,11 +2317,11 @@ gdaui_basic_form_new_in_dialog (GdaSet *paramlist, GtkWindow *parent,
 	const gchar *rtitle;
 
 	form = gdaui_basic_form_new (paramlist);
- 
+
 	rtitle = title;
 	if (!rtitle)
 		rtitle = _("Values to be filled");
-		
+
 	dlg = gtk_dialog_new_with_buttons (rtitle, parent,
 					   GTK_DIALOG_MODAL,
 					   GTK_STOCK_CANCEL,
@@ -2327,8 +2346,8 @@ gdaui_basic_form_new_in_dialog (GdaSet *paramlist, GtkWindow *parent,
 #endif
 		gtk_widget_show (label);
 	}
-	
-	
+
+
 #if GTK_CHECK_VERSION(2,18,0)
 	gtk_container_set_border_width (GTK_CONTAINER (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg)))), 4);
 	gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), form,
@@ -2344,10 +2363,10 @@ gdaui_basic_form_new_in_dialog (GdaSet *paramlist, GtkWindow *parent,
 	g_signal_connect (G_OBJECT (form), "holder-changed",
 			  G_CALLBACK (form_holder_changed), dlg);
 	g_object_set_data (G_OBJECT (dlg), "form", form);
-	
+
 	gtk_widget_show_all (form);
 	form_holder_changed (GDAUI_BASIC_FORM (form), NULL, FALSE, GTK_DIALOG (dlg));
-	
+
 	return dlg;
 }
 
@@ -2355,8 +2374,90 @@ static void
 form_holder_changed (GdauiBasicForm *form, GdaHolder *param, gboolean is_user_modif, GtkDialog *dlg)
 {
 	gboolean valid;
-	
+
 	valid = gdaui_basic_form_is_valid (form);
-	
+
 	gtk_dialog_set_response_sensitive (dlg, GTK_RESPONSE_ACCEPT, valid);
 }
+
+/**
+ * gdaui_basic_form_set_data_layout_from_file
+ * @form: a #GdauiBasicForm
+ * @file_name:
+ * @parent_table:
+ *
+ * Sets a data layout according an XML description contained in @file_name
+ *
+ * Since: 4.2
+ */
+void
+gdaui_basic_form_set_data_layout_from_file (GdauiBasicForm *form, const gchar *file_name, const gchar *parent_table)
+{
+	g_return_if_fail (GDAUI_IS_BASIC_FORM (form));
+	g_return_if_fail (file_name);
+        g_return_if_fail (parent_table);
+
+	xmlDocPtr doc;
+        doc = xmlParseFile (file_name);
+        if (doc == NULL) {
+                g_warning (_("'%s' Document not parsed successfully\n"), file_name);
+                return;
+        }
+
+        xmlDtdPtr dtd = NULL;
+
+	gchar *file = gda_gbr_get_file_path (GDA_DATA_DIR, LIBGDA_ABI_NAME, "dtd", "data-layout.dtd", NULL);
+        if (g_file_test (file, G_FILE_TEST_EXISTS))
+                dtd = xmlParseDTD (NULL, BAD_CAST file);
+        if (dtd == NULL) {
+                g_warning (_("'%s' DTD not parsed successfully. "
+                             "XML data layout validation will not be "
+                             "performed (some errors may occur)"), file);
+        }
+        g_free (file);
+
+        /* Get the root element node */
+        xmlNodePtr root_node = NULL;
+        root_node = xmlDocGetRootElement (doc);
+
+        /* Must have root element, a name and the name must be "data_layouts" */
+        if (!root_node ||
+            !root_node->name ||
+            xmlStrcmp (root_node->name, BAD_CAST "data_layouts")) {
+                xmlFreeDoc (doc);
+                return;
+        }
+
+        xmlNodePtr node;
+        for (node = root_node->children; node != NULL; node = node->next) {
+
+                if (node->type == XML_ELEMENT_NODE &&
+                    !xmlStrcmp (node->name, BAD_CAST "data_layout")) {
+                        gboolean retval = FALSE;
+                        xmlChar *str;
+
+                        str = xmlGetProp (node, BAD_CAST "parent_table");
+                        if (str) {
+                                if (strcmp ((gchar*) str, parent_table) == 0)
+                                        retval = TRUE;
+                                //g_print ("parent_table: %s\n", str);
+                                xmlFree (str);
+                        }
+
+                        str = xmlGetProp (node, BAD_CAST "name");
+                        if (str) {
+                                if (retval && !strcmp ((gchar*) str, "details"))  // Now proceed
+                                        g_object_set (G_OBJECT (form), "data-layout", node, NULL);
+                                //g_print ("name: %s\n", str);
+                                xmlFree (str);
+                        }
+                }
+        }
+
+        /* Free the document */
+        xmlFreeDoc (doc);
+
+        /* Free the global variables that may
+         * have been allocated by the parser */
+        xmlCleanupParser ();
+}
diff --git a/libgda-ui/gdaui-basic-form.h b/libgda-ui/gdaui-basic-form.h
index 4ac6096..11cb16a 100644
--- a/libgda-ui/gdaui-basic-form.h
+++ b/libgda-ui/gdaui-basic-form.h
@@ -52,6 +52,7 @@ struct _GdauiBasicFormClass
 	/* signals */
         void       (*holder_changed) (GdauiBasicForm *form, GdaHolder *holder, gboolean is_user_action);
 	void       (*activated)      (GdauiBasicForm *form);
+	void       (*layout_changed) (GdauiBasicForm *form);
 };
 
 /* 
@@ -77,6 +78,9 @@ void              gdaui_basic_form_set_entries_to_default   (GdauiBasicForm *for
 GtkWidget        *gdaui_basic_form_get_entry_widget         (GdauiBasicForm *form, GdaHolder *holder);
 GtkWidget        *gdaui_basic_form_get_label_widget         (GdauiBasicForm *form, GdaHolder *holder);
 
+void              gdaui_basic_form_set_data_layout_from_file(GdauiBasicForm *form, const gchar *file_name,
+							     const gchar *parent_table);
+
 G_END_DECLS
 
 #endif
diff --git a/libgda-ui/gdaui-cloud.c b/libgda-ui/gdaui-cloud.c
index 9171379..e18b25a 100644
--- a/libgda-ui/gdaui-cloud.c
+++ b/libgda-ui/gdaui-cloud.c
@@ -24,6 +24,7 @@
 #include "gdaui-cloud.h"
 #include <gdk/gdkkeysyms.h>
 #include "internal/popup-container.h"
+#include "gdaui-data-selector.h"
 
 static void gdaui_cloud_class_init (GdauiCloudClass * class);
 static void gdaui_cloud_init (GdauiCloud *wid);
@@ -37,9 +38,20 @@ static void gdaui_cloud_get_property (GObject *object,
 				      GValue *value,
 				      GParamSpec *pspec);
 
+/* GdauiDataSelector interface */
+static void              gdaui_cloud_selector_init (GdauiDataSelectorIface *iface);
+static GdaDataModel     *cloud_selector_get_model (GdauiDataSelector *iface);
+static void              cloud_selector_set_model (GdauiDataSelector *iface, GdaDataModel *model);
+static GArray           *cloud_selector_get_selected_rows (GdauiDataSelector *iface);
+static GdaDataModelIter *cloud_selector_get_current_selection (GdauiDataSelector *iface);
+static gboolean          cloud_selector_select_row (GdauiDataSelector *iface, gint row);
+static void              cloud_selector_unselect_row (GdauiDataSelector *iface, gint row);
+static void              cloud_selector_set_column_visible (GdauiDataSelector *iface, gint column, gboolean visible);
+
 struct _GdauiCloudPriv
 {
 	GdaDataModel        *model;
+	GdaDataModelIter    *iter;
 	gint                 label_column;
 	gint                 weight_column;
 	GdauiCloudWeightFunc weight_func;
@@ -57,12 +69,11 @@ struct _GdauiCloudPriv
 };
 
 enum {
-        SELECTION_CHANGED,
 	ACTIVATE,
         LAST_SIGNAL
 };
 
-static guint objects_cloud_signals[LAST_SIGNAL] = { 0, 0 };
+static guint objects_cloud_signals[LAST_SIGNAL] = { 0 };
 
 /* get a pointer to the parents to be able to call their destructor */
 static GObjectClass *parent_class = NULL;
@@ -94,9 +105,16 @@ gdaui_cloud_get_type (void)
 			sizeof (GdauiCloud),
 			0,
 			(GInstanceInitFunc) gdaui_cloud_init
-		};		
+		};
+
+		static const GInterfaceInfo selector_info = {
+                        (GInterfaceInitFunc) gdaui_cloud_selector_init,
+                        NULL,
+                        NULL
+                };
 
 		type = g_type_register_static (GTK_TYPE_VBOX, "GdauiCloud", &info, 0);
+		g_type_add_interface_static (type, GDAUI_TYPE_DATA_SELECTOR, &selector_info);
 	}
 
 	return type;
@@ -123,13 +141,6 @@ gdaui_cloud_class_init (GdauiCloudClass *klass)
 	GTK_WIDGET_CLASS (object_class)->map = cloud_map;
 
 	/* signals */
-        objects_cloud_signals [SELECTION_CHANGED] =
-                g_signal_new ("selection-changed",
-                              G_TYPE_FROM_CLASS (object_class),
-                              G_SIGNAL_RUN_FIRST,
-                              G_STRUCT_OFFSET (GdauiCloudClass, selection_changed),
-                              NULL, NULL,
-                              g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
         objects_cloud_signals [ACTIVATE] =
                 g_signal_new ("activate",
                               G_TYPE_FROM_CLASS (object_class),
@@ -137,7 +148,6 @@ gdaui_cloud_class_init (GdauiCloudClass *klass)
                               G_STRUCT_OFFSET (GdauiCloudClass, activate),
                               NULL, NULL,
                               g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
-        klass->selection_changed = NULL;
         klass->activate = NULL;
 
 	/* Properties */
@@ -163,6 +173,48 @@ gdaui_cloud_class_init (GdauiCloudClass *klass)
 }
 
 static void
+gdaui_cloud_selector_init (GdauiDataSelectorIface *iface)
+{
+	iface->get_model = cloud_selector_get_model;
+	iface->set_model = cloud_selector_set_model;
+	iface->get_selected_rows = cloud_selector_get_selected_rows;
+	iface->get_current_selection = cloud_selector_get_current_selection;
+	iface->select_row = cloud_selector_select_row;
+	iface->unselect_row = cloud_selector_unselect_row;
+	iface->set_column_visible = cloud_selector_set_column_visible;
+}
+
+static void
+sync_iter_with_selection (GdauiCloud *cloud)
+{
+	GSList *list;
+	gint selrow = -1;
+
+	if (! cloud->priv->iter)
+		return;
+
+	/* locate selected row */
+	for (list = cloud->priv->selected_tags; list; list = list->next) {
+		gint row;
+		row = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (list->data), "row")) - 1;
+		if (row >= 0) {
+			if (selrow == -1)
+				selrow = row;
+			else {
+				selrow = -1;
+				break;
+			}
+		}
+	}
+	
+	/* update iter */
+	if ((selrow == -1) || !gda_data_model_iter_move_to_row (cloud->priv->iter, selrow)) {
+		gda_data_model_iter_invalidate_contents (cloud->priv->iter);
+		g_object_set (G_OBJECT (cloud->priv->iter), "current-row", -1, NULL);
+	}
+}
+
+static void
 update_display (GdauiCloud *cloud)
 {
 	GtkTextBuffer *tbuffer;
@@ -177,6 +229,8 @@ update_display (GdauiCloud *cloud)
 		g_slist_foreach (cloud->priv->selected_tags, (GFunc) g_object_unref, NULL);
 		g_slist_free (cloud->priv->selected_tags);
 		cloud->priv->selected_tags = NULL;
+		sync_iter_with_selection (cloud);
+		g_signal_emit_by_name (cloud, "selection-changed");
 	}
 
 	if (!cloud->priv->model)
@@ -371,6 +425,8 @@ gdaui_cloud_dispose (GObject *object)
 			g_slist_foreach (cloud->priv->selected_tags, (GFunc) g_object_unref, NULL);
 			g_slist_free (cloud->priv->selected_tags);
 		}
+                if (cloud->priv->iter)
+                        g_object_unref (cloud->priv->iter);
                 if (cloud->priv->model)
                         g_object_unref (cloud->priv->model);
 		if (cloud->priv->tbuffer)
@@ -405,6 +461,10 @@ gdaui_cloud_set_property (GObject *object,
 	case PROP_MODEL:
 		model = (GdaDataModel*) g_value_get_object (value);
 		if (cloud->priv->model != model) {
+			if (cloud->priv->iter) {
+				g_object_unref (cloud->priv->iter);
+				cloud->priv->iter = NULL;
+			}
 			if (cloud->priv->model) {
 				g_signal_handlers_disconnect_by_func (cloud->priv->model,
 								      G_CALLBACK (model_reset_cb), cloud);
@@ -503,8 +563,9 @@ gdaui_cloud_set_selection_mode   (GdauiCloud *cloud, GtkSelectionMode mode)
 			}
 
 			g_slist_free (cloud->priv->selected_tags);
-			g_signal_emit (cloud, objects_cloud_signals [SELECTION_CHANGED], 0);
 			cloud->priv->selected_tags = NULL;
+			sync_iter_with_selection (cloud);
+			g_signal_emit_by_name (cloud, "selection-changed");
 		}
 		break;
 	case GTK_SELECTION_SINGLE:
@@ -524,7 +585,8 @@ gdaui_cloud_set_selection_mode   (GdauiCloud *cloud, GtkSelectionMode mode)
 			}
 			g_slist_free (cloud->priv->selected_tags);
 			cloud->priv->selected_tags = newsel;
-			g_signal_emit (cloud, objects_cloud_signals [SELECTION_CHANGED], 0);
+			sync_iter_with_selection (cloud);
+			g_signal_emit_by_name (cloud, "selection-changed");
 		}
 		break;
 	case GTK_SELECTION_MULTIPLE:
@@ -536,33 +598,6 @@ gdaui_cloud_set_selection_mode   (GdauiCloud *cloud, GtkSelectionMode mode)
 	cloud->priv->selection_mode = mode;
 }
 
-/**
- * gdaui_cloud_get_selection
- * @cloud: a #GdauiCloud widget
- * 
- * Returns the list of the currently selected rows in a #GdauiCloud widget. 
- * The returned value is a list of integers (use GPOINTER_TO_INT()) which represent each of the selected rows.
- *
- * Returns: a new list, should be freed (by calling g_list_free) when no longer needed.
- *
- * Since: 4.2
- */
-GList *
-gdaui_cloud_get_selection (GdauiCloud *cloud)
-{
-	GList *retlist = NULL;
-	GSList *list;
-	g_return_val_if_fail (GDAUI_IS_CLOUD (cloud), NULL);
-
-	for (list = cloud->priv->selected_tags; list; list = list->next) {
-		gint row;
-		row = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (list->data), "row")) - 1;
-		if (row >= 0)
-			retlist = g_list_prepend (retlist, GINT_TO_POINTER (row));
-	}
-	return retlist;
-}
-
 static void
 row_clicked (GdauiCloud *cloud, gint row, GtkTextTag *tag)
 {
@@ -629,7 +664,8 @@ row_clicked (GdauiCloud *cloud, gint row, GtkTextTag *tag)
 		}
 	}
 
-	g_signal_emit (cloud, objects_cloud_signals [SELECTION_CHANGED], 0);
+	sync_iter_with_selection (cloud);
+	g_signal_emit_by_name (cloud, "selection-changed");
 }
 
 static GdkCursor *hand_cursor = NULL;
@@ -1065,3 +1101,143 @@ gdaui_cloud_set_weight_func (GdauiCloud *cloud, GdauiCloudWeightFunc func, gpoin
 		update_display (cloud);
 	}
 }
+
+/* GdauiDataSelector interface */
+static GdaDataModel *
+cloud_selector_get_model (GdauiDataSelector *iface)
+{
+	GdauiCloud *cloud;
+	cloud = GDAUI_CLOUD (iface);
+	return cloud->priv->model;
+}
+
+static void
+cloud_selector_set_model (GdauiDataSelector *iface, GdaDataModel *model)
+{
+	g_object_set (G_OBJECT (iface), "model", model, NULL);
+}
+
+static GArray *
+cloud_selector_get_selected_rows (GdauiDataSelector *iface)
+{
+	GArray *retval = NULL;
+	GdauiCloud *cloud;
+	GSList *list;
+
+	cloud = GDAUI_CLOUD (iface);
+	for (list = cloud->priv->selected_tags; list; list = list->next) {
+		gint row;
+		row = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (list->data), "row")) - 1;
+		if (row >= 0) {
+			if (!retval)
+				retval = g_array_new (FALSE, FALSE, sizeof (gint));
+			g_array_append_val (retval, row);
+		}
+	}
+	return retval;
+
+}
+
+static GdaDataModelIter *
+cloud_selector_get_current_selection (GdauiDataSelector *iface)
+{
+	GdauiCloud *cloud;
+
+	cloud = GDAUI_CLOUD (iface);
+	if (! cloud->priv->iter && cloud->priv->model) {
+		cloud->priv->iter = gda_data_model_create_iter (cloud->priv->model);
+		sync_iter_with_selection (cloud);
+	}
+
+	return cloud->priv->iter;
+}
+
+typedef struct {
+	gint row_to_find;
+	GtkTextTag *tag;
+} RowLookup;
+
+static void
+text_tag_table_foreach_cb2 (GtkTextTag *tag, RowLookup *rl)
+{
+	if (rl->tag)
+		return; /* row already found */
+	gint srow;
+	srow = GPOINTER_TO_INT (g_object_get_data ((GObject*) tag, "row")) - 1;
+	if (srow == rl->row_to_find)
+		rl->tag = tag;
+}
+
+static gboolean
+cloud_selector_select_row (GdauiDataSelector *iface, gint row)
+{
+	GdauiCloud *cloud;
+	GSList *list;
+
+	cloud = GDAUI_CLOUD (iface);
+	if (cloud->priv->selection_mode == GTK_SELECTION_NONE)
+		return FALSE;
+
+	/* test if row already selected */
+	for (list = cloud->priv->selected_tags; list; list = list->next) {
+		gint srow;
+		srow = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (list->data), "row")) - 1;
+		if (srow == row)
+			return TRUE;
+	}
+
+	/* try to select row */
+	RowLookup rl;
+	rl.row_to_find = row;
+	rl.tag = NULL;
+	gtk_text_tag_table_foreach (gtk_text_buffer_get_tag_table (cloud->priv->tbuffer),
+				    (GtkTextTagTableForeach) text_tag_table_foreach_cb2,
+				    (gpointer) &rl);
+	if (rl.tag) {
+		row_clicked (cloud, row, rl.tag);
+		for (list = cloud->priv->selected_tags; list; list = list->next) {
+			gint srow;
+			srow = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (list->data), "row")) - 1;
+			if (srow == row)
+				return TRUE;
+		}
+		return FALSE;
+	}
+	else
+		return FALSE;
+}
+
+static void
+cloud_selector_unselect_row (GdauiDataSelector *iface, gint row)
+{
+	GdauiCloud *cloud;
+	GSList *list;
+
+	cloud = GDAUI_CLOUD (iface);
+	if (cloud->priv->selection_mode == GTK_SELECTION_NONE)
+		return;
+
+	/* test if row already selected */
+	for (list = cloud->priv->selected_tags; list; list = list->next) {
+		gint srow;
+		GtkTextTag *tag = (GtkTextTag*) list->data;
+		srow = GPOINTER_TO_INT (g_object_get_data ((GObject*) tag, "row")) - 1;
+		if (srow == row) {
+			cloud->priv->selected_tags = g_slist_remove (cloud->priv->selected_tags, tag);
+			g_object_set ((GObject*) tag,
+				      "background-set", FALSE,
+				      NULL);
+			g_object_unref ((GObject*) tag);
+
+			sync_iter_with_selection (cloud);
+			g_signal_emit_by_name (cloud, "selection-changed");
+			break;
+		}
+	}
+}
+
+static void
+cloud_selector_set_column_visible (GdauiDataSelector *iface, gint column, gboolean visible)
+{
+	/* nothing to do */
+}
diff --git a/libgda-ui/gdaui-cloud.h b/libgda-ui/gdaui-cloud.h
index e2b66a9..b828422 100644
--- a/libgda-ui/gdaui-cloud.h
+++ b/libgda-ui/gdaui-cloud.h
@@ -47,7 +47,6 @@ struct _GdauiCloud
 struct _GdauiCloudClass
 {
 	GtkVBoxClass       parent_class;
-	void            (* selection_changed) (GdauiCloud *cloud);
 	void            (* activate) (GdauiCloud *cloud, gint row);
 };
 
@@ -58,7 +57,6 @@ GType             gdaui_cloud_get_type             (void) G_GNUC_CONST;
 
 GtkWidget        *gdaui_cloud_new                  (GdaDataModel *model, gint label_column, gint weight_column);
 void              gdaui_cloud_set_selection_mode   (GdauiCloud *cloud, GtkSelectionMode mode);
-GList            *gdaui_cloud_get_selection        (GdauiCloud *cloud);
 
 void              gdaui_cloud_filter               (GdauiCloud *cloud, const gchar *filter);
 GtkWidget        *gdaui_cloud_create_filter_widget (GdauiCloud *cloud);
diff --git a/libgda-ui/gdaui-combo.c b/libgda-ui/gdaui-combo.c
index 384ce37..fc8cbc1 100644
--- a/libgda-ui/gdaui-combo.c
+++ b/libgda-ui/gdaui-combo.c
@@ -27,19 +27,26 @@
 #include <gtk/gtk.h>
 #include "gdaui-combo.h"
 #include "gdaui-data-store.h"
+#include "gdaui-data-selector.h"
 
 struct _GdauiComboPrivate {
 	GdaDataModel     *model; /* proxied model (the one when _set_model() is called) */
+	GdaDataModelIter *iter; /* for @model, may be NULL */
 	GdauiDataStore   *store; /* model proxy */
 
 	/* columns of the model to display */
 	gint              n_cols;
 	gint             *cols_index;
+
+	/* columns' chars width if computed, for all the model's columns */
+	gint             *cols_width;
+
+	gulong            changed_id; /* signal handler ID for the "changed" signal */
 };
 
 static void gdaui_combo_class_init   (GdauiComboClass *klass);
 static void gdaui_combo_init         (GdauiCombo *combo,
-					 GdauiComboClass *klass);
+				      GdauiComboClass *klass);
 static void gdaui_combo_set_property (GObject *object,
 				      guint paramid,
 				      const GValue *value,
@@ -51,9 +58,20 @@ static void gdaui_combo_get_property (GObject *object,
 static void gdaui_combo_dispose      (GObject *object);
 static void gdaui_combo_finalize     (GObject *object);
 
+/* GdauiDataSelector interface */
+static void              gdaui_combo_selector_init (GdauiDataSelectorIface *iface);
+static GdaDataModel     *combo_selector_get_model (GdauiDataSelector *iface);
+static void              combo_selector_set_model (GdauiDataSelector *iface, GdaDataModel *model);
+static GArray           *combo_selector_get_selected_rows (GdauiDataSelector *iface);
+static GdaDataModelIter *combo_selector_get_current_selection (GdauiDataSelector *iface);
+static gboolean          combo_selector_select_row (GdauiDataSelector *iface, gint row);
+static void              combo_selector_unselect_row (GdauiDataSelector *iface, gint row);
+static void              combo_selector_set_column_visible (GdauiDataSelector *iface, gint column, gboolean visible);
+
 enum {
 	PROP_0,
-	PROP_MODEL
+	PROP_MODEL,
+	PROP_AS_LIST
 };
 
 /* get a pointer to the parents to be able to call their destructor */
@@ -80,7 +98,15 @@ gdaui_combo_get_type (void)
 			0,
 			(GInstanceInitFunc) gdaui_combo_init
 		};
+
+		static const GInterfaceInfo selector_info = {
+                        (GInterfaceInitFunc) gdaui_combo_selector_init,
+                        NULL,
+                        NULL
+                };
+
 		type = g_type_register_static (GTK_TYPE_COMBO_BOX, "GdauiCombo", &info, 0);
+		g_type_add_interface_static (type, GDAUI_TYPE_DATA_SELECTOR, &selector_info);
 	}
 	return type;
 }
@@ -102,8 +128,26 @@ gdaui_combo_class_init (GdauiComboClass *klass)
 					 g_param_spec_object ("model", _("The data model to display"), NULL, 
 							      GDA_TYPE_DATA_MODEL,
 							      (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+	g_object_class_install_property (object_class, PROP_AS_LIST,
+					 g_param_spec_boolean ("as-list", _("Display popup as list"), NULL, 
+							       FALSE,
+							      (G_PARAM_READABLE | G_PARAM_WRITABLE)));
+}
+
+static void
+gdaui_combo_selector_init (GdauiDataSelectorIface *iface)
+{
+	iface->get_model = combo_selector_get_model;
+	iface->set_model = combo_selector_set_model;
+	iface->get_selected_rows = combo_selector_get_selected_rows;
+	iface->get_current_selection = combo_selector_get_current_selection;
+	iface->select_row = combo_selector_select_row;
+	iface->unselect_row = combo_selector_unselect_row;
+	iface->set_column_visible = combo_selector_set_column_visible;
 }
 
+static void selection_changed_cb (GtkComboBox *widget, gpointer data);
+
 static void
 gdaui_combo_init (GdauiCombo *combo, GdauiComboClass *klass)
 {
@@ -113,15 +157,45 @@ gdaui_combo_init (GdauiCombo *combo, GdauiComboClass *klass)
 	combo->priv = g_new0 (GdauiComboPrivate, 1);
 	combo->priv->model = NULL;
 	combo->priv->store = NULL;
+	combo->priv->iter = NULL;
 
 	gtk_combo_box_set_wrap_width (GTK_COMBO_BOX (combo), 0);
+	combo->priv->changed_id = g_signal_connect (combo, "changed",
+						    G_CALLBACK (selection_changed_cb), NULL);
+}
+
+static void
+sync_iter_with_selection (GdauiCombo *combo)
+{
+	gint selrow = -1;
+	GtkTreeIter iter;
+
+	if (! combo->priv->iter)
+		return;
+
+	/* there is at most one selected row */
+	if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter))
+		selrow = gdaui_data_store_get_row_from_iter (combo->priv->store, &iter);
+	
+	/* update iter */
+	if ((selrow == -1) || !gda_data_model_iter_move_to_row (combo->priv->iter, selrow)) {
+		gda_data_model_iter_invalidate_contents (combo->priv->iter);
+		g_object_set (G_OBJECT (combo->priv->iter), "current-row", -1, NULL);
+	}
+}
+
+static void
+selection_changed_cb (GtkComboBox *widget, gpointer data)
+{
+	sync_iter_with_selection ((GdauiCombo *)widget);
+	g_signal_emit_by_name (widget, "selection-changed");
 }
 
 static void
 gdaui_combo_set_property (GObject *object,
-			     guint param_id,
-			     const GValue *value,
-			     GParamSpec *pspec)
+			  guint param_id,
+			  const GValue *value,
+			  GParamSpec *pspec)
 {
 	GdauiCombo *combo = (GdauiCombo *) object;
 
@@ -130,9 +204,26 @@ gdaui_combo_set_property (GObject *object,
 	switch (param_id) {
 	case PROP_MODEL :
 		gdaui_combo_set_model (combo,
-					  GDA_DATA_MODEL (g_value_get_object (value)),
-					  0, NULL);
+				       GDA_DATA_MODEL (g_value_get_object (value)),
+				       0, NULL);
 		break;
+	case PROP_AS_LIST: {
+		static gboolean rc_done = FALSE;
+		if (!rc_done) {
+			rc_done = TRUE;
+			gtk_rc_parse_string ("style \"gdaui-combo-as-list-style\"\n"
+					     "{\n"
+					     "GtkComboBox::appears-as-list = 1\n"
+					     "GtkComboBox::arrow-size = 10\n"
+					     "}\n"
+					     "widget \"*.gdaui-combo-as-list-style\" style \"gdaui-combo-as-list-style\"");
+		}
+		if (g_value_get_boolean (value))
+			gtk_widget_set_name ((GtkWidget*) combo, "gdaui-combo-as-list-style");
+		else
+			gtk_widget_set_name ((GtkWidget*) combo, NULL);
+		break;
+	}
 	default :
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 		break;
@@ -141,9 +232,9 @@ gdaui_combo_set_property (GObject *object,
 
 static void
 gdaui_combo_get_property (GObject *object,
-			     guint param_id,
-			     GValue *value,
-			     GParamSpec *pspec)
+			  guint param_id,
+			  GValue *value,
+			  GParamSpec *pspec)
 {
 	GdauiCombo *combo = (GdauiCombo *) object;
 
@@ -153,6 +244,12 @@ gdaui_combo_get_property (GObject *object,
 	case PROP_MODEL :
 		g_value_set_object (value, G_OBJECT (combo->priv->model));
 		break;
+	case PROP_AS_LIST: {
+		const gchar *name;
+		name = gtk_widget_get_name ((GtkWidget*) combo);
+		g_value_set_boolean (value, name && !strcmp (name, "gdaui-combo-as-list-style") ? TRUE : FALSE);
+		break;
+	}
 	default :
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 		break;
@@ -168,6 +265,9 @@ gdaui_combo_dispose (GObject *object)
 
 	/* free objects references */
 	if (combo->priv->store) {
+		g_signal_handler_disconnect (combo, combo->priv->changed_id);
+		if (combo->priv->iter)
+			g_object_unref (combo->priv->iter);
 		g_object_unref (G_OBJECT (combo->priv->store));
 		combo->priv->store = NULL;
 	}
@@ -186,6 +286,8 @@ gdaui_combo_finalize (GObject *object)
 	/* free memory */
 	if (combo->priv->cols_index)
 		g_free (combo->priv->cols_index);
+	if (combo->priv->cols_width)
+		g_free (combo->priv->cols_width);
 
 	g_free (combo->priv);
 	combo->priv = NULL;
@@ -200,6 +302,8 @@ gdaui_combo_finalize (GObject *object)
  * Create a new GdauiCombo widget.
  *
  * Returns: the newly-created widget.
+ *
+ * Since: 4.2
  */
 GtkWidget *
 gdaui_combo_new ()
@@ -215,12 +319,14 @@ gdaui_combo_new ()
  * gdaui_combo_new_with_model
  * @model: a #GdaDataModel object.
  * @n_cols: number of columns in the model to be shown
- * @cols_index: index of each column to be shown
+ * @cols_index: an array of columns to be shown, its size must be @n_cols
  *
  * Create a new GdauiCombo widget with a model. See gdaui_combo_set_model() for
  * more information about the @n_cols and @cols_index usage.
  *
  * Returns: the newly-created widget.
+ *
+ * Since: 4.2
  */
 GtkWidget *
 gdaui_combo_new_with_model (GdaDataModel *model, gint n_cols, gint *cols_index)
@@ -243,7 +349,7 @@ static void cell_layout_data_func (GtkCellLayout *cell_layout, GtkCellRenderer *
  * @combo: a #GdauiCombo widget.
  * @model: a #GdaDataModel object.
  * @n_cols: number of columns in the model to be shown
- * @cols_index: index of each column to be shown
+ * @cols_index: an array of columns to be shown, its size must be @n_cols
  *
  * Makes @combo display data stored in @model (makes the
  * combo widget refresh its list of values and display the values contained
@@ -251,11 +357,13 @@ static void cell_layout_data_func (GtkCellLayout *cell_layout, GtkCellRenderer *
  * and disassociate the previous model, if any.
  *
  * if @n_cols is 0, then all the columns of @model will be displayed in @combo.
+ *
+ * Since: 4.2
  */
 void
 gdaui_combo_set_model (GdauiCombo *combo, GdaDataModel *model, gint n_cols, gint *cols_index)
 {
-	gint ln_cols;
+	gint ln_cols, model_ncols = -1;
 	gint *lcols_index;
 	
 	g_return_if_fail (GDAUI_IS_COMBO (combo));
@@ -277,6 +385,11 @@ gdaui_combo_set_model (GdauiCombo *combo, GdaDataModel *model, gint n_cols, gint
 	combo->priv->n_cols = 0;
 	gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo));
 
+	if (combo->priv->cols_width) {
+		g_free (combo->priv->cols_width);
+		combo->priv->cols_width = NULL;
+	}
+
 	/* set model */
 	if (model) {
 		combo->priv->model = model;
@@ -284,11 +397,16 @@ gdaui_combo_set_model (GdauiCombo *combo, GdaDataModel *model, gint n_cols, gint
 		
 		combo->priv->store = GDAUI_DATA_STORE (gdaui_data_store_new (combo->priv->model));
 		gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (combo->priv->store));
-	} 
+		model_ncols = gda_data_model_get_n_columns (model);
+		combo->priv->cols_width = g_new (gint, model_ncols);
+		gint i;
+		for (i = 0; i < model_ncols; i++)
+			combo->priv->cols_width [i] = -1;
+	}
 	
 	if (!n_cols && model) {
 		gint i;
-		ln_cols = gda_data_model_get_n_columns (model);
+		ln_cols = model_ncols;
 		lcols_index = g_new (gint, ln_cols);
 		for (i = 0; i < ln_cols; i++)
 			lcols_index [i] = i;	
@@ -309,8 +427,28 @@ gdaui_combo_set_model (GdauiCombo *combo, GdaDataModel *model, gint n_cols, gint
 		combo->priv->n_cols = ln_cols;
 		memcpy (combo->priv->cols_index, lcols_index, sizeof (gint) * ln_cols);
 
+		/* compute cell renderers' widths in chars */
+		gint j, nrows;
+		const GValue *cvalue;
+		nrows = gda_data_model_get_n_rows (model);
+		for (j = 0; j < nrows; j++) {
+			for (i = 0; i < ln_cols; i++) {
+				cvalue = gda_data_model_get_value_at (model, combo->priv->cols_index [i], j, NULL);
+				if (cvalue && (G_VALUE_TYPE (cvalue) != GDA_TYPE_NULL)) {
+					gchar *str;
+					gint len;
+					dh = gda_get_default_handler (G_VALUE_TYPE (cvalue));
+					str = gda_data_handler_get_str_from_value (dh, cvalue);
+					len = strlen (str);
+					g_free (str);
+					if (len > combo->priv->cols_width [combo->priv->cols_index [i]])
+						combo->priv->cols_width [combo->priv->cols_index [i]] = len;
+				}
+			}
+		}
+
 		/* create cell renderers */
-		for (i=0; i<ln_cols; i++) {
+		for (i = 0; i < ln_cols; i++) {
 			GdaColumn *column;
 			GType type;
 
@@ -323,6 +461,9 @@ gdaui_combo_set_model (GdauiCombo *combo, GdaDataModel *model, gint n_cols, gint
 			renderer = gtk_cell_renderer_text_new ();
 			g_object_set_data (G_OBJECT (renderer), "data_handler", dh);
 			g_object_set_data (G_OBJECT (renderer), "colnum", GINT_TO_POINTER (index));
+			g_object_set ((GObject*) renderer, "width-chars",
+				      combo->priv->cols_width [index], NULL);
+			
 			gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
 			gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), renderer,
 							    (GtkCellLayoutDataFunc) cell_layout_data_func, combo, NULL);
@@ -352,27 +493,8 @@ cell_layout_data_func (GtkCellLayout *cell_layout, GtkCellRenderer *cell,
 	g_free (str);
 }
 
-/**
- * gdaui_combo_get_model
- * @combo: a #GdauiCombo widget.
- *
- * This function returns the #GdaDataModel from which @combo displays values.
- *
- * Returns: a #GdaDataModel containing the data from the #GdauiCombo widget.
- */
-GdaDataModel *
-gdaui_combo_get_model (GdauiCombo *combo)
-{
-	g_return_val_if_fail (GDAUI_IS_COMBO (combo), NULL);
-	g_return_val_if_fail (combo->priv, NULL);
-
-	if (GDA_IS_DATA_MODEL (combo->priv->model)) 
-		return GDA_DATA_MODEL (combo->priv->model);
-	return NULL;
-}
-
-/**
- * gdaui_combo_set_values
+/*
+ * _gdaui_combo_set_selected
  * @combo: a #GdauiCombo widget
  * @values: a list of #GValue
  *
@@ -384,18 +506,17 @@ gdaui_combo_get_model (GdauiCombo *combo)
  * Returns: TRUE if a row in the model was found to match the list of values.
  */
 gboolean
-gdaui_combo_set_values (GdauiCombo *combo, const GSList *values)
+_gdaui_combo_set_selected (GdauiCombo *combo, const GSList *values)
 {
 	g_return_val_if_fail (GDAUI_IS_COMBO (combo), FALSE);
-	g_return_val_if_fail (combo->priv, FALSE);
 	g_return_val_if_fail (combo->priv->cols_index, FALSE);
 	g_return_val_if_fail (g_slist_length ((GSList *) values) == combo->priv->n_cols, FALSE);
 
-	return gdaui_combo_set_values_ext (combo, values, combo->priv->cols_index);
+	return _gdaui_combo_set_selected_ext (combo, values, combo->priv->cols_index);
 }
 
-/**
- * gdaui_combo_get_values
+/*
+ * _gdaui_combo_get_selected
  * @combo: a #GdauiCombo widget
  *
  * Get a list of the currently selected values in @combo. The list itself must be free'd using g_slist_free(), 
@@ -405,22 +526,23 @@ gdaui_combo_set_values (GdauiCombo *combo, const GSList *values)
  * data model was associated to @combo.
  *
  * Returns: a new list of values, or %NULL if there is no displayed data in @combo.
+ *
+ * Since: 4.2
  */
 GSList *
-gdaui_combo_get_values (GdauiCombo *combo)
+_gdaui_combo_get_selected (GdauiCombo *combo)
 {
 	g_return_val_if_fail (GDAUI_IS_COMBO (combo), NULL);
-	g_return_val_if_fail (combo->priv, NULL);
 	if (!combo->priv->store)
 		return NULL;
 	g_return_val_if_fail (combo->priv->n_cols, NULL);
 	g_return_val_if_fail (combo->priv->cols_index, NULL);
 	
-	return gdaui_combo_get_values_ext (combo, combo->priv->n_cols, combo->priv->cols_index);
+	return _gdaui_combo_get_selected_ext (combo, combo->priv->n_cols, combo->priv->cols_index);
 }
 
-/**
- * gdaui_combo_set_values_ext
+/*
+ * _gdaui_combo_set_selected_ext
  * @combo: a #GdauiCombo widget
  * @values: a list of #GValue objects
  * @cols_index: array of gint, index of column to which each value in @values corresponds, or %NULL
@@ -437,13 +559,12 @@ gdaui_combo_get_values (GdauiCombo *combo)
  * Returns: TRUE if a row in the model was found to match the list of values.
  */
 gboolean
-gdaui_combo_set_values_ext (GdauiCombo *combo, const GSList *values, gint *cols_index)
+_gdaui_combo_set_selected_ext (GdauiCombo *combo, const GSList *values, gint *cols_index)
 {
 	gint row;
 	GdaDataProxy *proxy;
 
 	g_return_val_if_fail (GDAUI_IS_COMBO (combo), FALSE);
-	g_return_val_if_fail (combo->priv, FALSE);
 	g_return_val_if_fail (combo->priv->store, FALSE);
 	g_return_val_if_fail (values, FALSE);
 
@@ -454,8 +575,8 @@ gdaui_combo_set_values_ext (GdauiCombo *combo, const GSList *values, gint *cols_
 	return (row >= 0) ? TRUE : FALSE;
 }
 
-/**
- * gdaui_combo_get_values_ext
+/*
+ * _gdaui_combo_get_selected_ext
  * @combo: a #GdauiCombo widget
  * @n_cols: the number of columns for which values are requested
  * @cols_index: an array of @n_cols #gint indicating which column to get a value for, or %NULL
@@ -466,9 +587,11 @@ gdaui_combo_set_values_ext (GdauiCombo *combo, const GSList *values, gint *cols_
  * if n_cols equals 0 and @cols_index is %NULL, then a #GValue will be returned for each column of @combo's data model.
  *
  * Returns: a new list of values, or %NULL if there is no displayed data in @combo.
+ *
+ * Since: 4.2
  */
 GSList *
-gdaui_combo_get_values_ext (GdauiCombo *combo, gint n_cols, gint *cols_index)
+_gdaui_combo_get_selected_ext (GdauiCombo *combo, gint n_cols, gint *cols_index)
 {
 	GtkTreeIter iter;
 	GSList *retval = NULL;
@@ -476,7 +599,6 @@ gdaui_combo_get_values_ext (GdauiCombo *combo, gint n_cols, gint *cols_index)
 	GValue *value;
 
 	g_return_val_if_fail (GDAUI_IS_COMBO (combo), NULL);
-	g_return_val_if_fail (combo->priv, NULL);
 	if (! combo->priv->store)
 		return NULL;
 	if (!n_cols) {
@@ -503,46 +625,215 @@ gdaui_combo_get_values_ext (GdauiCombo *combo, gint n_cols, gint *cols_index)
 }
 
 /**
- * gdaui_combo_add_undef_choice
+ * gdaui_combo_add_null
  * @combo: a #GdauiCombo widget
  * @add_undef_choice:
  *
- * Tells if @combo should add a special entry representing an "undefined choice". The default is
+ * Tells if @combo should add a special entry representing an "undefined choice", as a %NULL entry. The default is
  * that only the available choices in @combo's model are presented.
+ *
+ * Since: 4.2
  */
 void
-gdaui_combo_add_undef_choice (GdauiCombo *combo, gboolean add_undef_choice)
+gdaui_combo_add_null (GdauiCombo *combo, gboolean add_null)
 {
 	g_return_if_fail (GDAUI_IS_COMBO (combo));
-	g_return_if_fail (combo->priv);
 
-	g_object_set (G_OBJECT (combo->priv->store), "prepend_null_entry", add_undef_choice, NULL);
+	g_object_set (G_OBJECT (combo->priv->store), "prepend-null-entry", add_null, NULL);
 }
 
 /**
- * gdaui_combo_undef_selected
+ * gdaui_combo_is_null_selected
  * @combo: a #GdauiCombo widget
  *
  * Tell if the currently selected entry represents the "undefined choice" entry.
  *
  * Returns:
+ *
+ * Since: 4.2
  */
 gboolean
-gdaui_combo_undef_selected (GdauiCombo *combo)
+gdaui_combo_is_null_selected (GdauiCombo *combo)
 {
 	gint active_row;
 	gboolean has_undef_choice;
 
 	g_return_val_if_fail (GDAUI_IS_COMBO (combo), FALSE);
-	g_return_val_if_fail (combo->priv, FALSE);
 
 	active_row = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
 	if (active_row == -1)
 		return TRUE;
 	
-	g_object_get (G_OBJECT (combo->priv->store), "prepend_null_entry", &has_undef_choice, NULL);
+	g_object_get (G_OBJECT (combo->priv->store), "prepend-null-entry", &has_undef_choice, NULL);
 	if (has_undef_choice && (active_row == 0))
 		return TRUE;
 
 	return FALSE;
 }
+
+/* GdauiDataSelector interface */
+static GdaDataModel *
+combo_selector_get_model (GdauiDataSelector *iface)
+{
+	GdauiCombo *combo;
+	combo = GDAUI_COMBO (iface);
+	return combo->priv->model;
+}
+
+static void
+combo_selector_set_model (GdauiDataSelector *iface, GdaDataModel *model)
+{
+	g_object_set (G_OBJECT (iface), "model", model, NULL);
+}
+
+static GArray *
+combo_selector_get_selected_rows (GdauiDataSelector *iface)
+{
+	GtkTreeIter iter;
+	GArray *retval = NULL;
+	GdauiCombo *combo;
+
+	combo = GDAUI_COMBO (iface);
+
+	/* there is at most one selected row */
+	if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter)) {
+		gint row;
+		row = gdaui_data_store_get_row_from_iter (combo->priv->store, &iter);
+		if (row >=0) {
+			if (!retval)
+				retval = g_array_new (FALSE, FALSE, sizeof (gint));
+			g_array_append_val (retval, row);
+		}
+	}
+
+	return retval;
+}
+
+static GdaDataModelIter *
+combo_selector_get_current_selection (GdauiDataSelector *iface)
+{
+	GdauiCombo *combo;
+
+	combo = GDAUI_COMBO (iface);
+	if (! combo->priv->iter && combo->priv->model) {
+		GdaDataModel *proxy;
+		proxy = (GdaDataModel*) gdaui_data_store_get_proxy (combo->priv->store);
+		combo->priv->iter = gda_data_model_create_iter (proxy);
+		sync_iter_with_selection (combo);
+	}
+
+	return combo->priv->iter;
+}
+
+static gboolean
+combo_selector_select_row (GdauiDataSelector *iface, gint row)
+{
+	GdauiCombo *combo;
+	GtkTreeIter iter;
+
+	combo = GDAUI_COMBO (iface);
+	gtk_combo_box_set_active (GTK_COMBO_BOX (combo), row);
+	if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter)) {
+		gint srow;
+		srow = gdaui_data_store_get_row_from_iter (combo->priv->store, &iter);
+		if (srow == row)
+			return TRUE;
+	}
+	return FALSE;
+}
+
+static void
+combo_selector_unselect_row (GdauiDataSelector *iface, gint row)
+{
+	GdauiCombo *combo;
+	GtkTreeIter iter;
+
+	combo = GDAUI_COMBO (iface);
+	if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter)) {
+		gint srow;
+		srow = gdaui_data_store_get_row_from_iter (combo->priv->store, &iter);
+		if (srow == row)
+			gtk_combo_box_set_active (GTK_COMBO_BOX (combo), -1);
+	}
+}
+
+static void
+combo_selector_set_column_visible (GdauiDataSelector *iface, gint column, gboolean visible)
+{
+	GdauiCombo *combo;
+	combo = GDAUI_COMBO (iface);
+
+	/* analyse existing columns */
+	GList *cells, *list;
+	gint cellpos;
+	cells = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (iface));
+	for (cellpos = 0, list = cells;
+	     list;
+	     cellpos ++, list = list->next) {
+		gint col;
+		col = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (list->data), "colnum"));
+		if (col == column) {
+			g_object_set (G_OBJECT (list->data), "visible", visible, NULL);
+			g_list_free (cells);
+			return;
+		}
+		else if (col > column)
+			break;
+	}
+	g_list_free (cells);
+
+	/* column does not exist at this point */
+	if (!visible || !combo->priv->model)
+		return;
+	if ((column < 0) || (column >= gda_data_model_get_n_columns (combo->priv->model))) {
+		g_warning (_("Column %d out of range (0-%d)"), column, gda_data_model_get_n_columns (combo->priv->model)-1);
+		return;
+	}
+
+	GdaDataHandler *dh;
+	if (combo->priv->cols_width[column] == -1) {
+		/* compute column width in chars */
+		gint j, nrows;
+		const GValue *cvalue;
+		nrows = gda_data_model_get_n_rows (combo->priv->model);
+		for (j = 0; j < nrows; j++) {
+			cvalue = gda_data_model_get_value_at (combo->priv->model, column, j, NULL);
+			if (cvalue && (G_VALUE_TYPE (cvalue) != GDA_TYPE_NULL)) {
+				gchar *str;
+				gint len;
+				dh = gda_get_default_handler (G_VALUE_TYPE (cvalue));
+				str = gda_data_handler_get_str_from_value (dh, cvalue);
+				len = strlen (str);
+				g_free (str);
+				if (len > combo->priv->cols_width [column])
+					combo->priv->cols_width [column] = len;
+			}
+		}
+	}
+
+	/* create cell renderer */
+	GdaColumn *mcolumn;
+	GType type;
+	GtkCellRenderer *renderer;
+
+	mcolumn = gda_data_model_describe_column (combo->priv->model, column);
+	type = gda_column_get_g_type (mcolumn);
+	dh = gda_get_default_handler (type);
+	
+	renderer = gtk_cell_renderer_text_new ();
+	g_object_set_data (G_OBJECT (renderer), "data_handler", dh);
+	g_object_set_data (G_OBJECT (renderer), "colnum", GINT_TO_POINTER (column));
+	
+	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
+	gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), renderer,
+					    (GtkCellLayoutDataFunc) cell_layout_data_func, combo, NULL);
+	gtk_cell_layout_reorder (GTK_CELL_LAYOUT (combo), renderer, cellpos);
+	g_object_set ((GObject*) renderer, "width-chars",
+		      combo->priv->cols_width [column], NULL);
+	/* Don't unref the renderer! */
+
+	gint ww;
+	g_object_get ((GObject*) iface, "wrap-width", &ww, NULL);
+	g_object_set ((GObject*) iface, "wrap-width", 1, NULL);
+	g_object_set ((GObject*) iface, "wrap-width", ww, NULL);
+}
diff --git a/libgda-ui/gdaui-combo.h b/libgda-ui/gdaui-combo.h
index 852c487..fcb4ff2 100644
--- a/libgda-ui/gdaui-combo.h
+++ b/libgda-ui/gdaui-combo.h
@@ -42,7 +42,7 @@ typedef struct _GdauiComboPrivate GdauiComboPrivate;
 
 struct _GdauiCombo {
 	GtkComboBox          object;
-	GdauiComboPrivate *priv;
+	GdauiComboPrivate   *priv;
 };
 
 struct _GdauiComboClass {
@@ -55,15 +55,15 @@ GtkWidget    *gdaui_combo_new              (void);
 GtkWidget    *gdaui_combo_new_with_model   (GdaDataModel *model, gint n_cols, gint *cols_index);
 
 void          gdaui_combo_set_model        (GdauiCombo *combo, GdaDataModel *model, gint n_cols, gint *cols_index);
-GdaDataModel *gdaui_combo_get_model        (GdauiCombo *combo);
-void          gdaui_combo_add_undef_choice (GdauiCombo *combo, gboolean add_undef_choice);
+void          gdaui_combo_add_null         (GdauiCombo *combo, gboolean add_null);
+gboolean      gdaui_combo_is_null_selected (GdauiCombo *combo);
 
-gboolean      gdaui_combo_set_values       (GdauiCombo *combo, const GSList *values);
-GSList       *gdaui_combo_get_values       (GdauiCombo *combo);
-gboolean      gdaui_combo_undef_selected   (GdauiCombo *combo);
 
-gboolean      gdaui_combo_set_values_ext   (GdauiCombo *combo, const GSList *values, gint *cols_index);
-GSList       *gdaui_combo_get_values_ext   (GdauiCombo *combo, gint n_cols, gint *cols_index);
+/* private API */
+gboolean      _gdaui_combo_set_selected     (GdauiCombo *combo, const GSList *values);
+GSList       *_gdaui_combo_get_selected     (GdauiCombo *combo);
+gboolean      _gdaui_combo_set_selected_ext (GdauiCombo *combo, const GSList *values, gint *cols_index);
+GSList       *_gdaui_combo_get_selected_ext (GdauiCombo *combo, gint n_cols, gint *cols_index);
 
 
 G_END_DECLS
diff --git a/libgda-ui/gdaui-data-entry.c b/libgda-ui/gdaui-data-entry.c
index 9d623fd..83a7e86 100644
--- a/libgda-ui/gdaui-data-entry.c
+++ b/libgda-ui/gdaui-data-entry.c
@@ -21,28 +21,8 @@
 #include "gdaui-data-entry.h"
 #include "marshallers/gdaui-marshal.h"
 
-
-/* Description:
- *
- * This interface is used to access any widget which implements basic data editing (usually an editing
- * area and a button to have some more control on the value being edited).
- *
- * The interface allows to control how the widget works and to query the value and the attributes
- * of the data held by the widget.
- *
- * The widget can store the original value (to be able to tell if the value has been changed
- * by the user) and a default value (which will be returned if the user explicitly forces the widget
- * to be set to the default value).
- *
- * Control methods allow to set the type of value to be edited (the requested type must be 
- * compatible with what the widget can handle), set the value (which replaces the currently edited
- * value), set the value and the original value (the value passed as argument is set and is also
- * considered to be the original value).
- */
-
 /* signals */
-enum
-{
+enum {
 	CONTENTS_MODIFIED,
 	CONTENTS_ACTIVATED,
 	STATUS_CHANGED,
@@ -70,7 +50,7 @@ gdaui_data_entry_get_type (void)
 			0,
 			(GInstanceInitFunc) NULL
 		};
-		
+
 		type = g_type_register_static (G_TYPE_INTERFACE, "GdauiDataEntry", &info, 0);
 	}
 	return type;
@@ -78,14 +58,14 @@ gdaui_data_entry_get_type (void)
 
 static gboolean
 contents_valid_accumulator (GSignalInvocationHint *ihint,
-		   GValue *return_accu,
-		   const GValue *handler_return,
-		   gpointer data)
+			    GValue *return_accu,
+			    const GValue *handler_return,
+			    gpointer data)
 {
         gboolean thisvalue;
 
         thisvalue = g_value_get_boolean (handler_return);
-        g_value_set_boolean (return_accu, thisvalue); 
+        g_value_set_boolean (return_accu, thisvalue);
 
         return thisvalue; /* stop signal if 'thisvalue' is FALSE */
 }
@@ -143,10 +123,12 @@ gdaui_data_entry_iface_init (gpointer g_class)
 /**
  * gdaui_data_entry_set_value_type
  * @de: a #GtkWidget object which implements the #GdauiDataEntry interface
- * @type: 
+ * @type:
  *
  * Sets the type of value the GdauiDataEntry will handle. The type must be compatible with what
  * the widget can handle.
+ *
+ * Since: 4.2
  */
 void
 gdaui_data_entry_set_value_type (GdauiDataEntry *de, GType type)
@@ -165,6 +147,8 @@ gdaui_data_entry_set_value_type (GdauiDataEntry *de, GType type)
  * Fetch the type of data the GdauiDataEntry handles
  *
  * Returns: the GType type
+ *
+ * Since: 4.2
  */
 GType
 gdaui_data_entry_get_value_type (GdauiDataEntry *de)
@@ -179,14 +163,18 @@ gdaui_data_entry_get_value_type (GdauiDataEntry *de)
 /**
  * gdaui_data_entry_set_value
  * @de: a #GtkWidget object which implements the #GdauiDataEntry interface
- * @value: 
+ * @value: a #GValue, or %NULL
  *
  * Push a value into the GdauiDataEntry. The value parameter must either be:
- * - NULL or of type GDA_TYPE_NULL, or
- * - of type specified using gdaui_data_entry_set_value_type.
+ * <itemizedlist>
+ *   <listitem><para>NULL or of type GDA_TYPE_NULL, or</para></listitem>
+ *   <listitem><para>of type specified using gdaui_data_entry_set_value_type().</para></listitem>
+ * </itemizedlist>
+ *
+ * Since: 4.2
  */
 void
-gdaui_data_entry_set_value (GdauiDataEntry *de, const GValue * value)
+gdaui_data_entry_set_value (GdauiDataEntry *de, const GValue *value)
 {
 	g_return_if_fail (GDAUI_IS_DATA_ENTRY (de));
 
@@ -203,7 +191,9 @@ gdaui_data_entry_set_value (GdauiDataEntry *de, const GValue * value)
  * then the returned value is of type GDA_TYPE_NULL or is the default value if it
  * has been provided to the widget (and is of the same type as the one provided by @de).
  *
- * Returns: a new GValue
+ * Returns: a new #GValue
+ *
+ * Since: 4.2
  */
 GValue *
 gdaui_data_entry_get_value (GdauiDataEntry *de)
@@ -223,11 +213,13 @@ gdaui_data_entry_get_value (GdauiDataEntry *de)
  *
  * Tests the validity of @de's contents. The validity is a determined from:
  * <itemizedlist>
- * <listitem><para>the @de widget itself if it is capable of doing it (depending on the implementation)</para></listitem>
- * <listitem><para>the results of the "contents_valid" signal which can be connected from </para></listitem>
+ *   <listitem><para>the @de widget itself if it is capable of doing it (depending on the implementation)</para></listitem>
+ *   <listitem><para>the results of the "contents_valid" signal which can be connected from </para></listitem>
  * </itemizedlist>
  *
  * Returns: TRUE if @de's contents is valid
+ *
+ * Since: 4.2
  */
 gboolean
 gdaui_data_entry_content_is_valid (GdauiDataEntry *de, GError **error)
@@ -243,10 +235,12 @@ gdaui_data_entry_content_is_valid (GdauiDataEntry *de, GError **error)
 /**
  * gdaui_data_entry_set_original_value
  * @de: a #GtkWidget object which implements the #GdauiDataEntry interface
- * @value: 
+ * @value: a #GValue, or %NULL
  *
  * Push a value into the GdauiDataEntry in the same way as gdaui_data_entry_set_value() but
  * also sets this value as the original value.
+ *
+ * Since: 4.2
  */
 void
 gdaui_data_entry_set_original_value (GdauiDataEntry *de, const GValue *value)
@@ -262,13 +256,15 @@ gdaui_data_entry_set_original_value (GdauiDataEntry *de, const GValue *value)
  * @de: a #GtkWidget object which implements the #GdauiDataEntry interface
  *
  * Tells that the current value in @de is to be considered as the original value
+ *
+ * Since: 4.2
  */
 void
 gdaui_data_entry_reset (GdauiDataEntry *de)
 {
 	GValue *value;
 	g_return_if_fail (GDAUI_IS_DATA_ENTRY (de));
-	
+
 	value = gdaui_data_entry_get_value (de);
 	gdaui_data_entry_set_original_value (de, value);
 	if (value)
@@ -282,7 +278,9 @@ gdaui_data_entry_reset (GdauiDataEntry *de)
  *
  * Fetch the original value held in the GdauiDataEntry widget
  *
- * Returns: the GValue
+ * Returns: the #GValue (not modifiable)
+ *
+ * Since: 4.2
  */
 const GValue *
 gdaui_data_entry_get_original_value (GdauiDataEntry *de)
@@ -299,13 +297,17 @@ gdaui_data_entry_get_original_value (GdauiDataEntry *de)
 /**
  * gdaui_data_entry_set_value_default
  * @de: a #GtkWidget object which implements the #GdauiDataEntry interface
- * @value: 
+ * @value: a #GValue, or %NULL
  *
  * Sets the default value for the GdauiDataEntry which gets displayed when the
  * user forces the default value. If it is not set then it is set to type GDA_TYPE_NULL.
  * The value parameter must either be:
- * - NULL or of type GDA_TYPE_NULL, or
- * - of type specified using gdaui_data_entry_set_value_type.
+ * <itemizedlist>
+ *   <listitem><para>NULL or of type GDA_TYPE_NULL, or</para></listitem>
+ *   <listitem><para>of type specified using gdaui_data_entry_set_value_type().</para></listitem>
+ * </itemizedlist>
+ *
+ * Since: 4.2
  */
 void
 gdaui_data_entry_set_value_default (GdauiDataEntry *de, const GValue *value)
@@ -325,6 +327,8 @@ gdaui_data_entry_set_value_default (GdauiDataEntry *de, const GValue *value)
  *
  * Sets the parameters of the GdauiDataEntry. Only the attributes corresponding to the
  * mask are set, the other ones are ignored.
+ *
+ * Since: 4.2
  */
 void
 gdaui_data_entry_set_attributes (GdauiDataEntry *de, GdaValueAttribute attrs, GdaValueAttribute mask)
@@ -342,6 +346,8 @@ gdaui_data_entry_set_attributes (GdauiDataEntry *de, GdaValueAttribute attrs, Gd
  * Retrieves the parameters of the GdauiDataEntry widget.
  *
  * Returns: the OR'ed bits corresponding to the attributes.
+ *
+ * Since: 4.2
  */
 GdaValueAttribute
 gdaui_data_entry_get_attributes (GdauiDataEntry *de)
@@ -358,10 +364,12 @@ gdaui_data_entry_get_attributes (GdauiDataEntry *de)
 /**
  * gdaui_data_entry_get_handler
  * @de: a #GtkWidget object which implements the #GdauiDataEntry interface
- * 
+ *
  * Fetch the GdaDataHandler the GdauiDataEntry is using
  *
  * Returns: the GdaDataHandler object
+ *
+ * Since: 4.2
  */
 GdaDataHandler  *
 gdaui_data_entry_get_handler (GdauiDataEntry *de)
@@ -381,6 +389,8 @@ gdaui_data_entry_get_handler (GdauiDataEntry *de)
  * Used for the layout of the widget in containers.
  *
  * Returns: TRUE if the widget should expand
+ *
+ * Since: 4.2
  */
 gboolean
 gdaui_data_entry_expand_in_layout (GdauiDataEntry *de)
@@ -396,9 +406,11 @@ gdaui_data_entry_expand_in_layout (GdauiDataEntry *de)
 /**
  * gdaui_data_entry_set_editable
  * @de: a #GtkWidget object which implements the #GdauiDataEntry interface
- * @editable:
+ * @editable: set to %TRUE to have an editable data entry
  *
  * Set if @de can be modified or not by the user
+ *
+ * Since: 4.2
  */
 void
 gdaui_data_entry_set_editable (GdauiDataEntry *de, gboolean editable)
@@ -416,6 +428,8 @@ gdaui_data_entry_set_editable (GdauiDataEntry *de, gboolean editable)
  * @de: a #GtkWidget object which implements the #GdauiDataEntry interface
  *
  * Makes @de grab the focus for the window it's in
+ *
+ * Since: 4.2
  */
 void
 gdaui_data_entry_grab_focus (GdauiDataEntry *de)
diff --git a/libgda-ui/gdaui-data-widget-filter.c b/libgda-ui/gdaui-data-filter.c
similarity index 68%
rename from libgda-ui/gdaui-data-widget-filter.c
rename to libgda-ui/gdaui-data-filter.c
index 418a689..8d29a77 100644
--- a/libgda-ui/gdaui-data-widget-filter.c
+++ b/libgda-ui/gdaui-data-filter.c
@@ -1,4 +1,4 @@
-/* gdaui-data-widget-filter.c
+/* gdaui-data-filter.c
  *
  * Copyright (C) 2007 - 2009 Vivien Malerba
  *
@@ -21,36 +21,36 @@
 #include <string.h>
 #include <glib/gi18n-lib.h>
 #include <libgda/libgda.h>
-#include "gdaui-data-widget.h"
-#include "gdaui-data-widget-filter.h"
+#include "gdaui-data-proxy.h"
+#include "gdaui-data-filter.h"
 
-static void gdaui_data_widget_filter_class_init (GdauiDataWidgetFilterClass * class);
-static void gdaui_data_widget_filter_init (GdauiDataWidgetFilter *wid);
-static void gdaui_data_widget_filter_dispose (GObject *object);
+static void gdaui_data_filter_class_init (GdauiDataFilterClass * class);
+static void gdaui_data_filter_init (GdauiDataFilter *wid);
+static void gdaui_data_filter_dispose (GObject *object);
 
-static void gdaui_data_widget_filter_set_property (GObject *object,
-						    guint param_id,
-						    const GValue *value,
-						    GParamSpec *pspec);
-static void gdaui_data_widget_filter_get_property (GObject *object,
-						    guint param_id,
-						    GValue *value,
-						    GParamSpec *pspec);
+static void gdaui_data_filter_set_property (GObject *object,
+					    guint param_id,
+					    const GValue *value,
+					    GParamSpec *pspec);
+static void gdaui_data_filter_get_property (GObject *object,
+					    guint param_id,
+					    GValue *value,
+					    GParamSpec *pspec);
 
 
 /* callbacks */
-static void proxy_filter_changed_cb (GdaDataProxy *proxy, GdauiDataWidgetFilter *filter);
-static void release_proxy (GdauiDataWidgetFilter *filter);
-static void data_widget_destroyed_cb (GdauiDataWidget *wid, GdauiDataWidgetFilter *filter);
-static void data_widget_proxy_changed_cb (GdauiDataWidget *data_widget, 
-					  GdaDataProxy *proxy, GdauiDataWidgetFilter *filter);
+static void proxy_filter_changed_cb (GdaDataProxy *proxy, GdauiDataFilter *filter);
+static void release_proxy (GdauiDataFilter *filter);
+static void data_widget_destroyed_cb (GdauiDataProxy *wid, GdauiDataFilter *filter);
+static void data_widget_proxy_changed_cb (GdauiDataProxy *data_widget, 
+					  GdaDataProxy *proxy, GdauiDataFilter *filter);
 
-static void clear_filter_cb (GtkButton *button, GdauiDataWidgetFilter *filter);
-static void apply_filter_cb (GtkButton *button, GdauiDataWidgetFilter *filter);
+static void clear_filter_cb (GtkButton *button, GdauiDataFilter *filter);
+static void apply_filter_cb (GtkButton *button, GdauiDataFilter *filter);
 
-struct _GdauiDataWidgetFilterPriv
+struct _GdauiDataFilterPriv
 {
-	GdauiDataWidget *data_widget;
+	GdauiDataProxy   *data_widget;
 	GdaDataProxy      *proxy;
 
 	GtkWidget         *filter_entry;
@@ -61,52 +61,51 @@ struct _GdauiDataWidgetFilterPriv
 static GObjectClass *parent_class = NULL;
 
 /* properties */
-enum
-{
-        PROP_0,
-        PROP_DATA_WIDGET
+enum {
+	PROP_0,
+	PROP_DATA_WIDGET
 };
 
 GType
-gdaui_data_widget_filter_get_type (void)
+gdaui_data_filter_get_type (void)
 {
 	static GType type = 0;
 
 	if (G_UNLIKELY (type == 0)) {
 		static const GTypeInfo filter = {
-			sizeof (GdauiDataWidgetFilterClass),
+			sizeof (GdauiDataFilterClass),
 			(GBaseInitFunc) NULL,
 			(GBaseFinalizeFunc) NULL,
-			(GClassInitFunc) gdaui_data_widget_filter_class_init,
+			(GClassInitFunc) gdaui_data_filter_class_init,
 			NULL,
 			NULL,
-			sizeof (GdauiDataWidgetFilter),
+			sizeof (GdauiDataFilter),
 			0,
-			(GInstanceInitFunc) gdaui_data_widget_filter_init
+			(GInstanceInitFunc) gdaui_data_filter_init
 		};		
 
-		type = g_type_register_static (GTK_TYPE_VBOX, "GdauiDataWidgetFilter", &filter, 0);
+		type = g_type_register_static (GTK_TYPE_VBOX, "GdauiDataFilter", &filter, 0);
 	}
 
 	return type;
 }
 
 static void
-gdaui_data_widget_filter_class_init (GdauiDataWidgetFilterClass * class)
+gdaui_data_filter_class_init (GdauiDataFilterClass * class)
 {
 	GObjectClass   *object_class = G_OBJECT_CLASS (class);
 	
 	parent_class = g_type_class_peek_parent (class);
 
 
-	object_class->dispose = gdaui_data_widget_filter_dispose;
+	object_class->dispose = gdaui_data_filter_dispose;
 
 	/* Properties */
-        object_class->set_property = gdaui_data_widget_filter_set_property;
-        object_class->get_property = gdaui_data_widget_filter_get_property;
+        object_class->set_property = gdaui_data_filter_set_property;
+        object_class->get_property = gdaui_data_filter_get_property;
 	g_object_class_install_property (object_class, PROP_DATA_WIDGET,
-                                         g_param_spec_object ("data_widget", NULL, NULL, GDAUI_TYPE_DATA_WIDGET,
-                                                               G_PARAM_READABLE | G_PARAM_WRITABLE));
+                                         g_param_spec_object ("data-widget", NULL, NULL, GDAUI_TYPE_DATA_PROXY,
+							      G_PARAM_READABLE | G_PARAM_WRITABLE));
 }
 
 static void
@@ -137,12 +136,12 @@ unset_wait_cursor (GtkWidget *w)
 #if GTK_CHECK_VERSION(2,18,0)
 		gdk_window_set_cursor (gtk_widget_get_window (parent), NULL);
 #else
-		gdk_window_set_cursor (parent->window, NULL);
+	gdk_window_set_cursor (parent->window, NULL);
 #endif
 }
 
 static void
-apply_filter_cb (GtkButton *button, GdauiDataWidgetFilter *filter)
+apply_filter_cb (GtkButton *button, GdauiDataFilter *filter)
 {
 	const gchar *expr;
 	gchar *err = NULL;
@@ -189,19 +188,19 @@ apply_filter_cb (GtkButton *button, GdauiDataWidgetFilter *filter)
 }
 
 static void
-clear_filter_cb (GtkButton *button, GdauiDataWidgetFilter *filter)
+clear_filter_cb (GtkButton *button, GdauiDataFilter *filter)
 {
 	gtk_entry_set_text (GTK_ENTRY (filter->priv->filter_entry), "");
 	apply_filter_cb (button, filter);
 }
 
 static void
-gdaui_data_widget_filter_init (GdauiDataWidgetFilter * wid)
+gdaui_data_filter_init (GdauiDataFilter * wid)
 {
 	GtkWidget *table, *label, *entry, *button, *bbox;
 	gchar *str;
 
-	wid->priv = g_new0 (GdauiDataWidgetFilterPriv, 1);
+	wid->priv = g_new0 (GdauiDataFilterPriv, 1);
 	wid->priv->data_widget = NULL;
 	wid->priv->proxy = NULL;
 
@@ -244,29 +243,31 @@ gdaui_data_widget_filter_init (GdauiDataWidgetFilter * wid)
 }
 
 /**
- * gdaui_data_widget_filter_new
- * @data_widget: a widget implementing the #GdauiDataWidget interface
+ * gdaui_data_filter_new
+ * @data_widget: a widget implementing the #GdauiDataProxy interface
  *
- * Creates a new #GdauiDataWidgetFilter widget suitable to change the filter expression
+ * Creates a new #GdauiDataFilter widget suitable to change the filter expression
  * for @data_widget's displayed rows
  *
  * Returns: the new widget
+ *
+ * Since: 4.2
  */
 GtkWidget *
-gdaui_data_widget_filter_new (GdauiDataWidget *data_widget)
+gdaui_data_filter_new (GdauiDataProxy *data_widget)
 {
 	GtkWidget *filter;
 
-	g_return_val_if_fail (!data_widget || GDAUI_IS_DATA_WIDGET (data_widget), NULL);
+	g_return_val_if_fail (!data_widget || GDAUI_IS_DATA_PROXY (data_widget), NULL);
 
-	filter = (GtkWidget *) g_object_new (GDAUI_TYPE_DATA_WIDGET_FILTER, 
+	filter = (GtkWidget *) g_object_new (GDAUI_TYPE_DATA_FILTER, 
 					     "data_widget", data_widget, NULL);
 
 	return filter;
 }
 
 static void
-data_widget_destroyed_cb (GdauiDataWidget *wid, GdauiDataWidgetFilter *filter)
+data_widget_destroyed_cb (GdauiDataProxy *wid, GdauiDataFilter *filter)
 {
 	g_assert (wid == filter->priv->data_widget);
 	g_signal_handlers_disconnect_by_func (G_OBJECT (wid),
@@ -278,7 +279,7 @@ data_widget_destroyed_cb (GdauiDataWidget *wid, GdauiDataWidgetFilter *filter)
 }
 
 static void
-proxy_filter_changed_cb (GdaDataProxy *proxy, GdauiDataWidgetFilter *filter)
+proxy_filter_changed_cb (GdaDataProxy *proxy, GdauiDataFilter *filter)
 {
 	const gchar *expr;
 
@@ -288,7 +289,7 @@ proxy_filter_changed_cb (GdaDataProxy *proxy, GdauiDataWidgetFilter *filter)
 }
 
 static void
-release_proxy (GdauiDataWidgetFilter *filter)
+release_proxy (GdauiDataFilter *filter)
 {
 	g_signal_handlers_disconnect_by_func (G_OBJECT (filter->priv->proxy),
 					      G_CALLBACK (proxy_filter_changed_cb), filter);
@@ -297,19 +298,19 @@ release_proxy (GdauiDataWidgetFilter *filter)
 }
 
 static void
-data_widget_proxy_changed_cb (GdauiDataWidget *data_widget, GdaDataProxy *proxy, GdauiDataWidgetFilter *filter)
+data_widget_proxy_changed_cb (GdauiDataProxy *data_widget, GdaDataProxy *proxy, GdauiDataFilter *filter)
 {
 	g_object_set (G_OBJECT (filter), "data_widget", data_widget, NULL);
 }
 
 static void
-gdaui_data_widget_filter_dispose (GObject *object)
+gdaui_data_filter_dispose (GObject *object)
 {
-	GdauiDataWidgetFilter *filter;
+	GdauiDataFilter *filter;
 
 	g_return_if_fail (object != NULL);
-	g_return_if_fail (GDAUI_IS_DATA_WIDGET_FILTER (object));
-	filter = GDAUI_DATA_WIDGET_FILTER (object);
+	g_return_if_fail (GDAUI_IS_DATA_FILTER (object));
+	filter = GDAUI_DATA_FILTER (object);
 
 	if (filter->priv) {
 		if (filter->priv->proxy)
@@ -327,14 +328,14 @@ gdaui_data_widget_filter_dispose (GObject *object)
 }
 
 static void
-gdaui_data_widget_filter_set_property (GObject *object,
-					guint param_id,
-					const GValue *value,
-					GParamSpec *pspec)
+gdaui_data_filter_set_property (GObject *object,
+				guint param_id,
+				const GValue *value,
+				GParamSpec *pspec)
 {
-	GdauiDataWidgetFilter *filter;
+	GdauiDataFilter *filter;
 
-        filter = GDAUI_DATA_WIDGET_FILTER (object);
+        filter = GDAUI_DATA_FILTER (object);
         if (filter->priv) {
                 switch (param_id) {
                 case PROP_DATA_WIDGET:
@@ -343,7 +344,7 @@ gdaui_data_widget_filter_set_property (GObject *object,
 			if (filter->priv->proxy)
 				release_proxy (filter);
 
-			filter->priv->data_widget = GDAUI_DATA_WIDGET(g_value_get_object (value));
+			filter->priv->data_widget = GDAUI_DATA_PROXY (g_value_get_object (value));
 			if (filter->priv->data_widget) {
 				GdaDataProxy *proxy;
 
@@ -354,7 +355,7 @@ gdaui_data_widget_filter_set_property (GObject *object,
 						  G_CALLBACK (data_widget_proxy_changed_cb), filter);
 
 				/* proxy */
-				proxy = gdaui_data_widget_get_proxy (filter->priv->data_widget);
+				proxy = gdaui_data_proxy_get_proxy (filter->priv->data_widget);
 				if (proxy) {
 					filter->priv->proxy = proxy;
 					g_object_ref (filter->priv->proxy);
@@ -372,14 +373,14 @@ gdaui_data_widget_filter_set_property (GObject *object,
 }
 
 static void
-gdaui_data_widget_filter_get_property (GObject *object,
-					guint param_id,
-					GValue *value,
-					GParamSpec *pspec)
+gdaui_data_filter_get_property (GObject *object,
+				guint param_id,
+				GValue *value,
+				GParamSpec *pspec)
 {
-	GdauiDataWidgetFilter *filter;
+	GdauiDataFilter *filter;
 
-        filter = GDAUI_DATA_WIDGET_FILTER (object);
+        filter = GDAUI_DATA_FILTER (object);
         if (filter->priv) {
                 switch (param_id) {
 		case PROP_DATA_WIDGET:
diff --git a/libgda-ui/gdaui-data-filter.h b/libgda-ui/gdaui-data-filter.h
new file mode 100644
index 0000000..a7bd160
--- /dev/null
+++ b/libgda-ui/gdaui-data-filter.h
@@ -0,0 +1,66 @@
+/* gdaui-data-filter.h
+ *
+ * Copyright (C) 2007 - 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_DATA_FILTER__
+#define __GDAUI_DATA_FILTER__
+
+#include <gtk/gtk.h>
+#include <libgda/gda-decl.h>
+#include <libgda-ui/gdaui-decl.h>
+
+G_BEGIN_DECLS
+
+#define GDAUI_TYPE_DATA_FILTER          (gdaui_data_filter_get_type())
+#define GDAUI_DATA_FILTER(obj)          G_TYPE_CHECK_INSTANCE_CAST (obj, gdaui_data_filter_get_type(), GdauiDataFilter)
+#define GDAUI_DATA_FILTER_CLASS(klass)  G_TYPE_CHECK_CLASS_CAST (klass, gdaui_data_filter_get_type (), GdauiDataFilterClass)
+#define GDAUI_IS_DATA_FILTER(obj)       G_TYPE_CHECK_INSTANCE_TYPE (obj, gdaui_data_filter_get_type ())
+
+
+typedef struct _GdauiDataFilter      GdauiDataFilter;
+typedef struct _GdauiDataFilterClass GdauiDataFilterClass;
+typedef struct _GdauiDataFilterPriv  GdauiDataFilterPriv;
+
+/* struct for the object's data */
+struct _GdauiDataFilter
+{
+	GtkVBox                      object;
+
+	GdauiDataFilterPriv *priv;
+};
+
+/* struct for the object's class */
+struct _GdauiDataFilterClass
+{
+	GtkVBoxClass                 parent_class;
+};
+
+/* 
+ * Generic widget's methods 
+ */
+GType             gdaui_data_filter_get_type                  (void) G_GNUC_CONST;
+
+GtkWidget        *gdaui_data_filter_new                       (GdauiDataProxy *data_widget);
+
+G_END_DECLS
+
+#endif
+
+
+
diff --git a/libgda-ui/gdaui-data-widget-info.c b/libgda-ui/gdaui-data-proxy-info.c
similarity index 66%
rename from libgda-ui/gdaui-data-widget-info.c
rename to libgda-ui/gdaui-data-proxy-info.c
index ed74354..69e3eeb 100644
--- a/libgda-ui/gdaui-data-widget-info.c
+++ b/libgda-ui/gdaui-data-proxy-info.c
@@ -1,4 +1,4 @@
-/* gdaui-data-widget-info.c
+/* gdaui-data-proxy-info.c
  *
  * Copyright (C) 2006 - 2009 Vivien Malerba <malerba gnome-db org>
  *
@@ -21,41 +21,41 @@
 #include <string.h>
 #include <glib/gi18n-lib.h>
 #include <libgda/libgda.h>
-#include "gdaui-data-widget.h"
+#include "gdaui-data-proxy.h"
+#include "gdaui-data-selector.h"
 #include "gdaui-raw-grid.h"
-#include "gdaui-data-widget-info.h"
+#include "gdaui-data-proxy-info.h"
 #include "gdaui-enum-types.h"
 
-static void gdaui_data_widget_info_class_init (GdauiDataWidgetInfoClass * class);
-static void gdaui_data_widget_info_init (GdauiDataWidgetInfo *wid);
-static void gdaui_data_widget_info_dispose (GObject *object);
+static void gdaui_data_proxy_info_class_init (GdauiDataProxyInfoClass * class);
+static void gdaui_data_proxy_info_init (GdauiDataProxyInfo *wid);
+static void gdaui_data_proxy_info_dispose (GObject *object);
 
-static void gdaui_data_widget_info_set_property (GObject *object,
-						    guint param_id,
-						    const GValue *value,
-						    GParamSpec *pspec);
-static void gdaui_data_widget_info_get_property (GObject *object,
-						    guint param_id,
-						    GValue *value,
-						    GParamSpec *pspec);
+static void gdaui_data_proxy_info_set_property (GObject *object,
+						guint param_id,
+						const GValue *value,
+						GParamSpec *pspec);
+static void gdaui_data_proxy_info_get_property (GObject *object,
+						guint param_id,
+						GValue *value,
+						GParamSpec *pspec);
 
-static void modif_buttons_make (GdauiDataWidgetInfo *info);
-static void modif_buttons_update (GdauiDataWidgetInfo *info);
+static void modif_buttons_make (GdauiDataProxyInfo *info);
+static void modif_buttons_update (GdauiDataProxyInfo *info);
 
-static void data_widget_proxy_changed_cb (GdauiDataWidget *data_widget, GdaDataProxy *proxy, GdauiDataWidgetInfo *info);
-static void proxy_changed_cb (GdaDataProxy *proxy, GdauiDataWidgetInfo *info);
-static void proxy_sample_changed_cb (GdaDataProxy *proxy, gint sample_start, gint sample_end, GdauiDataWidgetInfo *info);
-static void proxy_row_changed_cb (GdaDataProxy *proxy, gint row, GdauiDataWidgetInfo *info);
-static void raw_grid_selection_changed_cb (GdauiRawGrid *grid, gboolean row_selected, 
-					   GdauiDataWidgetInfo *info);
+static void data_proxy_proxy_changed_cb (GdauiDataProxy *data_proxy, GdaDataProxy *proxy, GdauiDataProxyInfo *info);
+static void proxy_changed_cb (GdaDataProxy *proxy, GdauiDataProxyInfo *info);
+static void proxy_sample_changed_cb (GdaDataProxy *proxy, gint sample_start, gint sample_end, GdauiDataProxyInfo *info);
+static void proxy_row_changed_cb (GdaDataProxy *proxy, gint row, GdauiDataProxyInfo *info);
+static void raw_grid_selection_changed_cb (GdauiRawGrid *grid, GdauiDataProxyInfo *info);
 
 
-struct _GdauiDataWidgetInfoPriv
+struct _GdauiDataProxyInfoPriv
 {
-	GdauiDataWidget *data_widget;
+	GdauiDataProxy *data_proxy;
 	GdaDataProxy      *proxy;
 	GdaDataModelIter  *iter;
-	GdauiDataWidgetInfoFlag flags; /* ORed values. */
+	GdauiDataProxyInfoFlag flags; /* ORed values. */
 
 	GtkUIManager      *uimanager;
 
@@ -70,108 +70,110 @@ struct _GdauiDataWidgetInfoPriv
 static GObjectClass *parent_class = NULL;
 
 /* properties */
-enum
-{
-        PROP_0,
-        PROP_DATA_WIDGET,
+enum {
+	PROP_0,
+	PROP_DATA_PROXY,
 	PROP_FLAGS
 };
 
 GType
-gdaui_data_widget_info_get_type (void)
+gdaui_data_proxy_info_get_type (void)
 {
 	static GType type = 0;
 
 	if (G_UNLIKELY (type == 0)) {
 		static const GTypeInfo info = {
-			sizeof (GdauiDataWidgetInfoClass),
+			sizeof (GdauiDataProxyInfoClass),
 			(GBaseInitFunc) NULL,
 			(GBaseFinalizeFunc) NULL,
-			(GClassInitFunc) gdaui_data_widget_info_class_init,
+			(GClassInitFunc) gdaui_data_proxy_info_class_init,
 			NULL,
 			NULL,
-			sizeof (GdauiDataWidgetInfo),
+			sizeof (GdauiDataProxyInfo),
 			0,
-			(GInstanceInitFunc) gdaui_data_widget_info_init
-		};		
+			(GInstanceInitFunc) gdaui_data_proxy_info_init
+		};
 
-		type = g_type_register_static (GTK_TYPE_HBOX, "GdauiDataWidgetInfo", &info, 0);
+		type = g_type_register_static (GTK_TYPE_HBOX, "GdauiDataProxyInfo", &info, 0);
 	}
 
 	return type;
 }
 
 static void
-gdaui_data_widget_info_class_init (GdauiDataWidgetInfoClass *klass)
+gdaui_data_proxy_info_class_init (GdauiDataProxyInfoClass *klass)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	
+
 	parent_class = g_type_class_peek_parent (klass);
 
 
-	object_class->dispose = gdaui_data_widget_info_dispose;
+	object_class->dispose = gdaui_data_proxy_info_dispose;
 
 	/* Properties */
-        object_class->set_property = gdaui_data_widget_info_set_property;
-        object_class->get_property = gdaui_data_widget_info_get_property;
-	g_object_class_install_property (object_class, PROP_DATA_WIDGET,
-                                         g_param_spec_object ("data_widget", NULL, NULL, GDAUI_TYPE_DATA_WIDGET,
-                                                               G_PARAM_READABLE | G_PARAM_WRITABLE));
+        object_class->set_property = gdaui_data_proxy_info_set_property;
+        object_class->get_property = gdaui_data_proxy_info_get_property;
+	g_object_class_install_property (object_class, PROP_DATA_PROXY,
+                                         g_param_spec_object ("data-proxy", NULL, NULL, GDAUI_TYPE_DATA_PROXY,
+							      G_PARAM_READABLE | G_PARAM_WRITABLE));
 	g_object_class_install_property (object_class, PROP_FLAGS,
-                                         g_param_spec_flags ("flags", NULL, NULL, GDAUI_TYPE_DATA_WIDGET_INFO_FLAG, 
-							    GDAUI_DATA_WIDGET_INFO_CURRENT_ROW,
-							    G_PARAM_READABLE | G_PARAM_WRITABLE));
+                                         g_param_spec_flags ("flags", NULL, NULL, GDAUI_TYPE_DATA_PROXY_INFO_FLAG,
+							     GDAUI_DATA_PROXY_INFO_CURRENT_ROW,
+							     G_PARAM_READABLE | G_PARAM_WRITABLE));
 }
 
 static void
-gdaui_data_widget_info_init (GdauiDataWidgetInfo *wid)
+gdaui_data_proxy_info_init (GdauiDataProxyInfo *wid)
 {
-	wid->priv = g_new0 (GdauiDataWidgetInfoPriv, 1);
-	wid->priv->data_widget = NULL;
+	wid->priv = g_new0 (GdauiDataProxyInfoPriv, 1);
+	wid->priv->data_proxy = NULL;
 	wid->priv->proxy = NULL;
+	wid->priv->row_spin = NULL;
 }
 
 /**
- * gdaui_data_widget_info_new
- * @data_widget: a widget implementing the #GdauiDataWidget interface
+ * gdaui_data_proxy_info_new
+ * @data_proxy: a widget implementing the #GdauiDataProxy interface
  * @flags: OR'ed values, specifying what to display in the new widget
  *
- * Creates a new #GdauiDataWidgetInfo widget suitable to display information about @data_widget
+ * Creates a new #GdauiDataProxyInfo widget suitable to display information about @data_proxy
  *
  * Returns: the new widget
+ *
+ * Since: 4.2
  */
 GtkWidget *
-gdaui_data_widget_info_new (GdauiDataWidget *data_widget, GdauiDataWidgetInfoFlag flags)
+gdaui_data_proxy_info_new (GdauiDataProxy *data_proxy, GdauiDataProxyInfoFlag flags)
 {
 	GtkWidget *info;
 
-	g_return_val_if_fail (!data_widget || GDAUI_IS_DATA_WIDGET (data_widget), NULL);
+	g_return_val_if_fail (!data_proxy || GDAUI_IS_DATA_PROXY (data_proxy), NULL);
 
-	info = (GtkWidget *) g_object_new (GDAUI_TYPE_DATA_WIDGET_INFO, 
-					   "data_widget", data_widget, 
+	info = (GtkWidget *) g_object_new (GDAUI_TYPE_DATA_PROXY_INFO,
+					   "data-proxy", data_proxy,
 					   "flags", flags, NULL);
 
 	return info;
 }
 
 static void
-data_widget_destroyed_cb (GdauiDataWidget *wid, GdauiDataWidgetInfo *info)
+data_proxy_destroyed_cb (GdauiDataProxy *wid, GdauiDataProxyInfo *info)
 {
-	g_assert (wid == info->priv->data_widget);
+	g_assert (wid == info->priv->data_proxy);
 	g_signal_handlers_disconnect_by_func (G_OBJECT (wid),
-					      G_CALLBACK (data_widget_destroyed_cb), info);
+					      G_CALLBACK (data_proxy_destroyed_cb), info);
 	g_signal_handlers_disconnect_by_func (G_OBJECT (wid),
-					      G_CALLBACK (data_widget_proxy_changed_cb), info);
-	if (GDAUI_IS_RAW_GRID (info->priv->data_widget))
-		g_signal_handlers_disconnect_by_func (info->priv->data_widget,
+					      G_CALLBACK (data_proxy_proxy_changed_cb), info);
+	if (GDAUI_IS_RAW_GRID (info->priv->data_proxy))
+		g_signal_handlers_disconnect_by_func (info->priv->data_proxy,
 						      G_CALLBACK (raw_grid_selection_changed_cb), info);
 
-	info->priv->data_widget = NULL;
+	info->priv->data_proxy = NULL;
 }
 
 
 static void
-release_proxy (GdauiDataWidgetInfo *info)
+release_proxy (GdauiDataProxyInfo *info)
 {
 	g_signal_handlers_disconnect_by_func (G_OBJECT (info->priv->proxy),
 					      G_CALLBACK (proxy_changed_cb), info);
@@ -183,9 +185,9 @@ release_proxy (GdauiDataWidgetInfo *info)
 	info->priv->proxy = NULL;
 }
 
-static void iter_row_changed_cb (GdaDataModelIter *iter, gint row, GdauiDataWidgetInfo *info);
+static void iter_row_changed_cb (GdaDataModelIter *iter, gint row, GdauiDataProxyInfo *info);
 static void
-release_iter (GdauiDataWidgetInfo *info)
+release_iter (GdauiDataProxyInfo *info)
 {
 	g_signal_handlers_disconnect_by_func (info->priv->iter,
 					      G_CALLBACK (iter_row_changed_cb), info);
@@ -194,19 +196,19 @@ release_iter (GdauiDataWidgetInfo *info)
 }
 
 static void
-data_widget_proxy_changed_cb (GdauiDataWidget *data_widget, GdaDataProxy *proxy, GdauiDataWidgetInfo *info)
+data_proxy_proxy_changed_cb (GdauiDataProxy *data_proxy, GdaDataProxy *proxy, GdauiDataProxyInfo *info)
 {
-	g_object_set (G_OBJECT (info), "data_widget", data_widget, NULL);
+	g_object_set (G_OBJECT (info), "data-proxy", data_proxy, NULL);
 }
 
 static void
-gdaui_data_widget_info_dispose (GObject *object)
+gdaui_data_proxy_info_dispose (GObject *object)
 {
-	GdauiDataWidgetInfo *info;
+	GdauiDataProxyInfo *info;
 
 	g_return_if_fail (object != NULL);
-	g_return_if_fail (GDAUI_IS_DATA_WIDGET_INFO (object));
-	info = GDAUI_DATA_WIDGET_INFO (object);
+	g_return_if_fail (GDAUI_IS_DATA_PROXY_INFO (object));
+	info = GDAUI_DATA_PROXY_INFO (object);
 
 	if (info->priv) {
 		if (info->priv->idle_id)
@@ -215,8 +217,8 @@ gdaui_data_widget_info_dispose (GObject *object)
 			release_proxy (info);
 		if (info->priv->iter)
 			release_iter (info);
-		if (info->priv->data_widget)
-			data_widget_destroyed_cb (info->priv->data_widget, info);
+		if (info->priv->data_proxy)
+			data_proxy_destroyed_cb (info->priv->data_proxy, info);
 
 		/* the private area itself */
 		g_free (info->priv);
@@ -228,59 +230,59 @@ gdaui_data_widget_info_dispose (GObject *object)
 }
 
 static void
-gdaui_data_widget_info_set_property (GObject *object,
-				     guint param_id,
-				     const GValue *value,
-				     GParamSpec *pspec)
+gdaui_data_proxy_info_set_property (GObject *object,
+				    guint param_id,
+				    const GValue *value,
+				    GParamSpec *pspec)
 {
-	GdauiDataWidgetInfo *info;
+	GdauiDataProxyInfo *info;
 
-        info = GDAUI_DATA_WIDGET_INFO (object);
+        info = GDAUI_DATA_PROXY_INFO (object);
         if (info->priv) {
                 switch (param_id) {
-                case PROP_DATA_WIDGET:
-			if (info->priv->data_widget)
-				data_widget_destroyed_cb (info->priv->data_widget, info);
-			if (info->priv->iter) 
+                case PROP_DATA_PROXY:
+			if (info->priv->data_proxy)
+				data_proxy_destroyed_cb (info->priv->data_proxy, info);
+			if (info->priv->iter)
 				release_iter (info);
 			if (info->priv->proxy)
 				release_proxy (info);
 
-			info->priv->data_widget = GDAUI_DATA_WIDGET (g_value_get_object (value));
-			if (info->priv->data_widget) {
+			info->priv->data_proxy = GDAUI_DATA_PROXY (g_value_get_object (value));
+			if (info->priv->data_proxy) {
 				GdaDataProxy *proxy;
 				GdaDataModelIter *iter;
 
 				/* data widget */
-				g_signal_connect (info->priv->data_widget, "destroy",
-						  G_CALLBACK (data_widget_destroyed_cb), info);
-				g_signal_connect (info->priv->data_widget, "proxy_changed",
-						  G_CALLBACK (data_widget_proxy_changed_cb), info);
-				if (GDAUI_IS_RAW_GRID (info->priv->data_widget))
-					g_signal_connect (info->priv->data_widget, "selection_changed",
+				g_signal_connect (info->priv->data_proxy, "destroy",
+						  G_CALLBACK (data_proxy_destroyed_cb), info);
+				g_signal_connect (info->priv->data_proxy, "proxy-changed",
+						  G_CALLBACK (data_proxy_proxy_changed_cb), info);
+				if (GDAUI_IS_RAW_GRID (info->priv->data_proxy))
+					g_signal_connect (info->priv->data_proxy, "selection-changed",
 							  G_CALLBACK (raw_grid_selection_changed_cb), info);
 
 				/* proxy */
-				proxy = gdaui_data_widget_get_proxy (info->priv->data_widget);
+				proxy = gdaui_data_proxy_get_proxy (info->priv->data_proxy);
 				if (proxy) {
 					info->priv->proxy = proxy;
 					g_object_ref (info->priv->proxy);
 					g_signal_connect (G_OBJECT (proxy), "changed",
 							  G_CALLBACK (proxy_changed_cb), info);
-					g_signal_connect (G_OBJECT (proxy), "sample_changed",
+					g_signal_connect (G_OBJECT (proxy), "sample-changed",
 							  G_CALLBACK (proxy_sample_changed_cb), info);
-					g_signal_connect (G_OBJECT (proxy), "row_inserted",
+					g_signal_connect (G_OBJECT (proxy), "row-inserted",
 							  G_CALLBACK (proxy_row_changed_cb), info);
-					g_signal_connect (G_OBJECT (proxy), "row_removed",
+					g_signal_connect (G_OBJECT (proxy), "row-removed",
 							  G_CALLBACK (proxy_row_changed_cb), info);
-					
+
 					/* iter */
-					iter = gdaui_data_widget_get_current_data (GDAUI_DATA_WIDGET 
-										      (info->priv->data_widget));
+					iter = gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR
+											  (info->priv->data_proxy));
 					info->priv->iter = iter;
 					if (iter) {
 						g_object_ref (G_OBJECT (iter));
-						g_signal_connect (iter, "row_changed",
+						g_signal_connect (iter, "row-changed",
 								  G_CALLBACK (iter_row_changed_cb), info);
 					}
 				}
@@ -289,16 +291,16 @@ gdaui_data_widget_info_set_property (GObject *object,
                         break;
                 case PROP_FLAGS:
 			info->priv->flags = g_value_get_flags (value);
+			if (info->priv->row_spin) {
+				gtk_widget_destroy (info->priv->row_spin);
+				info->priv->row_spin = NULL;
+			}
 			if (info->priv->buttons_bar) {
 				gtk_widget_destroy (info->priv->buttons_bar);
 				info->priv->buttons_bar = NULL;
 			}
 			if (info->priv->current_sample)
 				info->priv->current_sample = NULL;
-			if (info->priv->row_spin) {
-				gtk_widget_destroy (info->priv->row_spin);
-				info->priv->row_spin = NULL;
-			}
 
 			modif_buttons_make (info);
 			modif_buttons_update (info);
@@ -311,18 +313,18 @@ gdaui_data_widget_info_set_property (GObject *object,
 }
 
 static void
-gdaui_data_widget_info_get_property (GObject *object,
-				     guint param_id,
-				     GValue *value,
-				     GParamSpec *pspec)
+gdaui_data_proxy_info_get_property (GObject *object,
+				    guint param_id,
+				    GValue *value,
+				    GParamSpec *pspec)
 {
-	GdauiDataWidgetInfo *info;
+	GdauiDataProxyInfo *info;
 
-        info = GDAUI_DATA_WIDGET_INFO (object);
+        info = GDAUI_DATA_PROXY_INFO (object);
         if (info->priv) {
                 switch (param_id) {
-		case PROP_DATA_WIDGET:
-			g_value_set_pointer (value, info->priv->data_widget);
+		case PROP_DATA_PROXY:
+			g_value_set_pointer (value, info->priv->data_proxy);
 			break;
 		case PROP_FLAGS:
 			g_value_set_flags (value, info->priv->flags);
@@ -331,36 +333,36 @@ gdaui_data_widget_info_get_property (GObject *object,
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 			break;
                 }
-        }	
+        }
 }
 
 
 static void
-proxy_changed_cb (GdaDataProxy *proxy, GdauiDataWidgetInfo *info)
+proxy_changed_cb (GdaDataProxy *proxy, GdauiDataProxyInfo *info)
 {
 	modif_buttons_update (info);
 }
 
 static void
-proxy_sample_changed_cb (GdaDataProxy *proxy, gint sample_start, gint sample_end, GdauiDataWidgetInfo *info)
+proxy_sample_changed_cb (GdaDataProxy *proxy, gint sample_start, gint sample_end, GdauiDataProxyInfo *info)
 {
 	modif_buttons_update (info);
 }
 
 static void
-proxy_row_changed_cb (GdaDataProxy *proxy, gint row, GdauiDataWidgetInfo *info)
+proxy_row_changed_cb (GdaDataProxy *proxy, gint row, GdauiDataProxyInfo *info)
 {
 	modif_buttons_update (info);
 }
 
 static void
-iter_row_changed_cb (GdaDataModelIter *iter, gint row, GdauiDataWidgetInfo *info)
+iter_row_changed_cb (GdaDataModelIter *iter, gint row, GdauiDataProxyInfo *info)
 {
 	modif_buttons_update (info);
 }
 
 static void
-raw_grid_selection_changed_cb (GdauiRawGrid *grid, gboolean row_selected, GdauiDataWidgetInfo *info)
+raw_grid_selection_changed_cb (GdauiRawGrid *grid, GdauiDataProxyInfo *info)
 {
 	modif_buttons_update (info);
 }
@@ -401,48 +403,49 @@ static const gchar *ui_chunck_change =
 	"  </toolbar>"
 	"</ui>";
 
-static void row_spin_changed_cb (GtkSpinButton *spin, GdauiDataWidgetInfo *info);
+static void row_spin_changed_cb (GtkSpinButton *spin, GdauiDataProxyInfo *info);
 static void
-modif_buttons_make (GdauiDataWidgetInfo *info)
+modif_buttons_make (GdauiDataProxyInfo *info)
 {
 	GtkWidget *wid;
-	GdauiDataWidgetInfoFlag flags = info->priv->flags;
+	GdauiDataProxyInfoFlag flags = info->priv->flags;
 	static gboolean rc_done = FALSE;
 
 	if (!rc_done) {
                 rc_done = TRUE;
-                gtk_rc_parse_string ("style \"gdaui-data-widget-info-style\"\n"
+                gtk_rc_parse_string ("style \"gdaui-data-proxy-info-style\"\n"
                                      "{\n"
                                      "GtkToolbar::shadow-type = GTK_SHADOW_NONE\n"
                                      "xthickness = 0\n"
                                      "ythickness = 0\n"
                                      "}\n"
-                                     "widget \"*.gdaui-data-widget-info\" style \"gdaui-data-widget-info-style\"");
+                                     "widget \"*.gdaui-data-proxy-info\" style \"gdaui-data-proxy-info-style\"");
         }
 
-	if (! info->priv->data_widget)
+	if (! info->priv->data_proxy)
 		return;
 
-	if (flags & (GDAUI_DATA_WIDGET_INFO_ROW_MODIFY_BUTTONS |
-		     GDAUI_DATA_WIDGET_INFO_ROW_MOVE_BUTTONS |
-		     GDAUI_DATA_WIDGET_INFO_CHUNCK_CHANGE_BUTTONS)) {
+	if (flags & (GDAUI_DATA_PROXY_INFO_ROW_MODIFY_BUTTONS |
+		     GDAUI_DATA_PROXY_INFO_ROW_MOVE_BUTTONS |
+		     GDAUI_DATA_PROXY_INFO_CHUNCK_CHANGE_BUTTONS)) {
 		GtkActionGroup *actions;
 		GtkUIManager *ui;
 
-		actions = gdaui_data_widget_get_actions_group (info->priv->data_widget);
+		actions = gdaui_data_proxy_get_actions_group (info->priv->data_proxy);
 		ui = gtk_ui_manager_new ();
 		gtk_ui_manager_insert_action_group (ui, actions, 0);
-		if (flags & GDAUI_DATA_WIDGET_INFO_ROW_MODIFY_BUTTONS)
+		if (flags & GDAUI_DATA_PROXY_INFO_ROW_MODIFY_BUTTONS)
 			gtk_ui_manager_add_ui_from_string (ui, ui_row_modif, -1, NULL);
-		if (flags & GDAUI_DATA_WIDGET_INFO_ROW_MOVE_BUTTONS)
+		if (flags & GDAUI_DATA_PROXY_INFO_ROW_MOVE_BUTTONS)
 			gtk_ui_manager_add_ui_from_string (ui, ui_row_move, -1, NULL);
-		if (flags & GDAUI_DATA_WIDGET_INFO_CHUNCK_CHANGE_BUTTONS)
+		if (flags & GDAUI_DATA_PROXY_INFO_CHUNCK_CHANGE_BUTTONS)
 			gtk_ui_manager_add_ui_from_string (ui, ui_chunck_change, -1, NULL);
 
 		info->priv->uimanager = ui;
 		info->priv->buttons_bar = gtk_ui_manager_get_widget (ui, "/ToolBar");
+		gtk_toolbar_set_icon_size (GTK_TOOLBAR (info->priv->buttons_bar), GTK_ICON_SIZE_SMALL_TOOLBAR);
 		g_object_set (G_OBJECT (info->priv->buttons_bar), "toolbar-style", GTK_TOOLBAR_ICONS, NULL);
-		gtk_widget_set_name (info->priv->buttons_bar, "gdaui-data-widget-info");
+		gtk_widget_set_name (info->priv->buttons_bar, "gdaui-data-proxy-info");
 		gtk_toolbar_set_tooltips (GTK_TOOLBAR (info->priv->buttons_bar), TRUE);
 		gtk_box_pack_start (GTK_BOX (info), info->priv->buttons_bar, TRUE, TRUE, 0);
 	}
@@ -451,9 +454,9 @@ modif_buttons_make (GdauiDataWidgetInfo *info)
 	}
 	gtk_widget_show (info->priv->buttons_bar);
 
-	if (flags & GDAUI_DATA_WIDGET_INFO_CURRENT_ROW) {
+	if (flags & GDAUI_DATA_PROXY_INFO_CURRENT_ROW) {
 		GtkWidget *toolwid;
-		if (flags & GDAUI_DATA_WIDGET_INFO_ROW_MOVE_BUTTONS) {
+		if (flags & GDAUI_DATA_PROXY_INFO_ROW_MOVE_BUTTONS) {
 			toolwid = gtk_hbox_new (FALSE, 0);
 
 			/* read-write spin counter (mainly for forms) */
@@ -487,7 +490,7 @@ modif_buttons_make (GdauiDataWidgetInfo *info)
 }
 
 static void
-row_spin_changed_cb (GtkSpinButton *spin, GdauiDataWidgetInfo *info)
+row_spin_changed_cb (GtkSpinButton *spin, GdauiDataProxyInfo *info)
 {
 	gint row;
 	gint value = gtk_spin_button_get_value (spin);
@@ -496,12 +499,13 @@ row_spin_changed_cb (GtkSpinButton *spin, GdauiDataWidgetInfo *info)
 	    (value <= gda_data_model_get_n_rows (GDA_DATA_MODEL (info->priv->proxy))))
 		row = value - 1;
 
-	gda_data_model_iter_move_to_row (gdaui_data_widget_get_current_data (info->priv->data_widget), row);
+	gda_data_model_iter_move_to_row (gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (info->priv->data_proxy)),
+					 row);
 }
 
-static gboolean idle_modif_buttons_update (GdauiDataWidgetInfo *info);
+static gboolean idle_modif_buttons_update (GdauiDataProxyInfo *info);
 static void
-modif_buttons_update (GdauiDataWidgetInfo *info)
+modif_buttons_update (GdauiDataProxyInfo *info)
 {
 	if (info->priv->idle_id == 0)
 		info->priv->idle_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE,
@@ -515,11 +519,11 @@ modif_buttons_update (GdauiDataWidgetInfo *info)
 #define UNBLOCK_SPIN (g_signal_handlers_unblock_by_func (G_OBJECT (info->priv->row_spin), \
 							 G_CALLBACK (row_spin_changed_cb), info))
 static gboolean
-idle_modif_buttons_update (GdauiDataWidgetInfo *info)
+idle_modif_buttons_update (GdauiDataProxyInfo *info)
 {
 	GdaDataModelIter *model_iter;
 	gboolean wrows, filtered_proxy = FALSE;
-	gint has_selection;	
+	gint has_selection;
 	gint row;
 
 	gint proxy_rows = 0;
@@ -528,9 +532,9 @@ idle_modif_buttons_update (GdauiDataWidgetInfo *info)
 
 	GtkAction *action;
 	gint sample_first_row = 0, sample_last_row = 0, sample_size = 0;
-	GdauiDataWidgetInfoFlag flags = 0;
+	GdauiDataProxyInfoFlag flags = 0;
 
-	model_iter = gdaui_data_widget_get_current_data (info->priv->data_widget);
+	model_iter = gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (info->priv->data_proxy));
 	if (info->priv->proxy) {
 		filtered_proxy = gda_data_proxy_get_filter_expr (info->priv->proxy) ? TRUE : FALSE;
 		proxy_rows = gda_data_model_get_n_rows (GDA_DATA_MODEL (info->priv->proxy));
@@ -554,9 +558,9 @@ idle_modif_buttons_update (GdauiDataWidgetInfo *info)
 	/* sensitiveness of the text indications and of the spin button */
 	wrows = (proxy_rows <= 0) ? FALSE : TRUE;
 	row = model_iter ? gda_data_model_iter_get_row (model_iter) : 0;
-	if (info->priv->flags & GDAUI_DATA_WIDGET_INFO_CURRENT_ROW) {
+	if (info->priv->flags & GDAUI_DATA_PROXY_INFO_CURRENT_ROW) {
 		if (proxy_rows < 0) {
-			if (info->priv->flags & GDAUI_DATA_WIDGET_INFO_ROW_MOVE_BUTTONS) {
+			if (info->priv->flags & GDAUI_DATA_PROXY_INFO_ROW_MOVE_BUTTONS) {
 				BLOCK_SPIN;
 				gtk_spin_button_set_range (GTK_SPIN_BUTTON (info->priv->row_spin), 0, 1);
 				gtk_spin_button_set_value (GTK_SPIN_BUTTON (info->priv->row_spin), 0);
@@ -569,9 +573,9 @@ idle_modif_buttons_update (GdauiDataWidgetInfo *info)
 		else {
 			gchar *str;
 			gint total;
-			
+
 			total = sample_first_row + proxy_rows;
-			if (info->priv->flags & GDAUI_DATA_WIDGET_INFO_ROW_MOVE_BUTTONS) {
+			if (info->priv->flags & GDAUI_DATA_PROXY_INFO_ROW_MOVE_BUTTONS) {
 				if (total <= 0)
 					str = g_strdup (" / 0");
 				else {
@@ -594,11 +598,11 @@ idle_modif_buttons_update (GdauiDataWidgetInfo *info)
 					if (all_rows < 0)
 						str = g_strdup_printf ("%d - %d /?", sample_first_row + 1, total);
 					else {
-						if (filtered_proxy) 
-							str = g_strdup_printf ("%d - %d / (%d)", 
+						if (filtered_proxy)
+							str = g_strdup_printf ("%d - %d / (%d)",
 									       sample_first_row + 1, total, all_rows);
 						else
-							str = g_strdup_printf ("%d - %d / %d", 
+							str = g_strdup_printf ("%d - %d / %d",
 									       sample_first_row + 1, total, all_rows);
 					}
 				}
@@ -623,23 +627,23 @@ idle_modif_buttons_update (GdauiDataWidgetInfo *info)
 
 		if (info->priv->proxy) {
 			changed = gda_data_proxy_has_changed (info->priv->proxy);
-			
+
 			has_selection = (row >= 0) ? TRUE : FALSE;
 			if (has_selection) {
 				to_be_deleted = gda_data_proxy_row_is_deleted (info->priv->proxy, row);
 				is_inserted = gda_data_proxy_row_is_inserted (info->priv->proxy, row);
 			}
-			else 
-				if (GDAUI_IS_RAW_GRID (info->priv->data_widget)) {
+			else
+				if (GDAUI_IS_RAW_GRID (info->priv->data_proxy)) {
 					/* bad for encapsulation, but very useful... */
 					GList *sel, *list;
-					
-					sel = gdaui_raw_grid_get_selection ((GdauiRawGrid*) info->priv->data_widget);
+
+					sel = _gdaui_raw_grid_get_selection ((GdauiRawGrid*) info->priv->data_proxy);
 					if (sel) {
 						list = sel;
 						while (list && (!force_del_btn || !force_undel_btn)) {
-							if ((GPOINTER_TO_INT (list->data) != -1) && 
-							    gda_data_proxy_row_is_deleted (info->priv->proxy, 
+							if ((GPOINTER_TO_INT (list->data) != -1) &&
+							    gda_data_proxy_row_is_deleted (info->priv->proxy,
 											   GPOINTER_TO_INT (list->data)))
 								force_undel_btn = TRUE;
 							else
@@ -659,64 +663,64 @@ idle_modif_buttons_update (GdauiDataWidgetInfo *info)
 				}
 		}
 
-		if (info->priv->flags & GDAUI_DATA_WIDGET_INFO_ROW_MODIFY_BUTTONS) {
-			GdauiDataWidgetWriteMode mode;
-			mode = gdaui_data_widget_get_write_mode (info->priv->data_widget);
+		if (info->priv->flags & GDAUI_DATA_PROXY_INFO_ROW_MODIFY_BUTTONS) {
+			GdauiDataProxyWriteMode mode;
+			mode = gdaui_data_proxy_get_write_mode (info->priv->data_proxy);
 
 			action = gtk_ui_manager_get_action (info->priv->uimanager, "/ToolBar/ActionCommit");
 			g_object_set (G_OBJECT (action), "sensitive", changed ? TRUE : FALSE, NULL);
-			if (mode == GDAUI_DATA_WIDGET_WRITE_ON_VALUE_CHANGE)
+			if (mode == GDAUI_DATA_PROXY_WRITE_ON_VALUE_CHANGE)
 				gtk_action_set_visible (action, FALSE);
 			else
 				gtk_action_set_visible (action, TRUE);
-			
+
 			action = gtk_ui_manager_get_action (info->priv->uimanager, "/ToolBar/ActionReset");
 			g_object_set (G_OBJECT (action), "sensitive", changed ? TRUE : FALSE, NULL);
-			if (mode == GDAUI_DATA_WIDGET_WRITE_ON_VALUE_CHANGE)
+			if (mode == GDAUI_DATA_PROXY_WRITE_ON_VALUE_CHANGE)
 				gtk_action_set_visible (action, FALSE);
 			else
 				gtk_action_set_visible (action, TRUE);
-			
+
 			action = gtk_ui_manager_get_action (info->priv->uimanager, "/ToolBar/ActionNew");
-			g_object_set (G_OBJECT (action), "sensitive", 
+			g_object_set (G_OBJECT (action), "sensitive",
 				      flags & GDA_DATA_MODEL_ACCESS_INSERT ? TRUE : FALSE, NULL);
-			
+
 			action = gtk_ui_manager_get_action (info->priv->uimanager, "/ToolBar/ActionDelete");
 			wrows = is_inserted ||
-				((flags & GDA_DATA_MODEL_ACCESS_DELETE) && 
+				((flags & GDA_DATA_MODEL_ACCESS_DELETE) &&
 				 (force_del_btn || (! to_be_deleted && has_selection)));
 			g_object_set (G_OBJECT (action), "sensitive", wrows, NULL);
-			
+
 			action = gtk_ui_manager_get_action (info->priv->uimanager, "/ToolBar/ActionUndelete");
-			wrows = (flags & GDA_DATA_MODEL_ACCESS_DELETE) && 
+			wrows = (flags & GDA_DATA_MODEL_ACCESS_DELETE) &&
 				(force_undel_btn || (to_be_deleted && has_selection));
 			g_object_set (G_OBJECT (action), "sensitive", wrows, NULL);
 
-			if ((mode == GDAUI_DATA_WIDGET_WRITE_ON_ROW_CHANGE) ||
-			    (mode == GDAUI_DATA_WIDGET_WRITE_ON_VALUE_CHANGE) ||
-			    (mode == GDAUI_DATA_WIDGET_WRITE_ON_VALUE_ACTIVATED))
+			if ((mode == GDAUI_DATA_PROXY_WRITE_ON_ROW_CHANGE) ||
+			    (mode == GDAUI_DATA_PROXY_WRITE_ON_VALUE_CHANGE) ||
+			    (mode == GDAUI_DATA_PROXY_WRITE_ON_VALUE_ACTIVATED))
 				gtk_action_set_visible (action, FALSE);
-			else 
+			else
 				gtk_action_set_visible (action, TRUE);
 		}
 	}
 
 	/* current row moving */
-	if (info->priv->flags & GDAUI_DATA_WIDGET_INFO_ROW_MOVE_BUTTONS) {
+	if (info->priv->flags & GDAUI_DATA_PROXY_INFO_ROW_MOVE_BUTTONS) {
 		action = gtk_ui_manager_get_action (info->priv->uimanager, "/ToolBar/ActionFirstRecord");
 		g_object_set (G_OBJECT (action), "sensitive", (row <= 0) ? FALSE : TRUE, NULL);
 		action = gtk_ui_manager_get_action (info->priv->uimanager, "/ToolBar/ActionPrevRecord");
 		g_object_set (G_OBJECT (action), "sensitive", (row <= 0) ? FALSE : TRUE, NULL);
 		action = gtk_ui_manager_get_action (info->priv->uimanager, "/ToolBar/ActionNextRecord");
-		g_object_set (G_OBJECT (action), "sensitive", (row == proxy_rows -1) || (row < 0) ? FALSE : TRUE, 
+		g_object_set (G_OBJECT (action), "sensitive", (row == proxy_rows -1) || (row < 0) ? FALSE : TRUE,
 			      NULL);
 		action = gtk_ui_manager_get_action (info->priv->uimanager, "/ToolBar/ActionLastRecord");
-		g_object_set (G_OBJECT (action), "sensitive", (row == proxy_rows -1) || (row < 0) ? FALSE : TRUE, 
+		g_object_set (G_OBJECT (action), "sensitive", (row == proxy_rows -1) || (row < 0) ? FALSE : TRUE,
 			      NULL);
 	}
 
 	/* chunck indications */
-	if (info->priv->flags & GDAUI_DATA_WIDGET_INFO_CHUNCK_CHANGE_BUTTONS) {
+	if (info->priv->flags & GDAUI_DATA_PROXY_INFO_CHUNCK_CHANGE_BUTTONS) {
 		gboolean abool;
 		wrows = (sample_size > 0) ? TRUE : FALSE;
 		action = gtk_ui_manager_get_action (info->priv->uimanager, "/ToolBar/ActionFirstChunck");
@@ -731,11 +735,11 @@ idle_modif_buttons_update (GdauiDataWidgetInfo *info)
 	}
 
 	/* filter */
-	if (info->priv->flags & GDAUI_DATA_WIDGET_INFO_NO_FILTER) {
+	if (info->priv->flags & GDAUI_DATA_PROXY_INFO_NO_FILTER) {
 		action = gtk_ui_manager_get_action (info->priv->uimanager, "/ToolBar/ActionFilter");
 		g_object_set (G_OBJECT (action), "visible", FALSE, NULL);
 	}
-	
+
 	if (info->priv->uimanager)
 		gtk_ui_manager_ensure_update (info->priv->uimanager);
 
diff --git a/libgda-ui/gdaui-data-proxy-info.h b/libgda-ui/gdaui-data-proxy-info.h
new file mode 100644
index 0000000..ddf146e
--- /dev/null
+++ b/libgda-ui/gdaui-data-proxy-info.h
@@ -0,0 +1,75 @@
+/* gdaui-data-proxy-info.h
+ *
+ * Copyright (C) 2006 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_DATA_PROXY_INFO__
+#define __GDAUI_DATA_PROXY_INFO__
+
+#include <gtk/gtk.h>
+#include <libgda/gda-decl.h>
+#include <libgda-ui/gdaui-decl.h>
+
+G_BEGIN_DECLS
+
+#define GDAUI_TYPE_DATA_PROXY_INFO          (gdaui_data_proxy_info_get_type())
+#define GDAUI_DATA_PROXY_INFO(obj)          G_TYPE_CHECK_INSTANCE_CAST (obj, gdaui_data_proxy_info_get_type(), GdauiDataProxyInfo)
+#define GDAUI_DATA_PROXY_INFO_CLASS(klass)  G_TYPE_CHECK_CLASS_CAST (klass, gdaui_data_proxy_info_get_type (), GdauiDataProxyInfoClass)
+#define GDAUI_IS_DATA_PROXY_INFO(obj)       G_TYPE_CHECK_INSTANCE_TYPE (obj, gdaui_data_proxy_info_get_type ())
+
+
+typedef struct _GdauiDataProxyInfo      GdauiDataProxyInfo;
+typedef struct _GdauiDataProxyInfoClass GdauiDataProxyInfoClass;
+typedef struct _GdauiDataProxyInfoPriv  GdauiDataProxyInfoPriv;
+
+typedef enum 
+{
+	GDAUI_DATA_PROXY_INFO_NONE = 0,
+	GDAUI_DATA_PROXY_INFO_CURRENT_ROW    = 1 << 0,
+	GDAUI_DATA_PROXY_INFO_ROW_MODIFY_BUTTONS = 1 << 2,
+	GDAUI_DATA_PROXY_INFO_ROW_MOVE_BUTTONS = 1 << 3,
+	GDAUI_DATA_PROXY_INFO_CHUNCK_CHANGE_BUTTONS = 1 << 4,
+	GDAUI_DATA_PROXY_INFO_NO_FILTER = 1 << 5
+} GdauiDataProxyInfoFlag;
+
+/* struct for the object's data */
+struct _GdauiDataProxyInfo
+{
+	GtkHBox                 object;
+
+	GdauiDataProxyInfoPriv *priv;
+};
+
+/* struct for the object's class */
+struct _GdauiDataProxyInfoClass
+{
+	GtkHBoxClass            parent_class;
+};
+
+/* 
+ * Generic widget's methods 
+ */
+GType             gdaui_data_proxy_info_get_type (void) G_GNUC_CONST;
+GtkWidget        *gdaui_data_proxy_info_new      (GdauiDataProxy *data_proxy, GdauiDataProxyInfoFlag flags);
+
+G_END_DECLS
+
+#endif
+
+
+
diff --git a/libgda-ui/gdaui-data-proxy.c b/libgda-ui/gdaui-data-proxy.c
new file mode 100644
index 0000000..aa44bea
--- /dev/null
+++ b/libgda-ui/gdaui-data-proxy.c
@@ -0,0 +1,293 @@
+/* gdaui-data-widget.c
+ *
+ * Copyright (C) 2004 - 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 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 <string.h>
+#include <libgda/libgda.h>
+#include <libgda/binreloc/gda-binreloc.h>
+#include "gdaui-data-proxy.h"
+#include  <glib/gi18n-lib.h>
+#include <libgda-ui/gdaui-raw-form.h>
+#include <libgda-ui/gdaui-raw-grid.h>
+
+/* signals */
+enum {
+        PROXY_CHANGED,
+        LAST_SIGNAL
+};
+
+static gint gdaui_data_proxy_signals[LAST_SIGNAL] = { 0 };
+
+static void gdaui_data_proxy_iface_init (gpointer g_class);
+
+GType
+gdaui_data_proxy_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0)) {
+		static const GTypeInfo info = {
+			sizeof (GdauiDataProxyIface),
+			(GBaseInitFunc) gdaui_data_proxy_iface_init,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) NULL,
+			NULL,
+			NULL,
+			0,
+			0,
+			(GInstanceInitFunc) NULL
+		};
+		
+		type = g_type_register_static (G_TYPE_INTERFACE, "GdauiDataProxy", &info, 0);
+		g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+	}
+	return type;
+}
+
+
+static void
+gdaui_data_proxy_iface_init (gpointer g_class)
+{
+	static gboolean initialized = FALSE;
+
+	if (! initialized) {
+		gdaui_data_proxy_signals[PROXY_CHANGED] = 
+			g_signal_new ("proxy-changed",
+                                      GDAUI_TYPE_DATA_PROXY,
+                                      G_SIGNAL_RUN_FIRST,
+                                      G_STRUCT_OFFSET (GdauiDataProxyIface, proxy_changed),
+                                      NULL, NULL,
+                                      g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE,
+                                      1, GDA_TYPE_DATA_PROXY);
+		initialized = TRUE;
+	}
+}
+
+/**
+ * gdaui_data_proxy_get_proxy
+ * @iface: an object which implements the #GdauiDataProxy interface
+ *
+ * Get a pointer to the #GdaDataProxy being used by @iface
+ *
+ * Returns: a #GdaDataProxy pointer
+ *
+ * Since: 4.2
+ */
+GdaDataProxy *
+gdaui_data_proxy_get_proxy (GdauiDataProxy *iface)
+{
+	g_return_val_if_fail (GDAUI_IS_DATA_PROXY (iface), NULL);
+	
+	if (GDAUI_DATA_PROXY_GET_IFACE (iface)->get_proxy)
+		return (GDAUI_DATA_PROXY_GET_IFACE (iface)->get_proxy) (iface);
+	else
+		return NULL;
+}
+
+/**
+ * gdaui_data_proxy_column_set_editable
+ * @iface: an object which implements the #GdauiDataProxy interface
+ * @column: column number of the data
+ * @editable:
+ *
+ * Sets if the data entry in the @iface widget at @column (in the data model @iface operates on)
+ * can be edited or not.
+ *
+ * Since: 4.2
+ */
+void 
+gdaui_data_proxy_column_set_editable (GdauiDataProxy *iface, gint column, gboolean editable)
+{
+	g_return_if_fail (GDAUI_IS_DATA_PROXY (iface));
+
+	if (GDAUI_DATA_PROXY_GET_IFACE (iface)->set_column_editable)
+		(GDAUI_DATA_PROXY_GET_IFACE (iface)->set_column_editable) (iface, column, editable);	
+}
+
+/**
+ * gdaui_data_proxy_column_show_actions
+ * @iface: an object which implements the #GdauiDataProxy interface
+ * @column: column number of the data, or -1 to apply the setting to all the columns
+ * @show_actions:
+ * 
+ * Sets if the data entry in the @iface widget at @column (in the data model @iface operates on) must show its
+ * actions menu or not.
+ *
+ * Since: 4.2
+ */
+void
+gdaui_data_proxy_column_show_actions (GdauiDataProxy *iface, gint column, gboolean show_actions)
+{
+	g_return_if_fail (GDAUI_IS_DATA_PROXY (iface));
+
+	if (GDAUI_DATA_PROXY_GET_IFACE (iface)->show_column_actions)
+		(GDAUI_DATA_PROXY_GET_IFACE (iface)->show_column_actions) (iface, column, show_actions);
+}
+
+/**
+ * gdaui_data_proxy_get_actions_group
+ * @iface: an object which implements the #GdauiDataProxy interface
+ *
+ * Each widget imlplementing the #GdauiDataProxy interface provides actions. Actions can be triggered
+ * using the gdaui_data_proxy_perform_action() method, but using this method allows for the creation of
+ * toolbars, menus, etc calling these actions.
+ *
+ * The actions are among: 
+ * <itemizedlist><listitem><para>Data edition actions: "ActionNew", "ActionCommit", 
+ *    "ActionDelete, "ActionUndelete, "ActionReset", </para></listitem>
+ * <listitem><para>Record by record moving: "ActionFirstRecord", "ActionPrevRecord", 
+ *    "ActionNextRecord", "ActionLastRecord",</para></listitem>
+ * <listitem><para>Chuncks of records moving: "ActionFirstChunck", "ActionPrevChunck", 
+ *     "ActionNextChunck", "ActionLastChunck".</para></listitem>
+ * <listitem><para>Filtering: "ActionFilter"</para></listitem></itemizedlist>
+ * 
+ * Returns: the #GtkActionGroup with all the possible actions on the widget.
+ *
+ * Since: 4.2
+ */
+GtkActionGroup *
+gdaui_data_proxy_get_actions_group (GdauiDataProxy *iface)
+{
+	g_return_val_if_fail (GDAUI_IS_DATA_PROXY (iface), NULL);
+
+	if (GDAUI_DATA_PROXY_GET_IFACE (iface)->get_actions_group)
+		return (GDAUI_DATA_PROXY_GET_IFACE (iface)->get_actions_group) (iface);
+	return NULL;
+}
+
+/**
+ * gdaui_data_proxy_perform_action
+ * @iface: an object which implements the #GdauiDataProxy interface
+ * @action: a #GdauiAction action
+ *
+ * Forces the widget to perform the selected @action, as if the user
+ * had pressed on the corresponding action button in the @iface widget,
+ * if the corresponding action is possible and if the @iface widget
+ * supports the action.
+ *
+ * Since: 4.2
+ */
+void
+gdaui_data_proxy_perform_action (GdauiDataProxy *iface, GdauiAction action)
+{
+	gchar *action_name = NULL;
+	GtkActionGroup *group;
+	GtkAction *gtkaction;
+
+	g_return_if_fail (GDAUI_IS_DATA_PROXY (iface));
+	group = gdaui_data_proxy_get_actions_group (iface);
+	if (!group) {
+		g_warning ("Object class %s does not support the gdaui_data_proxy_get_actions_group() method",
+			   G_OBJECT_TYPE_NAME (iface));
+		return;
+	}
+	
+	switch (action) {
+	case GDAUI_ACTION_NEW_DATA:
+		action_name = "ActionNew";
+		break;
+	case GDAUI_ACTION_WRITE_MODIFIED_DATA:
+		action_name = "ActionCommit";
+		break;
+        case GDAUI_ACTION_DELETE_SELECTED_DATA:
+		action_name = "ActionDelete";
+		break;
+        case GDAUI_ACTION_UNDELETE_SELECTED_DATA:
+		action_name = "ActionUndelete";
+		break;
+        case GDAUI_ACTION_RESET_DATA:
+		action_name = "ActionReset";
+		break;
+        case GDAUI_ACTION_MOVE_FIRST_RECORD:
+		action_name = "ActionFirstRecord";
+		break;
+        case GDAUI_ACTION_MOVE_PREV_RECORD:
+		action_name = "ActionPrevRecord";
+		break;
+        case GDAUI_ACTION_MOVE_NEXT_RECORD:
+		action_name = "ActionNextRecord";
+		break;
+        case GDAUI_ACTION_MOVE_LAST_RECORD:
+		action_name = "ActionLastRecord";
+		break;
+        case GDAUI_ACTION_MOVE_FIRST_CHUNCK:
+		action_name = "ActionFirstChunck";
+		break;
+        case GDAUI_ACTION_MOVE_PREV_CHUNCK:
+		action_name = "ActionPrevChunck";
+		break;
+        case GDAUI_ACTION_MOVE_NEXT_CHUNCK:
+		action_name = "ActionNextChunck";
+		break;
+        case GDAUI_ACTION_MOVE_LAST_CHUNCK:
+		action_name = "ActionLastChunck";
+		break;
+	default:
+		g_assert_not_reached ();
+	}
+
+	gtkaction = gtk_action_group_get_action (group, action_name);
+	if (gtkaction)
+		gtk_action_activate (gtkaction);
+}
+
+/**
+ * gdaui_data_proxy_set_write_mode
+ * @iface: an object which implements the #GdauiDataProxy interface
+ * @mode:
+ *
+ * Specifies the way the modifications stored in the #GdaDataProxy used internally by @iface are written back to
+ * the #GdaDataModel which holds the data displayed in @iface.
+ *
+ * Returns: TRUE if the proposed mode has been taken into account
+ *
+ * Since: 4.2
+ */
+gboolean
+gdaui_data_proxy_set_write_mode (GdauiDataProxy *iface, GdauiDataProxyWriteMode mode)
+{
+	g_return_val_if_fail (GDAUI_IS_DATA_PROXY (iface), FALSE);
+	
+	if (GDAUI_DATA_PROXY_GET_IFACE (iface)->set_write_mode)
+		return (GDAUI_DATA_PROXY_GET_IFACE (iface)->set_write_mode) (iface, mode);
+	else 
+		return FALSE;
+}
+
+/**
+ * gdaui_data_proxy_get_write_mode
+ * @iface: an object which implements the #GdauiDataProxy interface
+ *
+ * Get the way the modifications stored in the #GdaDataProxy used internally by @iface are written back to
+ * the #GdaDataModel which holds the data displayed in @iface.
+ *
+ * Returns: the write mode used by @iface
+ *
+ * Since: 4.2
+ */
+GdauiDataProxyWriteMode
+gdaui_data_proxy_get_write_mode (GdauiDataProxy *iface)
+{
+	g_return_val_if_fail (GDAUI_IS_DATA_PROXY (iface), GDAUI_DATA_PROXY_WRITE_ON_DEMAND);
+	
+	if (GDAUI_DATA_PROXY_GET_IFACE (iface)->get_write_mode)
+		return (GDAUI_DATA_PROXY_GET_IFACE (iface)->get_write_mode) (iface);
+	else 
+		return GDAUI_DATA_PROXY_WRITE_ON_DEMAND;
+}
diff --git a/libgda-ui/gdaui-data-proxy.h b/libgda-ui/gdaui-data-proxy.h
new file mode 100644
index 0000000..961e817
--- /dev/null
+++ b/libgda-ui/gdaui-data-proxy.h
@@ -0,0 +1,76 @@
+/* gdaui-data-proxy.h
+ *
+ * Copyright (C) 2004 - 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 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_DATA_PROXY_H_
+#define __GDAUI_DATA_PROXY_H_
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <libgda/gda-decl.h>
+#include "gdaui-decl.h"
+#include "gdaui-enums.h"
+
+G_BEGIN_DECLS
+
+#define GDAUI_TYPE_DATA_PROXY          (gdaui_data_proxy_get_type())
+#define GDAUI_DATA_PROXY(obj)          G_TYPE_CHECK_INSTANCE_CAST (obj, GDAUI_TYPE_DATA_PROXY, GdauiDataProxy)
+#define GDAUI_IS_DATA_PROXY(obj)       G_TYPE_CHECK_INSTANCE_TYPE (obj, GDAUI_TYPE_DATA_PROXY)
+#define GDAUI_DATA_PROXY_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GDAUI_TYPE_DATA_PROXY, GdauiDataProxyIface))
+
+typedef enum {
+	GDAUI_DATA_PROXY_WRITE_ON_DEMAND           = 0, /* write only when explicitly requested */
+	GDAUI_DATA_PROXY_WRITE_ON_ROW_CHANGE       = 1, /* write when the current selected row changes */
+	GDAUI_DATA_PROXY_WRITE_ON_VALUE_ACTIVATED  = 2, /* write when user activates a value change */
+	GDAUI_DATA_PROXY_WRITE_ON_VALUE_CHANGE     = 3  /* write when a parameters's value changes */
+} GdauiDataProxyWriteMode;
+
+/* struct for the interface */
+struct _GdauiDataProxyIface
+{
+	GTypeInterface           g_iface;
+
+	/* virtual table */
+	GdaDataProxy        *(* get_proxy)           (GdauiDataProxy *iface);
+	void                 (* set_column_editable) (GdauiDataProxy *iface, gint column, gboolean editable);
+	void                 (* show_column_actions) (GdauiDataProxy *iface, gint column, gboolean show_actions);
+	GtkActionGroup      *(* get_actions_group)   (GdauiDataProxy *iface);
+	gboolean             (* set_write_mode)      (GdauiDataProxy *iface, GdauiDataProxyWriteMode mode);
+	GdauiDataProxyWriteMode (* get_write_mode)(GdauiDataProxy *iface);
+
+	/* signals */
+	void                 (* proxy_changed)       (GdauiDataProxy *iface, GdaDataProxy *proxy);
+};
+
+GType             gdaui_data_proxy_get_type                  (void) G_GNUC_CONST;
+
+GdaDataProxy     *gdaui_data_proxy_get_proxy                 (GdauiDataProxy *iface);
+GtkActionGroup   *gdaui_data_proxy_get_actions_group         (GdauiDataProxy *iface);
+void              gdaui_data_proxy_perform_action            (GdauiDataProxy *iface, GdauiAction action);
+
+void              gdaui_data_proxy_column_set_editable       (GdauiDataProxy *iface, gint column, gboolean editable);
+void              gdaui_data_proxy_column_show_actions       (GdauiDataProxy *iface, gint column, gboolean show_actions);
+
+gboolean          gdaui_data_proxy_set_write_mode            (GdauiDataProxy *iface, GdauiDataProxyWriteMode mode);
+GdauiDataProxyWriteMode gdaui_data_proxy_get_write_mode   (GdauiDataProxy *iface);
+
+G_END_DECLS
+
+#endif
diff --git a/libgda-ui/gdaui-data-selector.c b/libgda-ui/gdaui-data-selector.c
new file mode 100644
index 0000000..5063d9e
--- /dev/null
+++ b/libgda-ui/gdaui-data-selector.c
@@ -0,0 +1,224 @@
+/* gdaui-data-selector.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 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 <string.h>
+#include <libgda/binreloc/gda-binreloc.h>
+#include "gdaui-data-selector.h"
+#include  <glib/gi18n-lib.h>
+#include <libgda-ui/gdaui-raw-form.h>
+#include <libgda-ui/gdaui-raw-grid.h>
+
+/* signals */
+enum
+{
+        SELECTION_CHANGED,
+        LAST_SIGNAL
+};
+
+static gint gdaui_data_selector_signals[LAST_SIGNAL] = { 0 };
+
+static void gdaui_data_selector_iface_init (gpointer g_class);
+
+GType
+gdaui_data_selector_get_type (void)
+{
+	static GType type = 0;
+
+	if (G_UNLIKELY (type == 0)) {
+		static const GTypeInfo info = {
+			sizeof (GdauiDataSelectorIface),
+			(GBaseInitFunc) gdaui_data_selector_iface_init,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) NULL,
+			NULL,
+			NULL,
+			0,
+			0,
+			(GInstanceInitFunc) NULL
+		};
+		
+		type = g_type_register_static (G_TYPE_INTERFACE, "GdauiDataSelector", &info, 0);
+		g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+	}
+	return type;
+}
+
+
+static void
+gdaui_data_selector_iface_init (gpointer g_class)
+{
+	static gboolean initialized = FALSE;
+
+	if (! initialized) {
+		gdaui_data_selector_signals[SELECTION_CHANGED] = 
+			g_signal_new ("selection-changed",
+                                      GDAUI_TYPE_DATA_SELECTOR,
+                                      G_SIGNAL_RUN_FIRST,
+                                      G_STRUCT_OFFSET (GdauiDataSelectorIface, selection_changed),
+                                      NULL, NULL,
+                                      g_cclosure_marshal_VOID__VOID, G_TYPE_NONE,
+                                      0);
+
+		initialized = TRUE;
+	}
+}
+
+/**
+ * gdaui_data_selector_get_model
+ * @iface: an object which implements the #GdauiDataSelector interface
+ *
+ * Queries the #GdaDataModel from which the data displayed by the widget implementing @iface
+ * are. Beware that the returned data model may be different than the one used when the
+ * widget was created in case it uses a #GdaDataProxy.
+ *
+ * Returns: the #GdaDataModel
+ *
+ * Since: 4.2
+ */
+GdaDataModel *
+gdaui_data_selector_get_model (GdauiDataSelector *iface)
+{
+	g_return_val_if_fail (GDAUI_IS_DATA_SELECTOR (iface), NULL);
+	
+	if (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->get_model)
+		return (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->get_model) (iface);
+	return NULL;
+}
+
+/**
+ * gdaui_data_selector_set_model
+ * @iface: an object which implements the #GdauiDataSelector interface
+ * @model: a #GdaDataModel to use
+ *
+ * Sets the data model from which the data being displayed are. Also see gdaui_data_selector_get_model()
+ *
+ * Since: 4.2
+ */
+void
+gdaui_data_selector_set_model (GdauiDataSelector *iface, GdaDataModel *model)
+{
+	g_return_if_fail (GDAUI_IS_DATA_SELECTOR (iface));
+	g_return_if_fail (!model || GDA_IS_DATA_MODEL (model));
+	
+	if (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->set_model)
+		(GDAUI_DATA_SELECTOR_GET_IFACE (iface)->set_model) (iface, model);
+}
+
+/**
+ * gdaui_data_selector_get_selected_rows
+ * @iface: an object which implements the #GdauiDataSelector interface
+ *
+ * Gat an array of selected rows. If no row is selected, the the returned value is %NULL.
+ *
+ * Returns: an array of #gint values, one for each selected row. Use g_array_free() when
+ * finished (passing %TRUE as the last argument)
+ *
+ * Since: 4.2
+ */
+GArray *
+gdaui_data_selector_get_selected_rows (GdauiDataSelector *iface)
+{
+	g_return_val_if_fail (GDAUI_IS_DATA_SELECTOR (iface), NULL);
+	
+	if (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->get_selected_rows)
+		return (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->get_selected_rows) (iface);
+	else
+		return NULL;
+}
+
+/**
+ * gdaui_data_selector_select_row
+ * @iface: an object which implements the #GdauiDataSelector interface
+ * @row: the row to select
+ *
+ * Returns: %TRUE if the row has been selected
+ *
+ * Since: 4.2
+ */
+gboolean
+gdaui_data_selector_select_row (GdauiDataSelector *iface, gint row)
+{
+	g_return_val_if_fail (GDAUI_IS_DATA_SELECTOR (iface), FALSE);
+	
+	if (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->select_row)
+		return (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->select_row) (iface, row);
+	else
+		return FALSE;
+}
+
+/**
+ * gdaui_data_selector_unselect_row
+ * @iface: an object which implements the #GdauiDataSelector interface
+ * @row: the row to unselect
+ *
+ * Since: 4.2
+ */
+void
+gdaui_data_selector_unselect_row (GdauiDataSelector *iface, gint row)
+{
+	g_return_if_fail (GDAUI_IS_DATA_SELECTOR (iface));
+	
+	if (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->unselect_row)
+		(GDAUI_DATA_SELECTOR_GET_IFACE (iface)->unselect_row) (iface, row);
+}
+
+/**
+ * gdaui_data_selector_set_column_visible
+ * @iface: an object which implements the #GdauiDataSelector interface
+ * @column: a column number, starting at 0
+ * @visible: required visibility of the data in the @column column
+ *
+ * Shows or hides the data at column @column
+ *
+ * Since: 4.2
+ */
+void
+gdaui_data_selector_set_column_visible (GdauiDataSelector *iface, gint column, gboolean visible)
+{
+	g_return_if_fail (GDAUI_IS_DATA_SELECTOR (iface));
+	
+	if (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->set_column_visible)
+		(GDAUI_DATA_SELECTOR_GET_IFACE (iface)->set_column_visible) (iface, column, visible);
+}
+
+/**
+ * gdaui_data_selector_get_data_set
+ * @iface: an object which implements the #GdauiDataSelector interface
+ *
+ * Get the #GdaDataModelIter object represented the current selected row in @iface. This
+ * function may return either %NULL or an invalid iterator (see gda_data_model_iter_is_valid()) if
+ * the selection cannot be represented by a single selected row.
+ *
+ * Note that the returned #GdaDataModelIter is actually an iterator iterating on the #GdaDataModel
+ * returned by the gdaui_data_selector_get_model() method.
+ *
+ * Returns: a pointer to a #GdaDataModelIter object, or %NULL
+ *
+ * Since: 4.2
+ */
+GdaDataModelIter *
+gdaui_data_selector_get_data_set (GdauiDataSelector *iface)
+{
+	g_return_val_if_fail (GDAUI_IS_DATA_SELECTOR (iface), NULL);
+
+	if (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->get_current_selection)
+		return (GDAUI_DATA_SELECTOR_GET_IFACE (iface)->get_current_selection) (iface);
+	return NULL;
+}
diff --git a/libgda-ui/gdaui-data-selector.h b/libgda-ui/gdaui-data-selector.h
new file mode 100644
index 0000000..935d15b
--- /dev/null
+++ b/libgda-ui/gdaui-data-selector.h
@@ -0,0 +1,70 @@
+/* gdaui-data-selector.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 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_DATA_SELECTOR_H_
+#define __GDAUI_DATA_SELECTOR_H_
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <libgda/libgda.h>
+#include "gdaui-decl.h"
+
+G_BEGIN_DECLS
+
+#define GDAUI_TYPE_DATA_SELECTOR          (gdaui_data_selector_get_type())
+#define GDAUI_DATA_SELECTOR(obj)          G_TYPE_CHECK_INSTANCE_CAST (obj, GDAUI_TYPE_DATA_SELECTOR, GdauiDataSelector)
+#define GDAUI_IS_DATA_SELECTOR(obj)       G_TYPE_CHECK_INSTANCE_TYPE (obj, GDAUI_TYPE_DATA_SELECTOR)
+#define GDAUI_DATA_SELECTOR_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GDAUI_TYPE_DATA_SELECTOR, GdauiDataSelectorIface))
+
+typedef struct _GdauiDataSelectorIface GdauiDataSelectorIface;
+typedef struct _GdauiDataSelector GdauiDataSelector;
+
+/* struct for the interface */
+struct _GdauiDataSelectorIface
+{
+	GTypeInterface           g_iface;
+
+	/* virtual table */
+	GdaDataModel     *(*get_model)             (GdauiDataSelector *iface);
+	void              (*set_model)             (GdauiDataSelector *iface, GdaDataModel *model);
+	GArray           *(*get_selected_rows)     (GdauiDataSelector *iface);
+	GdaDataModelIter *(*get_current_selection) (GdauiDataSelector *iface);
+	gboolean          (*select_row)            (GdauiDataSelector *iface, gint row);
+	void              (*unselect_row)          (GdauiDataSelector *iface, gint row);
+	void              (*set_column_visible)    (GdauiDataSelector *iface, gint column, gboolean visible);
+
+	/* signals */
+	void              (* selection_changed)    (GdauiDataSelector *iface);
+};
+
+GType             gdaui_data_selector_get_type              (void) G_GNUC_CONST;
+
+GdaDataModel     *gdaui_data_selector_get_model             (GdauiDataSelector *iface);
+void              gdaui_data_selector_set_model             (GdauiDataSelector *iface, GdaDataModel *model);
+GArray           *gdaui_data_selector_get_selected_rows     (GdauiDataSelector *iface);
+GdaDataModelIter *gdaui_data_selector_get_data_set (GdauiDataSelector *iface);
+gboolean          gdaui_data_selector_select_row            (GdauiDataSelector *iface, gint row);
+void              gdaui_data_selector_unselect_row          (GdauiDataSelector *iface, gint row);
+void              gdaui_data_selector_set_column_visible    (GdauiDataSelector *iface, gint column, gboolean visible);
+
+G_END_DECLS
+
+#endif
diff --git a/libgda-ui/gdaui-data-store.c b/libgda-ui/gdaui-data-store.c
index 8a3b564..6546a2f 100644
--- a/libgda-ui/gdaui-data-store.c
+++ b/libgda-ui/gdaui-data-store.c
@@ -28,17 +28,16 @@ static void gdaui_data_store_init (GdauiDataStore *store);
 static void gdaui_data_store_dispose (GObject *object);
 
 static void gdaui_data_store_set_property (GObject *object,
-					      guint param_id,
-					      const GValue *value,
-					      GParamSpec *pspec);
+					   guint param_id,
+					   const GValue *value,
+					   GParamSpec *pspec);
 static void gdaui_data_store_get_property (GObject *object,
-					      guint param_id,
-					      GValue *value,
-					      GParamSpec *pspec);
+					   guint param_id,
+					   GValue *value,
+					   GParamSpec *pspec);
 
 /* properties */
-enum
-{
+enum {
 	PROP_0,
 	PROP_MODEL,
 	PROP_PROXY,
@@ -87,7 +86,7 @@ gdaui_data_store_get_type (void)
 			sizeof (GdauiDataStore),
 			0,
 			(GInstanceInitFunc) gdaui_data_store_init
-		};		
+		};
 
 		static const GInterfaceInfo data_model_info = {
 			(GInterfaceInitFunc) data_store_tree_model_init,
@@ -123,7 +122,7 @@ static void
 gdaui_data_store_class_init (GdauiDataStoreClass * class)
 {
 	GObjectClass   *object_class = G_OBJECT_CLASS (class);
-	
+
 	parent_class = g_type_class_peek_parent (class);
 
 	object_class->dispose = gdaui_data_store_dispose;
@@ -164,9 +163,12 @@ row_inserted_cb (GdaDataProxy *proxy, gint row, GtkTreeModel *store)
 	((GdauiDataStore*) store)->priv->stamp = g_random_int ();
 	path = gtk_tree_path_new ();
         gtk_tree_path_append_index (path, row);
-	g_assert (gtk_tree_model_get_iter (store, &iter, path));
-	gtk_tree_model_row_inserted (store, path, &iter);
-	gtk_tree_path_free (path);
+	if (gtk_tree_model_get_iter (store, &iter, path)) {
+		gtk_tree_model_row_inserted (store, path, &iter);
+		gtk_tree_path_free (path);
+	}
+	else
+		g_warning ("OOh0");
 }
 
 static void
@@ -178,9 +180,12 @@ row_updated_cb (GdaDataProxy *proxy, gint row, GtkTreeModel *store)
 	((GdauiDataStore*) store)->priv->stamp = g_random_int ();
 	path = gtk_tree_path_new ();
         gtk_tree_path_append_index (path, row);
-	g_assert (gtk_tree_model_get_iter (store, &iter, path));
-	gtk_tree_model_row_changed (store, path, &iter);
-	gtk_tree_path_free (path);
+	if (gtk_tree_model_get_iter (store, &iter, path)) {
+		gtk_tree_model_row_changed (store, path, &iter);
+		gtk_tree_path_free (path);
+	}
+	else
+		g_warning ("OOh1");
 }
 
 static void
@@ -201,12 +206,12 @@ proxy_reset_cb (GdaDataProxy *proxy, GtkTreeModel *store)
 {
 	gint i, nrows;
 
-	while (((GdauiDataStore*) store)->priv->nrows > 0) 
+	while (((GdauiDataStore*) store)->priv->nrows > 0)
 		row_removed_cb (proxy, ((GdauiDataStore*) store)->priv->nrows - 1, store);
 
 	nrows = gda_data_model_get_n_rows ((GdaDataModel *) proxy);;
 	((GdauiDataStore*) store)->priv->nrows = 0;
-	for (i = 0; i < nrows; i++) 
+	for (i = 0; i < nrows; i++)
 		row_inserted_cb (proxy, i, store);
 }
 
@@ -246,9 +251,9 @@ gdaui_data_store_dispose (GObject *object)
 
 static void
 gdaui_data_store_set_property (GObject *object,
-				  guint param_id,
-				  const GValue *value,
-				  GParamSpec *pspec)
+			       guint param_id,
+			       const GValue *value,
+			       GParamSpec *pspec)
 {
 	GdauiDataStore *store;
 
@@ -273,11 +278,11 @@ gdaui_data_store_set_property (GObject *object,
 			store->priv->nrows = gda_data_model_get_n_rows (GDA_DATA_MODEL (store->priv->proxy));
 
 			/* connect to row changes */
-			g_signal_connect (G_OBJECT (proxy), "row_inserted",
+			g_signal_connect (G_OBJECT (proxy), "row-inserted",
 					  G_CALLBACK (row_inserted_cb), store);
-			g_signal_connect (G_OBJECT (proxy), "row_updated",
+			g_signal_connect (G_OBJECT (proxy), "row-updated",
 					  G_CALLBACK (row_updated_cb), store);
-			g_signal_connect (G_OBJECT (proxy), "row_removed",
+			g_signal_connect (G_OBJECT (proxy), "row-removed",
 					  G_CALLBACK (row_removed_cb), store);
 			g_signal_connect (G_OBJECT (proxy), "reset",
 					  G_CALLBACK (proxy_reset_cb), store);
@@ -296,9 +301,9 @@ gdaui_data_store_set_property (GObject *object,
 
 static void
 gdaui_data_store_get_property (GObject *object,
-				  guint param_id,
-				  GValue *value,
-				  GParamSpec *pspec)
+			       guint param_id,
+			       GValue *value,
+			       GParamSpec *pspec)
 {
 	GdauiDataStore *store;
 
@@ -315,7 +320,7 @@ gdaui_data_store_get_property (GObject *object,
 			break;
 		case PROP_ADD_NULL_ENTRY: {
 			gboolean prop;
-			
+
 			g_object_get (store->priv->proxy, "prepend_null_entry", &prop, NULL);
 			g_value_set_boolean (value, prop);
 			break;
@@ -331,6 +336,8 @@ gdaui_data_store_get_property (GObject *object,
  * Creates a #GtkTreeModel interface with a #GdaDataModel
  *
  * Returns: the new object
+ *
+ * Since: 4.2
  */
 GtkTreeModel *
 gdaui_data_store_new (GdaDataModel *model)
@@ -352,11 +359,13 @@ gdaui_data_store_new (GdaDataModel *model)
  *
  * Stores a value in the @store data model.
  *
- * Returns: TRUE on succes
+ * Returns: TRUE on success
+ *
+ * Since: 4.2
  */
 gboolean
 gdaui_data_store_set_value (GdauiDataStore *store, GtkTreeIter *iter,
-			       gint col, const GValue *value)
+			    gint col, const GValue *value)
 {
 	gint row, model_nb_cols;
 
@@ -395,13 +404,13 @@ gdaui_data_store_set_value (GdauiDataStore *store, GtkTreeIter *iter,
 		gint proxy_col;
 
 		proxy_col = (col < model_nb_cols) ? col : col - model_nb_cols;
-		return gda_data_model_set_value_at (GDA_DATA_MODEL (store->priv->proxy), 
+		return gda_data_model_set_value_at (GDA_DATA_MODEL (store->priv->proxy),
 						    proxy_col, row, value, NULL);
 	}
 
 	/* value's attributes */
 	if ((col >= model_nb_cols) && (col < 2 * model_nb_cols)) {
-		gda_data_proxy_alter_value_attributes (store->priv->proxy, row, col - model_nb_cols, 
+		gda_data_proxy_alter_value_attributes (store->priv->proxy, row, col - model_nb_cols,
 						       g_value_get_uint (value));
 		return TRUE;
 	}
@@ -414,6 +423,8 @@ gdaui_data_store_set_value (GdauiDataStore *store, GtkTreeIter *iter,
  * @iter: the considered row
  *
  * Marks the row pointed by @iter to be deleted
+ *
+ * Since: 4.2
  */
 void
 gdaui_data_store_delete (GdauiDataStore *store, GtkTreeIter *iter)
@@ -437,6 +448,8 @@ gdaui_data_store_delete (GdauiDataStore *store, GtkTreeIter *iter)
  * @iter: the considered row
  *
  * Remove the "to be deleted" mark the row pointed by @iter, if it existed.
+ *
+ * Since: 4.2
  */
 void
 gdaui_data_store_undelete (GdauiDataStore *store, GtkTreeIter *iter)
@@ -462,6 +475,8 @@ gdaui_data_store_undelete (GdauiDataStore *store, GtkTreeIter *iter)
  * Appends a new row.
  *
  * Returns: TRUE if no error occurred
+ *
+ * Since: 4.2
  */
 gboolean
 gdaui_data_store_append (GdauiDataStore *store, GtkTreeIter *iter)
@@ -489,6 +504,8 @@ gdaui_data_store_append (GdauiDataStore *store, GtkTreeIter *iter)
  * @store: a #GdauiDataStore object
  *
  * Returns: the internal #GdaDataProxy being used by @store
+ *
+ * Since: 4.2
  */
 GdaDataProxy *
 gdaui_data_store_get_proxy (GdauiDataStore *store)
@@ -505,7 +522,10 @@ gdaui_data_store_get_proxy (GdauiDataStore *store)
  * @iter: a valid #GtkTreeIter
  *
  * Get the number of the row represented by @iter
+ *
  * Returns: the row number, or -1 if an error occurred
+ *
+ * Since: 4.2
  */
 gint
 gdaui_data_store_get_row_from_iter (GdauiDataStore *store, GtkTreeIter *iter)
@@ -531,10 +551,12 @@ gdaui_data_store_get_row_from_iter (GdauiDataStore *store, GtkTreeIter *iter)
  * NOTE: the @cols_index array MUST contain a column index for each value in @values
  *
  * Returns: TRUE if the row has been identified @iter was set
+ *
+ * Since: 4.2
  */
 gboolean
 gdaui_data_store_get_iter_from_values (GdauiDataStore *store, GtkTreeIter *iter,
-					  GSList *values, gint *cols_index)
+				       GSList *values, gint *cols_index)
 {
 	gint row;
 
@@ -542,7 +564,7 @@ gdaui_data_store_get_iter_from_values (GdauiDataStore *store, GtkTreeIter *iter,
         g_return_val_if_fail (store->priv, FALSE);
         g_return_val_if_fail (store->priv->proxy, FALSE);
 	g_return_val_if_fail (values, FALSE);
-	
+
 	row = gda_data_model_get_row_from_values (GDA_DATA_MODEL (store->priv->proxy), values, cols_index);
 	if (row >= 0) {
 		if (iter) {
@@ -557,7 +579,7 @@ gdaui_data_store_get_iter_from_values (GdauiDataStore *store, GtkTreeIter *iter,
 
 
 
-/* 
+/*
  * GtkTreeModel Interface implementation
  *
  * REM about the GtkTreeIter: only the iter->user_data is used to retrieve a row in the data model:
@@ -582,7 +604,7 @@ data_store_get_n_columns (GtkTreeModel *tree_model)
         store = GDAUI_DATA_STORE (tree_model);
         g_return_val_if_fail (store->priv, 0);
         g_return_val_if_fail (store->priv->proxy, 0);
-	
+
         return gda_data_model_get_n_columns (GDA_DATA_MODEL (store->priv->proxy));
 }
 
@@ -627,7 +649,7 @@ data_store_get_column_type (GtkTreeModel *tree_model, gint index)
 	if (retval == 0)
 		g_warning ("Unknown GdaDataProxy column: %d", index);
 
-	return retval;	
+	return retval;
 }
 
 static gboolean
@@ -705,15 +727,15 @@ data_store_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, gint column,
 			g_value_set_pointer (value, gda_data_proxy_get_proxied_model (store->priv->proxy));
 			break;
 		case DATA_STORE_COL_MODEL_ROW:
-			g_value_set_int (value, gda_data_proxy_get_proxied_model_row (store->priv->proxy, 
+			g_value_set_int (value, gda_data_proxy_get_proxied_model_row (store->priv->proxy,
 										      GPOINTER_TO_INT (iter->user_data)));
 			break;
 		case DATA_STORE_COL_MODIFIED:
-			g_value_set_boolean (value, gda_data_proxy_row_has_changed (store->priv->proxy, 
+			g_value_set_boolean (value, gda_data_proxy_row_has_changed (store->priv->proxy,
 										    GPOINTER_TO_INT (iter->user_data)));
 			break;
 		case DATA_STORE_COL_TO_DELETE:
-			g_value_set_boolean (value, gda_data_proxy_row_is_deleted (store->priv->proxy, 
+			g_value_set_boolean (value, gda_data_proxy_row_is_deleted (store->priv->proxy,
 										   GPOINTER_TO_INT (iter->user_data)));
 			break;
 		default:
@@ -730,12 +752,12 @@ data_store_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, gint column,
 		gint proxy_col;
 
 		proxy_col = (column < model_nb_cols) ? column : column - model_nb_cols;
-		tmp = gda_data_model_get_value_at ((GdaDataModel*) store->priv->proxy, 
-						   proxy_col, 
+		tmp = gda_data_model_get_value_at ((GdaDataModel*) store->priv->proxy,
+						   proxy_col,
 						   GPOINTER_TO_INT (iter->user_data), NULL);
-		
+
 		rettype = data_store_get_column_type (tree_model, column);
-		
+
 		if (rettype == G_TYPE_POINTER)
 			g_value_set_pointer (value, (gpointer) tmp);
 		else if (tmp)
@@ -751,7 +773,7 @@ data_store_get_value (GtkTreeModel *tree_model, GtkTreeIter *iter, gint column,
 	if ((column >= model_nb_cols) && (column < 2 * model_nb_cols)) {
 		guint attr;
 
-		attr = gda_data_proxy_get_value_attributes (store->priv->proxy, 
+		attr = gda_data_proxy_get_value_attributes (store->priv->proxy,
 							    GPOINTER_TO_INT (iter->user_data), column - model_nb_cols);
 		g_value_set_uint (value, attr);
 	}
diff --git a/libgda-ui/gdaui-decl.h b/libgda-ui/gdaui-decl.h
index 6519b39..5cfb529 100644
--- a/libgda-ui/gdaui-decl.h
+++ b/libgda-ui/gdaui-decl.h
@@ -25,8 +25,8 @@
  * Interfaces 
  */
 
-typedef struct _GdauiDataWidget       GdauiDataWidget;
-typedef struct _GdauiDataWidgetIface  GdauiDataWidgetIface;
+typedef struct _GdauiDataProxy       GdauiDataProxy;
+typedef struct _GdauiDataProxyIface  GdauiDataProxyIface;
 
 /* 
  * Colors
diff --git a/libgda-ui/gdaui-form.c b/libgda-ui/gdaui-form.c
index ad17b28..b5a5ef6 100644
--- a/libgda-ui/gdaui-form.c
+++ b/libgda-ui/gdaui-form.c
@@ -1,6 +1,6 @@
 /* gdaui-form.c
  *
- * Copyright (C) 2002 - 2007 Vivien Malerba
+ * Copyright (C) 2002 - 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
@@ -22,21 +22,42 @@
 #include <glib/gi18n-lib.h>
 #include <libgda/libgda.h>
 #include "gdaui-form.h"
-#include "gdaui-data-widget.h"
+#include "gdaui-data-proxy.h"
+#include "gdaui-data-selector.h"
 #include "gdaui-raw-form.h"
-#include "gdaui-data-widget-info.h"
+#include "gdaui-data-proxy-info.h"
+#include "gdaui-enum-types.h"
 
 static void gdaui_form_class_init (GdauiFormClass * class);
 static void gdaui_form_init (GdauiForm *wid);
 
 static void gdaui_form_set_property (GObject *object,
-					guint param_id,
-					const GValue *value,
-					GParamSpec *pspec);
+				     guint param_id,
+				     const GValue *value,
+				     GParamSpec *pspec);
 static void gdaui_form_get_property (GObject *object,
-					guint param_id,
-					GValue *value,
-					GParamSpec *pspec);
+				     guint param_id,
+				     GValue *value,
+				     GParamSpec *pspec);
+
+/* GdauiDataProxy interface */
+static void            gdaui_form_widget_init         (GdauiDataProxyIface *iface);
+static GdaDataProxy   *gdaui_form_get_proxy           (GdauiDataProxy *iface);
+static void            gdaui_form_set_column_editable (GdauiDataProxy *iface, gint column, gboolean editable);
+static void            gdaui_form_show_column_actions (GdauiDataProxy *iface, gint column, gboolean show_actions);
+static GtkActionGroup *gdaui_form_get_actions_group   (GdauiDataProxy *iface);
+static gboolean        gdaui_form_widget_set_write_mode (GdauiDataProxy *iface, GdauiDataProxyWriteMode mode);
+static GdauiDataProxyWriteMode gdaui_form_widget_get_write_mode (GdauiDataProxy *iface);
+
+/* GdauiDataSelector interface */
+static void              gdaui_form_selector_init (GdauiDataSelectorIface *iface);
+static GdaDataModel     *gdaui_form_selector_get_model (GdauiDataSelector *iface);
+static void              gdaui_form_selector_set_model (GdauiDataSelector *iface, GdaDataModel *model);
+static GArray           *gdaui_form_selector_get_selected_rows (GdauiDataSelector *iface);
+static GdaDataModelIter *gdaui_form_selector_get_current_selection (GdauiDataSelector *iface);
+static gboolean          gdaui_form_selector_select_row (GdauiDataSelector *iface, gint row);
+static void              gdaui_form_selector_unselect_row (GdauiDataSelector *iface, gint row);
+static void              gdaui_form_selector_set_column_visible (GdauiDataSelector *iface, gint column, gboolean visible);
 
 struct _GdauiFormPriv
 {
@@ -48,12 +69,12 @@ struct _GdauiFormPriv
 static GObjectClass *parent_class = NULL;
 
 /* properties */
-enum
-{
-        PROP_0,
-        PROP_RAW_FORM,
+enum {
+	PROP_0,
+	PROP_RAW_FORM,
 	PROP_INFO,
-	PROP_MODEL
+	PROP_MODEL,
+	PROP_INFO_FLAGS
 };
 
 GType
@@ -72,32 +93,75 @@ gdaui_form_get_type (void)
 			sizeof (GdauiForm),
 			0,
 			(GInstanceInitFunc) gdaui_form_init
-		};		
+		};
+
+		static const GInterfaceInfo proxy_info = {
+                        (GInterfaceInitFunc) gdaui_form_widget_init,
+                        NULL,
+                        NULL
+                };
+
+		static const GInterfaceInfo selector_info = {
+                        (GInterfaceInitFunc) gdaui_form_selector_init,
+                        NULL,
+                        NULL
+                };
 
 		type = g_type_register_static (GTK_TYPE_VBOX, "GdauiForm", &info, 0);
+		g_type_add_interface_static (type, GDAUI_TYPE_DATA_PROXY, &proxy_info);
+		g_type_add_interface_static (type, GDAUI_TYPE_DATA_SELECTOR, &selector_info);
 	}
 
 	return type;
 }
 
 static void
+gdaui_form_widget_init (GdauiDataProxyIface *iface)
+{
+	iface->get_proxy = gdaui_form_get_proxy;
+	iface->set_column_editable = gdaui_form_set_column_editable;
+	iface->show_column_actions = gdaui_form_show_column_actions;
+	iface->get_actions_group = gdaui_form_get_actions_group;
+	iface->set_write_mode = gdaui_form_widget_set_write_mode;
+	iface->get_write_mode = gdaui_form_widget_get_write_mode;
+}
+
+static void
+gdaui_form_selector_init (GdauiDataSelectorIface *iface)
+{
+	iface->get_model = gdaui_form_selector_get_model;
+	iface->set_model = gdaui_form_selector_set_model;
+	iface->get_selected_rows = gdaui_form_selector_get_selected_rows;
+	iface->get_current_selection = gdaui_form_selector_get_current_selection;
+	iface->select_row = gdaui_form_selector_select_row;
+	iface->unselect_row = gdaui_form_selector_unselect_row;
+	iface->set_column_visible = gdaui_form_selector_set_column_visible;
+}
+
+static void
 gdaui_form_class_init (GdauiFormClass *class)
 {
 	GObjectClass   *object_class = G_OBJECT_CLASS (class);
-	
+
 	parent_class = g_type_class_peek_parent (class);
 
 	/* Properties */
-	
+
         object_class->set_property = gdaui_form_set_property;
         object_class->get_property = gdaui_form_get_property;
 	g_object_class_install_property (object_class, PROP_RAW_FORM,
-                                         g_param_spec_object ("raw_form", NULL, NULL, GDAUI_TYPE_RAW_FORM,
-                                                               G_PARAM_READABLE));
+                                         g_param_spec_object ("raw-form", NULL, NULL, GDAUI_TYPE_RAW_FORM,
+							      G_PARAM_READABLE));
 	g_object_class_install_property (object_class, PROP_INFO,
-                                         g_param_spec_object ("widget_info", NULL, NULL, GDAUI_TYPE_DATA_WIDGET_INFO,
+                                         g_param_spec_object ("info", NULL, NULL, GDAUI_TYPE_DATA_PROXY_INFO,
 							      G_PARAM_READABLE));
-	
+
+	g_object_class_install_property (object_class, PROP_INFO_FLAGS,
+                                         g_param_spec_flags ("info-flags", NULL, NULL,
+							     GDAUI_TYPE_DATA_PROXY_INFO_FLAG,
+							     GDAUI_DATA_PROXY_INFO_CURRENT_ROW,
+							     G_PARAM_READABLE | G_PARAM_WRITABLE));
+
 	g_object_class_install_property (object_class, PROP_MODEL,
 					 g_param_spec_object ("model", NULL, NULL,
 							      GDA_TYPE_DATA_MODEL,
@@ -105,21 +169,32 @@ gdaui_form_class_init (GdauiFormClass *class)
 }
 
 static void
+form_layout_changed_cb (GdauiBasicForm *raw_form, GdauiForm *form)
+{
+	gboolean expand;
+	g_object_get (G_OBJECT (form->priv->raw_form), "can-expand", &expand, NULL);
+	gtk_container_child_set (GTK_CONTAINER (form), form->priv->raw_form,
+				 "expand", expand, "fill", expand, NULL);
+	gtk_widget_queue_resize ((GtkWidget*) form);
+}
+
+static void
 gdaui_form_init (GdauiForm *form)
 {
 	form->priv = g_new0 (GdauiFormPriv, 1);
 	form->priv->raw_form = NULL;
 	form->priv->info = NULL;
-	
+
 	form->priv->raw_form = gdaui_raw_form_new (NULL);
-	gtk_box_pack_start (GTK_BOX (form), form->priv->raw_form, TRUE, TRUE, 0);
+	gtk_box_pack_start (GTK_BOX (form), form->priv->raw_form, FALSE, FALSE, 0);
 	gtk_widget_show (form->priv->raw_form);
+	g_signal_connect (form->priv->raw_form, "layout-changed",
+			  G_CALLBACK (form_layout_changed_cb), form);
 
-	form->priv->info = gdaui_data_widget_info_new (GDAUI_DATA_WIDGET (form->priv->raw_form), 
-							  GDAUI_DATA_WIDGET_INFO_CURRENT_ROW |
-							  GDAUI_DATA_WIDGET_INFO_ROW_MODIFY_BUTTONS |
-							  GDAUI_DATA_WIDGET_INFO_ROW_MOVE_BUTTONS);
-	gtk_box_pack_start (GTK_BOX (form), form->priv->info, FALSE, TRUE, 0);
+	form->priv->info = gdaui_data_proxy_info_new (GDAUI_DATA_PROXY (form->priv->raw_form),
+						      GDAUI_DATA_PROXY_INFO_CURRENT_ROW |
+						      GDAUI_DATA_PROXY_INFO_ROW_MOVE_BUTTONS);
+	gtk_box_pack_start (GTK_BOX (form), form->priv->info, FALSE, FALSE, 0);
 	gtk_widget_show (form->priv->info);
 
 }
@@ -131,40 +206,49 @@ gdaui_form_init (GdauiForm *form)
  * Creates a new #GdauiForm widget suitable to display the data in @model
  *
  *  Returns: the new widget
+ *
+ *
+ * Since: 4.2
  */
 GtkWidget *
 gdaui_form_new (GdaDataModel *model)
 {
 	GdauiForm *form;
-	
+
 	g_return_val_if_fail (!model || GDA_IS_DATA_MODEL (model), NULL);
-	
-	form = (GdauiForm *) g_object_new (GDAUI_TYPE_FORM,
-	                                     "model", model, NULL);
-	
+
+	form = (GdauiForm *) g_object_new (GDAUI_TYPE_FORM, "model", model, NULL);
+
 	return (GtkWidget *) form;
 }
 
 
 static void
 gdaui_form_set_property (GObject *object,
-				 guint param_id,
-				 const GValue *value,
-				 GParamSpec *pspec)
+			 guint param_id,
+			 const GValue *value,
+			 GParamSpec *pspec)
 {
 	GdauiForm *form;
 	GdaDataModel *model;
 
 	form = GDAUI_FORM (object);
-	
+
 	if (form->priv) {
 		switch (param_id) {
-		case PROP_MODEL:
+		case PROP_MODEL: {
+			gboolean expand;
 			model = GDA_DATA_MODEL (g_value_get_object (value));
-			g_object_set (G_OBJECT(form->priv->raw_form),
-			              "model", model, NULL);
+			g_object_set (G_OBJECT (form->priv->raw_form), "model", model, NULL);
+			g_object_get (G_OBJECT (form->priv->raw_form), "can-expand", &expand, NULL);
+			gtk_container_child_set (GTK_CONTAINER (form), form->priv->raw_form,
+						 "expand", expand, "fill", expand, NULL);
+			gtk_widget_queue_resize ((GtkWidget*) form);
+			break;
+		}
+		case PROP_INFO_FLAGS:
+			g_object_set (G_OBJECT (form->priv->info), "flags", g_value_get_flags (value), NULL);
 			break;
-			
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 			break;
@@ -174,9 +258,9 @@ gdaui_form_set_property (GObject *object,
 
 static void
 gdaui_form_get_property (GObject *object,
-				 guint param_id,
-				 GValue *value,
-				 GParamSpec *pspec)
+			 guint param_id,
+			 GValue *value,
+			 GParamSpec *pspec)
 {
 	GdauiForm *form;
 	GdaDataModel *model;
@@ -190,9 +274,14 @@ gdaui_form_get_property (GObject *object,
 		case PROP_INFO:
 			g_value_set_object (value, form->priv->info);
 			break;
+		case PROP_INFO_FLAGS: {
+			GdauiDataProxyInfoFlag flags;
+			g_object_get (G_OBJECT (form->priv->info), "flags", &flags, NULL);
+			g_value_set_flags (value, flags);
+			break;
+		}
 		case PROP_MODEL:
-			g_object_get (G_OBJECT (form->priv->raw_form),
-			              "model", &model, NULL);
+			g_object_get (G_OBJECT (form->priv->raw_form), "model", &model, NULL);
 			g_value_take_object (value, G_OBJECT (model));
 			break;
 		default:
@@ -201,3 +290,86 @@ gdaui_form_get_property (GObject *object,
 		}
         }
 }
+
+/* GdauiDataProxy interface */
+static GdaDataProxy *
+gdaui_form_get_proxy (GdauiDataProxy *iface)
+{
+	return gdaui_data_proxy_get_proxy ((GdauiDataProxy*) GDAUI_FORM (iface)->priv->raw_form);
+}
+
+static void
+gdaui_form_set_column_editable (GdauiDataProxy *iface, gint column, gboolean editable)
+{
+	gdaui_data_proxy_column_set_editable ((GdauiDataProxy*) GDAUI_FORM (iface)->priv->raw_form,
+					      column, editable);
+}
+
+static void
+gdaui_form_show_column_actions (GdauiDataProxy *iface, gint column, gboolean show_actions)
+{
+	gdaui_data_proxy_column_show_actions ((GdauiDataProxy*) GDAUI_FORM (iface)->priv->raw_form,
+					      column, show_actions);
+}
+
+static GtkActionGroup *
+gdaui_form_get_actions_group (GdauiDataProxy *iface)
+{
+	return gdaui_data_proxy_get_actions_group ((GdauiDataProxy*) GDAUI_FORM (iface)->priv->raw_form);
+}
+
+static gboolean
+gdaui_form_widget_set_write_mode (GdauiDataProxy *iface, GdauiDataProxyWriteMode mode)
+{
+	return gdaui_data_proxy_set_write_mode ((GdauiDataProxy*) GDAUI_FORM (iface)->priv->raw_form, mode);
+}
+
+static GdauiDataProxyWriteMode
+gdaui_form_widget_get_write_mode (GdauiDataProxy *iface)
+{
+	return gdaui_data_proxy_get_write_mode ((GdauiDataProxy*) GDAUI_FORM (iface)->priv->raw_form);
+}
+
+/* GdauiDataSelector interface */
+static GdaDataModel *
+gdaui_form_selector_get_model (GdauiDataSelector *iface)
+{
+	return gdaui_data_selector_get_model ((GdauiDataSelector*) GDAUI_FORM (iface)->priv->raw_form);
+}
+
+static void
+gdaui_form_selector_set_model (GdauiDataSelector *iface, GdaDataModel *model)
+{
+	gdaui_data_selector_set_model ((GdauiDataSelector*) GDAUI_FORM (iface)->priv->raw_form, model);
+}
+
+static GArray *
+gdaui_form_selector_get_selected_rows (GdauiDataSelector *iface)
+{
+	return gdaui_data_selector_get_selected_rows ((GdauiDataSelector*) GDAUI_FORM (iface)->priv->raw_form);
+}
+
+static GdaDataModelIter *
+gdaui_form_selector_get_current_selection (GdauiDataSelector *iface)
+{
+	return gdaui_data_selector_get_data_set ((GdauiDataSelector*) GDAUI_FORM (iface)->priv->raw_form);
+}
+
+static gboolean
+gdaui_form_selector_select_row (GdauiDataSelector *iface, gint row)
+{
+	return gdaui_data_selector_select_row ((GdauiDataSelector*) GDAUI_FORM (iface)->priv->raw_form, row);
+}
+
+static void
+gdaui_form_selector_unselect_row (GdauiDataSelector *iface, gint row)
+{
+	gdaui_data_selector_unselect_row ((GdauiDataSelector*) GDAUI_FORM (iface)->priv->raw_form, row);
+}
+
+static void
+gdaui_form_selector_set_column_visible (GdauiDataSelector *iface, gint column, gboolean visible)
+{
+	gdaui_data_selector_set_column_visible ((GdauiDataSelector*) GDAUI_FORM (iface)->priv->raw_form,
+						column, visible);
+}
diff --git a/libgda-ui/gdaui-grid.c b/libgda-ui/gdaui-grid.c
index 306bf24..a3bc072 100644
--- a/libgda-ui/gdaui-grid.c
+++ b/libgda-ui/gdaui-grid.c
@@ -22,9 +22,11 @@
 #include <glib/gi18n-lib.h>
 #include <libgda/libgda.h>
 #include "gdaui-grid.h"
-#include "gdaui-data-widget.h"
+#include "gdaui-data-proxy.h"
+#include "gdaui-data-selector.h"
 #include "gdaui-raw-grid.h"
-#include "gdaui-data-widget-info.h"
+#include "gdaui-data-proxy-info.h"
+#include "gdaui-enum-types.h"
 
 static void gdaui_grid_class_init (GdauiGridClass * class);
 static void gdaui_grid_init (GdauiGrid *wid);
@@ -38,6 +40,25 @@ static void gdaui_grid_get_property (GObject *object,
 				     GValue *value,
 				     GParamSpec *pspec);
 
+/* GdauiDataProxy interface */
+static void            gdaui_grid_widget_init         (GdauiDataProxyIface *iface);
+static GdaDataProxy   *gdaui_grid_get_proxy           (GdauiDataProxy *iface);
+static void            gdaui_grid_set_column_editable (GdauiDataProxy *iface, gint column, gboolean editable);
+static void            gdaui_grid_show_column_actions (GdauiDataProxy *iface, gint column, gboolean show_actions);
+static GtkActionGroup *gdaui_grid_get_actions_group   (GdauiDataProxy *iface);
+static gboolean        gdaui_grid_widget_set_write_mode (GdauiDataProxy *iface, GdauiDataProxyWriteMode mode);
+static GdauiDataProxyWriteMode gdaui_grid_widget_get_write_mode (GdauiDataProxy *iface);
+
+/* GdauiDataSelector interface */
+static void              gdaui_grid_selector_init (GdauiDataSelectorIface *iface);
+static GdaDataModel     *gdaui_grid_selector_get_model (GdauiDataSelector *iface);
+static void              gdaui_grid_selector_set_model (GdauiDataSelector *iface, GdaDataModel *model);
+static GArray           *gdaui_grid_selector_get_selected_rows (GdauiDataSelector *iface);
+static GdaDataModelIter *gdaui_grid_selector_get_current_selection (GdauiDataSelector *iface);
+static gboolean          gdaui_grid_selector_select_row (GdauiDataSelector *iface, gint row);
+static void              gdaui_grid_selector_unselect_row (GdauiDataSelector *iface, gint row);
+static void              gdaui_grid_selector_set_column_visible (GdauiDataSelector *iface, gint column, gboolean visible);
+
 struct _GdauiGridPriv
 {
 	GtkWidget *raw_grid;
@@ -48,12 +69,12 @@ struct _GdauiGridPriv
 static GObjectClass *parent_class = NULL;
 
 /* properties */
-enum
-{
-        PROP_0,
-        PROP_RAW_GRID,
+enum {
+	PROP_0,
+	PROP_RAW_GRID,
 	PROP_INFO,
-	PROP_MODEL
+	PROP_MODEL,
+	PROP_INFO_FLAGS
 };
 
 GType
@@ -72,32 +93,75 @@ gdaui_grid_get_type (void)
 			sizeof (GdauiGrid),
 			0,
 			(GInstanceInitFunc) gdaui_grid_init
-		};		
+		};
+
+		static const GInterfaceInfo proxy_info = {
+                        (GInterfaceInitFunc) gdaui_grid_widget_init,
+                        NULL,
+                        NULL
+                };
+
+		static const GInterfaceInfo selector_info = {
+                        (GInterfaceInitFunc) gdaui_grid_selector_init,
+                        NULL,
+                        NULL
+                };
 
 		type = g_type_register_static (GTK_TYPE_VBOX, "GdauiGrid", &info, 0);
+		g_type_add_interface_static (type, GDAUI_TYPE_DATA_PROXY, &proxy_info);
+		g_type_add_interface_static (type, GDAUI_TYPE_DATA_SELECTOR, &selector_info);
+
 	}
 
 	return type;
 }
 
 static void
+gdaui_grid_widget_init (GdauiDataProxyIface *iface)
+{
+	iface->get_proxy = gdaui_grid_get_proxy;
+	iface->set_column_editable = gdaui_grid_set_column_editable;
+	iface->show_column_actions = gdaui_grid_show_column_actions;
+	iface->get_actions_group = gdaui_grid_get_actions_group;
+	iface->set_write_mode = gdaui_grid_widget_set_write_mode;
+	iface->get_write_mode = gdaui_grid_widget_get_write_mode;
+}
+
+static void
+gdaui_grid_selector_init (GdauiDataSelectorIface *iface)
+{
+	iface->get_model = gdaui_grid_selector_get_model;
+	iface->set_model = gdaui_grid_selector_set_model;
+	iface->get_selected_rows = gdaui_grid_selector_get_selected_rows;
+	iface->get_current_selection = gdaui_grid_selector_get_current_selection;
+	iface->select_row = gdaui_grid_selector_select_row;
+	iface->unselect_row = gdaui_grid_selector_unselect_row;
+	iface->set_column_visible = gdaui_grid_selector_set_column_visible;
+}
+
+static void
 gdaui_grid_class_init (GdauiGridClass *class)
 {
 	GObjectClass   *object_class = G_OBJECT_CLASS (class);
-	
+
 	parent_class = g_type_class_peek_parent (class);
 
 	/* Properties */
         object_class->set_property = gdaui_grid_set_property;
         object_class->get_property = gdaui_grid_get_property;
 	g_object_class_install_property (object_class, PROP_RAW_GRID,
-                                         g_param_spec_object ("raw_grid", NULL, NULL, 
+                                         g_param_spec_object ("raw-grid", NULL, NULL,
 							      GDAUI_TYPE_RAW_GRID,
 							      G_PARAM_READABLE));
 	g_object_class_install_property (object_class, PROP_INFO,
-                                         g_param_spec_object ("widget_info", NULL, NULL, 
-							      GDAUI_TYPE_DATA_WIDGET_INFO,
+                                         g_param_spec_object ("info", NULL, NULL,
+							      GDAUI_TYPE_DATA_PROXY_INFO,
 							      G_PARAM_READABLE));
+	g_object_class_install_property (object_class, PROP_INFO_FLAGS,
+                                         g_param_spec_flags ("info-flags", NULL, NULL,
+							     GDAUI_TYPE_DATA_PROXY_INFO_FLAG,
+							     GDAUI_DATA_PROXY_INFO_CURRENT_ROW,
+							     G_PARAM_READABLE | G_PARAM_WRITABLE));
 	g_object_class_install_property (object_class, PROP_MODEL,
 	                                 g_param_spec_object ("model", NULL, NULL,
 	                                                      GDA_TYPE_DATA_MODEL,
@@ -108,11 +172,11 @@ static void
 gdaui_grid_init (GdauiGrid *grid)
 {
 	GtkWidget *sw;
-	
+
 	grid->priv = g_new0 (GdauiGridPriv, 1);
 	grid->priv->raw_grid = NULL;
 	grid->priv->info = NULL;
-	
+
 	sw = gtk_scrolled_window_new (NULL, NULL);
         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
         gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN);
@@ -123,10 +187,8 @@ gdaui_grid_init (GdauiGrid *grid)
 	gtk_container_add (GTK_CONTAINER (sw), grid->priv->raw_grid);
 	gtk_widget_show (grid->priv->raw_grid);
 
-	grid->priv->info = gdaui_data_widget_info_new (GDAUI_DATA_WIDGET (grid->priv->raw_grid), 
-							  GDAUI_DATA_WIDGET_INFO_CURRENT_ROW |
-							  GDAUI_DATA_WIDGET_INFO_ROW_MODIFY_BUTTONS |
-							  GDAUI_DATA_WIDGET_INFO_CHUNCK_CHANGE_BUTTONS);
+	grid->priv->info = gdaui_data_proxy_info_new (GDAUI_DATA_PROXY (grid->priv->raw_grid),
+						      GDAUI_DATA_PROXY_INFO_CURRENT_ROW);
 	gtk_box_pack_start (GTK_BOX (grid), grid->priv->info, FALSE, TRUE, 0);
 	gtk_widget_show (grid->priv->info);
 }
@@ -137,13 +199,15 @@ gdaui_grid_init (GdauiGrid *grid)
  *
  * Creates a new #GdauiGrid widget suitable to display the data in @model
  *
- *  Returns: the new widget
+ * Returns: the new widget
+ *
+ * Since: 4.2
  */
 GtkWidget *
 gdaui_grid_new (GdaDataModel *model)
 {
 	GdauiGrid *grid;
-	
+
 	g_return_val_if_fail (!model || GDA_IS_DATA_MODEL (model), NULL);
 
 	grid = (GdauiGrid *) g_object_new (GDAUI_TYPE_GRID,
@@ -155,20 +219,22 @@ gdaui_grid_new (GdaDataModel *model)
 
 static void
 gdaui_grid_set_property (GObject *object,
-				 guint param_id,
-				 const GValue *value,
-				 GParamSpec *pspec)
+			 guint param_id,
+			 const GValue *value,
+			 GParamSpec *pspec)
 {
 	GdauiGrid *grid;
 	GdaDataModel *model;
-	
+
 	grid = GDAUI_GRID (object);
-	
+
 	switch (param_id) {
 	case PROP_MODEL:
 		model = GDA_DATA_MODEL (g_value_get_object (value));
-		g_object_set(G_OBJECT (grid->priv->raw_grid),
-		             "model", model, NULL);
+		g_object_set (G_OBJECT (grid->priv->raw_grid), "model", model, NULL);
+		break;
+	case PROP_INFO_FLAGS:
+		g_object_set (G_OBJECT (grid->priv->info), "flags", g_value_get_flags (value), NULL);
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
@@ -178,15 +244,15 @@ gdaui_grid_set_property (GObject *object,
 
 static void
 gdaui_grid_get_property (GObject *object,
-				 guint param_id,
-				 GValue *value,
-				 GParamSpec *pspec)
+			 guint param_id,
+			 GValue *value,
+			 GParamSpec *pspec)
 {
 	GdauiGrid *grid;
 	GdaDataModel *model;
 
 	grid = GDAUI_GRID (object);
-	
+
 	switch (param_id) {
 	case PROP_RAW_GRID:
 		g_value_set_object (value, grid->priv->raw_grid);
@@ -194,36 +260,20 @@ gdaui_grid_get_property (GObject *object,
 	case PROP_INFO:
 		g_value_set_object (value, grid->priv->info);
 		break;
+	case PROP_INFO_FLAGS: {
+			GdauiDataProxyInfoFlag flags;
+			g_object_get (G_OBJECT (grid->priv->info), "flags", &flags, NULL);
+			g_value_set_flags (value, flags);
+			break;
+		}
 	case PROP_MODEL:
-		g_object_get (G_OBJECT (grid->priv->raw_grid),
-		              "model", &model, NULL);
+		g_object_get (G_OBJECT (grid->priv->raw_grid), "model", &model, NULL);
 		g_value_take_object (value, G_OBJECT (model));
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 		break;
-	}	
-}
-
-/**
- * gdaui_grid_get_selection
- * @grid: a #GdauiGrid widget
- * 
- * Returns the list of the currently selected rows in a #GdauiGrid widget. 
- * The returned value is a list of integers, which represent each of the selected rows.
- *
- * If new rows have been inserted, then those new rows will have a row number equal to -1.
- * This function is a wrapper around the gdaui_raw_grid_get_selection() function.
- *
- * Returns: a new list, should be freed (by calling g_list_free) when no longer needed.
- */
-GList *
-gdaui_grid_get_selection (GdauiGrid *grid)
-{
-	g_return_val_if_fail (grid && GDAUI_IS_GRID (grid), NULL);
-	g_return_val_if_fail (grid->priv, NULL);
-
-	return gdaui_raw_grid_get_selection (GDAUI_RAW_GRID (grid->priv->raw_grid));
+	}
 }
 
 /**
@@ -231,7 +281,7 @@ gdaui_grid_get_selection (GdauiGrid *grid)
  * @grid: a #GdauiGrid widget
  * @sample_size:
  *
- *
+ * Since: 4.2
  */
 void
 gdaui_grid_set_sample_size (GdauiGrid *grid, gint sample_size)
@@ -241,3 +291,86 @@ gdaui_grid_set_sample_size (GdauiGrid *grid, gint sample_size)
 
 	gdaui_raw_grid_set_sample_size (GDAUI_RAW_GRID (grid->priv->raw_grid), sample_size);
 }
+
+/* GdauiDataProxy interface */
+static GdaDataProxy *
+gdaui_grid_get_proxy (GdauiDataProxy *iface)
+{
+	return gdaui_data_proxy_get_proxy ((GdauiDataProxy*) GDAUI_GRID (iface)->priv->raw_grid);
+}
+
+static void
+gdaui_grid_set_column_editable (GdauiDataProxy *iface, gint column, gboolean editable)
+{
+	gdaui_data_proxy_column_set_editable ((GdauiDataProxy*) GDAUI_GRID (iface)->priv->raw_grid,
+					      column, editable);
+}
+
+static void
+gdaui_grid_show_column_actions (GdauiDataProxy *iface, gint column, gboolean show_actions)
+{
+	gdaui_data_proxy_column_show_actions ((GdauiDataProxy*) GDAUI_GRID (iface)->priv->raw_grid,
+					      column, show_actions);
+}
+
+static GtkActionGroup *
+gdaui_grid_get_actions_group (GdauiDataProxy *iface)
+{
+	return gdaui_data_proxy_get_actions_group ((GdauiDataProxy*) GDAUI_GRID (iface)->priv->raw_grid);
+}
+
+static gboolean
+gdaui_grid_widget_set_write_mode (GdauiDataProxy *iface, GdauiDataProxyWriteMode mode)
+{
+	return gdaui_data_proxy_set_write_mode ((GdauiDataProxy*) GDAUI_GRID (iface)->priv->raw_grid, mode);
+}
+
+static GdauiDataProxyWriteMode
+gdaui_grid_widget_get_write_mode (GdauiDataProxy *iface)
+{
+	return gdaui_data_proxy_get_write_mode ((GdauiDataProxy*) GDAUI_GRID (iface)->priv->raw_grid);
+}
+
+/* GdauiDataSelector interface */
+static GdaDataModel *
+gdaui_grid_selector_get_model (GdauiDataSelector *iface)
+{
+	return gdaui_data_selector_get_model ((GdauiDataSelector*) GDAUI_GRID (iface)->priv->raw_grid);
+}
+
+static void
+gdaui_grid_selector_set_model (GdauiDataSelector *iface, GdaDataModel *model)
+{
+	gdaui_data_selector_set_model ((GdauiDataSelector*) GDAUI_GRID (iface)->priv->raw_grid, model);
+}
+
+static GArray *
+gdaui_grid_selector_get_selected_rows (GdauiDataSelector *iface)
+{
+	return gdaui_data_selector_get_selected_rows ((GdauiDataSelector*) GDAUI_GRID (iface)->priv->raw_grid);
+}
+
+static GdaDataModelIter *
+gdaui_grid_selector_get_current_selection (GdauiDataSelector *iface)
+{
+	return gdaui_data_selector_get_data_set ((GdauiDataSelector*) GDAUI_GRID (iface)->priv->raw_grid);
+}
+
+static gboolean
+gdaui_grid_selector_select_row (GdauiDataSelector *iface, gint row)
+{
+	return gdaui_data_selector_select_row ((GdauiDataSelector*) GDAUI_GRID (iface)->priv->raw_grid, row);
+}
+
+static void
+gdaui_grid_selector_unselect_row (GdauiDataSelector *iface, gint row)
+{
+	gdaui_data_selector_unselect_row ((GdauiDataSelector*) GDAUI_GRID (iface)->priv->raw_grid, row);
+}
+
+static void
+gdaui_grid_selector_set_column_visible (GdauiDataSelector *iface, gint column, gboolean visible)
+{
+	gdaui_data_selector_set_column_visible ((GdauiDataSelector*) GDAUI_GRID (iface)->priv->raw_grid,
+						column, visible);
+}
diff --git a/libgda-ui/gdaui-grid.h b/libgda-ui/gdaui-grid.h
index 6e87989..cf65406 100644
--- a/libgda-ui/gdaui-grid.h
+++ b/libgda-ui/gdaui-grid.h
@@ -55,7 +55,6 @@ struct _GdauiGridClass
 GType             gdaui_grid_get_type            (void) G_GNUC_CONST;
 
 GtkWidget        *gdaui_grid_new                 (GdaDataModel *model);
-GList            *gdaui_grid_get_selection       (GdauiGrid *grid);
 void              gdaui_grid_set_sample_size     (GdauiGrid *grid, gint sample_size);
 
 G_END_DECLS
diff --git a/libgda-ui/gdaui-provider-selector.c b/libgda-ui/gdaui-provider-selector.c
index e7d672e..c6cd94b 100644
--- a/libgda-ui/gdaui-provider-selector.c
+++ b/libgda-ui/gdaui-provider-selector.c
@@ -26,14 +26,13 @@
 #include <libgda-ui/gdaui-provider-selector.h>
 #include <libgda-ui/gdaui-combo.h>
 
-#define PARENT_TYPE GDAUI_TYPE_COMBO
-
 struct _GdauiProviderSelectorPrivate {
+	gint dummy;
 };
 
 static void gdaui_provider_selector_class_init (GdauiProviderSelectorClass *klass);
 static void gdaui_provider_selector_init       (GdauiProviderSelector *selector,
-						   GdauiProviderSelectorClass *klass);
+						GdauiProviderSelectorClass *klass);
 static void gdaui_provider_selector_finalize   (GObject *object);
 
 static GObjectClass *parent_class = NULL;
@@ -57,7 +56,7 @@ show_providers (GdauiProviderSelector *selector)
 
 	g_value_set_string (tmpval = gda_value_new (G_TYPE_STRING), "SQLite");
 	list = g_slist_append (NULL, tmpval);
-	gdaui_combo_set_values_ext (GDAUI_COMBO (selector), list, cols);
+	_gdaui_combo_set_selected_ext (GDAUI_COMBO (selector), list, cols);
 	gda_value_free ((GValue *)(list->data));
 	g_slist_free (list);
 	g_object_unref (model);
@@ -79,7 +78,7 @@ gdaui_provider_selector_class_init (GdauiProviderSelectorClass *klass)
 
 static void
 gdaui_provider_selector_init (GdauiProviderSelector *selector,
-				 GdauiProviderSelectorClass *klass)
+			      GdauiProviderSelectorClass *klass)
 {
 	g_return_if_fail (GDAUI_IS_PROVIDER_SELECTOR (selector));
 
@@ -117,9 +116,7 @@ gdaui_provider_selector_get_type (void)
 			0,
 			(GInstanceInitFunc) gdaui_provider_selector_init
 		};
-		type = g_type_register_static (PARENT_TYPE,
-					       "GdauiProviderSelector",
-					       &info, 0);
+		type = g_type_register_static (GDAUI_TYPE_COMBO, "GdauiProviderSelector", &info, 0);
 	}
 	return type;
 }
@@ -147,6 +144,8 @@ gdaui_provider_selector_new (void)
  * Get the selected provider.
  *
  * Returns: the selected provider, or %NULL if no provider is selected
+ *
+ * Since: 4.2
  */
 const gchar *
 gdaui_provider_selector_get_provider (GdauiProviderSelector *selector)
@@ -155,7 +154,7 @@ gdaui_provider_selector_get_provider (GdauiProviderSelector *selector)
 	const gchar *str;
 
 	g_return_val_if_fail (GDAUI_IS_PROVIDER_SELECTOR (selector), NULL);
-	list = gdaui_combo_get_values (GDAUI_COMBO (selector));
+	list = _gdaui_combo_get_selected (GDAUI_COMBO (selector));
 	if (list && list->data) {
 		str = g_value_get_string ((GValue *)(list->data));
 		g_slist_free (list);
@@ -173,6 +172,8 @@ gdaui_provider_selector_get_provider (GdauiProviderSelector *selector)
  * Forces @selector to be set on @provider
  *
  * Returns: TRUE if @provider has been selected
+ *
+ * Since: 4.2
  */
 gboolean
 gdaui_provider_selector_set_provider (GdauiProviderSelector *selector, const gchar *provider)
@@ -185,11 +186,11 @@ gdaui_provider_selector_set_provider (GdauiProviderSelector *selector, const gch
 
 	if (provider && *provider)
 		g_value_set_string (tmpval = gda_value_new (G_TYPE_STRING), provider);
-	else 
+	else
 		g_value_set_string (tmpval = gda_value_new (G_TYPE_STRING), "SQLite");
 
 	list = g_slist_append (NULL, tmpval);
-	retval = gdaui_combo_set_values_ext (GDAUI_COMBO (selector), list, cols);
+	retval = _gdaui_combo_set_selected_ext (GDAUI_COMBO (selector), list, cols);
 	gda_value_free ((GValue *)(list->data));
 	g_slist_free (list);
 
@@ -203,12 +204,14 @@ gdaui_provider_selector_set_provider (GdauiProviderSelector *selector, const gch
  * Get the selected provider as a #GdaServerProvider object
  *
  * Returns: a new #GdaServerProvider or %NULL if an error occurred
+ *
+ * Since: 4.2
  */
 GdaServerProvider *
 gdaui_provider_selector_get_provider_obj (GdauiProviderSelector *selector)
 {
 	const gchar *pname;
-	
+
 	g_return_val_if_fail (GDAUI_IS_PROVIDER_SELECTOR (selector), NULL);
 
 	pname = gdaui_provider_selector_get_provider (selector);
diff --git a/libgda-ui/gdaui-raw-form.c b/libgda-ui/gdaui-raw-form.c
index dfb08d3..eda2e37 100644
--- a/libgda-ui/gdaui-raw-form.c
+++ b/libgda-ui/gdaui-raw-form.c
@@ -24,23 +24,24 @@
 #include <libgda/gda-data-proxy.h>
 #include <glib/gi18n-lib.h>
 #include "gdaui-raw-form.h"
-#include "gdaui-data-widget.h"
+#include "gdaui-data-selector.h"
+#include "gdaui-data-proxy.h"
 #include "gdaui-basic-form.h"
-#include "gdaui-data-widget-filter.h"
+#include "gdaui-data-filter.h"
 #include "internal/utility.h"
 
 static void gdaui_raw_form_class_init (GdauiRawFormClass * class);
 static void gdaui_raw_form_init (GdauiRawForm *wid);
-static void gdaui_raw_form_dispose (GObject   *object);
+static void gdaui_raw_form_dispose (GObject *object);
 
 static void gdaui_raw_form_set_property (GObject *object,
-					    guint param_id,
-					    const GValue *value,
-					    GParamSpec *pspec);
+					 guint param_id,
+					 const GValue *value,
+					 GParamSpec *pspec);
 static void gdaui_raw_form_get_property (GObject *object,
-					    guint param_id,
-					    GValue *value,
-					    GParamSpec *pspec);
+					 guint param_id,
+					 GValue *value,
+					 GParamSpec *pspec);
 
 static void gdaui_raw_form_initialize (GdauiRawForm *form, GtkWidget *layout, GHashTable *box_widgets);
 
@@ -50,19 +51,24 @@ static void proxy_changed_cb (GdaDataProxy *proxy, GdauiRawForm *form);
 static void proxy_reset_cb (GdaDataProxy *proxy, GdauiRawForm *form);
 static void proxy_row_inserted_or_removed_cb (GdaDataProxy *proxy, gint row, GdauiRawForm *form);
 
-/* GdauiDataWidget interface */
-static void            gdaui_raw_form_widget_init         (GdauiDataWidgetIface *iface);
-static GdaDataProxy   *gdaui_raw_form_get_proxy           (GdauiDataWidget *iface);
-static void            gdaui_raw_form_col_set_show        (GdauiDataWidget *iface, gint column, gboolean shown);
-static void            gdaui_raw_form_set_column_editable (GdauiDataWidget *iface, gint column, gboolean editable);
-static void            gdaui_raw_form_show_column_actions (GdauiDataWidget *iface, gint column, gboolean show_actions);
-static GtkActionGroup *gdaui_raw_form_get_actions_group   (GdauiDataWidget *iface);
-static GdaDataModelIter *gdaui_raw_form_widget_get_data_set   (GdauiDataWidget *iface);
-static GdaDataModel   *gdaui_raw_form_widget_get_gda_model (GdauiDataWidget *iface);
-static void            gdaui_raw_form_widget_set_gda_model (GdauiDataWidget *iface, GdaDataModel *model);
-static gboolean        gdaui_raw_form_widget_set_write_mode (GdauiDataWidget *iface, GdauiDataWidgetWriteMode mode);
-static GdauiDataWidgetWriteMode gdaui_raw_form_widget_get_write_mode (GdauiDataWidget *iface);
-static void gdaui_raw_form_set_data_layout (GdauiDataWidget  *iface, gpointer  data);
+/* GdauiDataProxy interface */
+static void            gdaui_raw_form_widget_init         (GdauiDataProxyIface *iface);
+static GdaDataProxy   *gdaui_raw_form_get_proxy           (GdauiDataProxy *iface);
+static void            gdaui_raw_form_set_column_editable (GdauiDataProxy *iface, gint column, gboolean editable);
+static void            gdaui_raw_form_show_column_actions (GdauiDataProxy *iface, gint column, gboolean show_actions);
+static GtkActionGroup *gdaui_raw_form_get_actions_group   (GdauiDataProxy *iface);
+static gboolean        gdaui_raw_form_widget_set_write_mode (GdauiDataProxy *iface, GdauiDataProxyWriteMode mode);
+static GdauiDataProxyWriteMode gdaui_raw_form_widget_get_write_mode (GdauiDataProxy *iface);
+
+/* GdauiDataSelector interface */
+static void              gdaui_raw_form_selector_init (GdauiDataSelectorIface *iface);
+static GdaDataModel     *gdaui_raw_form_selector_get_model (GdauiDataSelector *iface);
+static void              gdaui_raw_form_selector_set_model (GdauiDataSelector *iface, GdaDataModel *model);
+static GArray           *gdaui_raw_form_selector_get_selected_rows (GdauiDataSelector *iface);
+static GdaDataModelIter *gdaui_raw_form_selector_get_current_selection (GdauiDataSelector *iface);
+static gboolean          gdaui_raw_form_selector_select_row (GdauiDataSelector *iface, gint row);
+static void              gdaui_raw_form_selector_unselect_row (GdauiDataSelector *iface, gint row);
+static void              gdaui_raw_form_selector_set_column_visible (GdauiDataSelector *iface, gint column, gboolean visible);
 
 struct _GdauiRawFormPriv
 {
@@ -70,7 +76,7 @@ struct _GdauiRawFormPriv
 	GdaDataProxy               *proxy; /* proxy for @model */
 	GdaDataModelIter           *iter;  /* proxy's iter */
 
-	GdauiDataWidgetWriteMode  write_mode;
+	GdauiDataProxyWriteMode  write_mode;
 
 	GtkActionGroup             *actions_group;
 
@@ -85,9 +91,8 @@ struct _GdauiRawFormPriv
 static GObjectClass *parent_class = NULL;
 
 /* properties */
-enum
-{
-        PROP_0,
+enum {
+	PROP_0,
 	PROP_MODEL,
 };
 
@@ -107,42 +112,56 @@ gdaui_raw_form_get_type (void)
 			sizeof (GdauiRawForm),
 			0,
 			(GInstanceInitFunc) gdaui_raw_form_init
-		};		
-		
-		static const GInterfaceInfo work_widget_info = {
+		};
+
+		static const GInterfaceInfo proxy_info = {
                         (GInterfaceInitFunc) gdaui_raw_form_widget_init,
                         NULL,
                         NULL
                 };
-		
+
+		static const GInterfaceInfo selector_info = {
+                        (GInterfaceInitFunc) gdaui_raw_form_selector_init,
+                        NULL,
+                        NULL
+                };
+
 		type = g_type_register_static (GDAUI_TYPE_BASIC_FORM, "GdauiRawForm", &info, 0);
-		g_type_add_interface_static (type, GDAUI_TYPE_DATA_WIDGET, &work_widget_info);
+		g_type_add_interface_static (type, GDAUI_TYPE_DATA_PROXY, &proxy_info);
+		g_type_add_interface_static (type, GDAUI_TYPE_DATA_SELECTOR, &selector_info);
 	}
 
 	return type;
 }
 
 static void
-gdaui_raw_form_widget_init (GdauiDataWidgetIface *iface)
+gdaui_raw_form_widget_init (GdauiDataProxyIface *iface)
 {
 	iface->get_proxy = gdaui_raw_form_get_proxy;
-	iface->col_set_show = gdaui_raw_form_col_set_show;
 	iface->set_column_editable = gdaui_raw_form_set_column_editable;
 	iface->show_column_actions = gdaui_raw_form_show_column_actions;
 	iface->get_actions_group = gdaui_raw_form_get_actions_group;
-	iface->get_data_set = gdaui_raw_form_widget_get_data_set;
-	iface->get_gda_model = gdaui_raw_form_widget_get_gda_model;
-	iface->set_gda_model = gdaui_raw_form_widget_set_gda_model;
 	iface->set_write_mode = gdaui_raw_form_widget_set_write_mode;
 	iface->get_write_mode = gdaui_raw_form_widget_get_write_mode;
-	iface->set_data_layout = gdaui_raw_form_set_data_layout;
+}
+
+static void
+gdaui_raw_form_selector_init (GdauiDataSelectorIface *iface)
+{
+	iface->get_model = gdaui_raw_form_selector_get_model;
+	iface->set_model = gdaui_raw_form_selector_set_model;
+	iface->get_selected_rows = gdaui_raw_form_selector_get_selected_rows;
+	iface->get_current_selection = gdaui_raw_form_selector_get_current_selection;
+	iface->select_row = gdaui_raw_form_selector_select_row;
+	iface->unselect_row = gdaui_raw_form_selector_unselect_row;
+	iface->set_column_visible = gdaui_raw_form_selector_set_column_visible;
 }
 
 static void
 gdaui_raw_form_class_init (GdauiRawFormClass * class)
 {
 	GObjectClass   *object_class = G_OBJECT_CLASS (class);
-	
+
 	parent_class = g_type_class_peek_parent (class);
 	object_class->dispose = gdaui_raw_form_dispose;
 
@@ -151,7 +170,7 @@ gdaui_raw_form_class_init (GdauiRawFormClass * class)
         object_class->get_property = gdaui_raw_form_get_property;
 	g_object_class_install_property (object_class, PROP_MODEL,
 					 g_param_spec_object ("model", _("Data to display"), NULL, GDA_TYPE_DATA_MODEL,
-                                                               G_PARAM_READABLE | G_PARAM_WRITABLE));
+							      G_PARAM_READABLE | G_PARAM_WRITABLE));
 }
 
 static void action_new_cb (GtkAction *action, GdauiRawForm *form);
@@ -168,15 +187,15 @@ static void action_filter_cb (GtkAction *action, GdauiRawForm *form);
 static GtkActionEntry ui_actions[] = {
 	{ "ActionNew", GTK_STOCK_ADD, "_New", NULL, "Create a new data entry", G_CALLBACK (action_new_cb)},
 	{ "ActionDelete", GTK_STOCK_REMOVE, "_Delete", NULL, "Delete the selected entry", G_CALLBACK (action_delete_cb)},
-	{ "ActionUndelete", GTK_STOCK_UNDELETE, "_Undelete", NULL, "Cancels the deletion of the current entry", 
-	  G_CALLBACK (action_undelete_cb)},	
+	{ "ActionUndelete", GTK_STOCK_UNDELETE, "_Undelete", NULL, "Cancels the deletion of the current entry",
+	  G_CALLBACK (action_undelete_cb)},
 	{ "ActionCommit", GTK_STOCK_SAVE, "_Commit", NULL, "Commit the latest changes", G_CALLBACK (action_commit_cb)},
 	{ "ActionReset", GTK_STOCK_REFRESH, "_Reset", NULL, "Reset the data", G_CALLBACK (action_reset_cb)},
-	{ "ActionFirstRecord", GTK_STOCK_GOTO_FIRST, "_First record", NULL, "Go to first record of records", 
+	{ "ActionFirstRecord", GTK_STOCK_GOTO_FIRST, "_First record", NULL, "Go to first record of records",
 	  G_CALLBACK (action_first_record_cb)},
-	{ "ActionLastRecord", GTK_STOCK_GOTO_LAST, "_Last record", NULL, "Go to last record of records", 
+	{ "ActionLastRecord", GTK_STOCK_GOTO_LAST, "_Last record", NULL, "Go to last record of records",
 	  G_CALLBACK (action_last_record_cb)},
-	{ "ActionPrevRecord", GTK_STOCK_GO_BACK, "_Previous record", NULL, "Go to previous record of records", 
+	{ "ActionPrevRecord", GTK_STOCK_GO_BACK, "_Previous record", NULL, "Go to previous record of records",
 	  G_CALLBACK (action_prev_record_cb)},
 	{ "ActionNextRecord", GTK_STOCK_GO_FORWARD, "Ne_xt record", NULL, "Go to next record of records",
 	  G_CALLBACK (action_next_record_cb)},
@@ -189,15 +208,15 @@ action_new_activated_cb (GtkAction *action, GdauiRawForm *wid)
 {
 	/* make the first entry grab the focus */
 	if (wid->priv->iter && GDA_SET (wid->priv->iter)->holders)
-		gdaui_basic_form_entry_grab_focus (GDAUI_BASIC_FORM (wid), 
-						      (GdaHolder *)
-						      GDA_SET (wid->priv->iter)->holders->data);
+		gdaui_basic_form_entry_grab_focus (GDAUI_BASIC_FORM (wid),
+						   (GdaHolder *)
+						   GDA_SET (wid->priv->iter)->holders->data);
 }
 
 static void
 form_activated_cb (GdauiRawForm *form, gpointer data)
 {
-	if (form->priv->write_mode == GDAUI_DATA_WIDGET_WRITE_ON_VALUE_ACTIVATED) {
+	if (form->priv->write_mode == GDAUI_DATA_PROXY_WRITE_ON_VALUE_ACTIVATED) {
 		gint row;
 
 		row = gda_data_model_iter_get_row (form->priv->iter);
@@ -207,8 +226,8 @@ form_activated_cb (GdauiRawForm *form, gpointer data)
 				GError *error = NULL;
 				if (!gda_data_proxy_apply_row_changes (form->priv->proxy, row, &error)) {
 					gboolean discard;
-					discard = _gdaui_utility_display_error_with_keep_or_discard_choice ((GdauiDataWidget *) form, 
-												     error);
+					discard = _gdaui_utility_display_error_with_keep_or_discard_choice ((GdauiDataProxy *) form,
+													    error);
 					if (discard)
 						gda_data_proxy_cancel_row_changes (form->priv->proxy, row, -1);
 					g_error_free (error);
@@ -221,7 +240,7 @@ form_activated_cb (GdauiRawForm *form, gpointer data)
 static void
 form_holder_changed_cb (GdauiRawForm *form, gpointer data)
 {
-	if (form->priv->write_mode == GDAUI_DATA_WIDGET_WRITE_ON_VALUE_CHANGE) {
+	if (form->priv->write_mode == GDAUI_DATA_PROXY_WRITE_ON_VALUE_CHANGE) {
 		gint row;
 
 		row = gda_data_model_iter_get_row (form->priv->iter);
@@ -230,7 +249,7 @@ form_holder_changed_cb (GdauiRawForm *form, gpointer data)
 			if (gda_data_proxy_row_has_changed (form->priv->proxy, row)) {
 				GError *error = NULL;
 				if (!gda_data_proxy_apply_row_changes (form->priv->proxy, row, &error)) {
-					_gdaui_utility_display_error ((GdauiDataWidget *) form, TRUE, error);
+					_gdaui_utility_display_error ((GdauiDataProxy *) form, TRUE, error);
 					if (error)
 						g_error_free (error);
 				}
@@ -248,7 +267,7 @@ gdaui_raw_form_init (GdauiRawForm *wid)
 	wid->priv->model = NULL;
 	wid->priv->proxy = NULL;
 	wid->priv->iter = NULL;
-	wid->priv->write_mode = GDAUI_DATA_WIDGET_WRITE_ON_DEMAND;
+	wid->priv->write_mode = GDAUI_DATA_PROXY_WRITE_ON_DEMAND;
 
 	g_signal_connect (G_OBJECT (wid), "activated",
 			  G_CALLBACK (form_activated_cb), NULL);
@@ -273,15 +292,17 @@ gdaui_raw_form_init (GdauiRawForm *wid)
  * Creates a new #GdauiRawForm widget to display data in @model
  *
  * Returns: the new widget
+ *
+ * Since: 4.2
  */
 GtkWidget *
 gdaui_raw_form_new (GdaDataModel *model)
 {
 	GObject *obj;
-	
+
 	obj = g_object_new (GDAUI_TYPE_RAW_FORM, "model", model, NULL);
 
-	return GTK_WIDGET (obj);	
+	return GTK_WIDGET (obj);
 }
 
 static void
@@ -294,9 +315,9 @@ gdaui_raw_form_dispose (GObject *object)
 	form = GDAUI_RAW_FORM (object);
 
 	if (form->priv) {
-		if (form->priv->filter) 
+		if (form->priv->filter)
 			gtk_widget_destroy (form->priv->filter);
-		if (form->priv->filter_window) 
+		if (form->priv->filter_window)
 			gtk_widget_destroy (form->priv->filter_window);
 
 		/* proxy's iterator */
@@ -308,7 +329,7 @@ gdaui_raw_form_dispose (GObject *object)
 			g_object_unref (form->priv->iter);
 			form->priv->iter = NULL;
 		}
-		
+
 		/* proxy */
 		if (form->priv->proxy) {
 			g_signal_handlers_disconnect_by_func (G_OBJECT (form->priv->proxy),
@@ -322,7 +343,7 @@ gdaui_raw_form_dispose (GObject *object)
 		}
 
 		/* UI */
-		if (form->priv->actions_group) 
+		if (form->priv->actions_group)
 			g_object_unref (G_OBJECT (form->priv->actions_group));
 
 		/* the private area itself */
@@ -336,9 +357,9 @@ gdaui_raw_form_dispose (GObject *object)
 
 static void
 gdaui_raw_form_set_property (GObject *object,
-				guint param_id,
-				const GValue *value,
-				GParamSpec *pspec)
+			     guint param_id,
+			     const GValue *value,
+			     GParamSpec *pspec)
 {
 	GdauiRawForm *form;
 	gpointer ptr;
@@ -359,9 +380,9 @@ gdaui_raw_form_set_property (GObject *object,
 
 				g_object_unref (G_OBJECT (form->priv->iter));
 				form->priv->iter = NULL;
-				
+
 				g_signal_handlers_disconnect_by_func (G_OBJECT (form->priv->proxy),
-								      G_CALLBACK (proxy_row_inserted_or_removed_cb), 
+								      G_CALLBACK (proxy_row_inserted_or_removed_cb),
 								      form);
 				g_signal_handlers_disconnect_by_func (G_OBJECT (form->priv->proxy),
 								      G_CALLBACK (proxy_changed_cb), form);
@@ -405,9 +426,8 @@ gdaui_raw_form_set_property (GObject *object,
 				gdaui_raw_form_initialize (form, NULL, NULL);
 			}
 
-			gdaui_raw_form_widget_set_write_mode ((GdauiDataWidget *) form, form->priv->write_mode);
-			g_signal_emit_by_name (object, "proxy_changed", form->priv->proxy);
-			g_signal_emit_by_name (object, "iter_changed", form->priv->iter);
+			gdaui_raw_form_widget_set_write_mode ((GdauiDataProxy *) form, form->priv->write_mode);
+			g_signal_emit_by_name (object, "proxy-changed", form->priv->proxy);
 			break;
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
@@ -418,9 +438,9 @@ gdaui_raw_form_set_property (GObject *object,
 
 static void
 gdaui_raw_form_get_property (GObject *object,
-			   guint param_id,
-			   GValue *value,
-			   GParamSpec *pspec)
+			     guint param_id,
+			     GValue *value,
+			     GParamSpec *pspec)
 {
 	GdauiRawForm *form;
 
@@ -428,12 +448,12 @@ gdaui_raw_form_get_property (GObject *object,
         if (form->priv) {
                 switch (param_id) {
 		case PROP_MODEL:
-			g_value_set_object(value, form->priv->model);					
+			g_value_set_object(value, form->priv->model);
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 			break;
 		}
-        }	
+        }
 }
 
 static GError *
@@ -441,15 +461,15 @@ iter_validate_set_cb (GdaDataModelIter *iter, GdauiRawForm *form)
 {
 	GError *error = NULL;
 	gint row = gda_data_model_iter_get_row (iter);
-	
+
 	if (row < 0)
 		return NULL;
 
-	if ((form->priv->write_mode >= GDAUI_DATA_WIDGET_WRITE_ON_ROW_CHANGE) &&
-		/* write back the current row */
+	if ((form->priv->write_mode >= GDAUI_DATA_PROXY_WRITE_ON_ROW_CHANGE) &&
+	    /* write back the current row */
 	    gda_data_proxy_row_has_changed (form->priv->proxy, row) &&
 	    !gda_data_proxy_apply_row_changes (form->priv->proxy, row, &error)) {
-		if (_gdaui_utility_display_error_with_keep_or_discard_choice ((GdauiDataWidget *) form, 
+		if (_gdaui_utility_display_error_with_keep_or_discard_choice ((GdauiDataProxy *) form,
 									      error)) {
 			gda_data_proxy_cancel_row_changes (form->priv->proxy, row, -1);
 			if (error) {
@@ -458,7 +478,7 @@ iter_validate_set_cb (GdaDataModelIter *iter, GdauiRawForm *form)
 			}
 		}
 	}
-	
+
 	return error;
 }
 
@@ -477,8 +497,8 @@ iter_row_changed_cb (GdaDataModelIter *iter, gint row, GdauiRawForm *form)
 		for (i = 0, params = ((GdaSet *) iter)->holders; params; i++, params = params->next) {
 			param = (GdaHolder *) params->data;
 			attributes = gda_data_proxy_get_value_attributes (form->priv->proxy, row, i);
-			gdaui_basic_form_entry_set_editable ((GdauiBasicForm *) form, 
-								param, !(attributes & GDA_VALUE_ATTR_NO_MODIF));
+			gdaui_basic_form_entry_set_editable ((GdauiBasicForm *) form,
+							     param, !(attributes & GDA_VALUE_ATTR_NO_MODIF));
 		}
 	}
 }
@@ -487,7 +507,7 @@ static void
 proxy_changed_cb (GdaDataProxy *proxy, GdauiRawForm *form)
 {
 	/* TO remove ? */
-	gtk_widget_set_sensitive (GTK_WIDGET (form), 
+	gtk_widget_set_sensitive (GTK_WIDGET (form),
 				  gda_data_model_get_n_rows (GDA_DATA_MODEL (form->priv->proxy)) == 0 ? FALSE : TRUE);
 }
 
@@ -510,7 +530,7 @@ proxy_row_inserted_or_removed_cb (GdaDataProxy *proxy, gint row, GdauiRawForm *f
 /*
  * Real initialization
  */
-static void 
+static void
 gdaui_raw_form_initialize (GdauiRawForm *form, GtkWidget *layout, GHashTable *box_widgets)
 {
 	/*
@@ -523,25 +543,25 @@ gdaui_raw_form_initialize (GdauiRawForm *form, GtkWidget *layout, GHashTable *bo
 
 		TO_IMPLEMENT;
 		/* GSList *list; */
-/* 		GdaHolder *param; */
-/* 		GdaSetNode *node; */
-/* 		gpointer widget; */
-
-/* 		fbw = g_hash_table_new (NULL, NULL); */
-/* 		g_object_get (G_OBJECT (orig_query), "really_all_fields", &list, NULL); */
-/* 		while (list) { */
-/* 			widget = g_hash_table_lookup (box_widgets, list->data); */
-/* 			if (widget) { */
-/* 				node = gdaui_work_core_find_context_node (form->priv->core, GDA_QUERY_FIELD (list->data)); */
-/* 				if (node) */
-/* 					g_hash_table_insert (fbw, node, widget); */
-/* 			} */
-/* 			list = g_slist_next (list); */
-/* 		} */
+		/* 		GdaHolder *param; */
+		/* 		GdaSetNode *node; */
+		/* 		gpointer widget; */
+
+		/* 		fbw = g_hash_table_new (NULL, NULL); */
+		/* 		g_object_get (G_OBJECT (orig_query), "really_all_fields", &list, NULL); */
+		/* 		while (list) { */
+		/* 			widget = g_hash_table_lookup (box_widgets, list->data); */
+		/* 			if (widget) { */
+		/* 				node = gdaui_work_core_find_context_node (form->priv->core, GDA_QUERY_FIELD (list->data)); */
+		/* 				if (node) */
+		/* 					g_hash_table_insert (fbw, node, widget); */
+		/* 			} */
+		/* 			list = g_slist_next (list); */
+		/* 		} */
 	}
 
-	/* 
-	 * the form itself 
+	/*
+	 * the form itself
 	 */
 	if (!layout && gda_data_proxy_is_read_only (form->priv->proxy))
 		g_object_set ((GObject*) form, "show-actions", FALSE, NULL);
@@ -562,27 +582,33 @@ action_new_cb (GtkAction *action, GdauiRawForm *form)
 	GError *error = NULL;
 	GSList *list;
 
-	if (form->priv->write_mode >= GDAUI_DATA_WIDGET_WRITE_ON_ROW_CHANGE) 
-		if (! gda_set_is_valid (GDA_SET (form->priv->iter), NULL))
+	if (form->priv->write_mode >= GDAUI_DATA_PROXY_WRITE_ON_ROW_CHANGE)
+		if (gda_data_model_iter_is_valid (form->priv->iter) &&
+		    ! gda_set_is_valid (GDA_SET (form->priv->iter), NULL))
 			return;
 
 	/* append a row in the proxy */
+	g_signal_handlers_block_by_func (form, G_CALLBACK (form_holder_changed_cb), NULL);
 	newrow = gda_data_model_append_row (GDA_DATA_MODEL (form->priv->proxy), &error);
 	if (newrow == -1) {
-		g_warning (_("Can't append row to data model: %s"), 
+		g_warning (_("Can't append row to data model: %s"),
 			   error && error->message ? error->message : _("Unknown error"));
 		g_error_free (error);
+		g_signal_handlers_unblock_by_func (form, G_CALLBACK (form_holder_changed_cb), NULL);
 		return;
 	}
 
-	g_assert (gda_data_model_iter_move_to_row (form->priv->iter, newrow));
+	if (!gda_data_model_iter_move_to_row (form->priv->iter, newrow)) {
+		g_warning ("Can't set GdaDataModelIterator on new row");
+		g_signal_handlers_unblock_by_func (form, G_CALLBACK (form_holder_changed_cb), NULL);
+		return;
+	}
 
 	/* set parameters to their default values */
-	list = GDA_SET (form->priv->iter)->holders;
-	while (list) {
+	for (list = GDA_SET (form->priv->iter)->holders; list; list = list->next) {
 		GdaHolder *param;
 		const GValue *value;
-		
+
 		g_object_get (G_OBJECT (list->data), "full_bind", &param, NULL);
 		if (! param) {
 			value = gda_holder_get_default_value (GDA_HOLDER (list->data));
@@ -591,9 +617,9 @@ action_new_cb (GtkAction *action, GdauiRawForm *form)
 		}
 		else
 			g_object_unref (param);
-		
-		list = g_slist_next (list);
 	}
+	g_signal_handlers_unblock_by_func (form, G_CALLBACK (form_holder_changed_cb), NULL);
+	form_holder_changed_cb (form, NULL);
 }
 
 static void
@@ -605,7 +631,7 @@ action_delete_cb (GtkAction *action, GdauiRawForm *form)
 	g_return_if_fail (row >= 0);
 	gda_data_proxy_delete (form->priv->proxy, row);
 
-	if (form->priv->write_mode >= GDAUI_DATA_WIDGET_WRITE_ON_ROW_CHANGE) {
+	if (form->priv->write_mode >= GDAUI_DATA_PROXY_WRITE_ON_ROW_CHANGE) {
 		/* force the proxy to apply the current row deletion */
 		gint newrow;
 
@@ -613,7 +639,7 @@ action_delete_cb (GtkAction *action, GdauiRawForm *form)
 		if (row == newrow) {/* => row has been marked as delete but nit yet really deleted */
 			GError *error = NULL;
 			if (!gda_data_proxy_apply_row_changes (form->priv->proxy, row, &error)) {
-				_gdaui_utility_display_error ((GdauiDataWidget *) form, TRUE, error);
+				_gdaui_utility_display_error ((GdauiDataProxy *) form, TRUE, error);
 				if (error)
 					g_error_free (error);
 			}
@@ -641,14 +667,14 @@ action_commit_cb (GtkAction *action, GdauiRawForm *form)
 
 	mod1 = gda_data_proxy_get_n_modified_rows (form->priv->proxy);
 	row = gda_data_model_iter_get_row (form->priv->iter);
-	if (form->priv->write_mode >= GDAUI_DATA_WIDGET_WRITE_ON_ROW_CHANGE) {
+	if (form->priv->write_mode >= GDAUI_DATA_PROXY_WRITE_ON_ROW_CHANGE) {
 		gint newrow;
 
 		allok = gda_data_proxy_apply_row_changes (form->priv->proxy, row, &error);
 		if (allok) {
 			newrow = gda_data_model_iter_get_row (form->priv->iter);
 			if (row != newrow) /* => current row has changed because the proxy had to emit a "row_removed" when
-					      actually succeeded the commit 
+					      actually succeeded the commit
 					      => we need to come back to that row
 					   */
 				gda_data_model_iter_move_to_row (form->priv->iter, row);
@@ -661,9 +687,9 @@ action_commit_cb (GtkAction *action, GdauiRawForm *form)
 	if (!allok) {
 		if (mod1 != mod2)
 			/* the data model has changed while doing the writing */
-			_gdaui_utility_display_error ((GdauiDataWidget *) form, FALSE, error);
+			_gdaui_utility_display_error ((GdauiDataProxy *) form, FALSE, error);
 		else
-			_gdaui_utility_display_error ((GdauiDataWidget *) form, TRUE, error);
+			_gdaui_utility_display_error ((GdauiDataProxy *) form, TRUE, error);
 		g_error_free (error);
 	}
 
@@ -751,7 +777,7 @@ filter_position_func (GtkWidget *widget,
 	screen = gdk_drawable_get_screen (window);
 	monitor_num = gdk_screen_get_monitor_at_window (screen, window);
 	gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
-  
+
 	gtk_widget_realize (search_dialog);
 
 	gdk_window_get_origin (window, &tree_x, &tree_y);
@@ -779,14 +805,14 @@ filter_position_func (GtkWidget *widget,
 
 static gboolean
 popup_grab_on_window (GdkWindow  *window,
-                      guint32     activate_time) 
+                      guint32     activate_time)
 {
         if (gdk_pointer_grab (window, TRUE,
                               GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
                               NULL, NULL,
                               activate_time) == 0) {
 
-                if (gdk_keyboard_grab (window, TRUE, activate_time) == 0) 
+                if (gdk_keyboard_grab (window, TRUE, activate_time) == 0)
                         return TRUE;
 		else {
                         gdk_pointer_ungrab (activate_time);
@@ -802,11 +828,11 @@ action_filter_cb (GtkAction *action, GdauiRawForm *form)
 {
 	GtkWidget *toplevel;
 	toplevel = gtk_widget_get_toplevel (GTK_WIDGET (form));
-	
+
 	if (!form->priv->filter_window) {
 		/* create filter window */
 		GtkWidget *frame, *vbox;
-	       
+
 		form->priv->filter_window = gtk_window_new (GTK_WINDOW_POPUP);
 
 		gtk_widget_set_events (form->priv->filter_window,
@@ -821,7 +847,7 @@ action_filter_cb (GtkAction *action, GdauiRawForm *form)
 			gtk_window_group_add_window (GTK_WINDOW (toplevel)->group,
 						     GTK_WINDOW (form->priv->filter_window));
 #endif
-		
+
 		g_signal_connect (form->priv->filter_window, "delete_event",
 				  G_CALLBACK (filter_event), form);
 		g_signal_connect (form->priv->filter_window, "button_press_event",
@@ -832,15 +858,15 @@ action_filter_cb (GtkAction *action, GdauiRawForm *form)
 		gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
 		gtk_widget_show (frame);
 		gtk_container_add (GTK_CONTAINER (form->priv->filter_window), frame);
-		
+
 		vbox = gtk_vbox_new (FALSE, 0);
 		gtk_widget_show (vbox);
 		gtk_container_add (GTK_CONTAINER (frame), vbox);
 		gtk_container_set_border_width (GTK_CONTAINER (vbox), 3);
-		
+
 		/* add real filter widget */
 		if (! form->priv->filter) {
-			form->priv->filter = gdaui_data_widget_filter_new (GDAUI_DATA_WIDGET (form));
+			form->priv->filter = gdaui_data_filter_new (GDAUI_DATA_PROXY (form));
 			gtk_widget_show (form->priv->filter);
 		}
 		gtk_container_add (GTK_CONTAINER (vbox), form->priv->filter);
@@ -888,12 +914,12 @@ arrow_actions_real_do (GdauiRawForm *form, gint movement)
 	row = gda_data_model_iter_get_row (form->priv->iter);
 	g_return_if_fail (row >= 0);
 	oldrow = row;
-	
+
 	/* see if some data have been modified and need to be written to the DBMS */
 	/* if ((form->priv->mode & GDAUI_ACTION_MODIF_AUTO_COMMIT) && */
-/* 	    gda_data_proxy_has_changed (form->priv->proxy)) */
-/* 		action_commit_cb (NULL, form); */
-	
+	/* 	    gda_data_proxy_has_changed (form->priv->proxy)) */
+	/* 		action_commit_cb (NULL, form); */
+
 	/* movement */
 	switch (movement) {
 	case -2:
@@ -919,10 +945,10 @@ arrow_actions_real_do (GdauiRawForm *form, gint movement)
 }
 
 /*
- * GdauiDataWidget interface implementation
+ * GdauiDataProxy interface implementation
  */
 static GdaDataProxy *
-gdaui_raw_form_get_proxy (GdauiDataWidget *iface)
+gdaui_raw_form_get_proxy (GdauiDataProxy *iface)
 {
 	GdauiRawForm *form;
 
@@ -933,23 +959,8 @@ gdaui_raw_form_get_proxy (GdauiDataWidget *iface)
 	return form->priv->proxy;
 }
 
-static void
-gdaui_raw_form_col_set_show (GdauiDataWidget *iface, gint column, gboolean shown)
-{
-	GdauiRawForm *form;
-	GdaHolder *param;
-
-	g_return_if_fail (GDAUI_IS_RAW_FORM (iface));
-	form = GDAUI_RAW_FORM (iface);
-	g_return_if_fail (form->priv);
-
-	param = gda_data_model_iter_get_holder_for_field (form->priv->iter, column);
-	g_return_if_fail (param);
-	gdaui_basic_form_entry_set_visible (GDAUI_BASIC_FORM (form), param, shown);
-}
-
 void
-gdaui_raw_form_set_column_editable (GdauiDataWidget *iface, gint column, gboolean editable)
+gdaui_raw_form_set_column_editable (GdauiDataProxy *iface, gint column, gboolean editable)
 {
 	GdauiRawForm *form;
 
@@ -968,23 +979,23 @@ gdaui_raw_form_set_column_editable (GdauiDataWidget *iface, gint column, gboolea
 }
 
 static void
-gdaui_raw_form_show_column_actions (GdauiDataWidget *iface, gint column, gboolean show_actions)
+gdaui_raw_form_show_column_actions (GdauiDataProxy *iface, gint column, gboolean show_actions)
 {
 	GdauiRawForm *form;
-	
+
 	g_return_if_fail (GDAUI_IS_RAW_FORM (iface));
 	form = GDAUI_RAW_FORM (iface);
 	g_return_if_fail (form->priv);
-	
+
 	/* REM: don't take care of the @column argument */
 	g_object_set ((GObject*) form, "show-actions", show_actions, NULL);
 }
 
 static GtkActionGroup *
-gdaui_raw_form_get_actions_group (GdauiDataWidget *iface)
+gdaui_raw_form_get_actions_group (GdauiDataProxy *iface)
 {
 	GdauiRawForm *form;
-	
+
 	g_return_val_if_fail (GDAUI_IS_RAW_FORM (iface), NULL);
 	form = GDAUI_RAW_FORM (iface);
 	g_return_val_if_fail (form->priv, NULL);
@@ -992,75 +1003,99 @@ gdaui_raw_form_get_actions_group (GdauiDataWidget *iface)
 	return form->priv->actions_group;
 }
 
-static GdaDataModelIter *
-gdaui_raw_form_widget_get_data_set (GdauiDataWidget *iface)
+static gboolean
+gdaui_raw_form_widget_set_write_mode (GdauiDataProxy *iface, GdauiDataProxyWriteMode mode)
 {
 	GdauiRawForm *form;
-	
-	g_return_val_if_fail (GDAUI_IS_RAW_FORM (iface), NULL);
+
+	g_return_val_if_fail (GDAUI_IS_RAW_FORM (iface), FALSE);
 	form = GDAUI_RAW_FORM (iface);
-	g_return_val_if_fail (form->priv, NULL);
+	g_return_val_if_fail (form->priv, FALSE);
 
-	return form->priv->iter;
+	form->priv->write_mode = mode;
+	return TRUE;
 }
 
+static GdauiDataProxyWriteMode
+gdaui_raw_form_widget_get_write_mode (GdauiDataProxy *iface)
+{
+	GdauiRawForm *form;
+
+	g_return_val_if_fail (GDAUI_IS_RAW_FORM (iface), GDAUI_DATA_PROXY_WRITE_ON_DEMAND);
+	form = GDAUI_RAW_FORM (iface);
+	g_return_val_if_fail (form->priv, GDAUI_DATA_PROXY_WRITE_ON_DEMAND);
+
+	return form->priv->write_mode;
+}
+
+/* GdauiDataSelector interface */
 static GdaDataModel *
-gdaui_raw_form_widget_get_gda_model (GdauiDataWidget *iface)
+gdaui_raw_form_selector_get_model (GdauiDataSelector *iface)
 {
 	GdauiRawForm *form;
-	
+
 	g_return_val_if_fail (GDAUI_IS_RAW_FORM (iface), NULL);
 	form = GDAUI_RAW_FORM (iface);
-	g_return_val_if_fail (form->priv, NULL);
 
-	return form->priv->model;	
+	return GDA_DATA_MODEL (form->priv->proxy);
 }
 
 static void
-gdaui_raw_form_widget_set_gda_model (GdauiDataWidget *iface, GdaDataModel *model)
+gdaui_raw_form_selector_set_model (GdauiDataSelector *iface, GdaDataModel *model)
 {
 	GdauiRawForm *form;
-	
+
 	g_return_if_fail (GDAUI_IS_RAW_FORM (iface));
 	form = GDAUI_RAW_FORM (iface);
-	g_return_if_fail (form->priv);
 
 	g_object_set (form, "model", model, NULL);
 }
 
-static gboolean
-gdaui_raw_form_widget_set_write_mode (GdauiDataWidget *iface, GdauiDataWidgetWriteMode mode)
+static GArray *
+gdaui_raw_form_selector_get_selected_rows (GdauiDataSelector *iface)
+{
+	TO_IMPLEMENT;
+	return NULL;
+}
+
+static GdaDataModelIter *
+gdaui_raw_form_selector_get_current_selection (GdauiDataSelector *iface)
 {
 	GdauiRawForm *form;
-	
-	g_return_val_if_fail (GDAUI_IS_RAW_FORM (iface), FALSE);
+
+	g_return_val_if_fail (GDAUI_IS_RAW_FORM (iface), NULL);
 	form = GDAUI_RAW_FORM (iface);
-	g_return_val_if_fail (form->priv, FALSE);
 
-	form->priv->write_mode = mode;
-	return TRUE;
+	return form->priv->iter;
 }
 
-static GdauiDataWidgetWriteMode
-gdaui_raw_form_widget_get_write_mode (GdauiDataWidget *iface)
+static gboolean
+gdaui_raw_form_selector_select_row (GdauiDataSelector *iface, gint row)
 {
 	GdauiRawForm *form;
-	
-	g_return_val_if_fail (GDAUI_IS_RAW_FORM (iface), GDAUI_DATA_WIDGET_WRITE_ON_DEMAND);
-	form = GDAUI_RAW_FORM (iface);
-	g_return_val_if_fail (form->priv, GDAUI_DATA_WIDGET_WRITE_ON_DEMAND);
 
-	return form->priv->write_mode;
+	g_return_val_if_fail (GDAUI_IS_RAW_FORM (iface), FALSE);
+	form = (GdauiRawForm*) iface;
+
+	return gda_data_model_iter_move_to_row (form->priv->iter, row);
+}
+
+static void
+gdaui_raw_form_selector_unselect_row (GdauiDataSelector *iface, gint row)
+{
+	TO_IMPLEMENT;
 }
 
 static void
-gdaui_raw_form_set_data_layout (GdauiDataWidget  *iface, gpointer  data)
+gdaui_raw_form_selector_set_column_visible (GdauiDataSelector *iface, gint column, gboolean visible)
 {
-	GdauiRawForm *raw_form;
-	
+	GdauiRawForm *form;
+	GdaHolder *param;
+
 	g_return_if_fail (GDAUI_IS_RAW_FORM (iface));
-	raw_form = GDAUI_RAW_FORM (iface);
-	g_return_if_fail (raw_form->priv);
+	form = GDAUI_RAW_FORM (iface);
 
-	g_object_set (G_OBJECT (raw_form), "data_layout", data, NULL);
+	param = gda_data_model_iter_get_holder_for_field (form->priv->iter, column);
+	g_return_if_fail (param);
+	gdaui_basic_form_entry_set_visible (GDAUI_BASIC_FORM (form), param, visible);
 }
diff --git a/libgda-ui/gdaui-raw-grid.c b/libgda-ui/gdaui-raw-grid.c
index da05234..52dbe5c 100644
--- a/libgda-ui/gdaui-raw-grid.c
+++ b/libgda-ui/gdaui-raw-grid.c
@@ -23,13 +23,15 @@
 #include <glib/gi18n-lib.h>
 #include <libgda/libgda.h>
 #include "gdaui-raw-grid.h"
-#include "gdaui-data-widget.h"
-#include "gdaui-data-widget-filter.h"
+#include "gdaui-data-proxy.h"
+#include "gdaui-data-filter.h"
+#include "gdaui-data-selector.h"
 #include "internal/utility.h"
 #include "marshallers/gdaui-marshal.h"
 #include "gdaui-easy.h"
 #include "data-entries/gdaui-data-cell-renderer-combo.h"
 #include "data-entries/gdaui-data-cell-renderer-info.h"
+#include <libgda/binreloc/gda-binreloc.h>
 
 static void gdaui_raw_grid_class_init (GdauiRawGridClass *klass);
 static void gdaui_raw_grid_init (GdauiRawGrid *wid);
@@ -50,25 +52,29 @@ static void proxy_sample_changed_cb (GdaDataProxy *proxy, gint sample_start, gin
 static void proxy_row_updated_cb (GdaDataProxy *proxy, gint proxy_row, GdauiRawGrid *grid);
 static void proxy_reset_cb (GdaDataProxy *proxy, GdauiRawGrid *grid);
 static void paramlist_public_data_changed_cb (GdauiSet *paramlist, GdauiRawGrid *grid);
-static void paramlist_param_attr_changed_cb (GdaSet *paramlist, GdaHolder *param, 
+static void paramlist_param_attr_changed_cb (GdaSet *paramlist, GdaHolder *param,
 					     const gchar *att_name, const GValue *att_value, GdauiRawGrid *grid);
 static GError *iter_validate_set_cb (GdaDataModelIter *iter, GdauiRawGrid *grid);
 static void iter_row_changed_cb (GdaDataModelIter *iter, gint row, GdauiRawGrid *grid);
 
-/* GdauiDataWidget interface */
-static void            gdaui_raw_grid_widget_init           (GdauiDataWidgetIface *iface);
-static GdaDataProxy   *gdaui_raw_grid_get_proxy             (GdauiDataWidget *iface);
-static void            gdaui_raw_grid_col_set_show          (GdauiDataWidget *iface, gint column, gboolean shown);
-static void            gdaui_raw_grid_set_column_editable   (GdauiDataWidget *iface, gint column, gboolean editable);
-static void            gdaui_raw_grid_show_column_actions   (GdauiDataWidget *iface, gint column, gboolean show_actions);
-static GtkActionGroup *gdaui_raw_grid_get_actions_group     (GdauiDataWidget *iface);
-static GdaDataModelIter *gdaui_raw_grid_widget_get_data_set   (GdauiDataWidget *iface);
-
-static GdaDataModel   *gdaui_raw_grid_widget_get_gda_model             (GdauiDataWidget *iface);
-static void            gdaui_raw_grid_widget_set_gda_model             (GdauiDataWidget *iface, GdaDataModel *model);
-static gboolean        gdaui_raw_grid_widget_set_write_mode (GdauiDataWidget *iface, GdauiDataWidgetWriteMode mode);
-static GdauiDataWidgetWriteMode gdaui_raw_grid_widget_get_write_mode (GdauiDataWidget *iface);
-static void            gdaui_raw_grid_set_data_layout (GdauiDataWidget  *iface, gpointer  data);
+/* GdauiDataProxy interface */
+static void            gdaui_raw_grid_widget_init           (GdauiDataProxyIface *iface);
+static GdaDataProxy   *gdaui_raw_grid_get_proxy             (GdauiDataProxy *iface);
+static void            gdaui_raw_grid_set_column_editable   (GdauiDataProxy *iface, gint column, gboolean editable);
+static void            gdaui_raw_grid_show_column_actions   (GdauiDataProxy *iface, gint column, gboolean show_actions);
+static GtkActionGroup *gdaui_raw_grid_get_actions_group     (GdauiDataProxy *iface);
+static gboolean        gdaui_raw_grid_widget_set_write_mode (GdauiDataProxy *iface, GdauiDataProxyWriteMode mode);
+static GdauiDataProxyWriteMode gdaui_raw_grid_widget_get_write_mode (GdauiDataProxy *iface);
+
+/* GdauiDataSelector interface */
+static void              gdaui_raw_grid_selector_init (GdauiDataSelectorIface *iface);
+static GdaDataModel     *gdaui_raw_grid_selector_get_model (GdauiDataSelector *iface);
+static void              gdaui_raw_grid_selector_set_model (GdauiDataSelector *iface, GdaDataModel *model);
+static GArray           *gdaui_raw_grid_selector_get_selected_rows (GdauiDataSelector *iface);
+static GdaDataModelIter *gdaui_raw_grid_selector_get_current_selection (GdauiDataSelector *iface);
+static gboolean          gdaui_raw_grid_selector_select_row (GdauiDataSelector *iface, gint row);
+static void              gdaui_raw_grid_selector_unselect_row (GdauiDataSelector *iface, gint row);
+static void              gdaui_raw_grid_selector_set_column_visible (GdauiDataSelector *iface, gint column, gboolean visible);
 
 typedef struct {
 	GdauiSetGroup   *group;
@@ -102,7 +108,7 @@ struct _GdauiRawGridPriv
 	GtkActionGroup             *actions_group;
 
 	gint                        export_type; /* used by the export dialog */
-	GdauiDataWidgetWriteMode    write_mode;
+	GdauiDataProxyWriteMode    write_mode;
 
 	GtkWidget                  *filter;
 	GtkWidget                  *filter_window;
@@ -113,25 +119,24 @@ static GObjectClass *parent_class = NULL;
 
 /* signals */
 enum
-{
-        SELECTION_CHANGED,
-	DOUBLE_CLICKED,
-	POPULATE_POPUP,
-        LAST_SIGNAL
-};
+	{
+		DOUBLE_CLICKED,
+		POPULATE_POPUP,
+		LAST_SIGNAL
+	};
 
-static gint gdaui_raw_grid_signals[LAST_SIGNAL] = { 0, 0, 0 };
+static gint gdaui_raw_grid_signals[LAST_SIGNAL] = { 0, 0 };
 
 
 /* properties */
 enum
-{
-        PROP_0,
-	PROP_MODEL,
-	PROP_DATA_LAYOUT,
-	PROP_INFO_CELL_VISIBLE,
-	PROP_GLOBAL_ACTIONS_VISIBLE
-};
+	{
+		PROP_0,
+		PROP_MODEL,
+		PROP_DATA_LAYOUT,
+		PROP_INFO_CELL_VISIBLE,
+		PROP_GLOBAL_ACTIONS_VISIBLE
+	};
 
 /*Callbacks */
 
@@ -140,11 +145,11 @@ enum
  */
 
 static gboolean tree_view_event_cb (GtkWidget *treeview, GdkEvent *event, GdauiRawGrid *grid);
-static gint     tree_view_popup_button_pressed_cb (GtkWidget *widget, GdkEventButton *event, 
+static gint     tree_view_popup_button_pressed_cb (GtkWidget *widget, GdkEventButton *event,
 						   GdauiRawGrid *grid);
 
 static void     tree_view_selection_changed_cb (GtkTreeSelection *selection, GdauiRawGrid *grid);
-static void     tree_view_row_activated_cb     (GtkTreeView *tree_view, GtkTreePath *path, 
+static void     tree_view_row_activated_cb     (GtkTreeView *tree_view, GtkTreePath *path,
 						GtkTreeViewColumn *column, GdauiRawGrid *grid);
 
 static void action_new_cb (GtkAction *action, GdauiRawGrid *grid);
@@ -161,15 +166,15 @@ static void action_filter_cb (GtkAction *action, GdauiRawGrid *grid);
 static GtkActionEntry ui_actions[] = {
 	{ "ActionNew", GTK_STOCK_ADD, "_New", NULL, "Create a new data entry", G_CALLBACK (action_new_cb)},
 	{ "ActionDelete", GTK_STOCK_REMOVE, "_Delete", NULL, "Delete the selected entry", G_CALLBACK (action_delete_cb)},
-	{ "ActionUndelete", GTK_STOCK_UNDELETE, "_Undelete", NULL, "Cancels the deletion of the selected entry", 
+	{ "ActionUndelete", GTK_STOCK_UNDELETE, "_Undelete", NULL, "Cancels the deletion of the selected entry",
 	  G_CALLBACK (action_undelete_cb)},
 	{ "ActionCommit", GTK_STOCK_SAVE, "_Commit", NULL, "Commit the latest changes", G_CALLBACK (action_commit_cb)},
 	{ "ActionReset", GTK_STOCK_REFRESH, "_Reset", NULL, "Reset the data", G_CALLBACK (action_reset_cb)},
-	{ "ActionFirstChunck", GTK_STOCK_GOTO_FIRST, "_First chunck", NULL, "Go to first chunck of records", 
+	{ "ActionFirstChunck", GTK_STOCK_GOTO_FIRST, "_First chunck", NULL, "Go to first chunck of records",
 	  G_CALLBACK (action_first_chunck_cb)},
-	{ "ActionLastChunck", GTK_STOCK_GOTO_LAST, "_Last chunck", NULL, "Go to last chunck of records", 
+	{ "ActionLastChunck", GTK_STOCK_GOTO_LAST, "_Last chunck", NULL, "Go to last chunck of records",
 	  G_CALLBACK (action_last_chunck_cb)},
-	{ "ActionPrevChunck", GTK_STOCK_GO_BACK, "_Previous chunck", NULL, "Go to previous chunck of records", 
+	{ "ActionPrevChunck", GTK_STOCK_GO_BACK, "_Previous chunck", NULL, "Go to previous chunck of records",
 	  G_CALLBACK (action_prev_chunck_cb)},
 	{ "ActionNextChunck", GTK_STOCK_GO_FORWARD, "Ne_xt chunck", NULL, "Go to next chunck of records",
 	  G_CALLBACK (action_next_chunck_cb)},
@@ -193,35 +198,49 @@ gdaui_raw_grid_get_type (void)
 			sizeof (GdauiRawGrid),
 			0,
 			(GInstanceInitFunc) gdaui_raw_grid_init
-		};		
+		};
 
-		static const GInterfaceInfo data_widget_info = {
+		static const GInterfaceInfo proxy_info = {
                         (GInterfaceInitFunc) gdaui_raw_grid_widget_init,
                         NULL,
                         NULL
                 };
-		
+
+		static const GInterfaceInfo selector_info = {
+                        (GInterfaceInitFunc) gdaui_raw_grid_selector_init,
+                        NULL,
+                        NULL
+                };
+
 		type = g_type_register_static (GTK_TYPE_TREE_VIEW, "GdauiRawGrid", &info, 0);
-		g_type_add_interface_static (type, GDAUI_TYPE_DATA_WIDGET, &data_widget_info);
+		g_type_add_interface_static (type, GDAUI_TYPE_DATA_PROXY, &proxy_info);
+		g_type_add_interface_static (type, GDAUI_TYPE_DATA_SELECTOR, &selector_info);
 	}
 
 	return type;
 }
 
 static void
-gdaui_raw_grid_widget_init (GdauiDataWidgetIface *iface)
+gdaui_raw_grid_widget_init (GdauiDataProxyIface *iface)
 {
 	iface->get_proxy = gdaui_raw_grid_get_proxy;
-	iface->col_set_show = gdaui_raw_grid_col_set_show;
 	iface->set_column_editable = gdaui_raw_grid_set_column_editable;
 	iface->show_column_actions = gdaui_raw_grid_show_column_actions;
 	iface->get_actions_group = gdaui_raw_grid_get_actions_group;
-	iface->get_data_set = gdaui_raw_grid_widget_get_data_set;
-	iface->get_gda_model = gdaui_raw_grid_widget_get_gda_model;
-	iface->set_gda_model = gdaui_raw_grid_widget_set_gda_model;
 	iface->set_write_mode = gdaui_raw_grid_widget_set_write_mode;
-	iface->get_write_mode = gdaui_raw_grid_widget_get_write_mode;	
-	iface->set_data_layout = gdaui_raw_grid_set_data_layout;
+	iface->get_write_mode = gdaui_raw_grid_widget_get_write_mode;
+}
+
+static void
+gdaui_raw_grid_selector_init (GdauiDataSelectorIface *iface)
+{
+	iface->get_model = gdaui_raw_grid_selector_get_model;
+	iface->set_model = gdaui_raw_grid_selector_set_model;
+	iface->get_selected_rows = gdaui_raw_grid_selector_get_selected_rows;
+	iface->get_current_selection = gdaui_raw_grid_selector_get_current_selection;
+	iface->select_row = gdaui_raw_grid_selector_select_row;
+	iface->unselect_row = gdaui_raw_grid_selector_unselect_row;
+	iface->set_column_visible = gdaui_raw_grid_selector_set_column_visible;
 }
 
 static void
@@ -230,15 +249,7 @@ gdaui_raw_grid_class_init (GdauiRawGridClass *klass)
 	GObjectClass  *object_class = G_OBJECT_CLASS (klass);
 	parent_class = g_type_class_peek_parent (klass);
 
-	gdaui_raw_grid_signals[SELECTION_CHANGED] = 
-		g_signal_new ("selection_changed",
-                              G_TYPE_FROM_CLASS (object_class),
-                              G_SIGNAL_RUN_FIRST,
-                              G_STRUCT_OFFSET (GdauiRawGridClass, selection_changed),
-                              NULL, NULL,
-                              _gdaui_marshal_VOID__BOOLEAN, G_TYPE_NONE,
-                              1, G_TYPE_BOOLEAN);
-	gdaui_raw_grid_signals[DOUBLE_CLICKED] = 
+	gdaui_raw_grid_signals[DOUBLE_CLICKED] =
 		g_signal_new ("double_clicked",
                               G_TYPE_FROM_CLASS (object_class),
                               G_SIGNAL_RUN_FIRST,
@@ -246,7 +257,7 @@ gdaui_raw_grid_class_init (GdauiRawGridClass *klass)
                               NULL, NULL,
                               _gdaui_marshal_VOID__INT, G_TYPE_NONE,
                               1, G_TYPE_INT);
-	gdaui_raw_grid_signals[POPULATE_POPUP] = 
+	gdaui_raw_grid_signals[POPULATE_POPUP] =
 		g_signal_new ("populate_popup",
                               G_TYPE_FROM_CLASS (object_class),
                               G_SIGNAL_RUN_FIRST,
@@ -263,15 +274,15 @@ gdaui_raw_grid_class_init (GdauiRawGridClass *klass)
 	g_object_class_install_property (object_class, PROP_MODEL,
                                          g_param_spec_object ("model", _("Data to display"), NULL, GDA_TYPE_DATA_MODEL,
 							      G_PARAM_READABLE | G_PARAM_WRITABLE));
-	
+
 	g_object_class_install_property (object_class, PROP_DATA_LAYOUT,
-					 g_param_spec_pointer ("data_layout", 
+					 g_param_spec_pointer ("data_layout",
 							       _("Pointer to an XML data layout specification"), NULL,
 							       G_PARAM_WRITABLE));
 	g_object_class_install_property (object_class, PROP_INFO_CELL_VISIBLE,
                                          g_param_spec_boolean ("info_cell_visible", NULL, _("Info cell visible"), FALSE,
                                                                G_PARAM_READABLE | G_PARAM_WRITABLE));
-															   
+
 	g_object_class_install_property (object_class, PROP_GLOBAL_ACTIONS_VISIBLE,
                                          g_param_spec_boolean ("global_actions_visible", NULL, _("Global Actions visible"), FALSE,
                                                                G_PARAM_READABLE | G_PARAM_WRITABLE));
@@ -282,7 +293,7 @@ gdaui_raw_grid_init (GdauiRawGrid *grid)
 {
 	GtkTreeView *tree_view;
 	GtkTreeSelection *selection;
-	
+
 	grid->priv = g_new0 (GdauiRawGridPriv, 1);
 	grid->priv->store = NULL;
 	grid->priv->proxy = NULL;
@@ -291,8 +302,8 @@ gdaui_raw_grid_init (GdauiRawGrid *grid)
 	grid->priv->columns_data = NULL;
 	grid->priv->columns_hash = g_hash_table_new (NULL, NULL);
 	grid->priv->export_type = 2;
-	grid->priv->write_mode = GDAUI_DATA_WIDGET_WRITE_ON_DEMAND;
-	
+	grid->priv->write_mode = GDAUI_DATA_PROXY_WRITE_ON_DEMAND;
+
 	tree_view = GTK_TREE_VIEW (grid);
 	gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE);
 	gtk_tree_view_set_enable_search (GTK_TREE_VIEW (tree_view), TRUE);
@@ -324,7 +335,9 @@ gdaui_raw_grid_init (GdauiRawGrid *grid)
  *
  * Creates a new #GdauiRawGrid widget suitable to display the data in @model
  *
- *  Returns: the new widget
+ * Returns: the new widget
+ *
+ * Since: 4.2
  */
 GtkWidget *
 gdaui_raw_grid_new (GdaDataModel *model)
@@ -357,9 +370,9 @@ gdaui_raw_grid_dispose (GObject *object)
 			grid->priv->actions_group = NULL;
 		}
 
-		if (grid->priv->filter) 
+		if (grid->priv->filter)
 			gtk_widget_destroy (grid->priv->filter);
-		if (grid->priv->filter_window) 
+		if (grid->priv->filter_window)
 			gtk_widget_destroy (grid->priv->filter_window);
 
 		/* the private area itself */
@@ -439,8 +452,8 @@ load_xml_data_layout_item (GdauiRawGrid  *grid,
 	gint index = g_slist_index (GDA_SET (grid->priv->iter)->holders, holder);
 
 	grid->priv->reordered_indexes = g_slist_insert (grid->priv->reordered_indexes,
-						     GINT_TO_POINTER(index),
-						     sequence - 1);
+							GINT_TO_POINTER(index),
+							sequence - 1);
 
         GdauiSetGroup *group = _gdaui_set_get_group (grid->priv->iter_info, holder);
         if (!group)
@@ -771,9 +784,9 @@ gdaui_raw_grid_set_property (GObject *object,
 
 			if (model)
 				g_return_if_fail (GDA_IS_DATA_MODEL (model));
-			
+
 			reset = !proxy_reset_was_soft (grid, model);
-			
+
 			if (reset)
 				gdaui_raw_grid_clean (grid);
 			else {
@@ -783,13 +796,13 @@ gdaui_raw_grid_set_property (GObject *object,
 
 			if (!model)
 				return;
-			
+
 			grid->priv->store = GDAUI_DATA_STORE (gdaui_data_store_new (model));
 
 			if (reset) {
 				grid->priv->proxy = gdaui_data_store_get_proxy (grid->priv->store);
 				grid->priv->data_model = gda_data_proxy_get_proxied_model (grid->priv->proxy);
-				
+
 				g_object_ref (G_OBJECT (grid->priv->proxy));
 				g_signal_connect (grid->priv->proxy, "sample_changed",
 						  G_CALLBACK (proxy_sample_changed_cb), grid);
@@ -797,27 +810,26 @@ gdaui_raw_grid_set_property (GObject *object,
 						  G_CALLBACK (proxy_row_updated_cb), grid);
 				g_signal_connect (grid->priv->proxy, "reset",
 						  G_CALLBACK (proxy_reset_cb), grid);
-				
+
 				grid->priv->iter = gda_data_model_create_iter (GDA_DATA_MODEL (grid->priv->proxy));
-				grid->priv->iter_info = gdaui_set_new (GDA_SET (grid->priv->iter));
-				
+				grid->priv->iter_info = _gdaui_set_new (GDA_SET (grid->priv->iter));
+
 				g_signal_connect (grid->priv->iter_info, "public_data_changed",
 						  G_CALLBACK (paramlist_public_data_changed_cb), grid);
 				g_signal_connect (grid->priv->iter, "holder-attr-changed",
 						  G_CALLBACK (paramlist_param_attr_changed_cb), grid);
-				
+
 				g_signal_connect (grid->priv->iter, "row_changed",
 						  G_CALLBACK (iter_row_changed_cb), grid);
 				g_signal_connect (grid->priv->iter, "validate-set",
 						  G_CALLBACK (iter_validate_set_cb), grid);
-				
+
 				gda_data_model_iter_invalidate_contents (grid->priv->iter);
-				
+
 				gtk_tree_view_set_model ((GtkTreeView *) grid, GTK_TREE_MODEL (grid->priv->store));
 				init_tree_view (grid);
-				
-				g_signal_emit_by_name (object, "proxy_changed", grid->priv->proxy);
-				g_signal_emit_by_name (object, "iter_changed", grid->priv->iter);
+
+				g_signal_emit_by_name (object, "proxy-changed", grid->priv->proxy);
 			}
 			else {
 				grid->priv->data_model = gda_data_proxy_get_proxied_model (grid->priv->proxy);
@@ -828,10 +840,10 @@ gdaui_raw_grid_set_property (GObject *object,
 				init_tree_view (grid);
 				apply_hidden_columns (grid, hidden_cols);
 			}
-				
+
 			break;
 		}
-				
+
 		case PROP_DATA_LAYOUT: {
 			xmlNodePtr node = g_value_get_pointer (value);
 
@@ -899,24 +911,24 @@ gdaui_raw_grid_set_property (GObject *object,
 		}
 
 			break;
-				
+
 		case PROP_INFO_CELL_VISIBLE: {
 			GSList *list;
 			gboolean show = g_value_get_boolean (value);
 			grid->priv->default_show_info_cell = show;
-	
+
 			for (list = grid->priv->columns_data; list; list = list->next) {
 				COLUMN_DATA (list->data)->info_shown = show;
-				g_object_set (G_OBJECT (COLUMN_DATA (list->data)->info_cell), "visible", 
+				g_object_set (G_OBJECT (COLUMN_DATA (list->data)->info_cell), "visible",
 					      show, NULL);
 			}
 		}
 			break;
-			
+
 		case PROP_GLOBAL_ACTIONS_VISIBLE:
 			gtk_action_group_set_visible (grid->priv->actions_group, g_value_get_boolean (value));
 			break;
-		
+
 		default:
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 			break;
@@ -949,14 +961,14 @@ gdaui_raw_grid_get_property (GObject *object,
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 			break;
                 }
-        }	
+        }
 }
 
-/**
- * gdaui_raw_grid_get_selection
+/*
+ * _gdaui_raw_grid_get_selection
  * @grid: a #GdauiRawGrid widget
  *
- * Returns the list of the currently selected rows in a #GdauiRawGrid widget. 
+ * Returns the list of the currently selected rows in a #GdauiRawGrid widget.
  * The returned value is a list of integers, which represent each of the selected rows.
  *
  * If new rows have been inserted, then those new rows will have a row number equal to -1.
@@ -964,7 +976,7 @@ gdaui_raw_grid_get_property (GObject *object,
  * Returns: a new list, should be freed (by calling g_list_free) when no longer needed.
  */
 GList *
-gdaui_raw_grid_get_selection (GdauiRawGrid *grid)
+_gdaui_raw_grid_get_selection (GdauiRawGrid *grid)
 {
 	GtkTreeSelection *selection;
 	GList *selected_rows;
@@ -980,14 +992,13 @@ gdaui_raw_grid_get_selection (GdauiRawGrid *grid)
 		gint row;
 
 		list = selected_rows;
-		while (list) {
+		for (list = selected_rows; list; list = list->next) {
 			if (gtk_tree_model_get_iter (GTK_TREE_MODEL (grid->priv->store), &iter,
 						     (GtkTreePath *)(list->data))) {
-				gtk_tree_model_get (GTK_TREE_MODEL (grid->priv->store), &iter, 
+				gtk_tree_model_get (GTK_TREE_MODEL (grid->priv->store), &iter,
 						    DATA_STORE_COL_MODEL_ROW, &row, -1);
 				retlist = g_list_prepend (retlist, GINT_TO_POINTER (row));
 			}
-			list = g_list_next (list);
 		}
 		g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
 		g_list_free (selected_rows);
@@ -1008,12 +1019,12 @@ replace_double_underscores (gchar *str)
 {
         gchar **arr;
         gchar *ret;
-	
+
         arr = g_strsplit (str, "_", 0);
         ret = g_strjoinv ("__", arr);
         g_strfreev (arr);
 	g_free (str);
-	
+
         return ret;
 }
 
@@ -1022,11 +1033,11 @@ static void     cell_renderer_value_set_attributes (GtkTreeViewColumn *tree_colu
 static void     cell_renderer_info_set_attributes  (GtkTreeViewColumn *tree_column, GtkCellRenderer *cell,
 						    GtkTreeModel *tree_model, GtkTreeIter *iter, GdauiRawGrid *grid);
 
-static void     data_cell_value_changed (GtkCellRenderer *renderer, const gchar *path, 
+static void     data_cell_value_changed (GtkCellRenderer *renderer, const gchar *path,
 					 const GValue *new_value, GdauiRawGrid *grid);
-static void     data_cell_values_changed (GtkCellRenderer *renderer, const gchar *path, 
+static void     data_cell_values_changed (GtkCellRenderer *renderer, const gchar *path,
 					  GSList *new_values, GSList *all_new_values, GdauiRawGrid *grid);
-static void     data_cell_status_changed (GtkCellRenderer *renderer, const gchar *path, 
+static void     data_cell_status_changed (GtkCellRenderer *renderer, const gchar *path,
 					  GdaValueAttribute requested_action, GdauiRawGrid *grid);
 static void     treeview_column_clicked_cb (GtkTreeViewColumn *tree_column, GdauiRawGrid *grid);
 
@@ -1071,25 +1082,25 @@ init_tree_view (GdauiRawGrid *grid)
 			gchar *title;
 			gboolean nullok = TRUE;
 			GSList *nodes;
-			
+
 			nodes = group->group->nodes;
 			while (nodes && nullok) {
 				if (gda_holder_get_not_null (GDA_HOLDER (GDA_SET_NODE (nodes->data)->holder)))
 					nullok = FALSE;
 				nodes = g_slist_next (nodes);
 			}
-			
+
 			/* determine title */
 			if (g_slist_length (group->group->nodes) == 1)
 				title = (gchar *) g_object_get_data (G_OBJECT (GDA_SET_NODE (group->group->nodes->data)->holder),
 								     "name");
-			else 
+			else
 				title = (gchar *) g_object_get_data (G_OBJECT (group->group->nodes_source->data_model),
 								     "name");
 
 			if (title)
 				title = replace_double_underscores (g_strdup (title));
-			else 
+			else
 				/* FIXME: find a better label */
 				title = g_strdup (_("Value"));
 
@@ -1099,12 +1110,12 @@ init_tree_view (GdauiRawGrid *grid)
 			column_data->data_cell = renderer;
 			g_hash_table_insert (grid->priv->columns_hash, renderer, column_data);
 			gtk_tree_view_insert_column_with_data_func (tree_view, i, title, renderer,
-								    (GtkTreeCellDataFunc) cell_renderer_value_set_attributes, 
+								    (GtkTreeCellDataFunc) cell_renderer_value_set_attributes,
 								    grid, NULL);
 			column = gtk_tree_view_get_column (tree_view, i);
 			g_free (title);
 
-			g_signal_connect (G_OBJECT (renderer), "changed", 
+			g_signal_connect (G_OBJECT (renderer), "changed",
 					  G_CALLBACK (data_cell_values_changed), grid);
 
 			g_object_set_data (G_OBJECT (column), "source", group->group->nodes_source);
@@ -1116,7 +1127,7 @@ init_tree_view (GdauiRawGrid *grid)
 			const GValue *plugin_val;
 			gchar *title;
 			gint model_col;
-			
+
 			param = GDA_HOLDER (GDA_SET_NODE (group->group->nodes->data)->holder);
 			g_type = gda_holder_get_g_type (param);
 
@@ -1127,7 +1138,7 @@ init_tree_view (GdauiRawGrid *grid)
 				title = NULL;
 			if (!title)
 				title = g_strdup (_("No title"));
-			
+
 			plugin_val = gda_holder_get_attribute (param, GDAUI_ATTRIBUTE_PLUGIN);
 			if (plugin_val) {
 				if (G_VALUE_TYPE (plugin_val) == G_TYPE_STRING)
@@ -1140,7 +1151,7 @@ init_tree_view (GdauiRawGrid *grid)
 			column_data->data_cell = renderer;
 			g_hash_table_insert (grid->priv->columns_hash, renderer, column_data);
 			gtk_tree_view_insert_column_with_data_func (tree_view, i, title, renderer,
-								    (GtkTreeCellDataFunc) cell_renderer_value_set_attributes, 
+								    (GtkTreeCellDataFunc) cell_renderer_value_set_attributes,
 								    grid, NULL);
 			column = gtk_tree_view_get_column (tree_view, i);
 			g_free (title);
@@ -1148,7 +1159,7 @@ init_tree_view (GdauiRawGrid *grid)
 			model_col = g_slist_index (((GdaSet *)grid->priv->iter)->holders, param);
 			g_object_set_data (G_OBJECT (renderer), "model_col", GINT_TO_POINTER (model_col));
 
-			g_signal_connect (G_OBJECT (renderer), "changed", 
+			g_signal_connect (G_OBJECT (renderer), "changed",
 					  G_CALLBACK (data_cell_value_changed), grid);
 		}
 
@@ -1166,8 +1177,8 @@ init_tree_view (GdauiRawGrid *grid)
 		column_data->info_cell = renderer;
 		g_hash_table_insert (grid->priv->columns_hash, renderer, column_data);
 		gtk_tree_view_column_pack_end (column, renderer, FALSE);
-		gtk_tree_view_column_set_cell_data_func (column, renderer, 
-							 (GtkTreeCellDataFunc) cell_renderer_info_set_attributes, 
+		gtk_tree_view_column_set_cell_data_func (column, renderer,
+							 (GtkTreeCellDataFunc) cell_renderer_info_set_attributes,
 							 grid, NULL);
 		g_signal_connect (G_OBJECT (renderer), "status_changed",
 				  G_CALLBACK (data_cell_status_changed), grid);
@@ -1181,7 +1192,7 @@ init_tree_view (GdauiRawGrid *grid)
 }
 
 /*
- * Set the attributes for each cell renderer which is not the information cell renderer, 
+ * Set the attributes for each cell renderer which is not the information cell renderer,
  * called by each cell renderer before actually displaying anything.
  */
 static void
@@ -1196,9 +1207,12 @@ cell_renderer_value_set_attributes (GtkTreeViewColumn *tree_column,
 	ColumnData *column_data;
 
 	column_data = g_hash_table_lookup (grid->priv->columns_hash, cell);
-	g_assert (column_data);
+	if (!column_data) {
+		g_warning ("Missing column data");
+		return;
+	}
 	group = column_data->group;
-	
+
 	if (group->group->nodes_source) {
 		/* parameters depending on a GdaDataModel */
 		GList *values = NULL;
@@ -1219,35 +1233,35 @@ cell_renderer_value_set_attributes (GtkTreeViewColumn *tree_column,
 		 * external events and we can't know when it has changed.
 		 */
 		attributes = _gdaui_utility_proxy_compute_attributes_for_group (group, grid->priv->store, grid->priv->iter,
-										  iter, &to_be_deleted);
+										iter, &to_be_deleted);
 		values = _gdaui_utility_proxy_compute_values_for_group (group, grid->priv->store, grid->priv->iter, iter,
-									  TRUE);
+									TRUE);
 		if (!values) {
-			values = _gdaui_utility_proxy_compute_values_for_group (group, grid->priv->store, 
-									 grid->priv->iter, iter, FALSE);
-			g_object_set (G_OBJECT (cell), 
+			values = _gdaui_utility_proxy_compute_values_for_group (group, grid->priv->store,
+										grid->priv->iter, iter, FALSE);
+			g_object_set (G_OBJECT (cell),
 				      "values_display", values,
 				      "value_attributes", attributes,
 				      "editable", !column_data->data_locked && !(attributes & GDA_VALUE_ATTR_NO_MODIF),
 				      "show_expander", !column_data->data_locked && !(attributes & GDA_VALUE_ATTR_NO_MODIF),
 				      "cell_background", GDAUI_COLOR_NORMAL_MODIF,
-				      "cell_background-set", 
+				      "cell_background-set",
 				      ! (attributes & GDA_VALUE_ATTR_IS_UNCHANGED) || to_be_deleted,
-				      "to_be_deleted", to_be_deleted, 
+				      "to_be_deleted", to_be_deleted,
 				      "visible", !(attributes & GDA_VALUE_ATTR_UNUSED),
 				      NULL);
 			g_list_free (values);
 		}
 		else {
-			g_object_set (G_OBJECT (cell), 
+			g_object_set (G_OBJECT (cell),
 				      "values_display", values,
 				      "value_attributes", attributes,
 				      "editable", !column_data->data_locked && !(attributes & GDA_VALUE_ATTR_NO_MODIF),
 				      "show_expander", !column_data->data_locked && !(attributes & GDA_VALUE_ATTR_NO_MODIF),
 				      "cell_background", GDAUI_COLOR_NORMAL_MODIF,
-				      "cell_background-set", 
+				      "cell_background-set",
 				      ! (attributes & GDA_VALUE_ATTR_IS_UNCHANGED) || to_be_deleted,
-				      "to_be_deleted", to_be_deleted, 
+				      "to_be_deleted", to_be_deleted,
 				      "visible", !(attributes & GDA_VALUE_ATTR_UNUSED),
 				      NULL);
 			g_list_free (values);
@@ -1265,25 +1279,25 @@ cell_renderer_value_set_attributes (GtkTreeViewColumn *tree_column,
 		g_assert (g_slist_length (group->group->nodes) == 1);
 		col = g_slist_index (((GdaSet *)grid->priv->iter)->holders,
 				     GDA_SET_NODE (group->group->nodes->data)->holder);
-		gtk_tree_model_get (GTK_TREE_MODEL (grid->priv->store), iter, 
+		gtk_tree_model_get (GTK_TREE_MODEL (grid->priv->store), iter,
 				    DATA_STORE_COL_TO_DELETE, &to_be_deleted,
 				    DATA_STORE_COL_MODEL_ROW, &row,
-				    col, &value, 
+				    col, &value,
 				    offset + col, &attributes, -1);
-		g_object_set (G_OBJECT (cell), 
+		g_object_set (G_OBJECT (cell),
 			      "value", value,
 			      "value_attributes", attributes,
 			      "editable", !column_data->data_locked && !(attributes & GDA_VALUE_ATTR_NO_MODIF),
 			      "cell_background", GDAUI_COLOR_NORMAL_MODIF,
 			      "cell_background-set", ! (attributes & GDA_VALUE_ATTR_IS_UNCHANGED) || to_be_deleted,
-			      "to_be_deleted", to_be_deleted, 
+			      "to_be_deleted", to_be_deleted,
 			      "visible", !(attributes & GDA_VALUE_ATTR_UNUSED),
 			      NULL);
 	}
 }
 
 /*
- * Set the attributes for each information cell renderer, 
+ * Set the attributes for each information cell renderer,
  * called by each cell renderer before actually displaying anything.
  */
 static void
@@ -1298,23 +1312,26 @@ cell_renderer_info_set_attributes (GtkTreeViewColumn *tree_column,
 	ColumnData *column_data;
 
 	column_data = g_hash_table_lookup (grid->priv->columns_hash, cell);
-	g_assert (column_data);
+	if (!column_data) {
+		g_warning ("Missing column data");
+		return;
+	}
 	group = column_data->group;
-	
+
 	if (group->group->nodes_source) {
 		/* parameters depending on a GdaDataModel */
 		GdaSetSource *source;
 
 		source = g_object_get_data (G_OBJECT (tree_column), "source");
 
-		attributes = _gdaui_utility_proxy_compute_attributes_for_group (group, grid->priv->store, grid->priv->iter, 
-										  iter, &to_be_deleted);
-		g_object_set (G_OBJECT (cell), 
+		attributes = _gdaui_utility_proxy_compute_attributes_for_group (group, grid->priv->store, grid->priv->iter,
+										iter, &to_be_deleted);
+		g_object_set (G_OBJECT (cell),
 			      "editable", !column_data->data_locked && !(attributes & GDA_VALUE_ATTR_NO_MODIF),
 			      "value_attributes", attributes,
 			      "cell_background", GDAUI_COLOR_NORMAL_MODIF,
 			      "cell_background-set", ! (attributes & GDA_VALUE_ATTR_IS_UNCHANGED) || to_be_deleted,
-			      "to_be_deleted", to_be_deleted, 
+			      "to_be_deleted", to_be_deleted,
 			      "visible", column_data->info_shown && !(attributes & GDA_VALUE_ATTR_UNUSED),
 			      NULL);
 	}
@@ -1323,22 +1340,22 @@ cell_renderer_info_set_attributes (GtkTreeViewColumn *tree_column,
 		gint col;
 		gint offset;
 		gint row;
-		
+
 		offset = gda_data_model_get_n_columns (gda_data_proxy_get_proxied_model (grid->priv->proxy));
 
 		g_assert (g_slist_length (group->group->nodes) == 1);
 		col = g_slist_index (((GdaSet *)grid->priv->iter)->holders,
 				     GDA_SET_NODE (group->group->nodes->data)->holder);
-		gtk_tree_model_get (GTK_TREE_MODEL (grid->priv->store), iter, 
+		gtk_tree_model_get (GTK_TREE_MODEL (grid->priv->store), iter,
 				    DATA_STORE_COL_TO_DELETE, &to_be_deleted,
 				    DATA_STORE_COL_MODEL_ROW, &row,
 				    offset + col, &attributes, -1);
-		g_object_set (G_OBJECT (cell), 
+		g_object_set (G_OBJECT (cell),
 			      "editable", !column_data->data_locked && !(attributes & GDA_VALUE_ATTR_NO_MODIF),
 			      "value_attributes", attributes,
 			      "cell_background", GDAUI_COLOR_NORMAL_MODIF,
 			      "cell_background-set", ! (attributes & GDA_VALUE_ATTR_IS_UNCHANGED) || to_be_deleted,
-			      "to_be_deleted", to_be_deleted, 
+			      "to_be_deleted", to_be_deleted,
 			      "visible", column_data->info_shown && !(attributes & GDA_VALUE_ATTR_UNUSED),
 			      NULL);
 	}
@@ -1357,17 +1374,17 @@ data_cell_value_changed (GtkCellRenderer *renderer, const gchar *path, const GVa
 	GtkTreeIter iter;
 	GdauiSetGroup *group;
 	ColumnData *column_data;
-	
+
 	column_data = g_hash_table_lookup (grid->priv->columns_hash, renderer);
 	g_assert (column_data);
 	group = column_data->group;
 	g_assert (g_slist_length (group->group->nodes) == 1);
 
 	if (set_iter_from_path (grid, path, &iter)) {
-		    gint col;
-		    col = g_slist_index (((GdaSet *)grid->priv->iter)->holders,
-					 GDA_SET_NODE (group->group->nodes->data)->holder);
-		    gdaui_data_store_set_value (grid->priv->store, &iter, col, new_value);
+		gint col;
+		col = g_slist_index (((GdaSet *)grid->priv->iter)->holders,
+				     GDA_SET_NODE (group->group->nodes->data)->holder);
+		gdaui_data_store_set_value (grid->priv->store, &iter, col, new_value);
 	}
 }
 
@@ -1378,7 +1395,7 @@ data_cell_value_changed (GtkCellRenderer *renderer, const gchar *path, const GVa
  * Apply the new_value to the GTkTreeModel (grid->priv->store)
  */
 static void
-data_cell_values_changed (GtkCellRenderer *renderer, const gchar *path, 
+data_cell_values_changed (GtkCellRenderer *renderer, const gchar *path,
 			  GSList *new_values, GSList *all_new_values, GdauiRawGrid *grid)
 {
 	GtkTreeIter iter;
@@ -1395,7 +1412,7 @@ data_cell_values_changed (GtkCellRenderer *renderer, const gchar *path,
 	else
 		/* the reason for not having any value is that the GdauiDataCellRendererCombo had no selected item */
 		return;
-	
+
 	if (set_iter_from_path (grid, path, &iter)) {
 		GSList *list, *params;
 		gint col, proxy_row;
@@ -1403,14 +1420,14 @@ data_cell_values_changed (GtkCellRenderer *renderer, const gchar *path,
 		proxy_row = gdaui_data_store_get_row_from_iter (grid->priv->store, &iter);
 
 		/* update the GdauiDataStore */
-		for (params = group->group->nodes, list = new_values; 
-		     list; 
+		for (params = group->group->nodes, list = new_values;
+		     list;
 		     params = params->next, list = list->next) {
 			col = g_slist_index (((GdaSet *)grid->priv->iter)->holders,
 					     GDA_SET_NODE (params->data)->holder);
 			gdaui_data_store_set_value (grid->priv->store, &iter, col, (GValue *)(list->data));
 		}
-		
+
 #ifdef PROXY_STORE_EXTRA_VALUES
 		/* call gda_data_proxy_set_model_row_value() */
 		gint i;
@@ -1441,7 +1458,7 @@ set_iter_from_path (GdauiRawGrid *grid, const gchar *path, GtkTreeIter *iter)
 		return FALSE;
 	}
 	gtk_tree_path_free (treepath);
-	
+
 	return TRUE;
 }
 
@@ -1458,7 +1475,7 @@ treeview_column_clicked_cb (GtkTreeViewColumn *tree_column, GdauiRawGrid *grid)
 		GdaHolder *param = ((GdaSetNode*) nodes->data)->holder;
 		gint pos;
 		g_assert (param);
-		
+
 		pos = g_slist_index (GDA_SET (grid->priv->iter)->holders, param);
 		if (pos >= 0) {
 			gda_data_proxy_set_ordering_column (grid->priv->proxy, pos, NULL);
@@ -1498,7 +1515,7 @@ data_cell_status_changed (GtkCellRenderer *renderer, const gchar *path, GdaValue
 		return;
 	}
 	gtk_tree_path_free (treepath);
-	
+
 	g_value_set_uint (attribute = gda_value_new (G_TYPE_UINT), requested_action);
 	if (group->group->nodes_source) {
 		/* parameters depending on a GdaDataModel */
@@ -1517,14 +1534,14 @@ data_cell_status_changed (GtkCellRenderer *renderer, const gchar *path, GdaValue
 		gint i;
 		for (i = 0; i < group->nodes_source->shown_n_cols; i++) {
 			col = group->nodes_source->shown_cols_index[i];
-			
+
 			if (requested_action & GDA_VALUE_ATTR_IS_NULL)
-				gda_data_proxy_set_model_row_value (grid->priv->proxy, 
+				gda_data_proxy_set_model_row_value (grid->priv->proxy,
 								    group->nodes_source->data_model,
 								    proxy_row, col, NULL);
 			else {
 				if (requested_action & GDA_VALUE_ATTR_IS_UNCHANGED)
-					gda_data_proxy_clear_model_row_value (grid->priv->proxy, 
+					gda_data_proxy_clear_model_row_value (grid->priv->proxy,
 									      group->nodes_source->data_model,
 									      proxy_row, col);
 				else {
@@ -1571,7 +1588,7 @@ action_delete_cb (GtkAction *action, GdauiRawGrid *grid)
 	GtkTreeModel *model;
 	GList *sel_rows;
 	GdaDataProxy *proxy;
-	
+
 	select = gtk_tree_view_get_selection (GTK_TREE_VIEW (grid));
 	sel_rows = gtk_tree_selection_get_selected_rows (select, &model);
 	proxy = gdaui_data_store_get_proxy (GDAUI_DATA_STORE (model));
@@ -1580,13 +1597,13 @@ action_delete_cb (GtkAction *action, GdauiRawGrid *grid)
 	 * row numbers might also have changed */
 	while (sel_rows) {
 		gtk_tree_model_get_iter (model, &iter, (GtkTreePath *) (sel_rows->data));
-		if (!gda_data_proxy_row_is_deleted (proxy, 
-						    gdaui_data_store_get_row_from_iter (GDAUI_DATA_STORE (model), 
-											   &iter))) {
+		if (!gda_data_proxy_row_is_deleted (proxy,
+						    gdaui_data_store_get_row_from_iter (GDAUI_DATA_STORE (model),
+											&iter))) {
 			gdaui_data_store_delete (grid->priv->store, &iter);
 			g_list_foreach (sel_rows, (GFunc) gtk_tree_path_free, NULL);
 			g_list_free (sel_rows);
-			sel_rows = gtk_tree_selection_get_selected_rows (select, &model); 
+			sel_rows = gtk_tree_selection_get_selected_rows (select, &model);
 		}
 		else
 			sel_rows = sel_rows->next;
@@ -1600,7 +1617,7 @@ action_undelete_cb (GtkAction *action, GdauiRawGrid *grid)
 	GtkTreeSelection *select;
 	GtkTreeModel *model;
 	GList *sel_rows, *cur_row;
-	
+
 	select = gtk_tree_view_get_selection (GTK_TREE_VIEW (grid));
 	sel_rows = gtk_tree_selection_get_selected_rows (select, &model);
 	cur_row = sel_rows;
@@ -1623,14 +1640,14 @@ action_commit_cb (GtkAction *action, GdauiRawGrid *grid)
 
 	mod1 = gda_data_proxy_get_n_modified_rows (grid->priv->proxy);
 	row = gda_data_model_iter_get_row (grid->priv->iter);
-	if (grid->priv->write_mode >= GDAUI_DATA_WIDGET_WRITE_ON_ROW_CHANGE) {
+	if (grid->priv->write_mode >= GDAUI_DATA_PROXY_WRITE_ON_ROW_CHANGE) {
 		gint newrow;
 
 		allok = gda_data_proxy_apply_row_changes (grid->priv->proxy, row, &error);
 		if (allok) {
 			newrow = gda_data_model_iter_get_row (grid->priv->iter);
 			if (row != newrow) /* => current row has changed because the proxy had to emit a "row_removed" when
-					      actually succeeded the commit 
+					      actually succeeded the commit
 					      => we need to come back to that row
 					   */
 				gda_data_model_iter_move_to_row (grid->priv->iter, row);
@@ -1643,9 +1660,9 @@ action_commit_cb (GtkAction *action, GdauiRawGrid *grid)
 	if (!allok) {
 		if (mod1 != mod2)
 			/* the data model has changed while doing the writing */
-			_gdaui_utility_display_error ((GdauiDataWidget *) grid, FALSE, error);
+			_gdaui_utility_display_error ((GdauiDataProxy *) grid, FALSE, error);
 		else
-			_gdaui_utility_display_error ((GdauiDataWidget *) grid, TRUE, error);
+			_gdaui_utility_display_error ((GdauiDataProxy *) grid, TRUE, error);
 		g_error_free (error);
 	}
 }
@@ -1745,7 +1762,7 @@ filter_position_func (GtkWidget *widget,
 
 	monitor_num = gdk_screen_get_monitor_at_window (screen, window);
 	gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
-  
+
 	gtk_widget_realize (search_dialog);
 
 	gdk_window_get_origin (window, &tree_x, &tree_y);
@@ -1773,14 +1790,14 @@ filter_position_func (GtkWidget *widget,
 
 static gboolean
 popup_grab_on_window (GdkWindow  *window,
-                      guint32     activate_time) 
+                      guint32     activate_time)
 {
         if (gdk_pointer_grab (window, TRUE,
                               GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
                               NULL, NULL,
                               activate_time) == 0) {
 
-                if (gdk_keyboard_grab (window, TRUE, activate_time) == 0) 
+                if (gdk_keyboard_grab (window, TRUE, activate_time) == 0)
                         return TRUE;
 		else {
                         gdk_pointer_ungrab (activate_time);
@@ -1796,11 +1813,11 @@ action_filter_cb (GtkAction *action, GdauiRawGrid *grid)
 {
 	GtkWidget *toplevel;
 	toplevel = gtk_widget_get_toplevel (GTK_WIDGET (grid));
-	
+
 	if (!grid->priv->filter_window) {
 		/* create filter window */
 		GtkWidget *frame, *vbox;
-	       
+
 		grid->priv->filter_window = gtk_window_new (GTK_WINDOW_POPUP);
 
 		gtk_widget_set_events (grid->priv->filter_window,
@@ -1815,7 +1832,7 @@ action_filter_cb (GtkAction *action, GdauiRawGrid *grid)
 			gtk_window_group_add_window (GTK_WINDOW (toplevel)->group,
 						     GTK_WINDOW (grid->priv->filter_window));
 #endif
-		
+
 		g_signal_connect (grid->priv->filter_window, "delete_event",
 				  G_CALLBACK (filter_event), grid);
 		g_signal_connect (grid->priv->filter_window, "button_press_event",
@@ -1826,15 +1843,15 @@ action_filter_cb (GtkAction *action, GdauiRawGrid *grid)
 		gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN);
 		gtk_widget_show (frame);
 		gtk_container_add (GTK_CONTAINER (grid->priv->filter_window), frame);
-		
+
 		vbox = gtk_vbox_new (FALSE, 0);
 		gtk_widget_show (vbox);
 		gtk_container_add (GTK_CONTAINER (frame), vbox);
 		gtk_container_set_border_width (GTK_CONTAINER (vbox), 3);
-		
+
 		/* add real filter widget */
 		if (! grid->priv->filter) {
-			grid->priv->filter = gdaui_data_widget_filter_new (GDAUI_DATA_WIDGET (grid));
+			grid->priv->filter = gdaui_data_filter_new (GDAUI_DATA_PROXY (grid));
 			gtk_widget_show (grid->priv->filter);
 		}
 		gtk_container_add (GTK_CONTAINER (vbox), grid->priv->filter);
@@ -1866,23 +1883,25 @@ action_filter_cb (GtkAction *action, GdauiRawGrid *grid)
 	gtk_widget_show (grid->priv->filter_window);
 #if GTK_CHECK_VERSION(2,18,0)
 	popup_grab_on_window (gtk_widget_get_window (grid->priv->filter_window),
+			      gtk_get_current_event_time ());
 #else
 	popup_grab_on_window (grid->priv->filter_window->window,
+			      gtk_get_current_event_time ());
 #endif
-			      gtk_get_current_event_time ());	
+	
 }
 
 /*
  * Catch any event in the GtkTreeView widget
  */
-static gboolean 
+static gboolean
 tree_view_event_cb (GtkWidget *treeview, GdkEvent *event, GdauiRawGrid *grid)
 {
 	gboolean done = FALSE;
 
 	if (event->type == GDK_KEY_PRESS) {
 		GdkEventKey *ekey = (GdkEventKey *) event;
-		guint modifiers = gtk_accelerator_get_default_mod_mask ();		
+		guint modifiers = gtk_accelerator_get_default_mod_mask ();
 
 		/* Tab to move one column left or right */
 		if (ekey->keyval == GDK_Tab) {
@@ -1902,13 +1921,13 @@ tree_view_event_cb (GtkWidget *treeview, GdkEvent *event, GdauiRawGrid *grid)
 
 				if (((ekey->state & modifiers) == GDK_SHIFT_MASK) || ((ekey->state & modifiers) == GDK_CONTROL_MASK))
 					col = g_list_previous (col); /* going to previous column */
-				else 
+				else
 					col = g_list_next (col); /* going to next column */
 
 				if (col) {
 					renderer = g_object_get_data (G_OBJECT (col->data), "data_renderer");
-					gtk_tree_view_set_cursor_on_cell (GTK_TREE_VIEW (treeview), path, 
-									  GTK_TREE_VIEW_COLUMN (col->data), 
+					gtk_tree_view_set_cursor_on_cell (GTK_TREE_VIEW (treeview), path,
+									  GTK_TREE_VIEW_COLUMN (col->data),
 									  renderer, FALSE);
 					gtk_widget_grab_focus (treeview);
 					done = TRUE;
@@ -1918,7 +1937,7 @@ tree_view_event_cb (GtkWidget *treeview, GdkEvent *event, GdauiRawGrid *grid)
 			if (path)
 				gtk_tree_path_free (path);
 		}
-		
+
 		/* DELETE to delete the selected row */
 		if (ekey->keyval == GDK_Delete) {
 			GtkTreeIter iter;
@@ -1931,7 +1950,7 @@ tree_view_event_cb (GtkWidget *treeview, GdkEvent *event, GdauiRawGrid *grid)
 			cur_row = sel_rows;
 			while (cur_row) {
 				gtk_tree_model_get_iter (model, &iter, (GtkTreePath *) (cur_row->data));
-				if (((ekey->state & modifiers) == GDK_SHIFT_MASK) || 
+				if (((ekey->state & modifiers) == GDK_SHIFT_MASK) ||
 				    ((ekey->state & modifiers) == GDK_CONTROL_MASK))
 					gdaui_data_store_undelete (grid->priv->store, &iter);
 				else
@@ -1940,7 +1959,7 @@ tree_view_event_cb (GtkWidget *treeview, GdkEvent *event, GdauiRawGrid *grid)
 			}
 			g_list_foreach (sel_rows, (GFunc) gtk_tree_path_free, NULL);
 			g_list_free (sel_rows);
-			
+
 			done = TRUE;
 		}
 	}
@@ -1971,48 +1990,48 @@ tree_view_popup_button_pressed_cb (GtkWidget *widget, GdkEventButton *event, Gda
 	GtkTreeSelection *selection;
 	GtkSelectionMode sel_mode;
 
-        if (event->button != 3)
-                return FALSE;
+	if (event->button != 3)
+		return FALSE;
 
 	tree_view = GTK_TREE_VIEW (grid);
 	selection = gtk_tree_view_get_selection (tree_view);
 	sel_mode = gtk_tree_selection_get_mode (selection);
 
-        /* create the menu */
-        menu = gtk_menu_new ();
+	/* create the menu */
+	menu = gtk_menu_new ();
 	if (sel_mode == GTK_SELECTION_MULTIPLE)
 		gtk_menu_append (GTK_MENU (menu),
-				 new_menu_item (_("Select _All"), FALSE, 
-							 G_CALLBACK (menu_select_all_cb), grid));
+				 new_menu_item (_("Select _All"), FALSE,
+						G_CALLBACK (menu_select_all_cb), grid));
 
 	if ((sel_mode == GTK_SELECTION_SINGLE) || (sel_mode == GTK_SELECTION_MULTIPLE))
 		gtk_menu_append (GTK_MENU (menu),
 				 new_menu_item (_("_Clear Selection"), FALSE,
-							 G_CALLBACK (menu_unselect_all_cb), grid));
-        gtk_menu_append (GTK_MENU (menu),
+						G_CALLBACK (menu_unselect_all_cb), grid));
+	gtk_menu_append (GTK_MENU (menu),
 			 new_check_menu_item (_("Show Column _Titles"),
 					      gtk_tree_view_get_headers_visible (tree_view),
 					      G_CALLBACK (menu_show_columns_cb), grid));
 
 	gtk_menu_append (GTK_MENU (menu),
-				 new_menu_item (_("_Set filter"), FALSE,
-							 G_CALLBACK (menu_set_filter_cb), grid));
+			 new_menu_item (_("_Set filter"), FALSE,
+					G_CALLBACK (menu_set_filter_cb), grid));
 	gtk_menu_append (GTK_MENU (menu),
-				 new_menu_item (_("_Unset filter"), FALSE,
-							 G_CALLBACK (menu_unset_filter_cb), grid));
+			 new_menu_item (_("_Unset filter"), FALSE,
+					G_CALLBACK (menu_unset_filter_cb), grid));
 
 	if (sel_mode != GTK_SELECTION_NONE) {
 		gtk_menu_append (GTK_MENU (menu), gtk_separator_menu_item_new ());
 		gtk_menu_append (GTK_MENU (menu), new_menu_item (GTK_STOCK_SAVE_AS, TRUE,
-					       G_CALLBACK (menu_save_as_cb), grid));
+								 G_CALLBACK (menu_save_as_cb), grid));
 	}
 
 	/* allow listeners to add their custom menu items */
-        g_signal_emit (G_OBJECT (grid), gdaui_raw_grid_signals [POPULATE_POPUP], 0, GTK_MENU (menu));
-        gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, event->button, event->time);
-        gtk_widget_show_all (menu);
-	
-        return TRUE;
+	g_signal_emit (G_OBJECT (grid), gdaui_raw_grid_signals [POPULATE_POPUP], 0, GTK_MENU (menu));
+	gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, event->button, event->time);
+	gtk_widget_show_all (menu);
+
+	return TRUE;
 }
 
 static GtkWidget *
@@ -2027,7 +2046,7 @@ new_menu_item (const gchar *label,
 		item = gtk_image_menu_item_new_from_stock (label, NULL);
 	else
 		item = gtk_menu_item_new_with_mnemonic (label);
-	
+
 	g_signal_connect (G_OBJECT (item), "activate",
 			  G_CALLBACK (cb_func), user_data);
 
@@ -2041,10 +2060,10 @@ new_check_menu_item (const gchar *label,
 		     gpointer user_data)
 {
 	GtkWidget *item;
-	
+
 	item = gtk_check_menu_item_new_with_mnemonic (label);
 	gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), active);
-	
+
 	g_signal_connect (G_OBJECT (item), "toggled",
 			  G_CALLBACK (cb_func), user_data);
 
@@ -2056,7 +2075,7 @@ menu_select_all_cb (GtkWidget *widget, GdauiRawGrid *grid)
 {
 	GtkTreeSelection *selection;
 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (grid));
-	
+
 	gtk_tree_selection_select_all (selection);
 }
 
@@ -2065,18 +2084,18 @@ menu_unselect_all_cb (GtkWidget *widget, GdauiRawGrid *grid)
 {
 	GtkTreeSelection *selection;
 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (grid));
-	
+
 	gtk_tree_selection_unselect_all (selection);
 }
 
 static void
 menu_show_columns_cb (GtkWidget *widget, GdauiRawGrid *grid)
 {
-        GtkCheckMenuItem *item;
+	GtkCheckMenuItem *item;
 
-        item = (GtkCheckMenuItem *) widget;
+	item = (GtkCheckMenuItem *) widget;
 
-        g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (item));
+	g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (item));
 	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (grid),
 					   gtk_check_menu_item_get_active (item));
 }
@@ -2104,54 +2123,54 @@ menu_save_as_cb (GtkWidget *widget, GdauiRawGrid *grid)
 	gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
 	gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
 
-	str = g_strdup_printf ("<big><b>%s:</b></big>\n%s", _("Saving data to a file"), 
+	str = g_strdup_printf ("<big><b>%s:</b></big>\n%s", _("Saving data to a file"),
 			       _("The data will be exported without any of the modifications which may "
 				 "have been made and have not been committed."));
-        label = gtk_label_new ("");
-        gtk_label_set_markup (GTK_LABEL (label), str);
-        gtk_misc_set_alignment (GTK_MISC (label), 0., -1);
+	label = gtk_label_new ("");
+	gtk_label_set_markup (GTK_LABEL (label), str);
+	gtk_misc_set_alignment (GTK_MISC (label), 0., -1);
 	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
-        g_free (str);
+	g_free (str);
 
 #if GTK_CHECK_VERSION(2,18,0)
 	dbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
 #else
 	dbox = GTK_DIALOG (dialog)->vbox;
 #endif
-        gtk_box_pack_start (GTK_BOX (dbox), label, FALSE, TRUE, 2);
+	gtk_box_pack_start (GTK_BOX (dbox), label, FALSE, TRUE, 2);
 
 	str = g_strdup_printf ("<b>%s:</b>", _("File name"));
-        label = gtk_label_new ("");
-        gtk_label_set_markup (GTK_LABEL (label), str);
-        gtk_misc_set_alignment (GTK_MISC (label), 0., -1);
-        g_free (str);
-        gtk_box_pack_start (GTK_BOX (dbox), label, FALSE, TRUE, 2);
+	label = gtk_label_new ("");
+	gtk_label_set_markup (GTK_LABEL (label), str);
+	gtk_misc_set_alignment (GTK_MISC (label), 0., -1);
+	g_free (str);
+	gtk_box_pack_start (GTK_BOX (dbox), label, FALSE, TRUE, 2);
 
 	hbox = gtk_hbox_new (FALSE, 0); /* HIG */
-        gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, FALSE, 5);
-        gtk_widget_show (hbox);
-        label = gtk_label_new ("    ");
-        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-        gtk_widget_show (label);
+	gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, FALSE, 5);
+	gtk_widget_show (hbox);
+	label = gtk_label_new ("    ");
+	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+	gtk_widget_show (label);
 
 	filename = gtk_file_chooser_widget_new (GTK_FILE_CHOOSER_ACTION_SAVE);
 	g_object_set_data (G_OBJECT (dialog), "filename", filename);
 	gtk_box_pack_start (GTK_BOX (hbox), filename, TRUE, TRUE, 0);
 
-	str = g_strdup_printf ("<b>%s:</b>", _("Details")); 
-        label = gtk_label_new ("");
-        gtk_label_set_markup (GTK_LABEL (label), str);
-        gtk_misc_set_alignment (GTK_MISC (label), 0., -1);
-        g_free (str);
-        gtk_box_pack_start (GTK_BOX (dbox), label, FALSE, TRUE, 2);
+	str = g_strdup_printf ("<b>%s:</b>", _("Details"));
+	label = gtk_label_new ("");
+	gtk_label_set_markup (GTK_LABEL (label), str);
+	gtk_misc_set_alignment (GTK_MISC (label), 0., -1);
+	g_free (str);
+	gtk_box_pack_start (GTK_BOX (dbox), label, FALSE, TRUE, 2);
 
 	hbox = gtk_hbox_new (FALSE, 0); /* HIG */
-        gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, FALSE, 5);
-        gtk_widget_show (hbox);
-        label = gtk_label_new ("    ");
-        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-        gtk_widget_show (label);
-	
+	gtk_box_pack_start (GTK_BOX (dbox), hbox, FALSE, FALSE, 5);
+	gtk_widget_show (hbox);
+	label = gtk_label_new ("    ");
+	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+	gtk_widget_show (label);
+
 	table = gtk_table_new (2, 2, FALSE);
 	gtk_table_set_row_spacings (GTK_TABLE (table), 5);
 	gtk_table_set_col_spacings (GTK_TABLE (table), 5);
@@ -2191,7 +2210,7 @@ menu_save_as_cb (GtkWidget *widget, GdauiRawGrid *grid)
 	gtk_combo_box_append_text (GTK_COMBO_BOX (types), _("Comma-delimited"));
 	gtk_combo_box_append_text (GTK_COMBO_BOX (types), _("XML"));
 	gtk_combo_box_set_active (GTK_COMBO_BOX (types), grid->priv->export_type);
-	
+
 	/* run the dialog */
 	g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (save_as_response_cb), grid);
 	gtk_widget_show_all (dialog);
@@ -2206,7 +2225,7 @@ save_as_response_cb (GtkDialog *dialog, guint response_id, GdauiRawGrid *grid)
 	gint export_type;
 	GtkWidget *filename;
 	gboolean selection_only = FALSE;
-	
+
 	if (response_id == GTK_RESPONSE_OK) {
 		gchar *body;
 		gchar *path;
@@ -2218,7 +2237,7 @@ save_as_response_cb (GtkDialog *dialog, guint response_id, GdauiRawGrid *grid)
 
 		types = g_object_get_data (G_OBJECT (dialog), "types");
 		filename = g_object_get_data (G_OBJECT (dialog), "filename");
-		selection_only = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON 
+		selection_only = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
 							       (g_object_get_data (G_OBJECT (dialog), "sel_only")));
 
 		/* output columns computation */
@@ -2231,7 +2250,7 @@ save_as_response_cb (GtkDialog *dialog, guint response_id, GdauiRawGrid *grid)
 				GSList *params;
 
 				group = g_object_get_data (G_OBJECT (list->data), "__gdaui_group");
-				for (params = group->group->nodes; params; nb_cols ++, params = params->next) 
+				for (params = group->group->nodes; params; nb_cols ++, params = params->next)
 					cols [nb_cols] = g_slist_index (((GdaSet *)grid->priv->iter)->holders,
 									GDA_SET_NODE (params->data)->holder);
 			}
@@ -2257,7 +2276,7 @@ save_as_response_cb (GtkDialog *dialog, guint response_id, GdauiRawGrid *grid)
 			}
 			g_list_free (sel_rows);
 		}
-		
+
 		/* Actual ouput computations */
 		export_type = gtk_combo_box_get_active (GTK_COMBO_BOX (types));
 		grid->priv->export_type = export_type;
@@ -2267,8 +2286,8 @@ save_as_response_cb (GtkDialog *dialog, guint response_id, GdauiRawGrid *grid)
 			paramlist = gda_set_new (NULL);
 			gda_set_add_holder (paramlist, param);
 			g_object_unref (param);
-			body = gda_data_model_export_to_string (GDA_DATA_MODEL (grid->priv->data_model), 
-								GDA_DATA_MODEL_IO_TEXT_SEPARATED, 
+			body = gda_data_model_export_to_string (GDA_DATA_MODEL (grid->priv->data_model),
+								GDA_DATA_MODEL_IO_TEXT_SEPARATED,
 								cols, nb_cols, rows, nb_rows, paramlist);
 			g_object_unref (paramlist);
 			break;
@@ -2277,8 +2296,8 @@ save_as_response_cb (GtkDialog *dialog, guint response_id, GdauiRawGrid *grid)
 			paramlist = gda_set_new (NULL);
 			gda_set_add_holder (paramlist, param);
 			g_object_unref (param);
-			body = gda_data_model_export_to_string (GDA_DATA_MODEL (grid->priv->data_model), 
-								GDA_DATA_MODEL_IO_TEXT_SEPARATED, 
+			body = gda_data_model_export_to_string (GDA_DATA_MODEL (grid->priv->data_model),
+								GDA_DATA_MODEL_IO_TEXT_SEPARATED,
 								cols, nb_cols, rows, nb_rows, paramlist);
 			g_object_unref (paramlist);
 			break;
@@ -2290,8 +2309,8 @@ save_as_response_cb (GtkDialog *dialog, guint response_id, GdauiRawGrid *grid)
 			paramlist = gda_set_new (NULL);
 			gda_set_add_holder (paramlist, param);
 			g_object_unref (param);
-			body = gda_data_model_export_to_string (GDA_DATA_MODEL (grid->priv->data_model), 
-								GDA_DATA_MODEL_IO_DATA_ARRAY_XML, 
+			body = gda_data_model_export_to_string (GDA_DATA_MODEL (grid->priv->data_model),
+								GDA_DATA_MODEL_IO_DATA_ARRAY_XML,
 								cols, nb_cols, rows, nb_rows, paramlist);
 			g_object_unref (paramlist);
 			break;
@@ -2322,7 +2341,7 @@ save_as_response_cb (GtkDialog *dialog, guint response_id, GdauiRawGrid *grid)
 					return;
 				}
 				g_free (path);
-			} 
+			}
 			else {
 				_gdaui_utility_show_error (NULL, _("You must specify a file name"));
 				g_free (body);
@@ -2352,7 +2371,7 @@ confirm_file_overwrite (GtkWindow *parent, const gchar *path)
 			   _("If you choose yes, the contents will be lost."),
 			   NULL);
 	g_free (msg);
-	dialog = gtk_message_dialog_new_with_markup (parent, 
+	dialog = gtk_message_dialog_new_with_markup (parent,
 						     GTK_DIALOG_DESTROY_WITH_PARENT |
 						     GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION,
 						     GTK_BUTTONS_CLOSE, "%s", str);
@@ -2408,7 +2427,7 @@ tree_view_row_activated_cb (GtkTreeView *tree_view, GtkTreePath *path, GtkTreeVi
 	g_signal_emit (G_OBJECT (grid), gdaui_raw_grid_signals[DOUBLE_CLICKED], 0, *indices);
 #ifdef debug_signal
 	g_print ("<< 'DOUBLE_CLICKED' from %s %p\n", G_OBJECT_TYPE_NAME (grid), grid);
-#endif	
+#endif
 }
 
 /*
@@ -2419,9 +2438,8 @@ tree_view_selection_changed_cb (GtkTreeSelection *selection, GdauiRawGrid *grid)
 {
 	GtkTreeIter iter;
 	GtkTreeModel *model;
-	gboolean row_selected = FALSE;
 	gint has_selection;
-	
+
 	/* block the GdaDataModelIter' "changed" signal */
 	g_signal_handlers_block_by_func (grid->priv->iter,
 					 G_CALLBACK (iter_row_changed_cb), grid);
@@ -2441,9 +2459,9 @@ tree_view_selection_changed_cb (GtkTreeSelection *selection, GdauiRawGrid *grid)
 		has_selection = gtk_tree_selection_get_selected (selection, &model, &iter) ? 1 : 0;
 
 	if (has_selection == 1) {
-		if (!gda_data_model_iter_move_to_row (grid->priv->iter, 
-						     gdaui_data_store_get_row_from_iter (grid->priv->store, 
-											    &iter))) {
+		if (!gda_data_model_iter_move_to_row (grid->priv->iter,
+						      gdaui_data_store_get_row_from_iter (grid->priv->store,
+											  &iter))) {
 			/* selection changing is refused, return to the current selected row */
 			GtkTreePath *path;
 			path = gtk_tree_path_new_from_indices (gda_data_model_iter_get_row (grid->priv->iter), -1);
@@ -2457,7 +2475,6 @@ tree_view_selection_changed_cb (GtkTreeSelection *selection, GdauiRawGrid *grid)
 
 			gtk_tree_path_free (path);
 		}
-		row_selected = TRUE;
 	}
 	else {
 		/* render all the parameters invalid, and make the iter point to row -1 */
@@ -2465,13 +2482,7 @@ tree_view_selection_changed_cb (GtkTreeSelection *selection, GdauiRawGrid *grid)
 		gda_data_model_iter_move_to_row (grid->priv->iter, -1);
 	}
 
-#ifdef debug_signal
-	g_print (">> 'SELECTION_CHANGED' from %s %p\n", G_OBJECT_TYPE_NAME (grid), grid);
-#endif
-	g_signal_emit (G_OBJECT (grid), gdaui_raw_grid_signals[SELECTION_CHANGED], 0, row_selected);
-#ifdef debug_signal
-	g_print ("<< 'SELECTION_CHANGED' from %s %p\n", G_OBJECT_TYPE_NAME (grid), grid);
-#endif
+	g_signal_emit_by_name (G_OBJECT (grid), "selection-changed");
 
 	/* unblock the GdaDataModelIter' "changed" signal */
 	g_signal_handlers_unblock_by_func (grid->priv->iter,
@@ -2492,9 +2503,10 @@ get_column_data (GdauiRawGrid *grid, GdauiSetGroup *group)
 
 /**
  * gdaui_raw_grid_set_sample_size
- * @grid:
+ * @grid: a #GdauiRawGrid
  * @sample_size:
  *
+ * Since: 4.2
  */
 void
 gdaui_raw_grid_set_sample_size (GdauiRawGrid *grid, gint sample_size)
@@ -2507,26 +2519,111 @@ gdaui_raw_grid_set_sample_size (GdauiRawGrid *grid, gint sample_size)
 
 /**
  * gdaui_raw_grid_set_sample_start
- * @grid:
+ * @grid: a #GdauiRawGrid
  * @sample_start:
  *
+ *
+ * Since: 4.2
  */
 void
 gdaui_raw_grid_set_sample_start (GdauiRawGrid *grid, gint sample_start)
 {
 	g_return_if_fail (grid && GDAUI_IS_RAW_GRID (grid));
 	g_return_if_fail (grid->priv);
-	
+
 	gda_data_proxy_set_sample_start (grid->priv->proxy, sample_start);
 }
 
+/**
+ * gdaui_raw_grid_set_data_layout_from_file
+ * @grid: a #GdauiRawGrid
+ * @file_name:
+ * @parent_table:
+ *
+ * Sets a data layout according an XML description contained in @file_name
+ *
+ * Since: 4.2
+ */
+void
+gdaui_raw_grid_set_data_layout_from_file (GdauiRawGrid *grid, const gchar *file_name,
+					  const gchar *parent_table)
+{
+	g_return_if_fail (GDAUI_IS_RAW_GRID (grid));
+	g_return_if_fail (file_name);
+	g_return_if_fail (parent_table);
+
+	xmlDocPtr doc;
+	doc = xmlParseFile (file_name);
+	if (doc == NULL) {
+		g_warning (_("'%s' Document not parsed successfully\n"), file_name);
+		return;
+	}
+
+	xmlDtdPtr dtd = NULL;
+
+	gchar *file = gda_gbr_get_file_path (GDA_DATA_DIR, LIBGDA_ABI_NAME, "dtd", "data-layout.dtd", NULL);
+	if (g_file_test (file, G_FILE_TEST_EXISTS))
+		dtd = xmlParseDTD (NULL, BAD_CAST file);
+	if (dtd == NULL) {
+		g_warning (_("'%s' DTD not parsed successfully. "
+			     "XML data layout validation will not be "
+			     "performed (some errors may occur)"), file);
+	}
+	g_free (file);
+
+	/* Get the root element node */
+	xmlNodePtr root_node = NULL;
+	root_node = xmlDocGetRootElement (doc);
+
+	/* Must have root element, a name and the name must be "data_layouts" */
+	if (!root_node ||
+	    !root_node->name ||
+	    xmlStrcmp (root_node->name, BAD_CAST "data_layouts")) {
+		xmlFreeDoc (doc);
+		return;
+	}
+
+	xmlNodePtr node;
+	for (node = root_node->children; node != NULL; node = node->next) {
+
+		if (node->type == XML_ELEMENT_NODE &&
+		    !xmlStrcmp (node->name, BAD_CAST "data_layout")) {
+			gboolean retval = FALSE;
+			xmlChar *str;
+
+			str = xmlGetProp (node, BAD_CAST "parent_table");
+			if (str) {
+				if (strcmp ((gchar*) str, parent_table) == 0)
+					retval = TRUE;
+				//g_print ("parent_table: %s\n", str);
+				xmlFree (str);
+			}
+
+			str = xmlGetProp (node, BAD_CAST "name");
+			if (str) {
+				if (retval && !strcmp ((gchar*) str, "list"))  // Now proceed
+					g_object_set (G_OBJECT (grid), "data-layout", node, NULL);
+				//g_print ("name: %s\n", str);
+				xmlFree (str);
+			}
+		}
+	}
+
+	/* Free the document */
+	xmlFreeDoc (doc);
+
+	/* Free the global variables that may
+	 * have been allocated by the parser */
+	xmlCleanupParser ();
+
+}
 
 /*
- * GdauiDataWidget interface
+ * GdauiDataProxy interface
  */
 
 static GdaDataProxy *
-gdaui_raw_grid_get_proxy (GdauiDataWidget *iface)
+gdaui_raw_grid_get_proxy (GdauiDataProxy *iface)
 {
 	GdauiRawGrid *grid;
 	g_return_val_if_fail (GDAUI_IS_RAW_GRID (iface), NULL);
@@ -2537,7 +2634,7 @@ gdaui_raw_grid_get_proxy (GdauiDataWidget *iface)
 }
 
 static void
-gdaui_raw_grid_set_column_editable (GdauiDataWidget *iface, gint column, gboolean editable)
+gdaui_raw_grid_set_column_editable (GdauiDataProxy *iface, gint column, gboolean editable)
 {
 	GdauiRawGrid *grid;
 	GdaHolder *param;
@@ -2547,7 +2644,7 @@ gdaui_raw_grid_set_column_editable (GdauiDataWidget *iface, gint column, gboolea
 	g_return_if_fail (GDAUI_IS_RAW_GRID (iface));
 	grid = GDAUI_RAW_GRID (iface);
 	g_return_if_fail (grid->priv);
-	
+
 	if (grid->priv->data_model) {
 		editable = editable && !gda_data_proxy_is_read_only (grid->priv->proxy);
 
@@ -2559,7 +2656,7 @@ gdaui_raw_grid_set_column_editable (GdauiDataWidget *iface, gint column, gboolea
 
 		column_data = get_column_data (grid, group);
 		g_return_if_fail (column_data);
-		
+
 		if (editable && !gda_data_proxy_is_read_only (grid->priv->proxy))
 			column_data->data_locked = FALSE;
 		else
@@ -2568,7 +2665,7 @@ gdaui_raw_grid_set_column_editable (GdauiDataWidget *iface, gint column, gboolea
 }
 
 static void
-gdaui_raw_grid_show_column_actions (GdauiDataWidget *iface, gint column, gboolean show_actions)
+gdaui_raw_grid_show_column_actions (GdauiDataProxy *iface, gint column, gboolean show_actions)
 {
 	GdauiRawGrid *grid;
 
@@ -2584,13 +2681,13 @@ gdaui_raw_grid_show_column_actions (GdauiDataWidget *iface, gint column, gboolea
 		/* setting applies only to the @column column */
 		param = gda_data_model_iter_get_holder_for_field (grid->priv->iter, column);
 		g_return_if_fail (param);
-		
+
 		group = _gdaui_set_get_group (grid->priv->iter_info, param);
 		g_return_if_fail (group);
 
 		cdata = get_column_data (grid, group);
 		g_return_if_fail (cdata);
-		
+
 		if (show_actions != cdata->info_shown) {
 			cdata->info_shown = show_actions;
 			g_object_set (G_OBJECT (cdata->info_cell), "visible", cdata->info_shown, NULL);
@@ -2610,69 +2707,16 @@ gdaui_raw_grid_show_column_actions (GdauiDataWidget *iface, gint column, gboolea
 	}
 }
 
-static void
-gdaui_raw_grid_col_set_show (GdauiDataWidget *iface, gint column, gboolean shown)
-{
-	GdauiRawGrid *grid;
-	gint pos = -1;
-	GtkTreeViewColumn *viewcol;
-	GdaSetGroup *group;
-	GdaHolder *param;
-
-	g_return_if_fail (GDAUI_IS_RAW_GRID (iface));
-	grid = GDAUI_RAW_GRID (iface);
-	g_return_if_fail (grid->priv);
-
-	param = gda_data_model_iter_get_holder_for_field (grid->priv->iter, column);
-	g_return_if_fail (param);
-
-	group = gda_set_get_group ((GdaSet *)grid->priv->iter, param);	
-	pos = g_slist_index (((GdaSet *)grid->priv->iter)->groups_list, group);	
-	g_assert (pos >= 0);
-
-	viewcol = gtk_tree_view_get_column (GTK_TREE_VIEW (grid), pos);
-
-	/* Sets the column's visibility */
-	gtk_tree_view_column_set_visible (viewcol, shown);
-}
-
-
 static GtkActionGroup *
-gdaui_raw_grid_get_actions_group (GdauiDataWidget *iface)
-{
-	GdauiRawGrid *grid;
-	
-	g_return_val_if_fail (GDAUI_IS_RAW_GRID (iface), NULL);
-	grid = GDAUI_RAW_GRID (iface);
-	g_return_val_if_fail (grid->priv, NULL);
-
-	return grid->priv->actions_group;
-}
-
-static GdaDataModelIter *
-gdaui_raw_grid_widget_get_data_set (GdauiDataWidget *iface)
+gdaui_raw_grid_get_actions_group (GdauiDataProxy *iface)
 {
 	GdauiRawGrid *grid;
-	
-	g_return_val_if_fail (GDAUI_IS_RAW_GRID (iface), NULL);
-	grid = GDAUI_RAW_GRID (iface);
-	g_return_val_if_fail (grid->priv, NULL);
 
-	return grid->priv->iter;
-}
-
-
-static GdaDataModel *
-gdaui_raw_grid_widget_get_gda_model (GdauiDataWidget *iface)
-{
-	GdauiRawGrid *grid;
 	g_return_val_if_fail (GDAUI_IS_RAW_GRID (iface), NULL);
 	grid = GDAUI_RAW_GRID (iface);
 	g_return_val_if_fail (grid->priv, NULL);
 
-	/* warning: here we are returning the *original* GdaDataModel */
-
-	return GDA_DATA_MODEL (grid->priv->data_model);
+	return grid->priv->actions_group;
 }
 
 static void
@@ -2684,7 +2728,7 @@ paramlist_public_data_changed_cb (GdauiSet *info, GdauiRawGrid *grid)
 	if (grid->priv->columns_data) {
 		GSList *list;
 		for (list = grid->priv->columns_data; list; list = list->next) {
-                        g_free (((ColumnData *) (list->data))->tooltip_text);
+			g_free (((ColumnData *) (list->data))->tooltip_text);
 			g_free (list->data);
 		}
 		g_slist_free (grid->priv->columns_data);
@@ -2741,7 +2785,7 @@ apply_hidden_columns (GdauiRawGrid *grid, gboolean *hidden_cols)
 }
 
 static void
-paramlist_param_attr_changed_cb (GdaSet *paramlist, GdaHolder *param, 
+paramlist_param_attr_changed_cb (GdaSet *paramlist, GdaHolder *param,
 				 const gchar *att_name, const GValue *att_value, GdauiRawGrid *grid)
 {
 	if (!strcmp (att_name, GDAUI_ATTRIBUTE_PLUGIN)) {
@@ -2761,18 +2805,18 @@ paramlist_param_attr_changed_cb (GdaSet *paramlist, GdaHolder *param,
 static GError *
 iter_validate_set_cb (GdaDataModelIter *iter, GdauiRawGrid *grid)
 {
-GError *error = NULL;
+	GError *error = NULL;
 	gint row = gda_data_model_iter_get_row (iter);
-	
+
 	if (row < 0)
 		return NULL;
 
-	if ((grid->priv->write_mode >= GDAUI_DATA_WIDGET_WRITE_ON_ROW_CHANGE) &&
-		/* write back the current row */
+	if ((grid->priv->write_mode >= GDAUI_DATA_PROXY_WRITE_ON_ROW_CHANGE) &&
+	    /* write back the current row */
 	    gda_data_proxy_row_has_changed (grid->priv->proxy, row) &&
 	    !gda_data_proxy_apply_row_changes (grid->priv->proxy, row, &error)) {
-		if (_gdaui_utility_display_error_with_keep_or_discard_choice ((GdauiDataWidget *) grid, 
-										error)) {
+		if (_gdaui_utility_display_error_with_keep_or_discard_choice ((GdauiDataProxy *) grid,
+									      error)) {
 			gda_data_proxy_cancel_row_changes (grid->priv->proxy, row, -1);
 			if (error) {
 				g_error_free (error);
@@ -2780,8 +2824,8 @@ GError *error = NULL;
 			}
 		}
 	}
-	
-	return error;	
+
+	return error;
 }
 
 static void
@@ -2791,7 +2835,7 @@ iter_row_changed_cb (GdaDataModelIter *iter, gint row, GdauiRawGrid *grid)
 	GtkTreePath *path;
 
 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (grid));
-	
+
 	if (row >= 0) {
 		GtkSelectionMode mode;
 		GtkTreeIter treeiter;
@@ -2823,9 +2867,9 @@ proxy_sample_changed_cb (GdaDataProxy *proxy, gint sample_start, gint sample_end
 static void
 proxy_row_updated_cb (GdaDataProxy *proxy, gint proxy_row, GdauiRawGrid *grid)
 {
-	if (grid->priv->write_mode == GDAUI_DATA_WIDGET_WRITE_ON_VALUE_ACTIVATED) {
+	if (grid->priv->write_mode == GDAUI_DATA_PROXY_WRITE_ON_VALUE_ACTIVATED) {
 		gint row;
-		
+
 		/* REM: this may lead to problems in the proxy because it is not re-entrant, solution: add a very short timeout */
 		row = gda_data_model_iter_get_row (grid->priv->iter);
 		if ((row >= 0) && (row == proxy_row)) {
@@ -2840,8 +2884,8 @@ proxy_row_updated_cb (GdaDataProxy *proxy, gint proxy_row, GdauiRawGrid *grid)
 
 				if (!gda_data_proxy_apply_row_changes (grid->priv->proxy, row, &error)) {
 					gboolean discard;
-					discard = _gdaui_utility_display_error_with_keep_or_discard_choice ((GdauiDataWidget *) grid, 
-												     error);
+					discard = _gdaui_utility_display_error_with_keep_or_discard_choice ((GdauiDataProxy *) grid,
+													    error);
 					if (discard)
 						gda_data_proxy_cancel_row_changes (grid->priv->proxy, row, -1);
 					g_error_free (error);
@@ -2862,18 +2906,6 @@ proxy_reset_cb (GdaDataProxy *proxy, GdauiRawGrid *grid)
 }
 
 static void
-gdaui_raw_grid_widget_set_gda_model (GdauiDataWidget *iface, GdaDataModel *model)
-{
-	GdauiRawGrid *grid;
-
-	g_return_if_fail (GDAUI_IS_RAW_GRID (iface));
-	grid = GDAUI_RAW_GRID (iface);
-	g_return_if_fail (grid->priv);
-	
-	g_object_set (grid, "model", model, NULL);
-}
-
-static void
 gdaui_raw_grid_soft_clean (GdauiRawGrid *grid)
 {
 	GList *columns, *list;
@@ -2892,7 +2924,7 @@ gdaui_raw_grid_soft_clean (GdauiRawGrid *grid)
 	if (grid->priv->columns_data) {
 		GSList *list;
 		for (list = grid->priv->columns_data; list; list = list->next) {
-                        g_free (((ColumnData *) (list->data))->tooltip_text);
+			g_free (((ColumnData *) (list->data))->tooltip_text);
 			g_free (list->data);
 		}
 		g_slist_free (grid->priv->columns_data);
@@ -2927,7 +2959,7 @@ gdaui_raw_grid_clean (GdauiRawGrid *grid)
 		grid->priv->iter = NULL;
 		grid->priv->iter_info = NULL;
 	}
-	
+
 	/* proxy */
 	if (grid->priv->proxy) {
 		g_signal_handlers_disconnect_by_func (grid->priv->proxy, G_CALLBACK (proxy_sample_changed_cb), grid);
@@ -2939,21 +2971,21 @@ gdaui_raw_grid_clean (GdauiRawGrid *grid)
 }
 
 static gboolean
-gdaui_raw_grid_widget_set_write_mode (GdauiDataWidget *iface, GdauiDataWidgetWriteMode mode)
+gdaui_raw_grid_widget_set_write_mode (GdauiDataProxy *iface, GdauiDataProxyWriteMode mode)
 {
 	GdauiRawGrid *grid;
-	
+
 	g_return_val_if_fail (GDAUI_IS_RAW_GRID (iface), FALSE);
 	grid = GDAUI_RAW_GRID (iface);
 	g_return_val_if_fail (grid->priv, FALSE);
 
 	grid->priv->write_mode = mode;
-	if (mode == GDAUI_DATA_WIDGET_WRITE_ON_VALUE_CHANGE) {
-		grid->priv->write_mode = GDAUI_DATA_WIDGET_WRITE_ON_VALUE_ACTIVATED;
+	if (mode == GDAUI_DATA_PROXY_WRITE_ON_VALUE_CHANGE) {
+		grid->priv->write_mode = GDAUI_DATA_PROXY_WRITE_ON_VALUE_ACTIVATED;
 		return FALSE;
 	}
 
-	if (mode == GDAUI_DATA_WIDGET_WRITE_ON_ROW_CHANGE) {
+	if (mode == GDAUI_DATA_PROXY_WRITE_ON_ROW_CHANGE) {
 		GtkTreeSelection *selection;
 		selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (grid));
 		gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
@@ -2961,27 +2993,128 @@ gdaui_raw_grid_widget_set_write_mode (GdauiDataWidget *iface, GdauiDataWidgetWri
 	return TRUE;
 }
 
-static GdauiDataWidgetWriteMode
-gdaui_raw_grid_widget_get_write_mode (GdauiDataWidget *iface)
+static GdauiDataProxyWriteMode
+gdaui_raw_grid_widget_get_write_mode (GdauiDataProxy *iface)
 {
 	GdauiRawGrid *grid;
-	
-	g_return_val_if_fail (GDAUI_IS_RAW_GRID (iface), GDAUI_DATA_WIDGET_WRITE_ON_DEMAND);
+
+	g_return_val_if_fail (GDAUI_IS_RAW_GRID (iface), GDAUI_DATA_PROXY_WRITE_ON_DEMAND);
 	grid = GDAUI_RAW_GRID (iface);
-	g_return_val_if_fail (grid->priv, GDAUI_DATA_WIDGET_WRITE_ON_DEMAND);
+	g_return_val_if_fail (grid->priv, GDAUI_DATA_PROXY_WRITE_ON_DEMAND);
 
 	return grid->priv->write_mode;
 }
 
+/* GdauiDataSelector interface */
+static GdaDataModel *
+gdaui_raw_grid_selector_get_model (GdauiDataSelector *iface)
+{
+	GdauiRawGrid *grid;
+
+	g_return_val_if_fail (GDAUI_IS_RAW_GRID (iface), NULL);
+	grid = GDAUI_RAW_GRID (iface);
+
+	return GDA_DATA_MODEL (grid->priv->proxy);
+}
+
 static void
-gdaui_raw_grid_set_data_layout (GdauiDataWidget  *iface, gpointer  data)
+gdaui_raw_grid_selector_set_model (GdauiDataSelector *iface, GdaDataModel *model)
 {
-	GdauiRawGrid *raw_grid;
-	
+	GdauiRawGrid *grid;
+
 	g_return_if_fail (GDAUI_IS_RAW_GRID (iface));
-	raw_grid = GDAUI_RAW_GRID (iface);
-	g_return_if_fail (raw_grid->priv);
+	grid = GDAUI_RAW_GRID (iface);
 
-	g_object_set (G_OBJECT (raw_grid), "data_layout", data, NULL);
+	g_object_set (grid, "model", model, NULL);
 }
 
+static GArray *
+gdaui_raw_grid_selector_get_selected_rows (GdauiDataSelector *iface)
+{
+	GtkTreeSelection *selection;
+	GList *selected_rows;
+	GdauiRawGrid *grid;
+
+	g_return_val_if_fail (GDAUI_IS_RAW_GRID (iface), NULL);
+	grid = GDAUI_RAW_GRID (iface);
+
+	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (grid));
+	selected_rows = gtk_tree_selection_get_selected_rows (selection, NULL);
+	if (selected_rows) {
+		GList *list;
+		GArray *selarray = NULL;
+		GtkTreeIter iter;
+		gint row;
+
+		for (list = selected_rows; list; list = list->next) {
+			if (gtk_tree_model_get_iter (GTK_TREE_MODEL (grid->priv->store), &iter,
+						     (GtkTreePath *)(list->data))) {
+				gtk_tree_model_get (GTK_TREE_MODEL (grid->priv->store), &iter,
+						    DATA_STORE_COL_MODEL_ROW, &row, -1);
+				if (!selarray)
+					selarray = g_array_new (FALSE, FALSE, sizeof (gint));
+				g_array_append_val (selarray, row);
+			}
+		}
+		g_list_foreach (selected_rows, (GFunc) gtk_tree_path_free, NULL);
+		g_list_free (selected_rows);
+		return selarray;
+	}
+	else
+		return NULL;
+}
+
+static GdaDataModelIter *
+gdaui_raw_grid_selector_get_current_selection (GdauiDataSelector *iface)
+{
+	GdauiRawGrid *grid;
+
+	g_return_val_if_fail (GDAUI_IS_RAW_GRID (iface), NULL);
+	grid = GDAUI_RAW_GRID (iface);
+
+	return grid->priv->iter;
+}
+
+static gboolean
+gdaui_raw_grid_selector_select_row (GdauiDataSelector *iface, gint row)
+{
+	GdauiRawGrid *grid;
+
+	g_return_val_if_fail (GDAUI_IS_RAW_GRID (iface), FALSE);
+	grid = (GdauiRawGrid*) iface;
+
+	TO_IMPLEMENT;
+	return FALSE;
+}
+
+static void
+gdaui_raw_grid_selector_unselect_row (GdauiDataSelector *iface, gint row)
+{
+	TO_IMPLEMENT;
+}
+
+static void
+gdaui_raw_grid_selector_set_column_visible (GdauiDataSelector *iface, gint column, gboolean visible)
+{
+	GdauiRawGrid *grid;
+	gint pos = -1;
+	GtkTreeViewColumn *viewcol;
+	GdaSetGroup *group;
+	GdaHolder *param;
+
+	g_return_if_fail (GDAUI_IS_RAW_GRID (iface));
+	grid = GDAUI_RAW_GRID (iface);
+	g_return_if_fail (grid->priv);
+
+	param = gda_data_model_iter_get_holder_for_field (grid->priv->iter, column);
+	g_return_if_fail (param);
+
+	group = gda_set_get_group ((GdaSet *)grid->priv->iter, param);
+	pos = g_slist_index (((GdaSet *)grid->priv->iter)->groups_list, group);
+	g_assert (pos >= 0);
+
+	viewcol = gtk_tree_view_get_column (GTK_TREE_VIEW (grid), pos);
+
+	/* Sets the column's visibility */
+	gtk_tree_view_column_set_visible (viewcol, visible);
+}
diff --git a/libgda-ui/gdaui-raw-grid.h b/libgda-ui/gdaui-raw-grid.h
index 547fc4b..908c922 100644
--- a/libgda-ui/gdaui-raw-grid.h
+++ b/libgda-ui/gdaui-raw-grid.h
@@ -38,17 +38,16 @@ typedef struct _GdauiRawGridPriv  GdauiRawGridPriv;
 /* struct for the object's data */
 struct _GdauiRawGrid
 {
-	GtkTreeView             object;
+	GtkTreeView         object;
 
-	GdauiRawGridPriv     *priv;
+	GdauiRawGridPriv   *priv;
 };
 
 /* struct for the object's class */
 struct _GdauiRawGridClass
 {
-	GtkTreeViewClass        parent_class;
+	GtkTreeViewClass    parent_class;
 
-	void             (* selection_changed) (GdauiRawGrid *grid, gboolean row_selected);
 	void             (* double_clicked)    (GdauiRawGrid *grid, gint row);
         void             (* populate_popup)    (GdauiRawGrid *grid, GtkMenu *menu);
 };
@@ -63,7 +62,10 @@ GtkWidget        *gdaui_raw_grid_new                       (GdaDataModel *model)
 void              gdaui_raw_grid_set_sample_size           (GdauiRawGrid *grid, gint sample_size);
 void              gdaui_raw_grid_set_sample_start          (GdauiRawGrid *grid, gint sample_start);
 
-GList            *gdaui_raw_grid_get_selection             (GdauiRawGrid *grid);
+void              gdaui_raw_grid_set_data_layout_from_file (GdauiRawGrid *grid, const gchar *file_name,
+							    const gchar *parent_table);
+/* private API */
+GList            *_gdaui_raw_grid_get_selection            (GdauiRawGrid *grid);
 
 G_END_DECLS
 
diff --git a/libgda-ui/gdaui-server-operation.c b/libgda-ui/gdaui-server-operation.c
index e44aa80..67d2da9 100644
--- a/libgda-ui/gdaui-server-operation.c
+++ b/libgda-ui/gdaui-server-operation.c
@@ -1,6 +1,6 @@
 /* gdaui-server-operation.c
  *
- * Copyright (C) 2006 - 2008 Vivien Malerba
+ * Copyright (C) 2006 - 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
@@ -27,28 +27,28 @@
 #include "gdaui-raw-grid.h"
 #include "gdaui-raw-form.h"
 #include "gdaui-data-store.h"
-#include "gdaui-data-widget.h"
-#include "gdaui-data-widget-info.h"
+#include "gdaui-data-proxy.h"
+#include "gdaui-data-selector.h"
+#include "gdaui-data-proxy-info.h"
 
 static void gdaui_server_operation_class_init (GdauiServerOperationClass *class);
 static void gdaui_server_operation_init (GdauiServerOperation *wid);
 static void gdaui_server_operation_dispose (GObject *object);
 
 static void gdaui_server_operation_set_property (GObject *object,
-					      guint param_id,
-					      const GValue *value,
-					      GParamSpec *pspec);
+						 guint param_id,
+						 const GValue *value,
+						 GParamSpec *pspec);
 static void gdaui_server_operation_get_property (GObject *object,
-					      guint param_id,
-					      GValue *value,
-					      GParamSpec *pspec);
+						 guint param_id,
+						 GValue *value,
+						 GParamSpec *pspec);
 
 static void gdaui_server_operation_fill (GdauiServerOperation *form);
 
 /* properties */
-enum
-{
-        PROP_0,
+enum {
+	PROP_0,
 	PROP_SERVER_OP_OBJ,
 	PROP_OPT_HEADER
 };
@@ -118,7 +118,7 @@ widget_data_find (GdauiServerOperation *form, const gchar *path)
 
 	list = form->priv->widget_data;
 	while (list && !wd) {
-		if (WIDGET_DATA (list->data)->path_name && 
+		if (WIDGET_DATA (list->data)->path_name &&
 		    !strcmp (WIDGET_DATA (list->data)->path_name, array[1]))
 			wd = WIDGET_DATA (list->data);
 		list = list->next;
@@ -133,12 +133,12 @@ widget_data_find (GdauiServerOperation *form, const gchar *path)
 		if (end && *end)
 			index = -1; /* could not convert array[i] to an int */
 
-		if ((index >= 0) && wd->children && !WIDGET_DATA (wd->children->data)->path_name) 
+		if ((index >= 0) && wd->children && !WIDGET_DATA (wd->children->data)->path_name)
 			wd = g_slist_nth_data (wd->children, index);
 		else {
 			wd = NULL;
 			while (list && !wd) {
-				if (WIDGET_DATA (list->data)->path_name && 
+				if (WIDGET_DATA (list->data)->path_name &&
 				    !strcmp (WIDGET_DATA (list->data)->path_name, array[i]))
 					wd = WIDGET_DATA (list->data);
 				list = list->next;
@@ -171,8 +171,8 @@ gdaui_server_operation_get_type (void)
 			sizeof (GdauiServerOperation),
 			0,
 			(GInstanceInitFunc) gdaui_server_operation_init
-		};		
-		
+		};
+
 		type = g_type_register_static (GTK_TYPE_VBOX, "GdauiServerOperation", &info, 0);
 	}
 
@@ -183,7 +183,7 @@ static void
 gdaui_server_operation_class_init (GdauiServerOperationClass *class)
 {
 	GObjectClass *object_class = G_OBJECT_CLASS (class);
-	
+
 	parent_class = g_type_class_peek_parent (class);
 
 	object_class->dispose = gdaui_server_operation_dispose;
@@ -192,15 +192,15 @@ gdaui_server_operation_class_init (GdauiServerOperationClass *class)
         object_class->set_property = gdaui_server_operation_set_property;
         object_class->get_property = gdaui_server_operation_get_property;
 	g_object_class_install_property (object_class, PROP_SERVER_OP_OBJ,
-					 g_param_spec_object ("server_operation", 
-							       _("The specification of the operation to implement"), 
-							       NULL, GDA_TYPE_SERVER_OPERATION,
-							       G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
-							       G_PARAM_READABLE));
+					 g_param_spec_object ("server_operation",
+							      _("The specification of the operation to implement"),
+							      NULL, GDA_TYPE_SERVER_OPERATION,
+							      G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
+							      G_PARAM_READABLE));
 	g_object_class_install_property (object_class, PROP_OPT_HEADER,
-					 g_param_spec_boolean ("opt_header",
+					 g_param_spec_boolean ("hide-single-header",
 							       _("Request section header to be hidden if there is only one section"),
-							       NULL, FALSE, G_PARAM_CONSTRUCT | G_PARAM_READABLE | 
+							       NULL, FALSE, G_PARAM_CONSTRUCT | G_PARAM_READABLE |
 							       G_PARAM_WRITABLE));
 }
 
@@ -227,6 +227,8 @@ gdaui_server_operation_init (GdauiServerOperation * wid)
  * node of @paramlist.
  *
  * Returns: the new widget
+ *
+ * Since: 4.2
  */
 GtkWidget *
 gdaui_server_operation_new (GdaServerOperation *op)
@@ -265,7 +267,7 @@ gdaui_server_operation_dispose (GObject *object)
 			g_slist_free (form->priv->widget_data);
 			form->priv->widget_data = NULL;
 		}
-		
+
 #ifdef HAVE_LIBGLADE
 		if (form->priv->glade)
 			g_object_unref (form->priv->glade);
@@ -283,9 +285,9 @@ gdaui_server_operation_dispose (GObject *object)
 
 static void
 gdaui_server_operation_set_property (GObject *object,
-					guint param_id,
-					const GValue *value,
-					GParamSpec *pspec)
+				     guint param_id,
+				     const GValue *value,
+				     GParamSpec *pspec)
 {
 	GdauiServerOperation *form;
 
@@ -301,9 +303,9 @@ gdaui_server_operation_set_property (GObject *object,
 			form->priv->op = GDA_SERVER_OPERATION(g_value_get_object (value));
 			if (form->priv->op) {
 				g_return_if_fail (GDA_IS_SERVER_OPERATION (form->priv->op));
-				
+
 				g_object_ref (form->priv->op);
-				
+
 				gdaui_server_operation_fill (form);
 				g_signal_connect (G_OBJECT (form->priv->op), "sequence_item_added",
 						  G_CALLBACK (sequence_item_added_cb), form);
@@ -323,9 +325,9 @@ gdaui_server_operation_set_property (GObject *object,
 
 static void
 gdaui_server_operation_get_property (GObject *object,
-				  guint param_id,
-				  GValue *value,
-				  GParamSpec *pspec)
+				     guint param_id,
+				     GValue *value,
+				     GParamSpec *pspec)
 {
 	GdauiServerOperation *form;
 
@@ -342,20 +344,20 @@ gdaui_server_operation_get_property (GObject *object,
 			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 			break;
                 }
-        }	
+        }
 }
 
 /*
  * create the entries in the widget
  */
 
-static GtkWidget *fill_create_widget (GdauiServerOperation *form, const gchar *path, 
+static GtkWidget *fill_create_widget (GdauiServerOperation *form, const gchar *path,
 				      gchar **section_str, GSList **label_widgets);
 static void seq_add_item (GtkButton *button, GdauiServerOperation *form);
 static void seq_del_item (GtkButton *button, GdauiServerOperation *form);
 
 
-/* 
+/*
  * @path is like "/SEQ", DOES NOT contain the index of the item to add, which is also in @index
  */
 static void
@@ -372,10 +374,10 @@ sequence_table_attach_widget (GdauiServerOperation *form, GtkWidget *table, GtkW
 	/* new widget */
 	expand = g_object_get_data (G_OBJECT (wid), "expand") ?  TRUE : FALSE;
 	gtk_table_attach (GTK_TABLE (table), wid, 0, 1, index, index + 1,
-			  GTK_FILL | GTK_EXPAND, 
+			  GTK_FILL | GTK_EXPAND,
 			  expand ? (GTK_FILL | GTK_EXPAND) : GTK_SHRINK, 0, 0);
 	gtk_widget_show (wid);
-	
+
 	/* "-" button */
 	image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU);
 	wid = gtk_button_new ();
@@ -387,18 +389,18 @@ sequence_table_attach_widget (GdauiServerOperation *form, GtkWidget *table, GtkW
 	g_object_set_data (G_OBJECT (wid), "_index", GINT_TO_POINTER (index+1));
 	g_signal_connect (G_OBJECT (wid), "clicked",
 			  G_CALLBACK (seq_del_item), form);
-	if (size <= min) 
+	if (size <= min)
 		gtk_widget_set_sensitive (wid, FALSE);
 }
 
-static GtkWidget *create_table_fields_array_create_widget (GdauiServerOperation *form, const gchar *path, 
+static GtkWidget *create_table_fields_array_create_widget (GdauiServerOperation *form, const gchar *path,
 							   gchar **section_str, GSList **label_widgets);
 static GtkWidget *
 fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **section_str, GSList **label_widgets)
 {
 	GdaServerOperationNode *info_node;
 	GtkWidget *plwid = NULL;
-		
+
 	info_node = gda_server_operation_get_node_info (form->priv->op, path);
 	g_assert (info_node);
 
@@ -409,7 +411,7 @@ fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **secti
 
 	/* very custom widget rendering goes here */
 	if ((gda_server_operation_get_op_type (form->priv->op) == GDA_SERVER_OPERATION_CREATE_TABLE) &&
-	    !strcmp (path, "/FIELDS_A")) 
+	    !strcmp (path, "/FIELDS_A"))
 		return create_table_fields_array_create_widget (form, path, section_str, label_widgets);
 
 	/* generic widget rendering */
@@ -420,7 +422,7 @@ fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **secti
 		plist = info_node->plist;
 		plwid = gdaui_basic_form_new (plist);
 		g_object_set ((GObject*) plwid, "show-actions", FALSE, NULL);
-	       
+
 		if (section_str) {
 			const gchar *name;
 			name = g_object_get_data (G_OBJECT (plist), "name");
@@ -431,7 +433,7 @@ fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **secti
 		}
 		if (label_widgets) {
 			GSList *params;
-			
+
 			params = plist->holders;
 			while (params) {
 				GtkWidget *label_entry;
@@ -453,25 +455,25 @@ fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **secti
 		GtkWidget *box, *grid;
 
 		plwid = gtk_scrolled_window_new (NULL, NULL);
-		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (plwid), 
+		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (plwid),
 						GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-		gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (plwid), 
+		gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (plwid),
 						     GTK_SHADOW_NONE);
 
 		model = info_node->model;
 		grid = gdaui_raw_grid_new (model);
 		gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (plwid), grid);
-		gtk_viewport_set_shadow_type (GTK_VIEWPORT (gtk_bin_get_child (GTK_BIN (plwid))), 
+		gtk_viewport_set_shadow_type (GTK_VIEWPORT (gtk_bin_get_child (GTK_BIN (plwid))),
 					      GTK_SHADOW_NONE);
-		gdaui_data_widget_set_write_mode (GDAUI_DATA_WIDGET (grid),
-						     GDAUI_DATA_WIDGET_WRITE_ON_ROW_CHANGE);
+		gdaui_data_proxy_set_write_mode (GDAUI_DATA_PROXY (grid),
+						 GDAUI_DATA_PROXY_WRITE_ON_ROW_CHANGE);
 		gtk_widget_show (grid);
 
-		proxy = gdaui_data_widget_get_proxy (GDAUI_DATA_WIDGET (grid));
+		proxy = gdaui_data_proxy_get_proxy (GDAUI_DATA_PROXY (grid));
 		g_object_set (G_OBJECT (grid), "info-cell-visible", FALSE, NULL);
 
-		winfo = gdaui_data_widget_info_new (GDAUI_DATA_WIDGET (grid), 
-						       GDAUI_DATA_WIDGET_INFO_ROW_MODIFY_BUTTONS);
+		winfo = gdaui_data_proxy_info_new (GDAUI_DATA_PROXY (grid),
+						   GDAUI_DATA_PROXY_INFO_ROW_MODIFY_BUTTONS);
 
 		box = gtk_vbox_new (FALSE, 0);
 		gtk_box_pack_start (GTK_BOX (box), plwid, TRUE, TRUE, 0);
@@ -481,9 +483,9 @@ fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **secti
 		gtk_widget_show (winfo);
 
 		plwid = box;
-		
+
 		if (section_str)
-			*section_str = g_strdup_printf ("<b>%s:</b>", 
+			*section_str = g_strdup_printf ("<b>%s:</b>",
 							(gchar*) g_object_get_data (G_OBJECT (model), "name"));
 
 		if (label_widgets) {
@@ -491,7 +493,7 @@ fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **secti
 			gchar *str;
 
 			if (info_node->status == GDA_SERVER_OPERATION_STATUS_REQUIRED) {
-				str = g_strdup_printf ("<b>%s:</b>", 
+				str = g_strdup_printf ("<b>%s:</b>",
 						       (gchar*) g_object_get_data (G_OBJECT (model), "name"));
 				label_entry = gtk_label_new (str);
 				gtk_label_set_use_markup (GTK_LABEL (label_entry), TRUE);
@@ -505,7 +507,7 @@ fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **secti
 
 			gtk_widget_show (label_entry);
 			str = (gchar *) g_object_get_data (G_OBJECT (model), "descr");
-			if (str && *str) 
+			if (str && *str)
 				gtk_widget_set_tooltip_text (label_entry, str);
 
 			*label_widgets = g_slist_prepend (*label_widgets, label_entry);
@@ -529,7 +531,7 @@ fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **secti
 		g_object_unref (plist);
 
 		if (section_str)
-			*section_str = g_strdup_printf ("<b>%s:</b>", 
+			*section_str = g_strdup_printf ("<b>%s:</b>",
 							(gchar*) g_object_get_data (G_OBJECT (param), "name"));
 		if (label_widgets) {
 			GtkWidget *label_entry;
@@ -545,7 +547,7 @@ fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **secti
 		WidgetData *wdp, *wd;
 		gchar *parent_path = NULL, *path_name = NULL;
 		guint max;
-		
+
 		max = gda_server_operation_get_sequence_max_size (form->priv->op, path);
 		if (section_str) {
 			const gchar *seq_name;
@@ -555,16 +557,16 @@ fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **secti
 
 		plwid = gtk_scrolled_window_new (NULL, NULL);
 
-		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (plwid), 
+		gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (plwid),
 						GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-		gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (plwid), 
+		gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (plwid),
 						     GTK_SHADOW_NONE);
 
 		size = gda_server_operation_get_sequence_size (form->priv->op, path);
 		table = gtk_table_new (size + 1, 2, FALSE);
 		gtk_table_set_row_spacings (GTK_TABLE (table), 10);
 		gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (plwid), table);
-		gtk_viewport_set_shadow_type (GTK_VIEWPORT (gtk_bin_get_child (GTK_BIN (plwid))), 
+		gtk_viewport_set_shadow_type (GTK_VIEWPORT (gtk_bin_get_child (GTK_BIN (plwid))),
 					      GTK_SHADOW_NONE);
 		gtk_widget_show (table);
 
@@ -577,12 +579,12 @@ fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **secti
 			form->priv->widget_data = g_slist_append (form->priv->widget_data, wd);
 		g_free (parent_path);
 		g_free (path_name);
-			
+
 		/* existing entries */
 		for (n = 0; n < size; n++) {
 			GtkWidget *wid;
 			gchar *str;
-			
+
 			str = g_strdup_printf ("%s/%d", path, n);
 			wid = fill_create_widget (form, str, NULL, NULL);
 			sequence_table_attach_widget (form, table, wid, path, n);
@@ -596,7 +598,7 @@ fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **secti
 			gtk_table_attach (GTK_TABLE (table), wid, 0, 1, size, size + 1,
 					  GTK_EXPAND | GTK_FILL, GTK_SHRINK, 0, 0);
 			gtk_widget_show (wid);
-			
+
 			image = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU);
 			wid = gtk_button_new ();
 			gtk_button_set_image (GTK_BUTTON (wid), image);
@@ -644,8 +646,8 @@ fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **secti
 							gtk_widget_ref (label_entry);
 							gtk_container_remove (GTK_CONTAINER (parent), label_entry);
 						}
-						gtk_table_attach (GTK_TABLE (table), label_entry, 
-								  0, 1, tab_index, tab_index+1, 
+						gtk_table_attach (GTK_TABLE (table), label_entry,
+								  0, 1, tab_index, tab_index+1,
 								  GTK_FILL | GTK_SHRINK, GTK_SHRINK, 0, 0);
 						if (parent)
 							gtk_widget_unref (label_entry);
@@ -659,9 +661,9 @@ fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **secti
 				expand = g_object_get_data (G_OBJECT (wid), "expand") ? TRUE : FALSE;
 				seq_expand = seq_expand || expand;
 				if (nb_labels > 0)
-					gtk_table_attach (GTK_TABLE (table), wid, 1, 2, 
+					gtk_table_attach (GTK_TABLE (table), wid, 1, 2,
 							  tab_index - nb_labels, tab_index,
-							  GTK_FILL | GTK_EXPAND, 
+							  GTK_FILL | GTK_EXPAND,
 							  expand ? (GTK_FILL | GTK_EXPAND) : GTK_SHRINK, 0, 0);
 				else {
 					gtk_table_attach (GTK_TABLE (table), wid, 1, 2, tab_index, tab_index +1,
@@ -673,7 +675,7 @@ fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **secti
 			}
 			plwid = table;
 		}
-		else 
+		else
 			plwid = fill_create_widget (form, node_names[0], NULL, NULL);
 
 		g_object_set_data (G_OBJECT (plwid), "expand", GINT_TO_POINTER (seq_expand));
@@ -689,13 +691,13 @@ fill_create_widget (GdauiServerOperation *form, const gchar *path, gchar **secti
 	}
 	default:
 		g_assert_not_reached ();
-		break;			
+		break;
 	}
-	
+
 	return plwid;
 }
 
-static void 
+static void
 gdaui_server_operation_fill (GdauiServerOperation *form)
 {
 	gint i;
@@ -712,14 +714,14 @@ gdaui_server_operation_fill (GdauiServerOperation *form)
 	/* load Glade file for specific GUI if it exists */
 #ifdef HAVE_LIBGLADE
 	glade_file = gdaui_gbr_get_data_dir_path ("server_operation.glade");
-	form->priv->glade = glade_xml_new (glade_file, 
-					   gda_server_operation_op_type_to_string (gda_server_operation_get_op_type (form->priv->op)), 
+	form->priv->glade = glade_xml_new (glade_file,
+					   gda_server_operation_op_type_to_string (gda_server_operation_get_op_type (form->priv->op)),
 					   NULL);
 	g_free (glade_file);
 	if (form->priv->glade) {
 		GtkWidget *mainw;
-		mainw = glade_xml_get_widget (form->priv->glade, 
-					     gda_server_operation_op_type_to_string (gda_server_operation_get_op_type (form->priv->op)));
+		mainw = glade_xml_get_widget (form->priv->glade,
+					      gda_server_operation_op_type_to_string (gda_server_operation_get_op_type (form->priv->op)));
 		if (mainw) {
 			gtk_box_pack_start (GTK_BOX (form), mainw, TRUE, TRUE, 0);
 			gtk_widget_show (mainw);
@@ -753,7 +755,7 @@ gdaui_server_operation_fill (GdauiServerOperation *form)
 
 		plwid = fill_create_widget (form, topnodes[i], &section_str, NULL);
 		if (plwid) {
-			GdaServerOperationNodeStatus status;			
+			GdaServerOperationNodeStatus status;
 			GtkWidget *label = NULL, *hbox = NULL;
 
 			if (! (form->priv->opt_header && (g_strv_length (topnodes) == 1)) && section_str) {
@@ -763,20 +765,20 @@ gdaui_server_operation_fill (GdauiServerOperation *form)
 				gtk_misc_set_alignment (GTK_MISC (label), 0., -1);
 				gtk_label_set_markup (GTK_LABEL (label), section_str);
 				g_free (section_str);
-			
+
 				hbox = gtk_hbox_new (FALSE, 0); /* HIG */
 				gtk_widget_show (hbox);
 				lab = gtk_label_new ("    ");
 				gtk_box_pack_start (GTK_BOX (hbox), lab, FALSE, FALSE, 0);
 				gtk_widget_show (lab);
-			
+
 				gtk_box_pack_start (GTK_BOX (hbox), plwid, TRUE, TRUE, 0);
 				gtk_widget_show (plwid);
 			}
-			else 
+			else
 				gtk_widget_show (plwid);
-			
-			
+
+
 			gda_server_operation_get_node_type (form->priv->op, topnodes[i], &status);
 			switch (status) {
 			case GDA_SERVER_OPERATION_STATUS_OPTIONAL: {
@@ -817,7 +819,7 @@ gdaui_server_operation_fill (GdauiServerOperation *form)
 				break;
 			}
 		}
-			
+
 		i++;
 	}
 
@@ -843,7 +845,7 @@ gdaui_server_operation_fill (GdauiServerOperation *form)
 				if (GTK_IS_NOTEBOOK (parent)) {
 					gint pageno;
 
-					pageno = gtk_notebook_page_num (GTK_NOTEBOOK (parent), 
+					pageno = gtk_notebook_page_num (GTK_NOTEBOOK (parent),
 									(GtkWidget *) (list->data));
 					gtk_notebook_remove_page (GTK_NOTEBOOK (parent), pageno);
 				}
@@ -856,7 +858,7 @@ gdaui_server_operation_fill (GdauiServerOperation *form)
 #endif
 
 	g_strfreev (topnodes);
-	
+
 }
 
 /*
@@ -874,7 +876,7 @@ seq_add_item (GtkButton *button, GdauiServerOperation *form)
 /*
  * For sequences: removing an item by clicking on the "-" button
  */
-static void 
+static void
 seq_del_item (GtkButton *button, GdauiServerOperation *form)
 {
 	gchar *seq_path, *item_path;
@@ -896,7 +898,7 @@ struct MoveChild {
 	guint16    top_attach;
 };
 
-static void 
+static void
 sequence_item_added_cb (GdaServerOperation *op, const gchar *seq_path, gint item_index, GdauiServerOperation *form)
 {
 	GtkWidget *table;
@@ -914,49 +916,53 @@ sequence_item_added_cb (GdaServerOperation *op, const gchar *seq_path, gint item
 	g_assert (wd);
 	table = wd->widget;
 	g_assert (table);
-	
+
 	/* resize table */
 	gtk_table_resize (GTK_TABLE (table), size+1, 2);
 
 	/* move children DOWN if necessary */
 	children = gtk_container_get_children (GTK_CONTAINER (table));
 	for (list = children; list; list = list->next) {
-		GtkTableChild *tc = (GtkTableChild *) (list->data);
+		GtkWidget *child = GTK_WIDGET (list->data);
 
-		if (tc->widget) {
+		if (child) {
+			guint top_attach, left_attach;
+			gtk_container_child_get (GTK_CONTAINER (table), child,
+						 "top-attach", &top_attach,
+						 "left-attach", &left_attach, NULL);
 			/* ADD/REMOVE button sensitivity */
-			if (tc->left_attach == 1) {
-				if (tc->top_attach == size-1)
-					gtk_widget_set_sensitive (tc->widget, (size < max) ? TRUE : FALSE);
+			if (left_attach == 1) {
+				if (top_attach == size-1)
+					gtk_widget_set_sensitive (child, (size < max) ? TRUE : FALSE);
 				else
-					gtk_widget_set_sensitive (tc->widget, (size > min) ? TRUE : FALSE);
+					gtk_widget_set_sensitive (child, (size > min) ? TRUE : FALSE);
 			}
 
 			/* move children DOWN if necessary and change the "_index" property */
-			if (tc->top_attach >= item_index) {
+			if (top_attach >= item_index) {
 				struct MoveChild *mc;
 				gint index;
 
 				mc = g_new (struct MoveChild, 1);
-				mc->widget = tc->widget;
-				mc->top_attach = tc->top_attach + 1;
+				mc->widget = child;
+				mc->top_attach = top_attach + 1;
 				to_move = g_list_append (to_move, mc);
 
-				index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tc->widget), "_index"));
+				index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (child), "_index"));
 				if (index > 0)
-					g_object_set_data (G_OBJECT (tc->widget), "_index", 
+					g_object_set_data (G_OBJECT (child), "_index",
 							   GINT_TO_POINTER (index + 1));
 			}
 		}
 	}
 	g_list_free (children);
 
-	
+
 	for (list = to_move; list; list = list->next) {
 		struct MoveChild *mc;
 
 		mc = (struct MoveChild *) (list->data);
-		gtk_container_child_set (GTK_CONTAINER (table), mc->widget, 
+		gtk_container_child_set (GTK_CONTAINER (table), mc->widget,
 					 "top-attach", mc->top_attach,
 					 "bottom-attach", mc->top_attach + 1, NULL);
 		g_free (list->data);
@@ -1004,46 +1010,53 @@ sequence_item_remove_cb (GdaServerOperation *op, const gchar *seq_path, gint ite
 	/* remove the widget associated to the sequence item */
 	children = gtk_container_get_children (GTK_CONTAINER (table));
 	for (list = children; list; ) {
-		GtkTableChild *tc = (GtkTableChild *) (list->data);
-
-		if (tc->widget && (tc->top_attach == item_index)) {
-			gtk_widget_destroy (tc->widget);
-			g_list_free (children);
-			children = gtk_container_get_children (GTK_CONTAINER (table));
-			list = children;
+		GtkWidget *child = GTK_WIDGET (list->data);
+		if (child) {
+			guint top_attach;
+			gtk_container_child_get (GTK_CONTAINER (table), child,
+						 "top-attach", &top_attach, NULL);
+			if (top_attach == item_index) {
+				gtk_widget_destroy (child);
+				g_list_free (children);
+				children = gtk_container_get_children (GTK_CONTAINER (table));
+				list = children;
+				continue;
+			}
 		}
-		else
-			list = list->next;
+		list = list->next;
 	}
 	g_list_free (children);
 
 	/* move children UP if necessary */
 	children = gtk_container_get_children (GTK_CONTAINER (table));
 	for (list = children; list; list = list->next) {
-		GtkTableChild *tc = (GtkTableChild *) (list->data);
-
-		if (tc->widget) {
+		GtkWidget *child = GTK_WIDGET (list->data);
+		if (child) {
+			guint top_attach, left_attach;
+			gtk_container_child_get (GTK_CONTAINER (table), child,
+						 "top-attach", &top_attach,
+						 "left-attach", &left_attach, NULL);
 			/* ADD/REMOVE button sensitivity */
-			if (tc->left_attach == 1) {
-				if (tc->top_attach == size)
-					gtk_widget_set_sensitive (tc->widget, TRUE);
+			if (left_attach == 1) {
+				if (top_attach == size)
+					gtk_widget_set_sensitive (child, TRUE);
 				else
-					gtk_widget_set_sensitive (tc->widget, (size-1 > min) ? TRUE : FALSE);
+					gtk_widget_set_sensitive (child, (size-1 > min) ? TRUE : FALSE);
 			}
 
 			/* move widgets UP if necessary and change the "_index" property */
-			if (tc->top_attach > item_index) {
+			if (top_attach > item_index) {
 				struct MoveChild *mc;
 				gint index;
-				
+
 				mc = g_new (struct MoveChild, 1);
-				mc->widget = tc->widget;
-				mc->top_attach = tc->top_attach - 1;
+				mc->widget = child;
+				mc->top_attach = top_attach - 1;
 				to_move = g_list_append (to_move, mc);
-				
-				index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tc->widget), "_index"));
+
+				index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (child), "_index"));
 				if (index > 0)
-					g_object_set_data (G_OBJECT (tc->widget), "_index", 
+					g_object_set_data (G_OBJECT (child), "_index",
 							   GINT_TO_POINTER (index - 1));
 			}
 		}
@@ -1054,7 +1067,7 @@ sequence_item_remove_cb (GdaServerOperation *op, const gchar *seq_path, gint ite
 		struct MoveChild *mc;
 
 		mc = (struct MoveChild *) (list->data);
-		gtk_container_child_set (GTK_CONTAINER (table), mc->widget, 
+		gtk_container_child_set (GTK_CONTAINER (table), mc->widget,
 					 "top-attach", mc->top_attach,
 					 "bottom-attach", mc->top_attach + 1, NULL);
 		g_free (list->data);
@@ -1081,10 +1094,12 @@ sequence_item_remove_cb (GdaServerOperation *op, const gchar *seq_path, gint ite
  * "form".
  *
  * Returns: the new #GtkDialog widget
+ *
+ * Since: 4.2
  */
 GtkWidget *
 gdaui_server_operation_new_in_dialog (GdaServerOperation *op, GtkWindow *parent,
-					 const gchar *title, const gchar *header)
+				      const gchar *title, const gchar *header)
 {
 	GtkWidget *form;
 	GtkWidget *dlg;
@@ -1092,11 +1107,11 @@ gdaui_server_operation_new_in_dialog (GdaServerOperation *op, GtkWindow *parent,
 	const gchar *rtitle;
 
 	form = gdaui_server_operation_new (op);
- 
+
 	rtitle = title;
 	if (!rtitle)
 		rtitle = _("Server operation specification");
-		
+
 	dlg = gtk_dialog_new_with_buttons (rtitle, parent,
 					   GTK_DIALOG_MODAL,
 					   GTK_STOCK_OK,
@@ -1132,10 +1147,10 @@ gdaui_server_operation_new_in_dialog (GdaServerOperation *op, GtkWindow *parent,
 /*
  * CREATE_TABLE "/FIELDS_A" Custom widgets rendering
  */
-static void create_table_grid_fields_iter_row_changed_cb (GdaDataModelIter *grid_iter, gint row, 
+static void create_table_grid_fields_iter_row_changed_cb (GdaDataModelIter *grid_iter, gint row,
 							  GdaDataModelIter *form_iter);
 static GtkWidget *
-create_table_fields_array_create_widget (GdauiServerOperation *form, const gchar *path, 
+create_table_fields_array_create_widget (GdauiServerOperation *form, const gchar *path,
 					 gchar **section_str, GSList **label_widgets)
 {
 	GdaServerOperationNode *info_node;
@@ -1144,12 +1159,11 @@ create_table_fields_array_create_widget (GdauiServerOperation *form, const gchar
 	GdaDataProxy *proxy;
 	gint name_col, col, nbcols;
 	GdaDataModelIter *grid_iter, *form_iter;
-		
+
 	info_node = gda_server_operation_get_node_info (form->priv->op, path);
 	g_assert (info_node->type == GDA_SERVER_OPERATION_NODE_DATA_MODEL);
 
 	hlayout = gtk_hpaned_new ();
-	gtk_widget_set_usize (hlayout, 800, 600);
 
 	/* form for field properties */
 	box = gtk_vbox_new (FALSE, 0);
@@ -1161,9 +1175,9 @@ create_table_fields_array_create_widget (GdauiServerOperation *form, const gchar
 	gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
 
 	form_props = gdaui_raw_form_new (GDA_DATA_MODEL (info_node->model));
-	proxy = gdaui_data_widget_get_proxy (GDAUI_DATA_WIDGET (form_props));
-	gdaui_data_widget_set_write_mode (GDAUI_DATA_WIDGET (form_props),
-					     GDAUI_DATA_WIDGET_WRITE_ON_VALUE_CHANGE);
+	proxy = gdaui_data_proxy_get_proxy (GDAUI_DATA_PROXY (form_props));
+	gdaui_data_proxy_set_write_mode (GDAUI_DATA_PROXY (form_props),
+					 GDAUI_DATA_PROXY_WRITE_ON_VALUE_CHANGE);
 	gtk_box_pack_start (GTK_BOX (box), form_props, TRUE, TRUE, 0);
 
 	gtk_widget_show_all (box);
@@ -1178,40 +1192,37 @@ create_table_fields_array_create_widget (GdauiServerOperation *form, const gchar
 	gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
 
 	sw = gtk_scrolled_window_new (NULL, NULL);
-	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), 
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
 					GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_NONE);
 
-	grid_fields = gdaui_raw_grid_new (GDA_DATA_MODEL(proxy));
+	grid_fields = gdaui_raw_grid_new (GDA_DATA_MODEL (proxy));
 	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (grid_fields), FALSE);
-	gtk_widget_set_usize (grid_fields, 300, 200);
-	g_object_set (G_OBJECT (grid_fields), "info-cell-visible", FALSE, NULL);	
+	g_object_set (G_OBJECT (grid_fields), "info-cell-visible", FALSE, NULL);
 
-	/*name_col = gda_data_model_get_column_index_by_name (GDA_DATA_MODEL (proxy), "rr");*/
 	name_col = 0;
 	nbcols = gda_data_proxy_get_proxied_model_n_cols (proxy);
 	g_assert (name_col < nbcols);
 	for (col = 0; col < name_col; col++)
-		gdaui_data_widget_column_hide (GDAUI_DATA_WIDGET (grid_fields), col);
+		gdaui_data_selector_set_column_visible (GDAUI_DATA_SELECTOR (grid_fields), col, FALSE);
 	for (col = name_col + 1; col < nbcols; col++)
-		gdaui_data_widget_column_hide (GDAUI_DATA_WIDGET (grid_fields), col);
+		gdaui_data_selector_set_column_visible (GDAUI_DATA_SELECTOR (grid_fields), col, FALSE);
 
 	gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sw), grid_fields);
-	gtk_viewport_set_shadow_type (GTK_VIEWPORT (gtk_bin_get_child (GTK_BIN (sw))), 
+	gtk_viewport_set_shadow_type (GTK_VIEWPORT (gtk_bin_get_child (GTK_BIN (sw))),
 				      GTK_SHADOW_NONE);
 	gtk_box_pack_start (GTK_BOX (box), sw, TRUE, TRUE, 0);
 
 	/* buttons to add/remove fields */
-	winfo = gdaui_data_widget_info_new (GDAUI_DATA_WIDGET (form_props), 
-					       GDAUI_DATA_WIDGET_INFO_ROW_MODIFY_BUTTONS);
-
+	winfo = gdaui_data_proxy_info_new (GDAUI_DATA_PROXY (form_props),
+					   GDAUI_DATA_PROXY_INFO_ROW_MODIFY_BUTTONS);
 	gtk_box_pack_start (GTK_BOX (box), winfo, FALSE, FALSE, 0);
 
 	gtk_widget_show_all (box);
 
 	/* keep the selections in sync */
-	grid_iter = gdaui_data_widget_get_current_data (GDAUI_DATA_WIDGET (grid_fields));
-	form_iter = gdaui_data_widget_get_current_data (GDAUI_DATA_WIDGET (form_props));
+	grid_iter = gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (grid_fields));
+	form_iter = gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (form_props));
 	g_signal_connect (grid_iter, "row_changed",
 			  G_CALLBACK (create_table_grid_fields_iter_row_changed_cb), form_iter);
 	g_signal_connect (form_iter, "row_changed",
@@ -1222,7 +1233,7 @@ create_table_fields_array_create_widget (GdauiServerOperation *form, const gchar
 	{
 		GtkActionGroup *group;
 		GtkAction *action;
-		group = gdaui_data_widget_get_actions_group (GDAUI_DATA_WIDGET (form_props));
+		group = gdaui_data_proxy_get_actions_group (GDAUI_DATA_PROXY (form_props));
 		action = gtk_action_group_get_action (group, "ActionNew");
 		g_object_set (G_OBJECT (action), "tooltip", _("Add a new field"), NULL);
 		action = gtk_action_group_get_action (group, "ActionDelete");
diff --git a/libgda-ui/gdaui-set.c b/libgda-ui/gdaui-set.c
index 11a70ee..7b65a0b 100644
--- a/libgda-ui/gdaui-set.c
+++ b/libgda-ui/gdaui-set.c
@@ -67,7 +67,7 @@ enum {
 static gint gdaui_set_signals[LAST_SIGNAL] = { 0 };
 
 GType
-gdaui_set_get_type (void)
+_gdaui_set_get_type (void)
 {
 	static GType type = 0;
 
@@ -131,8 +131,8 @@ gdaui_set_init (GdauiSet *set)
 	set->priv->set = NULL;
 }
 
-/**
- * gdaui_set_new
+/*
+ * _gdaui_set_new
  * @set: a #GdaSet
  *
  * Creates a new #GdauiSet which wraps @set's properties
@@ -140,7 +140,7 @@ gdaui_set_init (GdauiSet *set)
  *  Returns: the new widget
  */
 GdauiSet *
-gdaui_set_new (GdaSet *set)
+_gdaui_set_new (GdaSet *set)
 {
 	g_return_val_if_fail (GDA_IS_SET (set), NULL);
 
@@ -381,7 +381,7 @@ gdaui_set_get_property (GObject *object,
 	}	
 }
 
-/**
+/*
  * _gdaui_set_get_group
  */
 GdauiSetGroup  *
diff --git a/libgda-ui/gdaui-set.h b/libgda-ui/gdaui-set.h
index 6823976..705e7e9 100644
--- a/libgda-ui/gdaui-set.h
+++ b/libgda-ui/gdaui-set.h
@@ -26,10 +26,10 @@
 
 G_BEGIN_DECLS
 
-#define GDAUI_TYPE_SET          (gdaui_set_get_type())
-#define GDAUI_SET(obj)          G_TYPE_CHECK_INSTANCE_CAST (obj, gdaui_set_get_type(), GdauiSet)
-#define GDAUI_SET_CLASS(klass)  G_TYPE_CHECK_CLASS_CAST (klass, gdaui_set_get_type (), GdauiSetClass)
-#define GDAUI_IS_SET(obj)       G_TYPE_CHECK_INSTANCE_TYPE (obj, gdaui_set_get_type ())
+#define GDAUI_TYPE_SET          (_gdaui_set_get_type())
+#define GDAUI_SET(obj)          G_TYPE_CHECK_INSTANCE_CAST (obj, _gdaui_set_get_type(), GdauiSet)
+#define GDAUI_SET_CLASS(klass)  G_TYPE_CHECK_CLASS_CAST (klass, _gdaui_set_get_type (), GdauiSetClass)
+#define GDAUI_IS_SET(obj)       G_TYPE_CHECK_INSTANCE_TYPE (obj, _gdaui_set_get_type ())
 
 
 typedef struct _GdauiSet      GdauiSet;
@@ -93,9 +93,9 @@ struct _GdauiSetClass
 /* 
  * Generic widget's methods 
  */
-GType             gdaui_set_get_type            (void) G_GNUC_CONST;
+GType             _gdaui_set_get_type            (void) G_GNUC_CONST;
 
-GdauiSet         *gdaui_set_new                 (GdaSet *set);
+GdauiSet         *_gdaui_set_new                 (GdaSet *set);
 GdauiSetGroup    *_gdaui_set_get_group          (GdauiSet *dbset, GdaHolder *holder);
 
 G_END_DECLS
diff --git a/libgda-ui/internal/gdaui-dsn-selector.c b/libgda-ui/internal/gdaui-dsn-selector.c
index ba506a2..302dbce 100644
--- a/libgda-ui/internal/gdaui-dsn-selector.c
+++ b/libgda-ui/internal/gdaui-dsn-selector.c
@@ -119,7 +119,7 @@ gdaui_dsn_selector_set_property (GObject *object,
 	switch (param_id) {
 	case PROP_SOURCE_NAME:
 		list = g_slist_append (NULL, (gpointer) value);
-		gdaui_combo_set_values_ext (GDAUI_COMBO (selector), list, cols_index);
+		_gdaui_combo_set_selected_ext (GDAUI_COMBO (selector), list, cols_index);
 		g_slist_free (list);
 		break;
 	}
@@ -138,7 +138,7 @@ gdaui_dsn_selector_get_property (GObject *object,
 
 	switch (param_id) {
 	case PROP_SOURCE_NAME:
-		list = gdaui_combo_get_values_ext (GDAUI_COMBO (selector), 1, cols_index);
+		list = _gdaui_combo_get_selected_ext (GDAUI_COMBO (selector), 1, cols_index);
 		if (list && list->data) {
 			g_value_set_string (value, g_value_get_string ((GValue*) list->data));
 			g_slist_free (list);
diff --git a/libgda-ui/internal/utility.c b/libgda-ui/internal/utility.c
index 097ad63..90ec629 100644
--- a/libgda-ui/internal/utility.c
+++ b/libgda-ui/internal/utility.c
@@ -384,7 +384,7 @@ _gdaui_utility_proxy_compute_values_for_group (GdauiSetGroup *group, GdauiDataSt
  * Errors reporting
  */
 static GtkWidget *
-create_data_error_dialog (GdauiDataWidget *form, gboolean with_question, gboolean can_discard, GError *filled_error)
+create_data_error_dialog (GdauiDataProxy *form, gboolean with_question, gboolean can_discard, GError *filled_error)
 {
 	GtkWidget *dlg;
 	const gchar *msg1 = NULL, *msg2 = NULL;
@@ -464,7 +464,7 @@ create_data_error_dialog (GdauiDataWidget *form, gboolean with_question, gboolea
  * Returns: TRUE if current data can be discarded
  */
 gboolean
-_gdaui_utility_display_error_with_keep_or_discard_choice (GdauiDataWidget *form, GError *filled_error)
+_gdaui_utility_display_error_with_keep_or_discard_choice (GdauiDataProxy *form, GError *filled_error)
 {
 	GtkWidget *dlg;
 	gint res;
@@ -491,7 +491,7 @@ _gdaui_utility_display_error_with_keep_or_discard_choice (GdauiDataWidget *form,
  * led to the error.
  */
 void
-_gdaui_utility_display_error (GdauiDataWidget *form, gboolean can_discard, GError *filled_error)
+_gdaui_utility_display_error (GdauiDataProxy *form, gboolean can_discard, GError *filled_error)
 {
 	GtkWidget *dlg;
 	
diff --git a/libgda-ui/internal/utility.h b/libgda-ui/internal/utility.h
index 28c2763..7479bc6 100644
--- a/libgda-ui/internal/utility.h
+++ b/libgda-ui/internal/utility.h
@@ -23,7 +23,7 @@
 #include <libgda-ui/gdaui-data-entry.h>
 #include <libgda-ui/gdaui-data-store.h>
 #include <libgda-ui/gdaui-set.h>
-#include <libgda-ui/gdaui-data-widget.h>
+#include <libgda-ui/gdaui-data-proxy.h>
 
 /*
  *
@@ -48,9 +48,9 @@ GList           *_gdaui_utility_proxy_compute_values_for_group     (GdauiSetGrou
 								    GtkTreeIter *tree_iter, gboolean model_values);
 
 /*
- * Some dialogs used by GnomeDbDataWidget widgets
+ * Some dialogs used by GnomeDbDataProxy widgets
  */
-gboolean         _gdaui_utility_display_error_with_keep_or_discard_choice (GdauiDataWidget *form, GError *filled_error);
-void             _gdaui_utility_display_error                             (GdauiDataWidget *form, gboolean can_discard, GError *filled_error);
+gboolean         _gdaui_utility_display_error_with_keep_or_discard_choice (GdauiDataProxy *form, GError *filled_error);
+void             _gdaui_utility_display_error                             (GdauiDataProxy *form, gboolean can_discard, GError *filled_error);
 void             _gdaui_utility_show_error (GtkWindow *parent, const gchar *format, ...);
 
diff --git a/libgda-ui/libgda-ui.h b/libgda-ui/libgda-ui.h
index cb9c3c7..eb783d7 100644
--- a/libgda-ui/libgda-ui.h
+++ b/libgda-ui/libgda-ui.h
@@ -29,25 +29,25 @@
 #include <libgda-ui/gdaui-basic-form.h>
 #include <libgda-ui/gdaui-combo.h>
 #include <libgda-ui/gdaui-data-store.h>
-#include <libgda-ui/gdaui-data-widget-filter.h>
-#include <libgda-ui/gdaui-data-widget.h>
+#include <libgda-ui/gdaui-data-filter.h>
+#include <libgda-ui/gdaui-data-proxy.h>
 #include <libgda-ui/gdaui-easy.h>
 #include <libgda-ui/gdaui-enums.h>
 #include <libgda-ui/gdaui-raw-form.h>
 #include <libgda-ui/gdaui-form.h>
-#include <libgda-ui/gdaui-set.h>
 #include <libgda-ui/gdaui-raw-grid.h>
 #include <libgda-ui/gdaui-grid.h>
-#include <libgda-ui/gdaui-data-widget-info.h>
+#include <libgda-ui/gdaui-data-proxy-info.h>
 #include <libgda-ui/gdaui-provider-selector.h>
 #include <libgda-ui/gdaui-server-operation.h>
 #include <libgda-ui/gdaui-login.h>
 #include <libgda-ui/gdaui-tree-store.h>
 #include <libgda-ui/gdaui-cloud.h>
+#include <libgda-ui/gdaui-data-selector.h>
 
 G_BEGIN_DECLS
 
-void             gdaui_init (void);
+void gdaui_init (void);
 
 G_END_DECLS
 
diff --git a/libgda-ui/libgda-ui.symbols b/libgda-ui/libgda-ui.symbols
index 6fa6bc5..c57bc4d 100644
--- a/libgda-ui/libgda-ui.symbols
+++ b/libgda-ui/libgda-ui.symbols
@@ -17,21 +17,16 @@
 	gdaui_basic_form_set_entries_to_default
 	gdaui_cloud_create_filter_widget
 	gdaui_cloud_filter
-	gdaui_cloud_get_selection
 	gdaui_cloud_get_type
 	gdaui_cloud_new
 	gdaui_cloud_set_selection_mode
-	gdaui_combo_add_undef_choice
-	gdaui_combo_get_model
+	gdaui_cloud_set_weight_func
+	gdaui_combo_add_null
 	gdaui_combo_get_type
-	gdaui_combo_get_values
-	gdaui_combo_get_values_ext
 	gdaui_combo_new
 	gdaui_combo_new_with_model
 	gdaui_combo_set_model
-	gdaui_combo_set_values
-	gdaui_combo_set_values_ext
-	gdaui_combo_undef_selected
+	gdaui_combo_is_null_selected
 	gdaui_data_cell_renderer_boolean_get_type
 	gdaui_data_cell_renderer_boolean_new
 	gdaui_data_cell_renderer_combo_get_type
diff --git a/libgda/gda-data-model-iter.c b/libgda/gda-data-model-iter.c
index c699e02..7a3c001 100644
--- a/libgda/gda-data-model-iter.c
+++ b/libgda/gda-data-model-iter.c
@@ -589,14 +589,37 @@ gda_data_model_iter_move_to_row (GdaDataModelIter *iter, gint row)
 		    (gda_data_model_iter_get_row (iter) != row) && 
 		    ! gda_set_is_valid ((GdaSet*) iter, NULL))
 			return FALSE;
-		
+
+		gboolean *null_oks = NULL;
+		if (GDA_SET (iter)->holders) {
+			gint i;
+			GSList *list;
+
+			null_oks = g_new (gboolean, g_slist_length (GDA_SET (iter)->holders));
+			for (i = 0, list = GDA_SET (iter)->holders; list; i++, list = list->next) {
+				null_oks[i] = gda_holder_get_not_null ((GdaHolder*) list->data);
+				gda_holder_set_not_null ((GdaHolder*) list->data, FALSE);
+			}
+		}
+
+		gboolean move_ok;
 		model = iter->priv->data_model;
 		if (GDA_DATA_MODEL_GET_CLASS (model)->i_iter_at_row)
-			return (GDA_DATA_MODEL_GET_CLASS (model)->i_iter_at_row) (model, iter, row);
+			move_ok = (GDA_DATA_MODEL_GET_CLASS (model)->i_iter_at_row) (model, iter, row);
 		else {
 			/* default method */
-			return gda_data_model_iter_move_to_row_default (model, iter, row);
+			move_ok = gda_data_model_iter_move_to_row_default (model, iter, row);
+		}
+		
+		if (null_oks) {
+			gint i;
+			GSList *list;
+			for (i = 0, list = GDA_SET (iter)->holders; list; i++, list = list->next)
+				gda_holder_set_not_null ((GdaHolder*) list->data, null_oks[i]);
+			g_free (null_oks);
 		}
+		
+		return move_ok;
 	}
 }
 
@@ -860,7 +883,8 @@ gda_data_model_iter_get_row (GdaDataModelIter *iter)
  *
  * Declare all the parameters in @iter invalid, without modifying the
  * #GdaDataModel @iter is for or changing the row it represents. This method
- * is for internal usage.
+ * is for internal usage. Note that for gda_data_model_iter_is_valid() to return %FALSE,
+ * it is also necessary to set the "current-row" property to -1.
  */
 void
 gda_data_model_iter_invalidate_contents (GdaDataModelIter *iter)
diff --git a/libgda/gda-data-model.c b/libgda/gda-data-model.c
index ee8cb4c..b1467ef 100644
--- a/libgda/gda-data-model.c
+++ b/libgda/gda-data-model.c
@@ -61,7 +61,7 @@ enum {
 	LAST_SIGNAL
 };
 
-static guint gda_data_model_signals[LAST_SIGNAL];
+static guint gda_data_model_signals[LAST_SIGNAL] = {0, 0, 0, 0, 0};
 
 /* module error */
 GQuark gda_data_model_error_quark (void)
@@ -250,7 +250,6 @@ gda_data_model_row_inserted (GdaDataModel *model, gint row)
 		g_signal_emit (G_OBJECT (model),
 			       gda_data_model_signals[ROW_INSERTED],
 			       0, row);
-
 		_gda_data_model_signal_emit_changed (model);
 	}
 }
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 0491e60..3ae6f91 100755
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -115,8 +115,8 @@ libgda-ui/gdaui-basic-form.c
 libgda-ui/gdaui-cloud.c
 libgda-ui/gdaui-combo.c
 libgda-ui/gdaui-data-store.c
-libgda-ui/gdaui-data-widget.c
-libgda-ui/gdaui-data-widget-filter.c
+libgda-ui/gdaui-data-proxy.c
+libgda-ui/gdaui-data-filter.c
 libgda-ui/gdaui-init.c
 libgda-ui/gdaui-login.c
 libgda-ui/gdaui-raw-form.c
diff --git a/providers/web/gda-web-recordset.c b/providers/web/gda-web-recordset.c
index a321fa4..a685644 100644
--- a/providers/web/gda-web-recordset.c
+++ b/providers/web/gda-web-recordset.c
@@ -434,7 +434,8 @@ gda_web_recordset_store (GdaWebRecordset *rs, xmlNodePtr data_node, GError **err
 
 		column = gda_data_model_describe_column ((GdaDataModel*) rs, i);
 		i++;
-		xmlSetProp (node, BAD_CAST "gdatype", gda_g_type_to_string (gda_column_get_g_type (column)));
+		xmlSetProp (node, BAD_CAST "gdatype",
+			    BAD_CAST gda_g_type_to_string (gda_column_get_g_type (column)));
 	}
 
 	/* for each row in @data_mode, insert the row in @rs->priv->rs_cnc */
diff --git a/testing/gdaui-test-data-entries.c b/testing/gdaui-test-data-entries.c
index 1684b12..57e76e5 100644
--- a/testing/gdaui-test-data-entries.c
+++ b/testing/gdaui-test-data-entries.c
@@ -938,19 +938,16 @@ build_form_test_for_gtype (GdaDataHandler *dh, GType type, const gchar *plugin_n
 	if (model) {
 		GdaSet *plist;
 		GdaHolder *param;
-		GdauiDataWidget *datawid;
 		GValue *value;
 
 		wid = gdaui_form_new (model);
-		g_object_get (G_OBJECT (wid), "raw-form", &datawid, NULL);
-		g_object_set (G_OBJECT (datawid), "show-actions", TRUE, NULL);
-		plist = GDA_SET (gdaui_data_widget_get_current_data (GDAUI_DATA_WIDGET (datawid)));
+		plist = GDA_SET (gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (wid)));
+		gdaui_data_proxy_column_show_actions (GDAUI_DATA_PROXY (wid), -1, TRUE);
 		param = plist->holders->data;
 
 		value = gda_value_new_from_string (plugin_name, G_TYPE_STRING);
 		gda_holder_set_attribute_static (param, GDAUI_ATTRIBUTE_PLUGIN, value);
 		gda_value_free (value);
-		g_object_unref (datawid);
 	}
 	else {
 		gchar *str;
@@ -974,19 +971,16 @@ build_grid_test_for_gtype (GdaDataHandler *dh, GType type, const gchar *plugin_n
 	if (model) {
 		GdaSet *plist;
 		GdaHolder *param;
-		GdauiDataWidget *datawid;
 		GValue *value;
 		
 		wid = gdaui_grid_new (model);
-		g_object_get (G_OBJECT (wid), "raw-grid", &datawid, NULL);
-		g_object_set (G_OBJECT (datawid), "info-cell-visible", TRUE, NULL);
-		plist = GDA_SET (gdaui_data_widget_get_current_data (GDAUI_DATA_WIDGET (datawid)));
+		plist = GDA_SET (gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (wid)));
+		gdaui_data_proxy_column_show_actions (GDAUI_DATA_PROXY (wid), -1, TRUE);
 		param = plist->holders->data;
 
 		value = gda_value_new_from_string (plugin_name, G_TYPE_STRING);
 		gda_holder_set_attribute_static (param, GDAUI_ATTRIBUTE_PLUGIN, value);
 		gda_value_free (value);
-		g_object_unref (datawid);
 	}
 	else {
 		gchar *str;
diff --git a/tools/browser/common/gdaui-data-import.c b/tools/browser/common/gdaui-data-import.c
index 1cb62bd..ac27544 100644
--- a/tools/browser/common/gdaui-data-import.c
+++ b/tools/browser/common/gdaui-data-import.c
@@ -25,7 +25,9 @@
 #include <libgda-ui/gdaui-combo.h>
 #include <libgda-ui/gdaui-grid.h>
 #include <libgda-ui/gdaui-raw-grid.h>
-#include <libgda-ui/gdaui-data-widget-info.h>
+#include <libgda-ui/gdaui-data-proxy.h>
+#include <libgda-ui/gdaui-data-proxy-info.h>
+#include <libgda-ui/gdaui-data-selector.h>
 #include <libgda/binreloc/gda-binreloc.h>
 
 static void gdaui_data_import_class_init (GdauiDataImportClass *class);
@@ -381,17 +383,16 @@ spec_changed_cb (GtkWidget *wid, GdauiDataImport *import)
 	}
 
 	if (import->priv->encoding_combo) {
-		GSList *values;
-
-		values = gdaui_combo_get_values (GDAUI_COMBO (import->priv->encoding_combo));
-		if (values) {
+		GdaDataModelIter *iter;
+		
+		iter = gdaui_data_selector_get_data_set (GDAUI_DATA_SELECTOR (import->priv->encoding_combo));;
+		if (iter) {
 			GdaHolder *h;
 			h = g_object_new (GDA_TYPE_HOLDER, "id", "ENCODING", "g-type", G_TYPE_STRING, NULL);
 			
-			gda_holder_set_value (h, (GValue *) values->data, NULL);
+			gda_holder_set_value (h, (GValue *) gda_data_model_iter_get_value_at (iter, 0), NULL);
 			gda_set_add_holder (options, h);
 			g_object_unref (h);
-			g_slist_free (values);
 		}
 	}
 
@@ -412,21 +413,14 @@ spec_changed_cb (GtkWidget *wid, GdauiDataImport *import)
 		g_object_unref (options);
 
 	if (import->priv->model) {
-		GObject *raw;
-		GObject *info;
-
 		gtk_widget_hide (import->priv->no_data_label);
 		import->priv->preview_grid = gdaui_grid_new (import->priv->model);
 
-		g_object_get (G_OBJECT (import->priv->preview_grid), "raw-grid", &raw, 
-			      "widget-info", &info, NULL);
-		g_object_set (raw, "info-cell-visible", FALSE, NULL);
-		gdaui_raw_grid_set_sample_size (GDAUI_RAW_GRID (raw), 50);
-		g_object_set (info, "flags", 
-			      GDAUI_DATA_WIDGET_INFO_CHUNCK_CHANGE_BUTTONS | 
-			      GDAUI_DATA_WIDGET_INFO_CURRENT_ROW, NULL);
-		g_object_unref (info);
-
+		gdaui_data_proxy_column_show_actions (GDAUI_DATA_PROXY (import->priv->preview_grid), -1, FALSE);
+		gdaui_grid_set_sample_size (GDAUI_GRID (import->priv->preview_grid), 50);
+		g_object_set (G_OBJECT (import->priv->preview_grid), "info-flags",
+			      GDAUI_DATA_PROXY_INFO_CHUNCK_CHANGE_BUTTONS | 
+			      GDAUI_DATA_PROXY_INFO_CURRENT_ROW, NULL);
 		gtk_box_pack_start (GTK_BOX (import->priv->preview_box), import->priv->preview_grid, TRUE, TRUE, 0);
 		gtk_widget_show (import->priv->preview_grid);
 	}
diff --git a/tools/browser/query-exec/query-result.c b/tools/browser/query-exec/query-result.c
index 970d229..36bd887 100644
--- a/tools/browser/query-exec/query-result.c
+++ b/tools/browser/query-exec/query-result.c
@@ -333,6 +333,9 @@ make_widget_for_data_model (GdaDataModel *model)
 	GtkWidget *grid;
 	grid = gdaui_grid_new (model);
 	gdaui_grid_set_sample_size (GDAUI_GRID (grid), 300);
+	g_object_set (G_OBJECT (grid), "info-flags",
+		      GDAUI_DATA_PROXY_INFO_CHUNCK_CHANGE_BUTTONS | 
+		      GDAUI_DATA_PROXY_INFO_CURRENT_ROW, NULL);
 	return grid;
 }
 



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