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