2 * This file is part of hildon-libs
4 * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
6 * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
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 or any later version.
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.
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
26 * SECTION:hildon-sort-dialog
27 * @short_description: A widget for defining the sorting order of items
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.
40 #include <gtk/gtkcombobox.h>
41 #include <gtk/gtkbox.h>
42 #include <hildon-widgets/hildon-caption.h>
43 #include "hildon-sort-dialog.h"
46 #define _(String) dgettext(PACKAGE, String)
48 static GtkDialogClass *parent_class;
50 #define HILDON_SORT_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE \
51 ((obj), HILDON_TYPE_SORT_DIALOG, HildonSortDialogPrivate));
53 typedef struct _HildonSortDialogPrivate HildonSortDialogPrivate;
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,
61 static void hildon_sort_dialog_get_property(GObject * object,
63 GValue * value, GParamSpec * pspec);
64 static void reconstruct_combo (HildonSortDialog * dialog,
67 static gint hildon_sort_dialog_add_sort_key_with_sorting(HildonSortDialog * dialog,
68 const gchar * sort_key,
70 static void sort_key_changed(GtkWidget * widget,
71 HildonSortDialog * dialog);
72 static void hildon_sort_dialog_finalize(GObject * object);
81 struct _HildonSortDialogPrivate {
82 /* Sort category widgets */
84 GtkWidget *caption_key;
86 /* Sort order widgets */
87 GtkWidget *combo_order;
88 GtkWidget *caption_order;
90 /* Index value counter */
93 /* If the current order displayed is reversed */
96 /* An array for each key representing if a key should be reverse-sorted */
97 gboolean *key_reversed;
100 /* Private functions */
102 static void sort_key_changed(GtkWidget * widget, HildonSortDialog * dialog)
104 g_return_if_fail(HILDON_IS_SORT_DIALOG(dialog));
106 HildonSortDialogPrivate *priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
108 gint index = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
110 if (priv->key_reversed [index] != priv->reversed) {
111 reconstruct_combo (dialog, TRUE, priv->key_reversed [index]);
112 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combo_order), 0);
115 priv->reversed = priv->key_reversed [index];
119 * Initialises the sort dialog class.
121 static void hildon_sort_dialog_class_init(HildonSortDialogClass * class)
123 GObjectClass *gobject_class = G_OBJECT_CLASS(class);
124 parent_class = g_type_class_peek_parent(class);
125 g_type_class_add_private(class, sizeof(HildonSortDialogPrivate));
127 gobject_class->set_property = hildon_sort_dialog_set_property;
128 gobject_class->get_property = hildon_sort_dialog_get_property;
129 gobject_class->finalize = (gpointer) hildon_sort_dialog_finalize;
131 g_object_class_install_property(gobject_class, PROP_SORT_KEY,
132 g_param_spec_int("sort-key",
134 "The currently active sort key",
137 0, G_PARAM_READWRITE));
139 g_object_class_install_property(gobject_class, PROP_SORT_ORDER,
140 g_param_spec_enum("sort-order",
142 "The current sorting order",
148 static gint hildon_sort_dialog_add_sort_key_with_sorting(HildonSortDialog * dialog, const gchar * sort_key, gboolean sorting)
150 HildonSortDialogPrivate *priv;
152 g_return_val_if_fail(HILDON_IS_SORT_DIALOG(dialog), -1);
154 priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
155 gboolean *new_array = g_malloc (sizeof (gboolean) * (priv->index_counter + 1));
157 /* Rewrite the old values */
159 for (i = 0; i < priv->index_counter; i++)
160 new_array [i] = priv->key_reversed [i];
162 new_array [priv->index_counter] = sorting;
163 gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_key), sort_key);
165 /* Free the old one and reassign */
166 if (priv->key_reversed != NULL)
167 g_free (priv->key_reversed);
168 priv->key_reversed = new_array;
170 return priv->index_counter++;
173 static void reconstruct_combo (HildonSortDialog * dialog, gboolean remove, gboolean reversed)
175 HildonSortDialogPrivate *priv;
176 priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
179 gtk_combo_box_remove_text(GTK_COMBO_BOX(priv->combo_order), 1);
180 gtk_combo_box_remove_text(GTK_COMBO_BOX(priv->combo_order), 0);
184 gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order), _("ckdg_va_sort_descending"));
185 gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order), _("ckdg_va_sort_ascending"));
187 gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order), _("ckdg_va_sort_ascending"));
188 gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order), _("ckdg_va_sort_descending"));
192 static void hildon_sort_dialog_init(HildonSortDialog * dialog)
194 HildonSortDialogPrivate *priv;
197 g_assert(HILDON_IS_SORT_DIALOG(dialog));
199 priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
201 priv->index_counter = 0;
202 priv->reversed = FALSE;
203 priv->key_reversed = NULL;
205 group = GTK_SIZE_GROUP(gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL));
207 gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
208 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
209 gtk_window_set_title(GTK_WINDOW(dialog), _("ckdg_ti_sort"));
212 priv->combo_key = gtk_combo_box_new_text();
213 priv->caption_key = hildon_caption_new(group, _("ckdg_fi_sort_field"), priv->combo_key,
214 NULL, HILDON_CAPTION_OPTIONAL);
215 hildon_caption_set_separator(HILDON_CAPTION(priv->caption_key), "");
216 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
217 priv->caption_key, FALSE, FALSE, 0);
220 priv->combo_order = gtk_combo_box_new_text();
221 reconstruct_combo (dialog, FALSE, FALSE);
223 priv->caption_order = hildon_caption_new(group, _("ckdg_fi_sort_order"),
225 NULL, HILDON_CAPTION_OPTIONAL);
226 hildon_caption_set_separator(HILDON_CAPTION(priv->caption_order), "");
227 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
228 priv->caption_order, FALSE, FALSE, 0);
230 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combo_key), 0);
231 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combo_order), 0);
232 g_signal_connect (G_OBJECT (priv->combo_key), "changed", (gpointer) sort_key_changed, dialog);
234 /* Create the OK/CANCEL buttons */
235 (void) gtk_dialog_add_button(GTK_DIALOG(dialog),
236 _("ckdg_bd_sort_dialog_ok"),
238 (void) gtk_dialog_add_button(GTK_DIALOG(dialog),
239 _("ckdg_bd_sort_dialog_cancel"),
240 GTK_RESPONSE_CANCEL);
241 /* FIXME: Hardcoded sizes are bad */
242 gtk_window_resize(GTK_WINDOW(dialog), 370, 100);
243 gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
245 g_object_unref(group); /* Captions now own their references to sizegroup */
248 /* Public functions */
251 * hildon_sort_dialog_get_type:
253 * Returns GType for HildonSortDialog as produced by
254 * g_type_register_static().
256 * Returns: HildonSortDialog type
258 GType hildon_sort_dialog_get_type()
260 static GType dialog_type = 0;
263 static const GTypeInfo dialog_info = {
264 sizeof(HildonSortDialogClass),
265 NULL, /* base_init */
266 NULL, /* base_finalize */
267 (GClassInitFunc) hildon_sort_dialog_class_init,
268 NULL, /* class_finalize */
269 NULL, /* class_data */
270 sizeof(HildonSortDialog),
272 (GInstanceInitFunc) hildon_sort_dialog_init
275 dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
283 * hildon_sort_dialog_new:
284 * @parent: widget to be transient for, or NULL if none
286 * HildonSortDialog contains two HildonCaptions with combo boxes.
288 * Returns: pointer to a new @HildonSortDialog widget
290 GtkWidget *hildon_sort_dialog_new(GtkWindow * parent)
292 GtkWidget *sort_dialog = g_object_new(HILDON_TYPE_SORT_DIALOG, NULL);
295 gtk_window_set_transient_for(GTK_WINDOW(sort_dialog), parent);
301 * hildon_sort_dialog_get_sort_key:
302 * @dialog: the #HildonSortDialog widget
304 * Gets index to currently active sort key.
306 * Returns: an integer which is the index value of the "Sort by"
309 gint hildon_sort_dialog_get_sort_key(HildonSortDialog * dialog)
311 GtkWidget *combo_key;
312 HildonSortDialogPrivate *priv;
314 g_return_val_if_fail(HILDON_IS_SORT_DIALOG(dialog), -1);
316 priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
318 combo_key = gtk_bin_get_child(GTK_BIN(priv->caption_key));
320 return gtk_combo_box_get_active(GTK_COMBO_BOX(combo_key));
324 * hildon_sort_dialog_get_sort_order:
325 * @dialog: the #HildonSortDialog widget
327 * Gets current sorting order from "Sort order" field.
329 * Returns: current sorting order as #GtkSortType
331 GtkSortType hildon_sort_dialog_get_sort_order(HildonSortDialog * dialog)
333 GtkWidget *combo_order;
334 HildonSortDialogPrivate *priv;
336 g_return_val_if_fail(HILDON_IS_SORT_DIALOG(dialog), 0);
338 priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
339 combo_order = gtk_bin_get_child(GTK_BIN(priv->caption_order));
341 gint sort_order = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_order));
344 return (sort_order == 0) ? 1 : 0;
350 * hildon_sort_dialog_set_sort_key:
351 * @dialog: the #HildonSortDialog widget
352 * @key: combo box's index value
354 * Sets the index value of the #HildonSortDialog widget.
356 void hildon_sort_dialog_set_sort_key(HildonSortDialog * dialog, gint key)
358 GtkWidget *combo_key;
359 HildonSortDialogPrivate *priv;
361 g_return_if_fail(HILDON_IS_SORT_DIALOG(dialog));
363 priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
364 combo_key = gtk_bin_get_child(GTK_BIN(priv->caption_key));
365 gtk_combo_box_set_active(GTK_COMBO_BOX(combo_key), key);
367 g_object_notify (G_OBJECT (dialog), "sort-key");
371 * hildon_sort_dialog_set_sort_order:
372 * @dialog: the #HildonSortDialog widget
373 * @order: combo box's index value
375 * Sets the index value of the #HildonSortDialog widget.
378 hildon_sort_dialog_set_sort_order(HildonSortDialog * dialog,
381 GtkWidget *combo_order;
382 HildonSortDialogPrivate *priv;
384 g_return_if_fail(HILDON_IS_SORT_DIALOG(dialog));
386 priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
387 combo_order = gtk_bin_get_child(GTK_BIN(priv->caption_order));
390 order = (order == 0) ? 1 : 0;
392 gtk_combo_box_set_active(GTK_COMBO_BOX(combo_order), order);
394 g_object_notify (G_OBJECT (dialog), "sort-order");
398 * hildon_sort_dialog_add_sort_key:
399 * @dialog: the #HildonSortDialog widget
400 * @sort_key: combo box's index value
402 * Adds a new sort key and returns the respective index in
405 * Returns: an integer which is the index of the added combo box's
409 hildon_sort_dialog_add_sort_key(HildonSortDialog * dialog,
410 const gchar * sort_key)
412 return hildon_sort_dialog_add_sort_key_with_sorting (dialog, sort_key, FALSE);
416 * hildon_sort_dialog_add_sort_key_reversed:
417 * @dialog: the #HildonSortDialog widget
418 * @sort_key: combo box's index value
420 * Adds a new sort key and returns the respective index in
421 * sort key combobox. The default sort order for this key is reversed (Descending first).
423 * Returns: an integer which is the index of the added combo box's
429 hildon_sort_dialog_add_sort_key_reversed(HildonSortDialog * dialog,
430 const gchar * sort_key)
432 return hildon_sort_dialog_add_sort_key_with_sorting (dialog, sort_key, TRUE);
436 hildon_sort_dialog_set_property(GObject * object,
438 const GValue * value, GParamSpec * pspec)
440 HildonSortDialog *dialog;
442 dialog = HILDON_SORT_DIALOG(object);
446 hildon_sort_dialog_set_sort_key(dialog, g_value_get_int(value));
448 case PROP_SORT_ORDER:
449 hildon_sort_dialog_set_sort_order(dialog, g_value_get_enum(value));
452 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
458 hildon_sort_dialog_get_property(GObject * object,
459 guint prop_id, GValue * value, GParamSpec * pspec)
461 HildonSortDialog *dialog;
463 dialog = HILDON_SORT_DIALOG(object);
467 g_value_set_int(value, hildon_sort_dialog_get_sort_key(dialog));
469 case PROP_SORT_ORDER:
470 g_value_set_enum(value, hildon_sort_dialog_get_sort_order(dialog));
473 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
479 hildon_sort_dialog_finalize(GObject * object)
481 HildonSortDialogPrivate *priv;
482 HildonSortDialog *dialog;
484 g_return_if_fail (HILDON_IS_SORT_DIALOG (object));
485 dialog = HILDON_SORT_DIALOG(object);
487 priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
488 if (priv != NULL && priv->key_reversed != NULL)
489 g_free(priv->key_reversed);
491 if (G_OBJECT_CLASS(parent_class)->finalize)
492 G_OBJECT_CLASS(parent_class)->finalize(object);