diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:45:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:45:20 +0000 |
commit | ae1c76ff830d146d41e88d6fba724c0a54bce868 (patch) | |
tree | 3c354bec95af07be35fc71a4b738268496f1a1c4 /panels/region/cc-region-panel.c | |
parent | Initial commit. (diff) | |
download | gnome-control-center-ae1c76ff830d146d41e88d6fba724c0a54bce868.tar.xz gnome-control-center-ae1c76ff830d146d41e88d6fba724c0a54bce868.zip |
Adding upstream version 1:43.6.upstream/1%43.6upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'panels/region/cc-region-panel.c')
-rw-r--r-- | panels/region/cc-region-panel.c | 879 |
1 files changed, 879 insertions, 0 deletions
diff --git a/panels/region/cc-region-panel.c b/panels/region/cc-region-panel.c new file mode 100644 index 0000000..bba51e9 --- /dev/null +++ b/panels/region/cc-region-panel.c @@ -0,0 +1,879 @@ +/* + * Copyright (C) 2010 Intel, Inc + * + * 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 <http://www.gnu.org/licenses/>. + * + * Author: Sergey Udaltsov <svu@gnome.org> + * + */ + +#include <config.h> +#include <errno.h> +#include <locale.h> +#include <glib/gi18n.h> +#include <gio/gio.h> +#include <gio/gdesktopappinfo.h> +#include <gtk/gtk.h> +#include <polkit/polkit.h> + +#include "cc-region-panel.h" +#include "cc-region-resources.h" +#include "cc-language-chooser.h" +#include "cc-format-chooser.h" + +#include "cc-common-language.h" + +#define GNOME_DESKTOP_USE_UNSTABLE_API +#include <libgnome-desktop/gnome-languages.h> +#include <libgnome-desktop/gnome-xkb-info.h> + +#include <act/act.h> + +#define GNOME_SYSTEM_LOCALE_DIR "org.gnome.system.locale" +#define KEY_REGION "region" + +#define DEFAULT_LOCALE "en_US.utf-8" + +typedef enum { + USER, + SYSTEM, +} CcLocaleTarget; + +struct _CcRegionPanel { + CcPanel parent_instance; + + GtkListBoxRow *formats_row; + GtkInfoBar *infobar; + GtkSizeGroup *input_size_group; + AdwActionRow *login_formats_row; + GtkWidget *login_group; + AdwActionRow *login_language_row; + GtkListBoxRow *language_row; + GtkButton *restart_button; + + gboolean login_auto_apply; + GPermission *permission; + GDBusProxy *localed; + GDBusProxy *session; + + ActUserManager *user_manager; + ActUser *user; + GSettings *locale_settings; + + gchar *language; + gchar *region; + gchar *system_language; + gchar *system_region; +}; + +CC_PANEL_REGISTER (CcRegionPanel, cc_region_panel) + +/* Auxiliary methods */ + +static GFile * +get_needs_restart_file (void) +{ + g_autofree gchar *path = NULL; + + path = g_build_filename (g_get_user_runtime_dir (), + "gnome-control-center-region-needs-restart", + NULL); + return g_file_new_for_path (path); +} + +static void +restart_now (CcRegionPanel *self) +{ + g_autoptr(GFile) file = NULL; + + file = get_needs_restart_file (); + g_file_delete (file, NULL, NULL); + + g_dbus_proxy_call (self->session, + "Logout", + g_variant_new ("(u)", 0), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL, NULL); +} + +static void +set_restart_notification_visible (CcRegionPanel *self, + const gchar *locale, + gboolean visible) +{ + locale_t new_locale; + locale_t current_locale; + g_autoptr(GFile) file = NULL; + g_autoptr(GFileOutputStream) output_stream = NULL; + g_autoptr(GError) error = NULL; + + if (locale) { + new_locale = newlocale (LC_MESSAGES_MASK, locale, (locale_t) 0); + if (new_locale != (locale_t) 0) { + current_locale = uselocale (new_locale); + uselocale (current_locale); + freelocale (new_locale); + } else { + g_warning ("Failed to create locale %s: %s", locale, g_strerror (errno)); + } + } + + gtk_info_bar_set_revealed (self->infobar, visible); + + file = get_needs_restart_file (); + + if (!visible) { + g_file_delete (file, NULL, NULL); + return; + } + + output_stream = g_file_create (file, G_FILE_CREATE_NONE, NULL, &error); + if (output_stream == NULL) { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) + g_warning ("Unable to create %s: %s", g_file_get_path (file), error->message); + } +} + +typedef struct { + CcRegionPanel *self; + int category; + gchar *target_locale; +} MaybeNotifyData; + +static void +maybe_notify_data_free (MaybeNotifyData *data) +{ + g_free (data->target_locale); + g_free (data); +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (MaybeNotifyData, maybe_notify_data_free) + +static void +maybe_notify_finish (GObject *source, + GAsyncResult *res, + gpointer data) +{ + g_autoptr(MaybeNotifyData) mnd = data; + CcRegionPanel *self = mnd->self; + g_autoptr(GError) error = NULL; + g_autoptr(GVariant) retval = NULL; + g_autofree gchar *current_lang_code = NULL; + g_autofree gchar *current_country_code = NULL; + g_autofree gchar *target_lang_code = NULL; + g_autofree gchar *target_country_code = NULL; + const gchar *current_locale = NULL; + + retval = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, &error); + if (!retval) { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Failed to get locale: %s\n", error->message); + return; + } + + g_variant_get (retval, "(&s)", ¤t_locale); + + if (!gnome_parse_locale (current_locale, + ¤t_lang_code, + ¤t_country_code, + NULL, + NULL)) + return; + + if (!gnome_parse_locale (mnd->target_locale, + &target_lang_code, + &target_country_code, + NULL, + NULL)) + return; + + if (g_str_equal (current_lang_code, target_lang_code) == FALSE || + g_str_equal (current_country_code, target_country_code) == FALSE) + set_restart_notification_visible (self, + mnd->category == LC_MESSAGES ? mnd->target_locale : NULL, + TRUE); + else + set_restart_notification_visible (self, + mnd->category == LC_MESSAGES ? mnd->target_locale : NULL, + FALSE); +} + +static void +maybe_notify (CcRegionPanel *self, + int category, + const gchar *target_locale) +{ + MaybeNotifyData *mnd; + + mnd = g_new0 (MaybeNotifyData, 1); + mnd->self = self; + mnd->category = category; + mnd->target_locale = g_strdup (target_locale); + + g_dbus_proxy_call (self->session, + "GetLocale", + g_variant_new ("(i)", category), + G_DBUS_CALL_FLAGS_NONE, + -1, + cc_panel_get_cancellable (CC_PANEL (self)), + maybe_notify_finish, + mnd); +} + +static void +set_localed_locale (CcRegionPanel *self) +{ + g_autoptr(GVariantBuilder) b = NULL; + g_autofree gchar *lang_value = NULL; + + b = g_variant_builder_new (G_VARIANT_TYPE ("as")); + lang_value = g_strconcat ("LANG=", self->system_language, NULL); + g_variant_builder_add (b, "s", lang_value); + + if (self->system_region != NULL) { + g_autofree gchar *time_value = NULL; + g_autofree gchar *numeric_value = NULL; + g_autofree gchar *monetary_value = NULL; + g_autofree gchar *measurement_value = NULL; + g_autofree gchar *paper_value = NULL; + time_value = g_strconcat ("LC_TIME=", self->system_region, NULL); + g_variant_builder_add (b, "s", time_value); + numeric_value = g_strconcat ("LC_NUMERIC=", self->system_region, NULL); + g_variant_builder_add (b, "s", numeric_value); + monetary_value = g_strconcat ("LC_MONETARY=", self->system_region, NULL); + g_variant_builder_add (b, "s", monetary_value); + measurement_value = g_strconcat ("LC_MEASUREMENT=", self->system_region, NULL); + g_variant_builder_add (b, "s", measurement_value); + paper_value = g_strconcat ("LC_PAPER=", self->system_region, NULL); + g_variant_builder_add (b, "s", paper_value); + } + g_dbus_proxy_call (self->localed, + "SetLocale", + g_variant_new ("(asb)", b, TRUE), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, NULL, NULL); +} + +static void +set_system_language (CcRegionPanel *self, + const gchar *language) +{ + if (g_strcmp0 (language, self->system_language) == 0) + return; + + g_free (self->system_language); + self->system_language = g_strdup (language); + + set_localed_locale (self); +} + +static void +update_language (CcRegionPanel *self, + CcLocaleTarget target, + const gchar *language) +{ + switch (target) { + case USER: + if (g_strcmp0 (language, self->language) == 0) + return; + act_user_set_language (self->user, language); + if (self->login_auto_apply) + set_system_language (self, language); + maybe_notify (self, LC_MESSAGES, language); + break; + + case SYSTEM: + set_system_language (self, language); + break; + } +} + +static void +set_system_region (CcRegionPanel *self, + const gchar *region) +{ + if (g_strcmp0 (region, self->system_region) == 0) + return; + + g_free (self->system_region); + self->system_region = g_strdup (region); + + set_localed_locale (self); +} + +static void +update_region (CcRegionPanel *self, + CcLocaleTarget target, + const gchar *region) +{ + switch (target) { + case USER: + if (g_strcmp0 (region, self->region) == 0) + return; + if (region == NULL || region[0] == '\0') + g_settings_reset (self->locale_settings, KEY_REGION); + else + g_settings_set_string (self->locale_settings, KEY_REGION, region); + if (self->login_auto_apply) + set_system_region (self, region); + + if (region == NULL || region[0] == '\0') { + // Formats (region) are being reset as part of changing the language, + // and that already triggers the notification check. + return; + } + + maybe_notify (self, LC_TIME, region); + break; + + case SYSTEM: + set_system_region (self, region); + break; + } +} + +static void +language_response (CcRegionPanel *self, + gint response_id, + CcLanguageChooser *chooser) +{ + const gchar *language; + + if (response_id == GTK_RESPONSE_OK) { + CcLocaleTarget target; + + language = cc_language_chooser_get_language (chooser); + target = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (chooser), "target")); + update_language (self, target, language); + + /* Keep format strings consistent with the user's language */ + update_region (self, target, NULL); + } + + gtk_window_destroy (GTK_WINDOW (chooser)); +} + +static const gchar * +get_effective_language (CcRegionPanel *self, + CcLocaleTarget target) +{ + switch (target) { + case USER: + return self->language; + case SYSTEM: + return self->system_language; + default: + g_assert_not_reached (); + } +} + +static void +show_language_chooser (CcRegionPanel *self, + CcLocaleTarget target) +{ + CcLanguageChooser *chooser; + CcShell *shell; + + shell = cc_panel_get_shell (CC_PANEL (self)); + chooser = cc_language_chooser_new (); + gtk_window_set_transient_for (GTK_WINDOW (chooser), GTK_WINDOW (cc_shell_get_toplevel (shell))); + cc_language_chooser_set_language (chooser, get_effective_language (self, target)); + g_object_set_data (G_OBJECT (chooser), "target", GINT_TO_POINTER (target)); + g_signal_connect_object (chooser, "response", + G_CALLBACK (language_response), self, G_CONNECT_SWAPPED); + gtk_window_present (GTK_WINDOW (chooser)); +} + +static const gchar * +get_effective_region (CcRegionPanel *self, + CcLocaleTarget target) +{ + const gchar *region = NULL; + + switch (target) { + case USER: + region = self->region; + break; + + case SYSTEM: + region = self->system_region; + break; + } + + /* Region setting might be empty - show the language because + * that's what LC_TIME and others will effectively be when the + * user logs in again. */ + if (region == NULL || region[0] == '\0') + region = get_effective_language (self, target); + + return region; +} + +static void +format_response (CcRegionPanel *self, + gint response_id, + CcFormatChooser *chooser) +{ + const gchar *region; + + if (response_id == GTK_RESPONSE_OK) { + CcLocaleTarget target; + + region = cc_format_chooser_get_region (chooser); + target = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (chooser), "target")); + + update_region (self, target, region); + } + + gtk_window_destroy (GTK_WINDOW (chooser)); +} + +static void +show_region_chooser (CcRegionPanel *self, + CcLocaleTarget target) +{ + CcFormatChooser *chooser; + CcShell *shell; + + shell = cc_panel_get_shell (CC_PANEL (self)); + chooser = cc_format_chooser_new (); + gtk_window_set_transient_for (GTK_WINDOW (chooser), GTK_WINDOW (cc_shell_get_toplevel (shell))); + cc_format_chooser_set_region (chooser, get_effective_region (self, target)); + g_object_set_data (G_OBJECT (chooser), "target", GINT_TO_POINTER (target)); + g_signal_connect_object (chooser, "response", + G_CALLBACK (format_response), self, G_CONNECT_SWAPPED); + gtk_window_present (GTK_WINDOW (chooser)); +} + +static gboolean +permission_acquired (GPermission *permission, GAsyncResult *res, const gchar *action) +{ + g_autoptr(GError) error = NULL; + + if (!g_permission_acquire_finish (permission, res, &error)) { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Failed to acquire permission to %s: %s\n", error->message, action); + return FALSE; + } + + return TRUE; +} + +static void +choose_language_permission_cb (GObject *source, GAsyncResult *res, gpointer user_data) +{ + CcRegionPanel *self = user_data; + if (permission_acquired (G_PERMISSION (source), res, "choose language")) + show_language_chooser (self, SYSTEM); +} + +static void +choose_region_permission_cb (GObject *source, GAsyncResult *res, gpointer user_data) +{ + CcRegionPanel *self = user_data; + if (permission_acquired (G_PERMISSION (source), res, "choose region")) + show_region_chooser (self, SYSTEM); +} + +static void +update_user_region_row (CcRegionPanel *self) +{ + const gchar *region = get_effective_region (self, USER); + g_autofree gchar *name = NULL; + + if (region) + name = gnome_get_country_from_locale (region, region); + + if (!name) + name = gnome_get_country_from_locale (DEFAULT_LOCALE, DEFAULT_LOCALE); + + adw_action_row_set_subtitle (ADW_ACTION_ROW (self->formats_row), name); +} + +static void +update_user_language_row (CcRegionPanel *self) +{ + g_autofree gchar *name = NULL; + + if (self->language) + name = gnome_get_language_from_locale (self->language, self->language); + + if (!name) + name = gnome_get_language_from_locale (DEFAULT_LOCALE, DEFAULT_LOCALE); + + adw_action_row_set_subtitle (ADW_ACTION_ROW (self->language_row), name); + + /* Formats will change too if not explicitly set. */ + update_user_region_row (self); +} + +static void +update_language_from_user (CcRegionPanel *self) +{ + const gchar *language = NULL; + + if (act_user_is_loaded (self->user)) + language = act_user_get_language (self->user); + + if (language == NULL || *language == '\0') + language = setlocale (LC_MESSAGES, NULL); + + g_free (self->language); + self->language = g_strdup (language); + update_user_language_row (self); +} + +static void +update_region_from_setting (CcRegionPanel *self) +{ + g_free (self->region); + self->region = g_settings_get_string (self->locale_settings, KEY_REGION); + update_user_region_row (self); +} + +static void +setup_language_section (CcRegionPanel *self) +{ + self->user = act_user_manager_get_user_by_id (self->user_manager, getuid ()); + g_signal_connect_object (self->user, "notify::language", + G_CALLBACK (update_language_from_user), self, G_CONNECT_SWAPPED); + g_signal_connect_object (self->user, "notify::is-loaded", + G_CALLBACK (update_language_from_user), self, G_CONNECT_SWAPPED); + + self->locale_settings = g_settings_new (GNOME_SYSTEM_LOCALE_DIR); + g_signal_connect_object (self->locale_settings, "changed::" KEY_REGION, + G_CALLBACK (update_region_from_setting), self, G_CONNECT_SWAPPED); + + update_language_from_user (self); + update_region_from_setting (self); +} + +static void +update_login_region (CcRegionPanel *self) +{ + g_autofree gchar *name = NULL; + + if (self->system_region) + name = gnome_get_country_from_locale (self->system_region, self->system_region); + + if (!name) + name = gnome_get_country_from_locale (DEFAULT_LOCALE, DEFAULT_LOCALE); + + adw_action_row_set_subtitle (ADW_ACTION_ROW (self->login_formats_row), name); +} + +static void +update_login_language (CcRegionPanel *self) +{ + g_autofree gchar *name = NULL; + + if (self->system_language) + name = gnome_get_language_from_locale (self->system_language, self->system_language); + + if (!name) + name = gnome_get_language_from_locale (DEFAULT_LOCALE, DEFAULT_LOCALE); + + adw_action_row_set_subtitle (self->login_language_row, name); + update_login_region (self); +} + +static void +set_login_button_visibility (CcRegionPanel *self) +{ + gboolean has_multiple_users; + gboolean loaded; + + g_object_get (self->user_manager, "is-loaded", &loaded, NULL); + if (!loaded) + return; + + g_object_get (self->user_manager, "has-multiple-users", &has_multiple_users, NULL); + + self->login_auto_apply = !has_multiple_users && g_permission_get_allowed (self->permission); + gtk_widget_set_visible (self->login_group, !self->login_auto_apply); + + g_signal_handlers_disconnect_by_func (self->user_manager, set_login_button_visibility, self); +} + +/* Callbacks */ + +static void +on_localed_properties_changed (GDBusProxy *localed_proxy, + GVariant *changed_properties, + const gchar **invalidated_properties, + CcRegionPanel *self) +{ + g_autoptr(GVariant) v = NULL; + + v = g_dbus_proxy_get_cached_property (localed_proxy, "Locale"); + if (v) { + g_autofree const gchar **strv = NULL; + gsize len; + gint i; + const gchar *lang, *messages, *time; + + strv = g_variant_get_strv (v, &len); + + lang = messages = time = NULL; + for (i = 0; strv[i]; i++) { + if (g_str_has_prefix (strv[i], "LANG=")) { + lang = strv[i] + strlen ("LANG="); + } else if (g_str_has_prefix (strv[i], "LC_MESSAGES=")) { + messages = strv[i] + strlen ("LC_MESSAGES="); + } else if (g_str_has_prefix (strv[i], "LC_TIME=")) { + time = strv[i] + strlen ("LC_TIME="); + } + } + if (!lang) { + lang = setlocale (LC_MESSAGES, NULL); + } + if (!messages) { + messages = lang; + } + g_free (self->system_language); + self->system_language = g_strdup (messages); + g_free (self->system_region); + self->system_region = g_strdup (time); + + update_login_language (self); + } +} + +static void +localed_proxy_ready (GObject *source, + GAsyncResult *res, + gpointer data) +{ + CcRegionPanel *self = data; + GDBusProxy *proxy; + g_autoptr(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\n", error->message); + return; + } + + self->localed = proxy; + + g_signal_connect_object (self->localed, + "g-properties-changed", + G_CALLBACK (on_localed_properties_changed), + self, + 0); + + on_localed_properties_changed (self->localed, NULL, NULL, self); +} + +static void +setup_login_permission (CcRegionPanel *self) +{ + g_autoptr(GDBusConnection) bus = NULL; + g_autoptr(GError) error = NULL; + gboolean can_acquire; + gboolean loaded; + + self->permission = polkit_permission_new_sync ("org.freedesktop.locale1.set-locale", NULL, NULL, &error); + if (self->permission == NULL) { + g_warning ("Could not get 'org.freedesktop.locale1.set-locale' permission: %s", + error->message); + return; + } + + 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", + cc_panel_get_cancellable (CC_PANEL (self)), + (GAsyncReadyCallback) localed_proxy_ready, + self); + + g_object_get (self->user_manager, "is-loaded", &loaded, NULL); + if (loaded) + set_login_button_visibility (self); + else + g_signal_connect_object (self->user_manager, "notify::is-loaded", + G_CALLBACK (set_login_button_visibility), self, G_CONNECT_SWAPPED); + + can_acquire = self->permission && + (g_permission_get_allowed (self->permission) || + g_permission_get_can_acquire (self->permission)); + gtk_widget_set_sensitive (self->login_group, can_acquire); +} + +static void +session_proxy_ready (GObject *source, + GAsyncResult *res, + gpointer data) +{ + CcRegionPanel *self = data; + GDBusProxy *proxy; + g_autoptr(GError) error = NULL; + + proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + + if (!proxy) { + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Failed to contact gnome-session: %s\n", error->message); + return; + } + + self->session = proxy; +} + +static void +on_login_formats_row_activated_cb (GtkListBoxRow *row, + CcRegionPanel *self) +{ + if (g_permission_get_allowed (self->permission)) { + show_region_chooser (self, SYSTEM); + } else if (g_permission_get_can_acquire (self->permission)) { + g_permission_acquire_async (self->permission, + cc_panel_get_cancellable (CC_PANEL (self)), + choose_region_permission_cb, + self); + } +} + +static void +on_login_language_row_activated_cb (GtkListBoxRow *row, + CcRegionPanel *self) +{ + if (g_permission_get_allowed (self->permission)) { + show_language_chooser (self, SYSTEM); + } else if (g_permission_get_can_acquire (self->permission)) { + g_permission_acquire_async (self->permission, + cc_panel_get_cancellable (CC_PANEL (self)), + choose_language_permission_cb, + self); + } +} + +static void +on_user_formats_row_activated_cb (GtkListBoxRow *row, + CcRegionPanel *self) +{ + show_region_chooser (self, USER); +} + +static void +on_user_language_row_activated_cb (GtkListBoxRow *row, + CcRegionPanel *self) +{ + show_language_chooser (self, USER); +} + +/* CcPanel overrides */ + +static const char * +cc_region_panel_get_help_uri (CcPanel *panel) +{ + return "help:gnome-help/prefs-language"; +} + +/* GObject overrides */ + +static void +cc_region_panel_finalize (GObject *object) +{ + CcRegionPanel *self = CC_REGION_PANEL (object); + GtkWidget *chooser; + + if (self->user_manager) { + g_signal_handlers_disconnect_by_data (self->user_manager, self); + self->user_manager = NULL; + } + + if (self->user) { + g_signal_handlers_disconnect_by_data (self->user, self); + self->user = NULL; + } + + g_clear_object (&self->permission); + g_clear_object (&self->localed); + g_clear_object (&self->session); + g_clear_object (&self->locale_settings); + g_free (self->language); + g_free (self->region); + g_free (self->system_language); + g_free (self->system_region); + + chooser = g_object_get_data (G_OBJECT (self), "input-chooser"); + if (chooser) + gtk_window_destroy (GTK_WINDOW (chooser)); + + G_OBJECT_CLASS (cc_region_panel_parent_class)->finalize (object); +} + +static void +cc_region_panel_class_init (CcRegionPanelClass * klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + CcPanelClass *panel_class = CC_PANEL_CLASS (klass); + + panel_class->get_help_uri = cc_region_panel_get_help_uri; + + object_class->finalize = cc_region_panel_finalize; + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/region/cc-region-panel.ui"); + + gtk_widget_class_bind_template_child (widget_class, CcRegionPanel, formats_row); + gtk_widget_class_bind_template_child (widget_class, CcRegionPanel, infobar); + gtk_widget_class_bind_template_child (widget_class, CcRegionPanel, login_formats_row); + gtk_widget_class_bind_template_child (widget_class, CcRegionPanel, login_group); + gtk_widget_class_bind_template_child (widget_class, CcRegionPanel, login_language_row); + gtk_widget_class_bind_template_child (widget_class, CcRegionPanel, language_row); + gtk_widget_class_bind_template_child (widget_class, CcRegionPanel, restart_button); + + gtk_widget_class_bind_template_callback (widget_class, on_login_formats_row_activated_cb); + gtk_widget_class_bind_template_callback (widget_class, on_login_language_row_activated_cb); + gtk_widget_class_bind_template_callback (widget_class, on_user_formats_row_activated_cb); + gtk_widget_class_bind_template_callback (widget_class, on_user_language_row_activated_cb); + gtk_widget_class_bind_template_callback (widget_class, restart_now); +} + +static void +cc_region_panel_init (CcRegionPanel *self) +{ + g_autoptr(GFile) needs_restart_file = NULL; + + g_resources_register (cc_region_get_resource ()); + + gtk_widget_init_template (GTK_WIDGET (self)); + + self->user_manager = act_user_manager_get_default (); + + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.gnome.SessionManager", + "/org/gnome/SessionManager", + "org.gnome.SessionManager", + cc_panel_get_cancellable (CC_PANEL (self)), + session_proxy_ready, + self); + + setup_login_permission (self); + setup_language_section (self); + + needs_restart_file = get_needs_restart_file (); + if (g_file_query_exists (needs_restart_file, NULL)) + set_restart_notification_visible (self, NULL, TRUE); +} |