gtkaboutdialog.c 78 KB
Newer Older
Cody Russell's avatar
Cody Russell committed
1
/* GTK - The GIMP Toolkit
2 3 4 5 6
 * Copyright (C) 2001 CodeFactory AB
 * Copyright (C) 2001, 2002 Anders Carlsson
 * Copyright (C) 2003, 2004 Matthias Clasen <mclasen@redhat.com>
 *
 * This library is free software; you can redistribute it and/or
Matthias Clasen's avatar
Matthias Clasen committed
7 8
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
9 10 11 12 13 14 15 16
 * 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
Matthias Clasen's avatar
Matthias Clasen committed
17
 * License along with this library; if not, write to the
18 19 20 21 22
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
23
 * Author: Anders Carlsson <andersca@gnome.org>
24 25 26 27
 *
 * Modified by the GTK+ Team and others 1997-2004.  See the AUTHORS
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
Matthias Clasen's avatar
Matthias Clasen committed
28
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
29 30
 */

31
#include "config.h"
32

33 34
#include <string.h>

35
#include "gtkaboutdialog.h"
36
#include "gtkalignment.h"
37 38 39
#include "gtkbutton.h"
#include "gtkbbox.h"
#include "gtkdialog.h"
40
#include "gtkgrid.h"
41 42 43
#include "gtkhbox.h"
#include "gtkimage.h"
#include "gtklabel.h"
44
#include "gtklinkbutton.h"
45 46
#include "gtkmarshalers.h"
#include "gtknotebook.h"
47
#include "gtkorientable.h"
48 49 50 51 52
#include "gtkscrolledwindow.h"
#include "gtkstock.h"
#include "gtktextview.h"
#include "gtkvbox.h"
#include "gtkiconfactory.h"
53
#include "gtkshow.h"
54
#include "gtkmainprivate.h"
55
#include "gtkmessagedialog.h"
56
#include "gtktogglebutton.h"
57
#include "gtktypebuiltins.h"
58
#include "gtkprivate.h"
59 60
#include "gtkintl.h"

61 62 63 64 65

/**
 * SECTION:gtkaboutdialog
 * @Short_description: Display information about an application
 * @Title: GtkAboutDialog
66
 * @See_also: #GTK_STOCK_ABOUT
67
 *
68
 * The GtkAboutDialog offers a simple way to display information about
69 70 71 72 73 74
 * a program like its logo, name, copyright, website and license. It is
 * also possible to give credits to the authors, documenters, translators
 * and artists who have worked on the program. An about dialog is typically
 * opened when the user selects the <literal>About</literal> option from
 * the <literal>Help</literal> menu. All parts of the dialog are optional.
 *
75 76 77 78
 * About dialog often contain links and email addresses. GtkAboutDialog
 * displays these as clickable links. By default, it calls gtk_show_uri()
 * when a user clicks one. The behaviour can be overridden with the
 * #GtkAboutDialog::activate-link signal.
79
 *
80
 * To make constructing a GtkAboutDialog as convenient as possible, you can
81 82 83 84 85 86 87
 * use the function gtk_show_about_dialog() which constructs and shows a dialog
 * and keeps it around so that it can be shown again.
 *
 * Note that GTK+ sets a default title of <literal>_("About &percnt;s")</literal>
 * on the dialog window (where &percnt;s is replaced by the name of the
 * application, but in order to ensure proper translation of the title,
 * applications should set the title property explicitly when constructing
88
 * a GtkAboutDialog, as shown in the following example:
89 90 91 92 93 94 95 96 97
 * <informalexample><programlisting>
 * gtk_show_about_dialog (NULL,
 *                        "program-name", "ExampleCode",
 *                        "logo", example_logo,
 *                        "title" _("About ExampleCode"),
 *                        NULL);
 * </programlisting></informalexample>
 */

98 99 100
static GdkColor default_link_color = { 0, 0, 0, 0xeeee };
static GdkColor default_visited_link_color = { 0, 0x5555, 0x1a1a, 0x8b8b };

101 102 103
/* Translators: this is the license preamble; the string at the end
 * contains the URL of the license.
 */
104
static const gchar *gtk_license_preamble = N_("This program comes with ABSOLUTELY NO WARRANTY; for details, visit <a href=\"%s\">%s</a>");
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122

/* URLs for each GtkLicense type; keep in the same order as the enumeration */
static const gchar *gtk_license_urls[] = {
  NULL,
  NULL,

  "http://www.gnu.org/licenses/old-licenses/gpl-2.0.html",
  "http://www.gnu.org/licenses/gpl.html",

  "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html",
  "http://www.gnu.org/licenses/lgpl.html",

  "http://opensource.org/licenses/bsd-license.php",
  "http://opensource.org/licenses/mit-license.php",

  "http://opensource.org/licenses/artistic-license-2.0.php"
};

123
struct _GtkAboutDialogPrivate 
124 125 126 127 128
{
  gchar *name;
  gchar *version;
  gchar *copyright;
  gchar *comments;
129 130
  gchar *website_url;
  gchar *website_text;
131 132
  gchar *translator_credits;
  gchar *license;
Matthias Clasen's avatar
Matthias Clasen committed
133

134 135 136
  gchar **authors;
  gchar **documenters;
  gchar **artists;
Matthias Clasen's avatar
Matthias Clasen committed
137

138 139 140 141
  gint credits_page;
  gint license_page;

  GtkWidget *notebook;
142 143
  GtkWidget *logo_image;
  GtkWidget *name_label;
144
  GtkWidget *version_label;
145 146
  GtkWidget *comments_label;
  GtkWidget *copyright_label;
147
  GtkWidget *license_label;
148
  GtkWidget *website_label;
149 150 151

  GtkWidget *credits_button;
  GtkWidget *license_button;
Matthias Clasen's avatar
Matthias Clasen committed
152

153 154
  GdkCursor *hand_cursor;
  GdkCursor *regular_cursor;
Matthias Clasen's avatar
Matthias Clasen committed
155

156 157
  GSList *visited_links;

158 159
  GtkLicense license_type;

160 161
  guint hovering_over_link : 1;
  guint wrap_license : 1;
162 163 164 165 166
};

#define GTK_ABOUT_DIALOG_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_ABOUT_DIALOG, GtkAboutDialogPrivate))


Matthias Clasen's avatar
Matthias Clasen committed
167
enum
168 169 170 171 172 173 174 175 176 177 178 179 180
{
  PROP_0,
  PROP_NAME,
  PROP_VERSION,
  PROP_COPYRIGHT,
  PROP_COMMENTS,
  PROP_WEBSITE,
  PROP_WEBSITE_LABEL,
  PROP_LICENSE,
  PROP_AUTHORS,
  PROP_DOCUMENTERS,
  PROP_TRANSLATOR_CREDITS,
  PROP_ARTISTS,
181
  PROP_LOGO,
182
  PROP_LOGO_ICON_NAME,
183 184
  PROP_WRAP_LICENSE,
  PROP_LICENSE_TYPE
185 186 187 188
};

static void                 gtk_about_dialog_finalize       (GObject            *object);
static void                 gtk_about_dialog_get_property   (GObject            *object,
Matthias Clasen's avatar
Matthias Clasen committed
189 190 191
                                                             guint               prop_id,
                                                             GValue             *value,
                                                             GParamSpec         *pspec);
192
static void                 gtk_about_dialog_set_property   (GObject            *object,
Matthias Clasen's avatar
Matthias Clasen committed
193 194 195
                                                             guint               prop_id,
                                                             const GValue       *value,
                                                             GParamSpec         *pspec);
196
static void                 gtk_about_dialog_show           (GtkWidget          *widge);
197 198 199
static void                 update_name_version             (GtkAboutDialog     *about);
static GtkIconSet *         icon_set_new_from_pixbufs       (GList              *pixbufs);
static void                 follow_if_link                  (GtkAboutDialog     *about,
Matthias Clasen's avatar
Matthias Clasen committed
200 201
                                                             GtkTextView        *text_view,
                                                             GtkTextIter        *iter);
202
static void                 set_cursor_if_appropriate       (GtkAboutDialog     *about,
203
                                                             GtkTextView        *text_view,
204
                                                             GdkDevice          *device,
205 206
                                                             gint                x,
                                                             gint                y);
207
static void                 display_credits_page            (GtkWidget          *button,
Matthias Clasen's avatar
Matthias Clasen committed
208
                                                             gpointer            data);
209
static void                 display_license_page            (GtkWidget          *button,
Matthias Clasen's avatar
Matthias Clasen committed
210
                                                             gpointer            data);
211
static void                 close_cb                        (GtkAboutDialog     *about);
212 213
static gboolean             gtk_about_dialog_activate_link  (GtkAboutDialog     *about,
                                                             const gchar        *uri);
214

215 216 217 218
enum {
  ACTIVATE_LINK,
  LAST_SIGNAL
};
219

220
static guint signals[LAST_SIGNAL] = { 0 };
221

Matthias Clasen's avatar
Matthias Clasen committed
222
G_DEFINE_TYPE (GtkAboutDialog, gtk_about_dialog, GTK_TYPE_DIALOG)
223

224

225 226 227 228 229
static void
gtk_about_dialog_class_init (GtkAboutDialogClass *klass)
{
  GObjectClass *object_class;
  GtkWidgetClass *widget_class;
Matthias Clasen's avatar
Matthias Clasen committed
230

231 232
  object_class = (GObjectClass *)klass;
  widget_class = (GtkWidgetClass *)klass;
Matthias Clasen's avatar
Matthias Clasen committed
233

234 235 236 237 238
  object_class->set_property = gtk_about_dialog_set_property;
  object_class->get_property = gtk_about_dialog_get_property;

  object_class->finalize = gtk_about_dialog_finalize;

239
  widget_class->show = gtk_about_dialog_show;
240

241 242 243 244 245 246 247 248 249 250 251 252 253
  klass->activate_link = gtk_about_dialog_activate_link;

  /**
   * GtkAboutDialog::activate-link:
   * @label: The object on which the signal was emitted
   * @uri: the URI that is activated
   *
   * The signal which gets emitted to activate a URI.
   * Applications may connect to it to override the default behaviour,
   * which is to call gtk_show_uri().
   *
   * Returns: %TRUE if the link has been activated
   *
254
   * Since: 2.24
255 256 257 258 259 260 261 262 263 264
   */
  signals[ACTIVATE_LINK] =
    g_signal_new ("activate-link",
                  G_TYPE_FROM_CLASS (object_class),
                  G_SIGNAL_RUN_LAST,
                  G_STRUCT_OFFSET (GtkAboutDialogClass, activate_link),
                  _gtk_boolean_handled_accumulator, NULL,
                  _gtk_marshal_BOOLEAN__STRING,
                  G_TYPE_BOOLEAN, 1, G_TYPE_STRING);

Matthias Clasen's avatar
Matthias Clasen committed
265
  /**
266
   * GtkAboutDialog:program-name:
Matthias Clasen's avatar
Matthias Clasen committed
267
   *
Matthias Clasen's avatar
Matthias Clasen committed
268
   * The name of the program.
Matthias Clasen's avatar
Matthias Clasen committed
269 270
   * If this is not set, it defaults to g_get_application_name().
   *
271
   * Since: 2.12
Matthias Clasen's avatar
Matthias Clasen committed
272
   */
273
  g_object_class_install_property (object_class,
Matthias Clasen's avatar
Matthias Clasen committed
274 275 276 277 278 279
                                   PROP_NAME,
                                   g_param_spec_string ("program-name",
                                                        P_("Program name"),
                                                        P_("The name of the program. If this is not set, it defaults to g_get_application_name()"),
                                                        NULL,
                                                        GTK_PARAM_READWRITE));
280

Matthias Clasen's avatar
Matthias Clasen committed
281 282 283
  /**
   * GtkAboutDialog:version:
   *
Matthias Clasen's avatar
Matthias Clasen committed
284
   * The version of the program.
Matthias Clasen's avatar
Matthias Clasen committed
285 286
   *
   * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
287
   */
288
  g_object_class_install_property (object_class,
Matthias Clasen's avatar
Matthias Clasen committed
289 290 291 292 293 294
                                   PROP_VERSION,
                                   g_param_spec_string ("version",
                                                        P_("Program version"),
                                                        P_("The version of the program"),
                                                        NULL,
                                                        GTK_PARAM_READWRITE));
Matthias Clasen's avatar
Matthias Clasen committed
295 296 297 298

  /**
   * GtkAboutDialog:copyright:
   *
Matthias Clasen's avatar
Matthias Clasen committed
299
   * Copyright information for the program.
Matthias Clasen's avatar
Matthias Clasen committed
300 301
   *
   * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
302
   */
303
  g_object_class_install_property (object_class,
Matthias Clasen's avatar
Matthias Clasen committed
304 305 306 307 308 309 310
                                   PROP_COPYRIGHT,
                                   g_param_spec_string ("copyright",
                                                        P_("Copyright string"),
                                                        P_("Copyright information for the program"),
                                                        NULL,
                                                        GTK_PARAM_READWRITE));
        
Matthias Clasen's avatar
Matthias Clasen committed
311 312 313 314

  /**
   * GtkAboutDialog:comments:
   *
Matthias Clasen's avatar
Matthias Clasen committed
315
   * Comments about the program. This string is displayed in a label
Matthias Clasen's avatar
Matthias Clasen committed
316 317 318 319
   * in the main dialog, thus it should be a short explanation of
   * the main purpose of the program, not a detailed list of features.
   *
   * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
320
   */
321
  g_object_class_install_property (object_class,
Matthias Clasen's avatar
Matthias Clasen committed
322 323 324 325 326 327
                                   PROP_COMMENTS,
                                   g_param_spec_string ("comments",
                                                        P_("Comments string"),
                                                        P_("Comments about the program"),
                                                        NULL,
                                                        GTK_PARAM_READWRITE));
Matthias Clasen's avatar
Matthias Clasen committed
328 329 330 331

  /**
   * GtkAboutDialog:license:
   *
Matthias Clasen's avatar
Matthias Clasen committed
332
   * The license of the program. This string is displayed in a
Matthias Clasen's avatar
Matthias Clasen committed
333
   * text view in a secondary dialog, therefore it is fine to use
334 335 336
   * a long multi-paragraph text. Note that the text is only wrapped
   * in the text view if the "wrap-license" property is set to %TRUE;
   * otherwise the text itself must contain the intended linebreaks.
337 338 339
   * When setting this property to a non-%NULL value, the
   * #GtkAboutDialog:license-type property is set to %GTK_LICENSE_CUSTOM
   * as a side effect.
Matthias Clasen's avatar
Matthias Clasen committed
340 341
   *
   * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
342
   */
343
  g_object_class_install_property (object_class,
Matthias Clasen's avatar
Matthias Clasen committed
344 345 346 347 348 349
                                   PROP_LICENSE,
                                   g_param_spec_string ("license",
                                                        _("License"),
                                                        _("The license of the program"),
                                                        NULL,
                                                        GTK_PARAM_READWRITE));
350

351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
  /**
   * GtkAboutDialog:license-type:
   *
   * The license of the program, as a value of the %GtkLicense enumeration.
   *
   * The #GtkAboutDialog will automatically fill out a standard disclaimer
   * and link the user to the appropriate online resource for the license
   * text.
   *
   * If %GTK_LICENSE_UNKNOWN is used, the link used will be the same
   * specified in the #GtkAboutDialog:website property.
   *
   * If %GTK_LICENSE_CUSTOM is used, the current contents of the
   * #GtkAboutDialog:license property are used.
   *
   * For any other #GtkLicense value, the contents of the
   * #GtkAboutDialog:license property are also set by this property as
   * a side effect.
   *
   * Since: 3.0
   */
  g_object_class_install_property (object_class,
                                   PROP_LICENSE_TYPE,
                                   g_param_spec_enum ("license-type",
                                                      P_("License Type"),
                                                      P_("The license type of the program"),
                                                      GTK_TYPE_LICENSE,
                                                      GTK_LICENSE_UNKNOWN,
                                                      GTK_PARAM_READWRITE));

Matthias Clasen's avatar
Matthias Clasen committed
381 382 383
  /**
   * GtkAboutDialog:website:
   *
Matthias Clasen's avatar
Matthias Clasen committed
384
   * The URL for the link to the website of the program.
Matthias Clasen's avatar
Matthias Clasen committed
385 386 387
   * This should be a string starting with "http://.
   *
   * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
388
   */
389
  g_object_class_install_property (object_class,
Matthias Clasen's avatar
Matthias Clasen committed
390 391 392 393 394 395
                                   PROP_WEBSITE,
                                   g_param_spec_string ("website",
                                                        P_("Website URL"),
                                                        P_("The URL for the link to the website of the program"),
                                                        NULL,
                                                        GTK_PARAM_READWRITE));
396

Matthias Clasen's avatar
Matthias Clasen committed
397 398 399
  /**
   * GtkAboutDialog:website-label:
   *
400
   * The label for the link to the website of the program.
Matthias Clasen's avatar
Matthias Clasen committed
401 402
   *
   * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
403
   */
404
  g_object_class_install_property (object_class,
Matthias Clasen's avatar
Matthias Clasen committed
405 406 407
                                   PROP_WEBSITE_LABEL,
                                   g_param_spec_string ("website-label",
                                                        P_("Website label"),
408
                                                        P_("The label for the link to the website of the program"),
Matthias Clasen's avatar
Matthias Clasen committed
409 410
                                                        NULL,
                                                        GTK_PARAM_READWRITE));
411

Matthias Clasen's avatar
Matthias Clasen committed
412 413 414 415 416 417 418 419
  /**
   * GtkAboutDialog:authors:
   *
   * The authors of the program, as a %NULL-terminated array of strings.
   * Each string may contain email addresses and URLs, which will be displayed
   * as links, see the introduction for more details.
   *
   * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
420
   */
421
  g_object_class_install_property (object_class,
Matthias Clasen's avatar
Matthias Clasen committed
422 423 424 425 426 427
                                   PROP_AUTHORS,
                                   g_param_spec_boxed ("authors",
                                                       P_("Authors"),
                                                       P_("List of authors of the program"),
                                                       G_TYPE_STRV,
                                                       GTK_PARAM_READWRITE));
Matthias Clasen's avatar
Matthias Clasen committed
428 429 430 431 432 433 434 435 436

  /**
   * GtkAboutDialog:documenters:
   *
   * The people documenting the program, as a %NULL-terminated array of strings.
   * Each string may contain email addresses and URLs, which will be displayed
   * as links, see the introduction for more details.
   *
   * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
437
   */
438
  g_object_class_install_property (object_class,
Matthias Clasen's avatar
Matthias Clasen committed
439 440 441 442 443 444
                                   PROP_DOCUMENTERS,
                                   g_param_spec_boxed ("documenters",
                                                       P_("Documenters"),
                                                       P_("List of people documenting the program"),
                                                       G_TYPE_STRV,
                                                       GTK_PARAM_READWRITE));
445

Matthias Clasen's avatar
Matthias Clasen committed
446 447 448
  /**
   * GtkAboutDialog:artists:
   *
Matthias Clasen's avatar
Matthias Clasen committed
449 450 451
   * The people who contributed artwork to the program, as a %NULL-terminated
   * array of strings. Each string may contain email addresses and URLs, which
   * will be displayed as links, see the introduction for more details.
Matthias Clasen's avatar
Matthias Clasen committed
452 453
   *
   * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
454
   */
455
  g_object_class_install_property (object_class,
Matthias Clasen's avatar
Matthias Clasen committed
456 457 458 459 460 461
                                   PROP_ARTISTS,
                                   g_param_spec_boxed ("artists",
                                                       P_("Artists"),
                                                       P_("List of people who have contributed artwork to the program"),
                                                       G_TYPE_STRV,
                                                       GTK_PARAM_READWRITE));
462

Matthias Clasen's avatar
Matthias Clasen committed
463 464 465 466 467 468 469 470 471

  /**
   * GtkAboutDialog:translator-credits:
   *
   * Credits to the translators. This string should be marked as translatable.
   * The string may contain email addresses and URLs, which will be displayed
   * as links, see the introduction for more details.
   *
   * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
472
   */
473
  g_object_class_install_property (object_class,
Matthias Clasen's avatar
Matthias Clasen committed
474 475 476 477 478 479 480
                                   PROP_TRANSLATOR_CREDITS,
                                   g_param_spec_string ("translator-credits",
                                                        P_("Translator credits"),
                                                        P_("Credits to the translators. This string should be marked as translatable"),
                                                        NULL,
                                                        GTK_PARAM_READWRITE));
        
Matthias Clasen's avatar
Matthias Clasen committed
481 482 483
  /**
   * GtkAboutDialog:logo:
   *
Matthias Clasen's avatar
Matthias Clasen committed
484
   * A logo for the about box. If this is not set, it defaults to
Matthias Clasen's avatar
Matthias Clasen committed
485 486 487
   * gtk_window_get_default_icon_list().
   *
   * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
488
   */
489
  g_object_class_install_property (object_class,
Matthias Clasen's avatar
Matthias Clasen committed
490 491 492 493 494 495
                                   PROP_LOGO,
                                   g_param_spec_object ("logo",
                                                        P_("Logo"),
                                                        P_("A logo for the about box. If this is not set, it defaults to gtk_window_get_default_icon_list()"),
                                                        GDK_TYPE_PIXBUF,
                                                        GTK_PARAM_READWRITE));
496

Matthias Clasen's avatar
Matthias Clasen committed
497 498 499 500
  /**
   * GtkAboutDialog:logo-icon-name:
   *
   * A named icon to use as the logo for the about box. This property
Matthias Clasen's avatar
Matthias Clasen committed
501
   * overrides the #GtkAboutDialog:logo property.
Matthias Clasen's avatar
Matthias Clasen committed
502 503
   *
   * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
504
   */
505
  g_object_class_install_property (object_class,
Matthias Clasen's avatar
Matthias Clasen committed
506 507 508 509 510 511
                                   PROP_LOGO_ICON_NAME,
                                   g_param_spec_string ("logo-icon-name",
                                                        P_("Logo Icon Name"),
                                                        P_("A named icon to use as the logo for the about box."),
                                                        NULL,
                                                        GTK_PARAM_READWRITE));
512 513 514 515 516
  /**
   * GtkAboutDialog:wrap-license:
   *
   * Whether to wrap the text in the license dialog.
   *
Matthias Clasen's avatar
Matthias Clasen committed
517
   * Since: 2.8
Matthias Clasen's avatar
Matthias Clasen committed
518
   */
519
  g_object_class_install_property (object_class,
Matthias Clasen's avatar
Matthias Clasen committed
520 521 522 523 524 525
                                   PROP_WRAP_LICENSE,
                                   g_param_spec_boolean ("wrap-license",
                                                         P_("Wrap license"),
                                                         P_("Whether to wrap the license text."),
                                                         FALSE,
                                                         GTK_PARAM_READWRITE));
526

527 528 529 530

  g_type_class_add_private (object_class, sizeof (GtkAboutDialogPrivate));
}

531
static gboolean
532 533
emit_activate_link (GtkAboutDialog *about,
                    const gchar    *uri)
534
{
535
  gboolean handled = FALSE;
536

537
  g_signal_emit (about, signals[ACTIVATE_LINK], 0, uri, &handled);
538 539 540 541

  return TRUE;
}

542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629
static void
update_license_button_visibility (GtkAboutDialog *about)
{
  GtkAboutDialogPrivate *priv = about->priv;

  if (priv->license_type == GTK_LICENSE_CUSTOM && priv->license != NULL)
    gtk_widget_show (priv->license_button);
  else
    gtk_widget_hide (priv->license_button);
}

static void
update_credits_button_visibility (GtkAboutDialog *about)
{
  GtkAboutDialogPrivate *priv = about->priv;
  gboolean show;

  show = (priv->authors != NULL ||
          priv->documenters != NULL ||
          priv->artists != NULL ||
         (priv->translator_credits != NULL &&
          strcmp (priv->translator_credits, "translator_credits") &&
          strcmp (priv->translator_credits, "translator-credits")));
  if (show)
    gtk_widget_show (priv->credits_button);
  else
    gtk_widget_hide (priv->credits_button);
}

static void
switch_page (GtkAboutDialog *about,
             gint            page)
{
  GtkAboutDialogPrivate *priv = about->priv;

  gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), page);
}

static void
display_main_page (GtkButton *button,
                   gpointer   data)
{
  GtkAboutDialog *about = (GtkAboutDialog *)data;

  switch_page (about, 0);
}

static void
credits_button_clicked (GtkButton *button,
                        gpointer   data)
{
  GtkAboutDialog *about = (GtkAboutDialog *)data;
  GtkAboutDialogPrivate *priv = about->priv;
  gboolean active;

  active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));

  if (active)
    {
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->license_button), FALSE);
      display_credits_page (NULL, data);
    }
  else
    {
      display_main_page (NULL, data);
    }
}

static void
license_button_clicked (GtkButton *button,
                        gpointer   data)
{
  GtkAboutDialog *about = (GtkAboutDialog *)data;
  GtkAboutDialogPrivate *priv = about->priv;
  gboolean active;

  active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));

  if (active)
    {
      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->credits_button), FALSE);
      display_license_page (NULL, data);
    }
  else
    {
      display_main_page (NULL, data);
    }
}
630 631 632
static void
gtk_about_dialog_init (GtkAboutDialog *about)
{
633
  GtkDialog *dialog = GTK_DIALOG (about);
634
  GtkAboutDialogPrivate *priv;
635
  GtkWidget *vbox, *page_vbox, *hbox, *button, *close_button, *image;
636
  GtkWidget *content_area, *action_area;
637 638 639

  /* Data */
  priv = GTK_ABOUT_DIALOG_GET_PRIVATE (about);
640
  about->priv = priv;
641 642 643 644 645

  priv->name = NULL;
  priv->version = NULL;
  priv->copyright = NULL;
  priv->comments = NULL;
646 647
  priv->website_url = NULL;
  priv->website_text = NULL;
648
  priv->translator_credits = NULL;
649
  priv->license = NULL;
650 651 652 653 654 655 656
  priv->authors = NULL;
  priv->documenters = NULL;
  priv->artists = NULL;

  priv->hand_cursor = gdk_cursor_new (GDK_HAND2);
  priv->regular_cursor = gdk_cursor_new (GDK_XTERM);
  priv->hovering_over_link = FALSE;
657
  priv->wrap_license = FALSE;
658

659 660
  priv->license_type = GTK_LICENSE_UNKNOWN;

661 662 663
  content_area = gtk_dialog_get_content_area (dialog);
  action_area = gtk_dialog_get_action_area (dialog);

664
  gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
665 666
  gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
  gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
667

668 669 670
  /* Widgets */
  gtk_widget_push_composite_child ();

671
  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
672
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
673
  gtk_box_pack_start (GTK_BOX (content_area), vbox, TRUE, TRUE, 0);
674 675 676 677 678 679 680 681 682

  priv->logo_image = gtk_image_new ();
  gtk_box_pack_start (GTK_BOX (vbox), priv->logo_image, FALSE, FALSE, 0);

  priv->name_label = gtk_label_new (NULL);
  gtk_label_set_selectable (GTK_LABEL (priv->name_label), TRUE);
  gtk_label_set_justify (GTK_LABEL (priv->name_label), GTK_JUSTIFY_CENTER);
  gtk_box_pack_start (GTK_BOX (vbox), priv->name_label, FALSE, FALSE, 0);

683 684 685 686 687 688 689 690 691 692 693 694 695 696 697
  priv->notebook = gtk_notebook_new ();
  gtk_box_pack_start (GTK_BOX (vbox), priv->notebook, TRUE, TRUE, 0);
  gtk_widget_set_size_request (priv->notebook, 400, 100);

  page_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
  gtk_widget_show (page_vbox);
  gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
  gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
  gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), page_vbox, NULL);

  priv->version_label = gtk_label_new (NULL);
  gtk_label_set_selectable (GTK_LABEL (priv->version_label), TRUE);
  gtk_label_set_justify (GTK_LABEL (priv->version_label), GTK_JUSTIFY_CENTER);
  gtk_box_pack_start (GTK_BOX (page_vbox), priv->version_label, FALSE, FALSE, 0);

698 699 700 701
  priv->comments_label = gtk_label_new (NULL);
  gtk_label_set_selectable (GTK_LABEL (priv->comments_label), TRUE);
  gtk_label_set_justify (GTK_LABEL (priv->comments_label), GTK_JUSTIFY_CENTER);
  gtk_label_set_line_wrap (GTK_LABEL (priv->comments_label), TRUE);
702
  gtk_box_pack_start (GTK_BOX (page_vbox), priv->comments_label, FALSE, FALSE, 0);
703

704 705
  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
  gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
706
  gtk_box_pack_start (GTK_BOX (page_vbox), hbox, FALSE, FALSE, 0);
707 708 709 710 711

  priv->website_label = button = gtk_label_new ("");
  gtk_widget_set_no_show_all (button, TRUE);
  gtk_label_set_selectable (GTK_LABEL (button), TRUE);
  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
712 713
  g_signal_connect_swapped (button, "activate-link",
                            G_CALLBACK (emit_activate_link), about);
714

715 716 717 718 719 720 721 722 723 724 725 726
  priv->license_label = gtk_label_new (NULL);
  gtk_label_set_use_markup (GTK_LABEL (priv->license_label), TRUE);
  gtk_label_set_selectable (GTK_LABEL (priv->license_label), TRUE);
  gtk_label_set_justify (GTK_LABEL (priv->license_label), GTK_JUSTIFY_CENTER);
  gtk_box_pack_end (GTK_BOX (page_vbox), priv->license_label, FALSE, FALSE, 0);
  gtk_label_set_line_wrap (GTK_LABEL (priv->license_label), TRUE);

  priv->copyright_label = gtk_label_new (NULL);
  gtk_label_set_selectable (GTK_LABEL (priv->copyright_label), TRUE);
  gtk_label_set_justify (GTK_LABEL (priv->copyright_label), GTK_JUSTIFY_CENTER);
  gtk_box_pack_end (GTK_BOX (page_vbox), priv->copyright_label, FALSE, FALSE, 0);

727
  gtk_widget_show (vbox);
728
  gtk_widget_show (priv->notebook);
729 730 731 732
  gtk_widget_show (priv->logo_image);
  gtk_widget_show (priv->name_label);
  gtk_widget_show (hbox);

Matthias Clasen's avatar
Matthias Clasen committed
733
  /* Add the close button */
734
  close_button = gtk_dialog_add_button (GTK_DIALOG (about), GTK_STOCK_CLOSE,
Matthias Clasen's avatar
Matthias Clasen committed
735
                                        GTK_RESPONSE_CANCEL);
736
  gtk_dialog_set_default_response (GTK_DIALOG (about), GTK_RESPONSE_CANCEL);
737 738

  /* Add the credits button */
739
  button = gtk_toggle_button_new_with_mnemonic (_("C_redits"));
740
  gtk_widget_set_can_default (button, TRUE);
741 742
  image = gtk_image_new_from_stock (GTK_STOCK_ABOUT, GTK_ICON_SIZE_BUTTON);
  gtk_button_set_image (GTK_BUTTON (button), image);
743
  gtk_widget_set_no_show_all (button, TRUE);
744
  gtk_box_pack_end (GTK_BOX (action_area), button, FALSE, TRUE, 0);
745
  gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (action_area), button, TRUE);
746
  g_signal_connect (button, "clicked",
747
                    G_CALLBACK (credits_button_clicked), about);
748
  priv->credits_button = button;
749
  priv->credits_page = 0;
750 751

  /* Add the license button */
752
  button = gtk_toggle_button_new_with_mnemonic (_("_License"));
753
  gtk_widget_set_can_default (button, TRUE);
754
  gtk_widget_set_no_show_all (button, TRUE);
755
  gtk_box_pack_end (GTK_BOX (action_area), button, FALSE, TRUE, 0);
756
  gtk_button_box_set_child_secondary (GTK_BUTTON_BOX (action_area), button, TRUE);
757
  g_signal_connect (button, "clicked",
758
                    G_CALLBACK (license_button_clicked), about);
759
  priv->license_button = button;
760 761 762
  priv->license_page = 0;

  switch_page (about, 0);
763 764 765 766

  gtk_window_set_resizable (GTK_WINDOW (about), FALSE);

  gtk_widget_pop_composite_child ();
767

768 769 770
  gtk_widget_grab_default (close_button);
  gtk_widget_grab_focus (close_button);

771
  /* force defaults */
772
  gtk_about_dialog_set_program_name (about, NULL);
773
  gtk_about_dialog_set_logo (about, NULL);
774 775 776 777 778 779
}

static void
gtk_about_dialog_finalize (GObject *object)
{
  GtkAboutDialog *about = GTK_ABOUT_DIALOG (object);
780
  GtkAboutDialogPrivate *priv = about->priv;
781 782 783 784 785 786

  g_free (priv->name);
  g_free (priv->version);
  g_free (priv->copyright);
  g_free (priv->comments);
  g_free (priv->license);
787 788
  g_free (priv->website_url);
  g_free (priv->website_text);
789 790 791 792 793 794
  g_free (priv->translator_credits);

  g_strfreev (priv->authors);
  g_strfreev (priv->documenters);
  g_strfreev (priv->artists);

795 796 797
  g_slist_foreach (priv->visited_links, (GFunc)g_free, NULL);
  g_slist_free (priv->visited_links);

798 799
  g_object_unref (priv->hand_cursor);
  g_object_unref (priv->regular_cursor);
800

801 802 803 804
  G_OBJECT_CLASS (gtk_about_dialog_parent_class)->finalize (object);
}

static void
Matthias Clasen's avatar
Matthias Clasen committed
805 806 807 808
gtk_about_dialog_set_property (GObject      *object,
                               guint         prop_id,
                               const GValue *value,
                               GParamSpec   *pspec)
809 810
{
  GtkAboutDialog *about = GTK_ABOUT_DIALOG (object);
811
  GtkAboutDialogPrivate *priv = about->priv;
812

Matthias Clasen's avatar
Matthias Clasen committed
813
  switch (prop_id)
814 815
    {
    case PROP_NAME:
816
      gtk_about_dialog_set_program_name (about, g_value_get_string (value));
817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832
      break;
    case PROP_VERSION:
      gtk_about_dialog_set_version (about, g_value_get_string (value));
      break;
    case PROP_COMMENTS:
      gtk_about_dialog_set_comments (about, g_value_get_string (value));
      break;
    case PROP_WEBSITE:
      gtk_about_dialog_set_website (about, g_value_get_string (value));
      break;
    case PROP_WEBSITE_LABEL:
      gtk_about_dialog_set_website_label (about, g_value_get_string (value));
      break;
    case PROP_LICENSE:
      gtk_about_dialog_set_license (about, g_value_get_string (value));
      break;
833 834 835
    case PROP_LICENSE_TYPE:
      gtk_about_dialog_set_license_type (about, g_value_get_enum (value));
      break;
836 837 838 839 840
    case PROP_COPYRIGHT:
      gtk_about_dialog_set_copyright (about, g_value_get_string (value));
      break;
    case PROP_LOGO:
      gtk_about_dialog_set_logo (about, g_value_get_object (value));
Matthias Clasen's avatar
Matthias Clasen committed
841
      break;
842
    case PROP_AUTHORS:
843
      gtk_about_dialog_set_authors (about, (const gchar**)g_value_get_boxed (value));
844 845
      break;
    case PROP_DOCUMENTERS:
846
      gtk_about_dialog_set_documenters (about, (const gchar**)g_value_get_boxed (value));
Matthias Clasen's avatar
Matthias Clasen committed
847
      break;
848
    case PROP_ARTISTS:
849
      gtk_about_dialog_set_artists (about, (const gchar**)g_value_get_boxed (value));
Matthias Clasen's avatar
Matthias Clasen committed
850
      break;
851 852 853
    case PROP_TRANSLATOR_CREDITS:
      gtk_about_dialog_set_translator_credits (about, g_value_get_string (value));
      break;
854 855 856
    case PROP_LOGO_ICON_NAME:
      gtk_about_dialog_set_logo_icon_name (about, g_value_get_string (value));
      break;
857 858 859
    case PROP_WRAP_LICENSE:
      priv->wrap_license = g_value_get_boolean (value);
      break;
860 861 862 863 864 865 866
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

static void
Matthias Clasen's avatar
Matthias Clasen committed
867 868 869 870
gtk_about_dialog_get_property (GObject    *object,
                               guint       prop_id,
                               GValue     *value,
                               GParamSpec *pspec)
871 872
{
  GtkAboutDialog *about = GTK_ABOUT_DIALOG (object);
873
  GtkAboutDialogPrivate *priv = about->priv;
874
        
875
  switch (prop_id) 
876 877 878 879 880 881 882 883 884 885 886 887 888 889
    {
    case PROP_NAME:
      g_value_set_string (value, priv->name);
      break;
    case PROP_VERSION:
      g_value_set_string (value, priv->version);
      break;
    case PROP_COPYRIGHT:
      g_value_set_string (value, priv->copyright);
      break;
    case PROP_COMMENTS:
      g_value_set_string (value, priv->comments);
      break;
    case PROP_WEBSITE:
890
      g_value_set_string (value, priv->website_url);
891 892
      break;
    case PROP_WEBSITE_LABEL:
893
      g_value_set_string (value, priv->website_text);
894 895 896 897
      break;
    case PROP_LICENSE:
      g_value_set_string (value, priv->license);
      break;
898 899 900
    case PROP_LICENSE_TYPE:
      g_value_set_enum (value, priv->license_type);
      break;
901 902 903 904 905 906 907 908 909 910 911 912 913
    case PROP_TRANSLATOR_CREDITS:
      g_value_set_string (value, priv->translator_credits);
      break;
    case PROP_AUTHORS:
      g_value_set_boxed (value, priv->authors);
      break;
    case PROP_DOCUMENTERS:
      g_value_set_boxed (value, priv->documenters);
      break;
    case PROP_ARTISTS:
      g_value_set_boxed (value, priv->artists);
      break;
    case PROP_LOGO:
914
      if (gtk_image_get_storage_type (GTK_IMAGE (priv->logo_image)) == GTK_IMAGE_PIXBUF)
Matthias Clasen's avatar
Matthias Clasen committed
915
        g_value_set_object (value, gtk_image_get_pixbuf (GTK_IMAGE (priv->logo_image)));
916
      else
Matthias Clasen's avatar
Matthias Clasen committed
917
        g_value_set_object (value, NULL);
918 919 920
      break;
    case PROP_LOGO_ICON_NAME:
      if (gtk_image_get_storage_type (GTK_IMAGE (priv->logo_image)) == GTK_IMAGE_ICON_NAME)
Matthias Clasen's avatar
Matthias Clasen committed
921 922
        {
          const gchar *icon_name;
923

Matthias Clasen's avatar
Matthias Clasen committed
924 925 926
          gtk_image_get_icon_name (GTK_IMAGE (priv->logo_image), &icon_name, NULL);
          g_value_set_string (value, icon_name);
        }
927
      else
Matthias Clasen's avatar
Matthias Clasen committed
928
        g_value_set_string (value, NULL);
929
      break;
930 931 932
    case PROP_WRAP_LICENSE:
      g_value_set_boolean (value, priv->wrap_license);
      break;
933 934 935 936 937 938
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }
}

939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970
static gboolean
gtk_about_dialog_activate_link (GtkAboutDialog *about,
                                const gchar    *uri)
{
  GdkScreen *screen;
  GError *error = NULL;

  screen = gtk_widget_get_screen (GTK_WIDGET (about));

  if (!gtk_show_uri (screen, uri, gtk_get_current_event_time (), &error))
    {
      GtkWidget *dialog;

      dialog = gtk_message_dialog_new (GTK_WINDOW (about),
                                       GTK_DIALOG_DESTROY_WITH_PARENT |
                                       GTK_DIALOG_MODAL,
                                       GTK_MESSAGE_ERROR,
                                       GTK_BUTTONS_CLOSE,
                                       "%s", _("Could not show link"));
      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                                "%s", error->message);
      g_error_free (error);

      g_signal_connect (dialog, "response",
                        G_CALLBACK (gtk_widget_destroy), NULL);

      gtk_window_present (GTK_WINDOW (dialog));
    }

  return TRUE;
}

971 972 973
static void
update_website (GtkAboutDialog *about)
{
974
  GtkAboutDialogPrivate *priv = about->priv;
975

976 977
  gtk_widget_show (priv->website_label);

978
  if (priv->website_url)
979
    {
980
      gchar *markup;
981 982

      if (priv->website_text)
983 984 985 986 987 988 989 990 991 992 993
        {
          gchar *escaped;

          escaped = g_markup_escape_text (priv->website_text, -1);
          markup = g_strdup_printf ("<a href=\"%s\">%s</a>",
                                    priv->website_url, escaped);
          g_free (escaped);
        }
      else
        {
          markup = g_strdup_printf ("<a href=\"%s\">%s</a>",
994
                                    priv->website_url, _("Homepage"));
995 996
        }

997
      gtk_label_set_markup (GTK_LABEL (priv->website_label), markup);
998
      g_free (markup);
999 1000 1001
    }
  else
    {
1002
      if (priv->website_text)
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
        gtk_label_set_text (GTK_LABEL (priv->website_label), priv->website_text);
      else
        gtk_widget_hide (priv->website_label);
    }
}

static void
gtk_about_dialog_show (GtkWidget *widget)
{
  update_website (GTK_ABOUT_DIALOG (widget));
Matthias Clasen's avatar
Matthias Clasen committed
1013

1014 1015 1016
  GTK_WIDGET_CLASS (gtk_about_dialog_parent_class)->show (widget);
}

1017 1018 1019
/**
 * gtk_about_dialog_get_program_name:
 * @about: a #GtkAboutDialog
Matthias Clasen's avatar
Matthias Clasen committed
1020
 *
1021
 * Returns the program name displayed in the about dialog.
Matthias Clasen's avatar
Matthias Clasen committed
1022
 *
1023 1024 1025 1026
 * Return value: The program name. The string is owned by the about
 *  dialog and must not be modified.
 *
 * Since: 2.12
Matthias Clasen's avatar
Matthias Clasen committed
1027
 */
1028 1029
G_CONST_RETURN gchar *
gtk_about_dialog_get_program_name (GtkAboutDialog *about)
1030 1031
{
  GtkAboutDialogPrivate *priv;
Matthias Clasen's avatar
Matthias Clasen committed
1032

1033 1034
  g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);

1035
  priv = about->priv;
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045

  return priv->name;
}

static void
update_name_version (GtkAboutDialog *about)
{
  GtkAboutDialogPrivate *priv;
  gchar *title_string, *name_string;

1046
  priv = about->priv;
1047 1048 1049 1050 1051

  title_string = g_strdup_printf (_("About %s"), priv->name);
  gtk_window_set_title (GTK_WINDOW (about), title_string);
  g_free (title_string);

Matthias Clasen's avatar
Matthias Clasen committed
1052
  if (priv->version != NULL)
1053 1054 1055 1056
    {
      gtk_label_set_markup (GTK_LABEL (priv->version_label), priv->version);
      gtk_widget_show (priv->version_label);
    }
1057
  else
1058
    gtk_widget_hide (priv->version_label);
1059

1060 1061
  name_string = g_markup_printf_escaped ("<span weight=\"bold\">%s</span>",
                                         priv->name);
1062 1063 1064 1065
  gtk_label_set_markup (GTK_LABEL (priv->name_label), name_string);
  g_free (name_string);
}

1066 1067 1068 1069 1070
/**
 * gtk_about_dialog_set_program_name:
 * @about: a #GtkAboutDialog
 * @name: the program name
 *
Matthias Clasen's avatar
Matthias Clasen committed
1071
 * Sets the name to display in the about dialog.
1072
 * If this is not set, it defaults to g_get_application_name().
Matthias Clasen's avatar
Matthias Clasen committed
1073
 *
1074
 * Since: 2.12
Matthias Clasen's avatar
Matthias Clasen committed
1075
 */
1076
void
Matthias Clasen's avatar
Matthias Clasen committed
1077
gtk_about_dialog_set_program_name (GtkAboutDialog *about,
1078
                                   const gchar    *name)
1079 1080 1081 1082 1083
{
  GtkAboutDialogPrivate *priv;
  gchar *tmp;

  g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));
Matthias Clasen's avatar
Matthias Clasen committed
1084

1085 1086
  priv = about->priv;

1087 1088 1089 1090 1091 1092
  tmp = priv->name;
  priv->name = g_strdup (name ? name : g_get_application_name ());
  g_free (tmp);

  update_name_version (about);

1093
  g_object_notify (G_OBJECT (about), "program-name");
1094 1095
}

1096

1097 1098 1099
/**
 * gtk_about_dialog_get_version:
 * @about: a #GtkAboutDialog
Matthias Clasen's avatar
Matthias Clasen committed
1100
 *
1101
 * Returns the version string.
Matthias Clasen's avatar
Matthias Clasen committed
1102
 *
1103 1104 1105 1106
 * Return value: The version string. The string is owned by the about
 *  dialog and must not be modified.
 *
 * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
1107
 */
1108 1109 1110 1111 1112
G_CONST_RETURN gchar *
gtk_about_dialog_get_version (GtkAboutDialog *about)
{
  g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);

1113
  return about->priv->version;
1114 1115 1116 1117 1118
}

/**
 * gtk_about_dialog_set_version:
 * @about: a #GtkAboutDialog
1119
 * @version: (allow-none): the version string
1120 1121
 *
 * Sets the version string to display in the about dialog.
Matthias Clasen's avatar
Matthias Clasen committed
1122
 *
1123
 * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
1124
 */
1125
void
Matthias Clasen's avatar
Matthias Clasen committed
1126 1127
gtk_about_dialog_set_version (GtkAboutDialog *about,
                              const gchar    *version)
1128 1129 1130 1131 1132 1133
{
  GtkAboutDialogPrivate *priv;
  gchar *tmp;

  g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));

1134 1135
  priv = about->priv;

1136
  tmp = priv->version;
1137
  priv->version = g_strdup (version);
Matthias Clasen's avatar
Matthias Clasen committed
1138
  g_free (tmp);
1139 1140 1141 1142 1143 1144 1145 1146 1147

  update_name_version (about);

  g_object_notify (G_OBJECT (about), "version");
}

/**
 * gtk_about_dialog_get_copyright:
 * @about: a #GtkAboutDialog
Matthias Clasen's avatar
Matthias Clasen committed
1148
 *
1149
 * Returns the copyright string.
Matthias Clasen's avatar
Matthias Clasen committed
1150
 *
1151 1152 1153 1154
 * Return value: The copyright string. The string is owned by the about
 *  dialog and must not be modified.
 *
 * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
1155
 */
1156 1157 1158 1159 1160
G_CONST_RETURN gchar *
gtk_about_dialog_get_copyright (GtkAboutDialog *about)
{
  g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);

1161
  return about->priv->copyright;
1162 1163 1164 1165 1166
}

/**
 * gtk_about_dialog_set_copyright:
 * @about: a #GtkAboutDialog
1167
 * @copyright: (allow-none) the copyright string
Matthias Clasen's avatar
Matthias Clasen committed
1168
 *
1169
 * Sets the copyright string to display in the about dialog.
Matthias Clasen's avatar
Matthias Clasen committed
1170
 * This should be a short string of one or two lines.
1171 1172
 *
 * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
1173
 */
1174
void
Matthias Clasen's avatar
Matthias Clasen committed
1175 1176
gtk_about_dialog_set_copyright (GtkAboutDialog *about,
                                const gchar    *copyright)
1177 1178 1179 1180 1181 1182
{
  GtkAboutDialogPrivate *priv;
  gchar *copyright_string, *tmp;

  g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));

1183
  priv = about->priv;
Matthias Clasen's avatar
Matthias Clasen committed
1184

1185
  tmp = priv->copyright;
1186
  priv->copyright = g_strdup (copyright);
1187
  g_free (tmp);
Matthias Clasen's avatar
Matthias Clasen committed
1188 1189

  if (priv->copyright != NULL)
1190
    {
Matthias Clasen's avatar
Matthias Clasen committed
1191 1192
      copyright_string = g_markup_printf_escaped ("<span size=\"small\">%s</span>",
                                                  priv->copyright);
1193 1194
      gtk_label_set_markup (GTK_LABEL (priv->copyright_label), copyright_string);
      g_free (copyright_string);
Matthias Clasen's avatar
Matthias Clasen committed
1195

1196 1197
      gtk_widget_show (priv->copyright_label);
    }
Matthias Clasen's avatar
Matthias Clasen committed
1198
  else
1199
    gtk_widget_hide (priv->copyright_label);
Matthias Clasen's avatar
Matthias Clasen committed
1200

1201 1202 1203 1204 1205 1206
  g_object_notify (G_OBJECT (about), "copyright");
}

/**
 * gtk_about_dialog_get_comments:
 * @about: a #GtkAboutDialog
Matthias Clasen's avatar
Matthias Clasen committed
1207
 *
1208
 * Returns the comments string.
Matthias Clasen's avatar
Matthias Clasen committed
1209
 *
1210 1211 1212 1213
 * Return value: The comments. The string is owned by the about
 *  dialog and must not be modified.
 *
 * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
1214
 */
1215 1216 1217 1218 1219
G_CONST_RETURN gchar *
gtk_about_dialog_get_comments (GtkAboutDialog *about)
{
  g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);

1220
  return about->priv->comments;
1221 1222 1223 1224 1225
}

/**
 * gtk_about_dialog_set_comments:
 * @about: a #GtkAboutDialog
1226
 * @comments: (allow-none): a comments string
Matthias Clasen's avatar
Matthias Clasen committed
1227 1228 1229
 *
 * Sets the comments string to display in the about dialog.
 * This should be a short string of one or two lines.
1230 1231
 *
 * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
1232
 */
1233
void
Matthias Clasen's avatar
Matthias Clasen committed
1234 1235
gtk_about_dialog_set_comments (GtkAboutDialog *about,
                               const gchar    *comments)
1236 1237 1238 1239 1240 1241
{
  GtkAboutDialogPrivate *priv;
  gchar *tmp;

  g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));

1242
  priv = about->priv;
Matthias Clasen's avatar
Matthias Clasen committed
1243

1244
  tmp = priv->comments;
Matthias Clasen's avatar
Matthias Clasen committed
1245
  if (comments)
1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263
    {
      priv->comments = g_strdup (comments);
      gtk_label_set_text (GTK_LABEL (priv->comments_label), priv->comments);
      gtk_widget_show (priv->comments_label);
    }
  else
    {
      priv->comments = NULL;
      gtk_widget_hide (priv->comments_label);
    }
  g_free (tmp);

  g_object_notify (G_OBJECT (about), "comments");
}

/**
 * gtk_about_dialog_get_license:
 * @about: a #GtkAboutDialog
Matthias Clasen's avatar
Matthias Clasen committed
1264
 *
1265
 * Returns the license information.
Matthias Clasen's avatar
Matthias Clasen committed
1266
 *
1267 1268 1269 1270
 * Return value: The license information. The string is owned by the about
 *  dialog and must not be modified.
 *
 * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
1271
 */
1272 1273 1274 1275 1276
G_CONST_RETURN gchar *
gtk_about_dialog_get_license (GtkAboutDialog *about)
{
  g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);

1277
  return about->priv->license;
1278 1279 1280 1281 1282
}

/**
 * gtk_about_dialog_set_license:
 * @about: a #GtkAboutDialog
1283
 * @license: (allow-none): the license information or %NULL
1284 1285 1286 1287
 *
 * Sets the license information to be displayed in the secondary
 * license dialog. If @license is %NULL, the license button is
 * hidden.
Matthias Clasen's avatar
Matthias Clasen committed
1288
 *
1289
 * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
1290
 */
1291
void
Matthias Clasen's avatar
Matthias Clasen committed
1292 1293
gtk_about_dialog_set_license (GtkAboutDialog *about,
                              const gchar    *license)
1294 1295 1296 1297 1298 1299
{
  GtkAboutDialogPrivate *priv;
  gchar *tmp;

  g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));

1300
  priv = about->priv;
1301 1302

  tmp = priv->license;
Matthias Clasen's avatar
Matthias Clasen committed
1303
  if (license)
1304 1305
    {
      priv->license = g_strdup (license);
1306
      priv->license_type = GTK_LICENSE_CUSTOM;
1307 1308 1309 1310
    }
  else
    {
      priv->license = NULL;
1311
      priv->license_type = GTK_LICENSE_UNKNOWN;
1312 1313 1314
    }
  g_free (tmp);

1315 1316 1317 1318
  gtk_widget_hide (priv->license_label);

  update_license_button_visibility (about);

1319
  g_object_notify (G_OBJECT (about), "license");
1320
  g_object_notify (G_OBJECT (about), "license-type");
1321 1322
}

1323 1324 1325 1326
/**
 * gtk_about_dialog_get_wrap_license:
 * @about: a #GtkAboutDialog
 *
Matthias Clasen's avatar
Matthias Clasen committed
1327
 * Returns whether the license text in @about is
1328 1329
 * automatically wrapped.
 *
Matthias Clasen's avatar
Matthias Clasen committed
1330
 * Returns: %TRUE if the license text is wrapped
1331 1332 1333 1334 1335 1336 1337 1338
 *
 * Since: 2.8
 */
gboolean
gtk_about_dialog_get_wrap_license (GtkAboutDialog *about)
{
  g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), FALSE);

1339
  return about->priv->wrap_license;
1340 1341 1342 1343 1344 1345 1346
}

/**
 * gtk_about_dialog_set_wrap_license:
 * @about: a #GtkAboutDialog
 * @wrap_license: whether to wrap the license
 *
Matthias Clasen's avatar
Matthias Clasen committed
1347
 * Sets whether the license text in @about is
1348
 * automatically wrapped.
Matthias Clasen's avatar
Matthias Clasen committed
1349
 *
1350 1351 1352 1353 1354 1355 1356 1357 1358 1359
 * Since: 2.8
 */
void
gtk_about_dialog_set_wrap_license (GtkAboutDialog *about,
                                   gboolean        wrap_license)
{
  GtkAboutDialogPrivate *priv;

  g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));

1360
  priv = about->priv;
1361 1362

  wrap_license = wrap_license != FALSE;
Matthias Clasen's avatar
Matthias Clasen committed
1363

1364 1365 1366 1367 1368 1369 1370 1371
  if (priv->wrap_license != wrap_license)
    {
       priv->wrap_license = wrap_license;

       g_object_notify (G_OBJECT (about), "wrap-license");
    }
}

1372 1373 1374
/**
 * gtk_about_dialog_get_website:
 * @about: a #GtkAboutDialog
Matthias Clasen's avatar
Matthias Clasen committed
1375
 *
1376
 * Returns the website URL.
Matthias Clasen's avatar
Matthias Clasen committed
1377
 *
1378 1379 1380 1381
 * Return value: The website URL. The string is owned by the about
 *  dialog and must not be modified.
 *
 * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
1382
 */
1383 1384 1385 1386
G_CONST_RETURN gchar *
gtk_about_dialog_get_website (GtkAboutDialog *about)
{
  GtkAboutDialogPrivate *priv;
Matthias Clasen's avatar
Matthias Clasen committed
1387

1388 1389
  g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);

1390
  priv = about->priv;
1391

1392
  return priv->website_url;
1393 1394 1395 1396 1397
}

/**
 * gtk_about_dialog_set_website:
 * @about: a #GtkAboutDialog
1398
 * @website: (allow-none): a URL string starting with "http://"
Matthias Clasen's avatar
Matthias Clasen committed
1399
 *
1400 1401 1402
 * Sets the URL to use for the website link.
 *
 * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
1403
 */
1404
void
Matthias Clasen's avatar
Matthias Clasen committed
1405 1406
gtk_about_dialog_set_website (GtkAboutDialog *about,
                              const gchar    *website)
1407 1408 1409 1410 1411 1412
{
  GtkAboutDialogPrivate *priv;
  gchar *tmp;

  g_return_if_fail (GTK_IS_ABOUT_DIALOG (about));

1413
  priv = about->priv;
Matthias Clasen's avatar
Matthias Clasen committed
1414

1415 1416
  tmp = priv->website_url;
  priv->website_url = g_strdup (website);
Matthias Clasen's avatar
Matthias Clasen committed
1417
  g_free (tmp);
1418 1419

  update_website (about);
1420 1421 1422 1423 1424 1425 1426

  g_object_notify (G_OBJECT (about), "website");
}

/**
 * gtk_about_dialog_get_website_label:
 * @about: a #GtkAboutDialog
Matthias Clasen's avatar
Matthias Clasen committed
1427 1428 1429 1430 1431
 *
 * Returns the label used for the website link.
 *
 * Return value: The label used for the website link. The string is
 *     owned by the about dialog and must not be modified.
1432 1433
 *
 * Since: 2.6
Matthias Clasen's avatar
Matthias Clasen committed
1434
 */
1435 1436 1437 1438
G_CONST_RETURN gchar *
gtk_about_dialog_get_website_label (GtkAboutDialog *about)
{
  GtkAboutDialogPrivate *priv;
Matthias Clasen's avatar
Matthias Clasen committed
1439

1440 1441
  g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL);

Cody Russell's avatar