summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Blandford <jrb@redhat.com>2001-09-25 16:44:39 +0000
committerJonathan Blandford <jrb@src.gnome.org>2001-09-25 16:44:39 +0000
commit92841cb95add212c35b2ef58129f043c33676c52 (patch)
treea58a60c4bc75ea3f716bfd59d3c193cf417fc5f4
parent8a2d408daed1b616ab760cdfeec050cb6e54c1de (diff)
downloadgdk-pixbuf-92841cb95add212c35b2ef58129f043c33676c52.tar.gz
Make a GtkCellEditable (get_widget_window_size): Change to let it honor
Tue Sep 25 12:34:42 2001 Jonathan Blandford <jrb@redhat.com> * gtk/gtkentry.c: Make a GtkCellEditable (get_widget_window_size): Change to let it honor size_allocate when a CellEditable. * gtk/gtktreeview.c: M-x clean-line-ends. Lots of focus and editable changes. (gtk_tree_view_set_cursor): Now you can set the cursor horizontally, as well as start editing. * gtk/gtkstyle.c (gtk_default_draw_check): changing toggle drawing code to look more like the other check buttons. * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_get_size): Change the way we calculate cell size. * gtk/gtkmarshal.list (VOID:STRING,STRING): new marshaller. * demos/gtk-demo/sizegroup.c: Add mnemonics. * gtk/gtkcellrenderer.c (gtk_cell_renderer_get_size): Fix docs. Fix logic. * gtk/gtkcellrenderertext.c: Change to be editable. * gtk/gtkcellrenderertoggle.c: Change to be activatable. * test/testtreesort.c: Fix misspelling * test/testreecolumns.c: Add mnemonics. * test/testreeedit.c: New test program.
-rw-r--r--ChangeLog34
-rw-r--r--ChangeLog.pre-2-034
-rw-r--r--ChangeLog.pre-2-1034
-rw-r--r--ChangeLog.pre-2-234
-rw-r--r--ChangeLog.pre-2-434
-rw-r--r--ChangeLog.pre-2-634
-rw-r--r--ChangeLog.pre-2-834
-rw-r--r--demos/gtk-demo/appwindow.c10
-rw-r--r--demos/gtk-demo/sizegroup.c13
-rw-r--r--docs/tree-column-sizing.txt2
-rw-r--r--gtk/gtkcellrenderer.c56
-rw-r--r--gtk/gtkcellrenderertext.c96
-rw-r--r--gtk/gtkcellrenderertext.h4
-rw-r--r--gtk/gtkcellrenderertoggle.c63
-rw-r--r--gtk/gtkcellrenderertoggle.h3
-rw-r--r--gtk/gtkentry.c80
-rw-r--r--gtk/gtkentry.h4
-rw-r--r--gtk/gtkmarshal.list1
-rw-r--r--gtk/gtkmarshalers.list1
-rw-r--r--gtk/gtkstyle.c15
-rw-r--r--gtk/gtktreeprivate.h1
-rw-r--r--gtk/gtktreeview.c787
-rw-r--r--gtk/gtktreeview.h5
-rw-r--r--gtk/gtktreeviewcolumn.c197
-rw-r--r--gtk/gtktreeviewcolumn.h3
-rw-r--r--tests/Makefile.am6
-rw-r--r--tests/testtreecolumns.c8
-rw-r--r--tests/testtreeedit.c140
-rw-r--r--tests/testtreefocus.c4
-rw-r--r--tests/testtreesort.c2
30 files changed, 1233 insertions, 506 deletions
diff --git a/ChangeLog b/ChangeLog
index bb81bc4b9..b3dc1a473 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+Tue Sep 25 12:34:42 2001 Jonathan Blandford <jrb@redhat.com>
+
+ * gtk/gtkentry.c: Make a GtkCellEditable
+ (get_widget_window_size): Change to let it honor size_allocate
+ when a CellEditable.
+
+ * gtk/gtktreeview.c: M-x clean-line-ends. Lots of focus and
+ editable changes.
+ (gtk_tree_view_set_cursor): Now you can set the cursor
+ horizontally, as well as start editing.
+
+ * gtk/gtkstyle.c (gtk_default_draw_check): changing toggle drawing
+ code to look more like the other check buttons.
+
+ * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_get_size):
+ Change the way we calculate cell size.
+
+ * gtk/gtkmarshal.list (VOID:STRING,STRING): new marshaller.
+
+ * demos/gtk-demo/sizegroup.c: Add mnemonics.
+
+ * gtk/gtkcellrenderer.c (gtk_cell_renderer_get_size): Fix docs.
+ Fix logic.
+
+ * gtk/gtkcellrenderertext.c: Change to be editable.
+
+ * gtk/gtkcellrenderertoggle.c: Change to be activatable.
+
+ * test/testtreesort.c: Fix misspelling
+
+ * test/testreecolumns.c: Add mnemonics.
+
+ * test/testreeedit.c: New test program.
+
2001-09-25 Havoc Pennington <hp@pobox.com>
* gtk/gtkwindow.c: Put notes in gtk_window_set_has_frame(),
diff --git a/ChangeLog.pre-2-0 b/ChangeLog.pre-2-0
index bb81bc4b9..b3dc1a473 100644
--- a/ChangeLog.pre-2-0
+++ b/ChangeLog.pre-2-0
@@ -1,3 +1,37 @@
+Tue Sep 25 12:34:42 2001 Jonathan Blandford <jrb@redhat.com>
+
+ * gtk/gtkentry.c: Make a GtkCellEditable
+ (get_widget_window_size): Change to let it honor size_allocate
+ when a CellEditable.
+
+ * gtk/gtktreeview.c: M-x clean-line-ends. Lots of focus and
+ editable changes.
+ (gtk_tree_view_set_cursor): Now you can set the cursor
+ horizontally, as well as start editing.
+
+ * gtk/gtkstyle.c (gtk_default_draw_check): changing toggle drawing
+ code to look more like the other check buttons.
+
+ * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_get_size):
+ Change the way we calculate cell size.
+
+ * gtk/gtkmarshal.list (VOID:STRING,STRING): new marshaller.
+
+ * demos/gtk-demo/sizegroup.c: Add mnemonics.
+
+ * gtk/gtkcellrenderer.c (gtk_cell_renderer_get_size): Fix docs.
+ Fix logic.
+
+ * gtk/gtkcellrenderertext.c: Change to be editable.
+
+ * gtk/gtkcellrenderertoggle.c: Change to be activatable.
+
+ * test/testtreesort.c: Fix misspelling
+
+ * test/testreecolumns.c: Add mnemonics.
+
+ * test/testreeedit.c: New test program.
+
2001-09-25 Havoc Pennington <hp@pobox.com>
* gtk/gtkwindow.c: Put notes in gtk_window_set_has_frame(),
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index bb81bc4b9..b3dc1a473 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,37 @@
+Tue Sep 25 12:34:42 2001 Jonathan Blandford <jrb@redhat.com>
+
+ * gtk/gtkentry.c: Make a GtkCellEditable
+ (get_widget_window_size): Change to let it honor size_allocate
+ when a CellEditable.
+
+ * gtk/gtktreeview.c: M-x clean-line-ends. Lots of focus and
+ editable changes.
+ (gtk_tree_view_set_cursor): Now you can set the cursor
+ horizontally, as well as start editing.
+
+ * gtk/gtkstyle.c (gtk_default_draw_check): changing toggle drawing
+ code to look more like the other check buttons.
+
+ * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_get_size):
+ Change the way we calculate cell size.
+
+ * gtk/gtkmarshal.list (VOID:STRING,STRING): new marshaller.
+
+ * demos/gtk-demo/sizegroup.c: Add mnemonics.
+
+ * gtk/gtkcellrenderer.c (gtk_cell_renderer_get_size): Fix docs.
+ Fix logic.
+
+ * gtk/gtkcellrenderertext.c: Change to be editable.
+
+ * gtk/gtkcellrenderertoggle.c: Change to be activatable.
+
+ * test/testtreesort.c: Fix misspelling
+
+ * test/testreecolumns.c: Add mnemonics.
+
+ * test/testreeedit.c: New test program.
+
2001-09-25 Havoc Pennington <hp@pobox.com>
* gtk/gtkwindow.c: Put notes in gtk_window_set_has_frame(),
diff --git a/ChangeLog.pre-2-2 b/ChangeLog.pre-2-2
index bb81bc4b9..b3dc1a473 100644
--- a/ChangeLog.pre-2-2
+++ b/ChangeLog.pre-2-2
@@ -1,3 +1,37 @@
+Tue Sep 25 12:34:42 2001 Jonathan Blandford <jrb@redhat.com>
+
+ * gtk/gtkentry.c: Make a GtkCellEditable
+ (get_widget_window_size): Change to let it honor size_allocate
+ when a CellEditable.
+
+ * gtk/gtktreeview.c: M-x clean-line-ends. Lots of focus and
+ editable changes.
+ (gtk_tree_view_set_cursor): Now you can set the cursor
+ horizontally, as well as start editing.
+
+ * gtk/gtkstyle.c (gtk_default_draw_check): changing toggle drawing
+ code to look more like the other check buttons.
+
+ * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_get_size):
+ Change the way we calculate cell size.
+
+ * gtk/gtkmarshal.list (VOID:STRING,STRING): new marshaller.
+
+ * demos/gtk-demo/sizegroup.c: Add mnemonics.
+
+ * gtk/gtkcellrenderer.c (gtk_cell_renderer_get_size): Fix docs.
+ Fix logic.
+
+ * gtk/gtkcellrenderertext.c: Change to be editable.
+
+ * gtk/gtkcellrenderertoggle.c: Change to be activatable.
+
+ * test/testtreesort.c: Fix misspelling
+
+ * test/testreecolumns.c: Add mnemonics.
+
+ * test/testreeedit.c: New test program.
+
2001-09-25 Havoc Pennington <hp@pobox.com>
* gtk/gtkwindow.c: Put notes in gtk_window_set_has_frame(),
diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4
index bb81bc4b9..b3dc1a473 100644
--- a/ChangeLog.pre-2-4
+++ b/ChangeLog.pre-2-4
@@ -1,3 +1,37 @@
+Tue Sep 25 12:34:42 2001 Jonathan Blandford <jrb@redhat.com>
+
+ * gtk/gtkentry.c: Make a GtkCellEditable
+ (get_widget_window_size): Change to let it honor size_allocate
+ when a CellEditable.
+
+ * gtk/gtktreeview.c: M-x clean-line-ends. Lots of focus and
+ editable changes.
+ (gtk_tree_view_set_cursor): Now you can set the cursor
+ horizontally, as well as start editing.
+
+ * gtk/gtkstyle.c (gtk_default_draw_check): changing toggle drawing
+ code to look more like the other check buttons.
+
+ * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_get_size):
+ Change the way we calculate cell size.
+
+ * gtk/gtkmarshal.list (VOID:STRING,STRING): new marshaller.
+
+ * demos/gtk-demo/sizegroup.c: Add mnemonics.
+
+ * gtk/gtkcellrenderer.c (gtk_cell_renderer_get_size): Fix docs.
+ Fix logic.
+
+ * gtk/gtkcellrenderertext.c: Change to be editable.
+
+ * gtk/gtkcellrenderertoggle.c: Change to be activatable.
+
+ * test/testtreesort.c: Fix misspelling
+
+ * test/testreecolumns.c: Add mnemonics.
+
+ * test/testreeedit.c: New test program.
+
2001-09-25 Havoc Pennington <hp@pobox.com>
* gtk/gtkwindow.c: Put notes in gtk_window_set_has_frame(),
diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6
index bb81bc4b9..b3dc1a473 100644
--- a/ChangeLog.pre-2-6
+++ b/ChangeLog.pre-2-6
@@ -1,3 +1,37 @@
+Tue Sep 25 12:34:42 2001 Jonathan Blandford <jrb@redhat.com>
+
+ * gtk/gtkentry.c: Make a GtkCellEditable
+ (get_widget_window_size): Change to let it honor size_allocate
+ when a CellEditable.
+
+ * gtk/gtktreeview.c: M-x clean-line-ends. Lots of focus and
+ editable changes.
+ (gtk_tree_view_set_cursor): Now you can set the cursor
+ horizontally, as well as start editing.
+
+ * gtk/gtkstyle.c (gtk_default_draw_check): changing toggle drawing
+ code to look more like the other check buttons.
+
+ * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_get_size):
+ Change the way we calculate cell size.
+
+ * gtk/gtkmarshal.list (VOID:STRING,STRING): new marshaller.
+
+ * demos/gtk-demo/sizegroup.c: Add mnemonics.
+
+ * gtk/gtkcellrenderer.c (gtk_cell_renderer_get_size): Fix docs.
+ Fix logic.
+
+ * gtk/gtkcellrenderertext.c: Change to be editable.
+
+ * gtk/gtkcellrenderertoggle.c: Change to be activatable.
+
+ * test/testtreesort.c: Fix misspelling
+
+ * test/testreecolumns.c: Add mnemonics.
+
+ * test/testreeedit.c: New test program.
+
2001-09-25 Havoc Pennington <hp@pobox.com>
* gtk/gtkwindow.c: Put notes in gtk_window_set_has_frame(),
diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8
index bb81bc4b9..b3dc1a473 100644
--- a/ChangeLog.pre-2-8
+++ b/ChangeLog.pre-2-8
@@ -1,3 +1,37 @@
+Tue Sep 25 12:34:42 2001 Jonathan Blandford <jrb@redhat.com>
+
+ * gtk/gtkentry.c: Make a GtkCellEditable
+ (get_widget_window_size): Change to let it honor size_allocate
+ when a CellEditable.
+
+ * gtk/gtktreeview.c: M-x clean-line-ends. Lots of focus and
+ editable changes.
+ (gtk_tree_view_set_cursor): Now you can set the cursor
+ horizontally, as well as start editing.
+
+ * gtk/gtkstyle.c (gtk_default_draw_check): changing toggle drawing
+ code to look more like the other check buttons.
+
+ * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_get_size):
+ Change the way we calculate cell size.
+
+ * gtk/gtkmarshal.list (VOID:STRING,STRING): new marshaller.
+
+ * demos/gtk-demo/sizegroup.c: Add mnemonics.
+
+ * gtk/gtkcellrenderer.c (gtk_cell_renderer_get_size): Fix docs.
+ Fix logic.
+
+ * gtk/gtkcellrenderertext.c: Change to be editable.
+
+ * gtk/gtkcellrenderertoggle.c: Change to be activatable.
+
+ * test/testtreesort.c: Fix misspelling
+
+ * test/testreecolumns.c: Add mnemonics.
+
+ * test/testreeedit.c: New test program.
+
2001-09-25 Havoc Pennington <hp@pobox.com>
* gtk/gtkwindow.c: Put notes in gtk_window_set_has_frame(),
diff --git a/demos/gtk-demo/appwindow.c b/demos/gtk-demo/appwindow.c
index fd86d8dd9..cb88dc7fe 100644
--- a/demos/gtk-demo/appwindow.c
+++ b/demos/gtk-demo/appwindow.c
@@ -43,12 +43,12 @@ static GtkItemFactoryEntry menu_items[] =
{ "/File/sep1", NULL, menuitem_cb, 0, "<Separator>" },
{ "/File/_Quit", "<control>Q", menuitem_cb, 0, "<StockItem>", GTK_STOCK_QUIT },
- { "/_Preferences", NULL, 0, 0, "<Branch>" },
- { "/_Preferences/_Color", NULL, 0, 0, "<Branch>" },
- { "/_Preferences/Color/_Red", NULL, menuitem_cb, 0, "<RadioItem>" },
- { "/_Preferences/Color/_Green", NULL, menuitem_cb, 0, "/Preferences/Color/Red" },
+ { "/_Preferences", NULL, 0, 0, "<Branch>" },
+ { "/_Preferences/_Color", NULL, 0, 0, "<Branch>" },
+ { "/_Preferences/Color/_Red", NULL, menuitem_cb, 0, "<RadioItem>" },
+ { "/_Preferences/Color/_Green", NULL, menuitem_cb, 0, "/Preferences/Color/Red" },
{ "/_Preferences/Color/_Blue", NULL, menuitem_cb, 0, "/Preferences/Color/Red" },
- { "/_Preferences/_Shape", NULL, 0, 0, "<Branch>" },
+ { "/_Preferences/_Shape", NULL, 0, 0, "<Branch>" },
{ "/_Preferences/Shape/_Square", NULL, menuitem_cb, 0, "<RadioItem>" },
{ "/_Preferences/Shape/_Rectangle", NULL, menuitem_cb, 0, "/Preferences/Shape/Square" },
{ "/_Preferences/Shape/_Oval", NULL, menuitem_cb, 0, "/Preferences/Shape/Rectangle" },
diff --git a/demos/gtk-demo/sizegroup.c b/demos/gtk-demo/sizegroup.c
index fe87feff5..536dd7453 100644
--- a/demos/gtk-demo/sizegroup.c
+++ b/demos/gtk-demo/sizegroup.c
@@ -52,7 +52,7 @@ add_row (GtkTable *table,
GtkWidget *option_menu;
GtkWidget *label;
- label = gtk_label_new (label_text);
+ label = gtk_label_new_with_mnemonic (label_text);
gtk_misc_set_alignment (GTK_MISC (label), 0, 1);
gtk_table_attach (GTK_TABLE (table), label,
0, 1, row, row + 1,
@@ -60,6 +60,7 @@ add_row (GtkTable *table,
0, 0);
option_menu = create_option_menu (options);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), option_menu);
gtk_size_group_add_widget (size_group, option_menu);
gtk_table_attach (GTK_TABLE (table), option_menu,
1, 2, row, row + 1,
@@ -137,8 +138,8 @@ do_sizegroup (void)
gtk_table_set_col_spacings (GTK_TABLE (table), 10);
gtk_container_add (GTK_CONTAINER (frame), table);
- add_row (GTK_TABLE (table), 0, size_group, "Foreground", color_options);
- add_row (GTK_TABLE (table), 1, size_group, "Background", color_options);
+ add_row (GTK_TABLE (table), 0, size_group, "_Foreground", color_options);
+ add_row (GTK_TABLE (table), 1, size_group, "_Background", color_options);
/* And another frame holding line style options
*/
@@ -151,11 +152,11 @@ do_sizegroup (void)
gtk_table_set_col_spacings (GTK_TABLE (table), 10);
gtk_container_add (GTK_CONTAINER (frame), table);
- add_row (GTK_TABLE (table), 0, size_group, "Dashing", dash_options);
- add_row (GTK_TABLE (table), 1, size_group, "Line ends", end_options);
+ add_row (GTK_TABLE (table), 0, size_group, "_Dashing", dash_options);
+ add_row (GTK_TABLE (table), 1, size_group, "_Line ends", end_options);
/* And a check button to turn grouping on and off */
- check_button = gtk_check_button_new_with_label ("Enable grouping");
+ check_button = gtk_check_button_new_with_mnemonic ("_Enable grouping");
gtk_box_pack_start (GTK_BOX (vbox), check_button, FALSE, FALSE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
diff --git a/docs/tree-column-sizing.txt b/docs/tree-column-sizing.txt
index 367755fe5..09e872434 100644
--- a/docs/tree-column-sizing.txt
+++ b/docs/tree-column-sizing.txt
@@ -30,7 +30,7 @@ HOW THE GTKTREEVIEWCOLUMN STORES SIZE:
======================================
There are a number of size related fields in the GtkTreeViewColumn
-structure:
+structure. These are all valid after realization:
sizing The sizing method to use when calculating the size
of the column. Can be grow_only, resizable, auto, and fixed.
diff --git a/gtk/gtkcellrenderer.c b/gtk/gtkcellrenderer.c
index 4cd5ae493..651dc7f7a 100644
--- a/gtk/gtkcellrenderer.c
+++ b/gtk/gtkcellrenderer.c
@@ -318,7 +318,9 @@ gtk_cell_renderer_set_property (GObject *object,
* Obtains the width and height needed to render the cell. Used by view widgets
* to determine the appropriate size for the cell_area passed to
* gtk_cell_renderer_render(). If @cell_area is not %NULL, fills in the x and y
- * offsets (if set) of the cell relative to this location.
+ * offsets (if set) of the cell relative to this location. Please note that the
+ * values set in @width and @height, as well as those in @x_offset and @y_offset
+ * are inclusive of the xpad and ypad properties.
**/
void
gtk_cell_renderer_get_size (GtkCellRenderer *cell,
@@ -329,29 +331,24 @@ gtk_cell_renderer_get_size (GtkCellRenderer *cell,
gint *width,
gint *height)
{
- gint *real_width = NULL;
- gint *real_height = NULL;
+ gint *real_width = width;
+ gint *real_height = height;
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->get_size != NULL);
- if (width)
+ if (width && cell->width != -1)
{
- if (cell->width == -1)
- real_width = width;
- else
- *width = cell->width;
+ real_width = NULL;
+ *width = cell->width;
}
- if (height)
+ if (height && cell->height != -1)
{
- if (cell->height == -1)
- real_height = height;
- else
- *height = cell->height;
+ real_height = NULL;
+ *height = cell->height;
}
- if (real_width || real_height)
- GTK_CELL_RENDERER_GET_CLASS (cell)->get_size (cell, widget, cell_area, x_offset, y_offset, real_width, real_height);
+ GTK_CELL_RENDERER_GET_CLASS (cell)->get_size (cell, widget, cell_area, x_offset, y_offset, real_width, real_height);
}
/**
@@ -364,15 +361,13 @@ gtk_cell_renderer_get_size (GtkCellRenderer *cell,
* @expose_area: area that actually needs updating
* @flags: flags that affect rendering
*
- * Invokes the virtual render function of the #GtkCellRenderer. The
- * three passed-in rectangles are areas of @window. Most renderers
- * will draw to @cell_area; the xalign, yalign, xpad, and ypad fields
- * of the #GtkCellRenderer should be honored with respect to
- * @cell_area. @background_area includes the blank space around the
- * cell, and also the area containing the tree expander; so the
- * @background_area rectangles for all cells tile to cover the entire
- * @window. Cell renderers can use the @background_area to draw custom expanders, for
- * example. @expose_area is a clip rectangle.
+ * Invokes the virtual render function of the #GtkCellRenderer. The three
+ * passed-in rectangles are areas of @window. Most renderers will draw within
+ * @cell_area; the xalign, yalign, xpad, and ypad fields of the #GtkCellRenderer
+ * should be honored with respect to @cell_area. @background_area includes the
+ * blank space around the cell, and also the area containing the tree expander;
+ * so the @background_area rectangles for all cells tile to cover the entire
+ * @window. @expose_area is a clip rectangle.
*
**/
void
@@ -384,11 +379,6 @@ gtk_cell_renderer_render (GtkCellRenderer *cell,
GdkRectangle *expose_area,
GtkCellRendererState flags)
{
- /* It's actually okay to pass in a NULL cell, as we run into that
- * a lot
- */
- if (cell == NULL)
- return;
g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->render != NULL);
@@ -407,8 +397,8 @@ gtk_cell_renderer_render (GtkCellRenderer *cell,
* @event: a #GdkEvent
* @widget: widget that received the event
* @path: widget-dependent string representation of the event location; e.g. for #GtkTreeView, a string representation of #GtkTreePath
- * @background_area: background area as passed to gtk_cell_renderer_render()
- * @cell_area: cell area as passed to gtk_cell_renderer_render()
+ * @background_area: background area as passed to @gtk_cell_renderer_render
+ * @cell_area: cell area as passed to @gtk_cell_renderer_render
* @flags: render flags
*
* Passes an activate event to the cell renderer for possible processing. Some
@@ -449,8 +439,8 @@ gtk_cell_renderer_activate (GtkCellRenderer *cell,
* @event: a #GdkEvent
* @widget: widget that received the event
* @path: widget-dependent string representation of the event location; e.g. for #GtkTreeView, a string representation of #GtkTreePath
- * @background_area: background area as passed to gtk_cell_renderer_render()
- * @cell_area: cell area as passed to gtk_cell_renderer_render()
+ * @background_area: background area as passed to @gtk_cell_renderer_render
+ * @cell_area: cell area as passed to @gtk_cell_renderer_render
* @flags: render flags
*
* Passes an activate event to the cell renderer for possible processing.
diff --git a/gtk/gtkcellrenderertext.c b/gtk/gtkcellrenderertext.c
index 0055dff58..bced2d8c1 100644
--- a/gtk/gtkcellrenderertext.c
+++ b/gtk/gtkcellrenderertext.c
@@ -19,6 +19,9 @@
#include <stdlib.h>
#include "gtkcellrenderertext.h"
+#include "gtkeditable.h"
+#include "gtkentry.h"
+#include "gtksignal.h"
#include "gtkintl.h"
static void gtk_cell_renderer_text_init (GtkCellRendererText *celltext);
@@ -48,7 +51,18 @@ static void gtk_cell_renderer_text_render (GtkCellRenderer *cell,
GdkRectangle *expose_area,
guint flags);
+static GtkCellEditable *gtk_cell_renderer_text_start_editing (GtkCellRenderer *cell,
+ GdkEvent *event,
+ GtkWidget *widget,
+ gchar *path,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GtkCellRendererState flags);
+enum {
+ EDITED,
+ LAST_SIGNAL
+};
enum {
PROP_0,
@@ -94,6 +108,9 @@ enum {
};
static gpointer parent_class;
+static guint text_cell_renderer_signals [LAST_SIGNAL];
+
+#define GTK_CELL_RENDERER_TEXT_PATH "gtk-cell-renderer-text-path"
GtkType
gtk_cell_renderer_text_get_type (void)
@@ -128,7 +145,7 @@ gtk_cell_renderer_text_init (GtkCellRendererText *celltext)
GTK_CELL_RENDERER (celltext)->yalign = 0.5;
GTK_CELL_RENDERER (celltext)->xpad = 2;
GTK_CELL_RENDERER (celltext)->ypad = 2;
-
+ GTK_CELL_RENDERER (celltext)->mode = GTK_CELL_RENDERER_MODE_EDITABLE;
celltext->fixed_height_rows = -1;
celltext->font = pango_font_description_new ();
}
@@ -148,7 +165,8 @@ gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
cell_class->get_size = gtk_cell_renderer_text_get_size;
cell_class->render = gtk_cell_renderer_text_render;
-
+ cell_class->start_editing = gtk_cell_renderer_text_start_editing;
+
g_object_class_install_property (object_class,
PROP_TEXT,
g_param_spec_string ("text",
@@ -390,6 +408,17 @@ gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
ADD_SET_PROP ("underline_set", PROP_UNDERLINE_SET,
_("Underline set"),
_("Whether this tag affects underlining"));
+
+ text_cell_renderer_signals [EDITED] =
+ gtk_signal_new ("edited",
+ GTK_RUN_LAST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkCellRendererTextClass, edited),
+ gtk_marshal_VOID__STRING_STRING,
+ GTK_TYPE_NONE, 2,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+
}
static void
@@ -1135,12 +1164,12 @@ gtk_cell_renderer_text_get_size (GtkCellRenderer *cell,
if (x_offset)
{
*x_offset = cell->xalign * (cell_area->width - rect.width - (2 * cell->xpad));
- *x_offset = MAX (*x_offset, 0) + cell->xpad;
+ *x_offset = MAX (*x_offset, 0);
}
if (y_offset)
{
*y_offset = cell->yalign * (cell_area->height - rect.height - (2 * cell->ypad));
- *y_offset = MAX (*y_offset, 0) + cell->ypad;
+ *y_offset = MAX (*y_offset, 0);
}
}
@@ -1202,7 +1231,7 @@ gtk_cell_renderer_text_render (GtkCellRenderer *cell,
g_object_unref (G_OBJECT (gc));
}
-
+
gtk_paint_layout (widget->style,
window,
state,
@@ -1210,12 +1239,60 @@ gtk_cell_renderer_text_render (GtkCellRenderer *cell,
cell_area,
widget,
"cellrenderertext",
- cell_area->x + x_offset,
- cell_area->y + y_offset,
+ cell_area->x + x_offset + cell->xpad,
+ cell_area->y + y_offset + cell->ypad,
layout);
g_object_unref (G_OBJECT (layout));
}
+static void
+gtk_cell_renderer_text_editing_done (GtkCellEditable *entry,
+ gpointer data)
+{
+ gchar *path;
+ gchar *new_text;
+
+ path = g_object_get_data (G_OBJECT (entry), GTK_CELL_RENDERER_TEXT_PATH);
+ new_text = gtk_entry_get_text (GTK_ENTRY (entry));
+
+ gtk_signal_emit (GTK_OBJECT (data), text_cell_renderer_signals[EDITED], path, new_text);
+}
+
+static GtkCellEditable *
+gtk_cell_renderer_text_start_editing (GtkCellRenderer *cell,
+ GdkEvent *event,
+ GtkWidget *widget,
+ gchar *path,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GtkCellRendererState flags)
+{
+ GtkCellRendererText *celltext;
+ GtkWidget *entry;
+
+ celltext = GTK_CELL_RENDERER_TEXT (cell);
+
+ /* If the cell isn't editable we return NULL. */
+ if (celltext->editable == FALSE)
+ return NULL;
+
+ entry = g_object_new (GTK_TYPE_ENTRY,
+ "has_frame", FALSE,
+ NULL);
+
+ gtk_entry_set_text (GTK_ENTRY (entry), celltext->text);
+ g_object_set_data_full (G_OBJECT (entry), GTK_CELL_RENDERER_TEXT_PATH, g_strdup (path), g_free);
+
+ gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
+
+ gtk_widget_show (entry);
+ gtk_signal_connect (GTK_OBJECT (entry),
+ "editing_done",
+ G_CALLBACK (gtk_cell_renderer_text_editing_done),
+ celltext);
+ return GTK_CELL_EDITABLE (entry);
+
+}
/**
* gtk_cell_renderer_text_set_fixed_height_from_font:
@@ -1226,8 +1303,9 @@ gtk_cell_renderer_text_render (GtkCellRenderer *cell,
* "y_pad" property set on it. Further changes in these properties do not
* affect the height, so they must be accompanied by a subsequent call to this
* function. Using this function is unflexible, and should really only be used
- * if calculating the size of a cell is too slow. If @no_rows is -1, then the
- * fixed height is unset, and the height is determined by the properties again.
+ * if calculating the size of a cell is too slow (ie, a massive number of cells
+ * displayed). If @number_of_rows is -1, then the fixed height is unset, and
+ * the height is determined by the properties again.
**/
void
gtk_cell_renderer_text_set_fixed_height_from_font (GtkCellRendererText *renderer,
diff --git a/gtk/gtkcellrenderertext.h b/gtk/gtkcellrenderertext.h
index 41a8fcb7e..dfc4f8b3d 100644
--- a/gtk/gtkcellrenderertext.h
+++ b/gtk/gtkcellrenderertext.h
@@ -79,6 +79,10 @@ struct _GtkCellRendererText
struct _GtkCellRendererTextClass
{
GtkCellRendererClass parent_class;
+
+ void (* edited) (GtkCellRendererText *cell_renderer_text,
+ gchar *path,
+ gchar *new_text);
};
GtkType gtk_cell_renderer_text_get_type (void);
diff --git a/gtk/gtkcellrenderertoggle.c b/gtk/gtkcellrenderertoggle.c
index fac7dd7bd..845266f6e 100644
--- a/gtk/gtkcellrenderertoggle.c
+++ b/gtk/gtkcellrenderertoggle.c
@@ -62,6 +62,7 @@ enum {
enum {
PROP_ZERO,
+ PROP_ACTIVATABLE,
PROP_ACTIVE,
PROP_RADIO
};
@@ -101,6 +102,7 @@ gtk_cell_renderer_toggle_get_type (void)
static void
gtk_cell_renderer_toggle_init (GtkCellRendererToggle *celltoggle)
{
+ celltoggle->activatable = TRUE;
celltoggle->active = FALSE;
celltoggle->radio = FALSE;
GTK_CELL_RENDERER (celltoggle)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
@@ -131,6 +133,15 @@ gtk_cell_renderer_toggle_class_init (GtkCellRendererToggleClass *class)
G_PARAM_WRITABLE));
g_object_class_install_property (object_class,
+ PROP_ACTIVATABLE,
+ g_param_spec_boolean ("activatable",
+ _("Activatable"),
+ _("The toggle button can be activated"),
+ TRUE,
+ G_PARAM_READABLE |
+ G_PARAM_WRITABLE));
+
+ g_object_class_install_property (object_class,
PROP_RADIO,
g_param_spec_boolean ("radio",
_("Radio state"),
@@ -163,6 +174,9 @@ gtk_cell_renderer_toggle_get_property (GObject *object,
case PROP_ACTIVE:
g_value_set_boolean (value, celltoggle->active);
break;
+ case PROP_ACTIVATABLE:
+ g_value_set_boolean (value, celltoggle->activatable);
+ break;
case PROP_RADIO:
g_value_set_boolean (value, celltoggle->radio);
break;
@@ -187,6 +201,10 @@ gtk_cell_renderer_toggle_set_property (GObject *object,
celltoggle->active = g_value_get_boolean (value);
g_object_notify (G_OBJECT(object), "active");
break;
+ case PROP_ACTIVATABLE:
+ celltoggle->activatable = g_value_get_boolean (value);
+ g_object_notify (G_OBJECT(object), "activatable");
+ break;
case PROP_RADIO:
celltoggle->radio = g_value_get_boolean (value);
g_object_notify (G_OBJECT(object), "radio");
@@ -241,13 +259,13 @@ gtk_cell_renderer_toggle_get_size (GtkCellRenderer *cell,
{
if (x_offset)
{
- *x_offset = cell->xalign * (cell_area->width - calc_width - (2 * cell->xpad));
- *x_offset = MAX (*x_offset, 0) + cell->xpad;
+ *x_offset = cell->xalign * (cell_area->width - calc_width);
+ *x_offset = MAX (*x_offset, 0);
}
if (y_offset)
{
- *y_offset = cell->yalign * (cell_area->height - calc_height - (2 * cell->ypad));
- *y_offset = MAX (*y_offset, 0) + cell->ypad;
+ *y_offset = cell->yalign * (cell_area->height - calc_height);
+ *y_offset = MAX (*y_offset, 0);
}
}
}
@@ -281,21 +299,17 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
{
if (GTK_WIDGET_HAS_FOCUS (widget))
- {
- state = GTK_STATE_SELECTED;
- }
+ state = GTK_STATE_SELECTED;
else
- {
- state = GTK_STATE_ACTIVE;
- }
+ state = GTK_STATE_ACTIVE;
}
- else if (cell->mode == GTK_CELL_RENDERER_MODE_INERT)
+ else if (celltoggle->activatable)
{
- state = GTK_STATE_INSENSITIVE;
+ state = GTK_STATE_NORMAL;
}
else
{
- state = GTK_STATE_NORMAL;
+ state = GTK_STATE_INSENSITIVE;
}
if (celltoggle->radio)
@@ -306,7 +320,7 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
cell_area, widget, "cellradio",
cell_area->x + x_offset + cell->xpad,
cell_area->y + y_offset + cell->ypad,
- width, height);
+ width - 1, height - 1);
}
else
{
@@ -316,7 +330,7 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
cell_area, widget, "cellcheck",
cell_area->x + x_offset + cell->xpad,
cell_area->y + y_offset + cell->ypad,
- width, height);
+ width - 1, height - 1);
}
}
@@ -330,24 +344,15 @@ gtk_cell_renderer_toggle_activate (GtkCellRenderer *cell,
guint flags)
{
GtkCellRendererToggle *celltoggle;
- gboolean retval = FALSE;
celltoggle = GTK_CELL_RENDERER_TOGGLE (cell);
-
- switch (event->type)
+ if (celltoggle->activatable)
{
- case GDK_BUTTON_PRESS:
- {
- gtk_signal_emit (GTK_OBJECT (cell), toggle_cell_signals[TOGGLED], path);
- retval = TRUE;
- }
- break;
-
- default:
- break;
+ gtk_signal_emit (GTK_OBJECT (cell), toggle_cell_signals[TOGGLED], path);
+ return TRUE;
}
-
- return retval;
+
+ return FALSE;
}
/**
diff --git a/gtk/gtkcellrenderertoggle.h b/gtk/gtkcellrenderertoggle.h
index f1918e1cf..db166112f 100644
--- a/gtk/gtkcellrenderertoggle.h
+++ b/gtk/gtkcellrenderertoggle.h
@@ -43,6 +43,7 @@ struct _GtkCellRendererToggle
/*< private >*/
guint active : 1;
+ guint activatable : 1;
guint radio : 1;
};
@@ -50,7 +51,7 @@ struct _GtkCellRendererToggleClass
{
GtkCellRendererClass parent_class;
- void (* toggled) (GtkCellRendererToggle *celltoggle,
+ void (* toggled) (GtkCellRendererToggle *cell_renderer_toggle,
gchar *path);
};
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index 0715097f2..c8931e481 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -30,6 +30,7 @@
#include "gdk/gdkkeysyms.h"
#include "gtkbindings.h"
+#include "gtkcelleditable.h"
#include "gtkclipboard.h"
#include "gtkdnd.h"
#include "gtkentry.h"
@@ -100,8 +101,9 @@ static GtkTargetEntry target_table[] = {
/* GObject, GtkObject methods
*/
-static void gtk_entry_class_init (GtkEntryClass *klass);
-static void gtk_entry_editable_init (GtkEditableClass *iface);
+static void gtk_entry_class_init (GtkEntryClass *klass);
+static void gtk_entry_editable_init (GtkEditableClass *iface);
+static void gtk_entry_cell_editable_init (GtkCellEditableIface *iface);
static void gtk_entry_init (GtkEntry *entry);
static void gtk_entry_set_property (GObject *object,
guint prop_id,
@@ -189,6 +191,11 @@ static gboolean gtk_entry_get_selection_bounds (GtkEditable *editable,
gint *start,
gint *end);
+/* GtkCellEditable method implementations
+ */
+static void gtk_entry_start_editing (GtkCellEditable *cell_editable,
+ GdkEvent *event);
+
/* Default signal handlers
*/
static void gtk_entry_real_insert_text (GtkEntry *entry,
@@ -298,10 +305,20 @@ gtk_entry_get_type (void)
NULL /* interface_data */
};
+ static const GInterfaceInfo cell_editable_info =
+ {
+ (GInterfaceInitFunc) gtk_entry_cell_editable_init, /* interface_init */
+ NULL, /* interface_finalize */
+ NULL /* interface_data */
+ };
+
entry_type = gtk_type_unique (GTK_TYPE_WIDGET, &entry_info);
g_type_add_interface_static (entry_type,
GTK_TYPE_EDITABLE,
&editable_info);
+ g_type_add_interface_static (entry_type,
+ GTK_TYPE_CELL_EDITABLE,
+ &cell_editable_info);
}
return entry_type;
@@ -764,6 +781,12 @@ gtk_entry_editable_init (GtkEditableClass *iface)
}
static void
+gtk_entry_cell_editable_init (GtkCellEditableIface *iface)
+{
+ iface->start_editing = gtk_entry_start_editing;
+}
+
+static void
gtk_entry_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -881,7 +904,7 @@ gtk_entry_init (GtkEntry *entry)
entry->invisible_char = '*';
entry->dnd_position = -1;
entry->width_chars = -1;
-
+ entry->is_cell_renderer = FALSE;
entry->has_frame = TRUE;
gtk_drag_dest_set (GTK_WIDGET (entry),
@@ -1179,13 +1202,23 @@ get_widget_window_size (GtkEntry *entry,
*x = widget->allocation.x;
if (y)
- *y = widget->allocation.y + (widget->allocation.height - requisition.height) / 2;
+ {
+ if (entry->is_cell_renderer)
+ *y = widget->allocation.y;
+ else
+ *y = widget->allocation.y + (widget->allocation.height - requisition.height) / 2;
+ }
if (width)
*width = widget->allocation.width;
if (height)
- *height = requisition.height;
+ {
+ if (entry->is_cell_renderer)
+ *height = widget->allocation.height;
+ else
+ *height = requisition.height;
+ }
}
static void
@@ -1777,6 +1810,43 @@ gtk_entry_style_set (GtkWidget *widget,
}
}
+/* GtkCellEditable method implementations
+ */
+static void
+gtk_cell_editable_entry_activated (GtkEntry *entry, gpointer data)
+{
+ gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (entry));
+ gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (entry));
+}
+
+static gboolean
+gtk_cell_editable_key_press_event (GtkEntry *entry,
+ GdkEventKey *key_event,
+ gpointer data)
+{
+ if (key_event->keyval == GDK_Escape)
+ {
+ gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (entry));
+ gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (entry));
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+gtk_entry_start_editing (GtkCellEditable *cell_editable,
+ GdkEvent *event)
+{
+ GTK_ENTRY (cell_editable)->is_cell_renderer = TRUE;
+
+ g_signal_connect (G_OBJECT (cell_editable), "activate",
+ G_CALLBACK (gtk_cell_editable_entry_activated), NULL);
+ g_signal_connect (G_OBJECT (cell_editable), "key_press_event",
+ G_CALLBACK (gtk_cell_editable_key_press_event), NULL);
+}
+
/* Default signal handlers
*/
static void
diff --git a/gtk/gtkentry.h b/gtk/gtkentry.h
index 5ec2049e4..90b7bf5b5 100644
--- a/gtk/gtkentry.h
+++ b/gtk/gtkentry.h
@@ -84,7 +84,9 @@ struct _GtkEntry
guint cursor_visible : 1;
guint in_click : 1; /* Flag so we don't select all when clicking in entry to focus in */
-
+
+ guint is_cell_renderer : 1;
+
guint button;
guint blink_timeout;
guint recompute_idle;
diff --git a/gtk/gtkmarshal.list b/gtk/gtkmarshal.list
index 186140fba..23a66260e 100644
--- a/gtk/gtkmarshal.list
+++ b/gtk/gtkmarshal.list
@@ -77,6 +77,7 @@ VOID:POINTER,INT
VOID:POINTER,POINTER,POINTER
VOID:POINTER,UINT
VOID:STRING
+VOID:STRING,STRING
VOID:STRING,INT,POINTER
VOID:UINT,BOXED,UINT,FLAGS,FLAGS
VOID:UINT,OBJECT,UINT,FLAGS,FLAGS
diff --git a/gtk/gtkmarshalers.list b/gtk/gtkmarshalers.list
index 186140fba..23a66260e 100644
--- a/gtk/gtkmarshalers.list
+++ b/gtk/gtkmarshalers.list
@@ -77,6 +77,7 @@ VOID:POINTER,INT
VOID:POINTER,POINTER,POINTER
VOID:POINTER,UINT
VOID:STRING
+VOID:STRING,STRING
VOID:STRING,INT,POINTER
VOID:UINT,BOXED,UINT,FLAGS,FLAGS
VOID:UINT,OBJECT,UINT,FLAGS,FLAGS
diff --git a/gtk/gtkstyle.c b/gtk/gtkstyle.c
index 5a91aab43..d3a7fc7c2 100644
--- a/gtk/gtkstyle.c
+++ b/gtk/gtkstyle.c
@@ -3018,19 +3018,12 @@ gtk_default_draw_check (GtkStyle *style,
x, y,
width, height);
+ x -= (1 + INDICATOR_PART_SIZE - width) / 2;
+ y -= (((1 + INDICATOR_PART_SIZE - height) / 2) - 1);
if (shadow_type == GTK_SHADOW_IN)
{
- gdk_draw_line (window,
- widget->style->fg_gc[state_type],
- x, y,
- x + width,
- y + height);
- gdk_draw_line (window,
- widget->style->fg_gc[state_type],
- x + width,
- y,
- x,
- y + height);
+ draw_part (window, style->text_gc[state_type], area, x, y, CHECK_TEXT);
+ draw_part (window, style->text_aa_gc[state_type], area, x, y, CHECK_AA);
}
}
else
diff --git a/gtk/gtktreeprivate.h b/gtk/gtktreeprivate.h
index 33235b5fe..5ffedf56e 100644
--- a/gtk/gtktreeprivate.h
+++ b/gtk/gtktreeprivate.h
@@ -109,7 +109,6 @@ struct _GtkTreeViewPrivate
/* Focus code */
GtkTreeViewColumn *focus_column;
- GtkTreeViewColumn *scroll_column;
/* Selection stuff */
GtkTreeRowReference *anchor;
diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c
index 9b6366e3c..c0a180d6a 100644
--- a/gtk/gtktreeview.c
+++ b/gtk/gtktreeview.c
@@ -106,6 +106,7 @@ enum
TOGGLE_CURSOR_ROW,
EXPAND_COLLAPSE_CURSOR_ROW,
SELECT_CURSOR_PARENT,
+ START_INTERACTIVE_SEARCH,
LAST_SIGNAL
};
@@ -313,6 +314,8 @@ static void gtk_tree_view_check_dirty_and_clean (GtkTreeView
static void gtk_tree_view_clamp_node_visible (GtkTreeView *tree_view,
GtkRBTree *tree,
GtkRBNode *node);
+static void gtk_tree_view_clamp_column_visible (GtkTreeView *tree_view,
+ GtkTreeViewColumn *column);
static gboolean gtk_tree_view_maybe_begin_dragging_row (GtkTreeView *tree_view,
GdkEventMotion *event);
static void _gtk_tree_view_update_col_width (GtkTreeView *tree_view);
@@ -337,8 +340,6 @@ static gboolean gtk_tree_view_real_expand_row (GtkTreeView
static void gtk_tree_view_real_set_cursor (GtkTreeView *tree_view,
GtkTreePath *path,
gboolean clear_and_select);
-static void gtk_tree_view_ensure_focus_column (GtkTreeView *tree_view);
-
/* interactive search */
static void gtk_tree_view_search_dialog_destroy (GtkWidget *search_dialog,
@@ -370,25 +371,27 @@ static gboolean gtk_tree_view_search_iter (GtkTreeModel *model
gint n);
static void gtk_tree_view_search_init (GtkWidget *entry,
GtkTreeView *tree_view);
-static void gtk_tree_view_interactive_search (GtkTreeView *tree_view,
- GdkEventKey *key);
static void gtk_tree_view_put (GtkTreeView *tree_view,
GtkWidget *child_widget,
gint x,
gint y,
gint width,
gint height);
-static void gtk_tree_view_start_editing (GtkTreeView *tree_view,
- GtkTreeViewColumn *column,
- GtkCellEditable *cell_editable,
- GdkRectangle *cell_area,
- GdkEvent *event,
- guint flags);
-static void gtk_tree_view_stop_editing (GtkTreeView *tree_view);
+static gboolean gtk_tree_view_start_editing (GtkTreeView *tree_view,
+ GtkTreePath *cursor_path);
+static void gtk_tree_view_real_start_editing (GtkTreeView *tree_view,
+ GtkTreeViewColumn *column,
+ GtkTreePath *path,
+ GtkCellEditable *cell_editable,
+ GdkRectangle *cell_area,
+ GdkEvent *event,
+ guint flags);
+static void gtk_tree_view_stop_editing (GtkTreeView *tree_view);
+static void gtk_tree_view_real_start_interactive_search (GtkTreeView *tree_view);
static GtkContainerClass *parent_class = NULL;
-static guint tree_view_signals[LAST_SIGNAL] = { 0 };
+static guint tree_view_signals [LAST_SIGNAL] = { 0 };
@@ -482,6 +485,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
class->toggle_cursor_row = gtk_tree_view_real_toggle_cursor_row;
class->expand_collapse_cursor_row = gtk_tree_view_real_expand_collapse_cursor_row;
class->select_cursor_parent = gtk_tree_view_real_select_cursor_parent;
+ class->start_interactive_search = gtk_tree_view_real_start_interactive_search;
/* Properties */
@@ -556,7 +560,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
_("View allows user to search through columns interactively"),
TRUE,
G_PARAM_READWRITE));
-
+
g_object_class_install_property (o_class,
PROP_SEARCH_COLUMN,
g_param_spec_int ("search_column",
@@ -566,40 +570,46 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
G_MAXINT,
0,
G_PARAM_READWRITE));
-
+
/* Style properties */
- /* the width of the column resize windows */
#define _TREE_VIEW_EXPANDER_SIZE 10
#define _TREE_VIEW_VERTICAL_SEPARATOR 2
-#define _TREE_VIEW_HORIZONTAL_SEPARATOR 0
+#define _TREE_VIEW_HORIZONTAL_SEPARATOR 2
gtk_widget_class_install_style_property (widget_class,
g_param_spec_int ("expander_size",
_("Expander Size"),
- _("Size of the expander arrow"),
+ _("Size of the expander arrow."),
0,
G_MAXINT,
_TREE_VIEW_EXPANDER_SIZE,
G_PARAM_READABLE));
-
+
gtk_widget_class_install_style_property (widget_class,
g_param_spec_int ("vertical_separator",
_("Vertical Separator Width"),
- _("Vertical space between cells"),
+ _("Vertical space between cells. Must be an even number."),
0,
G_MAXINT,
_TREE_VIEW_VERTICAL_SEPARATOR,
G_PARAM_READABLE));
-
+
gtk_widget_class_install_style_property (widget_class,
g_param_spec_int ("horizontal_separator",
_("Horizontal Separator Width"),
- _("Horizontal space between cells"),
+ _("Horizontal space between cells. Must be an even number."),
0,
G_MAXINT,
_TREE_VIEW_HORIZONTAL_SEPARATOR,
G_PARAM_READABLE));
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_boolean ("allow_rules",
+ _("Allow Rules"),
+ _("Allow drawing of alternating color rows."),
+ TRUE,
+ G_PARAM_READABLE));
+
/* Signals */
widget_class->set_scroll_adjustments_signal =
gtk_signal_new ("set_scroll_adjustments",
@@ -718,6 +728,15 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
gtk_marshal_NONE__NONE,
GTK_TYPE_NONE, 0);
+ tree_view_signals[START_INTERACTIVE_SEARCH] =
+ g_signal_new ("start_interactive_search",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST | GTK_RUN_ACTION,
+ G_STRUCT_OFFSET (GtkTreeViewClass, start_interactive_search),
+ NULL, NULL,
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
+
/* Key bindings */
gtk_tree_view_add_move_binding (binding_set, GDK_Up, 0,
GTK_MOVEMENT_DISPLAY_LINES, -1);
@@ -815,6 +834,9 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, 0, "select_cursor_parent", 0);
+ gtk_binding_entry_add_signal (binding_set, GDK_s, GDK_CONTROL_MASK, "start_interactive_search", 0);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_S, GDK_CONTROL_MASK, "start_interactive_search", 0);
}
static void
@@ -829,7 +851,7 @@ gtk_tree_view_init (GtkTreeView *tree_view)
/* We need some padding */
tree_view->priv->tab_offset += EXPANDER_EXTRA_PADDING;
-
+
tree_view->priv->n_columns = 0;
tree_view->priv->header_height = 1;
tree_view->priv->x_drag = 0;
@@ -967,7 +989,9 @@ gtk_tree_view_destroy (GtkObject *object)
GtkWidget *search_dialog;
GList *list;
- if (tree_view->priv->columns != NULL)
+ gtk_tree_view_stop_editing (tree_view);
+
+ if (tree_view->priv->columns != NULL)
{
list = tree_view->priv->columns;
while (list)
@@ -1014,7 +1038,7 @@ gtk_tree_view_destroy (GtkObject *object)
tree_view->priv->drag_dest_row = NULL;
}
-
+
if (tree_view->priv->column_drop_func_data &&
tree_view->priv->column_drop_func_data_destroy)
{
@@ -1236,6 +1260,9 @@ gtk_tree_view_realize (GtkWidget *widget)
}
tree_view->priv->scroll_to_column = NULL;
}
+
+ if (GTK_WIDGET_CLASS (parent_class)->map)
+ (* GTK_WIDGET_CLASS (parent_class)->map) (widget);
}
static void
@@ -1265,7 +1292,7 @@ gtk_tree_view_unrealize (GtkWidget *widget)
gtk_timeout_remove (tree_view->priv->expand_collapse_timeout);
tree_view->priv->expand_collapse_timeout = 0;
}
-
+
for (list = tree_view->priv->columns; list; list = list->next)
_gtk_tree_view_column_unrealize_button (GTK_TREE_VIEW_COLUMN (list->data));
@@ -1425,12 +1452,11 @@ gtk_tree_view_size_allocate (GtkWidget *widget,
GtkTreeViewChild *child = tmp_list->data;
tmp_list = tmp_list->next;
- /* totally ignore our childs allocation <-: */
+ /* totally ignore our childs requisition */
allocation.x = child->x;
allocation.y = child->y;
allocation.width = child->width;
allocation.height = child->height;
-
gtk_widget_size_allocate (child->widget, &allocation);
}
@@ -1487,12 +1513,17 @@ gtk_tree_view_button_press (GtkWidget *widget,
GdkRectangle background_area;
GdkRectangle cell_area;
gint vertical_separator;
+ gint horizontal_separator;
g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
tree_view = GTK_TREE_VIEW (widget);
- gtk_widget_style_get (widget, "vertical_separator", &vertical_separator, NULL);
+ gtk_tree_view_stop_editing (tree_view);
+ gtk_widget_style_get (widget,
+ "vertical_separator", &vertical_separator,
+ "horizontal_separator", &horizontal_separator,
+ NULL);
if (event->window == tree_view->priv->bin_window)
{
@@ -1528,7 +1559,7 @@ gtk_tree_view_button_press (GtkWidget *widget,
}
/* find the node that was clicked */
- new_y = ((gint)event->y<TREE_VIEW_HEADER_HEIGHT (tree_view))?TREE_VIEW_HEADER_HEIGHT (tree_view):(gint)event->y;
+ new_y = ((gint) event->y < TREE_VIEW_HEADER_HEIGHT (tree_view)) ? TREE_VIEW_HEADER_HEIGHT (tree_view) : (gint)event->y;
y_offset = -_gtk_rbtree_find_offset (tree_view->priv->tree,
TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, new_y),
&tree,
@@ -1541,8 +1572,8 @@ gtk_tree_view_button_press (GtkWidget *widget,
/* Get the path and the node */
path = _gtk_tree_view_find_path (tree_view, tree, node);
depth = gtk_tree_path_get_depth (path);
- background_area.y = y_offset + event->y + vertical_separator;
- background_area.height = GTK_RBNODE_GET_HEIGHT (node) - vertical_separator;
+ background_area.y = y_offset + event->y;
+ background_area.height = GTK_RBNODE_GET_HEIGHT (node);
background_area.x = 0;
/* Let the column have a chance at selecting it. */
@@ -1551,7 +1582,7 @@ gtk_tree_view_button_press (GtkWidget *widget,
GtkTreeIter iter;
GtkCellEditable *cell_editable = NULL;
/* FIXME: get the right flags */
- guint flags = 0;
+ guint flags = 0;
column = list->data;
@@ -1559,18 +1590,6 @@ gtk_tree_view_button_press (GtkWidget *widget,
continue;
background_area.width = column->width;
- if (gtk_tree_view_is_expander_column (tree_view, column) &&
- TREE_VIEW_DRAW_EXPANDERS(tree_view))
- {
- cell_area = background_area;
- cell_area.x += depth*tree_view->priv->tab_offset;
- cell_area.width -= depth*tree_view->priv->tab_offset;
- }
- else
- {
- cell_area = background_area;
- }
-
if ((background_area.x > (gint) event->x) ||
(background_area.y > (gint) event->y) ||
(background_area.x + background_area.width <= (gint) event->x) ||
@@ -1580,6 +1599,18 @@ gtk_tree_view_button_press (GtkWidget *widget,
continue;
}
+ cell_area = background_area;
+ cell_area.width -= horizontal_separator;
+ cell_area.height -= vertical_separator;
+ cell_area.x += horizontal_separator/2;
+ cell_area.y += vertical_separator/2;
+ if (gtk_tree_view_is_expander_column (tree_view, column) &&
+ TREE_VIEW_DRAW_EXPANDERS(tree_view))
+ {
+ cell_area.x += depth*tree_view->priv->tab_offset;
+ cell_area.width -= depth*tree_view->priv->tab_offset;
+ }
+
gtk_tree_model_get_iter (tree_view->priv->model, &iter, path);
gtk_tree_view_column_cell_set_cell_data (column,
tree_view->priv->model,
@@ -1598,13 +1629,14 @@ gtk_tree_view_button_press (GtkWidget *widget,
{
if (cell_editable != NULL)
{
- gtk_tree_view_stop_editing (tree_view);
- gtk_tree_view_start_editing (tree_view,
- column,
- cell_editable,
- &cell_area,
- (GdkEvent *)event,
- flags);
+ gtk_tree_view_real_start_editing (tree_view,
+ column,
+ path,
+ cell_editable,
+ &cell_area,
+ (GdkEvent *)event,
+ flags);
+
}
g_free (path_string);
gtk_tree_path_free (path);
@@ -1921,28 +1953,6 @@ ensure_unprelighted (GtkTreeView *tree_view)
g_assert (tree_view->priv->prelight_node == NULL);
}
-static void
-gtk_tree_view_ensure_focus_column (GtkTreeView *tree_view)
-{
- GList *list;
- if (tree_view->priv->focus_column != NULL &&
- tree_view->priv->focus_column->visible)
- return;
-
- if (tree_view->priv->focus_column)
- gtk_tree_view_column_cell_focus (tree_view->priv->focus_column, 0, TRUE);
-
- for (list = tree_view->priv->columns; list; list = list->next)
- {
- GtkTreeViewColumn *column = list->data;
-
- if (column->visible)
- {
- gtk_tree_view_column_cell_focus (column, 1, FALSE);
- return;
- }
- }
-}
@@ -2057,7 +2067,7 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view)
NULL);
width = expander_size;
-
+
/* Get x, y, width, height of arrow */
if (reorder->left_column)
{
@@ -2132,7 +2142,7 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view)
NULL);
width = expander_size;
-
+
/* Get x, y, width, height of arrow */
width = width/2; /* remember, the arrow only takes half the available width */
gdk_window_get_origin (widget->window, &x, &y);
@@ -2431,17 +2441,23 @@ gtk_tree_view_bin_expose (GtkWidget *widget,
GtkTreePath *drag_dest_path;
GList *last_column;
gint vertical_separator;
+ gint horizontal_separator;
+ gboolean allow_rules;
g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE);
tree_view = GTK_TREE_VIEW (widget);
- gtk_widget_style_get (widget, "vertical_separator", &vertical_separator, NULL);
+ gtk_widget_style_get (widget,
+ "horizontal_separator", &horizontal_separator,
+ "vertical_separator", &vertical_separator,
+ "allow_rules", &allow_rules,
+ NULL);
if (tree_view->priv->tree == NULL)
return TRUE;
gtk_tree_view_check_dirty_and_clean (GTK_TREE_VIEW (widget));
- gtk_tree_view_ensure_focus_column (GTK_TREE_VIEW (widget));
+
/* we want to account for a potential HEADER offset. That is, if the header
* exists, we want to offset our event by its height to find the right node.
*/
@@ -2516,7 +2532,7 @@ gtk_tree_view_bin_expose (GtkWidget *widget,
flags |= GTK_CELL_RENDERER_SELECTED;
parity = _gtk_rbtree_node_find_parity (tree, node);
-
+
for (list = tree_view->priv->columns; list; list = list->next)
{
GtkTreeViewColumn *column = list->data;
@@ -2550,17 +2566,15 @@ gtk_tree_view_bin_expose (GtkWidget *widget,
cell_area = background_area;
cell_area.y += vertical_separator / 2;
+ cell_area.x += horizontal_separator / 2;
cell_area.height -= vertical_separator;
+ cell_area.width -= horizontal_separator;
/* Select the detail for drawing the cell. relevant
* factors are parity, sortedness, and whether to
* display rules.
*/
-
- /* FIXME when we have style properties, clean this up.
- */
-
- if (tree_view->priv->has_rules)
+ if (allow_rules && tree_view->priv->has_rules)
{
if (flags & GTK_CELL_RENDERER_SORTED)
{
@@ -2653,8 +2667,9 @@ gtk_tree_view_bin_expose (GtkWidget *widget,
flags);
}
if (node == cursor &&
- GTK_WIDGET_HAS_FOCUS (widget) &&
- column == tree_view->priv->focus_column)
+ ((column == tree_view->priv->focus_column &&
+ GTK_WIDGET_HAS_FOCUS (widget)) ||
+ (column == tree_view->priv->edited_column)))
{
gtk_tree_view_column_cell_draw_focus (column,
event->window,
@@ -2806,7 +2821,6 @@ gtk_tree_view_key_press (GtkWidget *widget,
GdkEventKey *event)
{
GtkTreeView *tree_view = (GtkTreeView *) widget;
- gint retval;
if (GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_IN_COLUMN_DRAG))
{
@@ -2818,12 +2832,7 @@ gtk_tree_view_key_press (GtkWidget *widget,
return TRUE;
}
- retval = (* GTK_WIDGET_CLASS (parent_class)->key_press_event) (widget, event);
-
- if (! retval)
- gtk_tree_view_interactive_search (tree_view, event);
-
- return retval;
+ return (* GTK_WIDGET_CLASS (parent_class)->key_press_event) (widget, event);
}
/* FIXME Is this function necessary? Can I get an enter_notify event
@@ -2892,7 +2901,7 @@ gtk_tree_view_leave_notify (GtkWidget *widget,
NULL);
ensure_unprelighted (tree_view);
-
+
return TRUE;
}
@@ -2932,8 +2941,7 @@ gtk_tree_view_focus_out (GtkWidget *widget,
/* destroy interactive search dialog */
search_dialog = gtk_object_get_data (GTK_OBJECT (widget), "search-dialog");
if (search_dialog)
- gtk_tree_view_search_dialog_destroy (search_dialog,
- GTK_TREE_VIEW (widget));
+ gtk_tree_view_search_dialog_destroy (search_dialog, GTK_TREE_VIEW (widget));
return FALSE;
}
@@ -3178,7 +3186,7 @@ open_row_timeout (gpointer data)
gboolean result = FALSE;
GDK_THREADS_ENTER ();
-
+
gtk_tree_view_get_drag_dest_row (tree_view,
&dest_path,
&pos);
@@ -3196,10 +3204,10 @@ open_row_timeout (gpointer data)
{
if (dest_path)
gtk_tree_path_free (dest_path);
-
+
result = TRUE;
}
-
+
GDK_THREADS_LEAVE ();
return result;
@@ -4017,16 +4025,6 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view,
return (focus_child != NULL);
}
-/* We make the assumption that if container->focus_child != NULL, the focus must
- * be in the header. For now, this is accurate. It may not be in the future.
- */
-
-/* The sordid relationship between focus_column and scroll_column:
- *
- * The focus_column represents the column that currently has keyboard focus, and
- * is used when navigating columns by keyboard. scroll_column is used for
- * handling scrolling by keyboard, such that in cases.
- */
static gint
gtk_tree_view_focus (GtkWidget *widget,
GtkDirectionType direction)
@@ -4046,6 +4044,7 @@ gtk_tree_view_focus (GtkWidget *widget,
focus_child = container->focus_child;
+ gtk_tree_view_stop_editing (GTK_TREE_VIEW (widget));
/* Case 1. Headers currently have focus. */
if (focus_child)
{
@@ -4194,7 +4193,7 @@ gtk_tree_view_real_move_cursor (GtkTreeView *tree_view,
if (tree_view->priv->tree == NULL)
return;
-
+ gtk_tree_view_stop_editing (tree_view);
GTK_TREE_VIEW_SET_FLAG (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS);
gtk_widget_grab_focus (GTK_WIDGET (tree_view));
@@ -4219,10 +4218,10 @@ gtk_tree_view_real_move_cursor (GtkTreeView *tree_view,
}
}
-static void
-gtk_tree_view_put (GtkTreeView *tree_view,
- GtkWidget *child_widget,
- gint x,
+static void
+gtk_tree_view_put (GtkTreeView *tree_view,
+ GtkWidget *child_widget,
+ gint x,
gint y,
gint width,
gint height)
@@ -4231,7 +4230,7 @@ gtk_tree_view_put (GtkTreeView *tree_view,
g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
g_return_if_fail (GTK_IS_WIDGET (child_widget));
-
+
child = g_new (GtkTreeViewChild, 1);
child->widget = child_widget;
@@ -4241,7 +4240,7 @@ gtk_tree_view_put (GtkTreeView *tree_view,
child->height = height;
tree_view->priv->children = g_list_append (tree_view->priv->children, child);
-
+
if (GTK_WIDGET_REALIZED (tree_view))
gtk_widget_set_parent_window (child->widget, tree_view->priv->bin_window);
@@ -4334,6 +4333,7 @@ gtk_tree_view_row_changed (GtkTreeModel *model,
{
_gtk_rbtree_node_set_height (tree, node, height + vertical_separator);
gtk_widget_queue_resize (GTK_WIDGET (data));
+ _gtk_tree_view_update_size (tree_view);
goto done;
}
if (dirty_marked)
@@ -4542,14 +4542,14 @@ gtk_tree_view_row_deleted (GtkTreeModel *model,
g_return_if_fail (path != NULL);
+ gtk_tree_row_reference_deleted (G_OBJECT (data), path);
+
if (_gtk_tree_view_find_node (tree_view, path, &tree, &node))
return;
if (tree == NULL)
return;
- gtk_tree_row_reference_deleted (G_OBJECT (data), path);
-
/* Change the selection */
selection_changed = GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED);
@@ -4572,7 +4572,7 @@ gtk_tree_view_row_deleted (GtkTreeModel *model,
GTK_RBNODE_UNSET_FLAG (tree_view->priv->expanded_collapsed_node, GTK_RBNODE_IS_SEMI_EXPANDED);
tree_view->priv->expanded_collapsed_node = NULL;
}
-
+
if (tree_view->priv->destroy_count_func)
{
gint child_count = 0;
@@ -4801,9 +4801,9 @@ gtk_tree_view_insert_iter_height (GtkTreeView *tree_view,
GList *list;
gint max_height = 0;
gint vertical_separator;
-
+
gtk_widget_style_get (GTK_WIDGET (tree_view), "vertical_separator", &vertical_separator, NULL);
-
+
/* do stuff with node */
for (list = tree_view->priv->columns; list; list = list->next)
{
@@ -4890,10 +4890,13 @@ gtk_tree_view_calc_size (GtkTreeView *tree_view,
GtkTreeViewColumn *column;
gint max_height;
gint vertical_separator;
-
+ gint horizontal_separator;
TREE_VIEW_INTERNAL_ASSERT_VOID (tree != NULL);
- gtk_widget_style_get (GTK_WIDGET (tree_view), "vertical_separator", &vertical_separator, NULL);
+ gtk_widget_style_get (GTK_WIDGET (tree_view),
+ "vertical_separator", &vertical_separator,
+ "horizontal_separator", &horizontal_separator,
+ NULL);
temp = tree->root;
while (temp->left != tree->nil)
@@ -4928,9 +4931,9 @@ gtk_tree_view_calc_size (GtkTreeView *tree_view,
if (gtk_tree_view_is_expander_column (tree_view, column) &&
TREE_VIEW_DRAW_EXPANDERS (tree_view))
_gtk_tree_view_column_set_width (column,
- MAX (column->width, depth * tree_view->priv->tab_offset + width));
+ MAX (column->width, depth * tree_view->priv->tab_offset + width + horizontal_separator));
else
- _gtk_tree_view_column_set_width (column, MAX (column->width, width));
+ _gtk_tree_view_column_set_width (column, MAX (column->width, width + horizontal_separator));
}
_gtk_rbtree_node_set_height (tree, temp, max_height);
@@ -4954,7 +4957,12 @@ gtk_tree_view_discover_dirty_iter (GtkTreeView *tree_view,
GList *list;
gboolean retval = FALSE;
gint tmpheight;
-
+ gint horizontal_separator;
+
+ gtk_widget_style_get (GTK_WIDGET (tree_view),
+ "horizontal_separator", &horizontal_separator,
+ NULL);
+
if (height)
*height = 0;
@@ -4966,12 +4974,11 @@ gtk_tree_view_discover_dirty_iter (GtkTreeView *tree_view,
continue;
if (!column->visible)
continue;
-
+
gtk_tree_view_column_cell_set_cell_data (column, tree_view->priv->model, iter,
GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_PARENT),
node->children?TRUE:FALSE);
-
if (height)
{
gtk_tree_view_column_cell_get_size (column,
@@ -4989,7 +4996,7 @@ gtk_tree_view_discover_dirty_iter (GtkTreeView *tree_view,
if (gtk_tree_view_is_expander_column (tree_view, column) &&
TREE_VIEW_DRAW_EXPANDERS (tree_view))
{
- if (depth * tree_view->priv->tab_offset + width > column->width)
+ if (depth * tree_view->priv->tab_offset + horizontal_separator + width > column->requested_width)
{
gtk_tree_view_column_cell_set_dirty (column);
retval = TRUE;
@@ -4997,7 +5004,7 @@ gtk_tree_view_discover_dirty_iter (GtkTreeView *tree_view,
}
else
{
- if (width > column->width)
+ if (horizontal_separator + width > column->requested_width)
{
gtk_tree_view_column_cell_set_dirty (column);
retval = TRUE;
@@ -5045,7 +5052,7 @@ gtk_tree_view_discover_dirty (GtkTreeView *tree_view,
gtk_tree_view_discover_dirty_iter (tree_view,
iter,
depth,
- FALSE,
+ NULL,
temp);
if (gtk_tree_model_iter_children (tree_view->priv->model, &child, iter) &&
temp->children != NULL)
@@ -5059,8 +5066,8 @@ gtk_tree_view_discover_dirty (GtkTreeView *tree_view,
/**
* gtk_tree_view_check_dirty_and_clean:
* @tree_view: A #GtkTreeView
- *
- * Does all the actual sizing for
+ *
+ * Does all the actual sizing for
**/
static void
gtk_tree_view_check_dirty_and_clean (GtkTreeView *tree_view)
@@ -5141,10 +5148,24 @@ gtk_tree_view_clamp_node_visible (GtkTreeView *tree_view,
}
-/* This function could be more efficient.
- * I'll optimize it if profiling seems to imply that
- * it's important
- */
+static void
+gtk_tree_view_clamp_column_visible (GtkTreeView *tree_view,
+ GtkTreeViewColumn *column)
+{
+ if (column == NULL)
+ return;
+ if ((tree_view->priv->hadjustment->value + tree_view->priv->hadjustment->page_size) <
+ (column->button->allocation.x + column->button->allocation.width))
+ gtk_adjustment_set_value (tree_view->priv->hadjustment,
+ column->button->allocation.x + column->button->allocation.width -
+ tree_view->priv->hadjustment->page_size);
+ else if (tree_view->priv->hadjustment->value > column->button->allocation.x)
+ gtk_adjustment_set_value (tree_view->priv->hadjustment,
+ column->button->allocation.x);
+}
+
+/* This function could be more efficient. I'll optimize it if profiling seems
+ * to imply that it is important */
GtkTreePath *
_gtk_tree_view_find_path (GtkTreeView *tree_view,
GtkRBTree *tree,
@@ -5563,9 +5584,9 @@ gtk_tree_view_queue_draw_arrow (GtkTreeView *tree_view,
if (clip_rect)
{
GdkRectangle new_rect;
-
+
gdk_rectangle_intersect (clip_rect, &rect, &new_rect);
-
+
gdk_window_invalidate_rect (tree_view->priv->bin_window, &new_rect, TRUE);
}
else
@@ -5635,7 +5656,7 @@ gtk_tree_view_draw_arrow (GtkTreeView *tree_view,
gint vertical_separator;
gint expander_size;
GtkExpanderStyle expander_style;
-
+
gtk_widget_style_get (GTK_WIDGET (tree_view),
"vertical_separator", &vertical_separator,
"expander_size", &expander_size,
@@ -5749,6 +5770,18 @@ gtk_tree_view_focus_to_cursor (GtkTreeView *tree_view)
gtk_tree_view_real_set_cursor (tree_view, cursor_path, TRUE);
}
gtk_tree_path_free (cursor_path);
+ if (tree_view->priv->focus_column == NULL)
+ {
+ GList *list;
+ for (list = tree_view->priv->columns; list; list = list->next)
+ {
+ if (GTK_TREE_VIEW_COLUMN (list->data)->visible)
+ {
+ tree_view->priv->focus_column = GTK_TREE_VIEW_COLUMN (list->data);
+ break;
+ }
+ }
+ }
}
static void
@@ -5829,9 +5862,7 @@ gtk_tree_view_move_cursor_page_up_down (GtkTreeView *tree_view,
_gtk_rbtree_find_offset (tree_view->priv->tree, y, &cursor_tree, &cursor_node);
cursor_path = _gtk_tree_view_find_path (tree_view, cursor_tree, cursor_node);
g_return_if_fail (cursor_path != NULL);
- gtk_tree_view_real_set_cursor (tree_view,
- cursor_path,
- TRUE);
+ gtk_tree_view_real_set_cursor (tree_view, cursor_path, TRUE);
}
static void
@@ -5870,19 +5901,19 @@ gtk_tree_view_move_cursor_left_right (GtkTreeView *tree_view,
break;
}
}
-
+
while (list)
{
column = list->data;
if (column->visible == FALSE)
goto loop_end;
- gtk_tree_view_column_cell_set_cell_data (column,
- tree_view->priv->model,
- &iter,
- GTK_RBNODE_FLAG_SET (cursor_node, GTK_RBNODE_IS_PARENT),
- cursor_node->children?TRUE:FALSE);
- if (gtk_tree_view_column_cell_focus (column, count, FALSE))
+ gtk_tree_view_column_cell_set_cell_data (column,
+ tree_view->priv->model,
+ &iter,
+ GTK_RBNODE_FLAG_SET (cursor_node, GTK_RBNODE_IS_PARENT),
+ cursor_node->children?TRUE:FALSE);
+ if (gtk_tree_view_column_cell_focus (column, count))
{
tree_view->priv->focus_column = column;
found_column = TRUE;
@@ -5901,9 +5932,8 @@ gtk_tree_view_move_cursor_left_right (GtkTreeView *tree_view,
cursor_tree,
cursor_node,
NULL);
- return;
}
- g_print ("scroll now!\n");
+ gtk_tree_view_clamp_column_visible (tree_view, tree_view->priv->focus_column);
}
static void
@@ -5959,8 +5989,8 @@ gtk_tree_view_real_select_cursor_row (GtkTreeView *tree_view)
GtkRBNode *cursor_node = NULL;
GtkTreePath *cursor_path = NULL;
GdkModifierType state = 0;
-
cursor_path = NULL;
+
if (tree_view->priv->cursor)
cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
@@ -5969,12 +5999,22 @@ gtk_tree_view_real_select_cursor_row (GtkTreeView *tree_view)
_gtk_tree_view_find_node (tree_view, cursor_path,
&cursor_tree, &cursor_node);
+
if (cursor_tree == NULL)
{
gtk_tree_path_free (cursor_path);
return;
}
+ if (tree_view->priv->focus_column)
+ {
+ if (gtk_tree_view_start_editing (tree_view, cursor_path))
+ {
+ gtk_tree_path_free (cursor_path);
+ return;
+ }
+ }
+
gtk_get_current_event_state (&state);
_gtk_tree_selection_internal_select_node (tree_view->priv->selection,
cursor_node,
@@ -5985,7 +6025,9 @@ gtk_tree_view_real_select_cursor_row (GtkTreeView *tree_view)
gtk_tree_view_clamp_node_visible (tree_view, cursor_tree, cursor_node);
gtk_widget_grab_focus (GTK_WIDGET (tree_view));
- gtk_tree_view_queue_draw_path (tree_view, cursor_path, NULL);
+ gtk_tree_view_queue_draw_node (tree_view, cursor_tree, cursor_node, NULL);
+ gtk_tree_view_row_activated (tree_view, cursor_path, tree_view->priv->focus_column);
+
gtk_tree_path_free (cursor_path);
}
@@ -6096,6 +6138,58 @@ gtk_tree_view_real_select_cursor_parent (GtkTreeView *tree_view)
gtk_tree_path_free (cursor_path);
}
+static void
+gtk_tree_view_real_start_interactive_search (GtkTreeView *tree_view)
+{
+ GtkWidget *window;
+ GtkWidget *entry;
+
+ if (tree_view->priv->enable_search == FALSE ||
+ tree_view->priv->search_column < 0)
+ return;
+
+ /* set up window */
+ window = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_window_set_title (GTK_WINDOW (window), "search dialog");
+ gtk_container_set_border_width (GTK_CONTAINER (window), 3);
+ gtk_window_set_modal (GTK_WINDOW (window), TRUE);
+ gtk_signal_connect
+ (GTK_OBJECT (window), "delete_event",
+ GTK_SIGNAL_FUNC (gtk_tree_view_search_delete_event),
+ tree_view);
+ gtk_signal_connect
+ (GTK_OBJECT (window), "key_press_event",
+ GTK_SIGNAL_FUNC (gtk_tree_view_search_key_press_event),
+ tree_view);
+ gtk_signal_connect
+ (GTK_OBJECT (window), "button_press_event",
+ GTK_SIGNAL_FUNC (gtk_tree_view_search_button_press_event),
+ tree_view);
+
+ /* add entry */
+ entry = gtk_entry_new ();
+ gtk_widget_show (entry);
+ gtk_signal_connect
+ (GTK_OBJECT (entry), "changed",
+ GTK_SIGNAL_FUNC (gtk_tree_view_search_init),
+ tree_view);
+ gtk_container_add (GTK_CONTAINER (window), entry);
+
+ /* done, show it */
+ tree_view->priv->search_dialog_position_func (tree_view, window);
+ gtk_widget_show_all (window);
+ gtk_widget_grab_focus (entry);
+
+ /* position window */
+
+ gtk_object_set_data (GTK_OBJECT (window), "text",
+ gtk_entry_get_text (GTK_ENTRY (entry)));
+ gtk_object_set_data (GTK_OBJECT (tree_view), "search-dialog", window);
+
+ /* search first matching iter */
+ gtk_tree_view_search_init (entry, tree_view);
+}
+
void
_gtk_tree_view_update_size (GtkTreeView *tree_view)
{
@@ -6982,7 +7076,7 @@ gtk_tree_view_move_column_after (GtkTreeView *tree_view,
* gtk_tree_view_set_expander_column:
* @tree_view: A #GtkTreeView
* @column: NULL, or the column to draw the expander arrow at.
- *
+ *
* Sets the column to draw the expander arrow at. It must be in @tree_view. If
* @column is %NULL, then the expander arrow is fixed at the first column.
**/
@@ -7204,8 +7298,6 @@ gtk_tree_view_row_activated (GtkTreeView *tree_view,
{
g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
- /* FIXME: Actually activate the path internally, not just emit the signal */
- /* g_warning ("FIXME: Actually activate the path internally, not just emit the signal\n"); */
g_signal_emit (G_OBJECT(tree_view), tree_view_signals[ROW_ACTIVATED], 0, path, column);
}
@@ -7277,13 +7369,13 @@ expand_collapse_timeout (gpointer data)
gboolean redraw;
GDK_THREADS_ENTER ();
-
+
redraw = FALSE;
expanding = TRUE;
node = tree_view->priv->expanded_collapsed_node;
tree = tree_view->priv->expanded_collapsed_tree;
-
+
if (node->children == NULL)
expanding = FALSE;
@@ -7295,7 +7387,7 @@ expand_collapse_timeout (gpointer data)
GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_SEMI_EXPANDED);
redraw = TRUE;
-
+
}
else if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SEMI_EXPANDED))
{
@@ -7417,7 +7509,7 @@ gtk_tree_view_real_expand_row (GtkTreeView *tree_view,
if (tree_view->priv->expand_collapse_timeout)
gtk_timeout_remove (tree_view->priv->expand_collapse_timeout);
-
+
if (tree_view->priv->expanded_collapsed_node != NULL)
{
GTK_RBNODE_UNSET_FLAG (tree_view->priv->expanded_collapsed_node, GTK_RBNODE_IS_SEMI_EXPANDED);
@@ -7427,7 +7519,7 @@ gtk_tree_view_real_expand_row (GtkTreeView *tree_view,
tree_view->priv->expand_collapse_timeout = gtk_timeout_add (50, expand_collapse_timeout, tree_view);
tree_view->priv->expanded_collapsed_node = node;
tree_view->priv->expanded_collapsed_tree = tree;
-
+
GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_SEMI_COLLAPSED);
if (GTK_WIDGET_MAPPED (tree_view))
@@ -7497,7 +7589,7 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view,
/* if the prelighted node is a child of us, we want to unprelight it. We have
* a chance to prelight the correct node below */
-
+
if (tree_view->priv->prelight_tree)
{
GtkRBTree *parent_tree;
@@ -7528,7 +7620,7 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view,
if (gtk_tree_view_column_get_sizing (column) == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
gtk_tree_view_column_cell_set_dirty (column);
}
-
+
if (tree_view->priv->destroy_count_func)
{
GtkTreePath *child_path;
@@ -7559,7 +7651,7 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view,
tree_view->priv->expanded_collapsed_tree = tree;
GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_SEMI_EXPANDED);
-
+
if (GTK_WIDGET_MAPPED (tree_view))
{
gtk_widget_queue_draw (GTK_WIDGET (tree_view));
@@ -7713,9 +7805,9 @@ gtk_tree_view_map_expanded_rows (GtkTreeView *tree_view,
* gtk_tree_view_row_expanded:
* @tree_view: A #GtkTreeView.
* @path: A #GtkTreePath to test expansion state.
- *
+ *
* Returns TRUE if the node pointed to by @path is expanded in @tree_view.
- *
+ *
* Return value: TRUE if #path is expanded.
**/
gboolean
@@ -7837,21 +7929,45 @@ gtk_tree_view_real_set_cursor (GtkTreeView *tree_view,
* gtk_tree_view_set_cursor:
* @tree_view: A #GtkTreeView
* @path: A #GtkTreePath
+ * @focus_column: A #GtkTreeViewColumn, or NULL
+ * @start_editing: %TRUE if the specified cell should start being edited.
*
* Sets the current keyboard focus to be at @path, and selects it. This is
* useful when you want to focus the user's attention on a particular row. If
- * you want to give the user keyboard focus in the tree_view, you should use
- * this function to set the correct path, and gtk_widget_grab_focus (GTK_WIDGET
- * (tree_view)) to actually give focus to the @tree_view.
+ * @column is not %NULL, then focus is given to the column specified by it.
+ * Additionally, if @column is specified, and @start_editing is %TRUE, then
+ * editing should be started in the specified cell. Keyboard focus is given to
+ * the widget after this is called.
**/
void
-gtk_tree_view_set_cursor (GtkTreeView *tree_view,
- GtkTreePath *path)
+gtk_tree_view_set_cursor (GtkTreeView *tree_view,
+ GtkTreePath *path,
+ GtkTreeViewColumn *focus_column,
+ gboolean start_editing)
{
g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
g_return_if_fail (path != NULL);
+ if (focus_column)
+ g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (focus_column));
gtk_tree_view_real_set_cursor (tree_view, path, TRUE);
+
+ gtk_widget_grab_focus (GTK_WIDGET (tree_view));
+ if (focus_column && focus_column->visible)
+ {
+ GList *list;
+ gboolean column_in_tree = FALSE;
+
+ for (list = tree_view->priv->columns; list; list = list->next)
+ if (list->data == focus_column)
+ {
+ column_in_tree = TRUE;
+ break;
+ }
+ g_return_if_fail (column_in_tree);
+ if (start_editing)
+ gtk_tree_view_start_editing (tree_view, path);
+ }
}
@@ -7990,12 +8106,13 @@ gtk_tree_view_get_path_at_pos (GtkTreeView *tree_view,
*
* Fills the bounding rectangle in tree window coordinates for the cell at the
* row specified by @path and the column specified by @column. If @path is
- * %NULL, the y and height fields of the rectangle will be filled with 0. If
- * @column is %NULL, the x and width fields will be filled with 0. The sum of
- * all cell rects does not cover the entire tree; there are extra pixels in
- * between rows, for example. The returned rectangle is equivalent to the
- * @cell_area passed to gtk_cell_renderer_render(). This function is only valid
- * if #tree_view is realized.
+ * %NULL, or points to a path not currently displayed, the y and height fields
+ * of the rectangle will be filled with 0. If @column is %NULL, the x and width
+ * fields will be filled with 0. The sum of all cell rects does not cover the
+ * entire tree; there are extra pixels in between rows, for example. The
+ * returned rectangle is equivalent to the @cell_area passed to
+ * gtk_cell_renderer_render(). This function is only valid if #tree_view is
+ * realized.
**/
void
gtk_tree_view_get_cell_area (GtkTreeView *tree_view,
@@ -8006,6 +8123,7 @@ gtk_tree_view_get_cell_area (GtkTreeView *tree_view,
GtkRBTree *tree = NULL;
GtkRBNode *node = NULL;
gint vertical_separator;
+ gint horizontal_separator;
g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
g_return_if_fail (column == NULL || GTK_IS_TREE_VIEW_COLUMN (column));
@@ -8013,37 +8131,40 @@ gtk_tree_view_get_cell_area (GtkTreeView *tree_view,
g_return_if_fail (!column || column->tree_view == (GtkWidget *) tree_view);
g_return_if_fail (GTK_WIDGET_REALIZED (tree_view));
- gtk_widget_style_get (GTK_WIDGET (tree_view), "vertical_separator", &vertical_separator, NULL);
+ gtk_widget_style_get (GTK_WIDGET (tree_view),
+ "vertical_separator", &vertical_separator,
+ "horizontal_separator", &horizontal_separator,
+ NULL);
rect->x = 0;
rect->y = 0;
rect->width = 0;
rect->height = 0;
+ if (column)
+ {
+ rect->x = column->button->allocation.x + horizontal_separator/2;
+ rect->width = column->button->allocation.width - horizontal_separator;
+ }
+
if (path)
{
/* Get vertical coords */
+ if (_gtk_tree_view_find_node (tree_view, path, &tree, &node) &&
+ tree != NULL)
+ return;
- _gtk_tree_view_find_node (tree_view, path, &tree, &node);
-
- if (tree == NULL)
- {
- g_warning (G_STRLOC": no row corresponding to path");
- return;
- }
-
- /* Remember that the rbtree stores node height including the vertical
- * separator, see comment at top of file.
- */
rect->y = CELL_FIRST_PIXEL (tree_view, tree, node, vertical_separator);
-
rect->height = CELL_HEIGHT (node, vertical_separator);
- }
- if (column)
- {
- rect->x = column->button->allocation.x;
- rect->width = column->button->allocation.width;
+ if (gtk_tree_view_is_expander_column (tree_view, column) &&
+ TREE_VIEW_DRAW_EXPANDERS (tree_view))
+ {
+ gint depth = gtk_tree_path_get_depth (path) - 1;
+ rect->x += depth * tree_view->priv->tab_offset;
+ rect->width -= depth * tree_view->priv->tab_offset;
+ rect->width = MAX (rect->width, 0);
+ }
}
}
@@ -8054,17 +8175,16 @@ gtk_tree_view_get_cell_area (GtkTreeView *tree_view,
* @column: a #GtkTreeViewColumn for the column, or %NULL to get only vertical coordiantes
* @rect: rectangle to fill with cell background rect
*
- * Fills the bounding rectangle in tree window coordinates for the
- * cell at the row specified by @path and the column specified by
- * @column. If @path is %NULL, the y and height fields of the
- * rectangle will be filled with 0. If @column is %NULL, the x and
- * width fields will be filled with 0. The returned rectangle is
- * equivalent to the @background_area passed to
- * gtk_cell_renderer_render(). These background areas tile to cover
- * the entire tree window (except for the area used for header
- * buttons). Contrast with the cell_area, returned by
- * gtk_tree_view_get_cell_area(), which returns only the cell itself,
- * excluding surrounding borders and the tree expander area.
+ * Fills the bounding rectangle in tree window coordinates for the cell at the
+ * row specified by @path and the column specified by @column. If @path is
+ * %NULL, or points to a node not found in the tree, the y and height fields of
+ * the rectangle will be filled with 0. If @column is %NULL, the x and width
+ * fields will be filled with 0. The returned rectangle is equivalent to the
+ * @background_area passed to gtk_cell_renderer_render(). These background
+ * areas tile to cover the entire tree window (except for the area used for
+ * header buttons). Contrast with the cell_area, returned by
+ * gtk_tree_view_get_cell_area(), which returns only the cell itself, excluding
+ * surrounding borders and the tree expander area.
*
**/
void
@@ -8089,13 +8209,9 @@ gtk_tree_view_get_background_area (GtkTreeView *tree_view,
{
/* Get vertical coords */
- _gtk_tree_view_find_node (tree_view, path, &tree, &node);
-
- if (tree == NULL)
- {
- g_warning (G_STRLOC": no row corresponding to path");
- return;
- }
+ if (_gtk_tree_view_find_node (tree_view, path, &tree, &node) &&
+ tree != NULL)
+ return;
rect->y = BACKGROUND_FIRST_PIXEL (tree_view, tree, node);
@@ -8163,14 +8279,9 @@ gtk_tree_view_widget_to_tree_coords (GtkTreeView *tree_view,
g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
if (tx)
- {
- *tx = wx + tree_view->priv->hadjustment->value;
- }
-
+ *tx = wx + tree_view->priv->hadjustment->value;
if (ty)
- {
- *ty = wy + tree_view->priv->vadjustment->value;
- }
+ *ty = wy + tree_view->priv->vadjustment->value;
}
/**
@@ -8195,14 +8306,9 @@ gtk_tree_view_tree_to_widget_coords (GtkTreeView *tree_view,
g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
if (wx)
- {
- *wx = tx - tree_view->priv->hadjustment->value;
- }
-
+ *wx = tx - tree_view->priv->hadjustment->value;
if (wy)
- {
- *wy = ty - tree_view->priv->vadjustment->value;
- }
+ *wy = ty - tree_view->priv->vadjustment->value;
}
@@ -8585,7 +8691,7 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView *tree_view,
* @func: Function to be called when a view row is destroyed, or NULL
* @data: User data to be passed to @func, or NULL
* @destroy: Destroy notifier for @data, or NULL
- *
+ *
* This function should almost never be used. It is meant for private use by
* ATK for determining the number of visible children that are removed when the
* user collapses a row, or a row is deleted.
@@ -8608,7 +8714,7 @@ gtk_tree_view_set_destroy_count_func (GtkTreeView *tree_view,
/*
- * Interactive search
+ * Interactive search
*/
/**
@@ -8657,7 +8763,7 @@ gint
gtk_tree_view_get_search_column (GtkTreeView *tree_view)
{
g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), 0);
-
+
return (tree_view->priv->search_column);
}
@@ -8680,7 +8786,7 @@ gtk_tree_view_set_search_column (GtkTreeView *tree_view,
return;
tree_view->priv->search_column = column;
-
+
}
/**
@@ -8732,7 +8838,7 @@ gtk_tree_view_search_dialog_destroy (GtkWidget *search_dialog,
{
/* remove data from tree_view */
gtk_object_remove_data (GTK_OBJECT (tree_view), "search-dialog");
-
+
gtk_widget_destroy (search_dialog);
}
@@ -8756,84 +8862,6 @@ gtk_tree_view_search_position_func (GtkTreeView *tree_view,
tree_y + tree_height);
}
-static void
-gtk_tree_view_interactive_search (GtkTreeView *tree_view,
- GdkEventKey *event)
-{
- GtkWidget *window;
- GtkWidget *entry;
-
- g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
- switch (event->keyval)
- {
- case GDK_Shift_L:
- case GDK_Shift_R:
- case GDK_Control_L:
- case GDK_Control_R:
- case GDK_Caps_Lock:
- case GDK_Shift_Lock:
- case GDK_Meta_L:
- case GDK_Meta_R:
- case GDK_Alt_L:
- case GDK_Alt_R:
- case GDK_Super_L:
- case GDK_Super_R:
- case GDK_Hyper_L:
- case GDK_Hyper_R:
- case GDK_Mode_switch:
- return;
- default:
- break;
- }
-
- if (tree_view->priv->enable_search == FALSE ||
- tree_view->priv->search_column < 0)
- return;
-
- /* set up window */
- window = gtk_window_new (GTK_WINDOW_POPUP);
- gtk_window_set_title (GTK_WINDOW (window), "search dialog");
- gtk_container_set_border_width (GTK_CONTAINER (window), 3);
- gtk_window_set_modal (GTK_WINDOW (window), TRUE);
- gtk_signal_connect
- (GTK_OBJECT (window), "delete_event",
- GTK_SIGNAL_FUNC (gtk_tree_view_search_delete_event),
- tree_view);
- gtk_signal_connect
- (GTK_OBJECT (window), "key_press_event",
- GTK_SIGNAL_FUNC (gtk_tree_view_search_key_press_event),
- tree_view);
- gtk_signal_connect
- (GTK_OBJECT (window), "button_press_event",
- GTK_SIGNAL_FUNC (gtk_tree_view_search_button_press_event),
- tree_view);
-
- /* add entry */
- entry = gtk_entry_new ();
- gtk_widget_show (entry);
- gtk_signal_connect
- (GTK_OBJECT (entry), "changed",
- GTK_SIGNAL_FUNC (gtk_tree_view_search_init),
- tree_view);
- gtk_container_add (GTK_CONTAINER (window), entry);
-
- /* done, show it */
- tree_view->priv->search_dialog_position_func (tree_view, window);
- gtk_widget_show_all (window);
- gtk_widget_grab_focus (entry);
-
- gtk_widget_event (entry, (GdkEvent *) event);
-
- /* position window */
-
- gtk_object_set_data (GTK_OBJECT (window), "text",
- gtk_entry_get_text (GTK_ENTRY (entry)));
- gtk_object_set_data (GTK_OBJECT (tree_view), "search-dialog", window);
-
- /* search first matching iter */
- gtk_tree_view_search_init (entry, tree_view);
-}
-
static gboolean
gtk_tree_view_search_delete_event (GtkWidget *widget,
GdkEventAny *event,
@@ -8842,7 +8870,7 @@ gtk_tree_view_search_delete_event (GtkWidget *widget,
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
gtk_tree_view_search_dialog_destroy (widget, tree_view);
-
+
return TRUE;
}
@@ -8854,7 +8882,7 @@ gtk_tree_view_search_button_press_event (GtkWidget *widget,
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
gtk_tree_view_search_dialog_destroy (widget, tree_view);
-
+
return TRUE;
}
@@ -8865,10 +8893,11 @@ gtk_tree_view_search_key_press_event (GtkWidget *widget,
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), FALSE);
-
+
/* close window */
- if (event->keyval == GDK_Escape || event->keyval == GDK_Return
- || event->keyval == GDK_Tab)
+ if (event->keyval == GDK_Escape ||
+ event->keyval == GDK_Return ||
+ event->keyval == GDK_Tab)
{
gtk_tree_view_search_dialog_destroy (widget, tree_view);
return TRUE;
@@ -8877,20 +8906,17 @@ gtk_tree_view_search_key_press_event (GtkWidget *widget,
/* select previous matching iter */
if (event->keyval == GDK_Up)
{
- gtk_tree_view_search_move (widget,
- tree_view,
- TRUE);
+ gtk_tree_view_search_move (widget, tree_view, TRUE);
return TRUE;
}
/* select next matching iter */
if (event->keyval == GDK_Down)
{
- gtk_tree_view_search_move (widget,
- tree_view,
- FALSE);
+ gtk_tree_view_search_move (widget, tree_view, FALSE);
return TRUE;
}
+
return FALSE;
}
@@ -8917,23 +8943,25 @@ gtk_tree_view_search_move (GtkWidget *window,
return;
len = strlen (text);
-
+
if (len < 1)
return;
model = gtk_tree_view_get_model (tree_view);
selection = gtk_tree_view_get_selection (tree_view);
-
+
/* search */
gtk_tree_selection_unselect_all (selection);
gtk_tree_model_get_iter_root (model, &iter);
-
+
ret = gtk_tree_view_search_iter (model, selection, &iter, text,
&count, up?((*selected_iter) - 1):((*selected_iter + 1)));
-
+
if (ret)
- /* found */
- *selected_iter += up?(-1):(1);
+ {
+ /* found */
+ *selected_iter += up?(-1):(1);
+ }
else
{
/* return to old iter */
@@ -8942,7 +8970,6 @@ gtk_tree_view_search_move (GtkWidget *window,
gtk_tree_view_search_iter (model, selection,
&iter, text,
&count, *selected_iter);
-
}
}
@@ -8966,12 +8993,12 @@ gtk_tree_view_search_equal_func (GtkTreeModel *model,
normalized_key = g_utf8_normalize (key, -1, G_NORMALIZE_ALL);
case_normalized_string = g_utf8_casefold (normalized_string, -1);
case_normalized_key = g_utf8_casefold (normalized_key, -1);
-
+
key_len = strlen (case_normalized_key);
if (!strncmp (case_normalized_key, case_normalized_string, key_len))
retval = FALSE;
-
+
g_value_unset (&value);
g_free (normalized_key);
g_free (normalized_string);
@@ -9014,7 +9041,7 @@ gtk_tree_view_search_iter (GtkTreeModel *model,
if (path)
gtk_tree_path_free (path);
-
+
return TRUE;
}
}
@@ -9029,7 +9056,7 @@ gtk_tree_view_search_iter (GtkTreeModel *model,
while (node->left != tree->nil)
node = node->left;
-
+
tmp = *iter;
has_child = gtk_tree_model_iter_children (model, iter, &tmp);
gtk_tree_path_append_index (path, 0);
@@ -9044,13 +9071,13 @@ gtk_tree_view_search_iter (GtkTreeModel *model,
do
{
node = _gtk_rbtree_next (tree, node);
-
+
if (node)
{
gboolean has_next;
-
+
has_next = gtk_tree_model_iter_next (model, iter);
-
+
done = TRUE;
gtk_tree_path_next (path);
@@ -9090,7 +9117,7 @@ gtk_tree_view_search_iter (GtkTreeModel *model,
if (path)
gtk_tree_path_free (path);
-
+
return FALSE;
}
@@ -9107,10 +9134,10 @@ gtk_tree_view_search_init (GtkWidget *entry,
GtkTreeIter iter;
GtkTreeModel *model;
GtkTreeSelection *selection;
-
+
g_return_if_fail (GTK_IS_ENTRY (entry));
g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
-
+
window = gtk_widget_get_parent (entry);
text = gtk_entry_get_text (GTK_ENTRY (entry));
len = strlen (text);
@@ -9126,14 +9153,14 @@ gtk_tree_view_search_init (GtkWidget *entry,
if (len < 1)
return;
-
+
gtk_tree_model_get_iter_root (model, &iter);
-
+
ret = gtk_tree_view_search_iter (model, selection,
&iter, text,
&count, 1);
- if (ret)
+ if (ret)
{
selected_iter = g_malloc (sizeof (int));
*selected_iter = 1;
@@ -9148,20 +9175,85 @@ gtk_tree_view_remove_widget (GtkCellEditable *cell_editable,
{
g_return_if_fail (tree_view->priv->edited_column != NULL);
_gtk_tree_view_column_stop_editing (tree_view->priv->edited_column);
+ tree_view->priv->edited_column = NULL;
+
gtk_container_remove (GTK_CONTAINER (tree_view),
GTK_WIDGET (cell_editable));
+ gtk_widget_grab_focus (GTK_WIDGET (tree_view));
+}
+
+static gboolean
+gtk_tree_view_start_editing (GtkTreeView *tree_view,
+ GtkTreePath *cursor_path)
+{
+ GtkTreeIter iter;
+ GdkRectangle background_area;
+ GdkRectangle cell_area;
+ GtkCellEditable *editable_widget = NULL;
+ gchar *path_string;
+ guint flags = 0; /* can be 0, as the flags are primarily for rendering */
+ gint retval = FALSE;
+ GtkRBTree *cursor_tree;
+ GtkRBNode *cursor_node;
+
+ g_assert (tree_view->priv->focus_column);
+
+ if (_gtk_tree_view_find_node (tree_view, cursor_path, &cursor_tree, &cursor_node) ||
+ cursor_node == NULL)
+ return FALSE;
+
+ path_string = gtk_tree_path_to_string (cursor_path);
+ gtk_tree_model_get_iter (tree_view->priv->model, &iter, cursor_path);
+ gtk_tree_view_column_cell_set_cell_data (tree_view->priv->focus_column,
+ tree_view->priv->model,
+ &iter,
+ GTK_RBNODE_FLAG_SET (cursor_node, GTK_RBNODE_IS_PARENT),
+ cursor_node->children?TRUE:FALSE);
+ gtk_tree_view_get_background_area (tree_view,
+ cursor_path,
+ tree_view->priv->focus_column,
+ &background_area);
+ gtk_tree_view_get_cell_area (tree_view,
+ cursor_path,
+ tree_view->priv->focus_column,
+ &cell_area);
+ if (_gtk_tree_view_column_cell_event (tree_view->priv->focus_column,
+ &editable_widget,
+ NULL,
+ path_string,
+ &background_area,
+ &cell_area,
+ flags))
+ {
+ retval = TRUE;
+ if (editable_widget != NULL)
+ {
+ gtk_tree_view_real_start_editing (tree_view,
+ tree_view->priv->focus_column,
+ cursor_path,
+ editable_widget,
+ &cell_area,
+ NULL,
+ flags);
+ }
+
+ }
+ g_free (path_string);
+ return retval;
}
static void
-gtk_tree_view_start_editing (GtkTreeView *tree_view,
- GtkTreeViewColumn *column,
- GtkCellEditable *cell_editable,
- GdkRectangle *cell_area,
- GdkEvent *event,
- guint flags)
+gtk_tree_view_real_start_editing (GtkTreeView *tree_view,
+ GtkTreeViewColumn *column,
+ GtkTreePath *path,
+ GtkCellEditable *cell_editable,
+ GdkRectangle *cell_area,
+ GdkEvent *event,
+ guint flags)
{
tree_view->priv->edited_column = column;
_gtk_tree_view_column_start_editing (column, GTK_CELL_EDITABLE (cell_editable));
+ gtk_tree_view_real_set_cursor (tree_view, path, FALSE);
GTK_TREE_VIEW_SET_FLAG (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS);
gtk_tree_view_put (tree_view,
GTK_WIDGET (cell_editable),
@@ -9177,6 +9269,7 @@ gtk_tree_view_stop_editing (GtkTreeView *tree_view)
{
if (tree_view->priv->edited_column == NULL)
return;
+
gtk_cell_editable_editing_done (tree_view->priv->edited_column->editable_widget);
gtk_cell_editable_remove_widget (tree_view->priv->edited_column->editable_widget);
}
diff --git a/gtk/gtktreeview.h b/gtk/gtktreeview.h
index 2c10f253c..2ce8aafd8 100644
--- a/gtk/gtktreeview.h
+++ b/gtk/gtktreeview.h
@@ -96,6 +96,7 @@ struct _GtkTreeViewClass
gboolean expand,
gboolean open_all);
void (* select_cursor_parent) (GtkTreeView *tree_view);
+ void (* start_interactive_search) (GtkTreeView *tree_view);
};
@@ -212,7 +213,9 @@ void gtk_tree_view_set_reorderable (GtkTreeView
gboolean reorderable);
gboolean gtk_tree_view_get_reorderable (GtkTreeView *tree_view);
void gtk_tree_view_set_cursor (GtkTreeView *tree_view,
- GtkTreePath *path);
+ GtkTreePath *path,
+ GtkTreeViewColumn *focus_column,
+ gboolean start_editing);
/* Layout information */
diff --git a/gtk/gtktreeviewcolumn.c b/gtk/gtktreeviewcolumn.c
index 7d477b0fa..34e5608e8 100644
--- a/gtk/gtktreeviewcolumn.c
+++ b/gtk/gtktreeviewcolumn.c
@@ -2129,39 +2129,34 @@ gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
}
}
-/**
- * gtk_tree_view_column_cell_render:
- * @tree_column: A #GtkTreeViewColumn.
- * @window: a #GdkDrawable to draw to
- * @background_area: entire cell area (including tree expanders and maybe padding on the sides)
- * @cell_area: area normally rendered by a cell renderer
- * @expose_area: area that actually needs updating
- * @flags: flags that affect rendering
- *
- * Renders the cell contained by #tree_column. This is used primarily by the
- * GtkTreeView.
- **/
-void
-gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
- GdkWindow *window,
- GdkRectangle *background_area,
- GdkRectangle *cell_area,
- GdkRectangle *expose_area,
- guint flags)
+/* both rendering and rendering focus are somewhat complicated, and a bit of
+ * code. Rather than duplicate them, we put them together to keep the code in
+ * one place
+ */
+static void
+gtk_tree_view_column_cell_render_or_focus (GtkTreeViewColumn *tree_column,
+ GdkWindow *window,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GdkRectangle *expose_area,
+ guint flags,
+ gboolean render,
+ GdkRectangle *focus_rectangle)
{
GList *list;
GdkRectangle real_cell_area;
gint expand_cell_count = 0;
gint full_requested_width = 0;
gint extra_space;
+ gint min_x, min_y, max_x, max_y;
- g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
- g_return_if_fail (background_area != NULL);
- g_return_if_fail (cell_area != NULL);
- g_return_if_fail (expose_area != NULL);
+ min_x = G_MAXINT;
+ min_y = G_MAXINT;
+ max_x = 0;
+ max_y = 0;
real_cell_area = *cell_area;
-
+
/* Find out how my extra space we have to allocate */
for (list = tree_column->cell_list; list; list = list->next)
{
@@ -2195,13 +2190,35 @@ gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
real_cell_area.width = info->requested_width +
(info->expand?extra_space:0);
- gtk_cell_renderer_render (info->cell,
- window,
- tree_column->tree_view,
- background_area,
- &real_cell_area,
- expose_area,
- flags);
+ if (render)
+ {
+ gtk_cell_renderer_render (info->cell,
+ window,
+ tree_column->tree_view,
+ background_area,
+ &real_cell_area,
+ expose_area,
+ flags);
+ }
+ else
+ {
+ gint x_offset, y_offset, width, height;
+
+ gtk_cell_renderer_get_size (info->cell,
+ tree_column->tree_view,
+ &real_cell_area,
+ &x_offset, &y_offset,
+ &width, &height);
+
+ if (min_x > (real_cell_area.x + x_offset))
+ min_x = real_cell_area.x + x_offset;
+ if (max_x < real_cell_area.x + x_offset + width)
+ max_x = real_cell_area.x + x_offset + width;
+ if (min_y > (real_cell_area.y + y_offset))
+ min_y = real_cell_area.y + y_offset;
+ if (max_y < real_cell_area.y + y_offset + height)
+ max_y = real_cell_area.y + y_offset + height;
+ }
real_cell_area.x += (info->requested_width + tree_column->spacing);
}
for (list = g_list_last (tree_column->cell_list); list; list = list->prev)
@@ -2227,6 +2244,59 @@ gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
flags);
real_cell_area.x += (info->requested_width + tree_column->spacing);
}
+ if (! render)
+ {
+ if (min_x >= max_x || min_y >= max_y)
+ {
+ *focus_rectangle = *cell_area;
+ focus_rectangle->x -= 1;
+ focus_rectangle->y -= 1;
+ focus_rectangle->width += 2;
+ focus_rectangle->height += 2;
+ }
+ else
+ {
+ focus_rectangle->x = min_x - 1;
+ focus_rectangle->y = min_y - 1;
+ focus_rectangle->width = (max_x - min_x) + 2;
+ focus_rectangle->height = (max_y - min_y) + 2;
+ }
+ }
+}
+
+/**
+ * gtk_tree_view_column_cell_render:
+ * @tree_column: A #GtkTreeViewColumn.
+ * @window: a #GdkDrawable to draw to
+ * @background_area: entire cell area (including tree expanders and maybe padding on the sides)
+ * @cell_area: area normally rendered by a cell renderer
+ * @expose_area: area that actually needs updating
+ * @flags: flags that affect rendering
+ *
+ * Renders the cell contained by #tree_column. This is used primarily by the
+ * GtkTreeView.
+ **/
+void
+gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
+ GdkWindow *window,
+ GdkRectangle *background_area,
+ GdkRectangle *cell_area,
+ GdkRectangle *expose_area,
+ guint flags)
+{
+ g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
+ g_return_if_fail (background_area != NULL);
+ g_return_if_fail (cell_area != NULL);
+ g_return_if_fail (expose_area != NULL);
+
+ gtk_tree_view_column_cell_render_or_focus (tree_column,
+ window,
+ background_area,
+ cell_area,
+ expose_area,
+ flags,
+ TRUE,
+ NULL);
}
gboolean
@@ -2266,7 +2336,13 @@ _gtk_tree_view_column_cell_event (GtkTreeViewColumn *tree_column,
background_area,
cell_area,
flags);
- return (*editable_widget != NULL);
+
+ if (*editable_widget != NULL)
+ {
+ g_return_val_if_fail (GTK_IS_CELL_EDITABLE (*editable_widget), FALSE);
+
+ return TRUE;
+ }
}
return FALSE;
}
@@ -2274,13 +2350,10 @@ _gtk_tree_view_column_cell_event (GtkTreeViewColumn *tree_column,
gboolean
gtk_tree_view_column_cell_focus (GtkTreeViewColumn *tree_column,
- gint direction,
- gboolean unfocus)
+ gint direction)
{
- if (unfocus)
- GTK_TREE_VIEW (tree_column->tree_view)->priv->focus_column = NULL;
- else
- GTK_TREE_VIEW (tree_column->tree_view)->priv->focus_column = tree_column;
+ if (GTK_TREE_VIEW (tree_column->tree_view)->priv->focus_column == tree_column)
+ return FALSE;
return TRUE;
}
@@ -2292,15 +2365,45 @@ gtk_tree_view_column_cell_draw_focus (GtkTreeViewColumn *tree_column,
GdkRectangle *expose_area,
guint flags)
{
- gtk_paint_focus (tree_column->tree_view->style,
- window,
- NULL,
- tree_column->tree_view,
- "treeview",
- cell_area->x,
- cell_area->y,
- cell_area->width-1,
- cell_area->height);
+ g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
+ if (tree_column->editable_widget)
+ {
+ /* This function is only called on the editable row when editing.
+ */
+
+ gtk_paint_focus (tree_column->tree_view->style,
+ window,
+ NULL,
+ tree_column->tree_view,
+ "treeview",
+ cell_area->x - 1,
+ cell_area->y - 1,
+ cell_area->width + 2 - 1,
+ cell_area->height + 2 - 1);
+
+ }
+ else
+ {
+ GdkRectangle focus_rectangle;
+ gtk_tree_view_column_cell_render_or_focus (tree_column,
+ window,
+ background_area,
+ cell_area,
+ expose_area,
+ flags,
+ FALSE,
+ &focus_rectangle);
+
+ gtk_paint_focus (tree_column->tree_view->style,
+ window,
+ NULL,
+ tree_column->tree_view,
+ "treeview",
+ focus_rectangle.x,
+ focus_rectangle.y,
+ focus_rectangle.width - 1,
+ focus_rectangle.height - 1);
+ }
}
gboolean
diff --git a/gtk/gtktreeviewcolumn.h b/gtk/gtktreeviewcolumn.h
index 9bebfb8d6..d8fdd6b0e 100644
--- a/gtk/gtktreeviewcolumn.h
+++ b/gtk/gtktreeviewcolumn.h
@@ -217,8 +217,7 @@ gboolean gtk_tree_view_column_cell_event (GtkTreeViewCol
GdkRectangle *cell_area,
guint flags);
gboolean gtk_tree_view_column_cell_focus (GtkTreeViewColumn *tree_column,
- gint direction,
- gboolean unfocus);
+ gint direction);
void gtk_tree_view_column_cell_draw_focus (GtkTreeViewColumn *tree_column,
GdkWindow *window,
GdkRectangle *background_area,
diff --git a/tests/Makefile.am b/tests/Makefile.am
index ddb04fb83..44512c061 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -35,6 +35,7 @@ noinst_PROGRAMS = \
$(testsocket_programs) \
testtext \
testtextbuffer \
+ testtreeedit \
testtreeview \
testtreefocus \
testtreecolumns \
@@ -52,6 +53,7 @@ testsocket_DEPENDENCIES = $(DEPS)
testsocket_child_DEPENDENCIES = $(DEPS)
testtext_DEPENDENCIES = $(TEST_DEPS)
testtextbuffer_DEPENDENCIES = $(TEST_DEPS)
+testtreeedit_DEPENDENCIS = $(DEPS)
testtreeview_DEPENDENCIES = $(DEPS)
testtreefocus_DEPENDENCIES = $(DEPS)
testtreecolumns_DEPENDENCIES = $(DEPS)
@@ -68,6 +70,7 @@ testselection_LDADD = $(LDADDS)
testsocket_LDADD = $(LDADDS)
testsocket_child_LDADD = $(LDADDS)
testtextbuffer_LDADD = $(LDADDS)
+testtreeedit_LDADD = $(LDADDS)
testtreeview_LDADD = $(LDADDS)
testtreefocus_LDADD = $(LDADDS)
testtreecolumns_LDADD = $(LDADDS)
@@ -79,6 +82,9 @@ testgtk_SOURCES = \
prop-editor.c \
testgtk.c
+testtreeedit_SOURCES = \
+ testtreeedit.c
+
testtreeview_SOURCES = \
prop-editor.c \
testtreeview.c
diff --git a/tests/testtreecolumns.c b/tests/testtreecolumns.c
index f0468ca6a..c57eb0755 100644
--- a/tests/testtreecolumns.c
+++ b/tests/testtreecolumns.c
@@ -620,14 +620,14 @@ main (int argc, char *argv[])
gtk_button_box_set_child_size (GTK_BUTTON_BOX (bbox), 0, 0);
gtk_box_pack_start (GTK_BOX (vbox2), bbox, TRUE, TRUE, 0);
- button = gtk_button_new_with_label ("<<");
+ button = gtk_button_new_with_mnemonic ("<< (_Q)");
gtk_widget_set_sensitive (button, FALSE);
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (add_left_clicked), top_right_tree_view);
g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (top_right_tree_view))),
"changed", GTK_SIGNAL_FUNC (selection_changed), button);
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
- button = gtk_button_new_with_label (">>");
+ button = gtk_button_new_with_mnemonic (">> (_W)");
gtk_widget_set_sensitive (button, FALSE);
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (add_right_clicked), top_right_tree_view);
g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (left_tree_view))),
@@ -639,14 +639,14 @@ main (int argc, char *argv[])
gtk_button_box_set_child_size (GTK_BUTTON_BOX (bbox), 0, 0);
gtk_box_pack_start (GTK_BOX (vbox2), bbox, TRUE, TRUE, 0);
- button = gtk_button_new_with_label ("<<");
+ button = gtk_button_new_with_mnemonic ("<< (_E)");
gtk_widget_set_sensitive (button, FALSE);
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (add_left_clicked), bottom_right_tree_view);
g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (bottom_right_tree_view))),
"changed", GTK_SIGNAL_FUNC (selection_changed), button);
gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
- button = gtk_button_new_with_label (">>");
+ button = gtk_button_new_with_mnemonic (">> (_R)");
gtk_widget_set_sensitive (button, FALSE);
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (add_right_clicked), bottom_right_tree_view);
g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (left_tree_view))),
diff --git a/tests/testtreeedit.c b/tests/testtreeedit.c
new file mode 100644
index 000000000..c9f595062
--- /dev/null
+++ b/tests/testtreeedit.c
@@ -0,0 +1,140 @@
+#include <gtk/gtk.h>
+
+typedef struct {
+ const gchar *string;
+ gboolean is_editable;
+} ListEntry;
+
+enum {
+ STRING_COLUMN,
+ IS_EDITABLE_COLUMN,
+ NUM_COLUMNS
+};
+
+static ListEntry model_strings[] =
+{
+ {"A simple string", TRUE },
+ {"Another string!", TRUE },
+ {"Guess what, a third string. This one can't be edited", FALSE },
+ {"And then a fourth string. Neither can this", FALSE },
+ {"Multiline\nFun!", TRUE },
+ { NULL }
+};
+
+static GtkTreeModel *
+create_model (void)
+{
+ GtkListStore *model;
+ GtkTreeIter iter;
+ gint i;
+
+ model = gtk_list_store_new (NUM_COLUMNS,
+ G_TYPE_STRING,
+ G_TYPE_BOOLEAN);
+
+ for (i = 0; model_strings[i].string != NULL; i++)
+ {
+ gtk_list_store_append (model, &iter);
+
+ gtk_list_store_set (model, &iter,
+ STRING_COLUMN, model_strings[i].string,
+ IS_EDITABLE_COLUMN, model_strings[i].is_editable,
+ -1);
+ }
+
+ return GTK_TREE_MODEL (model);
+}
+
+static void
+toggled (GtkCellRendererToggle *cell,
+ gchar *path_string,
+ gpointer data)
+{
+ GtkTreeModel *model = GTK_TREE_MODEL (data);
+ GtkTreeIter iter;
+ GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
+ gboolean value;
+
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter, IS_EDITABLE_COLUMN, &value, -1);
+
+ value = !value;
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, IS_EDITABLE_COLUMN, value, -1);
+
+ gtk_tree_path_free (path);
+}
+
+static void
+edited (GtkCellRendererText *cell,
+ gchar *path_string,
+ gchar *new_text,
+ gpointer data)
+{
+ GtkTreeModel *model = GTK_TREE_MODEL (data);
+ GtkTreeIter iter;
+ GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
+
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_list_store_set (GTK_LIST_STORE (model), &iter, STRING_COLUMN, new_text, -1);
+
+ gtk_tree_path_free (path);
+}
+
+gint
+main (gint argc, gchar **argv)
+{
+ GtkWidget *window;
+ GtkWidget *scrolled_window;
+ GtkWidget *tree_view;
+ GtkTreeModel *tree_model;
+ GtkCellRenderer *renderer;
+
+ gtk_init (&argc, &argv);
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (window), "GtkTreeView editing sample");
+ gtk_signal_connect (GTK_OBJECT (window), "destroy", gtk_main_quit, NULL);
+
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_ETCHED_IN);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (window), scrolled_window);
+
+ tree_model = create_model ();
+ tree_view = gtk_tree_view_new_with_model (tree_model);
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE);
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), FALSE);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
+ -1, "String",
+ renderer,
+ "text", STRING_COLUMN,
+ "editable", IS_EDITABLE_COLUMN,
+ NULL);
+
+ g_signal_connect (G_OBJECT (renderer), "edited",
+ G_CALLBACK (edited), tree_model);
+ renderer = gtk_cell_renderer_toggle_new ();
+ g_signal_connect (G_OBJECT (renderer), "toggled",
+ G_CALLBACK (toggled), tree_model);
+
+ g_object_set (G_OBJECT (renderer),
+ "xalign", 0.0,
+ "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE,
+ NULL);
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
+ -1, "Editable",
+ renderer,
+ "active", IS_EDITABLE_COLUMN,
+ NULL);
+ gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
+
+ gtk_window_set_default_size (GTK_WINDOW (window),
+ 650, 400);
+
+ gtk_widget_show_all (window);
+ gtk_main ();
+
+ return 0;
+}
diff --git a/tests/testtreefocus.c b/tests/testtreefocus.c
index 08a3207c4..ca5afd318 100644
--- a/tests/testtreefocus.c
+++ b/tests/testtreefocus.c
@@ -348,7 +348,7 @@ main (int argc, char *argv[])
renderer,
"active", ALEX_COLUMN,
"visible", VISIBLE_COLUMN,
- "can_activate", WORLD_COLUMN,
+ "activatable", WORLD_COLUMN,
NULL);
column = gtk_tree_view_get_column (GTK_TREE_VIEW (tree_view), col_offset - 1);
gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column), GTK_TREE_VIEW_COLUMN_FIXED);
@@ -381,7 +381,7 @@ main (int argc, char *argv[])
renderer,
"active", TIM_COLUMN,
"visible", VISIBLE_COLUMN,
- "can_activate", WORLD_COLUMN,
+ "activatable", WORLD_COLUMN,
NULL);
column = gtk_tree_view_get_column (GTK_TREE_VIEW (tree_view), col_offset - 1);
gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column), GTK_TREE_VIEW_COLUMN_FIXED);
diff --git a/tests/testtreesort.c b/tests/testtreesort.c
index b9f285efa..0dba6d29c 100644
--- a/tests/testtreesort.c
+++ b/tests/testtreesort.c
@@ -12,7 +12,7 @@ struct _ListSort
static ListSort data[] =
{
- { "Apples", "Transmorgrify long word to demonstrate weirdness", "Exculpatory", "Gesundheit"},
+ { "Apples", "Transmogrify long word to demonstrate weirdness", "Exculpatory", "Gesundheit"},
{ "Oranges", "Wicker", "Adamantine", "Convivial" },
{ "Bovine Spongiform Encephilopathy", "Sleazebucket", "Mountaineer", "Pander" },
{ "Foot and Mouth", "Lampshade", "Skim Milk\nFull Milk", "Viewless" },