1 /* gtktreesortable.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, see <http://www.gnu.org/licenses/>.
16  */
17 
18 
19 #include "config.h"
20 #include "gtktreesortable.h"
21 #include "gtkmarshalers.h"
22 #include "gtkintl.h"
23 
24 
25 /**
26  * SECTION:gtktreesortable
27  * @Short_description: The interface for sortable models used by GtkTreeView
28  * @Title: GtkTreeSortable
29  * @See_also:#GtkTreeModel, #GtkTreeView
30  *
31  * #GtkTreeSortable is an interface to be implemented by tree models which
32  * support sorting. The #GtkTreeView uses the methods provided by this interface
33  * to sort the model.
34  */
35 
36 
37 static void gtk_tree_sortable_base_init (gpointer g_class);
38 
39 GType
gtk_tree_sortable_get_type(void)40 gtk_tree_sortable_get_type (void)
41 {
42   static GType tree_sortable_type = 0;
43 
44   if (! tree_sortable_type)
45     {
46       const GTypeInfo tree_sortable_info =
47       {
48 	sizeof (GtkTreeSortableIface), /* class_size */
49 	gtk_tree_sortable_base_init,   /* base_init */
50 	NULL,		/* base_finalize */
51 	NULL,
52 	NULL,		/* class_finalize */
53 	NULL,		/* class_data */
54 	0,
55 	0,
56 	NULL
57       };
58 
59       tree_sortable_type =
60 	g_type_register_static (G_TYPE_INTERFACE, I_("GtkTreeSortable"),
61 				&tree_sortable_info, 0);
62 
63       g_type_interface_add_prerequisite (tree_sortable_type, GTK_TYPE_TREE_MODEL);
64     }
65 
66   return tree_sortable_type;
67 }
68 
69 static void
gtk_tree_sortable_base_init(gpointer g_class)70 gtk_tree_sortable_base_init (gpointer g_class)
71 {
72   static gboolean initialized = FALSE;
73 
74   if (! initialized)
75     {
76       /**
77        * GtkTreeSortable::sort-column-changed:
78        * @sortable: the object on which the signal is emitted
79        *
80        * The ::sort-column-changed signal is emitted when the sort column
81        * or sort order of @sortable is changed. The signal is emitted before
82        * the contents of @sortable are resorted.
83        */
84       g_signal_new (I_("sort-column-changed"),
85                     GTK_TYPE_TREE_SORTABLE,
86                     G_SIGNAL_RUN_LAST,
87                     G_STRUCT_OFFSET (GtkTreeSortableIface, sort_column_changed),
88                     NULL, NULL,
89                     NULL,
90                     G_TYPE_NONE, 0);
91       initialized = TRUE;
92     }
93 }
94 
95 /**
96  * gtk_tree_sortable_sort_column_changed:
97  * @sortable: A #GtkTreeSortable
98  *
99  * Emits a #GtkTreeSortable::sort-column-changed signal on @sortable.
100  */
101 void
gtk_tree_sortable_sort_column_changed(GtkTreeSortable * sortable)102 gtk_tree_sortable_sort_column_changed (GtkTreeSortable *sortable)
103 {
104   g_return_if_fail (GTK_IS_TREE_SORTABLE (sortable));
105 
106   g_signal_emit_by_name (sortable, "sort-column-changed");
107 }
108 
109 /**
110  * gtk_tree_sortable_get_sort_column_id:
111  * @sortable: A #GtkTreeSortable
112  * @sort_column_id: (out): The sort column id to be filled in
113  * @order: (out): The #GtkSortType to be filled in
114  *
115  * Fills in @sort_column_id and @order with the current sort column and the
116  * order. It returns %TRUE unless the @sort_column_id is
117  * %GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID or
118  * %GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID.
119  *
120  * Returns: %TRUE if the sort column is not one of the special sort
121  *   column ids.
122  **/
123 gboolean
gtk_tree_sortable_get_sort_column_id(GtkTreeSortable * sortable,gint * sort_column_id,GtkSortType * order)124 gtk_tree_sortable_get_sort_column_id (GtkTreeSortable  *sortable,
125 				      gint             *sort_column_id,
126 				      GtkSortType      *order)
127 {
128   GtkTreeSortableIface *iface;
129 
130   g_return_val_if_fail (GTK_IS_TREE_SORTABLE (sortable), FALSE);
131 
132   iface = GTK_TREE_SORTABLE_GET_IFACE (sortable);
133 
134   g_return_val_if_fail (iface != NULL, FALSE);
135   g_return_val_if_fail (iface->get_sort_column_id != NULL, FALSE);
136 
137   return (* iface->get_sort_column_id) (sortable, sort_column_id, order);
138 }
139 
140 /**
141  * gtk_tree_sortable_set_sort_column_id:
142  * @sortable: A #GtkTreeSortable
143  * @sort_column_id: the sort column id to set
144  * @order: The sort order of the column
145  *
146  * Sets the current sort column to be @sort_column_id. The @sortable will
147  * resort itself to reflect this change, after emitting a
148  * #GtkTreeSortable::sort-column-changed signal. @sort_column_id may either be
149  * a regular column id, or one of the following special values:
150  *
151  * - %GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID: the default sort function
152  *   will be used, if it is set
153  *
154  * - %GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID: no sorting will occur
155  */
156 void
gtk_tree_sortable_set_sort_column_id(GtkTreeSortable * sortable,gint sort_column_id,GtkSortType order)157 gtk_tree_sortable_set_sort_column_id (GtkTreeSortable  *sortable,
158 				      gint              sort_column_id,
159 				      GtkSortType       order)
160 {
161   GtkTreeSortableIface *iface;
162 
163   g_return_if_fail (GTK_IS_TREE_SORTABLE (sortable));
164 
165   iface = GTK_TREE_SORTABLE_GET_IFACE (sortable);
166 
167   g_return_if_fail (iface != NULL);
168   g_return_if_fail (iface->set_sort_column_id != NULL);
169 
170   (* iface->set_sort_column_id) (sortable, sort_column_id, order);
171 }
172 
173 /**
174  * gtk_tree_sortable_set_sort_func:
175  * @sortable: A #GtkTreeSortable
176  * @sort_column_id: the sort column id to set the function for
177  * @sort_func: The comparison function
178  * @user_data: (allow-none): User data to pass to @sort_func, or %NULL
179  * @destroy: (allow-none): Destroy notifier of @user_data, or %NULL
180  *
181  * Sets the comparison function used when sorting to be @sort_func. If the
182  * current sort column id of @sortable is the same as @sort_column_id, then
183  * the model will sort using this function.
184  */
185 void
gtk_tree_sortable_set_sort_func(GtkTreeSortable * sortable,gint sort_column_id,GtkTreeIterCompareFunc sort_func,gpointer user_data,GDestroyNotify destroy)186 gtk_tree_sortable_set_sort_func (GtkTreeSortable        *sortable,
187 				 gint                    sort_column_id,
188 				 GtkTreeIterCompareFunc  sort_func,
189 				 gpointer                user_data,
190 				 GDestroyNotify          destroy)
191 {
192   GtkTreeSortableIface *iface;
193 
194   g_return_if_fail (GTK_IS_TREE_SORTABLE (sortable));
195   g_return_if_fail (sort_func != NULL);
196 
197   iface = GTK_TREE_SORTABLE_GET_IFACE (sortable);
198 
199   g_return_if_fail (iface != NULL);
200   g_return_if_fail (iface->set_sort_func != NULL);
201   g_return_if_fail (sort_column_id >= 0);
202 
203   (* iface->set_sort_func) (sortable, sort_column_id, sort_func, user_data, destroy);
204 }
205 
206 /**
207  * gtk_tree_sortable_set_default_sort_func:
208  * @sortable: A #GtkTreeSortable
209  * @sort_func: The comparison function
210  * @user_data: (allow-none): User data to pass to @sort_func, or %NULL
211  * @destroy: (allow-none): Destroy notifier of @user_data, or %NULL
212  *
213  * Sets the default comparison function used when sorting to be @sort_func.
214  * If the current sort column id of @sortable is
215  * %GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, then the model will sort using
216  * this function.
217  *
218  * If @sort_func is %NULL, then there will be no default comparison function.
219  * This means that once the model  has been sorted, it can’t go back to the
220  * default state. In this case, when the current sort column id of @sortable
221  * is %GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, the model will be unsorted.
222  */
223 void
gtk_tree_sortable_set_default_sort_func(GtkTreeSortable * sortable,GtkTreeIterCompareFunc sort_func,gpointer user_data,GDestroyNotify destroy)224 gtk_tree_sortable_set_default_sort_func (GtkTreeSortable        *sortable,
225 					 GtkTreeIterCompareFunc  sort_func,
226 					 gpointer                user_data,
227 					 GDestroyNotify          destroy)
228 {
229   GtkTreeSortableIface *iface;
230 
231   g_return_if_fail (GTK_IS_TREE_SORTABLE (sortable));
232 
233   iface = GTK_TREE_SORTABLE_GET_IFACE (sortable);
234 
235   g_return_if_fail (iface != NULL);
236   g_return_if_fail (iface->set_default_sort_func != NULL);
237 
238   (* iface->set_default_sort_func) (sortable, sort_func, user_data, destroy);
239 }
240 
241 /**
242  * gtk_tree_sortable_has_default_sort_func:
243  * @sortable: A #GtkTreeSortable
244  *
245  * Returns %TRUE if the model has a default sort function. This is used
246  * primarily by GtkTreeViewColumns in order to determine if a model can
247  * go back to the default state, or not.
248  *
249  * Returns: %TRUE, if the model has a default sort function
250  */
251 gboolean
gtk_tree_sortable_has_default_sort_func(GtkTreeSortable * sortable)252 gtk_tree_sortable_has_default_sort_func (GtkTreeSortable *sortable)
253 {
254   GtkTreeSortableIface *iface;
255 
256   g_return_val_if_fail (GTK_IS_TREE_SORTABLE (sortable), FALSE);
257 
258   iface = GTK_TREE_SORTABLE_GET_IFACE (sortable);
259 
260   g_return_val_if_fail (iface != NULL, FALSE);
261   g_return_val_if_fail (iface->has_default_sort_func != NULL, FALSE);
262 
263   return (* iface->has_default_sort_func) (sortable);
264 }
265