diff --git a/gtk/gtkaboutdialog.c b/gtk/gtkaboutdialog.c index c527949078..490a66d9b0 100644 --- a/gtk/gtkaboutdialog.c +++ b/gtk/gtkaboutdialog.c @@ -142,6 +142,7 @@ struct _GtkAboutDialogPrivate gchar *website_text; gchar *translator_credits; gchar *license; + gchar *system_information; gchar **authors; gchar **documenters; @@ -151,11 +152,13 @@ struct _GtkAboutDialogPrivate gboolean credits_page_initialized; gboolean license_page_initialized; + gboolean system_page_initialized; GtkWidget *stack; GtkWidget *stack_switcher; GtkWidget *credits_button; GtkWidget *license_button; + GtkWidget *system_button; GtkWidget *logo_image; GtkWidget *name_label; @@ -167,9 +170,11 @@ struct _GtkAboutDialogPrivate GtkWidget *credits_page; GtkWidget *license_page; + GtkWidget *system_page; GtkWidget *credits_grid; GtkWidget *license_view; + GtkWidget *system_view; GdkCursor *hand_cursor; GdkCursor *regular_cursor; @@ -194,6 +199,7 @@ enum PROP_WEBSITE, PROP_WEBSITE_LABEL, PROP_LICENSE, + PROP_SYSTEM_INFORMATION, PROP_AUTHORS, PROP_DOCUMENTERS, PROP_TRANSLATOR_CREDITS, @@ -228,6 +234,7 @@ static void set_cursor_if_appropriate (GtkAboutDialog gint y); static void populate_credits_page (GtkAboutDialog *about); static void populate_license_page (GtkAboutDialog *about); +static void populate_system_page (GtkAboutDialog *about); static void close_cb (GtkAboutDialog *about); static gboolean gtk_about_dialog_activate_link (GtkAboutDialog *about, const gchar *uri); @@ -282,6 +289,14 @@ stack_visible_child_notify (GtkStack *stack, priv->license_page_initialized = TRUE; } } + else if (child == priv->system_page) + { + if (!priv->system_page_initialized) + { + populate_system_page (about); + priv->system_page_initialized = TRUE; + } + } return FALSE; } @@ -399,6 +414,10 @@ gtk_about_dialog_class_init (GtkAboutDialogClass *klass) * #GtkAboutDialog:license-type property is set to %GTK_LICENSE_CUSTOM * as a side effect. * + * The text may contain links in this format + * and email references in the form , and these will + * be converted into clickable links. + * * Since: 2.6 */ props[PROP_LICENSE] = @@ -408,6 +427,27 @@ gtk_about_dialog_class_init (GtkAboutDialogClass *klass) NULL, GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); + /** + * GtkAboutDialog:system-information: + * + * Information about the system on which the program is running. + * This is displayed in a separate tab, therefore it is fine to use + * a long multi-paragraph text. Note that the text should contain + * the intended linebreaks. + * + * The text may contain links in this format + * and email references in the form , and these will + * be converted into clickable links. + * + * Since: 3.90 + */ + props[PROP_SYSTEM_INFORMATION] = + g_param_spec_string ("system-information", + P_("System Information"), + P_("Information about the system on which the program is running"), + NULL, + GTK_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); + /** * GtkAboutDialog:license-type: * @@ -592,8 +632,10 @@ gtk_about_dialog_class_init (GtkAboutDialogClass *klass) gtk_widget_class_bind_template_child_private (widget_class, GtkAboutDialog, website_label); gtk_widget_class_bind_template_child_private (widget_class, GtkAboutDialog, credits_page); gtk_widget_class_bind_template_child_private (widget_class, GtkAboutDialog, license_page); + gtk_widget_class_bind_template_child_private (widget_class, GtkAboutDialog, system_page); gtk_widget_class_bind_template_child_private (widget_class, GtkAboutDialog, credits_grid); gtk_widget_class_bind_template_child_private (widget_class, GtkAboutDialog, license_view); + gtk_widget_class_bind_template_child_private (widget_class, GtkAboutDialog, system_view); gtk_widget_class_bind_template_callback (widget_class, emit_activate_link); gtk_widget_class_bind_template_callback (widget_class, text_view_event_after); @@ -619,7 +661,8 @@ update_stack_switcher_visibility (GtkAboutDialog *about) GtkAboutDialogPrivate *priv = about->priv; if (gtk_widget_get_visible (priv->credits_page) || - gtk_widget_get_visible (priv->license_page)) + gtk_widget_get_visible (priv->license_page) || + gtk_widget_get_visible (priv->system_page)) gtk_widget_show (priv->stack_switcher); else gtk_widget_hide (priv->stack_switcher); @@ -638,6 +681,19 @@ update_license_button_visibility (GtkAboutDialog *about) update_stack_switcher_visibility (about); } +static void +update_system_button_visibility (GtkAboutDialog *about) +{ + GtkAboutDialogPrivate *priv = about->priv; + + if (priv->system_information != NULL && priv->system_information[0] != '\0') + gtk_widget_show (priv->system_page); + else + gtk_widget_hide (priv->system_page); + + update_stack_switcher_visibility (about); +} + static void update_credits_button_visibility (GtkAboutDialog *about) { @@ -841,6 +897,9 @@ gtk_about_dialog_set_property (GObject *object, case PROP_LICENSE: gtk_about_dialog_set_license (about, g_value_get_string (value)); break; + case PROP_SYSTEM_INFORMATION: + gtk_about_dialog_set_system_information (about, g_value_get_string (value)); + break; case PROP_LICENSE_TYPE: gtk_about_dialog_set_license_type (about, g_value_get_enum (value)); break; @@ -906,6 +965,9 @@ gtk_about_dialog_get_property (GObject *object, case PROP_LICENSE: g_value_set_string (value, priv->license); break; + case PROP_SYSTEM_INFORMATION: + g_value_set_string (value, priv->system_information); + break; case PROP_LICENSE_TYPE: g_value_set_enum (value, priv->license_type); break; @@ -1354,6 +1416,30 @@ gtk_about_dialog_set_license (GtkAboutDialog *about, g_object_notify_by_pspec (G_OBJECT (about), props[PROP_LICENSE_TYPE]); } +const gchar * +gtk_about_dialog_get_system_information (GtkAboutDialog *about) +{ + g_return_val_if_fail (GTK_IS_ABOUT_DIALOG (about), NULL); + + return about->priv->system_information; +} + +void +gtk_about_dialog_set_system_information (GtkAboutDialog *about, + const gchar *system_information) +{ + GtkAboutDialogPrivate *priv; + + g_return_if_fail (GTK_IS_ABOUT_DIALOG (about)); + + priv = about->priv; + + priv->system_information = g_strdup (system_information); + update_system_button_visibility (about); + + g_object_notify_by_pspec (G_OBJECT (about), props[PROP_SYSTEM_INFORMATION]); +} + /** * gtk_about_dialog_get_wrap_license: * @about: a #GtkAboutDialog @@ -2354,6 +2440,20 @@ populate_license_page (GtkAboutDialog *about) g_object_unref (buffer); } +static void +populate_system_page (GtkAboutDialog *about) +{ + GtkAboutDialogPrivate *priv = about->priv; + GtkTextBuffer *buffer; + gchar *strings[2]; + + strings[0] = priv->system_information; + strings[1] = NULL; + buffer = text_buffer_new (about, strings); + gtk_text_view_set_buffer (GTK_TEXT_VIEW (priv->system_view), buffer); + g_object_unref (buffer); +} + /** * gtk_about_dialog_new: * diff --git a/gtk/gtkaboutdialog.h b/gtk/gtkaboutdialog.h index d00ea09134..98a532ea36 100644 --- a/gtk/gtkaboutdialog.h +++ b/gtk/gtkaboutdialog.h @@ -163,6 +163,11 @@ void gtk_about_dialog_set_wrap_license (GtkAboutDialog gboolean wrap_license); GDK_AVAILABLE_IN_ALL +const gchar * gtk_about_dialog_get_system_information (GtkAboutDialog *about); +GDK_AVAILABLE_IN_ALL +void gtk_about_dialog_set_system_information (GtkAboutDialog *about, + const gchar *system_information); +GDK_AVAILABLE_IN_ALL const gchar * gtk_about_dialog_get_website (GtkAboutDialog *about); GDK_AVAILABLE_IN_ALL void gtk_about_dialog_set_website (GtkAboutDialog *about, diff --git a/gtk/ui/gtkaboutdialog.ui b/gtk/ui/gtkaboutdialog.ui index 5c795a4a30..3a2729668c 100644 --- a/gtk/ui/gtkaboutdialog.ui +++ b/gtk/ui/gtkaboutdialog.ui @@ -87,7 +87,6 @@ 0 - 1 @@ -99,7 +98,19 @@ 0 - 2 + + + + + copyright + center + 1 + 1 + 1 + 60 + + + 0 @@ -114,23 +125,6 @@ 0 - end - 3 - - - - - copyright - center - 1 - 1 - 1 - 60 - - - 0 - end - 4 @@ -212,6 +206,39 @@ License + + + 1 + vertical + 8 + + + 1 + never + in + + + 1 + 0 + 8 + 8 + 0 + + + + + + + + 1 + + + + + system + System + + 1