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
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.
35 #include "hildon-sort-dialog.h"
38 #include <gtk/gtkcombobox.h>
39 #include <gtk/gtkbox.h>
40 #include "hildon-caption.h"
42 #define _(String) dgettext(PACKAGE, String)
44 static GtkDialogClass *parent_class;
46 #define HILDON_SORT_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE \
47 ((obj), HILDON_TYPE_SORT_DIALOG, HildonSortDialogPrivate));
49 typedef struct _HildonSortDialogPrivate HildonSortDialogPrivate;
51 static void hildon_sort_dialog_class_init(HildonSortDialogClass * class);
52 static void hildon_sort_dialog_init(HildonSortDialog * widget);
53 static void hildon_sort_dialog_set_property(GObject * object,
57 static void hildon_sort_dialog_get_property(GObject * object,
59 GValue * value, GParamSpec * pspec);
60 static void reconstruct_combo (HildonSortDialog * dialog,
63 static void sort_key_changed(GtkWidget * widget,
64 HildonSortDialog * dialog);
65 static void hildon_sort_dialog_finalize(GObject * object);
74 struct _HildonSortDialogPrivate {
75 /* Sort category widgets */
77 GtkWidget *caption_key;
79 /* Sort order widgets */
80 GtkWidget *combo_order;
81 GtkWidget *caption_order;
83 /* Index value counter */
86 /* If the current order displayed is reversed */
89 /* An array for each key representing if a key should be reverse-sorted */
90 gboolean *key_reversed;
93 /* Private functions */
95 static void sort_key_changed(GtkWidget * widget, HildonSortDialog * dialog)
97 g_return_if_fail(HILDON_IS_SORT_DIALOG(dialog));
99 HildonSortDialogPrivate *priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
101 gint index = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
103 if (priv->key_reversed [index] != priv->reversed) {
104 reconstruct_combo (dialog, TRUE, priv->key_reversed [index]);
105 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combo_order), 0);
108 priv->reversed = priv->key_reversed [index];
112 * Initialises the sort dialog class.
114 static void hildon_sort_dialog_class_init(HildonSortDialogClass * class)
116 GObjectClass *gobject_class = G_OBJECT_CLASS(class);
117 parent_class = g_type_class_peek_parent(class);
118 g_type_class_add_private(class, sizeof(HildonSortDialogPrivate));
120 gobject_class->set_property = hildon_sort_dialog_set_property;
121 gobject_class->get_property = hildon_sort_dialog_get_property;
122 gobject_class->finalize = (gpointer) hildon_sort_dialog_finalize;
124 g_object_class_install_property(gobject_class, PROP_SORT_KEY,
125 g_param_spec_int("sort-key",
127 "The currently active sort key",
130 0, G_PARAM_READWRITE));
132 g_object_class_install_property(gobject_class, PROP_SORT_ORDER,
133 g_param_spec_enum("sort-order",
135 "The current sorting order",
141 gint hildon_sort_dialog_add_sort_key_with_sorting(HildonSortDialog * dialog, const gchar * sort_key, gboolean sorting)
143 HildonSortDialogPrivate *priv;
145 g_return_val_if_fail(HILDON_IS_SORT_DIALOG(dialog), -1);
147 priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
148 gboolean *new_array = g_malloc (sizeof (gboolean) * (priv->index_counter + 1));
150 /* Rewrite the old values */
152 for (i = 0; i < priv->index_counter; i++)
153 new_array [i] = priv->key_reversed [i];
155 new_array [priv->index_counter] = sorting;
156 gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_key), sort_key);
158 /* Free the old one and reassign */
159 if (priv->key_reversed != NULL)
160 g_free (priv->key_reversed);
161 priv->key_reversed = new_array;
163 return priv->index_counter++;
166 static void reconstruct_combo (HildonSortDialog * dialog, gboolean remove, gboolean reversed)
168 HildonSortDialogPrivate *priv;
169 priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
172 gtk_combo_box_remove_text(GTK_COMBO_BOX(priv->combo_order), 1);
173 gtk_combo_box_remove_text(GTK_COMBO_BOX(priv->combo_order), 0);
177 gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order), _("ckdg_va_sort_descending"));
178 gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order), _("ckdg_va_sort_ascending"));
180 gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order), _("ckdg_va_sort_ascending"));
181 gtk_combo_box_append_text(GTK_COMBO_BOX(priv->combo_order), _("ckdg_va_sort_descending"));
185 static void hildon_sort_dialog_init(HildonSortDialog * dialog)
187 HildonSortDialogPrivate *priv;
190 g_assert(HILDON_IS_SORT_DIALOG(dialog));
192 priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
194 priv->index_counter = 0;
195 priv->reversed = FALSE;
196 priv->key_reversed = NULL;
198 group = GTK_SIZE_GROUP(gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL));
200 gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
201 gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
202 gtk_window_set_title(GTK_WINDOW(dialog), _("ckdg_ti_sort"));
205 priv->combo_key = gtk_combo_box_new_text();
206 priv->caption_key = hildon_caption_new(group, _("ckdg_fi_sort_field"), priv->combo_key,
207 NULL, HILDON_CAPTION_OPTIONAL);
208 hildon_caption_set_separator(HILDON_CAPTION(priv->caption_key), "");
209 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
210 priv->caption_key, FALSE, FALSE, 0);
213 priv->combo_order = gtk_combo_box_new_text();
214 reconstruct_combo (dialog, FALSE, FALSE);
216 priv->caption_order = hildon_caption_new(group, _("ckdg_fi_sort_order"),
218 NULL, HILDON_CAPTION_OPTIONAL);
219 hildon_caption_set_separator(HILDON_CAPTION(priv->caption_order), "");
220 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
221 priv->caption_order, FALSE, FALSE, 0);
223 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combo_key), 0);
224 gtk_combo_box_set_active(GTK_COMBO_BOX(priv->combo_order), 0);
225 g_signal_connect (G_OBJECT (priv->combo_key), "changed", (gpointer) sort_key_changed, dialog);
227 /* Create the OK/CANCEL buttons */
228 (void) gtk_dialog_add_button(GTK_DIALOG(dialog),
229 _("ckdg_bd_sort_dialog_ok"),
231 (void) gtk_dialog_add_button(GTK_DIALOG(dialog),
232 _("ckdg_bd_sort_dialog_cancel"),
233 GTK_RESPONSE_CANCEL);
234 /* FIXME: Hardcoded sizes are bad */
235 gtk_window_resize(GTK_WINDOW(dialog), 370, 100);
236 gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
238 g_object_unref(group); /* Captions now own their references to sizegroup */
241 /* Public functions */
244 * hildon_sort_dialog_get_type:
246 * Returns GType for HildonSortDialog as produced by
247 * g_type_register_static().
249 * Returns: HildonSortDialog type
251 GType hildon_sort_dialog_get_type()
253 static GType dialog_type = 0;
256 static const GTypeInfo dialog_info = {
257 sizeof(HildonSortDialogClass),
258 NULL, /* base_init */
259 NULL, /* base_finalize */
260 (GClassInitFunc) hildon_sort_dialog_class_init,
261 NULL, /* class_finalize */
262 NULL, /* class_data */
263 sizeof(HildonSortDialog),
265 (GInstanceInitFunc) hildon_sort_dialog_init
268 dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
276 * hildon_sort_dialog_new:
277 * @parent: widget to be transient for, or NULL if none
279 * HildonSortDialog contains two HildonCaptions with combo boxes.
281 * Returns: pointer to a new @HildonSortDialog widget
283 GtkWidget *hildon_sort_dialog_new(GtkWindow * parent)
285 GtkWidget *sort_dialog = g_object_new(HILDON_TYPE_SORT_DIALOG, NULL);
288 gtk_window_set_transient_for(GTK_WINDOW(sort_dialog), parent);
294 * hildon_sort_dialog_get_sort_key:
295 * @dialog: the #HildonSortDialog widget
297 * Gets index to currently active sort key.
299 * Returns: an integer which is the index value of the "Sort by"
302 gint hildon_sort_dialog_get_sort_key(HildonSortDialog * dialog)
304 GtkWidget *combo_key;
305 HildonSortDialogPrivate *priv;
307 g_return_val_if_fail(HILDON_IS_SORT_DIALOG(dialog), -1);
309 priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
311 combo_key = gtk_bin_get_child(GTK_BIN(priv->caption_key));
313 return gtk_combo_box_get_active(GTK_COMBO_BOX(combo_key));
317 * hildon_sort_dialog_get_sort_order:
318 * @dialog: the #HildonSortDialog widget
320 * Gets current sorting order from "Sort order" field.
322 * Returns: current sorting order as #GtkSortType
324 GtkSortType hildon_sort_dialog_get_sort_order(HildonSortDialog * dialog)
326 GtkWidget *combo_order;
327 HildonSortDialogPrivate *priv;
329 g_return_val_if_fail(HILDON_IS_SORT_DIALOG(dialog), 0);
331 priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
332 combo_order = gtk_bin_get_child(GTK_BIN(priv->caption_order));
334 gint sort_order = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_order));
337 return (sort_order == 0) ? 1 : 0;
343 * hildon_sort_dialog_set_sort_key:
344 * @dialog: the #HildonSortDialog widget
345 * @key: combo box's index value
347 * Sets the index value of the #HildonSortDialog widget.
349 void hildon_sort_dialog_set_sort_key(HildonSortDialog * dialog, gint key)
351 GtkWidget *combo_key;
352 HildonSortDialogPrivate *priv;
354 g_return_if_fail(HILDON_IS_SORT_DIALOG(dialog));
356 priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
357 combo_key = gtk_bin_get_child(GTK_BIN(priv->caption_key));
358 gtk_combo_box_set_active(GTK_COMBO_BOX(combo_key), key);
360 g_object_notify (G_OBJECT (dialog), "sort-key");
364 * hildon_sort_dialog_set_sort_order:
365 * @dialog: the #HildonSortDialog widget
366 * @order: combo box's index value
368 * Sets the index value of the #HildonSortDialog widget.
371 hildon_sort_dialog_set_sort_order(HildonSortDialog * dialog,
374 GtkWidget *combo_order;
375 HildonSortDialogPrivate *priv;
377 g_return_if_fail(HILDON_IS_SORT_DIALOG(dialog));
379 priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
380 combo_order = gtk_bin_get_child(GTK_BIN(priv->caption_order));
383 order = (order == 0) ? 1 : 0;
385 gtk_combo_box_set_active(GTK_COMBO_BOX(combo_order), order);
387 g_object_notify (G_OBJECT (dialog), "sort-order");
391 * hildon_sort_dialog_add_sort_key:
392 * @dialog: the #HildonSortDialog widget
393 * @sort_key: combo box's index value
395 * Adds a new sort key and returns the respective index in
398 * Returns: an integer which is the index of the added combo box's
402 hildon_sort_dialog_add_sort_key(HildonSortDialog * dialog,
403 const gchar * sort_key)
405 return hildon_sort_dialog_add_sort_key_with_sorting (dialog, sort_key, FALSE);
409 * hildon_sort_dialog_add_sort_key_reversed:
410 * @dialog: the #HildonSortDialog widget
411 * @sort_key: combo box's index value
413 * Adds a new sort key and returns the respective index in
414 * sort key combobox. The default sort order for this key is reversed (Descending first).
416 * Returns: an integer which is the index of the added combo box's
422 hildon_sort_dialog_add_sort_key_reversed(HildonSortDialog * dialog,
423 const gchar * sort_key)
425 return hildon_sort_dialog_add_sort_key_with_sorting (dialog, sort_key, TRUE);
429 hildon_sort_dialog_set_property(GObject * object,
431 const GValue * value, GParamSpec * pspec)
433 HildonSortDialog *dialog;
435 dialog = HILDON_SORT_DIALOG(object);
439 hildon_sort_dialog_set_sort_key(dialog, g_value_get_int(value));
441 case PROP_SORT_ORDER:
442 hildon_sort_dialog_set_sort_order(dialog, g_value_get_enum(value));
445 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
451 hildon_sort_dialog_get_property(GObject * object,
452 guint prop_id, GValue * value, GParamSpec * pspec)
454 HildonSortDialog *dialog;
456 dialog = HILDON_SORT_DIALOG(object);
460 g_value_set_int(value, hildon_sort_dialog_get_sort_key(dialog));
462 case PROP_SORT_ORDER:
463 g_value_set_enum(value, hildon_sort_dialog_get_sort_order(dialog));
466 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
472 hildon_sort_dialog_finalize(GObject * object)
474 HildonSortDialogPrivate *priv;
475 HildonSortDialog *dialog;
477 g_return_if_fail (HILDON_IS_SORT_DIALOG (object));
478 dialog = HILDON_SORT_DIALOG(object);
480 priv = HILDON_SORT_DIALOG_GET_PRIVATE(dialog);
481 if (priv != NULL && priv->key_reversed != NULL)
482 g_free(priv->key_reversed);
484 if (G_OBJECT_CLASS(parent_class)->finalize)
485 G_OBJECT_CLASS(parent_class)->finalize(object);