]> Pileus Git - ~andy/gtk/blob - gtk/gtkmessagedialog.c
9b3306328025d352c76dea73a73d2b5cbaa4a830
[~andy/gtk] / gtk / gtkmessagedialog.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 2 -*- */
2 /* GTK - The GIMP Toolkit
3  * Copyright (C) 2000 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 /*
22  * Modified by the GTK+ Team and others 1997-2003.  See the AUTHORS
23  * file for a list of people on the GTK+ Team.  See the ChangeLog
24  * files for a list of changes.  These files are distributed with
25  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
26  */
27
28 #include <config.h>
29 #include <string.h>
30
31 #include "gtkmessagedialog.h"
32 #include "gtklabel.h"
33 #include "gtkhbox.h"
34 #include "gtkvbox.h"
35 #include "gtkimage.h"
36 #include "gtkstock.h"
37 #include "gtkiconfactory.h"
38 #include "gtkintl.h"
39 #include "gtkprivate.h"
40 #include "gtkalias.h"
41
42 #define GTK_MESSAGE_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_MESSAGE_DIALOG, GtkMessageDialogPrivate))
43
44 typedef struct _GtkMessageDialogPrivate GtkMessageDialogPrivate;
45
46 struct _GtkMessageDialogPrivate
47 {
48   GtkWidget *secondary_label;
49   guint message_type : 3;
50   guint has_primary_markup : 1;
51   guint has_secondary_text : 1;
52 };
53
54 static void gtk_message_dialog_style_set  (GtkWidget             *widget,
55                                            GtkStyle              *prev_style);
56
57 static void gtk_message_dialog_set_property (GObject          *object,
58                                              guint             prop_id,
59                                              const GValue     *value,
60                                              GParamSpec       *pspec);
61 static void gtk_message_dialog_get_property (GObject          *object,
62                                              guint             prop_id,
63                                              GValue           *value,
64                                              GParamSpec       *pspec);
65 static void gtk_message_dialog_add_buttons  (GtkMessageDialog *message_dialog,
66                                              GtkButtonsType    buttons);
67
68 enum {
69   PROP_0,
70   PROP_MESSAGE_TYPE,
71   PROP_BUTTONS,
72   PROP_TEXT,
73   PROP_USE_MARKUP,
74   PROP_SECONDARY_TEXT,
75   PROP_SECONDARY_USE_MARKUP,
76   PROP_IMAGE
77 };
78
79 G_DEFINE_TYPE (GtkMessageDialog, gtk_message_dialog, GTK_TYPE_DIALOG)
80
81 static void
82 gtk_message_dialog_class_init (GtkMessageDialogClass *class)
83 {
84   GtkWidgetClass *widget_class;
85   GObjectClass *gobject_class;
86
87   widget_class = GTK_WIDGET_CLASS (class);
88   gobject_class = G_OBJECT_CLASS (class);
89   
90   widget_class->style_set = gtk_message_dialog_style_set;
91
92   gobject_class->set_property = gtk_message_dialog_set_property;
93   gobject_class->get_property = gtk_message_dialog_get_property;
94   
95   gtk_widget_class_install_style_property (widget_class,
96                                            g_param_spec_int ("message-border",
97                                                              P_("Image/label border"),
98                                                              P_("Width of border around the label and image in the message dialog"),
99                                                              0,
100                                                              G_MAXINT,
101                                                              12,
102                                                              GTK_PARAM_READABLE));
103   /**
104    * GtkMessageDialog:use-separator:
105    *
106    * Whether to draw a separator line between the message label and the buttons
107    * in the dialog.
108    *
109    * Since: 2.4
110    */
111   gtk_widget_class_install_style_property (widget_class,
112                                            g_param_spec_boolean ("use-separator",
113                                                                  P_("Use separator"),
114                                                                  P_("Whether to put a separator between the message dialog's text and the buttons"),
115                                                                  FALSE,
116                                                                  GTK_PARAM_READABLE));
117   /**
118    * GtkMessageDialog:message-type:
119    *
120    * The type of the message. The type is used to determine
121    * the image that is shown in the dialog, unless the image is 
122    * explicitly set by the ::image property.
123    */
124   g_object_class_install_property (gobject_class,
125                                    PROP_MESSAGE_TYPE,
126                                    g_param_spec_enum ("message-type",
127                                                       P_("Message Type"),
128                                                       P_("The type of message"),
129                                                       GTK_TYPE_MESSAGE_TYPE,
130                                                       GTK_MESSAGE_INFO,
131                                                       GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
132   g_object_class_install_property (gobject_class,
133                                    PROP_BUTTONS,
134                                    g_param_spec_enum ("buttons",
135                                                       P_("Message Buttons"),
136                                                       P_("The buttons shown in the message dialog"),
137                                                       GTK_TYPE_BUTTONS_TYPE,
138                                                       GTK_BUTTONS_NONE,
139                                                       GTK_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
140
141   /**
142    * GtkMessageDialog:text:
143    * 
144    * The primary text of the message dialog. If the dialog has 
145    * a secondary text, this will appear as the title.
146    *
147    * Since: 2.10
148    */
149   g_object_class_install_property (gobject_class,
150                                    PROP_TEXT,
151                                    g_param_spec_string ("text",
152                                                         P_("Text"),
153                                                         P_("The primary text of the message dialog"),
154                                                         NULL,
155                                                         GTK_PARAM_READWRITE));
156
157   /**
158    * GtkMessageDialog:use-markup:
159    * 
160    * %TRUE if the primary text of the dialog includes Pango markup. 
161    * See pango_parse_markup(). 
162    *
163    * Since: 2.10
164    */
165   g_object_class_install_property (gobject_class,
166                                    PROP_USE_MARKUP,
167                                    g_param_spec_boolean ("use-markup",
168                                                          P_("Use Markup"),
169                                                          P_("The primary text of the title includes Pango markup."),
170                                                          FALSE,
171                                                          GTK_PARAM_READWRITE));
172   
173   /**
174    * GtkMessageDialog:secondary-text:
175    * 
176    * The secondary text of the message dialog. 
177    *
178    * Since: 2.10
179    */
180   g_object_class_install_property (gobject_class,
181                                    PROP_SECONDARY_TEXT,
182                                    g_param_spec_string ("secondary-text",
183                                                         P_("Secondary Text"),
184                                                         P_("The secondary text of the message dialog"),
185                                                         NULL,
186                                                         GTK_PARAM_READWRITE));
187
188   /**
189    * GtkMessageDialog:secondary-use-markup:
190    * 
191    * %TRUE if the secondary text of the dialog includes Pango markup. 
192    * See pango_parse_markup(). 
193    *
194    * Since: 2.10
195    */
196   g_object_class_install_property (gobject_class,
197                                    PROP_SECONDARY_USE_MARKUP,
198                                    g_param_spec_boolean ("secondary-use-markup",
199                                                          P_("Use Markup in secondary"),
200                                                          P_("The secondary text includes Pango markup."),
201                                                          FALSE,
202                                                          GTK_PARAM_READWRITE));
203
204   /**
205    * GtkMessageDialog:image:
206    * 
207    * The image for this dialog.
208    *
209    * Since: 2.10
210    */
211   g_object_class_install_property (gobject_class,
212                                    PROP_IMAGE,
213                                    g_param_spec_object ("image",
214                                                         P_("Image"),
215                                                         P_("The image"),
216                                                         GTK_TYPE_WIDGET,
217                                                         GTK_PARAM_READWRITE));
218
219   g_type_class_add_private (gobject_class,
220                             sizeof (GtkMessageDialogPrivate));
221 }
222
223 static void
224 gtk_message_dialog_init (GtkMessageDialog *dialog)
225 {
226   GtkWidget *hbox, *vbox;
227   GtkMessageDialogPrivate *priv;
228
229   priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (dialog);
230
231   gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
232   gtk_window_set_title (GTK_WINDOW (dialog), "");
233   gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), TRUE);
234
235   priv->has_primary_markup = FALSE;
236   priv->has_secondary_text = FALSE;
237   priv->secondary_label = gtk_label_new (NULL);
238   gtk_widget_set_no_show_all (priv->secondary_label, TRUE);
239   
240   dialog->label = gtk_label_new (NULL);
241   dialog->image = gtk_image_new_from_stock (NULL, GTK_ICON_SIZE_DIALOG);
242   gtk_misc_set_alignment (GTK_MISC (dialog->image), 0.5, 0.0);
243   
244   gtk_label_set_line_wrap  (GTK_LABEL (dialog->label), TRUE);
245   gtk_label_set_selectable (GTK_LABEL (dialog->label), TRUE);
246   gtk_misc_set_alignment   (GTK_MISC  (dialog->label), 0.0, 0.0);
247   
248   gtk_label_set_line_wrap  (GTK_LABEL (priv->secondary_label), TRUE);
249   gtk_label_set_selectable (GTK_LABEL (priv->secondary_label), TRUE);
250   gtk_misc_set_alignment   (GTK_MISC  (priv->secondary_label), 0.0, 0.0);
251
252   hbox = gtk_hbox_new (FALSE, 12);
253   vbox = gtk_vbox_new (FALSE, 12);
254
255   gtk_box_pack_start (GTK_BOX (vbox), dialog->label,
256                       FALSE, FALSE, 0);
257
258   gtk_box_pack_start (GTK_BOX (vbox), priv->secondary_label,
259                       TRUE, TRUE, 0);
260
261   gtk_box_pack_start (GTK_BOX (hbox), dialog->image,
262                       FALSE, FALSE, 0);
263
264   gtk_box_pack_start (GTK_BOX (hbox), vbox,
265                       TRUE, TRUE, 0);
266
267   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
268                       hbox,
269                       FALSE, FALSE, 0);
270
271   gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
272   gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
273   gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 14); /* 14 + 2 * 5 = 24 */
274   gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 5);
275   gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 6);
276
277   gtk_widget_show_all (hbox);
278
279   _gtk_dialog_set_ignore_separator (GTK_DIALOG (dialog), TRUE);
280 }
281
282 static void
283 setup_primary_label_font (GtkMessageDialog *dialog)
284 {
285   gint size;
286   PangoFontDescription *font_desc;
287   GtkMessageDialogPrivate *priv;
288
289   priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (dialog);
290
291   /* unset the font settings */
292   gtk_widget_modify_font (dialog->label, NULL);
293
294   if (priv->has_secondary_text && !priv->has_primary_markup)
295     {
296       size = pango_font_description_get_size (dialog->label->style->font_desc);
297       font_desc = pango_font_description_new ();
298       pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
299       pango_font_description_set_size (font_desc, size * PANGO_SCALE_LARGE);
300       gtk_widget_modify_font (dialog->label, font_desc);
301       pango_font_description_free (font_desc);
302     }
303 }
304
305 static void
306 setup_type (GtkMessageDialog *dialog,
307             GtkMessageType    type)
308 {
309   GtkMessageDialogPrivate *priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (dialog);
310   const gchar *stock_id = NULL;
311  
312   priv->message_type = type;
313
314   switch (type)
315     {
316     case GTK_MESSAGE_INFO:
317       stock_id = GTK_STOCK_DIALOG_INFO;
318       break;
319
320     case GTK_MESSAGE_QUESTION:
321       stock_id = GTK_STOCK_DIALOG_QUESTION;
322       break;
323
324     case GTK_MESSAGE_WARNING:
325       stock_id = GTK_STOCK_DIALOG_WARNING;
326       break;
327       
328     case GTK_MESSAGE_ERROR:
329       stock_id = GTK_STOCK_DIALOG_ERROR;
330       break;
331
332     case GTK_MESSAGE_OTHER:
333       break;
334
335     default:
336       g_warning ("Unknown GtkMessageType %u", type);
337       break;
338     }
339
340   if (stock_id)
341     gtk_image_set_from_stock (GTK_IMAGE (dialog->image), stock_id,
342                               GTK_ICON_SIZE_DIALOG);
343 }
344
345 static void 
346 gtk_message_dialog_set_property (GObject      *object,
347                                  guint         prop_id,
348                                  const GValue *value,
349                                  GParamSpec   *pspec)
350 {
351   GtkMessageDialog *dialog;
352   GtkMessageDialogPrivate *priv;
353
354   dialog = GTK_MESSAGE_DIALOG (object);
355   priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (dialog);
356   
357   switch (prop_id)
358     {
359     case PROP_MESSAGE_TYPE:
360       setup_type (dialog, g_value_get_enum (value));
361       break;
362     case PROP_BUTTONS:
363       gtk_message_dialog_add_buttons (dialog, g_value_get_enum (value));
364       break;
365     case PROP_TEXT:
366       if (priv->has_primary_markup)
367         gtk_label_set_markup (GTK_LABEL (dialog->label), 
368                               g_value_get_string (value));
369       else
370         gtk_label_set_text (GTK_LABEL (dialog->label), 
371                             g_value_get_string (value));
372       break;
373     case PROP_USE_MARKUP:
374       priv->has_primary_markup = g_value_get_boolean (value) != FALSE;
375       gtk_label_set_use_markup (GTK_LABEL (dialog->label), 
376                                 priv->has_primary_markup);
377       setup_primary_label_font (dialog);
378       break;
379     case PROP_SECONDARY_TEXT:
380       {
381         const gchar *txt = g_value_get_string (value);
382         
383         if (gtk_label_get_use_markup (GTK_LABEL (priv->secondary_label)))
384           gtk_label_set_markup (GTK_LABEL (priv->secondary_label), txt);
385         else
386           gtk_label_set_text (GTK_LABEL (priv->secondary_label), txt);
387
388         if (txt)
389           {
390             priv->has_secondary_text = TRUE;
391             gtk_widget_show (priv->secondary_label);
392           }
393         else
394           {
395             priv->has_secondary_text = FALSE;
396             gtk_widget_hide (priv->secondary_label);
397           }
398         setup_primary_label_font (dialog);
399       }
400       break;
401     case PROP_SECONDARY_USE_MARKUP:
402       gtk_label_set_use_markup (GTK_LABEL (priv->secondary_label), 
403                                 g_value_get_boolean (value));
404       break;
405     case PROP_IMAGE:
406       gtk_message_dialog_set_image (dialog, (GtkWidget *)g_value_get_object (value));
407       break;
408
409     default:
410       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
411       break;
412     }
413 }
414
415 static void 
416 gtk_message_dialog_get_property (GObject     *object,
417                                  guint        prop_id,
418                                  GValue      *value,
419                                  GParamSpec  *pspec)
420 {
421   GtkMessageDialog *dialog;
422   GtkMessageDialogPrivate *priv;
423
424   dialog = GTK_MESSAGE_DIALOG (object);
425   priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (dialog);
426     
427   switch (prop_id)
428     {
429     case PROP_MESSAGE_TYPE:
430       g_value_set_enum (value, (GtkMessageType) priv->message_type);
431       break;
432     case PROP_TEXT:
433       g_value_set_string (value, gtk_label_get_label (GTK_LABEL (dialog->label)));
434       break;
435     case PROP_USE_MARKUP:
436       g_value_set_boolean (value, priv->has_primary_markup);
437       break;
438     case PROP_SECONDARY_TEXT:
439       if (priv->has_secondary_text)
440       g_value_set_string (value, 
441                           gtk_label_get_label (GTK_LABEL (priv->secondary_label)));
442       else
443         g_value_set_string (value, NULL);
444       break;
445     case PROP_SECONDARY_USE_MARKUP:
446       if (priv->has_secondary_text)
447         g_value_set_boolean (value, 
448                              gtk_label_get_use_markup (GTK_LABEL (priv->secondary_label)));
449       else
450         g_value_set_boolean (value, FALSE);
451       break;
452     case PROP_IMAGE:
453       g_value_set_object (value, dialog->image);
454       break;
455     default:
456       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
457       break;
458     }
459 }
460
461 /**
462  * gtk_message_dialog_new:
463  * @parent: transient parent, or %NULL for none 
464  * @flags: flags
465  * @type: type of message
466  * @buttons: set of buttons to use
467  * @message_format: printf()-style format string, or %NULL
468  * @Varargs: arguments for @message_format
469  * 
470  * Creates a new message dialog, which is a simple dialog with an icon
471  * indicating the dialog type (error, warning, etc.) and some text the
472  * user may want to see. When the user clicks a button a "response"
473  * signal is emitted with response IDs from #GtkResponseType. See
474  * #GtkDialog for more details.
475  * 
476  * Return value: a new #GtkMessageDialog
477  **/
478 GtkWidget*
479 gtk_message_dialog_new (GtkWindow     *parent,
480                         GtkDialogFlags flags,
481                         GtkMessageType type,
482                         GtkButtonsType buttons,
483                         const gchar   *message_format,
484                         ...)
485 {
486   GtkWidget *widget;
487   GtkDialog *dialog;
488   gchar* msg = NULL;
489   va_list args;
490
491   g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL);
492
493   widget = g_object_new (GTK_TYPE_MESSAGE_DIALOG,
494                          "message-type", type,
495                          "buttons", buttons,
496                          NULL);
497   dialog = GTK_DIALOG (widget);
498
499   if (flags & GTK_DIALOG_NO_SEPARATOR)
500     {
501       g_warning ("The GTK_DIALOG_NO_SEPARATOR flag cannot be used for GtkMessageDialog");
502       flags &= ~GTK_DIALOG_NO_SEPARATOR;
503     }
504
505   if (message_format)
506     {
507       va_start (args, message_format);
508       msg = g_strdup_vprintf (message_format, args);
509       va_end (args);
510
511       gtk_label_set_text (GTK_LABEL (GTK_MESSAGE_DIALOG (widget)->label),
512                           msg);
513
514       g_free (msg);
515     }
516
517   if (parent != NULL)
518     gtk_window_set_transient_for (GTK_WINDOW (widget),
519                                   GTK_WINDOW (parent));
520   
521   if (flags & GTK_DIALOG_MODAL)
522     gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
523
524   if (flags & GTK_DIALOG_DESTROY_WITH_PARENT)
525     gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
526
527   return widget;
528 }
529
530 /**
531  * gtk_message_dialog_new_with_markup:
532  * @parent: transient parent, or %NULL for none 
533  * @flags: flags
534  * @type: type of message
535  * @buttons: set of buttons to use
536  * @message_format: printf()-style format string, or %NULL
537  * @Varargs: arguments for @message_format
538  * 
539  * Creates a new message dialog, which is a simple dialog with an icon
540  * indicating the dialog type (error, warning, etc.) and some text which
541  * is marked up with the <link linkend="PangoMarkupFormat">Pango text markup language</link>.
542  * When the user clicks a button a "response" signal is emitted with
543  * response IDs from #GtkResponseType. See #GtkDialog for more details.
544  *
545  * Special XML characters in the printf() arguments passed to this
546  * function will automatically be escaped as necessary.
547  * (See g_markup_printf_escaped() for how this is implemented.)
548  * Usually this is what you want, but if you have an existing
549  * Pango markup string that you want to use literally as the
550  * label, then you need to use gtk_message_dialog_set_markup()
551  * instead, since you can't pass the markup string either
552  * as the format (it might contain '%' characters) or as a string
553  * argument.
554  *
555  * <informalexample><programlisting>
556  *  GtkWidget *dialog;
557  *  dialog = gtk_message_dialog_new (main_application_window,
558  *                                   GTK_DIALOG_DESTROY_WITH_PARENT,
559  *                                   GTK_MESSAGE_ERROR,
560  *                                   GTK_BUTTONS_CLOSE,
561  *                                   NULL);
562  *  gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog),
563  *                                 markup);
564  * </programlisting></informalexample>
565  * 
566  * Return value: a new #GtkMessageDialog
567  *
568  * Since: 2.4
569  **/
570 GtkWidget*
571 gtk_message_dialog_new_with_markup (GtkWindow     *parent,
572                                     GtkDialogFlags flags,
573                                     GtkMessageType type,
574                                     GtkButtonsType buttons,
575                                     const gchar   *message_format,
576                                     ...)
577 {
578   GtkWidget *widget;
579   va_list args;
580   gchar *msg = NULL;
581
582   g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL);
583
584   widget = gtk_message_dialog_new (parent, flags, type, buttons, NULL);
585
586   if (message_format)
587     {
588       va_start (args, message_format);
589       msg = g_markup_vprintf_escaped (message_format, args);
590       va_end (args);
591
592       gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (widget), msg);
593
594       g_free (msg);
595     }
596
597   return widget;
598 }
599
600 /**
601  * gtk_message_dialog_set_image:
602  * @dialog: a #GtkMessageDialog
603  * @image: the image
604  * 
605  * Sets the dialog's image to @image.
606  *
607  * Since: 2.10
608  **/
609 void
610 gtk_message_dialog_set_image (GtkMessageDialog *dialog,
611                               GtkWidget        *image)
612 {
613   GtkMessageDialogPrivate *priv;
614   GtkWidget *parent;
615
616   g_return_if_fail (GTK_IS_MESSAGE_DIALOG (dialog));
617
618   priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (dialog);
619
620   priv->message_type = GTK_MESSAGE_OTHER;
621   
622   parent = dialog->image->parent;
623   gtk_container_add (GTK_CONTAINER (parent), image);
624   gtk_container_remove (GTK_CONTAINER (parent), dialog->image);
625   gtk_box_reorder_child (GTK_BOX (parent), image, 0);
626
627   dialog->image = image;
628
629   g_object_notify (G_OBJECT (dialog), "image");
630 }
631
632 /**
633  * gtk_message_dialog_set_markup:
634  * @message_dialog: a #GtkMessageDialog
635  * @str: markup string (see <link linkend="PangoMarkupFormat">Pango markup format</link>)
636  * 
637  * Sets the text of the message dialog to be @str, which is marked
638  * up with the <link linkend="PangoMarkupFormat">Pango text markup
639  * language</link>.
640  *
641  * Since: 2.4
642  **/
643 void
644 gtk_message_dialog_set_markup (GtkMessageDialog *message_dialog,
645                                const gchar      *str)
646 {
647   GtkMessageDialogPrivate *priv;
648
649   g_return_if_fail (GTK_IS_MESSAGE_DIALOG (message_dialog));
650
651   priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (message_dialog);
652   priv->has_primary_markup = TRUE;
653   gtk_label_set_markup (GTK_LABEL (message_dialog->label), str);
654 }
655
656 /**
657  * gtk_message_dialog_format_secondary_text:
658  * @message_dialog: a #GtkMessageDialog
659  * @message_format: printf()-style format string, or %NULL
660  * @Varargs: arguments for @message_format
661  * 
662  * Sets the secondary text of the message dialog to be @message_format 
663  * (with printf()-style).
664  *
665  * Note that setting a secondary text makes the primary text become
666  * bold, unless you have provided explicit markup.
667  *
668  * Since: 2.6
669  **/
670 void
671 gtk_message_dialog_format_secondary_text (GtkMessageDialog *message_dialog,
672                                           const gchar      *message_format,
673                                           ...)
674 {
675   va_list args;
676   gchar *msg = NULL;
677   GtkMessageDialogPrivate *priv;
678
679   g_return_if_fail (GTK_IS_MESSAGE_DIALOG (message_dialog));
680
681   priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (message_dialog);
682
683   if (message_format)
684     {
685       priv->has_secondary_text = TRUE;
686
687       va_start (args, message_format);
688       msg = g_strdup_vprintf (message_format, args);
689       va_end (args);
690
691       gtk_widget_show (priv->secondary_label);
692       gtk_label_set_text (GTK_LABEL (priv->secondary_label), msg);
693
694       g_free (msg);
695     }
696   else
697     {
698       priv->has_secondary_text = FALSE;
699       gtk_widget_hide (priv->secondary_label);
700     }
701
702   setup_primary_label_font (message_dialog);
703 }
704
705 /**
706  * gtk_message_dialog_format_secondary_markup:
707  * @message_dialog: a #GtkMessageDialog
708  * @message_format: printf()-style markup string (see 
709      <link linkend="PangoMarkupFormat">Pango markup format</link>), or %NULL
710  * @Varargs: arguments for @message_format
711  * 
712  * Sets the secondary text of the message dialog to be @message_format (with 
713  * printf()-style), which is marked up with the 
714  * <link linkend="PangoMarkupFormat">Pango text markup language</link>.
715  *
716  * Note that setting a secondary text makes the primary text become
717  * bold, unless you have provided explicit markup.
718  *
719  * Due to an oversight, this function does not escape special XML characters
720  * like gtk_message_dialog_new_with_markup() does. Thus, if the arguments 
721  * may contain special XML characters, you should use g_markup_printf_escaped()
722  * to escape it.
723
724  * <informalexample><programlisting>
725  * gchar *msg;
726  *  
727  * msg = g_markup_printf_escaped (message_format, ...);
728  * gtk_message_dialog_format_secondary_markup (message_dialog, "&percnt;s", msg);
729  * g_free (msg);
730  * </programlisting></informalexample>
731  *
732  * Since: 2.6
733  **/
734 void
735 gtk_message_dialog_format_secondary_markup (GtkMessageDialog *message_dialog,
736                                             const gchar      *message_format,
737                                             ...)
738 {
739   va_list args;
740   gchar *msg = NULL;
741   GtkMessageDialogPrivate *priv;
742
743   g_return_if_fail (GTK_IS_MESSAGE_DIALOG (message_dialog));
744
745   priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (message_dialog);
746
747   if (message_format)
748     {
749       priv->has_secondary_text = TRUE;
750
751       va_start (args, message_format);
752       msg = g_strdup_vprintf (message_format, args);
753       va_end (args);
754
755       gtk_widget_show (priv->secondary_label);
756       gtk_label_set_markup (GTK_LABEL (priv->secondary_label), msg);
757
758       g_free (msg);
759     }
760   else
761     {
762       priv->has_secondary_text = FALSE;
763       gtk_widget_hide (priv->secondary_label);
764     }
765
766   setup_primary_label_font (message_dialog);
767 }
768
769 static void
770 gtk_message_dialog_add_buttons (GtkMessageDialog* message_dialog,
771                                 GtkButtonsType buttons)
772 {
773   GtkDialog* dialog = GTK_DIALOG (message_dialog);
774
775   switch (buttons)
776     {
777     case GTK_BUTTONS_NONE:
778       /* nothing */
779       break;
780
781     case GTK_BUTTONS_OK:
782       gtk_dialog_add_button (dialog,
783                              GTK_STOCK_OK,
784                              GTK_RESPONSE_OK);
785       break;
786
787     case GTK_BUTTONS_CLOSE:
788       gtk_dialog_add_button (dialog,
789                              GTK_STOCK_CLOSE,
790                              GTK_RESPONSE_CLOSE);
791       break;
792
793     case GTK_BUTTONS_CANCEL:
794       gtk_dialog_add_button (dialog,
795                              GTK_STOCK_CANCEL,
796                              GTK_RESPONSE_CANCEL);
797       break;
798
799     case GTK_BUTTONS_YES_NO:
800       gtk_dialog_add_button (dialog,
801                              GTK_STOCK_NO,
802                              GTK_RESPONSE_NO);
803       gtk_dialog_add_button (dialog,
804                              GTK_STOCK_YES,
805                              GTK_RESPONSE_YES);
806       gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
807                                                GTK_RESPONSE_YES,
808                                                GTK_RESPONSE_NO,
809                                                -1);
810       break;
811
812     case GTK_BUTTONS_OK_CANCEL:
813       gtk_dialog_add_button (dialog,
814                              GTK_STOCK_CANCEL,
815                              GTK_RESPONSE_CANCEL);
816       gtk_dialog_add_button (dialog,
817                              GTK_STOCK_OK,
818                              GTK_RESPONSE_OK);
819       gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
820                                                GTK_RESPONSE_OK,
821                                                GTK_RESPONSE_CANCEL,
822                                                -1);
823       break;
824       
825     default:
826       g_warning ("Unknown GtkButtonsType");
827       break;
828     } 
829
830   g_object_notify (G_OBJECT (message_dialog), "buttons");
831 }
832
833 static void
834 gtk_message_dialog_style_set (GtkWidget *widget,
835                               GtkStyle  *prev_style)
836 {
837   GtkMessageDialog *dialog = GTK_MESSAGE_DIALOG (widget);
838   gboolean use_separator;
839   GtkWidget *parent;
840   gint border_width;
841
842   parent = GTK_WIDGET (GTK_MESSAGE_DIALOG (widget)->image->parent);
843
844   if (parent)
845     {
846       gtk_widget_style_get (widget, "message-border",
847                             &border_width, NULL);
848       
849       gtk_container_set_border_width (GTK_CONTAINER (parent),
850                                       MAX (0, border_width - 7));
851     }
852
853   gtk_widget_style_get (widget,
854                         "use-separator", &use_separator,
855                         NULL);
856
857   _gtk_dialog_set_ignore_separator (GTK_DIALOG (widget), FALSE);
858   gtk_dialog_set_has_separator (GTK_DIALOG (widget), use_separator);
859   _gtk_dialog_set_ignore_separator (GTK_DIALOG (widget), TRUE);
860
861   setup_primary_label_font (dialog);
862
863   if (GTK_WIDGET_CLASS (gtk_message_dialog_parent_class)->style_set)
864     (GTK_WIDGET_CLASS (gtk_message_dialog_parent_class)->style_set) (widget, prev_style);
865 }
866
867 #define __GTK_MESSAGE_DIALOG_C__
868 #include "gtkaliasdef.c"