diff --git a/app/core/gimp-utils.c b/app/core/gimp-utils.c index 5bd0f493fd..ba6c2ee1a7 100644 --- a/app/core/gimp-utils.c +++ b/app/core/gimp-utils.c @@ -75,9 +75,15 @@ typedef struct const gchar *lang; GString *original; gint foreign_level; + + gchar **introduction; + GList **release_items; } ParseState; +static gchar * gimp_appstream_parse (const gchar *as_text, + gchar **introduction, + GList **release_items); static void appstream_text_start_element (GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, @@ -955,49 +961,19 @@ gimp_ascii_strtod (const gchar *nptr, gchar * gimp_appstream_to_pango_markup (const gchar *as_text) { - static const GMarkupParser appstream_text_parser = - { - appstream_text_start_element, - appstream_text_end_element, - appstream_text_characters, - NULL, /* passthrough */ - NULL /* error */ - }; - - GimpXmlParser *xml_parser; - gchar *markup = NULL; - GError *error = NULL; - ParseState state; - - state.level = 0; - state.foreign_level = -1; - state.text = g_string_new (NULL); - state.numbered_list = FALSE; - state.unnumbered_list = FALSE; - state.lang = g_getenv ("LANGUAGE"); - state.original = NULL; - - xml_parser = gimp_xml_parser_new (&appstream_text_parser, &state); - if (as_text && - ! gimp_xml_parser_parse_buffer (xml_parser, as_text, -1, &error)) - { - g_printerr ("%s: %s\n", G_STRFUNC, error->message); - g_error_free (error); - } - - /* Append possibly last original text without proper localization. */ - if (state.original) - { - g_string_append (state.text, state.original->str); - g_string_free (state.original, TRUE); - } - - markup = g_string_free (state.text, FALSE); - gimp_xml_parser_free (xml_parser); - - return markup; + return gimp_appstream_parse (as_text, NULL, NULL); } +void +gimp_appstream_to_pango_markups (const gchar *as_text, + gchar **introduction, + GList **release_items) +{ + gchar * markup; + + markup = gimp_appstream_parse (as_text, introduction, release_items); + g_free (markup); +} gint gimp_g_list_compare (GList *list1, @@ -1308,6 +1284,61 @@ gimp_create_image_from_buffer (Gimp *gimp, /* Private functions */ + +static gchar * +gimp_appstream_parse (const gchar *as_text, + gchar **introduction, + GList **release_items) +{ + static const GMarkupParser appstream_text_parser = + { + appstream_text_start_element, + appstream_text_end_element, + appstream_text_characters, + NULL, /* passthrough */ + NULL /* error */ + }; + + GimpXmlParser *xml_parser; + gchar *markup = NULL; + GError *error = NULL; + ParseState state; + + state.level = 0; + state.foreign_level = -1; + state.text = g_string_new (NULL); + state.list_num = 0; + state.numbered_list = FALSE; + state.unnumbered_list = FALSE; + state.lang = g_getenv ("LANGUAGE"); + state.original = NULL; + state.introduction = introduction; + state.release_items = release_items; + + xml_parser = gimp_xml_parser_new (&appstream_text_parser, &state); + if (as_text && + ! gimp_xml_parser_parse_buffer (xml_parser, as_text, -1, &error)) + { + g_printerr ("%s: %s\n", G_STRFUNC, error->message); + g_error_free (error); + } + + /* Append possibly last original text without proper localization. */ + if (state.original) + { + g_string_append (state.text, state.original->str); + g_string_free (state.original, TRUE); + } + + if (release_items) + *release_items = g_list_reverse (*release_items); + + markup = g_string_free (state.text, FALSE); + gimp_xml_parser_free (xml_parser); + + return markup; +} + static void appstream_text_start_element (GMarkupParseContext *context, const gchar *element_name, @@ -1367,6 +1398,7 @@ appstream_text_start_element (GMarkupParseContext *context, else if (g_strcmp0 (element_name, "ul") == 0) { state->unnumbered_list = TRUE; + state->list_num = 0; } else if (g_strcmp0 (element_name, "ol") == 0) { @@ -1407,6 +1439,10 @@ appstream_text_end_element (GMarkupParseContext *context, { if (state->foreign_level < 0) { + if (state->introduction && + *state->introduction == NULL) + *state->introduction = g_strdup (state->original ? state->original->str : state->text->str); + if (state->original) g_string_append (state->original, "\n\n"); else @@ -1440,8 +1476,24 @@ appstream_text_characters (GMarkupParseContext *context, { ParseState *state = user_data; - if (state->foreign_level < 0) + if (state->foreign_level < 0 && text_len > 0) { + if (state->list_num > 0 && state->release_items) + { + GList **items = state->release_items; + + if (state->list_num == g_list_length (*(state->release_items))) + { + gchar *tmp = (*items)->data; + + (*items)->data = g_strconcat (tmp, text, NULL); + g_free (tmp); + } + else + { + *items = g_list_prepend (*items, g_strdup (text)); + } + } if (state->original) g_string_append (state->original, text); else diff --git a/app/core/gimp-utils.h b/app/core/gimp-utils.h index 4523b9247c..ccc8906b48 100644 --- a/app/core/gimp-utils.h +++ b/app/core/gimp-utils.h @@ -102,6 +102,9 @@ gboolean gimp_ascii_strtod (const gchar *nptr, gdouble *result); gchar * gimp_appstream_to_pango_markup (const gchar *as_text); +void gimp_appstream_to_pango_markups (const gchar *as_text, + gchar **introduction, + GList **release_items); gint gimp_g_list_compare (GList *list1, GList *list2); diff --git a/app/dialogs/welcome-dialog.c b/app/dialogs/welcome-dialog.c index 004b9f6749..f4e1b15f3a 100644 --- a/app/dialogs/welcome-dialog.c +++ b/app/dialogs/welcome-dialog.c @@ -74,15 +74,15 @@ welcome_dialog_create (Gimp *gimp) GtkWidget *vbox; GtkWidget *hbox; GtkWidget *image; + GtkWidget *listbox; GtkWidget *widget; - GtkTextBuffer *buffer; - GtkTextIter iter; - gchar *release_link; gchar *appdata_path; gchar *title; gchar *markup; + gchar *release_introduction = NULL; + GList *release_items = NULL; gchar *tmp; gint row; @@ -344,26 +344,55 @@ welcome_dialog_create (Gimp *gimp) /* Release note contents. */ - scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0); - gtk_widget_show (scrolled_window); + gimp_appstream_to_pango_markups (release_notes, + &release_introduction, + &release_items); + if (release_introduction) + { + widget = gtk_label_new (NULL); + gtk_label_set_markup (GTK_LABEL (widget), release_introduction); + gtk_label_set_max_width_chars (GTK_LABEL (widget), 70); + gtk_label_set_selectable (GTK_LABEL (widget), FALSE); + gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_LEFT); + gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE); + gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); - widget = gtk_text_view_new (); - gtk_widget_set_vexpand (widget, TRUE); - gtk_widget_set_hexpand (widget, TRUE); - gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (widget), GTK_WRAP_WORD_CHAR); - gtk_text_view_set_editable (GTK_TEXT_VIEW (widget), FALSE); - gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (widget), FALSE); - gtk_text_view_set_justification (GTK_TEXT_VIEW (widget), GTK_JUSTIFY_LEFT); - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget)); - gtk_text_buffer_get_start_iter (buffer, &iter); + g_free (release_introduction); + } - markup = gimp_appstream_to_pango_markup (release_notes); - gtk_text_buffer_insert_markup (buffer, &iter, markup, -1); - g_free (markup); + if (release_items) + { + GList *item; - gtk_container_add (GTK_CONTAINER (scrolled_window), widget); - gtk_widget_show (widget); + scrolled_window = gtk_scrolled_window_new (NULL, NULL); + gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0); + gtk_widget_show (scrolled_window); + + listbox = gtk_list_box_new (); + + for (item = release_items; item; item = item->next) + { + GtkWidget *row; + + row = gtk_list_box_row_new (); + widget = gtk_label_new (NULL); + gtk_label_set_markup (GTK_LABEL (widget), item->data); + gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE); + gtk_label_set_line_wrap_mode (GTK_LABEL (widget), PANGO_WRAP_WORD); + gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_LEFT); + gtk_widget_set_halign (widget, GTK_ALIGN_START); + gtk_label_set_xalign (GTK_LABEL (widget), 0.0); + gtk_container_add (GTK_CONTAINER (row), widget); + + gtk_list_box_insert (GTK_LIST_BOX (listbox), row, -1); + gtk_widget_show_all (row); + } + gtk_container_add (GTK_CONTAINER (scrolled_window), listbox); + gtk_widget_show (listbox); + + g_list_free_full (release_items, g_free); + } hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);