2005-08-30 Tommi Komulainen <tommi.komulainen@nokia.com>
[hildon] / hildon-widgets / hildon-note.c
1 /*
2  * This file is part of hildon-libs
3  *
4  * Copyright (C) 2005 Nokia Corporation.
5  *
6  * Contact: Luc Pionchon <luc.pionchon@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; either 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  * @file hildon-note.c
27  *
28  * This file contains API for conformation, information
29  * and cancel notes. 
30  * 
31  * 9/2004 Removed animation type of cancel note as separate task.
32  */
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 #include "hildon-note.h"
39 #include <gtk/gtklabel.h>
40 #include <gtk/gtkimage.h>
41 #include <gtk/gtkhbox.h>
42 #include <gtk/gtkalignment.h>
43 #include <gtk/gtkvbox.h>
44 #include <gtk/gtkbutton.h>
45 #include <libintl.h>
46 #include <hildon-widgets/hildon-defines.h>
47
48 #include <stdio.h>
49 #include <string.h>
50 #include <unistd.h>
51 #include <signal.h>
52
53 #include <esd.h>
54
55 /* Can these be included from somewhere? */
56
57 #define OSSO_MEDIA_SERVICE "com.nokia.osso_media_server"
58 #define OSSO_MEDIA_PATH "/com/nokia/osso_media_server"
59 #define OSSO_MEDIA_INTERFACE "com.nokia.osso_media_server.sound"
60 #define OSSO_MEDIA_PLAY_METHOD "play_sound"
61
62 #define CONFIRMATION_SOUND_URI "file:///usr/share/sounds/"\
63                                 "ui-confirmation_note.wav"
64 #define CONFIRMATION_SOUND_PATH "/usr/share/sounds/ui-confirmation_note.wav"
65
66 #define INFORMATION_SOUND_URI "file:///usr/share/sounds/"\
67                                "ui-information_note.wav"
68 #define INFORMATION_SOUND_PATH "/usr/share/sounds/ui-information_note.wav"
69
70 #define HILDON_NOTE_CONFIRMATION_ICON        "qgn_note_confirm"
71 #define HILDON_NOTE_INFORMATION_ICON         "qgn_note_info"
72
73 #define ELLIPSATION_STRING "\342\200\246"
74 #define BOX_SPACING 10
75
76 /* Not exactly sure what this actually _should_ be, because there is
77    practically no documentation for the ESD... */
78
79 #define ESD_NAME "hildon-note-instance"
80
81 #define _(String) dgettext(PACKAGE, String)
82
83 static GtkDialogClass *parent_class;
84
85 #define HILDON_NOTE_GET_PRIVATE(obj)\
86  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
87   HILDON_TYPE_NOTE, HildonNotePrivate));
88
89 typedef struct _HildonNotePrivate HildonNotePrivate;
90
91 static void hildon_note_class_init(HildonNoteClass * class);
92 static void hildon_note_init(HildonNote * dialog);
93
94 static void hildon_note_create (HildonNote *note);
95 static void hildon_note_create_form(GtkDialog * dialog, GtkWidget * item,
96                                     gboolean IsHorizontal);
97 static void hildon_note_finalize(GObject * obj_self);
98 static void hildon_note_realize (GtkWidget *widget);
99
100 static GObject *hildon_note_constructor(GType type,
101                                         guint n_construct_properties,
102                                         GObjectConstructParam
103                                         * construct_properties);
104 static void hildon_note_set_property(GObject * object,
105                                      guint prop_id,
106                                      const GValue * value,
107                                      GParamSpec * pspec);
108 static void hildon_note_get_property(GObject * object,
109                                      guint prop_id,
110                                      GValue * value, GParamSpec * pspec);
111
112 static gboolean
113 sound_handling(GtkWidget * widget, gpointer data);
114
115 /* common measurement */
116 const int _HILDON_NOTE_CONFIRMATION_TEXT_MAX_WIDTH = 319; 
117
118 struct _HildonNotePrivate {
119     GtkWidget *okButton;
120     GtkWidget *cancelButton;
121     GtkWidget *label;
122     GtkWidget *box;
123
124     HildonNoteType note_n;
125     GtkWidget *progressbar;
126     gchar *icon;
127
128     gchar *original_description;
129
130     gboolean constructed;
131 };
132
133 enum {
134     PROP_NONE = 0,
135     PROP_HILDON_NOTE_TYPE,
136     PROP_HILDON_NOTE_DESCRIPTION,
137     PROP_HILDON_NOTE_ICON,
138     PROP_HILDON_NOTE_PROGRESSBAR
139 };
140
141 gulong sound_signal_handler = 0;
142
143 /* This function is just a modified version of two_lines_truncate
144  * in gtk-infoprint.c */
145 static void
146 hildon_note_five_line_truncate(const HildonNote * note, const gchar * text)
147 {
148     gchar *result = NULL;
149     PangoLayout *layout;
150     PangoContext *context;
151     gchar *str = NULL;
152     int max_width = _HILDON_NOTE_CONFIRMATION_TEXT_MAX_WIDTH;
153     HildonNotePrivate *priv;
154
155     priv = HILDON_NOTE_GET_PRIVATE(note);
156
157     if (priv->original_description != NULL)
158         g_free(priv->original_description);
159
160     priv->original_description = g_strdup(text);
161
162     if (text == NULL) {
163         str = g_strdup("");
164     } else {
165         str = g_strdup(text);
166     }
167
168     context = gtk_widget_get_pango_context(GTK_WIDGET(note));
169
170     {
171         gchar *lines[5] = { NULL, NULL, NULL, NULL, NULL };
172         guint current_line = 0;
173         guint last_line;
174
175         layout = pango_layout_new(context);
176         pango_layout_set_text(layout, str, -1);
177         pango_layout_set_width(layout, max_width * PANGO_SCALE);
178         pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
179         last_line = MIN(4, pango_layout_get_line_count(layout) - 1);
180
181         for (current_line = 0;
182              current_line <= last_line;
183              current_line++) {
184             PangoLayoutLine *line = pango_layout_get_line(layout,
185                                                           current_line);
186
187             if (current_line == last_line)
188                 lines[current_line] = g_strdup(str + line->start_index);
189             else
190                 lines[current_line] = g_strndup(str + line->start_index,
191                                                 line->length);
192
193             pango_layout_line_ref(line);
194             pango_layout_line_unref(line);
195         }
196
197         g_object_unref(layout);
198
199         layout = pango_layout_new(context);
200         pango_layout_set_text(layout, lines[last_line], -1);
201
202         {
203             PangoLayoutLine *line;
204             gint index = 0;
205
206             /* Here we ellipsize the last line... */
207             if (pango_layout_get_line_count(layout) > 1) {
208                 gchar *templine = NULL;
209
210                 line = pango_layout_get_line(layout, 0);
211                 templine = g_strndup(lines[last_line], line->length);
212                 g_free(lines[last_line]);
213                 lines[last_line] = g_strconcat(templine, ELLIPSATION_STRING, NULL);
214                 g_free(templine);
215             }
216
217             if (pango_layout_xy_to_index(layout,
218                                          max_width * PANGO_SCALE, 0,
219                                          &index, NULL) == TRUE) {
220                 gint ellipsiswidth;
221                 gchar *tempresult;
222                 PangoLayout *ellipsis = pango_layout_new(context);
223
224                 pango_layout_set_text(ellipsis, ELLIPSATION_STRING, -1);
225                 pango_layout_get_size(ellipsis, &ellipsiswidth, NULL);
226                 pango_layout_xy_to_index(layout,
227                                          max_width * PANGO_SCALE -
228                                          ellipsiswidth, 0, &index,
229                                          NULL);
230                 g_object_unref(G_OBJECT(ellipsis));
231                 tempresult = g_strndup(lines[last_line], index);
232                 lines[last_line] = g_strconcat(tempresult,
233                                                ELLIPSATION_STRING,
234                                                NULL);
235                 g_free(tempresult);
236             }
237         }
238
239         for (current_line = 0; current_line <= last_line; current_line++)
240             g_strchomp(lines[current_line]);
241
242         result = g_strconcat(lines[0], "\n",
243                              lines[1], "\n",
244                              lines[2], "\n",
245                              lines[3], "\n",
246                              lines[4], "\n", NULL);
247
248         for (current_line = 0; current_line <= last_line; current_line++)
249             g_free(lines[current_line]);
250
251         g_object_unref(layout);
252
253     }
254
255     if (result == NULL)
256         result = g_strdup(str);
257
258     gtk_label_set_text(GTK_LABEL(priv->label), result);
259
260     g_free(str);
261     g_free(result);
262
263 }
264
265 static void
266 hildon_note_one_line_truncate(const HildonNote * note, const gchar * text)
267 {
268     PangoLayout *layout;
269     PangoContext *context;
270     gchar *str = NULL;
271     int max_width = _HILDON_NOTE_CONFIRMATION_TEXT_MAX_WIDTH;
272     HildonNotePrivate *priv;
273     PangoLayoutLine *line;
274     gint index = 0;
275
276     priv = HILDON_NOTE_GET_PRIVATE(note);
277
278     if (priv->original_description != NULL)
279         g_free(priv->original_description);
280
281     priv->original_description = g_strdup(text);
282
283     str = g_strdup(text == NULL ? "" : text);
284     context = gtk_widget_get_pango_context(GTK_WIDGET(note));
285
286     layout = pango_layout_new(context);
287     pango_layout_set_text(layout, str, -1);
288     pango_layout_set_width(layout, max_width * PANGO_SCALE);
289     pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
290
291     if (pango_layout_get_line_count(layout) > 1) {
292         gchar *templine = NULL;
293
294         line = pango_layout_get_line(layout, 0);
295         templine = g_strndup(str, line->length);
296         g_free(str);
297         str = g_strconcat(templine, ELLIPSATION_STRING, NULL);
298         g_free(templine);
299     }
300
301     if (pango_layout_xy_to_index(layout,
302                                  max_width * PANGO_SCALE, 0,
303                                  &index, NULL) == TRUE) {
304         gint ellipsiswidth;
305         gchar *tempresult;
306         PangoLayout *ellipsis = pango_layout_new(context);
307
308         pango_layout_set_text(ellipsis, ELLIPSATION_STRING, -1);
309         pango_layout_get_size(ellipsis, &ellipsiswidth, NULL);
310         pango_layout_xy_to_index(layout,
311                                  max_width * PANGO_SCALE -
312                                  ellipsiswidth, 0, &index,
313                                  NULL);
314         g_object_unref(G_OBJECT(ellipsis));
315         tempresult = g_strndup(str, index);
316         str = g_strconcat(tempresult,
317                           ELLIPSATION_STRING,
318                           NULL);
319         g_free(tempresult);
320     }
321
322     g_object_unref(layout);
323     gtk_label_set_text(GTK_LABEL(priv->label), str);
324     g_free(str);
325 }
326
327 static void
328 hildon_note_set_property(GObject * object,
329                          guint prop_id,
330                          const GValue * value, GParamSpec * pspec)
331 {
332     HildonNote *note = HILDON_NOTE(object);
333     HildonNotePrivate *priv;
334
335     priv = HILDON_NOTE_GET_PRIVATE(note);
336
337     switch (prop_id) {
338     case PROP_HILDON_NOTE_TYPE:
339         priv->note_n = g_value_get_enum(value);
340         if (priv->constructed) {
341             hildon_note_create (note);
342         }
343         break;
344
345     case PROP_HILDON_NOTE_DESCRIPTION:
346         if (priv->note_n == HILDON_NOTE_PROGRESSBAR_TYPE)
347             hildon_note_one_line_truncate(note, g_value_get_string(value));
348         else
349             hildon_note_five_line_truncate(note, g_value_get_string(value));
350         break;
351
352     case PROP_HILDON_NOTE_ICON:
353         if( priv->icon )
354                 g_free(priv->icon);
355         priv->icon = g_value_dup_string(value);
356         if (priv->constructed) {
357             hildon_note_create (note);
358         }
359         break;
360
361     case PROP_HILDON_NOTE_PROGRESSBAR:
362         priv->progressbar = g_value_get_object(value);
363         if (priv->constructed) {
364             hildon_note_create (note);
365         }
366         break;
367
368     default:
369         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
370         break;
371     }
372 }
373
374 static void
375 hildon_note_get_property(GObject * object,
376                          guint prop_id, GValue * value, GParamSpec * pspec)
377 {
378     HildonNote *note = HILDON_NOTE(object);
379     HildonNotePrivate *priv;
380
381     priv = HILDON_NOTE_GET_PRIVATE(note);
382
383     switch (prop_id) {
384     case PROP_HILDON_NOTE_TYPE:
385         g_value_set_enum(value, priv->note_n);
386         break;
387
388     case PROP_HILDON_NOTE_DESCRIPTION:
389         if (priv->original_description != NULL) {
390             g_value_set_string(value, priv->original_description);
391         } else {
392             g_value_set_string(value, "");
393         }
394         break;
395
396     case PROP_HILDON_NOTE_ICON:
397         g_value_set_string(value, priv->icon);
398         break;
399
400     case PROP_HILDON_NOTE_PROGRESSBAR:
401         g_value_set_object(value, priv->progressbar);
402         break;
403
404     default:
405         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
406         break;
407     }
408 }
409
410 GType hildon_note_type_get_type (void)
411 {
412   static GType notetype = 0;
413   if (notetype == 0) {
414     static const GEnumValue values[] = {
415       { HILDON_NOTE_CONFIRMATION_TYPE,
416         "HILDON_NOTE_CONFIRMATION_TYPE", 
417         "confirmation" },
418       { HILDON_NOTE_CONFIRMATION_BUTTON_TYPE,
419         "HILDON_NOTE_CONFIRMATION_BUTTON_TYPE",
420         "confirmation-button" },
421       { HILDON_NOTE_INFORMATION_TYPE,
422         "HILDON_NOTE_INFORMATION_TYPE",
423         "note-information" },
424       { HILDON_NOTE_INFORMATION_THEME_TYPE,
425         "HILDON_NOTE_INFORMATION_THEME_TYPE",
426         "note-information-theme" },
427       { HILDON_NOTE_PROGRESSBAR_TYPE,
428         "HILDON_NOTE_PROGRESSBAR_TYPE",
429         "note-progressbar" },
430       { 0, NULL, NULL }
431     };
432     notetype = g_enum_register_static ("HildonNoteType", values);
433   }
434   return notetype;
435 }
436
437
438 GType hildon_note_get_type()
439 {
440     static GType dialog_type = 0;
441
442     if (!dialog_type) {
443         static const GTypeInfo dialog_info = {
444             sizeof(HildonNoteClass),
445             NULL,       /* base_init */
446             NULL,       /* base_finalize */
447             (GClassInitFunc) hildon_note_class_init,
448             NULL,       /* class_finalize */
449             NULL,       /* class_data */
450             sizeof(HildonNote),
451             0,  /* n_preallocs */
452             (GInstanceInitFunc) hildon_note_init
453         };
454         dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
455                                              "HildonNote",
456                                              &dialog_info, 0);
457     }
458     return dialog_type;
459 }
460
461 static GObject *hildon_note_constructor(GType type,
462                                         guint n_construct_properties,
463                                         GObjectConstructParam *
464                                         construct_properties)
465 {
466     GObject *dialog;
467     HildonNotePrivate *priv;
468
469     dialog = G_OBJECT_CLASS(parent_class)->constructor
470              (type, n_construct_properties, construct_properties);
471     priv = HILDON_NOTE_GET_PRIVATE(dialog);
472
473     hildon_note_create (HILDON_NOTE (dialog));
474
475     priv->constructed = TRUE;
476
477     return dialog;
478 }
479
480 static void hildon_note_class_init(HildonNoteClass * class)
481 {
482     GObjectClass *object_class = G_OBJECT_CLASS(class);
483     GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(class);
484
485     /* set the global parent_class */
486     parent_class = g_type_class_peek_parent(class);
487
488     g_type_class_add_private(class, sizeof(HildonNotePrivate));
489
490     object_class->finalize = hildon_note_finalize;
491
492     object_class->set_property = hildon_note_set_property;
493     object_class->get_property = hildon_note_get_property;
494     object_class->constructor = hildon_note_constructor;
495
496     widget_class->realize = hildon_note_realize;
497
498     g_object_class_install_property(object_class,
499         PROP_HILDON_NOTE_TYPE,
500         g_param_spec_enum("note_type",
501                           "note type",
502                           "The type of the note dialog",
503                           hildon_note_type_get_type(),
504                           HILDON_NOTE_CONFIRMATION_TYPE,
505                           G_PARAM_READWRITE));
506
507   /**
508    * HildonNote:description:
509    *
510    * Description for note.
511    */
512     g_object_class_install_property(object_class,
513         PROP_HILDON_NOTE_DESCRIPTION,
514         g_param_spec_string("description",
515                             "note description",
516                             "The text that appears in the note dialog",
517                             "",
518                             G_PARAM_READWRITE));
519
520   /**
521    * HildonNote:icon:
522    *
523    * Icon for note.
524    */
525     g_object_class_install_property(object_class,
526         PROP_HILDON_NOTE_ICON,
527         g_param_spec_string("icon",
528                             "note icon",
529                             "The name of the icon that appears in the note dialog",
530                             "",
531                             G_PARAM_READWRITE));
532
533   /**
534    * HildonNote:progressbar:
535    *
536    * Progresbar for note.
537    */
538     g_object_class_install_property(object_class,
539         PROP_HILDON_NOTE_PROGRESSBAR,
540         g_param_spec_object("progressbar",
541                             "Progressbar widget",
542                             "The progressbar that appear in the note dialog",
543                             GTK_TYPE_PROGRESS_BAR,
544                             G_PARAM_READWRITE));
545 }
546
547 static void hildon_note_init(HildonNote * dialog)
548 {
549     HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE(dialog);
550
551     priv->label = gtk_label_new(NULL);
552     priv->original_description = NULL;
553     priv->icon = NULL;
554     
555     gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
556     gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
557
558     /* Because ESD is synchronous, we wish to play sound after the
559        note is already on screen to avoid blocking its appearance */
560     sound_signal_handler = 
561       g_signal_connect_after(G_OBJECT(dialog), "expose-event",
562                              G_CALLBACK(sound_handling), dialog);
563 }
564
565
566 static void hildon_note_finalize(GObject * obj_self)
567 {
568     HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE(obj_self);
569
570     if(priv->icon)
571         g_free(priv->icon);
572
573     if (priv->original_description != NULL)
574         g_free(priv->original_description);
575
576     G_OBJECT_CLASS(parent_class)->finalize(obj_self);
577 }
578
579 static void
580 hildon_note_realize (GtkWidget *widget)
581 {
582     GTK_WIDGET_CLASS (parent_class)->realize (widget);
583
584     gdk_window_set_decorations (widget->window, GDK_DECOR_BORDER);
585 }
586
587 static void
588 hildon_note_create (HildonNote *note)
589 {
590     HildonNotePrivate *priv;
591     GtkWidget *item = NULL;
592     gboolean IsHorizontal = TRUE;
593
594     priv = HILDON_NOTE_GET_PRIVATE (note);
595
596     if (priv->okButton) {
597         gtk_container_remove (GTK_CONTAINER (priv->okButton->parent),
598                               priv->okButton);
599         priv->okButton = NULL;
600     }
601
602     if (priv->cancelButton) {
603         gtk_container_remove (GTK_CONTAINER (priv->cancelButton->parent),
604                               priv->cancelButton);
605         priv->cancelButton = NULL;
606     }
607
608     if (priv->progressbar && priv->progressbar->parent) {
609         gtk_container_remove (GTK_CONTAINER (priv->progressbar->parent),
610                               priv->progressbar);
611         priv->progressbar = NULL;
612     }
613
614     if (priv->note_n == HILDON_NOTE_CONFIRMATION_TYPE ||
615         priv->note_n == HILDON_NOTE_CONFIRMATION_BUTTON_TYPE ||
616         priv->note_n == HILDON_NOTE_INFORMATION_THEME_TYPE ||
617         priv->note_n == HILDON_NOTE_INFORMATION_TYPE) {
618
619         if (priv->note_n == HILDON_NOTE_CONFIRMATION_TYPE) {
620             /* ok button clickable with mouse or whatever */
621             priv->okButton = 
622                 gtk_dialog_add_button(GTK_DIALOG(note),
623                                       _("Ecdg_bd_confirmation_note_ok"),
624                                       GTK_RESPONSE_OK);
625             /* cancel button clickable with mouse or whatever */
626             priv->cancelButton =
627                 gtk_dialog_add_button(GTK_DIALOG(note),
628                                       _("Ecdg_bd_confirmation_note_cancel"),
629                                       GTK_RESPONSE_CANCEL);
630
631         } else if (priv->note_n == HILDON_NOTE_INFORMATION_TYPE || 
632                    priv->note_n == HILDON_NOTE_INFORMATION_THEME_TYPE ) {
633             priv->okButton = NULL;
634             /* cancel button clickable with mouse or whatever */
635             priv->cancelButton =
636                 gtk_dialog_add_button(GTK_DIALOG(note),
637                                       _("Ecdg_bd_information_note_ok"),
638                                       GTK_RESPONSE_CANCEL);
639         }
640
641         if ((priv->note_n == HILDON_NOTE_INFORMATION_TYPE ||
642             priv->note_n == HILDON_NOTE_INFORMATION_THEME_TYPE) && 
643                   priv->icon)
644         {
645             item = gtk_image_new_from_icon_name(priv->icon,
646                                             HILDON_ICON_SIZE_BIG_NOTE);
647         }
648         else {
649           if (priv->note_n == HILDON_NOTE_CONFIRMATION_TYPE ||
650             priv->note_n == HILDON_NOTE_CONFIRMATION_BUTTON_TYPE)
651           {
652             item = gtk_image_new_from_icon_name(HILDON_NOTE_CONFIRMATION_ICON, 
653                                                 HILDON_ICON_SIZE_BIG_NOTE);
654           } else {
655             item = gtk_image_new_from_icon_name(HILDON_NOTE_INFORMATION_ICON, 
656                                                 HILDON_ICON_SIZE_BIG_NOTE);
657             }
658         }
659
660     } else {
661         priv->cancelButton = 
662             gtk_dialog_add_button(GTK_DIALOG(note),
663                                   _("Ecdg_bd_cancel_note_cancel"),
664                                   GTK_RESPONSE_CANCEL);
665         IsHorizontal = FALSE;
666
667         item = priv->progressbar;
668     }
669
670     hildon_note_create_form(GTK_DIALOG(note), item, IsHorizontal);
671 }
672
673 static void
674 hildon_note_create_form(GtkDialog * dialog, GtkWidget * item,
675                         gboolean IsHorizontal)
676 {
677     HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE(dialog);
678
679     g_object_ref (priv->label);
680
681     if (priv->label->parent) {
682         gtk_container_remove (GTK_CONTAINER (priv->label->parent), priv->label);
683     }
684
685     if (priv->box) {
686         gtk_container_remove (GTK_CONTAINER (priv->box->parent), priv->box);
687         priv->box = NULL;
688     }
689
690     if (IsHorizontal) {
691         priv->box = gtk_hbox_new(FALSE, BOX_SPACING);
692         gtk_container_add(GTK_CONTAINER(dialog->vbox), priv->box);
693
694         if (item) {
695             GtkWidget *alignment = gtk_alignment_new(0, 0, 0, 0);
696
697             gtk_box_pack_start(GTK_BOX(priv->box), alignment, FALSE, FALSE, 0);
698             gtk_container_add(GTK_CONTAINER(alignment), item);
699         }
700         gtk_box_pack_start(GTK_BOX(priv->box), priv->label, FALSE, FALSE, 0);
701
702     } else {
703         priv->box = gtk_vbox_new(FALSE, BOX_SPACING);
704         gtk_container_add(GTK_CONTAINER(dialog->vbox), priv->box);
705         gtk_box_pack_start(GTK_BOX(priv->box), priv->label, FALSE, FALSE, 0);
706
707         if (item) {
708             gtk_box_pack_start(GTK_BOX(priv->box), item, FALSE, FALSE, 0);
709         }
710     }
711     
712     gtk_widget_show_all(priv->box);
713
714     g_object_unref (priv->label);
715 }
716
717 /**
718  * hildon_note_new_confirmation_add_buttons:
719  * @parent: The parent window. The X window ID of the parent window
720  *   has to be the same as the X window ID of the application. This is
721  *   important so that the window manager could handle the windows
722  *   correctly.
723  *   In GTK the X window ID can be checked with
724  *   GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
725  * @description: The message to confirm.
726  * @Varargs: Arguments pairs for new buttons(label and return value)
727  * 
728  * Create a new confirmation note. Confirmation note has a text, 
729  * two buttons and infinite number of additional buttons and an icon.
730  *
731  * Return value: A #GtkWidget pointer of the note.
732  */
733 GtkWidget *hildon_note_new_confirmation_add_buttons(GtkWindow * parent,
734                                                     const gchar *
735                                                     description, ...)
736 {
737     va_list args;
738     char *message = " ";
739     int value;
740
741     GtkWidget *conf_note =
742         g_object_new(HILDON_TYPE_NOTE,
743                      "note_type", HILDON_NOTE_CONFIRMATION_BUTTON_TYPE,
744                      "description", description,
745                      "icon", HILDON_NOTE_CONFIRMATION_ICON, 
746                      NULL);
747
748     g_return_val_if_fail(conf_note, FALSE);
749
750     if (parent != NULL)
751         gtk_window_set_transient_for(GTK_WINDOW(conf_note), parent);
752
753     va_start(args, description);
754
755     while (TRUE) {
756         message = va_arg(args, char *);
757
758         if (!message) {
759             break;
760         }
761         value = va_arg(args, int);
762
763         gtk_dialog_add_button(GTK_DIALOG(conf_note), message, value);
764     }
765
766     va_end(args);
767
768     return conf_note;
769 }
770
771
772 /**
773  * hildon_note_new_confirmation:
774  * @parent: The parent window. The X window ID of the parent window
775  *   has to be the same as the X window ID of the application. This is
776  *   important so that the window manager could handle the windows
777  *   correctly. In GTK the X window ID can be checked with
778  *   GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
779  * @description: The message to confirm.
780  * 
781  * Create a new confirmation note. Confirmation note has a text, 
782  * two buttons and an default confirmation stock icon.
783  *
784  * Return value: A #GtkWidget pointer of the note.
785  */
786 GtkWidget *hildon_note_new_confirmation(GtkWindow * parent,
787                                         const gchar * description)
788 {
789     return hildon_note_new_confirmation_with_icon_name
790         (parent, description, HILDON_NOTE_CONFIRMATION_ICON);
791 }
792
793
794 /**
795  * hildon_note_new_confirmation_with_icon_stock:
796  * @parent: The parent window. The X window ID of the parent window
797  *   has to be the same as the X window ID of the application. This is
798  *   important so that the window manager could handle the windows
799  *   correctly. In GTK the X window ID can be checked with
800  *   GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
801  * @description: The message to confirm.
802  * @stock_id: Icon to be displayed. If NULL, default icon is used.
803  * 
804  * Create a new confirmation note. Confirmation note has a text, 
805  * two buttons and an icon.
806  *
807  * Return value: A #GtkWidget pointer of the note.
808  */
809 GtkWidget *hildon_note_new_confirmation_with_icon_stock(GtkWindow * parent,
810                                                         const gchar *
811                                                         description,
812                                                         const gchar *
813                                                         stock_id)
814 {
815     GtkWidget *dialog = g_object_new(HILDON_TYPE_NOTE,
816                                      "note_type",
817                                      HILDON_NOTE_CONFIRMATION_TYPE,
818                                      "description", description, "icon",
819                                      stock_id, NULL);
820
821     if (parent != NULL)
822         gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
823
824     return dialog;
825 }
826
827 /**
828  * hildon_note_new_confirmation_with_icon_name:
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 with
833  *   GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
834  * @description: The message to confirm.
835  * @icon_name: Icon to be displayed. If NULL, default icon is used.
836  * 
837  * Create a new confirmation note. Confirmation note has a text, 
838  * two buttons and an icon.
839  *
840  * Return value: A #GtkWidget pointer of the note.
841  */
842 GtkWidget *hildon_note_new_confirmation_with_icon_name(GtkWindow * parent,
843                                                         const gchar *
844                                                         description,
845                                                         const gchar *
846                                                         icon_name)
847 {
848     GtkWidget *dialog = g_object_new(HILDON_TYPE_NOTE,
849                                      "note_type",
850                                      HILDON_NOTE_CONFIRMATION_TYPE,
851                                      "description", description, "icon",
852                                      icon_name, NULL);
853
854     if (parent != NULL)
855         gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
856
857     return dialog;
858 }
859
860 /**
861  * hildon_note_new_information:
862  * @parent: The parent window. The X window ID of the parent window
863  *   has to be the same as the X window ID of the application. This is
864  *   important so that the window manager could handle the windows
865  *   correctly. In GTK the X window ID can be checked with
866  *   GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
867  * @description: The message to confirm.
868  * 
869  * Create a new information note. Information note has a text,
870  * 'OK' labeled button and an icon.
871  * 
872  * Return value: A #GtkWidget pointer of the note.
873  */
874 GtkWidget *hildon_note_new_information(GtkWindow * parent,
875                                        const gchar * description)
876 {
877     return hildon_note_new_information_with_icon_stock
878         (parent, description, "qgn_note_info");
879 }
880
881 /**
882  * hildon_note_new_information_with_icon_stock:
883  * @parent: The parent window. The X window ID of the parent window
884  *   has to be the same as the X window ID of the application. This is
885  *   important so that the window manager could handle the windows
886  *   correctly. In GTK the X window ID can be checked with
887  *   GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
888  * @description: The message to confirm.
889  * @stock_id: Icon to be displayed. If NULL, default icon is used.
890  * 
891  * Create a new information note. Information note has a text,
892  * 'OK' labeled button and an icon.
893  * 
894  * Return value: A #GtkWidget pointer of the note.
895  */
896 GtkWidget *hildon_note_new_information_with_icon_stock(GtkWindow * parent,
897                                                        const gchar *
898                                                        description,
899                                                        const gchar *
900                                                        stock_id)
901 {
902     GtkWidget *dialog = g_object_new(HILDON_TYPE_NOTE,
903                                      "note_type",
904                                      HILDON_NOTE_INFORMATION_TYPE,
905                                      "description", description,
906                                      "icon", stock_id, NULL);
907
908     if (parent != NULL)
909         gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
910
911     return dialog;
912 }
913
914 /**
915  * hildon_note_new_information_with_icon_name:
916  * @parent: The parent window. The X window ID of the parent window
917  *   has to be the same as the X window ID of the application. This is
918  *   important so that the window manager could handle the windows
919  *   correctly. In GTK the X window ID can be checked with
920  *   GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
921  * @description: The message to confirm.
922  * @icon_name: Icon to be displayed. If NULL, default icon is used.
923  * 
924  * Create a new information note. Information note has a text,
925  * 'OK' labeled button and an icon.
926  * 
927  * Return value: A #GtkWidget pointer of the note.
928  */
929 GtkWidget *hildon_note_new_information_with_icon_name(GtkWindow * parent,
930                                                        const gchar *
931                                                        description,
932                                                        const gchar *
933                                                        icon_name)
934 {
935     GtkWidget *dialog = g_object_new(HILDON_TYPE_NOTE,
936                                      "note_type",
937                                      HILDON_NOTE_INFORMATION_THEME_TYPE,
938                                      "description", description,
939                                      "icon", icon_name, NULL);
940
941     if (parent != NULL)
942         gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
943
944     return dialog;
945 }
946
947 /**
948  * hildon_note_new_information_with_icon_theme:
949  * @parent: The parent window. The X window ID of the parent window
950  *   has to be the same as the X window ID of the application. This is
951  *   important so that the window manager could handle the windows
952  *   correctly. In GTK the X window ID can be checked with
953  *   GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
954  * @description: The message to confirm.
955  * @icon: #GtkIconTheme icon to be displayed.
956  * 
957  * Create a new information note. Information note has a text,
958  * 'OK' labeled button and an icon.
959  * 
960  * Return value: A #GtkWidget pointer of the note. 
961  * If NULL, default icon is used.
962  */
963 GtkWidget *hildon_note_new_information_with_icon_theme(GtkWindow *parent,
964                                                        const gchar *description,
965                                                        const gchar *icon)
966 {
967     GtkWidget *dialog = g_object_new(HILDON_TYPE_NOTE,
968                                      "note_type",
969                                      HILDON_NOTE_INFORMATION_THEME_TYPE,
970                                      "description", description,
971                                      "icon", icon, NULL);
972
973     if (parent != NULL)
974         gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
975
976     return dialog;
977 }
978
979 /**
980  * hildon_note_new_cancel_with_progress_bar:
981  * @parent: The parent window. The X window ID of the parent window
982  *   has to be the same as the X window ID of the application. This is
983  *   important so that the window manager could handle the windows
984  *   correctly. In GTK the X window ID can be checked with
985  *   GDK_WINDOW_XID(GTK_WIDGET(parent)->window).
986  * @description: The action to cancel.
987  * @progressbar: A pointer to #GtkProgressBar to be filled with the
988  *   progressbar assigned to this note. Use this to set the fraction of
989  *   progressbar done.
990  *
991  * Create a new cancel note with a progress bar. The note has a text,
992  * 'Cancel' labeled button and a progress bar.
993  *
994  * Return value: A #GtkDialog. Use this to get rid of this note when you
995  *   no longer need it.
996  */
997 GtkWidget *hildon_note_new_cancel_with_progress_bar(GtkWindow * parent,
998                                                     const gchar *
999                                                     description,
1000                                                     GtkProgressBar *
1001                                                     progressbar)
1002 {
1003     GtkWidget *dialog = g_object_new(HILDON_TYPE_NOTE,
1004                                      "note_type",
1005                                      HILDON_NOTE_PROGRESSBAR_TYPE,
1006                                      "description", description,
1007                                      "progressbar",
1008                                      progressbar, NULL);
1009
1010     if (parent != NULL)
1011         gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
1012
1013     return dialog;
1014 }
1015
1016
1017 /**
1018  * hildon_note_set_button_text:
1019  * @note: A #HildonNote
1020  * @text: Sets the button text and if there is two buttons in dialog, 
1021  *   the button texts will be &lt;text&gt;, "Cancel".  
1022  *
1023  * Sets the button text to be used by this hildon_note widget.
1024  */
1025 void hildon_note_set_button_text(HildonNote * note, const gchar * text)
1026 {
1027     HildonNotePrivate *priv;
1028
1029     priv = HILDON_NOTE_GET_PRIVATE(HILDON_NOTE(note));
1030     if (priv->okButton) {
1031         gtk_button_set_label(GTK_BUTTON(priv->okButton), text);
1032         gtk_button_set_label(GTK_BUTTON(priv->cancelButton),
1033                              _("Ecdg_bd_confirmation_note_cancel"));
1034     } else {
1035         gtk_button_set_label(GTK_BUTTON(priv->cancelButton), text);
1036     }
1037 }
1038
1039 /**
1040  * hildon_note_set_button_texts:
1041  * @note: A #HildonNote
1042  * @text: Sets the button text and if there is two buttons in dialog, 
1043  *   the button texts will be &lt;textOk&gt;, &lt;textCancel&gt;.  
1044  *
1045  * Sets the button texts to be used by this hildon_note widget.
1046  */
1047 void hildon_note_set_button_texts(HildonNote * note, const gchar * textOk,
1048                                  const gchar * textCancel)
1049 {
1050     HildonNotePrivate *priv;
1051
1052     priv = HILDON_NOTE_GET_PRIVATE(HILDON_NOTE(note));
1053     if (priv->okButton) {
1054       gtk_button_set_label(GTK_BUTTON(priv->okButton), textOk);
1055       gtk_button_set_label(GTK_BUTTON(priv->cancelButton),
1056                            textCancel);
1057     } else {
1058       gtk_button_set_label(GTK_BUTTON(priv->cancelButton), textCancel);
1059     }
1060 }
1061
1062
1063
1064 static gboolean
1065 sound_handling(GtkWidget * widget, gpointer data)
1066 {
1067   
1068   HildonNotePrivate *priv = HILDON_NOTE_GET_PRIVATE(HILDON_NOTE(widget));
1069
1070   if (priv->note_n != HILDON_NOTE_INFORMATION_TYPE &&
1071       priv->note_n != HILDON_NOTE_INFORMATION_THEME_TYPE &&
1072       priv->note_n != HILDON_NOTE_CONFIRMATION_TYPE &&
1073       priv->note_n != HILDON_NOTE_CONFIRMATION_BUTTON_TYPE)
1074     {
1075       g_signal_handler_disconnect(G_OBJECT(widget),
1076                                   sound_signal_handler);
1077       return FALSE;
1078     }
1079
1080   if (priv->note_n == HILDON_NOTE_INFORMATION_TYPE ||
1081       priv->note_n == HILDON_NOTE_INFORMATION_THEME_TYPE)
1082     {
1083       esd_play_file(ESD_NAME, INFORMATION_SOUND_PATH, 1);
1084
1085       g_signal_handler_disconnect(G_OBJECT(widget), sound_signal_handler);
1086       return FALSE;
1087     }
1088
1089     else if (priv->note_n == HILDON_NOTE_CONFIRMATION_TYPE ||
1090            priv->note_n ==  HILDON_NOTE_CONFIRMATION_BUTTON_TYPE)
1091     {
1092       esd_play_file(ESD_NAME, CONFIRMATION_SOUND_PATH, 1);
1093
1094       g_signal_handler_disconnect(G_OBJECT(widget), sound_signal_handler);
1095       return FALSE;
1096     }
1097   g_signal_handler_disconnect(G_OBJECT(widget), sound_signal_handler);
1098   return FALSE;
1099 }