summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTristan Van Berkom <tvb@src.gnome.org>2008-11-25 05:13:54 +0000
committerTristan Van Berkom <tvb@src.gnome.org>2008-11-25 05:13:54 +0000
commitf8371bbb8c234e5d1e209123ab0a5ac80b4d1867 (patch)
treea59136ed9124f85d6eabeff0e35f307610873e2e
parent59e22199087f62e2c9cd7f64e041f521cee0576f (diff)
downloadglade-f8371bbb8c234e5d1e209123ab0a5ac80b4d1867.tar.gz
Hijack the cntl-n accelerator too now.
* 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. svn path=/trunk/; revision=2048
-rw-r--r--ChangeLog8
-rw-r--r--gladeui/glade-utils.c3
-rw-r--r--plugins/gtk+/glade-column-types.c316
-rw-r--r--plugins/gtk+/glade-model-data.c164
-rw-r--r--plugins/gtk+/glade-store-editor.c6
5 files changed, 369 insertions, 128 deletions
diff --git a/ChangeLog b/ChangeLog
index a82ce28f..93598ef6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-11-25 Tristan Van Berkom <tvb@gnome.org>
+
+ * 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.
+
2008-11-23 Tristan Van Berkom <tvb@gnome.org>
* gladeui/glade-widget.c:
diff --git a/gladeui/glade-utils.c b/gladeui/glade-utils.c
index bf117102..166a1bd3 100644
--- a/gladeui/glade-utils.c
+++ b/gladeui/glade-utils.c
@@ -2294,7 +2294,8 @@ glade_utils_hijack_key_press (GtkWindow *win,
((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);
diff --git a/plugins/gtk+/glade-column-types.c b/plugins/gtk+/glade-column-types.c
index 29b0cf4d..061608c1 100644
--- a/plugins/gtk+/glade-column-types.c
+++ b/plugins/gtk+/glade-column-types.c
@@ -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 @@ enum
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 @@ type_alpha_sort (GType *a, GType *b)
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 @@ column_types_store_populate_enums_flags (GtkTreeStore *store,
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 @@ typedef struct
{
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 @@ eprop_column_adjust_rows (GladeEditorProperty *eprop, GList *columns)
glade_model_data_tree_free (data_tree);
}
-
static void
eprop_column_append (GladeEditorProperty *eprop,
GType type,
@@ -348,31 +387,10 @@ eprop_column_append (GladeEditorProperty *eprop,
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 @@ glade_eprop_column_types_delete_clicked (GtkWidget *button,
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_eprop_column_types_delete_clicked (GtkWidget *button,
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_eprop_column_types_delete_clicked (GtkWidget *button,
glade_command_pop_group ();
g_free (column_name);
+
+ eprop_types->want_focus = FALSE;
+
}
+
+ return (event->keyval == GDK_Delete);
}
static gboolean
@@ -479,6 +508,18 @@ eprop_treeview_row_deleted (GtkTreeModel *tree_model,
}
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 @@ eprop_column_load (GladeEPropColumnTypes *eprop_types,
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;
-
- if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (eprop_types->store), &iter))
+ GtkTreeIter iter;
+ gint n_children;
+
+ 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_eprop_column_types_load (GladeEditorProperty *eprop, GladeProperty *proper
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 @@ column_name_edited (GtkCellRendererText *cell,
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 @@ column_name_edited (GtkCellRendererText *cell,
}
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 @@ glade_eprop_column_types_create_input (GladeEditorProperty *eprop)
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);
+/* 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);
+/* 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 @@ glade_eprop_column_types_create_input (GladeEditorProperty *eprop)
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 @@ glade_eprop_column_types_create_input (GladeEditorProperty *eprop)
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));
diff --git a/plugins/gtk+/glade-model-data.c b/plugins/gtk+/glade-model-data.c
index accf1865..4940fda2 100644
--- a/plugins/gtk+/glade-model-data.c
+++ b/plugins/gtk+/glade-model-data.c
@@ -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 @@ typedef struct
/* 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 @@ update_data_tree_idle (GladeEditorProperty *eprop)
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 @@ glade_eprop_model_data_add_clicked (GtkWidget *button,
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 @@ glade_eprop_model_data_delete_clicked (GtkWidget *button,
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 @@ value_toggled (GtkCellRendererToggle *cell,
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 @@ value_i18n_clicked (GladeCellRendererButton *cell,
{
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 @@ value_text_edited (GtkCellRendererText *cell,
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 @@ value_text_edited (GtkCellRendererText *cell,
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 @@ eprop_model_generate_column (GladeEditorProperty *eprop,
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 @@ eprop_model_data_generate_columns (GladeEditorProperty *eprop)
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 @@ eprop_model_data_generate_columns (GladeEditorProperty *eprop)
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;
- 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));
+ n_children = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (eprop_data->store), NULL);
- new_item_path = gtk_tree_model_get_path (GTK_TREE_MODEL (eprop_data->store), last_iter);
+ 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))
+
+ {
+ 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 @@ glade_eprop_model_data_load (GladeEditorProperty *eprop,
/* 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 @@ glade_eprop_model_data_create_input (GladeEditorProperty *eprop)
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;
diff --git a/plugins/gtk+/glade-store-editor.c b/plugins/gtk+/glade-store-editor.c
index fad1618a..c1e29f1a 100644
--- a/plugins/gtk+/glade-store-editor.c
+++ b/plugins/gtk+/glade-store-editor.c
@@ -196,7 +196,8 @@ glade_store_editor_new (GladeWidgetAdaptor *adaptor,
/* 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 @@ glade_store_editor_new (GladeWidgetAdaptor *adaptor,
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);