2006-08-30 Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
[hildon] / hildon-widgets / hildon-sort-dialog.c
1 /*
2  * This file is part of hildon-libs
3  *
4  * Copyright (C) 2005, 2006 Nokia Corporation.
5  *
6  * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; version 2.1 of
11  * the License.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  *
23  */
24
25 /** 
26  * SECTION:hildon-sort-dialog
27  * @short_description: A widget for defining the sorting order of items
28  * 
29  * HildonSortDialog is used to define an order (ascending/descending)
30  * and a field by which items are sorted in a list. The combo boxes
31  * display the current value when the dialog is opened.
32  */
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 #include <stdio.h>
39 #include <libintl.h>
40 #include <gtk/gtkcombobox.h>
41 #include <gtk/gtkbox.h>
42 #include <hildon-widgets/hildon-caption.h>
43 #include "hildon-sort-dialog.h"
44
45
46 #define _(String) dgettext(PACKAGE, String)
47
48 static GtkDialogClass *parent_class;
49
50 #define HILDON_SORT_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE \
51                 ((obj), HILDON_TYPE_SORT_DIALOG, HildonSortDialogPrivate));
52
53 typedef struct _HildonSortDialogPrivate HildonSortDialogPrivate;
54
55 static void hildon_sort_dialog_class_init(HildonSortDialogClass * class);
56 static void hildon_sort_dialog_init(HildonSortDialog * widget);
57 static void hildon_sort_dialog_set_property(GObject * object,
58                                      guint prop_id,
59                                      const GValue * value,
60                                      GParamSpec * pspec);
61 static void hildon_sort_dialog_get_property(GObject * object,
62                                      guint prop_id,
63                                      GValue * value, GParamSpec * pspec);
64
65 enum {
66     PROP_0,
67     PROP_SORT_KEY,
68     PROP_SORT_ORDER
69 };
70
71 /* private data */
72 struct _HildonSortDialogPrivate {
73     /* Sort category widgets */
74     GtkWidget *combo_key;
75     GtkWidget *caption_key;
76
77     /* Sort order widgets */
78     GtkWidget *combo_order;
79     GtkWidget *caption_order;
80
81     /* Index value counter */
82     gint index_counter;
83 };
84
85 /* Private functions */
86
87 /*
88  * Initialises the sort dialog class.
89  */
90 static void hildon_sort_dialog_class_init(HildonSortDialogClass * class)
91 {
92     GObjectClass *gobject_class = G_OBJECT_CLASS(class);
93     parent_class = g_type_class_peek_parent(class);
94     g_type_class_add_private(class, sizeof(HildonSortDialogPrivate));
95     
96     gobject_class->set_property = hildon_sort_dialog_set_property;
97     gobject_class->get_property = hildon_sort_dialog_get_property;
98     
99     g_object_class_install_property(gobject_class, PROP_SORT_KEY,
100         g_param_spec_int("sort-key",
101                          "Sort Key",
102                          "The currently active sort key",
103                          G_MININT,
104                          G_MAXINT,
105                          0, G_PARAM_READWRITE));
106     
107     g_object_class_install_property(gobject_class, PROP_SORT_ORDER,
108         g_param_spec_enum("sort-order",
109                          "Sort Order",
110                          "The current sorting order",
111                          GTK_TYPE_SORT_TYPE,
112                          GTK_SORT_ASCENDING,
113                          G_PARAM_READWRITE));
114 }
115
116 static void hildon_sort_dialog_init(HildonSortDialog * dialog)
117 {
118     HildonSortDialogPrivate *priv;
119     GtkSizeGroup *group;
120
121     g_assert(HILDON_IS_SORT_DIALOG(dialog));
122
123     priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
124
125     priv->index_counter = 0;
126
127     group = GTK_SIZE_GROUP(gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL));
128
129     gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
130     gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
131     gtk_window_set_title(GTK_WINDOW(dialog), _("ckdg_ti_sort"));
132
133     /* Tab one */
134     priv->combo_key = gtk_combo_box_new_text();
135     priv->caption_key = hildon_caption_new(group, _("ckdg_fi_sort_field"), priv->combo_key,
136                                         NULL, HILDON_CAPTION_OPTIONAL);
137     hildon_caption_set_separator(HILDON_CAPTION(priv->caption_key), "");
138     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
139                        priv->caption_key, FALSE, FALSE, 0);
140
141     /* Tab two */
142     priv->combo_order = gtk_combo_box_new_text();
143     gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order),
144                               _("ckdg_va_sort_ascending"));
145     gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order),
146                               _("ckdg_va_sort_descending"));
147
148     priv->caption_order = hildon_caption_new(group, _("ckdg_fi_sort_order"),
149                                         priv->combo_order,
150                                         NULL, HILDON_CAPTION_OPTIONAL);
151     hildon_caption_set_separator(HILDON_CAPTION(priv->caption_order), "");
152     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
153                        priv->caption_order, FALSE, FALSE, 0);
154
155     gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combo_key), 0);
156     gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combo_order), 0);
157
158     /* Create the OK/CANCEL buttons */
159     (void) gtk_dialog_add_button(GTK_DIALOG(dialog),
160                                            _("ckdg_bd_sort_dialog_ok"),
161                                            GTK_RESPONSE_OK);
162     (void) gtk_dialog_add_button(GTK_DIALOG(dialog),
163                                                _("ckdg_bd_sort_dialog_cancel"),
164                                                GTK_RESPONSE_CANCEL);
165     /* FIXME: Hardcoded sizes are bad */
166     gtk_window_resize(GTK_WINDOW(dialog), 370, 100);
167     gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
168
169     g_object_unref(group); /* Captions now own their references to sizegroup */
170 }
171
172 /* Public functions */
173
174 /**
175  * hildon_sort_dialog_get_type:
176  *
177  * Returns GType for HildonSortDialog as produced by 
178  * g_type_register_static().
179  *
180  * Returns: HildonSortDialog type
181  */
182 GType hildon_sort_dialog_get_type()
183 {
184     static GType dialog_type = 0;
185
186     if (!dialog_type) {
187         static const GTypeInfo dialog_info = {
188             sizeof(HildonSortDialogClass),
189             NULL,       /* base_init */
190             NULL,       /* base_finalize */
191             (GClassInitFunc) hildon_sort_dialog_class_init,
192             NULL,       /* class_finalize */
193             NULL,       /* class_data */
194             sizeof(HildonSortDialog),
195             0,  /* n_preallocs */
196             (GInstanceInitFunc) hildon_sort_dialog_init
197         };
198
199         dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
200                                              "HildonSortDialog",
201                                              &dialog_info, 0);
202     }
203     return dialog_type;
204 }
205
206 /**
207  * hildon_sort_dialog_new:
208  * @parent: widget to be transient for, or NULL if none
209  *
210  * HildonSortDialog contains two HildonCaptions with combo boxes. 
211  *
212  * Returns: pointer to a new @HildonSortDialog widget
213  */
214 GtkWidget *hildon_sort_dialog_new(GtkWindow * parent)
215 {
216     GtkWidget *sort_dialog = g_object_new(HILDON_TYPE_SORT_DIALOG, NULL);
217
218     if (parent)
219         gtk_window_set_transient_for(GTK_WINDOW(sort_dialog), parent);
220
221     return sort_dialog;
222 }
223
224 /**
225  * hildon_sort_dialog_get_sort_key:
226  * @dialog: the #HildonSortDialog widget
227  *
228  * Gets index to currently active sort key.
229  * 
230  * Returns: an integer which is the index value of the "Sort by" 
231  * field 
232  */
233 gint hildon_sort_dialog_get_sort_key(HildonSortDialog * dialog)
234 {
235     GtkWidget *combo_key;
236     HildonSortDialogPrivate *priv;
237
238     g_return_val_if_fail(HILDON_IS_SORT_DIALOG(dialog), -1);
239
240     priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
241     
242     combo_key = gtk_bin_get_child(GTK_BIN(priv->caption_key));
243         
244     return gtk_combo_box_get_active(GTK_COMBO_BOX(combo_key));
245 }
246
247 /**
248  * hildon_sort_dialog_get_sort_order:
249  * @dialog: the #HildonSortDialog widget
250  *
251  * Gets current sorting order from "Sort order" field.
252  *
253  * Returns: current sorting order as #GtkSortType
254  */
255 GtkSortType hildon_sort_dialog_get_sort_order(HildonSortDialog * dialog)
256 {
257     GtkWidget *combo_order;
258     HildonSortDialogPrivate *priv;
259
260     g_return_val_if_fail(HILDON_IS_SORT_DIALOG(dialog), 0);
261
262     priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
263     combo_order = gtk_bin_get_child(GTK_BIN(priv->caption_order));
264         
265     return gtk_combo_box_get_active(GTK_COMBO_BOX(combo_order));
266 }
267
268 /**
269  * hildon_sort_dialog_set_sort_key:
270  * @dialog: the #HildonSortDialog widget
271  * @key: combo box's index value
272  *
273  * Sets the index value of the #HildonSortDialog widget.
274  */
275 void hildon_sort_dialog_set_sort_key(HildonSortDialog * dialog, gint key)
276 {
277     GtkWidget *combo_key;
278     HildonSortDialogPrivate *priv;
279
280     g_return_if_fail(HILDON_IS_SORT_DIALOG(dialog));
281
282     priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
283     combo_key = gtk_bin_get_child(GTK_BIN(priv->caption_key));
284     gtk_combo_box_set_active(GTK_COMBO_BOX(combo_key), key);
285
286     g_object_notify (G_OBJECT (dialog), "sort-key");
287 }
288
289 /**
290  * hildon_sort_dialog_set_sort_order:
291  * @dialog: the #HildonSortDialog widget
292  * @order: combo box's index value
293  *
294  * Sets the index value of the #HildonSortDialog widget.
295  */
296 void
297 hildon_sort_dialog_set_sort_order(HildonSortDialog * dialog,
298                                   GtkSortType order)
299 {
300     GtkWidget *combo_order;
301     HildonSortDialogPrivate *priv;
302
303     g_return_if_fail(HILDON_IS_SORT_DIALOG(dialog));
304
305     priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
306     combo_order = gtk_bin_get_child(GTK_BIN(priv->caption_order));
307     gtk_combo_box_set_active(GTK_COMBO_BOX(combo_order), order);
308
309     g_object_notify (G_OBJECT (dialog), "sort-order");
310 }
311
312 /**
313  * hildon_sort_dialog_add_sort_key:
314  * @dialog: the #HildonSortDialog widget
315  * @sort_key: combo box's index value
316  *
317  * Adds a new sort key and returns the respective index in
318  * sort key combobox.
319  *
320  * Returns: an integer which is the index of the added combo box's
321  * item
322  */
323 gint
324 hildon_sort_dialog_add_sort_key(HildonSortDialog * dialog,
325                                 const gchar * sort_key)
326 {
327     HildonSortDialogPrivate *priv;
328
329     g_return_val_if_fail(HILDON_IS_SORT_DIALOG(dialog), -1);
330
331     priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
332     gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_key), sort_key);
333
334     return priv->index_counter++;
335 }
336
337 static void
338 hildon_sort_dialog_set_property(GObject * object,
339                          guint prop_id,
340                          const GValue * value, GParamSpec * pspec)
341 {
342     HildonSortDialog *dialog;
343
344     dialog = HILDON_SORT_DIALOG(object);
345
346     switch (prop_id) {
347     case PROP_SORT_KEY:
348         hildon_sort_dialog_set_sort_key(dialog, g_value_get_int(value));
349         break;
350     case PROP_SORT_ORDER:
351         hildon_sort_dialog_set_sort_order(dialog, g_value_get_enum(value));
352         break;
353     default:
354         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
355         break;
356     }
357 }
358
359 static void
360 hildon_sort_dialog_get_property(GObject * object,
361                          guint prop_id, GValue * value, GParamSpec * pspec)
362 {
363     HildonSortDialog *dialog;
364
365     dialog = HILDON_SORT_DIALOG(object);
366
367     switch (prop_id) {
368     case PROP_SORT_KEY:
369         g_value_set_int(value, hildon_sort_dialog_get_sort_key(dialog));
370         break;
371     case PROP_SORT_ORDER:
372         g_value_set_enum(value, hildon_sort_dialog_get_sort_order(dialog));
373         break;
374     default:
375         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
376         break;
377     }
378 }
379