glade3 r2048 - in trunk: . gladeui plugins/gtk+



Author: tvb
Date: Tue Nov 25 05:13:54 2008
New Revision: 2048
URL: http://svn.gnome.org/viewvc/glade3?rev=2048&view=rev

Log:

	* gladeui/glade-utils.c: Hijack the cntl-n accelerator too now.

	* plugins/gtk+/glade-column-types.c, plugins/gtk+/glade-model-data.c, plugins/gtk+/glade-store-editor.c:
	Enhanced model editing, now there is completion in type names, and column types are defined inline
	with no add or delete keys, model data can be edited and navigated without using the pointer either.



Modified:
   trunk/ChangeLog
   trunk/gladeui/glade-utils.c
   trunk/plugins/gtk+/glade-column-types.c
   trunk/plugins/gtk+/glade-model-data.c
   trunk/plugins/gtk+/glade-store-editor.c

Modified: trunk/gladeui/glade-utils.c
==============================================================================
--- trunk/gladeui/glade-utils.c	(original)
+++ trunk/gladeui/glade-utils.c	Tue Nov 25 05:13:54 2008
@@ -2294,7 +2294,8 @@
 	     ((event->state & GDK_CONTROL_MASK) && /* CNTL keys... */
 	      ((event->keyval == GDK_c || event->keyval == GDK_C) || /* CNTL-C (copy)  */
 	       (event->keyval == GDK_x || event->keyval == GDK_X) || /* CNTL-X (cut)   */
-	       (event->keyval == GDK_v || event->keyval == GDK_V))))) /* CNTL-V (paste) */
+	       (event->keyval == GDK_v || event->keyval == GDK_V) || /* CNTL-V (paste) */
+	       (event->keyval == GDK_n || event->keyval == GDK_N))))) /* CNTL-N (new project) */
 	{
 		return gtk_widget_event (win->focus_widget, 
 					 (GdkEvent *)event);

Modified: trunk/plugins/gtk+/glade-column-types.c
==============================================================================
--- trunk/plugins/gtk+/glade-column-types.c	(original)
+++ trunk/plugins/gtk+/glade-column-types.c	Tue Nov 25 05:13:54 2008
@@ -23,11 +23,12 @@
 
 #include <config.h>
 
-#include <gladeui/glade.h>
 #include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
 #include <glib/gi18n-lib.h>
 #include <string.h>
 
+#include <gladeui/glade.h>
 #include "glade-column-types.h"
 #include "glade-model-data.h"
 
@@ -36,6 +37,10 @@
 	COLUMN_NAME,
 	COLUMN_GTYPE,
 	COLUMN_COLUMN_NAME,
+	COLUMN_TYPE_EDITABLE,
+	COLUMN_NAME_EDITABLE,
+	COLUMN_TYPE_FOREGROUND,
+	COLUMN_TYPE_STYLE,
 	N_COLUMNS
 };
 
@@ -53,6 +58,37 @@
 	return strcmp (g_type_name (*a), g_type_name (*b));
 }
 
+static GType 
+lookup_type (const gchar *type_name)
+{
+	GtkTreeIter  iter;
+	gchar       *iter_type_name;
+	GType        type = 0;
+
+	if (gtk_tree_model_get_iter_first (types_model, &iter))
+	{
+		do 
+		{
+			iter_type_name = NULL;
+			gtk_tree_model_get (types_model, &iter,
+					    COLUMN_NAME, &iter_type_name,
+					    COLUMN_GTYPE, &type, 
+					    -1);
+			g_assert (iter_type_name);
+
+			if (strcmp (iter_type_name, type_name) == 0)
+			{
+				g_free (iter_type_name);
+				break;
+			}
+			
+			g_free (iter_type_name);
+		}
+		while (gtk_tree_model_iter_next (types_model, &iter));
+	}
+	return type;
+}
+
 static void
 column_types_store_populate_enums_flags (GtkTreeStore *store,
 					 gboolean      enums)
@@ -80,7 +116,10 @@
 			    strcmp (g_type_name (pclass->pspec->value_type), "GladeStock") == 0 ||
 			    strcmp (g_type_name (pclass->pspec->value_type), "GladeStockImage") == 0 ||
 			    strcmp (g_type_name (pclass->pspec->value_type), "GladeGtkImageType") == 0 ||
-			    strcmp (g_type_name (pclass->pspec->value_type), "GladeGtkButtonType") == 0)
+			    strcmp (g_type_name (pclass->pspec->value_type), "GladeGtkButtonType") == 0 ||
+			    strcmp (g_type_name (pclass->pspec->value_type), "GladeGnomeDruidPagePosition") == 0 ||
+			    strcmp (g_type_name (pclass->pspec->value_type), "GladeGnomeIconListSelectionMode") == 0 ||
+			    strcmp (g_type_name (pclass->pspec->value_type), "GladeGnomeMessageBoxType") == 0)
 				continue;
 
 			if ((enums ? G_TYPE_IS_ENUM (pclass->pspec->value_type) : 
@@ -220,15 +259,16 @@
 {
 	GladeEditorProperty parent_instance;
 
-	GtkComboBox      *combo;
 	GtkListStore     *store;
 	GtkTreeView      *view;
 	GtkTreeSelection *selection;
 
 	GladeNameContext *context;
 
-	gboolean          adding_column;
+	gboolean           adding_column;
+	gboolean           want_focus;
 	GtkTreeViewColumn *name_column;
+	GtkTreeViewColumn *type_column;
 } GladeEPropColumnTypes;
 
 GLADE_MAKE_EPROP (GladeEPropColumnTypes, glade_eprop_column_types)
@@ -311,7 +351,6 @@
 	glade_model_data_tree_free (data_tree);
 }
 
-
 static void
 eprop_column_append (GladeEditorProperty *eprop,
 		     GType type,
@@ -348,31 +387,10 @@
 	eprop_types->adding_column = FALSE;
 }
 
-static void
-glade_eprop_column_types_add_clicked (GtkWidget *button, 
-				      GladeEPropColumnTypes *eprop_types)
-{
-	GtkTreeIter iter;
-	GType type2add;
-	gchar *type_name, *column_name;
-	
-	if (gtk_combo_box_get_active_iter (eprop_types->combo, &iter) == FALSE)
-		return;
-	
-	gtk_tree_model_get (types_model, &iter,
-			    COLUMN_GTYPE, &type2add,
-			    -1);
-	
-	type_name = g_ascii_strdown (g_type_name (type2add), -1);
-	column_name = glade_name_context_new_name (eprop_types->context, type_name);
-	eprop_column_append (GLADE_EDITOR_PROPERTY (eprop_types), type2add, column_name);
-	g_free (column_name);
-	g_free (type_name);
-}
-
-static void
-glade_eprop_column_types_delete_clicked (GtkWidget *button, 
-					 GladeEditorProperty *eprop)
+static gboolean
+eprop_treeview_key_press (GtkWidget           *treeview,
+			  GdkEventKey         *event,
+			  GladeEditorProperty *eprop)
 {
 	/* Remove from list and commit value, dont touch the liststore except in load() */
 	GladeEPropColumnTypes *eprop_types = GLADE_EPROP_COLUMN_TYPES (eprop);
@@ -382,11 +400,15 @@
 	GValue                 value = { 0, };
 	gchar                 *column_name;
 
-	if (gtk_tree_selection_get_selected (eprop_types->selection, NULL, &iter))
+	if (event->keyval == GDK_Delete &&
+	    gtk_tree_selection_get_selected (eprop_types->selection, NULL, &iter))
 	{
 		gtk_tree_model_get (GTK_TREE_MODEL (eprop_types->store), &iter,
 				    COLUMN_COLUMN_NAME, &column_name, -1);
-		g_assert (column_name);
+
+		/* Cant delete the symbolic "add new" row */
+		if (!column_name)
+			return TRUE;
 
 		glade_property_get (eprop->property, &columns);
 		if (columns)
@@ -402,6 +424,8 @@
 		glade_command_push_group (_("Setting columns on %s"), 
 					  glade_widget_get_name (eprop->property->widget));
 
+		eprop_types->want_focus = TRUE;
+
 		g_value_init (&value, GLADE_TYPE_COLUMN_TYPE_LIST);
 		g_value_take_boxed (&value, columns);
 		glade_editor_property_commit (eprop, &value);
@@ -411,7 +435,12 @@
 		glade_command_pop_group ();
 
 		g_free (column_name);
+
+		eprop_types->want_focus = FALSE;
+
 	}
+
+	return (event->keyval == GDK_Delete);
 }
 
 static gboolean
@@ -479,6 +508,18 @@
 }
 
 static void
+eprop_column_add_new (GladeEPropColumnTypes *eprop_types)
+{
+	gtk_list_store_insert_with_values (eprop_types->store, NULL, -1,
+					   COLUMN_NAME, _("<type here to define a new column>"),
+					   COLUMN_TYPE_EDITABLE, TRUE,
+					   COLUMN_NAME_EDITABLE, FALSE,
+					   COLUMN_TYPE_FOREGROUND, "Gray",
+					   COLUMN_TYPE_STYLE, PANGO_STYLE_ITALIC,
+					   -1);
+}
+
+static void
 eprop_column_load (GladeEPropColumnTypes *eprop_types,
 		   GType type,
 		   const gchar *column_name)
@@ -487,37 +528,56 @@
 					   COLUMN_NAME, g_type_name (type),
 					   COLUMN_GTYPE, type,
 					   COLUMN_COLUMN_NAME, column_name,
+					   COLUMN_TYPE_EDITABLE, FALSE,
+					   COLUMN_NAME_EDITABLE, TRUE,
+					   COLUMN_TYPE_FOREGROUND, "Black",
+					   COLUMN_TYPE_STYLE, PANGO_STYLE_NORMAL,
 					   -1);
 }
 
-static gboolean
-eprop_types_focus_idle (GladeEPropColumnTypes *eprop_types)
+
+static void
+eprop_types_focus_cell (GladeEPropColumnTypes *eprop_types, gboolean add_cell)
 {
 	/* Focus and edit the first column of a newly added row */
 	if (eprop_types->store)
 	{
 		GtkTreePath *new_item_path;
-		GtkTreeIter  iter, *last_iter = NULL;
+		GtkTreeIter  iter;
+		gint n_children;
 
-		if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (eprop_types->store), &iter))
+		n_children = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (eprop_types->store), NULL);
+		if (n_children > (add_cell ? 0 : 1) &&
+		    gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (eprop_types->store),
+						   &iter,
+						   NULL,
+						   n_children - (add_cell ? 1 : 2)))
 		{
-			do {
-				if (last_iter)
-					gtk_tree_iter_free (last_iter);
-				last_iter = gtk_tree_iter_copy (&iter);
-			} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (eprop_types->store), &iter));
-
-			new_item_path = gtk_tree_model_get_path (GTK_TREE_MODEL (eprop_types->store), last_iter);
+			new_item_path = gtk_tree_model_get_path (GTK_TREE_MODEL (eprop_types->store), &iter);
 
 			gtk_widget_grab_focus (GTK_WIDGET (eprop_types->view));
 			gtk_tree_view_expand_to_path (eprop_types->view, new_item_path);
+
 			gtk_tree_view_set_cursor (eprop_types->view, new_item_path,
-						  eprop_types->name_column, TRUE);
+						  add_cell ? eprop_types->type_column : eprop_types->name_column, 
+						  add_cell ? FALSE : TRUE);
 			
 			gtk_tree_path_free (new_item_path);
-			gtk_tree_iter_free (last_iter);
 		}
 	}
+}
+
+static gboolean
+eprop_types_focus_new (GladeEPropColumnTypes *eprop_types)
+{
+	eprop_types_focus_cell (eprop_types, TRUE);
+	return FALSE;
+}
+
+static gboolean
+eprop_types_focus_name (GladeEPropColumnTypes *eprop_types)
+{
+	eprop_types_focus_cell (eprop_types, FALSE);
 	return FALSE;
 }
 
@@ -556,8 +616,12 @@
 		glade_name_context_add_name (eprop_types->context, data->column_name);
 	}
 
+	eprop_column_add_new (eprop_types);
+
 	if (eprop_types->adding_column && list)
-		g_idle_add ((GSourceFunc)eprop_types_focus_idle, eprop);
+		eprop_types_focus_name (eprop_types);
+	else if (eprop_types->want_focus)
+		eprop_types_focus_new (eprop_types);
 
 	g_signal_handlers_unblock_by_func (G_OBJECT (eprop_types->store), 
 					   eprop_treeview_row_deleted, eprop);
@@ -610,6 +674,7 @@
 	glade_command_push_group (_("Setting columns on %s"), 
 				  glade_widget_get_name (eprop->property->widget));
 
+	eprop_types->want_focus = TRUE;
 
 	g_value_init (&value, GLADE_TYPE_COLUMN_TYPE_LIST);
 	g_value_take_boxed (&value, columns);
@@ -627,32 +692,78 @@
 	}
 	glade_command_pop_group ();
 
+	eprop_types->want_focus = FALSE;
+
 	g_free (old_column_name);
 	g_free (column_name);
 }
 
+
+static void
+column_type_edited (GtkCellRendererText *cell,
+		    const gchar         *path,
+		    const gchar         *type_name,
+		    GladeEditorProperty *eprop)
+{
+	GladeEPropColumnTypes *eprop_types = GLADE_EPROP_COLUMN_TYPES (eprop);
+	GtkTreeIter            iter;
+	GType                  type;
+	gchar                 *column_name;
+
+	if (!gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (eprop_types->store), &iter, path))
+		return;
+
+	if ((type = lookup_type (type_name)) != 0)
+	{
+		column_name = glade_name_context_new_name (eprop_types->context, type_name);
+		eprop_column_append (eprop, type, column_name);
+		g_free (column_name);
+	}
+	else
+	{
+		eprop_types->want_focus = TRUE;
+		glade_editor_property_load (eprop, eprop->property);
+		eprop_types->want_focus = FALSE;
+	}
+}
+
+
+static void
+types_combo_editing_started (GtkCellRenderer       *renderer,
+			     GtkCellEditable       *editable,
+			     gchar                 *path,
+			     GladeEditorProperty   *eprop)
+{
+	GtkEntryCompletion *completion = gtk_entry_completion_new ();
+
+	gtk_entry_completion_set_model (completion, types_model);
+	gtk_entry_completion_set_text_column (completion, 0);
+	gtk_entry_completion_set_inline_completion (completion, TRUE);
+	gtk_entry_set_completion (GTK_ENTRY (GTK_BIN (editable)->child), completion);
+	g_object_unref (G_OBJECT (completion));
+}
+
+
 static GtkWidget *
 glade_eprop_column_types_create_input (GladeEditorProperty *eprop)
 {
 	GladeEPropColumnTypes *eprop_types = GLADE_EPROP_COLUMN_TYPES (eprop);
-	GtkWidget *vbox, *hbox, *button, *swin, *label;
+	GtkWidget *vbox, *swin, *label;
 	GtkCellRenderer *cell;
-	GtkTreeViewColumn *col;
 	gchar *string;
 
 	vbox = gtk_vbox_new (FALSE, 2);
 	
-	hbox = gtk_hbox_new (FALSE, 4);
+/* 	hbox = gtk_hbox_new (FALSE, 4); */
 
 	if (!types_model)
 	{
 		/* We make sure to do this after all the adaptors are parsed 
 		 * because we load the enums/flags from the adaptors
 		 */
-		types_model = (GtkTreeModel *)gtk_tree_store_new (N_COLUMNS,
+		types_model = (GtkTreeModel *)gtk_tree_store_new (2,
 								  G_TYPE_STRING,
-								  G_TYPE_GTYPE,
-								  G_TYPE_STRING);
+								  G_TYPE_GTYPE);
 
 		column_types_store_populate (GTK_TREE_STORE (types_model));
 	}
@@ -666,34 +777,34 @@
 	gtk_misc_set_padding (GTK_MISC (label), 2, 4);
 	gtk_box_pack_start (GTK_BOX (vbox), label,  FALSE, TRUE, 0);
 
-	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+/* 	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); */
 	
-	eprop_types->combo = GTK_COMBO_BOX (gtk_combo_box_new_with_model (types_model));
-	cell = gtk_cell_renderer_text_new ();
-	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (eprop_types->combo),
-				    cell, TRUE);
-	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (eprop_types->combo),
-					cell, "text", COLUMN_NAME, NULL);
-	gtk_combo_box_set_active (eprop_types->combo, 0);
-	gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (eprop_types->combo), TRUE, TRUE, 0);
-
-	button = gtk_button_new ();
-	gtk_button_set_image (GTK_BUTTON (button),
-			      gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON));
-	gtk_box_pack_start (GTK_BOX (hbox), button,  FALSE, FALSE, 0);
-
-	g_signal_connect (G_OBJECT (button), "clicked",
-			  G_CALLBACK (glade_eprop_column_types_add_clicked), 
-			  eprop_types);
-	
-	button = gtk_button_new ();
-	gtk_button_set_image (GTK_BUTTON (button),
-			      gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_BUTTON));
-	gtk_box_pack_start (GTK_BOX (hbox), button,  FALSE, FALSE, 0);
-
-	g_signal_connect (G_OBJECT (button), "clicked",
-			  G_CALLBACK (glade_eprop_column_types_delete_clicked), 
-			  eprop_types);
+/* 	eprop_types->combo = GTK_COMBO_BOX (gtk_combo_box_new_with_model (types_model)); */
+/* 	cell = gtk_cell_renderer_text_new (); */
+/* 	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (eprop_types->combo), */
+/* 				    cell, TRUE); */
+/* 	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (eprop_types->combo), */
+/* 					cell, "text", COLUMN_NAME, NULL); */
+/* 	gtk_combo_box_set_active (eprop_types->combo, 0); */
+/* 	gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET (eprop_types->combo), TRUE, TRUE, 0); */
+
+/* 	button = gtk_button_new (); */
+/* 	gtk_button_set_image (GTK_BUTTON (button), */
+/* 			      gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON)); */
+/* 	gtk_box_pack_start (GTK_BOX (hbox), button,  FALSE, FALSE, 0); */
+
+/* 	g_signal_connect (G_OBJECT (button), "clicked", */
+/* 			  G_CALLBACK (glade_eprop_column_types_add_clicked),  */
+/* 			  eprop_types); */
+	
+/* 	button = gtk_button_new (); */
+/* 	gtk_button_set_image (GTK_BUTTON (button), */
+/* 			      gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_BUTTON)); */
+/* 	gtk_box_pack_start (GTK_BOX (hbox), button,  FALSE, FALSE, 0); */
+
+/* 	g_signal_connect (G_OBJECT (button), "clicked", */
+/* 			  G_CALLBACK (glade_eprop_column_types_delete_clicked),  */
+/* 			  eprop_types); */
 	
 	swin = gtk_scrolled_window_new (NULL, NULL);
 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swin), GTK_SHADOW_IN);
@@ -703,7 +814,11 @@
 	eprop_types->store = gtk_list_store_new (N_COLUMNS,
 						 G_TYPE_STRING,
 						 G_TYPE_GTYPE,
-						 G_TYPE_STRING);
+						 G_TYPE_STRING,
+						 G_TYPE_BOOLEAN,
+						 G_TYPE_BOOLEAN,
+						 G_TYPE_STRING,
+						 PANGO_TYPE_STYLE);
 
 	g_signal_connect (eprop_types->store, "row-deleted",
 			  G_CALLBACK (eprop_treeview_row_deleted),
@@ -711,31 +826,52 @@
 	
 	eprop_types->view = (GtkTreeView *)gtk_tree_view_new_with_model (GTK_TREE_MODEL (eprop_types->store));
 	eprop_types->selection = gtk_tree_view_get_selection (eprop_types->view);
-
 	
 	gtk_tree_view_set_reorderable (eprop_types->view, TRUE);
 	//gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
 
+	g_signal_connect (eprop_types->view, "key-press-event",
+			  G_CALLBACK (eprop_treeview_key_press),
+			  eprop);
+
+
 	/* type column */
-	col = gtk_tree_view_column_new_with_attributes ("Column type", 
-							gtk_cell_renderer_text_new (),
-							"text", COLUMN_NAME,
-							NULL);
-	gtk_tree_view_append_column (eprop_types->view, col);	
+	cell = gtk_cell_renderer_combo_new ();
+	g_object_set (G_OBJECT (cell), 
+		      "text-column", COLUMN_NAME,
+		      "model", types_model, 
+		      NULL);
+
+	g_signal_connect (G_OBJECT (cell), "editing-started",
+			  G_CALLBACK (types_combo_editing_started), eprop);
+
+	g_signal_connect (G_OBJECT (cell), "edited",
+			  G_CALLBACK (column_type_edited), eprop);
+
+	eprop_types->type_column = 
+		gtk_tree_view_column_new_with_attributes ("Column type", cell,
+							  "foreground", COLUMN_TYPE_FOREGROUND,
+							  "style", COLUMN_TYPE_STYLE,
+							  "editable", COLUMN_TYPE_EDITABLE,
+							  "text", COLUMN_NAME,
+							  NULL);
 
+	gtk_tree_view_column_set_expand (eprop_types->type_column, TRUE);
+	gtk_tree_view_append_column (eprop_types->view, eprop_types->type_column);	
 
 	/* name column */
 	cell = gtk_cell_renderer_text_new ();
-	g_object_set (G_OBJECT (cell), "editable", TRUE, NULL);
-
 	g_signal_connect (G_OBJECT (cell), "edited",
 			  G_CALLBACK (column_name_edited), eprop);
 	
 	eprop_types->name_column = 
-		gtk_tree_view_column_new_with_attributes ("Column name", 
-							  cell,
+		gtk_tree_view_column_new_with_attributes ("Column name",  cell,
+							  "editable", COLUMN_NAME_EDITABLE,
 							  "text", COLUMN_COLUMN_NAME,
 							  NULL);
+
+	gtk_tree_view_column_set_expand (eprop_types->name_column, TRUE);
+
 	gtk_tree_view_append_column (eprop_types->view, eprop_types->name_column);	
 	gtk_container_add (GTK_CONTAINER (swin), GTK_WIDGET (eprop_types->view));
 	

Modified: trunk/plugins/gtk+/glade-model-data.c
==============================================================================
--- trunk/plugins/gtk+/glade-model-data.c	(original)
+++ trunk/plugins/gtk+/glade-model-data.c	Tue Nov 25 05:13:54 2008
@@ -24,6 +24,7 @@
 
 #include <gladeui/glade.h>
 #include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
 #include <glib/gi18n-lib.h>
 #include <string.h>
 
@@ -251,7 +252,9 @@
 
 	/* Used for setting focus on newly added rows */
 	gboolean             adding_row;
-	GtkTreeViewColumn   *first_column;
+	gboolean             want_focus;
+	gint                 editing_row;
+	gint                 editing_column;
 } GladeEPropModelData;
 
 GLADE_MAKE_EPROP (GladeEPropModelData, glade_eprop_model_data)
@@ -313,11 +316,28 @@
 	return FALSE;
 }
 
+static gboolean
+update_and_focus_data_tree_idle (GladeEditorProperty *eprop)
+{
+	GladeEPropModelData *eprop_data = GLADE_EPROP_MODEL_DATA (eprop);
+	GValue               value = { 0, };
+
+	eprop_data->want_focus = TRUE;
+	
+	g_value_init (&value, GLADE_TYPE_MODEL_DATA_TREE);
+	g_value_take_boxed (&value, eprop_data->pending_data_tree);
+	glade_editor_property_commit (eprop, &value);
+	g_value_unset (&value);
+
+	eprop_data->pending_data_tree = NULL;
+
+	eprop_data->want_focus = FALSE;
+
+	return FALSE;
+}
 
-/* User pressed add: append row and commit values  */
 static void
-glade_eprop_model_data_add_clicked (GtkWidget *button, 
-				    GladeEditorProperty *eprop)
+glade_eprop_model_data_add_row (GladeEditorProperty *eprop)
 {
 	GladeEPropModelData *eprop_data = GLADE_EPROP_MODEL_DATA (eprop);
 	GValue value = { 0, };
@@ -349,10 +369,8 @@
 	eprop_data->adding_row = FALSE;
 }
 
-/* User pressed delete: remove selected row and commit values  */
 static void
-glade_eprop_model_data_delete_clicked (GtkWidget *button, 
-				       GladeEditorProperty *eprop)
+glade_eprop_model_data_delete_selected (GladeEditorProperty *eprop)
 {
 	GtkTreeIter iter;
 	GladeEPropModelData *eprop_data = GLADE_EPROP_MODEL_DATA (eprop);
@@ -384,7 +402,40 @@
 	eprop_data->pending_data_tree = data_tree;
 	g_idle_add ((GSourceFunc)update_data_tree_idle, eprop);
 }
- 
+
+static void
+glade_eprop_model_data_add_clicked (GtkWidget *button, 
+				    GladeEditorProperty *eprop)
+{
+	glade_eprop_model_data_add_row (eprop);
+}
+
+static void
+glade_eprop_model_data_delete_clicked (GtkWidget *button, 
+				       GladeEditorProperty *eprop)
+{
+	glade_eprop_model_data_delete_selected (eprop);
+}
+
+static gboolean
+eprop_treeview_key_press (GtkWidget           *treeview,
+			  GdkEventKey         *event,
+			  GladeEditorProperty *eprop)
+{
+	if (event->keyval == GDK_Delete)
+	{
+		glade_eprop_model_data_delete_selected (eprop);
+		return TRUE;
+	}
+	else if ((event->state & GDK_CONTROL_MASK) != 0 &&
+		 (event->keyval == GDK_n || event->keyval == GDK_N))
+	{
+		glade_eprop_model_data_add_row (eprop);
+		return TRUE;
+	}
+
+	return FALSE;
+} 
 
 static gboolean
 data_changed_idle (GladeEditorProperty *eprop)
@@ -542,11 +593,13 @@
 
 	g_value_set_boolean (&data->value, !active);
 
+	eprop_data->editing_row    = row;
+	eprop_data->editing_column = colnum;
 	if (eprop_data->pending_data_tree)
 		glade_model_data_tree_free (eprop_data->pending_data_tree);
 
 	eprop_data->pending_data_tree = data_tree;
-	g_idle_add ((GSourceFunc)update_data_tree_idle, eprop);
+	g_idle_add ((GSourceFunc)update_and_focus_data_tree_idle, eprop);
 }
 
 static void
@@ -593,11 +646,13 @@
 	{
 		g_value_set_string (&data->value, new_text);
 		
+		eprop_data->editing_row    = row;
+		eprop_data->editing_column = colnum;
 		if (eprop_data->pending_data_tree)
 			glade_model_data_tree_free (eprop_data->pending_data_tree);
 		
 		eprop_data->pending_data_tree = data_tree;
-		g_idle_add ((GSourceFunc)update_data_tree_idle, eprop);
+		g_idle_add ((GSourceFunc)update_and_focus_data_tree_idle, eprop);
 	}
 	else
 		glade_model_data_tree_free (data_tree);
@@ -622,7 +677,6 @@
 	if (!gtk_tree_model_get_iter_from_string (GTK_TREE_MODEL (eprop_data->store), &iter, path))
 		return;
 
-
 	gtk_tree_model_get (GTK_TREE_MODEL (eprop_data->store), &iter,
 			    COLUMN_ROW, &row,
 			    -1);
@@ -644,11 +698,13 @@
 	g_value_unset (value);
 	g_free (value);
 	
+	eprop_data->editing_row    = row;
+	eprop_data->editing_column = colnum;
 	if (eprop_data->pending_data_tree)
 		glade_model_data_tree_free (eprop_data->pending_data_tree);
 
 	eprop_data->pending_data_tree = data_tree;
-	g_idle_add ((GSourceFunc)update_data_tree_idle, eprop);
+	g_idle_add ((GSourceFunc)update_and_focus_data_tree_idle, eprop);
 }
 
 static GtkTreeViewColumn *
@@ -664,6 +720,7 @@
 
 	gtk_tree_view_column_set_title (column, data->name);
 	gtk_tree_view_column_set_resizable (column, TRUE);
+	gtk_tree_view_column_set_expand (column, TRUE);
 
 	/* Support enum and flag types, and a hardcoded list of fundamental types */
 	if (type == G_TYPE_CHAR ||
@@ -790,8 +847,6 @@
 	if (!data_tree || !data_tree->children || !data_tree->children->children)
 		return;
 
-	eprop_data->first_column = NULL;
-
 	/* Append new columns */
 	for (colnum = 0, iter_node = data_tree->children->children; iter_node; 
 	     colnum++, iter_node = iter_node->next)
@@ -800,44 +855,72 @@
 
 		column = eprop_model_generate_column (eprop, colnum, iter_data);
 		gtk_tree_view_append_column (eprop_data->view, column);
-
-		if (!eprop_data->first_column)
-			eprop_data->first_column = column;
 	}
 }
 
-static gboolean
-eprop_data_focus_idle (GladeEPropModelData *eprop_data)
+static void
+eprop_data_focus_new (GladeEPropModelData *eprop_data)
 {
 	/* Focus and edit the first column of a newly added row */
-	if (eprop_data->store && eprop_data->first_column)
+	if (eprop_data->store)
 	{
 		GtkTreePath *new_item_path;
-		GtkTreeIter  iter, *last_iter = NULL;
+		GtkTreeIter  iter;
+		GtkTreeViewColumn *column;
+		gint n_children;
+
+		n_children = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (eprop_data->store), NULL);
+
+		if ((column = gtk_tree_view_get_column (eprop_data->view, eprop_data->editing_column)) != NULL &&
+		    n_children > 0 && 
+		    gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (eprop_data->store),
+						   &iter,
+						   NULL,
+						   n_children - 1))
 
-		if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (eprop_data->store), &iter))
 		{
-			do {
-				if (last_iter)
-					gtk_tree_iter_free (last_iter);
-				last_iter = gtk_tree_iter_copy (&iter);
-			} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (eprop_data->store), &iter));
-
-			new_item_path = gtk_tree_model_get_path (GTK_TREE_MODEL (eprop_data->store), last_iter);
+			new_item_path = gtk_tree_model_get_path (GTK_TREE_MODEL (eprop_data->store), &iter);
 
 			gtk_widget_grab_focus (GTK_WIDGET (eprop_data->view));
 			gtk_tree_view_expand_to_path (eprop_data->view, new_item_path);
 			gtk_tree_view_set_cursor (eprop_data->view, new_item_path,
-						  eprop_data->first_column, TRUE);
+						  column, TRUE);
 			
 			gtk_tree_path_free (new_item_path);
-			gtk_tree_iter_free (last_iter);
 		}
 	}
-	return FALSE;
 }
 
 static void
+eprop_data_focus_editing_cell (GladeEPropModelData *eprop_data)
+{
+	/* Focus and edit the first column of a newly added row */
+	if (eprop_data->store && eprop_data->want_focus && 
+	    eprop_data->editing_column >= 0 && eprop_data->editing_row >= 0)
+	{
+		GtkTreePath *item_path;
+		GtkTreeIter  iter;
+		GtkTreeViewColumn *column;
+
+		if ((column = gtk_tree_view_get_column (eprop_data->view, eprop_data->editing_column)) != NULL &&
+		    gtk_tree_model_iter_nth_child (GTK_TREE_MODEL (eprop_data->store),
+						   &iter,
+						   NULL,
+						   eprop_data->editing_row))
+		{
+			item_path = gtk_tree_model_get_path (GTK_TREE_MODEL (eprop_data->store), &iter);
+
+			gtk_widget_grab_focus (GTK_WIDGET (eprop_data->view));
+			gtk_tree_view_expand_to_path (eprop_data->view, item_path);
+			gtk_tree_view_set_cursor (eprop_data->view, item_path,
+						  column, FALSE);
+			gtk_tree_path_free (item_path);
+		}
+	}
+}
+
+
+static void
 glade_eprop_model_data_load (GladeEditorProperty *eprop, 
 			     GladeProperty       *property)
 {
@@ -870,8 +953,14 @@
 	/* Create new columns with renderers */
 	eprop_model_data_generate_columns (eprop);
 
-	if (eprop_data->adding_row && eprop_data->store && eprop_data->first_column)
-		g_idle_add ((GSourceFunc)eprop_data_focus_idle, eprop_data);
+	if (eprop_data->store)
+	{
+		if (eprop_data->adding_row)
+			eprop_data_focus_new (eprop_data);
+		else if (eprop_data->want_focus && 
+			 eprop_data->editing_row >= 0 && eprop_data->editing_column >= 0)
+			eprop_data_focus_editing_cell (eprop_data);
+	}
 }
 
 static GtkWidget *
@@ -921,12 +1010,17 @@
 	gtk_box_pack_start (GTK_BOX (vbox), swin, TRUE, TRUE, 0);
 
 	eprop_data->view = (GtkTreeView *)gtk_tree_view_new ();
+
+	g_signal_connect (eprop_data->view, "key-press-event",
+			  G_CALLBACK (eprop_treeview_key_press),
+			  eprop);
+
 	
 	gtk_tree_view_set_reorderable (GTK_TREE_VIEW (eprop_data->view), TRUE);
 	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (eprop_data->view), TRUE);
 	gtk_container_add (GTK_CONTAINER (swin), GTK_WIDGET (eprop_data->view));
 
-	g_object_set (G_OBJECT (vbox), "height-request", 190, NULL);
+	g_object_set (G_OBJECT (vbox), "height-request", 300, NULL);
 	
 	gtk_widget_show_all (vbox);
 	return vbox;

Modified: trunk/plugins/gtk+/glade-store-editor.c
==============================================================================
--- trunk/plugins/gtk+/glade-store-editor.c	(original)
+++ trunk/plugins/gtk+/glade-store-editor.c	Tue Nov 25 05:13:54 2008
@@ -196,7 +196,8 @@
 	/* Add descriptive label */
 	label = gtk_label_new (_("Define columns for your liststore, "
 				 "giving them meaningful names will help you to retrieve "
-				 "them when setting cell renderer attributes."));
+				 "them when setting cell renderer attributes (press the "
+				 "Delete key to remove the selected column)"));
 	gtk_label_set_line_wrap (GTK_LABEL(label), TRUE);
 	gtk_label_set_line_wrap_mode (GTK_LABEL(label), PANGO_WRAP_WORD);
 	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 6);
@@ -220,7 +221,8 @@
 	gtk_container_add (GTK_CONTAINER (alignment), vbox);
 
 	/* Add descriptive label */
-	label = gtk_label_new (_("Add remove and edit rows of data (define some columns first)."));
+	label = gtk_label_new (_("Add remove and edit rows of data (you can optionally use CNTL-N to add "
+				 "new rows and the Delete key to remove the selected row)"));
 	gtk_label_set_line_wrap (GTK_LABEL(label), TRUE);
 	gtk_label_set_line_wrap_mode (GTK_LABEL(label), PANGO_WRAP_WORD);
 	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 6);



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