[gnome-db] libgnomedb usability patch



Hey guys,

(hope you had a nice xmas)

I found some time to improve a bit libgnomedb's usability.

The attached patch does the following:

- main dialog: increased initial size (to view at least 4 dsn), center
the window;

- main menu: auto-sensitive items, removed 'preferences', moved
'properties' to 'file', added 'select all', 'clear selection' in 'edit'
and introduced 'view' (for notebook switching), added meaningful
keyboard shortcuts;

- alert boxes are HIG compliant;

- fixed capitalization and missing final dot in several UI elements;

- added mnemonics to all UI elements I could find;

- improved the dsn popup menu (added 'properties' and 'delete' options),
 replaced show/hide column titles options with a single check menu item,
added separators;

- dsn properties dialog: instant apply [1], added a 'revert' button;

- save model dialog: replaced the radio buttons with an option menu,
replaced 'ok' button with an auto-sensible 'save' button;

- etc... (several less-important changes);

I will try to write a ChangeLog entry asap. Within the meantime please
apply locally the patch and test gnome-database-properties. Tell me what
do you think about it!

Cheers,

--
Laurent

[1]: with the current instant apply implementation, it is not possible
to change the name of a data source, so the dsn text field is at the
moment read-only.  BTW I don't know if the implementation I provided is
the good way to do it (nevertheless it seems to work pretty well).
Index: control-center/database-capplet.c
===================================================================
RCS file: /cvs/gnome/libgnomedb/control-center/database-capplet.c,v
retrieving revision 1.6
diff -u -r1.6 database-capplet.c
--- control-center/database-capplet.c	6 Jul 2003 19:25:33 -0000	1.6
+++ control-center/database-capplet.c	27 Dec 2003 15:17:48 -0000
@@ -28,9 +28,6 @@
 #include "dsn-config.h"
 #include "provider-config.h"
 
-#define DSN_PAGE      "DSN_Page"
-#define PROVIDER_PAGE "Provider_Page"
-
 /*
  * Public functions
  */
@@ -94,3 +91,82 @@
 	if (current_widget == dsn)
 		dsn_config_edit_properties (dsn);
 }
+
+void
+database_capplet_select_all (GtkWidget *capplet)
+{
+	GtkWidget *dsn, *provider, *current_widget;
+	gint current;
+
+	dsn = g_object_get_data (G_OBJECT (capplet), DSN_PAGE);
+	provider = g_object_get_data (G_OBJECT (capplet), PROVIDER_PAGE);
+
+	current = gtk_notebook_get_current_page (GTK_NOTEBOOK (capplet));
+	if (current == -1)
+		return;
+
+	current_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (capplet), current);
+	if (current_widget == dsn)
+		dsn_config_select_all (dsn);
+	else
+		if (current_widget == provider)
+			provider_config_select_all (provider);
+}
+
+void
+database_capplet_deselect_all (GtkWidget *capplet)
+{
+	GtkWidget *dsn, *provider, *current_widget;
+	gint current;
+
+	dsn = g_object_get_data (G_OBJECT (capplet), DSN_PAGE);
+	provider = g_object_get_data (G_OBJECT (capplet), PROVIDER_PAGE);
+
+	current = gtk_notebook_get_current_page (GTK_NOTEBOOK (capplet));
+	if (current == -1)
+		return;
+
+	current_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (capplet), current);
+	if (current_widget == dsn)
+		dsn_config_unselect_all (dsn);
+	else
+		if (current_widget == provider)
+			provider_config_unselect_all (provider);
+}
+
+gboolean
+database_capplet_has_selection (GtkWidget *capplet)
+{
+	GtkWidget *dsn, *provider, *current_widget;
+	gint current;
+
+	dsn = g_object_get_data (G_OBJECT (capplet), DSN_PAGE);
+	provider = g_object_get_data (G_OBJECT (capplet), PROVIDER_PAGE);
+
+	current = gtk_notebook_get_current_page (GTK_NOTEBOOK (capplet));
+	if (current == -1)
+		return FALSE;
+
+	current_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (capplet), current);
+	if (current_widget == dsn)
+		return dsn_config_has_selection (dsn);
+	else
+		if (current_widget == provider)
+			return provider_config_has_selection (provider);
+	return FALSE;
+}
+
+void
+database_capplet_switch (GtkWidget *capplet, const gchar *page)
+{
+	GtkWidget *notebook_page;
+	gint num;
+	
+	notebook_page = g_object_get_data (G_OBJECT (capplet), page);
+	g_return_if_fail (GTK_IS_WIDGET (notebook_page));
+	
+	num = gtk_notebook_page_num (GTK_NOTEBOOK (capplet), notebook_page);
+	g_return_if_fail (num != -1);
+
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (capplet), num);
+}
Index: control-center/database-capplet.h
===================================================================
RCS file: /cvs/gnome/libgnomedb/control-center/database-capplet.h,v
retrieving revision 1.2
diff -u -r1.2 database-capplet.h
--- control-center/database-capplet.h	6 Jul 2003 19:25:33 -0000	1.2
+++ control-center/database-capplet.h	27 Dec 2003 15:17:48 -0000
@@ -24,8 +24,15 @@
 
 #include <gtk/gtkwidget.h>
 
+#define DSN_PAGE      "DSN_Page"
+#define PROVIDER_PAGE "Provider_Page"
+
 GtkWidget *database_capplet_new (void);
 void       database_capplet_edit_properties (GtkWidget *capplet);
 void       database_capplet_delete (GtkWidget *capplet);
+void       database_capplet_select_all (GtkWidget *capplet);
+void       database_capplet_deselect_all (GtkWidget *capplet);
+gboolean   database_capplet_has_selection (GtkWidget *capplet);
+void       database_capplet_switch (GtkWidget *capplet, const gchar *page);
 
 #endif
Index: control-center/dsn-config.c
===================================================================
RCS file: /cvs/gnome/libgnomedb/control-center/dsn-config.c,v
retrieving revision 1.28
diff -u -r1.28 dsn-config.c
--- control-center/dsn-config.c	11 Oct 2003 12:56:55 -0000	1.28
+++ control-center/dsn-config.c	27 Dec 2003 15:17:49 -0000
@@ -108,6 +108,43 @@
 	dsn_config_edit_properties (GTK_WIDGET (user_data));
 }
 
+static void
+list_popup_properties_cb (GtkWidget *menu, gpointer user_data)
+{
+	dsn_config_edit_properties (GTK_WIDGET (user_data));
+}
+
+static void
+list_popup_delete_cb (GtkWidget *menu, gpointer user_data)
+{
+	dsn_config_delete (GTK_WIDGET (user_data));
+}
+
+static void
+list_popup_cb (GnomeDbGrid *grid, GtkMenu *menu, gpointer user_data)
+{
+	GtkWidget *item_delete, *item_properties;
+	gboolean ok;
+
+	item_delete = gnome_db_new_menu_item (GTK_STOCK_DELETE,
+					      TRUE,
+					      G_CALLBACK (list_popup_delete_cb),
+					      user_data);
+	item_properties = gnome_db_new_menu_item (GTK_STOCK_PROPERTIES,
+						  TRUE,
+						  G_CALLBACK (list_popup_properties_cb),
+						  user_data);
+
+	ok = gnome_db_grid_get_selection (grid) != NULL;
+	gtk_widget_set_sensitive (item_delete, ok);
+	gtk_widget_set_sensitive (item_properties, ok);
+
+	gtk_menu_prepend (menu, gtk_separator_menu_item_new ());
+	gtk_menu_prepend (menu, item_delete);
+	gtk_menu_prepend (menu, gtk_separator_menu_item_new ());
+	gtk_menu_prepend (menu, item_properties);
+}
+
 /*
  * Public functions
  */
@@ -152,6 +189,8 @@
 	gtk_widget_show (priv->dsn_list);
 	g_signal_connect (G_OBJECT (priv->dsn_list), "double_clicked",
 			  G_CALLBACK (list_double_clicked_cb), dsn);
+	g_signal_connect (G_OBJECT (priv->dsn_list), "create_popup_menu",
+			  G_CALLBACK (list_popup_cb), dsn);
 	gtk_table_attach (GTK_TABLE (table), priv->dsn_list, 0, 1, 0, 1,
 			  GTK_FILL | GTK_SHRINK | GTK_EXPAND,
 			  GTK_FILL | GTK_SHRINK | GTK_EXPAND,
@@ -217,26 +256,52 @@
 static void
 foreach_remove_cb (GnomeDbGrid *grid, gint row, gpointer user_data)
 {
+	DsnConfigPrivate *priv;
 	GdaDataModel *model;
+	GtkWidget *dialog;
+	GtkWidget *button;
 	gchar *str;
-	DsnConfigPrivate *priv = (DsnConfigPrivate *) user_data;
+	gchar *dsn;
 
+	priv = (DsnConfigPrivate *) user_data;
 	model = gnome_db_grid_get_model (GNOME_DB_GRID (priv->dsn_list));
 	if (!GDA_IS_DATA_MODEL (model))
 		return;
 
-	str = gda_value_stringify (
+	dsn = gda_value_stringify (
 		(GdaValue *) gda_data_model_get_value_at (model, 0, row));
-	if (!str)
+	if (dsn == NULL)
 		return;
 
-	if (gnome_db_yes_no_dialog (
-		    gtk_widget_get_toplevel (priv->dsn_list),
-		    _("Do you want to remove '%s' data source?"),
-		    str)) {
-		gnome_db_config_remove_data_source (str);
-	}
-
+	str = g_strdup_printf (
+		_("Are you sure you want to remove the data source '%s'?"),
+		dsn);
+
+	dialog = gnome_db_new_alert (
+		GTK_WINDOW (gtk_widget_get_toplevel (priv->dsn_list)),
+		GTK_MESSAGE_QUESTION,
+		str,
+		NULL);
+		
+	button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+	GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+	gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
+				      button,
+				      GTK_RESPONSE_CANCEL);
+	button = gtk_button_new_from_stock (GTK_STOCK_DELETE);
+	gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
+				      button,
+				      GTK_RESPONSE_OK);
+	gtk_dialog_set_default_response (GTK_DIALOG (dialog),
+					 GTK_RESPONSE_CANCEL);
+	
+	gtk_widget_show_all (dialog);
+	if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) 
+		gnome_db_config_remove_data_source (dsn);
+
+	/* free memory */
+	gtk_widget_destroy (dialog);
+	g_free (dsn);
 	g_free (str);
 }
 
@@ -250,3 +315,30 @@
 					(GnomeDbGridForeachFunc) foreach_remove_cb,
 					priv);
 }
+
+void
+dsn_config_select_all (GtkWidget *dsn)
+{
+	DsnConfigPrivate *priv;
+
+	priv = g_object_get_data (G_OBJECT (dsn), DSN_CONFIG_DATA);
+	gnome_db_grid_select_all (GNOME_DB_GRID (priv->dsn_list));	
+}
+
+void
+dsn_config_unselect_all (GtkWidget *dsn)
+{
+	DsnConfigPrivate *priv;
+
+	priv = g_object_get_data (G_OBJECT (dsn), DSN_CONFIG_DATA);
+	gnome_db_grid_unselect_all (GNOME_DB_GRID (priv->dsn_list));	
+}
+
+gboolean
+dsn_config_has_selection (GtkWidget *dsn)
+{
+	DsnConfigPrivate *priv;
+
+	priv = g_object_get_data (G_OBJECT (dsn), DSN_CONFIG_DATA);
+	return gnome_db_grid_get_selection (GNOME_DB_GRID (priv->dsn_list)) != NULL;
+}
Index: control-center/dsn-config.h
===================================================================
RCS file: /cvs/gnome/libgnomedb/control-center/dsn-config.h,v
retrieving revision 1.2
diff -u -r1.2 dsn-config.h
--- control-center/dsn-config.h	6 Jul 2003 19:25:33 -0000	1.2
+++ control-center/dsn-config.h	27 Dec 2003 15:17:49 -0000
@@ -27,5 +27,8 @@
 GtkWidget *dsn_config_new (void);
 void       dsn_config_edit_properties (GtkWidget *dsn);
 void       dsn_config_delete (GtkWidget *dsn);
+void       dsn_config_select_all (GtkWidget *dsn);
+void       dsn_config_unselect_all (GtkWidget *dsn);
+gboolean   dsn_config_has_selection (GtkWidget *dsn);
 
 #endif
Index: control-center/dsn-properties-dialog.c
===================================================================
RCS file: /cvs/gnome/libgnomedb/control-center/dsn-properties-dialog.c,v
retrieving revision 1.5
diff -u -r1.5 dsn-properties-dialog.c
--- control-center/dsn-properties-dialog.c	3 Sep 2003 10:49:14 -0000	1.5
+++ control-center/dsn-properties-dialog.c	27 Dec 2003 15:17:49 -0000
@@ -32,10 +32,33 @@
 #include <libgnomedb/utils.h>
 #include "dsn-properties-dialog.h"
 
+enum {
+	REVERT_BUTTON
+};
+
+static void
+save_dsn (GnomeDbDsnConfig *props)
+{
+	GdaDataSourceInfo *dsn_info;
+
+	g_return_if_fail (GNOME_DB_IS_DSN_CONFIG (props));
+	dsn_info = gnome_db_dsn_config_get_info (GNOME_DB_DSN_CONFIG (props));
+	if (dsn_info) {
+		gnome_db_config_save_data_source (dsn_info->name,
+						  dsn_info->provider,
+						  dsn_info->cnc_string,
+						  dsn_info->description,
+						  dsn_info->username,
+						  dsn_info->password);
+		gnome_db_config_free_data_source_info (dsn_info);
+	}
+}
+
 static void
 dsn_changed_cb (GnomeDbDsnConfig *config, gpointer user_data)
 {
-	gtk_dialog_set_response_sensitive (GTK_DIALOG (user_data), GTK_RESPONSE_OK, TRUE);
+	gtk_dialog_set_response_sensitive (GTK_DIALOG (user_data), REVERT_BUTTON, TRUE);
+	save_dsn (config);
 }
 
 static void
@@ -68,22 +91,24 @@
 void
 dsn_properties_dialog (GtkWindow *parent, const gchar *dsn)
 {
-	GdaDataSourceInfo *dsn_info;
+	GdaDataSourceInfo *old_dsn_info;
 	GtkWidget *dialog, *props, *notebook, *page;
 	GdkPixbuf *icon;
 
-	dsn_info = gnome_db_config_find_data_source (dsn);
-	if (!dsn_info)
+	old_dsn_info = gnome_db_config_find_data_source (dsn);
+	if (!old_dsn_info)
 		return;
 
 	/* create the dialog */
 	dialog = gtk_dialog_new_with_buttons (
-		_("Data source properties"),
+		_("Data Source Properties"),
 		parent, GTK_DIALOG_DESTROY_WITH_PARENT,
-		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-		GTK_STOCK_SAVE, GTK_RESPONSE_OK,
+		GTK_STOCK_REVERT_TO_SAVED, REVERT_BUTTON,
+		GTK_STOCK_CLOSE, GTK_RESPONSE_OK,
 		NULL);
-	gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE);
+	gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+	gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+	gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), REVERT_BUTTON, FALSE);
 
 	icon = gdk_pixbuf_new_from_file (LIBGNOMEDB_ICONSDIR "/gnome-db.png", NULL);
 	if (icon) {
@@ -93,43 +118,36 @@
 
 	gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 12);
 	notebook = gnome_db_new_notebook_widget ();
+	gtk_container_set_border_width (GTK_CONTAINER (notebook), 5);
 	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), notebook, TRUE, TRUE, 0);
 
-	g_object_set_data (G_OBJECT (notebook), "GdaDataSourceName", dsn);
+	g_object_set_data (G_OBJECT (notebook), "GdaDataSourceName", (gpointer) dsn);
 
 	/* create data source settings page */
 	props = gnome_db_dsn_config_new ();
 	gtk_container_set_border_width (GTK_CONTAINER (props), 12);
-	gnome_db_dsn_config_set_info (GNOME_DB_DSN_CONFIG (props), dsn_info);
+	gnome_db_dsn_config_set_info (GNOME_DB_DSN_CONFIG (props), old_dsn_info);
 	gtk_widget_show (props);
 	g_signal_connect (G_OBJECT (props), "changed", G_CALLBACK (dsn_changed_cb), dialog);
-	gtk_notebook_append_page (GTK_NOTEBOOK (notebook), props, gtk_label_new (dsn_info->name));
+	gtk_notebook_append_page (GTK_NOTEBOOK (notebook), props, gtk_label_new (_("Basic")));
 
 	/* create tables page */
 	page = tables_page_new ();
 	gtk_container_set_border_width (GTK_CONTAINER (page), 12);
 	gtk_notebook_append_page (GTK_NOTEBOOK (notebook), page, gtk_label_new (_("Tables")));
 
-	gnome_db_config_free_data_source_info (dsn_info);
 
 	g_signal_connect (G_OBJECT (notebook), "switch-page",
 			  G_CALLBACK (notebook_switch_page_cb), page);
 
 	/* run the dialog */
-	if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
-		dsn_info = gnome_db_dsn_config_get_info (GNOME_DB_DSN_CONFIG (props));
-		if (dsn_info) {
-			gnome_db_config_save_data_source (dsn_info->name,
-						     dsn_info->provider,
-						     dsn_info->cnc_string,
-						     dsn_info->description,
-						     dsn_info->username,
-						     dsn_info->password);
-			gnome_db_config_free_data_source_info (dsn_info);
-		}
+	while (gtk_dialog_run (GTK_DIALOG (dialog)) == REVERT_BUTTON) {
+		/* reverting changes... */
+		gnome_db_dsn_config_set_info (GNOME_DB_DSN_CONFIG (props), old_dsn_info);
+		gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), REVERT_BUTTON, FALSE);
 	}
-
 	gtk_widget_destroy (dialog);
 
 	/* free memory */
+	gnome_db_config_free_data_source_info (old_dsn_info);
 }
Index: control-center/main.c
===================================================================
RCS file: /cvs/gnome/libgnomedb/control-center/main.c,v
retrieving revision 1.11
diff -u -r1.11 main.c
--- control-center/main.c	27 Aug 2003 22:42:06 -0000	1.11
+++ control-center/main.c	27 Dec 2003 15:17:50 -0000
@@ -19,6 +19,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#include <string.h>
 #include <gtk/gtkdialog.h>
 #include <gtk/gtkstock.h>
 #include <libgnomedb/libgnomedb.h>
@@ -31,6 +32,48 @@
 #include "../libgnomedb/gnome-db-window.h"
 
 static void
+prepare_menu (GnomeDbWindow *window, GtkNotebook *notebook)
+{
+	GtkWidget *current_widget, *wdsn;
+	gboolean dsn, selection;
+	BonoboUIComponent *uic;
+	gint current;
+	
+	current = gtk_notebook_get_current_page (notebook);
+	g_return_if_fail (current != -1);
+	current_widget = gtk_notebook_get_nth_page (notebook, current);
+	g_return_if_fail (current_widget != NULL);
+
+	wdsn = g_object_get_data (G_OBJECT (notebook), DSN_PAGE); 
+	dsn = current_widget == wdsn;
+	selection = database_capplet_has_selection (GTK_WIDGET (notebook));
+
+	uic = gnome_db_window_get_ui_component (window);
+        bonobo_ui_component_set_prop (uic, "/commands/DatabaseProperties",
+				      "sensitive", dsn && selection ? "1" : "0",
+				      NULL);
+        bonobo_ui_component_set_prop (uic, "/commands/EditDelete",
+				      "sensitive", dsn && selection ? "1" : "0",
+				      NULL);
+       	bonobo_ui_component_set_prop (uic, "/commands/ViewDataSources",
+				      "state", dsn ? "1" : "0", NULL);
+       	bonobo_ui_component_set_prop (uic, "/commands/ViewProviders",
+				      "state", dsn ? "0" : "1", NULL);
+}
+
+/*
+ * Callbacks
+ */
+
+/* Database */
+static void
+menu_database_cb (GtkWidget *shell, gpointer user_data)
+{
+	prepare_menu (GNOME_DB_WINDOW (shell), GTK_NOTEBOOK (user_data));
+}
+
+/* Database/New */
+static void
 druid_finished_cb (GnomeDbDsnConfigDruid *druid, gboolean error, gpointer user_data)
 {
 	const GdaDataSourceInfo *dsn_info;
@@ -53,18 +96,6 @@
 }
 
 static void
-edit_delete_cb (GtkWidget *shell, gpointer user_data)
-{
-	database_capplet_delete (GTK_WIDGET (user_data));
-}
-
-static void
-edit_properties_cb (GtkWidget *shell, gpointer user_data)
-{
-	database_capplet_edit_properties (GTK_WIDGET (user_data));
-}
-
-static void
 file_new_cb (GtkWidget *shell, gpointer user_data)
 {
 	GtkWidget *druid, *dialog;
@@ -93,28 +124,101 @@
 	gtk_widget_show (dialog);
 }
 
+/* Database/Properties */
+static void
+file_properties_cb (GtkWidget *shell, gpointer user_data)
+{
+	database_capplet_edit_properties (GTK_WIDGET (user_data));
+}
+
+/* Database/Close */
 static void
 window_closed_cb (GnomeDbWindow *window, gpointer user_data)
 {
 	gnome_db_main_quit ();
 }
 
+/* Edit */
+static void
+menu_edit_cb (GtkWidget *shell, gpointer user_data)
+{
+	prepare_menu (GNOME_DB_WINDOW (shell), GTK_NOTEBOOK (user_data));
+}
+
+/* Edit/Delete */
+static void
+edit_delete_cb (GtkWidget *shell, gpointer user_data)
+{
+	database_capplet_delete (GTK_WIDGET (user_data));
+}
+
+/* Edit/Select All */
+static void
+edit_select_all_cb (GtkWidget *shell, gpointer user_data)
+{
+	database_capplet_select_all (GTK_WIDGET (user_data));
+}
+
+/* Edit/Clear Selection */
+static void
+edit_deselect_all_cb (GtkWidget *shell, gpointer user_data)
+{
+	database_capplet_deselect_all (GTK_WIDGET (user_data));
+}
+
+/* View */
+static void
+menu_view_cb (GtkWidget *shell, gpointer user_data)
+{
+	prepare_menu (GNOME_DB_WINDOW (shell), GTK_NOTEBOOK (user_data));
+}
+
+/* View/Data Sources */
+static void
+view_data_sources_cb (GtkWidget *shell, gpointer user_data)
+{
+	database_capplet_switch (GTK_WIDGET (user_data), DSN_PAGE);
+}
+
+/* View/Providers */
+static void
+view_providers_cb (GtkWidget *shell, gpointer user_data)
+{
+	database_capplet_switch (GTK_WIDGET (user_data), PROVIDER_PAGE);
+}
+
 static void
 create_main_window (gpointer user_data)
 {
+	DbShellCallbacks *callbacks;
 	GtkWidget *window;
 	GtkWidget *capplet;
 
 	capplet = database_capplet_new ();
         gtk_container_set_border_width (GTK_CONTAINER (capplet), 6);
 
+	/* setup callbacks */
+	callbacks = g_new0 (DbShellCallbacks, 1);
+	memset (callbacks, 0, sizeof (DbShellCallbacks));
+	callbacks->menu_database_func = menu_database_cb;
+	callbacks->new_func = file_new_cb;
+	callbacks->edit_properties_func = file_properties_cb;
+	callbacks->menu_edit_func = menu_edit_cb;
+	callbacks->delete_func = edit_delete_cb;
+	callbacks->select_all_func = edit_select_all_cb;
+	callbacks->deselect_all_func = edit_deselect_all_cb;
+	callbacks->menu_view_func = menu_view_cb;
+	callbacks->view_data_sources_func = view_data_sources_cb;
+	callbacks->view_providers_func = view_providers_cb;
+
 	/* create the dialog */
-	window = db_shell_new (_("Database Properties"), capplet, NULL,
-			       (DbShellCallbackFunc) file_new_cb,
-			       (DbShellCallbackFunc) edit_delete_cb,
-			       (DbShellCallbackFunc) edit_properties_cb,
+	window = db_shell_new (_("Database Properties"),
+			       capplet,
+			       NULL,
+			       callbacks,
 			       capplet);
 	gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
+	gnome_db_window_show (GNOME_DB_WINDOW (window));
 
 	g_signal_connect (G_OBJECT (window), "close",
 			  G_CALLBACK (window_closed_cb), NULL);
Index: control-center/provider-config.c
===================================================================
RCS file: /cvs/gnome/libgnomedb/control-center/provider-config.c,v
retrieving revision 1.11
diff -u -r1.11 provider-config.c
--- control-center/provider-config.c	11 Oct 2003 12:56:55 -0000	1.11
+++ control-center/provider-config.c	27 Dec 2003 15:17:50 -0000
@@ -129,7 +129,7 @@
 
 	label = gnome_db_new_label_widget (
 		_("Providers are external plugins that provide access "
-		  "to a specific data source The default provider is "
+		  "to a specific data source. The default provider is "
 		  "always installed, which allows access to databases "
 		  "stored in XML files. Other providers usually "
 		  "distributed along with libgda/gnome-db include "
@@ -141,3 +141,30 @@
 
 	return provider;
 }
+
+void
+provider_config_select_all (GtkWidget *provider)
+{
+	ProviderConfigPrivate *priv;
+
+	priv = g_object_get_data (G_OBJECT (provider), PROVIDER_CONFIG_DATA);
+	gnome_db_grid_select_all (GNOME_DB_GRID (priv->provider_list));
+}
+
+void
+provider_config_unselect_all (GtkWidget *provider)
+{
+	ProviderConfigPrivate *priv;
+
+	priv = g_object_get_data (G_OBJECT (provider), PROVIDER_CONFIG_DATA);
+	gnome_db_grid_unselect_all (GNOME_DB_GRID (priv->provider_list));
+}
+
+gboolean
+provider_config_has_selection (GtkWidget *provider)
+{
+	ProviderConfigPrivate *priv;
+
+	priv = g_object_get_data (G_OBJECT (provider), PROVIDER_CONFIG_DATA);
+	return gnome_db_grid_get_selection (GNOME_DB_GRID (priv->provider_list)) != NULL;
+}
Index: control-center/provider-config.h
===================================================================
RCS file: /cvs/gnome/libgnomedb/control-center/provider-config.h,v
retrieving revision 1.1
diff -u -r1.1 provider-config.h
--- control-center/provider-config.h	5 Jun 2002 18:13:35 -0000	1.1
+++ control-center/provider-config.h	27 Dec 2003 15:17:50 -0000
@@ -25,5 +25,8 @@
 #include <gtk/gtkwidget.h>
 
 GtkWidget *provider_config_new (void);
+void       provider_config_select_all (GtkWidget *provider);
+void       provider_config_unselect_all (GtkWidget *provider);
+gboolean   provider_config_has_selection (GtkWidget *provider);
 
 #endif
Index: libgnomedb/db-shell.c
===================================================================
RCS file: /cvs/gnome/libgnomedb/libgnomedb/db-shell.c,v
retrieving revision 1.6
diff -u -r1.6 db-shell.c
--- libgnomedb/db-shell.c	30 Nov 2003 22:35:22 -0000	1.6
+++ libgnomedb/db-shell.c	27 Dec 2003 15:17:51 -0000
@@ -27,10 +27,7 @@
 typedef struct {
 	GtkWidget *shell;
 	GdaConnection *cnc;
-
-	DbShellCallbackFunc new_func;
-	DbShellCallbackFunc delete_func;
-	DbShellCallbackFunc edit_properties_func;
+	DbShellCallbacks *callbacks;
 	gpointer user_data;
 } DbShellData;
 
@@ -44,6 +41,7 @@
 		"Vivien Malerba <malerba gnome-db org>",
 		"Carlos Perello Marin <carlos gnome-db org>",
 		"Gonzalo Paniagua Javier <gonzalo gnome-db org>",
+		"Laurent Sansonetti <lrz gnome org>",
 		NULL
 	};
 	const gchar *documenters[] = {
@@ -80,55 +78,52 @@
 	gnome_db_window_close (GNOME_DB_WINDOW (dsd->shell));
 }
 
-static void
-command_delete (BonoboUIComponent *uic, void *data, const char *path)
-{
-	DbShellData *dsd = data;
-
-	if (dsd->delete_func)
-		dsd->delete_func (dsd->shell, dsd->user_data);
-}
-
-static void
-command_edit_properties (BonoboUIComponent *uic, void *data, const char *path)
-{
-	DbShellData *dsd = data;
-
-	if (dsd->edit_properties_func)
-		dsd->edit_properties_func (dsd->shell, dsd->user_data);
-}
-
-static void
-command_new (BonoboUIComponent *uic, void *data, const char *path)
-{
-	DbShellData *dsd = data;
+#define DEFINE_VERB_CB(x)								\
+	static void command_##x (BonoboUIComponent *uic, void *data, const char *path)	\
+	{										\
+		DbShellData *dsd = data; 						\
+		if (dsd->callbacks->x##_func) 						\
+			dsd->callbacks->x##_func (dsd->shell, dsd->user_data); 		\
+	}
 
-	if (dsd->new_func)
-		dsd->new_func (dsd->shell, dsd->user_data);
-}
+#define DEFINE_LIST_CB(x)								\
+	static void command_##x (BonoboUIComponent *component, const char *path,	\
+				 Bonobo_UIComponent_EventType type, const char *state,	\
+				 gpointer data)						\
+	{										\
+		DbShellData *dsd = data; 						\
+		if (dsd->callbacks->x##_func) 						\
+			dsd->callbacks->x##_func (dsd->shell, dsd->user_data); 		\
+	}
 
-static void
-command_preferences (BonoboUIComponent *uic, void *data, const char *path)
-{
-}
+DEFINE_VERB_CB (menu_database)
+DEFINE_VERB_CB (new)
+DEFINE_VERB_CB (edit_properties)
+DEFINE_VERB_CB (save_connection)
+DEFINE_VERB_CB (menu_edit)
+DEFINE_VERB_CB (delete)
+DEFINE_VERB_CB (select_all)
+DEFINE_VERB_CB (deselect_all)
+DEFINE_VERB_CB (menu_view)
 
-static void
-command_save_connection (BonoboUIComponent *uic, void *data, const char *path)
-{
-	DbShellData *dsd = data;
+DEFINE_LIST_CB (view_data_sources)
+DEFINE_LIST_CB (view_providers)
 
-	
-}
+#undef DEFINE_VERB_CB
+#undef DEFINE_LIST_CB
 
 static BonoboUIVerb db_shell_verbs [] = {
+	BONOBO_UI_VERB ("Database", command_menu_database),
 	BONOBO_UI_VERB ("DatabaseClose", command_close),
 	BONOBO_UI_VERB ("DatabaseNew", command_new),
 	BONOBO_UI_VERB ("DatabaseSaveConnection", command_save_connection),
+	BONOBO_UI_VERB ("DatabaseProperties", command_edit_properties),
+	BONOBO_UI_VERB ("Edit", command_menu_edit),
 	BONOBO_UI_VERB ("EditDelete", command_delete),
-	BONOBO_UI_VERB ("EditProperties", command_edit_properties),
-	BONOBO_UI_VERB ("SettingsPreferences", command_preferences),
+	BONOBO_UI_VERB ("EditSelectAll", command_select_all),
+	BONOBO_UI_VERB ("EditDeselectAll", command_deselect_all),
+	BONOBO_UI_VERB ("View", command_menu_view),
 	BONOBO_UI_VERB ("HelpAbout", command_about),
-
 	BONOBO_UI_VERB_END
 };
 
@@ -139,6 +134,7 @@
 
 	dsd->shell = NULL;
 	dsd->cnc = NULL;
+	g_free (dsd->callbacks);
 	g_free (dsd);
 
 	g_object_set_data (G_OBJECT (window), "GNOME_DB_Shell_PrivateData", NULL);
@@ -150,42 +146,43 @@
 	gboolean connected;
 	BonoboUIComponent *uic;
 
-	if (GDA_IS_CONNECTION (dsd->cnc) && gda_connection_is_open (dsd->cnc))
-		connected = TRUE;
-	else
-		connected = FALSE;
-
+	connected = GDA_IS_CONNECTION (dsd->cnc) && gda_connection_is_open (dsd->cnc);
 	uic = gnome_db_window_get_ui_component (GNOME_DB_WINDOW (dsd->shell));
 
 	bonobo_ui_component_set_prop (uic, "/commands/DatabaseSaveConnection", "hidden",
 				      connected ? "0" : "1",
 				      NULL);
 	bonobo_ui_component_set_prop (uic, "/commands/DatabaseNew", "hidden",
-				      dsd->new_func ? "0" : "1",
+				      dsd->callbacks->new_func ? "0" : "1",
+				      NULL);
+	bonobo_ui_component_set_prop (uic, "/commands/DatabaseProperties", "hidden",
+				      dsd->callbacks->edit_properties_func ? "0" : "1",
 				      NULL);
 	bonobo_ui_component_set_prop (uic, "/commands/EditDelete", "hidden",
-				      dsd->delete_func ? "0" : "1",
+				      dsd->callbacks->delete_func ? "0" : "1",
 				      NULL);
-	bonobo_ui_component_set_prop (uic, "/commands/EditProperties", "hidden",
-				      dsd->edit_properties_func ? "0" : "1",
+	bonobo_ui_component_set_prop (uic, "/commands/EditSelectAll", "hidden",
+				      dsd->callbacks->select_all_func ? "0" : "1",
+				      NULL);
+	bonobo_ui_component_set_prop (uic, "/commands/EditDeselectAll", "hidden",
+				      dsd->callbacks->deselect_all_func ? "0" : "1",
 				      NULL);
 }
 
 GtkWidget *
-db_shell_new (const gchar *title, GtkWidget *widget, GdaConnection *cnc,
-	      DbShellCallbackFunc new_func,
-	      DbShellCallbackFunc delete_func,
-	      DbShellCallbackFunc edit_properties_func,
+db_shell_new (const gchar *title,
+	      GtkWidget *widget,
+	      GdaConnection *cnc,
+	      DbShellCallbacks *callbacks,
 	      gpointer user_data)
 {
+	BonoboUIComponent *uic;
 	DbShellData *dsd;
 	GdkPixbuf *icon;
 
 	dsd = g_new0 (DbShellData, 1);
 	dsd->cnc = cnc;
-	dsd->new_func = new_func;
-	dsd->delete_func = delete_func;
-	dsd->edit_properties_func = edit_properties_func;
+	dsd->callbacks = callbacks;
 	dsd->user_data = user_data;
 
 	/* create the main window */
@@ -200,11 +197,16 @@
 		gtk_window_set_icon (GTK_WINDOW (dsd->shell), icon);
 		g_object_unref (icon);
 	}
+	
+	/* FIXME: move this code in gnome_db_window_new () */
+	uic = gnome_db_window_get_ui_component (GNOME_DB_WINDOW (dsd->shell));
+	bonobo_ui_component_add_listener (uic, "ViewDataSources",
+					  command_view_data_sources, dsd);
+	bonobo_ui_component_add_listener (uic, "ViewProviders",
+					  command_view_providers, dsd);
 
 	gnome_db_window_set_contents (GNOME_DB_WINDOW (dsd->shell), widget);
-	gtk_widget_show (widget);
-	gtk_window_set_default_size (GTK_WINDOW (dsd->shell), 400, 350);
-	gtk_widget_show (dsd->shell);
+	gtk_window_set_default_size (GTK_WINDOW (dsd->shell), 400, 380);
 
 	sensitize_ui (dsd);
 
Index: libgnomedb/db-shell.h
===================================================================
RCS file: /cvs/gnome/libgnomedb/libgnomedb/db-shell.h,v
retrieving revision 1.4
diff -u -r1.4 db-shell.h
--- libgnomedb/db-shell.h	6 Jul 2003 19:25:43 -0000	1.4
+++ libgnomedb/db-shell.h	27 Dec 2003 15:17:51 -0000
@@ -27,10 +27,24 @@
 
 typedef void (* DbShellCallbackFunc) (GtkWidget *shell, gpointer user_data);
 
-GtkWidget *db_shell_new (const gchar *title, GtkWidget *widget, GdaConnection *cnc,
-			 DbShellCallbackFunc new_func,
-			 DbShellCallbackFunc delete_func,
-			 DbShellCallbackFunc edit_properties_func,
+typedef struct {
+	DbShellCallbackFunc menu_database_func;
+	DbShellCallbackFunc new_func;
+	DbShellCallbackFunc edit_properties_func;
+	DbShellCallbackFunc save_connection_func;
+	DbShellCallbackFunc menu_edit_func;
+	DbShellCallbackFunc delete_func;
+	DbShellCallbackFunc select_all_func;
+	DbShellCallbackFunc deselect_all_func;
+	DbShellCallbackFunc menu_view_func;
+	DbShellCallbackFunc view_data_sources_func;
+	DbShellCallbackFunc view_providers_func;
+} DbShellCallbacks;
+
+GtkWidget *db_shell_new (const gchar *title,
+			 GtkWidget *widget,
+			 GdaConnection *cnc,
+			 DbShellCallbacks *callbacks,
 			 gpointer user_data);
 
 #endif
Index: libgnomedb/db-shell.xml
===================================================================
RCS file: /cvs/gnome/libgnomedb/libgnomedb/db-shell.xml,v
retrieving revision 1.5
diff -u -r1.5 db-shell.xml
--- libgnomedb/db-shell.xml	24 Nov 2003 17:37:31 -0000	1.5
+++ libgnomedb/db-shell.xml	27 Dec 2003 15:17:51 -0000
@@ -1,32 +1,41 @@
 <Root>
   <commands>
+    <cmd name="Database"/>
     <cmd name="DatabaseNew" _tip="Create new entry" pixtype="stock" pixname="gtk-new" accel="*Control*n"/>
     <cmd name="DatabaseSaveConnection" _tip="Save connection parameters to file" pixtype="stock" pixname="gtk-save" accel="*Control*s"/>
+    <cmd name="DatabaseProperties" _tip="Edit properties for selected item" pixtype="stock" pixname="gtk-properties"/>
     <cmd name="DatabaseClose" _tip="Close this window" pixtype="stock" pixname="gtk-close" accel="*Control*w"/>
-    <cmd name="EditDelete" _tip="Delete selected items" pixtype="stock" pixname="gtk-delete" accel="*Control*d"/>
-    <cmd name="EditProperties" _tip="Edit properties for selected item" pixtype="stock" pixname="gtk-properties"/>
-    <cmd name="SettingsPreferences" _tip="Edit application preferences" pixtype="stock" pixname="gtk-preferences"/>
+    <cmd name="Edit"/>
+    <cmd name="EditDelete" _tip="Delete selected items" pixtype="stock" pixname="gtk-delete" accel="Delete"/>
+    <cmd name="EditSelectAll" _tip="Select all items" accel="*Control*a"/>
+    <cmd name="EditDeselectAll" _tip="Deselect all items" accel="*Control**Shift*a"/>
+    <cmd name="View"/>
+    <cmd name="ViewDataSources" _tip="View data sources" accel="*Alt*1"/>
+    <cmd name="ViewProviders" _tip="View providers" accel="*Alt*2"/>
     <cmd name="HelpAbout" _tip="About GNOME-DB" pixtype="stock" pixname="gnome-stock-about"/>
   </commands>
   
   <menu id="MenuBar">
-    <submenu name="Database" _label="_Database">
+    <submenu name="Database" verb="Database" _label="_Database">
       <menuitem name="DatabaseNew" verb="DatabaseNew" _label="New..."/>
       <menuitem name="DatabaseSaveConnection" verb="DatabaseSaveConnection" _label="_Save Connection"/>
       <separator/>
+      <menuitem name="DatabaseProperties" verb="DatabaseProperties" _label="_Properties"/>
+      <separator/>
       <menuitem name="DatabaseClose" verb="DatabaseClose" _label="_Close"/>
     </submenu>
-    <submenu name="Edit" _label="_Edit">
+    <submenu name="Edit" verb="Edit" _label="_Edit">
       <menuitem name="EditDelete" verb="EditDelete" _label="_Delete"/>
-      <menuitem name="EditProperties" verb="EditProperties" _label="_Properties..."/>
+      <separator/>
+      <menuitem name="EditSelectAll" verb="EditSelectAll" _label="Select _All"/>
+      <menuitem name="EditDeselectAll" verb="EditDeselectAll" _label="_Clear selection"/>
     </submenu>
-    <submenu name="Settings" _label="_Settings">
-      <menuitem name="SettingsPreferences" verb="SettingsPreferences" _label="_Preferences"/>
+    <submenu name="View" verb="View" _label="_View"> 
+      <menuitem name="ViewDataSources" verb="ViewDataSources" _label="_Data Sources" type="radio" group="SwitchPanel" state="1"/>
+      <menuitem name="ViewProviders" verb="ViewProviders" _label="_Providers" type="radio" group="SwitchPanel"/>
     </submenu>
     <submenu name="Help" _label="_Help">
       <menuitem name="HelpAbout" verb="HelpAbout" _label="About"/>
     </submenu>
-
   </menu>
-
 </Root>
Index: libgnomedb/gnome-db-dsn-config-druid.c
===================================================================
RCS file: /cvs/gnome/libgnomedb/libgnomedb/gnome-db-dsn-config-druid.c,v
retrieving revision 1.24
diff -u -r1.24 gnome-db-dsn-config-druid.c
--- libgnomedb/gnome-db-dsn-config-druid.c	28 Oct 2003 13:11:37 -0000	1.24
+++ libgnomedb/gnome-db-dsn-config-druid.c	27 Dec 2003 15:17:53 -0000
@@ -243,11 +243,15 @@
 		param = (const gchar *) l->data;
 		if (param) {
 			GHashTable *values;
+			gchar *title;
 
 			box = gnome_db_new_hbox_widget (TRUE, 0);
-			label = gnome_db_new_label_widget (param);
+			title = g_strdup_printf ("_%s:", param);
+			label = gnome_db_new_label_widget (title);
+			g_free (title);
 			gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
 			widget = gnome_db_new_entry_widget (0, TRUE);
+			gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
 			if (!g_strcasecmp (param, "PASSWORD"))
 				gtk_entry_set_visibility (GTK_ENTRY (widget), FALSE);
 
@@ -397,36 +401,36 @@
 		  "items for your new data source. Some of them (description,\n"
 		  "username) are optional, whereas the others are mandatory.\n"
 		  "If you don't know which provider to use, just select\n"
-		  "the default one"));
+		  "the default one."));
 	gnome_druid_page_standard_append_item (
 		GNOME_DRUID_PAGE_STANDARD (druid->priv->general_page), NULL, label, NULL);
 
 	druid->priv->general_name = gnome_db_new_entry_widget (0, TRUE);
 	gnome_druid_page_standard_append_item (
 		GNOME_DRUID_PAGE_STANDARD (druid->priv->general_page),
-		_("Data source name"), druid->priv->general_name, NULL);
+		_("Data source _name:"), druid->priv->general_name, NULL);
 
 	druid->priv->general_provider = gnome_db_provider_selector_new ();
 	gtk_widget_show (druid->priv->general_provider);
 	gnome_druid_page_standard_append_item (
 		GNOME_DRUID_PAGE_STANDARD (druid->priv->general_page),
-		_("Provider"), druid->priv->general_provider, NULL);
+		_("_Provider:"), druid->priv->general_provider, NULL);
 
 	druid->priv->general_description = gnome_db_new_entry_widget (0, TRUE);
 	gnome_druid_page_standard_append_item (
 		GNOME_DRUID_PAGE_STANDARD (druid->priv->general_page),
-		_("Description"), druid->priv->general_description, NULL);
+		_("_Description:"), druid->priv->general_description, NULL);
 
 	druid->priv->general_username = gnome_db_new_entry_widget (0, TRUE);
 	gnome_druid_page_standard_append_item (
 		GNOME_DRUID_PAGE_STANDARD (druid->priv->general_page),
-		_("Username"), druid->priv->general_username, NULL);
+		_("_Username:"), druid->priv->general_username, NULL);
 
 	druid->priv->general_password = gnome_db_new_entry_widget (0, TRUE);
 	gtk_entry_set_visibility (GTK_ENTRY (druid->priv->general_password), FALSE);
 	gnome_druid_page_standard_append_item (
 		GNOME_DRUID_PAGE_STANDARD (druid->priv->general_page),
-		_("Password"), druid->priv->general_password, NULL);
+		_("P_assword:"), druid->priv->general_password, NULL);
 
 	gtk_widget_show (druid->priv->general_page);
 	gnome_druid_append_page (GNOME_DRUID (druid),
@@ -446,7 +450,7 @@
 		_("The following fields represent the information needed by the\n"
 		  "provider you selected in the previous page to open a given\n"
 		  "connection. This information is provider-specific, so check\n"
-		  "the manual for more information"));
+		  "the manual for more information."));
 	gnome_druid_page_standard_append_item (
 		GNOME_DRUID_PAGE_STANDARD (druid->priv->provider_page), NULL, label, NULL);
 
@@ -470,7 +474,7 @@
 		_("All information needed to create a new data source\n"
 		  "has been retrieved. Now, press 'Apply' to close\n"
 		  "this dialog. To open your newly created data source,\n"
-		  "just select it when asked for a data source"),
+		  "just select it when asked for a data source."),
 		  druid->priv->logo, NULL, NULL);
 	gtk_widget_show (druid->priv->end_page);
 	gnome_druid_append_page (GNOME_DRUID (druid),
Index: libgnomedb/gnome-db-dsn-config.c
===================================================================
RCS file: /cvs/gnome/libgnomedb/libgnomedb/gnome-db-dsn-config.c,v
retrieving revision 1.12
diff -u -r1.12 gnome-db-dsn-config.c
--- libgnomedb/gnome-db-dsn-config.c	6 Jul 2003 23:22:07 -0000	1.12
+++ libgnomedb/gnome-db-dsn-config.c	27 Dec 2003 15:17:53 -0000
@@ -20,6 +20,7 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#include <gtk/gtklabel.h>
 #include <gtk/gtktable.h>
 #include <libgnomedb/gnome-db-dsn-config.h>
 #include <libgnomedb/gnome-db-provider-selector.h>
@@ -100,55 +101,62 @@
 	table = gnome_db_new_table_widget (6, 3, FALSE);
 	gtk_box_pack_start (GTK_BOX (config), table, TRUE, TRUE, 0);
 
-	label = gnome_db_new_label_widget (_("Data source name"));
+	label = gnome_db_new_label_widget (_("Data source _name:"));
 	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
 	config->priv->wname = gnome_db_new_entry_widget (0, TRUE);
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), config->priv->wname);
+	gtk_widget_set_sensitive (config->priv->wname, FALSE); /* FIXME */
 	g_signal_connect (G_OBJECT (config->priv->wname), "changed",
 			  G_CALLBACK (field_changed_cb), config);
 	gtk_table_attach (GTK_TABLE (table), config->priv->wname, 1, 2, 0, 1,
-			  GTK_FILL, GTK_FILL, 0, 0);
+			  GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);
 
-	label = gnome_db_new_label_widget (_("Provider"));
+	label = gnome_db_new_label_widget (_("_Provider:"));
 	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
 	config->priv->wprovider = gnome_db_provider_selector_new ();
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), config->priv->wprovider);
 	gtk_widget_show (config->priv->wprovider);
 	g_signal_connect (G_OBJECT (config->priv->wprovider), "changed",
 			  G_CALLBACK (field_changed_cb), config);
 	gtk_table_attach (GTK_TABLE (table), config->priv->wprovider, 1, 2, 1, 2,
-			  GTK_FILL, GTK_FILL, 0, 0);
+			  GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);
 
-	label = gnome_db_new_label_widget (_("Connection string"));
+	label = gnome_db_new_label_widget (_("Connection _string:"));
 	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 0, 0);
 	config->priv->wstring = gnome_db_new_entry_widget (0, TRUE);
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), config->priv->wstring);
 	g_signal_connect (G_OBJECT (config->priv->wstring), "changed",
 			  G_CALLBACK (field_changed_cb), config);
 	gtk_table_attach (GTK_TABLE (table), config->priv->wstring, 1, 2, 2, 3,
-			  GTK_FILL, GTK_FILL, 0, 0);
+			  GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);
 
-	label = gnome_db_new_label_widget (_("Description"));
+	label = gnome_db_new_label_widget (_("_Description:"));
 	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 0, 0);
 	config->priv->wdesc = gnome_db_new_entry_widget (0, TRUE);
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), config->priv->wdesc);
 	g_signal_connect (G_OBJECT (config->priv->wdesc), "changed",
 			  G_CALLBACK (field_changed_cb), config);
 	gtk_table_attach (GTK_TABLE (table), config->priv->wdesc, 1, 2, 3, 4,
-			  GTK_FILL, GTK_FILL, 0, 0);
+			  GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);
 
-	label = gnome_db_new_label_widget (_("Username"));
+	label = gnome_db_new_label_widget (_("_Username:"));
 	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5, GTK_FILL, GTK_FILL, 0, 0);
 	config->priv->wuser = gnome_db_new_entry_widget (0, TRUE);
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), config->priv->wuser);
 	g_signal_connect (G_OBJECT (config->priv->wuser), "changed",
 			  G_CALLBACK (field_changed_cb), config);
 	gtk_table_attach (GTK_TABLE (table), config->priv->wuser, 1, 2, 4, 5,
-			  GTK_FILL, GTK_FILL, 0, 0);
+			  GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);
 
-	label = gnome_db_new_label_widget (_("Password"));
+	label = gnome_db_new_label_widget (_("P_assword:"));
 	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 5, 6, GTK_FILL, GTK_FILL, 0, 0);
 	config->priv->wpassword = gnome_db_new_entry_widget (0, TRUE);
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), config->priv->wpassword);
 	gtk_entry_set_visibility (GTK_ENTRY (config->priv->wpassword), FALSE);
 	g_signal_connect (G_OBJECT (config->priv->wpassword), "changed",
 			  G_CALLBACK (field_changed_cb), config);
 	gtk_table_attach (GTK_TABLE (table), config->priv->wpassword, 1, 2, 5, 6,
-			  GTK_FILL, GTK_FILL, 0, 0);
+			  GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 0);
 }
 
 static void
Index: libgnomedb/gnome-db-grid.c
===================================================================
RCS file: /cvs/gnome/libgnomedb/libgnomedb/gnome-db-grid.c,v
retrieving revision 1.51
diff -u -r1.51 gnome-db-grid.c
--- libgnomedb/gnome-db-grid.c	17 Dec 2003 22:43:47 -0000	1.51
+++ libgnomedb/gnome-db-grid.c	27 Dec 2003 15:17:55 -0000
@@ -23,14 +23,16 @@
 #include <string.h>
 #include <glib/gfileutils.h>
 #include <libgda/gda-util.h>
+#include <gtk/gtkcheckmenuitem.h>
 #include <gtk/gtkdialog.h>
+#include <gtk/gtklabel.h>
 #include <gtk/gtkradiobutton.h>
+#include <gtk/gtkseparatormenuitem.h>
 #include <gtk/gtkstock.h>
 #include <gtk/gtktable.h>
 #include <gtk/gtktreeselection.h>
 #include <gtk/gtktreeview.h>
 #include <gtk/gtkwindow.h>
-#include <gtk/gtkimagemenuitem.h>
 #include <gobject/gmarshal.h>
 #include <libgnomedb/gnome-db-form.h>
 #include <libgnomedb/gnome-db-gray-bar.h>
@@ -129,19 +131,49 @@
 }
 #endif
 
-static void
-menu_hide_columns_cb (GtkWidget *widget, gpointer user_data)
+static gboolean
+confirm_overwrite (GtkWindow *parent, const gchar *path)
 {
-	GnomeDbGrid *grid = (GnomeDbGrid *) user_data;
+	GtkWidget *dialog, *button;
+	gboolean yes;
+	gchar *msg;
+
+	msg = g_strdup_printf (_("File '%s' already exists.\n"
+				 "Do you want to overwrite it?"), path);
+
+	/* build the dialog */
+	dialog = gnome_db_new_alert (
+		NULL,
+		GTK_MESSAGE_QUESTION,
+		msg,
+		_("If you choose yes, the contents will be lost."));
+	button = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+	GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+	gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
+				      button,
+				      GTK_RESPONSE_NO);
+	gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
+				      gtk_button_new_from_stock (GTK_STOCK_YES),
+				      GTK_RESPONSE_YES);
+	gtk_dialog_set_default_response (GTK_DIALOG (dialog),
+					 GTK_RESPONSE_NO);
 
-	g_return_if_fail (GNOME_DB_IS_GRID (grid));
-	gnome_db_grid_hide_column_titles (grid);
-}
+	/* run the dialog */
+	gtk_widget_show_all (dialog);
+	yes = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES;
 
+	/* free memory */
+	gtk_widget_destroy (dialog);
+	g_free (msg);
+	return yes;
+}
+					    
 #ifdef BUILD_WITH_GNOME
 static void
 save_as_response_cb (GtkDialog *dialog, guint response_id, gpointer user_data)
 {
+	GtkWidget *types;
+	GtkWidget *sel_type;
 	GtkWidget *to_tab;
 	GtkWidget *to_comma;
 	GtkWidget *to_xml;
@@ -152,16 +184,20 @@
 		gchar *body;
 		gchar *path;
 
+		types = g_object_get_data (G_OBJECT (dialog), "types");
 		to_tab = g_object_get_data (G_OBJECT (dialog), "to_tab");
 		to_comma = g_object_get_data (G_OBJECT (dialog), "to_comma");
 		to_xml = g_object_get_data (G_OBJECT (dialog), "to_xml");
 		filename = g_object_get_data (G_OBJECT (dialog), "filename");
 
-		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (to_tab)))
+		sel_type = gtk_menu_get_active (
+			GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (types))));
+
+		if (sel_type == to_tab)
 			body = gda_data_model_to_tab_separated (grid->priv->model);
-		else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (to_comma)))
+		else if (sel_type == to_comma)
 			body = gda_data_model_to_comma_separated (grid->priv->model);
-		else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (to_xml)))
+		else if (sel_type == to_xml)
 			body = gda_data_model_to_xml (grid->priv->model, TRUE);
 		else
 			body = NULL;
@@ -170,14 +206,11 @@
 			path = gnome_file_entry_get_full_path (GNOME_FILE_ENTRY (filename), FALSE);
 			if (path) {
 				if (g_file_test (path, G_FILE_TEST_EXISTS)) {
-					if (!gnome_db_yes_no_dialog (GTK_WIDGET (dialog),
-								     _("File %s already exists\n"
-								       "Do you want to overwrite it?"), path)) {
+					if (!confirm_overwrite (GTK_WINDOW (dialog), path)) {
 						g_free (body);
 						g_free (path);
 						return;
 					}
-					    
 				}
 
 				if (!gda_file_save (path, body, strlen (body))) {
@@ -201,16 +234,23 @@
 }
 
 static void
+filename_changed_cb (GtkWidget *widget, GtkDialog *dialog)
+{
+	gboolean ok = gnome_file_entry_get_full_path (GNOME_FILE_ENTRY (widget), FALSE) != NULL;
+	gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, ok);
+}
+
+static void
 menu_save_as_cb (GtkWidget *widget, gpointer user_data)
 {
 	GtkWidget *dialog;
 	GtkWidget *table;
 	GtkWidget *label;
 	GtkWidget *filename;
+	GtkWidget *types;
 	GtkWidget *to_tab;
 	GtkWidget *to_comma;
 	GtkWidget *to_xml;
-	GdkPixbuf *icon;
 	GnomeDbGrid *grid = (GnomeDbGrid *) user_data;
 
 	g_return_if_fail (GNOME_DB_IS_GRID (grid));
@@ -218,46 +258,49 @@
 
 	/* create dialog box */
 	dialog = gtk_dialog_new_with_buttons (
-		_("Save as"),
+		_("Saving Model"),
 		GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (grid))), 0,
 		GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-		GTK_STOCK_OK, GTK_RESPONSE_OK,
+		GTK_STOCK_SAVE, GTK_RESPONSE_OK,
 		NULL);
-
-	icon = gdk_pixbuf_new_from_file (LIBGNOMEDB_ICONSDIR "/gnome-db.png", NULL);
-	if (icon) {
-		gtk_window_set_icon (GTK_WINDOW (dialog), icon);
-		g_object_unref (icon);
-	}
-
-	table = gnome_db_new_table_widget (6, 2, FALSE);
-	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), table, TRUE, TRUE, 0);
-
-	label = gnome_db_new_label_widget (_("Save to"));
+	gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+	gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
+	gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE);
+
+	table = gnome_db_new_table_widget (2, 2, FALSE);
+	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), table, TRUE, TRUE, 6);
+	label = gtk_label_new_with_mnemonic (_("File _name:"));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
 	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 2, 2);
-	filename = gnome_db_new_file_entry_widget ("gnome-db-grid-save-as", _("Select File"));
+	filename = gnome_db_new_file_entry_widget ("gnome-db-grid-save-as",
+						   _("Select File"));
+	g_signal_connect (G_OBJECT (filename), "changed",
+			  G_CALLBACK (filename_changed_cb), dialog);
 	g_object_set_data (G_OBJECT (dialog), "filename", filename);
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), filename);
 	gtk_table_attach (GTK_TABLE (table), filename, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 2, 2);
 
-	to_tab = gnome_db_new_radio_button_widget (NULL, _("Tab-delimited file"));
+	label = gtk_label_new_with_mnemonic (_("File _type:"));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
+	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 2, 2);
+	types = gnome_db_new_option_menu_widget ();
+	gtk_label_set_mnemonic_widget (GTK_LABEL (label), types);
+	gtk_table_attach (GTK_TABLE (table), types, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 2, 2);
+	g_object_set_data (G_OBJECT (dialog), "types", types);
+	to_tab = gnome_db_option_menu_add_item (GTK_OPTION_MENU (types),
+						_("Tab-delimited"));
 	g_object_set_data (G_OBJECT (dialog), "to_tab", to_tab);
-	gtk_table_attach (GTK_TABLE (table), to_tab, 1, 2, 1, 2, GTK_FILL, GTK_FILL, 2, 2);
-
-	to_comma = gnome_db_new_radio_button_widget (
-		gtk_radio_button_get_group (GTK_RADIO_BUTTON (to_tab)),
-		_("Comma-delimited file"));
+	to_comma = gnome_db_option_menu_add_item (GTK_OPTION_MENU (types),
+						  _("Comma-delimited"));
 	g_object_set_data (G_OBJECT (dialog), "to_comma", to_comma);
-	gtk_table_attach (GTK_TABLE (table), to_comma, 1, 2, 2, 3, GTK_FILL, GTK_FILL, 2, 2);
-
-	to_xml = gnome_db_new_radio_button_widget (
-		gtk_radio_button_get_group (GTK_RADIO_BUTTON (to_tab)),
-		_("XML file"));
+	to_xml = gnome_db_option_menu_add_item (GTK_OPTION_MENU (types),
+						_("XML"));
+	gnome_db_option_menu_set_selection (GTK_OPTION_MENU (types), _("XML"));
 	g_object_set_data (G_OBJECT (dialog), "to_xml", to_xml);
-	gtk_table_attach (GTK_TABLE (table), to_xml, 1, 2, 3, 4, GTK_FILL, GTK_FILL, 2, 2);
 
 	/* run the dialog */
 	g_signal_connect (G_OBJECT (dialog), "response", G_CALLBACK (save_as_response_cb), grid);
-	gtk_widget_show (dialog);
+	gtk_widget_show_all (dialog);
 }
 #endif
 
@@ -273,10 +316,18 @@
 static void
 menu_show_columns_cb (GtkWidget *widget, gpointer user_data)
 {
-	GnomeDbGrid *grid = (GnomeDbGrid *) user_data;
+	GnomeDbGrid *grid;
+	GtkCheckMenuItem *item;
+
+	grid = (GnomeDbGrid *) user_data;
+	item = (GtkCheckMenuItem *) widget;
 
 	g_return_if_fail (GNOME_DB_IS_GRID (grid));
-	gnome_db_grid_show_column_titles (grid);
+	g_return_if_fail (GTK_IS_CHECK_MENU_ITEM (item));
+
+	gnome_db_grid_set_column_titles_visible (
+		grid, 
+		gtk_check_menu_item_get_active (item));
 }
 
 static void
@@ -288,6 +339,7 @@
 	gnome_db_grid_unselect_all (grid);
 }
 
+#if 0
 static void
 menu_view_detail_cb (GtkWidget *widget, gpointer user_data)
 {
@@ -321,6 +373,7 @@
 	gtk_dialog_run (GTK_DIALOG (dialog));
 	gtk_widget_destroy (dialog);
 }
+#endif
 
 static void
 model_row_removed_cb (GdaDataModel *model, gint row, gpointer user_data)
@@ -343,22 +396,6 @@
 	}
 }
 
-static void
-add_popup_menu_item (GtkMenu *menu, const gchar *label, gboolean pixmap, GCallback cb_func, gpointer user_data)
-{
-	GtkWidget *item;
-
-	if (pixmap)
-		item = gtk_image_menu_item_new_from_stock (label, NULL);
-	else
-		item = gtk_menu_item_new_with_label (label);
-	g_signal_connect (G_OBJECT (item), "activate",
-			  G_CALLBACK (cb_func), user_data);
-	gtk_menu_append (GTK_MENU (menu), item);
-	gtk_widget_show (item);
-
-}
-
 static gint
 popup_button_pressed_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
 {
@@ -366,18 +403,40 @@
 	GnomeDbGrid *grid = (GnomeDbGrid *) user_data;
 
 	g_return_val_if_fail (GNOME_DB_IS_GRID (grid), FALSE);
-
+	
 	if (event->button != 3)
 		return FALSE;
 
 	/* create the menu */
 	menu = gtk_menu_new ();
-	add_popup_menu_item (GTK_MENU (menu), _("Select All"), FALSE, G_CALLBACK (menu_select_all_cb), grid);
-	add_popup_menu_item (GTK_MENU (menu), _("Clear selection"), FALSE, G_CALLBACK (menu_unselect_all_cb), grid);
-	add_popup_menu_item (GTK_MENU (menu), _("Show columns"), FALSE, G_CALLBACK (menu_show_columns_cb), grid);
-	add_popup_menu_item (GTK_MENU (menu), _("Hide columns"), FALSE, G_CALLBACK (menu_hide_columns_cb), grid);
+	gtk_menu_append (
+		GTK_MENU (menu),
+		gnome_db_new_menu_item (_("Select _All"),
+					FALSE,
+					G_CALLBACK (menu_select_all_cb),
+					grid));	
+	gtk_menu_append (
+		GTK_MENU (menu),
+		gnome_db_new_menu_item (_("_Clear selection"),
+					FALSE,
+					G_CALLBACK (menu_unselect_all_cb),
+					grid));
+	gtk_menu_append (
+		GTK_MENU (menu),
+		gnome_db_new_check_menu_item (
+			_("Show column _titles"),
+			gnome_db_grid_get_column_titles_visible (grid),
+			G_CALLBACK (menu_show_columns_cb),
+			grid));
+
 #ifdef BUILD_WITH_GNOME
-	add_popup_menu_item (GTK_MENU (menu), GTK_STOCK_SAVE_AS, TRUE, G_CALLBACK (menu_save_as_cb), grid);
+	gtk_menu_append (GTK_MENU (menu), gtk_separator_menu_item_new ());
+	gtk_menu_append (
+		GTK_MENU (menu),
+		gnome_db_new_menu_item (GTK_STOCK_SAVE_AS,
+					TRUE,
+				      	G_CALLBACK (menu_save_as_cb),
+					grid));
 #endif
 #if 0
 	add_popup_menu_item (GTK_MENU (menu), _("Describe"), G_CALLBACK (menu_describe_cb), grid);
@@ -387,6 +446,7 @@
 	/* allow listeners to add their custom menu items */
 	g_signal_emit (G_OBJECT (grid), gnome_db_grid_signals[CREATE_POPUP_MENU], 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;
 }
@@ -1047,23 +1107,23 @@
 }
 
 /**
- * gnome_db_grid_hide_column_titles
+ * gnome_db_grid_set_column_titles_visible
  */
 void
-gnome_db_grid_hide_column_titles (GnomeDbGrid *grid)
+gnome_db_grid_set_column_titles_visible (GnomeDbGrid *grid, gboolean visible)
 {
 	g_return_if_fail (GNOME_DB_IS_GRID (grid));
-	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (grid->priv->tree_view), FALSE);
+	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (grid->priv->tree_view), visible);
 }
 
 /**
- * gnome_db_grid_show_column_titles
+ * gnome_db_grid_get_column_titles_visible
  */
-void
-gnome_db_grid_show_column_titles (GnomeDbGrid *grid)
+gboolean
+gnome_db_grid_get_column_titles_visible (GnomeDbGrid *grid)
 {
-	g_return_if_fail (GNOME_DB_IS_GRID (grid));
-	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (grid->priv->tree_view), TRUE);
+	g_return_val_if_fail (GNOME_DB_IS_GRID (grid), FALSE);
+	return gtk_tree_view_get_headers_visible (GTK_TREE_VIEW (grid->priv->tree_view));
 }
 
 /**
Index: libgnomedb/gnome-db-grid.h
===================================================================
RCS file: /cvs/gnome/libgnomedb/libgnomedb/gnome-db-grid.h,v
retrieving revision 1.18
diff -u -r1.18 gnome-db-grid.h
--- libgnomedb/gnome-db-grid.h	17 Dec 2003 15:35:42 -0000	1.18
+++ libgnomedb/gnome-db-grid.h	27 Dec 2003 15:17:56 -0000
@@ -82,8 +82,12 @@
 void             gnome_db_grid_set_selection_mode (GnomeDbGrid *grid,
 						   GtkSelectionMode mode);
 
-void             gnome_db_grid_hide_column_titles (GnomeDbGrid *grid);
-void             gnome_db_grid_show_column_titles (GnomeDbGrid *grid);
+void             gnome_db_grid_set_column_titles_visible (GnomeDbGrid *grid, gboolean visible);
+gboolean         gnome_db_grid_get_column_titles_visible (GnomeDbGrid *grid);
+#define gnome_db_grid_show_column_titles(grid) \
+	(gnome_db_grid_set_column_titles_visible (grid, TRUE))
+#define gnome_db_grid_hide_column_titles(grid) \
+	(gnome_db_grid_set_column_titles_visible (grid, FALSE))
 void             gnome_db_grid_hide_column (GnomeDbGrid *grid, gint col);
 void             gnome_db_grid_show_column (GnomeDbGrid *grid, gint col);
 
Index: libgnomedb/gnome-db-util.c
===================================================================
RCS file: /cvs/gnome/libgnomedb/libgnomedb/gnome-db-util.c,v
retrieving revision 1.55
diff -u -r1.55 gnome-db-util.c
--- libgnomedb/gnome-db-util.c	19 Sep 2003 13:40:36 -0000	1.55
+++ libgnomedb/gnome-db-util.c	27 Dec 2003 15:17:57 -0000
@@ -26,6 +26,7 @@
 #include <glib-object.h>
 #include <gtk/gtkbutton.h>
 #include <gtk/gtkcheckbutton.h>
+#include <gtk/gtkcheckmenuitem.h>
 #include <gtk/gtkcombo.h>
 #include <gtk/gtkfilesel.h>
 #include <gtk/gtkframe.h>
@@ -33,15 +34,18 @@
 #include <gtk/gtkhbox.h>
 #include <gtk/gtkhpaned.h>
 #include <gtk/gtkhseparator.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkimagemenuitem.h>
 #include <gtk/gtklabel.h>
-#include <gtk/gtkmenu.h>
 #include <gtk/gtkmain.h>
+#include <gtk/gtkmenu.h>
 #include <gtk/gtkmenuitem.h>
 #include <gtk/gtkmenushell.h>
 #include <gtk/gtkmessagedialog.h>
 #include <gtk/gtknotebook.h>
 #include <gtk/gtkradiobutton.h>
 #include <gtk/gtkscrolledwindow.h>
+#include <gtk/gtkseparatormenuitem.h>
 #include <gtk/gtkstatusbar.h>
 #include <gtk/gtkstock.h>
 #include <gtk/gtktable.h>
@@ -267,7 +271,7 @@
 {
 	GtkWidget *label;
 
-	label = gtk_label_new (text);
+	label = gtk_label_new_with_mnemonic (text);
 	gtk_label_set_selectable (GTK_LABEL (label), TRUE);
 	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
 	gtk_widget_show (label);
@@ -800,39 +804,83 @@
 }
 
 /**
- * gnome_db_yes_no_dialog
+ * gnome_db_new_alert
  */
-gboolean
-gnome_db_yes_no_dialog (GtkWidget *parent, const gchar *format, ...)
+GtkWidget *
+gnome_db_new_alert (GtkWindow *parent,
+		    GtkMessageType type,
+		    const gchar *primary_text,
+		    const gchar *secondary_text)
 {
-	va_list args;
-        gchar sz[2048];
+	const gchar *stock_id = NULL;
+	gchar *str;
 	GtkWidget *dialog;
-	GdkPixbuf *icon;
-	gboolean retval = FALSE;
+	GtkWidget *image;
+	GtkWidget *label;
+	GtkWidget *hbox;
+	GtkWidget *vbox;
 
-	/* build the message string */
-        va_start (args, format);
-        vsprintf (sz, format, args);
-        va_end (args);
+	g_return_val_if_fail (primary_text != NULL, NULL);
 
-	/* create the dialog */
-	dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
-					 GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION,
-					 GTK_BUTTONS_YES_NO, sz);
-	gtk_window_set_title (GTK_WINDOW (dialog), _("Question"));
-
-	icon = gdk_pixbuf_new_from_file (LIBGNOMEDB_ICONSDIR "/gnome-db.png", NULL);
-	if (icon) {
-		gtk_window_set_icon (GTK_WINDOW (dialog), icon);
-		g_object_unref (icon);
+	dialog = gtk_dialog_new_with_buttons ("",
+					     parent,
+					     GTK_DIALOG_DESTROY_WITH_PARENT |
+					     GTK_DIALOG_NO_SEPARATOR |
+					     GTK_DIALOG_MODAL,
+					     NULL);
+					     
+	gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+	gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
+	gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 12);
+
+	hbox = gtk_hbox_new (FALSE, 12);
+	gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
+	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox,
+			    TRUE, TRUE, 0);
+
+	switch (type) {
+	case GTK_MESSAGE_INFO:
+		stock_id = GTK_STOCK_DIALOG_INFO;
+		break;
+	case GTK_MESSAGE_WARNING:
+		stock_id = GTK_STOCK_DIALOG_WARNING;
+		break;
+	case GTK_MESSAGE_QUESTION:
+		stock_id = GTK_STOCK_DIALOG_QUESTION;
+		break;
+	case GTK_MESSAGE_ERROR:
+		stock_id = GTK_STOCK_DIALOG_ERROR;
+		break;
 	}
+	g_return_val_if_fail (stock_id != NULL, NULL);
 
-	if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES)
-		retval = TRUE;
-	gtk_widget_destroy (dialog);
+	image = gtk_image_new_from_stock (stock_id,
+					  GTK_ICON_SIZE_DIALOG);
+	gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
+	gtk_box_pack_start (GTK_BOX (hbox), image, TRUE, TRUE, 0);
+
+	vbox = gtk_vbox_new (FALSE, 6);
+	gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+
+	label = gtk_label_new (NULL);
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+	str = g_strconcat ("<span weight=\"bold\" size=\"larger\">",
+			   primary_text,
+			   "</span>",
+			   NULL);
+	gtk_label_set_markup (GTK_LABEL (label), str);
+	g_free (str);
+	gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
+
+	if (secondary_text != NULL) {
+		label = gtk_label_new (secondary_text);
+		gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+		gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+		gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
+	}
 
-	return retval;
+	return dialog;
 }
 
 /**
@@ -847,12 +895,15 @@
 
 	/* build the message string */
         va_start (args, format);
-        vsprintf (sz, format, args);
+        vsnprintf (sz, sizeof sz, format, args);
         va_end (args);
 
 	/* create the error message dialog */
-	dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
-					 GTK_BUTTONS_CLOSE, sz);
+	dialog = gnome_db_new_alert (NULL, GTK_MESSAGE_ERROR, sz, NULL);
+	gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
+				      gtk_button_new_from_stock (GTK_STOCK_OK),
+				      GTK_RESPONSE_OK);
+	gtk_widget_show_all (dialog);
 	gtk_dialog_run (GTK_DIALOG (dialog));
 	gtk_widget_destroy (dialog);
 }
@@ -872,12 +923,15 @@
 
 	/* build the message string */
         va_start (args, format);
-        vsprintf (sz, format, args);
+        vsnprintf (sz, sizeof sz, format, args);
         va_end (args);
 
-	/* create the error message dialog */
-	dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO,
-					 GTK_BUTTONS_CLOSE, sz);
+	/* create the info message dialog */
+	dialog = gnome_db_new_alert (NULL, GTK_MESSAGE_INFO, sz, NULL);
+	gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
+				      gtk_button_new_from_stock (GTK_STOCK_OK),
+				      GTK_RESPONSE_OK);
+	gtk_widget_show_all (dialog);
 	gtk_dialog_run (GTK_DIALOG (dialog));
 	gtk_widget_destroy (dialog);
 }
@@ -918,3 +972,39 @@
                 g_object_set_data (G_OBJECT (window), "Panel:WindowBusy", GINT_TO_POINTER (busy));
         }
 }
+
+GtkWidget *
+gnome_db_new_check_menu_item (const gchar *label,
+			      gboolean active,
+			      GCallback cb_func,
+			      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);
+
+	return item;
+}
+
+GtkWidget *
+gnome_db_new_menu_item (const gchar *label,
+		 	gboolean pixmap,
+		        GCallback cb_func,
+			gpointer user_data)
+{
+	GtkWidget *item;
+
+	if (pixmap)
+		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);
+
+	return item;
+}
Index: libgnomedb/gnome-db-util.h
===================================================================
RCS file: /cvs/gnome/libgnomedb/libgnomedb/gnome-db-util.h,v
retrieving revision 1.30
diff -u -r1.30 gnome-db-util.h
--- libgnomedb/gnome-db-util.h	19 Sep 2003 13:40:36 -0000	1.30
+++ libgnomedb/gnome-db-util.h	27 Dec 2003 15:17:58 -0000
@@ -25,11 +25,13 @@
 
 #include <libgda/gda-data-model.h>
 #include <gtk/gtkentry.h>
+#include <gtk/gtkmessagedialog.h>
 #include <gtk/gtkoptionmenu.h>
 #include <gtk/gtktextview.h>
 #include <gtk/gtktoolbar.h>
 #include <gtk/gtktreemodel.h>
 #include <gtk/gtkwidget.h>
+#include <gtk/gtkwindow.h>
 #ifdef BUILD_WITH_GNOME
 #include <libgnomeui/gnome-popup-menu.h>
 #endif
@@ -93,13 +95,27 @@
 void         gnome_db_text_set_text (GtkTextView *text, const gchar *contents, gint len);
 
 gchar       *gnome_db_select_file_dialog (GtkWidget *parent, const gchar *title);
-gboolean     gnome_db_yes_no_dialog (GtkWidget *parent, const gchar *format, ...);
+
+GtkWidget   *gnome_db_new_alert (GtkWindow *parent,
+				 GtkMessageType type,
+				 const gchar *primary_text,
+				 const gchar *secondary_text);
+
 void         gnome_db_show_error (const gchar *format, ...);
 void         gnome_db_show_message (const gchar *format, ...);
 
 void         gnome_db_push_cursor_busy (GtkWidget *window);
 void         gnome_db_pop_cursor_busy (GtkWidget *window);
 
+GtkWidget   *gnome_db_new_menu_item (const gchar *label,
+				     gboolean pixmap,
+				     GCallback cb_func,
+				     gpointer user_data);
+GtkWidget   *gnome_db_new_check_menu_item (const gchar *label,
+					   gboolean active,
+					   GCallback cb_func,
+					   gpointer user_data);
+
 G_END_DECLS
 
 #endif


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