+/* Implementation of GtkCellLayout interface
+ */
+
+static void
+gtk_tree_view_column_cell_layout_pack_start (GtkCellLayout *cell_layout,
+ GtkCellRenderer *cell,
+ gboolean expand)
+{
+ GtkTreeViewColumn *column;
+ GtkTreeViewColumnCellInfo *cell_info;
+
+ g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
+ column = GTK_TREE_VIEW_COLUMN (cell_layout);
+ g_return_if_fail (! gtk_tree_view_column_get_cell_info (column, cell));
+
+ g_object_ref (cell);
+ gtk_object_sink (GTK_OBJECT (cell));
+
+ cell_info = g_new0 (GtkTreeViewColumnCellInfo, 1);
+ cell_info->cell = cell;
+ cell_info->expand = expand ? TRUE : FALSE;
+ cell_info->pack = GTK_PACK_START;
+ cell_info->has_focus = 0;
+ cell_info->attributes = NULL;
+
+ column->cell_list = g_list_append (column->cell_list, cell_info);
+}
+
+static void
+gtk_tree_view_column_cell_layout_pack_end (GtkCellLayout *cell_layout,
+ GtkCellRenderer *cell,
+ gboolean expand)
+{
+ GtkTreeViewColumn *column;
+ GtkTreeViewColumnCellInfo *cell_info;
+
+ g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
+ column = GTK_TREE_VIEW_COLUMN (cell_layout);
+ g_return_if_fail (! gtk_tree_view_column_get_cell_info (column, cell));
+
+ g_object_ref (cell);
+ gtk_object_sink (GTK_OBJECT (cell));
+
+ cell_info = g_new0 (GtkTreeViewColumnCellInfo, 1);
+ cell_info->cell = cell;
+ cell_info->expand = expand ? TRUE : FALSE;
+ cell_info->pack = GTK_PACK_END;
+ cell_info->has_focus = 0;
+ cell_info->attributes = NULL;
+
+ column->cell_list = g_list_append (column->cell_list, cell_info);
+}
+
+static void
+gtk_tree_view_column_cell_layout_clear (GtkCellLayout *cell_layout)
+{
+ GtkTreeViewColumn *column;
+
+ g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
+ column = GTK_TREE_VIEW_COLUMN (cell_layout);
+
+ while (column->cell_list)
+ {
+ GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *)column->cell_list->data;
+
+ gtk_tree_view_column_cell_layout_clear_attributes (cell_layout, info->cell);
+ g_object_unref (G_OBJECT (info->cell));
+ g_free (info);
+ column->cell_list = g_list_delete_link (column->cell_list,
+ column->cell_list);
+ }
+}
+
+static void
+gtk_tree_view_column_cell_layout_add_attribute (GtkCellLayout *cell_layout,
+ GtkCellRenderer *cell,
+ const gchar *attribute,
+ gint column)
+{
+ GtkTreeViewColumn *tree_column;
+ GtkTreeViewColumnCellInfo *info;
+
+ g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
+ tree_column = GTK_TREE_VIEW_COLUMN (cell_layout);
+
+ info = gtk_tree_view_column_get_cell_info (tree_column, cell);
+ g_return_if_fail (info != NULL);
+
+ info->attributes = g_slist_prepend (info->attributes, GINT_TO_POINTER (column));
+ info->attributes = g_slist_prepend (info->attributes, g_strdup (attribute));
+
+ if (tree_column->tree_view)
+ _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
+}
+
+static void
+gtk_tree_view_column_cell_layout_set_cell_data_func (GtkCellLayout *cell_layout,
+ GtkCellRenderer *cell,
+ GtkCellLayoutDataFunc func,
+ gpointer func_data,
+ GDestroyNotify destroy)
+{
+ GtkTreeViewColumn *column;
+ GtkTreeViewColumnCellInfo *info;
+
+ g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
+ column = GTK_TREE_VIEW_COLUMN (cell_layout);
+
+ info = gtk_tree_view_column_get_cell_info (column, cell);
+ g_return_if_fail (info != NULL);
+
+ if (info->destroy)
+ {
+ GDestroyNotify d = info->destroy;
+
+ info->destroy = NULL;
+ d (info->func_data);
+ }
+
+ info->func = (GtkTreeCellDataFunc)func;
+ info->func_data = func_data;
+ info->destroy = destroy;
+
+ if (column->tree_view)
+ _gtk_tree_view_column_cell_set_dirty (column, TRUE);
+}
+
+static void
+gtk_tree_view_column_cell_layout_clear_attributes (GtkCellLayout *cell_layout,
+ GtkCellRenderer *cell_renderer)
+{
+ GtkTreeViewColumn *column;
+ GtkTreeViewColumnCellInfo *info;
+
+ g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
+ column = GTK_TREE_VIEW_COLUMN (cell_layout);
+
+ info = gtk_tree_view_column_get_cell_info (column, cell_renderer);
+ gtk_tree_view_column_clear_attributes_by_info (column, info);
+}
+
+static void
+gtk_tree_view_column_cell_layout_reorder (GtkCellLayout *cell_layout,
+ GtkCellRenderer *cell,
+ gint position)
+{
+ GList *link;
+ GtkTreeViewColumn *column;
+ GtkTreeViewColumnCellInfo *info;
+
+ g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (cell_layout));
+ column = GTK_TREE_VIEW_COLUMN (cell_layout);
+
+ info = gtk_tree_view_column_get_cell_info (column, cell);
+
+ g_return_if_fail (info != NULL);
+ g_return_if_fail (position >= 0);
+
+ link = g_list_find (column->cell_list, info);
+
+ g_return_if_fail (link != NULL);
+
+ column->cell_list = g_list_remove_link (column->cell_list, link);
+ column->cell_list = g_list_insert (column->cell_list, info, position);
+
+ gtk_widget_queue_draw (column->tree_view);
+}
+
+static void
+gtk_tree_view_column_clear_attributes_by_info (GtkTreeViewColumn *tree_column,
+ GtkTreeViewColumnCellInfo *info)
+{
+ GSList *list;
+
+ list = info->attributes;
+
+ while (list && list->next)
+ {
+ g_free (list->data);
+ list = list->next->next;
+ }
+ g_slist_free (info->attributes);
+ info->attributes = NULL;
+
+ if (tree_column->tree_view)
+ _gtk_tree_view_column_cell_set_dirty (tree_column, TRUE);
+}
+