mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-10-06 01:12:40 +02:00
Compare commits
3 Commits
5099a13987
...
wip/Jehan/
Author | SHA1 | Date | |
---|---|---|---|
|
68ac064cf2 | ||
|
fb37c5cdd2 | ||
|
53008ec00a |
@@ -129,6 +129,12 @@ enum
|
||||
PROP_LAST_RELEASE_COMMENT,
|
||||
PROP_LAST_REVISION,
|
||||
PROP_LAST_KNOWN_RELEASE,
|
||||
PROP_LAST_MESSAGE_ID,
|
||||
PROP_MESSAGES,
|
||||
PROP_MESSAGE_TITLES,
|
||||
PROP_MESSAGE_IMAGES,
|
||||
PROP_MESSAGE_DATES,
|
||||
PROP_N_NEW_MESSAGES,
|
||||
#ifdef G_OS_WIN32
|
||||
PROP_WIN32_POINTER_INPUT_API,
|
||||
#endif
|
||||
@@ -700,6 +706,43 @@ gimp_core_config_class_init (GimpCoreConfigClass *klass)
|
||||
0, G_MAXINT, 0,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_STRING (object_class, PROP_LAST_MESSAGE_ID,
|
||||
"last-message-id",
|
||||
"ID of the last message from core team",
|
||||
LAST_KNOWN_RELEASE_BLURB,
|
||||
NULL,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
/* These are messages from the official GIMP team. We don't want to
|
||||
* store these in gimprc. We only store the last message ID. Yet we
|
||||
* want to keep these in a property for passing them through.
|
||||
*/
|
||||
g_object_class_install_property (object_class, PROP_MESSAGES,
|
||||
g_param_spec_boxed ("messages", NULL, NULL,
|
||||
G_TYPE_STRV,
|
||||
GIMP_PARAM_STATIC_STRINGS |
|
||||
GIMP_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class, PROP_MESSAGE_TITLES,
|
||||
g_param_spec_boxed ("message-titles", NULL, NULL,
|
||||
G_TYPE_STRV,
|
||||
GIMP_PARAM_STATIC_STRINGS |
|
||||
GIMP_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class, PROP_MESSAGE_IMAGES,
|
||||
g_param_spec_boxed ("message-images", NULL, NULL,
|
||||
G_TYPE_STRV,
|
||||
GIMP_PARAM_STATIC_STRINGS |
|
||||
GIMP_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class, PROP_MESSAGE_DATES,
|
||||
g_param_spec_boxed ("message-dates", NULL, NULL,
|
||||
G_TYPE_STRV,
|
||||
GIMP_PARAM_STATIC_STRINGS |
|
||||
GIMP_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class, PROP_N_NEW_MESSAGES,
|
||||
g_param_spec_int ("n-new-messages", NULL, NULL,
|
||||
0, G_MAXINT, 0,
|
||||
GIMP_PARAM_STATIC_STRINGS |
|
||||
GIMP_PARAM_READWRITE));
|
||||
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_SAVE_DOCUMENT_HISTORY,
|
||||
"save-document-history",
|
||||
"Save document history",
|
||||
@@ -857,6 +900,12 @@ gimp_core_config_init (GimpCoreConfig *config)
|
||||
|
||||
gimp_color_set_alpha (red, 0.5);
|
||||
config->quick_mask_color = red;
|
||||
config->last_message_id = NULL;
|
||||
config->messages = NULL;
|
||||
config->message_titles = NULL;
|
||||
config->message_images = NULL;
|
||||
config->message_dates = NULL;
|
||||
config->n_new_messages = 0;
|
||||
|
||||
config->default_image = g_object_new (GIMP_TYPE_TEMPLATE,
|
||||
"name", "Default Image",
|
||||
@@ -921,6 +970,12 @@ gimp_core_config_finalize (GObject *object)
|
||||
g_clear_pointer (&core_config->last_release_comment, g_free);
|
||||
g_clear_pointer (&core_config->config_version, g_free);
|
||||
|
||||
g_clear_pointer (&core_config->last_message_id, g_free);
|
||||
g_strfreev (core_config->messages);
|
||||
g_strfreev (core_config->message_titles);
|
||||
g_strfreev (core_config->message_images);
|
||||
g_strfreev (core_config->message_dates);
|
||||
|
||||
g_clear_object (&core_config->default_image);
|
||||
g_clear_object (&core_config->default_grid);
|
||||
g_clear_object (&core_config->color_management);
|
||||
@@ -1157,6 +1212,24 @@ gimp_core_config_set_property (GObject *object,
|
||||
g_set_str (&core_config->last_known_release, version);
|
||||
}
|
||||
break;
|
||||
case PROP_LAST_MESSAGE_ID:
|
||||
g_set_str (&core_config->last_message_id, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_MESSAGES:
|
||||
core_config->messages = g_value_dup_boxed (value);
|
||||
break;
|
||||
case PROP_MESSAGE_TITLES:
|
||||
core_config->message_titles = g_value_dup_boxed (value);
|
||||
break;
|
||||
case PROP_MESSAGE_IMAGES:
|
||||
core_config->message_images = g_value_dup_boxed (value);
|
||||
break;
|
||||
case PROP_MESSAGE_DATES:
|
||||
core_config->message_dates = g_value_dup_boxed (value);
|
||||
break;
|
||||
case PROP_N_NEW_MESSAGES:
|
||||
core_config->n_new_messages = g_value_get_int (value);
|
||||
break;
|
||||
case PROP_CONFIG_VERSION:
|
||||
g_set_str (&core_config->config_version,
|
||||
g_value_get_string (value));
|
||||
@@ -1431,6 +1504,24 @@ gimp_core_config_get_property (GObject *object,
|
||||
case PROP_LAST_KNOWN_RELEASE:
|
||||
g_value_set_string (value, core_config->last_known_release);
|
||||
break;
|
||||
case PROP_LAST_MESSAGE_ID:
|
||||
g_value_set_string (value, core_config->last_message_id);
|
||||
break;
|
||||
case PROP_MESSAGES:
|
||||
g_value_set_boxed (value, core_config->messages);
|
||||
break;
|
||||
case PROP_MESSAGE_TITLES:
|
||||
g_value_set_boxed (value, core_config->message_titles);
|
||||
break;
|
||||
case PROP_MESSAGE_IMAGES:
|
||||
g_value_set_boxed (value, core_config->message_images);
|
||||
break;
|
||||
case PROP_MESSAGE_DATES:
|
||||
g_value_set_boxed (value, core_config->message_dates);
|
||||
break;
|
||||
case PROP_N_NEW_MESSAGES:
|
||||
g_value_set_int (value, core_config->n_new_messages);
|
||||
break;
|
||||
case PROP_CONFIG_VERSION:
|
||||
g_value_set_string (value, core_config->config_version);
|
||||
break;
|
||||
|
@@ -118,6 +118,13 @@ struct _GimpCoreConfig
|
||||
gchar *last_release_comment;
|
||||
gint last_revision;
|
||||
|
||||
gchar *last_message_id;
|
||||
gchar **messages;
|
||||
gchar **message_titles;
|
||||
gchar **message_images;
|
||||
gchar **message_dates;
|
||||
gint n_new_messages;
|
||||
|
||||
gchar *config_version;
|
||||
};
|
||||
|
||||
|
@@ -208,7 +208,7 @@ dialogs_welcome_get (GimpDialogFactory *factory,
|
||||
GimpUIManager *ui_manager,
|
||||
gint view_size)
|
||||
{
|
||||
return welcome_dialog_create (context->gimp, TRUE);
|
||||
return welcome_dialog_create (context->gimp, TRUE, FALSE);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
|
@@ -66,7 +66,8 @@
|
||||
|
||||
static GtkWidget * welcome_dialog_new (Gimp *gimp,
|
||||
GimpConfig *config,
|
||||
gboolean show_welcome_page);
|
||||
gboolean show_welcome_page,
|
||||
gboolean show_messages_page);
|
||||
static void welcome_dialog_response (GtkWidget *widget,
|
||||
gint response_id,
|
||||
GtkWidget *dialog);
|
||||
@@ -96,6 +97,10 @@ static void welcome_dialog_create_creation_page (Gimp *gimp,
|
||||
GimpConfig *config,
|
||||
GtkWidget *welcome_dialog,
|
||||
GtkWidget *main_vbox);
|
||||
static void welcome_dialog_create_messages_page (Gimp *gimp,
|
||||
GimpConfig *config,
|
||||
GtkWidget *welcome_dialog,
|
||||
GtkWidget *main_vbox);
|
||||
static void welcome_dialog_create_release_page (Gimp *gimp,
|
||||
GtkWidget *welcome_dialog,
|
||||
GtkWidget *main_vbox);
|
||||
@@ -133,12 +138,16 @@ static void welcome_dialog_open_image_accelerator (GtkAccelGroup *accel_grou
|
||||
|
||||
static gboolean welcome_scrollable_resize (gpointer data);
|
||||
|
||||
static void welcome_dialog_messages_notified (GimpCoreConfig *config,
|
||||
const GParamSpec *pspec,
|
||||
GtkWidget *dialog);
|
||||
|
||||
static GtkWidget *welcome_dialog;
|
||||
|
||||
GtkWidget *
|
||||
welcome_dialog_create (Gimp *gimp,
|
||||
gboolean show_welcome_page)
|
||||
gboolean show_welcome_page,
|
||||
gboolean show_messages_page)
|
||||
{
|
||||
GimpConfig *config;
|
||||
GimpConfig *config_copy;
|
||||
@@ -165,7 +174,7 @@ welcome_dialog_create (Gimp *gimp,
|
||||
config, 0);
|
||||
|
||||
g_set_weak_pointer (&welcome_dialog,
|
||||
welcome_dialog_new (gimp, config_copy, show_welcome_page));
|
||||
welcome_dialog_new (gimp, config_copy, show_welcome_page, show_messages_page));
|
||||
|
||||
g_object_set_data (G_OBJECT (welcome_dialog), "gimp", gimp);
|
||||
|
||||
@@ -183,7 +192,8 @@ welcome_dialog_create (Gimp *gimp,
|
||||
static GtkWidget *
|
||||
welcome_dialog_new (Gimp *gimp,
|
||||
GimpConfig *config,
|
||||
gboolean show_welcome_page)
|
||||
gboolean show_welcome_page,
|
||||
gboolean show_messages_page)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
GList *windows;
|
||||
@@ -202,6 +212,8 @@ welcome_dialog_new (Gimp *gimp,
|
||||
GdkModifierType accel_mods;
|
||||
gchar **accels;
|
||||
|
||||
gchar **messages = NULL;
|
||||
|
||||
/* Translators: the %s string will be the version, e.g. "3.0". */
|
||||
title = g_strdup_printf (_("Welcome to GIMP %s"), GIMP_VERSION);
|
||||
windows = gimp_get_image_windows (gimp);
|
||||
@@ -302,9 +314,22 @@ welcome_dialog_new (Gimp *gimp,
|
||||
gtk_widget_set_visible (main_vbox, TRUE);
|
||||
|
||||
/* If dialog is set to always show on load, switch to the Create page */
|
||||
if (! show_welcome_page)
|
||||
if (! show_welcome_page && ! show_messages_page)
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (stack), "gimp-welcome-create");
|
||||
|
||||
g_object_get (gimp->config, "messages", &messages, NULL);
|
||||
g_object_set_data (G_OBJECT (dialog), "gimp", gimp);
|
||||
g_object_set_data (G_OBJECT (dialog), "show-welcome", GINT_TO_POINTER (show_welcome_page));
|
||||
g_object_set_data (G_OBJECT (dialog), "show-messages", GINT_TO_POINTER (show_messages_page));
|
||||
g_object_set_data (G_OBJECT (dialog), "stack", stack);
|
||||
if (messages && g_strv_length (messages) > 0)
|
||||
welcome_dialog_messages_notified (gimp->config, NULL, dialog);
|
||||
else
|
||||
g_signal_connect (gimp->config, "notify::messages",
|
||||
(GCallback) welcome_dialog_messages_notified,
|
||||
dialog);
|
||||
g_strfreev (messages);
|
||||
|
||||
if (gimp_welcome_dialog_n_items > 0)
|
||||
{
|
||||
main_vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box),
|
||||
@@ -962,6 +987,126 @@ welcome_dialog_create_contribute_page (Gimp *gimp,
|
||||
gtk_widget_set_visible (button, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
welcome_dialog_create_messages_page (Gimp *gimp,
|
||||
GimpConfig *config,
|
||||
GtkWidget *welcome_dialog,
|
||||
GtkWidget *main_vbox)
|
||||
{
|
||||
GtkWidget *label;
|
||||
gchar *markup;
|
||||
gchar *text;
|
||||
gchar **messages;
|
||||
gchar **titles;
|
||||
gchar **images;
|
||||
gchar **dates;
|
||||
gint n_new_messages;
|
||||
|
||||
g_object_get (config,
|
||||
"messages", &messages,
|
||||
"message-titles", &titles,
|
||||
"message-images", &images,
|
||||
"message-dates", &dates,
|
||||
"n-new-messages", &n_new_messages,
|
||||
NULL);
|
||||
|
||||
if (n_new_messages > 0)
|
||||
{
|
||||
text = g_strdup_printf (ngettext ("You have a new message from the GIMP team:",
|
||||
"You have %d new messages from the GIMP team:",
|
||||
n_new_messages),
|
||||
n_new_messages);
|
||||
markup = g_strdup_printf ("<big><b>%s</b></big>", text);
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label), markup);
|
||||
g_free (text);
|
||||
g_free (markup);
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0);
|
||||
gtk_widget_set_visible (label, TRUE);
|
||||
}
|
||||
|
||||
for (gint i = 0; messages[i]; i++)
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *frame_label;
|
||||
|
||||
if (i == n_new_messages && i != 0)
|
||||
{
|
||||
GtkWidget *separator;
|
||||
|
||||
separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), separator, FALSE, FALSE, 0);
|
||||
gtk_widget_set_visible (separator, TRUE);
|
||||
|
||||
text = g_strdup_printf ("Older messages:");
|
||||
markup = g_strdup_printf ("<big><b>%s</b></big>", text);
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label), markup);
|
||||
g_free (text);
|
||||
g_free (markup);
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0);
|
||||
gtk_widget_set_visible (label, TRUE);
|
||||
}
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
|
||||
gtk_widget_set_visible (frame, TRUE);
|
||||
|
||||
frame_label = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
|
||||
gtk_frame_set_label_widget (GTK_FRAME (frame), frame_label);
|
||||
gtk_widget_set_visible (frame_label, TRUE);
|
||||
|
||||
markup = g_strdup_printf ("<u>%s</u>", titles[i]);
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label), markup);
|
||||
gtk_box_pack_start (GTK_BOX (frame_label), label, FALSE, FALSE, 0);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_visible (label, TRUE);
|
||||
g_free (markup);
|
||||
|
||||
text = g_markup_escape_text (dates[i], -1);
|
||||
markup = g_strdup_printf ("<i>%s</i>", text);
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label), markup);
|
||||
gtk_box_pack_start (GTK_BOX (frame_label), label, FALSE, FALSE, 0);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_visible (label, TRUE);
|
||||
g_free (text);
|
||||
g_free (markup);
|
||||
|
||||
/* Note: I don't use a GtkTextView on purpose because it doesn't
|
||||
* support links in pango markup.
|
||||
*/
|
||||
label = gtk_label_new (NULL);
|
||||
gtk_label_set_markup (GTK_LABEL (label), messages[i]);
|
||||
gtk_widget_set_margin_top (label, 8);
|
||||
gtk_widget_set_margin_bottom (label, 14);
|
||||
gtk_widget_set_margin_start (label, 8);
|
||||
gtk_widget_set_margin_end (label, 8);
|
||||
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_valign (label, GTK_ALIGN_START);
|
||||
gtk_widget_set_hexpand (label, TRUE);
|
||||
gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_line_wrap_mode (GTK_LABEL (label), PANGO_WRAP_WORD_CHAR);
|
||||
gtk_label_set_track_visited_links (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_max_width_chars (GTK_LABEL (label), 80);
|
||||
gtk_label_set_width_chars (GTK_LABEL (label), 80);
|
||||
gtk_label_set_selectable (GTK_LABEL (label), TRUE);
|
||||
gtk_label_set_lines (GTK_LABEL (label), -1);
|
||||
gtk_label_set_xalign (GTK_LABEL (label), 0.0);
|
||||
gtk_container_add (GTK_CONTAINER (frame), label);
|
||||
gtk_widget_set_visible (label, TRUE);
|
||||
}
|
||||
|
||||
g_strfreev (messages);
|
||||
g_strfreev (titles);
|
||||
g_strfreev (images);
|
||||
g_strfreev (dates);
|
||||
}
|
||||
|
||||
static void
|
||||
welcome_dialog_create_release_page (Gimp *gimp,
|
||||
GtkWidget *welcome_dialog,
|
||||
@@ -1554,3 +1699,41 @@ welcome_dialog_open_image_accelerator (GtkAccelGroup *accel_group,
|
||||
if (gimp_ui_manager_activate_action (manager, "file", action_name))
|
||||
gtk_widget_destroy (welcome_dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
welcome_dialog_messages_notified (GimpCoreConfig *config,
|
||||
const GParamSpec *pspec,
|
||||
GtkWidget *dialog)
|
||||
{
|
||||
Gimp *gimp;
|
||||
GtkWidget *main_vbox;
|
||||
GtkWidget *prefs_box;
|
||||
GtkWidget *stack;
|
||||
GtkTreeIter top_iter;
|
||||
gboolean show_welcome;
|
||||
gboolean show_messages;
|
||||
|
||||
g_signal_handlers_disconnect_by_func (config,
|
||||
(GCallback) welcome_dialog_messages_notified,
|
||||
dialog);
|
||||
|
||||
gimp = g_object_get_data (G_OBJECT (dialog), "gimp");
|
||||
prefs_box = g_object_get_data (G_OBJECT (dialog), "prefs-box");
|
||||
stack = g_object_get_data (G_OBJECT (dialog), "stack");
|
||||
show_welcome = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (dialog), "show-welcome"));
|
||||
show_messages = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (dialog), "show-messages"));
|
||||
main_vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box),
|
||||
"dialog-information",
|
||||
_("Team Messages"),
|
||||
_("Team Messages"),
|
||||
"gimp-welcome-messages",
|
||||
NULL, &top_iter);
|
||||
gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
|
||||
|
||||
welcome_dialog_create_messages_page (gimp, GIMP_CONFIG (gimp->config), dialog, main_vbox);
|
||||
gtk_widget_set_visible (main_vbox, TRUE);
|
||||
|
||||
if (config->n_new_messages > 0 && ((pspec != NULL && ! show_welcome) ||
|
||||
(pspec == NULL && show_messages)))
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (stack), "gimp-welcome-messages");
|
||||
}
|
||||
|
@@ -22,4 +22,5 @@
|
||||
|
||||
|
||||
GtkWidget * welcome_dialog_create (Gimp *gimp,
|
||||
gboolean show_welcome_page);
|
||||
gboolean show_welcome_page,
|
||||
gboolean show_messages_page);
|
||||
|
@@ -55,6 +55,19 @@ static gboolean gimp_update_known (GimpCoreConfig *config,
|
||||
gint64 release_timestamp,
|
||||
gint build_revision,
|
||||
const gchar *comment);
|
||||
static gboolean gimp_update_get_highest (JsonParser *parser,
|
||||
gchar **highest_version,
|
||||
gint64 *release_timestamp,
|
||||
gint *build_revision,
|
||||
gchar **build_comment,
|
||||
gboolean unstable);
|
||||
static gboolean gimp_update_get_messages (JsonParser *parser,
|
||||
gchar **top_message_id,
|
||||
gchar ***titles,
|
||||
gchar ***messages,
|
||||
gchar ***images,
|
||||
gchar ***dates,
|
||||
gint *new_messages);
|
||||
static void gimp_check_updates_process (const gchar *source,
|
||||
gchar *file_contents,
|
||||
gsize file_length,
|
||||
@@ -67,6 +80,9 @@ static void gimp_check_updates_callback (GObject *source,
|
||||
static void gimp_update_about_dialog (GimpCoreConfig *config,
|
||||
const GParamSpec *pspec,
|
||||
gpointer user_data);
|
||||
static void gimp_update_welcome_dialog (GimpCoreConfig *config,
|
||||
const GParamSpec *pspec,
|
||||
gpointer user_data);
|
||||
|
||||
static const gchar * gimp_get_version_url (void);
|
||||
|
||||
@@ -327,6 +343,291 @@ gimp_update_get_highest (JsonParser *parser,
|
||||
return (*highest_version != NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_update_get_messages (JsonParser *parser,
|
||||
gchar **top_message_id,
|
||||
gchar ***titles,
|
||||
gchar ***messages,
|
||||
gchar ***images,
|
||||
gchar ***dates,
|
||||
gint *new_messages)
|
||||
{
|
||||
GStrvBuilder *titles_builder;
|
||||
GStrvBuilder *messages_builder;
|
||||
GStrvBuilder *images_builder;
|
||||
GStrvBuilder *dates_builder;
|
||||
JsonPath *path;
|
||||
JsonNode *result;
|
||||
JsonArray *messages_array;
|
||||
gchar *new_top_message_id = NULL;
|
||||
const gchar *path_str;
|
||||
const gchar *build_category;
|
||||
GError *error = NULL;
|
||||
gint i;
|
||||
gboolean is_new_message = TRUE;
|
||||
|
||||
g_return_val_if_fail (top_message_id != NULL, FALSE);
|
||||
g_return_val_if_fail (titles != NULL, FALSE);
|
||||
g_return_val_if_fail (messages != NULL, FALSE);
|
||||
g_return_val_if_fail (images != NULL, FALSE);
|
||||
g_return_val_if_fail (dates != NULL, FALSE);
|
||||
g_return_val_if_fail (new_messages != NULL, FALSE);
|
||||
|
||||
*titles = NULL;
|
||||
*messages = NULL;
|
||||
*images = NULL;
|
||||
*dates = NULL;
|
||||
*new_messages = 0;
|
||||
|
||||
path_str = "$['MESSAGES'][*]";
|
||||
path = json_path_new ();
|
||||
if (! json_path_compile (path, path_str, &error))
|
||||
{
|
||||
g_warning ("%s: path compilation failed: %s\n",
|
||||
G_STRFUNC, error->message);
|
||||
g_clear_error (&error);
|
||||
g_object_unref (path);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
result = json_path_match (path, json_parser_get_root (parser));
|
||||
if (! JSON_NODE_HOLDS_ARRAY (result))
|
||||
{
|
||||
g_printerr ("%s: match for \"%s\" is not a JSON array.\n",
|
||||
G_STRFUNC, path_str);
|
||||
g_object_unref (path);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
titles_builder = g_strv_builder_new ();
|
||||
messages_builder = g_strv_builder_new ();
|
||||
images_builder = g_strv_builder_new ();
|
||||
dates_builder = g_strv_builder_new ();
|
||||
|
||||
#if defined(GIMP_RELEASE)
|
||||
#if defined(GIMP_UNSTABLE)
|
||||
build_category = "devel";
|
||||
#else
|
||||
build_category = "stable";
|
||||
#endif
|
||||
#else
|
||||
build_category = "nightly";
|
||||
#endif
|
||||
|
||||
messages_array = json_node_get_array (result);
|
||||
for (i = 0; i < (gint) json_array_get_length (messages_array); i++)
|
||||
{
|
||||
JsonObject *msg;
|
||||
|
||||
msg = json_array_get_object_element (messages_array, i);
|
||||
if (! json_object_has_member (msg, "title") ||
|
||||
! json_object_has_member (msg, "message") ||
|
||||
! json_object_has_member (msg, "id") ||
|
||||
! json_object_has_member (msg, "date"))
|
||||
{
|
||||
/* JSON file data bug. */
|
||||
g_printerr ("%s: message %d misses mandatory elements.\n",
|
||||
G_STRFUNC, i);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
const gchar *id;
|
||||
const gchar *date;
|
||||
GDateTime *datetime;
|
||||
gchar *str;
|
||||
|
||||
id = json_object_get_string_member (msg, "id");
|
||||
|
||||
if (json_object_has_member (msg, "conditions"))
|
||||
{
|
||||
JsonArray *conditions;
|
||||
gboolean valid_message = FALSE;
|
||||
gint j;
|
||||
|
||||
conditions = json_object_get_array_member (msg, "conditions");
|
||||
/* The "conditions" is a list where if one condition
|
||||
* matches, then the message is considered valid.
|
||||
*/
|
||||
for (j = 0; j < (gint) json_array_get_length (conditions); j++)
|
||||
{
|
||||
gchar *condition;
|
||||
gchar *token;
|
||||
|
||||
condition = g_strdup (json_array_get_string_element (conditions, j));
|
||||
/* The format of conditions is:
|
||||
* "[os]:[build-id]:[stable|devel|nightly]:[ver]"
|
||||
* - Any part can be replaced by "*" to mean it
|
||||
* matches any value.
|
||||
* - Any missing section means "*" (so for instance,
|
||||
* you could just have a
|
||||
* "windows:org.gimp.GIMP_official" condition.
|
||||
* - The "[ver]" can be an exact version, e.g.
|
||||
* "3.0.4", but it can also ">3.0.4" or "<=3.0.4" or
|
||||
* again ">=3.0.0,<=3.0.4" for any version in between
|
||||
* these. I.e. a comma-separated list of version
|
||||
* comparisons.
|
||||
*/
|
||||
token = strtok (condition, ":");
|
||||
|
||||
if (g_strcmp0 (token, "*") == 0 ||
|
||||
g_strcmp0 (token, GIMP_BUILD_PLATFORM_FAMILY) == 0)
|
||||
{
|
||||
token = strtok (NULL, ":");
|
||||
if (token == NULL)
|
||||
{
|
||||
valid_message = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (token, "*") == 0 ||
|
||||
g_strcmp0 (token, GIMP_BUILD_ID) == 0)
|
||||
{
|
||||
token = strtok (NULL, ":");
|
||||
if (token == NULL)
|
||||
{
|
||||
valid_message = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (token, "*") == 0 ||
|
||||
g_strcmp0 (token, build_category) == 0)
|
||||
{
|
||||
gchar *vertok;
|
||||
|
||||
token = strtok (NULL, ":");
|
||||
if (token == NULL && g_strcmp0 (token, "*") == 0)
|
||||
{
|
||||
valid_message = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
valid_message = TRUE;
|
||||
|
||||
vertok = strtok (token, ",");
|
||||
while (vertok != NULL)
|
||||
{
|
||||
if (strlen (vertok) > 2 &&
|
||||
vertok[1] == '=')
|
||||
{
|
||||
if (vertok[0] == '>' &&
|
||||
gimp_version_cmp (vertok + 2, NULL) > 0)
|
||||
{
|
||||
valid_message = FALSE;
|
||||
break;
|
||||
}
|
||||
else if (vertok[0] == '<' &&
|
||||
gimp_version_cmp (vertok + 2, NULL) < 0)
|
||||
{
|
||||
valid_message = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (strlen (vertok) > 1 &&
|
||||
(vertok[0] == '>' || vertok[0] == '<'))
|
||||
{
|
||||
if (vertok[0] == '>' &&
|
||||
gimp_version_cmp (vertok + 1, NULL) >= 0)
|
||||
{
|
||||
valid_message = FALSE;
|
||||
break;
|
||||
}
|
||||
else if (vertok[0] == '<' &&
|
||||
gimp_version_cmp (vertok + 1, NULL) <= 0)
|
||||
{
|
||||
valid_message = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (strlen (vertok) > 0 &&
|
||||
gimp_version_cmp (vertok, NULL) != 0)
|
||||
{
|
||||
valid_message = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (! valid_message)
|
||||
break;
|
||||
|
||||
vertok = strtok (NULL, ",");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_free (condition);
|
||||
|
||||
if (valid_message)
|
||||
break;
|
||||
}
|
||||
|
||||
if (! valid_message)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*top_message_id &&
|
||||
is_new_message &&
|
||||
g_strcmp0 (id, *top_message_id) == 0)
|
||||
/* Below messages were all shown in previous runs. */
|
||||
is_new_message = FALSE;
|
||||
|
||||
if (is_new_message)
|
||||
(*new_messages)++;
|
||||
|
||||
date = json_object_get_string_member (msg, "date");
|
||||
str = g_strdup_printf ("%s 00:00:00Z", date);
|
||||
datetime = g_date_time_new_from_iso8601 (str, NULL);
|
||||
g_free (str);
|
||||
|
||||
if (datetime)
|
||||
{
|
||||
gchar *date = g_date_time_format (datetime, "%x");
|
||||
g_strv_builder_add (dates_builder, date);
|
||||
|
||||
g_free (date);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* JSON file data bug. */
|
||||
g_printerr ("%s: date for message %d not properly formatted: %s\n",
|
||||
G_STRFUNC, i, date);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (new_top_message_id == NULL)
|
||||
new_top_message_id = g_strdup (id);
|
||||
}
|
||||
|
||||
g_strv_builder_add (titles_builder, json_object_get_string_member (msg, "title"));
|
||||
g_strv_builder_add (messages_builder, json_object_get_string_member (msg, "message"));
|
||||
if (json_object_has_member (msg, "image"))
|
||||
g_strv_builder_add (images_builder, json_object_get_string_member (msg, "image"));
|
||||
else
|
||||
g_strv_builder_add (images_builder, "");
|
||||
}
|
||||
|
||||
*titles = g_strv_builder_end (titles_builder);
|
||||
*messages = g_strv_builder_end (messages_builder);
|
||||
*images = g_strv_builder_end (images_builder);
|
||||
*dates = g_strv_builder_end (dates_builder);
|
||||
|
||||
json_node_unref (result);
|
||||
g_object_unref (path);
|
||||
g_strv_builder_unref (titles_builder);
|
||||
g_strv_builder_unref (messages_builder);
|
||||
g_strv_builder_unref (images_builder);
|
||||
g_strv_builder_unref (dates_builder);
|
||||
|
||||
if (new_top_message_id)
|
||||
{
|
||||
g_free (*top_message_id);
|
||||
*top_message_id = new_top_message_id;
|
||||
}
|
||||
|
||||
return (g_strv_length (*titles) != 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_check_updates_process (const gchar *source,
|
||||
gchar *file_contents,
|
||||
@@ -337,6 +638,14 @@ gimp_check_updates_process (const gchar *source,
|
||||
gchar *build_comment = NULL;
|
||||
gint64 release_timestamp = 0;
|
||||
gint build_revision = 0;
|
||||
|
||||
gchar *last_message_id = NULL;
|
||||
gchar **titles = NULL;
|
||||
gchar **messages = NULL;
|
||||
gchar **images = NULL;
|
||||
gchar **dates = NULL;
|
||||
gint new_messages = 0;
|
||||
|
||||
GError *error = NULL;
|
||||
JsonParser *parser;
|
||||
|
||||
@@ -387,8 +696,41 @@ gimp_check_updates_process (const gchar *source,
|
||||
|
||||
gimp_update_known (config, last_version, release_timestamp, build_revision, build_comment);
|
||||
|
||||
g_object_get (config,
|
||||
"last-message-id", &last_message_id,
|
||||
NULL);
|
||||
|
||||
if (gimp_update_get_messages (parser, &last_message_id,
|
||||
&titles, &messages, &images, &dates,
|
||||
&new_messages))
|
||||
{
|
||||
g_object_set (config,
|
||||
"messages", messages,
|
||||
"message-titles", titles,
|
||||
"message-images", images,
|
||||
"message-dates", dates,
|
||||
"n-new-messages", new_messages,
|
||||
NULL);
|
||||
|
||||
if (config->last_known_release == NULL)
|
||||
/* Only update the last message ID if we didn't pop-up the About
|
||||
* dialog to announce a new release. Indeed in such a case, we
|
||||
* won't display the new message(s) and therefore the user
|
||||
* likely won't get knowledge of it (unless they were to later
|
||||
* open the Welcome dialog on their own.
|
||||
*/
|
||||
g_object_set (config,
|
||||
"last-message-id", last_message_id,
|
||||
NULL);
|
||||
}
|
||||
|
||||
g_clear_pointer (&last_version, g_free);
|
||||
g_clear_pointer (&build_comment, g_free);
|
||||
g_clear_pointer (&last_message_id, g_free);
|
||||
g_strfreev (titles);
|
||||
g_strfreev (messages);
|
||||
g_strfreev (images);
|
||||
|
||||
g_object_unref (parser);
|
||||
g_free (file_contents);
|
||||
}
|
||||
@@ -448,6 +790,30 @@ gimp_update_about_dialog (GimpCoreConfig *config,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_update_welcome_dialog (GimpCoreConfig *config,
|
||||
const GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
#ifndef GIMP_CONSOLE_COMPILATION
|
||||
Gimp *gimp = user_data;
|
||||
#endif
|
||||
|
||||
g_signal_handlers_disconnect_by_func (config,
|
||||
(GCallback) gimp_update_welcome_dialog,
|
||||
user_data);
|
||||
|
||||
if (config->last_known_release == NULL &&
|
||||
config->n_new_messages > 0)
|
||||
{
|
||||
#ifndef GIMP_CONSOLE_COMPILATION
|
||||
gtk_widget_show (welcome_dialog_create (gimp, FALSE, TRUE));
|
||||
#else
|
||||
g_printerr (_("You have new messages from the GIMP team."));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static const gchar *
|
||||
gimp_get_version_url (void)
|
||||
{
|
||||
@@ -519,7 +885,7 @@ gimp_update_auto_check (GimpCoreConfig *config,
|
||||
* dialog to always appear on load, show the Create page on start.
|
||||
*/
|
||||
if (! gimp->no_interface)
|
||||
gtk_widget_set_visible (welcome_dialog_create (gimp, is_update),
|
||||
gtk_widget_set_visible (welcome_dialog_create (gimp, is_update, FALSE),
|
||||
TRUE);
|
||||
|
||||
/* Do not check for new updates when GIMP was just updated. */
|
||||
@@ -562,6 +928,9 @@ gimp_update_auto_check (GimpCoreConfig *config,
|
||||
g_signal_connect (config, "notify::last-known-release",
|
||||
(GCallback) gimp_update_about_dialog,
|
||||
gimp);
|
||||
g_signal_connect (config, "notify::n-new-messages",
|
||||
(GCallback) gimp_update_welcome_dialog,
|
||||
gimp);
|
||||
|
||||
gimp_update_check (config);
|
||||
|
||||
|
Reference in New Issue
Block a user