From e05fb7b3e36c052baf0dd607ddeb22c0a2b5cbde Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:47:04 +0200 Subject: Adding upstream version 43.2. Signed-off-by: Daniel Baumann --- .../pages/language/cc-language-chooser.c | 597 +++++++++++++++++++++ .../pages/language/cc-language-chooser.h | 63 +++ gnome-initial-setup/pages/language/cc-util.c | 105 ++++ gnome-initial-setup/pages/language/cc-util.h | 28 + .../pages/language/gis-language-page.c | 312 +++++++++++ .../pages/language/gis-language-page.h | 57 ++ .../pages/language/gis-language-page.ui | 48 ++ .../pages/language/gis-welcome-widget.c | 242 +++++++++ .../pages/language/gis-welcome-widget.h | 56 ++ .../pages/language/gis-welcome-widget.ui | 14 + .../pages/language/language-chooser.ui | 22 + .../pages/language/language.gresource.xml | 10 + gnome-initial-setup/pages/language/meson.build | 16 + 13 files changed, 1570 insertions(+) create mode 100644 gnome-initial-setup/pages/language/cc-language-chooser.c create mode 100644 gnome-initial-setup/pages/language/cc-language-chooser.h create mode 100644 gnome-initial-setup/pages/language/cc-util.c create mode 100644 gnome-initial-setup/pages/language/cc-util.h create mode 100644 gnome-initial-setup/pages/language/gis-language-page.c create mode 100644 gnome-initial-setup/pages/language/gis-language-page.h create mode 100644 gnome-initial-setup/pages/language/gis-language-page.ui create mode 100644 gnome-initial-setup/pages/language/gis-welcome-widget.c create mode 100644 gnome-initial-setup/pages/language/gis-welcome-widget.h create mode 100644 gnome-initial-setup/pages/language/gis-welcome-widget.ui create mode 100644 gnome-initial-setup/pages/language/language-chooser.ui create mode 100644 gnome-initial-setup/pages/language/language.gresource.xml create mode 100644 gnome-initial-setup/pages/language/meson.build (limited to 'gnome-initial-setup/pages/language') diff --git a/gnome-initial-setup/pages/language/cc-language-chooser.c b/gnome-initial-setup/pages/language/cc-language-chooser.c new file mode 100644 index 0000000..309704c --- /dev/null +++ b/gnome-initial-setup/pages/language/cc-language-chooser.c @@ -0,0 +1,597 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2013 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Written by: + * Jasper St. Pierre + * Matthias Clasen + */ + +#include "config.h" +#include "cc-language-chooser.h" + +#include +#include +#include + +#include + +#define GNOME_DESKTOP_USE_UNSTABLE_API +#include + +#include "cc-common-language.h" +#include "cc-util.h" + +#include + +struct _CcLanguageChooserPrivate +{ + GtkWidget *filter_entry; + GtkWidget *language_list; + + GtkWidget *no_results; + GtkWidget *more_item; + + gboolean showing_extra; + gchar *language; +}; +typedef struct _CcLanguageChooserPrivate CcLanguageChooserPrivate; +G_DEFINE_TYPE_WITH_PRIVATE (CcLanguageChooser, cc_language_chooser, GTK_TYPE_BOX); + +enum { + PROP_0, + PROP_LANGUAGE, + PROP_SHOWING_EXTRA, + PROP_LAST, +}; + +static GParamSpec *obj_props[PROP_LAST]; + +enum { + CONFIRM, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +typedef struct { + GtkWidget *box; + GtkWidget *checkmark; + + gchar *locale_id; + gchar *locale_name; + gchar *locale_current_name; + gchar *locale_untranslated_name; + gchar *sort_key; + gboolean is_extra; +} LanguageWidget; + +static LanguageWidget * +get_language_widget (GtkWidget *widget) +{ + return g_object_get_data (G_OBJECT (widget), "language-widget"); +} + +static GtkWidget * +padded_label_new (char *text) +{ + GtkWidget *widget; + widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_widget_set_halign (widget, GTK_ALIGN_CENTER); + gtk_widget_set_margin_top (widget, 12); + gtk_widget_set_margin_bottom (widget, 12); + gtk_box_append (GTK_BOX (widget), gtk_label_new (text)); + return widget; +} + +static void +language_widget_free (gpointer data) +{ + LanguageWidget *widget = data; + + /* This is called when the box is destroyed, + * so don't bother destroying the widget and + * children again. */ + g_free (widget->locale_id); + g_free (widget->locale_name); + g_free (widget->locale_current_name); + g_free (widget->locale_untranslated_name); + g_free (widget->sort_key); + g_free (widget); +} + +static GtkWidget * +language_widget_new (const char *locale_id, + gboolean is_extra) +{ + GtkWidget *label; + gchar *locale_name, *locale_current_name, *locale_untranslated_name; + gchar *language = NULL; + gchar *language_name; + gchar *country = NULL; + gchar *country_name = NULL; + LanguageWidget *widget = g_new0 (LanguageWidget, 1); + + if (!gnome_parse_locale (locale_id, &language, &country, NULL, NULL)) + return NULL; + + language_name = gnome_get_language_from_code (language, locale_id); + if (language_name == NULL) + language_name = gnome_get_language_from_code (language, NULL); + + if (country) { + country_name = gnome_get_country_from_code (country, locale_id); + if (country_name == NULL) + country_name = gnome_get_country_from_code (country, NULL); + } + + locale_name = gnome_get_language_from_locale (locale_id, locale_id); + locale_current_name = gnome_get_language_from_locale (locale_id, NULL); + locale_untranslated_name = gnome_get_language_from_locale (locale_id, "C"); + + widget->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_widget_set_margin_top (widget->box, 12); + gtk_widget_set_margin_bottom (widget->box, 12); + gtk_widget_set_margin_start (widget->box, 12); + gtk_widget_set_margin_end (widget->box, 12); + gtk_widget_set_halign (widget->box, GTK_ALIGN_FILL); + + label = gtk_label_new (language_name); + gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END); + gtk_label_set_max_width_chars (GTK_LABEL (label), 30); + gtk_label_set_xalign (GTK_LABEL (label), 0); + gtk_box_append (GTK_BOX (widget->box), label); + + widget->checkmark = gtk_image_new_from_icon_name ("object-select-symbolic"); + gtk_box_append (GTK_BOX (widget->box), widget->checkmark); + + if (country_name) { + label = gtk_label_new (country_name); + gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END); + gtk_label_set_max_width_chars (GTK_LABEL (label), 30); + gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label"); + gtk_label_set_xalign (GTK_LABEL (label), 0); + gtk_widget_set_hexpand (label, TRUE); + gtk_widget_set_halign (label, GTK_ALIGN_END); + gtk_box_append (GTK_BOX (widget->box), label); + } + + widget->locale_id = g_strdup (locale_id); + widget->locale_name = locale_name; + widget->locale_current_name = locale_current_name; + widget->locale_untranslated_name = locale_untranslated_name; + widget->is_extra = is_extra; + widget->sort_key = cc_util_normalize_casefold_and_unaccent (locale_name); + + g_object_set_data_full (G_OBJECT (widget->box), "language-widget", widget, + language_widget_free); + + g_free (language); + g_free (language_name); + g_free (country); + g_free (country_name); + + return widget->box; +} + +static void +sync_all_checkmarks (CcLanguageChooser *chooser) +{ + CcLanguageChooserPrivate *priv = cc_language_chooser_get_instance_private (chooser); + GtkWidget *row; + + row = gtk_widget_get_first_child (priv->language_list); + while (row) { + LanguageWidget *widget; + GtkWidget *child; + gboolean should_be_visible; + + child = gtk_list_box_row_get_child (GTK_LIST_BOX_ROW (row)); + widget = get_language_widget (child); + + if (widget == NULL) + return; + + should_be_visible = g_str_equal (widget->locale_id, priv->language); + gtk_widget_set_opacity (widget->checkmark, should_be_visible ? 1.0 : 0.0); + + row = gtk_widget_get_next_sibling (row); + } +} + +static GtkWidget * +more_widget_new (void) +{ + GtkWidget *widget; + GtkWidget *arrow; + + widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); + gtk_widget_set_tooltip_text (widget, _("Moreā€¦")); + + arrow = g_object_new (GTK_TYPE_IMAGE, + "icon-name", "view-more-symbolic", + "hexpand", TRUE, + "halign", GTK_ALIGN_CENTER, + NULL); + gtk_style_context_add_class (gtk_widget_get_style_context (arrow), "dim-label"); + gtk_widget_set_margin_top (widget, 12); + gtk_widget_set_margin_bottom (widget, 12); + gtk_box_append (GTK_BOX (widget), arrow); + + return widget; +} + +static GtkWidget * +no_results_widget_new (void) +{ + GtkWidget *widget; + + widget = padded_label_new (_("No languages found")); + gtk_widget_set_sensitive (widget, FALSE); + + return widget; +} + +static void +add_one_language (CcLanguageChooser *chooser, + const char *locale_id, + gboolean is_initial) +{ + CcLanguageChooserPrivate *priv = cc_language_chooser_get_instance_private (chooser); + GtkWidget *widget; + + if (!cc_common_language_has_font (locale_id)) { + return; + } + + widget = language_widget_new (locale_id, !is_initial); + if (widget) + gtk_list_box_append (GTK_LIST_BOX (priv->language_list), widget); +} + +static void +add_languages (CcLanguageChooser *chooser, + char **locale_ids, + GHashTable *initial) +{ + CcLanguageChooserPrivate *priv = cc_language_chooser_get_instance_private (chooser); + GHashTableIter iter; + gchar *key; + + g_hash_table_iter_init (&iter, initial); + while (g_hash_table_iter_next (&iter, (gpointer *)&key, NULL)) { + add_one_language (chooser, key, TRUE); + } + + while (*locale_ids) { + const gchar *locale_id; + + locale_id = *locale_ids; + locale_ids ++; + + if (!g_hash_table_lookup (initial, locale_id)) + add_one_language (chooser, locale_id, FALSE); + } + + gtk_list_box_append (GTK_LIST_BOX (priv->language_list), priv->more_item); + gtk_list_box_set_placeholder (GTK_LIST_BOX (priv->language_list), priv->no_results); +} + +static void +add_all_languages (CcLanguageChooser *chooser) +{ + g_auto(GStrv) locale_ids = NULL; + g_autoptr(GHashTable) initial = NULL; + + locale_ids = gnome_get_all_locales (); + initial = cc_common_language_get_initial_languages (); + add_languages (chooser, locale_ids, initial); +} + +static gboolean +language_visible (GtkListBoxRow *row, + gpointer user_data) +{ + CcLanguageChooser *chooser = user_data; + CcLanguageChooserPrivate *priv = cc_language_chooser_get_instance_private (chooser); + LanguageWidget *widget; + gboolean visible; + GtkWidget *child; + const char *search_term; + + child = gtk_list_box_row_get_child (row); + if (child == priv->more_item) + return !priv->showing_extra; + + widget = get_language_widget (child); + + if (!priv->showing_extra && widget->is_extra) + return FALSE; + + search_term = gtk_editable_get_text (GTK_EDITABLE (priv->filter_entry)); + if (!search_term || !*search_term) + return TRUE; + + visible = FALSE; + + visible = g_str_match_string (search_term, widget->locale_name, TRUE); + if (visible) + goto out; + + visible = g_str_match_string (search_term, widget->locale_current_name, TRUE); + if (visible) + goto out; + + visible = g_str_match_string (search_term, widget->locale_untranslated_name, TRUE); + if (visible) + goto out; + + out: + return visible; +} + +static gint +sort_languages (GtkListBoxRow *a, + GtkListBoxRow *b, + gpointer data) +{ + LanguageWidget *la, *lb; + int ret; + + la = get_language_widget (gtk_list_box_row_get_child (a)); + lb = get_language_widget (gtk_list_box_row_get_child (b)); + + if (la == NULL) + return 1; + + if (lb == NULL) + return -1; + + if (la->is_extra && !lb->is_extra) + return 1; + + if (!la->is_extra && lb->is_extra) + return -1; + + ret = g_strcmp0 (la->sort_key, lb->sort_key); + if (ret != 0) + return ret; + + return g_strcmp0 (la->locale_id, lb->locale_id); +} + +static void +filter_changed (GtkEntry *entry, + CcLanguageChooser *chooser) +{ + CcLanguageChooserPrivate *priv = cc_language_chooser_get_instance_private (chooser); + gtk_list_box_invalidate_filter (GTK_LIST_BOX (priv->language_list)); +} + +static void +show_more (CcLanguageChooser *chooser) +{ + CcLanguageChooserPrivate *priv = cc_language_chooser_get_instance_private (chooser); + + gtk_widget_grab_focus (priv->filter_entry); + + gtk_widget_set_valign (GTK_WIDGET (chooser), GTK_ALIGN_FILL); + + priv->showing_extra = TRUE; + gtk_list_box_invalidate_filter (GTK_LIST_BOX (priv->language_list)); + g_object_notify_by_pspec (G_OBJECT (chooser), obj_props[PROP_SHOWING_EXTRA]); +} + +static void +set_locale_id (CcLanguageChooser *chooser, + const gchar *new_locale_id) +{ + CcLanguageChooserPrivate *priv = cc_language_chooser_get_instance_private (chooser); + + if (g_strcmp0 (priv->language, new_locale_id) == 0) + return; + + g_free (priv->language); + priv->language = g_strdup (new_locale_id); + + sync_all_checkmarks (chooser); + + g_object_notify_by_pspec (G_OBJECT (chooser), obj_props[PROP_LANGUAGE]); +} + +static gboolean +confirm_choice (gpointer data) +{ + GtkWidget *widget = data; + + g_signal_emit (widget, signals[CONFIRM], 0); + + return G_SOURCE_REMOVE; +} + +static void +row_activated (GtkListBox *box, + GtkListBoxRow *row, + CcLanguageChooser *chooser) +{ + CcLanguageChooserPrivate *priv = cc_language_chooser_get_instance_private (chooser); + GtkWidget *child; + LanguageWidget *widget; + + if (row == NULL) + return; + + child = gtk_list_box_row_get_child (row); + if (child == priv->more_item) { + show_more (chooser); + } else { + widget = get_language_widget (child); + if (widget == NULL) + return; + if (g_strcmp0 (priv->language, widget->locale_id) == 0) + g_idle_add (confirm_choice, chooser); + else + set_locale_id (chooser, widget->locale_id); + } +} + +static void +cc_language_chooser_constructed (GObject *object) +{ + CcLanguageChooser *chooser = CC_LANGUAGE_CHOOSER (object); + CcLanguageChooserPrivate *priv = cc_language_chooser_get_instance_private (chooser); + + G_OBJECT_CLASS (cc_language_chooser_parent_class)->constructed (object); + + priv->more_item = more_widget_new (); + priv->no_results = no_results_widget_new (); + + gtk_list_box_set_sort_func (GTK_LIST_BOX (priv->language_list), + sort_languages, chooser, NULL); + gtk_list_box_set_filter_func (GTK_LIST_BOX (priv->language_list), + language_visible, chooser, NULL); + gtk_list_box_set_selection_mode (GTK_LIST_BOX (priv->language_list), + GTK_SELECTION_NONE); + add_all_languages (chooser); + + g_signal_connect (priv->filter_entry, "changed", + G_CALLBACK (filter_changed), + chooser); + + g_signal_connect (priv->language_list, "row-activated", + G_CALLBACK (row_activated), chooser); + + if (priv->language == NULL) + priv->language = cc_common_language_get_current_language (); + + sync_all_checkmarks (chooser); +} + +static void +cc_language_chooser_finalize (GObject *object) +{ + CcLanguageChooser *chooser = CC_LANGUAGE_CHOOSER (object); + CcLanguageChooserPrivate *priv = cc_language_chooser_get_instance_private (chooser); + + g_free (priv->language); + + G_OBJECT_CLASS (cc_language_chooser_parent_class)->finalize (object); +} + +static void +cc_language_chooser_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + CcLanguageChooser *chooser = CC_LANGUAGE_CHOOSER (object); + switch (prop_id) { + case PROP_LANGUAGE: + g_value_set_string (value, cc_language_chooser_get_language (chooser)); + break; + case PROP_SHOWING_EXTRA: + g_value_set_boolean (value, cc_language_chooser_get_showing_extra (chooser)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +cc_language_chooser_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + CcLanguageChooser *chooser = CC_LANGUAGE_CHOOSER (object); + switch (prop_id) { + case PROP_LANGUAGE: + cc_language_chooser_set_language (chooser, g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +cc_language_chooser_class_init (CcLanguageChooserClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/control-center/language-chooser.ui"); + + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), CcLanguageChooser, filter_entry); + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), CcLanguageChooser, language_list); + + object_class->finalize = cc_language_chooser_finalize; + object_class->get_property = cc_language_chooser_get_property; + object_class->set_property = cc_language_chooser_set_property; + object_class->constructed = cc_language_chooser_constructed; + + signals[CONFIRM] = g_signal_new ("confirm", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (CcLanguageChooserClass, confirm), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + obj_props[PROP_LANGUAGE] = + g_param_spec_string ("language", "", "", "", + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + obj_props[PROP_SHOWING_EXTRA] = + g_param_spec_string ("showing-extra", "", "", "", + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, PROP_LAST, obj_props); +} + +static void +cc_language_chooser_init (CcLanguageChooser *chooser) +{ + gtk_widget_init_template (GTK_WIDGET (chooser)); +} + +void +cc_language_chooser_clear_filter (CcLanguageChooser *chooser) +{ + CcLanguageChooserPrivate *priv = cc_language_chooser_get_instance_private (chooser); + gtk_editable_set_text (GTK_EDITABLE (priv->filter_entry), ""); +} + +const gchar * +cc_language_chooser_get_language (CcLanguageChooser *chooser) +{ + CcLanguageChooserPrivate *priv = cc_language_chooser_get_instance_private (chooser); + return priv->language; +} + +void +cc_language_chooser_set_language (CcLanguageChooser *chooser, + const gchar *language) +{ + set_locale_id (chooser, language); +} + +gboolean +cc_language_chooser_get_showing_extra (CcLanguageChooser *chooser) +{ + CcLanguageChooserPrivate *priv = cc_language_chooser_get_instance_private (chooser); + return priv->showing_extra; +} diff --git a/gnome-initial-setup/pages/language/cc-language-chooser.h b/gnome-initial-setup/pages/language/cc-language-chooser.h new file mode 100644 index 0000000..749af78 --- /dev/null +++ b/gnome-initial-setup/pages/language/cc-language-chooser.h @@ -0,0 +1,63 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2013 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Written by: + * Jasper St. Pierre + * Matthias Clasen + */ + +#ifndef __CC_LANGUAGE_CHOOSER_H__ +#define __CC_LANGUAGE_CHOOSER_H__ + +#include +#include + +#define CC_TYPE_LANGUAGE_CHOOSER (cc_language_chooser_get_type ()) +#define CC_LANGUAGE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CC_TYPE_LANGUAGE_CHOOSER, CcLanguageChooser)) +#define CC_LANGUAGE_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CC_TYPE_LANGUAGE_CHOOSER, CcLanguageChooserClass)) +#define CC_IS_LANGUAGE_CHOOSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CC_TYPE_LANGUAGE_CHOOSER)) +#define CC_IS_LANGUAGE_CHOOSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CC_TYPE_LANGUAGE_CHOOSER)) +#define CC_LANGUAGE_CHOOSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CC_TYPE_LANGUAGE_CHOOSER, CcLanguageChooserClass)) + +G_BEGIN_DECLS + +typedef struct _CcLanguageChooser CcLanguageChooser; +typedef struct _CcLanguageChooserClass CcLanguageChooserClass; + +struct _CcLanguageChooser +{ + GtkBox parent; +}; + +struct _CcLanguageChooserClass +{ + GtkBoxClass parent_class; + + void (*confirm) (CcLanguageChooser *chooser); +}; + +GType cc_language_chooser_get_type (void); + +void cc_language_chooser_clear_filter (CcLanguageChooser *chooser); +const gchar * cc_language_chooser_get_language (CcLanguageChooser *chooser); +void cc_language_chooser_set_language (CcLanguageChooser *chooser, + const gchar *language); +gboolean cc_language_chooser_get_showing_extra (CcLanguageChooser *chooser); + +G_END_DECLS + +#endif /* __CC_LANGUAGE_CHOOSER_H__ */ diff --git a/gnome-initial-setup/pages/language/cc-util.c b/gnome-initial-setup/pages/language/cc-util.c new file mode 100644 index 0000000..e51a9d2 --- /dev/null +++ b/gnome-initial-setup/pages/language/cc-util.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2012 Giovanni Campagna + * + * The Control Center is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * The Control Center 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 General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with the Control Center; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "config.h" + +#include + + +#include "cc-util.h" + +/* Combining diacritical mark? + * Basic range: [0x0300,0x036F] + * Supplement: [0x1DC0,0x1DFF] + * For Symbols: [0x20D0,0x20FF] + * Half marks: [0xFE20,0xFE2F] + */ +#define IS_CDM_UCS4(c) (((c) >= 0x0300 && (c) <= 0x036F) || \ + ((c) >= 0x1DC0 && (c) <= 0x1DFF) || \ + ((c) >= 0x20D0 && (c) <= 0x20FF) || \ + ((c) >= 0xFE20 && (c) <= 0xFE2F)) + +/* Copied from tracker/src/libtracker-fts/tracker-parser-glib.c under the GPL + * And then from gnome-shell/src/shell-util.c + * + * Originally written by Aleksander Morgado + */ +char * +cc_util_normalize_casefold_and_unaccent (const char *str) +{ + char *normalized, *tmp; + int i = 0, j = 0, ilen; + + if (str == NULL) + return NULL; + + normalized = g_utf8_normalize (str, -1, G_NORMALIZE_NFKD); + tmp = g_utf8_casefold (normalized, -1); + g_free (normalized); + + ilen = strlen (tmp); + + while (i < ilen) + { + gunichar unichar; + gchar *next_utf8; + gint utf8_len; + + /* Get next character of the word as UCS4 */ + unichar = g_utf8_get_char_validated (&tmp[i], -1); + + /* Invalid UTF-8 character or end of original string. */ + if (unichar == (gunichar) -1 || + unichar == (gunichar) -2) + { + break; + } + + /* Find next UTF-8 character */ + next_utf8 = g_utf8_next_char (&tmp[i]); + utf8_len = next_utf8 - &tmp[i]; + + if (IS_CDM_UCS4 ((guint32) unichar)) + { + /* If the given unichar is a combining diacritical mark, + * just update the original index, not the output one */ + i += utf8_len; + continue; + } + + /* If already found a previous combining + * diacritical mark, indexes are different so + * need to copy characters. As output and input + * buffers may overlap, need to use memmove + * instead of memcpy */ + if (i != j) + { + memmove (&tmp[j], &tmp[i], utf8_len); + } + + /* Update both indexes */ + i += utf8_len; + j += utf8_len; + } + + /* Force proper string end */ + tmp[j] = '\0'; + + return tmp; +} diff --git a/gnome-initial-setup/pages/language/cc-util.h b/gnome-initial-setup/pages/language/cc-util.h new file mode 100644 index 0000000..42b09ff --- /dev/null +++ b/gnome-initial-setup/pages/language/cc-util.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2012 Giovanni Campagna + * + * The Control Center is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * The Control Center 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 General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with the Control Center; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + + +#ifndef _CC_UTIL_H +#define _CC_UTIL_H + +#include + +char *cc_util_normalize_casefold_and_unaccent (const char *str); + +#endif diff --git a/gnome-initial-setup/pages/language/gis-language-page.c b/gnome-initial-setup/pages/language/gis-language-page.c new file mode 100644 index 0000000..f62b2ad --- /dev/null +++ b/gnome-initial-setup/pages/language/gis-language-page.c @@ -0,0 +1,312 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2012 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Written by: + * Jasper St. Pierre + * Michael Wood + * + * Based on gnome-control-center cc-region-panel.c + */ + +/* Language page {{{1 */ + +#define PAGE_ID "language" + +#define GNOME_SYSTEM_LOCALE_DIR "org.gnome.system.locale" +#define REGION_KEY "region" + +#include "config.h" +#include "language-resources.h" +#include "gis-welcome-widget.h" +#include "cc-language-chooser.h" +#include "gis-language-page.h" + +#include +#include +#include +#include + +struct _GisLanguagePagePrivate +{ + GtkWidget *logo; + GtkWidget *welcome_widget; + GtkWidget *language_chooser; + + GDBusProxy *localed; + GPermission *permission; + const gchar *new_locale_id; + + GCancellable *cancellable; +}; +typedef struct _GisLanguagePagePrivate GisLanguagePagePrivate; + +G_DEFINE_TYPE_WITH_PRIVATE (GisLanguagePage, gis_language_page, GIS_TYPE_PAGE); + +static void +set_localed_locale (GisLanguagePage *self) +{ + GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (self); + GVariantBuilder *b; + gchar *s; + + b = g_variant_builder_new (G_VARIANT_TYPE ("as")); + s = g_strconcat ("LANG=", priv->new_locale_id, NULL); + g_variant_builder_add (b, "s", s); + g_free (s); + + g_dbus_proxy_call (priv->localed, + "SetLocale", + g_variant_new ("(asb)", b, TRUE), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL, NULL); + g_variant_builder_unref (b); +} + +static void +change_locale_permission_acquired (GObject *source, + GAsyncResult *res, + gpointer data) +{ + GisLanguagePage *page = GIS_LANGUAGE_PAGE (data); + GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page); + GError *error = NULL; + gboolean allowed; + + allowed = g_permission_acquire_finish (priv->permission, res, &error); + if (error) { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Failed to acquire permission: %s", error->message); + g_error_free (error); + return; + } + + if (allowed) + set_localed_locale (page); +} + +static void +user_loaded (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + gchar *new_locale_id = user_data; + + act_user_set_language (ACT_USER (object), new_locale_id); + + g_free (new_locale_id); +} + +static void +language_changed (CcLanguageChooser *chooser, + GParamSpec *pspec, + GisLanguagePage *page) +{ + GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page); + GisDriver *driver; + GSettings *region_settings; + ActUser *user; + + priv->new_locale_id = cc_language_chooser_get_language (chooser); + driver = GIS_PAGE (page)->driver; + + gis_driver_set_user_language (driver, priv->new_locale_id, TRUE); + gtk_widget_set_default_direction (gtk_get_locale_direction ()); + + if (gis_driver_get_mode (driver) == GIS_DRIVER_MODE_NEW_USER) { + if (g_permission_get_allowed (priv->permission)) { + set_localed_locale (page); + } + else if (g_permission_get_can_acquire (priv->permission)) { + g_permission_acquire_async (priv->permission, + NULL, + change_locale_permission_acquired, + page); + } + } + + /* Ensure we won't override the selected language for format strings */ + region_settings = g_settings_new (GNOME_SYSTEM_LOCALE_DIR); + g_settings_reset (region_settings, REGION_KEY); + g_object_unref (region_settings); + + user = act_user_manager_get_user (act_user_manager_get_default (), + g_get_user_name ()); + if (act_user_is_loaded (user)) + act_user_set_language (user, priv->new_locale_id); + else + g_signal_connect (user, + "notify::is-loaded", + G_CALLBACK (user_loaded), + g_strdup (priv->new_locale_id)); + + gis_welcome_widget_show_locale (GIS_WELCOME_WIDGET (priv->welcome_widget), + priv->new_locale_id); +} + +static void +localed_proxy_ready (GObject *source, + GAsyncResult *res, + gpointer data) +{ + GisLanguagePage *self = data; + GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (self); + GDBusProxy *proxy; + GError *error = NULL; + + proxy = g_dbus_proxy_new_finish (res, &error); + + if (!proxy) { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Failed to contact localed: %s", error->message); + g_error_free (error); + return; + } + + priv->localed = proxy; +} + +static void +update_distro_logo (GisLanguagePage *page) +{ + GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page); + g_autofree char *id = g_get_os_info (G_OS_INFO_KEY_ID); + gsize i; + + static const struct { + const char *id; + const char *logo; + } id_to_logo[] = { + { "debian", "emblem-debian" }, + { "fedora", "fedora-logo-icon" }, + { "ubuntu", "ubuntu-logo-icon" }, + { "openSUSE Tumbleweed", "opensuse-logo-icon" }, + { "openSUSE Leap", "opensuse-logo-icon" }, + { "SLED", "suse-logo-icon" }, + { "SLES", "suse-logo-icon" }, + }; + + for (i = 0; i < G_N_ELEMENTS (id_to_logo); i++) + { + if (g_strcmp0 (id, id_to_logo[i].id) == 0) + { + g_object_set (priv->logo, "icon-name", id_to_logo[i].logo, NULL); + break; + } + } +} + +static void +language_confirmed (CcLanguageChooser *chooser, + GisLanguagePage *page) +{ + gis_assistant_next_page (gis_driver_get_assistant (GIS_PAGE (page)->driver)); +} + +static void +gis_language_page_constructed (GObject *object) +{ + GisLanguagePage *page = GIS_LANGUAGE_PAGE (object); + GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page); + GDBusConnection *bus; + + g_type_ensure (CC_TYPE_LANGUAGE_CHOOSER); + + G_OBJECT_CLASS (gis_language_page_parent_class)->constructed (object); + + update_distro_logo (page); + + g_signal_connect (priv->language_chooser, "notify::language", + G_CALLBACK (language_changed), page); + g_signal_connect (priv->language_chooser, "confirm", + G_CALLBACK (language_confirmed), page); + + /* If we're in new user mode then we're manipulating system settings */ + if (gis_driver_get_mode (GIS_PAGE (page)->driver) == GIS_DRIVER_MODE_NEW_USER) + { + priv->permission = polkit_permission_new_sync ("org.freedesktop.locale1.set-locale", NULL, NULL, NULL); + + bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL); + g_dbus_proxy_new (bus, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + NULL, + "org.freedesktop.locale1", + "/org/freedesktop/locale1", + "org.freedesktop.locale1", + priv->cancellable, + (GAsyncReadyCallback) localed_proxy_ready, + object); + g_object_unref (bus); + } + + gis_page_set_complete (GIS_PAGE (page), TRUE); + gtk_widget_show (GTK_WIDGET (page)); +} + +static void +gis_language_page_locale_changed (GisPage *page) +{ + gis_page_set_title (GIS_PAGE (page), _("Welcome")); +} + +static void +gis_language_page_dispose (GObject *object) +{ + GisLanguagePage *page = GIS_LANGUAGE_PAGE (object); + GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page); + + g_clear_object (&priv->permission); + g_clear_object (&priv->localed); + g_clear_object (&priv->cancellable); + + G_OBJECT_CLASS (gis_language_page_parent_class)->dispose (object); +} + +static void +gis_language_page_class_init (GisLanguagePageClass *klass) +{ + GisPageClass *page_class = GIS_PAGE_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/initial-setup/gis-language-page.ui"); + + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisLanguagePage, welcome_widget); + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisLanguagePage, language_chooser); + gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisLanguagePage, logo); + + page_class->page_id = PAGE_ID; + page_class->locale_changed = gis_language_page_locale_changed; + object_class->constructed = gis_language_page_constructed; + object_class->dispose = gis_language_page_dispose; +} + +static void +gis_language_page_init (GisLanguagePage *page) +{ + g_resources_register (language_get_resource ()); + g_type_ensure (GIS_TYPE_WELCOME_WIDGET); + g_type_ensure (CC_TYPE_LANGUAGE_CHOOSER); + + gtk_widget_init_template (GTK_WIDGET (page)); +} + +GisPage * +gis_prepare_language_page (GisDriver *driver) +{ + return g_object_new (GIS_TYPE_LANGUAGE_PAGE, + "driver", driver, + NULL); +} diff --git a/gnome-initial-setup/pages/language/gis-language-page.h b/gnome-initial-setup/pages/language/gis-language-page.h new file mode 100644 index 0000000..7636021 --- /dev/null +++ b/gnome-initial-setup/pages/language/gis-language-page.h @@ -0,0 +1,57 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2012 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Written by: + * Jasper St. Pierre + */ + +#ifndef __GIS_LANGUAGE_PAGE_H__ +#define __GIS_LANGUAGE_PAGE_H__ + +#include + +#include "gnome-initial-setup.h" + +G_BEGIN_DECLS + +#define GIS_TYPE_LANGUAGE_PAGE (gis_language_page_get_type ()) +#define GIS_LANGUAGE_PAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIS_TYPE_LANGUAGE_PAGE, GisLanguagePage)) +#define GIS_LANGUAGE_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIS_TYPE_LANGUAGE_PAGE, GisLanguagePageClass)) +#define GIS_IS_LANGUAGE_PAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIS_TYPE_LANGUAGE_PAGE)) +#define GIS_IS_LANGUAGE_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIS_TYPE_LANGUAGE_PAGE)) +#define GIS_LANGUAGE_PAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIS_TYPE_LANGUAGE_PAGE, GisLanguagePageClass)) + +typedef struct _GisLanguagePage GisLanguagePage; +typedef struct _GisLanguagePageClass GisLanguagePageClass; + +struct _GisLanguagePage +{ + GisPage parent; +}; + +struct _GisLanguagePageClass +{ + GisPageClass parent_class; +}; + +GType gis_language_page_get_type (void); + +GisPage *gis_prepare_language_page (GisDriver *driver); + +G_END_DECLS + +#endif /* __GIS_LANGUAGE_PAGE_H__ */ diff --git a/gnome-initial-setup/pages/language/gis-language-page.ui b/gnome-initial-setup/pages/language/gis-language-page.ui new file mode 100644 index 0000000..307360c --- /dev/null +++ b/gnome-initial-setup/pages/language/gis-language-page.ui @@ -0,0 +1,48 @@ + + + + diff --git a/gnome-initial-setup/pages/language/gis-welcome-widget.c b/gnome-initial-setup/pages/language/gis-welcome-widget.c new file mode 100644 index 0000000..4d58a37 --- /dev/null +++ b/gnome-initial-setup/pages/language/gis-welcome-widget.c @@ -0,0 +1,242 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2013 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Written by: + * Jasper St. Pierre + */ + +#include "config.h" +#include "gis-welcome-widget.h" + +#include +#include +#include + +#include "cc-common-language.h" + +struct _GisWelcomeWidgetPrivate +{ + AdwCarousel *carousel; + GHashTable *translation_widgets; /* (element-type owned utf8 unowned GtkWidget) (owned) */ + + guint timeout_id; +}; +typedef struct _GisWelcomeWidgetPrivate GisWelcomeWidgetPrivate; + +#define TIMEOUT 5 + +G_DEFINE_TYPE_WITH_PRIVATE (GisWelcomeWidget, gis_welcome_widget, ADW_TYPE_BIN); + +static gboolean +advance_stack (gpointer user_data) +{ + GisWelcomeWidget *widget = user_data; + GisWelcomeWidgetPrivate *priv = gis_welcome_widget_get_instance_private (widget); + GtkWidget *child; + unsigned int next_page; + unsigned int n_pages; + double current_page; + + n_pages = adw_carousel_get_n_pages (priv->carousel); + if (n_pages == 0) + goto out; + + current_page = ceil (adw_carousel_get_position (priv->carousel)); + next_page = ((int) current_page + 1) % n_pages; + + child = gtk_widget_get_first_child (GTK_WIDGET (priv->carousel)); + while (next_page-- > 0) + child = gtk_widget_get_next_sibling (child); + + adw_carousel_scroll_to (priv->carousel, child, TRUE); + + out: + return G_SOURCE_CONTINUE; +} + +static void +gis_welcome_widget_start (GisWelcomeWidget *widget) +{ + GisWelcomeWidgetPrivate *priv = gis_welcome_widget_get_instance_private (widget); + + if (priv->timeout_id > 0) + return; + + priv->timeout_id = g_timeout_add_seconds (5, advance_stack, widget); +} + +static void +gis_welcome_widget_stop (GisWelcomeWidget *widget) +{ + GisWelcomeWidgetPrivate *priv = gis_welcome_widget_get_instance_private (widget); + + if (priv->timeout_id == 0) + return; + + g_source_remove (priv->timeout_id); + priv->timeout_id = 0; +} + +static void +gis_welcome_widget_map (GtkWidget *widget) +{ + GTK_WIDGET_CLASS (gis_welcome_widget_parent_class)->map (widget); + gis_welcome_widget_start (GIS_WELCOME_WIDGET (widget)); +} + +static void +gis_welcome_widget_unmap (GtkWidget *widget) +{ + GTK_WIDGET_CLASS (gis_welcome_widget_parent_class)->unmap (widget); + gis_welcome_widget_stop (GIS_WELCOME_WIDGET (widget)); +} + +static const char * +welcome (const char *locale_id) +{ + locale_t locale; + locale_t old_locale; + const char *welcome; + + locale = newlocale (LC_MESSAGES_MASK, locale_id, (locale_t) 0); + if (locale == (locale_t) 0) + { + if (errno == ENOENT) + g_debug ("Failed to create locale %s: %s", locale_id, g_strerror (errno)); + else + g_warning ("Failed to create locale %s: %s", locale_id, g_strerror (errno)); + + return "Welcome!"; + } + + old_locale = uselocale (locale); + + /* Translators: This is meant to be a warm, engaging welcome message, + * like greeting somebody at the door. If the exclamation mark is not + * suitable for this in your language you may replace it. + */ + welcome = _("Welcome!"); + + uselocale (old_locale); + freelocale (locale); + + return welcome; +} + +static GtkWidget * +big_label (const char *text) +{ + GtkWidget *label = gtk_label_new (text); + + gtk_style_context_add_class (gtk_widget_get_style_context (label), "title-1"); + + return label; +} + +static void +fill_carousel (GisWelcomeWidget *widget) +{ + GisWelcomeWidgetPrivate *priv = gis_welcome_widget_get_instance_private (widget); + g_autoptr(GHashTable) initial = cc_common_language_get_initial_languages (); + GHashTableIter iter; + gpointer key, value; + g_autoptr(GHashTable) added_translations = NULL; + + added_translations = g_hash_table_new (g_str_hash, g_str_equal); + + g_hash_table_iter_init (&iter, initial); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + const char *locale_id = key; + const char *text; + GtkWidget *label; + + if (!cc_common_language_has_font (locale_id)) + continue; + + text = welcome (locale_id); + label = g_hash_table_lookup (added_translations, text); + if (label == NULL) { + label = big_label (text); + adw_carousel_append (priv->carousel, label); + g_hash_table_insert (added_translations, (gpointer) text, label); + } + + g_hash_table_insert (priv->translation_widgets, g_strdup (locale_id), label); + } +} + +static void +gis_welcome_widget_constructed (GObject *object) +{ + G_OBJECT_CLASS (gis_welcome_widget_parent_class)->constructed (object); + + fill_carousel (GIS_WELCOME_WIDGET (object)); +} + +static void +gis_welcome_widget_dispose (GObject *object) +{ + GisWelcomeWidget *widget = GIS_WELCOME_WIDGET (object); + GisWelcomeWidgetPrivate *priv = gis_welcome_widget_get_instance_private (widget); + + g_clear_pointer (&priv->translation_widgets, g_hash_table_unref); + + G_OBJECT_CLASS (gis_welcome_widget_parent_class)->dispose (object); +} + +static void +gis_welcome_widget_class_init (GisWelcomeWidgetClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/initial-setup/gis-welcome-widget.ui"); + + gtk_widget_class_bind_template_child_private (widget_class, GisWelcomeWidget, carousel); + + object_class->constructed = gis_welcome_widget_constructed; + object_class->dispose = gis_welcome_widget_dispose; + widget_class->map = gis_welcome_widget_map; + widget_class->unmap = gis_welcome_widget_unmap; +} + +static void +gis_welcome_widget_init (GisWelcomeWidget *widget) +{ + GisWelcomeWidgetPrivate *priv = gis_welcome_widget_get_instance_private (widget); + + priv->translation_widgets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + gtk_widget_init_template (GTK_WIDGET (widget)); +} + +void +gis_welcome_widget_show_locale (GisWelcomeWidget *widget, + const char *locale_id) +{ + GisWelcomeWidgetPrivate *priv = gis_welcome_widget_get_instance_private (widget); + GtkWidget *label; + + /* Restart the widget to reset the timer. */ + gis_welcome_widget_stop (widget); + gis_welcome_widget_start (widget); + + label = g_hash_table_lookup (priv->translation_widgets, locale_id); + if (label) + adw_carousel_scroll_to (priv->carousel, label, FALSE); +} diff --git a/gnome-initial-setup/pages/language/gis-welcome-widget.h b/gnome-initial-setup/pages/language/gis-welcome-widget.h new file mode 100644 index 0000000..212b45f --- /dev/null +++ b/gnome-initial-setup/pages/language/gis-welcome-widget.h @@ -0,0 +1,56 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* + * Copyright (C) 2013 Red Hat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program 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 + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Written by: + * Jasper St. Pierre + */ + +#ifndef __GIS_WELCOME_WIDGET_H__ +#define __GIS_WELCOME_WIDGET_H__ + +#include + +G_BEGIN_DECLS + +#define GIS_TYPE_WELCOME_WIDGET (gis_welcome_widget_get_type ()) +#define GIS_WELCOME_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIS_TYPE_WELCOME_WIDGET, GisWelcomeWidget)) +#define GIS_WELCOME_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIS_TYPE_WELCOME_WIDGET, GisWelcomeWidgetClass)) +#define GIS_IS_WELCOME_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIS_TYPE_WELCOME_WIDGET)) +#define GIS_IS_WELCOME_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIS_TYPE_WELCOME_WIDGET)) +#define GIS_WELCOME_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIS_TYPE_WELCOME_WIDGET, GisWelcomeWidgetClass)) + +typedef struct _GisWelcomeWidget GisWelcomeWidget; +typedef struct _GisWelcomeWidgetClass GisWelcomeWidgetClass; + +struct _GisWelcomeWidget +{ + AdwBin parent; +}; + +struct _GisWelcomeWidgetClass +{ + AdwBinClass parent_class; +}; + +GType gis_welcome_widget_get_type (void); + +void gis_welcome_widget_show_locale (GisWelcomeWidget *widget, + const char *locale_id); + +G_END_DECLS + +#endif /* __GIS_WELCOME_WIDGET_H__ */ diff --git a/gnome-initial-setup/pages/language/gis-welcome-widget.ui b/gnome-initial-setup/pages/language/gis-welcome-widget.ui new file mode 100644 index 0000000..f6a26df --- /dev/null +++ b/gnome-initial-setup/pages/language/gis-welcome-widget.ui @@ -0,0 +1,14 @@ + + + + + diff --git a/gnome-initial-setup/pages/language/language-chooser.ui b/gnome-initial-setup/pages/language/language-chooser.ui new file mode 100644 index 0000000..90ee096 --- /dev/null +++ b/gnome-initial-setup/pages/language/language-chooser.ui @@ -0,0 +1,22 @@ + + + + diff --git a/gnome-initial-setup/pages/language/language.gresource.xml b/gnome-initial-setup/pages/language/language.gresource.xml new file mode 100644 index 0000000..de0688d --- /dev/null +++ b/gnome-initial-setup/pages/language/language.gresource.xml @@ -0,0 +1,10 @@ + + + + gis-language-page.ui + gis-welcome-widget.ui + + + language-chooser.ui + + diff --git a/gnome-initial-setup/pages/language/meson.build b/gnome-initial-setup/pages/language/meson.build new file mode 100644 index 0000000..ef6ba3f --- /dev/null +++ b/gnome-initial-setup/pages/language/meson.build @@ -0,0 +1,16 @@ +sources += gnome.compile_resources( + 'language-resources', + files('language.gresource.xml'), + c_name: 'language' +) + +sources += files( + 'cc-language-chooser.c', + 'cc-language-chooser.h', + 'cc-util.c', + 'cc-util.h', + 'gis-welcome-widget.c', + 'gis-welcome-widget.h', + 'gis-language-page.c', + 'gis-language-page.h', +) -- cgit v1.2.3