2009-02-02 Alberto Garcia <agarcia@igalia.com>
[hildon] / src / hildon-note.c
1 /*
2  * This file is a part of hildon
3  *
4  * Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
5  *
6  * Contact: Rodrigo Novo <rodrigo.novo@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, or (at your option) any later version.
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-note
27  * @short_description: A widget to ask confirmation from the user.
28  *
29  * #HildonNote is a convenient way to prompt users for a small amount of
30  * input. A simple note contains an information text and, in case of
31  * confirmation notes, it shows buttons to confirm or cancel. It also can
32  * include a progress bar.
33  *
34  * This widget provides convenient functions to create either
35  * information notes, confirmation notes or cancel notes, which are
36  * useful to show the progress of a requested task allowing the user
37  * to cancel it.
38  *
39  * To create information notes you can use
40  * hildon_note_new_information(). hildon_note_new_confirmation()
41  * creates a note with a text and two buttons to confirm or
42  * cancel. Note that it is possible to create a confirmation note with
43  * customized buttons by using
44  * hildon_note_new_confirmation_add_buttons().
45  *
46  * To create a note with a text, a progress bar and cancel button,
47  * hildon_note_new_cancel_with_progress_bar() can be used.
48  *
49  * <example>
50  * <title>HildonNote example</title>
51  * <programlisting>
52  * <!-- -->
53  * gboolean
54  * show_confirmation_note (GtkWindow *parent)
55  * {
56  *   gint retcode;
57  *   GtkWidget *note;
58  *   note = hildon_note_new_confirmation (parent, "Confirmation message...");
59  * <!-- -->
60  *   retcode = gtk_dialog_run (GTK_DIALOG (note));
61  *   gtk_widget_destroy (note);
62  * <!-- -->
63  *   if (retcode == GTK_RESPONSE_OK) {
64  *        g_debug ("User pressed 'OK' button'");
65  *        return TRUE;
66  *   } else {
67  *        g_debug ("User pressed 'Cancel' button");
68  *        return FALSE;
69  *   }
70  * }
71  * </programlisting>
72  * </example>
73  */
74
75 #ifdef                                          HAVE_CONFIG_H
76 #include                                        <config.h>
77 #endif
78
79 #include                                        <stdio.h>
80 #include                                        <string.h>
81 #include                                        <libintl.h>
82 #include                                        <X11/X.h>
83 #include                                        <X11/Xatom.h>
84 #include                                        <gdk/gdkx.h>
85
86 #undef HILDON_DISABLE_DEPRECATED
87
88 #include                                        "hildon-note.h"
89 #include                                        "hildon-defines.h"
90 #include                                        "hildon-sound.h"
91 #include                                        "hildon-banner.h" 
92 #include                                        "hildon-enum-types.h"
93 #include                                        "hildon-note-private.h"
94
95 #define                                         HILDON_INFORMATION_NOTE_MIN_HEIGHT 140
96
97 #define                                         HILDON_INFORMATION_NOTE_MARGIN 100
98
99 #define                                         CONFIRMATION_SOUND_PATH \
100                                                 "/usr/share/sounds/ui-confirmation_note.wav"
101
102 #define                                         INFORMATION_SOUND_PATH \
103                                                 "/usr/share/sounds/ui-information_note.wav"
104
105 #define                                         _(String) dgettext("hildon-libs", String)
106
107 static void 
108 hildon_note_class_init                          (HildonNoteClass *class);
109
110 static void
111 hildon_note_init                                (HildonNote *dialog);
112
113 static void 
114 hildon_note_rebuild                             (HildonNote *note);
115
116 static void
117 hildon_note_finalize                            (GObject *obj_self);
118
119 static void
120 hildon_note_realize                             (GtkWidget *widget);
121
122 static void
123 hildon_note_unrealize                           (GtkWidget *widget);
124
125 static void
126 label_size_request                              (GtkWidget      *label,
127                                                  GtkRequisition *req,
128                                                  GtkWidget      *note);
129
130 static void 
131 hildon_note_set_property                        (GObject *object,
132                                                  guint prop_id,
133                                                  const GValue *value,
134                                                  GParamSpec *pspec);
135
136 static void
137 hildon_note_get_property                        (GObject *object,
138                                                  guint prop_id,
139                                                  GValue *value, 
140                                                  GParamSpec *pspec);
141
142 static gboolean
143 sound_handling                                  (GtkWidget *widget, 
144                                                  GdkEventExpose *event, 
145                                                  gpointer data);
146
147 enum 
148 {
149     PROP_0,
150     PROP_HILDON_NOTE_TYPE,
151     PROP_HILDON_NOTE_DESCRIPTION,
152     PROP_HILDON_NOTE_ICON,
153     PROP_HILDON_NOTE_PROGRESSBAR,
154     PROP_HILDON_NOTE_STOCK_ICON
155 };
156
157 static GtkDialogClass*                          parent_class;
158
159 static gboolean
160 event_box_press_event                           (GtkEventBox    *event_box,
161                                                  GdkEventButton *event,
162                                                  GtkDialog      *note)
163 {
164     HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE (note);
165
166     if (priv->note_n == HILDON_NOTE_TYPE_INFORMATION ||
167         priv->note_n == HILDON_NOTE_TYPE_INFORMATION_THEME) {
168             gtk_dialog_response (note, GTK_RESPONSE_DELETE_EVENT);
169             return TRUE;
170     } else {
171             return FALSE;
172     }
173 }
174
175 static void
176 hildon_note_set_property                        (GObject *object,
177                                                  guint prop_id,
178                                                  const GValue *value, 
179                                                  GParamSpec * pspec)
180 {
181     HildonNote *note = HILDON_NOTE (object);
182     HildonNotePrivate *priv;
183     GtkWidget *widget;
184
185     priv = HILDON_NOTE_GET_PRIVATE (note);
186     g_assert (priv);
187
188     switch (prop_id) {
189
190         case PROP_HILDON_NOTE_TYPE:
191             priv->note_n = g_value_get_enum (value);
192             hildon_note_rebuild (note);
193             break;
194
195         case PROP_HILDON_NOTE_DESCRIPTION:
196             if (priv->original_description) 
197                     g_free (priv->original_description);
198             priv->original_description = g_value_dup_string (value);
199
200             gtk_label_set_text (GTK_LABEL (priv->label), priv->original_description);
201             /* FIXME Is the "original_description" used anywhere? */
202             
203             break;
204
205         case PROP_HILDON_NOTE_ICON:
206             if (priv->icon) {
207               g_free (priv->icon);
208             }
209             priv->icon = g_value_dup_string (value);
210             break;
211
212         case PROP_HILDON_NOTE_STOCK_ICON:
213             if (priv->stock_icon) {
214               g_free (priv->stock_icon);
215             }
216             priv->stock_icon = g_value_dup_string (value);
217             break;
218
219         case PROP_HILDON_NOTE_PROGRESSBAR:
220             widget = g_value_get_object (value);
221             if (widget != priv->progressbar)
222             {
223                 if (priv->progressbar)
224                     g_object_unref (priv->progressbar);
225
226                 priv->progressbar = widget;
227
228                 if (widget)
229                 {
230                     g_object_ref (widget);
231                     gtk_object_sink (GTK_OBJECT (widget));
232                 }
233
234                 hildon_note_rebuild (note);
235             }
236             break;
237
238         default:
239             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
240             break;
241     }
242 }
243
244 static void
245 hildon_note_get_property                        (GObject *object,
246                                                  guint prop_id, 
247                                                  GValue *value, 
248                                                  GParamSpec *pspec)
249 {
250     HildonNote *note = HILDON_NOTE (object);
251     HildonNotePrivate *priv;
252
253     priv = HILDON_NOTE_GET_PRIVATE (note);
254
255     switch (prop_id) {
256
257         case PROP_HILDON_NOTE_TYPE:
258             g_value_set_enum (value, priv->note_n);
259             break;
260
261         case PROP_HILDON_NOTE_DESCRIPTION:
262             g_value_set_string (value, priv->original_description);
263             break;
264
265         case PROP_HILDON_NOTE_ICON:
266             g_value_set_string (value, priv->icon);
267             break;
268
269         case PROP_HILDON_NOTE_STOCK_ICON:
270             g_value_set_string (value, priv->stock_icon);
271             break;
272
273         case PROP_HILDON_NOTE_PROGRESSBAR:
274             g_value_set_object (value, priv->progressbar);
275             break;
276
277         default:
278             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
279             break;
280     }
281 }
282
283 /**
284  * hildon_note_get_type:
285  *
286  * Returns GType for HildonNote.
287  *
288  * Returns: HildonNote type
289  */
290 GType G_GNUC_CONST
291 hildon_note_get_type                            (void)
292 {
293     static GType dialog_type = 0;
294
295     if (! dialog_type) {
296         static const GTypeInfo dialog_info = {
297             sizeof(HildonNoteClass),
298             NULL,       /* base_init */
299             NULL,       /* base_finalize */
300             (GClassInitFunc) hildon_note_class_init,
301             NULL,       /* class_finalize */
302             NULL,       /* class_data */
303             sizeof(HildonNote),
304             0,  /* n_preallocs */
305             (GInstanceInitFunc) hildon_note_init
306         };
307         dialog_type = g_type_register_static (GTK_TYPE_DIALOG,
308                 "HildonNote",
309                 &dialog_info, 0);
310     }
311     return dialog_type;
312 }
313
314 static void 
315 hildon_note_class_init                          (HildonNoteClass *class)
316 {
317     GObjectClass *object_class = G_OBJECT_CLASS (class);
318     GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
319
320     /* set the global parent_class */
321     parent_class = g_type_class_peek_parent (class);
322
323     g_type_class_add_private (class, sizeof (HildonNotePrivate));
324
325     object_class->finalize      = hildon_note_finalize;
326     object_class->set_property  = hildon_note_set_property;
327     object_class->get_property  = hildon_note_get_property;
328     widget_class->realize       = hildon_note_realize;
329     widget_class->unrealize     = hildon_note_unrealize;
330
331     g_object_class_install_property (object_class,
332             PROP_HILDON_NOTE_TYPE,
333             g_param_spec_enum ("note-type",
334                 "note type",
335                 "The type of the note dialog",
336                 hildon_note_type_get_type (),
337                 HILDON_NOTE_TYPE_CONFIRMATION,
338                 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
339
340     /**
341      * HildonNote:description:
342      *
343      * Description for the note.
344      */
345     g_object_class_install_property (object_class,
346             PROP_HILDON_NOTE_DESCRIPTION,
347             g_param_spec_string ("description",
348                 "note description",
349                 "The text that appears in the note dialog",
350                 "",
351                 G_PARAM_READWRITE));
352
353     /**
354      * HildonNote:icon:
355      *
356      * Icon for the note.
357      *
358      * Deprecated: Since 2.2
359      */
360     g_object_class_install_property (object_class,
361             PROP_HILDON_NOTE_ICON,
362             g_param_spec_string ("icon",
363                 "note icon",
364                 "The name of the icon that appears in the note dialog",
365                 "",
366                 G_PARAM_READWRITE));
367
368     /**
369      * HildonNote:stock-icon:
370      *
371      * Stock icon name for the note.
372      *
373      * Deprecated: Since 2.2
374      */
375     g_object_class_install_property (object_class,
376             PROP_HILDON_NOTE_STOCK_ICON,
377             g_param_spec_string ("stock-icon",
378                 "Stock note icon",
379                 "The stock name of the icon that appears in the note dialog",
380                 "",
381                 G_PARAM_READWRITE));
382
383     /**
384      * HildonNote:progressbar:
385      *
386      * Progressbar for the note (if any).
387      */
388     g_object_class_install_property (object_class,
389             PROP_HILDON_NOTE_PROGRESSBAR,
390             g_param_spec_object ("progressbar",
391                 "Progressbar widget",
392                 "The progressbar that appears in the note dialog",
393                 GTK_TYPE_PROGRESS_BAR,
394                 G_PARAM_READWRITE));
395 }
396
397 static void 
398 hildon_note_init                                (HildonNote *dialog)
399 {
400     HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE (dialog);
401     g_assert (priv);
402
403     priv->label = gtk_label_new (NULL);
404     gtk_label_set_line_wrap (GTK_LABEL (priv->label), TRUE);
405
406     priv->event_box = gtk_event_box_new ();
407     priv->icon = NULL;
408     priv->stock_icon = NULL;
409
410     gtk_event_box_set_visible_window (GTK_EVENT_BOX (priv->event_box), FALSE);
411     gtk_event_box_set_above_child (GTK_EVENT_BOX (priv->event_box), TRUE);
412     g_signal_connect (priv->event_box, "button-press-event",
413                       G_CALLBACK (event_box_press_event), dialog);
414
415     /* Acquire real references to our internal children, since
416        they are not nessecarily packed into container in each
417        layout */
418     g_object_ref_sink (priv->event_box);
419     g_object_ref_sink (priv->label);
420
421     gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
422     gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
423
424     /* We use special hint to turn the note into information notification. */
425     gtk_window_set_type_hint (GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_NOTIFICATION);
426 }
427
428
429 static void 
430 hildon_note_finalize                            (GObject *obj_self)
431 {
432     HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE (obj_self);
433     g_assert (priv);
434
435     /* FIXME Some of this stuff should be moved to dispose */
436
437     /* Free internal data */
438     if (priv->event_box)
439         g_object_unref (priv->event_box);
440
441     if (priv->label)
442         g_object_unref (priv->label);
443
444     if (priv->icon) {
445         g_free (priv->icon);
446         priv->icon = NULL;
447     }
448     if (priv->stock_icon) {
449         g_free (priv->stock_icon);
450         priv->stock_icon = NULL;
451     }
452
453     if (priv->progressbar)
454         g_object_unref (priv->progressbar);
455
456     if (priv->original_description)
457         g_free (priv->original_description);
458
459     G_OBJECT_CLASS (parent_class)->finalize (obj_self);
460 }
461
462 static void
463 label_size_request                              (GtkWidget      *label,
464                                                  GtkRequisition *req,
465                                                  GtkWidget      *note)
466 {
467     gint note_height = MAX (HILDON_INFORMATION_NOTE_MIN_HEIGHT, req->height);
468     g_object_set (note, "height-request", note_height, NULL);
469 }
470
471 static void
472 screen_size_changed                            (GdkScreen *screen,
473                                                 GtkWidget *note)
474 {
475     HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE (note);
476     gint screen_width = gdk_screen_get_width (screen);
477     gint text_width = screen_width - HILDON_INFORMATION_NOTE_MARGIN * 2;
478
479     g_object_set (note, "width-request", screen_width, NULL);
480     g_object_set (priv->label, "width-request", text_width, NULL);
481 }
482
483 static void
484 hildon_note_realize                             (GtkWidget *widget)
485 {
486     GdkDisplay *display;
487     gboolean is_info_note = FALSE;
488     Atom atom;
489     const gchar *notification_type;
490     HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE (widget);
491     g_assert (priv);
492
493     /* Make widget->window accessible */
494     GTK_WIDGET_CLASS (parent_class)->realize (widget);
495
496     /* Border only, no titlebar */
497     gdk_window_set_decorations (widget->window, GDK_DECOR_BORDER);
498
499     /* Because ESD is synchronous, we wish to play sound after the
500        note is already on screen to avoid blocking its appearance */
501     if (priv->sound_signal_handler == 0)
502         priv->sound_signal_handler = g_signal_connect_after(widget, 
503                 "expose-event", G_CALLBACK (sound_handling), NULL);
504
505     /* Set the _HILDON_NOTIFICATION_TYPE property so Matchbox places the window correctly */
506     display = gdk_drawable_get_display (widget->window);
507     atom = gdk_x11_get_xatom_by_name_for_display (display, "_HILDON_NOTIFICATION_TYPE");
508
509     if (priv->note_n == HILDON_NOTE_TYPE_INFORMATION ||
510         priv->note_n == HILDON_NOTE_TYPE_INFORMATION_THEME) {
511         notification_type = "_HILDON_NOTIFICATION_TYPE_INFO";
512         is_info_note = TRUE;
513     } else {
514         notification_type = "_HILDON_NOTIFICATION_TYPE_CONFIRMATION";
515     }
516
517     XChangeProperty (GDK_WINDOW_XDISPLAY (widget->window), GDK_WINDOW_XID (widget->window),
518                      atom, XA_STRING, 8, PropModeReplace, (guchar *) notification_type,
519                      strlen (notification_type));
520
521     if (is_info_note) {
522         GdkScreen *screen = gtk_widget_get_screen (widget);
523         g_signal_connect (priv->label, "size-request", G_CALLBACK (label_size_request), widget);
524         g_signal_connect (screen, "size-changed", G_CALLBACK (screen_size_changed), widget);
525         screen_size_changed (screen, widget);
526     }
527 }
528
529 static void
530 hildon_note_unrealize                           (GtkWidget *widget)
531 {
532     HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE (widget);
533     GdkScreen *screen = gtk_widget_get_screen (widget);
534
535     g_signal_handlers_disconnect_by_func (screen, G_CALLBACK (screen_size_changed), widget);
536     g_signal_handlers_disconnect_by_func (priv->label, G_CALLBACK (label_size_request), widget);
537
538     GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
539 }
540
541
542 /* Helper function for removing a widget from it's container.
543    we own a separate reference to each object we try to unpack,
544    so extra referencing is not needed. */
545 static void 
546 unpack_widget                                   (GtkWidget *widget)
547 {
548     g_assert (widget == NULL || GTK_IS_WIDGET (widget));
549
550     if (widget && widget->parent)
551         gtk_container_remove (GTK_CONTAINER (widget->parent), widget);
552 }
553
554 static void
555 hildon_note_rebuild                             (HildonNote *note)
556 {
557     GtkDialog *dialog;
558     HildonNotePrivate *priv;
559     gboolean IsHorizontal = TRUE;
560
561     g_assert (HILDON_IS_NOTE (note));
562
563     priv = HILDON_NOTE_GET_PRIVATE (note);
564     g_assert (priv);
565
566     dialog = GTK_DIALOG (note);
567
568     /* Reuse exiting content widgets for new layout */
569     unpack_widget (priv->label);
570     unpack_widget (priv->progressbar);
571     unpack_widget (priv->event_box);
572
573     /* Destroy old layout and buttons */
574     if (priv->box) {
575         gtk_widget_destroy (priv->box);
576         priv->box = NULL;
577     }
578     if (priv->okButton) {
579         gtk_widget_destroy (priv->okButton);
580         priv->okButton = NULL;
581     }
582     if (priv->cancelButton) {
583         gtk_widget_destroy (priv->cancelButton);
584         priv->cancelButton = NULL;
585     }
586
587     /* Add needed buttons and images for each note type */
588     switch (priv->note_n)
589     {
590         case HILDON_NOTE_TYPE_CONFIRMATION:
591             priv->okButton = gtk_dialog_add_button (dialog,
592                     _("wdgt_bd_yes"), GTK_RESPONSE_OK);
593             priv->cancelButton = gtk_dialog_add_button (dialog,
594                     _("wdgt_bd_no"), GTK_RESPONSE_CANCEL);
595             gtk_widget_show (priv->cancelButton);
596             gtk_widget_set_no_show_all (priv->cancelButton, FALSE);
597             break;
598
599         case HILDON_NOTE_TYPE_PROGRESSBAR:
600             priv->cancelButton = gtk_dialog_add_button (dialog,
601                     _("wdgt_bd_stop"), GTK_RESPONSE_CANCEL);
602             gtk_widget_show (priv->cancelButton);
603             gtk_widget_set_no_show_all (priv->cancelButton, FALSE);
604             IsHorizontal = FALSE;
605             break;
606
607         case HILDON_NOTE_TYPE_CONFIRMATION_BUTTON:
608         case HILDON_NOTE_TYPE_INFORMATION_THEME:
609         case HILDON_NOTE_TYPE_INFORMATION:
610         default:
611             break;
612     }
613
614     if (IsHorizontal) {
615         /* Pack item with label horizontally */
616         priv->box = gtk_hbox_new (FALSE, HILDON_MARGIN_DEFAULT);
617         gtk_container_add (GTK_CONTAINER (priv->event_box), priv->box);
618
619         gtk_box_pack_start (GTK_BOX (priv->box), priv->label, TRUE, TRUE, 0);
620
621     } else {
622         /* Pack item with label vertically */
623         priv->box = gtk_vbox_new (FALSE, HILDON_MARGIN_DOUBLE);
624         gtk_container_add (GTK_CONTAINER (priv->event_box), priv->box);
625         gtk_box_pack_start (GTK_BOX (priv->box), priv->label, TRUE, TRUE, 0);
626
627         if (priv->progressbar)
628             gtk_box_pack_start (GTK_BOX (priv->box), priv->progressbar, FALSE, FALSE, 0);
629     }
630
631     gtk_container_add (GTK_CONTAINER (dialog->vbox), priv->event_box);
632
633     gtk_widget_show_all (priv->event_box);
634 }
635
636 /**
637  * hildon_note_new_confirmation_add_buttons:
638  * @parent: the parent window. The X window ID of the parent window
639  *   has to be the same as the X window ID of the application. This is
640  *   important so that the window manager could handle the windows
641  *   correctly.
642  *   In GTK the X window ID can be checked using
643  *   GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
644  * @description: the message to confirm
645  * @Varargs: arguments pairs for new buttons(label and return value). 
646  *   Terminate the list with %NULL value.
647  * 
648  * Create a new confirmation note with custom buttons. Confirmation
649  * note has a text and any number of buttons. It's important to note
650  * that even though the name of the function might suggest, the
651  * default ok/cancel buttons are not appended but you have to provide
652  * all of the buttons.
653  *
654  * FIXME: This doc seems to be wrong, the two buttons aren't added so
655  * it would only contain the "additional" buttons? However, changing
656  * this would break those applications that rely on current behaviour.
657  *
658  * Returns: A #GtkWidget pointer of the note
659  */
660 GtkWidget*
661 hildon_note_new_confirmation_add_buttons        (GtkWindow *parent,
662                                                  const gchar *description,
663                                                  ...)
664 {
665     va_list args;
666     char *message;
667     int value;
668     GtkWidget *button;
669
670     g_return_val_if_fail (description != NULL, NULL);
671
672     GtkWidget *conf_note =
673         g_object_new (HILDON_TYPE_NOTE,
674                 "note-type", HILDON_NOTE_TYPE_CONFIRMATION_BUTTON,
675                 "description", description,
676                 NULL);
677
678     if (parent != NULL)
679         gtk_window_set_transient_for (GTK_WINDOW (conf_note), parent);
680
681     /* Add the buttons from varargs */
682     va_start(args, description);
683
684     while (TRUE) {
685         message = va_arg (args, char *);
686
687         if (! message) {
688             break;
689         }
690         value = va_arg (args, int);
691
692         button = gtk_dialog_add_button (GTK_DIALOG (conf_note), message, value);
693         /* maemo-gtk is going to set the "no-show-all" property all
694            cancel/close-like buttons to TRUE, so that they are not shown. On
695            the other hand, this confirmation note with custom buttons should
696            not obey this rule, so we need to make sure they are shown. */
697         gtk_widget_show (button);
698         gtk_widget_set_no_show_all (button, FALSE);
699     }
700
701     va_end (args);
702
703     return conf_note;
704 }
705
706
707 /**
708  * hildon_note_new_confirmation:
709  * @parent: the parent window. The X window ID of the parent window
710  *   has to be the same as the X window ID of the application. This is
711  *   important so that the window manager could handle the windows
712  *   correctly. In GTK the X window ID can be checked using
713  *   GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
714  * @description: the message to confirm
715  *
716  * Create a new confirmation note. Confirmation note has a text (description)
717  * that you specify and two buttons.
718  *
719  * Returns: a #GtkWidget pointer of the note
720  */
721 GtkWidget*
722 hildon_note_new_confirmation                    (GtkWindow *parent,
723                                                  const gchar *description)
724 {
725     GtkWidget *dialog = NULL;
726
727     g_return_val_if_fail (description != NULL, NULL);
728
729     dialog = g_object_new (HILDON_TYPE_NOTE,
730             "note-type",
731             HILDON_NOTE_TYPE_CONFIRMATION,
732             "description", description, NULL);
733
734     if (parent != NULL)
735         gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
736
737     return dialog;
738 }
739
740 /**
741  * hildon_note_new_confirmation_with_icon_name:
742  * @parent: the parent window. The X window ID of the parent window
743  *   has to be the same as the X window ID of the application. This is
744  *   important so that the window manager could handle the windows
745  *   correctly. In GTK the X window ID can be checked using
746  *   GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
747  * @description: the message to confirm
748  * @icon_name: icon to be displayed. If NULL, default icon is used.
749  * 
750  * Create a new confirmation note. Confirmation note has a text (description) 
751  * that you specify and two buttons.
752  *
753  * Deprecated: Since 2.2, icons are not shown in confirmation notes. Icons set
754  * with this function will be ignored. Use hildon_note_new_confirmation() instead.
755  *
756  * Returns: a #GtkWidget pointer of the note
757  */
758 GtkWidget*
759 hildon_note_new_confirmation_with_icon_name     (GtkWindow *parent,
760                                                  const gchar *description,
761                                                  const gchar *icon_name)
762 {
763   return hildon_note_new_confirmation (parent, description);
764 }
765
766 /**
767  * hildon_note_new_information:
768  * @parent: the parent window. The X window ID of the parent window
769  *   has to be the same as the X window ID of the application. This is
770  *   important so that the window manager could handle the windows
771  *   correctly. In GTK the X window ID can be checked using
772  *   GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
773  * @description: the message to confirm
774  * 
775  * Create a new information note. Information note has a text (description)
776  * that you specify and an OK button.
777  * 
778  * Returns: a #GtkWidget pointer of the note
779  */
780 GtkWidget*
781 hildon_note_new_information                     (GtkWindow *parent,
782                                                  const gchar *description)
783 {
784     GtkWidget *dialog = NULL;
785
786     g_return_val_if_fail (description != NULL, NULL);
787
788     dialog = g_object_new (HILDON_TYPE_NOTE,
789             "note-type",
790             HILDON_NOTE_TYPE_INFORMATION_THEME,
791             "description", description, NULL);
792
793     if (parent != NULL)
794         gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
795
796     return dialog;
797 }
798
799 /**
800  * hildon_note_new_information_with_icon_name:
801  * @parent: the parent window. The X window ID of the parent window
802  *   has to be the same as the X window ID of the application. This is
803  *   important so that the window manager could handle the windows
804  *   correctly. In GTK the X window ID can be checked using
805  *   GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
806  * @description: the message to confirm
807  * @icon_name: icon to be displayed. If NULL, default icon is used.
808  * 
809  * Create a new information note. Information note has text(description) 
810  * that you specify, an OK button and an icon.
811  * 
812  * Deprecated: Since 2.2, icons are not shown in confirmation notes. Icons set
813  * with this function will be ignored. Use hildon_note_new_information() instead.
814  *
815  * Returns: a #GtkWidget pointer of the note
816  */
817 GtkWidget*
818 hildon_note_new_information_with_icon_name      (GtkWindow * parent,
819                                                  const gchar *description,
820                                                  const gchar *icon_name)
821 {
822     return hildon_note_new_information (parent, description);
823 }
824
825 /* FIXME This documentation string LIES! */
826
827 /**
828  * hildon_note_new_cancel_with_progress_bar:
829  * @parent: the parent window. The X window ID of the parent window
830  *   has to be the same as the X window ID of the application. This is
831  *   important so that the window manager could handle the windows
832  *   correctly. In GTK the X window ID can be checked using
833  *   GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
834  * @description: the action to cancel
835  * @progressbar: a pointer to #GtkProgressBar to be filled with the
836  *   progressbar assigned to this note. Use this to set the fraction of
837  *   progressbar done. This parameter can be %NULL as well, in which
838  *   case plain text cancel note appears.
839  *
840  * Create a new cancel note with a progress bar. Cancel note has 
841  * text(description) that you specify, a Cancel button and a progress bar.
842  *
843  * Returns: a #GtkDialog. Use this to get rid of this note when you
844  *   no longer need it.
845  */
846 GtkWidget*
847 hildon_note_new_cancel_with_progress_bar        (GtkWindow *parent,
848                                                  const gchar *description,
849                                                  GtkProgressBar *progressbar)
850 {
851     GtkWidget *dialog = NULL;
852
853     g_return_val_if_fail (description != NULL, NULL);
854
855     dialog = g_object_new (HILDON_TYPE_NOTE,
856             "note-type",
857             HILDON_NOTE_TYPE_PROGRESSBAR,
858             "description", description,
859             "progressbar",
860             progressbar, NULL);
861
862     if (parent != NULL)
863         gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
864
865     return dialog;
866 }
867
868
869 /**
870  * hildon_note_set_button_text:
871  * @note: a #HildonNote
872  * @text: sets the button text and if there is two buttons in dialog, 
873  *   the button texts will be &lt;text&gt;, "Cancel".  
874  *
875  * Sets the button text to be used by the hildon_note widget.
876  */
877 void 
878 hildon_note_set_button_text                     (HildonNote *note, 
879                                                  const gchar *text)
880 {
881     HildonNotePrivate *priv;
882
883     g_return_if_fail (HILDON_IS_NOTE (note));
884
885     priv = HILDON_NOTE_GET_PRIVATE (HILDON_NOTE (note));
886     g_assert (priv);
887
888     if (priv->okButton) {
889         gtk_button_set_label (GTK_BUTTON (priv->okButton), text);
890         gtk_button_set_label (GTK_BUTTON (priv->cancelButton),
891                 _("wdgt_bd_no"));
892     } else {
893         gtk_button_set_label (GTK_BUTTON (priv->cancelButton), text);
894     }
895 }
896
897 /**
898  * hildon_note_set_button_texts:
899  * @note: a #HildonNote
900  * @text_ok: the new text of the default OK button
901  * @text_cancel: the new text of the default cancel button 
902  *
903  * Sets the button texts to be used by this hildon_note widget.
904  */
905 void 
906 hildon_note_set_button_texts                    (HildonNote *note,
907                                                  const gchar *text_ok,
908                                                  const gchar *text_cancel)
909 {
910     HildonNotePrivate *priv;
911
912     g_return_if_fail (HILDON_IS_NOTE (note));
913
914     priv = HILDON_NOTE_GET_PRIVATE (HILDON_NOTE (note));
915     g_assert (priv);
916
917     if (priv->okButton) {
918         gtk_button_set_label (GTK_BUTTON (priv->okButton), text_ok);
919         gtk_button_set_label (GTK_BUTTON (priv->cancelButton), text_cancel);
920     } else {
921         gtk_button_set_label (GTK_BUTTON (priv->cancelButton), text_cancel);
922     }
923 }
924
925 /* We play a system sound when the note comes visible */
926 static gboolean
927 sound_handling                                  (GtkWidget *widget, 
928                                                  GdkEventExpose *event, 
929                                                  gpointer data)
930 {
931     HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE (widget);
932     g_assert (priv);
933
934     g_signal_handler_disconnect (widget, priv->sound_signal_handler);
935
936     priv->sound_signal_handler = 0;
937
938     switch (priv->note_n)
939     {
940         case HILDON_NOTE_TYPE_INFORMATION:
941         case HILDON_NOTE_TYPE_INFORMATION_THEME:
942             hildon_play_system_sound (INFORMATION_SOUND_PATH);
943             break;
944
945         case HILDON_NOTE_TYPE_CONFIRMATION:
946         case HILDON_NOTE_TYPE_CONFIRMATION_BUTTON:
947             hildon_play_system_sound (CONFIRMATION_SOUND_PATH);
948             break;
949
950         default:
951             break;
952     };
953
954     return FALSE;
955 }