]> Pileus Git - ~andy/gtk/blob - gtk/gtkcellarea.c
Merge branch 'master' into treeview-refactor
[~andy/gtk] / gtk / gtkcellarea.c
1 /* gtkcellarea.c
2  *
3  * Copyright (C) 2010 Openismus GmbH
4  *
5  * Authors:
6  *      Tristan Van Berkom <tristanvb@openismus.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #include "gtkcelllayout.h"
25 #include "gtkcellarea.h"
26
27 /* GObjectClass */
28 static void      gtk_cell_area_dispose                             (GObject            *object);
29 static void      gtk_cell_area_finalize                            (GObject            *object);
30
31 /* GtkCellAreaClass */
32 static void      gtk_cell_area_real_get_preferred_height_for_width (GtkCellArea        *area,
33                                                                     GtkWidget          *widget,
34                                                                     gint                width,
35                                                                     gint               *minimum_height,
36                                                                     gint               *natural_height);
37 static void      gtk_cell_area_real_get_preferred_width_for_height (GtkCellArea        *area,
38                                                                     GtkWidget          *widget,
39                                                                     gint                height,
40                                                                     gint               *minimum_width,
41                                                                     gint               *natural_width);
42
43 /* GtkCellLayoutIface */
44 static void      gtk_cell_area_cell_layout_init              (GtkCellLayoutIface    *iface);
45 static void      gtk_cell_area_pack_default                  (GtkCellLayout         *cell_layout,
46                                                               GtkCellRenderer       *renderer,
47                                                               gboolean               expand);
48 static void      gtk_cell_area_clear                         (GtkCellLayout         *cell_layout);
49 static void      gtk_cell_area_add_attribute                 (GtkCellLayout         *cell_layout,
50                                                               GtkCellRenderer       *renderer,
51                                                               const gchar           *attribute,
52                                                               gint                   id);
53 static void      gtk_cell_area_set_cell_data_func            (GtkCellLayout         *cell_layout,
54                                                               GtkCellRenderer       *cell,
55                                                               GtkCellLayoutDataFunc  func,
56                                                               gpointer               func_data,
57                                                               GDestroyNotify         destroy);
58 static void      gtk_cell_area_clear_attributes              (GtkCellLayout         *cell_layout,
59                                                               GtkCellRenderer       *renderer);
60 static void      gtk_cell_area_reorder                       (GtkCellLayout         *cell_layout,
61                                                               GtkCellRenderer       *cell,
62                                                               gint                   position);
63 static GList    *gtk_cell_area_get_cells                     (GtkCellLayout         *cell_layout);
64
65 /* GtkCellLayoutDataFunc handling */
66 typedef struct {
67   GtkCellLayoutDataFunc func;
68   gpointer              data;
69   GDestroyNotify        destroy;
70 } CustomCellData;
71
72 static CustomCellData *custom_cell_data_new  (GtkCellLayoutDataFunc  func,
73                                               gpointer               data,
74                                               GDestroyNotify         destroy);
75 static void            custom_cell_data_free (CustomCellData        *custom);
76
77 /* Struct to pass data while looping over 
78  * cell renderer attributes
79  */
80 typedef struct {
81   GtkCellArea  *area;
82   GtkTreeModel *model;
83   GtkTreeIter  *iter;
84 } AttributeData;
85
86 struct _GtkCellAreaPrivate
87 {
88   GHashTable *custom_cell_data;
89 };
90
91 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GtkCellArea, gtk_cell_area, G_TYPE_INITIALLY_UNOWNED,
92                                   G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_LAYOUT,
93                                                          gtk_cell_area_cell_layout_init));
94
95 static void
96 gtk_cell_area_init (GtkCellArea *area)
97 {
98   GtkCellAreaPrivate *priv;
99
100   area->priv = G_TYPE_INSTANCE_GET_PRIVATE (area,
101                                             GTK_TYPE_CELL_AREA,
102                                             GtkCellAreaPrivate);
103   priv = area->priv;
104
105   priv->custom_cell_data = g_hash_table_new_full (g_direct_hash, 
106                                                   g_direct_equal,
107                                                   NULL, 
108                                                   (GDestroyNotify)custom_cell_data_free);
109 }
110
111 static void 
112 gtk_cell_area_class_init (GtkCellAreaClass *class)
113 {
114   GObjectClass *object_class = G_OBJECT_CLASS (class);
115   
116   /* GObjectClass */
117   object_class->dispose  = gtk_cell_area_dispose;
118   object_class->finalize = gtk_cell_area_finalize;
119
120   /* general */
121   class->add     = NULL;
122   class->remove  = NULL;
123   class->forall  = NULL;
124   class->event   = NULL;
125   class->render  = NULL;
126
127   /* attributes */
128   class->attribute_connect    = NULL;
129   class->attribute_disconnect = NULL;
130   class->attribute_forall     = NULL;
131
132   /* geometry */
133   class->get_request_mode               = NULL;
134   class->get_preferred_width            = NULL;
135   class->get_preferred_height           = NULL;
136   class->get_preferred_height_for_width = gtk_cell_area_real_get_preferred_height_for_width;
137   class->get_preferred_width_for_height = gtk_cell_area_real_get_preferred_width_for_height;
138
139   g_type_class_add_private (object_class, sizeof (GtkCellAreaPrivate));
140 }
141
142
143 /*************************************************************
144  *                      GObjectClass                         *
145  *************************************************************/
146 static void
147 gtk_cell_area_finalize (GObject *object)
148 {
149   GtkCellArea        *area   = GTK_CELL_AREA (object);
150   GtkCellAreaPrivate *priv   = area->priv;
151
152   /* All cell renderers should already be removed at this point,
153    * just kill our hash table here. 
154    */
155   g_hash_table_destroy (priv->custom_cell_data);
156
157   G_OBJECT_CLASS (gtk_cell_area_parent_class)->finalize (object);
158 }
159
160
161 static void
162 gtk_cell_area_dispose (GObject *object)
163 {
164   /* This removes every cell renderer that may be added to the GtkCellArea,
165    * subclasses should be breaking references to the GtkCellRenderers 
166    * at this point.
167    */
168   gtk_cell_layout_clear (GTK_CELL_LAYOUT (object));
169
170   G_OBJECT_CLASS (gtk_cell_area_parent_class)->dispose (object);
171 }
172
173
174 /*************************************************************
175  *                    GtkCellAreaClass                       *
176  *************************************************************/
177 static void
178 gtk_cell_area_real_get_preferred_height_for_width (GtkCellArea        *area,
179                                                    GtkWidget          *widget,
180                                                    gint                width,
181                                                    gint               *minimum_height,
182                                                    gint               *natural_height)
183 {
184   /* If the area doesnt do height-for-width, fallback on base preferred height */
185   GTK_CELL_AREA_GET_CLASS (area)->get_preferred_width (area, widget, minimum_height, natural_height);
186 }
187
188 static void
189 gtk_cell_area_real_get_preferred_width_for_height (GtkCellArea        *area,
190                                                    GtkWidget          *widget,
191                                                    gint                height,
192                                                    gint               *minimum_width,
193                                                    gint               *natural_width)
194 {
195   /* If the area doesnt do width-for-height, fallback on base preferred width */
196   GTK_CELL_AREA_GET_CLASS (area)->get_preferred_width (area, widget, minimum_width, natural_width);
197 }
198
199 /*************************************************************
200  *                   GtkCellLayoutIface                      *
201  *************************************************************/
202 static CustomCellData *
203 custom_cell_data_new (GtkCellLayoutDataFunc  func,
204                       gpointer               data,
205                       GDestroyNotify         destroy)
206 {
207   CustomCellData *custom = g_slice_new (CustomCellData);
208   
209   custom->func    = func;
210   custom->data    = data;
211   custom->destroy = destroy;
212
213   return custom;
214 }
215
216 static void
217 custom_cell_data_free (CustomCellData *custom)
218 {
219   if (custom->destroy)
220     custom->destroy (custom->data);
221
222   g_slice_free (CustomCellData, custom);
223 }
224
225 static void
226 gtk_cell_area_cell_layout_init (GtkCellLayoutIface *iface)
227 {
228   iface->pack_start         = gtk_cell_area_pack_default;
229   iface->pack_end           = gtk_cell_area_pack_default;
230   iface->clear              = gtk_cell_area_clear;
231   iface->add_attribute      = gtk_cell_area_add_attribute;
232   iface->set_cell_data_func = gtk_cell_area_set_cell_data_func;
233   iface->clear_attributes   = gtk_cell_area_clear_attributes;
234   iface->reorder            = gtk_cell_area_reorder;
235   iface->get_cells          = gtk_cell_area_get_cells;
236 }
237
238 static void
239 gtk_cell_area_pack_default (GtkCellLayout         *cell_layout,
240                             GtkCellRenderer       *renderer,
241                             gboolean               expand)
242 {
243   gtk_cell_area_add (GTK_CELL_AREA (cell_layout), renderer);
244 }
245
246 static void
247 gtk_cell_area_clear (GtkCellLayout *cell_layout)
248 {
249   GtkCellArea *area = GTK_CELL_AREA (cell_layout);
250   GList *l, *cells  =
251     gtk_cell_layout_get_cells (cell_layout);
252
253   for (l = cells; l; l = l->next)
254     {
255       GtkCellRenderer *renderer = l->data;
256       gtk_cell_area_remove (area, renderer);
257     }
258
259   g_list_free (cells);
260 }
261
262 static void
263 gtk_cell_area_add_attribute (GtkCellLayout         *cell_layout,
264                              GtkCellRenderer       *renderer,
265                              const gchar           *attribute,
266                              gint                   id)
267 {
268   gtk_cell_area_attribute_connect (GTK_CELL_AREA (cell_layout),
269                                    renderer, attribute, id);
270 }
271
272 typedef struct {
273   const gchar *attribute;
274   gchar        id;
275 } CellAttribute;
276
277 static void
278 accum_attributes (GtkCellArea      *area,
279                   GtkCellRenderer  *renderer,
280                   const gchar      *attribute,
281                   gint              id,
282                   GList           **accum)
283 {
284   CellAttribute *attrib = g_slice_new (CellAttribute);
285
286   attrib->attribute = attribute;
287   attrib->id        = id;
288
289   *accum = g_list_prepend (*accum, attrib);
290 }
291
292 static void
293 gtk_cell_area_set_cell_data_func (GtkCellLayout         *cell_layout,
294                                   GtkCellRenderer       *cell,
295                                   GtkCellLayoutDataFunc  func,
296                                   gpointer               func_data,
297                                   GDestroyNotify         destroy)
298 {
299   GtkCellArea        *area   = GTK_CELL_AREA (cell_layout);
300   GtkCellAreaPrivate *priv   = area->priv;
301   CustomCellData     *custom;
302
303   if (func)
304     {
305       custom = custom_cell_data_new (func, func_data, destroy);
306       g_hash_table_insert (priv->custom_cell_data, cell, custom);
307     }
308   else
309     g_hash_table_remove (priv->custom_cell_data, cell);
310 }
311
312
313 static void
314 gtk_cell_area_clear_attributes (GtkCellLayout         *cell_layout,
315                                 GtkCellRenderer       *renderer)
316 {
317   GtkCellArea *area = GTK_CELL_AREA (cell_layout);
318   GList       *l, *attributes = NULL;
319
320   /* Get a list of attributes so we dont modify the list inline */
321   gtk_cell_area_attribute_forall (area, renderer, 
322                                   (GtkCellAttributeCallback)accum_attributes,
323                                   &attributes);
324
325   for (l = attributes; l; l = l->next)
326     {
327       CellAttribute *attrib = l->data;
328
329       gtk_cell_area_attribute_disconnect (area, renderer, 
330                                           attrib->attribute, attrib->id);
331
332       g_slice_free (CellAttribute, attrib);
333     }
334
335   g_list_free (attributes);
336 }
337
338 static void 
339 gtk_cell_area_reorder (GtkCellLayout   *cell_layout,
340                        GtkCellRenderer *cell,
341                        gint             position)
342 {
343   g_warning ("GtkCellLayout::reorder not implemented for `%s'", 
344              g_type_name (G_TYPE_FROM_INSTANCE (cell_layout)));
345 }
346
347 static void
348 accum_cells (GtkCellRenderer *renderer,
349              GList          **accum)
350 {
351   *accum = g_list_prepend (*accum, renderer);
352 }
353
354 static GList *
355 gtk_cell_area_get_cells (GtkCellLayout *cell_layout)
356 {
357   GList *cells = NULL;
358
359   gtk_cell_area_forall (GTK_CELL_AREA (cell_layout), 
360                         (GtkCellCallback)accum_cells,
361                         &cells);
362
363   return g_list_reverse (cells);
364 }
365
366
367 /*************************************************************
368  *                            API                            *
369  *************************************************************/
370
371 /* Basic methods */
372 void
373 gtk_cell_area_add (GtkCellArea        *area,
374                    GtkCellRenderer    *renderer)
375 {
376   GtkCellAreaClass *class;
377
378   g_return_if_fail (GTK_IS_CELL_AREA (area));
379   g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
380
381   class = GTK_CELL_AREA_GET_CLASS (area);
382
383   if (class->add)
384     class->add (area, renderer);
385   else
386     g_warning ("GtkCellAreaClass::add not implemented for `%s'", 
387                g_type_name (G_TYPE_FROM_INSTANCE (area)));
388 }
389
390 void
391 gtk_cell_area_remove (GtkCellArea        *area,
392                       GtkCellRenderer    *renderer)
393 {
394   GtkCellAreaClass *class;
395
396   g_return_if_fail (GTK_IS_CELL_AREA (area));
397   g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
398
399   class = GTK_CELL_AREA_GET_CLASS (area);
400
401   /* Remove any custom cell data func we have for this renderer */
402   gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (area),
403                                       renderer, NULL, NULL, NULL);
404
405   if (class->remove)
406     class->remove (area, renderer);
407   else
408     g_warning ("GtkCellAreaClass::remove not implemented for `%s'", 
409                g_type_name (G_TYPE_FROM_INSTANCE (area)));
410 }
411
412 void
413 gtk_cell_area_forall (GtkCellArea        *area,
414                       GtkCellCallback     callback,
415                       gpointer            callback_data)
416 {
417   GtkCellAreaClass *class;
418
419   g_return_if_fail (GTK_IS_CELL_AREA (area));
420   g_return_if_fail (callback != NULL);
421
422   class = GTK_CELL_AREA_GET_CLASS (area);
423
424   if (class->forall)
425     class->forall (area, callback, callback_data);
426   else
427     g_warning ("GtkCellAreaClass::forall not implemented for `%s'", 
428                g_type_name (G_TYPE_FROM_INSTANCE (area)));
429 }
430
431 gint
432 gtk_cell_area_event (GtkCellArea        *area,
433                      GtkWidget          *widget,
434                      GdkEvent           *event,
435                      const GdkRectangle *cell_area)
436 {
437   GtkCellAreaClass *class;
438
439   g_return_val_if_fail (GTK_IS_CELL_AREA (area), 0);
440   g_return_val_if_fail (GTK_IS_WIDGET (widget), 0);
441   g_return_val_if_fail (event != NULL, 0);
442   g_return_val_if_fail (cell_area != NULL, 0);
443
444   class = GTK_CELL_AREA_GET_CLASS (area);
445
446   if (class->event)
447     return class->event (area, widget, event, cell_area);
448
449   g_warning ("GtkCellAreaClass::event not implemented for `%s'", 
450              g_type_name (G_TYPE_FROM_INSTANCE (area)));
451   return 0;
452 }
453
454 void
455 gtk_cell_area_render (GtkCellArea        *area,
456                       cairo_t            *cr,
457                       GtkWidget          *widget,
458                       const GdkRectangle *cell_area)
459 {
460   GtkCellAreaClass *class;
461
462   g_return_if_fail (GTK_IS_CELL_AREA (area));
463   g_return_if_fail (cr != NULL);
464   g_return_if_fail (GTK_IS_WIDGET (widget));
465   g_return_if_fail (cell_area != NULL);
466
467   class = GTK_CELL_AREA_GET_CLASS (area);
468
469   if (class->render)
470     class->render (area, cr, widget, cell_area);
471   else
472     g_warning ("GtkCellAreaClass::render not implemented for `%s'", 
473                g_type_name (G_TYPE_FROM_INSTANCE (area)));
474 }
475
476 /* Attributes */ 
477 void
478 gtk_cell_area_attribute_connect (GtkCellArea        *area,
479                                  GtkCellRenderer    *renderer,
480                                  const gchar        *attribute,
481                                  gint                id)
482 {
483   GtkCellAreaClass *class;
484
485   g_return_if_fail (GTK_IS_CELL_AREA (area));
486   g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
487   g_return_if_fail (attribute != NULL);
488
489   class = GTK_CELL_AREA_GET_CLASS (area);
490
491   if (class->attribute_connect)
492     class->attribute_connect (area, renderer, attribute, id);
493   else
494     g_warning ("GtkCellAreaClass::attribute_connect not implemented for `%s'", 
495                g_type_name (G_TYPE_FROM_INSTANCE (area)));
496 }
497
498 void 
499 gtk_cell_area_attribute_disconnect (GtkCellArea        *area,
500                                     GtkCellRenderer    *renderer,
501                                     const gchar        *attribute,
502                                     gint                id)
503 {
504   GtkCellAreaClass *class;
505
506   g_return_if_fail (GTK_IS_CELL_AREA (area));
507   g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
508   g_return_if_fail (attribute != NULL);
509
510   class = GTK_CELL_AREA_GET_CLASS (area);
511
512   if (class->attribute_disconnect)
513     class->attribute_disconnect (area, renderer, attribute, id);
514   else
515     g_warning ("GtkCellAreaClass::attribute_disconnect not implemented for `%s'", 
516                g_type_name (G_TYPE_FROM_INSTANCE (area)));
517 }
518
519 void
520 gtk_cell_area_attribute_forall (GtkCellArea             *area,
521                                 GtkCellRenderer         *renderer,
522                                 GtkCellAttributeCallback callback,
523                                 gpointer                 user_data)
524 {
525   GtkCellAreaClass *class;
526
527   g_return_if_fail (GTK_IS_CELL_AREA (area));
528   g_return_if_fail (GTK_IS_CELL_RENDERER (renderer));
529   g_return_if_fail (callback != NULL);
530
531   class = GTK_CELL_AREA_GET_CLASS (area);
532
533   if (class->attribute_forall)
534     class->attribute_forall (area, renderer, callback, user_data);
535   else
536     g_warning ("GtkCellAreaClass::attribute_forall not implemented for `%s'", 
537                g_type_name (G_TYPE_FROM_INSTANCE (area)));
538 }
539
540
541 /* Geometry */
542 GtkSizeRequestMode 
543 gtk_cell_area_get_request_mode (GtkCellArea *area)
544 {
545   GtkCellAreaClass *class;
546
547   g_return_val_if_fail (GTK_IS_CELL_AREA (area), 
548                         GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH);
549
550   class = GTK_CELL_AREA_GET_CLASS (area);
551
552   if (class->get_request_mode)
553     return class->get_request_mode (area);
554
555   g_warning ("GtkCellAreaClass::get_request_mode not implemented for `%s'", 
556              g_type_name (G_TYPE_FROM_INSTANCE (area)));
557   
558   return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
559 }
560
561 void
562 gtk_cell_area_get_preferred_width (GtkCellArea        *area,
563                                    GtkWidget          *widget,
564                                    gint               *minimum_size,
565                                    gint               *natural_size)
566 {
567   GtkCellAreaClass *class;
568
569   g_return_if_fail (GTK_IS_CELL_AREA (area));
570   g_return_if_fail (GTK_IS_WIDGET (widget));
571
572   class = GTK_CELL_AREA_GET_CLASS (area);
573
574   if (class->get_preferred_width)
575     class->get_preferred_width (area, widget, minimum_size, natural_size);
576   else
577     g_warning ("GtkCellAreaClass::get_preferred_width not implemented for `%s'", 
578                g_type_name (G_TYPE_FROM_INSTANCE (area)));
579 }
580
581 void
582 gtk_cell_area_get_preferred_height_for_width (GtkCellArea        *area,
583                                               GtkWidget          *widget,
584                                               gint                width,
585                                               gint               *minimum_height,
586                                               gint               *natural_height)
587 {
588   GtkCellAreaClass *class;
589
590   g_return_if_fail (GTK_IS_CELL_AREA (area));
591   g_return_if_fail (GTK_IS_WIDGET (widget));
592
593   class = GTK_CELL_AREA_GET_CLASS (area);
594   class->get_preferred_height_for_width (area, widget, width, minimum_height, natural_height);
595 }
596
597 void
598 gtk_cell_area_get_preferred_height (GtkCellArea        *area,
599                                     GtkWidget          *widget,
600                                     gint               *minimum_size,
601                                     gint               *natural_size)
602 {
603   GtkCellAreaClass *class;
604
605   g_return_if_fail (GTK_IS_CELL_AREA (area));
606   g_return_if_fail (GTK_IS_WIDGET (widget));
607
608   class = GTK_CELL_AREA_GET_CLASS (area);
609
610   if (class->get_preferred_height)
611     class->get_preferred_height (area, widget, minimum_size, natural_size);
612   else
613     g_warning ("GtkCellAreaClass::get_preferred_height not implemented for `%s'", 
614                g_type_name (G_TYPE_FROM_INSTANCE (area)));
615 }
616
617 void
618 gtk_cell_area_get_preferred_width_for_height (GtkCellArea        *area,
619                                               GtkWidget          *widget,
620                                               gint                height,
621                                               gint               *minimum_width,
622                                               gint               *natural_width)
623 {
624   GtkCellAreaClass *class;
625
626   g_return_if_fail (GTK_IS_CELL_AREA (area));
627   g_return_if_fail (GTK_IS_WIDGET (widget));
628
629   class = GTK_CELL_AREA_GET_CLASS (area);
630   class->get_preferred_width_for_height (area, widget, height, minimum_width, natural_width);
631 }
632
633
634 static void 
635 apply_attributes (GtkCellRenderer  *renderer,
636                   const gchar      *attribute,
637                   gint              id,
638                   AttributeData    *data)
639 {
640   GValue value = { 0, };
641
642   /* For each attribute of each renderer we apply the value
643    * from the model to the renderer here 
644    */
645   gtk_tree_model_get_value (data->model, data->iter, id, &value);
646   g_object_set_property (G_OBJECT (renderer), attribute, &value);
647   g_value_unset (&value);
648 }
649
650 static void 
651 apply_render_attributes (GtkCellRenderer *renderer,
652                          AttributeData   *data)
653 {
654   gtk_cell_area_attribute_forall (data->area, renderer, 
655                                   (GtkCellAttributeCallback)apply_attributes,
656                                   data);
657 }
658
659 static void
660 apply_custom_cell_data (GtkCellRenderer *renderer,
661                         CustomCellData  *custom,
662                         AttributeData   *data)
663 {
664   g_assert (custom->func);
665
666   /* For each renderer that has a GtkCellLayoutDataFunc set,
667    * go ahead and envoke it to apply the data from the model 
668    */
669   custom->func (GTK_CELL_LAYOUT (data->area), renderer,
670                 data->model, data->iter, custom->data);
671 }
672
673 void
674 gtk_cell_area_apply_attributes (GtkCellArea  *area,
675                                 GtkTreeModel *tree_model,
676                                 GtkTreeIter  *iter)
677 {
678   GtkCellAreaPrivate *priv;
679   AttributeData       data;
680
681   g_return_if_fail (GTK_IS_CELL_AREA (area));
682   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
683   g_return_if_fail (iter != NULL);
684
685   priv = area->priv;
686
687   /* For every cell renderer, for every attribute, apply the attribute */
688   data.area  = area;
689   data.model = tree_model;
690   data.iter  = iter;
691   gtk_cell_area_forall (area, (GtkCellCallback)apply_render_attributes, &data);
692
693   /* Now go over any custom cell data functions */
694   g_hash_table_foreach (priv->custom_cell_data, (GHFunc)apply_custom_cell_data, &data);
695 }