gtkmessagedialog.c 27 KB
Newer Older
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 2 -*- */
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/* GTK - The GIMP Toolkit
 * Copyright (C) 2000 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
22
 * Modified by the GTK+ Team and others 1997-2003.  See the AUTHORS
23 24 25 26 27
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 */

28
#include <config.h>
29 30
#include <string.h>

31
#include "gtkmessagedialog.h"
Matthias Clasen's avatar
Matthias Clasen committed
32
#include "gtkaccessible.h"
33 34
#include "gtklabel.h"
#include "gtkhbox.h"
35
#include "gtkvbox.h"
36 37 38
#include "gtkimage.h"
#include "gtkstock.h"
#include "gtkiconfactory.h"
39
#include "gtkintl.h"
40
#include "gtkprivate.h"
41
#include "gtkalias.h"
42

43 44 45 46 47 48 49
#define GTK_MESSAGE_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_MESSAGE_DIALOG, GtkMessageDialogPrivate))

typedef struct _GtkMessageDialogPrivate GtkMessageDialogPrivate;

struct _GtkMessageDialogPrivate
{
  GtkWidget *secondary_label;
Matthias Clasen's avatar
Matthias Clasen committed
50 51 52
  guint message_type : 3;
  guint has_primary_markup : 1;
  guint has_secondary_text : 1;
53 54
};

55 56
static void gtk_message_dialog_style_set  (GtkWidget             *widget,
                                           GtkStyle              *prev_style);
57

58 59 60 61 62 63 64 65 66 67 68 69 70 71
static void gtk_message_dialog_set_property (GObject          *object,
					     guint             prop_id,
					     const GValue     *value,
					     GParamSpec       *pspec);
static void gtk_message_dialog_get_property (GObject          *object,
					     guint             prop_id,
					     GValue           *value,
					     GParamSpec       *pspec);
static void gtk_message_dialog_add_buttons  (GtkMessageDialog *message_dialog,
					     GtkButtonsType    buttons);

enum {
  PROP_0,
  PROP_MESSAGE_TYPE,
72 73 74 75
  PROP_BUTTONS,
  PROP_TEXT,
  PROP_USE_MARKUP,
  PROP_SECONDARY_TEXT,
Matthias Clasen's avatar
Matthias Clasen committed
76 77
  PROP_SECONDARY_USE_MARKUP,
  PROP_IMAGE
78 79
};

Matthias Clasen's avatar
Matthias Clasen committed
80
G_DEFINE_TYPE (GtkMessageDialog, gtk_message_dialog, GTK_TYPE_DIALOG)
81 82 83 84

static void
gtk_message_dialog_class_init (GtkMessageDialogClass *class)
{
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 94

  gobject_class->set_property = gtk_message_dialog_set_property;
  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 99
                                                             P_("Image/label border"),
                                                             P_("Width of border around the label and image in the message dialog"),
100 101
                                                             0,
                                                             G_MAXINT,
102
                                                             12,
103
                                                             GTK_PARAM_READABLE));
104
  /**
Matthias Clasen's avatar
Matthias Clasen committed
105
   * GtkMessageDialog:use-separator:
106 107 108 109 110 111
   *
   * Whether to draw a separator line between the message label and the buttons
   * in the dialog.
   *
   * Since: 2.4
   */
Federico Mena Quintero's avatar
Federico Mena Quintero committed
112
  gtk_widget_class_install_style_property (widget_class,
113
					   g_param_spec_boolean ("use-separator",
Federico Mena Quintero's avatar
Federico Mena Quintero committed
114 115 116
								 P_("Use separator"),
								 P_("Whether to put a separator between the message dialog's text and the buttons"),
								 FALSE,
117
								 GTK_PARAM_READABLE));
Matthias Clasen's avatar
Matthias Clasen committed
118 119 120 121 122 123 124
  /**
   * GtkMessageDialog:message-type:
   *
   * The type of the message. The type is used to determine
   * the image that is shown in the dialog, unless the image is 
   * explicitly set by the ::image property.
   */
125 126
  g_object_class_install_property (gobject_class,
                                   PROP_MESSAGE_TYPE,
127
                                   g_param_spec_enum ("message-type",
128 129
						      P_("Message Type"),
						      P_("The type of message"),
130 131
						      GTK_TYPE_MESSAGE_TYPE,
                                                      GTK_MESSAGE_INFO,
132
                                                      GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
133 134 135
  g_object_class_install_property (gobject_class,
                                   PROP_BUTTONS,
                                   g_param_spec_enum ("buttons",
136 137
						      P_("Message Buttons"),
						      P_("The buttons shown in the message dialog"),
138 139
						      GTK_TYPE_BUTTONS_TYPE,
                                                      GTK_BUTTONS_NONE,
140
                                                      GTK_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
141 142 143 144 145 146 147 148 149 150 151 152 153 154

  /**
   * GtkMessageDialog:text:
   * 
   * The primary text of the message dialog. If the dialog has 
   * a secondary text, this will appear as the title.
   *
   * Since: 2.10
   */
  g_object_class_install_property (gobject_class,
                                   PROP_TEXT,
                                   g_param_spec_string ("text",
                                                        P_("Text"),
                                                        P_("The primary text of the message dialog"),
155
                                                        "",
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
                                                        GTK_PARAM_READWRITE));

  /**
   * GtkMessageDialog:use-markup:
   * 
   * %TRUE if the primary text of the dialog includes Pango markup. 
   * See pango_parse_markup(). 
   *
   * Since: 2.10
   */
  g_object_class_install_property (gobject_class,
				   PROP_USE_MARKUP,
				   g_param_spec_boolean ("use-markup",
							 P_("Use Markup"),
							 P_("The primary text of the title includes Pango markup."),
							 FALSE,
							 GTK_PARAM_READWRITE));
  
  /**
   * GtkMessageDialog:secondary-text:
   * 
   * The secondary text of the message dialog. 
   *
   * Since: 2.10
   */
  g_object_class_install_property (gobject_class,
                                   PROP_SECONDARY_TEXT,
                                   g_param_spec_string ("secondary-text",
                                                        P_("Secondary Text"),
                                                        P_("The secondary text of the message dialog"),
                                                        NULL,
                                                        GTK_PARAM_READWRITE));

  /**
   * GtkMessageDialog:secondary-use-markup:
   * 
   * %TRUE if the secondary text of the dialog includes Pango markup. 
   * See pango_parse_markup(). 
   *
   * Since: 2.10
   */
  g_object_class_install_property (gobject_class,
				   PROP_SECONDARY_USE_MARKUP,
				   g_param_spec_boolean ("secondary-use-markup",
							 P_("Use Markup in secondary"),
							 P_("The secondary text includes Pango markup."),
							 FALSE,
							 GTK_PARAM_READWRITE));

Matthias Clasen's avatar
Matthias Clasen committed
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
  /**
   * GtkMessageDialog:image:
   * 
   * The image for this dialog.
   *
   * Since: 2.10
   */
  g_object_class_install_property (gobject_class,
                                   PROP_IMAGE,
                                   g_param_spec_object ("image",
                                                        P_("Image"),
                                                        P_("The image"),
                                                        GTK_TYPE_WIDGET,
                                                        GTK_PARAM_READWRITE));

220 221
  g_type_class_add_private (gobject_class,
			    sizeof (GtkMessageDialogPrivate));
222 223 224 225 226
}

static void
gtk_message_dialog_init (GtkMessageDialog *dialog)
{
227 228 229 230
  GtkWidget *hbox, *vbox;
  GtkMessageDialogPrivate *priv;

  priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (dialog);
231 232

  gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
233 234
  gtk_window_set_title (GTK_WINDOW (dialog), "");
  gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), TRUE);
235 236 237 238

  priv->has_primary_markup = FALSE;
  priv->has_secondary_text = FALSE;
  priv->secondary_label = gtk_label_new (NULL);
239 240
  gtk_widget_set_no_show_all (priv->secondary_label, TRUE);
  
241 242
  dialog->label = gtk_label_new (NULL);
  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);
Havoc Pennington's avatar
Havoc Pennington committed
246
  gtk_label_set_selectable (GTK_LABEL (dialog->label), TRUE);
247
  gtk_misc_set_alignment   (GTK_MISC  (dialog->label), 0.0, 0.0);
Havoc Pennington's avatar
Havoc Pennington committed
248
  
249 250 251 252 253 254 255 256 257 258 259 260
  gtk_label_set_line_wrap  (GTK_LABEL (priv->secondary_label), TRUE);
  gtk_label_set_selectable (GTK_LABEL (priv->secondary_label), TRUE);
  gtk_misc_set_alignment   (GTK_MISC  (priv->secondary_label), 0.0, 0.0);

  hbox = gtk_hbox_new (FALSE, 12);
  vbox = gtk_vbox_new (FALSE, 12);

  gtk_box_pack_start (GTK_BOX (vbox), dialog->label,
                      FALSE, FALSE, 0);

  gtk_box_pack_start (GTK_BOX (vbox), priv->secondary_label,
                      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 269

  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
                      hbox,
270
                      FALSE, FALSE, 0);
271

272 273 274 275 276 277
  gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
  gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 14); /* 14 + 2 * 5 = 24 */
  gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 5);
  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 6);

278
  gtk_widget_show_all (hbox);
Federico Mena Quintero's avatar
Federico Mena Quintero committed
279 280

  _gtk_dialog_set_ignore_separator (GTK_DIALOG (dialog), TRUE);
281 282
}

283 284 285 286 287 288 289 290 291 292 293 294
static void
setup_primary_label_font (GtkMessageDialog *dialog)
{
  gint size;
  PangoFontDescription *font_desc;
  GtkMessageDialogPrivate *priv;

  priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (dialog);

  /* unset the font settings */
  gtk_widget_modify_font (dialog->label, NULL);

295
  if (priv->has_secondary_text && !priv->has_primary_markup)
296 297 298 299 300 301
    {
      size = pango_font_description_get_size (dialog->label->style->font_desc);
      font_desc = pango_font_description_new ();
      pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
      pango_font_description_set_size (font_desc, size * PANGO_SCALE_LARGE);
      gtk_widget_modify_font (dialog->label, font_desc);
302
      pango_font_description_free (font_desc);
303 304 305
    }
}

306 307 308 309
static void
setup_type (GtkMessageDialog *dialog,
	    GtkMessageType    type)
{
Matthias Clasen's avatar
Matthias Clasen committed
310
  GtkMessageDialogPrivate *priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (dialog);
311
  const gchar *stock_id = NULL;
Matthias Clasen's avatar
Matthias Clasen committed
312
  AtkObject *atk_obj;
Matthias Clasen's avatar
Matthias Clasen committed
313 314 315
 
  priv->message_type = type;

316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
  switch (type)
    {
    case GTK_MESSAGE_INFO:
      stock_id = GTK_STOCK_DIALOG_INFO;
      break;

    case GTK_MESSAGE_QUESTION:
      stock_id = GTK_STOCK_DIALOG_QUESTION;
      break;

    case GTK_MESSAGE_WARNING:
      stock_id = GTK_STOCK_DIALOG_WARNING;
      break;
      
    case GTK_MESSAGE_ERROR:
      stock_id = GTK_STOCK_DIALOG_ERROR;
      break;
333

Matthias Clasen's avatar
Matthias Clasen committed
334 335 336
    case GTK_MESSAGE_OTHER:
      break;

337
    default:
338
      g_warning ("Unknown GtkMessageType %u", type);
339 340 341
      break;
    }

Matthias Clasen's avatar
Matthias Clasen committed
342
  if (stock_id)
343 344
    gtk_image_set_from_stock (GTK_IMAGE (dialog->image), stock_id,
                              GTK_ICON_SIZE_DIALOG);
Matthias Clasen's avatar
Matthias Clasen committed
345 346 347 348 349 350 351 352 353 354 355 356 357
      
  atk_obj = gtk_widget_get_accessible (GTK_WIDGET (dialog));
  if (GTK_IS_ACCESSIBLE (atk_obj))
    {
      atk_object_set_role (atk_obj, ATK_ROLE_ALERT);
      if (stock_id)
        {
          GtkStockItem item;

          gtk_stock_lookup (stock_id, &item);
          atk_object_set_name (atk_obj, item.label);
        }
    }
358 359
}

360 361 362 363 364 365 366
static void 
gtk_message_dialog_set_property (GObject      *object,
				 guint         prop_id,
				 const GValue *value,
				 GParamSpec   *pspec)
{
  GtkMessageDialog *dialog;
367 368
  GtkMessageDialogPrivate *priv;

369
  dialog = GTK_MESSAGE_DIALOG (object);
370
  priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (dialog);
371 372 373 374 375 376 377 378 379
  
  switch (prop_id)
    {
    case PROP_MESSAGE_TYPE:
      setup_type (dialog, g_value_get_enum (value));
      break;
    case PROP_BUTTONS:
      gtk_message_dialog_add_buttons (dialog, g_value_get_enum (value));
      break;
380 381 382 383 384 385 386 387 388
    case PROP_TEXT:
      if (priv->has_primary_markup)
	gtk_label_set_markup (GTK_LABEL (dialog->label), 
			      g_value_get_string (value));
      else
	gtk_label_set_text (GTK_LABEL (dialog->label), 
			    g_value_get_string (value));
      break;
    case PROP_USE_MARKUP:
Matthias Clasen's avatar
Matthias Clasen committed
389
      priv->has_primary_markup = g_value_get_boolean (value) != FALSE;
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
      gtk_label_set_use_markup (GTK_LABEL (dialog->label), 
				priv->has_primary_markup);
      setup_primary_label_font (dialog);
      break;
    case PROP_SECONDARY_TEXT:
      {
	const gchar *txt = g_value_get_string (value);
	
	if (gtk_label_get_use_markup (GTK_LABEL (priv->secondary_label)))
	  gtk_label_set_markup (GTK_LABEL (priv->secondary_label), txt);
	else
	  gtk_label_set_text (GTK_LABEL (priv->secondary_label), txt);

	if (txt)
	  {
	    priv->has_secondary_text = TRUE;
	    gtk_widget_show (priv->secondary_label);
	  }
	else
	  {
	    priv->has_secondary_text = FALSE;
	    gtk_widget_hide (priv->secondary_label);
	  }
	setup_primary_label_font (dialog);
      }
      break;
    case PROP_SECONDARY_USE_MARKUP:
      gtk_label_set_use_markup (GTK_LABEL (priv->secondary_label), 
				g_value_get_boolean (value));
      break;
Matthias Clasen's avatar
Matthias Clasen committed
420 421 422 423
    case PROP_IMAGE:
      gtk_message_dialog_set_image (dialog, (GtkWidget *)g_value_get_object (value));
      break;

424 425 426 427 428 429 430 431 432 433 434 435 436
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void 
gtk_message_dialog_get_property (GObject     *object,
				 guint        prop_id,
				 GValue      *value,
				 GParamSpec  *pspec)
{
  GtkMessageDialog *dialog;
437 438
  GtkMessageDialogPrivate *priv;

439
  dialog = GTK_MESSAGE_DIALOG (object);
440 441
  priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (dialog);
    
442 443 444
  switch (prop_id)
    {
    case PROP_MESSAGE_TYPE:
Matthias Clasen's avatar
Matthias Clasen committed
445
      g_value_set_enum (value, (GtkMessageType) priv->message_type);
446
      break;
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
    case PROP_TEXT:
      g_value_set_string (value, gtk_label_get_label (GTK_LABEL (dialog->label)));
      break;
    case PROP_USE_MARKUP:
      g_value_set_boolean (value, priv->has_primary_markup);
      break;
    case PROP_SECONDARY_TEXT:
      if (priv->has_secondary_text)
      g_value_set_string (value, 
			  gtk_label_get_label (GTK_LABEL (priv->secondary_label)));
      else
	g_value_set_string (value, NULL);
      break;
    case PROP_SECONDARY_USE_MARKUP:
      if (priv->has_secondary_text)
	g_value_set_boolean (value, 
			     gtk_label_get_use_markup (GTK_LABEL (priv->secondary_label)));
      else
	g_value_set_boolean (value, FALSE);
      break;
Matthias Clasen's avatar
Matthias Clasen committed
467 468 469
    case PROP_IMAGE:
      g_value_set_object (value, dialog->image);
      break;
470 471 472 473 474 475
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

476 477
/**
 * gtk_message_dialog_new:
478
 * @parent: transient parent, or %NULL for none 
479 480 481
 * @flags: flags
 * @type: type of message
 * @buttons: set of buttons to use
482
 * @message_format: printf()-style format string, or %NULL
483 484 485 486
 * @Varargs: arguments for @message_format
 * 
 * Creates a new message dialog, which is a simple dialog with an icon
 * indicating the dialog type (error, warning, etc.) and some text the
487 488 489
 * user may want to see. When the user clicks a button a "response"
 * signal is emitted with response IDs from #GtkResponseType. See
 * #GtkDialog for more details.
490 491 492 493 494 495 496 497 498 499 500 501 502
 * 
 * Return value: a new #GtkMessageDialog
 **/
GtkWidget*
gtk_message_dialog_new (GtkWindow     *parent,
                        GtkDialogFlags flags,
                        GtkMessageType type,
                        GtkButtonsType buttons,
                        const gchar   *message_format,
                        ...)
{
  GtkWidget *widget;
  GtkDialog *dialog;
Matthias Clasen's avatar
Matthias Clasen committed
503
  gchar* msg = NULL;
504
  va_list args;
505 506 507

  g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL);

Manish Singh's avatar
Manish Singh committed
508
  widget = g_object_new (GTK_TYPE_MESSAGE_DIALOG,
509
			 "message-type", type,
Manish Singh's avatar
Manish Singh committed
510 511
			 "buttons", buttons,
			 NULL);
512 513
  dialog = GTK_DIALOG (widget);

Owen Taylor's avatar
Warn  
Owen Taylor committed
514 515 516 517 518 519
  if (flags & GTK_DIALOG_NO_SEPARATOR)
    {
      g_warning ("The GTK_DIALOG_NO_SEPARATOR flag cannot be used for GtkMessageDialog");
      flags &= ~GTK_DIALOG_NO_SEPARATOR;
    }

520 521 522
  if (message_format)
    {
      va_start (args, message_format);
Manish Singh's avatar
Manish Singh committed
523
      msg = g_strdup_vprintf (message_format, args);
524
      va_end (args);
525

526 527
      gtk_label_set_text (GTK_LABEL (GTK_MESSAGE_DIALOG (widget)->label),
                          msg);
528

529 530 531 532 533 534 535 536 537 538 539 540
      g_free (msg);
    }

  if (parent != NULL)
    gtk_window_set_transient_for (GTK_WINDOW (widget),
                                  GTK_WINDOW (parent));
  
  if (flags & GTK_DIALOG_MODAL)
    gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);

  if (flags & GTK_DIALOG_DESTROY_WITH_PARENT)
    gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
Havoc Pennington's avatar
Havoc Pennington committed
541

542 543 544
  return widget;
}

545 546 547 548 549 550 551 552 553 554 555 556 557 558 559
/**
 * gtk_message_dialog_new_with_markup:
 * @parent: transient parent, or %NULL for none 
 * @flags: flags
 * @type: type of message
 * @buttons: set of buttons to use
 * @message_format: printf()-style format string, or %NULL
 * @Varargs: arguments for @message_format
 * 
 * Creates a new message dialog, which is a simple dialog with an icon
 * indicating the dialog type (error, warning, etc.) and some text which
 * is marked up with the <link linkend="PangoMarkupFormat">Pango text markup language</link>.
 * When the user clicks a button a "response" signal is emitted with
 * response IDs from #GtkResponseType. See #GtkDialog for more details.
 *
560 561 562 563 564 565 566 567 568
 * Special XML characters in the printf() arguments passed to this
 * function will automatically be escaped as necessary.
 * (See g_markup_printf_escaped() for how this is implemented.)
 * Usually this is what you want, but if you have an existing
 * Pango markup string that you want to use literally as the
 * label, then you need to use gtk_message_dialog_set_markup()
 * instead, since you can't pass the markup string either
 * as the format (it might contain '%' characters) or as a string
 * argument.
Matthias Clasen's avatar
Matthias Clasen committed
569
 * |[
570 571 572 573
 *  GtkWidget *dialog;
 *  dialog = gtk_message_dialog_new (main_application_window,
 *                                   GTK_DIALOG_DESTROY_WITH_PARENT,
 *                                   GTK_MESSAGE_ERROR,
574
 *                                   GTK_BUTTONS_CLOSE,
575 576 577
 *                                   NULL);
 *  gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog),
 *                                 markup);
Matthias Clasen's avatar
Matthias Clasen committed
578
 * ]|
579 580 581 582 583 584 585 586 587 588 589 590 591 592 593
 * 
 * Return value: a new #GtkMessageDialog
 *
 * Since: 2.4
 **/
GtkWidget*
gtk_message_dialog_new_with_markup (GtkWindow     *parent,
                                    GtkDialogFlags flags,
                                    GtkMessageType type,
                                    GtkButtonsType buttons,
                                    const gchar   *message_format,
                                    ...)
{
  GtkWidget *widget;
  va_list args;
594
  gchar *msg = NULL;
595 596 597

  g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL);

598
  widget = gtk_message_dialog_new (parent, flags, type, buttons, NULL);
599 600 601 602

  if (message_format)
    {
      va_start (args, message_format);
603
      msg = g_markup_vprintf_escaped (message_format, args);
604 605
      va_end (args);

606
      gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (widget), msg);
607 608 609 610 611 612 613

      g_free (msg);
    }

  return widget;
}

Matthias Clasen's avatar
Matthias Clasen committed
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
/**
 * gtk_message_dialog_set_image:
 * @dialog: a #GtkMessageDialog
 * @image: the image
 * 
 * Sets the dialog's image to @image.
 *
 * Since: 2.10
 **/
void
gtk_message_dialog_set_image (GtkMessageDialog *dialog,
			      GtkWidget        *image)
{
  GtkMessageDialogPrivate *priv;
  GtkWidget *parent;

  g_return_if_fail (GTK_IS_MESSAGE_DIALOG (dialog));

  priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (dialog);

  priv->message_type = GTK_MESSAGE_OTHER;
  
  parent = dialog->image->parent;
  gtk_container_add (GTK_CONTAINER (parent), image);
  gtk_container_remove (GTK_CONTAINER (parent), dialog->image);
  gtk_box_reorder_child (GTK_BOX (parent), image, 0);

  dialog->image = image;

  g_object_notify (G_OBJECT (dialog), "image");
}

646 647 648 649 650 651 652 653 654 655 656 657 658
/**
 * gtk_message_dialog_set_markup:
 * @message_dialog: a #GtkMessageDialog
 * @str: markup string (see <link linkend="PangoMarkupFormat">Pango markup format</link>)
 * 
 * Sets the text of the message dialog to be @str, which is marked
 * up with the <link linkend="PangoMarkupFormat">Pango text markup
 * language</link>.
 *
 * Since: 2.4
 **/
void
gtk_message_dialog_set_markup (GtkMessageDialog *message_dialog,
659
                               const gchar      *str)
660
{
661 662
  GtkMessageDialogPrivate *priv;

663
  g_return_if_fail (GTK_IS_MESSAGE_DIALOG (message_dialog));
664 665 666

  priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (message_dialog);
  priv->has_primary_markup = TRUE;
667 668 669
  gtk_label_set_markup (GTK_LABEL (message_dialog->label), str);
}

670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732
/**
 * gtk_message_dialog_format_secondary_text:
 * @message_dialog: a #GtkMessageDialog
 * @message_format: printf()-style format string, or %NULL
 * @Varargs: arguments for @message_format
 * 
 * Sets the secondary text of the message dialog to be @message_format 
 * (with printf()-style).
 *
 * Note that setting a secondary text makes the primary text become
 * bold, unless you have provided explicit markup.
 *
 * Since: 2.6
 **/
void
gtk_message_dialog_format_secondary_text (GtkMessageDialog *message_dialog,
                                          const gchar      *message_format,
                                          ...)
{
  va_list args;
  gchar *msg = NULL;
  GtkMessageDialogPrivate *priv;

  g_return_if_fail (GTK_IS_MESSAGE_DIALOG (message_dialog));

  priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (message_dialog);

  if (message_format)
    {
      priv->has_secondary_text = TRUE;

      va_start (args, message_format);
      msg = g_strdup_vprintf (message_format, args);
      va_end (args);

      gtk_widget_show (priv->secondary_label);
      gtk_label_set_text (GTK_LABEL (priv->secondary_label), msg);

      g_free (msg);
    }
  else
    {
      priv->has_secondary_text = FALSE;
      gtk_widget_hide (priv->secondary_label);
    }

  setup_primary_label_font (message_dialog);
}

/**
 * gtk_message_dialog_format_secondary_markup:
 * @message_dialog: a #GtkMessageDialog
 * @message_format: printf()-style markup string (see 
     <link linkend="PangoMarkupFormat">Pango markup format</link>), or %NULL
 * @Varargs: arguments for @message_format
 * 
 * Sets the secondary text of the message dialog to be @message_format (with 
 * printf()-style), which is marked up with the 
 * <link linkend="PangoMarkupFormat">Pango text markup language</link>.
 *
 * Note that setting a secondary text makes the primary text become
 * bold, unless you have provided explicit markup.
 *
733 734 735 736
 * Due to an oversight, this function does not escape special XML characters
 * like gtk_message_dialog_new_with_markup() does. Thus, if the arguments 
 * may contain special XML characters, you should use g_markup_printf_escaped()
 * to escape it.
Matthias Clasen's avatar
2.7.4  
Matthias Clasen committed
737

738 739
 * <informalexample><programlisting>
 * gchar *msg;
Matthias Clasen's avatar
2.7.4  
Matthias Clasen committed
740
 *  
741 742 743 744 745
 * msg = g_markup_printf_escaped (message_format, ...);
 * gtk_message_dialog_format_secondary_markup (message_dialog, "&percnt;s", msg);
 * g_free (msg);
 * </programlisting></informalexample>
 *
746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782
 * Since: 2.6
 **/
void
gtk_message_dialog_format_secondary_markup (GtkMessageDialog *message_dialog,
                                            const gchar      *message_format,
                                            ...)
{
  va_list args;
  gchar *msg = NULL;
  GtkMessageDialogPrivate *priv;

  g_return_if_fail (GTK_IS_MESSAGE_DIALOG (message_dialog));

  priv = GTK_MESSAGE_DIALOG_GET_PRIVATE (message_dialog);

  if (message_format)
    {
      priv->has_secondary_text = TRUE;

      va_start (args, message_format);
      msg = g_strdup_vprintf (message_format, args);
      va_end (args);

      gtk_widget_show (priv->secondary_label);
      gtk_label_set_markup (GTK_LABEL (priv->secondary_label), msg);

      g_free (msg);
    }
  else
    {
      priv->has_secondary_text = FALSE;
      gtk_widget_hide (priv->secondary_label);
    }

  setup_primary_label_font (message_dialog);
}

783 784 785 786 787 788
static void
gtk_message_dialog_add_buttons (GtkMessageDialog* message_dialog,
				GtkButtonsType buttons)
{
  GtkDialog* dialog = GTK_DIALOG (message_dialog);

789 790 791 792 793 794 795 796
  switch (buttons)
    {
    case GTK_BUTTONS_NONE:
      /* nothing */
      break;

    case GTK_BUTTONS_OK:
      gtk_dialog_add_button (dialog,
797
                             GTK_STOCK_OK,
798
                             GTK_RESPONSE_OK);
799 800 801 802
      break;

    case GTK_BUTTONS_CLOSE:
      gtk_dialog_add_button (dialog,
803
                             GTK_STOCK_CLOSE,
804
                             GTK_RESPONSE_CLOSE);
805 806 807 808
      break;

    case GTK_BUTTONS_CANCEL:
      gtk_dialog_add_button (dialog,
809
                             GTK_STOCK_CANCEL,
810
                             GTK_RESPONSE_CANCEL);
811 812 813 814
      break;

    case GTK_BUTTONS_YES_NO:
      gtk_dialog_add_button (dialog,
815
                             GTK_STOCK_NO,
816
                             GTK_RESPONSE_NO);
817 818 819
      gtk_dialog_add_button (dialog,
                             GTK_STOCK_YES,
                             GTK_RESPONSE_YES);
820 821 822 823
      gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
					       GTK_RESPONSE_YES,
					       GTK_RESPONSE_NO,
					       -1);
824 825 826 827
      break;

    case GTK_BUTTONS_OK_CANCEL:
      gtk_dialog_add_button (dialog,
828
                             GTK_STOCK_CANCEL,
829
                             GTK_RESPONSE_CANCEL);
830 831 832
      gtk_dialog_add_button (dialog,
                             GTK_STOCK_OK,
                             GTK_RESPONSE_OK);
833 834 835 836
      gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
					       GTK_RESPONSE_OK,
					       GTK_RESPONSE_CANCEL,
					       -1);
837 838 839 840 841
      break;
      
    default:
      g_warning ("Unknown GtkButtonsType");
      break;
842
    } 
843 844

  g_object_notify (G_OBJECT (message_dialog), "buttons");
845
}
846 847 848 849 850

static void
gtk_message_dialog_style_set (GtkWidget *widget,
                              GtkStyle  *prev_style)
{
851
  GtkMessageDialog *dialog = GTK_MESSAGE_DIALOG (widget);
Federico Mena Quintero's avatar
Federico Mena Quintero committed
852
  gboolean use_separator;
853 854
  GtkWidget *parent;
  gint border_width;
855 856 857 858 859

  parent = GTK_WIDGET (GTK_MESSAGE_DIALOG (widget)->image->parent);

  if (parent)
    {
860
      gtk_widget_style_get (widget, "message-border",
861 862 863
                            &border_width, NULL);
      
      gtk_container_set_border_width (GTK_CONTAINER (parent),
864
                                      MAX (0, border_width - 7));
865 866
    }

Federico Mena Quintero's avatar
Federico Mena Quintero committed
867
  gtk_widget_style_get (widget,
868
			"use-separator", &use_separator,
Federico Mena Quintero's avatar
Federico Mena Quintero committed
869
			NULL);
870

Federico Mena Quintero's avatar
Federico Mena Quintero committed
871 872 873 874
  _gtk_dialog_set_ignore_separator (GTK_DIALOG (widget), FALSE);
  gtk_dialog_set_has_separator (GTK_DIALOG (widget), use_separator);
  _gtk_dialog_set_ignore_separator (GTK_DIALOG (widget), TRUE);

875 876
  setup_primary_label_font (dialog);

Matthias Clasen's avatar
Matthias Clasen committed
877 878
  if (GTK_WIDGET_CLASS (gtk_message_dialog_parent_class)->style_set)
    (GTK_WIDGET_CLASS (gtk_message_dialog_parent_class)->style_set) (widget, prev_style);
879
}
880 881 882

#define __GTK_MESSAGE_DIALOG_C__
#include "gtkaliasdef.c"