]> Pileus Git - ~andy/gtk/blob - gtk/gtktreeviewcolumn.c
use GtkSortType instead of GtkTreeSortOrder. (#59173).
[~andy/gtk] / gtk / gtktreeviewcolumn.c
1 /* gtktreeviewcolumn.c
2  * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "gtktreeviewcolumn.h"
21 #include "gtktreeview.h"
22 #include "gtktreeprivate.h"
23 #include "gtksignal.h"
24 #include "gtkbutton.h"
25 #include "gtkalignment.h"
26 #include "gtklabel.h"
27 #include "gtkhbox.h"
28 #include "gtkarrow.h"
29 #include "gtkintl.h"
30 #include <string.h>
31
32 enum
33 {
34   PROP_0,
35   PROP_VISIBLE,
36   PROP_SIZING,
37   PROP_WIDTH,
38   PROP_MIN_WIDTH,
39   PROP_MAX_WIDTH,
40   PROP_TITLE,
41   PROP_CLICKABLE,
42   PROP_WIDGET,
43   PROP_ALIGNMENT,
44   PROP_REORDERABLE,
45   PROP_SORT_INDICATOR,
46   PROP_SORT_ORDER
47 };
48
49 enum
50 {
51   CLICKED,
52   LAST_SIGNAL
53 };
54
55 typedef struct _GtkTreeViewColumnCellInfo GtkTreeViewColumnCellInfo;
56 struct _GtkTreeViewColumnCellInfo
57 {
58   GtkCellRenderer *cell;
59   GSList *attributes;
60   GtkTreeCellDataFunc func;
61   gpointer func_data;
62   GtkDestroyNotify destroy;
63   gint requested_width;
64   guint16 padding;
65   guint expand : 1;
66   guint fill : 1;
67   guint pack : 1;
68 };
69
70 /* Type methods */
71 static void gtk_tree_view_column_init                          (GtkTreeViewColumn       *tree_column);
72 static void gtk_tree_view_column_class_init                    (GtkTreeViewColumnClass  *klass);
73
74 /* GObject methods */
75 static void gtk_tree_view_column_set_property                  (GObject                 *object,
76                                                                 guint                    prop_id,
77                                                                 const GValue            *value,
78                                                                 GParamSpec              *pspec);
79 static void gtk_tree_view_column_get_property                  (GObject                 *object,
80                                                                 guint                    prop_id,
81                                                                 GValue                  *value,
82                                                                 GParamSpec              *pspec);
83 static void gtk_tree_view_column_finalize                      (GObject                 *object);
84
85 /* Button handling code */ 
86 static void gtk_tree_view_column_create_button                 (GtkTreeViewColumn       *tree_column);
87 static void gtk_tree_view_column_update_button                 (GtkTreeViewColumn       *tree_column);
88
89 /* Button signal handlers */
90 static gint gtk_tree_view_column_button_event                  (GtkWidget               *widget,
91                                                                 GdkEvent                *event,
92                                                                 gpointer                 data);
93 static void gtk_tree_view_column_button_realize                (GtkWidget               *widget,
94                                                                 gpointer                 data);
95 static void gtk_tree_view_column_button_clicked                (GtkWidget               *widget,
96                                                                 gpointer                 data);
97
98 /* Property handlers */
99 static void gtk_tree_view_model_sort_column_changed            (GtkTreeSortable         *sortable,
100                                                                 GtkTreeViewColumn       *tree_column);
101
102 /* Internal functions */
103 static void gtk_tree_view_column_sort                          (GtkTreeViewColumn       *tree_column,
104                                                                 gpointer                 data);
105 static void gtk_tree_view_column_setup_sort_column_id_callback (GtkTreeViewColumn       *tree_column);
106 static void gtk_tree_view_column_set_attributesv               (GtkTreeViewColumn       *tree_column,
107                                                                 GtkCellRenderer         *cell_renderer,
108                                                                 va_list                  args);
109 static GtkTreeViewColumnCellInfo *gtk_tree_view_column_get_cell_info (GtkTreeViewColumn *tree_column,
110                                                                       GtkCellRenderer   *cell_renderer);
111
112
113
114 static GtkObjectClass *parent_class = NULL;
115 static guint tree_column_signals[LAST_SIGNAL] = { 0 };
116
117
118 GtkType
119 gtk_tree_view_column_get_type (void)
120 {
121   static GtkType tree_column_type = 0;
122
123   if (!tree_column_type)
124     {
125       static const GTypeInfo tree_column_info =
126       {
127         sizeof (GtkTreeViewColumnClass),
128         NULL,           /* base_init */
129         NULL,           /* base_finalize */
130         (GClassInitFunc) gtk_tree_view_column_class_init,
131         NULL,           /* class_finalize */
132         NULL,           /* class_data */
133         sizeof (GtkTreeViewColumn),
134         0,
135         (GInstanceInitFunc) gtk_tree_view_column_init,
136       };
137
138       tree_column_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkTreeViewColumn", &tree_column_info, 0);
139     }
140
141   return tree_column_type;
142 }
143
144 static void
145 gtk_tree_view_column_class_init (GtkTreeViewColumnClass *class)
146 {
147   GObjectClass *object_class;
148
149   object_class = (GObjectClass*) class;
150
151   parent_class = g_type_class_peek_parent (class);
152
153   class->clicked = NULL;
154
155   object_class->finalize = gtk_tree_view_column_finalize;
156   object_class->set_property = gtk_tree_view_column_set_property;
157   object_class->get_property = gtk_tree_view_column_get_property;
158   
159   tree_column_signals[CLICKED] =
160     g_signal_new ("clicked",
161                   GTK_CLASS_TYPE (object_class),
162                   G_SIGNAL_RUN_LAST,
163                   G_STRUCT_OFFSET (GtkTreeViewColumnClass, clicked),
164                   NULL, NULL,
165                   gtk_marshal_VOID__VOID,
166                   GTK_TYPE_NONE, 0);
167
168   g_object_class_install_property (object_class,
169                                    PROP_VISIBLE,
170                                    g_param_spec_boolean ("visible",
171                                                         _("Visible"),
172                                                         _("Whether to display the column"),
173                                                          TRUE,
174                                                          G_PARAM_READABLE | G_PARAM_WRITABLE));
175   
176   g_object_class_install_property (object_class,
177                                    PROP_SIZING,
178                                    g_param_spec_enum ("sizing",
179                                                       _("Sizing"),
180                                                       _("Resize mode of the column"),
181                                                       GTK_TYPE_TREE_VIEW_COLUMN_SIZING,
182                                                       GTK_TREE_VIEW_COLUMN_AUTOSIZE,
183                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
184   
185   g_object_class_install_property (object_class,
186                                    PROP_WIDTH,
187                                    g_param_spec_int ("width",
188                                                      _("Width"),
189                                                      _("Current width of the column"),
190                                                      1,
191                                                      G_MAXINT,
192                                                      1, /* not useful */
193                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
194
195   g_object_class_install_property (object_class,
196                                    PROP_MIN_WIDTH,
197                                    g_param_spec_int ("min_width",
198                                                      _("Minimum Width"),
199                                                      _("Minimum allowed width of the column"),
200                                                      -1,
201                                                      G_MAXINT,
202                                                      1,
203                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
204
205   g_object_class_install_property (object_class,
206                                    PROP_MAX_WIDTH,
207                                    g_param_spec_int ("max_width",
208                                                      _("Maximum Width"),
209                                                      _("Maximum allowed width of the column"),
210                                                      -1,
211                                                      G_MAXINT,
212                                                      G_MAXINT,
213                                                      G_PARAM_READABLE | G_PARAM_WRITABLE));
214
215   g_object_class_install_property (object_class,
216                                    PROP_TITLE,
217                                    g_param_spec_string ("title",
218                                                         _("Title"),
219                                                         _("Title to appear in column header"),
220                                                         "",
221                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
222   
223   g_object_class_install_property (object_class,
224                                    PROP_CLICKABLE,
225                                    g_param_spec_boolean ("clickable",
226                                                         _("Clickable"),
227                                                         _("Whether the header can be clicked"),
228                                                          TRUE,
229                                                          G_PARAM_READABLE | G_PARAM_WRITABLE));
230   
231
232   g_object_class_install_property (object_class,
233                                    PROP_WIDGET,
234                                    g_param_spec_object ("widget",
235                                                         _("Widget"),
236                                                         _("Widget to put in column header button instead of column title"),
237                                                         GTK_TYPE_WIDGET,
238                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
239
240   g_object_class_install_property (object_class,
241                                    PROP_ALIGNMENT,
242                                    g_param_spec_float ("alignment",
243                                                        _("Alignment"),
244                                                        _("X Alignment of the column header text or widget"),
245                                                        0.0,
246                                                        1.0,
247                                                        0.5,
248                                                        G_PARAM_READABLE | G_PARAM_WRITABLE));
249
250   g_object_class_install_property (object_class,
251                                    PROP_REORDERABLE,
252                                    g_param_spec_boolean ("reorderable",
253                                                          _("Reorderable"),
254                                                          _("Wether the column can be reordered around the headers"),
255                                                          FALSE,
256                                                          G_PARAM_READABLE | G_PARAM_WRITABLE));
257
258   g_object_class_install_property (object_class,
259                                    PROP_SORT_INDICATOR,
260                                    g_param_spec_boolean ("sort_indicator",
261                                                         _("Sort indicator"),
262                                                         _("Whether to show a sort indicator"),
263                                                          FALSE,
264                                                          G_PARAM_READABLE | G_PARAM_WRITABLE));
265
266   g_object_class_install_property (object_class,
267                                    PROP_SORT_ORDER,
268                                    g_param_spec_enum ("sort_order",
269                                                       _("Sort order"),
270                                                       _("Sort direction the sort indicator should indicate"),
271                                                       GTK_TYPE_SORT_TYPE,
272                                                       GTK_SORT_ASCENDING,
273                                                       G_PARAM_READABLE | G_PARAM_WRITABLE));
274   
275 }
276
277 static void
278 gtk_tree_view_column_init (GtkTreeViewColumn *tree_column)
279 {
280   tree_column->button = NULL;
281   tree_column->xalign = 0.0;
282   tree_column->width = 1;
283   tree_column->requested_width = -1;
284   tree_column->min_width = -1;
285   tree_column->max_width = -1;
286   tree_column->column_type = GTK_TREE_VIEW_COLUMN_AUTOSIZE;
287   tree_column->visible = TRUE;
288   tree_column->clickable = FALSE;
289   tree_column->dirty = TRUE;
290   tree_column->sort_order = GTK_SORT_ASCENDING;
291   tree_column->show_sort_indicator = FALSE;
292   tree_column->property_changed_signal = 0;
293   tree_column->sort_clicked_signal = 0;
294   tree_column->sort_column_changed_signal = 0;
295   tree_column->sort_column_id = -1;
296   tree_column->reorderable = FALSE;
297   tree_column->maybe_reordered = FALSE;
298 }
299
300 static void
301 gtk_tree_view_column_finalize (GObject *object)
302 {
303   GtkTreeViewColumn *tree_column = (GtkTreeViewColumn *) object;
304   GList *list;
305
306   for (list = tree_column->cell_list; list; list = list->next)
307     {
308       GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
309       if (info->func_data && info->destroy)
310         (info->destroy) (info->func_data);
311       gtk_tree_view_column_clear_attributes (tree_column, info->cell);
312       g_object_unref (G_OBJECT (info->cell));
313       g_free (info);
314     }
315
316   g_free (tree_column->title);
317
318   G_OBJECT_CLASS (parent_class)->finalize (object);
319 }
320
321 static void
322 gtk_tree_view_column_set_property (GObject         *object,
323                                    guint            prop_id,
324                                    const GValue    *value,
325                                    GParamSpec      *pspec)
326 {
327   GtkTreeViewColumn *tree_column;
328
329   tree_column = GTK_TREE_VIEW_COLUMN (object);
330
331   switch (prop_id)
332     {
333     case PROP_VISIBLE:
334       gtk_tree_view_column_set_visible (tree_column,
335                                         g_value_get_boolean (value));
336       break;
337
338     case PROP_SIZING:
339       gtk_tree_view_column_set_sizing (tree_column,
340                                        g_value_get_enum (value));
341       break;
342
343     case PROP_WIDTH:
344       gtk_tree_view_column_set_width (tree_column,
345                                       g_value_get_int (value));
346       break;
347
348     case PROP_MIN_WIDTH:
349       gtk_tree_view_column_set_min_width (tree_column,
350                                           g_value_get_int (value));
351       break;
352
353     case PROP_MAX_WIDTH:
354       gtk_tree_view_column_set_max_width (tree_column,
355                                           g_value_get_int (value));
356       break;
357
358     case PROP_TITLE:
359       gtk_tree_view_column_set_title (tree_column,
360                                       g_value_get_string (value));
361       break;
362
363     case PROP_CLICKABLE:
364       gtk_tree_view_column_set_clickable (tree_column,
365                                           g_value_get_boolean (value));
366       break;
367
368     case PROP_WIDGET:
369       gtk_tree_view_column_set_widget (tree_column,
370                                        (GtkWidget*) g_value_get_object (value));
371       break;
372
373     case PROP_ALIGNMENT:
374       gtk_tree_view_column_set_alignment (tree_column,
375                                           g_value_get_float (value));
376       break;
377
378     case PROP_REORDERABLE:
379       gtk_tree_view_column_set_reorderable (tree_column,
380                                             g_value_get_boolean (value));
381       break;
382
383     case PROP_SORT_INDICATOR:
384       gtk_tree_view_column_set_sort_indicator (tree_column,
385                                                g_value_get_boolean (value));
386       break;
387
388     case PROP_SORT_ORDER:
389       gtk_tree_view_column_set_sort_order (tree_column,
390                                            g_value_get_enum (value));
391       break;
392       
393     default:
394       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
395       break;
396     }
397 }
398
399 static void
400 gtk_tree_view_column_get_property (GObject         *object,
401                                    guint            prop_id,
402                                    GValue          *value,
403                                    GParamSpec      *pspec)
404 {
405   GtkTreeViewColumn *tree_column;
406
407   tree_column = GTK_TREE_VIEW_COLUMN (object);
408
409   switch (prop_id)
410     {
411     case PROP_VISIBLE:
412       g_value_set_boolean (value,
413                            gtk_tree_view_column_get_visible (tree_column));
414       break;
415
416     case PROP_SIZING:
417       g_value_set_enum (value,
418                         gtk_tree_view_column_get_sizing (tree_column));
419       break;
420
421     case PROP_WIDTH:
422       g_value_set_int (value,
423                        gtk_tree_view_column_get_width (tree_column));
424       break;
425
426     case PROP_MIN_WIDTH:
427       g_value_set_int (value,
428                        gtk_tree_view_column_get_min_width (tree_column));
429       break;
430
431     case PROP_MAX_WIDTH:
432       g_value_set_int (value,
433                        gtk_tree_view_column_get_max_width (tree_column));
434       break;
435
436     case PROP_TITLE:
437       g_value_set_string (value,
438                           gtk_tree_view_column_get_title (tree_column));
439       break;
440
441     case PROP_CLICKABLE:
442       g_value_set_boolean (value,
443                            gtk_tree_view_column_get_clickable (tree_column));
444       break;
445
446     case PROP_WIDGET:
447       g_value_set_object (value,
448                           (GObject*) gtk_tree_view_column_get_widget (tree_column));
449       break;
450
451     case PROP_ALIGNMENT:
452       g_value_set_float (value,
453                          gtk_tree_view_column_get_alignment (tree_column));
454       break;
455
456     case PROP_REORDERABLE:
457       g_value_set_boolean (value,
458                            gtk_tree_view_column_get_reorderable (tree_column));
459       break;
460
461     case PROP_SORT_INDICATOR:
462       g_value_set_boolean (value,
463                            gtk_tree_view_column_get_sort_indicator (tree_column));
464       break;
465
466     case PROP_SORT_ORDER:
467       g_value_set_enum (value,
468                         gtk_tree_view_column_get_sort_order (tree_column));
469       break;
470       
471     default:
472       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
473       break;
474     }
475 }
476
477 /* Helper functions
478  */
479
480 /* Button handling code
481  */
482 static void
483 gtk_tree_view_column_create_button (GtkTreeViewColumn *tree_column)
484 {
485   GtkTreeView *tree_view;
486   GtkWidget *child;
487   GtkWidget *hbox;
488
489   tree_view = (GtkTreeView *) tree_column->tree_view;
490
491   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
492   g_return_if_fail (tree_column->button == NULL);
493
494   gtk_widget_push_composite_child ();
495   tree_column->button = gtk_button_new ();
496   gtk_widget_pop_composite_child ();
497
498   /* make sure we own a reference to it as well. */
499   if (tree_view->priv->header_window)
500     gtk_widget_set_parent_window (tree_column->button, tree_view->priv->header_window);
501   gtk_widget_set_parent (tree_column->button, GTK_WIDGET (tree_view));
502   
503   gtk_signal_connect (GTK_OBJECT (tree_column->button), "realize",
504                       (GtkSignalFunc) gtk_tree_view_column_button_realize,
505                       NULL);
506
507   gtk_signal_connect (GTK_OBJECT (tree_column->button), "event",
508                       (GtkSignalFunc) gtk_tree_view_column_button_event,
509                       (gpointer) tree_column);
510   
511   gtk_signal_connect (GTK_OBJECT (tree_column->button), "clicked",
512                       (GtkSignalFunc) gtk_tree_view_column_button_clicked,
513                       (gpointer) tree_column);
514
515   tree_column->alignment = gtk_alignment_new (tree_column->xalign, 0.5, 0.0, 0.0);
516
517   hbox = gtk_hbox_new (FALSE, 2);
518   tree_column->arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_IN);
519
520   if (tree_column->child)
521     child = tree_column->child;
522   else
523     {
524       child = gtk_label_new (tree_column->title);
525       gtk_widget_show (child);
526     }
527
528   if (tree_column->xalign <= 0.5)
529     gtk_box_pack_end (GTK_BOX (hbox), tree_column->arrow, FALSE, FALSE, 0);
530   else
531     gtk_box_pack_start (GTK_BOX (hbox), tree_column->arrow, FALSE, FALSE, 0);
532
533   gtk_box_pack_start (GTK_BOX (hbox), tree_column->alignment, TRUE, TRUE, 0);
534         
535   gtk_container_add (GTK_CONTAINER (tree_column->alignment), child);
536   gtk_container_add (GTK_CONTAINER (tree_column->button), hbox);
537
538   gtk_widget_show (hbox);
539   gtk_widget_show (tree_column->alignment);
540   gtk_tree_view_column_update_button (tree_column);
541 }
542
543 static void 
544 gtk_tree_view_column_update_button (GtkTreeViewColumn *tree_column)
545 {
546   GtkWidget *hbox;
547   GtkWidget *alignment;
548   GtkWidget *arrow;
549   GtkWidget *current_child;
550
551   /* Create a button if necessary */
552   if (tree_column->visible &&
553       tree_column->button == NULL &&
554       tree_column->tree_view &&
555       GTK_WIDGET_REALIZED (tree_column->tree_view))
556     gtk_tree_view_column_create_button (tree_column);
557   
558   if (! tree_column->button)
559     return;
560
561   hbox = GTK_BIN (tree_column->button)->child;
562   alignment = tree_column->alignment;
563   arrow = tree_column->arrow;
564   current_child = GTK_BIN (alignment)->child;
565
566   /* Set up the actual button */
567   gtk_alignment_set (GTK_ALIGNMENT (alignment), tree_column->xalign,
568                      0.5, 0.0, 0.0);
569       
570   if (tree_column->child)
571     {
572       if (current_child != tree_column->child)
573         {
574           gtk_container_remove (GTK_CONTAINER (alignment),
575                                 current_child);
576           gtk_container_add (GTK_CONTAINER (alignment),
577                              tree_column->child);
578         }
579     }
580   else 
581     {
582       if (current_child == NULL)
583         {
584           current_child = gtk_label_new (NULL);
585           gtk_widget_show (current_child);
586           gtk_container_add (GTK_CONTAINER (alignment),
587                              current_child);
588         }
589
590       g_return_if_fail (GTK_IS_LABEL (current_child));
591
592       if (tree_column->title)
593         gtk_label_set_text (GTK_LABEL (current_child),
594                             tree_column->title);
595       else
596         gtk_label_set_text (GTK_LABEL (current_child),
597                             "");
598     }
599
600   switch (tree_column->sort_order)
601     {
602     case GTK_SORT_ASCENDING:
603       gtk_arrow_set (GTK_ARROW (arrow),
604                      GTK_ARROW_DOWN,
605                      GTK_SHADOW_IN);
606       break;
607
608     case GTK_SORT_DESCENDING:
609       gtk_arrow_set (GTK_ARROW (arrow),
610                      GTK_ARROW_UP,
611                      GTK_SHADOW_IN);
612       break;
613           
614     default:
615       g_warning (G_STRLOC": bad sort order");
616       break;
617     }
618
619   /* Put arrow on the right if the text is left-or-center justified,
620        * and on the left otherwise; do this by packing boxes, so flipping
621        * text direction will reverse things
622        */
623   gtk_widget_ref (arrow);
624   gtk_container_remove (GTK_CONTAINER (hbox), arrow);
625
626   if (tree_column->xalign <= 0.5)
627     {
628       gtk_box_pack_end (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
629     }
630   else
631     {
632       gtk_box_pack_start (GTK_BOX (hbox), arrow, FALSE, FALSE, 0);
633       /* move it to the front */
634       gtk_box_reorder_child (GTK_BOX (hbox), arrow, 0);
635     }
636   gtk_widget_unref (arrow);
637
638   if (tree_column->show_sort_indicator)
639     gtk_widget_show (arrow);
640   else
641     gtk_widget_hide (arrow);
642
643   /* It's always safe to hide the button.  It isn't always safe to show it, as if you show it
644    * before it's realized, it'll get the wrong window. */
645   if (tree_column->button &&
646       tree_column->tree_view != NULL &&
647       GTK_WIDGET_REALIZED (tree_column->tree_view))
648     {
649       if (tree_column->visible)
650         {
651           gtk_widget_show_now (tree_column->button);
652           if (tree_column->window)
653             {
654               if (tree_column->column_type == GTK_TREE_VIEW_COLUMN_RESIZABLE)
655                 {
656                   gdk_window_show (tree_column->window);
657                   gdk_window_raise (tree_column->window);
658                 }
659               else
660                 {
661                   gdk_window_hide (tree_column->window);
662                 }
663             }
664         }
665       else
666         {
667           gtk_widget_hide (tree_column->button);
668           if (tree_column->window)
669             gdk_window_hide (tree_column->window);
670         }
671     }
672   
673   if (tree_column->reorderable || tree_column->clickable)
674     {
675       GTK_WIDGET_SET_FLAGS (tree_column->button, GTK_CAN_FOCUS);
676     }
677   else
678     {
679       GTK_WIDGET_UNSET_FLAGS (tree_column->button, GTK_CAN_FOCUS);
680       if (GTK_WIDGET_HAS_FOCUS (tree_column->button))
681         {
682           GtkWidget *toplevel = gtk_widget_get_toplevel (tree_column->tree_view);
683           if (GTK_WIDGET_TOPLEVEL (toplevel))
684             gtk_window_set_focus (GTK_WINDOW (toplevel), NULL);
685         }
686     }
687
688   tree_column->dirty = TRUE;
689   gtk_widget_queue_resize (tree_column->tree_view);
690 }
691
692 /* Button signal handlers
693  */
694
695 static gint
696 gtk_tree_view_column_button_event (GtkWidget *widget,
697                                    GdkEvent  *event,
698                                    gpointer   data)
699 {
700   GtkTreeViewColumn *column = (GtkTreeViewColumn *) data;
701
702   g_return_val_if_fail (event != NULL, FALSE);
703
704   if (event->type == GDK_BUTTON_PRESS &&
705       column->reorderable)
706     {
707       column->maybe_reordered = TRUE;
708       gdk_window_get_pointer (widget->window,
709                               &column->drag_x,
710                               &column->drag_y,
711                               NULL);
712       gtk_widget_grab_focus (widget);
713     }
714
715   if (event->type == GDK_BUTTON_RELEASE &&
716       column->maybe_reordered)
717     column->maybe_reordered = FALSE;
718
719   if (event->type == GDK_MOTION_NOTIFY &&
720       (column->maybe_reordered) &&
721       (gtk_drag_check_threshold (widget,
722                                  column->drag_x,
723                                  column->drag_y,
724                                  (gint) ((GdkEventMotion *)event)->x,
725                                  (gint) ((GdkEventMotion *)event)->y)))
726     {
727       column->maybe_reordered = FALSE;
728       _gtk_tree_view_column_start_drag (GTK_TREE_VIEW (column->tree_view), column);
729       return TRUE;
730     }
731   if (column->clickable == FALSE)
732     {
733       switch (event->type)
734         {
735         case GDK_BUTTON_PRESS:
736         case GDK_2BUTTON_PRESS:
737         case GDK_3BUTTON_PRESS:
738         case GDK_MOTION_NOTIFY:
739         case GDK_BUTTON_RELEASE:
740         case GDK_ENTER_NOTIFY:
741         case GDK_LEAVE_NOTIFY:
742           return TRUE;
743         default:
744           return FALSE;
745         }
746     }
747   return FALSE;
748 }
749
750 static void
751 gtk_tree_view_column_button_realize (GtkWidget *widget, gpointer data)
752 {
753   gdk_window_set_events (widget->window, gdk_window_get_events (widget->window) | GDK_POINTER_MOTION_MASK);
754 }
755
756 static void
757 gtk_tree_view_column_button_clicked (GtkWidget *widget, gpointer data)
758 {
759   g_signal_emit_by_name (G_OBJECT (data), "clicked");
760 }
761
762 static void
763 gtk_tree_view_model_sort_column_changed (GtkTreeSortable   *sortable,
764                                           GtkTreeViewColumn *column)
765 {
766   gint sort_column_id;
767   GtkSortType order;
768
769   if (gtk_tree_sortable_get_sort_column_id (sortable,
770                                             &sort_column_id,
771                                             &order))
772     {
773       if (sort_column_id == column->sort_column_id)
774         {
775           gtk_tree_view_column_set_sort_indicator (column, TRUE);
776           gtk_tree_view_column_set_sort_order (column, order);
777         }
778       else
779         {
780           gtk_tree_view_column_set_sort_indicator (column, FALSE);
781         }
782     }
783 }
784
785 static void
786 gtk_tree_view_column_sort (GtkTreeViewColumn *tree_column,
787                            gpointer           data)
788 {
789   GList *list;
790
791   g_return_if_fail (tree_column->tree_view != NULL);
792
793   if (tree_column->show_sort_indicator)
794     {
795       if (tree_column->sort_order == GTK_SORT_ASCENDING)
796         gtk_tree_view_column_set_sort_order (tree_column, GTK_SORT_DESCENDING);
797       else
798         gtk_tree_view_column_set_sort_order (tree_column, GTK_SORT_ASCENDING);
799     }
800   else
801     {
802       gtk_tree_view_column_set_sort_order (tree_column, GTK_SORT_ASCENDING);
803       gtk_tree_view_column_set_sort_indicator (tree_column, TRUE);
804     }
805
806   list = (GTK_TREE_VIEW (tree_column->tree_view)->priv->columns);
807   g_assert (list);
808   while (list)
809     {
810       GtkTreeViewColumn *tmp_column;
811
812       tmp_column = GTK_TREE_VIEW_COLUMN (list->data);
813       if (tmp_column->visible && tmp_column != tree_column)
814         gtk_tree_view_column_set_sort_indicator (tmp_column, FALSE);
815
816       list = list->next;
817     }
818
819   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (GTK_TREE_VIEW (tree_column->tree_view)->priv->model),
820                                         tree_column->sort_column_id,
821                                         tree_column->sort_order);
822 }
823
824
825 static void
826 gtk_tree_view_column_setup_sort_column_id_callback (GtkTreeViewColumn *tree_column)
827 {
828   GtkTreeModel *model;
829
830   if (tree_column->tree_view == NULL)
831     return;
832
833   model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_column->tree_view));
834
835   if (model == NULL)
836     return;
837
838   if (GTK_IS_TREE_SORTABLE (model) &&
839       tree_column->sort_column_id != -1)
840     {
841       gint real_sort_column_id;
842       GtkSortType real_order;
843
844       if (tree_column->sort_column_changed_signal == 0)
845         tree_column->sort_column_changed_signal =
846           g_signal_connect (G_OBJECT (model), "sort_column_changed",
847                             GTK_SIGNAL_FUNC (gtk_tree_view_model_sort_column_changed),
848                             tree_column);
849       
850       if (gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (model),
851                                                 &real_sort_column_id,
852                                                 &real_order) &&
853           (real_sort_column_id == tree_column->sort_column_id))
854         {
855           gtk_tree_view_column_set_sort_indicator (tree_column, TRUE);
856           gtk_tree_view_column_set_sort_order (tree_column, real_order);
857
858           return;
859         }
860     }
861 }
862
863
864 /* Exported Private Functions.
865  * These should only be called by gtktreeview.c or gtktreeviewcolumn.c
866  */
867
868 void
869 _gtk_tree_view_column_realize_button (GtkTreeViewColumn *column)
870 {
871   GtkTreeView *tree_view;
872   GdkWindowAttr attr;
873   guint attributes_mask;
874
875   tree_view = (GtkTreeView *)column->tree_view;
876
877   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
878   g_return_if_fail (GTK_WIDGET_REALIZED (tree_view));
879   g_return_if_fail (tree_view->priv->header_window != NULL);
880   g_return_if_fail (column->button != NULL);
881
882   gtk_widget_set_parent_window (column->button, tree_view->priv->header_window);
883
884   if (column->visible)
885     gtk_widget_show (column->button);
886
887   attr.window_type = GDK_WINDOW_CHILD;
888   attr.wclass = GDK_INPUT_ONLY;
889   attr.visual = gtk_widget_get_visual (GTK_WIDGET (tree_view));
890   attr.colormap = gtk_widget_get_colormap (GTK_WIDGET (tree_view));
891   attr.event_mask = gtk_widget_get_events (GTK_WIDGET (tree_view));
892   attr.event_mask = (GDK_BUTTON_PRESS_MASK |
893                      GDK_BUTTON_RELEASE_MASK |
894                      GDK_POINTER_MOTION_MASK |
895                      GDK_POINTER_MOTION_HINT_MASK |
896                      GDK_KEY_PRESS_MASK);
897   attributes_mask = GDK_WA_CURSOR | GDK_WA_X | GDK_WA_Y;
898   attr.cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW);
899   tree_view->priv->cursor_drag = attr.cursor;
900
901   attr.y = 0;
902   attr.width = TREE_VIEW_DRAG_WIDTH;
903   attr.height = tree_view->priv->header_height;
904
905   attr.x = (column->button->allocation.x + column->button->allocation.width) - 3;
906           
907   column->window = gdk_window_new (tree_view->priv->header_window,
908                                    &attr, attributes_mask);
909   gdk_window_set_user_data (column->window, tree_view);
910
911   gtk_tree_view_column_update_button (column);
912 }
913
914 void
915 _gtk_tree_view_column_unrealize_button (GtkTreeViewColumn *column)
916 {
917   g_return_if_fail (column != NULL);
918   g_return_if_fail (column->window != NULL);
919
920   gdk_window_set_user_data (column->window, NULL);
921   gdk_window_destroy (column->window);
922   column->window = NULL;
923 }
924
925 void
926 _gtk_tree_view_column_set_tree_view (GtkTreeViewColumn *column,
927                                      GtkTreeView       *tree_view)
928 {
929   g_assert (column->tree_view == NULL);
930
931   column->tree_view = GTK_WIDGET (tree_view);
932   gtk_tree_view_column_create_button (column);
933
934   column->property_changed_signal =
935           g_signal_connect_swapped (GTK_OBJECT (tree_view),
936                                     "notify::model",
937                                     GTK_SIGNAL_FUNC (gtk_tree_view_column_setup_sort_column_id_callback),
938                                     column);
939
940   gtk_tree_view_column_setup_sort_column_id_callback (column);
941 }
942
943 void
944 _gtk_tree_view_column_unset_tree_view (GtkTreeViewColumn *column)
945 {
946   if (column->tree_view && column->button)
947     {
948       gtk_container_remove (GTK_CONTAINER (column->tree_view), column->button);
949     }
950   if (column->property_changed_signal)
951     {
952       g_signal_handler_disconnect (G_OBJECT (column->tree_view), column->property_changed_signal);
953       column->property_changed_signal = 0;
954     }
955
956   if (column->sort_column_changed_signal)
957     {
958       g_signal_handler_disconnect (G_OBJECT (gtk_tree_view_get_model (GTK_TREE_VIEW (column->tree_view))),
959                                    column->sort_column_changed_signal);
960       column->sort_column_changed_signal = 0;
961     }
962
963   column->tree_view = NULL;
964   column->button = NULL;
965 }
966
967 void
968 _gtk_tree_view_column_set_width (GtkTreeViewColumn *tree_column,
969                                  gint               width)
970 {
971   if (tree_column->min_width != -1 &&
972       width <= tree_column->min_width)
973     width = tree_column->min_width;
974   else if (tree_column->max_width != -1 &&
975            width > tree_column->max_width)
976     width = tree_column->max_width;
977   
978   if (tree_column->width == width)
979     return;
980   
981   tree_column->width = width;
982
983   g_object_notify (G_OBJECT (tree_column), "width");
984
985   if (tree_column->tree_view != NULL)
986     gtk_widget_queue_resize (tree_column->tree_view);
987
988 }
989
990 /* Public Functions */
991
992
993 /**
994  * gtk_tree_view_column_new:
995  * 
996  * Creates a new #GtkTreeViewColumn.
997  * 
998  * Return value: A newly created #GtkTreeViewColumn.
999  **/
1000 GtkTreeViewColumn *
1001 gtk_tree_view_column_new (void)
1002 {
1003   GtkTreeViewColumn *tree_column;
1004
1005   tree_column = GTK_TREE_VIEW_COLUMN (gtk_type_new (GTK_TYPE_TREE_VIEW_COLUMN));
1006
1007   return tree_column;
1008 }
1009
1010 /**
1011  * gtk_tree_view_column_new_with_attributes:
1012  * @title: The title to set the header to.
1013  * @cell: The #GtkCellRenderer.
1014  * @Varargs: A NULL terminated list of attributes.
1015  * 
1016  * Creates a new #GtkTreeViewColumn with a number of default values.  This is
1017  * equivalent to calling @gtk_tree_view_column_set_title,
1018  * @gtk_tree_view_column_set_cell_renderer, and
1019  * @gtk_tree_view_column_set_attributes on the newly created #GtkTreeViewColumn.
1020  * 
1021  * Return value: A newly created #GtkTreeViewColumn.
1022  **/
1023 GtkTreeViewColumn *
1024 gtk_tree_view_column_new_with_attributes (const gchar     *title,
1025                                           GtkCellRenderer *cell,
1026                                           ...)
1027 {
1028   GtkTreeViewColumn *retval;
1029   va_list args;
1030
1031   retval = gtk_tree_view_column_new ();
1032
1033   gtk_tree_view_column_set_title (retval, title);
1034   gtk_tree_view_column_set_cell_renderer (retval, cell);
1035
1036   va_start (args, cell);
1037   gtk_tree_view_column_set_attributesv (retval, cell, args);
1038   va_end (args);
1039
1040   return retval;
1041 }
1042
1043 /**
1044  * gtk_tree_view_column_set_cell_renderer:
1045  * @tree_column: A #GtkTreeViewColumn.
1046  * @cell: The #GtkCellRenderer, or NULL.
1047  * 
1048  * Sets the cell renderer of the @tree_column.  If there is a cell
1049  * renderer already set, then it is removed.  If @cell is NULL, then
1050  * the cell renderer is unset.
1051  **/
1052 void
1053 gtk_tree_view_column_set_cell_renderer (GtkTreeViewColumn *tree_column,
1054                                         GtkCellRenderer   *cell)
1055 {
1056   gtk_tree_view_column_pack_start_cell_renderer (tree_column, cell, TRUE, TRUE, 0);
1057 }
1058
1059 static GtkTreeViewColumnCellInfo *
1060 gtk_tree_view_column_get_cell_info (GtkTreeViewColumn *tree_column,
1061                                     GtkCellRenderer   *cell_renderer)
1062 {
1063   GList *list;
1064   for (list = tree_column->cell_list; list; list = list->next)
1065     if (((GtkTreeViewColumnCellInfo *)list->data)->cell == cell_renderer)
1066       return (GtkTreeViewColumnCellInfo *) list->data;
1067   return NULL;
1068 }
1069
1070 /**
1071  * gtk_tree_view_column_pack_start_cell_renderer:
1072  * @tree_column: A #GtkTreeViewColumn.
1073  * @cell: The #GtkCellRenderer, 
1074  * @expand: TRUE if @cell is to be given extra space allocated to box.
1075  * @fill: TRUE if @cell is to fill space allocated to it.
1076  * @padding: extra space in pixels to place on the outside of the cell
1077  * 
1078  * Packs a cell into 
1079  **/
1080 void
1081 gtk_tree_view_column_pack_start_cell_renderer (GtkTreeViewColumn  *tree_column,
1082                                                GtkCellRenderer    *cell,
1083                                                gboolean            expand,
1084                                                gboolean            fill,
1085                                                guint               padding)
1086 {
1087   GtkTreeViewColumnCellInfo *cell_info;
1088
1089   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1090   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
1091   g_return_if_fail (! gtk_tree_view_column_get_cell_info (tree_column, cell));
1092
1093   g_object_ref (G_OBJECT (cell));
1094   gtk_object_sink (GTK_OBJECT (cell));
1095
1096   cell_info = g_new0 (GtkTreeViewColumnCellInfo, 1);
1097   cell_info->cell = cell;
1098   cell_info->expand = expand ? TRUE : FALSE;
1099   cell_info->fill = fill ? TRUE : FALSE;
1100   cell_info->pack = GTK_PACK_START;
1101   cell_info->attributes = NULL;
1102
1103   tree_column->cell_list = g_list_append (tree_column->cell_list, cell_info);
1104 }
1105
1106 void
1107 gtk_tree_view_column_pack_end_cell_renderer (GtkTreeViewColumn  *tree_column,
1108                                              GtkCellRenderer    *cell,
1109                                              gboolean            expand,
1110                                              gboolean            fill,
1111                                              guint               padding)
1112 {
1113   GtkTreeViewColumnCellInfo *cell_info;
1114
1115   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1116   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
1117   g_return_if_fail (! gtk_tree_view_column_get_cell_info (tree_column, cell));
1118
1119   g_object_ref (G_OBJECT (cell));
1120   gtk_object_sink (GTK_OBJECT (cell));
1121
1122   cell_info = g_new (GtkTreeViewColumnCellInfo, 1);
1123   cell_info->cell = cell;
1124   cell_info->expand = expand ? TRUE : FALSE;
1125   cell_info->fill = fill ? TRUE : FALSE;
1126   cell_info->pack = GTK_PACK_END;
1127   cell_info->attributes = NULL;
1128
1129   tree_column->cell_list = g_list_append (tree_column->cell_list, cell_info);
1130 }
1131
1132
1133 void
1134 gtk_tree_view_column_clear_cell_renderers (GtkTreeViewColumn *tree_column)
1135 {
1136   GList *list;
1137   g_return_if_fail (tree_column != NULL);
1138
1139   for (list = tree_column->cell_list; list; list = list->next)
1140     {
1141       GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *)list->data;
1142
1143       g_object_unref (G_OBJECT (info->cell));
1144       gtk_tree_view_column_clear_attributes (tree_column, info->cell);
1145       g_free (info);
1146     }
1147
1148   g_list_free (tree_column->cell_list);
1149   tree_column->cell_list = NULL;
1150 }
1151
1152 GList *
1153 gtk_tree_view_column_get_cell_renderers (GtkTreeViewColumn *tree_column)
1154 {
1155   GList *retval = NULL, *list;
1156
1157   g_return_val_if_fail (tree_column != NULL, NULL);
1158
1159   for (list = tree_column->cell_list; list; list = list->next)
1160     {
1161       GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *)list->data;
1162
1163       retval = g_list_append (retval, info->cell);
1164     }
1165
1166   return retval;
1167 }
1168
1169 /**
1170  * gtk_tree_view_column_add_attribute:
1171  * @tree_column: A #GtkTreeViewColumn.
1172  * @attribute: An attribute on the columns cell
1173  * @column: The column position on the model to get the attribute from.
1174  * 
1175  * Adds an attribute mapping to the list in @tree_column.  The @column is the
1176  * column position on the model to get a value from, and the @attribute is the
1177  * parameter on the @tree_column's cell renderer to set that value to.
1178  **/
1179 void
1180 gtk_tree_view_column_add_attribute (GtkTreeViewColumn *tree_column,
1181                                     GtkCellRenderer   *cell_renderer,
1182                                     const gchar       *attribute,
1183                                     gint               column)
1184 {
1185   GtkTreeViewColumnCellInfo *info;
1186
1187   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1188   info = gtk_tree_view_column_get_cell_info (tree_column, cell_renderer);
1189   g_return_if_fail (info != NULL);
1190
1191   info->attributes = g_slist_prepend (info->attributes, GINT_TO_POINTER (column));
1192   info->attributes = g_slist_prepend (info->attributes, g_strdup (attribute));
1193
1194   if (tree_column->tree_view)
1195     {
1196       tree_column->dirty = TRUE;
1197       gtk_widget_queue_resize (tree_column->tree_view);
1198     }
1199
1200 }
1201
1202 static void
1203 gtk_tree_view_column_set_attributesv (GtkTreeViewColumn *tree_column,
1204                                       GtkCellRenderer   *cell_renderer,
1205                                       va_list            args)
1206 {
1207   gchar *attribute;
1208   gint column;
1209
1210   attribute = va_arg (args, gchar *);
1211
1212   gtk_tree_view_column_clear_attributes (tree_column, cell_renderer);
1213   
1214   while (attribute != NULL)
1215     {
1216       column = va_arg (args, gint);
1217       gtk_tree_view_column_add_attribute (tree_column, cell_renderer, attribute, column);
1218       attribute = va_arg (args, gchar *);
1219     }
1220 }
1221
1222 /**
1223  * gtk_tree_view_column_set_attributes:
1224  * @tree_column: A #GtkTreeViewColumn.
1225  * @Varargs: A NULL terminated listing of attributes.
1226  * 
1227  * Sets the attributes in the list as the attributes of @tree_column.
1228  * The attributes should be in attribute/column order, as in
1229  * @gtk_tree_view_column_add_attribute. All existing attributes
1230  * are removed, and replaced with the new attributes.
1231  **/
1232 void
1233 gtk_tree_view_column_set_attributes (GtkTreeViewColumn *tree_column,
1234                                      GtkCellRenderer   *cell_renderer,
1235                                      ...)
1236 {
1237   va_list args;
1238
1239   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1240   g_return_if_fail (GTK_IS_CELL_RENDERER (cell_renderer));
1241   g_return_if_fail (gtk_tree_view_column_get_cell_info (tree_column, cell_renderer));
1242
1243   va_start (args, cell_renderer);
1244   gtk_tree_view_column_set_attributesv (tree_column, cell_renderer, args);
1245   va_end (args);
1246 }
1247
1248
1249 /**
1250  * gtk_tree_view_column_set_cell_data_func:
1251  * @tree_column: A #GtkTreeViewColumn
1252  * @func: The #GtkTreeViewColumnFunc to use. 
1253  * @func_data: The user data for @func.
1254  * @destroy: The destroy notification for @func_data
1255  * 
1256  * Sets the #GtkTreeViewColumnFunc to use for the column.  This function is used
1257  * instead of the standard attributes mapping for setting the column value, and
1258  * should set the value of @tree_column 's cell renderer as appropriate.  @func
1259  * may be NULL to remove an older one.
1260  **/
1261 void
1262 gtk_tree_view_column_set_cell_data_func (GtkTreeViewColumn   *tree_column,
1263                                          GtkCellRenderer     *cell_renderer,
1264                                          GtkTreeCellDataFunc  func,
1265                                          gpointer             func_data,
1266                                          GtkDestroyNotify     destroy)
1267 {
1268   GtkTreeViewColumnCellInfo *info;
1269
1270   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1271   g_return_if_fail (GTK_IS_CELL_RENDERER (cell_renderer));
1272   info = gtk_tree_view_column_get_cell_info (tree_column, cell_renderer);
1273
1274   g_return_if_fail (info != NULL);
1275
1276   if (func == info->func &&
1277       func_data == info->func_data &&
1278       destroy == info->destroy)
1279     return;
1280
1281   if (info->func_data && info->destroy)
1282     (info->destroy) (info->func_data);
1283
1284   info->func = func;
1285   info->func_data = func_data;
1286   info->destroy = destroy;
1287
1288   if (tree_column->tree_view)
1289     {
1290       tree_column->dirty = TRUE;
1291       gtk_widget_queue_resize (tree_column->tree_view);
1292     }
1293 }
1294
1295
1296 /**
1297  * gtk_tree_view_column_clear_attributes:
1298  * @tree_column: a #GtkTreeViewColumn
1299  *@cell_renderer: a #GtkCellRenderer to clear the attribute mapping on.
1300  * 
1301  * Clears all existing attributes previously set with
1302  * gtk_tree_view_column_set_attributes().
1303  **/
1304 void
1305 gtk_tree_view_column_clear_attributes (GtkTreeViewColumn *tree_column,
1306                                        GtkCellRenderer   *cell_renderer)
1307 {
1308   GtkTreeViewColumnCellInfo *info;
1309   GSList *list;
1310
1311   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1312   g_return_if_fail (GTK_IS_CELL_RENDERER (cell_renderer));
1313   info = gtk_tree_view_column_get_cell_info (tree_column, cell_renderer);
1314
1315   list = info->attributes;
1316
1317   while (list && list->next)
1318     {
1319       g_free (list->data);
1320       list = list->next->next;
1321     }
1322   g_slist_free (info->attributes);
1323   info->attributes = NULL;
1324
1325   if (tree_column->tree_view)
1326     {
1327       tree_column->dirty = TRUE;
1328       gtk_widget_queue_resize (tree_column->tree_view);
1329     }
1330 }
1331
1332
1333 /**
1334  * gtk_tree_view_column_set_spacing:
1335  * @tree_column: A #GtkTreeViewColumn.
1336  * @spacing: distance between cell renderers in pixels.
1337  * 
1338  * Sets the spacing field of @tree_column, which is the number of pixels to
1339  * place between cell renderers packed into it.
1340  **/
1341 void
1342 gtk_tree_view_column_set_spacing (GtkTreeViewColumn *tree_column,
1343                                   gint               spacing)
1344 {
1345   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1346   g_return_if_fail (spacing >= 0);
1347
1348   if (tree_column->spacing == spacing)
1349     return;
1350
1351   tree_column->spacing = spacing;
1352   if (tree_column->tree_view)
1353     {
1354       tree_column->dirty = TRUE;
1355       gtk_widget_queue_resize (tree_column->tree_view);
1356     }
1357 }
1358
1359 /**
1360  * gtk_tree_view_column_get_spacing:
1361  * @tree_column: A #GtkTreeViewColumn.
1362  * 
1363  * Returns the spacing of @tree_column.
1364  **/
1365 gint
1366 gtk_tree_view_column_get_spacing (GtkTreeViewColumn *tree_column)
1367 {
1368   g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1369
1370   return tree_column->spacing;
1371 }
1372
1373 /* Options for manipulating the columns */
1374
1375 /**
1376  * gtk_tree_view_column_set_visible:
1377  * @tree_column: A #GtkTreeViewColumn.
1378  * @visible: TRUE if the @tree_column is visible.
1379  * 
1380  * Sets the visibility of @tree_column.
1381  **/
1382 void
1383 gtk_tree_view_column_set_visible (GtkTreeViewColumn *tree_column,
1384                                   gboolean           visible)
1385 {
1386   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1387
1388   visible = !! visible;
1389   
1390   if (tree_column->visible == visible)
1391     return;
1392
1393   tree_column->visible = visible;
1394
1395   gtk_tree_view_column_update_button (tree_column);
1396   g_object_notify (G_OBJECT (tree_column), "visible");
1397 }
1398
1399 /**
1400  * gtk_tree_view_column_get_visible:
1401  * @tree_column: A #GtkTreeViewColumn.
1402  * 
1403  * Returns TRUE if @tree_column is visible.
1404  * 
1405  * Return value: whether the column is visible or not.  If it is visible, then
1406  * the tree will show the column.
1407  **/
1408 gboolean
1409 gtk_tree_view_column_get_visible (GtkTreeViewColumn *tree_column)
1410 {
1411   g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
1412
1413   return tree_column->visible;
1414 }
1415
1416 /**
1417  * gtk_tree_view_column_set_sizing:
1418  * @tree_column: A #GtkTreeViewColumn.
1419  * @type: The #GtkTreeViewColumnSizing.
1420  * 
1421  * Sets the growth behavior of @tree_column to @type.
1422  **/
1423 void
1424 gtk_tree_view_column_set_sizing (GtkTreeViewColumn       *tree_column,
1425                                  GtkTreeViewColumnSizing  type)
1426 {
1427   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1428
1429   if (type == tree_column->column_type)
1430     return;
1431
1432   if (tree_column->column_type == GTK_TREE_VIEW_COLUMN_AUTOSIZE &&
1433       tree_column->requested_width != -1)
1434     {
1435       gtk_tree_view_column_set_sizing (tree_column, tree_column->requested_width);
1436     }
1437   tree_column->column_type = type;
1438
1439   gtk_tree_view_column_update_button (tree_column);
1440
1441   if (type != GTK_TREE_VIEW_COLUMN_AUTOSIZE)
1442   g_object_notify (G_OBJECT (tree_column), "sizing");
1443 }
1444
1445 /**
1446  * gtk_tree_view_column_get_sizing:
1447  * @tree_column: A #GtkTreeViewColumn.
1448  * 
1449  * Returns the current type of @tree_column.
1450  * 
1451  * Return value: The type of @tree_column.
1452  **/
1453 GtkTreeViewColumnSizing
1454 gtk_tree_view_column_get_sizing (GtkTreeViewColumn *tree_column)
1455 {
1456   g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1457
1458   return tree_column->column_type;
1459 }
1460
1461 /**
1462  * gtk_tree_view_column_get_size:
1463  * @tree_column: A #GtkTreeViewColumn.
1464  * 
1465  * Returns the current size of the @tree_column in pixels.
1466  * 
1467  * Return value: The current size of the @tree_column.
1468  **/
1469 gint
1470 gtk_tree_view_column_get_size (GtkTreeViewColumn *tree_column)
1471 {
1472   g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1473
1474   return tree_column->width;
1475 }
1476
1477 /**
1478  * gtk_tree_view_column_set_width:
1479  * @tree_column: A #GtkTreeViewColumn.
1480  * @width: The size to set the @tree_column to.
1481  * 
1482  * Sets the size of the column in pixels, unless the the column type is
1483  * #GTK_TREE_VIEW_COLUMN_AUTOSIZE.  In this case, the value is discarded as the
1484  * size of the column is based on the calculated width of the column. The
1485  * width is clamped to the min/max width for the column.
1486  **/
1487 void
1488 gtk_tree_view_column_set_width (GtkTreeViewColumn *tree_column,
1489                                 gint               width)
1490 {
1491   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1492   g_return_if_fail (width > 0);
1493
1494   if (tree_column->column_type == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
1495     return;
1496
1497   tree_column->requested_width = width;
1498   _gtk_tree_view_column_set_width (tree_column, width);
1499 }
1500
1501 /**
1502  * gtk_tree_view_column_get_width:
1503  * @tree_column: a #GtkTreeViewColumn
1504  * 
1505  * Gets the value set by gtk_tree_view_column_set_width().
1506  * 
1507  * Return value: the width of the column
1508  **/
1509 gint
1510 gtk_tree_view_column_get_width (GtkTreeViewColumn *tree_column)
1511 {
1512   g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1513
1514   return tree_column->width;
1515 }
1516
1517 /**
1518  * gtk_tree_view_column_set_min_width:
1519  * @tree_column: A #GtkTreeViewColumn.
1520  * @min_width: The minimum width of the column in pixels, or -1.
1521  * 
1522  * Sets the minimum width of the @tree_column.  If @min_width is -1, then the
1523  * minimum width is unset.
1524  **/
1525 void
1526 gtk_tree_view_column_set_min_width (GtkTreeViewColumn *tree_column,
1527                                     gint               min_width)
1528 {
1529   gint real_min_width;
1530
1531   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1532   g_return_if_fail (min_width >= -1);
1533
1534   if (min_width == tree_column->min_width)
1535     return;
1536
1537   if (tree_column->tree_view == NULL)
1538     {
1539       tree_column->min_width = min_width;
1540       return;
1541     }
1542
1543   real_min_width = (tree_column->min_width == -1) ?
1544     tree_column->button->requisition.width : tree_column->min_width;
1545
1546   /* We want to queue a resize if the either the old min_size or the
1547    * new min_size determined the size of the column */
1548   if (GTK_WIDGET_REALIZED (tree_column->tree_view))
1549     {
1550       if ((tree_column->min_width > tree_column->width) ||
1551           (tree_column->min_width == -1 &&
1552            tree_column->button->requisition.width > tree_column->width) ||
1553           (min_width > tree_column->width) ||
1554           (min_width == -1 &&
1555            tree_column->button->requisition.width > tree_column->width))
1556         gtk_widget_queue_resize (tree_column->tree_view);
1557     }
1558
1559   if (tree_column->max_width != -1 && tree_column->max_width < real_min_width)
1560     tree_column->max_width = real_min_width;
1561
1562   tree_column->min_width = min_width;
1563
1564   g_object_notify (G_OBJECT (tree_column), "min_width");
1565 }
1566
1567 /**
1568  * gtk_tree_view_column_get_min_width:
1569  * @tree_column: A #GtkTreeViewColumn.
1570  * 
1571  * Returns the minimum width in pixels of the @tree_column, or -1 if no minimum
1572  * width is set.
1573  * 
1574  * Return value: The minimum width of the @tree_column.
1575  **/
1576 gint
1577 gtk_tree_view_column_get_min_width (GtkTreeViewColumn *tree_column)
1578 {
1579   g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), -1);
1580
1581   return tree_column->min_width;
1582 }
1583
1584 /**
1585  * gtk_tree_view_column_set_max_width:
1586  * @tree_column: A #GtkTreeViewColumn.
1587  * @max_width: The maximum width of the column in pixels, or -1.
1588  * 
1589  * Sets the maximum width of the @tree_column.  If @max_width is -1, then the
1590  * maximum width is unset.
1591  **/
1592 void
1593 gtk_tree_view_column_set_max_width (GtkTreeViewColumn *tree_column,
1594                                     gint               max_width)
1595 {
1596   gint real_max_width;
1597
1598   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1599   g_return_if_fail (max_width >= -1);
1600
1601   if (max_width == tree_column->max_width)
1602     return;
1603
1604   if (tree_column->tree_view == NULL)
1605     {
1606       tree_column->max_width = max_width;
1607       return;
1608     }
1609
1610   real_max_width = tree_column->max_width == -1 ?
1611     tree_column->button->requisition.width : tree_column->max_width;
1612
1613   if (tree_column->tree_view &&
1614       GTK_WIDGET_REALIZED (tree_column->tree_view) &&
1615       ((tree_column->max_width < tree_column->width) ||
1616        (max_width != -1 && max_width < tree_column->width)))
1617     gtk_widget_queue_resize (tree_column->tree_view);
1618
1619   tree_column->max_width = max_width;
1620
1621   if (real_max_width > max_width)
1622     tree_column->max_width = max_width;
1623
1624   g_object_notify (G_OBJECT (tree_column), "max_width");
1625 }
1626
1627 /**
1628  * gtk_tree_view_column_get_max_width:
1629  * @tree_column: A #GtkTreeViewColumn.
1630  * 
1631  * Returns the maximum width in pixels of the @tree_column, or -1 if no maximum
1632  * width is set.
1633  * 
1634  * Return value: The maximum width of the @tree_column.
1635  **/
1636 gint
1637 gtk_tree_view_column_get_max_width (GtkTreeViewColumn *tree_column)
1638 {
1639   g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), -1);
1640
1641   return tree_column->max_width;
1642 }
1643
1644 /**
1645  * gtk_tree_view_column_clicked:
1646  * @tree_column: a #GtkTreeViewColumn
1647  * 
1648  * Emits the "clicked" signal on the column.  This function will only work if
1649  * the user could have conceivably clicked on the button.
1650  **/
1651 void
1652 gtk_tree_view_column_clicked (GtkTreeViewColumn *tree_column)
1653 {
1654   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1655
1656   if (tree_column->visible &&
1657       tree_column->button &&
1658       tree_column->clickable)
1659     gtk_button_clicked (GTK_BUTTON (tree_column->button));
1660 }
1661
1662 /**
1663  * gtk_tree_view_column_set_title:
1664  * @tree_column: A #GtkTreeViewColumn.
1665  * @title: The title of the @tree_column.
1666  * 
1667  * Sets the title of the @tree_column.  If a custom widget has been set, then
1668  * this value is ignored.
1669  **/
1670 void
1671 gtk_tree_view_column_set_title (GtkTreeViewColumn *tree_column,
1672                                 const gchar       *title)
1673 {
1674   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1675
1676   g_free (tree_column->title);
1677   if (title)
1678     tree_column->title = g_strdup (title);
1679   else
1680     tree_column->title = NULL;
1681
1682   gtk_tree_view_column_update_button (tree_column);
1683   g_object_notify (G_OBJECT (tree_column), "title");
1684 }
1685
1686 /**
1687  * gtk_tree_view_column_get_title:
1688  * @tree_column: A #GtkTreeViewColumn.
1689  * 
1690  * Returns the title of the widget.  This value should not be modified.
1691  * 
1692  * Return value: the title of the column.
1693  **/
1694 G_CONST_RETURN gchar *
1695 gtk_tree_view_column_get_title (GtkTreeViewColumn *tree_column)
1696 {
1697   g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), NULL);
1698
1699   return tree_column->title;
1700 }
1701
1702 /**
1703  * gtk_tree_view_column_set_clickable:
1704  * @tree_column: A #GtkTreeViewColumn.
1705  * @clickable: TRUE if the header is active.
1706  * 
1707  * Sets the header to be active if @active is TRUE.  When the header is active,
1708  * then it can take keyboard focus, and can be clicked.
1709  **/
1710 void
1711 gtk_tree_view_column_set_clickable (GtkTreeViewColumn *tree_column,
1712                                     gboolean           clickable)
1713 {
1714   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1715
1716   if (tree_column->clickable == (clickable?TRUE:FALSE))
1717     return;
1718
1719   tree_column->clickable = (clickable?TRUE:FALSE);
1720   gtk_tree_view_column_update_button (tree_column);
1721   g_object_notify (G_OBJECT (tree_column), "clickable");
1722 }
1723
1724 /**
1725  * gtk_tree_view_column_get_clickable:
1726  * @tree_column: a #GtkTreeViewColumn
1727  * 
1728  * Returns %TRUE if the user can click on the header for the column.
1729  * 
1730  * Return value: whether the user can click the column header
1731  **/
1732 gboolean
1733 gtk_tree_view_column_get_clickable (GtkTreeViewColumn *tree_column)
1734 {
1735   g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
1736
1737   return tree_column->clickable;
1738 }
1739
1740 /**
1741  * gtk_tree_view_column_set_widget:
1742  * @tree_column: A #GtkTreeViewColumn.
1743  * @widget: A child #GtkWidget, or NULL.
1744  * 
1745  * Sets the widget in the header to be @widget.  If widget is NULL, then the
1746  * header button is set with a #GtkLabel set to the title of @tree_column.
1747  **/
1748 void
1749 gtk_tree_view_column_set_widget (GtkTreeViewColumn *tree_column,
1750                                  GtkWidget         *widget)
1751 {
1752   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1753   g_return_if_fail (widget == NULL || GTK_IS_WIDGET (widget));
1754
1755   if (widget)
1756     {
1757       gtk_object_ref (GTK_OBJECT (widget));
1758       gtk_object_sink (GTK_OBJECT (widget));
1759     }
1760
1761   if (tree_column->child)      
1762     gtk_object_unref (GTK_OBJECT (tree_column->child));
1763
1764   tree_column->child = widget;
1765   gtk_tree_view_column_update_button (tree_column);
1766   g_object_notify (G_OBJECT (tree_column), "widget");
1767 }
1768
1769 /**
1770  * gtk_tree_view_column_get_widget:
1771  * @tree_column: A #GtkTreeViewColumn.
1772  * 
1773  * Returns the #GtkWidget in the button in the column header.  If a custom
1774  * widget has not been set, then this will be a #GtkAlignment with a #GtkLabel
1775  * in it.
1776  * 
1777  * Return value: The #GtkWidget in the column header.
1778  **/
1779 GtkWidget *
1780 gtk_tree_view_column_get_widget (GtkTreeViewColumn *tree_column)
1781 {
1782   g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), NULL);
1783
1784   return tree_column->child;
1785 }
1786
1787 /**
1788  * gtk_tree_view_column_set_alignment:
1789  * @tree_column: A #GtkTreeViewColumn.
1790  * @xalign: alignment (0.0 for left, 0.5 for center, 1.0 for right)
1791  * 
1792  * Sets the alignment of the title or custom widget inside the column header.
1793  **/
1794 void
1795 gtk_tree_view_column_set_alignment (GtkTreeViewColumn *tree_column,
1796                                     gfloat             xalign)
1797 {
1798   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1799
1800   if (tree_column->xalign == xalign)
1801     return;
1802
1803   tree_column->xalign = xalign;
1804   gtk_tree_view_column_update_button (tree_column);
1805   g_object_notify (G_OBJECT (tree_column), "alignment");
1806 }
1807
1808 /**
1809  * gtk_tree_view_column_get_alignment:
1810  * @tree_column: A #GtkTreeViewColumn.
1811  * 
1812  * Returns the current x alignment of @tree_column.  This value can range
1813  * between 0.0 and 1.0.
1814  * 
1815  * Return value: The current alignent of @tree_column.
1816  **/
1817 gfloat
1818 gtk_tree_view_column_get_alignment (GtkTreeViewColumn *tree_column)
1819 {
1820   g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0.5);
1821
1822   return tree_column->xalign;
1823 }
1824
1825 void
1826 gtk_tree_view_column_set_reorderable (GtkTreeViewColumn *tree_column,
1827                                       gboolean           reorderable)
1828 {
1829   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1830
1831   /*  if (reorderable)
1832       gtk_tree_view_column_set_clickable (tree_column, TRUE);*/
1833
1834   if (tree_column->reorderable == (reorderable?TRUE:FALSE))
1835     return;
1836
1837   tree_column->reorderable = (reorderable?TRUE:FALSE);
1838   gtk_tree_view_column_update_button (tree_column);
1839   g_object_notify (G_OBJECT (tree_column), "reorderable");
1840 }
1841
1842 gboolean
1843 gtk_tree_view_column_get_reorderable (GtkTreeViewColumn *tree_column)
1844 {
1845   g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
1846
1847   return tree_column->reorderable;
1848 }
1849
1850
1851 /**
1852  * gtk_tree_view_column_set_sort_column_id:
1853  * @tree_column: a #GtkTreeViewColumn
1854  * @sort_column_id: The sort_column_id of the model to sort on.
1855  * 
1856  * Sets the logical sort_column_id that this column sorts on when this column is
1857  * selected for sorting.  Doing so makes the column header clickable.
1858  **/
1859 void
1860 gtk_tree_view_column_set_sort_column_id (GtkTreeViewColumn *tree_column,
1861                                          gint               sort_column_id)
1862 {
1863   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1864   g_return_if_fail (sort_column_id >= 0);
1865
1866   if (tree_column->sort_column_id == sort_column_id)
1867     return;
1868
1869   tree_column->sort_column_id = sort_column_id;
1870
1871   /* Handle unsetting the id */
1872   if (sort_column_id == -1)
1873     {
1874       if (tree_column->sort_clicked_signal)
1875         {
1876           g_signal_handler_disconnect (G_OBJECT (tree_column), tree_column->sort_clicked_signal);
1877           tree_column->sort_clicked_signal = 0;
1878         }
1879
1880       if (tree_column->sort_column_changed_signal)
1881         {
1882           g_signal_handler_disconnect (G_OBJECT (tree_column), tree_column->sort_column_changed_signal);
1883           tree_column->sort_column_changed_signal = 0;
1884         }
1885
1886       gtk_tree_view_column_set_sort_order (tree_column, GTK_SORT_ASCENDING);
1887       gtk_tree_view_column_set_sort_indicator (tree_column, FALSE);
1888       return;
1889     }
1890
1891   gtk_tree_view_column_set_clickable (tree_column, TRUE);
1892
1893   if (! tree_column->sort_clicked_signal)
1894     tree_column->sort_clicked_signal = g_signal_connect (G_OBJECT (tree_column),
1895                                                          "clicked",
1896                                                          G_CALLBACK (gtk_tree_view_column_sort),
1897                                                          NULL);
1898
1899   gtk_tree_view_column_setup_sort_column_id_callback (tree_column);
1900 }
1901
1902 /**
1903  * gtk_tree_view_column_get_sort_column_id:
1904  * @tree_column: a #GtkTreeViewColumn
1905  *
1906  * Gets the logical sort_column_id that the model sorts on when this
1907  * coumn is selected for sorting. See gtk_tree_view_column_set_sort_column_id().
1908  *
1909  * Return value: the current sort_column_id for this column, or -1 if
1910  *               this column can't be used for sorting.
1911  **/
1912 gint
1913 gtk_tree_view_column_get_sort_column_id (GtkTreeViewColumn *tree_column)
1914 {
1915   g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
1916
1917   return tree_column->sort_column_id;
1918 }
1919
1920 /**
1921  * gtk_tree_view_column_set_sort_indicator:
1922  * @tree_column: a #GtkTreeViewColumn
1923  * @setting: %TRUE to display an indicator that the column is sorted
1924  *
1925  * Call this function with a @setting of %TRUE to display an arrow in
1926  * the header button indicating the column is sorted. Call
1927  * gtk_tree_view_column_set_sort_order() to change the direction of
1928  * the arrow.
1929  * 
1930  **/
1931 void
1932 gtk_tree_view_column_set_sort_indicator (GtkTreeViewColumn     *tree_column,
1933                                          gboolean               setting)
1934 {
1935   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1936
1937   setting = setting != FALSE;
1938
1939   if (setting == tree_column->show_sort_indicator)
1940     return;
1941
1942   tree_column->show_sort_indicator = setting;
1943   gtk_tree_view_column_update_button (tree_column);
1944   g_object_notify (G_OBJECT (tree_column), "sort_indicator");
1945 }
1946
1947 /**
1948  * gtk_tree_view_column_get_sort_indicator:
1949  * @tree_column: a #GtkTreeViewColumn
1950  * 
1951  * Gets the value set by gtk_tree_view_column_set_sort_indicator().
1952  * 
1953  * Return value: whether the sort indicator arrow is displayed
1954  **/
1955 gboolean
1956 gtk_tree_view_column_get_sort_indicator  (GtkTreeViewColumn     *tree_column)
1957 {
1958   g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
1959
1960   return tree_column->show_sort_indicator;
1961 }
1962
1963 /**
1964  * gtk_tree_view_column_set_sort_order:
1965  * @tree_column: a #GtkTreeViewColumn
1966  * @order: sort order that the sort indicator should indicate
1967  *
1968  * Changes the appearance of the sort indicator. (This <emphasis>does
1969  * not</emphasis> actually sort the model.  Use
1970  * gtk_tree_view_column_set_sort_column_id() if you want automatic sorting
1971  * support.  This function is primarily for custom sorting behavior, and should
1972  * be used in conjunction with #gtk_tree_sortable_set_sort_column() to do
1973  * that. For custom models, the mechanism will vary. The sort indicator changes
1974  * direction to indicate normal sort or reverse sort. Note that you must have
1975  * the sort indicator enabled to see anything when calling this function; see
1976  * gtk_tree_view_column_set_sort_indicator().
1977  * 
1978  **/
1979 void
1980 gtk_tree_view_column_set_sort_order      (GtkTreeViewColumn     *tree_column,
1981                                           GtkSortType            order)
1982 {
1983   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
1984
1985   if (order == tree_column->sort_order)
1986     return;
1987
1988   tree_column->sort_order = order;
1989   gtk_tree_view_column_update_button (tree_column);
1990   g_object_notify (G_OBJECT (tree_column), "sort_order");
1991 }
1992
1993 /**
1994  * gtk_tree_view_column_get_sort_order:
1995  * @tree_column: a #GtkTreeViewColumn
1996  * 
1997  * Gets the value set by gtk_tree_view_column_set_sort_order().
1998  * 
1999  * Return value: the sort order the sort indicator is indicating
2000  **/
2001 GtkSortType
2002 gtk_tree_view_column_get_sort_order      (GtkTreeViewColumn     *tree_column)
2003 {
2004   g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), 0);
2005
2006   return tree_column->sort_order;
2007 }
2008
2009 /**
2010  * gtk_tree_view_column_cell_set_cell_data:
2011  * @tree_column: A #GtkTreeViewColumn.
2012  * @tree_model: The #GtkTreeModel to to get the cell renderers attributes from.
2013  * @iter: The #GtkTreeIter to to get the cell renderer's attributes from.
2014  * @is_expander: TRUE, if the row has children
2015  * @is_expanded: TRUE, if the row has visible children
2016  * 
2017  * Sets the cell renderer based on the @tree_model and @tree_node.  That is, for
2018  * every attribute mapping in @tree_column, it will get a value from the set
2019  * column on the @tree_node, and use that value to set the attribute on the cell
2020  * renderer.  This is used primarily by the GtkTreeView.
2021  **/
2022 void
2023 gtk_tree_view_column_cell_set_cell_data (GtkTreeViewColumn *tree_column,
2024                                          GtkTreeModel      *tree_model,
2025                                          GtkTreeIter       *iter,
2026                                          gboolean           is_expander,
2027                                          gboolean           is_expanded)
2028 {
2029   GSList *list;
2030   GValue value = { 0, };
2031   GList *cell_list;
2032
2033   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2034   g_return_if_fail (tree_column->cell_list != NULL);
2035
2036   if (tree_model == NULL)
2037     return;
2038
2039   for (cell_list = tree_column->cell_list; cell_list; cell_list = cell_list->next)
2040     {
2041       GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) cell_list->data;
2042       GObject *cell = (GObject *) info->cell;
2043
2044       list = info->attributes;
2045
2046       g_object_freeze_notify (cell);
2047       g_object_set (cell, "is_expander", is_expander, "is_expanded", is_expanded, NULL);
2048
2049       while (list && list->next)
2050         {
2051           gtk_tree_model_get_value (tree_model, iter,
2052                                     GPOINTER_TO_INT (list->next->data),
2053                                     &value);
2054           g_object_set_property (cell, (gchar *) list->data, &value);
2055           g_value_unset (&value);
2056           list = list->next->next;
2057         }
2058
2059       if (info->func)
2060         (* info->func) (tree_column, info->cell, tree_model, iter, info->func_data);
2061       g_object_thaw_notify (G_OBJECT (info->cell));
2062     }
2063
2064 }
2065
2066 /**
2067  * gtk_tree_view_column_cell_get_size:
2068  * @tree_column: A #GtkTreeViewColumn.
2069  * @cell_area: The area a the column will be allocated, or %NULL
2070  * @x_offset: location to return x offset of cell relative to @cell_area, or %NULL
2071  * @y_offset: location to return y offset of cell relative to @cell_area, or %NULL
2072  * @width: location to return width needed to render a cell, or %NULL
2073  * @height: location to return height needed to render a cell, or %NULL
2074  * 
2075  * Obtains the width and height needed to render the column.  This is used
2076  * primarily by the GtkTreeView.
2077  **/
2078 void
2079 gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
2080                                     GdkRectangle      *cell_area,
2081                                     gint              *x_offset,
2082                                     gint              *y_offset,
2083                                     gint              *width,
2084                                     gint              *height)
2085 {
2086   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2087
2088   gtk_cell_renderer_get_size (((GtkTreeViewColumnCellInfo *) tree_column->cell_list->data)->cell,
2089                               tree_column->tree_view,
2090                               cell_area,
2091                               x_offset,
2092                               y_offset,
2093                               width,
2094                               height);
2095
2096 }
2097
2098 /**
2099  * gtk_tree_view_column_cell_render:
2100  * @tree_column: A #GtkTreeViewColumn.
2101  * @window: a #GdkDrawable to draw to
2102  * @background_area: entire cell area (including tree expanders and maybe padding on the sides)
2103  * @cell_area: area normally rendered by a cell renderer
2104  * @expose_area: area that actually needs updating
2105  * @flags: flags that affect rendering
2106  * 
2107  * Renders the cell contained by #tree_column. This is used primarily by the
2108  * GtkTreeView.
2109  **/
2110 void
2111 gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
2112                                   GdkWindow         *window,
2113                                   GdkRectangle      *background_area,
2114                                   GdkRectangle      *cell_area,
2115                                   GdkRectangle      *expose_area,
2116                                   guint              flags)
2117 {
2118   gboolean visible;
2119   g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
2120
2121   g_object_get (G_OBJECT ((((GtkTreeViewColumnCellInfo *) tree_column->cell_list->data)->cell)), "visible", &visible, NULL);
2122   if (visible)
2123   gtk_cell_renderer_render (((GtkTreeViewColumnCellInfo *) tree_column->cell_list->data)->cell,
2124                             window,
2125                             tree_column->tree_view,
2126                             background_area,
2127                             cell_area,
2128                             expose_area,
2129                             flags);
2130 }
2131
2132 /**
2133  * gtk_tree_view_column_cell_event:
2134  * @tree_column: A #GtkTreeViewColumn.
2135  * @event: a #GdkEvent
2136  * @path_string: widget-dependent string representation of the event location; e.g. for #GtkTreeView, a string representation of #GtkTreePath
2137  * @background_area: background area as passed to gtk_cell_renderer_render()
2138  * @cell_area: cell area as passed to gtk_cell_renderer_render()
2139  * @flags: render flags
2140  * 
2141  * Handles an event.  This is used primarily by the GtkTreeView.
2142  * 
2143  * Return value: %TRUE if the event was consumed/handled
2144  **/
2145 gboolean
2146 gtk_tree_view_column_cell_event (GtkTreeViewColumn *tree_column,
2147                                  GdkEvent          *event,
2148                                  gchar             *path_string,
2149                                  GdkRectangle      *background_area,
2150                                  GdkRectangle      *cell_area,
2151                                  guint              flags)
2152 {
2153   gboolean visible, can_activate;
2154
2155   g_return_val_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column), FALSE);
2156
2157   g_object_get (G_OBJECT (((GtkTreeViewColumnCellInfo *) tree_column->cell_list->data)->cell),
2158                 "visible", &visible,
2159                 "can_activate", &can_activate,
2160                 NULL);
2161   if (visible && can_activate)
2162     {
2163       if (gtk_cell_renderer_event (((GtkTreeViewColumnCellInfo *) tree_column->cell_list->data)->cell,
2164                                    event,
2165                                    tree_column->tree_view,
2166                                    path_string,
2167                                    background_area,
2168                                    cell_area,
2169                                    flags))
2170         return TRUE;
2171
2172     }
2173   return FALSE;
2174 }
2175
2176 gboolean
2177 gtk_tree_view_column_cell_can_focus (GtkTreeViewColumn *tree_column)
2178 {
2179   GList *list;
2180   gboolean visible;
2181   gboolean can_activate;
2182
2183   for (list = tree_column->cell_list; list; list = list->next)
2184     {
2185       GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
2186       g_object_get (G_OBJECT (info->cell),
2187                     "can_activate", &can_activate,
2188                     "visible", &visible,
2189                     NULL);
2190       if (can_activate && visible)
2191         return TRUE;
2192     }
2193
2194   return FALSE;
2195 }
2196
2197
2198 gboolean
2199 gtk_tree_view_column_cell_is_visible (GtkTreeViewColumn *tree_column)
2200 {
2201   GList *list;
2202   gboolean visible;
2203
2204   for (list = tree_column->cell_list; list; list = list->next)
2205     {
2206       GtkTreeViewColumnCellInfo *info = (GtkTreeViewColumnCellInfo *) list->data;
2207       g_object_get (G_OBJECT (info->cell),
2208                     "visible", &visible,
2209                     NULL);
2210       if (visible)
2211         return TRUE;
2212     }
2213
2214   return FALSE;
2215 }