Fix up focus code a lot.

Mon Mar 12 21:02:08 2001  Jonathan Blandford  <jrb@redhat.com>

	* gtk/gtktreeview.c (gtk_tree_view_header_focus): Fix up focus
	code a lot.

	* gtk/gtktreedatalist.c (_gtk_tree_data_list_free): use
	g_mem_chunk.
	(_gtk_tree_data_list_alloc): use g_mem_chunk.
	(_gtk_tree_data_list_node_to_value): Fix to switch on
	G_TYPE_FUNDAMENTAL.
	(_gtk_tree_data_list_value_to_node): Fix to switch on
	G_TYPE_FUNDAMENTAL.
	(_gtk_tree_data_list_node_copy): Fix to switch on
	G_TYPE_FUNDAMENTAL.
This commit is contained in:
Jonathan Blandford 2001-03-13 02:00:37 +00:00 committed by Jonathan Blandford
parent b0752cb4b2
commit cf89a05f07
13 changed files with 292 additions and 278 deletions

View File

@ -1,3 +1,18 @@
Mon Mar 12 21:02:08 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtktreeview.c (gtk_tree_view_header_focus): Fix up focus
code a lot.
* gtk/gtktreedatalist.c (_gtk_tree_data_list_free): use
g_mem_chunk.
(_gtk_tree_data_list_alloc): use g_mem_chunk.
(_gtk_tree_data_list_node_to_value): Fix to switch on
G_TYPE_FUNDAMENTAL.
(_gtk_tree_data_list_value_to_node): Fix to switch on
G_TYPE_FUNDAMENTAL.
(_gtk_tree_data_list_node_copy): Fix to switch on
G_TYPE_FUNDAMENTAL.
2001-03-12 Havoc Pennington <hp@redhat.com> 2001-03-12 Havoc Pennington <hp@redhat.com>
* gtk/gtkwindow.c (gtk_window_class_init): Patch from John Margaglione * gtk/gtkwindow.c (gtk_window_class_init): Patch from John Margaglione

View File

@ -1,3 +1,18 @@
Mon Mar 12 21:02:08 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtktreeview.c (gtk_tree_view_header_focus): Fix up focus
code a lot.
* gtk/gtktreedatalist.c (_gtk_tree_data_list_free): use
g_mem_chunk.
(_gtk_tree_data_list_alloc): use g_mem_chunk.
(_gtk_tree_data_list_node_to_value): Fix to switch on
G_TYPE_FUNDAMENTAL.
(_gtk_tree_data_list_value_to_node): Fix to switch on
G_TYPE_FUNDAMENTAL.
(_gtk_tree_data_list_node_copy): Fix to switch on
G_TYPE_FUNDAMENTAL.
2001-03-12 Havoc Pennington <hp@redhat.com> 2001-03-12 Havoc Pennington <hp@redhat.com>
* gtk/gtkwindow.c (gtk_window_class_init): Patch from John Margaglione * gtk/gtkwindow.c (gtk_window_class_init): Patch from John Margaglione

View File

@ -1,3 +1,18 @@
Mon Mar 12 21:02:08 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtktreeview.c (gtk_tree_view_header_focus): Fix up focus
code a lot.
* gtk/gtktreedatalist.c (_gtk_tree_data_list_free): use
g_mem_chunk.
(_gtk_tree_data_list_alloc): use g_mem_chunk.
(_gtk_tree_data_list_node_to_value): Fix to switch on
G_TYPE_FUNDAMENTAL.
(_gtk_tree_data_list_value_to_node): Fix to switch on
G_TYPE_FUNDAMENTAL.
(_gtk_tree_data_list_node_copy): Fix to switch on
G_TYPE_FUNDAMENTAL.
2001-03-12 Havoc Pennington <hp@redhat.com> 2001-03-12 Havoc Pennington <hp@redhat.com>
* gtk/gtkwindow.c (gtk_window_class_init): Patch from John Margaglione * gtk/gtkwindow.c (gtk_window_class_init): Patch from John Margaglione

View File

@ -1,3 +1,18 @@
Mon Mar 12 21:02:08 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtktreeview.c (gtk_tree_view_header_focus): Fix up focus
code a lot.
* gtk/gtktreedatalist.c (_gtk_tree_data_list_free): use
g_mem_chunk.
(_gtk_tree_data_list_alloc): use g_mem_chunk.
(_gtk_tree_data_list_node_to_value): Fix to switch on
G_TYPE_FUNDAMENTAL.
(_gtk_tree_data_list_value_to_node): Fix to switch on
G_TYPE_FUNDAMENTAL.
(_gtk_tree_data_list_node_copy): Fix to switch on
G_TYPE_FUNDAMENTAL.
2001-03-12 Havoc Pennington <hp@redhat.com> 2001-03-12 Havoc Pennington <hp@redhat.com>
* gtk/gtkwindow.c (gtk_window_class_init): Patch from John Margaglione * gtk/gtkwindow.c (gtk_window_class_init): Patch from John Margaglione

View File

@ -1,3 +1,18 @@
Mon Mar 12 21:02:08 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtktreeview.c (gtk_tree_view_header_focus): Fix up focus
code a lot.
* gtk/gtktreedatalist.c (_gtk_tree_data_list_free): use
g_mem_chunk.
(_gtk_tree_data_list_alloc): use g_mem_chunk.
(_gtk_tree_data_list_node_to_value): Fix to switch on
G_TYPE_FUNDAMENTAL.
(_gtk_tree_data_list_value_to_node): Fix to switch on
G_TYPE_FUNDAMENTAL.
(_gtk_tree_data_list_node_copy): Fix to switch on
G_TYPE_FUNDAMENTAL.
2001-03-12 Havoc Pennington <hp@redhat.com> 2001-03-12 Havoc Pennington <hp@redhat.com>
* gtk/gtkwindow.c (gtk_window_class_init): Patch from John Margaglione * gtk/gtkwindow.c (gtk_window_class_init): Patch from John Margaglione

View File

@ -1,3 +1,18 @@
Mon Mar 12 21:02:08 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtktreeview.c (gtk_tree_view_header_focus): Fix up focus
code a lot.
* gtk/gtktreedatalist.c (_gtk_tree_data_list_free): use
g_mem_chunk.
(_gtk_tree_data_list_alloc): use g_mem_chunk.
(_gtk_tree_data_list_node_to_value): Fix to switch on
G_TYPE_FUNDAMENTAL.
(_gtk_tree_data_list_value_to_node): Fix to switch on
G_TYPE_FUNDAMENTAL.
(_gtk_tree_data_list_node_copy): Fix to switch on
G_TYPE_FUNDAMENTAL.
2001-03-12 Havoc Pennington <hp@redhat.com> 2001-03-12 Havoc Pennington <hp@redhat.com>
* gtk/gtkwindow.c (gtk_window_class_init): Patch from John Margaglione * gtk/gtkwindow.c (gtk_window_class_init): Patch from John Margaglione

View File

@ -1,3 +1,18 @@
Mon Mar 12 21:02:08 2001 Jonathan Blandford <jrb@redhat.com>
* gtk/gtktreeview.c (gtk_tree_view_header_focus): Fix up focus
code a lot.
* gtk/gtktreedatalist.c (_gtk_tree_data_list_free): use
g_mem_chunk.
(_gtk_tree_data_list_alloc): use g_mem_chunk.
(_gtk_tree_data_list_node_to_value): Fix to switch on
G_TYPE_FUNDAMENTAL.
(_gtk_tree_data_list_value_to_node): Fix to switch on
G_TYPE_FUNDAMENTAL.
(_gtk_tree_data_list_node_copy): Fix to switch on
G_TYPE_FUNDAMENTAL.
2001-03-12 Havoc Pennington <hp@redhat.com> 2001-03-12 Havoc Pennington <hp@redhat.com>
* gtk/gtkwindow.c (gtk_window_class_init): Patch from John Margaglione * gtk/gtkwindow.c (gtk_window_class_init): Patch from John Margaglione

View File

@ -547,7 +547,7 @@ gtk_list_store_set_cell (GtkListStore *list_store,
g_return_if_fail (GTK_IS_LIST_STORE (list_store)); g_return_if_fail (GTK_IS_LIST_STORE (list_store));
g_return_if_fail (iter != NULL); g_return_if_fail (iter != NULL);
g_return_if_fail (column >= 0 && column < list_store->n_columns); g_return_if_fail (column >= 0 && column < list_store->n_columns);
g_return_if_fail (value != NULL); g_return_if_fail (G_IS_VALUE (value));
if (! g_type_is_a (G_VALUE_TYPE (value), list_store->column_headers[column])) if (! g_type_is_a (G_VALUE_TYPE (value), list_store->column_headers[column]))
{ {

View File

@ -19,100 +19,23 @@
#include "gtktreedatalist.h" #include "gtktreedatalist.h"
static GMemChunk *tree_chunk = NULL;
#define TREE_CHUNK_PREALLOCS 64
/* node allocation /* node allocation
*/ */
struct _GAllocator /* from gmem.c */
{
gchar *name;
guint16 n_preallocs;
guint is_unused : 1;
guint type : 4;
GAllocator *last;
GMemChunk *mem_chunk;
GtkTreeDataList *free_nodes;
};
G_LOCK_DEFINE_STATIC (current_allocator);
static GAllocator *current_allocator = NULL;
/* HOLDS: current_allocator_lock */
static void
gtk_tree_data_list_validate_allocator (GAllocator *allocator)
{
g_return_if_fail (allocator != NULL);
g_return_if_fail (allocator->is_unused == TRUE);
if (allocator->type != G_ALLOCATOR_NODE)
{
allocator->type = G_ALLOCATOR_NODE;
if (allocator->mem_chunk)
{
g_mem_chunk_destroy (allocator->mem_chunk);
allocator->mem_chunk = NULL;
}
}
if (!allocator->mem_chunk)
{
allocator->mem_chunk = g_mem_chunk_new (allocator->name,
sizeof (GtkTreeDataList),
sizeof (GtkTreeDataList) * allocator->n_preallocs,
G_ALLOC_ONLY);
allocator->free_nodes = NULL;
}
allocator->is_unused = FALSE;
}
void
_gtk_tree_data_list_push_allocator (GAllocator *allocator)
{
G_LOCK (current_allocator);
gtk_tree_data_list_validate_allocator ( allocator );
allocator->last = current_allocator;
current_allocator = allocator;
G_UNLOCK (current_allocator);
}
void
_gtk_tree_data_list_pop_allocator (void)
{
G_LOCK (current_allocator);
if (current_allocator)
{
GAllocator *allocator;
allocator = current_allocator;
current_allocator = allocator->last;
allocator->last = NULL;
allocator->is_unused = TRUE;
}
G_UNLOCK (current_allocator);
}
GtkTreeDataList * GtkTreeDataList *
_gtk_tree_data_list_alloc (void) _gtk_tree_data_list_alloc (void)
{ {
GtkTreeDataList *list; GtkTreeDataList *list;
G_LOCK (current_allocator); if (tree_chunk == NULL)
if (!current_allocator) tree_chunk = g_mem_chunk_new ("treedatalist mem chunk",
{ sizeof (GtkTreeDataList),
GAllocator *allocator = g_allocator_new ("GTK+ default GtkTreeDataList allocator", sizeof (GtkTreeDataList) * TREE_CHUNK_PREALLOCS,
128); G_ALLOC_AND_FREE);
gtk_tree_data_list_validate_allocator (allocator);
allocator->last = NULL; list = g_chunk_new (GtkTreeDataList, tree_chunk);
current_allocator = allocator;
}
if (!current_allocator->free_nodes)
list = g_chunk_new (GtkTreeDataList, current_allocator->mem_chunk);
else
{
list = current_allocator->free_nodes;
current_allocator->free_nodes = list->next;
}
G_UNLOCK (current_allocator);
return list; return list;
} }
@ -121,31 +44,31 @@ void
_gtk_tree_data_list_free (GtkTreeDataList *list, _gtk_tree_data_list_free (GtkTreeDataList *list,
GType *column_headers) GType *column_headers)
{ {
GtkTreeDataList *tmp; GtkTreeDataList *tmp, *next;
gint i = 0; gint i = 0;
for (tmp = list; tmp; tmp = tmp->next) tmp = list;
while (tmp)
{ {
next = tmp->next;
if (g_type_is_a (column_headers [i], G_TYPE_STRING)) if (g_type_is_a (column_headers [i], G_TYPE_STRING))
g_free ((gchar *) tmp->data.v_pointer); g_free ((gchar *) tmp->data.v_pointer);
else if (g_type_is_a (column_headers [i], G_TYPE_OBJECT)) else if (g_type_is_a (column_headers [i], G_TYPE_OBJECT))
g_object_unref (G_OBJECT (tmp->data.v_pointer)); g_object_unref (G_OBJECT (tmp->data.v_pointer));
else if (g_type_is_a (column_headers [i], G_TYPE_BOXED)) else if (g_type_is_a (column_headers [i], G_TYPE_BOXED))
g_boxed_free (column_headers [i], (gpointer) tmp->data.v_pointer); g_boxed_free (column_headers [i], (gpointer) tmp->data.v_pointer);
i++;
}
G_LOCK (current_allocator); g_mem_chunk_free (tree_chunk, tmp);
list->next = current_allocator->free_nodes; i++;
current_allocator->free_nodes = list; tmp = next;
G_UNLOCK (current_allocator); }
} }
gboolean gboolean
_gtk_tree_data_list_check_type (GType type) _gtk_tree_data_list_check_type (GType type)
{ {
gint i = 0; gint i = 0;
static GType type_list[] = static GType type_list[] =
{ {
G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
@ -164,6 +87,10 @@ _gtk_tree_data_list_check_type (GType type)
G_TYPE_INVALID G_TYPE_INVALID
}; };
if (! G_TYPE_IS_VALUE_TYPE (type))
return FALSE;
while (type_list[i] != G_TYPE_INVALID) while (type_list[i] != G_TYPE_INVALID)
{ {
if (g_type_is_a (type, type_list[i])) if (g_type_is_a (type, type_list[i]))
@ -180,71 +107,105 @@ _gtk_tree_data_list_node_to_value (GtkTreeDataList *list,
{ {
g_value_init (value, type); g_value_init (value, type);
if (g_type_is_a (type, G_TYPE_BOOLEAN)) switch (G_TYPE_FUNDAMENTAL (type))
g_value_set_boolean (value, (gboolean) list->data.v_int); {
else if (g_type_is_a (type, G_TYPE_CHAR)) case G_TYPE_BOOLEAN:
g_value_set_char (value, (gchar) list->data.v_char); g_value_set_boolean (value, (gboolean) list->data.v_int);
else if (g_type_is_a (type, G_TYPE_UCHAR)) break;
g_value_set_uchar (value, (guchar) list->data.v_uchar); case G_TYPE_CHAR:
else if (g_type_is_a (type, G_TYPE_INT)) g_value_set_char (value, (gchar) list->data.v_char);
g_value_set_int (value, (gint) list->data.v_int); break;
else if (g_type_is_a (type, G_TYPE_UINT)) case G_TYPE_UCHAR:
g_value_set_uint (value, (guint) list->data.v_uint); g_value_set_uchar (value, (guchar) list->data.v_uchar);
else if (g_type_is_a (type, G_TYPE_ENUM)) break;
g_value_set_enum (value, list->data.v_int); case G_TYPE_INT:
else if (g_type_is_a (type, G_TYPE_FLAGS)) g_value_set_int (value, (gint) list->data.v_int);
g_value_set_flags (value, (int) list->data.v_int); break;
else if (g_type_is_a (type, G_TYPE_FLOAT)) case G_TYPE_UINT:
g_value_set_float (value, (gfloat) list->data.v_float); g_value_set_uint (value, (guint) list->data.v_uint);
else if (g_type_is_a (type, G_TYPE_DOUBLE)) break;
g_value_set_double (value, (gdouble) list->data.v_double); case G_TYPE_ENUM:
else if (g_type_is_a (type, G_TYPE_STRING)) g_value_set_enum (value, list->data.v_int);
g_value_set_string (value, (gchar *) list->data.v_pointer); break;
else if (g_type_is_a (type, G_TYPE_POINTER)) case G_TYPE_FLAGS:
g_value_set_pointer (value, (gpointer) list->data.v_pointer); g_value_set_flags (value, (int) list->data.v_int);
else if (g_type_is_a (type, G_TYPE_BOXED)) break;
g_value_set_boxed (value, (gpointer) list->data.v_pointer); case G_TYPE_FLOAT:
else if (g_type_is_a (type, G_TYPE_OBJECT)) g_value_set_float (value, (gfloat) list->data.v_float);
g_value_set_object (value, (GObject *) list->data.v_pointer); break;
else case G_TYPE_DOUBLE:
g_warning ("%s: Unsupported type (%s) retrieved.", G_STRLOC, g_type_name (value->g_type)); g_value_set_double (value, (gdouble) list->data.v_double);
break;
case G_TYPE_STRING:
g_value_set_string (value, (gchar *) list->data.v_pointer);
break;
case G_TYPE_POINTER:
g_value_set_pointer (value, (gpointer) list->data.v_pointer);
break;
case G_TYPE_BOXED:
g_value_set_boxed (value, (gpointer) list->data.v_pointer);
break;
case G_TYPE_OBJECT:
g_value_set_object (value, (GObject *) list->data.v_pointer);
break;
default:
g_warning ("%s: Unsupported type (%s) retrieved.", G_STRLOC, g_type_name (value->g_type));
break;
}
} }
void void
_gtk_tree_data_list_value_to_node (GtkTreeDataList *list, _gtk_tree_data_list_value_to_node (GtkTreeDataList *list,
GValue *value) GValue *value)
{ {
if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_BOOLEAN)) switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)))
list->data.v_int = g_value_get_boolean (value); {
else if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_CHAR)) case G_TYPE_BOOLEAN:
list->data.v_char = g_value_get_char (value); list->data.v_int = g_value_get_boolean (value);
else if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_UCHAR)) break;
list->data.v_uchar = g_value_get_uchar (value); case G_TYPE_CHAR:
else if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_INT)) list->data.v_char = g_value_get_char (value);
list->data.v_int = g_value_get_int (value); break;
else if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_ENUM)) case G_TYPE_UCHAR:
list->data.v_int = g_value_get_enum (value); list->data.v_uchar = g_value_get_uchar (value);
else if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_FLAGS)) break;
list->data.v_int = g_value_get_flags (value); case G_TYPE_INT:
else if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_UINT)) list->data.v_int = g_value_get_int (value);
list->data.v_uint = g_value_get_uint (value); break;
else if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_POINTER)) case G_TYPE_ENUM:
list->data.v_pointer = g_value_get_pointer (value); list->data.v_int = g_value_get_enum (value);
else if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_FLOAT)) break;
list->data.v_float = g_value_get_float (value); case G_TYPE_FLAGS:
else if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_DOUBLE)) list->data.v_int = g_value_get_flags (value);
list->data.v_double = g_value_get_double (value); break;
else if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_STRING)) case G_TYPE_UINT:
list->data.v_pointer = g_value_dup_string (value); list->data.v_uint = g_value_get_uint (value);
else if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_OBJECT)) break;
list->data.v_pointer = g_value_dup_object (value); case G_TYPE_POINTER:
else if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_BOXED)) list->data.v_pointer = g_value_get_pointer (value);
list->data.v_pointer = g_value_dup_boxed (value); break;
else case G_TYPE_FLOAT:
g_warning ("%s: Unsupported type (%s) stored.", G_STRLOC, g_type_name (G_VALUE_TYPE (value))); list->data.v_float = g_value_get_float (value);
break;
case G_TYPE_DOUBLE:
list->data.v_double = g_value_get_double (value);
break;
case G_TYPE_STRING:
list->data.v_pointer = g_value_dup_string (value);
break;
case G_TYPE_OBJECT:
list->data.v_pointer = g_value_dup_object (value);
break;
case G_TYPE_BOXED:
list->data.v_pointer = g_value_dup_boxed (value);
break;
default:
g_warning ("%s: Unsupported type (%s) stored.", G_STRLOC, g_type_name (G_VALUE_TYPE (value)));
break;
}
} }
GtkTreeDataList* GtkTreeDataList *
_gtk_tree_data_list_node_copy (GtkTreeDataList *list, _gtk_tree_data_list_node_copy (GtkTreeDataList *list,
GType type) GType type)
{ {
@ -254,37 +215,38 @@ _gtk_tree_data_list_node_copy (GtkTreeDataList *list,
new_list = _gtk_tree_data_list_alloc (); new_list = _gtk_tree_data_list_alloc ();
new_list->next = NULL; new_list->next = NULL;
if ((g_type_is_a (type, G_TYPE_UINT)) ||
(g_type_is_a (type, G_TYPE_INT)) ||
(g_type_is_a (type, G_TYPE_UCHAR)) ||
(g_type_is_a (type, G_TYPE_CHAR)) ||
(g_type_is_a (type, G_TYPE_BOOLEAN)) ||
(g_type_is_a (type, G_TYPE_POINTER)) ||
(g_type_is_a (type, G_TYPE_FLOAT)) ||
(g_type_is_a (type, G_TYPE_DOUBLE)))
new_list->data = list->data;
else if (g_type_is_a (type, G_TYPE_STRING)) switch (G_TYPE_FUNDAMENTAL (type))
new_list->data.v_pointer = g_strdup (list->data.v_pointer);
else if (g_type_is_a (type, G_TYPE_OBJECT))
{ {
case G_TYPE_UINT:
case G_TYPE_INT:
case G_TYPE_UCHAR:
case G_TYPE_CHAR:
case G_TYPE_BOOLEAN:
case G_TYPE_POINTER:
case G_TYPE_FLOAT:
case G_TYPE_DOUBLE:
new_list->data = list->data;
break;
case G_TYPE_STRING:
new_list->data.v_pointer = g_strdup (list->data.v_pointer);
break;
case G_TYPE_OBJECT:
new_list->data.v_pointer = list->data.v_pointer; new_list->data.v_pointer = list->data.v_pointer;
if (new_list->data.v_pointer) if (new_list->data.v_pointer)
g_object_ref (G_OBJECT (new_list->data.v_pointer)); g_object_ref (G_OBJECT (new_list->data.v_pointer));
} break;
else if (g_type_is_a (type, G_TYPE_BOXED)) case G_TYPE_BOXED:
{
if (list->data.v_pointer) if (list->data.v_pointer)
new_list->data.v_pointer = g_boxed_copy (type, list->data.v_pointer); new_list->data.v_pointer = g_boxed_copy (type, list->data.v_pointer);
else else
new_list->data.v_pointer = NULL; new_list->data.v_pointer = NULL;
break;
default:
g_warning ("Unsupported node type (%s) copied.", g_type_name (type));
break;
} }
else
g_warning ("Unsupported node type (%s) copied.", g_type_name (type));
return new_list; return new_list;
} }

View File

@ -41,8 +41,6 @@ struct _GtkTreeDataList
}; };
void _gtk_tree_data_list_push_allocator (GAllocator *allocator);
void _gtk_tree_data_list_pop_allocator (void);
GtkTreeDataList *_gtk_tree_data_list_alloc (void); GtkTreeDataList *_gtk_tree_data_list_alloc (void);
void _gtk_tree_data_list_free (GtkTreeDataList *list, void _gtk_tree_data_list_free (GtkTreeDataList *list,
GType *column_headers); GType *column_headers);

View File

@ -563,7 +563,7 @@ gtk_tree_store_set_cell (GtkTreeStore *tree_store,
g_return_if_fail (tree_store != NULL); g_return_if_fail (tree_store != NULL);
g_return_if_fail (GTK_IS_TREE_STORE (tree_store)); g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
g_return_if_fail (column >= 0 && column < tree_store->n_columns); g_return_if_fail (column >= 0 && column < tree_store->n_columns);
g_return_if_fail (value != NULL); g_return_if_fail (G_IS_VALUE (value));
if (! g_type_is_a (G_VALUE_TYPE (value), tree_store->column_headers[column])) if (! g_type_is_a (G_VALUE_TYPE (value), tree_store->column_headers[column]))
{ {

View File

@ -2075,128 +2075,74 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view,
last_column && last_column &&
!(GTK_TREE_VIEW_COLUMN (last_column->data)->visible) && !(GTK_TREE_VIEW_COLUMN (last_column->data)->visible) &&
GTK_WIDGET_CAN_FOCUS (GTK_TREE_VIEW_COLUMN (last_column->data)->button); GTK_WIDGET_CAN_FOCUS (GTK_TREE_VIEW_COLUMN (last_column->data)->button);
last_column = last_column->prev) last_column = last_column->prev);
;
for (first_column = tree_view->priv->columns; for (first_column = tree_view->priv->columns;
first_column && first_column &&
!(GTK_TREE_VIEW_COLUMN (first_column->data)->visible) && !(GTK_TREE_VIEW_COLUMN (first_column->data)->visible) &&
GTK_WIDGET_CAN_FOCUS (GTK_TREE_VIEW_COLUMN (first_column->data)->button); GTK_WIDGET_CAN_FOCUS (GTK_TREE_VIEW_COLUMN (first_column->data)->button);
first_column = first_column->next) first_column = first_column->next);
;
/* no headers are visible, or are focussable. We can't focus in or out. /* No headers are visible, or are focusable. We can't focus in or out.
* I wonder if focussable is a real word...
*/ */
if (last_column == NULL) if (last_column == NULL)
return FALSE; return FALSE;
/* First thing we want to handle is entering and leaving the headers.
*/
switch (dir) switch (dir)
{ {
case GTK_DIR_TAB_BACKWARD: case GTK_DIR_TAB_BACKWARD:
if (!focus_child)
{
focus_child = GTK_TREE_VIEW_COLUMN (last_column->data)->button;
gtk_widget_grab_focus (focus_child);
goto cleanup;
}
if (focus_child == GTK_TREE_VIEW_COLUMN (first_column->data)->button)
{
focus_child = NULL;
goto cleanup;
}
break;
case GTK_DIR_TAB_FORWARD: case GTK_DIR_TAB_FORWARD:
if (!focus_child) case GTK_DIR_UP:
case GTK_DIR_DOWN:
if (focus_child == NULL)
{ {
focus_child = GTK_TREE_VIEW_COLUMN (first_column->data)->button; if (tree_view->priv->focus_column == NULL)
focus_child = GTK_TREE_VIEW_COLUMN (first_column->data)->button;
else
focus_child = GTK_TREE_VIEW_COLUMN (tree_view->priv->focus_column->data)->button;
gtk_widget_grab_focus (focus_child); gtk_widget_grab_focus (focus_child);
goto cleanup; break;
} }
if (focus_child == GTK_TREE_VIEW_COLUMN (last_column->data)->button) return FALSE;
{
focus_child = NULL;
goto cleanup;
}
break;
case GTK_DIR_LEFT: case GTK_DIR_LEFT:
if (!focus_child) case GTK_DIR_RIGHT:
if (focus_child == NULL)
{
g_assert_not_reached ();
return FALSE;
}
if (gtk_container_focus (GTK_CONTAINER (focus_child), dir))
{
/* The focus moves inside the button. */
/* This is probably a great example of bad UI */
break;
}
/* We need to move the focus among the row of buttons. */
for (tmp_list = tree_view->priv->columns; tmp_list; tmp_list = tmp_list->next)
if (GTK_TREE_VIEW_COLUMN (tmp_list->data)->button == focus_child)
break;
if (tmp_list == first_column && dir == GTK_DIR_LEFT)
{ {
focus_child = GTK_TREE_VIEW_COLUMN (last_column->data)->button; focus_child = GTK_TREE_VIEW_COLUMN (last_column->data)->button;
gtk_widget_grab_focus (focus_child); gtk_widget_grab_focus (focus_child);
goto cleanup; break;
} }
if (focus_child == GTK_TREE_VIEW_COLUMN (first_column->data)->button) else if (tmp_list == last_column && dir == GTK_DIR_RIGHT)
{
focus_child = NULL;
goto cleanup;
}
break;
case GTK_DIR_RIGHT:
if (!focus_child)
{ {
focus_child = GTK_TREE_VIEW_COLUMN (first_column->data)->button; focus_child = GTK_TREE_VIEW_COLUMN (first_column->data)->button;
gtk_widget_grab_focus (focus_child); gtk_widget_grab_focus (focus_child);
goto cleanup; break;
} }
if (focus_child == GTK_TREE_VIEW_COLUMN (last_column->data)->button)
{
focus_child = NULL;
goto cleanup;
}
break;
case GTK_DIR_UP:
if (!focus_child)
{
focus_child = GTK_TREE_VIEW_COLUMN (first_column->data)->button;
gtk_widget_grab_focus (focus_child);
}
else
{
focus_child = NULL;
}
goto cleanup;
case GTK_DIR_DOWN:
if (!focus_child)
{
focus_child = GTK_TREE_VIEW_COLUMN (first_column->data)->button;
gtk_widget_grab_focus (focus_child);
}
else
{
focus_child = NULL;
}
goto cleanup;
}
/* We need to move the focus to the next button. */
if (focus_child)
{
for (tmp_list = tree_view->priv->columns; tmp_list; tmp_list = tmp_list->next)
if (GTK_TREE_VIEW_COLUMN (tmp_list->data)->button == focus_child)
{
if (gtk_container_focus (GTK_CONTAINER (GTK_TREE_VIEW_COLUMN (tmp_list->data)->button), dir))
{
/* The focus moves inside the button. */
/* This is probably a great example of bad UI */
goto cleanup;
}
break;
}
/* We need to move the focus among the row of buttons. */
while (tmp_list) while (tmp_list)
{ {
GtkTreeViewColumn *column; GtkTreeViewColumn *column;
if (dir == GTK_DIR_RIGHT || dir == GTK_DIR_TAB_FORWARD) if (dir == GTK_DIR_RIGHT)
tmp_list = tmp_list->next; tmp_list = tmp_list->next;
else else
tmp_list = tmp_list->prev; tmp_list = tmp_list->prev;
@ -2204,7 +2150,7 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view,
if (tmp_list == NULL) if (tmp_list == NULL)
{ {
g_warning ("Internal button not found"); g_warning ("Internal button not found");
goto cleanup; break;
} }
column = tmp_list->data; column = tmp_list->data;
if (column->button && if (column->button &&
@ -2216,9 +2162,12 @@ gtk_tree_view_header_focus (GtkTreeView *tree_view,
break; break;
} }
} }
break;
default:
g_assert_not_reached ();
break;
} }
cleanup:
/* if focus child is non-null, we assume it's been set to the current focus child /* if focus child is non-null, we assume it's been set to the current focus child
*/ */
if (focus_child) if (focus_child)
@ -2274,14 +2223,12 @@ gtk_tree_view_focus (GtkContainer *container,
switch (direction) switch (direction)
{ {
case GTK_DIR_LEFT: case GTK_DIR_LEFT:
case GTK_DIR_RIGHT:
return (gtk_tree_view_header_focus (tree_view, direction)); return (gtk_tree_view_header_focus (tree_view, direction));
case GTK_DIR_TAB_BACKWARD: case GTK_DIR_TAB_BACKWARD:
case GTK_DIR_UP: case GTK_DIR_UP:
return FALSE; return FALSE;
case GTK_DIR_TAB_FORWARD: case GTK_DIR_TAB_FORWARD:
if (gtk_tree_view_header_focus (tree_view, direction))
return TRUE;
case GTK_DIR_RIGHT:
case GTK_DIR_DOWN: case GTK_DIR_DOWN:
GTK_TREE_VIEW_SET_FLAG (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS); GTK_TREE_VIEW_SET_FLAG (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS);
gtk_widget_grab_focus (GTK_WIDGET (container)); gtk_widget_grab_focus (GTK_WIDGET (container));
@ -4186,6 +4133,9 @@ gtk_tree_view_remove_column (GtkTreeView *tree_view,
_gtk_tree_view_column_unset_tree_view (column); _gtk_tree_view_column_unset_tree_view (column);
if (GTK_TREE_VIEW_COLUMN (tree_view->priv->focus_column->data) == column)
tree_view->priv->focus_column = NULL;
tree_view->priv->columns = g_list_remove (tree_view->priv->columns, column); tree_view->priv->columns = g_list_remove (tree_view->priv->columns, column);
g_object_unref (G_OBJECT (column)); g_object_unref (G_OBJECT (column));

View File

@ -1,6 +1,5 @@
#include <gtk/gtk.h> #include <gtk/gtk.h>
typedef struct _TreeStruct TreeStruct; typedef struct _TreeStruct TreeStruct;
struct _TreeStruct struct _TreeStruct
{ {
@ -170,7 +169,7 @@ make_model (void)
OWEN_COLUMN, holiday->owen, OWEN_COLUMN, holiday->owen,
VISIBLE_COLUMN, TRUE, VISIBLE_COLUMN, TRUE,
-1); -1);
holiday ++; holiday ++;
} }
month ++; month ++;
@ -197,7 +196,7 @@ havoc_toggled (GtkCellRendererToggle *cell,
gtk_tree_path_free (path); gtk_tree_path_free (path);
} }
static void static void
owen_toggled (GtkCellRendererToggle *cell, owen_toggled (GtkCellRendererToggle *cell,
gchar *path_str, gchar *path_str,
@ -242,8 +241,8 @@ main (int argc, char *argv[])
gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0);
model = make_model (); model = make_model ();
tree_view = gtk_tree_view_new (); tree_view = gtk_tree_view_new_with_model (model);
g_object_set (G_OBJECT (tree_view), "model", model, NULL); // g_object_set (G_OBJECT (tree_view), "model", model, NULL);
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE); gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE);
renderer = gtk_cell_renderer_text_new (); renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view), gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
@ -273,7 +272,7 @@ main (int argc, char *argv[])
NULL); NULL);
g_object_unref (renderer); g_object_unref (renderer);
gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view); gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
gtk_widget_show_all (window); gtk_widget_show_all (window);
gtk_main (); gtk_main ();