From 06f198f48e41f6a91e93970cd795dfab3bad1643 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: May 18 2021 06:50:46 +0000 Subject: import gnome-settings-daemon-3.32.0-14.el8 --- diff --git a/SOURCES/0001-media-keys-Mark-screen-cast-as-stopped-if-it-was-sig.patch b/SOURCES/0001-media-keys-Mark-screen-cast-as-stopped-if-it-was-sig.patch new file mode 100644 index 0000000..e940d66 --- /dev/null +++ b/SOURCES/0001-media-keys-Mark-screen-cast-as-stopped-if-it-was-sig.patch @@ -0,0 +1,125 @@ +From a8115378fd876bfd4c3871428cdc16134ed484b1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Jonas=20=C3=85dahl?= +Date: Tue, 5 Jan 2021 11:11:18 +0100 +Subject: [PATCH] media-keys: Mark screen cast as stopped if it was signalled + as such + +gnome-shell now sends a 'Stopped' signal if it was stopped without +gsd-media-keys itself being the stopper. +--- + plugins/media-keys/gsd-media-keys-manager.c | 52 +++++++++++++++++++-- + 1 file changed, 49 insertions(+), 3 deletions(-) + +diff --git a/plugins/media-keys/gsd-media-keys-manager.c b/plugins/media-keys/gsd-media-keys-manager.c +index 4d251f08..a526d5cf 100644 +--- a/plugins/media-keys/gsd-media-keys-manager.c ++++ b/plugins/media-keys/gsd-media-keys-manager.c +@@ -210,6 +210,7 @@ struct GsdMediaKeysManagerPrivate + guint screencast_timeout_id; + gboolean screencast_recording; + GCancellable *screencast_cancellable; ++ guint screencast_stopped_signal_id; + + /* Rotation */ + guint iio_sensor_watch_id; +@@ -2346,20 +2347,26 @@ do_rfkill_action (GsdMediaKeysManager *manager, + } + + static void +-screencast_stop (GsdMediaKeysManager *manager) ++screencast_stopped (GsdMediaKeysManager *manager) + { + if (manager->priv->screencast_timeout_id > 0) { + g_source_remove (manager->priv->screencast_timeout_id); + manager->priv->screencast_timeout_id = 0; + } + ++ manager->priv->screencast_recording = FALSE; ++} ++ ++static void ++screencast_stop (GsdMediaKeysManager *manager) ++{ ++ screencast_stopped (manager); ++ + g_dbus_proxy_call (manager->priv->screencast_proxy, + "StopScreencast", NULL, + G_DBUS_CALL_FLAGS_NONE, -1, + manager->priv->screencast_cancellable, + NULL, NULL); +- +- manager->priv->screencast_recording = FALSE; + } + + static gboolean +@@ -2835,6 +2842,21 @@ initialize_volume_handler (GsdMediaKeysManager *manager) + gnome_settings_profile_end ("gvc_mixer_control_new"); + } + ++ ++static void ++on_screencast_stopped (GDBusConnection *connection, ++ const gchar *sender_name, ++ const gchar *object_path, ++ const gchar *interface_name, ++ const gchar *signal_name, ++ GVariant *parameters, ++ gpointer data) ++{ ++ GsdMediaKeysManager *manager = data; ++ ++ screencast_stopped (manager); ++} ++ + static void + on_screencast_proxy_ready (GObject *source, + GAsyncResult *result, +@@ -2850,7 +2872,20 @@ on_screencast_proxy_ready (GObject *source, + if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("Failed to create proxy for screencast: %s", error->message); + g_error_free (error); ++ return; + } ++ ++ manager->priv->screencast_stopped_signal_id = ++ g_dbus_connection_signal_subscribe (manager->priv->connection, ++ SHELL_DBUS_NAME ".Screencast", ++ SHELL_DBUS_NAME ".Screencast", ++ "Stopped", ++ SHELL_DBUS_PATH "/Screencast", ++ NULL, ++ G_DBUS_SIGNAL_FLAGS_NONE, ++ on_screencast_stopped, ++ manager, ++ NULL); + } + + static void +@@ -2901,6 +2936,11 @@ shell_presence_changed (GsdMediaKeysManager *manager) + on_screencast_proxy_ready, manager); + g_free (name_owner); + } else { ++ if (manager->priv->screencast_stopped_signal_id) ++ g_dbus_connection_signal_unsubscribe (manager->priv->connection, ++ manager->priv->screencast_stopped_signal_id); ++ manager->priv->screencast_stopped_signal_id = 0; ++ + g_ptr_array_set_size (manager->priv->keys, 0); + g_clear_object (&manager->priv->key_grabber); + g_clear_object (&manager->priv->screencast_proxy); +@@ -3091,6 +3131,12 @@ gsd_media_keys_manager_stop (GsdMediaKeysManager *manager) + priv->reenable_power_button_timer_id = 0; + } + ++ if (priv->screencast_stopped_signal_id) { ++ g_dbus_connection_signal_unsubscribe (priv->connection, ++ priv->screencast_stopped_signal_id); ++ priv->screencast_stopped_signal_id = 0; ++ } ++ + g_clear_pointer (&manager->priv->ca, ca_context_destroy); + + #if HAVE_GUDEV +-- +2.27.0 + diff --git a/SOURCES/0001-subman-Add-a-new-plugin-to-provide-system-subscripti.patch b/SOURCES/0001-subman-Add-a-new-plugin-to-provide-system-subscripti.patch new file mode 100644 index 0000000..bc13b55 --- /dev/null +++ b/SOURCES/0001-subman-Add-a-new-plugin-to-provide-system-subscripti.patch @@ -0,0 +1,1871 @@ +From bee6d42503ec9b56f6e10704db02bcedb6a4fdf1 Mon Sep 17 00:00:00 2001 +From: Richard Hughes +Date: Thu, 20 Aug 2020 11:16:09 -0400 +Subject: [PATCH 01/15] subman: Add a new plugin to provide system subscription + registration + +--- + meson.build | 1 + + plugins/meson.build | 1 + + plugins/subman/README.md | 56 + + plugins/subman/gsd-subman-common.c | 36 + + plugins/subman/gsd-subman-common.h | 40 + + plugins/subman/gsd-subman-helper.c | 378 +++++++ + plugins/subman/gsd-subscription-manager.c | 982 ++++++++++++++++++ + plugins/subman/gsd-subscription-manager.h | 63 ++ + plugins/subman/main.c | 8 + + plugins/subman/meson.build | 56 + + ...ome.SettingsDaemon.Subscription.desktop.in | 9 + + ...ettings-daemon.plugins.subman.policy.in.in | 27 + + ...gnome.settings-daemon.plugins.subman.rules | 7 + + 13 files changed, 1664 insertions(+) + create mode 100644 plugins/subman/README.md + create mode 100644 plugins/subman/gsd-subman-common.c + create mode 100644 plugins/subman/gsd-subman-common.h + create mode 100644 plugins/subman/gsd-subman-helper.c + create mode 100644 plugins/subman/gsd-subscription-manager.c + create mode 100644 plugins/subman/gsd-subscription-manager.h + create mode 100644 plugins/subman/main.c + create mode 100644 plugins/subman/meson.build + create mode 100644 plugins/subman/org.gnome.SettingsDaemon.Subscription.desktop.in + create mode 100644 plugins/subman/org.gnome.settings-daemon.plugins.subman.policy.in.in + create mode 100644 plugins/subman/org.gnome.settings-daemon.plugins.subman.rules + +diff --git a/meson.build b/meson.build +index 1632ea05..27bf8c4c 100644 +--- a/meson.build ++++ b/meson.build +@@ -70,60 +70,61 @@ if gsd_buildtype.contains('debug') + ] + + compiler_flags = cc.get_supported_arguments(test_cflags) + elif gsd_buildtype.contains('release') + common_flags += ['-DG_DISABLE_CAST_CHECKS'] + endif + + # Workaround for meson's bug + # https://github.com/mesonbuild/meson/pull/1896 + if get_option('b_ndebug') == true + common_flags += ['-DG_DISABLE_ASSERT'] + endif + + add_project_arguments(common_flags + compiler_flags, language: 'c') + + glib_dep = dependency('glib-2.0', version: '>= 2.56') + colord_dep = dependency('colord', version: '>= 1.0.2') + geocode_glib_dep = dependency('geocode-glib-1.0', version: '>= 3.10.0') + gio_dep = dependency('gio-2.0', version: '>= 2.53.0') + gio_unix_dep = dependency('gio-unix-2.0') + gnome_desktop_dep = dependency('gnome-desktop-3.0', version: '>= 3.11.1') + gsettings_desktop_dep = dependency('gsettings-desktop-schemas', version: '>= 3.27.90') + gtk_dep = dependency('gtk+-3.0', version: '>= 3.15.3') + gtk_x11_dep = dependency('gtk+-x11-3.0') + gweather_dep = dependency('gweather-3.0', version: '>= 3.9.5') + lcms_dep = dependency('lcms2', version: '>= 2.2') + libcanberra_gtk_dep = dependency('libcanberra-gtk3') + libgeoclue_dep = dependency('libgeoclue-2.0', version: '>= 2.3.1') + libnotify_dep = dependency('libnotify', version: '>= 0.7.3') + libpulse_mainloop_glib_dep = dependency('libpulse-mainloop-glib', version: '>= 2.0') ++jsonglib_dep = dependency('json-glib-1.0', version: '>= 1.1.1') + pango_dep = dependency('pango', version: '>= 1.20.0') + polkit_gobject_dep = dependency('polkit-gobject-1', version: '>= 0.103') + upower_glib_dep = dependency('upower-glib', version: '>= 0.99.0') + x11_dep = dependency('x11') + + m_dep = cc.find_library('m') + dl_dep = cc.find_library('dl') + + # ALSA integration (default enabled) + enable_alsa = get_option('alsa') + assert(enable_alsa or not host_is_linux, 'ALSA is not optional on Linux platforms') + + libgvc = subproject( + 'gvc', + default_options: [ + 'static=true', + 'alsa=' + enable_alsa.to_string() + ] + ) + libgvc_dep = libgvc.get_variable('libgvc_dep') + + # GUdev integration (default enabled) + enable_gudev = get_option('gudev') + if enable_gudev + gudev_dep = dependency('gudev-1.0') + endif + config_h.set10('HAVE_GUDEV', enable_gudev) + if host_is_linux + assert(enable_gudev, 'GUdev is not optional on Linux platforms') + endif +diff --git a/plugins/meson.build b/plugins/meson.build +index 3c4d42ac..4c9caf47 100644 +--- a/plugins/meson.build ++++ b/plugins/meson.build +@@ -1,35 +1,36 @@ + enabled_plugins = [ + ['a11y-settings', 'A11ySettings'], + ['account', 'Account'], + ['clipboard', 'Clipboard'], + ['color', 'Color'], ++ ['subman', 'Subscription'], + ['datetime', 'Datetime'], + ['dummy', ''], + ['power', 'Power'], + ['housekeeping', 'Housekeeping'], + ['keyboard', 'Keyboard'], + ['media-keys', 'MediaKeys'], + ['mouse', 'Mouse'], + ['screensaver-proxy', 'ScreensaverProxy'], + ['sharing', 'Sharing'], + ['sound', 'Sound'], + ['xsettings', 'XSettings'] + ] + + if enable_smartcard + enabled_plugins += [['smartcard', 'Smartcard']] + endif + + if enable_wacom + enabled_plugins += [['wacom', 'Wacom']] + endif + + if enable_cups + enabled_plugins += [['print-notifications', 'PrintNotifications']] + endif + + if enable_rfkill + enabled_plugins += [['rfkill', 'Rfkill']] + endif + + plugins_conf = configuration_data() +diff --git a/plugins/subman/README.md b/plugins/subman/README.md +new file mode 100644 +index 00000000..3e1cc3cd +--- /dev/null ++++ b/plugins/subman/README.md +@@ -0,0 +1,56 @@ ++GNOME Settings Daemon: Subscription Manager Plugin ++================================================== ++ ++Testing: ++ ++To add a test acccount on subscription.rhsm.stage.redhat.com, use Ethel: ++http://account-manager-stage.app.eng.rdu2.redhat.com/#view ++ ++Register with a username and password ++------------------------------------- ++ ++ gdbus call \ ++ --session \ ++ --dest org.gnome.SettingsDaemon.Subscription \ ++ --object-path /org/gnome/SettingsDaemon/Subscription \ ++ --method org.gnome.SettingsDaemon.Subscription.Register "{'kind':<'username'>,'hostname':<'subscription.rhsm.stage.redhat.com'>,'username':<'rhughes_test'>,'password':<'barbaz'>}" ++ ++To register with a certificate ++------------------------------ ++ ++ gdbus call \ ++ --session \ ++ --dest org.gnome.SettingsDaemon.Subscription \ ++ --object-path /org/gnome/SettingsDaemon/Subscription \ ++ --method org.gnome.SettingsDaemon.Subscription.Register "{'kind':<'key'>,'hostname':<'subscription.rhsm.stage.redhat.com'>,'organisation':<'foo'>,'activation-key':<'barbaz'>}" ++ ++To unregister ++------------- ++ ++ gdbus call \ ++ --session \ ++ --dest org.gnome.SettingsDaemon.Subscription \ ++ --object-path /org/gnome/SettingsDaemon/Subscription \ ++ --method org.gnome.SettingsDaemon.Subscription.Unregister ++ ++Debugging ++--------- ++ ++Get the UNIX socket using `Subscription.Register` then call something like: ++ ++ sudo G_MESSAGES_DEBUG=all ./plugins/subman/gsd-subman-helper \ ++ --address="unix:abstract=/var/run/dbus-ulGB1wfnbn,guid=71e6bf329d861ce366df7a1d5d036a5b" \ ++ --kind="register-with-username" \ ++ --username="rhughes_test" \ ++ --password="barbaz" \ ++ --hostname="subscription.rhsm.stage.redhat.com" \ ++ --organisation="" ++ ++You can all see some basic debugging running `rhsmd` in the foreground: ++ ++ sudo /usr/libexec/rhsmd -d -k ++ ++Known Limitations ++================= ++ ++Proxy servers are not supported, nor are custom host ports or prefixes. +diff --git a/plugins/subman/gsd-subman-common.c b/plugins/subman/gsd-subman-common.c +new file mode 100644 +index 00000000..e515131e +--- /dev/null ++++ b/plugins/subman/gsd-subman-common.c +@@ -0,0 +1,36 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2019 Richard Hughes ++ * ++ * 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 . ++ * ++ */ ++ ++#include "config.h" ++ ++#include "gsd-subman-common.h" ++ ++const gchar * ++gsd_subman_subscription_status_to_string (GsdSubmanSubscriptionStatus status) ++{ ++ if (status == GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID) ++ return "valid"; ++ if (status == GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID) ++ return "invalid"; ++ if (status == GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED) ++ return "disabled"; ++ if (status == GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID) ++ return "partially-valid"; ++ return "unknown"; ++} +diff --git a/plugins/subman/gsd-subman-common.h b/plugins/subman/gsd-subman-common.h +new file mode 100644 +index 00000000..fccf9f6a +--- /dev/null ++++ b/plugins/subman/gsd-subman-common.h +@@ -0,0 +1,40 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2019 Richard Hughes ++ * ++ * 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 . ++ * ++ */ ++ ++#ifndef __GSD_SUBMAN_COMMON_H ++#define __GSD_SUBMAN_COMMON_H ++ ++#include ++ ++G_BEGIN_DECLS ++ ++typedef enum { ++ GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN, ++ GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID, ++ GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID, ++ GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED, ++ GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID, ++ GSD_SUBMAN_SUBSCRIPTION_STATUS_LAST ++} GsdSubmanSubscriptionStatus; ++ ++const gchar *gsd_subman_subscription_status_to_string (GsdSubmanSubscriptionStatus status); ++ ++G_END_DECLS ++ ++#endif /* __GSD_SUBMAN_COMMON_H */ +diff --git a/plugins/subman/gsd-subman-helper.c b/plugins/subman/gsd-subman-helper.c +new file mode 100644 +index 00000000..182f7190 +--- /dev/null ++++ b/plugins/subman/gsd-subman-helper.c +@@ -0,0 +1,378 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2019 Richard Hughes ++ * ++ * Licensed under the GNU General Public License Version 2 ++ * ++ * 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, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#include "config.h" ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++static void ++_helper_convert_error (const gchar *json_txt, GError **error) ++{ ++ JsonNode *json_root; ++ JsonObject *json_obj; ++ const gchar *message; ++ g_autoptr(JsonParser) json_parser = json_parser_new (); ++ ++ /* this may be plain text or JSON :| */ ++ if (!json_parser_load_from_data (json_parser, json_txt, -1, NULL)) { ++ g_set_error_literal (error, ++ G_IO_ERROR, ++ G_IO_ERROR_NOT_SUPPORTED, ++ json_txt); ++ return; ++ } ++ json_root = json_parser_get_root (json_parser); ++ json_obj = json_node_get_object (json_root); ++ if (!json_object_has_member (json_obj, "message")) { ++ g_set_error (error, ++ G_IO_ERROR, ++ G_IO_ERROR_INVALID_DATA, ++ "no message' in %s", json_txt); ++ return; ++ } ++ message = json_object_get_string_member (json_obj, "message"); ++ if (g_strstr_len (message, -1, "Invalid user credentials") != NULL) { ++ g_set_error_literal (error, ++ G_IO_ERROR, ++ G_IO_ERROR_PERMISSION_DENIED, ++ message); ++ return; ++ } ++ g_set_error_literal (error, ++ G_IO_ERROR, ++ G_IO_ERROR_NOT_SUPPORTED, ++ message); ++} ++ ++static gboolean ++_helper_unregister (GError **error) ++{ ++ g_autoptr(GDBusProxy) proxy = NULL; ++ g_autoptr(GVariantBuilder) proxy_options = NULL; ++ g_autoptr(GVariant) res = NULL; ++ ++ g_debug ("unregistering"); ++ proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, ++ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | ++ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, ++ NULL, ++ "com.redhat.RHSM1", ++ "/com/redhat/RHSM1/Unregister", ++ "com.redhat.RHSM1.Unregister", ++ NULL, error); ++ if (proxy == NULL) { ++ g_prefix_error (error, "Failed to get proxy: "); ++ return FALSE; ++ } ++ proxy_options = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); ++ res = g_dbus_proxy_call_sync (proxy, ++ "Unregister", ++ g_variant_new ("(a{sv}s)", ++ proxy_options, ++ ""), /* lang */ ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, NULL, error); ++ return res != NULL; ++} ++ ++static gboolean ++_helper_auto_attach (GError **error) ++{ ++ const gchar *str = NULL; ++ g_autoptr(GDBusProxy) proxy = NULL; ++ g_autoptr(GVariantBuilder) proxy_options = NULL; ++ g_autoptr(GVariant) res = NULL; ++ ++ g_debug ("auto-attaching subscriptions"); ++ proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, ++ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | ++ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, ++ NULL, ++ "com.redhat.RHSM1", ++ "/com/redhat/RHSM1/Attach", ++ "com.redhat.RHSM1.Attach", ++ NULL, error); ++ if (proxy == NULL) { ++ g_prefix_error (error, "Failed to get proxy: "); ++ return FALSE; ++ } ++ proxy_options = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); ++ res = g_dbus_proxy_call_sync (proxy, ++ "AutoAttach", ++ g_variant_new ("(sa{sv}s)", ++ "", /* now? */ ++ proxy_options, ++ ""), /* lang */ ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, NULL, error); ++ if (res == NULL) ++ return FALSE; ++ g_variant_get (res, "(&s)", &str); ++ g_debug ("Attach.AutoAttach: %s", str); ++ return TRUE; ++} ++ ++static gboolean ++_helper_save_config (const gchar *key, const gchar *value, GError **error) ++{ ++ g_autoptr(GDBusProxy) proxy = NULL; ++ g_autoptr(GVariant) res = NULL; ++ proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, ++ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | ++ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, ++ NULL, ++ "com.redhat.RHSM1", ++ "/com/redhat/RHSM1/Config", ++ "com.redhat.RHSM1.Config", ++ NULL, error); ++ if (proxy == NULL) { ++ g_prefix_error (error, "Failed to get proxy: "); ++ return FALSE; ++ } ++ res = g_dbus_proxy_call_sync (proxy, "Set", ++ g_variant_new ("(svs)", ++ key, ++ g_variant_new_string (value), ++ ""), /* lang */ ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, NULL, error); ++ return res != NULL; ++} ++ ++int ++main (int argc, char *argv[]) ++{ ++ const gchar *userlang = ""; /* as root, so no translations */ ++ g_autofree gchar *activation_key = NULL; ++ g_autofree gchar *address = NULL; ++ g_autofree gchar *hostname = NULL; ++ g_autofree gchar *kind = NULL; ++ g_autofree gchar *organisation = NULL; ++ g_autofree gchar *password = NULL; ++ g_autofree gchar *port = NULL; ++ g_autofree gchar *prefix = NULL; ++ g_autofree gchar *proxy_server = NULL; ++ g_autofree gchar *username = NULL; ++ g_autoptr(GDBusConnection) conn_private = NULL; ++ g_autoptr(GDBusProxy) proxy = NULL; ++ g_autoptr(GError) error = NULL; ++ g_autoptr(GOptionContext) context = g_option_context_new (NULL); ++ g_autoptr(GVariantBuilder) proxy_options = NULL; ++ g_autoptr(GVariantBuilder) subman_conopts = NULL; ++ g_autoptr(GVariantBuilder) subman_options = NULL; ++ ++ const GOptionEntry options[] = { ++ { "kind", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, ++ &kind, "Kind, e.g. 'username' or 'key'", NULL }, ++ { "address", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, ++ &address, "UNIX address", NULL }, ++ { "username", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, ++ &username, "Username", NULL }, ++ { "password", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, ++ &password, "Password", NULL }, ++ { "organisation", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, ++ &organisation, "Organisation", NULL }, ++ { "activation-key", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, ++ &activation_key, "Activation keys", NULL }, ++ { "hostname", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, ++ &hostname, "Registration server hostname", NULL }, ++ { "prefix", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, ++ &prefix, "Registration server prefix", NULL }, ++ { "port", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, ++ &port, "Registration server port", NULL }, ++ { "proxy", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, ++ &proxy_server, "Proxy settings", NULL }, ++ { NULL} ++ }; ++ ++ /* check calling UID */ ++ if (getuid () != 0 || geteuid () != 0) { ++ g_printerr ("This program can only be used by the root user\n"); ++ return G_IO_ERROR_NOT_SUPPORTED; ++ } ++ g_option_context_add_main_entries (context, options, NULL); ++ if (!g_option_context_parse (context, &argc, &argv, &error)) { ++ g_printerr ("Failed to parse arguments: %s\n", error->message); ++ return G_IO_ERROR_NOT_SUPPORTED; ++ } ++ ++ /* uncommon actions */ ++ if (kind == NULL) { ++ g_printerr ("No --kind specified\n"); ++ return G_IO_ERROR_INVALID_DATA; ++ } ++ if (g_strcmp0 (kind, "unregister") == 0) { ++ if (!_helper_unregister (&error)) { ++ g_printerr ("Failed to Unregister: %s\n", error->message); ++ return G_IO_ERROR_NOT_INITIALIZED; ++ } ++ return EXIT_SUCCESS; ++ } ++ if (g_strcmp0 (kind, "auto-attach") == 0) { ++ if (!_helper_auto_attach (&error)) { ++ g_printerr ("Failed to AutoAttach: %s\n", error->message); ++ return G_IO_ERROR_NOT_INITIALIZED; ++ } ++ return EXIT_SUCCESS; ++ } ++ ++ /* connect to abstract socket for reasons */ ++ if (address == NULL) { ++ g_printerr ("No --address specified\n"); ++ return G_IO_ERROR_INVALID_DATA; ++ } ++ conn_private = g_dbus_connection_new_for_address_sync (address, ++ G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, ++ NULL, NULL, ++ &error); ++ if (conn_private == NULL) { ++ g_printerr ("Invalid --address specified: %s\n", error->message); ++ return G_IO_ERROR_INVALID_DATA; ++ } ++ proxy = g_dbus_proxy_new_sync (conn_private, ++ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, ++ NULL, /* GDBusInterfaceInfo */ ++ NULL, /* name */ ++ "/com/redhat/RHSM1/Register", ++ "com.redhat.RHSM1.Register", ++ NULL, &error); ++ if (proxy == NULL) { ++ g_printerr ("Count not contact RHSM: %s\n", error->message); ++ return G_IO_ERROR_NOT_FOUND; ++ } ++ ++ /* no options */ ++ subman_options = g_variant_builder_new (G_VARIANT_TYPE("a{ss}")); ++ ++ /* set registration server */ ++ if (hostname == NULL || hostname[0] == '\0') ++ hostname = g_strdup ("subscription.rhsm.redhat.com"); ++ if (prefix == NULL || prefix[0] == '\0') ++ prefix = g_strdup ("/subscription"); ++ if (port == NULL || port[0] == '\0') ++ port = g_strdup ("443"); ++ subman_conopts = g_variant_builder_new (G_VARIANT_TYPE("a{ss}")); ++ g_variant_builder_add (subman_conopts, "{ss}", "host", hostname); ++ g_variant_builder_add (subman_conopts, "{ss}", "handler", prefix); ++ g_variant_builder_add (subman_conopts, "{ss}", "port", port); ++ ++ /* call into RHSM */ ++ if (g_strcmp0 (kind, "register-with-key") == 0) { ++ g_auto(GStrv) activation_keys = NULL; ++ g_autoptr(GError) error_local = NULL; ++ g_autoptr(GVariant) res = NULL; ++ ++ if (activation_key == NULL) { ++ g_printerr ("Required --activation-key\n"); ++ return G_IO_ERROR_INVALID_DATA; ++ } ++ if (organisation == NULL) { ++ g_printerr ("Required --organisation\n"); ++ return G_IO_ERROR_INVALID_DATA; ++ } ++ ++ g_debug ("registering using activation key"); ++ activation_keys = g_strsplit (activation_key, ",", -1); ++ res = g_dbus_proxy_call_sync (proxy, ++ "RegisterWithActivationKeys", ++ g_variant_new ("(s^asa{ss}a{ss}s)", ++ organisation, ++ activation_keys, ++ subman_options, ++ subman_conopts, ++ userlang), ++ G_DBUS_CALL_FLAGS_NO_AUTO_START, ++ -1, NULL, &error_local); ++ if (res == NULL) { ++ g_dbus_error_strip_remote_error (error_local); ++ _helper_convert_error (error_local->message, &error); ++ g_printerr ("Failed to RegisterWithActivationKeys: %s\n", error->message); ++ return error->code; ++ } ++ } else if (g_strcmp0 (kind, "register-with-username") == 0) { ++ g_autoptr(GError) error_local = NULL; ++ g_autoptr(GVariant) res = NULL; ++ ++ g_debug ("registering using username and password"); ++ if (username == NULL) { ++ g_printerr ("Required --username\n"); ++ return G_IO_ERROR_INVALID_DATA; ++ } ++ if (password == NULL) { ++ g_printerr ("Required --password\n"); ++ return G_IO_ERROR_INVALID_DATA; ++ } ++ if (organisation == NULL) { ++ g_printerr ("Required --organisation\n"); ++ return G_IO_ERROR_INVALID_DATA; ++ } ++ res = g_dbus_proxy_call_sync (proxy, ++ "Register", ++ g_variant_new ("(sssa{ss}a{ss}s)", ++ organisation, ++ username, ++ password, ++ subman_options, ++ subman_conopts, ++ userlang), ++ G_DBUS_CALL_FLAGS_NO_AUTO_START, ++ -1, NULL, &error_local); ++ if (res == NULL) { ++ g_dbus_error_strip_remote_error (error_local); ++ _helper_convert_error (error_local->message, &error); ++ g_printerr ("Failed to Register: %s\n", error->message); ++ return error->code; ++ } ++ } else { ++ g_printerr ("Invalid --kind specified: %s\n", kind); ++ return G_IO_ERROR_INVALID_DATA; ++ } ++ ++ /* set the new hostname */ ++ if (!_helper_save_config ("server.hostname", hostname, &error)) { ++ g_printerr ("Failed to save hostname: %s\n", error->message); ++ return G_IO_ERROR_NOT_INITIALIZED; ++ } ++ if (!_helper_save_config ("server.prefix", prefix, &error)) { ++ g_printerr ("Failed to save prefix: %s\n", error->message); ++ return G_IO_ERROR_NOT_INITIALIZED; ++ } ++ if (!_helper_save_config ("server.port", port, &error)) { ++ g_printerr ("Failed to save port: %s\n", error->message); ++ return G_IO_ERROR_NOT_INITIALIZED; ++ } ++ ++ /* wait for rhsmd to notice the new config */ ++ g_usleep (G_USEC_PER_SEC * 5); ++ ++ /* auto-attach */ ++ if (!_helper_auto_attach (&error)) { ++ g_printerr ("Failed to AutoAttach: %s\n", error->message); ++ return G_IO_ERROR_NOT_INITIALIZED; ++ } ++ ++ return EXIT_SUCCESS; ++} +diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c +new file mode 100644 +index 00000000..08b13fa6 +--- /dev/null ++++ b/plugins/subman/gsd-subscription-manager.c +@@ -0,0 +1,982 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2019 Richard Hughes ++ * ++ * 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 . ++ * ++ */ ++ ++#include "config.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "gnome-settings-profile.h" ++#include "gsd-subman-common.h" ++#include "gsd-subscription-manager.h" ++ ++#define GSD_DBUS_NAME "org.gnome.SettingsDaemon" ++#define GSD_DBUS_PATH "/org/gnome/SettingsDaemon" ++#define GSD_DBUS_BASE_INTERFACE "org.gnome.SettingsDaemon" ++ ++#define GSD_SUBSCRIPTION_DBUS_NAME GSD_DBUS_NAME ".Subscription" ++#define GSD_SUBSCRIPTION_DBUS_PATH GSD_DBUS_PATH "/Subscription" ++#define GSD_SUBSCRIPTION_DBUS_INTERFACE GSD_DBUS_BASE_INTERFACE ".Subscription" ++ ++static const gchar introspection_xml[] = ++"" ++" " ++" " ++" " ++" " ++" " ++" " ++" " ++""; ++ ++#define GSD_SUBSCRIPTION_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_SUBSCRIPTION_MANAGER, GsdSubscriptionManagerPrivate)) ++ ++typedef enum { ++ _RHSM_INTERFACE_CONFIG, ++ _RHSM_INTERFACE_REGISTER_SERVER, ++ _RHSM_INTERFACE_ATTACH, ++ _RHSM_INTERFACE_ENTITLEMENT, ++ _RHSM_INTERFACE_PRODUCTS, ++ _RHSM_INTERFACE_CONSUMER, ++ _RHSM_INTERFACE_SYSPURPOSE, ++ _RHSM_INTERFACE_LAST ++} _RhsmInterface; ++ ++struct GsdSubscriptionManagerPrivate ++{ ++ /* D-Bus */ ++ guint name_id; ++ GDBusNodeInfo *introspection_data; ++ GDBusConnection *connection; ++ GCancellable *bus_cancellable; ++ ++ GDBusProxy *proxies[_RHSM_INTERFACE_LAST]; ++ const gchar *userlang; /* owned by GLib internally */ ++ GHashTable *config; /* str:str */ ++ gchar *address; ++ ++ GTimer *timer_last_notified; ++ NotifyNotification *notification_expired; ++ NotifyNotification *notification_registered; ++ NotifyNotification *notification_registration_required; ++ GsdSubmanSubscriptionStatus subscription_status; ++ GsdSubmanSubscriptionStatus subscription_status_last; ++}; ++ ++enum { ++ PROP_0, ++}; ++ ++static void gsd_subscription_manager_class_init (GsdSubscriptionManagerClass *klass); ++static void gsd_subscription_manager_init (GsdSubscriptionManager *subscription_manager); ++static void gsd_subscription_manager_finalize (GObject *object); ++ ++G_DEFINE_TYPE (GsdSubscriptionManager, gsd_subscription_manager, G_TYPE_OBJECT) ++ ++static gpointer manager_object = NULL; ++ ++GQuark ++gsd_subscription_manager_error_quark (void) ++{ ++ static GQuark quark = 0; ++ if (!quark) ++ quark = g_quark_from_static_string ("gsd_subscription_manager_error"); ++ return quark; ++} ++ ++static GsdSubmanSubscriptionStatus ++_client_subscription_status_from_text (const gchar *status_txt) ++{ ++ if (g_strcmp0 (status_txt, "Unknown") == 0) ++ return GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN; ++ if (g_strcmp0 (status_txt, "Current") == 0) ++ return GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID; ++ if (g_strcmp0 (status_txt, "Invalid") == 0) ++ return GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID; ++ if (g_strcmp0 (status_txt, "Disabled") == 0) ++ return GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED; ++ if (g_strcmp0 (status_txt, "Insufficient") == 0) ++ return GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID; ++ g_warning ("Unknown subscription status: %s", status_txt); // 'Current'? ++ return GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN; ++} ++ ++static void ++_emit_property_changed (GsdSubscriptionManager *manager, ++ const gchar *property_name, ++ GVariant *property_value) ++{ ++ GsdSubscriptionManagerPrivate *priv = manager->priv; ++ GVariantBuilder builder; ++ GVariantBuilder invalidated_builder; ++ ++ /* not yet connected */ ++ if (priv->connection == NULL) ++ return; ++ ++ /* build the dict */ ++ g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as")); ++ g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); ++ g_variant_builder_add (&builder, ++ "{sv}", ++ property_name, ++ property_value); ++ g_dbus_connection_emit_signal (priv->connection, ++ NULL, ++ GSD_SUBSCRIPTION_DBUS_PATH, ++ "org.freedesktop.DBus.Properties", ++ "PropertiesChanged", ++ g_variant_new ("(sa{sv}as)", ++ GSD_SUBSCRIPTION_DBUS_INTERFACE, ++ &builder, ++ &invalidated_builder), ++ NULL); ++ g_variant_builder_clear (&builder); ++ g_variant_builder_clear (&invalidated_builder); ++} ++ ++static gboolean ++_client_subscription_status_update (GsdSubscriptionManager *manager, GError **error) ++{ ++ GsdSubscriptionManagerPrivate *priv = manager->priv; ++ JsonNode *json_root; ++ JsonObject *json_obj; ++ const gchar *json_txt = NULL; ++ const gchar *status_txt = NULL; ++ g_autoptr(GVariant) val = NULL; ++ g_autoptr(JsonParser) json_parser = json_parser_new (); ++ ++ /* save old value */ ++ priv->subscription_status_last = priv->subscription_status; ++ ++ val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_ENTITLEMENT], ++ "GetStatus", ++ g_variant_new ("(ss)", ++ "", /* assumed as 'now' */ ++ priv->userlang), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, NULL, error); ++ if (val == NULL) ++ return FALSE; ++ g_variant_get (val, "(&s)", &json_txt); ++ g_debug ("Entitlement.GetStatus JSON: %s", json_txt); ++ if (!json_parser_load_from_data (json_parser, json_txt, -1, error)) ++ return FALSE; ++ json_root = json_parser_get_root (json_parser); ++ json_obj = json_node_get_object (json_root); ++ if (!json_object_has_member (json_obj, "status")) { ++ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, ++ "no Entitlement.GetStatus status in %s", json_txt); ++ return FALSE; ++ } ++ ++ status_txt = json_object_get_string_member (json_obj, "status"); ++ g_debug ("Entitlement.GetStatus: %s", status_txt); ++ priv->subscription_status = _client_subscription_status_from_text (status_txt); ++ ++ /* emit notification for g-c-c */ ++ if (priv->subscription_status != priv->subscription_status_last) { ++ _emit_property_changed (manager, "SubscriptionStatus", ++ g_variant_new_uint32 (priv->subscription_status)); ++ } ++ ++ return TRUE; ++} ++ ++static gboolean ++_client_syspurpose_update (GsdSubscriptionManager *manager, GError **error) ++{ ++ GsdSubscriptionManagerPrivate *priv = manager->priv; ++ JsonNode *json_root; ++ JsonObject *json_obj; ++ const gchar *json_txt = NULL; ++ g_autoptr(GVariant) val = NULL; ++ g_autoptr(JsonParser) json_parser = json_parser_new (); ++ ++ val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_SYSPURPOSE], ++ "GetSyspurpose", ++ g_variant_new ("(s)", priv->userlang), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, NULL, error); ++ if (val == NULL) ++ return FALSE; ++ g_variant_get (val, "(&s)", &json_txt); ++ g_debug ("Syspurpose.GetSyspurpose JSON: %s", json_txt); ++ if (!json_parser_load_from_data (json_parser, json_txt, -1, error)) ++ return FALSE; ++ json_root = json_parser_get_root (json_parser); ++ json_obj = json_node_get_object (json_root); ++ if (!json_object_has_member (json_obj, "status")) { ++ g_debug ("Syspurpose.GetSyspurpose: Unknown"); ++ return TRUE; ++ } ++ g_debug ("Syspurpose.GetSyspurpose: '%s", json_object_get_string_member (json_obj, "status")); ++ return TRUE; ++} ++ ++static gboolean ++_client_register_start (GsdSubscriptionManager *manager, GError **error) ++{ ++ GsdSubscriptionManagerPrivate *priv = manager->priv; ++ const gchar *address = NULL; ++ g_autoptr(GDBusProxy) proxy = NULL; ++ g_autoptr(GVariant) val = NULL; ++ ++ /* already started */ ++ if (priv->address != NULL) ++ return TRUE; ++ ++ /* apparently: "we can't send registration credentials over the regular ++ * system or session bus since those aren't really locked down..." */ ++ proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, ++ G_DBUS_PROXY_FLAGS_NONE, ++ NULL, ++ "com.redhat.RHSM1", ++ "/com/redhat/RHSM1/RegisterServer", ++ "com.redhat.RHSM1.RegisterServer", ++ NULL, error); ++ if (proxy == NULL) ++ return FALSE; ++ val = g_dbus_proxy_call_sync (proxy, "Start", ++ g_variant_new ("(s)", priv->userlang), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, NULL, error); ++ if (val == NULL) ++ return FALSE; ++ g_variant_get (val, "(&s)", &address); ++ g_debug ("RegisterServer.Start: %s", address); ++ priv->address = g_strdup (address); ++ return TRUE; ++} ++ ++static gboolean ++_client_register_stop (GsdSubscriptionManager *manager, GError **error) ++{ ++ GsdSubscriptionManagerPrivate *priv = manager->priv; ++ g_autoptr(GDBusProxy) proxy = NULL; ++ g_autoptr(GVariant) val = NULL; ++ ++ /* already started */ ++ if (priv->address == NULL) ++ return TRUE; ++ ++ /* stop registration server */ ++ proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, ++ G_DBUS_PROXY_FLAGS_NONE, ++ NULL, ++ "com.redhat.RHSM1", ++ "/com/redhat/RHSM1/RegisterServer", ++ "com.redhat.RHSM1.RegisterServer", ++ NULL, error); ++ if (proxy == NULL) ++ return FALSE; ++ val = g_dbus_proxy_call_sync (proxy, "Stop", ++ g_variant_new ("(s)", priv->userlang), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, NULL, error); ++ if (val == NULL) ++ return FALSE; ++ g_clear_pointer (&priv->address, g_free); ++ return TRUE; ++} ++ ++static gboolean ++_client_subprocess_wait_check (GSubprocess *subprocess, GError **error) ++{ ++ gint rc; ++ if (!g_subprocess_wait (subprocess, NULL, error)) { ++ g_prefix_error (error, "failed to run pkexec: "); ++ return FALSE; ++ } ++ rc = g_subprocess_get_exit_status (subprocess); ++ if (rc != 0) { ++ GInputStream *istream = g_subprocess_get_stderr_pipe (subprocess); ++ gchar buf[1024] = { 0x0 }; ++ gsize sz = 0; ++ g_input_stream_read_all (istream, buf, sizeof(buf) - 1, &sz, NULL, NULL); ++ if (sz == 0) { ++ g_set_error_literal (error, G_IO_ERROR, rc, ++ "Failed to run helper without stderr"); ++ return FALSE; ++ } ++ g_set_error_literal (error, G_IO_ERROR, rc, buf); ++ return FALSE; ++ } ++ return TRUE; ++} ++ ++typedef enum { ++ _NOTIFY_EXPIRED, ++ _NOTIFY_REGISTRATION_REQUIRED, ++ _NOTIFY_REGISTERED ++} _NotifyKind; ++ ++static void ++_show_notification (GsdSubscriptionManager *manager, _NotifyKind notify_kind) ++{ ++ GsdSubscriptionManagerPrivate *priv = manager->priv; ++ switch (notify_kind) { ++ case _NOTIFY_EXPIRED: ++ notify_notification_close (priv->notification_registered, NULL); ++ notify_notification_close (priv->notification_registration_required, NULL); ++ notify_notification_show (priv->notification_expired, NULL); ++ break; ++ case _NOTIFY_REGISTRATION_REQUIRED: ++ notify_notification_close (priv->notification_registered, NULL); ++ notify_notification_close (priv->notification_expired, NULL); ++ notify_notification_show (priv->notification_registration_required, NULL); ++ break; ++ case _NOTIFY_REGISTERED: ++ notify_notification_close (priv->notification_expired, NULL); ++ notify_notification_close (priv->notification_registration_required, NULL); ++ notify_notification_show (priv->notification_registered, NULL); ++ break; ++ default: ++ break; ++ } ++ g_timer_reset (priv->timer_last_notified); ++} ++ ++static void ++_client_maybe__show_notification (GsdSubscriptionManager *manager) ++{ ++ GsdSubscriptionManagerPrivate *priv = manager->priv; ++ ++ /* startup */ ++ if (priv->subscription_status_last == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN && ++ priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN) { ++ _show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED); ++ return; ++ } ++ ++ /* something changed */ ++ if (priv->subscription_status_last != priv->subscription_status) { ++ g_debug ("transisition from subscription status '%s' to '%s'", ++ gsd_subman_subscription_status_to_string (priv->subscription_status_last), ++ gsd_subman_subscription_status_to_string (priv->subscription_status)); ++ ++ /* needs registration */ ++ if (priv->subscription_status_last == GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID && ++ priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID) { ++ _show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED); ++ return; ++ } ++ ++ /* was unregistered */ ++ if (priv->subscription_status_last == GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID && ++ priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN) { ++ _show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED); ++ return; ++ } ++ ++ /* registered */ ++ if (priv->subscription_status_last == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN && ++ priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID && ++ g_timer_elapsed (priv->timer_last_notified, NULL) > 60) { ++ _show_notification (manager, _NOTIFY_REGISTERED); ++ return; ++ } ++ } ++ ++ /* nag again */ ++ if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN && ++ g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) { ++ _show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED); ++ return; ++ } ++ if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID && ++ g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) { ++ _show_notification (manager, _NOTIFY_EXPIRED); ++ return; ++ } ++ if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID && ++ g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) { ++ _show_notification (manager, _NOTIFY_EXPIRED); ++ return; ++ } ++} ++ ++static gboolean ++_client_register_with_keys (GsdSubscriptionManager *manager, ++ const gchar *hostname, ++ const gchar *organisation, ++ const gchar *activation_key, ++ GError **error) ++{ ++ GsdSubscriptionManagerPrivate *priv = manager->priv; ++ g_autoptr(GSubprocess) subprocess = NULL; ++ ++ /* apparently: "we can't send registration credentials over the regular ++ * system or session bus since those aren't really locked down..." */ ++ if (!_client_register_start (manager, error)) ++ return FALSE; ++ g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); ++ subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error, ++ "pkexec", LIBEXECDIR "/gsd-subman-helper", ++ "--kind", "register-with-key", ++ "--address", priv->address, ++ "--hostname", hostname, ++ "--organisation", organisation, ++ "--activation-key", activation_key, ++ NULL); ++ if (subprocess == NULL) { ++ g_prefix_error (error, "failed to find pkexec: "); ++ return FALSE; ++ } ++ if (!_client_subprocess_wait_check (subprocess, error)) ++ return FALSE; ++ ++ /* FIXME: also do on error? */ ++ if (!_client_register_stop (manager, error)) ++ return FALSE; ++ if (!_client_subscription_status_update (manager, error)) ++ return FALSE; ++ _client_maybe__show_notification (manager); ++ ++ /* success */ ++ return TRUE; ++} ++ ++static gboolean ++_client_register (GsdSubscriptionManager *manager, ++ const gchar *hostname, ++ const gchar *organisation, ++ const gchar *username, ++ const gchar *password, ++ GError **error) ++{ ++ GsdSubscriptionManagerPrivate *priv = manager->priv; ++ g_autoptr(GSubprocess) subprocess = NULL; ++ ++ /* fallback */ ++ if (organisation == NULL) ++ organisation = ""; ++ ++ /* apparently: "we can't send registration credentials over the regular ++ * system or session bus since those aren't really locked down..." */ ++ if (!_client_register_start (manager, error)) ++ return FALSE; ++ g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); ++ subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error, ++ "pkexec", LIBEXECDIR "/gsd-subman-helper", ++ "--kind", "register-with-username", ++ "--address", priv->address, ++ "--hostname", hostname, ++ "--organisation", organisation, ++ "--username", username, ++ "--password", password, ++ NULL); ++ if (subprocess == NULL) { ++ g_prefix_error (error, "failed to find pkexec: "); ++ return FALSE; ++ } ++ if (!_client_subprocess_wait_check (subprocess, error)) ++ return FALSE; ++ ++ /* FIXME: also do on error? */ ++ if (!_client_register_stop (manager, error)) ++ return FALSE; ++ if (!_client_subscription_status_update (manager, error)) ++ return FALSE; ++ _client_maybe__show_notification (manager); ++ return TRUE; ++} ++ ++static gboolean ++_client_unregister (GsdSubscriptionManager *manager, GError **error) ++{ ++ g_autoptr(GSubprocess) subprocess = NULL; ++ ++ /* apparently: "we can't send registration credentials over the regular ++ * system or session bus since those aren't really locked down..." */ ++ if (!_client_register_start (manager, error)) ++ return FALSE; ++ g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); ++ subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error, ++ "pkexec", LIBEXECDIR "/gsd-subman-helper", ++ "--kind", "unregister", ++ NULL); ++ if (subprocess == NULL) { ++ g_prefix_error (error, "failed to find pkexec: "); ++ return FALSE; ++ } ++ if (!_client_subprocess_wait_check (subprocess, error)) ++ return FALSE; ++ if (!_client_subscription_status_update (manager, error)) ++ return FALSE; ++ _client_maybe__show_notification (manager); ++ return TRUE; ++} ++ ++static gboolean ++_client_update_config (GsdSubscriptionManager *manager, GError **error) ++{ ++ GsdSubscriptionManagerPrivate *priv = manager->priv; ++ g_autoptr(GVariant) val = NULL; ++ g_autoptr(GVariant) val_server = NULL; ++ g_autoptr(GVariantDict) dict = NULL; ++ GVariantIter iter; ++ gchar *key; ++ gchar *value; ++ ++ val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_CONFIG], ++ "GetAll", ++ g_variant_new ("(s)", priv->userlang), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, NULL, error); ++ if (val == NULL) ++ return FALSE; ++ dict = g_variant_dict_new (g_variant_get_child_value (val, 0)); ++ val_server = g_variant_dict_lookup_value (dict, "server", G_VARIANT_TYPE("a{ss}")); ++ if (val_server != NULL) { ++ g_variant_iter_init (&iter, val_server); ++ while (g_variant_iter_next (&iter, "{ss}", &key, &value)) { ++ g_debug ("%s=%s", key, value); ++ g_hash_table_insert (priv->config, ++ g_steal_pointer (&key), ++ g_steal_pointer (&value)); ++ } ++ } ++ return TRUE; ++} ++ ++static void ++_subman_proxy_signal_cb (GDBusProxy *proxy, ++ const gchar *sender_name, ++ const gchar *signal_name, ++ GVariant *parameters, ++ GsdSubscriptionManager *manager) ++{ ++ g_autoptr(GError) error = NULL; ++ if (!_client_syspurpose_update (manager, &error)) { ++ g_warning ("failed to update syspurpose: %s", error->message); ++ g_clear_error (&error); ++ } ++ if (!_client_subscription_status_update (manager, &error)) { ++ g_warning ("failed to update subscription status: %s", error->message); ++ g_clear_error (&error); ++ } ++ _client_maybe__show_notification (manager); ++} ++ ++static void ++_client_unload (GsdSubscriptionManager *manager) ++{ ++ GsdSubscriptionManagerPrivate *priv = manager->priv; ++ for (guint i = 0; i < _RHSM_INTERFACE_LAST; i++) ++ g_clear_object (&priv->proxies[i]); ++ g_hash_table_unref (priv->config); ++} ++ ++static const gchar * ++_rhsm_interface_to_string (_RhsmInterface kind) ++{ ++ if (kind == _RHSM_INTERFACE_CONFIG) ++ return "Config"; ++ if (kind == _RHSM_INTERFACE_REGISTER_SERVER) ++ return "RegisterServer"; ++ if (kind == _RHSM_INTERFACE_ATTACH) ++ return "Attach"; ++ if (kind == _RHSM_INTERFACE_ENTITLEMENT) ++ return "Entitlement"; ++ if (kind == _RHSM_INTERFACE_PRODUCTS) ++ return "Products"; ++ if (kind == _RHSM_INTERFACE_CONSUMER) ++ return "Consumer"; ++ if (kind == _RHSM_INTERFACE_SYSPURPOSE) ++ return "Syspurpose"; ++ return NULL; ++} ++ ++static gboolean ++_client_load (GsdSubscriptionManager *manager, GError **error) ++{ ++ GsdSubscriptionManagerPrivate *priv = manager->priv; ++ ++ priv->config = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); ++ ++ /* connect to all the interfaces on the *different* objects :| */ ++ for (guint i = 0; i < _RHSM_INTERFACE_LAST; i++) { ++ const gchar *kind = _rhsm_interface_to_string (i); ++ g_autofree gchar *opath = g_strdup_printf ("/com/redhat/RHSM1/%s", kind); ++ g_autofree gchar *iface = g_strdup_printf ("com.redhat.RHSM1.%s", kind); ++ priv->proxies[i] = ++ g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, ++ G_DBUS_PROXY_FLAGS_NONE, ++ NULL, ++ "com.redhat.RHSM1", ++ opath, iface, ++ NULL, ++ error); ++ if (priv->proxies[i] == NULL) ++ return FALSE; ++ /* we want to get notified if the status of the system changes */ ++ g_signal_connect (priv->proxies[i], "g-signal", ++ G_CALLBACK (_subman_proxy_signal_cb), manager); ++ } ++ ++ /* get initial status */ ++ priv->userlang = ""; ++ if (!_client_update_config (manager, error)) ++ return FALSE; ++ if (!_client_subscription_status_update (manager, error)) ++ return FALSE; ++ if (!_client_syspurpose_update (manager, error)) ++ return FALSE; ++ ++ /* success */ ++ return TRUE; ++} ++ ++gboolean ++gsd_subscription_manager_start (GsdSubscriptionManager *manager, GError **error) ++{ ++ gboolean ret; ++ g_debug ("Starting subscription manager"); ++ gnome_settings_profile_start (NULL); ++ ret = _client_load (manager, error); ++ _client_maybe__show_notification (manager); ++ gnome_settings_profile_end (NULL); ++ return ret; ++} ++ ++void ++gsd_subscription_manager_stop (GsdSubscriptionManager *manager) ++{ ++ g_debug ("Stopping subscription manager"); ++ _client_unload (manager); ++} ++ ++static void ++gsd_subscription_manager_class_init (GsdSubscriptionManagerClass *klass) ++{ ++ GObjectClass *object_class = G_OBJECT_CLASS (klass); ++ object_class->finalize = gsd_subscription_manager_finalize; ++ notify_init ("gnome-settings-daemon"); ++ g_type_class_add_private (klass, sizeof (GsdSubscriptionManagerPrivate)); ++} ++ ++static void ++_launch_info_overview (void) ++{ ++ const gchar *argv[] = { "gnome-control-center", "info-overview", NULL }; ++ g_debug ("Running gnome-control-center info-overview"); ++ g_spawn_async (NULL, (gchar **) argv, NULL, G_SPAWN_SEARCH_PATH, ++ NULL, NULL, NULL, NULL); ++} ++ ++static void ++_notify_closed_cb (NotifyNotification *notification, gpointer user_data) ++{ ++ /* FIXME: only launch when clicking on the main body, not the window close */ ++ if (notify_notification_get_closed_reason (notification) == 0x400) ++ _launch_info_overview (); ++} ++ ++static void ++_notify_clicked_cb (NotifyNotification *notification, char *action, gpointer user_data) ++{ ++ _launch_info_overview (); ++} ++ ++static void ++gsd_subscription_manager_init (GsdSubscriptionManager *manager) ++{ ++ GsdSubscriptionManagerPrivate *priv = manager->priv = GSD_SUBSCRIPTION_MANAGER_GET_PRIVATE (manager); ++ ++ priv->timer_last_notified = g_timer_new (); ++ ++ /* expired */ ++ priv->notification_expired = ++ notify_notification_new (_("Subscription Has Expired"), ++ _("Add or renew a subscription to continue receiving software updates."), ++ NULL); ++ notify_notification_set_app_name (priv->notification_expired, _("Subscription")); ++ notify_notification_set_hint_string (priv->notification_expired, "desktop-entry", "subman-panel"); ++ notify_notification_set_hint_string (priv->notification_expired, "x-gnome-privacy-scope", "system"); ++ notify_notification_set_urgency (priv->notification_expired, NOTIFY_URGENCY_CRITICAL); ++ notify_notification_add_action (priv->notification_expired, ++ "info-overview", _("Subscribe System…"), ++ _notify_clicked_cb, ++ manager, NULL); ++ g_signal_connect (priv->notification_expired, "closed", ++ G_CALLBACK (_notify_closed_cb), manager); ++ ++ /* registered */ ++ priv->notification_registered = ++ notify_notification_new (_("Registration Successful"), ++ _("The system has been registered and software updates have been enabled."), ++ NULL); ++ notify_notification_set_app_name (priv->notification_registered, _("Subscription")); ++ notify_notification_set_hint_string (priv->notification_registered, "desktop-entry", "subman-panel"); ++ notify_notification_set_hint_string (priv->notification_registered, "x-gnome-privacy-scope", "system"); ++ notify_notification_set_urgency (priv->notification_registered, NOTIFY_URGENCY_CRITICAL); ++ g_signal_connect (priv->notification_registered, "closed", ++ G_CALLBACK (_notify_closed_cb), manager); ++ ++ /* registration required */ ++ priv->notification_registration_required = ++ notify_notification_new (_("System Not Registered"), ++ _("Please register your system to receive software updates."), ++ NULL); ++ notify_notification_set_app_name (priv->notification_registration_required, _("Subscription")); ++ notify_notification_set_hint_string (priv->notification_registration_required, "desktop-entry", "subman-panel"); ++ notify_notification_set_hint_string (priv->notification_registration_required, "x-gnome-privacy-scope", "system"); ++ notify_notification_set_urgency (priv->notification_registration_required, NOTIFY_URGENCY_CRITICAL); ++ notify_notification_add_action (priv->notification_registration_required, ++ "info-overview", _("Register System…"), ++ _notify_clicked_cb, ++ manager, NULL); ++ g_signal_connect (priv->notification_registration_required, "closed", ++ G_CALLBACK (_notify_closed_cb), manager); ++} ++ ++static void ++gsd_subscription_manager_finalize (GObject *object) ++{ ++ GsdSubscriptionManager *manager; ++ ++ g_return_if_fail (object != NULL); ++ g_return_if_fail (GSD_IS_SUBSCRIPTION_MANAGER (object)); ++ ++ manager = GSD_SUBSCRIPTION_MANAGER (object); ++ ++ gsd_subscription_manager_stop (manager); ++ ++ if (manager->priv->bus_cancellable != NULL) { ++ g_cancellable_cancel (manager->priv->bus_cancellable); ++ g_clear_object (&manager->priv->bus_cancellable); ++ } ++ ++ g_clear_pointer (&manager->priv->introspection_data, g_dbus_node_info_unref); ++ g_clear_object (&manager->priv->connection); ++ g_clear_object (&manager->priv->notification_expired); ++ g_clear_object (&manager->priv->notification_registered); ++ g_timer_destroy (manager->priv->timer_last_notified); ++ ++ if (manager->priv->name_id != 0) { ++ g_bus_unown_name (manager->priv->name_id); ++ manager->priv->name_id = 0; ++ } ++ ++ G_OBJECT_CLASS (gsd_subscription_manager_parent_class)->finalize (object); ++} ++ ++static void ++handle_method_call (GDBusConnection *connection, ++ const gchar *sender, ++ const gchar *object_path, ++ const gchar *interface_name, ++ const gchar *method_name, ++ GVariant *parameters, ++ GDBusMethodInvocation *invocation, ++ gpointer user_data) ++{ ++ GsdSubscriptionManager *manager = GSD_SUBSCRIPTION_MANAGER (user_data); ++ g_autoptr(GError) error = NULL; ++ ++ if (g_strcmp0 (method_name, "Register") == 0) { ++ const gchar *organisation = NULL; ++ const gchar *hostname = NULL; ++ ++ if (FALSE) { ++ g_dbus_method_invocation_return_error_literal (invocation, ++ G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED, ++ "Cannot register at this time"); ++ ++ return; ++ } ++ ++ g_autoptr(GVariantDict) dict = g_variant_dict_new (g_variant_get_child_value (parameters, 0)); ++ ++ const gchar *kind = NULL; ++ if (!g_variant_dict_lookup (dict, "kind", "&s", &kind)) { ++ g_dbus_method_invocation_return_error_literal (invocation, ++ G_IO_ERROR, G_IO_ERROR_FAILED, ++ "No kind specified"); ++ ++ return; ++ } ++ if (g_strcmp0 (kind, "username") == 0) { ++ const gchar *username = NULL; ++ const gchar *password = NULL; ++ g_variant_dict_lookup (dict, "hostname", "&s", &hostname); ++ g_variant_dict_lookup (dict, "organisation", "&s", &organisation); ++ g_variant_dict_lookup (dict, "username", "&s", &username); ++ g_variant_dict_lookup (dict, "password", "&s", &password); ++ if (!_client_register (manager, ++ hostname, ++ organisation, ++ username, ++ password, ++ &error)) { ++ g_dbus_method_invocation_return_gerror (invocation, error); ++ return; ++ } ++ } else if (g_strcmp0 (kind, "key") == 0) { ++ const gchar *activation_key = NULL; ++ g_variant_dict_lookup (dict, "hostname", "&s", &hostname); ++ g_variant_dict_lookup (dict, "organisation", "&s", &organisation); ++ g_variant_dict_lookup (dict, "activation-key", "&s", &activation_key); ++ if (!_client_register_with_keys (manager, ++ hostname, ++ organisation, ++ activation_key, ++ &error)) { ++ g_dbus_method_invocation_return_gerror (invocation, error); ++ return; ++ } ++ } else { ++ g_dbus_method_invocation_return_error_literal (invocation, ++ G_IO_ERROR, G_IO_ERROR_FAILED, ++ "Invalid kind specified"); ++ ++ return; ++ } ++ g_dbus_method_invocation_return_value (invocation, NULL); ++ } else if (g_strcmp0 (method_name, "Unregister") == 0) { ++ if (!_client_unregister (manager, &error)) { ++ g_dbus_method_invocation_return_gerror (invocation, error); ++ return; ++ } ++ g_dbus_method_invocation_return_value (invocation, NULL); ++ } else { ++ g_assert_not_reached (); ++ } ++} ++ ++static GVariant * ++handle_get_property (GDBusConnection *connection, ++ const gchar *sender, ++ const gchar *object_path, ++ const gchar *interface_name, ++ const gchar *property_name, ++ GError **error, gpointer user_data) ++{ ++ GsdSubscriptionManager *manager = GSD_SUBSCRIPTION_MANAGER (user_data); ++ GsdSubscriptionManagerPrivate *priv = manager->priv; ++ ++ if (g_strcmp0 (interface_name, GSD_SUBSCRIPTION_DBUS_INTERFACE) != 0) { ++ g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, ++ "No such interface: %s", interface_name); ++ return NULL; ++ } ++ ++ if (g_strcmp0 (property_name, "SubscriptionStatus") == 0) ++ return g_variant_new_uint32 (priv->subscription_status); ++ ++ g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, ++ "Failed to get property: %s", property_name); ++ return NULL; ++} ++ ++static gboolean ++handle_set_property (GDBusConnection *connection, ++ const gchar *sender, ++ const gchar *object_path, ++ const gchar *interface_name, ++ const gchar *property_name, ++ GVariant *value, ++ GError **error, gpointer user_data) ++{ ++ if (g_strcmp0 (interface_name, GSD_SUBSCRIPTION_DBUS_INTERFACE) != 0) { ++ g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, ++ "No such interface: %s", interface_name); ++ return FALSE; ++ } ++ g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, ++ "No such property: %s", property_name); ++ return FALSE; ++} ++ ++static const GDBusInterfaceVTable interface_vtable = ++{ ++ handle_method_call, ++ handle_get_property, ++ handle_set_property ++}; ++ ++static void ++name_lost_handler_cb (GDBusConnection *connection, const gchar *name, gpointer user_data) ++{ ++ g_debug ("lost name, so exiting"); ++ gtk_main_quit (); ++} ++ ++static void ++on_bus_gotten (GObject *source_object, GAsyncResult *res, GsdSubscriptionManager *manager) ++{ ++ GsdSubscriptionManagerPrivate *priv = manager->priv; ++ GDBusConnection *connection; ++ g_autoptr(GError) error = NULL; ++ ++ connection = g_bus_get_finish (res, &error); ++ if (connection == NULL) { ++ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) ++ g_warning ("Could not get session bus: %s", error->message); ++ return; ++ } ++ ++ priv->connection = connection; ++ g_dbus_connection_register_object (connection, ++ GSD_SUBSCRIPTION_DBUS_PATH, ++ priv->introspection_data->interfaces[0], ++ &interface_vtable, ++ manager, ++ NULL, ++ NULL); ++ priv->name_id = g_bus_own_name_on_connection (connection, ++ GSD_SUBSCRIPTION_DBUS_NAME, ++ G_BUS_NAME_OWNER_FLAGS_NONE, ++ NULL, ++ name_lost_handler_cb, ++ manager, ++ NULL); ++} ++ ++static void ++register_manager_dbus (GsdSubscriptionManager *manager) ++{ ++ GsdSubscriptionManagerPrivate *priv = manager->priv; ++ ++ priv->introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL); ++ g_assert (priv->introspection_data != NULL); ++ priv->bus_cancellable = g_cancellable_new (); ++ ++ g_bus_get (G_BUS_TYPE_SESSION, priv->bus_cancellable, ++ (GAsyncReadyCallback) on_bus_gotten, manager); ++} ++ ++GsdSubscriptionManager * ++gsd_subscription_manager_new (void) ++{ ++ if (manager_object != NULL) { ++ g_object_ref (manager_object); ++ } else { ++ manager_object = g_object_new (GSD_TYPE_SUBSCRIPTION_MANAGER, NULL); ++ g_object_add_weak_pointer (manager_object, ++ (gpointer *) &manager_object); ++ register_manager_dbus (manager_object); ++ } ++ ++ return GSD_SUBSCRIPTION_MANAGER (manager_object); ++} +diff --git a/plugins/subman/gsd-subscription-manager.h b/plugins/subman/gsd-subscription-manager.h +new file mode 100644 +index 00000000..6a524b1b +--- /dev/null ++++ b/plugins/subman/gsd-subscription-manager.h +@@ -0,0 +1,63 @@ ++/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- ++ * ++ * Copyright (C) 2019 Richard Hughes ++ * ++ * 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 . ++ * ++ */ ++ ++#ifndef __GSD_SUBSCRIPTION_MANAGER_H ++#define __GSD_SUBSCRIPTION_MANAGER_H ++ ++#include ++ ++G_BEGIN_DECLS ++ ++#define GSD_TYPE_SUBSCRIPTION_MANAGER (gsd_subscription_manager_get_type ()) ++#define GSD_SUBSCRIPTION_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GSD_TYPE_SUBSCRIPTION_MANAGER, GsdSubscriptionManager)) ++#define GSD_SUBSCRIPTION_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GSD_TYPE_SUBSCRIPTION_MANAGER, GsdSubscriptionManagerClass)) ++#define GSD_IS_SUBSCRIPTION_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GSD_TYPE_SUBSCRIPTION_MANAGER)) ++#define GSD_IS_SUBSCRIPTION_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GSD_TYPE_SUBSCRIPTION_MANAGER)) ++#define GSD_SUBSCRIPTION_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GSD_TYPE_SUBSCRIPTION_MANAGER, GsdSubscriptionManagerClass)) ++#define GSD_SUBSCRIPTION_MANAGER_ERROR (gsd_subscription_manager_error_quark ()) ++ ++typedef struct GsdSubscriptionManagerPrivate GsdSubscriptionManagerPrivate; ++ ++typedef struct ++{ ++ GObject parent; ++ GsdSubscriptionManagerPrivate *priv; ++} GsdSubscriptionManager; ++ ++typedef struct ++{ ++ GObjectClass parent_class; ++} GsdSubscriptionManagerClass; ++ ++enum ++{ ++ GSD_SUBSCRIPTION_MANAGER_ERROR_FAILED ++}; ++ ++GType gsd_subscription_manager_get_type (void); ++GQuark gsd_subscription_manager_error_quark (void); ++ ++GsdSubscriptionManager *gsd_subscription_manager_new (void); ++gboolean gsd_subscription_manager_start (GsdSubscriptionManager *manager, ++ GError **error); ++void gsd_subscription_manager_stop (GsdSubscriptionManager *manager); ++ ++G_END_DECLS ++ ++#endif /* __GSD_SUBSCRIPTION_MANAGER_H */ +diff --git a/plugins/subman/main.c b/plugins/subman/main.c +new file mode 100644 +index 00000000..28ac995b +--- /dev/null ++++ b/plugins/subman/main.c +@@ -0,0 +1,8 @@ ++#define NEW gsd_subscription_manager_new ++#define START gsd_subscription_manager_start ++#define STOP gsd_subscription_manager_stop ++#define MANAGER GsdSubscriptionManager ++#define GDK_BACKEND "x11" ++#include "gsd-subscription-manager.h" ++ ++#include "daemon-skeleton-gtk.h" +diff --git a/plugins/subman/meson.build b/plugins/subman/meson.build +new file mode 100644 +index 00000000..bfd073b6 +--- /dev/null ++++ b/plugins/subman/meson.build +@@ -0,0 +1,56 @@ ++sources = files( ++ 'gsd-subscription-manager.c', ++ 'gsd-subman-common.c', ++ 'main.c' ++) ++ ++deps = plugins_deps + [ ++ libnotify_dep, ++ gtk_dep, ++ jsonglib_dep, ++ m_dep, ++] ++ ++cflags += ['-DBINDIR="@0@"'.format(gsd_bindir)] ++cflags += ['-DLIBEXECDIR="@0@"'.format(gsd_libexecdir)] ++ ++executable( ++ 'gsd-' + plugin_name, ++ sources, ++ include_directories: [top_inc, common_inc], ++ dependencies: deps, ++ c_args: cflags, ++ install: true, ++ install_rpath: gsd_pkglibdir, ++ install_dir: gsd_libexecdir ++) ++ ++# .Register needs to be called from root as subman can't do PolicyKit... ++policy = 'org.gnome.settings-daemon.plugins.subman.policy' ++policy_in = configure_file( ++ input: policy + '.in.in', ++ output: policy + '.in', ++ configuration: plugins_conf ++) ++ ++i18n.merge_file( ++ policy, ++ input: policy_in, ++ output: policy, ++ po_dir: po_dir, ++ install: true, ++ install_dir: join_paths(gsd_datadir, 'polkit-1', 'actions') ++) ++ ++install_data('org.gnome.settings-daemon.plugins.subman.rules', ++ install_dir : join_paths(gsd_datadir, 'polkit-1', 'rules.d')) ++ ++executable( ++ 'gsd-subman-helper', ++ 'gsd-subman-helper.c', ++ include_directories: top_inc, ++ dependencies: [gio_dep, jsonglib_dep], ++ install: true, ++ install_rpath: gsd_pkglibdir, ++ install_dir: gsd_libexecdir ++) +diff --git a/plugins/subman/org.gnome.SettingsDaemon.Subscription.desktop.in b/plugins/subman/org.gnome.SettingsDaemon.Subscription.desktop.in +new file mode 100644 +index 00000000..14fe5915 +--- /dev/null ++++ b/plugins/subman/org.gnome.SettingsDaemon.Subscription.desktop.in +@@ -0,0 +1,9 @@ ++[Desktop Entry] ++Type=Application ++Name=GNOME Settings Daemon's subscription manager plugin ++Exec=@libexecdir@/gsd-subman ++OnlyShowIn=GNOME; ++NoDisplay=true ++X-GNOME-Autostart-Phase=Initialization ++X-GNOME-Autostart-Notify=true ++X-GNOME-AutoRestart=true +diff --git a/plugins/subman/org.gnome.settings-daemon.plugins.subman.policy.in.in b/plugins/subman/org.gnome.settings-daemon.plugins.subman.policy.in.in +new file mode 100644 +index 00000000..59e9fdd4 +--- /dev/null ++++ b/plugins/subman/org.gnome.settings-daemon.plugins.subman.policy.in.in +@@ -0,0 +1,27 @@ ++ ++ ++ ++ ++ ++ ++ GNOME Settings Daemon ++ http://git.gnome.org/browse/gnome-settings-daemon ++ emblem-synchronizing ++ ++ ++ Register the system ++ Authentication is required to register the system ++ ++ no ++ no ++ auth_admin_keep ++ ++ @libexecdir@/gsd-subman-helper ++ ++ ++ +diff --git a/plugins/subman/org.gnome.settings-daemon.plugins.subman.rules b/plugins/subman/org.gnome.settings-daemon.plugins.subman.rules +new file mode 100644 +index 00000000..1ed3a0ea +--- /dev/null ++++ b/plugins/subman/org.gnome.settings-daemon.plugins.subman.rules +@@ -0,0 +1,7 @@ ++polkit.addRule(function(action, subject) { ++ if (action.id == "org.gnome.settings-daemon.plugins.subman.register" && ++ subject.active == true && subject.local == true && ++ subject.isInGroup("wheel")) { ++ return polkit.Result.YES; ++ } ++}); +-- +2.30.0 + diff --git a/SOURCES/0002-subman-Add-InstalledProducts-dbus-property-for-g-c-c.patch b/SOURCES/0002-subman-Add-InstalledProducts-dbus-property-for-g-c-c.patch new file mode 100644 index 0000000..c7505ab --- /dev/null +++ b/SOURCES/0002-subman-Add-InstalledProducts-dbus-property-for-g-c-c.patch @@ -0,0 +1,768 @@ +From f723ed1078e050c4d966d40b2aea74970c74279c Mon Sep 17 00:00:00 2001 +From: Kalev Lember +Date: Thu, 27 Jun 2019 16:12:00 +0200 +Subject: [PATCH 02/15] subman: Add InstalledProducts dbus property for g-c-c + +--- + plugins/subman/gsd-subscription-manager.c | 135 ++++++++++++++++++++++ + 1 file changed, 135 insertions(+) + +diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c +index 08b13fa6..a8c18a26 100644 +--- a/plugins/subman/gsd-subscription-manager.c ++++ b/plugins/subman/gsd-subscription-manager.c +@@ -1,186 +1,304 @@ + /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2019 Richard Hughes ++ * Copyright (C) 2019 Kalev Lember + * + * 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 . + * + */ + + #include "config.h" + + #include + #include + #include + #include + #include + + #include "gnome-settings-profile.h" + #include "gsd-subman-common.h" + #include "gsd-subscription-manager.h" + + #define GSD_DBUS_NAME "org.gnome.SettingsDaemon" + #define GSD_DBUS_PATH "/org/gnome/SettingsDaemon" + #define GSD_DBUS_BASE_INTERFACE "org.gnome.SettingsDaemon" + + #define GSD_SUBSCRIPTION_DBUS_NAME GSD_DBUS_NAME ".Subscription" + #define GSD_SUBSCRIPTION_DBUS_PATH GSD_DBUS_PATH "/Subscription" + #define GSD_SUBSCRIPTION_DBUS_INTERFACE GSD_DBUS_BASE_INTERFACE ".Subscription" + + static const gchar introspection_xml[] = + "" + " " + " " + " " + " " + " " ++" " + " " + " " + ""; + + #define GSD_SUBSCRIPTION_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_SUBSCRIPTION_MANAGER, GsdSubscriptionManagerPrivate)) + + typedef enum { + _RHSM_INTERFACE_CONFIG, + _RHSM_INTERFACE_REGISTER_SERVER, + _RHSM_INTERFACE_ATTACH, + _RHSM_INTERFACE_ENTITLEMENT, + _RHSM_INTERFACE_PRODUCTS, + _RHSM_INTERFACE_CONSUMER, + _RHSM_INTERFACE_SYSPURPOSE, + _RHSM_INTERFACE_LAST + } _RhsmInterface; + + struct GsdSubscriptionManagerPrivate + { + /* D-Bus */ + guint name_id; + GDBusNodeInfo *introspection_data; + GDBusConnection *connection; + GCancellable *bus_cancellable; + + GDBusProxy *proxies[_RHSM_INTERFACE_LAST]; + const gchar *userlang; /* owned by GLib internally */ + GHashTable *config; /* str:str */ ++ GPtrArray *installed_products; + gchar *address; + + GTimer *timer_last_notified; + NotifyNotification *notification_expired; + NotifyNotification *notification_registered; + NotifyNotification *notification_registration_required; + GsdSubmanSubscriptionStatus subscription_status; + GsdSubmanSubscriptionStatus subscription_status_last; + }; + + enum { + PROP_0, + }; + + static void gsd_subscription_manager_class_init (GsdSubscriptionManagerClass *klass); + static void gsd_subscription_manager_init (GsdSubscriptionManager *subscription_manager); + static void gsd_subscription_manager_finalize (GObject *object); + + G_DEFINE_TYPE (GsdSubscriptionManager, gsd_subscription_manager, G_TYPE_OBJECT) + ++typedef struct ++{ ++ gchar *product_name; ++ gchar *product_id; ++ gchar *version; ++ gchar *arch; ++ gchar *status; ++ gchar *starts; ++ gchar *ends; ++} ProductData; ++ ++static void ++product_data_free (ProductData *product) ++{ ++ g_free (product->product_name); ++ g_free (product->product_id); ++ g_free (product->version); ++ g_free (product->arch); ++ g_free (product->status); ++ g_free (product->starts); ++ g_free (product->ends); ++ g_free (product); ++} ++ ++G_DEFINE_AUTOPTR_CLEANUP_FUNC (ProductData, product_data_free); ++ + static gpointer manager_object = NULL; + + GQuark + gsd_subscription_manager_error_quark (void) + { + static GQuark quark = 0; + if (!quark) + quark = g_quark_from_static_string ("gsd_subscription_manager_error"); + return quark; + } + + static GsdSubmanSubscriptionStatus + _client_subscription_status_from_text (const gchar *status_txt) + { + if (g_strcmp0 (status_txt, "Unknown") == 0) + return GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN; + if (g_strcmp0 (status_txt, "Current") == 0) + return GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID; + if (g_strcmp0 (status_txt, "Invalid") == 0) + return GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID; + if (g_strcmp0 (status_txt, "Disabled") == 0) + return GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED; + if (g_strcmp0 (status_txt, "Insufficient") == 0) + return GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID; + g_warning ("Unknown subscription status: %s", status_txt); // 'Current'? + return GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN; + } + ++static GVariant * ++_make_installed_products_variant (GPtrArray *installed_products) ++{ ++ GVariantBuilder builder; ++ g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); ++ ++ for (guint i = 0; i < installed_products->len; i++) { ++ ProductData *product = g_ptr_array_index (installed_products, i); ++ g_auto(GVariantDict) dict; ++ ++ g_variant_dict_init (&dict, NULL); ++ ++ g_variant_dict_insert (&dict, "product-name", "s", product->product_name); ++ g_variant_dict_insert (&dict, "product-id", "s", product->product_id); ++ g_variant_dict_insert (&dict, "version", "s", product->version); ++ g_variant_dict_insert (&dict, "arch", "s", product->arch); ++ g_variant_dict_insert (&dict, "status", "s", product->status); ++ g_variant_dict_insert (&dict, "starts", "s", product->starts); ++ g_variant_dict_insert (&dict, "ends", "s", product->ends); ++ ++ g_variant_builder_add_value (&builder, g_variant_dict_end (&dict)); ++ } ++ ++ return g_variant_builder_end (&builder); ++} ++ + static void + _emit_property_changed (GsdSubscriptionManager *manager, + const gchar *property_name, + GVariant *property_value) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + GVariantBuilder builder; + GVariantBuilder invalidated_builder; + + /* not yet connected */ + if (priv->connection == NULL) + return; + + /* build the dict */ + g_variant_builder_init (&invalidated_builder, G_VARIANT_TYPE ("as")); + g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY); + g_variant_builder_add (&builder, + "{sv}", + property_name, + property_value); + g_dbus_connection_emit_signal (priv->connection, + NULL, + GSD_SUBSCRIPTION_DBUS_PATH, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + g_variant_new ("(sa{sv}as)", + GSD_SUBSCRIPTION_DBUS_INTERFACE, + &builder, + &invalidated_builder), + NULL); + g_variant_builder_clear (&builder); + g_variant_builder_clear (&invalidated_builder); + } + ++static gboolean ++_client_installed_products_update (GsdSubscriptionManager *manager, GError **error) ++{ ++ GsdSubscriptionManagerPrivate *priv = manager->priv; ++ JsonNode *json_root; ++ JsonArray *json_products_array; ++ const gchar *json_txt = NULL; ++ g_autoptr(GVariant) val = NULL; ++ g_autoptr(JsonParser) json_parser = json_parser_new (); ++ ++ val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_PRODUCTS], ++ "ListInstalledProducts", ++ g_variant_new ("(sa{sv}s)", ++ "" /* filter_string */, ++ NULL /* proxy_options */, ++ priv->userlang), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, NULL, error); ++ if (val == NULL) ++ return FALSE; ++ g_variant_get (val, "(&s)", &json_txt); ++ g_debug ("Products.ListInstalledProducts JSON: %s", json_txt); ++ if (!json_parser_load_from_data (json_parser, json_txt, -1, error)) ++ return FALSE; ++ json_root = json_parser_get_root (json_parser); ++ json_products_array = json_node_get_array (json_root); ++ if (json_products_array == NULL) { ++ g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, ++ "no InstalledProducts array in %s", json_txt); ++ return FALSE; ++ } ++ ++ g_ptr_array_set_size (priv->installed_products, 0); ++ ++ for (guint i = 0; i < json_array_get_length (json_products_array); i++) { ++ JsonArray *json_product = json_array_get_array_element (json_products_array, i); ++ g_autoptr(ProductData) product = g_new0 (ProductData, 1); ++ ++ if (json_product == NULL) ++ continue; ++ if (json_array_get_length (json_product) < 8) { ++ g_debug ("Unexpected number of array elements in InstalledProducts JSON"); ++ continue; ++ } ++ ++ product->product_name = g_strdup (json_array_get_string_element (json_product, 0)); ++ product->product_id = g_strdup (json_array_get_string_element (json_product, 1)); ++ product->version = g_strdup (json_array_get_string_element (json_product, 2)); ++ product->arch = g_strdup (json_array_get_string_element (json_product, 3)); ++ product->status = g_strdup (json_array_get_string_element (json_product, 4)); ++ product->starts = g_strdup (json_array_get_string_element (json_product, 6)); ++ product->ends = g_strdup (json_array_get_string_element (json_product, 7)); ++ ++ g_ptr_array_add (priv->installed_products, g_steal_pointer (&product)); ++ } ++ ++ /* emit notification for g-c-c */ ++ _emit_property_changed (manager, "InstalledProducts", ++ _make_installed_products_variant (priv->installed_products)); ++ ++ return TRUE; ++} ++ + static gboolean + _client_subscription_status_update (GsdSubscriptionManager *manager, GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + JsonNode *json_root; + JsonObject *json_obj; + const gchar *json_txt = NULL; + const gchar *status_txt = NULL; + g_autoptr(GVariant) val = NULL; + g_autoptr(JsonParser) json_parser = json_parser_new (); + + /* save old value */ + priv->subscription_status_last = priv->subscription_status; + + val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_ENTITLEMENT], + "GetStatus", + g_variant_new ("(ss)", + "", /* assumed as 'now' */ + priv->userlang), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (val == NULL) + return FALSE; + g_variant_get (val, "(&s)", &json_txt); + g_debug ("Entitlement.GetStatus JSON: %s", json_txt); + if (!json_parser_load_from_data (json_parser, json_txt, -1, error)) + return FALSE; + json_root = json_parser_get_root (json_parser); + json_obj = json_node_get_object (json_root); + if (!json_object_has_member (json_obj, "status")) { +@@ -423,185 +541,195 @@ _client_register_with_keys (GsdSubscriptionManager *manager, + GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + g_autoptr(GSubprocess) subprocess = NULL; + + /* apparently: "we can't send registration credentials over the regular + * system or session bus since those aren't really locked down..." */ + if (!_client_register_start (manager, error)) + return FALSE; + g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); + subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error, + "pkexec", LIBEXECDIR "/gsd-subman-helper", + "--kind", "register-with-key", + "--address", priv->address, + "--hostname", hostname, + "--organisation", organisation, + "--activation-key", activation_key, + NULL); + if (subprocess == NULL) { + g_prefix_error (error, "failed to find pkexec: "); + return FALSE; + } + if (!_client_subprocess_wait_check (subprocess, error)) + return FALSE; + + /* FIXME: also do on error? */ + if (!_client_register_stop (manager, error)) + return FALSE; + if (!_client_subscription_status_update (manager, error)) + return FALSE; ++ if (!_client_installed_products_update (manager, error)) ++ return FALSE; + _client_maybe__show_notification (manager); + + /* success */ + return TRUE; + } + + static gboolean + _client_register (GsdSubscriptionManager *manager, + const gchar *hostname, + const gchar *organisation, + const gchar *username, + const gchar *password, + GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + g_autoptr(GSubprocess) subprocess = NULL; + + /* fallback */ + if (organisation == NULL) + organisation = ""; + + /* apparently: "we can't send registration credentials over the regular + * system or session bus since those aren't really locked down..." */ + if (!_client_register_start (manager, error)) + return FALSE; + g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); + subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error, + "pkexec", LIBEXECDIR "/gsd-subman-helper", + "--kind", "register-with-username", + "--address", priv->address, + "--hostname", hostname, + "--organisation", organisation, + "--username", username, + "--password", password, + NULL); + if (subprocess == NULL) { + g_prefix_error (error, "failed to find pkexec: "); + return FALSE; + } + if (!_client_subprocess_wait_check (subprocess, error)) + return FALSE; + + /* FIXME: also do on error? */ + if (!_client_register_stop (manager, error)) + return FALSE; + if (!_client_subscription_status_update (manager, error)) + return FALSE; ++ if (!_client_installed_products_update (manager, error)) ++ return FALSE; + _client_maybe__show_notification (manager); + return TRUE; + } + + static gboolean + _client_unregister (GsdSubscriptionManager *manager, GError **error) + { + g_autoptr(GSubprocess) subprocess = NULL; + + /* apparently: "we can't send registration credentials over the regular + * system or session bus since those aren't really locked down..." */ + if (!_client_register_start (manager, error)) + return FALSE; + g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); + subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error, + "pkexec", LIBEXECDIR "/gsd-subman-helper", + "--kind", "unregister", + NULL); + if (subprocess == NULL) { + g_prefix_error (error, "failed to find pkexec: "); + return FALSE; + } + if (!_client_subprocess_wait_check (subprocess, error)) + return FALSE; + if (!_client_subscription_status_update (manager, error)) + return FALSE; ++ if (!_client_installed_products_update (manager, error)) ++ return FALSE; + _client_maybe__show_notification (manager); + return TRUE; + } + + static gboolean + _client_update_config (GsdSubscriptionManager *manager, GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + g_autoptr(GVariant) val = NULL; + g_autoptr(GVariant) val_server = NULL; + g_autoptr(GVariantDict) dict = NULL; + GVariantIter iter; + gchar *key; + gchar *value; + + val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_CONFIG], + "GetAll", + g_variant_new ("(s)", priv->userlang), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (val == NULL) + return FALSE; + dict = g_variant_dict_new (g_variant_get_child_value (val, 0)); + val_server = g_variant_dict_lookup_value (dict, "server", G_VARIANT_TYPE("a{ss}")); + if (val_server != NULL) { + g_variant_iter_init (&iter, val_server); + while (g_variant_iter_next (&iter, "{ss}", &key, &value)) { + g_debug ("%s=%s", key, value); + g_hash_table_insert (priv->config, + g_steal_pointer (&key), + g_steal_pointer (&value)); + } + } + return TRUE; + } + + static void + _subman_proxy_signal_cb (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters, + GsdSubscriptionManager *manager) + { + g_autoptr(GError) error = NULL; + if (!_client_syspurpose_update (manager, &error)) { + g_warning ("failed to update syspurpose: %s", error->message); + g_clear_error (&error); + } + if (!_client_subscription_status_update (manager, &error)) { + g_warning ("failed to update subscription status: %s", error->message); + g_clear_error (&error); + } ++ if (!_client_installed_products_update (manager, &error)) { ++ g_warning ("failed to update installed products: %s", error->message); ++ g_clear_error (&error); ++ } + _client_maybe__show_notification (manager); + } + + static void + _client_unload (GsdSubscriptionManager *manager) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + for (guint i = 0; i < _RHSM_INTERFACE_LAST; i++) + g_clear_object (&priv->proxies[i]); + g_hash_table_unref (priv->config); + } + + static const gchar * + _rhsm_interface_to_string (_RhsmInterface kind) + { + if (kind == _RHSM_INTERFACE_CONFIG) + return "Config"; + if (kind == _RHSM_INTERFACE_REGISTER_SERVER) + return "RegisterServer"; + if (kind == _RHSM_INTERFACE_ATTACH) + return "Attach"; + if (kind == _RHSM_INTERFACE_ENTITLEMENT) + return "Entitlement"; + if (kind == _RHSM_INTERFACE_PRODUCTS) + return "Products"; + if (kind == _RHSM_INTERFACE_CONSUMER) + return "Consumer"; + if (kind == _RHSM_INTERFACE_SYSPURPOSE) + return "Syspurpose"; + return NULL; +@@ -613,60 +741,62 @@ _client_load (GsdSubscriptionManager *manager, GError **error) + GsdSubscriptionManagerPrivate *priv = manager->priv; + + priv->config = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + /* connect to all the interfaces on the *different* objects :| */ + for (guint i = 0; i < _RHSM_INTERFACE_LAST; i++) { + const gchar *kind = _rhsm_interface_to_string (i); + g_autofree gchar *opath = g_strdup_printf ("/com/redhat/RHSM1/%s", kind); + g_autofree gchar *iface = g_strdup_printf ("com.redhat.RHSM1.%s", kind); + priv->proxies[i] = + g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "com.redhat.RHSM1", + opath, iface, + NULL, + error); + if (priv->proxies[i] == NULL) + return FALSE; + /* we want to get notified if the status of the system changes */ + g_signal_connect (priv->proxies[i], "g-signal", + G_CALLBACK (_subman_proxy_signal_cb), manager); + } + + /* get initial status */ + priv->userlang = ""; + if (!_client_update_config (manager, error)) + return FALSE; + if (!_client_subscription_status_update (manager, error)) + return FALSE; ++ if (!_client_installed_products_update (manager, error)) ++ return FALSE; + if (!_client_syspurpose_update (manager, error)) + return FALSE; + + /* success */ + return TRUE; + } + + gboolean + gsd_subscription_manager_start (GsdSubscriptionManager *manager, GError **error) + { + gboolean ret; + g_debug ("Starting subscription manager"); + gnome_settings_profile_start (NULL); + ret = _client_load (manager, error); + _client_maybe__show_notification (manager); + gnome_settings_profile_end (NULL); + return ret; + } + + void + gsd_subscription_manager_stop (GsdSubscriptionManager *manager) + { + g_debug ("Stopping subscription manager"); + _client_unload (manager); + } + + static void + gsd_subscription_manager_class_init (GsdSubscriptionManagerClass *klass) + { + GObjectClass *object_class = G_OBJECT_CLASS (klass); +@@ -676,60 +806,61 @@ gsd_subscription_manager_class_init (GsdSubscriptionManagerClass *klass) + } + + static void + _launch_info_overview (void) + { + const gchar *argv[] = { "gnome-control-center", "info-overview", NULL }; + g_debug ("Running gnome-control-center info-overview"); + g_spawn_async (NULL, (gchar **) argv, NULL, G_SPAWN_SEARCH_PATH, + NULL, NULL, NULL, NULL); + } + + static void + _notify_closed_cb (NotifyNotification *notification, gpointer user_data) + { + /* FIXME: only launch when clicking on the main body, not the window close */ + if (notify_notification_get_closed_reason (notification) == 0x400) + _launch_info_overview (); + } + + static void + _notify_clicked_cb (NotifyNotification *notification, char *action, gpointer user_data) + { + _launch_info_overview (); + } + + static void + gsd_subscription_manager_init (GsdSubscriptionManager *manager) + { + GsdSubscriptionManagerPrivate *priv = manager->priv = GSD_SUBSCRIPTION_MANAGER_GET_PRIVATE (manager); + ++ priv->installed_products = g_ptr_array_new_with_free_func ((GDestroyNotify) product_data_free); + priv->timer_last_notified = g_timer_new (); + + /* expired */ + priv->notification_expired = + notify_notification_new (_("Subscription Has Expired"), + _("Add or renew a subscription to continue receiving software updates."), + NULL); + notify_notification_set_app_name (priv->notification_expired, _("Subscription")); + notify_notification_set_hint_string (priv->notification_expired, "desktop-entry", "subman-panel"); + notify_notification_set_hint_string (priv->notification_expired, "x-gnome-privacy-scope", "system"); + notify_notification_set_urgency (priv->notification_expired, NOTIFY_URGENCY_CRITICAL); + notify_notification_add_action (priv->notification_expired, + "info-overview", _("Subscribe System…"), + _notify_clicked_cb, + manager, NULL); + g_signal_connect (priv->notification_expired, "closed", + G_CALLBACK (_notify_closed_cb), manager); + + /* registered */ + priv->notification_registered = + notify_notification_new (_("Registration Successful"), + _("The system has been registered and software updates have been enabled."), + NULL); + notify_notification_set_app_name (priv->notification_registered, _("Subscription")); + notify_notification_set_hint_string (priv->notification_registered, "desktop-entry", "subman-panel"); + notify_notification_set_hint_string (priv->notification_registered, "x-gnome-privacy-scope", "system"); + notify_notification_set_urgency (priv->notification_registered, NOTIFY_URGENCY_CRITICAL); + g_signal_connect (priv->notification_registered, "closed", + G_CALLBACK (_notify_closed_cb), manager); + +@@ -740,60 +871,61 @@ gsd_subscription_manager_init (GsdSubscriptionManager *manager) + NULL); + notify_notification_set_app_name (priv->notification_registration_required, _("Subscription")); + notify_notification_set_hint_string (priv->notification_registration_required, "desktop-entry", "subman-panel"); + notify_notification_set_hint_string (priv->notification_registration_required, "x-gnome-privacy-scope", "system"); + notify_notification_set_urgency (priv->notification_registration_required, NOTIFY_URGENCY_CRITICAL); + notify_notification_add_action (priv->notification_registration_required, + "info-overview", _("Register System…"), + _notify_clicked_cb, + manager, NULL); + g_signal_connect (priv->notification_registration_required, "closed", + G_CALLBACK (_notify_closed_cb), manager); + } + + static void + gsd_subscription_manager_finalize (GObject *object) + { + GsdSubscriptionManager *manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (GSD_IS_SUBSCRIPTION_MANAGER (object)); + + manager = GSD_SUBSCRIPTION_MANAGER (object); + + gsd_subscription_manager_stop (manager); + + if (manager->priv->bus_cancellable != NULL) { + g_cancellable_cancel (manager->priv->bus_cancellable); + g_clear_object (&manager->priv->bus_cancellable); + } + ++ g_clear_pointer (&manager->priv->installed_products, g_ptr_array_unref); + g_clear_pointer (&manager->priv->introspection_data, g_dbus_node_info_unref); + g_clear_object (&manager->priv->connection); + g_clear_object (&manager->priv->notification_expired); + g_clear_object (&manager->priv->notification_registered); + g_timer_destroy (manager->priv->timer_last_notified); + + if (manager->priv->name_id != 0) { + g_bus_unown_name (manager->priv->name_id); + manager->priv->name_id = 0; + } + + G_OBJECT_CLASS (gsd_subscription_manager_parent_class)->finalize (object); + } + + static void + handle_method_call (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *method_name, + GVariant *parameters, + GDBusMethodInvocation *invocation, + gpointer user_data) + { + GsdSubscriptionManager *manager = GSD_SUBSCRIPTION_MANAGER (user_data); + g_autoptr(GError) error = NULL; + + if (g_strcmp0 (method_name, "Register") == 0) { + const gchar *organisation = NULL; + const gchar *hostname = NULL; +@@ -857,60 +989,63 @@ handle_method_call (GDBusConnection *connection, + if (!_client_unregister (manager, &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + g_dbus_method_invocation_return_value (invocation, NULL); + } else { + g_assert_not_reached (); + } + } + + static GVariant * + handle_get_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, gpointer user_data) + { + GsdSubscriptionManager *manager = GSD_SUBSCRIPTION_MANAGER (user_data); + GsdSubscriptionManagerPrivate *priv = manager->priv; + + if (g_strcmp0 (interface_name, GSD_SUBSCRIPTION_DBUS_INTERFACE) != 0) { + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, + "No such interface: %s", interface_name); + return NULL; + } + + if (g_strcmp0 (property_name, "SubscriptionStatus") == 0) + return g_variant_new_uint32 (priv->subscription_status); + ++ if (g_strcmp0 (property_name, "InstalledProducts") == 0) ++ return _make_installed_products_variant (priv->installed_products); ++ + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, + "Failed to get property: %s", property_name); + return NULL; + } + + static gboolean + handle_set_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GVariant *value, + GError **error, gpointer user_data) + { + if (g_strcmp0 (interface_name, GSD_SUBSCRIPTION_DBUS_INTERFACE) != 0) { + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, + "No such interface: %s", interface_name); + return FALSE; + } + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, + "No such property: %s", property_name); + return FALSE; + } + + static const GDBusInterfaceVTable interface_vtable = + { + handle_method_call, + handle_get_property, + handle_set_property + }; +-- +2.30.0 + diff --git a/SOURCES/0003-subman-Increase-RHSM-dbus-call-timeouts.patch b/SOURCES/0003-subman-Increase-RHSM-dbus-call-timeouts.patch new file mode 100644 index 0000000..b8a4ea4 --- /dev/null +++ b/SOURCES/0003-subman-Increase-RHSM-dbus-call-timeouts.patch @@ -0,0 +1,313 @@ +From 0d88b2133b20957e00b0eeb0c0f48932485cc73d Mon Sep 17 00:00:00 2001 +From: Kalev Lember +Date: Fri, 28 Jun 2019 18:10:36 +0200 +Subject: [PATCH 03/15] subman: Increase RHSM dbus call timeouts + +Increase the dbus timeouts to 5 minutes as the register/unregister calls +seem to routinely take more than a minute. +--- + plugins/subman/gsd-subman-helper.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/plugins/subman/gsd-subman-helper.c b/plugins/subman/gsd-subman-helper.c +index 182f7190..af7a82e9 100644 +--- a/plugins/subman/gsd-subman-helper.c ++++ b/plugins/subman/gsd-subman-helper.c +@@ -1,60 +1,62 @@ + /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2019 Richard Hughes + * + * Licensed under the GNU General Public License Version 2 + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + #include "config.h" + + #include + #include + #include + + #include + #include + ++#define DBUS_TIMEOUT 300000 /* 5 minutes */ ++ + static void + _helper_convert_error (const gchar *json_txt, GError **error) + { + JsonNode *json_root; + JsonObject *json_obj; + const gchar *message; + g_autoptr(JsonParser) json_parser = json_parser_new (); + + /* this may be plain text or JSON :| */ + if (!json_parser_load_from_data (json_parser, json_txt, -1, NULL)) { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + json_txt); + return; + } + json_root = json_parser_get_root (json_parser); + json_obj = json_node_get_object (json_root); + if (!json_object_has_member (json_obj, "message")) { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + "no message' in %s", json_txt); + return; + } + message = json_object_get_string_member (json_obj, "message"); + if (g_strstr_len (message, -1, "Invalid user credentials") != NULL) { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_PERMISSION_DENIED, +@@ -67,125 +69,128 @@ _helper_convert_error (const gchar *json_txt, GError **error) + message); + } + + static gboolean + _helper_unregister (GError **error) + { + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GVariantBuilder) proxy_options = NULL; + g_autoptr(GVariant) res = NULL; + + g_debug ("unregistering"); + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + "com.redhat.RHSM1", + "/com/redhat/RHSM1/Unregister", + "com.redhat.RHSM1.Unregister", + NULL, error); + if (proxy == NULL) { + g_prefix_error (error, "Failed to get proxy: "); + return FALSE; + } + proxy_options = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + res = g_dbus_proxy_call_sync (proxy, + "Unregister", + g_variant_new ("(a{sv}s)", + proxy_options, + ""), /* lang */ + G_DBUS_CALL_FLAGS_NONE, +- -1, NULL, error); ++ DBUS_TIMEOUT, ++ NULL, error); + return res != NULL; + } + + static gboolean + _helper_auto_attach (GError **error) + { + const gchar *str = NULL; + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GVariantBuilder) proxy_options = NULL; + g_autoptr(GVariant) res = NULL; + + g_debug ("auto-attaching subscriptions"); + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + "com.redhat.RHSM1", + "/com/redhat/RHSM1/Attach", + "com.redhat.RHSM1.Attach", + NULL, error); + if (proxy == NULL) { + g_prefix_error (error, "Failed to get proxy: "); + return FALSE; + } + proxy_options = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + res = g_dbus_proxy_call_sync (proxy, + "AutoAttach", + g_variant_new ("(sa{sv}s)", + "", /* now? */ + proxy_options, + ""), /* lang */ + G_DBUS_CALL_FLAGS_NONE, +- -1, NULL, error); ++ DBUS_TIMEOUT, ++ NULL, error); + if (res == NULL) + return FALSE; + g_variant_get (res, "(&s)", &str); + g_debug ("Attach.AutoAttach: %s", str); + return TRUE; + } + + static gboolean + _helper_save_config (const gchar *key, const gchar *value, GError **error) + { + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GVariant) res = NULL; + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + "com.redhat.RHSM1", + "/com/redhat/RHSM1/Config", + "com.redhat.RHSM1.Config", + NULL, error); + if (proxy == NULL) { + g_prefix_error (error, "Failed to get proxy: "); + return FALSE; + } + res = g_dbus_proxy_call_sync (proxy, "Set", + g_variant_new ("(svs)", + key, + g_variant_new_string (value), + ""), /* lang */ + G_DBUS_CALL_FLAGS_NONE, +- -1, NULL, error); ++ DBUS_TIMEOUT, ++ NULL, error); + return res != NULL; + } + + int + main (int argc, char *argv[]) + { + const gchar *userlang = ""; /* as root, so no translations */ + g_autofree gchar *activation_key = NULL; + g_autofree gchar *address = NULL; + g_autofree gchar *hostname = NULL; + g_autofree gchar *kind = NULL; + g_autofree gchar *organisation = NULL; + g_autofree gchar *password = NULL; + g_autofree gchar *port = NULL; + g_autofree gchar *prefix = NULL; + g_autofree gchar *proxy_server = NULL; + g_autofree gchar *username = NULL; + g_autoptr(GDBusConnection) conn_private = NULL; + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GError) error = NULL; + g_autoptr(GOptionContext) context = g_option_context_new (NULL); + g_autoptr(GVariantBuilder) proxy_options = NULL; + g_autoptr(GVariantBuilder) subman_conopts = NULL; + g_autoptr(GVariantBuilder) subman_options = NULL; + + const GOptionEntry options[] = { + { "kind", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, + &kind, "Kind, e.g. 'username' or 'key'", NULL }, + { "address", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, + &address, "UNIX address", NULL }, +@@ -278,95 +283,97 @@ main (int argc, char *argv[]) + g_variant_builder_add (subman_conopts, "{ss}", "host", hostname); + g_variant_builder_add (subman_conopts, "{ss}", "handler", prefix); + g_variant_builder_add (subman_conopts, "{ss}", "port", port); + + /* call into RHSM */ + if (g_strcmp0 (kind, "register-with-key") == 0) { + g_auto(GStrv) activation_keys = NULL; + g_autoptr(GError) error_local = NULL; + g_autoptr(GVariant) res = NULL; + + if (activation_key == NULL) { + g_printerr ("Required --activation-key\n"); + return G_IO_ERROR_INVALID_DATA; + } + if (organisation == NULL) { + g_printerr ("Required --organisation\n"); + return G_IO_ERROR_INVALID_DATA; + } + + g_debug ("registering using activation key"); + activation_keys = g_strsplit (activation_key, ",", -1); + res = g_dbus_proxy_call_sync (proxy, + "RegisterWithActivationKeys", + g_variant_new ("(s^asa{ss}a{ss}s)", + organisation, + activation_keys, + subman_options, + subman_conopts, + userlang), + G_DBUS_CALL_FLAGS_NO_AUTO_START, +- -1, NULL, &error_local); ++ DBUS_TIMEOUT, ++ NULL, &error_local); + if (res == NULL) { + g_dbus_error_strip_remote_error (error_local); + _helper_convert_error (error_local->message, &error); + g_printerr ("Failed to RegisterWithActivationKeys: %s\n", error->message); + return error->code; + } + } else if (g_strcmp0 (kind, "register-with-username") == 0) { + g_autoptr(GError) error_local = NULL; + g_autoptr(GVariant) res = NULL; + + g_debug ("registering using username and password"); + if (username == NULL) { + g_printerr ("Required --username\n"); + return G_IO_ERROR_INVALID_DATA; + } + if (password == NULL) { + g_printerr ("Required --password\n"); + return G_IO_ERROR_INVALID_DATA; + } + if (organisation == NULL) { + g_printerr ("Required --organisation\n"); + return G_IO_ERROR_INVALID_DATA; + } + res = g_dbus_proxy_call_sync (proxy, + "Register", + g_variant_new ("(sssa{ss}a{ss}s)", + organisation, + username, + password, + subman_options, + subman_conopts, + userlang), + G_DBUS_CALL_FLAGS_NO_AUTO_START, +- -1, NULL, &error_local); ++ DBUS_TIMEOUT, ++ NULL, &error_local); + if (res == NULL) { + g_dbus_error_strip_remote_error (error_local); + _helper_convert_error (error_local->message, &error); + g_printerr ("Failed to Register: %s\n", error->message); + return error->code; + } + } else { + g_printerr ("Invalid --kind specified: %s\n", kind); + return G_IO_ERROR_INVALID_DATA; + } + + /* set the new hostname */ + if (!_helper_save_config ("server.hostname", hostname, &error)) { + g_printerr ("Failed to save hostname: %s\n", error->message); + return G_IO_ERROR_NOT_INITIALIZED; + } + if (!_helper_save_config ("server.prefix", prefix, &error)) { + g_printerr ("Failed to save prefix: %s\n", error->message); + return G_IO_ERROR_NOT_INITIALIZED; + } + if (!_helper_save_config ("server.port", port, &error)) { + g_printerr ("Failed to save port: %s\n", error->message); + return G_IO_ERROR_NOT_INITIALIZED; + } + + /* wait for rhsmd to notice the new config */ + g_usleep (G_USEC_PER_SEC * 5); + + /* auto-attach */ + if (!_helper_auto_attach (&error)) { +-- +2.30.0 + diff --git a/SOURCES/0004-subman-Drop-userlang-field.patch b/SOURCES/0004-subman-Drop-userlang-field.patch new file mode 100644 index 0000000..559be02 --- /dev/null +++ b/SOURCES/0004-subman-Drop-userlang-field.patch @@ -0,0 +1,454 @@ +From df08a65d86626ff135a12d96cff6f48f3f1864ae Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 20 Aug 2020 11:20:47 -0400 +Subject: [PATCH 04/15] subman: Drop userlang field + +It's currently always erroneously set to empty string. + +This commit drops it, and just uses "C.UTF-8" everywhere, +which is what we actually want. +--- + plugins/subman/gsd-subscription-manager.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c +index a8c18a26..46f051a5 100644 +--- a/plugins/subman/gsd-subscription-manager.c ++++ b/plugins/subman/gsd-subscription-manager.c +@@ -45,61 +45,60 @@ static const gchar introspection_xml[] = + " " + " " + " " + " " + " " + " " + ""; + + #define GSD_SUBSCRIPTION_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_SUBSCRIPTION_MANAGER, GsdSubscriptionManagerPrivate)) + + typedef enum { + _RHSM_INTERFACE_CONFIG, + _RHSM_INTERFACE_REGISTER_SERVER, + _RHSM_INTERFACE_ATTACH, + _RHSM_INTERFACE_ENTITLEMENT, + _RHSM_INTERFACE_PRODUCTS, + _RHSM_INTERFACE_CONSUMER, + _RHSM_INTERFACE_SYSPURPOSE, + _RHSM_INTERFACE_LAST + } _RhsmInterface; + + struct GsdSubscriptionManagerPrivate + { + /* D-Bus */ + guint name_id; + GDBusNodeInfo *introspection_data; + GDBusConnection *connection; + GCancellable *bus_cancellable; + + GDBusProxy *proxies[_RHSM_INTERFACE_LAST]; +- const gchar *userlang; /* owned by GLib internally */ + GHashTable *config; /* str:str */ + GPtrArray *installed_products; + gchar *address; + + GTimer *timer_last_notified; + NotifyNotification *notification_expired; + NotifyNotification *notification_registered; + NotifyNotification *notification_registration_required; + GsdSubmanSubscriptionStatus subscription_status; + GsdSubmanSubscriptionStatus subscription_status_last; + }; + + enum { + PROP_0, + }; + + static void gsd_subscription_manager_class_init (GsdSubscriptionManagerClass *klass); + static void gsd_subscription_manager_init (GsdSubscriptionManager *subscription_manager); + static void gsd_subscription_manager_finalize (GObject *object); + + G_DEFINE_TYPE (GsdSubscriptionManager, gsd_subscription_manager, G_TYPE_OBJECT) + + typedef struct + { + gchar *product_name; + gchar *product_id; + gchar *version; + gchar *arch; + gchar *status; + gchar *starts; +@@ -197,61 +196,61 @@ _emit_property_changed (GsdSubscriptionManager *manager, + property_value); + g_dbus_connection_emit_signal (priv->connection, + NULL, + GSD_SUBSCRIPTION_DBUS_PATH, + "org.freedesktop.DBus.Properties", + "PropertiesChanged", + g_variant_new ("(sa{sv}as)", + GSD_SUBSCRIPTION_DBUS_INTERFACE, + &builder, + &invalidated_builder), + NULL); + g_variant_builder_clear (&builder); + g_variant_builder_clear (&invalidated_builder); + } + + static gboolean + _client_installed_products_update (GsdSubscriptionManager *manager, GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + JsonNode *json_root; + JsonArray *json_products_array; + const gchar *json_txt = NULL; + g_autoptr(GVariant) val = NULL; + g_autoptr(JsonParser) json_parser = json_parser_new (); + + val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_PRODUCTS], + "ListInstalledProducts", + g_variant_new ("(sa{sv}s)", + "" /* filter_string */, + NULL /* proxy_options */, +- priv->userlang), ++ "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (val == NULL) + return FALSE; + g_variant_get (val, "(&s)", &json_txt); + g_debug ("Products.ListInstalledProducts JSON: %s", json_txt); + if (!json_parser_load_from_data (json_parser, json_txt, -1, error)) + return FALSE; + json_root = json_parser_get_root (json_parser); + json_products_array = json_node_get_array (json_root); + if (json_products_array == NULL) { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + "no InstalledProducts array in %s", json_txt); + return FALSE; + } + + g_ptr_array_set_size (priv->installed_products, 0); + + for (guint i = 0; i < json_array_get_length (json_products_array); i++) { + JsonArray *json_product = json_array_get_array_element (json_products_array, i); + g_autoptr(ProductData) product = g_new0 (ProductData, 1); + + if (json_product == NULL) + continue; + if (json_array_get_length (json_product) < 8) { + g_debug ("Unexpected number of array elements in InstalledProducts JSON"); + continue; + } + + product->product_name = g_strdup (json_array_get_string_element (json_product, 0)); +@@ -263,179 +262,179 @@ _client_installed_products_update (GsdSubscriptionManager *manager, GError **err + product->ends = g_strdup (json_array_get_string_element (json_product, 7)); + + g_ptr_array_add (priv->installed_products, g_steal_pointer (&product)); + } + + /* emit notification for g-c-c */ + _emit_property_changed (manager, "InstalledProducts", + _make_installed_products_variant (priv->installed_products)); + + return TRUE; + } + + static gboolean + _client_subscription_status_update (GsdSubscriptionManager *manager, GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + JsonNode *json_root; + JsonObject *json_obj; + const gchar *json_txt = NULL; + const gchar *status_txt = NULL; + g_autoptr(GVariant) val = NULL; + g_autoptr(JsonParser) json_parser = json_parser_new (); + + /* save old value */ + priv->subscription_status_last = priv->subscription_status; + + val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_ENTITLEMENT], + "GetStatus", + g_variant_new ("(ss)", + "", /* assumed as 'now' */ +- priv->userlang), ++ "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (val == NULL) + return FALSE; + g_variant_get (val, "(&s)", &json_txt); + g_debug ("Entitlement.GetStatus JSON: %s", json_txt); + if (!json_parser_load_from_data (json_parser, json_txt, -1, error)) + return FALSE; + json_root = json_parser_get_root (json_parser); + json_obj = json_node_get_object (json_root); + if (!json_object_has_member (json_obj, "status")) { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + "no Entitlement.GetStatus status in %s", json_txt); + return FALSE; + } + + status_txt = json_object_get_string_member (json_obj, "status"); + g_debug ("Entitlement.GetStatus: %s", status_txt); + priv->subscription_status = _client_subscription_status_from_text (status_txt); + + /* emit notification for g-c-c */ + if (priv->subscription_status != priv->subscription_status_last) { + _emit_property_changed (manager, "SubscriptionStatus", + g_variant_new_uint32 (priv->subscription_status)); + } + + return TRUE; + } + + static gboolean + _client_syspurpose_update (GsdSubscriptionManager *manager, GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + JsonNode *json_root; + JsonObject *json_obj; + const gchar *json_txt = NULL; + g_autoptr(GVariant) val = NULL; + g_autoptr(JsonParser) json_parser = json_parser_new (); + + val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_SYSPURPOSE], + "GetSyspurpose", +- g_variant_new ("(s)", priv->userlang), ++ g_variant_new ("(s)", "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (val == NULL) + return FALSE; + g_variant_get (val, "(&s)", &json_txt); + g_debug ("Syspurpose.GetSyspurpose JSON: %s", json_txt); + if (!json_parser_load_from_data (json_parser, json_txt, -1, error)) + return FALSE; + json_root = json_parser_get_root (json_parser); + json_obj = json_node_get_object (json_root); + if (!json_object_has_member (json_obj, "status")) { + g_debug ("Syspurpose.GetSyspurpose: Unknown"); + return TRUE; + } + g_debug ("Syspurpose.GetSyspurpose: '%s", json_object_get_string_member (json_obj, "status")); + return TRUE; + } + + static gboolean + _client_register_start (GsdSubscriptionManager *manager, GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + const gchar *address = NULL; + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GVariant) val = NULL; + + /* already started */ + if (priv->address != NULL) + return TRUE; + + /* apparently: "we can't send registration credentials over the regular + * system or session bus since those aren't really locked down..." */ + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "com.redhat.RHSM1", + "/com/redhat/RHSM1/RegisterServer", + "com.redhat.RHSM1.RegisterServer", + NULL, error); + if (proxy == NULL) + return FALSE; + val = g_dbus_proxy_call_sync (proxy, "Start", +- g_variant_new ("(s)", priv->userlang), ++ g_variant_new ("(s)", "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (val == NULL) + return FALSE; + g_variant_get (val, "(&s)", &address); + g_debug ("RegisterServer.Start: %s", address); + priv->address = g_strdup (address); + return TRUE; + } + + static gboolean + _client_register_stop (GsdSubscriptionManager *manager, GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GVariant) val = NULL; + + /* already started */ + if (priv->address == NULL) + return TRUE; + + /* stop registration server */ + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "com.redhat.RHSM1", + "/com/redhat/RHSM1/RegisterServer", + "com.redhat.RHSM1.RegisterServer", + NULL, error); + if (proxy == NULL) + return FALSE; + val = g_dbus_proxy_call_sync (proxy, "Stop", +- g_variant_new ("(s)", priv->userlang), ++ g_variant_new ("(s)", "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (val == NULL) + return FALSE; + g_clear_pointer (&priv->address, g_free); + return TRUE; + } + + static gboolean + _client_subprocess_wait_check (GSubprocess *subprocess, GError **error) + { + gint rc; + if (!g_subprocess_wait (subprocess, NULL, error)) { + g_prefix_error (error, "failed to run pkexec: "); + return FALSE; + } + rc = g_subprocess_get_exit_status (subprocess); + if (rc != 0) { + GInputStream *istream = g_subprocess_get_stderr_pipe (subprocess); + gchar buf[1024] = { 0x0 }; + gsize sz = 0; + g_input_stream_read_all (istream, buf, sizeof(buf) - 1, &sz, NULL, NULL); + if (sz == 0) { + g_set_error_literal (error, G_IO_ERROR, rc, + "Failed to run helper without stderr"); + return FALSE; + } + g_set_error_literal (error, G_IO_ERROR, rc, buf); + return FALSE; + } +@@ -637,61 +636,61 @@ _client_unregister (GsdSubscriptionManager *manager, GError **error) + "pkexec", LIBEXECDIR "/gsd-subman-helper", + "--kind", "unregister", + NULL); + if (subprocess == NULL) { + g_prefix_error (error, "failed to find pkexec: "); + return FALSE; + } + if (!_client_subprocess_wait_check (subprocess, error)) + return FALSE; + if (!_client_subscription_status_update (manager, error)) + return FALSE; + if (!_client_installed_products_update (manager, error)) + return FALSE; + _client_maybe__show_notification (manager); + return TRUE; + } + + static gboolean + _client_update_config (GsdSubscriptionManager *manager, GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + g_autoptr(GVariant) val = NULL; + g_autoptr(GVariant) val_server = NULL; + g_autoptr(GVariantDict) dict = NULL; + GVariantIter iter; + gchar *key; + gchar *value; + + val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_CONFIG], + "GetAll", +- g_variant_new ("(s)", priv->userlang), ++ g_variant_new ("(s)", "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (val == NULL) + return FALSE; + dict = g_variant_dict_new (g_variant_get_child_value (val, 0)); + val_server = g_variant_dict_lookup_value (dict, "server", G_VARIANT_TYPE("a{ss}")); + if (val_server != NULL) { + g_variant_iter_init (&iter, val_server); + while (g_variant_iter_next (&iter, "{ss}", &key, &value)) { + g_debug ("%s=%s", key, value); + g_hash_table_insert (priv->config, + g_steal_pointer (&key), + g_steal_pointer (&value)); + } + } + return TRUE; + } + + static void + _subman_proxy_signal_cb (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters, + GsdSubscriptionManager *manager) + { + g_autoptr(GError) error = NULL; + if (!_client_syspurpose_update (manager, &error)) { + g_warning ("failed to update syspurpose: %s", error->message); + g_clear_error (&error); + } +@@ -736,61 +735,60 @@ _rhsm_interface_to_string (_RhsmInterface kind) + } + + static gboolean + _client_load (GsdSubscriptionManager *manager, GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + + priv->config = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + /* connect to all the interfaces on the *different* objects :| */ + for (guint i = 0; i < _RHSM_INTERFACE_LAST; i++) { + const gchar *kind = _rhsm_interface_to_string (i); + g_autofree gchar *opath = g_strdup_printf ("/com/redhat/RHSM1/%s", kind); + g_autofree gchar *iface = g_strdup_printf ("com.redhat.RHSM1.%s", kind); + priv->proxies[i] = + g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "com.redhat.RHSM1", + opath, iface, + NULL, + error); + if (priv->proxies[i] == NULL) + return FALSE; + /* we want to get notified if the status of the system changes */ + g_signal_connect (priv->proxies[i], "g-signal", + G_CALLBACK (_subman_proxy_signal_cb), manager); + } + + /* get initial status */ +- priv->userlang = ""; + if (!_client_update_config (manager, error)) + return FALSE; + if (!_client_subscription_status_update (manager, error)) + return FALSE; + if (!_client_installed_products_update (manager, error)) + return FALSE; + if (!_client_syspurpose_update (manager, error)) + return FALSE; + + /* success */ + return TRUE; + } + + gboolean + gsd_subscription_manager_start (GsdSubscriptionManager *manager, GError **error) + { + gboolean ret; + g_debug ("Starting subscription manager"); + gnome_settings_profile_start (NULL); + ret = _client_load (manager, error); + _client_maybe__show_notification (manager); + gnome_settings_profile_end (NULL); + return ret; + } + + void + gsd_subscription_manager_stop (GsdSubscriptionManager *manager) + { + g_debug ("Stopping subscription manager"); + _client_unload (manager); +-- +2.30.0 + diff --git a/SOURCES/0005-subman-Use-user-locale-for-registration-subscription.patch b/SOURCES/0005-subman-Use-user-locale-for-registration-subscription.patch new file mode 100644 index 0000000..fa6973b --- /dev/null +++ b/SOURCES/0005-subman-Use-user-locale-for-registration-subscription.patch @@ -0,0 +1,373 @@ +From db73e2211ecc746434d78d23d801c92581fa8824 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sun, 24 Jan 2021 15:04:17 -0500 +Subject: [PATCH 05/15] subman: Use user locale for registration/subscription + operations + +This makes sure that error messages are in the correct locale. +--- + plugins/subman/gsd-subman-helper.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/plugins/subman/gsd-subman-helper.c b/plugins/subman/gsd-subman-helper.c +index af7a82e9..f84e91bf 100644 +--- a/plugins/subman/gsd-subman-helper.c ++++ b/plugins/subman/gsd-subman-helper.c +@@ -1,61 +1,63 @@ + /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2019 Richard Hughes + * + * Licensed under the GNU General Public License Version 2 + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + #include "config.h" + + #include + #include + #include ++#include + + #include + #include + + #define DBUS_TIMEOUT 300000 /* 5 minutes */ ++static const char *locale; + + static void + _helper_convert_error (const gchar *json_txt, GError **error) + { + JsonNode *json_root; + JsonObject *json_obj; + const gchar *message; + g_autoptr(JsonParser) json_parser = json_parser_new (); + + /* this may be plain text or JSON :| */ + if (!json_parser_load_from_data (json_parser, json_txt, -1, NULL)) { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + json_txt); + return; + } + json_root = json_parser_get_root (json_parser); + json_obj = json_node_get_object (json_root); + if (!json_object_has_member (json_obj, "message")) { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + "no message' in %s", json_txt); + return; + } + message = json_object_get_string_member (json_obj, "message"); + if (g_strstr_len (message, -1, "Invalid user credentials") != NULL) { + g_set_error_literal (error, + G_IO_ERROR, +@@ -67,184 +69,187 @@ _helper_convert_error (const gchar *json_txt, GError **error) + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + message); + } + + static gboolean + _helper_unregister (GError **error) + { + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GVariantBuilder) proxy_options = NULL; + g_autoptr(GVariant) res = NULL; + + g_debug ("unregistering"); + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + "com.redhat.RHSM1", + "/com/redhat/RHSM1/Unregister", + "com.redhat.RHSM1.Unregister", + NULL, error); + if (proxy == NULL) { + g_prefix_error (error, "Failed to get proxy: "); + return FALSE; + } + proxy_options = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + res = g_dbus_proxy_call_sync (proxy, + "Unregister", + g_variant_new ("(a{sv}s)", + proxy_options, +- ""), /* lang */ ++ locale), + G_DBUS_CALL_FLAGS_NONE, + DBUS_TIMEOUT, + NULL, error); + return res != NULL; + } + + static gboolean + _helper_auto_attach (GError **error) + { + const gchar *str = NULL; + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GVariantBuilder) proxy_options = NULL; + g_autoptr(GVariant) res = NULL; + + g_debug ("auto-attaching subscriptions"); + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + "com.redhat.RHSM1", + "/com/redhat/RHSM1/Attach", + "com.redhat.RHSM1.Attach", + NULL, error); + if (proxy == NULL) { + g_prefix_error (error, "Failed to get proxy: "); + return FALSE; + } + proxy_options = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + res = g_dbus_proxy_call_sync (proxy, + "AutoAttach", + g_variant_new ("(sa{sv}s)", + "", /* now? */ + proxy_options, +- ""), /* lang */ ++ locale), + G_DBUS_CALL_FLAGS_NONE, + DBUS_TIMEOUT, + NULL, error); + if (res == NULL) + return FALSE; + g_variant_get (res, "(&s)", &str); + g_debug ("Attach.AutoAttach: %s", str); + return TRUE; + } + + static gboolean + _helper_save_config (const gchar *key, const gchar *value, GError **error) + { + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GVariant) res = NULL; + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + "com.redhat.RHSM1", + "/com/redhat/RHSM1/Config", + "com.redhat.RHSM1.Config", + NULL, error); + if (proxy == NULL) { + g_prefix_error (error, "Failed to get proxy: "); + return FALSE; + } + res = g_dbus_proxy_call_sync (proxy, "Set", + g_variant_new ("(svs)", + key, + g_variant_new_string (value), +- ""), /* lang */ ++ locale), + G_DBUS_CALL_FLAGS_NONE, + DBUS_TIMEOUT, + NULL, error); + return res != NULL; + } + + int + main (int argc, char *argv[]) + { +- const gchar *userlang = ""; /* as root, so no translations */ + g_autofree gchar *activation_key = NULL; + g_autofree gchar *address = NULL; + g_autofree gchar *hostname = NULL; + g_autofree gchar *kind = NULL; + g_autofree gchar *organisation = NULL; + g_autofree gchar *password = NULL; + g_autofree gchar *port = NULL; + g_autofree gchar *prefix = NULL; + g_autofree gchar *proxy_server = NULL; + g_autofree gchar *username = NULL; + g_autoptr(GDBusConnection) conn_private = NULL; + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GError) error = NULL; + g_autoptr(GOptionContext) context = g_option_context_new (NULL); + g_autoptr(GVariantBuilder) proxy_options = NULL; + g_autoptr(GVariantBuilder) subman_conopts = NULL; + g_autoptr(GVariantBuilder) subman_options = NULL; + + const GOptionEntry options[] = { + { "kind", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, + &kind, "Kind, e.g. 'username' or 'key'", NULL }, + { "address", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, + &address, "UNIX address", NULL }, + { "username", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, + &username, "Username", NULL }, + { "password", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, + &password, "Password", NULL }, + { "organisation", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, + &organisation, "Organisation", NULL }, + { "activation-key", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, + &activation_key, "Activation keys", NULL }, + { "hostname", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, + &hostname, "Registration server hostname", NULL }, + { "prefix", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, + &prefix, "Registration server prefix", NULL }, + { "port", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, + &port, "Registration server port", NULL }, + { "proxy", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, + &proxy_server, "Proxy settings", NULL }, + { NULL} + }; + + /* check calling UID */ + if (getuid () != 0 || geteuid () != 0) { + g_printerr ("This program can only be used by the root user\n"); + return G_IO_ERROR_NOT_SUPPORTED; + } ++ ++ setlocale (LC_ALL, ""); ++ locale = setlocale (LC_MESSAGES, NULL); ++ + g_option_context_add_main_entries (context, options, NULL); + if (!g_option_context_parse (context, &argc, &argv, &error)) { + g_printerr ("Failed to parse arguments: %s\n", error->message); + return G_IO_ERROR_NOT_SUPPORTED; + } + + /* uncommon actions */ + if (kind == NULL) { + g_printerr ("No --kind specified\n"); + return G_IO_ERROR_INVALID_DATA; + } + if (g_strcmp0 (kind, "unregister") == 0) { + if (!_helper_unregister (&error)) { + g_printerr ("Failed to Unregister: %s\n", error->message); + return G_IO_ERROR_NOT_INITIALIZED; + } + return EXIT_SUCCESS; + } + if (g_strcmp0 (kind, "auto-attach") == 0) { + if (!_helper_auto_attach (&error)) { + g_printerr ("Failed to AutoAttach: %s\n", error->message); + return G_IO_ERROR_NOT_INITIALIZED; + } + return EXIT_SUCCESS; + } + + /* connect to abstract socket for reasons */ + if (address == NULL) { + g_printerr ("No --address specified\n"); + return G_IO_ERROR_INVALID_DATA; +@@ -281,96 +286,96 @@ main (int argc, char *argv[]) + port = g_strdup ("443"); + subman_conopts = g_variant_builder_new (G_VARIANT_TYPE("a{ss}")); + g_variant_builder_add (subman_conopts, "{ss}", "host", hostname); + g_variant_builder_add (subman_conopts, "{ss}", "handler", prefix); + g_variant_builder_add (subman_conopts, "{ss}", "port", port); + + /* call into RHSM */ + if (g_strcmp0 (kind, "register-with-key") == 0) { + g_auto(GStrv) activation_keys = NULL; + g_autoptr(GError) error_local = NULL; + g_autoptr(GVariant) res = NULL; + + if (activation_key == NULL) { + g_printerr ("Required --activation-key\n"); + return G_IO_ERROR_INVALID_DATA; + } + if (organisation == NULL) { + g_printerr ("Required --organisation\n"); + return G_IO_ERROR_INVALID_DATA; + } + + g_debug ("registering using activation key"); + activation_keys = g_strsplit (activation_key, ",", -1); + res = g_dbus_proxy_call_sync (proxy, + "RegisterWithActivationKeys", + g_variant_new ("(s^asa{ss}a{ss}s)", + organisation, + activation_keys, + subman_options, + subman_conopts, +- userlang), ++ locale), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + DBUS_TIMEOUT, + NULL, &error_local); + if (res == NULL) { + g_dbus_error_strip_remote_error (error_local); + _helper_convert_error (error_local->message, &error); + g_printerr ("Failed to RegisterWithActivationKeys: %s\n", error->message); + return error->code; + } + } else if (g_strcmp0 (kind, "register-with-username") == 0) { + g_autoptr(GError) error_local = NULL; + g_autoptr(GVariant) res = NULL; + + g_debug ("registering using username and password"); + if (username == NULL) { + g_printerr ("Required --username\n"); + return G_IO_ERROR_INVALID_DATA; + } + if (password == NULL) { + g_printerr ("Required --password\n"); + return G_IO_ERROR_INVALID_DATA; + } + if (organisation == NULL) { + g_printerr ("Required --organisation\n"); + return G_IO_ERROR_INVALID_DATA; + } + res = g_dbus_proxy_call_sync (proxy, + "Register", + g_variant_new ("(sssa{ss}a{ss}s)", + organisation, + username, + password, + subman_options, + subman_conopts, +- userlang), ++ locale), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + DBUS_TIMEOUT, + NULL, &error_local); + if (res == NULL) { + g_dbus_error_strip_remote_error (error_local); + _helper_convert_error (error_local->message, &error); + g_printerr ("Failed to Register: %s\n", error->message); + return error->code; + } + } else { + g_printerr ("Invalid --kind specified: %s\n", kind); + return G_IO_ERROR_INVALID_DATA; + } + + /* set the new hostname */ + if (!_helper_save_config ("server.hostname", hostname, &error)) { + g_printerr ("Failed to save hostname: %s\n", error->message); + return G_IO_ERROR_NOT_INITIALIZED; + } + if (!_helper_save_config ("server.prefix", prefix, &error)) { + g_printerr ("Failed to save prefix: %s\n", error->message); + return G_IO_ERROR_NOT_INITIALIZED; + } + if (!_helper_save_config ("server.port", port, &error)) { + g_printerr ("Failed to save port: %s\n", error->message); + return G_IO_ERROR_NOT_INITIALIZED; + } + + /* wait for rhsmd to notice the new config */ + g_usleep (G_USEC_PER_SEC * 5); +-- +2.30.0 + diff --git a/SOURCES/0006-subman-Handle-subscription-manager-giving-invalid-st.patch b/SOURCES/0006-subman-Handle-subscription-manager-giving-invalid-st.patch new file mode 100644 index 0000000..cfd9b7c --- /dev/null +++ b/SOURCES/0006-subman-Handle-subscription-manager-giving-invalid-st.patch @@ -0,0 +1,236 @@ +From f8ddd2c711cd502c74eb9d45360914fe2e6e1b3f Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 20 Aug 2020 13:34:19 -0400 +Subject: [PATCH 06/15] subman: Handle subscription-manager giving invalid + status better + +subscription-manager potentially returns status messages that the +subman plugin treats as enum values translated in some unknown +other language. It could be tied to system locale, or due to a +caching bug a previous locale used. + +This commit tries to work around that bug, by instead relying on +the GetUUID() method and valid attribute. If there's no UUID we +know the system is unregistered. If there's a UUID but the valid +attribute is FALSE we know the system is registered, but hasn't +got proper entitlements. +--- + plugins/subman/gsd-subscription-manager.c | 69 ++++++++++++----------- + 1 file changed, 36 insertions(+), 33 deletions(-) + +diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c +index 46f051a5..e2c16056 100644 +--- a/plugins/subman/gsd-subscription-manager.c ++++ b/plugins/subman/gsd-subscription-manager.c +@@ -104,77 +104,60 @@ typedef struct + gchar *starts; + gchar *ends; + } ProductData; + + static void + product_data_free (ProductData *product) + { + g_free (product->product_name); + g_free (product->product_id); + g_free (product->version); + g_free (product->arch); + g_free (product->status); + g_free (product->starts); + g_free (product->ends); + g_free (product); + } + + G_DEFINE_AUTOPTR_CLEANUP_FUNC (ProductData, product_data_free); + + static gpointer manager_object = NULL; + + GQuark + gsd_subscription_manager_error_quark (void) + { + static GQuark quark = 0; + if (!quark) + quark = g_quark_from_static_string ("gsd_subscription_manager_error"); + return quark; + } + +-static GsdSubmanSubscriptionStatus +-_client_subscription_status_from_text (const gchar *status_txt) +-{ +- if (g_strcmp0 (status_txt, "Unknown") == 0) +- return GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN; +- if (g_strcmp0 (status_txt, "Current") == 0) +- return GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID; +- if (g_strcmp0 (status_txt, "Invalid") == 0) +- return GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID; +- if (g_strcmp0 (status_txt, "Disabled") == 0) +- return GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED; +- if (g_strcmp0 (status_txt, "Insufficient") == 0) +- return GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID; +- g_warning ("Unknown subscription status: %s", status_txt); // 'Current'? +- return GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN; +-} +- + static GVariant * + _make_installed_products_variant (GPtrArray *installed_products) + { + GVariantBuilder builder; + g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}")); + + for (guint i = 0; i < installed_products->len; i++) { + ProductData *product = g_ptr_array_index (installed_products, i); + g_auto(GVariantDict) dict; + + g_variant_dict_init (&dict, NULL); + + g_variant_dict_insert (&dict, "product-name", "s", product->product_name); + g_variant_dict_insert (&dict, "product-id", "s", product->product_id); + g_variant_dict_insert (&dict, "version", "s", product->version); + g_variant_dict_insert (&dict, "arch", "s", product->arch); + g_variant_dict_insert (&dict, "status", "s", product->status); + g_variant_dict_insert (&dict, "starts", "s", product->starts); + g_variant_dict_insert (&dict, "ends", "s", product->ends); + + g_variant_builder_add_value (&builder, g_variant_dict_end (&dict)); + } + + return g_variant_builder_end (&builder); + } + + static void + _emit_property_changed (GsdSubscriptionManager *manager, + const gchar *property_name, + GVariant *property_value) +@@ -248,94 +231,114 @@ _client_installed_products_update (GsdSubscriptionManager *manager, GError **err + + if (json_product == NULL) + continue; + if (json_array_get_length (json_product) < 8) { + g_debug ("Unexpected number of array elements in InstalledProducts JSON"); + continue; + } + + product->product_name = g_strdup (json_array_get_string_element (json_product, 0)); + product->product_id = g_strdup (json_array_get_string_element (json_product, 1)); + product->version = g_strdup (json_array_get_string_element (json_product, 2)); + product->arch = g_strdup (json_array_get_string_element (json_product, 3)); + product->status = g_strdup (json_array_get_string_element (json_product, 4)); + product->starts = g_strdup (json_array_get_string_element (json_product, 6)); + product->ends = g_strdup (json_array_get_string_element (json_product, 7)); + + g_ptr_array_add (priv->installed_products, g_steal_pointer (&product)); + } + + /* emit notification for g-c-c */ + _emit_property_changed (manager, "InstalledProducts", + _make_installed_products_variant (priv->installed_products)); + + return TRUE; + } + + static gboolean + _client_subscription_status_update (GsdSubscriptionManager *manager, GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; ++ g_autoptr(GVariant) uuid = NULL; ++ const gchar *uuid_txt = NULL; + JsonNode *json_root; + JsonObject *json_obj; + const gchar *json_txt = NULL; +- const gchar *status_txt = NULL; +- g_autoptr(GVariant) val = NULL; ++ g_autoptr(GVariant) status = NULL; + g_autoptr(JsonParser) json_parser = json_parser_new (); + + /* save old value */ + priv->subscription_status_last = priv->subscription_status; + +- val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_ENTITLEMENT], +- "GetStatus", +- g_variant_new ("(ss)", +- "", /* assumed as 'now' */ +- "C.UTF-8"), +- G_DBUS_CALL_FLAGS_NONE, +- -1, NULL, error); +- if (val == NULL) ++ uuid = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_CONSUMER], ++ "GetUuid", ++ g_variant_new ("(s)", ++ "C.UTF-8"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, NULL, error); ++ if (uuid == NULL) + return FALSE; +- g_variant_get (val, "(&s)", &json_txt); ++ ++ g_variant_get (uuid, "(&s)", &uuid_txt); ++ ++ status = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_ENTITLEMENT], ++ "GetStatus", ++ g_variant_new ("(ss)", ++ "", /* assumed as 'now' */ ++ "C.UTF-8"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, NULL, error); ++ if (status == NULL) ++ return FALSE; ++ g_variant_get (status, "(&s)", &json_txt); + g_debug ("Entitlement.GetStatus JSON: %s", json_txt); + if (!json_parser_load_from_data (json_parser, json_txt, -1, error)) + return FALSE; + json_root = json_parser_get_root (json_parser); + json_obj = json_node_get_object (json_root); +- if (!json_object_has_member (json_obj, "status")) { ++ if (!json_object_has_member (json_obj, "valid")) { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, +- "no Entitlement.GetStatus status in %s", json_txt); ++ "no Entitlement.GetStatus valid in %s", json_txt); + return FALSE; + } + +- status_txt = json_object_get_string_member (json_obj, "status"); +- g_debug ("Entitlement.GetStatus: %s", status_txt); +- priv->subscription_status = _client_subscription_status_from_text (status_txt); ++ gboolean is_valid = json_object_get_boolean_member (json_obj, "valid"); ++ ++ if (uuid_txt[0] != '\0') { ++ if (is_valid) { ++ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID; ++ } else { ++ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID; ++ } ++ } else { ++ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN; ++ } + + /* emit notification for g-c-c */ + if (priv->subscription_status != priv->subscription_status_last) { + _emit_property_changed (manager, "SubscriptionStatus", + g_variant_new_uint32 (priv->subscription_status)); + } + + return TRUE; + } + + static gboolean + _client_syspurpose_update (GsdSubscriptionManager *manager, GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + JsonNode *json_root; + JsonObject *json_obj; + const gchar *json_txt = NULL; + g_autoptr(GVariant) val = NULL; + g_autoptr(JsonParser) json_parser = json_parser_new (); + + val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_SYSPURPOSE], + "GetSyspurpose", + g_variant_new ("(s)", "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (val == NULL) + return FALSE; + g_variant_get (val, "(&s)", &json_txt); + g_debug ("Syspurpose.GetSyspurpose JSON: %s", json_txt); + if (!json_parser_load_from_data (json_parser, json_txt, -1, error)) +-- +2.30.0 + diff --git a/SOURCES/0007-subman-Force-re-subscribe-if-the-admin-already-subsc.patch b/SOURCES/0007-subman-Force-re-subscribe-if-the-admin-already-subsc.patch new file mode 100644 index 0000000..73acafa --- /dev/null +++ b/SOURCES/0007-subman-Force-re-subscribe-if-the-admin-already-subsc.patch @@ -0,0 +1,260 @@ +From 477dc8accccab568002bd19caa3fbf898bc05aad Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 25 Aug 2020 10:34:03 -0400 +Subject: [PATCH 07/15] subman: Force re-subscribe if the admin already + subscribed + +It's possible for an admin to to half-enroll the system with RHN, +using the CLI tools. + +Meaning, it's possible for them to register the system with the +service, but not attach to a purchased license for the machine, +the, so called, entitlements. + +The subman module always does both halves of the registration process +in lock step. This means, if an admin tries to register using GNOME +while in a half-registered state, subman will fail because the first +step, the registration step, is already finished. + +This commit addresses that problem by trying to unregister up front +before registering. +--- + plugins/subman/gsd-subman-helper.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/plugins/subman/gsd-subman-helper.c b/plugins/subman/gsd-subman-helper.c +index f84e91bf..3931ef2e 100644 +--- a/plugins/subman/gsd-subman-helper.c ++++ b/plugins/subman/gsd-subman-helper.c +@@ -51,61 +51,60 @@ _helper_convert_error (const gchar *json_txt, GError **error) + json_root = json_parser_get_root (json_parser); + json_obj = json_node_get_object (json_root); + if (!json_object_has_member (json_obj, "message")) { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + "no message' in %s", json_txt); + return; + } + message = json_object_get_string_member (json_obj, "message"); + if (g_strstr_len (message, -1, "Invalid user credentials") != NULL) { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_PERMISSION_DENIED, + message); + return; + } + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + message); + } + + static gboolean + _helper_unregister (GError **error) + { + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GVariantBuilder) proxy_options = NULL; + g_autoptr(GVariant) res = NULL; + +- g_debug ("unregistering"); + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + "com.redhat.RHSM1", + "/com/redhat/RHSM1/Unregister", + "com.redhat.RHSM1.Unregister", + NULL, error); + if (proxy == NULL) { + g_prefix_error (error, "Failed to get proxy: "); + return FALSE; + } + proxy_options = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + res = g_dbus_proxy_call_sync (proxy, + "Unregister", + g_variant_new ("(a{sv}s)", + proxy_options, + locale), + G_DBUS_CALL_FLAGS_NONE, + DBUS_TIMEOUT, + NULL, error); + return res != NULL; + } + + static gboolean + _helper_auto_attach (GError **error) + { + const gchar *str = NULL; + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GVariantBuilder) proxy_options = NULL; +@@ -208,60 +207,61 @@ main (int argc, char *argv[]) + { "prefix", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, + &prefix, "Registration server prefix", NULL }, + { "port", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, + &port, "Registration server port", NULL }, + { "proxy", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, + &proxy_server, "Proxy settings", NULL }, + { NULL} + }; + + /* check calling UID */ + if (getuid () != 0 || geteuid () != 0) { + g_printerr ("This program can only be used by the root user\n"); + return G_IO_ERROR_NOT_SUPPORTED; + } + + setlocale (LC_ALL, ""); + locale = setlocale (LC_MESSAGES, NULL); + + g_option_context_add_main_entries (context, options, NULL); + if (!g_option_context_parse (context, &argc, &argv, &error)) { + g_printerr ("Failed to parse arguments: %s\n", error->message); + return G_IO_ERROR_NOT_SUPPORTED; + } + + /* uncommon actions */ + if (kind == NULL) { + g_printerr ("No --kind specified\n"); + return G_IO_ERROR_INVALID_DATA; + } + if (g_strcmp0 (kind, "unregister") == 0) { ++ g_debug ("unregistering"); + if (!_helper_unregister (&error)) { + g_printerr ("Failed to Unregister: %s\n", error->message); + return G_IO_ERROR_NOT_INITIALIZED; + } + return EXIT_SUCCESS; + } + if (g_strcmp0 (kind, "auto-attach") == 0) { + if (!_helper_auto_attach (&error)) { + g_printerr ("Failed to AutoAttach: %s\n", error->message); + return G_IO_ERROR_NOT_INITIALIZED; + } + return EXIT_SUCCESS; + } + + /* connect to abstract socket for reasons */ + if (address == NULL) { + g_printerr ("No --address specified\n"); + return G_IO_ERROR_INVALID_DATA; + } + conn_private = g_dbus_connection_new_for_address_sync (address, + G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT, + NULL, NULL, + &error); + if (conn_private == NULL) { + g_printerr ("Invalid --address specified: %s\n", error->message); + return G_IO_ERROR_INVALID_DATA; + } + proxy = g_dbus_proxy_new_sync (conn_private, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + NULL, /* GDBusInterfaceInfo */ +@@ -277,96 +277,103 @@ main (int argc, char *argv[]) + /* no options */ + subman_options = g_variant_builder_new (G_VARIANT_TYPE("a{ss}")); + + /* set registration server */ + if (hostname == NULL || hostname[0] == '\0') + hostname = g_strdup ("subscription.rhsm.redhat.com"); + if (prefix == NULL || prefix[0] == '\0') + prefix = g_strdup ("/subscription"); + if (port == NULL || port[0] == '\0') + port = g_strdup ("443"); + subman_conopts = g_variant_builder_new (G_VARIANT_TYPE("a{ss}")); + g_variant_builder_add (subman_conopts, "{ss}", "host", hostname); + g_variant_builder_add (subman_conopts, "{ss}", "handler", prefix); + g_variant_builder_add (subman_conopts, "{ss}", "port", port); + + /* call into RHSM */ + if (g_strcmp0 (kind, "register-with-key") == 0) { + g_auto(GStrv) activation_keys = NULL; + g_autoptr(GError) error_local = NULL; + g_autoptr(GVariant) res = NULL; + + if (activation_key == NULL) { + g_printerr ("Required --activation-key\n"); + return G_IO_ERROR_INVALID_DATA; + } + if (organisation == NULL) { + g_printerr ("Required --organisation\n"); + return G_IO_ERROR_INVALID_DATA; + } + ++ g_debug ("trying to unregister in case machine is already registered"); ++ _helper_unregister (NULL); ++ + g_debug ("registering using activation key"); + activation_keys = g_strsplit (activation_key, ",", -1); + res = g_dbus_proxy_call_sync (proxy, + "RegisterWithActivationKeys", + g_variant_new ("(s^asa{ss}a{ss}s)", + organisation, + activation_keys, + subman_options, + subman_conopts, + locale), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + DBUS_TIMEOUT, + NULL, &error_local); + if (res == NULL) { + g_dbus_error_strip_remote_error (error_local); + _helper_convert_error (error_local->message, &error); + g_printerr ("Failed to RegisterWithActivationKeys: %s\n", error->message); + return error->code; + } + } else if (g_strcmp0 (kind, "register-with-username") == 0) { + g_autoptr(GError) error_local = NULL; + g_autoptr(GVariant) res = NULL; + +- g_debug ("registering using username and password"); + if (username == NULL) { + g_printerr ("Required --username\n"); + return G_IO_ERROR_INVALID_DATA; + } + if (password == NULL) { + g_printerr ("Required --password\n"); + return G_IO_ERROR_INVALID_DATA; + } + if (organisation == NULL) { + g_printerr ("Required --organisation\n"); + return G_IO_ERROR_INVALID_DATA; + } ++ ++ g_debug ("trying to unregister in case machine is already registered"); ++ _helper_unregister (NULL); ++ ++ g_debug ("registering using username and password"); + res = g_dbus_proxy_call_sync (proxy, + "Register", + g_variant_new ("(sssa{ss}a{ss}s)", + organisation, + username, + password, + subman_options, + subman_conopts, + locale), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + DBUS_TIMEOUT, + NULL, &error_local); + if (res == NULL) { + g_dbus_error_strip_remote_error (error_local); + _helper_convert_error (error_local->message, &error); + g_printerr ("Failed to Register: %s\n", error->message); + return error->code; + } + } else { + g_printerr ("Invalid --kind specified: %s\n", kind); + return G_IO_ERROR_INVALID_DATA; + } + + /* set the new hostname */ + if (!_helper_save_config ("server.hostname", hostname, &error)) { + g_printerr ("Failed to save hostname: %s\n", error->message); + return G_IO_ERROR_NOT_INITIALIZED; + } + if (!_helper_save_config ("server.prefix", prefix, &error)) { + g_printerr ("Failed to save prefix: %s\n", error->message); +-- +2.30.0 + diff --git a/SOURCES/0008-subman-Don-t-send-secrets-through-command-line.patch b/SOURCES/0008-subman-Don-t-send-secrets-through-command-line.patch new file mode 100644 index 0000000..bd85eaf --- /dev/null +++ b/SOURCES/0008-subman-Don-t-send-secrets-through-command-line.patch @@ -0,0 +1,576 @@ +From b73800da7f384eea66b6eb67f5f40129f3dfc372 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 25 Aug 2020 16:20:42 -0400 +Subject: [PATCH 08/15] subman: Don't send secrets through command line + +The command line is introspectable with "ps", and it even gets logged +to syslog, so it's not suitable for passing secrets. + +Unfortunately, the user's password is currently passed. + +This commit addresses that problem by passing the password through +stdin, instead. +--- + plugins/subman/gsd-subman-helper.c | 32 ++++++++------ + plugins/subman/gsd-subscription-manager.c | 52 ++++++++++++++++++++--- + plugins/subman/meson.build | 2 +- + 3 files changed, 66 insertions(+), 20 deletions(-) + +diff --git a/plugins/subman/gsd-subman-helper.c b/plugins/subman/gsd-subman-helper.c +index 3931ef2e..edf1e41f 100644 +--- a/plugins/subman/gsd-subman-helper.c ++++ b/plugins/subman/gsd-subman-helper.c +@@ -1,59 +1,61 @@ + /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2019 Richard Hughes + * + * Licensed under the GNU General Public License Version 2 + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + #include "config.h" + ++ + #include + #include + #include + #include + + #include ++#include + #include + + #define DBUS_TIMEOUT 300000 /* 5 minutes */ + static const char *locale; + + static void + _helper_convert_error (const gchar *json_txt, GError **error) + { + JsonNode *json_root; + JsonObject *json_obj; + const gchar *message; + g_autoptr(JsonParser) json_parser = json_parser_new (); + + /* this may be plain text or JSON :| */ + if (!json_parser_load_from_data (json_parser, json_txt, -1, NULL)) { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + json_txt); + return; + } + json_root = json_parser_get_root (json_parser); + json_obj = json_node_get_object (json_root); + if (!json_object_has_member (json_obj, "message")) { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + "no message' in %s", json_txt); + return; + } +@@ -149,86 +151,82 @@ _helper_save_config (const gchar *key, const gchar *value, GError **error) + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + "com.redhat.RHSM1", + "/com/redhat/RHSM1/Config", + "com.redhat.RHSM1.Config", + NULL, error); + if (proxy == NULL) { + g_prefix_error (error, "Failed to get proxy: "); + return FALSE; + } + res = g_dbus_proxy_call_sync (proxy, "Set", + g_variant_new ("(svs)", + key, + g_variant_new_string (value), + locale), + G_DBUS_CALL_FLAGS_NONE, + DBUS_TIMEOUT, + NULL, error); + return res != NULL; + } + + int + main (int argc, char *argv[]) + { + g_autofree gchar *activation_key = NULL; + g_autofree gchar *address = NULL; + g_autofree gchar *hostname = NULL; + g_autofree gchar *kind = NULL; + g_autofree gchar *organisation = NULL; +- g_autofree gchar *password = NULL; + g_autofree gchar *port = NULL; + g_autofree gchar *prefix = NULL; + g_autofree gchar *proxy_server = NULL; + g_autofree gchar *username = NULL; + g_autoptr(GDBusConnection) conn_private = NULL; + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GError) error = NULL; + g_autoptr(GOptionContext) context = g_option_context_new (NULL); + g_autoptr(GVariantBuilder) proxy_options = NULL; + g_autoptr(GVariantBuilder) subman_conopts = NULL; + g_autoptr(GVariantBuilder) subman_options = NULL; ++ g_autoptr(GInputStream) standard_input_stream = g_unix_input_stream_new (STDIN_FILENO, FALSE); + + const GOptionEntry options[] = { + { "kind", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, + &kind, "Kind, e.g. 'username' or 'key'", NULL }, + { "address", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, + &address, "UNIX address", NULL }, + { "username", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, + &username, "Username", NULL }, +- { "password", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, +- &password, "Password", NULL }, + { "organisation", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, + &organisation, "Organisation", NULL }, +- { "activation-key", '\0', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, +- &activation_key, "Activation keys", NULL }, + { "hostname", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, + &hostname, "Registration server hostname", NULL }, + { "prefix", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, + &prefix, "Registration server prefix", NULL }, + { "port", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, + &port, "Registration server port", NULL }, + { "proxy", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_STRING, + &proxy_server, "Proxy settings", NULL }, + { NULL} + }; + + /* check calling UID */ + if (getuid () != 0 || geteuid () != 0) { + g_printerr ("This program can only be used by the root user\n"); + return G_IO_ERROR_NOT_SUPPORTED; + } + + setlocale (LC_ALL, ""); + locale = setlocale (LC_MESSAGES, NULL); + + g_option_context_add_main_entries (context, options, NULL); + if (!g_option_context_parse (context, &argc, &argv, &error)) { + g_printerr ("Failed to parse arguments: %s\n", error->message); + return G_IO_ERROR_NOT_SUPPORTED; + } + + /* uncommon actions */ + if (kind == NULL) { + g_printerr ("No --kind specified\n"); + return G_IO_ERROR_INVALID_DATA; +@@ -267,109 +265,117 @@ main (int argc, char *argv[]) + NULL, /* GDBusInterfaceInfo */ + NULL, /* name */ + "/com/redhat/RHSM1/Register", + "com.redhat.RHSM1.Register", + NULL, &error); + if (proxy == NULL) { + g_printerr ("Count not contact RHSM: %s\n", error->message); + return G_IO_ERROR_NOT_FOUND; + } + + /* no options */ + subman_options = g_variant_builder_new (G_VARIANT_TYPE("a{ss}")); + + /* set registration server */ + if (hostname == NULL || hostname[0] == '\0') + hostname = g_strdup ("subscription.rhsm.redhat.com"); + if (prefix == NULL || prefix[0] == '\0') + prefix = g_strdup ("/subscription"); + if (port == NULL || port[0] == '\0') + port = g_strdup ("443"); + subman_conopts = g_variant_builder_new (G_VARIANT_TYPE("a{ss}")); + g_variant_builder_add (subman_conopts, "{ss}", "host", hostname); + g_variant_builder_add (subman_conopts, "{ss}", "handler", prefix); + g_variant_builder_add (subman_conopts, "{ss}", "port", port); + + /* call into RHSM */ + if (g_strcmp0 (kind, "register-with-key") == 0) { + g_auto(GStrv) activation_keys = NULL; + g_autoptr(GError) error_local = NULL; + g_autoptr(GVariant) res = NULL; ++ gchar activation_key[PIPE_BUF + 1] = ""; + +- if (activation_key == NULL) { +- g_printerr ("Required --activation-key\n"); +- return G_IO_ERROR_INVALID_DATA; +- } + if (organisation == NULL) { + g_printerr ("Required --organisation\n"); + return G_IO_ERROR_INVALID_DATA; + } + ++ g_input_stream_read (standard_input_stream, activation_key, sizeof (activation_key) - 1, NULL, &error_local); ++ ++ if (error_local != NULL) { ++ g_printerr ("Could not read activation key: %s\n", error_local->message); ++ return G_IO_ERROR_INVALID_DATA; ++ } ++ + g_debug ("trying to unregister in case machine is already registered"); + _helper_unregister (NULL); + + g_debug ("registering using activation key"); + activation_keys = g_strsplit (activation_key, ",", -1); + res = g_dbus_proxy_call_sync (proxy, + "RegisterWithActivationKeys", + g_variant_new ("(s^asa{ss}a{ss}s)", + organisation, + activation_keys, + subman_options, + subman_conopts, + locale), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + DBUS_TIMEOUT, + NULL, &error_local); + if (res == NULL) { + g_dbus_error_strip_remote_error (error_local); + _helper_convert_error (error_local->message, &error); + g_printerr ("Failed to RegisterWithActivationKeys: %s\n", error->message); + return error->code; + } + } else if (g_strcmp0 (kind, "register-with-username") == 0) { + g_autoptr(GError) error_local = NULL; + g_autoptr(GVariant) res = NULL; ++ gchar password[PIPE_BUF + 1] = ""; + + if (username == NULL) { + g_printerr ("Required --username\n"); + return G_IO_ERROR_INVALID_DATA; + } +- if (password == NULL) { +- g_printerr ("Required --password\n"); +- return G_IO_ERROR_INVALID_DATA; +- } + if (organisation == NULL) { + g_printerr ("Required --organisation\n"); + return G_IO_ERROR_INVALID_DATA; + } + ++ g_input_stream_read (standard_input_stream, password, sizeof (password) - 1, NULL, &error_local); ++ ++ if (error_local != NULL) { ++ g_printerr ("Could not read password: %s\n", error_local->message); ++ return G_IO_ERROR_INVALID_DATA; ++ } ++ + g_debug ("trying to unregister in case machine is already registered"); + _helper_unregister (NULL); + + g_debug ("registering using username and password"); + res = g_dbus_proxy_call_sync (proxy, + "Register", + g_variant_new ("(sssa{ss}a{ss}s)", + organisation, + username, + password, + subman_options, + subman_conopts, + locale), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + DBUS_TIMEOUT, + NULL, &error_local); + if (res == NULL) { + g_dbus_error_strip_remote_error (error_local); + _helper_convert_error (error_local->message, &error); + g_printerr ("Failed to Register: %s\n", error->message); + return error->code; + } + } else { + g_printerr ("Invalid --kind specified: %s\n", kind); + return G_IO_ERROR_INVALID_DATA; + } + + /* set the new hostname */ + if (!_helper_save_config ("server.hostname", hostname, &error)) { + g_printerr ("Failed to save hostname: %s\n", error->message); +diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c +index e2c16056..0838d490 100644 +--- a/plugins/subman/gsd-subscription-manager.c ++++ b/plugins/subman/gsd-subscription-manager.c +@@ -1,53 +1,54 @@ + /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2019 Richard Hughes + * Copyright (C) 2019 Kalev Lember + * + * 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 . + * + */ + + #include "config.h" + + #include ++#include + #include + #include + #include + #include + + #include "gnome-settings-profile.h" + #include "gsd-subman-common.h" + #include "gsd-subscription-manager.h" + + #define GSD_DBUS_NAME "org.gnome.SettingsDaemon" + #define GSD_DBUS_PATH "/org/gnome/SettingsDaemon" + #define GSD_DBUS_BASE_INTERFACE "org.gnome.SettingsDaemon" + + #define GSD_SUBSCRIPTION_DBUS_NAME GSD_DBUS_NAME ".Subscription" + #define GSD_SUBSCRIPTION_DBUS_PATH GSD_DBUS_PATH "/Subscription" + #define GSD_SUBSCRIPTION_DBUS_INTERFACE GSD_DBUS_BASE_INTERFACE ".Subscription" + + static const gchar introspection_xml[] = + "" + " " + " " + " " + " " + " " + " " + " " + " " + ""; + + #define GSD_SUBSCRIPTION_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_SUBSCRIPTION_MANAGER, GsdSubscriptionManagerPrivate)) +@@ -517,129 +518,168 @@ _client_maybe__show_notification (GsdSubscriptionManager *manager) + } + } + + /* nag again */ + if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN && + g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) { + _show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED); + return; + } + if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID && + g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) { + _show_notification (manager, _NOTIFY_EXPIRED); + return; + } + if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID && + g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) { + _show_notification (manager, _NOTIFY_EXPIRED); + return; + } + } + + static gboolean + _client_register_with_keys (GsdSubscriptionManager *manager, + const gchar *hostname, + const gchar *organisation, + const gchar *activation_key, + GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + g_autoptr(GSubprocess) subprocess = NULL; ++ g_autoptr(GBytes) stdin_buf = g_bytes_new (activation_key, strlen (activation_key) + 1); ++ g_autoptr(GBytes) stderr_buf = NULL; ++ gint rc; + + /* apparently: "we can't send registration credentials over the regular + * system or session bus since those aren't really locked down..." */ + if (!_client_register_start (manager, error)) + return FALSE; + g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); +- subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error, ++ subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE, error, + "pkexec", LIBEXECDIR "/gsd-subman-helper", + "--kind", "register-with-key", + "--address", priv->address, + "--hostname", hostname, + "--organisation", organisation, +- "--activation-key", activation_key, + NULL); + if (subprocess == NULL) { + g_prefix_error (error, "failed to find pkexec: "); + return FALSE; + } +- if (!_client_subprocess_wait_check (subprocess, error)) ++ ++ if (!g_subprocess_communicate (subprocess, stdin_buf, NULL, NULL, &stderr_buf, error)) { ++ g_prefix_error (error, "failed to run pkexec: "); + return FALSE; ++ } ++ ++ rc = g_subprocess_get_exit_status (subprocess); ++ if (rc != 0) { ++ if (g_bytes_get_size (stderr_buf) == 0) { ++ g_set_error_literal (error, G_IO_ERROR, rc, ++ "Failed to run helper without stderr"); ++ return FALSE; ++ } ++ ++ g_set_error (error, G_IO_ERROR, rc, ++ "%.*s", ++ g_bytes_get_size (stderr_buf), ++ g_bytes_get_data (stderr_buf, NULL)); ++ } + + /* FIXME: also do on error? */ + if (!_client_register_stop (manager, error)) + return FALSE; + if (!_client_subscription_status_update (manager, error)) + return FALSE; + if (!_client_installed_products_update (manager, error)) + return FALSE; + _client_maybe__show_notification (manager); + + /* success */ + return TRUE; + } + + static gboolean + _client_register (GsdSubscriptionManager *manager, + const gchar *hostname, + const gchar *organisation, + const gchar *username, + const gchar *password, + GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + g_autoptr(GSubprocess) subprocess = NULL; ++ g_autoptr(GBytes) stdin_buf = g_bytes_new (password, strlen (password) + 1); ++ g_autoptr(GBytes) stderr_buf = NULL; ++ gint rc; + + /* fallback */ + if (organisation == NULL) + organisation = ""; + + /* apparently: "we can't send registration credentials over the regular + * system or session bus since those aren't really locked down..." */ + if (!_client_register_start (manager, error)) + return FALSE; + g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); +- subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error, ++ subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE, ++ error, + "pkexec", LIBEXECDIR "/gsd-subman-helper", + "--kind", "register-with-username", + "--address", priv->address, + "--hostname", hostname, + "--organisation", organisation, + "--username", username, +- "--password", password, + NULL); + if (subprocess == NULL) { + g_prefix_error (error, "failed to find pkexec: "); + return FALSE; + } +- if (!_client_subprocess_wait_check (subprocess, error)) ++ ++ if (!g_subprocess_communicate (subprocess, stdin_buf, NULL, NULL, &stderr_buf, error)) { ++ g_prefix_error (error, "failed to run pkexec: "); + return FALSE; ++ } ++ ++ rc = g_subprocess_get_exit_status (subprocess); ++ if (rc != 0) { ++ if (g_bytes_get_size (stderr_buf) == 0) { ++ g_set_error_literal (error, G_IO_ERROR, rc, ++ "Failed to run helper without stderr"); ++ return FALSE; ++ } ++ ++ g_set_error (error, G_IO_ERROR, rc, ++ "%.*s", ++ g_bytes_get_size (stderr_buf), ++ g_bytes_get_data (stderr_buf, NULL)); ++ } + + /* FIXME: also do on error? */ + if (!_client_register_stop (manager, error)) + return FALSE; + if (!_client_subscription_status_update (manager, error)) + return FALSE; + if (!_client_installed_products_update (manager, error)) + return FALSE; + _client_maybe__show_notification (manager); + return TRUE; + } + + static gboolean + _client_unregister (GsdSubscriptionManager *manager, GError **error) + { + g_autoptr(GSubprocess) subprocess = NULL; + + /* apparently: "we can't send registration credentials over the regular + * system or session bus since those aren't really locked down..." */ + if (!_client_register_start (manager, error)) + return FALSE; + g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); + subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error, + "pkexec", LIBEXECDIR "/gsd-subman-helper", + "--kind", "unregister", + NULL); + if (subprocess == NULL) { + g_prefix_error (error, "failed to find pkexec: "); + return FALSE; + } +diff --git a/plugins/subman/meson.build b/plugins/subman/meson.build +index bfd073b6..e4b4589d 100644 +--- a/plugins/subman/meson.build ++++ b/plugins/subman/meson.build +@@ -22,35 +22,35 @@ executable( + c_args: cflags, + install: true, + install_rpath: gsd_pkglibdir, + install_dir: gsd_libexecdir + ) + + # .Register needs to be called from root as subman can't do PolicyKit... + policy = 'org.gnome.settings-daemon.plugins.subman.policy' + policy_in = configure_file( + input: policy + '.in.in', + output: policy + '.in', + configuration: plugins_conf + ) + + i18n.merge_file( + policy, + input: policy_in, + output: policy, + po_dir: po_dir, + install: true, + install_dir: join_paths(gsd_datadir, 'polkit-1', 'actions') + ) + + install_data('org.gnome.settings-daemon.plugins.subman.rules', + install_dir : join_paths(gsd_datadir, 'polkit-1', 'rules.d')) + + executable( + 'gsd-subman-helper', + 'gsd-subman-helper.c', + include_directories: top_inc, +- dependencies: [gio_dep, jsonglib_dep], ++ dependencies: [gio_dep, gio_unix_dep, jsonglib_dep], + install: true, + install_rpath: gsd_pkglibdir, + install_dir: gsd_libexecdir + ) +-- +2.30.0 + diff --git a/SOURCES/0009-subman-Don-t-treat-failure-to-attach-as-fatal.patch b/SOURCES/0009-subman-Don-t-treat-failure-to-attach-as-fatal.patch new file mode 100644 index 0000000..5edb2ae --- /dev/null +++ b/SOURCES/0009-subman-Don-t-treat-failure-to-attach-as-fatal.patch @@ -0,0 +1,310 @@ +From 1255b2b83284d262f6b8c3ceb23d499ddbf77d48 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 21 Jan 2021 09:52:19 -0500 +Subject: [PATCH 09/15] subman: Don't treat failure to attach as fatal + +Many organizations don't require specific subscriptions to get +updates (called "simple content access"). At the moment, +those systems get an error when registering. + +This commit quiets the error. +--- + plugins/subman/gsd-subman-helper.c | 46 ++++++++++++++++++++++++------ + 1 file changed, 37 insertions(+), 9 deletions(-) + +diff --git a/plugins/subman/gsd-subman-helper.c b/plugins/subman/gsd-subman-helper.c +index edf1e41f..53a4d56b 100644 +--- a/plugins/subman/gsd-subman-helper.c ++++ b/plugins/subman/gsd-subman-helper.c +@@ -25,145 +25,169 @@ + #include + #include + #include + #include + + #include + #include + #include + + #define DBUS_TIMEOUT 300000 /* 5 minutes */ + static const char *locale; + + static void + _helper_convert_error (const gchar *json_txt, GError **error) + { + JsonNode *json_root; + JsonObject *json_obj; + const gchar *message; + g_autoptr(JsonParser) json_parser = json_parser_new (); + + /* this may be plain text or JSON :| */ + if (!json_parser_load_from_data (json_parser, json_txt, -1, NULL)) { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + json_txt); + return; + } + json_root = json_parser_get_root (json_parser); + json_obj = json_node_get_object (json_root); ++ if (json_object_has_member (json_obj, "severity")) { ++ const gchar *severity; ++ ++ /* warnings are non-fatal so we ignore them ++ */ ++ severity = json_object_get_string_member (json_obj, "severity"); ++ if (g_strstr_len (severity, -1, "warning") != NULL) { ++ return; ++ } ++ } ++ + if (!json_object_has_member (json_obj, "message")) { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + "no message' in %s", json_txt); + return; + } + message = json_object_get_string_member (json_obj, "message"); + if (g_strstr_len (message, -1, "Invalid user credentials") != NULL) { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_PERMISSION_DENIED, + message); + return; + } + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_NOT_SUPPORTED, + message); + } + + static gboolean + _helper_unregister (GError **error) + { + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GVariantBuilder) proxy_options = NULL; + g_autoptr(GVariant) res = NULL; + + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + "com.redhat.RHSM1", + "/com/redhat/RHSM1/Unregister", + "com.redhat.RHSM1.Unregister", + NULL, error); + if (proxy == NULL) { + g_prefix_error (error, "Failed to get proxy: "); + return FALSE; + } + proxy_options = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + res = g_dbus_proxy_call_sync (proxy, + "Unregister", + g_variant_new ("(a{sv}s)", + proxy_options, + locale), + G_DBUS_CALL_FLAGS_NONE, + DBUS_TIMEOUT, + NULL, error); + return res != NULL; + } + + static gboolean + _helper_auto_attach (GError **error) + { + const gchar *str = NULL; ++ g_autoptr(GError) error_local = NULL; + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GVariantBuilder) proxy_options = NULL; + g_autoptr(GVariant) res = NULL; + + g_debug ("auto-attaching subscriptions"); + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + "com.redhat.RHSM1", + "/com/redhat/RHSM1/Attach", + "com.redhat.RHSM1.Attach", +- NULL, error); ++ NULL, &error_local); + if (proxy == NULL) { +- g_prefix_error (error, "Failed to get proxy: "); ++ g_dbus_error_strip_remote_error (error_local); ++ g_propagate_prefixed_error (error, ++ g_steal_pointer (&error_local), ++ "Failed to get proxy: "); + return FALSE; + } + proxy_options = g_variant_builder_new (G_VARIANT_TYPE_VARDICT); + res = g_dbus_proxy_call_sync (proxy, + "AutoAttach", + g_variant_new ("(sa{sv}s)", + "", /* now? */ + proxy_options, + locale), + G_DBUS_CALL_FLAGS_NONE, + DBUS_TIMEOUT, +- NULL, error); +- if (res == NULL) +- return FALSE; ++ NULL, &error_local); ++ if (res == NULL) { ++ g_dbus_error_strip_remote_error (error_local); ++ _helper_convert_error (error_local->message, error); ++ ++ if (*error != NULL) { ++ g_prefix_error (error, "Failed to get proxy: "); ++ return FALSE; ++ } ++ ++ return TRUE; ++ } + g_variant_get (res, "(&s)", &str); + g_debug ("Attach.AutoAttach: %s", str); + return TRUE; + } + + static gboolean + _helper_save_config (const gchar *key, const gchar *value, GError **error) + { + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GVariant) res = NULL; + proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + "com.redhat.RHSM1", + "/com/redhat/RHSM1/Config", + "com.redhat.RHSM1.Config", + NULL, error); + if (proxy == NULL) { + g_prefix_error (error, "Failed to get proxy: "); + return FALSE; + } + res = g_dbus_proxy_call_sync (proxy, "Set", + g_variant_new ("(svs)", + key, + g_variant_new_string (value), + locale), + G_DBUS_CALL_FLAGS_NONE, + DBUS_TIMEOUT, + NULL, error); +@@ -298,105 +322,109 @@ main (int argc, char *argv[]) + g_printerr ("Required --organisation\n"); + return G_IO_ERROR_INVALID_DATA; + } + + g_input_stream_read (standard_input_stream, activation_key, sizeof (activation_key) - 1, NULL, &error_local); + + if (error_local != NULL) { + g_printerr ("Could not read activation key: %s\n", error_local->message); + return G_IO_ERROR_INVALID_DATA; + } + + g_debug ("trying to unregister in case machine is already registered"); + _helper_unregister (NULL); + + g_debug ("registering using activation key"); + activation_keys = g_strsplit (activation_key, ",", -1); + res = g_dbus_proxy_call_sync (proxy, + "RegisterWithActivationKeys", + g_variant_new ("(s^asa{ss}a{ss}s)", + organisation, + activation_keys, + subman_options, + subman_conopts, + locale), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + DBUS_TIMEOUT, + NULL, &error_local); + if (res == NULL) { + g_dbus_error_strip_remote_error (error_local); + _helper_convert_error (error_local->message, &error); +- g_printerr ("Failed to RegisterWithActivationKeys: %s\n", error->message); +- return error->code; ++ if (error != NULL) { ++ g_printerr ("Failed to RegisterWithActivationKeys: %s\n", error->message); ++ return error->code; ++ } + } + } else if (g_strcmp0 (kind, "register-with-username") == 0) { + g_autoptr(GError) error_local = NULL; + g_autoptr(GVariant) res = NULL; + gchar password[PIPE_BUF + 1] = ""; + + if (username == NULL) { + g_printerr ("Required --username\n"); + return G_IO_ERROR_INVALID_DATA; + } + if (organisation == NULL) { + g_printerr ("Required --organisation\n"); + return G_IO_ERROR_INVALID_DATA; + } + + g_input_stream_read (standard_input_stream, password, sizeof (password) - 1, NULL, &error_local); + + if (error_local != NULL) { + g_printerr ("Could not read password: %s\n", error_local->message); + return G_IO_ERROR_INVALID_DATA; + } + + g_debug ("trying to unregister in case machine is already registered"); + _helper_unregister (NULL); + + g_debug ("registering using username and password"); + res = g_dbus_proxy_call_sync (proxy, + "Register", + g_variant_new ("(sssa{ss}a{ss}s)", + organisation, + username, + password, + subman_options, + subman_conopts, + locale), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + DBUS_TIMEOUT, + NULL, &error_local); + if (res == NULL) { + g_dbus_error_strip_remote_error (error_local); + _helper_convert_error (error_local->message, &error); +- g_printerr ("Failed to Register: %s\n", error->message); +- return error->code; ++ if (error != NULL) { ++ g_printerr ("Failed to Register: %s\n", error->message); ++ return error->code; ++ } + } + } else { + g_printerr ("Invalid --kind specified: %s\n", kind); + return G_IO_ERROR_INVALID_DATA; + } + + /* set the new hostname */ + if (!_helper_save_config ("server.hostname", hostname, &error)) { + g_printerr ("Failed to save hostname: %s\n", error->message); + return G_IO_ERROR_NOT_INITIALIZED; + } + if (!_helper_save_config ("server.prefix", prefix, &error)) { + g_printerr ("Failed to save prefix: %s\n", error->message); + return G_IO_ERROR_NOT_INITIALIZED; + } + if (!_helper_save_config ("server.port", port, &error)) { + g_printerr ("Failed to save port: %s\n", error->message); + return G_IO_ERROR_NOT_INITIALIZED; + } + + /* wait for rhsmd to notice the new config */ + g_usleep (G_USEC_PER_SEC * 5); + + /* auto-attach */ + if (!_helper_auto_attach (&error)) { + g_printerr ("Failed to AutoAttach: %s\n", error->message); + return G_IO_ERROR_NOT_INITIALIZED; + } + + return EXIT_SUCCESS; +-- +2.30.0 + diff --git a/SOURCES/0010-subman-Add-new-no-installed-products-state.patch b/SOURCES/0010-subman-Add-new-no-installed-products-state.patch new file mode 100644 index 0000000..efe9990 --- /dev/null +++ b/SOURCES/0010-subman-Add-new-no-installed-products-state.patch @@ -0,0 +1,427 @@ +From d53c27802c69773d63d108f57912035fd3caabf9 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sun, 24 Jan 2021 11:24:36 -0500 +Subject: [PATCH 10/15] subman: Add new no-installed-products state + +It's possible, though unlikley, the system has +no packages installed from Red Hat supported package sets. + +This commit adds a new state to track that situation. +--- + plugins/subman/gsd-subman-common.c | 2 ++ + plugins/subman/gsd-subman-common.h | 1 + + plugins/subman/gsd-subscription-manager.c | 17 +++++++---------- + 3 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/plugins/subman/gsd-subman-common.c b/plugins/subman/gsd-subman-common.c +index e515131e..eef5175d 100644 +--- a/plugins/subman/gsd-subman-common.c ++++ b/plugins/subman/gsd-subman-common.c +@@ -5,32 +5,34 @@ + * 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 . + * + */ + + #include "config.h" + + #include "gsd-subman-common.h" + + const gchar * + gsd_subman_subscription_status_to_string (GsdSubmanSubscriptionStatus status) + { + if (status == GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID) + return "valid"; + if (status == GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID) + return "invalid"; + if (status == GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED) + return "disabled"; + if (status == GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID) + return "partially-valid"; ++ if (status == GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS) ++ return "no-installed-products"; + return "unknown"; + } +diff --git a/plugins/subman/gsd-subman-common.h b/plugins/subman/gsd-subman-common.h +index fccf9f6a..f8a3d9f4 100644 +--- a/plugins/subman/gsd-subman-common.h ++++ b/plugins/subman/gsd-subman-common.h +@@ -3,38 +3,39 @@ + * Copyright (C) 2019 Richard Hughes + * + * 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 . + * + */ + + #ifndef __GSD_SUBMAN_COMMON_H + #define __GSD_SUBMAN_COMMON_H + + #include + + G_BEGIN_DECLS + + typedef enum { + GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN, + GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID, + GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID, + GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED, + GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID, ++ GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS, + GSD_SUBMAN_SUBSCRIPTION_STATUS_LAST + } GsdSubmanSubscriptionStatus; + + const gchar *gsd_subman_subscription_status_to_string (GsdSubmanSubscriptionStatus status); + + G_END_DECLS + + #endif /* __GSD_SUBMAN_COMMON_H */ +diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c +index 0838d490..46f8d35c 100644 +--- a/plugins/subman/gsd-subscription-manager.c ++++ b/plugins/subman/gsd-subscription-manager.c +@@ -242,60 +242,67 @@ _client_installed_products_update (GsdSubscriptionManager *manager, GError **err + product->version = g_strdup (json_array_get_string_element (json_product, 2)); + product->arch = g_strdup (json_array_get_string_element (json_product, 3)); + product->status = g_strdup (json_array_get_string_element (json_product, 4)); + product->starts = g_strdup (json_array_get_string_element (json_product, 6)); + product->ends = g_strdup (json_array_get_string_element (json_product, 7)); + + g_ptr_array_add (priv->installed_products, g_steal_pointer (&product)); + } + + /* emit notification for g-c-c */ + _emit_property_changed (manager, "InstalledProducts", + _make_installed_products_variant (priv->installed_products)); + + return TRUE; + } + + static gboolean + _client_subscription_status_update (GsdSubscriptionManager *manager, GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + g_autoptr(GVariant) uuid = NULL; + const gchar *uuid_txt = NULL; + JsonNode *json_root; + JsonObject *json_obj; + const gchar *json_txt = NULL; + g_autoptr(GVariant) status = NULL; + g_autoptr(JsonParser) json_parser = json_parser_new (); + + /* save old value */ + priv->subscription_status_last = priv->subscription_status; ++ if (!_client_installed_products_update (manager, error)) ++ goto out; ++ ++ if (priv->installed_products->len == 0) { ++ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS; ++ goto out; ++ } + + uuid = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_CONSUMER], + "GetUuid", + g_variant_new ("(s)", + "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (uuid == NULL) + return FALSE; + + g_variant_get (uuid, "(&s)", &uuid_txt); + + status = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_ENTITLEMENT], + "GetStatus", + g_variant_new ("(ss)", + "", /* assumed as 'now' */ + "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (status == NULL) + return FALSE; + g_variant_get (status, "(&s)", &json_txt); + g_debug ("Entitlement.GetStatus JSON: %s", json_txt); + if (!json_parser_load_from_data (json_parser, json_txt, -1, error)) + return FALSE; + json_root = json_parser_get_root (json_parser); + json_obj = json_node_get_object (json_root); + if (!json_object_has_member (json_obj, "valid")) { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + "no Entitlement.GetStatus valid in %s", json_txt); +@@ -563,62 +570,60 @@ _client_register_with_keys (GsdSubscriptionManager *manager, + NULL); + if (subprocess == NULL) { + g_prefix_error (error, "failed to find pkexec: "); + return FALSE; + } + + if (!g_subprocess_communicate (subprocess, stdin_buf, NULL, NULL, &stderr_buf, error)) { + g_prefix_error (error, "failed to run pkexec: "); + return FALSE; + } + + rc = g_subprocess_get_exit_status (subprocess); + if (rc != 0) { + if (g_bytes_get_size (stderr_buf) == 0) { + g_set_error_literal (error, G_IO_ERROR, rc, + "Failed to run helper without stderr"); + return FALSE; + } + + g_set_error (error, G_IO_ERROR, rc, + "%.*s", + g_bytes_get_size (stderr_buf), + g_bytes_get_data (stderr_buf, NULL)); + } + + /* FIXME: also do on error? */ + if (!_client_register_stop (manager, error)) + return FALSE; + if (!_client_subscription_status_update (manager, error)) + return FALSE; +- if (!_client_installed_products_update (manager, error)) +- return FALSE; + _client_maybe__show_notification (manager); + + /* success */ + return TRUE; + } + + static gboolean + _client_register (GsdSubscriptionManager *manager, + const gchar *hostname, + const gchar *organisation, + const gchar *username, + const gchar *password, + GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + g_autoptr(GSubprocess) subprocess = NULL; + g_autoptr(GBytes) stdin_buf = g_bytes_new (password, strlen (password) + 1); + g_autoptr(GBytes) stderr_buf = NULL; + gint rc; + + /* fallback */ + if (organisation == NULL) + organisation = ""; + + /* apparently: "we can't send registration credentials over the regular + * system or session bus since those aren't really locked down..." */ + if (!_client_register_start (manager, error)) + return FALSE; + g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); + subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE, +@@ -632,62 +637,60 @@ _client_register (GsdSubscriptionManager *manager, + NULL); + if (subprocess == NULL) { + g_prefix_error (error, "failed to find pkexec: "); + return FALSE; + } + + if (!g_subprocess_communicate (subprocess, stdin_buf, NULL, NULL, &stderr_buf, error)) { + g_prefix_error (error, "failed to run pkexec: "); + return FALSE; + } + + rc = g_subprocess_get_exit_status (subprocess); + if (rc != 0) { + if (g_bytes_get_size (stderr_buf) == 0) { + g_set_error_literal (error, G_IO_ERROR, rc, + "Failed to run helper without stderr"); + return FALSE; + } + + g_set_error (error, G_IO_ERROR, rc, + "%.*s", + g_bytes_get_size (stderr_buf), + g_bytes_get_data (stderr_buf, NULL)); + } + + /* FIXME: also do on error? */ + if (!_client_register_stop (manager, error)) + return FALSE; + if (!_client_subscription_status_update (manager, error)) + return FALSE; +- if (!_client_installed_products_update (manager, error)) +- return FALSE; + _client_maybe__show_notification (manager); + return TRUE; + } + + static gboolean + _client_unregister (GsdSubscriptionManager *manager, GError **error) + { + g_autoptr(GSubprocess) subprocess = NULL; + + /* apparently: "we can't send registration credentials over the regular + * system or session bus since those aren't really locked down..." */ + if (!_client_register_start (manager, error)) + return FALSE; + g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); + subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error, + "pkexec", LIBEXECDIR "/gsd-subman-helper", + "--kind", "unregister", + NULL); + if (subprocess == NULL) { + g_prefix_error (error, "failed to find pkexec: "); + return FALSE; + } + if (!_client_subprocess_wait_check (subprocess, error)) + return FALSE; + if (!_client_subscription_status_update (manager, error)) + return FALSE; + if (!_client_installed_products_update (manager, error)) + return FALSE; + _client_maybe__show_notification (manager); + return TRUE; +@@ -714,64 +717,60 @@ _client_update_config (GsdSubscriptionManager *manager, GError **error) + dict = g_variant_dict_new (g_variant_get_child_value (val, 0)); + val_server = g_variant_dict_lookup_value (dict, "server", G_VARIANT_TYPE("a{ss}")); + if (val_server != NULL) { + g_variant_iter_init (&iter, val_server); + while (g_variant_iter_next (&iter, "{ss}", &key, &value)) { + g_debug ("%s=%s", key, value); + g_hash_table_insert (priv->config, + g_steal_pointer (&key), + g_steal_pointer (&value)); + } + } + return TRUE; + } + + static void + _subman_proxy_signal_cb (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters, + GsdSubscriptionManager *manager) + { + g_autoptr(GError) error = NULL; + if (!_client_syspurpose_update (manager, &error)) { + g_warning ("failed to update syspurpose: %s", error->message); + g_clear_error (&error); + } + if (!_client_subscription_status_update (manager, &error)) { + g_warning ("failed to update subscription status: %s", error->message); + g_clear_error (&error); + } +- if (!_client_installed_products_update (manager, &error)) { +- g_warning ("failed to update installed products: %s", error->message); +- g_clear_error (&error); +- } + _client_maybe__show_notification (manager); + } + + static void + _client_unload (GsdSubscriptionManager *manager) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + for (guint i = 0; i < _RHSM_INTERFACE_LAST; i++) + g_clear_object (&priv->proxies[i]); + g_hash_table_unref (priv->config); + } + + static const gchar * + _rhsm_interface_to_string (_RhsmInterface kind) + { + if (kind == _RHSM_INTERFACE_CONFIG) + return "Config"; + if (kind == _RHSM_INTERFACE_REGISTER_SERVER) + return "RegisterServer"; + if (kind == _RHSM_INTERFACE_ATTACH) + return "Attach"; + if (kind == _RHSM_INTERFACE_ENTITLEMENT) + return "Entitlement"; + if (kind == _RHSM_INTERFACE_PRODUCTS) + return "Products"; + if (kind == _RHSM_INTERFACE_CONSUMER) + return "Consumer"; + if (kind == _RHSM_INTERFACE_SYSPURPOSE) + return "Syspurpose"; + return NULL; +@@ -782,62 +781,60 @@ _client_load (GsdSubscriptionManager *manager, GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + + priv->config = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + /* connect to all the interfaces on the *different* objects :| */ + for (guint i = 0; i < _RHSM_INTERFACE_LAST; i++) { + const gchar *kind = _rhsm_interface_to_string (i); + g_autofree gchar *opath = g_strdup_printf ("/com/redhat/RHSM1/%s", kind); + g_autofree gchar *iface = g_strdup_printf ("com.redhat.RHSM1.%s", kind); + priv->proxies[i] = + g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "com.redhat.RHSM1", + opath, iface, + NULL, + error); + if (priv->proxies[i] == NULL) + return FALSE; + /* we want to get notified if the status of the system changes */ + g_signal_connect (priv->proxies[i], "g-signal", + G_CALLBACK (_subman_proxy_signal_cb), manager); + } + + /* get initial status */ + if (!_client_update_config (manager, error)) + return FALSE; + if (!_client_subscription_status_update (manager, error)) + return FALSE; +- if (!_client_installed_products_update (manager, error)) +- return FALSE; + if (!_client_syspurpose_update (manager, error)) + return FALSE; + + /* success */ + return TRUE; + } + + gboolean + gsd_subscription_manager_start (GsdSubscriptionManager *manager, GError **error) + { + gboolean ret; + g_debug ("Starting subscription manager"); + gnome_settings_profile_start (NULL); + ret = _client_load (manager, error); + _client_maybe__show_notification (manager); + gnome_settings_profile_end (NULL); + return ret; + } + + void + gsd_subscription_manager_stop (GsdSubscriptionManager *manager) + { + g_debug ("Stopping subscription manager"); + _client_unload (manager); + } + + static void + gsd_subscription_manager_class_init (GsdSubscriptionManagerClass *klass) + { + GObjectClass *object_class = G_OBJECT_CLASS (klass); +-- +2.30.0 + diff --git a/SOURCES/0011-subman-Fix-some-build-warnings.patch b/SOURCES/0011-subman-Fix-some-build-warnings.patch new file mode 100644 index 0000000..2d70f9b --- /dev/null +++ b/SOURCES/0011-subman-Fix-some-build-warnings.patch @@ -0,0 +1,146 @@ +From 432850e943d72daedb1d352a0332d3fdee6078e2 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sun, 24 Jan 2021 11:26:40 -0500 +Subject: [PATCH 11/15] subman: Fix some build warnings + +--- + plugins/subman/gsd-subscription-manager.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c +index 46f8d35c..1f9ca447 100644 +--- a/plugins/subman/gsd-subscription-manager.c ++++ b/plugins/subman/gsd-subscription-manager.c +@@ -561,62 +561,62 @@ _client_register_with_keys (GsdSubscriptionManager *manager, + if (!_client_register_start (manager, error)) + return FALSE; + g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); + subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE, error, + "pkexec", LIBEXECDIR "/gsd-subman-helper", + "--kind", "register-with-key", + "--address", priv->address, + "--hostname", hostname, + "--organisation", organisation, + NULL); + if (subprocess == NULL) { + g_prefix_error (error, "failed to find pkexec: "); + return FALSE; + } + + if (!g_subprocess_communicate (subprocess, stdin_buf, NULL, NULL, &stderr_buf, error)) { + g_prefix_error (error, "failed to run pkexec: "); + return FALSE; + } + + rc = g_subprocess_get_exit_status (subprocess); + if (rc != 0) { + if (g_bytes_get_size (stderr_buf) == 0) { + g_set_error_literal (error, G_IO_ERROR, rc, + "Failed to run helper without stderr"); + return FALSE; + } + + g_set_error (error, G_IO_ERROR, rc, + "%.*s", +- g_bytes_get_size (stderr_buf), +- g_bytes_get_data (stderr_buf, NULL)); ++ (int) g_bytes_get_size (stderr_buf), ++ (char *) g_bytes_get_data (stderr_buf, NULL)); + } + + /* FIXME: also do on error? */ + if (!_client_register_stop (manager, error)) + return FALSE; + if (!_client_subscription_status_update (manager, error)) + return FALSE; + _client_maybe__show_notification (manager); + + /* success */ + return TRUE; + } + + static gboolean + _client_register (GsdSubscriptionManager *manager, + const gchar *hostname, + const gchar *organisation, + const gchar *username, + const gchar *password, + GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + g_autoptr(GSubprocess) subprocess = NULL; + g_autoptr(GBytes) stdin_buf = g_bytes_new (password, strlen (password) + 1); + g_autoptr(GBytes) stderr_buf = NULL; + gint rc; + + /* fallback */ + if (organisation == NULL) + organisation = ""; +@@ -628,62 +628,62 @@ _client_register (GsdSubscriptionManager *manager, + g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); + subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE, + error, + "pkexec", LIBEXECDIR "/gsd-subman-helper", + "--kind", "register-with-username", + "--address", priv->address, + "--hostname", hostname, + "--organisation", organisation, + "--username", username, + NULL); + if (subprocess == NULL) { + g_prefix_error (error, "failed to find pkexec: "); + return FALSE; + } + + if (!g_subprocess_communicate (subprocess, stdin_buf, NULL, NULL, &stderr_buf, error)) { + g_prefix_error (error, "failed to run pkexec: "); + return FALSE; + } + + rc = g_subprocess_get_exit_status (subprocess); + if (rc != 0) { + if (g_bytes_get_size (stderr_buf) == 0) { + g_set_error_literal (error, G_IO_ERROR, rc, + "Failed to run helper without stderr"); + return FALSE; + } + + g_set_error (error, G_IO_ERROR, rc, + "%.*s", +- g_bytes_get_size (stderr_buf), +- g_bytes_get_data (stderr_buf, NULL)); ++ (int) g_bytes_get_size (stderr_buf), ++ (char *) g_bytes_get_data (stderr_buf, NULL)); + } + + /* FIXME: also do on error? */ + if (!_client_register_stop (manager, error)) + return FALSE; + if (!_client_subscription_status_update (manager, error)) + return FALSE; + _client_maybe__show_notification (manager); + return TRUE; + } + + static gboolean + _client_unregister (GsdSubscriptionManager *manager, GError **error) + { + g_autoptr(GSubprocess) subprocess = NULL; + + /* apparently: "we can't send registration credentials over the regular + * system or session bus since those aren't really locked down..." */ + if (!_client_register_start (manager, error)) + return FALSE; + g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); + subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error, + "pkexec", LIBEXECDIR "/gsd-subman-helper", + "--kind", "unregister", + NULL); + if (subprocess == NULL) { + g_prefix_error (error, "failed to find pkexec: "); + return FALSE; + } + if (!_client_subprocess_wait_check (subprocess, error)) +-- +2.30.0 + diff --git a/SOURCES/0012-subman-Add-DBus-API-to-subscribe-for-updates-on-alre.patch b/SOURCES/0012-subman-Add-DBus-API-to-subscribe-for-updates-on-alre.patch new file mode 100644 index 0000000..30758fb --- /dev/null +++ b/SOURCES/0012-subman-Add-DBus-API-to-subscribe-for-updates-on-alre.patch @@ -0,0 +1,259 @@ +From 3bb3b2b09d34deafadd3cfe3355137afab20cb23 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sun, 24 Jan 2021 11:27:42 -0500 +Subject: [PATCH 12/15] subman: Add DBus API to subscribe for updates on + already registered system + +It's possible an admin may have registered their system without +attaching any subscriptions to it. + +At the moment, gnome-settings-daemon only provides a way to register +and subscribe in one step. + +This commit adds an API to support doing the last half of the process +on its own. +--- + plugins/subman/gsd-subscription-manager.c | 51 +++++++++++++++++++++++ + 1 file changed, 51 insertions(+) + +diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c +index 1f9ca447..705f8b11 100644 +--- a/plugins/subman/gsd-subscription-manager.c ++++ b/plugins/subman/gsd-subscription-manager.c +@@ -19,60 +19,61 @@ + */ + + #include "config.h" + + #include + #include + #include + #include + #include + #include + + #include "gnome-settings-profile.h" + #include "gsd-subman-common.h" + #include "gsd-subscription-manager.h" + + #define GSD_DBUS_NAME "org.gnome.SettingsDaemon" + #define GSD_DBUS_PATH "/org/gnome/SettingsDaemon" + #define GSD_DBUS_BASE_INTERFACE "org.gnome.SettingsDaemon" + + #define GSD_SUBSCRIPTION_DBUS_NAME GSD_DBUS_NAME ".Subscription" + #define GSD_SUBSCRIPTION_DBUS_PATH GSD_DBUS_PATH "/Subscription" + #define GSD_SUBSCRIPTION_DBUS_INTERFACE GSD_DBUS_BASE_INTERFACE ".Subscription" + + static const gchar introspection_xml[] = + "" + " " + " " + " " + " " + " " ++" " + " " + " " + " " + ""; + + #define GSD_SUBSCRIPTION_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSD_TYPE_SUBSCRIPTION_MANAGER, GsdSubscriptionManagerPrivate)) + + typedef enum { + _RHSM_INTERFACE_CONFIG, + _RHSM_INTERFACE_REGISTER_SERVER, + _RHSM_INTERFACE_ATTACH, + _RHSM_INTERFACE_ENTITLEMENT, + _RHSM_INTERFACE_PRODUCTS, + _RHSM_INTERFACE_CONSUMER, + _RHSM_INTERFACE_SYSPURPOSE, + _RHSM_INTERFACE_LAST + } _RhsmInterface; + + struct GsdSubscriptionManagerPrivate + { + /* D-Bus */ + guint name_id; + GDBusNodeInfo *introspection_data; + GDBusConnection *connection; + GCancellable *bus_cancellable; + + GDBusProxy *proxies[_RHSM_INTERFACE_LAST]; + GHashTable *config; /* str:str */ + GPtrArray *installed_products; + gchar *address; +@@ -669,60 +670,104 @@ _client_register (GsdSubscriptionManager *manager, + } + + static gboolean + _client_unregister (GsdSubscriptionManager *manager, GError **error) + { + g_autoptr(GSubprocess) subprocess = NULL; + + /* apparently: "we can't send registration credentials over the regular + * system or session bus since those aren't really locked down..." */ + if (!_client_register_start (manager, error)) + return FALSE; + g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); + subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, error, + "pkexec", LIBEXECDIR "/gsd-subman-helper", + "--kind", "unregister", + NULL); + if (subprocess == NULL) { + g_prefix_error (error, "failed to find pkexec: "); + return FALSE; + } + if (!_client_subprocess_wait_check (subprocess, error)) + return FALSE; + if (!_client_subscription_status_update (manager, error)) + return FALSE; + if (!_client_installed_products_update (manager, error)) + return FALSE; + _client_maybe__show_notification (manager); + return TRUE; + } + ++static gboolean ++_client_attach (GsdSubscriptionManager *manager, ++ GError **error) ++{ ++ g_autoptr(GSubprocess) subprocess = NULL; ++ g_autoptr(GBytes) stderr_buf = NULL; ++ gint rc; ++ ++ g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); ++ subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDERR_PIPE, ++ error, ++ "pkexec", LIBEXECDIR "/gsd-subman-helper", ++ "--kind", "auto-attach", ++ NULL); ++ if (subprocess == NULL) { ++ g_prefix_error (error, "failed to find pkexec: "); ++ return FALSE; ++ } ++ ++ if (!g_subprocess_communicate (subprocess, NULL, NULL, NULL, &stderr_buf, error)) { ++ g_prefix_error (error, "failed to run pkexec: "); ++ return FALSE; ++ } ++ ++ rc = g_subprocess_get_exit_status (subprocess); ++ if (rc != 0) { ++ if (g_bytes_get_size (stderr_buf) == 0) { ++ g_set_error_literal (error, G_IO_ERROR, rc, ++ "Failed to run helper without stderr"); ++ return FALSE; ++ } ++ ++ g_set_error (error, G_IO_ERROR, rc, ++ "%.*s", ++ (int) g_bytes_get_size (stderr_buf), ++ (char *) g_bytes_get_data (stderr_buf, NULL)); ++ } ++ ++ if (!_client_subscription_status_update (manager, error)) ++ return FALSE; ++ _client_maybe__show_notification (manager); ++ return TRUE; ++} ++ + static gboolean + _client_update_config (GsdSubscriptionManager *manager, GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + g_autoptr(GVariant) val = NULL; + g_autoptr(GVariant) val_server = NULL; + g_autoptr(GVariantDict) dict = NULL; + GVariantIter iter; + gchar *key; + gchar *value; + + val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_CONFIG], + "GetAll", + g_variant_new ("(s)", "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (val == NULL) + return FALSE; + dict = g_variant_dict_new (g_variant_get_child_value (val, 0)); + val_server = g_variant_dict_lookup_value (dict, "server", G_VARIANT_TYPE("a{ss}")); + if (val_server != NULL) { + g_variant_iter_init (&iter, val_server); + while (g_variant_iter_next (&iter, "{ss}", &key, &value)) { + g_debug ("%s=%s", key, value); + g_hash_table_insert (priv->config, + g_steal_pointer (&key), + g_steal_pointer (&value)); + } + } + return TRUE; +@@ -1002,60 +1047,66 @@ handle_method_call (GDBusConnection *connection, + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + } else if (g_strcmp0 (kind, "key") == 0) { + const gchar *activation_key = NULL; + g_variant_dict_lookup (dict, "hostname", "&s", &hostname); + g_variant_dict_lookup (dict, "organisation", "&s", &organisation); + g_variant_dict_lookup (dict, "activation-key", "&s", &activation_key); + if (!_client_register_with_keys (manager, + hostname, + organisation, + activation_key, + &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + } else { + g_dbus_method_invocation_return_error_literal (invocation, + G_IO_ERROR, G_IO_ERROR_FAILED, + "Invalid kind specified"); + + return; + } + g_dbus_method_invocation_return_value (invocation, NULL); + } else if (g_strcmp0 (method_name, "Unregister") == 0) { + if (!_client_unregister (manager, &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); + return; + } + g_dbus_method_invocation_return_value (invocation, NULL); ++ } else if (g_strcmp0 (method_name, "Attach") == 0) { ++ if (!_client_attach (manager, &error)) { ++ g_dbus_method_invocation_return_gerror (invocation, error); ++ return; ++ } ++ g_dbus_method_invocation_return_value (invocation, NULL); + } else { + g_assert_not_reached (); + } + } + + static GVariant * + handle_get_property (GDBusConnection *connection, + const gchar *sender, + const gchar *object_path, + const gchar *interface_name, + const gchar *property_name, + GError **error, gpointer user_data) + { + GsdSubscriptionManager *manager = GSD_SUBSCRIPTION_MANAGER (user_data); + GsdSubscriptionManagerPrivate *priv = manager->priv; + + if (g_strcmp0 (interface_name, GSD_SUBSCRIPTION_DBUS_INTERFACE) != 0) { + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, + "No such interface: %s", interface_name); + return NULL; + } + + if (g_strcmp0 (property_name, "SubscriptionStatus") == 0) + return g_variant_new_uint32 (priv->subscription_status); + + if (g_strcmp0 (property_name, "InstalledProducts") == 0) + return _make_installed_products_variant (priv->installed_products); + + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, + "Failed to get property: %s", property_name); +-- +2.30.0 + diff --git a/SOURCES/0013-subman-Improve-subscription-status-handling.patch b/SOURCES/0013-subman-Improve-subscription-status-handling.patch new file mode 100644 index 0000000..40d6c68 --- /dev/null +++ b/SOURCES/0013-subman-Improve-subscription-status-handling.patch @@ -0,0 +1,141 @@ +From d9eb6331efa92cd28a8ba3ccc1665c3744296465 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sun, 24 Jan 2021 11:34:03 -0500 +Subject: [PATCH 13/15] subman: Improve subscription status handling + +This commit improves how subscription-manager status is +parsed to give more detailed information about subscription +state. +--- + plugins/subman/gsd-subscription-manager.c | 33 +++++++++++++++++++---- + 1 file changed, 28 insertions(+), 5 deletions(-) + +diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c +index 705f8b11..6d80bfa9 100644 +--- a/plugins/subman/gsd-subscription-manager.c ++++ b/plugins/subman/gsd-subscription-manager.c +@@ -262,93 +262,116 @@ _client_subscription_status_update (GsdSubscriptionManager *manager, GError **er + GsdSubscriptionManagerPrivate *priv = manager->priv; + g_autoptr(GVariant) uuid = NULL; + const gchar *uuid_txt = NULL; + JsonNode *json_root; + JsonObject *json_obj; + const gchar *json_txt = NULL; + g_autoptr(GVariant) status = NULL; + g_autoptr(JsonParser) json_parser = json_parser_new (); + + /* save old value */ + priv->subscription_status_last = priv->subscription_status; + if (!_client_installed_products_update (manager, error)) + goto out; + + if (priv->installed_products->len == 0) { + priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS; + goto out; + } + + uuid = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_CONSUMER], + "GetUuid", + g_variant_new ("(s)", + "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (uuid == NULL) + return FALSE; + + g_variant_get (uuid, "(&s)", &uuid_txt); + ++ if (uuid_txt[0] == '\0') { ++ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN; ++ goto out; ++ } ++ + status = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_ENTITLEMENT], + "GetStatus", + g_variant_new ("(ss)", + "", /* assumed as 'now' */ + "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (status == NULL) + return FALSE; + g_variant_get (status, "(&s)", &json_txt); + g_debug ("Entitlement.GetStatus JSON: %s", json_txt); + if (!json_parser_load_from_data (json_parser, json_txt, -1, error)) + return FALSE; + json_root = json_parser_get_root (json_parser); + json_obj = json_node_get_object (json_root); ++ ++ const gchar *status_id = NULL; ++ ++ if (json_object_has_member (json_obj, "status_id")) { ++ status_id = json_object_get_string_member (json_obj, "status_id"); ++ } ++ + if (!json_object_has_member (json_obj, "valid")) { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, + "no Entitlement.GetStatus valid in %s", json_txt); + return FALSE; + } + + gboolean is_valid = json_object_get_boolean_member (json_obj, "valid"); + +- if (uuid_txt[0] != '\0') { +- if (is_valid) { ++ if (is_valid) { ++ if (g_strcmp0 (status_id, "disabled") != 0) { + priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID; + } else { +- priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID; ++ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED; ++ } ++ goto out; ++ } ++ ++ for (guint i = 0; i < priv->installed_products->len; i++) { ++ ProductData *product = g_ptr_array_index (priv->installed_products, i); ++ ++ if (g_strcmp0 (product->status, "subscribed") == 0) { ++ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID; ++ goto out; + } +- } else { +- priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN; + } + ++ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID; ++ ++out: + /* emit notification for g-c-c */ + if (priv->subscription_status != priv->subscription_status_last) { + _emit_property_changed (manager, "SubscriptionStatus", + g_variant_new_uint32 (priv->subscription_status)); + } + + return TRUE; + } + + static gboolean + _client_syspurpose_update (GsdSubscriptionManager *manager, GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + JsonNode *json_root; + JsonObject *json_obj; + const gchar *json_txt = NULL; + g_autoptr(GVariant) val = NULL; + g_autoptr(JsonParser) json_parser = json_parser_new (); + + val = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_SYSPURPOSE], + "GetSyspurpose", + g_variant_new ("(s)", "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (val == NULL) + return FALSE; + g_variant_get (val, "(&s)", &json_txt); + g_debug ("Syspurpose.GetSyspurpose JSON: %s", json_txt); + if (!json_parser_load_from_data (json_parser, json_txt, -1, error)) + return FALSE; +-- +2.30.0 + diff --git a/SOURCES/0014-subman-Drop-LAST-from-status-enum.patch b/SOURCES/0014-subman-Drop-LAST-from-status-enum.patch new file mode 100644 index 0000000..4f5c99e --- /dev/null +++ b/SOURCES/0014-subman-Drop-LAST-from-status-enum.patch @@ -0,0 +1,56 @@ +From a78b25b9507edb958a46779f2bb808bf678fa4a7 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sun, 24 Jan 2021 11:55:19 -0500 +Subject: [PATCH 14/15] subman: Drop "LAST" from status enum + +It's unused, so get rid of it. +--- + plugins/subman/gsd-subman-common.h | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/plugins/subman/gsd-subman-common.h b/plugins/subman/gsd-subman-common.h +index f8a3d9f4..88226564 100644 +--- a/plugins/subman/gsd-subman-common.h ++++ b/plugins/subman/gsd-subman-common.h +@@ -4,38 +4,37 @@ + * + * 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 . + * + */ + + #ifndef __GSD_SUBMAN_COMMON_H + #define __GSD_SUBMAN_COMMON_H + + #include + + G_BEGIN_DECLS + + typedef enum { + GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN, + GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID, + GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID, + GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED, + GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID, + GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS, +- GSD_SUBMAN_SUBSCRIPTION_STATUS_LAST + } GsdSubmanSubscriptionStatus; + + const gchar *gsd_subman_subscription_status_to_string (GsdSubmanSubscriptionStatus status); + + G_END_DECLS + + #endif /* __GSD_SUBMAN_COMMON_H */ +-- +2.30.0 + diff --git a/SOURCES/0015-subman-Clean-up-notification-behavior.patch b/SOURCES/0015-subman-Clean-up-notification-behavior.patch new file mode 100644 index 0000000..96585cd --- /dev/null +++ b/SOURCES/0015-subman-Clean-up-notification-behavior.patch @@ -0,0 +1,419 @@ +From 3412be1f63df2a5967ef92c27028368df1646b5c Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sun, 24 Jan 2021 12:41:20 -0500 +Subject: [PATCH 15/15] subman: Clean up notification behavior + +Notifications were only displayed for some status transitions. + +This commit introduces some booleans based on the old and new +statuses to make the code clearer and to make it easier to hit +all the cases. +--- + plugins/subman/gsd-subman-common.h | 1 + + plugins/subman/gsd-subscription-manager.c | 141 ++++++++++++++++++---- + 2 files changed, 120 insertions(+), 22 deletions(-) + +diff --git a/plugins/subman/gsd-subman-common.h b/plugins/subman/gsd-subman-common.h +index 88226564..9397dbe4 100644 +--- a/plugins/subman/gsd-subman-common.h ++++ b/plugins/subman/gsd-subman-common.h +@@ -1,40 +1,41 @@ + /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2019 Richard Hughes + * + * 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 . + * + */ + + #ifndef __GSD_SUBMAN_COMMON_H + #define __GSD_SUBMAN_COMMON_H + + #include + + G_BEGIN_DECLS + + typedef enum { ++ GSD_SUBMAN_SUBSCRIPTION_STATUS_NOT_READ = -1, + GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN, + GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID, + GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID, + GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED, + GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID, + GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS, + } GsdSubmanSubscriptionStatus; + + const gchar *gsd_subman_subscription_status_to_string (GsdSubmanSubscriptionStatus status); + + G_END_DECLS + + #endif /* __GSD_SUBMAN_COMMON_H */ +diff --git a/plugins/subman/gsd-subscription-manager.c b/plugins/subman/gsd-subscription-manager.c +index 6d80bfa9..aaccbbc6 100644 +--- a/plugins/subman/gsd-subscription-manager.c ++++ b/plugins/subman/gsd-subscription-manager.c +@@ -243,60 +243,61 @@ _client_installed_products_update (GsdSubscriptionManager *manager, GError **err + product->version = g_strdup (json_array_get_string_element (json_product, 2)); + product->arch = g_strdup (json_array_get_string_element (json_product, 3)); + product->status = g_strdup (json_array_get_string_element (json_product, 4)); + product->starts = g_strdup (json_array_get_string_element (json_product, 6)); + product->ends = g_strdup (json_array_get_string_element (json_product, 7)); + + g_ptr_array_add (priv->installed_products, g_steal_pointer (&product)); + } + + /* emit notification for g-c-c */ + _emit_property_changed (manager, "InstalledProducts", + _make_installed_products_variant (priv->installed_products)); + + return TRUE; + } + + static gboolean + _client_subscription_status_update (GsdSubscriptionManager *manager, GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + g_autoptr(GVariant) uuid = NULL; + const gchar *uuid_txt = NULL; + JsonNode *json_root; + JsonObject *json_obj; + const gchar *json_txt = NULL; + g_autoptr(GVariant) status = NULL; + g_autoptr(JsonParser) json_parser = json_parser_new (); + + /* save old value */ + priv->subscription_status_last = priv->subscription_status; ++ + if (!_client_installed_products_update (manager, error)) + goto out; + + if (priv->installed_products->len == 0) { + priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS; + goto out; + } + + uuid = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_CONSUMER], + "GetUuid", + g_variant_new ("(s)", + "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, error); + if (uuid == NULL) + return FALSE; + + g_variant_get (uuid, "(&s)", &uuid_txt); + + if (uuid_txt[0] == '\0') { + priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN; + goto out; + } + + status = g_dbus_proxy_call_sync (priv->proxies[_RHSM_INTERFACE_ENTITLEMENT], + "GetStatus", + g_variant_new ("(ss)", + "", /* assumed as 'now' */ + "C.UTF-8"), + G_DBUS_CALL_FLAGS_NONE, +@@ -485,109 +486,203 @@ typedef enum { + static void + _show_notification (GsdSubscriptionManager *manager, _NotifyKind notify_kind) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + switch (notify_kind) { + case _NOTIFY_EXPIRED: + notify_notification_close (priv->notification_registered, NULL); + notify_notification_close (priv->notification_registration_required, NULL); + notify_notification_show (priv->notification_expired, NULL); + break; + case _NOTIFY_REGISTRATION_REQUIRED: + notify_notification_close (priv->notification_registered, NULL); + notify_notification_close (priv->notification_expired, NULL); + notify_notification_show (priv->notification_registration_required, NULL); + break; + case _NOTIFY_REGISTERED: + notify_notification_close (priv->notification_expired, NULL); + notify_notification_close (priv->notification_registration_required, NULL); + notify_notification_show (priv->notification_registered, NULL); + break; + default: + break; + } + g_timer_reset (priv->timer_last_notified); + } + + static void + _client_maybe__show_notification (GsdSubscriptionManager *manager) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; ++ gboolean was_read, was_registered, had_subscriptions, needed_subscriptions; ++ gboolean is_read, is_registered, has_subscriptions, needs_subscriptions; ++ ++ switch (priv->subscription_status_last) { ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_NOT_READ: ++ was_read = FALSE; ++ was_registered = FALSE; ++ needed_subscriptions = TRUE; ++ had_subscriptions = FALSE; ++ break; ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN: ++ was_read = TRUE; ++ was_registered = FALSE; ++ needed_subscriptions = TRUE; ++ had_subscriptions = FALSE; ++ break; ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID: ++ was_read = TRUE; ++ was_registered = TRUE; ++ needed_subscriptions = TRUE; ++ had_subscriptions = TRUE; ++ break; ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID: ++ was_read = TRUE; ++ was_registered = TRUE; ++ needed_subscriptions = TRUE; ++ had_subscriptions = FALSE; ++ break; ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED: ++ was_read = TRUE; ++ was_registered = TRUE; ++ needed_subscriptions = FALSE; ++ had_subscriptions = FALSE; ++ break; ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID: ++ was_read = TRUE; ++ was_registered = TRUE; ++ needed_subscriptions = TRUE; ++ had_subscriptions = FALSE; ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS: ++ was_read = TRUE; ++ was_registered = FALSE; ++ needed_subscriptions = FALSE; ++ had_subscriptions = FALSE; ++ break; ++ } ++ ++ switch (priv->subscription_status) { ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_NOT_READ: ++ is_read = FALSE; ++ is_registered = FALSE; ++ needs_subscriptions = TRUE; ++ has_subscriptions = FALSE; ++ break; ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN: ++ is_read = TRUE; ++ is_registered = FALSE; ++ needs_subscriptions = TRUE; ++ has_subscriptions = FALSE; ++ break; ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID: ++ is_read = TRUE; ++ is_registered = TRUE; ++ needs_subscriptions = TRUE; ++ has_subscriptions = TRUE; ++ break; ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID: ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID: ++ is_read = TRUE; ++ is_registered = TRUE; ++ needs_subscriptions = TRUE; ++ has_subscriptions = FALSE; ++ break; ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_DISABLED: ++ is_read = TRUE; ++ is_registered = TRUE; ++ needs_subscriptions = FALSE; ++ has_subscriptions = FALSE; ++ break; ++ case GSD_SUBMAN_SUBSCRIPTION_STATUS_NO_INSTALLED_PRODUCTS: ++ is_read = TRUE; ++ is_registered = FALSE; ++ needs_subscriptions = FALSE; ++ has_subscriptions = FALSE; ++ break; ++ } + + /* startup */ +- if (priv->subscription_status_last == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN && +- priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN) { ++ if (!was_read && is_read && priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN) { + _show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED); + return; + } + + /* something changed */ +- if (priv->subscription_status_last != priv->subscription_status) { ++ if (was_read && is_read && priv->subscription_status_last != priv->subscription_status) { + g_debug ("transisition from subscription status '%s' to '%s'", + gsd_subman_subscription_status_to_string (priv->subscription_status_last), + gsd_subman_subscription_status_to_string (priv->subscription_status)); + +- /* needs registration */ +- if (priv->subscription_status_last == GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID && +- priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID) { +- _show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED); ++ /* needs subscription */ ++ if (is_registered && needs_subscriptions && !has_subscriptions) { ++ _show_notification (manager, _NOTIFY_EXPIRED); + return; + } + + /* was unregistered */ +- if (priv->subscription_status_last == GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID && +- priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN) { ++ if (was_registered && !is_registered) { + _show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED); + return; + } + +- /* registered */ +- if (priv->subscription_status_last == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN && +- priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_VALID && +- g_timer_elapsed (priv->timer_last_notified, NULL) > 60) { +- _show_notification (manager, _NOTIFY_REGISTERED); +- return; ++ /* just registered */ ++ if (!was_registered && is_registered) { ++ if (!needs_subscriptions || has_subscriptions) { ++ _show_notification (manager, _NOTIFY_REGISTERED); ++ return; ++ } ++ } ++ ++ /* subscriptions changed */ ++ if (was_registered && is_registered) { ++ /* subscribed */ ++ if (!had_subscriptions && ++ needs_subscriptions && has_subscriptions) { ++ _show_notification (manager, _NOTIFY_REGISTERED); ++ return; ++ } ++ ++ /* simple content access enabled */ ++ if (needed_subscriptions && !had_subscriptions && !needs_subscriptions) { ++ _show_notification (manager, _NOTIFY_REGISTERED); ++ return; ++ } + } + } + + /* nag again */ +- if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_UNKNOWN && ++ if (!is_registered && + g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) { + _show_notification (manager, _NOTIFY_REGISTRATION_REQUIRED); + return; + } +- if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_INVALID && +- g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) { +- _show_notification (manager, _NOTIFY_EXPIRED); +- return; +- } +- if (priv->subscription_status == GSD_SUBMAN_SUBSCRIPTION_STATUS_PARTIALLY_VALID && ++ if (is_registered && !has_subscriptions && needs_subscriptions && + g_timer_elapsed (priv->timer_last_notified, NULL) > 60 * 60 * 24) { + _show_notification (manager, _NOTIFY_EXPIRED); + return; + } + } + + static gboolean + _client_register_with_keys (GsdSubscriptionManager *manager, + const gchar *hostname, + const gchar *organisation, + const gchar *activation_key, + GError **error) + { + GsdSubscriptionManagerPrivate *priv = manager->priv; + g_autoptr(GSubprocess) subprocess = NULL; + g_autoptr(GBytes) stdin_buf = g_bytes_new (activation_key, strlen (activation_key) + 1); + g_autoptr(GBytes) stderr_buf = NULL; + gint rc; + + /* apparently: "we can't send registration credentials over the regular + * system or session bus since those aren't really locked down..." */ + if (!_client_register_start (manager, error)) + return FALSE; + g_debug ("spawning %s", LIBEXECDIR "/gsd-subman-helper"); + subprocess = g_subprocess_new (G_SUBPROCESS_FLAGS_STDIN_PIPE | G_SUBPROCESS_FLAGS_STDERR_PIPE, error, + "pkexec", LIBEXECDIR "/gsd-subman-helper", + "--kind", "register-with-key", + "--address", priv->address, + "--hostname", hostname, + "--organisation", organisation, +@@ -914,60 +1009,62 @@ gsd_subscription_manager_class_init (GsdSubscriptionManagerClass *klass) + static void + _launch_info_overview (void) + { + const gchar *argv[] = { "gnome-control-center", "info-overview", NULL }; + g_debug ("Running gnome-control-center info-overview"); + g_spawn_async (NULL, (gchar **) argv, NULL, G_SPAWN_SEARCH_PATH, + NULL, NULL, NULL, NULL); + } + + static void + _notify_closed_cb (NotifyNotification *notification, gpointer user_data) + { + /* FIXME: only launch when clicking on the main body, not the window close */ + if (notify_notification_get_closed_reason (notification) == 0x400) + _launch_info_overview (); + } + + static void + _notify_clicked_cb (NotifyNotification *notification, char *action, gpointer user_data) + { + _launch_info_overview (); + } + + static void + gsd_subscription_manager_init (GsdSubscriptionManager *manager) + { + GsdSubscriptionManagerPrivate *priv = manager->priv = GSD_SUBSCRIPTION_MANAGER_GET_PRIVATE (manager); + + priv->installed_products = g_ptr_array_new_with_free_func ((GDestroyNotify) product_data_free); + priv->timer_last_notified = g_timer_new (); ++ priv->subscription_status = GSD_SUBMAN_SUBSCRIPTION_STATUS_NOT_READ; ++ priv->subscription_status_last = GSD_SUBMAN_SUBSCRIPTION_STATUS_NOT_READ; + + /* expired */ + priv->notification_expired = + notify_notification_new (_("Subscription Has Expired"), + _("Add or renew a subscription to continue receiving software updates."), + NULL); + notify_notification_set_app_name (priv->notification_expired, _("Subscription")); + notify_notification_set_hint_string (priv->notification_expired, "desktop-entry", "subman-panel"); + notify_notification_set_hint_string (priv->notification_expired, "x-gnome-privacy-scope", "system"); + notify_notification_set_urgency (priv->notification_expired, NOTIFY_URGENCY_CRITICAL); + notify_notification_add_action (priv->notification_expired, + "info-overview", _("Subscribe System…"), + _notify_clicked_cb, + manager, NULL); + g_signal_connect (priv->notification_expired, "closed", + G_CALLBACK (_notify_closed_cb), manager); + + /* registered */ + priv->notification_registered = + notify_notification_new (_("Registration Successful"), + _("The system has been registered and software updates have been enabled."), + NULL); + notify_notification_set_app_name (priv->notification_registered, _("Subscription")); + notify_notification_set_hint_string (priv->notification_registered, "desktop-entry", "subman-panel"); + notify_notification_set_hint_string (priv->notification_registered, "x-gnome-privacy-scope", "system"); + notify_notification_set_urgency (priv->notification_registered, NOTIFY_URGENCY_CRITICAL); + g_signal_connect (priv->notification_registered, "closed", + G_CALLBACK (_notify_closed_cb), manager); + + /* registration required */ +-- +2.30.0 + diff --git a/SOURCES/0016-subman-Update-POTFILES.in.patch b/SOURCES/0016-subman-Update-POTFILES.in.patch new file mode 100644 index 0000000..f2882e1 --- /dev/null +++ b/SOURCES/0016-subman-Update-POTFILES.in.patch @@ -0,0 +1,25 @@ +From ff1278ecdebb5b23c80589a65f053d535a4d4f6a Mon Sep 17 00:00:00 2001 +From: Kalev Lember +Date: Fri, 12 Feb 2021 14:51:29 +0100 +Subject: [PATCH 16/16] subman: Update POTFILES.in + +--- + po/POTFILES.in | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/po/POTFILES.in b/po/POTFILES.in +index 7f17d5b5..9b94dc0f 100644 +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -25,6 +25,8 @@ plugins/print-notifications/gsd-printer.c + plugins/print-notifications/gsd-print-notifications-manager.c + plugins/smartcard/gsd-smartcard-manager.c + plugins/smartcard/gsd-smartcard-service.c ++plugins/subman/gsd-subscription-manager.c ++plugins/subman/org.gnome.settings-daemon.plugins.subman.policy.in.in + plugins/wacom/gsd-wacom-manager.c + plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in + plugins/xsettings/gsd-xsettings-manager.c +-- +2.29.2 + diff --git a/SOURCES/0017-Update-translations.patch b/SOURCES/0017-Update-translations.patch new file mode 100644 index 0000000..a44f255 --- /dev/null +++ b/SOURCES/0017-Update-translations.patch @@ -0,0 +1,9212 @@ +From 83a12a4f948c2771d8044a9db35b62c74e6df7be Mon Sep 17 00:00:00 2001 +From: Kalev Lember +Date: Mon, 1 Mar 2021 15:27:32 +0100 +Subject: [PATCH 17/17] Update translations + +https://bugzilla.redhat.com/show_bug.cgi?id=1876291 +--- + po/fr.po | 547 +++---- + po/ja.po | 4326 ++++++++++++++++++++++++++------------------------- + po/zh_CN.po | 1153 +++++++------- + 3 files changed, 2994 insertions(+), 3032 deletions(-) + +diff --git a/po/fr.po b/po/fr.po +index a42b9398..3f778d5f 100644 +--- a/po/fr.po ++++ b/po/fr.po +@@ -16,9 +16,8 @@ + msgid "" + msgstr "" + "Project-Id-Version: gnome-settings-daemon HEAD\n" +-"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-settings-daemon/" +-"issues\n" +-"POT-Creation-Date: 2019-01-18 13:47+0000\n" ++"Report-Msgid-Bugs-To: \n" ++"POT-Creation-Date: 2021-02-12 15:05+0100\n" + "PO-Revision-Date: 2019-02-12 21:55+0100\n" + "Last-Translator: Charles Monzat \n" + "Language-Team: GNOME French Team \n" +@@ -37,11 +36,7 @@ msgstr "Action quand la carte à puce est retirée" + msgid "" + "Set this to one of “none”, “lock-screen”, or “force-logout”. The action will " + "get performed when the smartcard used for log in is removed." +-msgstr "" +-"Définissez cette clé selon l’une des valeurs suivantes : « none » (aucune), " +-"« lock-screen » (verrouiller l’écran) ou « force-logout » (forcer la " +-"déconnexion). Cette action est effectuée lorsque la carte à puce utilisée " +-"pour se connecter est retirée." ++msgstr "Définissez cette clé selon l’une des valeurs suivantes : « none » (aucune), « lock-screen » (verrouiller l’écran) ou « force-logout » (forcer la déconnexion). Cette action est effectuée lorsque la carte à puce utilisée pour se connecter est retirée." + + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:25 + msgid "Possible values are “on”, “off”, and “custom”." +@@ -63,9 +58,7 @@ msgstr "Se souvenir de l’état du verrouillage numérique" + msgid "" + "When set to true, GNOME will remember the state of the NumLock LED between " + "sessions." +-msgstr "" +-"Si défini à vrai, GNOME se souvient de l’état de la diode lumineuse Verr. " +-"Num. entre les sessions." ++msgstr "Si défini à vrai, GNOME se souvient de l’état de la diode lumineuse Verr. Num. entre les sessions." + + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:45 + msgid "NumLock state" +@@ -79,9 +72,7 @@ msgstr "État conservé de la diode Verr. Num." + msgid "" + "Highlights the current location of the pointer when the Control key is " + "pressed and released." +-msgstr "" +-"Met en évidence la position du pointeur de la souris lorsque la touche Ctrl " +-"est pressée puis relâchée." ++msgstr "Met en évidence la position du pointeur de la souris lorsque la touche Ctrl est pressée puis relâchée." + + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:56 + msgid "Double click time" +@@ -101,9 +92,7 @@ msgstr "Distance avant qu’un glisser-déposer soit initié." + + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:68 + msgid "Whether the tablet’s orientation is locked, or rotated automatically." +-msgstr "" +-"Indique si l’orientation de la tablette est verrouillée ou si la rotation " +-"est automatique." ++msgstr "Indique si l’orientation de la tablette est verrouillée ou si la rotation est automatique." + + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:76 + msgid "Mouse button orientation" +@@ -123,9 +112,7 @@ msgstr "Simple clic" + msgid "" + "Acceleration multiplier for mouse motion. A value of -1 is the system " + "default." +-msgstr "" +-"Multiplicateur d’accélération pour le déplacement de la souris. Une valeur " +-"de -1 correspond à la valeur par défaut du système." ++msgstr "Multiplicateur d’accélération pour le déplacement de la souris. Une valeur de -1 correspond à la valeur par défaut du système." + + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:86 + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:148 +@@ -137,10 +124,7 @@ msgstr "Seuil de déplacement" + msgid "" + "Distance in pixels the pointer must move before accelerated mouse motion is " + "activated. A value of -1 is the system default." +-msgstr "" +-"Distance en pixels que le pointeur doit parcourir avant l’activation du " +-"déplacement de souris accéléré. Une valeur de -1 correspond à la valeur par " +-"défaut du système." ++msgstr "Distance en pixels que le pointeur doit parcourir avant l’activation du déplacement de souris accéléré. Une valeur de -1 correspond à la valeur par défaut du système." + + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:91 + msgid "Middle button emulation" +@@ -150,9 +134,7 @@ msgstr "Émulation du bouton du milieu" + msgid "" + "Enables middle mouse button emulation through simultaneous left and right " + "button click." +-msgstr "" +-"Active l’émulation du bouton du milieu de la souris par un clic simultané " +-"des boutons gauche et droit." ++msgstr "Active l’émulation du bouton du milieu de la souris par un clic simultané des boutons gauche et droit." + + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:101 + msgid "Key Repeat Interval" +@@ -178,9 +160,7 @@ msgstr "Désactivation du pavé tactile lors de la frappe" + msgid "" + "Set this to TRUE if you have problems with accidentally hitting the touchpad " + "while typing." +-msgstr "" +-"Définissez ce réglage à vrai si vous avez des problèmes avec l’activation " +-"inopinée du pavé tactile lorsque vous écrivez au clavier." ++msgstr "Définissez ce réglage à vrai si vous avez des problèmes avec l’activation inopinée du pavé tactile lorsque vous écrivez au clavier." + + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:118 + msgid "Enable horizontal scrolling" +@@ -190,9 +170,7 @@ msgstr "Activer le défilement horizontal" + msgid "" + "Set this to TRUE to allow horizontal scrolling by the same method selected " + "with the scroll_method key." +-msgstr "" +-"Définissez ce réglage à vrai pour permettre le défilement horizontal par la " +-"même méthode qui est définie par la clé scroll_method." ++msgstr "Définissez ce réglage à vrai pour permettre le défilement horizontal par la même méthode qui est définie par la clé scroll_method." + + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:123 + msgid "Select the touchpad scroll method" +@@ -202,10 +180,7 @@ msgstr "Méthode de défilement du pavé tactile" + msgid "" + "Select the touchpad scroll method. Supported values are: “disabled”, “edge-" + "scrolling”, “two-finger-scrolling”." +-msgstr "" +-"Choisissez la méthode de défilement du pavé tactile. Les valeurs prises en " +-"charge sont : « disabled » (désactivé), « edge-scrolling » (défilement sur " +-"les bords) et « two-finger-scrolling » (défilement à deux doigts)." ++msgstr "Choisissez la méthode de défilement du pavé tactile. Les valeurs prises en charge sont : « disabled » (désactivé), « edge-scrolling » (défilement sur les bords) et « two-finger-scrolling » (défilement à deux doigts)." + + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:128 + msgid "Enable mouse clicks with touchpad" +@@ -214,9 +189,7 @@ msgstr "Activer les clics de souris avec le pavé tactile" + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:129 + msgid "" + "Set this to TRUE to be able to send mouse clicks by tapping on the touchpad." +-msgstr "" +-"Définissez ce réglage à vrai pour pouvoir émuler des clics de souris en " +-"tapant sur le pavé tactile." ++msgstr "Définissez ce réglage à vrai pour pouvoir émuler des clics de souris en tapant sur le pavé tactile." + + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:133 + msgid "Enable touchpad" +@@ -234,10 +207,7 @@ msgstr "Orientation des boutons du pavé tactile" + msgid "" + "Swap left and right mouse buttons for left-handed mice with “left”, “right” " + "for right-handed, “mouse” to follow the mouse setting." +-msgstr "" +-"« left » inverse les boutons de souris gauche et droit pour les gauchers, " +-"« right » convient aux droitiers et « mouse » utilise le même réglage que " +-"pour la souris." ++msgstr "« left » inverse les boutons de souris gauche et droit pour les gauchers, « right » convient aux droitiers et « mouse » utilise le même réglage que pour la souris." + + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:153 + msgid "Natural scrolling" +@@ -245,14 +215,11 @@ msgstr "Défilement naturel" + + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:154 + msgid "Set this to TRUE to enable natural (reverse) scrolling for touchpads." +-msgstr "" +-"Définissez ce réglage à vrai pour activer le défilement naturel (inversé) " +-"pour les pavés tactiles." ++msgstr "Définissez ce réglage à vrai pour activer le défilement naturel (inversé) pour les pavés tactiles." + + #: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:161 + msgid "Mouse wheel emulation button. 0 to disable the feature." +-msgstr "" +-"Bouton d’émulation de la molette de la souris. 0 désactive la fonctionnalité." ++msgstr "Bouton d’émulation de la molette de la souris. 0 désactive la fonctionnalité." + + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:10 + msgid "Wacom stylus absolute mode" +@@ -268,9 +235,7 @@ msgstr "Zone de la tablette Wacom" + + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:16 + msgid "Set this to x1, y1 and x2, y2 of the area usable by the tools." +-msgstr "" +-"Définit les coordonnées x1, y1 et x2, y2 de la surface utilisable par les " +-"outils." ++msgstr "Définit les coordonnées x1, y1 et x2, y2 de la surface utilisable par les outils." + + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:20 + msgid "Wacom tablet aspect ratio" +@@ -280,9 +245,7 @@ msgstr "Proportions de la tablette Wacom" + msgid "" + "Enable this to restrict the Wacom tablet area to match the aspect ratio of " + "the output." +-msgstr "" +-"Activez cette option afin de limiter la surface de la tablette Wacom pour " +-"correspondre aux proportions de l’affichage." ++msgstr "Activez cette option afin de limiter la surface de la tablette Wacom pour correspondre aux proportions de l’affichage." + + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:25 + msgid "Wacom tablet rotation" +@@ -292,9 +255,7 @@ msgstr "Rotation de la tablette Wacom" + msgid "" + "Set this to “none”, “cw” for 90 degree clockwise, “half” for 180 degree, and " + "“ccw” for 90 degree counterclockwise." +-msgstr "" +-"Réglez-la à « none » (aucune), « cw » pour 90 degrés dans le sens horaire, " +-"« half » pour 180 degrés et « ccw » pour 90 degrés dans le sens anti-horaire." ++msgstr "Réglez-la à « none » (aucune), « cw » pour 90 degrés dans le sens horaire, « half » pour 180 degrés et « ccw » pour 90 degrés dans le sens anti-horaire." + + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:30 + msgid "Wacom touch feature" +@@ -302,9 +263,7 @@ msgstr "Fonctionnalités tactiles Wacom" + + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:31 + msgid "Enable this to move the cursor when the user touches the tablet." +-msgstr "" +-"Activer cette option pour déplacer le curseur lorsque l’utilisateur touche " +-"la tablette." ++msgstr "Activer cette option pour déplacer le curseur lorsque l’utilisateur touche la tablette." + + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:37 + msgid "Wacom stylus pressure curve" +@@ -313,9 +272,7 @@ msgstr "Courbe de pression du stylet Wacom" + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:38 + msgid "" + "Set this to x1, y1 and x2, y2 of the pressure curve applied to the stylus." +-msgstr "" +-"Définissez ici les coordonnées x1, y1 et x2, y2 selon la courbe de pression " +-"appliquée au stylet." ++msgstr "Définissez ici les coordonnées x1, y1 et x2, y2 selon la courbe de pression appliquée au stylet." + + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:42 + msgid "Wacom stylus button mapping" +@@ -333,9 +290,7 @@ msgstr "Seuil de pression pour le stylet Wacom" + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:48 + msgid "" + "Set this to the pressure value at which a stylus click event is generated." +-msgstr "" +-"Définissez ici la valeur de pression pour laquelle un évènement clic du " +-"stylet est généré." ++msgstr "Définissez ici la valeur de pression pour laquelle un évènement clic du stylet est généré." + + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:54 + msgid "Wacom eraser pressure curve" +@@ -344,9 +299,7 @@ msgstr "Courbe de pression de la gomme Wacom" + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:55 + msgid "" + "Set this to x1, y1 and x2, y2 of the pressure curve applied to the eraser." +-msgstr "" +-"Définissez ici les coordonnées x1, y1 et x2, y2 selon la courbe de pression " +-"appliquée à la gomme." ++msgstr "Définissez ici les coordonnées x1, y1 et x2, y2 selon la courbe de pression appliquée à la gomme." + + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:59 + msgid "Wacom eraser button mapping" +@@ -359,9 +312,7 @@ msgstr "Seuil de pression de la gomme Wacom" + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:65 + msgid "" + "Set this to the pressure value at which an eraser click event is generated." +-msgstr "" +-"Définissez ici la valeur de pression pour laquelle un évènement clic de la " +-"gomme est généré." ++msgstr "Définissez ici la valeur de pression pour laquelle un évènement clic de la gomme est généré." + + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:71 + msgid "Wacom button action type" +@@ -379,24 +330,17 @@ msgstr "Combinaison de touches pour l’action personnalisée" + msgid "" + "The keyboard shortcut generated when the button is pressed for custom " + "actions." +-msgstr "" +-"Le raccourci clavier généré quand le bouton est appuyé pour des actions " +-"personnalisées." ++msgstr "Le raccourci clavier généré quand le bouton est appuyé pour des actions personnalisées." + + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:81 + msgid "Key combinations for a touchring or touchstrip custom action" +-msgstr "" +-"Combinaisons de touches pour une action personnalisée du type touchring ou " +-"touchstrip" ++msgstr "Combinaisons de touches pour une action personnalisée du type touchring ou touchstrip" + + #: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:82 + msgid "" + "The keyboard shortcuts generated when a touchring or touchstrip is used for " + "custom actions (up followed by down)." +-msgstr "" +-"Les raccourcis de clavier générés quand le touchring ou le touchstrip est " +-"utilisé pour des actions personnalisées (mouvement vers le haut puis vers le " +-"bas)." ++msgstr "Les raccourcis de clavier générés quand le touchring ou le touchstrip est utilisé pour des actions personnalisées (mouvement vers le haut puis vers le bas)." + + #. Translators: This is the OLED display on an Intuos4 tablet: + #. http://eu.shop.wacom.eu/images/articles/d9abd9f2d4d88aa0649cda97a8077e2b_8.jpg +@@ -416,9 +360,7 @@ msgstr "La durée de validité d’un profil d’écran" + msgid "" + "This is the number of days after which the display color profile is " + "considered invalid." +-msgstr "" +-"Nombre de jours après quoi le profil colorimétrique de l’affichage est " +-"considéré comme périmé." ++msgstr "Nombre de jours après quoi le profil colorimétrique de l’affichage est considéré comme périmé." + + #: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:11 + msgid "The duration a printer profile is valid" +@@ -428,9 +370,7 @@ msgstr "La durée de validité d’un profil d’impression" + msgid "" + "This is the number of days after which the printer color profile is " + "considered invalid." +-msgstr "" +-"Nombre de jours après quoi le profil colorimétrique de l’impression est " +-"considéré comme périmé." ++msgstr "Nombre de jours après quoi le profil colorimétrique de l’impression est considéré comme périmé." + + #: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:16 + msgid "If the night light mode is enabled" +@@ -440,9 +380,7 @@ msgstr "Indique si le mode éclairage de nuit est activé" + msgid "" + "Night light mode changes the color temperature of your display when the sun " + "has gone down or at preset times." +-msgstr "" +-"Le mode éclairage de nuit modifie la température de couleur de l’écran " +-"lorsque la lumière solaire a baissé ou à des heures définies." ++msgstr "Le mode éclairage de nuit modifie la température de couleur de l’écran lorsque la lumière solaire a baissé ou à des heures définies." + + #: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:21 + msgid "Temperature of the display when enabled" +@@ -452,10 +390,7 @@ msgstr "La température de l’écran lorsqu’activé" + msgid "" + "This temperature in Kelvin is used to modify the screen tones when night " + "light mode is enabled. Higher values are bluer, lower redder." +-msgstr "" +-"Cette température exprimée en degrés Kelvin sert à modifier les couleurs " +-"d’affichage lorsque le mode éclairage de nuit est activé. Les valeurs les " +-"plus élevées tendent vers le bleu, les plus basses vers le rouge." ++msgstr "Cette température exprimée en degrés Kelvin sert à modifier les couleurs d’affichage lorsque le mode éclairage de nuit est activé. Les valeurs les plus élevées tendent vers le bleu, les plus basses vers le rouge." + + #: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:26 + msgid "Use the sunrise and sunset" +@@ -465,9 +400,7 @@ msgstr "Utiliser les heures de lever et coucher du soleil" + msgid "" + "Calculate the sunrise and sunset times automatically, from the current " + "location." +-msgstr "" +-"Calculer automatiquement les heures de lever et coucher du soleil en " +-"fonction de votre emplacement." ++msgstr "Calculer automatiquement les heures de lever et coucher du soleil en fonction de votre emplacement." + + #: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:31 + msgid "The start time" +@@ -477,9 +410,7 @@ msgstr "Heure de début" + msgid "" + "When “night-light-schedule-automatic” is disabled, use this start time in " + "hours from midnight." +-msgstr "" +-"Lorsque « night-light-schedule-automatic » est désactivé, utiliser cette " +-"heure de début en heures à partir de minuit." ++msgstr "Lorsque « night-light-schedule-automatic » est désactivé, utiliser cette heure de début en heures à partir de minuit." + + #: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:36 + msgid "The end time" +@@ -489,9 +420,7 @@ msgstr "Heure de fin" + msgid "" + "When “night-light-schedule-automatic” is disabled, use this end time in " + "hours from midnight." +-msgstr "" +-"Lorsque « night-light-schedule-automatic » est désactivé, utiliser cette " +-"heure de fin en heures à partir de minuit." ++msgstr "Lorsque « night-light-schedule-automatic » est désactivé, utiliser cette heure de fin en heures à partir de minuit." + + #: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:41 + msgid "The last detected position" +@@ -502,10 +431,7 @@ msgid "" + "When location services are available this represents the last detected " + "location. The default value is an invalid value to ensure it is always " + "updated at startup." +-msgstr "" +-"Lorsque les services de géolocalisation sont disponibles, ceci représente la " +-"dernière position géographique détectée. La valeur par défaut est une valeur " +-"non valide afin de toujours assurer sa mise à jour au démarrage." ++msgstr "Lorsque les services de géolocalisation sont disponibles, ceci représente la dernière position géographique détectée. La valeur par défaut est une valeur non valide afin de toujours assurer sa mise à jour au démarrage." + + #: data/org.gnome.settings-daemon.plugins.gschema.xml.in:6 + msgid "List of plugins that are allowed to be loaded" +@@ -515,9 +441,7 @@ msgstr "Liste des greffons autorisés au chargement" + msgid "" + "A list of strings representing the plugins that are allowed to be loaded " + "(default: “all”). This is only evaluated on startup." +-msgstr "" +-"Une liste de chaînes décrivant les greffons qui sont autorisés au chargement " +-"(la valeur par défaut est « all », tous). Cela n’est évalué qu’au démarrage." ++msgstr "Une liste de chaînes décrivant les greffons qui sont autorisés au chargement (la valeur par défaut est « all », tous). Cela n’est évalué qu’au démarrage." + + #: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:6 + msgid "Mount paths to ignore" +@@ -525,9 +449,7 @@ msgstr "Chemins de montage à ignorer" + + #: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:7 + msgid "Specify a list of mount paths to ignore when they run low on space." +-msgstr "" +-"Indique une liste de chemins de montage à ignorer lorsque leur espace disque " +-"est faible." ++msgstr "Indique une liste de chemins de montage à ignorer lorsque leur espace disque est faible." + + #: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:12 + msgid "Free percentage notify threshold" +@@ -537,10 +459,7 @@ msgstr "Seuil d’avertissement d’espace libre, en pourcentage" + msgid "" + "Percentage free space threshold for initial warning of low disk space. If " + "the percentage free space drops below this, a warning will be shown." +-msgstr "" +-"Seuil d’espace libre, en pourcentage, pour l’alerte initiale d’espace disque " +-"faible. Si le pourcentage d’espace libre tombe en dessous de ce seuil, une " +-"alerte est affichée." ++msgstr "Seuil d’espace libre, en pourcentage, pour l’alerte initiale d’espace disque faible. Si le pourcentage d’espace libre tombe en dessous de ce seuil, une alerte est affichée." + + #: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:18 + msgid "Subsequent free space percentage notify threshold" +@@ -550,9 +469,7 @@ msgstr "Seuil suivant d’avertissement d’espace libre, en pourcentage" + msgid "" + "Specify the percentage that the free disk space should reduce by before " + "issuing a subsequent warning." +-msgstr "" +-"Indique le pourcentage de réduction d’espace disque avant d’émettre un " +-"nouvel avertissement." ++msgstr "Indique le pourcentage de réduction d’espace disque avant d’émettre un nouvel avertissement." + + #: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:23 + msgid "Free space notify threshold" +@@ -562,9 +479,7 @@ msgstr "Seuil d’avertissement d’espace libre" + msgid "" + "Specify an amount in GB. If the amount of free space is more than this, no " + "warning will be shown." +-msgstr "" +-"Indique une taille en Go. Si la quantité d’espace disque disponible est " +-"supérieure à ce paramètre, aucune alerte ne sera affichée." ++msgstr "Indique une taille en Go. Si la quantité d’espace disque disponible est supérieure à ce paramètre, aucune alerte ne sera affichée." + + #: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:28 + msgid "Minimum notify period for repeated warnings" +@@ -574,9 +489,7 @@ msgstr "Intervalle minimum de répétition des avertissements" + msgid "" + "Specify a time in minutes. Subsequent warnings for a volume will not appear " + "more often than this period." +-msgstr "" +-"Indique un intervalle en minutes. C’est le délai minimal entre deux alertes " +-"pour un même volume." ++msgstr "Indique un intervalle en minutes. C’est le délai minimal entre deux alertes pour un même volume." + + #: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:6 + msgid "Custom keybindings" +@@ -776,9 +689,7 @@ msgstr "Copier une capture d’écran d’une fenêtre vers le presse-papiers" + + #: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:127 + msgid "Binding to copy a screenshot of a window to clipboard." +-msgstr "" +-"Raccourci pour copier une capture d’écran d’une fenêtre vers le presse-" +-"papiers." ++msgstr "Raccourci pour copier une capture d’écran d’une fenêtre vers le presse-papiers." + + #: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:131 + msgid "Copy a screenshot of an area to clipboard" +@@ -786,9 +697,7 @@ msgstr "Copier une capture d’une partie de l’écran vers le presse-papiers" + + #: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:132 + msgid "Binding to copy a screenshot of an area to clipboard." +-msgstr "" +-"Raccourci pour copier une capture d’une partie de l’écran vers le presse-" +-"papiers." ++msgstr "Raccourci pour copier une capture d’une partie de l’écran vers le presse-papiers." + + #: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:136 + msgid "Record a short video of the screen" +@@ -878,9 +787,7 @@ msgstr "Longueur maximale des enregistrements d’écran" + msgid "" + "The maximum length of single screen cast recordings in seconds or 0 for " + "unlimited" +-msgstr "" +-"Longueur maximale d’une capture d’écran vidéo en secondes ou 0 pour une " +-"durée illimitée" ++msgstr "Longueur maximale d’une capture d’écran vidéo en secondes ou 0 pour une durée illimitée" + + #: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:194 + msgid "Name" +@@ -913,9 +820,7 @@ msgstr "Luminosité de l’écran hors activité" + #: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:7 + msgid "" + "This is the laptop panel screen brightness used when the session is idle." +-msgstr "" +-"Il s’agit de la luminosité d’écran d’ordinateur portable utilisée lorsque la " +-"session n’est pas active." ++msgstr "Il s’agit de la luminosité d’écran d’ordinateur portable utilisée lorsque la session n’est pas active." + + #: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:11 + msgid "Dim the screen after a period of inactivity" +@@ -923,9 +828,7 @@ msgstr "Assombrir l’écran après une période d’inactivité" + + #: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:12 + msgid "If the screen should be dimmed to save power when the computer is idle." +-msgstr "" +-"Indique si l’écran doit être obscurci pour économiser de l’énergie lorsque " +-"l’ordinateur n’est pas actif." ++msgstr "Indique si l’écran doit être obscurci pour économiser de l’énergie lorsque l’ordinateur n’est pas actif." + + #: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:16 + msgid "Sleep timeout computer when on AC" +@@ -935,9 +838,7 @@ msgstr "Délai avant endormissement de l’ordinateur sur secteur" + msgid "" + "The amount of time in seconds the computer on AC power needs to be inactive " + "before it goes to sleep. A value of 0 means never." +-msgstr "" +-"Le nombre de secondes d’inactivité avant que l’ordinateur sur alimentation " +-"secteur ne passe en mode veille. Une valeur à 0 signifie jamais." ++msgstr "Le nombre de secondes d’inactivité avant que l’ordinateur sur alimentation secteur ne passe en mode veille. Une valeur à 0 signifie jamais." + + #: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:21 + #: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:31 +@@ -948,9 +849,7 @@ msgstr "Hibernation, mise en veille ou statu quo en cas d’inactivité" + #: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:32 + msgid "" + "The type of sleeping that should be performed when the computer is inactive." +-msgstr "" +-"Type d’endormissement qui doit être appliqué lorsque l’ordinateur est " +-"inactif." ++msgstr "Type d’endormissement qui doit être appliqué lorsque l’ordinateur est inactif." + + #: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:26 + msgid "Sleep timeout computer when on battery" +@@ -960,9 +859,7 @@ msgstr "Délai avant endormissement de l’ordinateur sur batterie" + msgid "" + "The amount of time in seconds the computer on battery power needs to be " + "inactive before it goes to sleep. A value of 0 means never." +-msgstr "" +-"Le nombre de secondes d’inactivité avant que l’ordinateur sur batterie ne " +-"passe en mode veille. Une valeur à 0 signifie jamais." ++msgstr "Le nombre de secondes d’inactivité avant que l’ordinateur sur batterie ne passe en mode veille. Une valeur à 0 signifie jamais." + + #: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:36 + msgid "Enable the ALS sensor" +@@ -981,10 +878,7 @@ msgid "" + "The action to take when the system power button is pressed. This action is " + "hard-coded (and the setting ignored) on virtual machines (power off) and " + "tablets (suspend)." +-msgstr "" +-"Action à entreprendre lorsque le bouton d’alimentation du système est " +-"pressé. Cette action est fixe (et ce réglage ignoré) pour les machines " +-"virtuelles (extinction) et les tablettes (mise en veille)." ++msgstr "Action à entreprendre lorsque le bouton d’alimentation du système est pressé. Cette action est fixe (et ce réglage ignoré) pour les machines virtuelles (extinction) et les tablettes (mise en veille)." + + #: data/org.gnome.settings-daemon.plugins.sharing.gschema.xml.in:6 + msgid "On which connections the service is enabled" +@@ -994,9 +888,7 @@ msgstr "Sur quelles connexions le service est activé" + msgid "" + "The list of NetworkManager connections (each one represented with its UUID) " + "on which this service is enabled and started." +-msgstr "" +-"La liste des connexions NetworkManager (chacune représentée par son UUID) " +-"sur lesquelles ce service est activé et démarré." ++msgstr "La liste des connexions NetworkManager (chacune représentée par son UUID) sur lesquelles ce service est activé et démarré." + + #: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:6 + msgid "Antialiasing" +@@ -1007,11 +899,7 @@ msgid "" + "The type of antialiasing to use when rendering fonts. Possible values are: " + "“none” for no antialiasing, “grayscale” for standard grayscale antialiasing, " + "and “rgba” for subpixel antialiasing (LCD screens only)." +-msgstr "" +-"Type de lissage utilisé pour le rendu des polices. Les valeurs possibles " +-"sont : « none » pour aucun lissage, « grayscale » pour le lissage classique " +-"en niveaux de gris et « rgba » pour le lissage sous-pixels (écrans LCD " +-"uniquement)." ++msgstr "Type de lissage utilisé pour le rendu des polices. Les valeurs possibles sont : « none » pour aucun lissage, « grayscale » pour le lissage classique en niveaux de gris et « rgba » pour le lissage sous-pixels (écrans LCD uniquement)." + + #: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:11 + msgid "Hinting" +@@ -1029,18 +917,7 @@ msgid "" + "(except for .otf: Y-only). This can lead to distortion and/or inconsistent " + "rendering depending on the quality of the font, the font format and the " + "state of FreeType’s font engines." +-msgstr "" +-"Type d’optimisation utilisé pour le rendu des polices. Les valeurs possibles " +-"sont : « none » pour aucune optimisation, « slight » pour adapter uniquement " +-"selon l’axe Y comme le font les moteurs propriétaires de rendu de polices " +-"ClearType de Microsoft, DirectWrite et ceux d’Adobe. Ignore l’optimisation " +-"native dans la police, génère l’optimisation de façon algorithmique. Utilisé " +-"par défaut chez Ubuntu. Recommandé. La signification des valeurs « medium » " +-"et « full » dépend du format de police (.ttf, .otf, .pfa/.pfb) et de la " +-"version de FreeType. Ils essaient généralement d’adapter les caractères en " +-"fonction des axes X et Y (sauf pour .otf : axe Y seulement). Cela peut " +-"causer des distorsions ou un rendu incohérent en fonction de la qualité de " +-"la police, de son format et de l’état des moteurs de police FreeType." ++msgstr "Type d’optimisation utilisé pour le rendu des polices. Les valeurs possibles sont : « none » pour aucune optimisation, « slight » pour adapter uniquement selon l’axe Y comme le font les moteurs propriétaires de rendu de polices ClearType de Microsoft, DirectWrite et ceux d’Adobe. Ignore l’optimisation native dans la police, génère l’optimisation de façon algorithmique. Utilisé par défaut chez Ubuntu. Recommandé. La signification des valeurs « medium » et « full » dépend du format de police (.ttf, .otf, .pfa/.pfb) et de la version de FreeType. Ils essaient généralement d’adapter les caractères en fonction des axes X et Y (sauf pour .otf : axe Y seulement). Cela peut causer des distorsions ou un rendu incohérent en fonction de la qualité de la police, de son format et de l’état des moteurs de police FreeType." + + #: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:16 + msgid "RGBA order" +@@ -1051,11 +928,7 @@ msgid "" + "The order of subpixel elements on an LCD screen; only used when antialiasing " + "is set to “rgba”. Possible values are: “rgb” for red on left (most common), " + "“bgr” for blue on left, “vrgb” for red on top, “vbgr” for red on bottom." +-msgstr "" +-"Ordre des éléments sous-pixels sur un écran LCD ; uniquement utilisé si le " +-"lissage est défini à « rgba ». Les valeurs possibles sont « rgb » pour le " +-"rouge à gauche (le plus courant), « bgr » pour le bleu à gauche, « vrgb » " +-"pour le rouge en haut, « vbgr » pour le rouge en bas." ++msgstr "Ordre des éléments sous-pixels sur un écran LCD ; uniquement utilisé si le lissage est défini à « rgba ». Les valeurs possibles sont « rgb » pour le rouge à gauche (le plus courant), « bgr » pour le bleu à gauche, « vrgb » pour le rouge en haut, « vbgr » pour le rouge en bas." + + #: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:21 + msgid "List of explicitly disabled GTK+ modules" +@@ -1065,9 +938,7 @@ msgstr "Liste de modules GTK+ désactivés de façon explicite" + msgid "" + "A list of strings representing the GTK+ modules that will not be loaded, " + "even if enabled by default in their configuration." +-msgstr "" +-"Liste de chaînes représentant les modules GTK+ à ne pas charger, même s’ils " +-"sont activés par défaut dans leur configuration." ++msgstr "Liste de chaînes représentant les modules GTK+ à ne pas charger, même s’ils sont activés par défaut dans leur configuration." + + #: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:26 + msgid "List of explicitly enabled GTK+ modules" +@@ -1077,9 +948,7 @@ msgstr "Liste de modules GTK+ activés de façon explicite" + msgid "" + "A list of strings representing the GTK+ modules that will be loaded, usually " + "in addition to conditional and forcibly disabled ones." +-msgstr "" +-"Liste de chaînes représentant les modules GTK+ à charger, en général en plus " +-"de ceux désactivés conditionnellement ou de force." ++msgstr "Liste de chaînes représentant les modules GTK+ à charger, en général en plus de ceux désactivés conditionnellement ou de force." + + #: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:31 + msgid "A dictionary of XSETTINGS to override" +@@ -1090,11 +959,7 @@ msgid "" + "This dictionary maps XSETTINGS names to overrides values. The values must be " + "either strings, signed int32s or (in the case of colors), 4-tuples of uint16 " + "(red, green, blue, alpha; 65535 is fully opaque)." +-msgstr "" +-"Ce dictionnaire contient des noms XSETTINGS dont les valeurs doivent être " +-"surchargées. Les valeurs doivent être des chaînes, des entiers signés int32 " +-"ou (dans le cas de couleurs), des tuples à 4 éléments uint16 (rouge, vert, " +-"bleu, alpha ; 65535 est l’opacité complète)." ++msgstr "Ce dictionnaire contient des noms XSETTINGS dont les valeurs doivent être surchargées. Les valeurs doivent être des chaînes, des entiers signés int32 ou (dans le cas de couleurs), des tuples à 4 éléments uint16 (rouge, vert, bleu, alpha ; 65535 est l’opacité complète)." + + #: plugins/color/gsd-color-calibrate.c:139 + msgid "Color" +@@ -1158,7 +1023,6 @@ msgid "Date & Time Settings" + msgstr "Paramètres de date et heure" + + #: plugins/housekeeping/gsd-disk-space.c:575 +-#| msgid "Disk space" + msgid "Disk Space" + msgstr "Espace disque" + +@@ -1184,9 +1048,7 @@ msgstr "Espace disque faible sur « %s »" + msgid "" + "The volume “%s” has only %s disk space remaining. You may free up some " + "space by emptying the trash." +-msgstr "" +-"Le volume « %s » n’a plus que %s d’espace disque disponible. Vous pouvez " +-"libérer de l’espace en vidant la corbeille." ++msgstr "Le volume « %s » n’a plus que %s d’espace disque disponible. Vous pouvez libérer de l’espace en vidant la corbeille." + + #: plugins/housekeeping/gsd-disk-space.c:644 + #, c-format +@@ -1202,39 +1064,37 @@ msgstr "Espace disque faible" + msgid "" + "This computer has only %s disk space remaining. You may free up some space " + "by emptying the trash." +-msgstr "" +-"Cet ordinateur n’a plus que %s d’espace disque disponible. Vous pouvez " +-"libérer de l’espace en vidant la corbeille." ++msgstr "Cet ordinateur n’a plus que %s d’espace disque disponible. Vous pouvez libérer de l’espace en vidant la corbeille." + + #: plugins/housekeeping/gsd-disk-space.c:654 + #, c-format + msgid "This computer has only %s disk space remaining." + msgstr "Cet ordinateur n’a plus que %s d’espace disque disponible." + +-#: plugins/media-keys/gsd-media-keys-manager.c:2284 ++#: plugins/media-keys/gsd-media-keys-manager.c:2288 + msgid "Bluetooth disabled" + msgstr "Bluetooth désactivé" + +-#: plugins/media-keys/gsd-media-keys-manager.c:2287 ++#: plugins/media-keys/gsd-media-keys-manager.c:2291 + msgid "Bluetooth enabled" + msgstr "Bluetooth activé" + +-#: plugins/media-keys/gsd-media-keys-manager.c:2291 ++#: plugins/media-keys/gsd-media-keys-manager.c:2295 + msgid "Airplane mode enabled" + msgstr "Mode avion activé" + +-#: plugins/media-keys/gsd-media-keys-manager.c:2294 ++#: plugins/media-keys/gsd-media-keys-manager.c:2298 + msgid "Airplane mode disabled" + msgstr "Mode avion désactivé" + +-#: plugins/media-keys/gsd-media-keys-manager.c:2322 ++#: plugins/media-keys/gsd-media-keys-manager.c:2326 + msgid "Hardware Airplane Mode" + msgstr "Mode avion matériel" + + #. Translators: this is a filename used for screencast + #. * recording, where "%d" and "%t" date and time, e.g. + #. * "Screencast from 07-17-2013 10:00:46 PM.webm" +-#: plugins/media-keys/gsd-media-keys-manager.c:2382 ++#: plugins/media-keys/gsd-media-keys-manager.c:2392 + #, no-c-format + msgid "Screencast from %d %t.webm" + msgstr "Capture d’écran vidéo de %d %t.webm" +@@ -1255,116 +1115,116 @@ msgstr "Capture d’écran faite" + msgid "Screenshot from %s" + msgstr "Capture d’écran de %s" + +-#: plugins/media-keys/shortcuts-list.h:45 + #: plugins/media-keys/shortcuts-list.h:46 ++#: plugins/media-keys/shortcuts-list.h:47 + msgid "Touchpad toggle" + msgstr "Interrupteur du pavé tactile" + +-#: plugins/media-keys/shortcuts-list.h:47 ++#: plugins/media-keys/shortcuts-list.h:48 + msgid "Touchpad On" + msgstr "Pavé tactile actif" + +-#: plugins/media-keys/shortcuts-list.h:48 ++#: plugins/media-keys/shortcuts-list.h:49 + msgid "Touchpad Off" + msgstr "Pavé tactile inactif" + +-#: plugins/media-keys/shortcuts-list.h:55 ++#: plugins/media-keys/shortcuts-list.h:56 + msgid "Quiet Volume Mute" + msgstr "Mettre en sourdine sans émettre de bruit" + +-#: plugins/media-keys/shortcuts-list.h:56 ++#: plugins/media-keys/shortcuts-list.h:57 + msgid "Quiet Volume Down" + msgstr "Baisser le volume sans émettre de bruit" + +-#: plugins/media-keys/shortcuts-list.h:57 ++#: plugins/media-keys/shortcuts-list.h:58 + msgid "Quiet Volume Up" + msgstr "Augmenter le volume sans émettre de bruit" + +-#: plugins/media-keys/shortcuts-list.h:58 ++#: plugins/media-keys/shortcuts-list.h:59 + msgid "Precise Volume Down" + msgstr "Baisser le volume avec précision" + +-#: plugins/media-keys/shortcuts-list.h:59 ++#: plugins/media-keys/shortcuts-list.h:60 + msgid "Precise Volume Up" + msgstr "Augmenter le volume avec précision" + +-#: plugins/media-keys/shortcuts-list.h:69 ++#: plugins/media-keys/shortcuts-list.h:70 + msgid "Lock Screen" + msgstr "Verrouiller l’écran" + +-#: plugins/media-keys/shortcuts-list.h:71 ++#: plugins/media-keys/shortcuts-list.h:72 + msgid "Help" + msgstr "Aide" + +-#: plugins/media-keys/shortcuts-list.h:88 ++#: plugins/media-keys/shortcuts-list.h:89 + msgid "Rewind" + msgstr "Retour rapide" + +-#: plugins/media-keys/shortcuts-list.h:89 ++#: plugins/media-keys/shortcuts-list.h:90 + msgid "Forward" + msgstr "Avance rapide" + +-#: plugins/media-keys/shortcuts-list.h:90 ++#: plugins/media-keys/shortcuts-list.h:91 + msgid "Repeat" + msgstr "Répétition" + +-#: plugins/media-keys/shortcuts-list.h:91 ++#: plugins/media-keys/shortcuts-list.h:92 + msgid "Random Play" + msgstr "Lecture aléatoire" + +-#: plugins/media-keys/shortcuts-list.h:92 ++#: plugins/media-keys/shortcuts-list.h:93 + msgid "Orientation Lock" + msgstr "Verrouiller l’orientation" + +-#: plugins/media-keys/shortcuts-list.h:101 ++#: plugins/media-keys/shortcuts-list.h:102 + msgid "Power Off" + msgstr "Éteindre" + + #. the kernel / Xorg names really are like this... + #. translators: "Sleep" means putting the machine to sleep, either through hibernate or suspend +-#: plugins/media-keys/shortcuts-list.h:104 ++#: plugins/media-keys/shortcuts-list.h:105 + msgid "Sleep" + msgstr "Mettre en veille" + +-#: plugins/media-keys/shortcuts-list.h:105 ++#: plugins/media-keys/shortcuts-list.h:106 + msgid "Suspend" + msgstr "Mettre en veille" + +-#: plugins/media-keys/shortcuts-list.h:106 ++#: plugins/media-keys/shortcuts-list.h:107 + msgid "Hibernate" + msgstr "Hiberner" + +-#: plugins/media-keys/shortcuts-list.h:107 ++#: plugins/media-keys/shortcuts-list.h:108 + msgid "Brightness Up" + msgstr "Augmenter la luminosité" + +-#: plugins/media-keys/shortcuts-list.h:108 ++#: plugins/media-keys/shortcuts-list.h:109 + msgid "Brightness Down" + msgstr "Diminuer la luminosité" + +-#: plugins/media-keys/shortcuts-list.h:109 ++#: plugins/media-keys/shortcuts-list.h:110 + msgid "Keyboard Brightness Up" + msgstr "Augmenter la luminosité du clavier" + +-#: plugins/media-keys/shortcuts-list.h:110 ++#: plugins/media-keys/shortcuts-list.h:111 + msgid "Keyboard Brightness Down" + msgstr "Diminuer la luminosité du clavier" + +-#: plugins/media-keys/shortcuts-list.h:111 ++#: plugins/media-keys/shortcuts-list.h:112 + msgid "Keyboard Brightness Toggle" + msgstr "Allumer/éteindre l’éclairage du clavier" + +-#: plugins/media-keys/shortcuts-list.h:112 ++#: plugins/media-keys/shortcuts-list.h:113 + msgid "Battery Status" + msgstr "État de la batterie" + +-#: plugins/media-keys/shortcuts-list.h:113 + #: plugins/media-keys/shortcuts-list.h:114 + #: plugins/media-keys/shortcuts-list.h:115 ++#: plugins/media-keys/shortcuts-list.h:116 + msgid "Toggle Airplane Mode" + msgstr "Inversion du mode avion" + +-#: plugins/media-keys/shortcuts-list.h:116 ++#: plugins/media-keys/shortcuts-list.h:117 + msgid "Toggle Bluetooth" + msgstr "Inversion de l’état Bluetooth" + +@@ -1406,330 +1266,303 @@ msgstr[0] "minute" + msgstr[1] "minutes" + + #. TRANSLATORS: this is the sound description +-#: plugins/power/gpm-common.c:438 plugins/power/gsd-power-manager.c:693 +-#: plugins/power/gsd-power-manager.c:790 ++#: plugins/power/gpm-common.c:438 plugins/power/gsd-power-manager.c:717 ++#: plugins/power/gsd-power-manager.c:814 + msgid "Battery is critically low" + msgstr "La batterie est très faible" + + #. TRANSLATORS: this is the notification application name +-#: plugins/power/gsd-power-manager.c:325 ++#: plugins/power/gsd-power-manager.c:347 + msgid "Power" + msgstr "Énergie" + + #. TRANSLATORS: UPS is now discharging +-#: plugins/power/gsd-power-manager.c:363 ++#: plugins/power/gsd-power-manager.c:387 + msgid "UPS Discharging" + msgstr "Onduleur en décharge" + + #. TRANSLATORS: tell the user how much time they have got +-#: plugins/power/gsd-power-manager.c:368 ++#: plugins/power/gsd-power-manager.c:392 + #, c-format + msgid "%s of UPS backup power remaining" + msgstr "Il reste %s d’autonomie à l’onduleur" + +-#: plugins/power/gsd-power-manager.c:371 ++#: plugins/power/gsd-power-manager.c:395 + msgid "Unknown amount of UPS backup power remaining" + msgstr "Autonomie restante de l’onduleur inconnue" + + #. TRANSLATORS: laptop battery low, and we only have one battery +-#: plugins/power/gsd-power-manager.c:446 ++#: plugins/power/gsd-power-manager.c:470 + msgid "Battery low" + msgstr "Batterie faible" + + #. TRANSLATORS: laptop battery low, and we have more than one kind of battery +-#: plugins/power/gsd-power-manager.c:449 ++#: plugins/power/gsd-power-manager.c:473 + msgid "Laptop battery low" + msgstr "Batterie du portable faible" + + #. TRANSLATORS: tell the user how much time they have got +-#: plugins/power/gsd-power-manager.c:456 ++#: plugins/power/gsd-power-manager.c:480 + #, c-format + msgid "Approximately %s remaining (%.0f%%)" + msgstr "Il reste environ %s (%.0f %%)" + + #. TRANSLATORS: UPS is starting to get a little low +-#: plugins/power/gsd-power-manager.c:461 ++#: plugins/power/gsd-power-manager.c:485 + msgid "UPS low" + msgstr "Onduleur faible" + + #. TRANSLATORS: tell the user how much time they have got +-#: plugins/power/gsd-power-manager.c:467 ++#: plugins/power/gsd-power-manager.c:491 + #, c-format + msgid "Approximately %s of remaining UPS backup power (%.0f%%)" + msgstr "Il reste environ %s d’autonomie à l’onduleur (%.0f %%)" + + #. TRANSLATORS: mouse is getting a little low + #. TRANSLATORS: the mouse battery is very low +-#: plugins/power/gsd-power-manager.c:472 plugins/power/gsd-power-manager.c:606 ++#: plugins/power/gsd-power-manager.c:496 plugins/power/gsd-power-manager.c:630 + msgid "Mouse battery low" + msgstr "Batterie de souris faible" + + #. TRANSLATORS: tell user more details +-#: plugins/power/gsd-power-manager.c:475 ++#: plugins/power/gsd-power-manager.c:499 + #, c-format + msgid "Wireless mouse is low in power (%.0f%%)" + msgstr "Il reste peu d’autonomie à la souris sans fil (%.0f %%)" + + #. TRANSLATORS: keyboard is getting a little low + #. TRANSLATORS: the keyboard battery is very low +-#: plugins/power/gsd-power-manager.c:479 plugins/power/gsd-power-manager.c:614 ++#: plugins/power/gsd-power-manager.c:503 plugins/power/gsd-power-manager.c:638 + msgid "Keyboard battery low" + msgstr "Batterie du clavier faible" + + #. TRANSLATORS: tell user more details +-#: plugins/power/gsd-power-manager.c:482 ++#: plugins/power/gsd-power-manager.c:506 + #, c-format + msgid "Wireless keyboard is low in power (%.0f%%)" + msgstr "Il reste peu d’autonomie au clavier sans fil (%.0f %%)" + + #. TRANSLATORS: PDA is getting a little low + #. TRANSLATORS: the PDA battery is very low +-#: plugins/power/gsd-power-manager.c:486 plugins/power/gsd-power-manager.c:623 ++#: plugins/power/gsd-power-manager.c:510 plugins/power/gsd-power-manager.c:647 + msgid "PDA battery low" + msgstr "Batterie d’assistant personnel faible" + + #. TRANSLATORS: tell user more details +-#: plugins/power/gsd-power-manager.c:489 ++#: plugins/power/gsd-power-manager.c:513 + #, c-format + msgid "PDA is low in power (%.0f%%)" + msgstr "Il reste peu d’autonomie à l’assistant personnel (%.0f %%)" + + #. TRANSLATORS: cell phone (mobile) is getting a little low + #. TRANSLATORS: the cell battery is very low +-#: plugins/power/gsd-power-manager.c:493 plugins/power/gsd-power-manager.c:633 +-#: plugins/power/gsd-power-manager.c:642 ++#: plugins/power/gsd-power-manager.c:517 plugins/power/gsd-power-manager.c:657 ++#: plugins/power/gsd-power-manager.c:666 + msgid "Cell phone battery low" + msgstr "Batterie de téléphone portable faible" + + #. TRANSLATORS: tell user more details +-#: plugins/power/gsd-power-manager.c:496 ++#: plugins/power/gsd-power-manager.c:520 + #, c-format + msgid "Cell phone is low in power (%.0f%%)" + msgstr "Il reste peu d’autonomie au téléphone portable (%.0f %%)" + + #. TRANSLATORS: media player, e.g. mp3 is getting a little low +-#: plugins/power/gsd-power-manager.c:500 ++#: plugins/power/gsd-power-manager.c:524 + msgid "Media player battery low" + msgstr "Batterie de lecteur multimédia faible" + + #. TRANSLATORS: tell user more details +-#: plugins/power/gsd-power-manager.c:503 ++#: plugins/power/gsd-power-manager.c:527 + #, c-format + msgid "Media player is low in power (%.0f%%)" + msgstr "Il reste peu d’autonomie au lecteur multimédia (%.0f %%)" + + #. TRANSLATORS: graphics tablet, e.g. wacom is getting a little low + #. TRANSLATORS: the cell battery is very low +-#: plugins/power/gsd-power-manager.c:507 plugins/power/gsd-power-manager.c:651 ++#: plugins/power/gsd-power-manager.c:531 plugins/power/gsd-power-manager.c:675 + msgid "Tablet battery low" + msgstr "Batterie de tablette faible" + + #. TRANSLATORS: tell user more details +-#: plugins/power/gsd-power-manager.c:510 ++#: plugins/power/gsd-power-manager.c:534 + #, c-format + msgid "Tablet is low in power (%.0f%%)" + msgstr "Il reste peu d’autonomie à la tablette (%.0f %%)" + + #. TRANSLATORS: computer, e.g. ipad is getting a little low + #. TRANSLATORS: the cell battery is very low +-#: plugins/power/gsd-power-manager.c:514 plugins/power/gsd-power-manager.c:660 ++#: plugins/power/gsd-power-manager.c:538 plugins/power/gsd-power-manager.c:684 + msgid "Attached computer battery low" + msgstr "Batterie de l’ordinateur connecté faible" + + #. TRANSLATORS: tell user more details +-#: plugins/power/gsd-power-manager.c:517 ++#: plugins/power/gsd-power-manager.c:541 + #, c-format + msgid "Attached computer is low in power (%.0f%%)" + msgstr "Il reste peu d’autonomie à l’ordinateur connecté (%.0f %%)" + + #. TRANSLATORS: this is the sound description +-#: plugins/power/gsd-power-manager.c:538 ++#: plugins/power/gsd-power-manager.c:562 + msgid "Battery is low" + msgstr "Batterie faible" + + #. TRANSLATORS: laptop battery critically low, and only have one kind of battery +-#: plugins/power/gsd-power-manager.c:570 ++#: plugins/power/gsd-power-manager.c:594 + msgid "Battery critically low" + msgstr "Batterie très faible" + + #. TRANSLATORS: laptop battery critically low, and we have more than one type of battery + #. TRANSLATORS: laptop battery is really, really, low +-#: plugins/power/gsd-power-manager.c:573 plugins/power/gsd-power-manager.c:720 ++#: plugins/power/gsd-power-manager.c:597 plugins/power/gsd-power-manager.c:744 + msgid "Laptop battery critically low" + msgstr "Batterie du portable très faible" + + #. TRANSLATORS: give the user a ultimatum +-#: plugins/power/gsd-power-manager.c:582 ++#: plugins/power/gsd-power-manager.c:606 + #, c-format + msgid "Computer will hibernate very soon unless it is plugged in." +-msgstr "" +-"L’ordinateur se mettra très rapidement en hibernation si l’alimentation " +-"n’est pas branchée." ++msgstr "L’ordinateur se mettra très rapidement en hibernation si l’alimentation n’est pas branchée." + + #. TRANSLATORS: give the user a ultimatum +-#: plugins/power/gsd-power-manager.c:586 ++#: plugins/power/gsd-power-manager.c:610 + #, c-format + msgid "Computer will shutdown very soon unless it is plugged in." +-msgstr "" +-"L’ordinateur s’éteindra très rapidement si l’alimentation n’est pas branchée." ++msgstr "L’ordinateur s’éteindra très rapidement si l’alimentation n’est pas branchée." + + #. TRANSLATORS: the UPS is very low + #. TRANSLATORS: UPS is really, really, low +-#: plugins/power/gsd-power-manager.c:594 plugins/power/gsd-power-manager.c:745 ++#: plugins/power/gsd-power-manager.c:618 plugins/power/gsd-power-manager.c:769 + msgid "UPS critically low" + msgstr "Onduleur très faible" + + #. TRANSLATORS: give the user a ultimatum +-#: plugins/power/gsd-power-manager.c:600 ++#: plugins/power/gsd-power-manager.c:624 + #, c-format + msgid "" + "Approximately %s of remaining UPS power (%.0f%%). Restore AC power to your " + "computer to avoid losing data." +-msgstr "" +-"Il reste environ %s d’autonomie à l’onduleur (%.0f %%). Branchez votre " +-"ordinateur au secteur pour éviter de perdre des données." ++msgstr "Il reste environ %s d’autonomie à l’onduleur (%.0f %%). Branchez votre ordinateur au secteur pour éviter de perdre des données." + + #. TRANSLATORS: the device is just going to stop working +-#: plugins/power/gsd-power-manager.c:609 ++#: plugins/power/gsd-power-manager.c:633 + #, c-format + msgid "" + "Wireless mouse is very low in power (%.0f%%). This device will soon stop " + "functioning if not charged." +-msgstr "" +-"Il reste très peu d’autonomie à la souris sans fil (%.0f %%). Elle " +-"s’arrêtera bientôt de fonctionner si elle n’est pas rechargée." ++msgstr "Il reste très peu d’autonomie à la souris sans fil (%.0f %%). Elle s’arrêtera bientôt de fonctionner si elle n’est pas rechargée." + + #. TRANSLATORS: the device is just going to stop working +-#: plugins/power/gsd-power-manager.c:617 ++#: plugins/power/gsd-power-manager.c:641 + #, c-format + msgid "" + "Wireless keyboard is very low in power (%.0f%%). This device will soon stop " + "functioning if not charged." +-msgstr "" +-"Il reste très peu d’autonomie au clavier sans fil (%.0f %%). Il s’arrêtera " +-"bientôt de fonctionner s’il n’est pas rechargé." ++msgstr "Il reste très peu d’autonomie au clavier sans fil (%.0f %%). Il s’arrêtera bientôt de fonctionner s’il n’est pas rechargé." + + #. TRANSLATORS: the device is just going to stop working +-#: plugins/power/gsd-power-manager.c:626 ++#: plugins/power/gsd-power-manager.c:650 + #, c-format + msgid "" + "PDA is very low in power (%.0f%%). This device will soon stop functioning if " + "not charged." +-msgstr "" +-"Il reste très peu d’autonomie à l’assistant personnel (%.0f %%). Il " +-"s’arrêtera bientôt de fonctionner s’il n’est pas rechargé." ++msgstr "Il reste très peu d’autonomie à l’assistant personnel (%.0f %%). Il s’arrêtera bientôt de fonctionner s’il n’est pas rechargé." + + #. TRANSLATORS: the device is just going to stop working +-#: plugins/power/gsd-power-manager.c:636 ++#: plugins/power/gsd-power-manager.c:660 + #, c-format + msgid "" + "Cell phone is very low in power (%.0f%%). This device will soon stop " + "functioning if not charged." +-msgstr "" +-"Il reste très peu d’autonomie au téléphone portable (%.0f %%). Il s’arrêtera " +-"bientôt de fonctionner s’il n’est pas rechargé." ++msgstr "Il reste très peu d’autonomie au téléphone portable (%.0f %%). Il s’arrêtera bientôt de fonctionner s’il n’est pas rechargé." + + #. TRANSLATORS: the device is just going to stop working +-#: plugins/power/gsd-power-manager.c:645 ++#: plugins/power/gsd-power-manager.c:669 + #, c-format + msgid "" + "Media player is very low in power (%.0f%%). This device will soon stop " + "functioning if not charged." +-msgstr "" +-"Il reste très peu d’autonomie au lecteur multimédia (%.0f %%). Il s’arrêtera " +-"bientôt de fonctionner s’il n’est pas rechargé." ++msgstr "Il reste très peu d’autonomie au lecteur multimédia (%.0f %%). Il s’arrêtera bientôt de fonctionner s’il n’est pas rechargé." + + #. TRANSLATORS: the device is just going to stop working +-#: plugins/power/gsd-power-manager.c:654 ++#: plugins/power/gsd-power-manager.c:678 + #, c-format + msgid "" + "Tablet is very low in power (%.0f%%). This device will soon stop functioning " + "if not charged." +-msgstr "" +-"Il reste très peu d’autonomie à la tablette (%.0f %%). Elle s’arrêtera " +-"bientôt de fonctionner si elle n’est pas rechargée." ++msgstr "Il reste très peu d’autonomie à la tablette (%.0f %%). Elle s’arrêtera bientôt de fonctionner si elle n’est pas rechargée." + + #. TRANSLATORS: the device is just going to stop working +-#: plugins/power/gsd-power-manager.c:663 ++#: plugins/power/gsd-power-manager.c:687 + #, c-format + msgid "" + "Attached computer is very low in power (%.0f%%). The device will soon " + "shutdown if not charged." +-msgstr "" +-"Il reste très peu d’autonomie à l’ordinateur connecté (%.0f %%). Il " +-"s’arrêtera bientôt de fonctionner s’il n’est pas rechargé." ++msgstr "Il reste très peu d’autonomie à l’ordinateur connecté (%.0f %%). Il s’arrêtera bientôt de fonctionner s’il n’est pas rechargé." + + #. TRANSLATORS: computer will hibernate +-#: plugins/power/gsd-power-manager.c:728 ++#: plugins/power/gsd-power-manager.c:752 + msgid "" + "The battery is below the critical level and this computer is about to " + "hibernate." +-msgstr "" +-"La batterie est au-dessous de son niveau critique ; l’ordinateur va se " +-"mettre en hibernation." ++msgstr "La batterie est au-dessous de son niveau critique ; l’ordinateur va se mettre en hibernation." + + #. TRANSLATORS: computer will just shutdown +-#: plugins/power/gsd-power-manager.c:733 ++#: plugins/power/gsd-power-manager.c:757 + msgid "" + "The battery is below the critical level and this computer is about to " + "shutdown." +-msgstr "" +-"La batterie est au-dessous de son niveau critique ; l’ordinateur va " +-"s’éteindre." ++msgstr "La batterie est au-dessous de son niveau critique ; l’ordinateur va s’éteindre." + + #. TRANSLATORS: computer will hibernate +-#: plugins/power/gsd-power-manager.c:753 ++#: plugins/power/gsd-power-manager.c:777 + msgid "" + "UPS is below the critical level and this computer is about to hibernate." +-msgstr "" +-"L’onduleur est au-dessous de son niveau critique ; l’ordinateur va se mettre " +-"en hibernation." ++msgstr "L’onduleur est au-dessous de son niveau critique ; l’ordinateur va se mettre en hibernation." + + #. TRANSLATORS: computer will just shutdown +-#: plugins/power/gsd-power-manager.c:758 ++#: plugins/power/gsd-power-manager.c:782 + msgid "UPS is below the critical level and this computer is about to shutdown." +-msgstr "" +-"L’onduleur est au-dessous de son niveau critique ; l’ordinateur va " +-"s’éteindre." ++msgstr "L’onduleur est au-dessous de son niveau critique ; l’ordinateur va s’éteindre." + + #. TRANSLATORS: this is the sound description +-#: plugins/power/gsd-power-manager.c:1236 ++#: plugins/power/gsd-power-manager.c:1260 + msgid "Lid has been opened" + msgstr "Ouverture de l’écran de l’ordinateur" + + #. TRANSLATORS: this is the sound description +-#: plugins/power/gsd-power-manager.c:1270 ++#: plugins/power/gsd-power-manager.c:1294 + msgid "Lid has been closed" + msgstr "Fermeture de l’écran de l’ordinateur" + + #. TRANSLATORS: this is the sound description +-#: plugins/power/gsd-power-manager.c:1832 ++#: plugins/power/gsd-power-manager.c:1856 + msgid "On battery power" + msgstr "Sur batterie" + + #. TRANSLATORS: this is the sound description +-#: plugins/power/gsd-power-manager.c:1837 ++#: plugins/power/gsd-power-manager.c:1861 + msgid "On AC power" + msgstr "Sur secteur" + +-#: plugins/power/gsd-power-manager.c:2029 ++#: plugins/power/gsd-power-manager.c:2051 + msgid "Automatic logout" + msgstr "Déconnexion automatique" + +-#: plugins/power/gsd-power-manager.c:2029 ++#: plugins/power/gsd-power-manager.c:2051 + msgid "You will soon log out because of inactivity." + msgstr "Vous allez être déconnecté bientôt faute d’activité." + +-#: plugins/power/gsd-power-manager.c:2034 ++#: plugins/power/gsd-power-manager.c:2056 + msgid "Automatic suspend" + msgstr "Veille automatique" + +-#: plugins/power/gsd-power-manager.c:2034 +-#: plugins/power/gsd-power-manager.c:2039 ++#: plugins/power/gsd-power-manager.c:2056 ++#: plugins/power/gsd-power-manager.c:2061 + msgid "Computer will suspend very soon because of inactivity." + msgstr "L’ordinateur se mettra en veille bientôt faute d’activité." + +-#: plugins/power/gsd-power-manager.c:2039 ++#: plugins/power/gsd-power-manager.c:2061 + msgid "Automatic hibernation" + msgstr "Hibernation automatique" + +@@ -1742,9 +1575,7 @@ msgstr "Modifier la luminosité de l’ordinateur portable" + + #: plugins/power/org.gnome.settings-daemon.plugins.power.policy.in.in:22 + msgid "Authentication is required to modify the laptop brightness" +-msgstr "" +-"Authentification nécessaire pour modifier la luminosité de l’ordinateur " +-"portable" ++msgstr "Authentification nécessaire pour modifier la luminosité de l’ordinateur portable" + + #. Translators: We are configuring new printer + #: plugins/print-notifications/gsd-printer.c:890 +@@ -1999,10 +1830,56 @@ msgstr "Alerte de l’imprimante" + msgid "Printer “%s”: “%s”." + msgstr "Imprimante « %s » : « %s »." + +-#: plugins/smartcard/gsd-smartcard-service.c:224 ++#: plugins/smartcard/gsd-smartcard-service.c:288 + msgid "User was not logged in with smartcard." + msgstr "L’utilisateur n’était pas connecté avec la carte à puce." + ++#: plugins/subman/gsd-subscription-manager.c:1044 ++msgid "Subscription Has Expired" ++msgstr "L'abonnement a expiré" ++ ++#: plugins/subman/gsd-subscription-manager.c:1045 ++msgid "Add or renew a subscription to continue receiving software updates." ++msgstr "Ajouter ou renouveler un abonnement pour continuer à recevoir les mises à jour de logiciels." ++ ++#: plugins/subman/gsd-subscription-manager.c:1047 ++#: plugins/subman/gsd-subscription-manager.c:1063 ++#: plugins/subman/gsd-subscription-manager.c:1075 ++msgid "Subscription" ++msgstr "Abonnement" ++ ++#: plugins/subman/gsd-subscription-manager.c:1052 ++msgid "Subscribe System…" ++msgstr "Abonnement du système..." ++ ++#: plugins/subman/gsd-subscription-manager.c:1060 ++msgid "Registration Successful" ++msgstr "Abonnement réussi" ++ ++#: plugins/subman/gsd-subscription-manager.c:1061 ++msgid "The system has been registered and software updates have been enabled." ++msgstr "Le système a été enregistré et les mises à jour du logiciel ont été activées." ++ ++#: plugins/subman/gsd-subscription-manager.c:1072 ++msgid "System Not Registered" ++msgstr "Le système n'est pas enregistré" ++ ++#: plugins/subman/gsd-subscription-manager.c:1073 ++msgid "Please register your system to receive software updates." ++msgstr "Enregistrez ce système pour recevoir les mises à jour du logiciel." ++ ++#: plugins/subman/gsd-subscription-manager.c:1080 ++msgid "Register System…" ++msgstr "Enregistrement du système..." ++ ++#: plugins/subman/org.gnome.settings-daemon.plugins.subman.policy.in.in:17 ++msgid "Register the system" ++msgstr "Enregistrer le système" ++ ++#: plugins/subman/org.gnome.settings-daemon.plugins.subman.policy.in.in:18 ++msgid "Authentication is required to register the system" ++msgstr "Authentification nécessaire pour enregistrer le système" ++ + #. SECURITY: + #. - A normal active user on the local machine does not need permission + #. to change the LED setting for a Wacom tablet +@@ -2012,9 +1889,7 @@ msgstr "Modifie les voyants allumés d’une tablette Wacom" + + #: plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in:21 + msgid "Authentication is required to modify the lit LED for a Wacom tablet" +-msgstr "" +-"Une authentification est nécessaire pour modifier les voyants allumés d’une " +-"tablette Wacom" ++msgstr "Une authentification est nécessaire pour modifier les voyants allumés d’une tablette Wacom" + + #. SECURITY: + #. - A normal active user on the local machine does not need permission +@@ -2025,6 +1900,4 @@ msgstr "Modifie les images des voyants d’une tablette Wacom" + + #: plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in:36 + msgid "Authentication is required to modify the OLED image for a Wacom tablet" +-msgstr "" +-"Une authentification est nécessaire pour modifier les images des voyants " +-"d’une tablette Wacom" ++msgstr "Une authentification est nécessaire pour modifier les images des voyants d’une tablette Wacom" +diff --git a/po/ja.po b/po/ja.po +index 8f045c38..ef77a4e1 100644 +--- a/po/ja.po ++++ b/po/ja.po +@@ -17,8 +17,8 @@ + msgid "" + msgstr "" + "Project-Id-Version: gnome-settings-daemon master\n" +-"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-settings-daemon&keywords=I18N+L10N&component=general\n" +-"POT-Creation-Date: 2013-09-18 13:55+0000\n" ++"Report-Msgid-Bugs-To: \n" ++"POT-Creation-Date: 2021-02-12 15:05+0100\n" + "PO-Revision-Date: 2013-09-21 07:10+0900\n" + "Last-Translator: Jiro Matsuzawa \n" + "Language-Team: Japanese \n" +@@ -28,1358 +28,1220 @@ msgstr "" + "Content-Transfer-Encoding: 8bit\n" + "Plural-Forms: nplurals=1; plural=0;\n" + +-#: ../data/gnome-settings-daemon.desktop.in.in.h:1 +-msgid "GNOME Settings Daemon" +-msgstr "GNOME 設定デーモン" +- +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:1 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:12 + msgid "Smartcard removal action" + msgstr "スマートカードを抜いた時のアクション" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:2 +-msgid "Set this to one of \"none\", \"lock-screen\", or \"force-logout\". The action will get performed when the smartcard used for log in is removed." +-msgstr "\"none\"、\"lock-screen\"、あるいは \"force-logout\" のうちの一つを指定します。スマートカードがログインに使用されたり、取り出された場合にそのアクションが実行されます。" ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:13 ++msgid "" ++"Set this to one of “none”, “lock-screen”, or “force-logout”. The action will " ++"get performed when the smartcard used for log in is removed." ++msgstr "\"none\"、\"lock-screen\"、あるいは \"force-logout\" のうちの 1 つを指定します。この操作は、ログインに使用したスマートカードが取り外されたときに実行されます。" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:25 ++msgid "Possible values are “on”, “off”, and “custom”." ++msgstr "使用可能な値は、\"on\"、\"off\"、および \"custom\" です。" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:35 ++msgid "Keyboard Bell Custom Filename" ++msgstr "キーボードベルカスタムファイル名" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:36 ++msgid "File name of the bell sound to be played." ++msgstr "再生するベル音のファイル名。" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:40 ++msgid "Remember NumLock state" ++msgstr "NumLock の状態を記憶する" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:41 ++msgid "" ++"When set to true, GNOME will remember the state of the NumLock LED between " ++"sessions." ++msgstr "true に設定すると、GNOME はセッション間の NumLock LED の状態を記憶します。" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:45 ++msgid "NumLock state" ++msgstr "NumLock の状態" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:46 ++msgid "The remembered state of the NumLock LED." ++msgstr "NumLock LED の記憶状態。" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:52 ++msgid "" ++"Highlights the current location of the pointer when the Control key is " ++"pressed and released." ++msgstr "コントロールキーが押されて、離された時、ポインターの現在位置をハイライトします。" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:56 ++msgid "Double click time" ++msgstr "ダブルクリックの時間" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:57 ++msgid "Length of a double click in milliseconds." ++msgstr "ダブルクリックの長さ(ミリ秒単位)です。" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:61 ++msgid "Drag threshold" ++msgstr "ドラッグのしきい値" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:62 ++msgid "Distance before a drag is started." ++msgstr "ドラッグが開始されるまでの距離です。" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:68 ++msgid "Whether the tablet’s orientation is locked, or rotated automatically." ++msgstr "タブレットの方向を固定するか、自動的に回転するか。" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:76 ++msgid "Mouse button orientation" ++msgstr "マウスボタンの方向" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:77 ++msgid "Swap left and right mouse buttons for left-handed mice." ++msgstr "左利きのマウス用に右、左ボタンを交換します。" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:81 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:143 ++msgid "Single Click" ++msgstr "シングルクリック" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:82 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:144 ++msgid "" ++"Acceleration multiplier for mouse motion. A value of -1 is the system " ++"default." ++msgstr "マウスモーションの加速度乗数。値 -1 がシステムのデフォルトです。" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:86 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:148 ++msgid "Motion Threshold" ++msgstr "モーションのしきい値" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:87 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:149 ++msgid "" ++"Distance in pixels the pointer must move before accelerated mouse motion is " ++"activated. A value of -1 is the system default." ++msgstr "マウスの加速モーションが有効になる前にポインターが移動する距離をピクセル単位で指定します。値 -1 がシステムのデフォルトです。" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:91 ++msgid "Middle button emulation" ++msgstr "中ボタンのエミュレーション" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:92 ++msgid "" ++"Enables middle mouse button emulation through simultaneous left and right " ++"button click." ++msgstr "マウスの中ボタンの左右ボタンの同時クリックによるエミュレーションを利用可能にします。" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:101 ++msgid "Key Repeat Interval" ++msgstr "キーリピートの間隔" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:3 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:102 ++msgid "Delay between repeats in milliseconds." ++msgstr "リピート間の遅延時間をミリ秒単位で指定します。" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:106 ++msgid "Initial Key Repeat Delay" ++msgstr "初期キーリピート遅延" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:107 ++msgid "Initial key repeat delay in milliseconds." ++msgstr "初期キーリピート遅延をミリ秒単位で指定します。" ++ ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:113 + msgid "Disable touchpad while typing" + msgstr "タイピング中にタッチパッドを無効にする" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:4 +-msgid "Set this to TRUE if you have problems with accidentally hitting the touchpad while typing." ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:114 ++msgid "" ++"Set this to TRUE if you have problems with accidentally hitting the touchpad " ++"while typing." + msgstr "タイプ中に誤ってタッチパッドに触れてしまう問題があるのであれば、TRUE に設定してください。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:5 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:118 + msgid "Enable horizontal scrolling" + msgstr "水平スクロールを有効にする" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:6 +-msgid "Set this to TRUE to allow horizontal scrolling by the same method selected with the scroll_method key." ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:119 ++msgid "" ++"Set this to TRUE to allow horizontal scrolling by the same method selected " ++"with the scroll_method key." + msgstr "この値を TRUE にすると、scroll_method キーで選択したのと同じ方法で、水平スクロールを許可します。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:7 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:123 + msgid "Select the touchpad scroll method" + msgstr "タッチパッドでのスクロールの方法の選択" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:8 +-msgid "Select the touchpad scroll method. Supported values are: \"disabled\", \"edge-scrolling\", \"two-finger-scrolling\"." +-msgstr "タッチパッドでのスクロール方法を選択します。指定できる値は次のとおりです。\"disabled\"、\"edge-scrolling\"、\"two-finger-scrolling\"" ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:124 ++msgid "" ++"Select the touchpad scroll method. Supported values are: “disabled”, “edge-" ++"scrolling”, “two-finger-scrolling”." ++msgstr "タッチパッドでのスクロール方法を選択します。指定できる値は、\"disabled\"、\"edge-scrolling\"、\"two-finger-scrolling\" です。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:9 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:128 + msgid "Enable mouse clicks with touchpad" + msgstr "タッチパッドでのマウスクリックを有効にする" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:10 +-msgid "Set this to TRUE to be able to send mouse clicks by tapping on the touchpad." ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:129 ++msgid "" ++"Set this to TRUE to be able to send mouse clicks by tapping on the touchpad." + msgstr "この値を TRUE にすると、タッチパッドをタップすることで、マウスクリックと同じ動作になるようにします。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:11 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:133 + msgid "Enable touchpad" + msgstr "タッチパッドを有効にする" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:12 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:134 + msgid "Set this to TRUE to enable all touchpads." + msgstr "この値を TRUE にすると、すべてのタッチパッドを有効にします。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:13 +-msgid "Highlights the current location of the pointer when the Control key is pressed and released." +-msgstr "コントロールキーが押されて、離された時、ポインターの現在位置をハイライトする" +- +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:14 +-msgid "Double click time" +-msgstr "ダブルクリックの時間" +- +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:15 +-msgid "Length of a double click in milliseconds." +-msgstr "ダブルクリックの長さ(ミリ秒単位)です。" +- +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:16 +-msgid "Drag threshold" +-msgstr "ドラッグのしきい値" ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:138 ++msgid "Touchpad button orientation" ++msgstr "タッチパッドボタンの方向" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:17 +-msgid "Distance before a drag is started." +-msgstr "ドラッグが開始されるまでの距離です。" ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:139 ++msgid "" ++"Swap left and right mouse buttons for left-handed mice with “left”, “right” " ++"for right-handed, “mouse” to follow the mouse setting." ++msgstr "左利き用のマウスボタンを「左」、右利き用のマウスボタンを「右」、マウスの設定に従うように「マウス」で左右を入れ替えます。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:18 +-msgid "Middle button emulation" +-msgstr "中ボタンのエミュレーション" ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:153 ++msgid "Natural scrolling" ++msgstr "ナチュラルスクロール" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:19 +-msgid "Enables middle mouse button emulation through simultaneous left and right button click." +-msgstr "マウスの中ボタンの左右ボタンの同時クリックによるエミュレーションを利用可能にします。" ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:154 ++msgid "Set this to TRUE to enable natural (reverse) scrolling for touchpads." ++msgstr "この値を TRUE にすると、すべてのタッチパッドのスクロールがナチュラル (逆) になります。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:20 +-msgid "Whether the tablet's orientation is locked, or rotated automatically." +-msgstr "タブレットの方向を固定するか自動的に回転するかです。" +- +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:21 +-msgid "Device hotplug custom command" +-msgstr "デバイスのホットプラグの独自コマンド" +- +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:22 +-msgid "Command to be run when a device is added or removed. An exit value of 1 means that the device will not be handled further by gnome-settings-daemon." +-msgstr "デバイスの接続または取り外し時に実行するコマンドです。終了ステータスが 1 である場合は、これ以上 gnome-settings-daemon によってデバイスが処理されないことを意味します。" +- +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:1 +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:1 +-#: ../data/org.gnome.settings-daemon.plugins.datetime.gschema.xml.in.in.h:1 +-#: ../data/org.gnome.settings-daemon.plugins.gschema.xml.in.in.h:3 +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:1 +-#: ../data/org.gnome.settings-daemon.plugins.keyboard.gschema.xml.in.in.h:1 +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:1 +-#: ../data/org.gnome.settings-daemon.plugins.orientation.gschema.xml.in.in.h:1 +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:1 +-#: ../data/org.gnome.settings-daemon.plugins.print-notifications.gschema.xml.in.in.h:1 +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:1 +-#: ../data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in.in.h:1 +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:1 +-msgid "Activation of this plugin" +-msgstr "このプラグインを有効化する" +- +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:2 +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:2 +-#: ../data/org.gnome.settings-daemon.plugins.datetime.gschema.xml.in.in.h:2 +-#: ../data/org.gnome.settings-daemon.plugins.gschema.xml.in.in.h:4 +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:2 +-#: ../data/org.gnome.settings-daemon.plugins.keyboard.gschema.xml.in.in.h:2 +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:2 +-#: ../data/org.gnome.settings-daemon.plugins.orientation.gschema.xml.in.in.h:2 +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:2 +-#: ../data/org.gnome.settings-daemon.plugins.print-notifications.gschema.xml.in.in.h:2 +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:2 +-#: ../data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in.in.h:2 +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:2 +-msgid "Whether this plugin would be activated by gnome-settings-daemon or not" +-msgstr "このプラグインを gnome-settings-daemon で有効化するかどうかです" +- +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:3 +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:3 +-#: ../data/org.gnome.settings-daemon.plugins.datetime.gschema.xml.in.in.h:3 +-#: ../data/org.gnome.settings-daemon.plugins.gschema.xml.in.in.h:5 +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:13 +-#: ../data/org.gnome.settings-daemon.plugins.keyboard.gschema.xml.in.in.h:3 +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:27 +-#: ../data/org.gnome.settings-daemon.plugins.orientation.gschema.xml.in.in.h:3 +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:3 +-#: ../data/org.gnome.settings-daemon.plugins.print-notifications.gschema.xml.in.in.h:3 +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:3 +-#: ../data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in.in.h:5 +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:7 +-msgid "Priority to use for this plugin" +-msgstr "このプラグインの優先度" +- +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:4 +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:4 +-#: ../data/org.gnome.settings-daemon.plugins.datetime.gschema.xml.in.in.h:4 +-#: ../data/org.gnome.settings-daemon.plugins.gschema.xml.in.in.h:6 +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:14 +-#: ../data/org.gnome.settings-daemon.plugins.keyboard.gschema.xml.in.in.h:4 +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:28 +-#: ../data/org.gnome.settings-daemon.plugins.orientation.gschema.xml.in.in.h:4 +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:4 +-#: ../data/org.gnome.settings-daemon.plugins.print-notifications.gschema.xml.in.in.h:4 +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:4 +-#: ../data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in.in.h:6 +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:8 +-msgid "Priority to use for this plugin in gnome-settings-daemon startup queue" +-msgstr "gnome-settings-daemon の起動時のキューで、このプラグインが使用される優先度" ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:161 ++msgid "Mouse wheel emulation button. 0 to disable the feature." ++msgstr "マウスホイールエミュレーションボタン。0 で機能を無効にします。" + + # stylus はそのままスタイラスとした。http://ja.wikipedia.org/wiki/%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%A9%E3%82%B9 +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:5 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:10 + msgid "Wacom stylus absolute mode" + msgstr "Wacom スタイラスの絶対座標モード" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:6 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:11 + msgid "Enable this to set the tablet to absolute mode." + msgstr "タブレットを絶対座標モードに設定することを可能にします。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:7 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:15 + msgid "Wacom tablet area" + msgstr "Wacom タブレットの範囲" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:8 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:16 + msgid "Set this to x1, y1 and x2, y2 of the area usable by the tools." + msgstr "以下の x1, y1 を、ツールで利用可能な領域 x2, y2 に設定します。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:9 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:20 + msgid "Wacom tablet aspect ratio" + msgstr "Wacom タブレットのアスペクト比" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:10 +-msgid "Enable this to restrict the Wacom tablet area to match the aspect ratio of the output." ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:21 ++msgid "" ++"Enable this to restrict the Wacom tablet area to match the aspect ratio of " ++"the output." + msgstr "Wacom タブレットの領域を出力のアスペクト比に一致させます。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:11 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:25 + msgid "Wacom tablet rotation" + msgstr "Wacom タブレットの回転" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:12 +-msgid "Set this to 'none', 'cw' for 90 degree clockwise, 'half' for 180 degree, and 'ccw' for 90 degree counterclockwise." +-msgstr "これを、'none'、90度時計回りの 'cw'、180度の 'half'、そして、90度反時計回りの 'ccw' に設定します。" ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:26 ++msgid "" ++"Set this to “none”, “cw” for 90 degree clockwise, “half” for 180 degree, and " ++"“ccw” for 90 degree counterclockwise." ++msgstr "これを、'none'、90 度時計回りの 'cw'、180度の 'half'、そして、90 度反時計回りの 'ccw' に設定します。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:13 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:30 + msgid "Wacom touch feature" + msgstr "Wacom のタッチ機能" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:14 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:31 + msgid "Enable this to move the cursor when the user touches the tablet." + msgstr "ユーザーがタブレットにタッチしたときにカーソルが動くようにします。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:15 +-msgid "Wacom tablet PC feature" +-msgstr "Wacom タブレット PC の機能" +- +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:16 +-msgid "Enable this to only report stylus events when the tip is pressed." +-msgstr "チップが押されたときにスタイラスイベントだけが送られるようにします。" +- +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:17 +-msgid "Wacom last calibrated resolution" +-msgstr "Wacom で最後にキャリブレーションした時の解像度" +- +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:18 +-msgid "Holds the last calibrated resolution to help check if calibration is needed." +-msgstr "キャリブレーションが必要かどうか判断できるように、最後にキャリブレーションした時の解像度を保持します。" +- +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:19 +-msgid "Wacom display mapping" +-msgstr "Wacom ディスプレイ・マッピング" +- +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:20 +-msgid "EDID information of monitor to map tablet to. Must be in the format [vendor, product, serial]. [\"\",\"\",\"\"] disables mapping." +-msgstr "モニターとタブレットのマップで EDID 情報を使用します。書式は、[vendor, product, serial] です。[\"\",\"\",\"\"] にするとマッピングできません。" +- +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:21 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:37 + msgid "Wacom stylus pressure curve" + msgstr "Wacom のスタイラスの圧力曲線" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:22 +-msgid "Set this to x1, y1 and x2, y2 of the pressure curve applied to the stylus." ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:38 ++msgid "" ++"Set this to x1, y1 and x2, y2 of the pressure curve applied to the stylus." + msgstr "以下の x1, y1 を、スタイラスの圧力曲線の x2, y2 に設定します。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:23 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:42 + msgid "Wacom stylus button mapping" + msgstr "Wacom スタイラスボタンのマッピング" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:24 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:43 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:60 + msgid "Set this to the logical button mapping." + msgstr "これをロジカルボタンのマッピングにします。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:25 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:47 + msgid "Wacom stylus pressure threshold" + msgstr "Wacom スタイラスの圧力しきい値" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:26 +-msgid "Set this to the pressure value at which a stylus click event is generated." ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:48 ++msgid "" ++"Set this to the pressure value at which a stylus click event is generated." + msgstr "これをスタイラスがクリックイベントを生成するしきい値にします。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:27 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:54 + msgid "Wacom eraser pressure curve" + msgstr "Wacom の消しゴムツールの圧力曲線" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:28 +-msgid "Set this to x1, y1 and x2, y2 of the pressure curve applied to the eraser." ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:55 ++msgid "" ++"Set this to x1, y1 and x2, y2 of the pressure curve applied to the eraser." + msgstr "以下の x1, y1 を、消しゴムツールの圧力曲線の x2, y2 に設定します。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:29 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:59 + msgid "Wacom eraser button mapping" + msgstr "Wacom の消しゴムボタンのマッピング" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:30 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:64 + msgid "Wacom eraser pressure threshold" + msgstr "Wacom 消しゴムツールの圧力しきい値" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:31 +-msgid "Set this to the pressure value at which an eraser click event is generated." ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:65 ++msgid "" ++"Set this to the pressure value at which an eraser click event is generated." + msgstr "これを消しゴムツールがクリックイベントを生成するしきい値にします。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:32 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:71 + msgid "Wacom button action type" + msgstr "Wacom ボタンアクションの型" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:33 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:72 + msgid "The type of action triggered by the button being pressed." + msgstr "ボタンが押された時に実行されるアクションの型です。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:34 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:76 + msgid "Key combination for the custom action" + msgstr "独自アクションのキーの組み合わせ" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:35 +-msgid "The keyboard shortcut generated when the button is pressed for custom actions." ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:77 ++msgid "" ++"The keyboard shortcut generated when the button is pressed for custom " ++"actions." + msgstr "独自アクションのボタンが押されたときに生成されるキーボードショートカットです。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:36 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:81 + msgid "Key combinations for a touchring or touchstrip custom action" + msgstr "タッチホイールやトラックパッドの独自アクションのキーの組み合わせ" + + # touchring を タッチホイール touchstrip を トラックパッド と訳出 +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:37 +-msgid "The keyboard shortcuts generated when a touchring or touchstrip is used for custom actions (up followed by down)." ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:82 ++msgid "" ++"The keyboard shortcuts generated when a touchring or touchstrip is used for " ++"custom actions (up followed by down)." + msgstr "タッチホイールやトラックパッドがカスタムアクションのために (上から順番に) 使用されるとき、生成されるキーボードショートカットです。" + + #. Translators: This is the OLED display on an Intuos4 tablet: + #. http://eu.shop.wacom.eu/images/articles/d9abd9f2d4d88aa0649cda97a8077e2b_8.jpg +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:40 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:88 + msgid "Button label for OLED display." +-msgstr "OLED ディスプレイのボタンラベル" ++msgstr "OLED ディスプレイのボタンラベル。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:41 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:89 + msgid "Label will be rendered to OLED display belonging to the button" +-msgstr "ボタンに対応する OLED ディスプレイに表示されるラベルです。" ++msgstr "ボタンに対応する OLED ディスプレイに表示されるラベルです" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:5 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:6 + msgid "The duration a display profile is valid" + msgstr "ディスプレイ・プロファイルの有効時間" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:6 +-msgid "This is the number of days after which the display color profile is considered invalid." ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:7 ++msgid "" ++"This is the number of days after which the display color profile is " ++"considered invalid." + msgstr "ディスプレイ・カラープロファイルが実施されてから、無効とされるまでの日数です。" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:7 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:11 + msgid "The duration a printer profile is valid" + msgstr "プリンター・プロファイルの有効時間" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:8 +-msgid "This is the number of days after which the printer color profile is considered invalid." ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:12 ++msgid "" ++"This is the number of days after which the printer color profile is " ++"considered invalid." + msgstr "プリンター・カラープロファイルが実施されてから、無効とされるまでの日数です。" + +-#: ../data/org.gnome.settings-daemon.plugins.gschema.xml.in.in.h:1 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:16 ++msgid "If the night light mode is enabled" ++msgstr "ナイトライトモードが有効な場合" ++ ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:17 ++msgid "" ++"Night light mode changes the color temperature of your display when the sun " ++"has gone down or at preset times." ++msgstr "ナイトライトモードでは、太陽が沈んだとき、またはあらかじめ設定した時間にディスプレイの色温度を変更します。" ++ ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:21 ++msgid "Temperature of the display when enabled" ++msgstr "有効時のディスプレイの温度" ++ ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:22 ++msgid "" ++"This temperature in Kelvin is used to modify the screen tones when night " ++"light mode is enabled. Higher values are bluer, lower redder." ++msgstr "この温度 (ケルビン) は、ナイトライトモードが有効のときに画面のトーンを変更するために使用されます。値が高いほど青く、低いほど赤くなります。" ++ ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:26 ++msgid "Use the sunrise and sunset" ++msgstr "日の出と日の入りを使用" ++ ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:27 ++msgid "" ++"Calculate the sunrise and sunset times automatically, from the current " ++"location." ++msgstr "現在地から日の出と日の入りの時間を自動的に計算します。" ++ ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:31 ++msgid "The start time" ++msgstr "開始時刻" ++ ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:32 ++msgid "" ++"When “night-light-schedule-automatic” is disabled, use this start time in " ++"hours from midnight." ++msgstr "“night-light-schedule-automatic” を無効にすると、この開始時刻を 0 時からの時間単位で使用します。" ++ ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:36 ++msgid "The end time" ++msgstr "終了時刻" ++ ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:37 ++msgid "" ++"When “night-light-schedule-automatic” is disabled, use this end time in " ++"hours from midnight." ++msgstr "“night-light-schedule-automatic” を無効にすると、この終了時刻を 0 時からの時間単位で使用します。" ++ ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:41 ++msgid "The last detected position" ++msgstr "最後に検出した位置" ++ ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:42 ++msgid "" ++"When location services are available this represents the last detected " ++"location. The default value is an invalid value to ensure it is always " ++"updated at startup." ++msgstr "位置情報サービスが利用可能な場合、最後に検出された位置情報を表します。このデフォルト値は、起動時に常に更新されるようにするために無効な値になっています。" ++ ++#: data/org.gnome.settings-daemon.plugins.gschema.xml.in:6 + msgid "List of plugins that are allowed to be loaded" + msgstr "ロードを許可するプラグインのリスト" + +-#: ../data/org.gnome.settings-daemon.plugins.gschema.xml.in.in.h:2 +-msgid "A list of strings representing the plugins that are allowed to be loaded (default: 'all'). The plugins still need to be marked as active to get loaded. This is only evaluated on startup." +-msgstr "ロードを許可するプラグインを表す文字列のリストです (デフォルト: 'all')。プラグインを読み込むには、さらにそれぞれが有効化対象としてマーキングされている必要があります。このキーは起動時にだけ評価されます。" ++#: data/org.gnome.settings-daemon.plugins.gschema.xml.in:7 ++msgid "" ++"A list of strings representing the plugins that are allowed to be loaded " ++"(default: “all”). This is only evaluated on startup." ++msgstr "ロードを許可するプラグインを表す文字列のリストです (デフォルト: all)。これは起動時にだけ評価されます。" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:3 ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:6 + msgid "Mount paths to ignore" + msgstr "無視するマウントパス" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:4 ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:7 + msgid "Specify a list of mount paths to ignore when they run low on space." +-msgstr "残り容量が少なくても無視するマウントパスの一覧を指定します" ++msgstr "残り容量が少なくても無視するマウントパスの一覧を指定します。" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:5 ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:12 + msgid "Free percentage notify threshold" + msgstr "空きパーセンテージ通知の閾値" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:6 +-msgid "Percentage free space threshold for initial warning of low disk space. If the percentage free space drops below this, a warning will be shown." ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:13 ++msgid "" ++"Percentage free space threshold for initial warning of low disk space. If " ++"the percentage free space drops below this, a warning will be shown." + msgstr "ディスクの残り容量が少なくなった時に最初に警告する閾値となる残り容量のパーセンテージです。残り容量のパーセンテージがこの値を下まわれば、警告が表示されます。" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:7 ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:18 + msgid "Subsequent free space percentage notify threshold" + msgstr "空き容量の連続通知のパーセンテージの閾値" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:8 +-msgid "Specify the percentage that the free disk space should reduce by before issuing a subsequent warning." ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:19 ++msgid "" ++"Specify the percentage that the free disk space should reduce by before " ++"issuing a subsequent warning." + msgstr "空き容量の警告を連続して出す前に、何パーセント空き容量を減らさなくてはならないかを指定します。" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:9 ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:23 + msgid "Free space notify threshold" + msgstr "空き容量の通知の閾値" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:10 +-msgid "Specify an amount in GB. If the amount of free space is more than this, no warning will be shown." ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:24 ++msgid "" ++"Specify an amount in GB. If the amount of free space is more than this, no " ++"warning will be shown." + msgstr "容量をGB単位で指定します。空き容量がこの値を上まわれば、警告は表示されません。" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:11 ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:28 + msgid "Minimum notify period for repeated warnings" + msgstr "警告の繰り返しの最小通知間隔" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:12 +-msgid "Specify a time in minutes. Subsequent warnings for a volume will not appear more often than this period." ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:29 ++msgid "" ++"Specify a time in minutes. Subsequent warnings for a volume will not appear " ++"more often than this period." + msgstr "時間を分単位で指定します。この時間より短い間隔で容量の警告を表示することはありません。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:3 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:6 + msgid "Custom keybindings" + msgstr "独自のキーバインディング" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:4 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:7 + msgid "List of custom keybindings" + msgstr "独自のキーバインディングのリスト" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:5 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:11 + msgid "Launch calculator" + msgstr "電卓を起動する" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:6 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:12 + msgid "Binding to launch the calculator." + msgstr "電卓を起動するキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:7 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:16 ++msgid "Launch settings" ++msgstr "起動設定" ++ ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:17 ++msgid "Binding to launch GNOME settings." ++msgstr "GNOME 設定を起動するためのキーバインディングです。" ++ ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:21 + msgid "Launch email client" + msgstr "E-メールクライアントを起動する" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:8 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:22 + msgid "Binding to launch the email client." + msgstr "E-メールクライアントを起動するキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:9 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:26 + msgid "Eject" + msgstr "メディアを取り出す" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:10 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:27 + msgid "Binding to eject an optical disc." + msgstr "光学ディスクを取り出すキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:11 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:31 + msgid "Launch help browser" + msgstr "ヘルプブラウザーを起動する" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:12 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:32 + msgid "Binding to launch the help browser." + msgstr "ヘルプブラウザーを起動するキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:13 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:36 + msgid "Home folder" + msgstr "ホームフォルダーを開く" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:14 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:37 + msgid "Binding to open the Home folder." + msgstr "ホームフォルダーを開くキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:15 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:41 + msgid "Launch media player" + msgstr "メディアプレーヤーを起動する" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:16 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:42 + msgid "Binding to launch the media player." + msgstr "メディアプレーヤーを起動するキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:17 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:46 + msgid "Next track" + msgstr "次のトラックに進む" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:18 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:47 + msgid "Binding to skip to next track." + msgstr "次のトラックにスキップするキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:19 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:51 + msgid "Pause playback" + msgstr "再生を一時停止する" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:20 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:52 + msgid "Binding to pause playback." + msgstr "再生を一時停止するキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:21 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:56 + msgid "Play (or play/pause)" + msgstr "再生する (または再生/一時停止する)" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:22 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:57 + msgid "Binding to start playback (or toggle play/pause)." + msgstr "再生を開始する (または再生と一時停止を切り替える) キーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:23 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:61 + msgid "Log out" + msgstr "ログアウトする" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:24 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:62 + msgid "Binding to log out." + msgstr "ログアウトするキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:25 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:66 + msgid "Previous track" + msgstr "前のトラックに戻る" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:26 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:67 + msgid "Binding to skip to previous track." + msgstr "前のトラックにスキップするキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:29 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:71 + msgid "Lock screen" + msgstr "画面をロックする" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:30 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:72 + msgid "Binding to lock the screen." + msgstr "画面をロックするキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:31 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:76 + msgid "Search" + msgstr "検索する" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:32 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:77 + msgid "Binding to launch the search tool." + msgstr "検索ツールを起動するキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:33 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:81 + msgid "Stop playback" + msgstr "再生を停止する" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:34 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:82 + msgid "Binding to stop playback." + msgstr "再生を停止するキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:35 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:86 + msgid "Volume down" + msgstr "音量を下げる" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:36 +-msgid "Binding to lower the system volume." ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:87 ++msgid "Binding to lower the volume." + msgstr "システムの音量を小さくするキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:37 +-msgid "Volume mute" +-msgstr "ミュートにする" ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:91 ++msgid "Volume mute/unmute" ++msgstr "システムの音量のミュート/ミュート解除" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:38 +-msgid "Binding to mute the system volume." +-msgstr "システムの音量をミュート (無音) にするキーバインディングです。" ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:92 ++msgid "Binding to mute/unmute the volume." ++msgstr "システムの音量をミュート (無音) またはミュート解除するキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:39 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:96 + msgid "Volume up" + msgstr "音量を上げる" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:40 +-msgid "Binding to raise the system volume." ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:97 ++msgid "Binding to raise the volume." + msgstr "システムの音量を大きくするキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:41 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:101 ++msgid "Microphone mute/unmute" ++msgstr "マイクのミュート/ミュート解除" ++ ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:102 ++msgid "Binding to mute/unmute the microphone." ++msgstr "システムの音量をミュート (無音) にするキーバインディングです。" ++ ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:106 + msgid "Take a screenshot" + msgstr "スクリーンショットを撮る" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:42 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:107 + msgid "Binding to take a screenshot." + msgstr "スクリーンショットを撮るキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:43 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:111 + msgid "Take a screenshot of a window" + msgstr "ウィンドウのスクリーンショットを撮る" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:44 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:112 + msgid "Binding to take a screenshot of a window." + msgstr "ウィンドウのスクリーンショットを撮るキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:45 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:116 + msgid "Take a screenshot of an area" + msgstr "選択領域のスクリーンショットを撮る" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:46 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:117 + msgid "Binding to take a screenshot of an area." + msgstr "選択領域のスクリーンショットを撮るキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:47 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:121 + msgid "Copy a screenshot to clipboard" + msgstr "スクリーンショットをクリップボードにコピーする" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:48 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:122 + msgid "Binding to copy a screenshot to clipboard." + msgstr "スクリーンショットをクリップボードにコピーするキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:49 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:126 + msgid "Copy a screenshot of a window to clipboard" + msgstr "ウィンドウのスクリーンショットをクリップボードにコピーする" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:50 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:127 + msgid "Binding to copy a screenshot of a window to clipboard." + msgstr "ウィンドウのスクリーンショットをクリップボードにコピーするキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:51 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:131 + msgid "Copy a screenshot of an area to clipboard" + msgstr "選択領域のスクリーンショットをクリップボードにコピーする" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:52 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:132 + msgid "Binding to copy a screenshot of an area to clipboard." + msgstr "選択領域のスクリーンショットをクリップボードにコピーするキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:53 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:136 + msgid "Record a short video of the screen" + msgstr "画面の動画 (スクリーンキャスト) を撮る" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:54 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:137 ++msgid "Binding to record a short video of the screen" ++msgstr "画面の動画 (スクリーンキャスト) を撮るキーバインディグ" ++ ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:141 + msgid "Launch web browser" + msgstr "ウェブブラウザーを起動する" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:55 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:142 + msgid "Binding to launch the web browser." + msgstr "ウェブブラウザーを起動するキーバインディングです。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:56 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:146 + msgid "Toggle magnifier" + msgstr "拡大鏡のオン/オフ切り替え" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:57 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:147 + msgid "Binding to show the screen magnifier" + msgstr "拡大鏡のオン/オフを切り替えるキーバインディングです" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:58 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:151 + msgid "Toggle screen reader" + msgstr "スクリーンリーダーのオン/オフ切り替え" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:59 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:152 + msgid "Binding to start the screen reader" + msgstr "スクリーンリーダーのオン/オフを切り替えるキーバインディングです" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:60 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:156 + msgid "Toggle on-screen keyboard" + msgstr "オンスクリーンキーボードのオン/オフ切り替え" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:61 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:157 + msgid "Binding to show the on-screen keyboard" + msgstr "オンスクリーンキーボードのオン/オフを切り替えるキーバインディングです" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:62 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:161 + msgid "Increase text size" + msgstr "文字サイズの拡大" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:63 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:162 + msgid "Binding to increase the text size" + msgstr "文字サイズを拡大するキーバインディングです" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:64 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:166 + msgid "Decrease text size" + msgstr "文字サイズの縮小" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:65 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:167 + msgid "Binding to decrease the text size" + msgstr "文字サイズを縮小するキーバインディングです" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:66 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:171 + msgid "Toggle contrast" + msgstr "コントラストの切り替え" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:67 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:172 + msgid "Binding to toggle the interface contrast" + msgstr "インターフェースのコントラストを切り替えるキーバインディングです" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:68 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:176 + msgid "Magnifier zoom in" + msgstr "拡大鏡ズームイン" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:69 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:177 + msgid "Binding for the magnifier to zoom in" +-msgstr "拡大鏡をズームインするキーバインディングです。" ++msgstr "拡大鏡をズームインするキーバインディングです" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:70 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:181 + msgid "Magnifier zoom out" + msgstr "拡大鏡ズームアウト" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:71 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:182 + msgid "Binding for the magnifier to zoom out" + msgstr "拡大鏡をズームアウトするキーバインディングです" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:72 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:186 ++msgid "Maximum length of screen recordings" ++msgstr "画面録画の最大長さ" ++ ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:187 ++msgid "" ++"The maximum length of single screen cast recordings in seconds or 0 for " ++"unlimited" ++msgstr "1 画面のキャスト録画の最大長さ (ミリ秒または、無制限には 0)" ++ ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:194 + msgid "Name" + msgstr "名前" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:73 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:195 + msgid "Name of the custom binding" + msgstr "独自のキーバインディングの名前です" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:74 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:199 + msgid "Binding" + msgstr "キーバインディング" + + # カスタムキーバインディングをバインドすること? +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:75 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:200 + msgid "Binding for the custom binding" + msgstr "独自のキーバインディングのためのキーバインディングです" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:76 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:204 + msgid "Command" + msgstr "コマンド" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:77 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:205 + msgid "Command to run when the binding is invoked" + msgstr "キーバインディングの呼び出し時に実行するコマンドです" + +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:5 +-msgid "Percentage considered low" +-msgstr "バッテリー残量低下と認識するパーセンテージ" +- +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:6 +-msgid "The percentage of the battery when it is considered low. Only valid when use-time-for-policy is false." +-msgstr "バッテリー残量が低下していると認識するパーセンテージです。use-time-for-policy が false のときだけ有効です。" +- +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:7 +-msgid "Percentage considered critical" +-msgstr "バッテリー残量が危険領域と認識するパーセンテージ" +- +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:8 +-msgid "The percentage of the battery when it is considered critical. Only valid when use-time-for-policy is false." +-msgstr "バッテリー残量が危険領域だと認識するパーセンテージです。use-time-for-policy が false のときだけ有効です。" +- +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:9 +-msgid "Percentage action is taken" +-msgstr "アクションを実施するパーセンテージ" +- +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:10 +-msgid "The percentage of the battery when the critical action is performed. Only valid when use-time-for-policy is false." +-msgstr "危険領域のアクションを実施するバッテリー残量のパーセンテージ。use-time-for-policy が false のときだけ有効です。" +- +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:11 +-msgid "The time remaining when low" +-msgstr "残量低下時の残り時間" +- +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:12 +-msgid "The time remaining in seconds of the battery when it is considered low. Only valid when use-time-for-policy is true." +-msgstr "残量低下時のバッテリーの残り秒数です。use-time-for-policy が true のときだけ有効です。" +- +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:13 +-msgid "The time remaining when critical" +-msgstr "残量が危険領域時の残り時間" +- +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:14 +-msgid "The time remaining in seconds of the battery when it is considered critical. Only valid when use-time-for-policy is true." +-msgstr "残量が危険領域時のバッテリーの残り秒数です。use-time-for-policy が true のときだけ有効です。" +- +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:15 +-msgid "The time remaining when action is taken" +-msgstr "アクション実施時のバッテリーの残り秒数" +- +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:16 +-msgid "The time remaining in seconds of the battery when critical action is taken. Only valid when use-time-for-policy is true." +-msgstr "危険領域時のアクション実施時のバッテリーの残り秒数です。use-time-for-policy が true のときだけ有効です。" +- +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:17 +-msgid "Whether to use time-based notifications" +-msgstr "時間基準の通知を使用するかどうか" +- +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:18 +-msgid "If time based notifications should be used. If set to false, then the percentage change is used instead, which may fix a broken ACPI BIOS." +-msgstr "時間基準の通知を使用するかどうかです。false に設定されている場合、パーセンテージの変化が代わりに使用され、壊れた ACPI BIOS を正してくれます。" +- +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:19 +-msgid "If we should show the recalled battery warning for a broken battery" +-msgstr "壊れたバッテリーに対して、リコールされたバッテリーだという警告を再び表示させるかどうか" +- +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:20 +-msgid "If we should show the recalled battery warning for a broken battery. Set this to false only if you know your battery is okay." +-msgstr "壊れたバッテリーに対して、リコールされたバッテリーだという警告を再び表示させるかどうかです。これを false に指定した場合、バッテリーが良好かどうかを知ることしかできません。" +- +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:5 +-msgid "Use mobile broadband connections" +-msgstr "モバイルブロードバンド接続を使用する" ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:6 ++msgid "The brightness of the screen when idle" ++msgstr "アイドル時の画面の明るさ" + +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:6 +-msgid "Use mobile broadband connections such as GSM and CDMA to check for updates." +-msgstr "更新の確認に GSM や CDMA などのモバイルブロードバンド接続を使用します。" +- +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:7 +-msgid "Automatically download updates in the background without confirmation" +-msgstr "バックグラウンドで自動的に更新をダウンロードする" +- +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:8 +-msgid "Automatically download updates in the background without confirmation. Updates will be auto-downloaded when using wired network connnections, and mobile broadband if 'connection-use-mobile' is enabled." +-msgstr "バックグラウンドで自動的に更新をダウンロードします。有線ネットワーク接続を使用しているとき、また 'connection-use-mobile' が有効でモバイルブロードバンドを使用しているときに、自動的に更新をダウンロードします。" +- +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:9 +-msgid "How often to check for updates" +-msgstr "更新の確認頻度" +- +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:10 +-msgid "How often to check for updates. Value is in seconds. This is a maximum amount of time that can pass between a security update being published, and the update being automatically installed or the user notified." +-msgstr "更新の確認頻度です。値は秒単位です。この最大時間は、セキュリティ更新の間隔になり、更新は自動的にインストールされる、またはユーザーに通知されます。" +- +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:11 +-msgid "How often to notify the user that non-critical updates are available" +-msgstr "クリティカルでない更新をユーザーに通知する頻度" +- +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:12 +-msgid "How often to tell the user there are non-critical updates. Value is in seconds. Security update notifications are always shown after the check for updates, but non-critical notifications should be shown a lot less frequently." +-msgstr "クリティカルではない更新が利用可能である場合にユーザーに通知する頻度です。値は秒単位です。セキュリティの更新の通知は、更新の調査後に毎回表示され、クリティカルではない通知はそれより低頻度で表示されます。" +- +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:13 +-msgid "The last time we told the user about non-critical notifications" +-msgstr "ユーザーにクリティカルではない通知を最後に行った時間" +- +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:14 +-msgid "The last time we notified the user about non-critical updates. Value is in seconds since the epoch, or zero for never." +-msgstr "ユーザーにクリティカルではない更新の通知を最後に行った時間です。値は、エポックからの秒単位、または、通知されていない場合のゼロです。" +- +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:15 +-msgid "How often to check for distribution upgrades" +-msgstr "ディストリビューションの更新の確認頻度" +- +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:16 +-msgid "How often to check for distribution upgrades. Value is in seconds." +-msgstr "ディストリビューションの更新の確認頻度です。値は秒単位です。" +- +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:17 +-msgid "How often to refresh the package cache" +-msgstr "パッケージキャッシュのリフレッシュ頻度" +- +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:18 +-msgid "How often to refresh the package cache. Value is in seconds." +-msgstr "パッケージキャッシュのリフレッシュ頻度です。値は秒単位です。" +- +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:19 +-msgid "Check for updates when running on battery power" +-msgstr "バッテリー電源での動作時に更新を確認する" +- +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:20 +-msgid "Check for updates when running on battery power." +-msgstr "バッテリー電源で動作しているときに更新を確認します。" ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:7 ++msgid "" ++"This is the laptop panel screen brightness used when the session is idle." ++msgstr "これは、セッションがアイドル状態のときに使用されるラップトップパネルの画面の明るさです。" + +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:21 +-msgid "Notify the user when distribution upgrades are available" +-msgstr "ディストリビューションの更新が利用可能になったときにユーザーに通知する" ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:11 ++msgid "Dim the screen after a period of inactivity" ++msgstr "操作しなくなってから一定の期間の後に画面を暗くする" + +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:22 +-msgid "Notify the user when distribution upgrades are available." +-msgstr "ディストリビューションの更新が利用可能になったときにユーザーに通知します。" ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:12 ++msgid "If the screen should be dimmed to save power when the computer is idle." ++msgstr "コンピューターがアイドル状態のときに節電のために画面を暗くする必要がある場合。" + +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:23 +-msgid "Ask the user if additional firmware should be installed" +-msgstr "追加のファームウェアをインストールするかユーザーに確認する" ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:16 ++msgid "Sleep timeout computer when on AC" ++msgstr "AC 接続時のコンピューターのスリープタイムアウト" + +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:24 +-msgid "Ask the user if additional firmware should be installed if it is available." +-msgstr "追加のファームウェアが利用可能である場合、インストールするかユーザーに確認します。" ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:17 ++msgid "" ++"The amount of time in seconds the computer on AC power needs to be inactive " ++"before it goes to sleep. A value of 0 means never." ++msgstr "AC 電源を使用しているコンピューターがスリープ状態になるまでの非アクティブの時間を秒単位で指定します。値が 0 の場合は、スリープ状態になりません。" + +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:25 +-msgid "Firmware files that should not be searched for" +-msgstr "検索しないファームウェアファイル" ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:21 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:31 ++msgid "Whether to hibernate, suspend or do nothing when inactive" ++msgstr "非アクティブ時にハイバネーションまたはサスペンドを行うか、または何もしないかどうか" + +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:26 +-msgid "Firmware files that should not be searched for, separated by commas. These can include '*' and '?' characters." +-msgstr "検索しないファームウェアファイルです。カンマで区切ります。'*' と '?' 文字を含めることができます。" ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:22 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:32 ++msgid "" ++"The type of sleeping that should be performed when the computer is inactive." ++msgstr "コンピューターが動作していない時に行うスリープのタイプ。" + +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:27 +-msgid "Devices that should be ignored" +-msgstr "無視するデバイス" ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:26 ++msgid "Sleep timeout computer when on battery" ++msgstr "バッテリー使用時コンピューターのスリープタイムアウト" + +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:28 +-msgid "Devices that should be ignored, separated by commas. These can include '*' and '?' characters." +-msgstr "カンマで分離された無視するデバイスです。 '*' と '?' 文字を含めてもかまいません。" ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:27 ++msgid "" ++"The amount of time in seconds the computer on battery power needs to be " ++"inactive before it goes to sleep. A value of 0 means never." ++msgstr "バッテリーのみで使用しているコンピューターがスリープ状態になるまでの非アクティブの時間を秒単位で指定します。値が 0 の場合は、スリープ状態になりません。" + +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:29 +-msgid "The filenames on removable media that designate it a software source." +-msgstr "ソフトウェアのソースとなるリムーバブルメディア上のファイル名です。" ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:36 ++msgid "Enable the ALS sensor" ++msgstr "ALS センサーを有効にする" + +-#: ../data/org.gnome.settings-daemon.plugins.updates.gschema.xml.in.in.h:30 +-msgid "When removable media is inserted, it is checked to see if it contains any important filenames in the root directory. If the filename matches, then an updates check is performed. This allows post-install disks to be used to update running systems." +-msgstr "リムーバブルメディアが挿入された時、ルートディレクトリに重要なファイル名が含まれていないかどうか調査します。ファイル名が一致した場合、更新の調査が実行されます。これで、すでにインストールしたディスクで実行中のシステムを更新することが可能になります。" ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:37 ++msgid "If the ambient light sensor functionality is enabled." ++msgstr "環境光センサー機能が有効な場合。" + +-#: ../data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in.in.h:3 +-msgid "File for default configuration for RandR" +-msgstr "RandR の初期設定ファイル" ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:41 ++msgid "Power button action" ++msgstr "電源ボタンアクション" + +-#: ../data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in.in.h:4 +-msgid "The XRandR plugin will look for a default configuration in the file specified by this key. This is similar to the ~/.config/monitors.xml that normally gets stored in users' home directories. If a user does not have such a file, or has one that does not match the user's setup of monitors, then the file specified by this key will be used instead." +-msgstr "XRandR プラグインはこのキーで指定されたファイルをデフォルトの設定ファイルとして検索します。これは通常、ユーザーのホームディレクトリに保存されている ~/.config/monitors.xml と同様のものです。もしそのようなファイルが無い場合、あるいはあったとしてもモニターの設定に合わない場合、このキーで指定されたファイルが代わりに使われます。" ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:42 ++msgid "" ++"The action to take when the system power button is pressed. This action is " ++"hard-coded (and the setting ignored) on virtual machines (power off) and " ++"tablets (suspend)." ++msgstr "システムの電源ボタンが押されたときに行うアクションです。このアクションは、仮想マシン (電源オフ) やタブレット (サスペンド) ではハードコードされています (設定は無視されます)。" + +-#: ../data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in.in.h:7 +-msgid "Whether to turn off specific monitors after boot" +-msgstr "ブート後に特定のモニターをオフにするかどうか" ++#: data/org.gnome.settings-daemon.plugins.sharing.gschema.xml.in:6 ++msgid "On which connections the service is enabled" ++msgstr "サービスが有効になっている接続" + +-#: ../data/org.gnome.settings-daemon.plugins.xrandr.gschema.xml.in.in.h:8 +-msgid "'clone' will display the same thing on all monitors, 'dock' will switch off the internal monitor, 'do-nothing' will use the default Xorg behaviour (extend the desktop in recent versions). The default, 'follow-lid', will choose between 'do-nothing' and 'dock' depending on whether the lid is (respectively) open or closed." +-msgstr "'clone' はすべてのモニターで同じ表示を行います。'dock' は内部モニターをオフにします。'do-nothing' はデフォルトの Xorg の動作になります (最近のバージョンではデスクトップを拡張します)。デフォルト値となる 'follow-lid' は、蓋が開いているか閉じているかによって、それぞれ 'do-nothing' か 'dock' かどちらかと同じ挙動になります。" ++#: data/org.gnome.settings-daemon.plugins.sharing.gschema.xml.in:7 ++msgid "" ++"The list of NetworkManager connections (each one represented with its UUID) " ++"on which this service is enabled and started." ++msgstr "このサービスが有効化され、開始された NetworkManager 接続のリスト (各接続はその UUID で表されます)。" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:3 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:6 + msgid "Antialiasing" + msgstr "アンチエイリアス" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:4 +-msgid "The type of antialiasing to use when rendering fonts. Possible values are: \"none\" for no antialiasing, \"grayscale\" for standard grayscale antialiasing, and \"rgba\" for subpixel antialiasing (LCD screens only)." +-msgstr "フォントを描画する際に使用するアンチエイリアスの種類を指定します。利用可能な値: \"none\" はアンチエイリアスを無効にする、\"grayscale\" は標準的なグレースケールのアンチエイリアス、\"rgba\" はサブピクセルをアンチエイリアスする (LCD 画面の場合のみ)" ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:7 ++msgid "" ++"The type of antialiasing to use when rendering fonts. Possible values are: " ++"“none” for no antialiasing, “grayscale” for standard grayscale antialiasing, " ++"and “rgba” for subpixel antialiasing (LCD screens only)." ++msgstr "フォントを描画する際に使用するアンチエイリアスの種類を指定します。利用可能な値: アンチエイリアスを無効にする \"none\"、標準的なグレースケールのアンチエイリアス \"grayscale\"、サブピクセルをアンチエイリアスする \"rgba\" (LCD 画面の場合のみ)。" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:5 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:11 + msgid "Hinting" + msgstr "ヒンティング" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:6 +-msgid "The type of hinting to use when rendering fonts. Possible values are: \"none\" for no hinting, \"slight\" for basic, \"medium\" for moderate, and \"full\" for maximum hinting (may cause distortion of letter forms)." +-msgstr "フォントを描画する際に使用するヒンティング (線幅を補正する) の種類を指定します。利用可能な値: \"none\" はヒンティングを無効にする、\"slight\" は基本的なヒンティングのみ、\"medium\" は穏やかなヒンティング、\"full\" は最大限のヒンティング (文字の形状に歪みが発生する可能性あり)" +- +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:9 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:12 ++msgid "" ++"The type of hinting to use when rendering fonts. Possible values are: “none” " ++"for no hinting and “slight” for fitting only to the Y-axis like Microsoft’s " ++"ClearType, DirectWrite and Adobe’s proprietary font rendering engine. " ++"Ignores native hinting within the font, generates hints algorithmically. " ++"Used on Ubuntu by default. Recommended. The meaning of “medium” and “full” " ++"depends on the font format (.ttf, .otf, .pfa/.pfb) and the installed version " ++"of FreeType. They usually try to fit glyphs to both the X and the Y axis " ++"(except for .otf: Y-only). This can lead to distortion and/or inconsistent " ++"rendering depending on the quality of the font, the font format and the " ++"state of FreeType’s font engines." ++msgstr "フォントをレンダリングする際に使用するヒンティングのタイプ。指定可能な値: ヒンティングを行わない場合は \"none\"、Microsoft の ClearType や DirectWrite、Adobe の独自のフォントレンダリングエンジンのような Y 軸にのみフィットさせる \"slight\"。フォント内のネイティブヒンティングを無視し、アルゴリズム的にヒンティングを生成します。デフォルトで Ubuntu で使用されています。推奨されています。\"medium\" や \"full\" の意味は、フォントフォーマット (.ttf, .otf, .pfa/.pfb) と、インストールされている FreeType のバージョンによって異なります。これらのフォントは通常、グリフを X 軸と Y 軸の両方に合わせようとします (.otf: Y 軸のみを除く)。これは、フォントの品質やフォントフォーマット、FreeType のフォントエンジンの状態によっては、歪みが生じたり、レンダリングに一貫性がなくなったりする可能性があります。" ++ ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:16 + msgid "RGBA order" + msgstr "RGBA の順番" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:10 +-msgid "The order of subpixel elements on an LCD screen; only used when antialiasing is set to \"rgba\". Possible values are: \"rgb\" for red on left (most common), \"bgr\" for blue on left, \"vrgb\" for red on top, \"vbgr\" for red on bottom." +-msgstr "LCD 画面でサブピクセルの各要素の順番を指定します (これは Antialiasing を \"rgba\" にセットした時にのみ適用されます)。利用可能な値: \"rgb\" は左端が赤色 (最も一般的)、\"bgr\" は左端が青色、\"vrgb\" は上端が赤色、\"vbgr\" は下端が赤色" ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:17 ++msgid "" ++"The order of subpixel elements on an LCD screen; only used when antialiasing " ++"is set to “rgba”. Possible values are: “rgb” for red on left (most common), " ++"“bgr” for blue on left, “vrgb” for red on top, “vbgr” for red on bottom." ++msgstr "LCD 画面でサブピクセルの各要素の順番を指定します (これは、アンチエイリアスを \"rgba\" にセットした時にのみ適用されます)。利用可能な値: \"rgb\" (左端が赤色) (最も一般的)、\"bgr\" (左端が青色)、\"vrgb\" (上端が赤色)、\"vbgr\" (下端が赤色)。" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:11 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:21 + msgid "List of explicitly disabled GTK+ modules" + msgstr "明示的に利用不可能な GTK+ モジュールのリスト" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:12 +-msgid "A list of strings representing the GTK+ modules that will not be loaded, even if enabled by default in their configuration." ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:22 ++msgid "" ++"A list of strings representing the GTK+ modules that will not be loaded, " ++"even if enabled by default in their configuration." + msgstr "ロードしない GTK+ モジュールを示す文字列のリストです。デフォルト設定では有効になっているものも指定できます。" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:13 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:26 + msgid "List of explicitly enabled GTK+ modules" + msgstr "明示的に利用可能な GTK+ モジュールのリスト" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:14 +-msgid "A list of strings representing the GTK+ modules that will be loaded, usually in addition to conditional and forcibly disabled ones." ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:27 ++msgid "" ++"A list of strings representing the GTK+ modules that will be loaded, usually " ++"in addition to conditional and forcibly disabled ones." + msgstr "ロードする GTK+ モジュールを示す文字列のリストです。デフォルト設定では無効になっているものも指定できます。" + +-#: ../gnome-settings-daemon/main.c:52 +-msgid "Enable debugging code" +-msgstr "デバッグ情報を有効にする" +- +-#: ../gnome-settings-daemon/main.c:53 +-msgid "Replace existing daemon" +-msgstr "既存のデーモンを置き換える" +- +-#: ../gnome-settings-daemon/main.c:54 +-msgid "Exit after a time (for debugging)" +-msgstr "しばらくしてから終了する (デバッグ用)" +- +-#: ../plugins/a11y-keyboard/a11y-keyboard.gnome-settings-plugin.in.h:1 +-msgid "Accessibility Keyboard" +-msgstr "アクセシビリティ・キーボード" +- +-#: ../plugins/a11y-keyboard/a11y-keyboard.gnome-settings-plugin.in.h:2 +-msgid "Accessibility keyboard plugin" +-msgstr "アクセシビリティ・キーボードのプラグイン" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:400 +-msgid "Slow Keys Turned On" +-msgstr "スローキーをオンにする" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:401 +-msgid "Slow Keys Turned Off" +-msgstr "スローキーをオフにする" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:402 +-msgid "You just held down the Shift key for 8 seconds. This is the shortcut for the Slow Keys feature, which affects the way your keyboard works." +-msgstr "[SHIFT] キーを8秒間押下しました。これはスローキー機能のショートカットとして、キーボード操作に影響を与えるものです。" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:412 +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:480 +-msgid "Universal Access" +-msgstr "ユニバーサルアクセス" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:418 +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:486 +-msgid "Turn Off" +-msgstr "オフにする" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:418 +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:486 +-msgid "Turn On" +-msgstr "オンにする" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:424 +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:492 +-msgid "Leave On" +-msgstr "オンのままにする" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:424 +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:492 +-msgid "Leave Off" +-msgstr "オフのままにする" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:465 +-msgid "Sticky Keys Turned On" +-msgstr "固定キーをオンにする" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:466 +-msgid "Sticky Keys Turned Off" +-msgstr "固定キーをオフにする" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:468 +-msgid "You just pressed the Shift key 5 times in a row. This is the shortcut for the Sticky Keys feature, which affects the way your keyboard works." +-msgstr "[SHIFT] キーを連続して5回押下しました。これは固定キー機能のショートカットとして、キーボード操作に影響を与えるものです。" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:470 +-msgid "You just pressed two keys at once, or pressed the Shift key 5 times in a row. This turns off the Sticky Keys feature, which affects the way your keyboard works." +-msgstr "同時に2つのキーを押下したか、あるいは [SHIFT] キーを連続して 5回押下しました。これは固定キー機能を無効にし、キーボード操作に影響を与えるものです。" +- +-#: ../plugins/a11y-settings/a11y-settings.gnome-settings-plugin.in.h:1 +-msgid "Accessibility settings" +-msgstr "アクセシビリティの設定" +- +-#: ../plugins/a11y-settings/a11y-settings.gnome-settings-plugin.in.h:2 +-msgid "Accessibility settings plugin" +-msgstr "アクセシビリティの設定プラグイン" +- +-#. Priority=100 +-#: ../plugins/clipboard/clipboard.gnome-settings-plugin.in.h:2 +-msgid "Clipboard" +-msgstr "クリップボード" +- +-#: ../plugins/clipboard/clipboard.gnome-settings-plugin.in.h:3 +-msgid "Clipboard plugin" +-msgstr "クリップボードのプラグイン" +- +-#: ../plugins/color/color.gnome-settings-plugin.in.h:1 +-#: ../plugins/color/gsd-color-calibrate.c:140 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:31 ++msgid "A dictionary of XSETTINGS to override" ++msgstr "オーバーライドする XSETTINGS の辞書" ++ ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:32 ++msgid "" ++"This dictionary maps XSETTINGS names to overrides values. The values must be " ++"either strings, signed int32s or (in the case of colors), 4-tuples of uint16 " ++"(red, green, blue, alpha; 65535 is fully opaque)." ++msgstr "この辞書は、XSETTINGS の名前をオーバーライド値にマッピングします。この値は、文字列、符号付きの int32、あるいは (色の場合は) uint16 の 4 つのタプル (赤、緑、青、アルファ、65535 は完全に不透明) のいずれかでなければなりません。" ++ ++#: plugins/color/gsd-color-calibrate.c:139 + msgid "Color" + msgstr "色" + +-#: ../plugins/color/color.gnome-settings-plugin.in.h:2 +-msgid "Color plugin" +-msgstr "カラープラグイン" +- +-#: ../plugins/color/gsd-color-calibrate.c:145 ++#. TRANSLATORS: button: this is to open GCM ++#: plugins/color/gsd-color-calibrate.c:145 + msgid "Recalibrate now" + msgstr "再キャリブレーションを行う" + + #. TRANSLATORS: this is when the device has not been recalibrated in a while +-#: ../plugins/color/gsd-color-calibrate.c:188 ++#: plugins/color/gsd-color-calibrate.c:188 + msgid "Recalibration required" + msgstr "再キャリブレーションが要求されています" + + #. TRANSLATORS: this is when the display has not been recalibrated in a while +-#: ../plugins/color/gsd-color-calibrate.c:200 ++#: plugins/color/gsd-color-calibrate.c:200 + #, c-format +-msgid "The display '%s' should be recalibrated soon." +-msgstr "ディスプレイ '%s' は、すぐに再キャリブレーションすべきです。" ++msgid "The display “%s” should be recalibrated soon." ++msgstr "ディスプレイ '%s' は、すぐに再キャリブレーションする必要があります。" + + #. TRANSLATORS: this is when the printer has not been recalibrated in a while +-#: ../plugins/color/gsd-color-calibrate.c:209 ++#: plugins/color/gsd-color-calibrate.c:209 + #, c-format +-msgid "The printer '%s' should be recalibrated soon." +-msgstr "プリンター '%s' は、すぐに再キャリブレーションすべきです。" ++msgid "The printer “%s” should be recalibrated soon." ++msgstr "プリンター '%s' は、すぐに再キャリブレーションする必要があります。" + + #. TRANSLATORS: this is the application name +-#: ../plugins/color/gsd-color-calibrate.c:347 +-#: ../plugins/color/gsd-color-calibrate.c:363 ++#: plugins/color/gsd-color-calibrate.c:347 ++#: plugins/color/gsd-color-calibrate.c:363 + msgid "GNOME Settings Daemon Color Plugin" + msgstr "GNOME 設定デーモンのカラープラグイン" + + #. TRANSLATORS: this is a sound description +-#: ../plugins/color/gsd-color-calibrate.c:349 ++#: plugins/color/gsd-color-calibrate.c:349 + msgid "Color calibration device added" + msgstr "カラーキャリブレーションデバイスが追加されました" + + #. TRANSLATORS: this is a sound description +-#: ../plugins/color/gsd-color-calibrate.c:365 ++#: plugins/color/gsd-color-calibrate.c:365 + msgid "Color calibration device removed" + msgstr "カラーキャリブレーションデバイスが取り外されました" + +-#. Priority=100 +-#: ../plugins/cursor/cursor.gnome-settings-plugin.in.h:2 +-msgid "Cursor" +-msgstr "カーソル" +- +-#: ../plugins/cursor/cursor.gnome-settings-plugin.in.h:3 +-msgid "Show/hide cursor on tablet devices" +-msgstr "タブレットデバイスでカーソルの表示/非表示を行います" +- +-#. Priority=100 +-#: ../plugins/datetime/datetime.gnome-settings-plugin.in.h:2 +-msgid "Date and Time" +-msgstr "日付と時刻" +- +-#: ../plugins/datetime/datetime.gnome-settings-plugin.in.h:3 +-msgid "Automatically update timezone and display notifications" +-msgstr "自動的にタイムゾーンを更新して通知を表示します" +- + #. Translators: UTC here means the Coordinated Universal Time. + #. * %:::z will be replaced by the offset from UTC e.g. UTC+02 +-#: ../plugins/datetime/gsd-datetime-manager.c:104 ++#: plugins/datetime/gsd-datetime-manager.c:88 + msgid "UTC%:::z" + msgstr "UTC%:::z" + +-#: ../plugins/datetime/gsd-datetime-manager.c:108 ++#: plugins/datetime/gsd-datetime-manager.c:92 + #, c-format + msgid "Time Zone Updated to %s (%s)" + msgstr "タイムゾーンの更新: %s (%s)" + +-#: ../plugins/datetime/gsd-datetime-manager.c:128 ++#: plugins/datetime/gsd-datetime-manager.c:108 ++msgid "Settings" ++msgstr "設定" ++ ++#: plugins/datetime/gsd-datetime-manager.c:118 + msgid "Date & Time Settings" + msgstr "日付と時刻の設定" + +-#: ../plugins/datetime/gsd-datetime-manager.c:136 +-msgid "Settings" +-msgstr "設定" ++#: plugins/housekeeping/gsd-disk-space.c:575 ++msgid "Disk Space" ++msgstr "ディスクの空き容量" + +-#: ../plugins/dummy/dummy.gnome-settings-plugin.in.h:1 +-msgid "Dummy" +-msgstr "ダミー" ++#: plugins/housekeeping/gsd-disk-space.c:588 ++msgid "Examine" ++msgstr "検査" ++ ++#: plugins/housekeeping/gsd-disk-space.c:599 ++msgid "Empty Trash" ++msgstr "ゴミ箱を空にする" + +-#: ../plugins/dummy/dummy.gnome-settings-plugin.in.h:2 +-msgid "Dummy plugin" +-msgstr "ダミーのプラグイン" ++#: plugins/housekeeping/gsd-disk-space.c:607 ++msgid "Ignore" ++msgstr "無視" + +-#: ../plugins/housekeeping/gsd-disk-space.c:588 ++#: plugins/housekeeping/gsd-disk-space.c:638 + #, c-format +-msgid "Low Disk Space on \"%s\"" +-msgstr "\"%s\" ディスクの空き容量が少なくなりました" ++msgid "Low Disk Space on “%s”" ++msgstr "\"%s\" の空き容量が少なくなりました" + +-#: ../plugins/housekeeping/gsd-disk-space.c:590 ++#: plugins/housekeeping/gsd-disk-space.c:640 + #, c-format +-msgid "The volume \"%s\" has only %s disk space remaining. You may free up some space by emptying the trash." +-msgstr "ボリューム \"%s\" にはディスクの残りが %s しかありません。ゴミ箱を空にして容量を増やしましょう。" ++msgid "" ++"The volume “%s” has only %s disk space remaining. You may free up some " ++"space by emptying the trash." ++msgstr "ボリューム \"%s\" にはディスクの残りが %s しかありません。ゴミ箱を空にすることで容量を開放できることがあります。" + +-#: ../plugins/housekeeping/gsd-disk-space.c:594 +-#: ../plugins/housekeeping/gsd-ldsm-dialog.c:81 ++#: plugins/housekeeping/gsd-disk-space.c:644 + #, c-format +-msgid "The volume \"%s\" has only %s disk space remaining." ++msgid "The volume “%s” has only %s disk space remaining." + msgstr "ボリューム \"%s\" にはディスクの残りが %s しかありません。" + +-#. Set up all the window stuff here +-#: ../plugins/housekeeping/gsd-disk-space.c:599 +-#: ../plugins/housekeeping/gsd-ldsm-dialog.c:205 ++#: plugins/housekeeping/gsd-disk-space.c:649 + msgid "Low Disk Space" + msgstr "ディスクの空き容量が少ないです" + +-#: ../plugins/housekeeping/gsd-disk-space.c:601 ++#: plugins/housekeeping/gsd-disk-space.c:651 + #, c-format +-msgid "This computer has only %s disk space remaining. You may free up some space by emptying the trash." ++msgid "" ++"This computer has only %s disk space remaining. You may free up some space " ++"by emptying the trash." + msgstr "このコンピューターにはディスクの残りが %s しかありません。ゴミ箱を空にして容量を増やしましょう。" + +-#: ../plugins/housekeeping/gsd-disk-space.c:604 +-#: ../plugins/housekeeping/gsd-ldsm-dialog.c:84 ++#: plugins/housekeeping/gsd-disk-space.c:654 + #, c-format + msgid "This computer has only %s disk space remaining." + msgstr "このコンピューターにはディスクの残りが %s しかありません。" + +-#: ../plugins/housekeeping/gsd-disk-space.c:619 +-msgid "Disk space" +-msgstr "ディスクの空き容量" +- +-#: ../plugins/housekeeping/gsd-disk-space.c:626 +-msgid "Examine" +-msgstr "検査" +- +-#: ../plugins/housekeeping/gsd-disk-space.c:634 +-#: ../plugins/housekeeping/gsd-ldsm-dialog.c:434 +-msgid "Empty Trash" +-msgstr "ゴミ箱を空にする" +- +-#: ../plugins/housekeeping/gsd-disk-space.c:641 +-#: ../plugins/housekeeping/gsd-ldsm-dialog.c:449 +-msgid "Ignore" +-msgstr "無視" +- +-#: ../plugins/housekeeping/gsd-ldsm-dialog.c:66 +-msgid "Don't show any warnings again for this file system" +-msgstr "このファイルシステムの警告は一切表示しない" +- +-#: ../plugins/housekeeping/gsd-ldsm-dialog.c:68 +-msgid "Don't show any warnings again" +-msgstr "警告を一切表示しない" +- +-#: ../plugins/housekeeping/gsd-ldsm-dialog.c:100 +-msgid "You can free up disk space by emptying the Trash, removing unused programs or files, or moving files to another disk or partition." +-msgstr "ゴミ箱を空にしたり、使っていないプログラムやファイルを削除したり、他のディスクやパーティションにファイルを移動することで、ディスクの空き容量を増やせます。" +- +-#: ../plugins/housekeeping/gsd-ldsm-dialog.c:103 +-msgid "You can free up disk space by removing unused programs or files, or by moving files to another disk or partition." +-msgstr "使っていないプログラムやファイルを削除したり、他のディスクやパーティションにファイルを移動することで、ディスク容量を増やせます。" +- +-#: ../plugins/housekeeping/gsd-ldsm-dialog.c:108 +-msgid "You can free up disk space by emptying the Trash, removing unused programs or files, or moving files to an external disk." +-msgstr "ゴミ箱を空にしたり、使っていないプログラムやファイルを削除したり、外付けディスクにファイルを移動することで、ディスクの空き容量を増やせます。" ++#: plugins/media-keys/gsd-media-keys-manager.c:2288 ++msgid "Bluetooth disabled" ++msgstr "Bluetooth 無効" + +-#: ../plugins/housekeeping/gsd-ldsm-dialog.c:111 +-msgid "You can free up disk space by removing unused programs or files, or by moving files to an external disk." +-msgstr "使っていないプログラムやファイルを削除したり、外付けディスクにファイルを移動することで、ディスクの空き容量を増やせます。" ++#: plugins/media-keys/gsd-media-keys-manager.c:2291 ++msgid "Bluetooth enabled" ++msgstr "Bluetooth 有効" + +-#: ../plugins/housekeeping/gsd-ldsm-dialog.c:442 +-msgid "Examine…" +-msgstr "調査中…" ++#: plugins/media-keys/gsd-media-keys-manager.c:2295 ++msgid "Airplane mode enabled" ++msgstr "機内モード有効" + +-#: ../plugins/housekeeping/housekeeping.gnome-settings-plugin.in.h:1 +-msgid "Housekeeping" +-msgstr "ハウスキーピング" ++#: plugins/media-keys/gsd-media-keys-manager.c:2298 ++msgid "Airplane mode disabled" ++msgstr "機内モード無効" + +-#: ../plugins/housekeeping/housekeeping.gnome-settings-plugin.in.h:2 +-msgid "Automatically prunes thumbnail caches and other transient files, and warns about low disk space" +-msgstr "不要なサムネイルキャッシュやその他の一時ファイルを削除し、ディスクスペースの容量が小さくなれば警告します" ++#: plugins/media-keys/gsd-media-keys-manager.c:2326 ++msgid "Hardware Airplane Mode" ++msgstr "ハードウェア機内モード" + +-#. TRANSLATORS: wireless keyboard with internal battery +-#: ../plugins/keyboard/keyboard.gnome-settings-plugin.in.h:1 +-#: ../plugins/power/gpm-common.c:611 +-msgid "Keyboard" +-msgid_plural "Keyboards" +-msgstr[0] "キーボード" +- +-#: ../plugins/keyboard/keyboard.gnome-settings-plugin.in.h:2 +-msgid "Keyboard plugin" +-msgstr "キーボードプラグイン" +- +-#: ../plugins/media-keys/gsd-media-keys-manager.c:2020 ++#. Translators: this is a filename used for screencast ++#. * recording, where "%d" and "%t" date and time, e.g. ++#. * "Screencast from 07-17-2013 10:00:46 PM.webm" ++#: plugins/media-keys/gsd-media-keys-manager.c:2392 ++#, no-c-format + msgid "Screencast from %d %t.webm" +-msgstr "Screencast from %d %t.webm" ++msgstr "%d %t.webm のスクリーンショット" + +-#: ../plugins/media-keys/gsd-screenshot-utils.c:84 ++#: plugins/media-keys/gsd-screenshot-utils.c:82 + msgid "Unable to capture a screenshot" + msgstr "スクリーンショットの撮影に失敗" + +-#: ../plugins/media-keys/gsd-screenshot-utils.c:115 +-#: ../plugins/media-keys/gsd-screenshot-utils.c:155 ++#: plugins/media-keys/gsd-screenshot-utils.c:113 ++#: plugins/media-keys/gsd-screenshot-utils.c:155 + msgid "Screenshot taken" + msgstr "スクリーンショットを撮影" + + #. translators: this is the name of the file that gets made up + #. * with the screenshot +-#: ../plugins/media-keys/gsd-screenshot-utils.c:304 ++#: plugins/media-keys/gsd-screenshot-utils.c:306 + #, c-format + msgid "Screenshot from %s" +-msgstr "Screenshot from %s" +- +-#. translators: +-#. * The device has been disabled +-#: ../plugins/media-keys/gvc/gvc-mixer-control.c:1830 +-msgid "Disabled" +-msgstr "無効" +- +-#. translators: +-#. * The number of sound outputs on a particular device +-#: ../plugins/media-keys/gvc/gvc-mixer-control.c:1837 +-#, c-format +-msgid "%u Output" +-msgid_plural "%u Outputs" +-msgstr[0] "%u 出力" +- +-#. translators: +-#. * The number of sound inputs on a particular device +-#: ../plugins/media-keys/gvc/gvc-mixer-control.c:1847 +-#, c-format +-msgid "%u Input" +-msgid_plural "%u Inputs" +-msgstr[0] "%u 入力" +- +-#: ../plugins/media-keys/gvc/gvc-mixer-control.c:2371 +-msgid "System Sounds" +-msgstr "システムの効果音" ++msgstr "%s のスクリーンショット" + +-#. Priority=100 +-#: ../plugins/media-keys/media-keys.gnome-settings-plugin.in.h:2 +-msgid "Media keys" +-msgstr "メディアキー" +- +-#: ../plugins/media-keys/media-keys.gnome-settings-plugin.in.h:3 +-msgid "Media keys plugin" +-msgstr "メディアキーのプラグイン" +- +-#: ../plugins/media-keys/shortcuts-list.h:101 ++#: plugins/media-keys/shortcuts-list.h:46 ++#: plugins/media-keys/shortcuts-list.h:47 + msgid "Touchpad toggle" + msgstr "タッチパッドの切り替え" + +-#: ../plugins/media-keys/shortcuts-list.h:102 ++#: plugins/media-keys/shortcuts-list.h:48 + msgid "Touchpad On" + msgstr "タッチパッドをオン" + +-#: ../plugins/media-keys/shortcuts-list.h:103 ++#: plugins/media-keys/shortcuts-list.h:49 + msgid "Touchpad Off" + msgstr "タッチパッドをオフ" + +-#: ../plugins/media-keys/shortcuts-list.h:107 +-#: ../plugins/media-keys/shortcuts-list.h:108 +-msgid "Microphone Mute" +-msgstr "マイクミュート" +- +-#: ../plugins/media-keys/shortcuts-list.h:109 ++#: plugins/media-keys/shortcuts-list.h:56 + msgid "Quiet Volume Mute" + msgstr "ミュートにする" + +-#: ../plugins/media-keys/shortcuts-list.h:110 ++#: plugins/media-keys/shortcuts-list.h:57 + msgid "Quiet Volume Down" + msgstr "音量を下げる" + +-#: ../plugins/media-keys/shortcuts-list.h:111 ++#: plugins/media-keys/shortcuts-list.h:58 + msgid "Quiet Volume Up" + msgstr "音量を上げる" + +-#: ../plugins/media-keys/shortcuts-list.h:120 ++#: plugins/media-keys/shortcuts-list.h:59 ++msgid "Precise Volume Down" ++msgstr "音量を正確に下げる" ++ ++#: plugins/media-keys/shortcuts-list.h:60 ++msgid "Precise Volume Up" ++msgstr "音量を正確に上げる" ++ ++#: plugins/media-keys/shortcuts-list.h:70 + msgid "Lock Screen" + msgstr "画面をロックする" + +-#: ../plugins/media-keys/shortcuts-list.h:135 ++#: plugins/media-keys/shortcuts-list.h:72 ++msgid "Help" ++msgstr "ヘルプ" ++ ++#: plugins/media-keys/shortcuts-list.h:89 + msgid "Rewind" + msgstr "巻き戻し" + +-#: ../plugins/media-keys/shortcuts-list.h:136 ++#: plugins/media-keys/shortcuts-list.h:90 + msgid "Forward" + msgstr "早送り" + +-#: ../plugins/media-keys/shortcuts-list.h:137 ++#: plugins/media-keys/shortcuts-list.h:91 + msgid "Repeat" + msgstr "リピート" + +-#: ../plugins/media-keys/shortcuts-list.h:138 ++#: plugins/media-keys/shortcuts-list.h:92 + msgid "Random Play" + msgstr "ランダム再生" + +-#. Key code of the XF86Display key (Fn-F7 on Thinkpads, Fn-F4 on HP machines, etc.) +-#: ../plugins/media-keys/shortcuts-list.h:139 +-#: ../plugins/media-keys/shortcuts-list.h:141 +-msgid "Video Out" +-msgstr "ビデオ出力" +- +-#. Key code of the XF86RotateWindows key (present on some tablets) +-#: ../plugins/media-keys/shortcuts-list.h:143 +-msgid "Rotate Screen" +-msgstr "画面回転" +- +-#: ../plugins/media-keys/shortcuts-list.h:144 ++#: plugins/media-keys/shortcuts-list.h:93 + msgid "Orientation Lock" + msgstr "画面方向ロック" + +-#: ../plugins/media-keys/shortcuts-list.h:153 ++#: plugins/media-keys/shortcuts-list.h:102 + msgid "Power Off" + msgstr "電源オフ" + + #. the kernel / Xorg names really are like this... + #. translators: "Sleep" means putting the machine to sleep, either through hibernate or suspend +-#: ../plugins/media-keys/shortcuts-list.h:156 ++#: plugins/media-keys/shortcuts-list.h:105 + msgid "Sleep" + msgstr "スリープ" + +-#: ../plugins/media-keys/shortcuts-list.h:157 ++#: plugins/media-keys/shortcuts-list.h:106 + msgid "Suspend" + msgstr "サスペンド" + +-#: ../plugins/media-keys/shortcuts-list.h:158 ++#: plugins/media-keys/shortcuts-list.h:107 + msgid "Hibernate" + msgstr "ハイバーネート" + +-#: ../plugins/media-keys/shortcuts-list.h:159 ++#: plugins/media-keys/shortcuts-list.h:108 + msgid "Brightness Up" + msgstr "明るさを上げる" + +-#: ../plugins/media-keys/shortcuts-list.h:160 ++#: plugins/media-keys/shortcuts-list.h:109 + msgid "Brightness Down" + msgstr "明るさを下げる" + +-#: ../plugins/media-keys/shortcuts-list.h:161 ++#: plugins/media-keys/shortcuts-list.h:110 + msgid "Keyboard Brightness Up" + msgstr "キーボードの明るさを上げる" + +-#: ../plugins/media-keys/shortcuts-list.h:162 ++#: plugins/media-keys/shortcuts-list.h:111 + msgid "Keyboard Brightness Down" + msgstr "キーボードの明るさを下げる" + +-#: ../plugins/media-keys/shortcuts-list.h:163 ++#: plugins/media-keys/shortcuts-list.h:112 + msgid "Keyboard Brightness Toggle" + msgstr "キーボードライトの切り替え" + +-#: ../plugins/media-keys/shortcuts-list.h:164 ++#: plugins/media-keys/shortcuts-list.h:113 + msgid "Battery Status" + msgstr "バッテリー状態" + +-#. TRANSLATORS: wireless mice with internal batteries +-#: ../plugins/mouse/mouse.gnome-settings-plugin.in.h:1 +-#: ../plugins/power/gpm-common.c:607 +-msgid "Mouse" +-msgid_plural "Mice" +-msgstr[0] "マウス" ++#: plugins/media-keys/shortcuts-list.h:114 ++#: plugins/media-keys/shortcuts-list.h:115 ++#: plugins/media-keys/shortcuts-list.h:116 ++msgid "Toggle Airplane Mode" ++msgstr "機内モードの切り替え" + +-#: ../plugins/mouse/mouse.gnome-settings-plugin.in.h:2 +-msgid "Mouse plugin" +-msgstr "マウスプラグイン" ++#: plugins/media-keys/shortcuts-list.h:117 ++msgid "Toggle Bluetooth" ++msgstr "Bluetooth の切り替え" + +-#. Priority=100 +-#: ../plugins/orientation/orientation.gnome-settings-plugin.in.h:2 +-msgid "Orientation" +-msgstr "画面の向き" +- +-#: ../plugins/orientation/orientation.gnome-settings-plugin.in.h:3 +-msgid "Orientation plugin" +-msgstr "画面方向プラグイン" +- +-#: ../plugins/power/gpm-common.c:73 ++#: plugins/power/gpm-common.c:92 + msgid "Unknown time" + msgstr "残り時間不明" + +-#: ../plugins/power/gpm-common.c:78 ++#: plugins/power/gpm-common.c:97 + #, c-format + msgid "%i minute" + msgid_plural "%i minutes" + msgstr[0] "%i 分" + +-#: ../plugins/power/gpm-common.c:88 ++#: plugins/power/gpm-common.c:107 + #, c-format + msgid "%i hour" + msgid_plural "%i hours" +@@ -1387,1600 +1249,1816 @@ msgstr[0] "%i 時間" + + #. TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes" + #. * Swap order with "%2$s %2$i %1$s %1$i if needed +-#: ../plugins/power/gpm-common.c:94 ++#: plugins/power/gpm-common.c:113 + #, c-format + msgid "%i %s %i %s" + msgstr "%i %s %i %s" + +-#: ../plugins/power/gpm-common.c:95 ++#: plugins/power/gpm-common.c:114 + msgid "hour" + msgid_plural "hours" + msgstr[0] "時間" + +-#: ../plugins/power/gpm-common.c:96 ++#: plugins/power/gpm-common.c:115 + msgid "minute" + msgid_plural "minutes" + msgstr[0] "分" + +-#. TRANSLATORS: The laptop battery is charged, and we know a time. +-#. * The parameter is the time, e.g. 7 hours 6 minutes +-#: ../plugins/power/gpm-common.c:343 +-#, c-format +-msgid "provides %s laptop runtime" +-msgstr "あと %s ノート PC のバッテリーで動作できます" +- +-#. TRANSLATORS: the device is discharging, and we have a time remaining +-#. * The first parameter is the device type, e.g. "Laptop battery" and +-#. * the second is the time, e.g. 7 hours 6 minutes +-#: ../plugins/power/gpm-common.c:354 +-#, c-format +-msgid "%s %s remaining" +-msgstr "残り %s %s" +- +-#. TRANSLATORS: device is charging, and we have a time to full and a percentage +-#. * The first parameter is the device type, e.g. "Laptop battery" and +-#. * the second is the time, e.g. "7 hours 6 minutes" +-#. TRANSLATORS: device is charging, and we have a time to full and a percentage. +-#. * The first parameter is the device type, e.g. "Laptop battery" and +-#. * the second is the time, e.g. "7 hours 6 minutes" +-#: ../plugins/power/gpm-common.c:375 ../plugins/power/gpm-common.c:392 +-#, c-format +-msgid "%s %s until charged" +-msgstr "充電完了まで %s %s" +- +-#. TRANSLATORS: the device is charging, and we have a time to full and empty. +-#. * The parameter is a time string, e.g. "7 hours 6 minutes" +-#: ../plugins/power/gpm-common.c:382 +-#, c-format +-msgid "provides %s battery runtime" +-msgstr "あと %s バッテリーで動作できます" +- +-#. TRANSLATORS: the type of data, e.g. Laptop battery +-#: ../plugins/power/gpm-common.c:473 +-msgid "Product:" +-msgstr "プロダクト:" +- +-#. TRANSLATORS: device is missing +-#. TRANSLATORS: device is charged +-#. TRANSLATORS: device is charging +-#. TRANSLATORS: device is discharging +-#: ../plugins/power/gpm-common.c:477 ../plugins/power/gpm-common.c:480 +-#: ../plugins/power/gpm-common.c:483 ../plugins/power/gpm-common.c:486 +-msgid "Status:" +-msgstr "状態:" +- +-#: ../plugins/power/gpm-common.c:477 +-msgid "Missing" +-msgstr "不明" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:480 ../plugins/power/gpm-common.c:749 +-msgid "Charged" +-msgstr "充電完了" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:483 ../plugins/power/gpm-common.c:737 +-msgid "Charging" +-msgstr "充電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:486 ../plugins/power/gpm-common.c:741 +-msgid "Discharging" +-msgstr "放電中" +- +-#. TRANSLATORS: percentage +-#: ../plugins/power/gpm-common.c:491 +-msgid "Percentage charge:" +-msgstr "充電率:" +- +-#. TRANSLATORS: manufacturer +-#: ../plugins/power/gpm-common.c:495 +-msgid "Vendor:" +-msgstr "ベンダー:" +- +-#. TRANSLATORS: how the battery is made, e.g. Lithium Ion +-#: ../plugins/power/gpm-common.c:500 +-msgid "Technology:" +-msgstr "種別:" +- +-#. TRANSLATORS: serial number of the battery +-#: ../plugins/power/gpm-common.c:504 +-msgid "Serial number:" +-msgstr "シリアル番号:" +- +-#. TRANSLATORS: model number of the battery +-#: ../plugins/power/gpm-common.c:508 +-msgid "Model:" +-msgstr "モデル:" +- +-#. TRANSLATORS: time to fully charged +-#: ../plugins/power/gpm-common.c:513 +-msgid "Charge time:" +-msgstr "充電時間:" +- +-#. TRANSLATORS: time to empty +-#: ../plugins/power/gpm-common.c:519 +-msgid "Discharge time:" +-msgstr "放電時間:" +- +-#. TRANSLATORS: Excellent, Good, Fair and Poor are all related to battery Capacity +-#: ../plugins/power/gpm-common.c:526 +-msgid "Excellent" +-msgstr "優" +- +-#: ../plugins/power/gpm-common.c:528 +-msgid "Good" +-msgstr "良" +- +-#: ../plugins/power/gpm-common.c:530 +-msgid "Fair" +-msgstr "可" +- +-#: ../plugins/power/gpm-common.c:532 +-msgid "Poor" +-msgstr "不可" +- +-#: ../plugins/power/gpm-common.c:536 +-msgid "Capacity:" +-msgstr "容量:" +- +-#: ../plugins/power/gpm-common.c:542 ../plugins/power/gpm-common.c:567 +-msgid "Current charge:" +-msgstr "現在の充電状態:" +- +-#: ../plugins/power/gpm-common.c:548 +-msgid "Last full charge:" +-msgstr "最近の完全充電:" +- +-# 直訳すると、デザイン料?定格充電としておく。 +-#: ../plugins/power/gpm-common.c:554 ../plugins/power/gpm-common.c:572 +-msgid "Design charge:" +-msgstr "定格充電:" +- +-#: ../plugins/power/gpm-common.c:559 +-msgid "Charge rate:" +-msgstr "充電率:" +- +-#. TRANSLATORS: system power cord +-#: ../plugins/power/gpm-common.c:591 +-msgid "AC adapter" +-msgid_plural "AC adapters" +-msgstr[0] "AC アダプター" +- +-#. TRANSLATORS: laptop primary battery +-#: ../plugins/power/gpm-common.c:595 +-msgid "Laptop battery" +-msgid_plural "Laptop batteries" +-msgstr[0] "ノート PC のバッテリー" +- +-#. TRANSLATORS: battery-backed AC power source +-#: ../plugins/power/gpm-common.c:599 +-msgid "UPS" +-msgid_plural "UPSs" +-msgstr[0] "UPS" +- +-#. TRANSLATORS: a monitor is a device to measure voltage and current +-#: ../plugins/power/gpm-common.c:603 +-msgid "Monitor" +-msgid_plural "Monitors" +-msgstr[0] "モニター" +- +-#. TRANSLATORS: portable device +-#: ../plugins/power/gpm-common.c:615 +-msgid "PDA" +-msgid_plural "PDAs" +-msgstr[0] "PDA" +- +-#. TRANSLATORS: cell phone (mobile...) +-#: ../plugins/power/gpm-common.c:619 +-msgid "Cell phone" +-msgid_plural "Cell phones" +-msgstr[0] "携帯電話" +- +-#. TRANSLATORS: media player, mp3 etc +-#: ../plugins/power/gpm-common.c:624 +-msgid "Media player" +-msgid_plural "Media players" +-msgstr[0] "メディアプレーヤー" +- +-#. TRANSLATORS: tablet device +-#: ../plugins/power/gpm-common.c:628 +-msgid "Tablet" +-msgid_plural "Tablets" +-msgstr[0] "タブレット" +- +-#. TRANSLATORS: tablet device +-#: ../plugins/power/gpm-common.c:632 +-msgid "Computer" +-msgid_plural "Computers" +-msgstr[0] "コンピューター" +- +-#. TRANSLATORS: battery technology +-#: ../plugins/power/gpm-common.c:696 +-msgid "Lithium Ion" +-msgstr "リチウムイオン" +- +-#. TRANSLATORS: battery technology +-#: ../plugins/power/gpm-common.c:700 +-msgid "Lithium Polymer" +-msgstr "リチウムポリマー" +- +-#. TRANSLATORS: battery technology +-#: ../plugins/power/gpm-common.c:704 +-msgid "Lithium Iron Phosphate" +-msgstr "リン酸鉄リチウムイオン" +- +-#. TRANSLATORS: battery technology +-#: ../plugins/power/gpm-common.c:708 +-msgid "Lead acid" +-msgstr "鉛蓄電池" +- +-#. TRANSLATORS: battery technology +-#: ../plugins/power/gpm-common.c:712 +-msgid "Nickel Cadmium" +-msgstr "ニッケルカドミウム" +- +-#. TRANSLATORS: battery technology +-#: ../plugins/power/gpm-common.c:716 +-msgid "Nickel metal hydride" +-msgstr "ニッケル水素" +- +-#. TRANSLATORS: battery technology +-#: ../plugins/power/gpm-common.c:720 +-msgid "Unknown technology" +-msgstr "種別不明" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:745 +-msgid "Empty" +-msgstr "空" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:753 +-msgid "Waiting to charge" +-msgstr "充電待ち" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:757 +-msgid "Waiting to discharge" +-msgstr "放電待ち" +- +-#. TRANSLATORS: device not present +-#: ../plugins/power/gpm-common.c:785 +-msgid "Laptop battery not present" +-msgstr "ノート PC のバッテリーがありません" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:789 +-msgid "Laptop battery is charging" +-msgstr "ノート PC のバッテリーの充電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:793 +-msgid "Laptop battery is discharging" +-msgstr "ノート PC のバッテリーの放電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:797 +-msgid "Laptop battery is empty" +-msgstr "ノート PC のバッテリーが空です" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:801 +-msgid "Laptop battery is charged" +-msgstr "ノート PC のバッテリーの充電完了" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:805 +-msgid "Laptop battery is waiting to charge" +-msgstr "ノート PC のバッテリーの充電待ちです" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:809 +-msgid "Laptop battery is waiting to discharge" +-msgstr "ノート PC のバッテリーの放電待ちです" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:818 +-msgid "UPS is charging" +-msgstr "UPS の充電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:822 +-msgid "UPS is discharging" +-msgstr "UPS の放電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:826 +-msgid "UPS is empty" +-msgstr "UPS のバッテリーが空です" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:830 +-msgid "UPS is charged" +-msgstr "UPS の充電完了" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:839 +-msgid "Mouse is charging" +-msgstr "マウスの充電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:843 +-msgid "Mouse is discharging" +-msgstr "マウスの放電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:847 +-msgid "Mouse is empty" +-msgstr "マウスのバッテリーが空です" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:851 +-msgid "Mouse is charged" +-msgstr "マウスの充電完了" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:860 +-msgid "Keyboard is charging" +-msgstr "キーボードの充電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:864 +-msgid "Keyboard is discharging" +-msgstr "キーボードの放電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:868 +-msgid "Keyboard is empty" +-msgstr "キーボードのバッテリーが空です" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:872 +-msgid "Keyboard is charged" +-msgstr "キーボードの充電完了" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:881 +-msgid "PDA is charging" +-msgstr "PDA の充電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:885 +-msgid "PDA is discharging" +-msgstr "PDA の放電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:889 +-msgid "PDA is empty" +-msgstr "PDA のバッテリーが空です" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:893 +-msgid "PDA is charged" +-msgstr "PDA の充電完了" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:902 +-msgid "Cell phone is charging" +-msgstr "携帯電話の充電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:906 +-msgid "Cell phone is discharging" +-msgstr "携帯電話の放電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:910 +-msgid "Cell phone is empty" +-msgstr "携帯電話のバッテリーが空です" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:914 +-msgid "Cell phone is charged" +-msgstr "携帯電話の充電完了" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:924 +-msgid "Media player is charging" +-msgstr "メディアプレーヤーの充電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:928 +-msgid "Media player is discharging" +-msgstr "メディアプレーヤーの放電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:932 +-msgid "Media player is empty" +-msgstr "メディアプレーヤーのバッテリーが空です" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:936 +-msgid "Media player is charged" +-msgstr "メディアプレーヤーの充電完了" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:945 +-msgid "Tablet is charging" +-msgstr "タブレットの充電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:949 +-msgid "Tablet is discharging" +-msgstr "タブレットの放電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:953 +-msgid "Tablet is empty" +-msgstr "タブレットのバッテリーが空です" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:957 +-msgid "Tablet is charged" +-msgstr "タブレットの充電完了" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:966 +-msgid "Computer is charging" +-msgstr "コンピューターの充電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:970 +-msgid "Computer is discharging" +-msgstr "コンピューターの放電中" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:974 +-msgid "Computer is empty" +-msgstr "コンピューターのバッテリーが空です" +- +-#. TRANSLATORS: battery state +-#: ../plugins/power/gpm-common.c:978 +-msgid "Computer is charged" +-msgstr "コンピューターの充電完了" +- + #. TRANSLATORS: this is the sound description +-#: ../plugins/power/gpm-common.c:1732 +-#: ../plugins/power/gsd-power-manager.c:1566 +-#: ../plugins/power/gsd-power-manager.c:1696 ++#: plugins/power/gpm-common.c:438 plugins/power/gsd-power-manager.c:717 ++#: plugins/power/gsd-power-manager.c:814 + msgid "Battery is critically low" + msgstr "バッテリーがひどく低下しています" + +-#. TRANSLATORS: the battery may be recalled by its vendor +-#: ../plugins/power/gsd-power-manager.c:849 +-msgid "Battery may be recalled" +-msgstr "バッテリーはリコール対象の可能性があります" +- +-# you may be at risk を 自己責任による変更物 と訳出したが、ここまで強い意味ではないかもしれない。 +-#: ../plugins/power/gsd-power-manager.c:852 +-#, c-format +-msgid "A battery in your computer may have been recalled by %s and you may be at risk." +-msgstr "お使いのバッテリーは、%s によりリコールされた可能性があり、危険を伴うおそれがあります。" +- +-#: ../plugins/power/gsd-power-manager.c:855 +-msgid "For more information visit the battery recall website." +-msgstr "詳細については、バッテリーのリコールに関するウェブサイトを参照してください。" +- +-#. TRANSLATORS: button text, visit the manufacturers recall website +-#: ../plugins/power/gsd-power-manager.c:866 +-msgid "Visit recall website" +-msgstr "リコールウェブサイトへ" +- +-#. TRANSLATORS: button text, do not show this bubble again +-#: ../plugins/power/gsd-power-manager.c:870 +-msgid "Do not show me this again" +-msgstr "この警告を一切表示しない" ++#. TRANSLATORS: this is the notification application name ++#: plugins/power/gsd-power-manager.c:347 ++msgid "Power" ++msgstr "電力" + + #. TRANSLATORS: UPS is now discharging +-#: ../plugins/power/gsd-power-manager.c:1120 ++#: plugins/power/gsd-power-manager.c:387 + msgid "UPS Discharging" + msgstr "UPS の充電中" + + #. TRANSLATORS: tell the user how much time they have got +-#: ../plugins/power/gsd-power-manager.c:1125 ++#: plugins/power/gsd-power-manager.c:392 + #, c-format + msgid "%s of UPS backup power remaining" +-msgstr "UPS のバックアップ電力の残り時間は %s です。" ++msgstr "UPS のバックアップ電力の残り時間は %s です" + +-#. TRANSLATORS: this is the notification application name +-#: ../plugins/power/gsd-power-manager.c:1146 +-#: ../plugins/power/gsd-power-manager.c:1376 +-#: ../plugins/power/gsd-power-manager.c:1549 +-#: ../plugins/power/gsd-power-manager.c:1687 +-#: ../plugins/power/gsd-power-manager.c:2921 +-#: ../plugins/power/power.gnome-settings-plugin.in.h:1 +-msgid "Power" +-msgstr "電力" ++#: plugins/power/gsd-power-manager.c:395 ++msgid "Unknown amount of UPS backup power remaining" ++msgstr "UPS のバックアップ電力の残りは不明です" + + #. TRANSLATORS: laptop battery low, and we only have one battery +-#: ../plugins/power/gsd-power-manager.c:1286 ++#: plugins/power/gsd-power-manager.c:470 + msgid "Battery low" + msgstr "バッテリー低下" + + #. TRANSLATORS: laptop battery low, and we have more than one kind of battery +-#: ../plugins/power/gsd-power-manager.c:1289 ++#: plugins/power/gsd-power-manager.c:473 + msgid "Laptop battery low" + msgstr "ノート PC のバッテリー低下" + + #. TRANSLATORS: tell the user how much time they have got +-#: ../plugins/power/gsd-power-manager.c:1296 ++#: plugins/power/gsd-power-manager.c:480 + #, c-format + msgid "Approximately %s remaining (%.0f%%)" + msgstr "約 %s 残っています (%.0f%%)" + + #. TRANSLATORS: UPS is starting to get a little low +-#: ../plugins/power/gsd-power-manager.c:1303 ++#: plugins/power/gsd-power-manager.c:485 + msgid "UPS low" + msgstr "UPS バッテリー低下" + + #. TRANSLATORS: tell the user how much time they have got +-#: ../plugins/power/gsd-power-manager.c:1309 ++#: plugins/power/gsd-power-manager.c:491 + #, c-format + msgid "Approximately %s of remaining UPS backup power (%.0f%%)" + msgstr "UPS バックアップ電力は約 %s 残っています (%.0f%%)" + + #. TRANSLATORS: mouse is getting a little low + #. TRANSLATORS: the mouse battery is very low +-#: ../plugins/power/gsd-power-manager.c:1314 +-#: ../plugins/power/gsd-power-manager.c:1473 ++#: plugins/power/gsd-power-manager.c:496 plugins/power/gsd-power-manager.c:630 + msgid "Mouse battery low" + msgstr "マウスのバッテリー低下" + + #. TRANSLATORS: tell user more details +-#: ../plugins/power/gsd-power-manager.c:1317 ++#: plugins/power/gsd-power-manager.c:499 + #, c-format + msgid "Wireless mouse is low in power (%.0f%%)" + msgstr "ワイヤレスマウスのバッテリーが低下しています (%.0f%%)" + + #. TRANSLATORS: keyboard is getting a little low + #. TRANSLATORS: the keyboard battery is very low +-#: ../plugins/power/gsd-power-manager.c:1321 +-#: ../plugins/power/gsd-power-manager.c:1481 ++#: plugins/power/gsd-power-manager.c:503 plugins/power/gsd-power-manager.c:638 + msgid "Keyboard battery low" + msgstr "キーボードのバッテリー低下" + + #. TRANSLATORS: tell user more details +-#: ../plugins/power/gsd-power-manager.c:1324 ++#: plugins/power/gsd-power-manager.c:506 + #, c-format + msgid "Wireless keyboard is low in power (%.0f%%)" + msgstr "ワイヤレスキーボードのバッテリーが低下しています (%.0f%%)" + + #. TRANSLATORS: PDA is getting a little low + #. TRANSLATORS: the PDA battery is very low +-#: ../plugins/power/gsd-power-manager.c:1328 +-#: ../plugins/power/gsd-power-manager.c:1490 ++#: plugins/power/gsd-power-manager.c:510 plugins/power/gsd-power-manager.c:647 + msgid "PDA battery low" + msgstr "PDA のバッテリー低下" + + #. TRANSLATORS: tell user more details +-#: ../plugins/power/gsd-power-manager.c:1331 ++#: plugins/power/gsd-power-manager.c:513 + #, c-format + msgid "PDA is low in power (%.0f%%)" + msgstr "PDA のバッテリーが低下しています (%.0f%%)" + + #. TRANSLATORS: cell phone (mobile) is getting a little low + #. TRANSLATORS: the cell battery is very low +-#: ../plugins/power/gsd-power-manager.c:1335 +-#: ../plugins/power/gsd-power-manager.c:1500 +-#: ../plugins/power/gsd-power-manager.c:1509 ++#: plugins/power/gsd-power-manager.c:517 plugins/power/gsd-power-manager.c:657 ++#: plugins/power/gsd-power-manager.c:666 + msgid "Cell phone battery low" + msgstr "携帯電話のバッテリー低下" + + #. TRANSLATORS: tell user more details +-#: ../plugins/power/gsd-power-manager.c:1338 ++#: plugins/power/gsd-power-manager.c:520 + #, c-format + msgid "Cell phone is low in power (%.0f%%)" + msgstr "携帯電話のバッテリーが低下しています (%.0f%%)" + + #. TRANSLATORS: media player, e.g. mp3 is getting a little low +-#: ../plugins/power/gsd-power-manager.c:1342 ++#: plugins/power/gsd-power-manager.c:524 + msgid "Media player battery low" + msgstr "メディアプレーヤーのバッテリー低下" + + #. TRANSLATORS: tell user more details +-#: ../plugins/power/gsd-power-manager.c:1345 ++#: plugins/power/gsd-power-manager.c:527 + #, c-format + msgid "Media player is low in power (%.0f%%)" + msgstr "メディアプレーヤーのバッテリーが低下しています (%.0f%%)" + + #. TRANSLATORS: graphics tablet, e.g. wacom is getting a little low + #. TRANSLATORS: the cell battery is very low +-#: ../plugins/power/gsd-power-manager.c:1349 +-#: ../plugins/power/gsd-power-manager.c:1518 ++#: plugins/power/gsd-power-manager.c:531 plugins/power/gsd-power-manager.c:675 + msgid "Tablet battery low" + msgstr "タブレットのバッテリー低下" + + #. TRANSLATORS: tell user more details +-#: ../plugins/power/gsd-power-manager.c:1352 ++#: plugins/power/gsd-power-manager.c:534 + #, c-format + msgid "Tablet is low in power (%.0f%%)" + msgstr "タブレットの電力が低下しています (%.0f%%)" + + #. TRANSLATORS: computer, e.g. ipad is getting a little low + #. TRANSLATORS: the cell battery is very low +-#: ../plugins/power/gsd-power-manager.c:1356 +-#: ../plugins/power/gsd-power-manager.c:1527 ++#: plugins/power/gsd-power-manager.c:538 plugins/power/gsd-power-manager.c:684 + msgid "Attached computer battery low" + msgstr "接続されたコンピューターのバッテリー低下" + + #. TRANSLATORS: tell user more details +-#: ../plugins/power/gsd-power-manager.c:1359 ++#: plugins/power/gsd-power-manager.c:541 + #, c-format + msgid "Attached computer is low in power (%.0f%%)" + msgstr "接続されたコンピューターのバッテリーが低下しています (%.0f%%)" + + #. TRANSLATORS: this is the sound description +-#: ../plugins/power/gsd-power-manager.c:1386 ++#: plugins/power/gsd-power-manager.c:562 + msgid "Battery is low" + msgstr "バッテリー低下" + + #. TRANSLATORS: laptop battery critically low, and only have one kind of battery +-#: ../plugins/power/gsd-power-manager.c:1427 ++#: plugins/power/gsd-power-manager.c:594 + msgid "Battery critically low" + msgstr "バッテリーがひどく低下" + + #. TRANSLATORS: laptop battery critically low, and we have more than one type of battery + #. TRANSLATORS: laptop battery is really, really, low +-#: ../plugins/power/gsd-power-manager.c:1430 +-#: ../plugins/power/gsd-power-manager.c:1601 ++#: plugins/power/gsd-power-manager.c:597 plugins/power/gsd-power-manager.c:744 + msgid "Laptop battery critically low" + msgstr "ノート PC のバッテリーがひどく低下" + +-#. TRANSLATORS: tell the use to insert the plug, as we're not going to do anything +-#: ../plugins/power/gsd-power-manager.c:1439 +-msgid "Plug in your AC adapter to avoid losing data." +-msgstr "データが失われないように AC アダプターを接続してください。" +- +-#. TRANSLATORS: give the user a ultimatum +-#: ../plugins/power/gsd-power-manager.c:1443 +-#, c-format +-msgid "Computer will suspend very soon unless it is plugged in." +-msgstr "アダプターを接続しない場合、コンピューターはまもなくサスペンドします。" +- + #. TRANSLATORS: give the user a ultimatum +-#: ../plugins/power/gsd-power-manager.c:1447 ++#: plugins/power/gsd-power-manager.c:606 + #, c-format + msgid "Computer will hibernate very soon unless it is plugged in." + msgstr "アダプターを接続しない場合、コンピューターはまもなくハイバネートします。" + + #. TRANSLATORS: give the user a ultimatum +-#: ../plugins/power/gsd-power-manager.c:1451 ++#: plugins/power/gsd-power-manager.c:610 + #, c-format + msgid "Computer will shutdown very soon unless it is plugged in." + msgstr "アダプターを接続しない場合、コンピューターはまもなくシャットダウンします。" + + #. TRANSLATORS: the UPS is very low + #. TRANSLATORS: UPS is really, really, low +-#: ../plugins/power/gsd-power-manager.c:1461 +-#: ../plugins/power/gsd-power-manager.c:1639 ++#: plugins/power/gsd-power-manager.c:618 plugins/power/gsd-power-manager.c:769 + msgid "UPS critically low" + msgstr "UPS の電源がひどく低下しています" + + #. TRANSLATORS: give the user a ultimatum +-#: ../plugins/power/gsd-power-manager.c:1467 ++#: plugins/power/gsd-power-manager.c:624 + #, c-format +-msgid "Approximately %s of remaining UPS power (%.0f%%). Restore AC power to your computer to avoid losing data." ++msgid "" ++"Approximately %s of remaining UPS power (%.0f%%). Restore AC power to your " ++"computer to avoid losing data." + msgstr "UPS 電源の残り時間は約 %s です(%.0f%%)。データを失わないように、コンピューターの AC 電源を復帰してください。" + + #. TRANSLATORS: the device is just going to stop working +-#: ../plugins/power/gsd-power-manager.c:1476 ++#: plugins/power/gsd-power-manager.c:633 + #, c-format +-msgid "Wireless mouse is very low in power (%.0f%%). This device will soon stop functioning if not charged." ++msgid "" ++"Wireless mouse is very low in power (%.0f%%). This device will soon stop " ++"functioning if not charged." + msgstr "ワイヤレスマウスの電源が非常に低くなっています(%.0f%%)。このデバイスは、充電されないとまもなく機能を停止します。" + + #. TRANSLATORS: the device is just going to stop working +-#: ../plugins/power/gsd-power-manager.c:1484 ++#: plugins/power/gsd-power-manager.c:641 + #, c-format +-msgid "Wireless keyboard is very low in power (%.0f%%). This device will soon stop functioning if not charged." ++msgid "" ++"Wireless keyboard is very low in power (%.0f%%). This device will soon stop " ++"functioning if not charged." + msgstr "ワイヤレスキーボードの電源が非常に低くなっています(%.0f%%)。このデバイスは、充電されないとまもなく機能を停止します。" + + #. TRANSLATORS: the device is just going to stop working +-#: ../plugins/power/gsd-power-manager.c:1493 ++#: plugins/power/gsd-power-manager.c:650 + #, c-format +-msgid "PDA is very low in power (%.0f%%). This device will soon stop functioning if not charged." ++msgid "" ++"PDA is very low in power (%.0f%%). This device will soon stop functioning if " ++"not charged." + msgstr "PDA の電源が非常に低くなっています(%.0f%%)。このデバイスは、充電されないとまもなく機能を停止します。" + + #. TRANSLATORS: the device is just going to stop working +-#: ../plugins/power/gsd-power-manager.c:1503 ++#: plugins/power/gsd-power-manager.c:660 + #, c-format +-msgid "Cell phone is very low in power (%.0f%%). This device will soon stop functioning if not charged." ++msgid "" ++"Cell phone is very low in power (%.0f%%). This device will soon stop " ++"functioning if not charged." + msgstr "携帯電話の電源が非常に低くなっています(%.0f%%)。このデバイスは、充電されないとまもなく機能を停止します。" + + #. TRANSLATORS: the device is just going to stop working +-#: ../plugins/power/gsd-power-manager.c:1512 ++#: plugins/power/gsd-power-manager.c:669 + #, c-format +-msgid "Media player is very low in power (%.0f%%). This device will soon stop functioning if not charged." ++msgid "" ++"Media player is very low in power (%.0f%%). This device will soon stop " ++"functioning if not charged." + msgstr "メディアプレーヤーの電源が非常に低下しています(%.0f%%)。このデバイスは、充電されないとまもなく機能を停止します。" + + #. TRANSLATORS: the device is just going to stop working +-#: ../plugins/power/gsd-power-manager.c:1521 ++#: plugins/power/gsd-power-manager.c:678 + #, c-format +-msgid "Tablet is very low in power (%.0f%%). This device will soon stop functioning if not charged." ++msgid "" ++"Tablet is very low in power (%.0f%%). This device will soon stop functioning " ++"if not charged." + msgstr "タブレットの電源が非常に低くなっています(%.0f%%)。このデバイスは、充電されないとまもなく機能を停止します。" + + #. TRANSLATORS: the device is just going to stop working +-#: ../plugins/power/gsd-power-manager.c:1530 ++#: plugins/power/gsd-power-manager.c:687 + #, c-format +-msgid "Attached computer is very low in power (%.0f%%). The device will soon shutdown if not charged." +-msgstr "接続されたコンピューターの電源が非常に低くなっています(%.0f%%)。このデバイスは、充電されないとまもなく機能を停止します。" +- +-#. TRANSLATORS: computer will shutdown without saving data +-#: ../plugins/power/gsd-power-manager.c:1609 +-msgid "The battery is below the critical level and this computer will power-off when the battery becomes completely empty." +-msgstr "バッテリーがクリティカルなレベルを下回っています。バッテリーが完全に空になると、このコンピューターは電源オフします。" +- +-#. TRANSLATORS: computer will suspend +-#: ../plugins/power/gsd-power-manager.c:1615 + msgid "" +-"The battery is below the critical level and this computer is about to suspend.\n" +-"NOTE: A small amount of power is required to keep your computer in a suspended state." +-msgstr "" +-"バッテリーがクリティカルなレベルを下回っています。このコンピューターはまもなくサスペンドします。\n" +-"注意: コンピューターのサスペンド状態を保つため、わずかな電力が必要です。" ++"Attached computer is very low in power (%.0f%%). The device will soon " ++"shutdown if not charged." ++msgstr "接続されたコンピューターの電源が非常に低くなっています(%.0f%%)。このデバイスは、充電されないとまもなく機能を停止します。" + + #. TRANSLATORS: computer will hibernate +-#: ../plugins/power/gsd-power-manager.c:1622 +-msgid "The battery is below the critical level and this computer is about to hibernate." ++#: plugins/power/gsd-power-manager.c:752 ++msgid "" ++"The battery is below the critical level and this computer is about to " ++"hibernate." + msgstr "バッテリーがクリティカルなレベルを下回っています。このコンピューターはまもなくハイバネートします。" + + #. TRANSLATORS: computer will just shutdown +-#: ../plugins/power/gsd-power-manager.c:1627 +-msgid "The battery is below the critical level and this computer is about to shutdown." ++#: plugins/power/gsd-power-manager.c:757 ++msgid "" ++"The battery is below the critical level and this computer is about to " ++"shutdown." + msgstr "バッテリーがクリティカルなレベルを下回っています。このコンピューターはまもなくシャットダウンします。" + +-#. TRANSLATORS: computer will shutdown without saving data +-#: ../plugins/power/gsd-power-manager.c:1647 +-msgid "UPS is below the critical level and this computer will power-off when the UPS becomes completely empty." +-msgstr "UPS がクリティカルなレベルを下回っています。 完全に空になるとこのコンピューターは電源オフします。" +- + #. TRANSLATORS: computer will hibernate +-#: ../plugins/power/gsd-power-manager.c:1653 +-msgid "UPS is below the critical level and this computer is about to hibernate." ++#: plugins/power/gsd-power-manager.c:777 ++msgid "" ++"UPS is below the critical level and this computer is about to hibernate." + msgstr "UPS がクリティカルなレベルを下回っています。このコンピューターはまもなくハイバネートします。" + + #. TRANSLATORS: computer will just shutdown +-#: ../plugins/power/gsd-power-manager.c:1658 ++#: plugins/power/gsd-power-manager.c:782 + msgid "UPS is below the critical level and this computer is about to shutdown." + msgstr "UPS がクリティカルなレベルを下回っています。このコンピューターはまもなくシャットダウンします。" + + #. TRANSLATORS: this is the sound description +-#: ../plugins/power/gsd-power-manager.c:2118 ++#: plugins/power/gsd-power-manager.c:1260 + msgid "Lid has been opened" + msgstr "ふたが開けられました" + + #. TRANSLATORS: this is the sound description +-#: ../plugins/power/gsd-power-manager.c:2156 ++#: plugins/power/gsd-power-manager.c:1294 + msgid "Lid has been closed" + msgstr "ふたが閉じられました" + +-#: ../plugins/power/gsd-power-manager.c:2899 +-msgid "Automatic logout" +-msgstr "自動ログアウト" ++#. TRANSLATORS: this is the sound description ++#: plugins/power/gsd-power-manager.c:1856 ++msgid "On battery power" ++msgstr "バッテリー電源使用時" + +-#: ../plugins/power/gsd-power-manager.c:2899 ++#. TRANSLATORS: this is the sound description ++#: plugins/power/gsd-power-manager.c:1861 ++msgid "On AC power" ++msgstr "AC 電源使用時" ++ ++#: plugins/power/gsd-power-manager.c:2051 ++msgid "Automatic logout" ++msgstr "自動ログアウト" ++ ++#: plugins/power/gsd-power-manager.c:2051 + msgid "You will soon log out because of inactivity." + msgstr "作業が行われていないため、まもなくログアウトします。" + +-#: ../plugins/power/gsd-power-manager.c:2904 +-msgid "Automatic suspend" +-msgstr "自動サスペンド" ++#: plugins/power/gsd-power-manager.c:2056 ++msgid "Automatic suspend" ++msgstr "自動サスペンド" ++ ++#: plugins/power/gsd-power-manager.c:2056 ++#: plugins/power/gsd-power-manager.c:2061 ++msgid "Computer will suspend very soon because of inactivity." ++msgstr "作業が行われていないため、コンピューターはまもなくサスペンドします。" ++ ++#: plugins/power/gsd-power-manager.c:2061 ++msgid "Automatic hibernation" ++msgstr "自動ハイバーネート" ++ ++#. SECURITY: ++#. - A normal active user on the local machine does not need permission ++#. to change the backlight brightness. ++#: plugins/power/org.gnome.settings-daemon.plugins.power.policy.in.in:21 ++msgid "Modify the laptop brightness" ++msgstr "ノート PC の輝度を変更します" ++ ++#: plugins/power/org.gnome.settings-daemon.plugins.power.policy.in.in:22 ++msgid "Authentication is required to modify the laptop brightness" ++msgstr "ノート PC の輝度を変更するには認証が必要です" ++ ++#. Translators: We are configuring new printer ++#: plugins/print-notifications/gsd-printer.c:890 ++msgid "Configuring new printer" ++msgstr "新しいプリンターを設定しています" ++ ++#. Translators: Just wait ++#: plugins/print-notifications/gsd-printer.c:892 ++msgid "Please wait…" ++msgstr "お待ちください..." ++ ++#. Translators: We have no driver installed for this printer ++#: plugins/print-notifications/gsd-printer.c:919 ++msgid "Missing printer driver" ++msgstr "プリンタードライバーが見つかりません" ++ ++#. Translators: We have no driver installed for the device ++#: plugins/print-notifications/gsd-printer.c:928 ++#, c-format ++msgid "No printer driver for %s." ++msgstr "%s のプリンタードライバーがありません。" ++ ++#. Translators: We have no driver installed for this printer ++#: plugins/print-notifications/gsd-printer.c:933 ++msgid "No driver for this printer." ++msgstr "このプリンターのドライバーがありません。" ++ ++#: plugins/print-notifications/gsd-printer.c:1031 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:290 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:538 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:920 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:1011 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:1055 ++msgid "Printers" ++msgstr "プリンター" ++ ++#. Translators: The printer is low on toner (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:374 ++#, c-format ++msgid "Printer “%s” is low on toner." ++msgstr "プリンター '%s' のトナーが少なくなりました。" ++ ++#. Translators: The printer has no toner left (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:378 ++#, c-format ++msgid "Printer “%s” has no toner left." ++msgstr "プリンター '%s' のトナーが残っていません。" ++ ++#. Translators: The printer is in the process of connecting to a shared network output device (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:382 ++#, c-format ++msgid "Printer “%s” may not be connected." ++msgstr "プリンター '%s' が接続されていないようです。" ++ ++#. Translators: One or more covers on the printer are open (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:386 ++#, c-format ++msgid "The cover is open on printer “%s”." ++msgstr "プリンター '%s' のカバーが開いています。" ++ ++#. Translators: A filter or backend is not installed (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:390 ++#, c-format ++msgid "There is a missing print filter for printer “%s”." ++msgstr "プリンター '%s' のプリントフィルターが見つかりません。" ++ ++#. Translators: One or more doors on the printer are open (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:395 ++#, c-format ++msgid "The door is open on printer “%s”." ++msgstr "プリンター '%s' のドアが開いています。" ++ ++#. Translators: "marker" is one color bin of the printer ++#: plugins/print-notifications/gsd-print-notifications-manager.c:399 ++#, c-format ++msgid "Printer “%s” is low on a marker supply." ++msgstr "プリンター '%s' のインクが少なくなりました。" ++ ++#. Translators: "marker" is one color bin of the printer ++#: plugins/print-notifications/gsd-print-notifications-manager.c:403 ++#, c-format ++msgid "Printer “%s” is out of a marker supply." ++msgstr "プリンター '%s' のインクがありません。" ++ ++#. Translators: At least one input tray is low on media (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:407 ++#, c-format ++msgid "Printer “%s” is low on paper." ++msgstr "プリンター '%s' の用紙が少なくなっています。" ++ ++#. Translators: At least one input tray is empty (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:411 ++#, c-format ++msgid "Printer “%s” is out of paper." ++msgstr "プリンター '%s' の用紙がなくなりました。" ++ ++#. Translators: The printer is offline (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:415 ++#, c-format ++msgid "Printer “%s” is currently off-line." ++msgstr "プリンター '%s' は現在オフラインです。" ++ ++#. Translators: The printer has detected an error (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:419 ++#, c-format ++msgid "There is a problem on printer “%s”." ++msgstr "プリンター '%s' で問題が発生しました。" ++ ++#. Translators: The printer has a job to print but the printer needs authentication to continue with the print ++#: plugins/print-notifications/gsd-print-notifications-manager.c:531 ++#, c-format ++msgid "%s Requires Authentication" ++msgstr "%s には認証が必要です" ++ ++#. Translators: A printer needs credentials to continue printing a job ++#: plugins/print-notifications/gsd-print-notifications-manager.c:533 ++#, c-format ++msgid "Credentials required in order to print" ++msgstr "印刷するために必要な認証情報" ++ ++#. Translators: The printer is low on toner (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:600 ++msgid "Toner low" ++msgstr "トナーが少なくなりました" ++ ++#. Translators: The printer has no toner left (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:602 ++msgid "Toner empty" ++msgstr "トナーが空になりました" ++ ++#. Translators: The printer is in the process of connecting to a shared network output device (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:604 ++msgid "Not connected?" ++msgstr "接続されていませんか?" ++ ++#. Translators: One or more covers on the printer are open (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:606 ++msgid "Cover open" ++msgstr "カバーが開いています" ++ ++#. Translators: A filter or backend is not installed (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:608 ++msgid "Printer configuration error" ++msgstr "プリンターの設定エラーです" ++ ++#. Translators: One or more doors on the printer are open (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:610 ++msgid "Door open" ++msgstr "ドアが開いています" ++ ++#. Translators: "marker" is one color bin of the printer ++#: plugins/print-notifications/gsd-print-notifications-manager.c:612 ++msgid "Marker supply low" ++msgstr "インクが少なくなりました" ++ ++#. Translators: "marker" is one color bin of the printer ++#: plugins/print-notifications/gsd-print-notifications-manager.c:614 ++msgid "Out of a marker supply" ++msgstr "インク切れです" ++ ++#. Translators: At least one input tray is low on media (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:616 ++msgid "Paper low" ++msgstr "用紙が少なくなりました" ++ ++#. Translators: At least one input tray is empty (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:618 ++msgid "Out of paper" ++msgstr "用紙切れです" ++ ++#. Translators: The printer is offline (same as in system-config-printer) ++#: plugins/print-notifications/gsd-print-notifications-manager.c:620 ++msgid "Printer off-line" ++msgstr "プリンターがオフラインです" ++ ++#. Translators: The printer has detected an error (same as in system-config-printer) ++#. Translators: This is a title of an error notification for a printer ++#: plugins/print-notifications/gsd-print-notifications-manager.c:622 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:997 ++msgid "Printer error" ++msgstr "プリンターエラー" ++ ++#. Translators: New printer has been added ++#: plugins/print-notifications/gsd-print-notifications-manager.c:670 ++msgid "Printer added" ++msgstr "プリンターが追加されました" ++ ++#. Translators: A print job has been stopped ++#: plugins/print-notifications/gsd-print-notifications-manager.c:687 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:725 ++msgctxt "print job state" ++msgid "Printing stopped" ++msgstr "印刷が停止されました" ++ ++#. Translators: "print-job xy" on a printer ++#: plugins/print-notifications/gsd-print-notifications-manager.c:689 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:695 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:701 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:707 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:719 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:727 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:735 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:743 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:751 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:775 ++#, c-format ++msgctxt "print job" ++msgid "“%s” on %s" ++msgstr "\"%s\" の \"%s\"" ++ ++#. Translators: A print job has been canceled ++#: plugins/print-notifications/gsd-print-notifications-manager.c:693 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:733 ++msgctxt "print job state" ++msgid "Printing canceled" ++msgstr "印刷がキャンセルされました" ++ ++#. Translators: A print job has been aborted ++#: plugins/print-notifications/gsd-print-notifications-manager.c:699 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:741 ++msgctxt "print job state" ++msgid "Printing aborted" ++msgstr "印刷が中止されました" ++ ++#. Translators: A print job has been completed ++#: plugins/print-notifications/gsd-print-notifications-manager.c:705 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:749 ++msgctxt "print job state" ++msgid "Printing completed" ++msgstr "印刷が完了しました" ++ ++#. Translators: A job is printing ++#: plugins/print-notifications/gsd-print-notifications-manager.c:717 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:773 ++msgctxt "print job state" ++msgid "Printing" ++msgstr "印刷" ++ ++#. Translators: This is a title of a report notification for a printer ++#: plugins/print-notifications/gsd-print-notifications-manager.c:991 ++msgid "Printer report" ++msgstr "プリンターの報告" ++ ++#. Translators: This is a title of a warning notification for a printer ++#: plugins/print-notifications/gsd-print-notifications-manager.c:994 ++msgid "Printer warning" ++msgstr "プリンターの警告" ++ ++#. Translators: "Printer 'MyPrinterName': 'Description of the report/warning/error from a PPD file'." ++#: plugins/print-notifications/gsd-print-notifications-manager.c:1004 ++#, c-format ++msgid "Printer “%s”: “%s”." ++msgstr "プリンター '%s': '%s'。" ++ ++#: plugins/smartcard/gsd-smartcard-service.c:288 ++msgid "User was not logged in with smartcard." ++msgstr "スマートカードではログインできません。" ++ ++#: plugins/subman/gsd-subscription-manager.c:1044 ++msgid "Subscription Has Expired" ++msgstr "サブスクリプションは期限切れです" ++ ++#: plugins/subman/gsd-subscription-manager.c:1045 ++msgid "Add or renew a subscription to continue receiving software updates." ++msgstr "ソフトウェアの更新を継続して受信するには、サブスクリプションを追加または更新します。" ++ ++#: plugins/subman/gsd-subscription-manager.c:1047 ++#: plugins/subman/gsd-subscription-manager.c:1063 ++#: plugins/subman/gsd-subscription-manager.c:1075 ++msgid "Subscription" ++msgstr "サブスクリプション" ++ ++#: plugins/subman/gsd-subscription-manager.c:1052 ++msgid "Subscribe System…" ++msgstr "システムのサブスクライブ..." ++ ++#: plugins/subman/gsd-subscription-manager.c:1060 ++msgid "Registration Successful" ++msgstr "登録成功" ++ ++#: plugins/subman/gsd-subscription-manager.c:1061 ++msgid "The system has been registered and software updates have been enabled." ++msgstr "システムが登録され、ソフトウェア更新が有効になりました。" ++ ++#: plugins/subman/gsd-subscription-manager.c:1072 ++msgid "System Not Registered" ++msgstr "システムは登録されていません" ++ ++#: plugins/subman/gsd-subscription-manager.c:1073 ++msgid "Please register your system to receive software updates." ++msgstr "ソフトウェア更新を受信するには、このシステムを登録してください。" ++ ++#: plugins/subman/gsd-subscription-manager.c:1080 ++msgid "Register System…" ++msgstr "システムの登録..." ++ ++#: plugins/subman/org.gnome.settings-daemon.plugins.subman.policy.in.in:17 ++msgid "Register the system" ++msgstr "システムの登録" ++ ++#: plugins/subman/org.gnome.settings-daemon.plugins.subman.policy.in.in:18 ++msgid "Authentication is required to register the system" ++msgstr "システムを登録するには、認証が必要です" ++ ++#. SECURITY: ++#. - A normal active user on the local machine does not need permission ++#. to change the LED setting for a Wacom tablet ++#: plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in:20 ++msgid "Modify the lit LED for a Wacom tablet" ++msgstr "Wacom タブレットの LED 設定の変更" ++ ++#: plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in:21 ++msgid "Authentication is required to modify the lit LED for a Wacom tablet" ++msgstr "Wacom タブレットの LED 設定の変更には認証が必要です" ++ ++#. SECURITY: ++#. - A normal active user on the local machine does not need permission ++#. to change the OLED images for a Wacom tablet ++#: plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in:35 ++msgid "Modify the OLED image for a Wacom tablet" ++msgstr "Wacom タブレットの OLED イメージの変更" ++ ++#: plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in:36 ++msgid "Authentication is required to modify the OLED image for a Wacom tablet" ++msgstr "Wacom タブレットの OLED イメージの変更には認証が必要です" ++ ++#~ msgid "GNOME Settings Daemon" ++#~ msgstr "GNOME 設定デーモン" ++ ++#~ msgid "Device hotplug custom command" ++#~ msgstr "デバイスのホットプラグの独自コマンド" ++ ++#~ msgid "" ++#~ "Command to be run when a device is added or removed. An exit value of 1 " ++#~ "means that the device will not be handled further by gnome-settings-" ++#~ "daemon." ++#~ msgstr "" ++#~ "デバイスの接続または取り外し時に実行するコマンドです。終了ステータスが 1 " ++#~ "である場合は、これ以上 gnome-settings-daemon によってデバイスが処理されな" ++#~ "いことを意味します。" ++ ++#~ msgid "Activation of this plugin" ++#~ msgstr "このプラグインを有効化する" ++ ++#~ msgid "" ++#~ "Whether this plugin would be activated by gnome-settings-daemon or not" ++#~ msgstr "このプラグインを gnome-settings-daemon で有効化するかどうかです" ++ ++#~ msgid "Priority to use for this plugin" ++#~ msgstr "このプラグインの優先度" ++ ++#~ msgid "" ++#~ "Priority to use for this plugin in gnome-settings-daemon startup queue" ++#~ msgstr "" ++#~ "gnome-settings-daemon の起動時のキューで、このプラグインが使用される優先度" ++ ++#~ msgid "Wacom tablet PC feature" ++#~ msgstr "Wacom タブレット PC の機能" ++ ++#~ msgid "Enable this to only report stylus events when the tip is pressed." ++#~ msgstr "" ++#~ "チップが押されたときにスタイラスイベントだけが送られるようにします。" ++ ++#~ msgid "Wacom last calibrated resolution" ++#~ msgstr "Wacom で最後にキャリブレーションした時の解像度" ++ ++#~ msgid "" ++#~ "Holds the last calibrated resolution to help check if calibration is " ++#~ "needed." ++#~ msgstr "" ++#~ "キャリブレーションが必要かどうか判断できるように、最後にキャリブレーション" ++#~ "した時の解像度を保持します。" ++ ++#~ msgid "Wacom display mapping" ++#~ msgstr "Wacom ディスプレイ・マッピング" ++ ++#~ msgid "" ++#~ "EDID information of monitor to map tablet to. Must be in the format " ++#~ "[vendor, product, serial]. [\"\",\"\",\"\"] disables mapping." ++#~ msgstr "" ++#~ "モニターとタブレットのマップで EDID 情報を使用します。書式は、[vendor, " ++#~ "product, serial] です。[\"\",\"\",\"\"] にするとマッピングできません。" ++ ++#~ msgid "Percentage considered low" ++#~ msgstr "バッテリー残量低下と認識するパーセンテージ" ++ ++#~ msgid "" ++#~ "The percentage of the battery when it is considered low. Only valid when " ++#~ "use-time-for-policy is false." ++#~ msgstr "" ++#~ "バッテリー残量が低下していると認識するパーセンテージです。use-time-for-" ++#~ "policy が false のときだけ有効です。" ++ ++#~ msgid "Percentage considered critical" ++#~ msgstr "バッテリー残量が危険領域と認識するパーセンテージ" ++ ++#~ msgid "" ++#~ "The percentage of the battery when it is considered critical. Only valid " ++#~ "when use-time-for-policy is false." ++#~ msgstr "" ++#~ "バッテリー残量が危険領域だと認識するパーセンテージです。use-time-for-" ++#~ "policy が false のときだけ有効です。" ++ ++#~ msgid "Percentage action is taken" ++#~ msgstr "アクションを実施するパーセンテージ" ++ ++#~ msgid "" ++#~ "The percentage of the battery when the critical action is performed. Only " ++#~ "valid when use-time-for-policy is false." ++#~ msgstr "" ++#~ "危険領域のアクションを実施するバッテリー残量のパーセンテージ。use-time-" ++#~ "for-policy が false のときだけ有効です。" ++ ++#~ msgid "The time remaining when low" ++#~ msgstr "残量低下時の残り時間" ++ ++#~ msgid "" ++#~ "The time remaining in seconds of the battery when it is considered low. " ++#~ "Only valid when use-time-for-policy is true." ++#~ msgstr "" ++#~ "残量低下時のバッテリーの残り秒数です。use-time-for-policy が true のときだ" ++#~ "け有効です。" ++ ++#~ msgid "The time remaining when critical" ++#~ msgstr "残量が危険領域時の残り時間" ++ ++#~ msgid "" ++#~ "The time remaining in seconds of the battery when it is considered " ++#~ "critical. Only valid when use-time-for-policy is true." ++#~ msgstr "" ++#~ "残量が危険領域時のバッテリーの残り秒数です。use-time-for-policy が true の" ++#~ "ときだけ有効です。" ++ ++#~ msgid "The time remaining when action is taken" ++#~ msgstr "アクション実施時のバッテリーの残り秒数" ++ ++#~ msgid "" ++#~ "The time remaining in seconds of the battery when critical action is " ++#~ "taken. Only valid when use-time-for-policy is true." ++#~ msgstr "" ++#~ "危険領域時のアクション実施時のバッテリーの残り秒数です。use-time-for-" ++#~ "policy が true のときだけ有効です。" ++ ++#~ msgid "Whether to use time-based notifications" ++#~ msgstr "時間基準の通知を使用するかどうか" ++ ++#~ msgid "" ++#~ "If time based notifications should be used. If set to false, then the " ++#~ "percentage change is used instead, which may fix a broken ACPI BIOS." ++#~ msgstr "" ++#~ "時間基準の通知を使用するかどうかです。false に設定されている場合、パーセン" ++#~ "テージの変化が代わりに使用され、壊れた ACPI BIOS を正してくれます。" ++ ++#~ msgid "If we should show the recalled battery warning for a broken battery" ++#~ msgstr "" ++#~ "壊れたバッテリーに対して、リコールされたバッテリーだという警告を再び表示さ" ++#~ "せるかどうか" ++ ++#~ msgid "" ++#~ "If we should show the recalled battery warning for a broken battery. Set " ++#~ "this to false only if you know your battery is okay." ++#~ msgstr "" ++#~ "壊れたバッテリーに対して、リコールされたバッテリーだという警告を再び表示さ" ++#~ "せるかどうかです。これを false に指定した場合、バッテリーが良好かどうかを" ++#~ "知ることしかできません。" ++ ++#~ msgid "Use mobile broadband connections" ++#~ msgstr "モバイルブロードバンド接続を使用する" ++ ++#~ msgid "" ++#~ "Use mobile broadband connections such as GSM and CDMA to check for " ++#~ "updates." ++#~ msgstr "" ++#~ "更新の確認に GSM や CDMA などのモバイルブロードバンド接続を使用します。" ++ ++#~ msgid "" ++#~ "Automatically download updates in the background without confirmation" ++#~ msgstr "バックグラウンドで自動的に更新をダウンロードする" ++ ++#~ msgid "" ++#~ "Automatically download updates in the background without confirmation. " ++#~ "Updates will be auto-downloaded when using wired network connnections, " ++#~ "and mobile broadband if 'connection-use-mobile' is enabled." ++#~ msgstr "" ++#~ "バックグラウンドで自動的に更新をダウンロードします。有線ネットワーク接続を" ++#~ "使用しているとき、また 'connection-use-mobile' が有効でモバイルブロードバ" ++#~ "ンドを使用しているときに、自動的に更新をダウンロードします。" ++ ++#~ msgid "How often to check for updates" ++#~ msgstr "更新の確認頻度" ++ ++#~ msgid "" ++#~ "How often to check for updates. Value is in seconds. This is a maximum " ++#~ "amount of time that can pass between a security update being published, " ++#~ "and the update being automatically installed or the user notified." ++#~ msgstr "" ++#~ "更新の確認頻度です。値は秒単位です。この最大時間は、セキュリティ更新の間隔" ++#~ "になり、更新は自動的にインストールされる、またはユーザーに通知されます。" ++ ++#~ msgid "How often to notify the user that non-critical updates are available" ++#~ msgstr "クリティカルでない更新をユーザーに通知する頻度" ++ ++#~ msgid "" ++#~ "How often to tell the user there are non-critical updates. Value is in " ++#~ "seconds. Security update notifications are always shown after the check " ++#~ "for updates, but non-critical notifications should be shown a lot less " ++#~ "frequently." ++#~ msgstr "" ++#~ "クリティカルではない更新が利用可能である場合にユーザーに通知する頻度です。" ++#~ "値は秒単位です。セキュリティの更新の通知は、更新の調査後に毎回表示され、ク" ++#~ "リティカルではない通知はそれより低頻度で表示されます。" ++ ++#~ msgid "The last time we told the user about non-critical notifications" ++#~ msgstr "ユーザーにクリティカルではない通知を最後に行った時間" ++ ++#~ msgid "" ++#~ "The last time we notified the user about non-critical updates. Value is " ++#~ "in seconds since the epoch, or zero for never." ++#~ msgstr "" ++#~ "ユーザーにクリティカルではない更新の通知を最後に行った時間です。値は、エ" ++#~ "ポックからの秒単位、または、通知されていない場合のゼロです。" ++ ++#~ msgid "How often to check for distribution upgrades" ++#~ msgstr "ディストリビューションの更新の確認頻度" ++ ++#~ msgid "How often to check for distribution upgrades. Value is in seconds." ++#~ msgstr "ディストリビューションの更新の確認頻度です。値は秒単位です。" ++ ++#~ msgid "How often to refresh the package cache" ++#~ msgstr "パッケージキャッシュのリフレッシュ頻度" ++ ++#~ msgid "How often to refresh the package cache. Value is in seconds." ++#~ msgstr "パッケージキャッシュのリフレッシュ頻度です。値は秒単位です。" ++ ++#~ msgid "Check for updates when running on battery power" ++#~ msgstr "バッテリー電源での動作時に更新を確認する" ++ ++#~ msgid "Check for updates when running on battery power." ++#~ msgstr "バッテリー電源で動作しているときに更新を確認します。" ++ ++#~ msgid "Notify the user when distribution upgrades are available" ++#~ msgstr "" ++#~ "ディストリビューションの更新が利用可能になったときにユーザーに通知する" ++ ++#~ msgid "Notify the user when distribution upgrades are available." ++#~ msgstr "" ++#~ "ディストリビューションの更新が利用可能になったときにユーザーに通知します。" ++ ++#~ msgid "Ask the user if additional firmware should be installed" ++#~ msgstr "追加のファームウェアをインストールするかユーザーに確認する" ++ ++#~ msgid "" ++#~ "Ask the user if additional firmware should be installed if it is " ++#~ "available." ++#~ msgstr "" ++#~ "追加のファームウェアが利用可能である場合、インストールするかユーザーに確認" ++#~ "します。" ++ ++#~ msgid "Firmware files that should not be searched for" ++#~ msgstr "検索しないファームウェアファイル" ++ ++#~ msgid "" ++#~ "Firmware files that should not be searched for, separated by commas. " ++#~ "These can include '*' and '?' characters." ++#~ msgstr "" ++#~ "検索しないファームウェアファイルです。カンマで区切ります。'*' と '?' 文字" ++#~ "を含めることができます。" ++ ++#~ msgid "Devices that should be ignored" ++#~ msgstr "無視するデバイス" ++ ++#~ msgid "" ++#~ "Devices that should be ignored, separated by commas. These can include " ++#~ "'*' and '?' characters." ++#~ msgstr "" ++#~ "カンマで分離された無視するデバイスです。 '*' と '?' 文字を含めてもかまいま" ++#~ "せん。" ++ ++#~ msgid "" ++#~ "The filenames on removable media that designate it a software source." ++#~ msgstr "ソフトウェアのソースとなるリムーバブルメディア上のファイル名です。" ++ ++#~ msgid "" ++#~ "When removable media is inserted, it is checked to see if it contains any " ++#~ "important filenames in the root directory. If the filename matches, then " ++#~ "an updates check is performed. This allows post-install disks to be used " ++#~ "to update running systems." ++#~ msgstr "" ++#~ "リムーバブルメディアが挿入された時、ルートディレクトリに重要なファイル名が" ++#~ "含まれていないかどうか調査します。ファイル名が一致した場合、更新の調査が実" ++#~ "行されます。これで、すでにインストールしたディスクで実行中のシステムを更新" ++#~ "することが可能になります。" ++ ++#~ msgid "File for default configuration for RandR" ++#~ msgstr "RandR の初期設定ファイル" ++ ++#~ msgid "" ++#~ "The XRandR plugin will look for a default configuration in the file " ++#~ "specified by this key. This is similar to the ~/.config/monitors.xml that " ++#~ "normally gets stored in users' home directories. If a user does not have " ++#~ "such a file, or has one that does not match the user's setup of monitors, " ++#~ "then the file specified by this key will be used instead." ++#~ msgstr "" ++#~ "XRandR プラグインはこのキーで指定されたファイルをデフォルトの設定ファイル" ++#~ "として検索します。これは通常、ユーザーのホームディレクトリに保存されてい" ++#~ "る ~/.config/monitors.xml と同様のものです。もしそのようなファイルが無い場" ++#~ "合、あるいはあったとしてもモニターの設定に合わない場合、このキーで指定され" ++#~ "たファイルが代わりに使われます。" ++ ++#~ msgid "Whether to turn off specific monitors after boot" ++#~ msgstr "ブート後に特定のモニターをオフにするかどうか" ++ ++#~ msgid "" ++#~ "'clone' will display the same thing on all monitors, 'dock' will switch " ++#~ "off the internal monitor, 'do-nothing' will use the default Xorg " ++#~ "behaviour (extend the desktop in recent versions). The default, 'follow-" ++#~ "lid', will choose between 'do-nothing' and 'dock' depending on whether " ++#~ "the lid is (respectively) open or closed." ++#~ msgstr "" ++#~ "'clone' はすべてのモニターで同じ表示を行います。'dock' は内部モニターをオ" ++#~ "フにします。'do-nothing' はデフォルトの Xorg の動作になります (最近のバー" ++#~ "ジョンではデスクトップを拡張します)。デフォルト値となる 'follow-lid' は、" ++#~ "蓋が開いているか閉じているかによって、それぞれ 'do-nothing' か 'dock' かど" ++#~ "ちらかと同じ挙動になります。" ++ ++#~ msgid "" ++#~ "The type of hinting to use when rendering fonts. Possible values are: " ++#~ "\"none\" for no hinting, \"slight\" for basic, \"medium\" for moderate, " ++#~ "and \"full\" for maximum hinting (may cause distortion of letter forms)." ++#~ msgstr "" ++#~ "フォントを描画する際に使用するヒンティング (線幅を補正する) の種類を指定し" ++#~ "ます。利用可能な値: \"none\" はヒンティングを無効にする、\"slight\" は基本" ++#~ "的なヒンティングのみ、\"medium\" は穏やかなヒンティング、\"full\" は最大限" ++#~ "のヒンティング (文字の形状に歪みが発生する可能性あり)" ++ ++#~ msgid "Enable debugging code" ++#~ msgstr "デバッグ情報を有効にする" ++ ++#~ msgid "Replace existing daemon" ++#~ msgstr "既存のデーモンを置き換える" ++ ++#~ msgid "Exit after a time (for debugging)" ++#~ msgstr "しばらくしてから終了する (デバッグ用)" ++ ++#~ msgid "Accessibility Keyboard" ++#~ msgstr "アクセシビリティ・キーボード" ++ ++#~ msgid "Accessibility keyboard plugin" ++#~ msgstr "アクセシビリティ・キーボードのプラグイン" ++ ++#~ msgid "Slow Keys Turned On" ++#~ msgstr "スローキーをオンにする" ++ ++#~ msgid "Slow Keys Turned Off" ++#~ msgstr "スローキーをオフにする" ++ ++#~ msgid "" ++#~ "You just held down the Shift key for 8 seconds. This is the shortcut for " ++#~ "the Slow Keys feature, which affects the way your keyboard works." ++#~ msgstr "" ++#~ "[SHIFT] キーを8秒間押下しました。これはスローキー機能のショートカットとし" ++#~ "て、キーボード操作に影響を与えるものです。" ++ ++#~ msgid "Universal Access" ++#~ msgstr "ユニバーサルアクセス" ++ ++#~ msgid "Turn Off" ++#~ msgstr "オフにする" ++ ++#~ msgid "Turn On" ++#~ msgstr "オンにする" ++ ++#~ msgid "Leave On" ++#~ msgstr "オンのままにする" ++ ++#~ msgid "Leave Off" ++#~ msgstr "オフのままにする" ++ ++#~ msgid "Sticky Keys Turned On" ++#~ msgstr "固定キーをオンにする" ++ ++#~ msgid "Sticky Keys Turned Off" ++#~ msgstr "固定キーをオフにする" ++ ++#~ msgid "" ++#~ "You just pressed the Shift key 5 times in a row. This is the shortcut " ++#~ "for the Sticky Keys feature, which affects the way your keyboard works." ++#~ msgstr "" ++#~ "[SHIFT] キーを連続して5回押下しました。これは固定キー機能のショートカット" ++#~ "として、キーボード操作に影響を与えるものです。" ++ ++#~ msgid "" ++#~ "You just pressed two keys at once, or pressed the Shift key 5 times in a " ++#~ "row. This turns off the Sticky Keys feature, which affects the way your " ++#~ "keyboard works." ++#~ msgstr "" ++#~ "同時に2つのキーを押下したか、あるいは [SHIFT] キーを連続して 5回押下しまし" ++#~ "た。これは固定キー機能を無効にし、キーボード操作に影響を与えるものです。" ++ ++#~ msgid "Accessibility settings" ++#~ msgstr "アクセシビリティの設定" ++ ++#~ msgid "Accessibility settings plugin" ++#~ msgstr "アクセシビリティの設定プラグイン" ++ ++#~ msgid "Clipboard" ++#~ msgstr "クリップボード" ++ ++#~ msgid "Clipboard plugin" ++#~ msgstr "クリップボードのプラグイン" ++ ++#~ msgid "Color plugin" ++#~ msgstr "カラープラグイン" ++ ++#~ msgid "Cursor" ++#~ msgstr "カーソル" ++ ++#~ msgid "Show/hide cursor on tablet devices" ++#~ msgstr "タブレットデバイスでカーソルの表示/非表示を行います" ++ ++#~ msgid "Date and Time" ++#~ msgstr "日付と時刻" ++ ++#~ msgid "Automatically update timezone and display notifications" ++#~ msgstr "自動的にタイムゾーンを更新して通知を表示します" ++ ++#~ msgid "Dummy" ++#~ msgstr "ダミー" ++ ++#~ msgid "Dummy plugin" ++#~ msgstr "ダミーのプラグイン" ++ ++#~ msgid "Don't show any warnings again for this file system" ++#~ msgstr "このファイルシステムの警告は一切表示しない" ++ ++#~ msgid "Don't show any warnings again" ++#~ msgstr "警告を一切表示しない" ++ ++#~ msgid "" ++#~ "You can free up disk space by emptying the Trash, removing unused " ++#~ "programs or files, or moving files to another disk or partition." ++#~ msgstr "" ++#~ "ゴミ箱を空にしたり、使っていないプログラムやファイルを削除したり、他のディ" ++#~ "スクやパーティションにファイルを移動することで、ディスクの空き容量を増やせ" ++#~ "ます。" ++ ++#~ msgid "" ++#~ "You can free up disk space by removing unused programs or files, or by " ++#~ "moving files to another disk or partition." ++#~ msgstr "" ++#~ "使っていないプログラムやファイルを削除したり、他のディスクやパーティション" ++#~ "にファイルを移動することで、ディスク容量を増やせます。" ++ ++#~ msgid "" ++#~ "You can free up disk space by emptying the Trash, removing unused " ++#~ "programs or files, or moving files to an external disk." ++#~ msgstr "" ++#~ "ゴミ箱を空にしたり、使っていないプログラムやファイルを削除したり、外付け" ++#~ "ディスクにファイルを移動することで、ディスクの空き容量を増やせます。" ++ ++#~ msgid "" ++#~ "You can free up disk space by removing unused programs or files, or by " ++#~ "moving files to an external disk." ++#~ msgstr "" ++#~ "使っていないプログラムやファイルを削除したり、外付けディスクにファイルを移" ++#~ "動することで、ディスクの空き容量を増やせます。" ++ ++#~ msgid "Examine…" ++#~ msgstr "調査中…" ++ ++#~ msgid "Housekeeping" ++#~ msgstr "ハウスキーピング" ++ ++#~ msgid "" ++#~ "Automatically prunes thumbnail caches and other transient files, and " ++#~ "warns about low disk space" ++#~ msgstr "" ++#~ "不要なサムネイルキャッシュやその他の一時ファイルを削除し、ディスクスペース" ++#~ "の容量が小さくなれば警告します" ++ ++#~ msgid "Keyboard" ++#~ msgid_plural "Keyboards" ++#~ msgstr[0] "キーボード" ++ ++#~ msgid "Keyboard plugin" ++#~ msgstr "キーボードプラグイン" ++ ++#~ msgid "Disabled" ++#~ msgstr "無効" ++ ++#~ msgid "%u Output" ++#~ msgid_plural "%u Outputs" ++#~ msgstr[0] "%u 出力" ++ ++#~ msgid "%u Input" ++#~ msgid_plural "%u Inputs" ++#~ msgstr[0] "%u 入力" ++ ++#~ msgid "System Sounds" ++#~ msgstr "システムの効果音" ++ ++#~ msgid "Media keys" ++#~ msgstr "メディアキー" ++ ++#~ msgid "Media keys plugin" ++#~ msgstr "メディアキーのプラグイン" ++ ++#~ msgid "Video Out" ++#~ msgstr "ビデオ出力" ++ ++#~ msgid "Rotate Screen" ++#~ msgstr "画面回転" ++ ++#~ msgid "Mouse" ++#~ msgid_plural "Mice" ++#~ msgstr[0] "マウス" ++ ++#~ msgid "Mouse plugin" ++#~ msgstr "マウスプラグイン" ++ ++#~ msgid "Orientation" ++#~ msgstr "画面の向き" ++ ++#~ msgid "Orientation plugin" ++#~ msgstr "画面方向プラグイン" ++ ++#~ msgid "provides %s laptop runtime" ++#~ msgstr "あと %s ノート PC のバッテリーで動作できます" ++ ++#~ msgid "%s %s remaining" ++#~ msgstr "残り %s %s" ++ ++#~ msgid "%s %s until charged" ++#~ msgstr "充電完了まで %s %s" ++ ++#~ msgid "provides %s battery runtime" ++#~ msgstr "あと %s バッテリーで動作できます" ++ ++#~ msgid "Product:" ++#~ msgstr "プロダクト:" ++ ++#~ msgid "Status:" ++#~ msgstr "状態:" ++ ++#~ msgid "Missing" ++#~ msgstr "不明" ++ ++#~ msgid "Charged" ++#~ msgstr "充電完了" ++ ++#~ msgid "Charging" ++#~ msgstr "充電中" ++ ++#~ msgid "Discharging" ++#~ msgstr "放電中" ++ ++#~ msgid "Percentage charge:" ++#~ msgstr "充電率:" ++ ++#~ msgid "Vendor:" ++#~ msgstr "ベンダー:" ++ ++#~ msgid "Technology:" ++#~ msgstr "種別:" ++ ++#~ msgid "Serial number:" ++#~ msgstr "シリアル番号:" ++ ++#~ msgid "Model:" ++#~ msgstr "モデル:" ++ ++#~ msgid "Discharge time:" ++#~ msgstr "放電時間:" ++ ++#~ msgid "Excellent" ++#~ msgstr "優" ++ ++#~ msgid "Good" ++#~ msgstr "良" ++ ++#~ msgid "Fair" ++#~ msgstr "可" ++ ++#~ msgid "Poor" ++#~ msgstr "不可" ++ ++#~ msgid "Capacity:" ++#~ msgstr "容量:" ++ ++#~ msgid "Current charge:" ++#~ msgstr "現在の充電状態:" ++ ++#~ msgid "Last full charge:" ++#~ msgstr "最近の完全充電:" ++ ++# 直訳すると、デザイン料?定格充電としておく。 ++#~ msgid "Design charge:" ++#~ msgstr "定格充電:" ++ ++#~ msgid "Charge rate:" ++#~ msgstr "充電率:" ++ ++#~ msgid "AC adapter" ++#~ msgid_plural "AC adapters" ++#~ msgstr[0] "AC アダプター" ++ ++#~ msgid "Laptop battery" ++#~ msgid_plural "Laptop batteries" ++#~ msgstr[0] "ノート PC のバッテリー" ++ ++#~ msgid "UPS" ++#~ msgid_plural "UPSs" ++#~ msgstr[0] "UPS" ++ ++#~ msgid "Monitor" ++#~ msgid_plural "Monitors" ++#~ msgstr[0] "モニター" ++ ++#~ msgid "PDA" ++#~ msgid_plural "PDAs" ++#~ msgstr[0] "PDA" ++ ++#~ msgid "Cell phone" ++#~ msgid_plural "Cell phones" ++#~ msgstr[0] "携帯電話" ++ ++#~ msgid "Media player" ++#~ msgid_plural "Media players" ++#~ msgstr[0] "メディアプレーヤー" ++ ++#~ msgid "Tablet" ++#~ msgid_plural "Tablets" ++#~ msgstr[0] "タブレット" ++ ++#~ msgid "Computer" ++#~ msgid_plural "Computers" ++#~ msgstr[0] "コンピューター" ++ ++#~ msgid "Lithium Ion" ++#~ msgstr "リチウムイオン" ++ ++#~ msgid "Lithium Polymer" ++#~ msgstr "リチウムポリマー" ++ ++#~ msgid "Lithium Iron Phosphate" ++#~ msgstr "リン酸鉄リチウムイオン" ++ ++#~ msgid "Lead acid" ++#~ msgstr "鉛蓄電池" ++ ++#~ msgid "Nickel Cadmium" ++#~ msgstr "ニッケルカドミウム" ++ ++#~ msgid "Nickel metal hydride" ++#~ msgstr "ニッケル水素" ++ ++#~ msgid "Unknown technology" ++#~ msgstr "種別不明" ++ ++#~ msgid "Empty" ++#~ msgstr "空" ++ ++#~ msgid "Waiting to charge" ++#~ msgstr "充電待ち" ++ ++#~ msgid "Waiting to discharge" ++#~ msgstr "放電待ち" ++ ++#~ msgid "Laptop battery not present" ++#~ msgstr "ノート PC のバッテリーがありません" ++ ++#~ msgid "Laptop battery is charging" ++#~ msgstr "ノート PC のバッテリーの充電中" ++ ++#~ msgid "Laptop battery is discharging" ++#~ msgstr "ノート PC のバッテリーの放電中" ++ ++#~ msgid "Laptop battery is empty" ++#~ msgstr "ノート PC のバッテリーが空です" ++ ++#~ msgid "Laptop battery is charged" ++#~ msgstr "ノート PC のバッテリーの充電完了" + +-#: ../plugins/power/gsd-power-manager.c:2904 +-#: ../plugins/power/gsd-power-manager.c:2909 +-msgid "Computer will suspend very soon because of inactivity." +-msgstr "作業が行われていないため、コンピューターはまもなくサスペンドします。" ++#~ msgid "Laptop battery is waiting to charge" ++#~ msgstr "ノート PC のバッテリーの充電待ちです" + +-#: ../plugins/power/gsd-power-manager.c:2909 +-msgid "Automatic hibernation" +-msgstr "自動ハイバーネート" ++#~ msgid "Laptop battery is waiting to discharge" ++#~ msgstr "ノート PC のバッテリーの放電待ちです" + +-#. SECURITY: +-#. - A normal active user on the local machine does not need permission +-#. to change the backlight brightness. +-#. +-#: ../plugins/power/org.gnome.settings-daemon.plugins.power.policy.in.in.h:5 +-msgid "Modify the laptop brightness" +-msgstr "ノート PC の輝度を変更します" ++#~ msgid "UPS is charging" ++#~ msgstr "UPS の充電中" + +-#: ../plugins/power/org.gnome.settings-daemon.plugins.power.policy.in.in.h:6 +-msgid "Authentication is required to modify the laptop brightness" +-msgstr "ノート PC の輝度を変更するには認証が必要です。" ++#~ msgid "UPS is discharging" ++#~ msgstr "UPS の放電中" + +-#: ../plugins/power/power.gnome-settings-plugin.in.h:2 +-msgid "Power plugin" +-msgstr "電源プラグイン" ++#~ msgid "UPS is empty" ++#~ msgstr "UPS のバッテリーが空です" + +-#. Translators: We are configuring new printer +-#: ../plugins/print-notifications/gsd-printer.c:891 +-msgid "Configuring new printer" +-msgstr "新しいプリンターを設定しています" ++#~ msgid "UPS is charged" ++#~ msgstr "UPS の充電完了" + +-#. Translators: Just wait +-#: ../plugins/print-notifications/gsd-printer.c:893 +-msgid "Please wait..." +-msgstr "お待ちください..." ++#~ msgid "Mouse is charging" ++#~ msgstr "マウスの充電中" + +-#. Translators: We have no driver installed for this printer +-#: ../plugins/print-notifications/gsd-printer.c:920 +-msgid "Missing printer driver" +-msgstr "プリンタードライバーが見つかりません" ++#~ msgid "Mouse is discharging" ++#~ msgstr "マウスの放電中" + +-#. Translators: We have no driver installed for the device +-#: ../plugins/print-notifications/gsd-printer.c:929 +-#, c-format +-msgid "No printer driver for %s." +-msgstr "%s のプリンタードライバーがありません。" ++#~ msgid "Mouse is empty" ++#~ msgstr "マウスのバッテリーが空です" + +-#. Translators: We have no driver installed for this printer +-#: ../plugins/print-notifications/gsd-printer.c:934 +-msgid "No driver for this printer." +-msgstr "このプリンターのドライバーがありません。" ++#~ msgid "Mouse is charged" ++#~ msgstr "マウスの充電完了" + +-#: ../plugins/print-notifications/gsd-printer.c:1032 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:264 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:703 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:793 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:836 +-msgid "Printers" +-msgstr "プリンター" ++#~ msgid "Keyboard is charging" ++#~ msgstr "キーボードの充電中" + +-#. Translators: The printer is low on toner (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:361 +-msgid "Toner low" +-msgstr "トナーが少なくなりました" ++#~ msgid "Keyboard is discharging" ++#~ msgstr "キーボードの放電中" + +-#. Translators: The printer has no toner left (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:363 +-msgid "Toner empty" +-msgstr "トナーが空になりました" ++#~ msgid "Keyboard is empty" ++#~ msgstr "キーボードのバッテリーが空です" + +-#. Translators: The printer is in the process of connecting to a shared network output device (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:365 +-msgid "Not connected?" +-msgstr "接続されていませんか?" ++#~ msgid "Keyboard is charged" ++#~ msgstr "キーボードの充電完了" + +-#. Translators: One or more covers on the printer are open (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:367 +-msgid "Cover open" +-msgstr "カバーが開いています" ++#~ msgid "PDA is charging" ++#~ msgstr "PDA の充電中" + +-#. Translators: A filter or backend is not installed (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:369 +-msgid "Printer configuration error" +-msgstr "プリンターの設定エラーです" ++#~ msgid "PDA is discharging" ++#~ msgstr "PDA の放電中" + +-#. Translators: One or more doors on the printer are open (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:371 +-msgid "Door open" +-msgstr "ドアが開いています" ++#~ msgid "PDA is empty" ++#~ msgstr "PDA のバッテリーが空です" + +-#. Translators: "marker" is one color bin of the printer +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:373 +-msgid "Marker supply low" +-msgstr "インクが少なくなりました" ++#~ msgid "PDA is charged" ++#~ msgstr "PDA の充電完了" + +-#. Translators: "marker" is one color bin of the printer +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:375 +-msgid "Out of a marker supply" +-msgstr "インク切れです" ++#~ msgid "Cell phone is charging" ++#~ msgstr "携帯電話の充電中" + +-#. Translators: At least one input tray is low on media (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:377 +-msgid "Paper low" +-msgstr "用紙が少なくなりました" ++#~ msgid "Cell phone is discharging" ++#~ msgstr "携帯電話の放電中" + +-#. Translators: At least one input tray is empty (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:379 +-msgid "Out of paper" +-msgstr "用紙切れです" ++#~ msgid "Cell phone is empty" ++#~ msgstr "携帯電話のバッテリーが空です" + +-#. Translators: The printer is offline (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:381 +-msgid "Printer off-line" +-msgstr "プリンターがオフラインです" ++#~ msgid "Cell phone is charged" ++#~ msgstr "携帯電話の充電完了" + +-#. Translators: The printer has detected an error (same as in system-config-printer) +-#. Translators: This is a title of an error notification for a printer +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:383 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:779 +-msgid "Printer error" +-msgstr "プリンターエラー" ++#~ msgid "Media player is charging" ++#~ msgstr "メディアプレーヤーの充電中" + +-#. Translators: The printer is low on toner (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:387 +-#, c-format +-msgid "Printer '%s' is low on toner." +-msgstr "プリンター '%s' のトナーが少なくなりました。" ++#~ msgid "Media player is discharging" ++#~ msgstr "メディアプレーヤーの放電中" + +-#. Translators: The printer has no toner left (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:389 +-#, c-format +-msgid "Printer '%s' has no toner left." +-msgstr "プリンター '%s' のトナーが残っていません。" ++#~ msgid "Media player is empty" ++#~ msgstr "メディアプレーヤーのバッテリーが空です" + +-#. Translators: The printer is in the process of connecting to a shared network output device (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:391 +-#, c-format +-msgid "Printer '%s' may not be connected." +-msgstr "プリンター '%s' が接続されていないようです。" ++#~ msgid "Media player is charged" ++#~ msgstr "メディアプレーヤーの充電完了" + +-#. Translators: One or more covers on the printer are open (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:393 +-#, c-format +-msgid "The cover is open on printer '%s'." +-msgstr "プリンター '%s' のカバーが開いています。" ++#~ msgid "Tablet is charging" ++#~ msgstr "タブレットの充電中" + +-#. Translators: A filter or backend is not installed (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:395 +-#, c-format +-msgid "There is a missing print filter for printer '%s'." +-msgstr "プリンター '%s' のプリントフィルターが見つかりません。" ++#~ msgid "Tablet is discharging" ++#~ msgstr "タブレットの放電中" + +-#. Translators: One or more doors on the printer are open (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:398 +-#, c-format +-msgid "The door is open on printer '%s'." +-msgstr "プリンター '%s' のドアが開いています。" ++#~ msgid "Tablet is empty" ++#~ msgstr "タブレットのバッテリーが空です" + +-#. Translators: "marker" is one color bin of the printer +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:400 +-#, c-format +-msgid "Printer '%s' is low on a marker supply." +-msgstr "プリンター '%s' のインクが少なくなりました。" ++#~ msgid "Tablet is charged" ++#~ msgstr "タブレットの充電完了" + +-#. Translators: "marker" is one color bin of the printer +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:402 +-#, c-format +-msgid "Printer '%s' is out of a marker supply." +-msgstr "プリンター '%s' のインクがありません。" ++#~ msgid "Computer is charging" ++#~ msgstr "コンピューターの充電中" + +-#. Translators: At least one input tray is low on media (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:404 +-#, c-format +-msgid "Printer '%s' is low on paper." +-msgstr "プリンター '%s' の用紙が少なくなっています。" ++#~ msgid "Computer is discharging" ++#~ msgstr "コンピューターの放電中" + +-#. Translators: At least one input tray is empty (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:406 +-#, c-format +-msgid "Printer '%s' is out of paper." +-msgstr "プリンター '%s' の用紙がなくなりました。" ++#~ msgid "Computer is empty" ++#~ msgstr "コンピューターのバッテリーが空です" + +-#. Translators: The printer is offline (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:408 +-#, c-format +-msgid "Printer '%s' is currently off-line." +-msgstr "プリンター '%s' は現在オフラインです。" ++#~ msgid "Computer is charged" ++#~ msgstr "コンピューターの充電完了" + +-#. Translators: The printer has detected an error (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:410 +-#, c-format +-msgid "There is a problem on printer '%s'." +-msgstr "プリンター '%s' で問題が発生しました。" ++#~ msgid "Battery may be recalled" ++#~ msgstr "バッテリーはリコール対象の可能性があります" + +-#. Translators: New printer has been added +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:457 +-msgid "Printer added" +-msgstr "プリンターが追加されました" ++# you may be at risk を 自己責任による変更物 と訳出したが、ここまで強い意味ではないかもしれない。 ++#~ msgid "" ++#~ "A battery in your computer may have been recalled by %s and you may be at " ++#~ "risk." ++#~ msgstr "" ++#~ "お使いのバッテリーは、%s によりリコールされた可能性があり、危険を伴うおそ" ++#~ "れがあります。" + +-#. Translators: A printer has been removed +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:465 +-msgid "Printer removed" +-msgstr "プリンターが削除されました" ++#~ msgid "For more information visit the battery recall website." ++#~ msgstr "" ++#~ "詳細については、バッテリーのリコールに関するウェブサイトを参照してくださ" ++#~ "い。" + +-#. Translators: A print job has been stopped +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:482 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:520 +-msgctxt "print job state" +-msgid "Printing stopped" +-msgstr "印刷が停止されました" ++#~ msgid "Visit recall website" ++#~ msgstr "リコールウェブサイトへ" + +-#. Translators: "print-job xy" on a printer +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:484 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:490 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:496 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:502 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:514 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:522 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:530 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:538 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:546 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:559 +-#, c-format +-msgctxt "print job" +-msgid "\"%s\" on %s" +-msgstr "\"%2$s\" のジョブ \"%1$s\"" ++#~ msgid "Do not show me this again" ++#~ msgstr "この警告を一切表示しない" + +-#. Translators: A print job has been canceled +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:488 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:528 +-msgctxt "print job state" +-msgid "Printing canceled" +-msgstr "印刷がキャンセルされました" ++#~ msgid "Plug in your AC adapter to avoid losing data." ++#~ msgstr "データが失われないように AC アダプターを接続してください。" + +-#. Translators: A print job has been aborted +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:494 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:536 +-msgctxt "print job state" +-msgid "Printing aborted" +-msgstr "印刷が中止されました" ++#~ msgid "Computer will suspend very soon unless it is plugged in." ++#~ msgstr "" ++#~ "アダプターを接続しない場合、コンピューターはまもなくサスペンドします。" + +-#. Translators: A print job has been completed +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:500 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:544 +-msgctxt "print job state" +-msgid "Printing completed" +-msgstr "印刷が完了しました" ++#~ msgid "" ++#~ "The battery is below the critical level and this computer will power-" ++#~ "off when the battery becomes completely empty." ++#~ msgstr "" ++#~ "バッテリーがクリティカルなレベルを下回っています。バッテリーが完全に空にな" ++#~ "ると、このコンピューターは電源オフします。" + +-#. Translators: A job is printing +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:512 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:557 +-msgctxt "print job state" +-msgid "Printing" +-msgstr "印刷" ++#~ msgid "" ++#~ "The battery is below the critical level and this computer is about to " ++#~ "suspend.\n" ++#~ "NOTE: A small amount of power is required to keep your computer in " ++#~ "a suspended state." ++#~ msgstr "" ++#~ "バッテリーがクリティカルなレベルを下回っています。このコンピューターはまも" ++#~ "なくサスペンドします。\n" ++#~ "注意: コンピューターのサスペンド状態を保つため、わずかな電力が必要" ++#~ "です。" + +-#. Translators: This is a title of a report notification for a printer +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:773 +-msgid "Printer report" +-msgstr "プリンターの報告" ++#~ msgid "" ++#~ "UPS is below the critical level and this computer will power-off " ++#~ "when the UPS becomes completely empty." ++#~ msgstr "" ++#~ "UPS がクリティカルなレベルを下回っています。 完全に空になるとこのコン" ++#~ "ピューターは電源オフします。" + +-#. Translators: This is a title of a warning notification for a printer +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:776 +-msgid "Printer warning" +-msgstr "プリンターの警告" ++#~ msgid "Power plugin" ++#~ msgstr "電源プラグイン" + +-#. Translators: "Printer 'MyPrinterName': 'Description of the report/warning/error from a PPD file'." +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:786 +-#, c-format +-msgid "Printer '%s': '%s'." +-msgstr "プリンター '%s': '%s'" ++#~ msgid "Printer removed" ++#~ msgstr "プリンターが削除されました" + +-#. Priority=100 +-#: ../plugins/print-notifications/print-notifications.gnome-settings-plugin.in.h:2 +-msgid "Print-notifications" +-msgstr "印刷通知" ++#~ msgid "Print-notifications" ++#~ msgstr "印刷通知" + +-#: ../plugins/print-notifications/print-notifications.gnome-settings-plugin.in.h:3 +-msgid "Print-notifications plugin" +-msgstr "印刷通知プラグイン" ++#~ msgid "Print-notifications plugin" ++#~ msgstr "印刷通知プラグイン" + +-#: ../plugins/remote-display/remote-display.gnome-settings-plugin.in.h:1 +-msgid "Remote Display" +-msgstr "リモートディスプレイ" ++#~ msgid "Remote Display" ++#~ msgstr "リモートディスプレイ" + +-#: ../plugins/remote-display/remote-display.gnome-settings-plugin.in.h:2 +-msgid "Disable animations on remote displays" +-msgstr "リモートディスプレイでアニメーションを無効にする" ++#~ msgid "Disable animations on remote displays" ++#~ msgstr "リモートディスプレイでアニメーションを無効にする" + +-#. Priority=100 +-#: ../plugins/rfkill/rfkill.gnome-settings-plugin.in.h:2 +-msgid "Rfkill" +-msgstr "Rfkill" ++#~ msgid "Rfkill" ++#~ msgstr "Rfkill" + +-#: ../plugins/rfkill/rfkill.gnome-settings-plugin.in.h:3 +-msgid "Rfkill plugin" +-msgstr "Rfkill プラグイン" ++#~ msgid "Rfkill plugin" ++#~ msgstr "Rfkill プラグイン" + +-#: ../plugins/screensaver-proxy/screensaver-proxy.gnome-settings-plugin.in.h:1 +-msgid "Screensaver Proxy" +-msgstr "スクリーンセーバープロキシ" ++#~ msgid "Screensaver Proxy" ++#~ msgstr "スクリーンセーバープロキシ" + +-#: ../plugins/screensaver-proxy/screensaver-proxy.gnome-settings-plugin.in.h:2 +-msgid "Proxy FreeDesktop screensaver inhibition to gnome-session" +-msgstr "gnome-session の機能を抑止する FreeDesktop スクリーンセーバープロキシ" ++#~ msgid "Proxy FreeDesktop screensaver inhibition to gnome-session" ++#~ msgstr "" ++#~ "gnome-session の機能を抑止する FreeDesktop スクリーンセーバープロキシ" + +-#: ../plugins/smartcard/gsd-smartcard-service.c:224 +-msgid "User was not logged in with smartcard." +-msgstr "スマートカードではログインできません" +- +-#: ../plugins/smartcard/smartcard.gnome-settings-plugin.in.h:1 +-msgid "Smartcard" +-msgstr "スマートカード" +- +-#: ../plugins/smartcard/smartcard.gnome-settings-plugin.in.h:2 +-msgid "Smartcard plugin" +-msgstr "スマートカードプラグイン" +- +-#: ../plugins/sound/sound.gnome-settings-plugin.in.h:1 +-msgid "Sound" +-msgstr "サウンド" +- +-#: ../plugins/sound/sound.gnome-settings-plugin.in.h:2 +-msgid "Sound Sample Cache plugin" +-msgstr "サウンドサンプルキャッシュのプラグイン" +- +-#. TRANSLATORS: we need to restart so the new hardware can re-request the firmware +-#: ../plugins/updates/gsd-updates-firmware.c:250 +-msgid "You will need to restart this computer before the hardware will work correctly." +-msgstr "ハードウェアを正しく動作させるには、コンピューターを再起動する必要があります。" +- +-#. TRANSLATORS: title of libnotify bubble +-#: ../plugins/updates/gsd-updates-firmware.c:253 +-#: ../plugins/updates/gsd-updates-firmware.c:281 +-#: ../plugins/updates/gsd-updates-firmware.c:309 +-msgid "Additional software was installed" +-msgstr "追加のソフトウェアがインストールされました" +- +-#: ../plugins/updates/gsd-updates-firmware.c:255 +-#: ../plugins/updates/gsd-updates-firmware.c:283 +-#: ../plugins/updates/gsd-updates-firmware.c:311 +-#: ../plugins/updates/gsd-updates-firmware.c:603 +-#: ../plugins/updates/gsd-updates-manager.c:383 +-#: ../plugins/updates/gsd-updates-manager.c:514 +-#: ../plugins/updates/gsd-updates-manager.c:578 +-#: ../plugins/updates/gsd-updates-manager.c:634 +-#: ../plugins/updates/gsd-updates-manager.c:1283 +-msgid "Software Updates" +-msgstr "ソフトウェアの更新" +- +-#. TRANSLATORS: we need to remove an replug so the new hardware can re-request the firmware +-#: ../plugins/updates/gsd-updates-firmware.c:278 +-msgid "You will need to remove and then reinsert the hardware before it will work correctly." +-msgstr "ハードウェアを正しく動作させるには、一度取り外してから接続し直す必要があります。" +- +-#. TRANSLATORS: we need to remove an replug so the new hardware can re-request the firmware +-#: ../plugins/updates/gsd-updates-firmware.c:306 +-msgid "Your hardware has been set up and is now ready to use." +-msgstr "ハードウェアの設定が完了し、使用可能になりました。" +- +-#. TRANSLATORS: we need another package to keep udev quiet +-#: ../plugins/updates/gsd-updates-firmware.c:587 +-msgid "Additional firmware is required to make hardware in this computer function correctly." +-msgstr "このコンピューターのハードウェアの機能を正常にするため、追加のファームウェアが必要です。" +- +-#. TRANSLATORS: title of libnotify bubble +-#: ../plugins/updates/gsd-updates-firmware.c:601 +-msgid "Additional firmware required" +-msgstr "追加のファームウェアの要求" +- +-#. TRANSLATORS: button label +-#: ../plugins/updates/gsd-updates-firmware.c:608 +-msgid "Install firmware" +-msgstr "ファームウェアのインストール" +- +-#. TRANSLATORS: we should ignore this device and not ask anymore +-#: ../plugins/updates/gsd-updates-firmware.c:611 +-msgid "Ignore devices" +-msgstr "デバイスを無視" +- +-#. TRANSLATORS: this is when the offline update failed +-#: ../plugins/updates/gsd-updates-manager.c:124 +-msgid "Failed To Update" +-msgstr "更新の失敗" +- +-#. TRANSLATORS: the transaction could not be completed +-#. * as a previous transaction was unfinished +-#: ../plugins/updates/gsd-updates-manager.c:130 +-msgid "A previous update was unfinished." +-msgstr "前回の更新が完了していません。" +- +-#. TRANSLATORS: the package manager needed to download +-#. * something with no network available +-#: ../plugins/updates/gsd-updates-manager.c:140 +-msgid "Network access was required but not available." +-msgstr "ネットワークアクセスが必要ですが、利用できません。" +- +-#. TRANSLATORS: if the package is not signed correctly +-#. * +-#: ../plugins/updates/gsd-updates-manager.c:149 +-msgid "An update was not signed in the correct way." +-msgstr "更新は正しい方法で署名されていません。" +- +-#. TRANSLATORS: the transaction failed in a way the user +-#. * probably cannot comprehend. Package management systems +-#. * really are teh suck. +-#: ../plugins/updates/gsd-updates-manager.c:159 +-msgid "The update could not be completed." +-msgstr "更新を完了できませんでした。" +- +-#. TRANSLATORS: the user aborted the update manually +-#: ../plugins/updates/gsd-updates-manager.c:164 +-msgid "The update was cancelled." +-msgstr "更新がキャンセルされました。" +- +-#. TRANSLATORS: the user must have updated manually after +-#. * the updates were prepared +-#: ../plugins/updates/gsd-updates-manager.c:170 +-msgid "An offline update was requested but no packages required updating." +-msgstr "オフラインの更新が要求されましたが、必要な更新パッケージはありません。" +- +-#. TRANSLATORS: we ran out of disk space +-#: ../plugins/updates/gsd-updates-manager.c:174 +-msgid "No space was left on the drive." +-msgstr "ドライブに空き領域がありません。" +- +-#. TRANSLATORS: the update process failed in a general +-#. * way, usually this message will come from source distros +-#. * like gentoo +-#: ../plugins/updates/gsd-updates-manager.c:182 +-msgid "An update failed to install correctly." +-msgstr "更新のインストールが正常に終わりませんでした。" +- +-#. TRANSLATORS: We didn't handle the error type +-#: ../plugins/updates/gsd-updates-manager.c:187 +-msgid "The offline update failed in an unexpected way." +-msgstr "オフラインの更新で予期せぬエラーが発生しました。" +- +-#. TRANSLATORS: these are geeky messages from the +-#. * package manager no mortal is supposed to understand, +-#. * but google might know what they mean +-#: ../plugins/updates/gsd-updates-manager.c:196 +-msgid "Detailed errors from the package manager follow:" +-msgstr "パッケージマネジャーからのエラーの詳細は次のとおり:" +- +-#. TRANSLATORS: a distro update is available, e.g. Fedora 8 to Fedora 9 +-#: ../plugins/updates/gsd-updates-manager.c:378 +-msgid "Distribution upgrades available" +-msgstr "ディストリビューションの更新が利用可能です。" +- +-#. TRANSLATORS: provides more information about the upgrade +-#: ../plugins/updates/gsd-updates-manager.c:388 +-msgid "More information" +-msgstr "更新の追加情報" +- +-#. TRANSLATORS: title in the libnotify popup +-#: ../plugins/updates/gsd-updates-manager.c:496 +-#: ../plugins/updates/gsd-updates-manager.c:560 +-msgid "Update" +-msgid_plural "Updates" +-msgstr[0] "更新" +- +-#. TRANSLATORS: message when there are security updates +-#: ../plugins/updates/gsd-updates-manager.c:499 +-msgid "An important software update is available" +-msgid_plural "Important software updates are available" +-msgstr[0] "重要なソフトウェアの更新が利用可能です" +- +-#. TRANSLATORS: button: open the update viewer to install updates +-#: ../plugins/updates/gsd-updates-manager.c:519 +-#: ../plugins/updates/gsd-updates-manager.c:583 +-msgid "Install updates" +-msgstr "更新のインストール" +- +-#. TRANSLATORS: message when there are non-security updates +-#: ../plugins/updates/gsd-updates-manager.c:563 +-msgid "A software update is available." +-msgid_plural "Software updates are available." +-msgstr[0] "ソフトウェアの更新が利用可能です。" +- +-#. TRANSLATORS: the updates mechanism +-#: ../plugins/updates/gsd-updates-manager.c:621 +-#: ../plugins/updates/updates.gnome-settings-plugin.in.h:1 +-msgid "Updates" +-msgstr "更新" +- +-#. TRANSLATORS: we failed to get the updates multiple times, +-#. * and now we need to inform the user that something might be wrong +-#: ../plugins/updates/gsd-updates-manager.c:625 +-msgid "Unable to access software updates" +-msgstr "ソフトウェアの更新にアクセスできません" +- +-#. TRANSLATORS: try again, this time launching the update viewer +-#: ../plugins/updates/gsd-updates-manager.c:628 +-msgid "Try again" +-msgstr "再試行" +- +-#. TRANSLATORS: the reason why we've inhibited it +-#: ../plugins/updates/gsd-updates-manager.c:1013 +-msgid "A transaction that cannot be interrupted is running" +-msgstr "実行時に中断できないトランザクションです" +- +-#. TRANSLATORS: title in the libnotify popup +-#: ../plugins/updates/gsd-updates-manager.c:1233 +-msgid "Software Update Installed" +-msgid_plural "Software Updates Installed" +-msgstr[0] "更新されたソフトウェアがインストールされました" +- +-#. TRANSLATORS: message when we've done offline updates +-#: ../plugins/updates/gsd-updates-manager.c:1238 +-msgid "An important OS update has been installed." +-msgid_plural "Important OS updates have been installed." +-msgstr[0] "重要な OS の更新がインストールされました。" +- +-#. TRANSLATORS: title in the libnotify popup +-#: ../plugins/updates/gsd-updates-manager.c:1264 +-msgid "Software Updates Failed" +-msgstr "ソフトウェアの更新に失敗しました" +- +-#. TRANSLATORS: message when we've not done offline updates +-#: ../plugins/updates/gsd-updates-manager.c:1267 +-msgid "An important OS update failed to be installed." +-msgstr "重要な OS 更新のインストールに失敗しました。" +- +-#. TRANSLATORS: button: review the offline update changes +-#: ../plugins/updates/gsd-updates-manager.c:1290 +-msgid "Review" +-msgstr "確認" +- +-#. TRANSLATORS: button: review the offline update changes +-#: ../plugins/updates/gsd-updates-manager.c:1294 +-msgid "Show details" +-msgstr "詳細の表示" +- +-#. TRANSLATORS: button: clear notification +-#: ../plugins/updates/gsd-updates-manager.c:1298 +-msgid "OK" +-msgstr "OK" +- +-#: ../plugins/updates/gsd-updates-manager.c:1438 +-msgid "Software Updates available" +-msgstr "ソフトウェアの更新が利用可能" +- +-#: ../plugins/updates/gsd-updates-manager.c:1439 +-msgid "Important OS and application updates are ready to be installed" +-msgstr "OS とアプリケーションの重要な更新をインストールする準備ができました" +- +-#: ../plugins/updates/gsd-updates-manager.c:1443 +-msgid "GNOME Software" +-msgstr "GNOME ソフトウェア" +- +-#. TRANSLATORS: don't install updates now +-#: ../plugins/updates/gsd-updates-manager.c:1448 +-msgid "Not Now" +-msgstr "あとで" +- +-#. TRANSLATORS: view available updates +-#: ../plugins/updates/gsd-updates-manager.c:1454 +-msgid "View" +-msgstr "表示" +- +-#. TRANSLATORS: install available updates +-#: ../plugins/updates/gsd-updates-manager.c:1460 +-msgid "Restart & Install" +-msgstr "再起動してインストール" +- +-#: ../plugins/updates/updates.gnome-settings-plugin.in.h:2 +-msgid "Updates plugin" +-msgstr "更新プラグイン" +- +-#: ../plugins/wacom/gsd-wacom-button-editor.c:51 +-msgctxt "Wacom action-type" +-msgid "None" +-msgstr "なし" +- +-#: ../plugins/wacom/gsd-wacom-button-editor.c:52 +-msgctxt "Wacom action-type" +-msgid "Send Keystroke" +-msgstr "キーストロークを送信" +- +-#: ../plugins/wacom/gsd-wacom-button-editor.c:53 +-msgctxt "Wacom action-type" +-msgid "Switch Monitor" +-msgstr "モニターを切り替える" +- +-#: ../plugins/wacom/gsd-wacom-button-editor.c:54 +-msgctxt "Wacom action-type" +-msgid "Show On-Screen Help" +-msgstr "オンスクリーンヘルプを表示" +- +-#: ../plugins/wacom/gsd-wacom-button-editor.c:184 +-msgctxt "keyboard shortcut" +-msgid "None" +-msgstr "なし" +- +-#: ../plugins/wacom/gsd-wacom-button-editor.c:459 +-msgid "Done" +-msgstr "完了" +- +-#. If no mode is available, we use "left-ring-mode-1" for backward compat +-#: ../plugins/wacom/gsd-wacom-device.c:1063 +-msgid "Left Ring" +-msgstr "左タッチホイール" +- +-#: ../plugins/wacom/gsd-wacom-device.c:1074 +-#, c-format +-msgid "Left Ring Mode #%d" +-msgstr "左タッチホイールのモード #%d" ++#~ msgid "Smartcard" ++#~ msgstr "スマートカード" + +-#. If no mode is available, we use "right-ring-mode-1" for backward compat +-#: ../plugins/wacom/gsd-wacom-device.c:1094 +-msgid "Right Ring" +-msgstr "右タッチホイール" ++#~ msgid "Smartcard plugin" ++#~ msgstr "スマートカードプラグイン" + +-#: ../plugins/wacom/gsd-wacom-device.c:1105 +-#, c-format +-msgid "Right Ring Mode #%d" +-msgstr "右タッチホイールのモード #%d" ++#~ msgid "Sound" ++#~ msgstr "サウンド" + +-#. If no mode is available, we use "left-strip-mode-1" for backward compat +-#: ../plugins/wacom/gsd-wacom-device.c:1147 +-msgid "Left Touchstrip" +-msgstr "左トラックパッド" ++#~ msgid "Sound Sample Cache plugin" ++#~ msgstr "サウンドサンプルキャッシュのプラグイン" + +-#: ../plugins/wacom/gsd-wacom-device.c:1158 +-#, c-format +-msgid "Left Touchstrip Mode #%d" +-msgstr "左トラックパッドのモード #%d" ++#~ msgid "" ++#~ "You will need to restart this computer before the hardware will work " ++#~ "correctly." ++#~ msgstr "" ++#~ "ハードウェアを正しく動作させるには、コンピューターを再起動する必要がありま" ++#~ "す。" + +-#. If no mode is available, we use "right-strip-mode-1" for backward compat +-#: ../plugins/wacom/gsd-wacom-device.c:1178 +-msgid "Right Touchstrip" +-msgstr "右トラックパッド" ++#~ msgid "Additional software was installed" ++#~ msgstr "追加のソフトウェアがインストールされました" + +-#: ../plugins/wacom/gsd-wacom-device.c:1189 +-#, c-format +-msgid "Right Touchstrip Mode #%d" +-msgstr "右トラックパッドのモード #%d" ++#~ msgid "Software Updates" ++#~ msgstr "ソフトウェアの更新" + +-#: ../plugins/wacom/gsd-wacom-device.c:1215 +-#, c-format +-msgid "Left Touchring Mode Switch" +-msgstr "左タッチホイールのモードスイッチ" ++#~ msgid "" ++#~ "You will need to remove and then reinsert the hardware before it will " ++#~ "work correctly." ++#~ msgstr "" ++#~ "ハードウェアを正しく動作させるには、一度取り外してから接続し直す必要があり" ++#~ "ます。" + +-#: ../plugins/wacom/gsd-wacom-device.c:1217 +-#, c-format +-msgid "Right Touchring Mode Switch" +-msgstr "右タッチホイールのモードスイッチ" ++#~ msgid "Your hardware has been set up and is now ready to use." ++#~ msgstr "ハードウェアの設定が完了し、使用可能になりました。" + +-#: ../plugins/wacom/gsd-wacom-device.c:1220 +-#, c-format +-msgid "Left Touchstrip Mode Switch" +-msgstr "左トラックパッドのモードスイッチ" ++#~ msgid "" ++#~ "Additional firmware is required to make hardware in this computer " ++#~ "function correctly." ++#~ msgstr "" ++#~ "このコンピューターのハードウェアの機能を正常にするため、追加のファームウェ" ++#~ "アが必要です。" + +-#: ../plugins/wacom/gsd-wacom-device.c:1222 +-#, c-format +-msgid "Right Touchstrip Mode Switch" +-msgstr "右トラックパッドのモードスイッチ" ++#~ msgid "Additional firmware required" ++#~ msgstr "追加のファームウェアの要求" + +-#: ../plugins/wacom/gsd-wacom-device.c:1227 +-#, c-format +-msgid "Mode Switch #%d" +-msgstr "モードスイッチ #%d" ++#~ msgid "Install firmware" ++#~ msgstr "ファームウェアのインストール" + +-#: ../plugins/wacom/gsd-wacom-device.c:1335 +-#, c-format +-msgid "Left Button #%d" +-msgstr "左ボタン #%d" ++#~ msgid "Ignore devices" ++#~ msgstr "デバイスを無視" + +-#: ../plugins/wacom/gsd-wacom-device.c:1338 +-#, c-format +-msgid "Right Button #%d" +-msgstr "右ボタン #%d" ++#~ msgid "Failed To Update" ++#~ msgstr "更新の失敗" + +-#: ../plugins/wacom/gsd-wacom-device.c:1341 +-#, c-format +-msgid "Top Button #%d" +-msgstr "上ボタン #%d" ++#~ msgid "A previous update was unfinished." ++#~ msgstr "前回の更新が完了していません。" + +-#: ../plugins/wacom/gsd-wacom-device.c:1344 +-#, c-format +-msgid "Bottom Button #%d" +-msgstr "下ボタン #%d" ++#~ msgid "Network access was required but not available." ++#~ msgstr "ネットワークアクセスが必要ですが、利用できません。" + +-#: ../plugins/wacom/gsd-wacom-key-shortcut-button.c:264 +-msgid "New shortcut…" +-msgstr "新しいショートカット…" ++#~ msgid "An update was not signed in the correct way." ++#~ msgstr "更新は正しい方法で署名されていません。" + +-#: ../plugins/wacom/gsd-wacom-manager.c:1079 +-#, c-format +-msgid "The \"%s\" tablet may not work as expected." +-msgstr "\"%s\" タブレットは期待通りに動作しない可能性があります。" ++#~ msgid "The update could not be completed." ++#~ msgstr "更新を完了できませんでした。" + +-#: ../plugins/wacom/gsd-wacom-manager.c:1080 +-msgid "Unknown Tablet Connected" +-msgstr "未知のタブレットを接続" ++#~ msgid "The update was cancelled." ++#~ msgstr "更新がキャンセルされました。" + +-#: ../plugins/wacom/gsd-wacom-manager.c:1083 +-#: ../plugins/wacom/gsd-wacom-manager.c:1658 +-msgid "Wacom Settings" +-msgstr "Wacom の設定" ++#~ msgid "An offline update was requested but no packages required updating." ++#~ msgstr "" ++#~ "オフラインの更新が要求されましたが、必要な更新パッケージはありません。" + +-#: ../plugins/wacom/gsd-wacom-manager.c:1651 +-#, c-format +-msgid "Tablet %s needs to be calibrated." +-msgstr "タブレット '%s' は、キャリブレーションする必要があります。" ++#~ msgid "No space was left on the drive." ++#~ msgstr "ドライブに空き領域がありません。" + +-#: ../plugins/wacom/gsd-wacom-manager.c:1653 +-msgid "Calibration needed" +-msgstr "キャリブレーションが必要" ++#~ msgid "An update failed to install correctly." ++#~ msgstr "更新のインストールが正常に終わりませんでした。" + +-#: ../plugins/wacom/gsd-wacom-manager.c:1667 +-msgid "Calibrate" +-msgstr "キャリブレーション" ++#~ msgid "The offline update failed in an unexpected way." ++#~ msgstr "オフラインの更新で予期せぬエラーが発生しました。" + +-#: ../plugins/wacom/gsd-wacom-osd-window.c:1048 +-#: ../plugins/wacom/gsd-wacom-osd-window.c:1068 +-#: ../plugins/wacom/gsd-wacom-osd-window.c:1079 +-msgctxt "Action type" +-msgid "None" +-msgstr "なし" ++#~ msgid "Detailed errors from the package manager follow:" ++#~ msgstr "パッケージマネジャーからのエラーの詳細は次のとおり:" + +-#: ../plugins/wacom/gsd-wacom-osd-window.c:1053 +-#, c-format +-msgctxt "Action type" +-msgid "Send Keystroke %s" +-msgstr "キーストローク %s を送信" ++#~ msgid "Distribution upgrades available" ++#~ msgstr "ディストリビューションの更新が利用可能です。" + +-#: ../plugins/wacom/gsd-wacom-osd-window.c:1071 +-msgctxt "Action type" +-msgid "Show On-Screen Help" +-msgstr "オンスクリーンヘルプを表示" ++#~ msgid "More information" ++#~ msgstr "更新の追加情報" + +-#: ../plugins/wacom/gsd-wacom-osd-window.c:1074 +-msgctxt "Action type" +-msgid "Switch Monitor" +-msgstr "モニターを切り替える" ++#~ msgid "Update" ++#~ msgid_plural "Updates" ++#~ msgstr[0] "更新" + +-#: ../plugins/wacom/gsd-wacom-osd-window.c:1112 +-#, c-format +-msgid "Mode %d: %s" +-msgstr "モード %d: %s" ++#~ msgid "An important software update is available" ++#~ msgid_plural "Important software updates are available" ++#~ msgstr[0] "重要なソフトウェアの更新が利用可能です" + +-#: ../plugins/wacom/gsd-wacom-osd-window.c:1321 +-msgid "(press any key to exit)" +-msgstr "(何かキーを押して終了)" ++#~ msgid "Install updates" ++#~ msgstr "更新のインストール" + +-#: ../plugins/wacom/gsd-wacom-osd-window.c:1330 +-msgid "Push a button to configure" +-msgstr "設定するボタンを押してください" ++#~ msgid "A software update is available." ++#~ msgid_plural "Software updates are available." ++#~ msgstr[0] "ソフトウェアの更新が利用可能です。" + +-#: ../plugins/wacom/gsd-wacom-osd-window.c:1330 +-msgid "(Esc to cancel)" +-msgstr "(Esc でキャンセル)" ++#~ msgid "Updates" ++#~ msgstr "更新" + +-#: ../plugins/wacom/gsd-wacom-osd-window.c:1960 +-msgid "Edit" +-msgstr "編集" ++#~ msgid "Unable to access software updates" ++#~ msgstr "ソフトウェアの更新にアクセスできません" + +-#. SECURITY: +-#. - A normal active user on the local machine does not need permission +-#. to change the LED setting for a Wacom tablet +-#. +-#: ../plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in.h:5 +-msgid "Modify the lit LED for a Wacom tablet" +-msgstr "Wacom タブレットの LED 設定の変更" ++#~ msgid "Try again" ++#~ msgstr "再試行" + +-#: ../plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in.h:6 +-msgid "Authentication is required to modify the lit LED for a Wacom tablet" +-msgstr "Wacom タブレットの LED 設定の変更には認証が必要です。" ++#~ msgid "A transaction that cannot be interrupted is running" ++#~ msgstr "実行時に中断できないトランザクションです" + +-#. SECURITY: +-#. - A normal active user on the local machine does not need permission +-#. to change the OLED images for a Wacom tablet +-#. +-#: ../plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in.h:11 +-msgid "Modify the OLED image for a Wacom tablet" +-msgstr "Wacom タブレットの OLED イメージの変更" ++#~ msgid "Software Update Installed" ++#~ msgid_plural "Software Updates Installed" ++#~ msgstr[0] "更新されたソフトウェアがインストールされました" + +-#: ../plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in.h:12 +-msgid "Authentication is required to modify the OLED image for a Wacom tablet" +-msgstr "Wacom タブレットの OLED イメージの変更には認証が必要です。" ++#~ msgid "An important OS update has been installed." ++#~ msgid_plural "Important OS updates have been installed." ++#~ msgstr[0] "重要な OS の更新がインストールされました。" + +-#: ../plugins/wacom/wacom.gnome-settings-plugin.in.h:1 +-msgid "Wacom" +-msgstr "Wacom" ++#~ msgid "Software Updates Failed" ++#~ msgstr "ソフトウェアの更新に失敗しました" + +-#: ../plugins/wacom/wacom.gnome-settings-plugin.in.h:2 +-msgid "Wacom plugin" +-msgstr "Wacom プラグイン" ++#~ msgid "An important OS update failed to be installed." ++#~ msgstr "重要な OS 更新のインストールに失敗しました。" + +-#: ../plugins/xrandr/gsd-xrandr-manager.c:977 +-#, c-format +-msgid "Could not refresh the screen information: %s" +-msgstr "スクリーンの情報を更新できませんでした: %s" ++#~ msgid "Review" ++#~ msgstr "確認" ++ ++#~ msgid "Show details" ++#~ msgstr "詳細の表示" ++ ++#~ msgid "OK" ++#~ msgstr "OK" ++ ++#~ msgid "Software Updates available" ++#~ msgstr "ソフトウェアの更新が利用可能" ++ ++#~ msgid "Important OS and application updates are ready to be installed" ++#~ msgstr "OS とアプリケーションの重要な更新をインストールする準備ができました" ++ ++#~ msgid "GNOME Software" ++#~ msgstr "GNOME ソフトウェア" ++ ++#~ msgid "Not Now" ++#~ msgstr "あとで" + +-#: ../plugins/xrandr/xrandr.gnome-settings-plugin.in.h:1 +-msgid "XRandR" +-msgstr "XRandR" ++#~ msgid "View" ++#~ msgstr "表示" + +-#: ../plugins/xrandr/xrandr.gnome-settings-plugin.in.h:2 +-msgid "Set up screen size and rotation settings" +-msgstr "画面の大きさや回転といった設定を管理します" ++#~ msgid "Restart & Install" ++#~ msgstr "再起動してインストール" + +-#: ../plugins/xsettings/xsettings.gnome-settings-plugin.in.h:1 +-msgid "X Settings" +-msgstr "X の設定" ++#~ msgid "Updates plugin" ++#~ msgstr "更新プラグイン" + +-#: ../plugins/xsettings/xsettings.gnome-settings-plugin.in.h:2 +-msgid "Manage X Settings" +-msgstr "X の設定を管理します" ++#~ msgctxt "Wacom action-type" ++#~ msgid "None" ++#~ msgstr "なし" ++ ++#~ msgctxt "Wacom action-type" ++#~ msgid "Send Keystroke" ++#~ msgstr "キーストロークを送信" ++ ++#~ msgctxt "Wacom action-type" ++#~ msgid "Switch Monitor" ++#~ msgstr "モニターを切り替える" ++ ++#~ msgctxt "Wacom action-type" ++#~ msgid "Show On-Screen Help" ++#~ msgstr "オンスクリーンヘルプを表示" ++ ++#~ msgctxt "keyboard shortcut" ++#~ msgid "None" ++#~ msgstr "なし" ++ ++#~ msgid "Done" ++#~ msgstr "完了" ++ ++#~ msgid "Left Ring" ++#~ msgstr "左タッチホイール" ++ ++#~ msgid "Left Ring Mode #%d" ++#~ msgstr "左タッチホイールのモード #%d" ++ ++#~ msgid "Right Ring" ++#~ msgstr "右タッチホイール" ++ ++#~ msgid "Right Ring Mode #%d" ++#~ msgstr "右タッチホイールのモード #%d" ++ ++#~ msgid "Left Touchstrip" ++#~ msgstr "左トラックパッド" ++ ++#~ msgid "Left Touchstrip Mode #%d" ++#~ msgstr "左トラックパッドのモード #%d" ++ ++#~ msgid "Right Touchstrip" ++#~ msgstr "右トラックパッド" ++ ++#~ msgid "Right Touchstrip Mode #%d" ++#~ msgstr "右トラックパッドのモード #%d" ++ ++#~ msgid "Left Touchring Mode Switch" ++#~ msgstr "左タッチホイールのモードスイッチ" ++ ++#~ msgid "Right Touchring Mode Switch" ++#~ msgstr "右タッチホイールのモードスイッチ" ++ ++#~ msgid "Left Touchstrip Mode Switch" ++#~ msgstr "左トラックパッドのモードスイッチ" ++ ++#~ msgid "Right Touchstrip Mode Switch" ++#~ msgstr "右トラックパッドのモードスイッチ" ++ ++#~ msgid "Mode Switch #%d" ++#~ msgstr "モードスイッチ #%d" ++ ++#~ msgid "Left Button #%d" ++#~ msgstr "左ボタン #%d" ++ ++#~ msgid "Right Button #%d" ++#~ msgstr "右ボタン #%d" ++ ++#~ msgid "Top Button #%d" ++#~ msgstr "上ボタン #%d" ++ ++#~ msgid "Bottom Button #%d" ++#~ msgstr "下ボタン #%d" ++ ++#~ msgid "New shortcut…" ++#~ msgstr "新しいショートカット…" ++ ++#~ msgid "The \"%s\" tablet may not work as expected." ++#~ msgstr "\"%s\" タブレットは期待通りに動作しない可能性があります。" ++ ++#~ msgid "Unknown Tablet Connected" ++#~ msgstr "未知のタブレットを接続" ++ ++#~ msgid "Tablet %s needs to be calibrated." ++#~ msgstr "タブレット '%s' は、キャリブレーションする必要があります。" ++ ++#~ msgid "Calibration needed" ++#~ msgstr "キャリブレーションが必要" ++ ++#~ msgid "Calibrate" ++#~ msgstr "キャリブレーション" ++ ++#~ msgctxt "Action type" ++#~ msgid "None" ++#~ msgstr "なし" ++ ++#~ msgctxt "Action type" ++#~ msgid "Send Keystroke %s" ++#~ msgstr "キーストローク %s を送信" ++ ++#~ msgctxt "Action type" ++#~ msgid "Show On-Screen Help" ++#~ msgstr "オンスクリーンヘルプを表示" ++ ++#~ msgctxt "Action type" ++#~ msgid "Switch Monitor" ++#~ msgstr "モニターを切り替える" ++ ++#~ msgid "Mode %d: %s" ++#~ msgstr "モード %d: %s" ++ ++#~ msgid "(press any key to exit)" ++#~ msgstr "(何かキーを押して終了)" ++ ++#~ msgid "Push a button to configure" ++#~ msgstr "設定するボタンを押してください" ++ ++#~ msgid "(Esc to cancel)" ++#~ msgstr "(Esc でキャンセル)" ++ ++#~ msgid "Edit" ++#~ msgstr "編集" ++ ++#~ msgid "Wacom" ++#~ msgstr "Wacom" ++ ++#~ msgid "Wacom plugin" ++#~ msgstr "Wacom プラグイン" ++ ++#~ msgid "Could not refresh the screen information: %s" ++#~ msgstr "スクリーンの情報を更新できませんでした: %s" ++ ++#~ msgid "XRandR" ++#~ msgstr "XRandR" ++ ++#~ msgid "Set up screen size and rotation settings" ++#~ msgstr "画面の大きさや回転といった設定を管理します" ++ ++#~ msgid "X Settings" ++#~ msgstr "X の設定" ++ ++#~ msgid "Manage X Settings" ++#~ msgstr "X の設定を管理します" + + #~ msgid "Could not enable mouse accessibility features" + #~ msgstr "マウスの操作性に関する機能を有効にできませんでした" + +-#~ msgid "Mouse accessibility requires Mousetweaks to be installed on your system." +-#~ msgstr "マウスのアクセシビリティに関する機能を有効にするには mousetweaks がインストールされている必要があります。" ++#~ msgid "" ++#~ "Mouse accessibility requires Mousetweaks to be installed on your system." ++#~ msgstr "" ++#~ "マウスのアクセシビリティに関する機能を有効にするには mousetweaks がインス" ++#~ "トールされている必要があります。" + + #~ msgid "received error or hang up from event source" + #~ msgstr "イベントの発生源からエラーを受け取ったか、ハングアップしました" +@@ -3010,7 +3088,8 @@ msgstr "X の設定を管理します" + #~ msgstr "バックアップしたディスプレイの設定に戻せませんでした" + + #~ msgid "The display will be reset to its previous configuration in %d second" +-#~ msgid_plural "The display will be reset to its previous configuration in %d seconds" ++#~ msgid_plural "" ++#~ "The display will be reset to its previous configuration in %d seconds" + #~ msgstr[0] " %d秒後に元のディスプレイの設定に戻ります" + + #~ msgid "Does the display look OK?" +@@ -3154,7 +3233,9 @@ msgstr "X の設定を管理します" + #~ msgid "You have just inserted a digital audio player." + #~ msgstr "デジタルオーディオプレーヤーが接続されました。" + +-#~ msgid "You have just inserted a medium with software intended to be automatically started." ++#~ msgid "" ++#~ "You have just inserted a medium with software intended to be " ++#~ "automatically started." + #~ msgstr "自動実行のソフトウェアメディアが挿入されました。" + + #~ msgid "You have just inserted a medium." +@@ -3163,8 +3244,12 @@ msgstr "X の設定を管理します" + #~ msgid "Choose what application to launch." + #~ msgstr "使用するアプリケーションを選択してください。" + +-#~ msgid "Select how to open \"%s\" and whether to perform this action in the future for other media of type \"%s\"." +-#~ msgstr "\"%s\" を開く方法を選択し、この動作を将来ほかのメディアタイプ \"%s\" でも実施するか選択してください。" ++#~ msgid "" ++#~ "Select how to open \"%s\" and whether to perform this action in the " ++#~ "future for other media of type \"%s\"." ++#~ msgstr "" ++#~ "\"%s\" を開く方法を選択し、この動作を将来ほかのメディアタイプ \"%s\" でも" ++#~ "実施するか選択してください。" + + #~ msgid "_Always perform this action" + #~ msgstr "常にこの動作を実施する(_A)" +@@ -3181,8 +3266,12 @@ msgstr "X の設定を管理します" + #~ msgid "Allowed keys" + #~ msgstr "利用可能なキーバインディング" + +-#~ msgid "If non-empty, keybindings will be ignored unless their settings directory is in the list. This is useful for lockdown." +-#~ msgstr "空でない場合、設定ディレクトリがこのリストになければ、キーバインディングは無視されます。これは主にロックダウンで有用です。" ++#~ msgid "" ++#~ "If non-empty, keybindings will be ignored unless their settings directory " ++#~ "is in the list. This is useful for lockdown." ++#~ msgstr "" ++#~ "空でない場合、設定ディレクトリがこのリストになければ、キーバインディングは" ++#~ "無視されます。これは主にロックダウンで有用です。" + + #~ msgid "Do you want to activate Slow Keys?" + #~ msgstr "スロー・キーを有効にしますか?" +@@ -3255,8 +3344,13 @@ msgstr "X の設定を管理します" + #~ msgid "_Layouts" + #~ msgstr "レイアウト(_L)" + +-#~ msgid "Could not get default terminal. Verify that your default terminal command is set and points to a valid application." +-#~ msgstr "デフォルトの端末を起動できませんでした。デフォルトの端末を起動するコマンドが指定され、それに対応するアプリケーションがインストールされているか確認してください。" ++#~ msgid "" ++#~ "Could not get default terminal. Verify that your default terminal command " ++#~ "is set and points to a valid application." ++#~ msgstr "" ++#~ "デフォルトの端末を起動できませんでした。デフォルトの端末を起動するコマンド" ++#~ "が指定され、それに対応するアプリケーションがインストールされているか確認し" ++#~ "てください。" + + #~ msgid "" + #~ "Couldn't execute command: %s\n" +@@ -3274,9 +3368,6 @@ msgstr "X の設定を管理します" + #~ msgid "Slot ID" + #~ msgstr "スロットID" + +-#~ msgid "The slot the card is in" +-#~ msgstr "カードの入っているスロット" +- + #~ msgid "Slot Series" + #~ msgstr "スロットシリーズ" + +@@ -3289,11 +3380,17 @@ msgstr "X の設定を管理します" + #~ msgid "Module" + #~ msgstr "モジュール" + +-#~ msgid "Priority to use for this plugin in gnome-settings-daemon startup queue." +-#~ msgstr "gnome-settings-daemon の起動時のキューで、このプラグインが使用される優先度。" ++#~ msgid "" ++#~ "Priority to use for this plugin in gnome-settings-daemon startup queue." ++#~ msgstr "" ++#~ "gnome-settings-daemon の起動時のキューで、このプラグインが使用される優先" ++#~ "度。" + +-#~ msgid "Whether this plugin would be activated by gnome-settings-daemon or not." +-#~ msgstr "このプラグインが gnome-settings-daemon でアクティベーションされるかどうか。" ++#~ msgid "" ++#~ "Whether this plugin would be activated by gnome-settings-daemon or not." ++#~ msgstr "" ++#~ "このプラグインが gnome-settings-daemon でアクティベーションされるかどう" ++#~ "か。" + + #~ msgid "Binding to enable or disable the touchpad." + #~ msgstr "タッチパッドを有効にするか無効にするかのキーバインディングです。" +@@ -3301,8 +3398,12 @@ msgstr "X の設定を管理します" + #~ msgid "Keyboard _Preferences" + #~ msgstr "キーボードの設定(_P)" + +-#~ msgid "Disable the keyboard layout indicator unconditionally, do not show it even if number of layouts is more than one." +-#~ msgstr "無条件にキーボードレイアウトの通知を無効にします。レイアウトの数が1より大きくても表示しません。" ++#~ msgid "" ++#~ "Disable the keyboard layout indicator unconditionally, do not show it " ++#~ "even if number of layouts is more than one." ++#~ msgstr "" ++#~ "無条件にキーボードレイアウトの通知を無効にします。レイアウトの数が1より大" ++#~ "きくても表示しません。" + + #~ msgid "Never show layout indicator" + #~ msgstr "レイアウトの通知を表示しない" +@@ -3310,8 +3411,13 @@ msgstr "X の設定を管理します" + #~ msgid "DPI" + #~ msgstr "DPI" + +-#~ msgid "The resolution used for converting font sizes to pixel sizes, in dots per inch. 0.0 DPI means that the X server's DPI will be used." +-#~ msgstr "フォントの大きさをピクセル単位の大きさに変換する際に使用する解像度を、ドット/インチ (DPI) 単位で表したものです。0.0 DPI ならば、X サーバーの DPI が使われます。" ++#~ msgid "" ++#~ "The resolution used for converting font sizes to pixel sizes, in dots per " ++#~ "inch. 0.0 DPI means that the X server's DPI will be used." ++#~ msgstr "" ++#~ "フォントの大きさをピクセル単位の大きさに変換する際に使用する解像度を、ドッ" ++#~ "ト/インチ (DPI) 単位で表したものです。0.0 DPI ならば、X サーバーの DPI が" ++#~ "使われます。" + + #~ msgid "Removing: %s" + #~ msgstr "削除中: %s" +@@ -3328,8 +3434,12 @@ msgstr "X の設定を管理します" + #~ msgid "Empty all of the items from the trash?" + #~ msgstr "ゴミ箱の中のすべてのアイテムを空にしますか?" + +-#~ msgid "If you choose to empty the trash, all items in it will be permanently lost. Please note that you can also delete them separately." +-#~ msgstr "ゴミ箱を空にすることを選択すると、すべてのアイテムは永遠に失なわれます。別途、それらを削除できることに留意してください。" ++#~ msgid "" ++#~ "If you choose to empty the trash, all items in it will be permanently " ++#~ "lost. Please note that you can also delete them separately." ++#~ msgstr "" ++#~ "ゴミ箱を空にすることを選択すると、すべてのアイテムは永遠に失なわれます。別" ++#~ "途、それらを削除できることに留意してください。" + + #~ msgid "_Empty Trash" + #~ msgstr "ゴミ箱を空にする(_E)" +@@ -3346,5 +3456,3 @@ msgstr "X の設定を管理します" + #~ msgid "Display keyboard LEDs on the panel" + #~ msgstr "キーボードの LED をパネルに表示する" + +-#~ msgid "Display pseudo-leds for keyboards that do not have physical LEDs for CapsLock, NumLock, and ScrollLock." +-#~ msgstr "物理的な LED を持たない CapsLock、NumLock、ScrollLock の擬似 LED を表示します。" +diff --git a/po/zh_CN.po b/po/zh_CN.po +index 86f2f3e4..9492ec38 100644 +--- a/po/zh_CN.po ++++ b/po/zh_CN.po +@@ -25,9 +25,8 @@ + msgid "" + msgstr "" + "Project-Id-Version: gnome-settings-daemon master\n" +-"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-" +-"settings-daemon&keywords=I18N+L10N&component=general\n" +-"POT-Creation-Date: 2017-09-01 14:22+0000\n" ++"Report-Msgid-Bugs-To: \n" ++"POT-Creation-Date: 2021-02-12 15:05+0100\n" + "PO-Revision-Date: 2017-09-02 01:42+0800\n" + "Last-Translator: Mingcong Bai \n" + "Language-Team: Chinese (simplified) \n" +@@ -38,319 +37,315 @@ msgstr "" + "Plural-Forms: nplurals=1; plural=0;\n" + "X-Generator: Poedit 2.0.2\n" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:1 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:12 + msgid "Smartcard removal action" + msgstr "智能卡移除动作" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:2 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:13 + msgid "" + "Set this to one of “none”, “lock-screen”, or “force-logout”. The action will " + "get performed when the smartcard used for log in is removed." +-msgstr "" +-"设置为“none”、“lock_screen”或“force_logout”之一。 当用于登录的智能卡被移除" +-"时,将执行这个动作。" ++msgstr "设置为“none”、“lock_screen”或“force_logout”之一。 当用于登录的智能卡被移除时,将执行这个动作。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:3 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:25 + msgid "Possible values are “on”, “off”, and “custom”." + msgstr "可用的值为“on”,“off”及“custom”。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:4 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:35 + msgid "Keyboard Bell Custom Filename" + msgstr "自定义键盘响铃文件" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:5 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:36 + msgid "File name of the bell sound to be played." + msgstr "要播放的响铃声音文件名。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:6 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:40 + msgid "Remember NumLock state" + msgstr "记住 NumLock 状态" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:7 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:41 + msgid "" + "When set to true, GNOME will remember the state of the NumLock LED between " + "sessions." + msgstr "当设为 true 时,GNOME 会在会话之间记住 NumLock LED 的状态。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:8 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:45 + msgid "NumLock state" + msgstr "NumLock 状态" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:9 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:46 + msgid "The remembered state of the NumLock LED." + msgstr "要记住的 NumLock LED 状态。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:10 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:52 + msgid "" + "Highlights the current location of the pointer when the Control key is " + "pressed and released." + msgstr "当按下并放开 Ctrl 键时,高亮显示鼠标指针的当前位置。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:11 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:56 + msgid "Double click time" + msgstr "双击时间" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:12 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:57 + msgid "Length of a double click in milliseconds." + msgstr "双击时长(以毫秒为单位)。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:13 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:61 + msgid "Drag threshold" + msgstr "触发拖拽动作的最小距离" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:14 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:62 + msgid "Distance before a drag is started." + msgstr "触发拖动的最小距离。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:15 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:68 + msgid "Whether the tablet’s orientation is locked, or rotated automatically." + msgstr "是锁定数位板的方向,还是自动旋转。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:16 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:76 + msgid "Mouse button orientation" + msgstr "鼠标键方向" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:17 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:77 + msgid "Swap left and right mouse buttons for left-handed mice." + msgstr "在左撇子鼠标上交换左右鼠标键。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:18 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:81 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:143 + msgid "Single Click" + msgstr "单击" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:19 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:82 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:144 + msgid "" + "Acceleration multiplier for mouse motion. A value of -1 is the system " + "default." + msgstr "鼠标运动的加速乘数。-1 为系统默认值。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:20 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:86 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:148 + msgid "Motion Threshold" + msgstr "触发加速的最小距离" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:21 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:87 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:149 + msgid "" + "Distance in pixels the pointer must move before accelerated mouse motion is " + "activated. A value of -1 is the system default." + msgstr "按像素计算的触发鼠标加速运动的最小距离。-1 为系统默认值。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:22 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:91 + msgid "Middle button emulation" + msgstr "中键模拟" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:23 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:92 + msgid "" + "Enables middle mouse button emulation through simultaneous left and right " + "button click." + msgstr "启用通过同时点击左键和右键来模拟中键。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:24 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:101 + msgid "Key Repeat Interval" + msgstr "键位重复间隔" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:25 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:102 + msgid "Delay between repeats in milliseconds." + msgstr "按毫秒计算的键位重复间的间隔。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:26 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:106 + msgid "Initial Key Repeat Delay" + msgstr "初始键位重复间隔" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:27 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:107 + msgid "Initial key repeat delay in milliseconds." + msgstr "按毫秒计算的初始键位重复间隔。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:28 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:113 + msgid "Disable touchpad while typing" + msgstr "在输入时禁用触摸板" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:29 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:114 + msgid "" + "Set this to TRUE if you have problems with accidentally hitting the touchpad " + "while typing." + msgstr "如果您打字时会因偶尔会碰到触摸板而造成麻烦,将其设置为真(TRUE)。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:30 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:118 + msgid "Enable horizontal scrolling" + msgstr "启用水平滚动" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:31 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:119 + msgid "" + "Set this to TRUE to allow horizontal scrolling by the same method selected " + "with the scroll_method key." +-msgstr "" +-"设置为真(TRUE),即启用水平卷页且使用与 scroll_method 键值选定的同种方式。" ++msgstr "设置为真(TRUE),即启用水平卷页且使用与 scroll_method 键值选定的同种方式。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:32 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:123 + msgid "Select the touchpad scroll method" + msgstr "选择触摸板滚动模式" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:33 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:124 + msgid "" + "Select the touchpad scroll method. Supported values are: “disabled”, “edge-" + "scrolling”, “two-finger-scrolling”." +-msgstr "" +-"选择触摸板滚动模式。支持的值有:“disabled”(禁用),“edge-scrolling”(边界滚" +-"动),“two-finger-scrolling”(双指滚动)。" ++msgstr "选择触摸板滚动模式。支持的值有:“disabled”(禁用),“edge-scrolling”(边界滚动),“two-finger-scrolling”(双指滚动)。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:34 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:128 + msgid "Enable mouse clicks with touchpad" + msgstr "启用触摸板的鼠标点击功能" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:35 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:129 + msgid "" + "Set this to TRUE to be able to send mouse clicks by tapping on the touchpad." + msgstr "设置为真(TRUE),即可在轻敲触摸板时发送鼠标点击信息。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:36 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:133 + msgid "Enable touchpad" + msgstr "启用触摸板" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:37 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:134 + msgid "Set this to TRUE to enable all touchpads." + msgstr "设置为真(TRUE)启用所有触摸板" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:38 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:138 + msgid "Touchpad button orientation" + msgstr "触摸板按键方向" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:39 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:139 + msgid "" + "Swap left and right mouse buttons for left-handed mice with “left”, “right” " + "for right-handed, “mouse” to follow the mouse setting." +-msgstr "" +-"设定“left”值以为左撇子鼠标交换左右鼠标按钮,为右撇子鼠标设定“right”值,设" +-"定“mouse”值以跟随鼠标设置。" ++msgstr "设定“left”值以为左撇子鼠标交换左右鼠标按钮,为右撇子鼠标设定“right”值,设定“mouse”值以跟随鼠标设置。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:40 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:153 + msgid "Natural scrolling" + msgstr "自然滚动" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:41 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:154 + msgid "Set this to TRUE to enable natural (reverse) scrolling for touchpads." + msgstr "将此值设置为 TRUE 以为触摸板启用自然(反向)滚动。" + +-#: ../data/org.gnome.settings-daemon.peripherals.gschema.xml.in.in.h:42 ++#: data/org.gnome.settings-daemon.peripherals.gschema.xml.in:161 + msgid "Mouse wheel emulation button. 0 to disable the feature." + msgstr "鼠标滚轮模拟键。设定 0 值以关闭此特性。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:1 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:10 + msgid "Wacom stylus absolute mode" +-msgstr "Wacom 手写笔绝对模式" ++msgstr "Wacom 手写笔绝对模式" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:2 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:11 + msgid "Enable this to set the tablet to absolute mode." + msgstr "启用此设置数位板为绝对模式" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:3 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:15 + msgid "Wacom tablet area" + msgstr "Wacom 数位板区域" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:4 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:16 + msgid "Set this to x1, y1 and x2, y2 of the area usable by the tools." + msgstr "将此值设置到此工具可以使用区域的 x1, y1 和 x2, y2。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:5 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:20 + msgid "Wacom tablet aspect ratio" + msgstr "Wacom 的数位板长宽比" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:6 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:21 + msgid "" + "Enable this to restrict the Wacom tablet area to match the aspect ratio of " + "the output." + msgstr "启用此设置限制数位板的区域以匹配输出的长宽比" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:7 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:25 + msgid "Wacom tablet rotation" + msgstr "Wacom 的数位板旋转" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:8 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:26 + msgid "" + "Set this to “none”, “cw” for 90 degree clockwise, “half” for 180 degree, and " + "“ccw” for 90 degree counterclockwise." +-msgstr "" +-"可以设置为“nono”,“cw”(顺时针 90 度),“half”(180 度),和“ccw”(逆时针90" +-"度)。" ++msgstr "可以设置为“nono”,“cw”(顺时针 90 度),“half”(180 度),和“ccw”(逆时针90度)。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:9 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:30 + msgid "Wacom touch feature" + msgstr "Wacom 的触控功能" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:10 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:31 + msgid "Enable this to move the cursor when the user touches the tablet." + msgstr "启用此项以在用户碰到数位板时移动光标。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:11 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:37 + msgid "Wacom stylus pressure curve" + msgstr "Wacom 手写笔压力曲线" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:12 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:38 + msgid "" + "Set this to x1, y1 and x2, y2 of the pressure curve applied to the stylus." + msgstr "将此值设置到 x1,y1 和 x2,y2 适用于手写笔压力曲线。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:13 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:42 + msgid "Wacom stylus button mapping" +-msgstr "Wacom 手写笔按钮映射" ++msgstr "Wacom 手写笔按钮映射" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:14 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:43 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:60 + msgid "Set this to the logical button mapping." + msgstr "逻辑按键映射设置。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:15 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:47 + msgid "Wacom stylus pressure threshold" + msgstr "Wacom 手写笔压力临界值" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:16 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:48 + msgid "" + "Set this to the pressure value at which a stylus click event is generated." + msgstr "当手写笔触摸活动发生时设置这个压力值" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:17 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:54 + msgid "Wacom eraser pressure curve" + msgstr "Wacom 擦写压力曲线" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:18 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:55 + msgid "" + "Set this to x1, y1 and x2, y2 of the pressure curve applied to the eraser." +-msgstr "将此值设置到 x1, y1 和 x2, y2 适用于擦写压力曲线。" ++msgstr "将此值设置到 x1, y1 和 x2, y2 适用于擦写压力曲线。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:19 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:59 + msgid "Wacom eraser button mapping" + msgstr "Wacom 擦写按钮映射" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:20 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:64 + msgid "Wacom eraser pressure threshold" + msgstr "Wacom 擦写压力临界值" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:21 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:65 + msgid "" + "Set this to the pressure value at which an eraser click event is generated." + msgstr "将此设置到压力值" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:22 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:71 + msgid "Wacom button action type" + msgstr "Wacom 按钮动作类型" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:23 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:72 + msgid "The type of action triggered by the button being pressed." + msgstr "按钮按下时触发的动作类型。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:24 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:76 + msgid "Key combination for the custom action" + msgstr "自定义动作的键绑定" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:25 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:77 + msgid "" + "The keyboard shortcut generated when the button is pressed for custom " + "actions." + msgstr "按下自定义动作的键时产生的键盘快捷方式。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:26 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:81 + msgid "Key combinations for a touchring or touchstrip custom action" + msgstr "触摸环或触摸带自定义动作的的键组合" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:27 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:82 + msgid "" + "The keyboard shortcuts generated when a touchring or touchstrip is used for " + "custom actions (up followed by down)." +@@ -358,574 +353,568 @@ msgstr "当触摸环或触摸带用做自定义动作(先向上再向下)时, + + #. Translators: This is the OLED display on an Intuos4 tablet: + #. http://eu.shop.wacom.eu/images/articles/d9abd9f2d4d88aa0649cda97a8077e2b_8.jpg +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:30 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:88 + msgid "Button label for OLED display." + msgstr "OLED 显示屏的按钮标签。" + +-#: ../data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in.in.h:31 ++#: data/org.gnome.settings-daemon.peripherals.wacom.gschema.xml.in:89 + msgid "Label will be rendered to OLED display belonging to the button" + msgstr "标签将被绘制到属于该按钮的 OLED 显示屏上" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:1 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:6 + msgid "The duration a display profile is valid" + msgstr "显示配置的有效期" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:2 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:7 + msgid "" + "This is the number of days after which the display color profile is " + "considered invalid." + msgstr "这是将显示颜色配置视为无效之前的持续天数" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:3 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:11 + msgid "The duration a printer profile is valid" + msgstr "打印机配置的有效期" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:4 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:12 + msgid "" + "This is the number of days after which the printer color profile is " + "considered invalid." + msgstr "这是将打印机配置视为无效之前的持续天数。" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:5 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:16 + msgid "If the night light mode is enabled" + msgstr "夜光模式是否已启用" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:6 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:17 + msgid "" + "Night light mode changes the color temperature of your display when the sun " +-"has gone down or at present times." +-msgstr "夜光模式可以根据太阳位置或当前时间修改您显示器的色温。" ++"has gone down or at preset times." ++msgstr "夜光模式可以在没有日光的情况或当前时间修改显示的色温。" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:7 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:21 + msgid "Temperature of the display when enabled" + msgstr "显示器的色温模式启用时" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:8 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:22 + msgid "" + "This temperature in Kelvin is used to modify the screen tones when night " + "light mode is enabled. Higher values are bluer, lower redder." +-msgstr "" +-"当夜光模式启用时,以开尔文表示的色温用来修改屏幕色调。数值越高蓝光量越多,反" +-"只红光量越多。" ++msgstr "当夜光模式启用时,以开尔文表示的色温用来修改屏幕色调。数值越高蓝光量越多,反只红光量越多。" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:9 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:26 + msgid "Use the sunrise and sunset" + msgstr "使用日出和日落" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:10 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:27 + msgid "" + "Calculate the sunrise and sunset times automatically, from the current " + "location." + msgstr "根据当前位置自动计算日出和日落。" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:11 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:31 + msgid "The start time" + msgstr "开始时间" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:12 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:32 + msgid "" + "When “night-light-schedule-automatic” is disabled, use this start time in " + "hours from midnight." +-msgstr "" +-"禁用“night-light-schedule-automatic”时,使用此距离午夜的小时数作为开始时间。" ++msgstr "禁用“night-light-schedule-automatic”时,使用此距离午夜的小时数作为开始时间。" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:13 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:36 + msgid "The end time" + msgstr "结束时间" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:14 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:37 + msgid "" + "When “night-light-schedule-automatic” is disabled, use this end time in " + "hours from midnight." +-msgstr "" +-"禁用“night-light-schedule-automatic”时,使用此距离午夜的小时数作为结束时间。" ++msgstr "禁用“night-light-schedule-automatic”时,使用此距离午夜的小时数作为结束时间。" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:15 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:41 + msgid "The last detected position" + msgstr "最后定位点" + +-#: ../data/org.gnome.settings-daemon.plugins.color.gschema.xml.in.in.h:16 ++#: data/org.gnome.settings-daemon.plugins.color.gschema.xml.in:42 + msgid "" + "When location services are available this represents the last detected " + "location. The default value is an invalid value to ensure it is always " + "updated at startup." +-msgstr "" +-"定位服务启用时当前最后一次获取到的位置。默认是一个无效值以保证总是会在启动时" +-"更新。" ++msgstr "定位服务启用时当前最后一次获取到的位置。默认是一个无效值以保证总是会在启动时更新。" + +-#: ../data/org.gnome.settings-daemon.plugins.gschema.xml.in.in.h:1 ++#: data/org.gnome.settings-daemon.plugins.gschema.xml.in:6 + msgid "List of plugins that are allowed to be loaded" + msgstr "允许加载的插件列表" + +-#: ../data/org.gnome.settings-daemon.plugins.gschema.xml.in.in.h:2 ++#: data/org.gnome.settings-daemon.plugins.gschema.xml.in:7 + msgid "" + "A list of strings representing the plugins that are allowed to be loaded " + "(default: “all”). This is only evaluated on startup." +-msgstr "" +-"一个代表允许加载插件的字符串列表(默认为“all”)。启动时才会检查此列表。" ++msgstr "一个代表允许加载插件的字符串列表(默认为“all”)。启动时才会检查此列表。" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:1 ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:6 + msgid "Mount paths to ignore" + msgstr "要忽略的挂载路径" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:2 ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:7 + msgid "Specify a list of mount paths to ignore when they run low on space." + msgstr "指定当运行在低硬盘空间时要忽略的挂载路径清单" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:3 ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:12 + msgid "Free percentage notify threshold" + msgstr "触发通知的最低可用百分比" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:4 ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:13 + msgid "" + "Percentage free space threshold for initial warning of low disk space. If " + "the percentage free space drops below this, a warning will be shown." +-msgstr "" +-"触发低硬盘空间初次警告的最低可用空间百分比。如果可用空间的百分比低于该值,将" +-"显示一个警告" ++msgstr "触发低硬盘空间初次警告的最低可用空间百分比。如果可用空间的百分比低于该值,将显示一个警告" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:5 ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:18 + msgid "Subsequent free space percentage notify threshold" + msgstr "触发通知的最低后续可用空间百分比" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:6 ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:19 + msgid "" + "Specify the percentage that the free disk space should reduce by before " + "issuing a subsequent warning." + msgstr "在发布一个后续警告之前,指定应减少的可用硬盘空间百分比。" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:7 ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:23 + msgid "Free space notify threshold" + msgstr "触发通知的最低可用空间" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:8 ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:24 + msgid "" + "Specify an amount in GB. If the amount of free space is more than this, no " + "warning will be shown." + msgstr "以 GB 为单位指定某个量。如果可用空间超过该值,将不再显示警告。" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:9 ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:28 + msgid "Minimum notify period for repeated warnings" + msgstr "重复警告的最小通知周期" + +-#: ../data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in.in.h:10 ++#: data/org.gnome.settings-daemon.plugins.housekeeping.gschema.xml.in:29 + msgid "" + "Specify a time in minutes. Subsequent warnings for a volume will not appear " + "more often than this period." + msgstr "以分钟为单位指定某个时间。该周期内不会多次显示某个卷的后续警告。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:1 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:6 + msgid "Custom keybindings" + msgstr "自定义键绑定" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:2 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:7 + msgid "List of custom keybindings" + msgstr "自定义键绑定列表" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:3 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:11 + msgid "Launch calculator" + msgstr "启动计算器" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:4 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:12 + msgid "Binding to launch the calculator." + msgstr "调用计算器的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:5 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:16 + msgid "Launch settings" + msgstr "启动设置" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:6 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:17 + msgid "Binding to launch GNOME settings." + msgstr "调用 GNOME 设置的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:7 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:21 + msgid "Launch email client" + msgstr "启动电子邮件客户端" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:8 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:22 + msgid "Binding to launch the email client." + msgstr "调用电子邮件客户端的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:9 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:26 + msgid "Eject" + msgstr "弹出" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:10 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:27 + msgid "Binding to eject an optical disc." + msgstr "弹出光盘的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:11 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:31 + msgid "Launch help browser" + msgstr "启动帮助浏览器" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:12 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:32 + msgid "Binding to launch the help browser." + msgstr "调用帮助浏览器的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:13 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:36 + msgid "Home folder" + msgstr "主文件夹" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:14 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:37 + msgid "Binding to open the Home folder." + msgstr "打开主文件夹的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:15 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:41 + msgid "Launch media player" + msgstr "启动媒体播放机" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:16 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:42 + msgid "Binding to launch the media player." + msgstr "调用媒体播放机的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:17 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:46 + msgid "Next track" + msgstr "下一音轨" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:18 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:47 + msgid "Binding to skip to next track." + msgstr "跳到下一音轨的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:19 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:51 + msgid "Pause playback" + msgstr "暂停回放" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:20 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:52 + msgid "Binding to pause playback." + msgstr "暂停播放的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:21 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:56 + msgid "Play (or play/pause)" + msgstr "播放(或播放/暂停)" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:22 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:57 + msgid "Binding to start playback (or toggle play/pause)." + msgstr "开始回放或切换 播放/暂停 的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:23 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:61 + msgid "Log out" + msgstr "注销" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:24 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:62 + msgid "Binding to log out." + msgstr "注销的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:25 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:66 + msgid "Previous track" + msgstr "上一音轨" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:26 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:67 + msgid "Binding to skip to previous track." + msgstr "跳到上一音轨的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:27 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:71 + msgid "Lock screen" + msgstr "锁住屏幕" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:28 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:72 + msgid "Binding to lock the screen." + msgstr "锁住屏幕的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:29 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:76 + msgid "Search" + msgstr "搜索" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:30 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:77 + msgid "Binding to launch the search tool." + msgstr "调用搜索工具的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:31 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:81 + msgid "Stop playback" + msgstr "停止回放" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:32 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:82 + msgid "Binding to stop playback." + msgstr "停止回放的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:33 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:86 + msgid "Volume down" + msgstr "音量降低" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:34 +-msgid "Binding to lower the system volume." +-msgstr "降低系统音量的键绑定。" ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:87 ++msgid "Binding to lower the volume." ++msgstr "降低音量。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:35 +-msgid "Volume mute" +-msgstr "静音" ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:91 ++msgid "Volume mute/unmute" ++msgstr "静音/取消静音" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:36 +-msgid "Binding to mute the system volume." +-msgstr "使系统静音的键绑定。" ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:92 ++msgid "Binding to mute/unmute the volume." ++msgstr "静音/取消静音。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:37 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:96 + msgid "Volume up" + msgstr "音量升高" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:38 +-msgid "Binding to raise the system volume." +-msgstr "升高系统音量的键绑定。" ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:97 ++msgid "Binding to raise the volume." ++msgstr "升高音量。" ++ ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:101 ++msgid "Microphone mute/unmute" ++msgstr "话筒静音/取消静音" ++ ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:102 ++msgid "Binding to mute/unmute the microphone." ++msgstr "话筒静音/取消静音。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:39 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:106 + msgid "Take a screenshot" + msgstr "截图" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:40 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:107 + msgid "Binding to take a screenshot." + msgstr "截图的快捷键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:41 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:111 + msgid "Take a screenshot of a window" + msgstr "截取窗口的截图" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:42 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:112 + msgid "Binding to take a screenshot of a window." + msgstr "截取窗口截图的快捷键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:43 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:116 + msgid "Take a screenshot of an area" + msgstr "截取一个区域的截图" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:44 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:117 + msgid "Binding to take a screenshot of an area." + msgstr "截取一个区域的截图快捷键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:45 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:121 + msgid "Copy a screenshot to clipboard" + msgstr "将截图复制到剪切板" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:46 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:122 + msgid "Binding to copy a screenshot to clipboard." + msgstr "将截图复制到剪切板的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:47 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:126 + msgid "Copy a screenshot of a window to clipboard" + msgstr "复制窗口的截图到剪切板" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:48 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:127 + msgid "Binding to copy a screenshot of a window to clipboard." + msgstr "复制窗口截图到剪切板的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:49 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:131 + msgid "Copy a screenshot of an area to clipboard" + msgstr "复制一个区域的截图到剪切板" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:50 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:132 + msgid "Binding to copy a screenshot of an area to clipboard." + msgstr "复制一个区域的截图到剪切板的快捷键。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:51 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:136 + msgid "Record a short video of the screen" + msgstr "录制屏幕操作的短视频" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:52 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:137 + msgid "Binding to record a short video of the screen" + msgstr "录制屏幕短视频的组合键绑定" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:53 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:141 + msgid "Launch web browser" + msgstr "启动网络浏览器" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:54 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:142 + msgid "Binding to launch the web browser." + msgstr "调用网络浏览器的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:55 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:146 + msgid "Toggle magnifier" + msgstr "切换放大镜" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:56 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:147 + msgid "Binding to show the screen magnifier" + msgstr "显示屏幕放大镜的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:57 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:151 + msgid "Toggle screen reader" + msgstr "切换屏幕阅读器" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:58 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:152 + msgid "Binding to start the screen reader" + msgstr "启动屏幕阅读器的键绑定" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:59 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:156 + msgid "Toggle on-screen keyboard" + msgstr "切换屏幕上键盘" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:60 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:157 + msgid "Binding to show the on-screen keyboard" + msgstr "显示屏幕键盘的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:61 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:161 + msgid "Increase text size" + msgstr "增大文本字号" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:62 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:162 + msgid "Binding to increase the text size" + msgstr "增大文本字号的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:63 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:166 + msgid "Decrease text size" + msgstr "减小文本字号" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:64 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:167 + msgid "Binding to decrease the text size" + msgstr "减小文本字号的键绑定。" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:65 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:171 + msgid "Toggle contrast" + msgstr "切换对比度" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:66 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:172 + msgid "Binding to toggle the interface contrast" + msgstr "界面对比度切换的键绑定" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:67 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:176 + msgid "Magnifier zoom in" + msgstr "放大镜放大" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:68 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:177 + msgid "Binding for the magnifier to zoom in" + msgstr "屏幕放大镜进行放大的键绑定" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:69 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:181 + msgid "Magnifier zoom out" + msgstr "放大镜缩小" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:70 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:182 + msgid "Binding for the magnifier to zoom out" + msgstr "屏幕放大镜进行缩小的键绑定" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:71 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:186 + msgid "Maximum length of screen recordings" + msgstr "屏幕录制的最大长度" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:72 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:187 + msgid "" + "The maximum length of single screen cast recordings in seconds or 0 for " + "unlimited" + msgstr "按秒计算的屏幕录制的最大长度,设置为 0 以取消限制" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:73 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:194 + msgid "Name" + msgstr "名称" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:74 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:195 + msgid "Name of the custom binding" + msgstr "自定义绑定的名称" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:75 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:199 + msgid "Binding" + msgstr "绑定" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:76 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:200 + msgid "Binding for the custom binding" + msgstr "用于自定义绑定的绑定" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:77 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:204 + msgid "Command" + msgstr "命令" + +-#: ../data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in.in.h:78 ++#: data/org.gnome.settings-daemon.plugins.media-keys.gschema.xml.in:205 + msgid "Command to run when the binding is invoked" + msgstr "触发此绑定时运行的命令。" + +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:1 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:6 + msgid "The brightness of the screen when idle" + msgstr "空闲时的屏幕亮度。" + +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:2 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:7 + msgid "" + "This is the laptop panel screen brightness used when the session is idle." + msgstr "这是会话空闲时笔记本电脑屏幕使用的亮度。" + +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:3 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:11 + msgid "Dim the screen after a period of inactivity" + msgstr "在空闲一段时间后黯淡屏幕" + +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:4 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:12 + msgid "If the screen should be dimmed to save power when the computer is idle." + msgstr "是否在电脑空闲时黯淡屏幕以节省能源。" + +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:5 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:16 + msgid "Sleep timeout computer when on AC" + msgstr "电脑插入交流电时的睡眠超时" + +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:6 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:17 + msgid "" + "The amount of time in seconds the computer on AC power needs to be inactive " + "before it goes to sleep. A value of 0 means never." +-msgstr "" +-"按秒计算的,电脑插入交流电后进入睡眠状态之前的空闲时长。0 值意味着永远不睡" +-"眠。" ++msgstr "按秒计算的,电脑插入交流电后进入睡眠状态之前的空闲时长。0 值意味着永远不睡眠。" + +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:7 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:21 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:31 + msgid "Whether to hibernate, suspend or do nothing when inactive" + msgstr "空闲时休眠,挂起或不作任何操作" + +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:8 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:22 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:32 + msgid "" + "The type of sleeping that should be performed when the computer is inactive." + msgstr "电脑空闲时采用的睡眠类型。" + +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:9 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:26 + msgid "Sleep timeout computer when on battery" + msgstr "电脑使用电池电源时的睡眠超时" + +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:10 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:27 + msgid "" + "The amount of time in seconds the computer on battery power needs to be " + "inactive before it goes to sleep. A value of 0 means never." +-msgstr "" +-"按秒计算的,电脑使用电池时进入睡眠状态之前的空闲时长。0 值意味着永远不睡眠。" ++msgstr "按秒计算的,电脑使用电池时进入睡眠状态之前的空闲时长。0 值意味着永远不睡眠。" + +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:11 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:36 + msgid "Enable the ALS sensor" + msgstr "启用 ALS 感应器" + +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:12 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:37 + msgid "If the ambient light sensor functionality is enabled." + msgstr "是否启用环境光感应器。" + +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:13 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:41 + msgid "Power button action" + msgstr "电源按钮动作" + +-#: ../data/org.gnome.settings-daemon.plugins.power.gschema.xml.in.in.h:14 ++#: data/org.gnome.settings-daemon.plugins.power.gschema.xml.in:42 + msgid "" + "The action to take when the system power button is pressed. This action is " + "hard-coded (and the setting ignored) on virtual machines (power off) and " + "tablets (suspend)." +-msgstr "" +-"按下系统电源按钮时进行的动作。该动作在虚拟机和平板电脑上是硬编码的(分别为关" +-"机和挂起)。" ++msgstr "按下系统电源按钮时进行的动作。该动作在虚拟机和平板电脑上是硬编码的(分别为关机和挂起)。" + +-#: ../data/org.gnome.settings-daemon.plugins.sharing.gschema.xml.in.in.h:1 ++#: data/org.gnome.settings-daemon.plugins.sharing.gschema.xml.in:6 + msgid "On which connections the service is enabled" + msgstr "服务已经被启用的连接" + +-#: ../data/org.gnome.settings-daemon.plugins.sharing.gschema.xml.in.in.h:2 ++#: data/org.gnome.settings-daemon.plugins.sharing.gschema.xml.in:7 + msgid "" + "The list of NetworkManager connections (each one represented with its UUID) " + "on which this service is enabled and started." + msgstr "服务已经被启用并启动的 NetworkManager 连接的列表(以UUID表示)。" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:1 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:6 + msgid "Antialiasing" + msgstr "反锯齿" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:2 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:7 + msgid "" + "The type of antialiasing to use when rendering fonts. Possible values are: " + "“none” for no antialiasing, “grayscale” for standard grayscale antialiasing, " + "and “rgba” for subpixel antialiasing (LCD screens only)." +-msgstr "" +-"绘制字体时使用的反锯齿类型。可能的设定有:“none”无反锯齿。“grayscale”标准灰度" +-"反锯齿。“rgba”次像素反锯齿(LCD 屏幕专用)。" ++msgstr "绘制字体时使用的反锯齿类型。可能的设定有:“none”无反锯齿。“grayscale”标准灰度反锯齿。“rgba”次像素反锯齿(LCD 屏幕专用)。" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:3 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:11 + msgid "Hinting" + msgstr "微调" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:4 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:12 + msgid "" + "The type of hinting to use when rendering fonts. Possible values are: “none” " + "for no hinting and “slight” for fitting only to the Y-axis like Microsoft’s " +@@ -937,437 +926,328 @@ msgid "" + "(except for .otf: Y-only). This can lead to distortion and/or inconsistent " + "rendering depending on the quality of the font, the font format and the " + "state of FreeType’s font engines." +-msgstr "" +-"渲染字体时要使用的微调设置。可能的数值有:“none”表示无微调。“slight”表示仅将" +-"字形对齐到 Y 轴,就像微软 ClearType、DirectWrite 和 Adobe 的专有字体渲染引擎" +-"一样。这将忽略字体内部的微调信息,直接使用自动算法进行微调。Ubuntu 默认使用这" +-"个设置,推荐使用这个设置。“medium”和“full”的含义取决于字体格式 (.ttf、.otf、." +-"pfa 或 .pfb) 和已安装的 FreeType 版本。这两者一般尝试将字符图形同时对齐到 X " +-"和 Y 轴(.otf 只对齐到 Y 轴)。这可能会导致混乱和/或不一致的渲染,取决于字体" +-"质量、字体格式和 FreeType 引擎的状态。" +- +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:5 ++msgstr "渲染字体时要使用的微调设置。可能的数值有:“none”表示无微调。“slight”表示仅将字形对齐到 Y 轴,就像微软 ClearType、DirectWrite 和 Adobe 的专有字体渲染引擎一样。这将忽略字体内部的微调信息,直接使用自动算法进行微调。Ubuntu 默认使用这个设置,推荐使用这个设置。“medium”和“full”的含义取决于字体格式 (.ttf、.otf、.pfa 或 .pfb) 和已安装的 FreeType 版本。这两者一般尝试将字符图形同时对齐到 X 和 Y 轴(.otf 只对齐到 Y 轴)。这可能会导致混乱和/或不一致的渲染,取决于字体质量、字体格式和 FreeType 引擎的状态。" ++ ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:16 + msgid "RGBA order" + msgstr "RGBA 顺序" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:6 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:17 + msgid "" + "The order of subpixel elements on an LCD screen; only used when antialiasing " + "is set to “rgba”. Possible values are: “rgb” for red on left (most common), " + "“bgr” for blue on left, “vrgb” for red on top, “vbgr” for red on bottom." +-msgstr "" +-"LCD 屏幕上次像素的顺序;仅在反锯齿设为“rgba”时有用。可能的设定值有:“rgb”红色" +-"在左侧(最常见设置)。“bgr”蓝色在左侧。“vrgb”红色在上端。“vbgr”红色在底部。" ++msgstr "LCD 屏幕上次像素的顺序;仅在反锯齿设为“rgba”时有用。可能的设定值有:“rgb”红色在左侧(最常见设置)。“bgr”蓝色在左侧。“vrgb”红色在上端。“vbgr”红色在底部。" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:7 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:21 + msgid "List of explicitly disabled GTK+ modules" + msgstr "单独指定禁止的 GTK+ 模块清单" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:8 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:22 + msgid "" + "A list of strings representing the GTK+ modules that will not be loaded, " + "even if enabled by default in their configuration." + msgstr "代表将不被加载的 GTK+ 模块的字符串列表,即便是其默认配置中启用的。" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:9 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:26 + msgid "List of explicitly enabled GTK+ modules" + msgstr "单独指定启用的 GTK+ 模块清单" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:10 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:27 + msgid "" + "A list of strings representing the GTK+ modules that will be loaded, usually " + "in addition to conditional and forcibly disabled ones." +-msgstr "" +-"代表将加载的 GTK+ 模块的字符串列表,通常加上有条件的和强制禁止的一些模块。" ++msgstr "代表将加载的 GTK+ 模块的字符串列表,通常加上有条件的和强制禁止的一些模块。" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:11 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:31 + msgid "A dictionary of XSETTINGS to override" + msgstr "要覆盖的 XSETTINGS 字典" + +-#: ../data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in.in.h:12 ++#: data/org.gnome.settings-daemon.plugins.xsettings.gschema.xml.in:32 + msgid "" + "This dictionary maps XSETTINGS names to overrides values. The values must be " + "either strings, signed int32s or (in the case of colors), 4-tuples of uint16 " + "(red, green, blue, alpha; 65535 is fully opaque)." +-msgstr "" +-"该字典用于映射需要覆盖的 XSETTINGS 为指定值。该值必须为字符串,signed int32 " +-"或 uint16 的四组数(用于颜色,分别对应红、绿、蓝、Alpha;Alpha 值为 65535 时" +-"表示不透明)。" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:398 +-msgid "Slow Keys Turned On" +-msgstr "迟缓按键已打开" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:399 +-msgid "Slow Keys Turned Off" +-msgstr "迟缓按键已关闭" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:400 +-msgid "" +-"You just held down the Shift key for 8 seconds. This is the shortcut for " +-"the Slow Keys feature, which affects the way your keyboard works." +-msgstr "" +-"您已经按下了 Shift 键 8 秒。这是迟缓按键功能的快捷键,这将影响您键盘工作的方" +-"式。" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:410 +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:478 +-msgid "Universal Access" +-msgstr "通用访问" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:416 +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:484 +-msgid "Turn Off" +-msgstr "关闭" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:416 +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:484 +-msgid "Turn On" +-msgstr "打开" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:422 +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:490 +-msgid "Leave On" +-msgstr "保持打开" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:422 +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:490 +-msgid "Leave Off" +-msgstr "保持关闭" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:463 +-msgid "Sticky Keys Turned On" +-msgstr "粘滞键已打开" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:464 +-msgid "Sticky Keys Turned Off" +-msgstr "粘滞键已关闭" +- +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:466 +-msgid "" +-"You just pressed the Shift key 5 times in a row. This is the shortcut for " +-"the Sticky Keys feature, which affects the way your keyboard works." +-msgstr "" +-"您刚刚连续按了五次 Shift 键。这是粘滞键特性的快捷键,这将影响您键盘的工作方" +-"式。" ++msgstr "该字典用于映射需要覆盖的 XSETTINGS 为指定值。该值必须为字符串,signed int32 或 uint16 的四组数(用于颜色,分别对应红、绿、蓝、Alpha;Alpha 值为 65535 时表示不透明)。" + +-#: ../plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c:468 +-msgid "" +-"You just pressed two keys at once, or pressed the Shift key 5 times in a " +-"row. This turns off the Sticky Keys feature, which affects the way your " +-"keyboard works." +-msgstr "" +-"您刚刚同时按下了两个键,或连续按了五次 Shift 键。这是取消粘滞键特性的快捷键," +-"这将影响您键盘的工作方式。" +- +-#: ../plugins/color/gsd-color-calibrate.c:139 ++#: plugins/color/gsd-color-calibrate.c:139 + msgid "Color" + msgstr "颜色" + + #. TRANSLATORS: button: this is to open GCM +-#: ../plugins/color/gsd-color-calibrate.c:144 ++#: plugins/color/gsd-color-calibrate.c:145 + msgid "Recalibrate now" + msgstr "立即重新校准" + + #. TRANSLATORS: this is when the device has not been recalibrated in a while +-#: ../plugins/color/gsd-color-calibrate.c:187 ++#: plugins/color/gsd-color-calibrate.c:188 + msgid "Recalibration required" + msgstr "需要重新校准" + + #. TRANSLATORS: this is when the display has not been recalibrated in a while +-#: ../plugins/color/gsd-color-calibrate.c:199 ++#: plugins/color/gsd-color-calibrate.c:200 + #, c-format + msgid "The display “%s” should be recalibrated soon." + msgstr "显示“%s”应该尽快校准。" + + #. TRANSLATORS: this is when the printer has not been recalibrated in a while +-#: ../plugins/color/gsd-color-calibrate.c:208 ++#: plugins/color/gsd-color-calibrate.c:209 + #, c-format + msgid "The printer “%s” should be recalibrated soon." + msgstr "打印机“%s”应该尽快校准。" + + #. TRANSLATORS: this is the application name +-#: ../plugins/color/gsd-color-calibrate.c:346 +-#: ../plugins/color/gsd-color-calibrate.c:362 ++#: plugins/color/gsd-color-calibrate.c:347 ++#: plugins/color/gsd-color-calibrate.c:363 + msgid "GNOME Settings Daemon Color Plugin" + msgstr "GNOME 设置守护程序颜色插件" + + #. TRANSLATORS: this is a sound description +-#: ../plugins/color/gsd-color-calibrate.c:348 ++#: plugins/color/gsd-color-calibrate.c:349 + msgid "Color calibration device added" + msgstr "已添加颜色校准设备" + + #. TRANSLATORS: this is a sound description +-#: ../plugins/color/gsd-color-calibrate.c:364 ++#: plugins/color/gsd-color-calibrate.c:365 + msgid "Color calibration device removed" + msgstr "已移除颜色校准设备" + + #. Translators: UTC here means the Coordinated Universal Time. + #. * %:::z will be replaced by the offset from UTC e.g. UTC+02 +-#: ../plugins/datetime/gsd-datetime-manager.c:88 ++#: plugins/datetime/gsd-datetime-manager.c:88 + msgid "UTC%:::z" + msgstr "UTC%:::z" + +-#: ../plugins/datetime/gsd-datetime-manager.c:92 ++#: plugins/datetime/gsd-datetime-manager.c:92 + #, c-format + msgid "Time Zone Updated to %s (%s)" + msgstr "时区已更新为 %s (%s)" + +-#: ../plugins/datetime/gsd-datetime-manager.c:108 ++#: plugins/datetime/gsd-datetime-manager.c:108 + msgid "Settings" + msgstr "设置" + +-#: ../plugins/datetime/gsd-datetime-manager.c:118 ++#: plugins/datetime/gsd-datetime-manager.c:118 + msgid "Date & Time Settings" + msgstr "日期和时间设置" + +-#: ../plugins/housekeeping/gsd-disk-space.c:574 +-msgid "Disk space" ++#: plugins/housekeeping/gsd-disk-space.c:575 ++msgid "Disk Space" + msgstr "磁盘空间" + +-#: ../plugins/housekeeping/gsd-disk-space.c:586 ++#: plugins/housekeeping/gsd-disk-space.c:588 + msgid "Examine" + msgstr "查看" + +-#: ../plugins/housekeeping/gsd-disk-space.c:597 ++#: plugins/housekeeping/gsd-disk-space.c:599 + msgid "Empty Trash" + msgstr "清空回收站" + +-#: ../plugins/housekeeping/gsd-disk-space.c:605 ++#: plugins/housekeeping/gsd-disk-space.c:607 + msgid "Ignore" + msgstr "忽略" + +-#: ../plugins/housekeeping/gsd-disk-space.c:636 ++#: plugins/housekeeping/gsd-disk-space.c:638 + #, c-format + msgid "Low Disk Space on “%s”" + msgstr "%s 上的磁盘空间不足" + +-#: ../plugins/housekeeping/gsd-disk-space.c:638 ++#: plugins/housekeeping/gsd-disk-space.c:640 + #, c-format + msgid "" + "The volume “%s” has only %s disk space remaining. You may free up some " + "space by emptying the trash." + msgstr "巻 %s 仅剩余 %s 的磁盘空间,请清空回收站释放一部分空间。" + +-#: ../plugins/housekeeping/gsd-disk-space.c:642 ++#: plugins/housekeeping/gsd-disk-space.c:644 + #, c-format + msgid "The volume “%s” has only %s disk space remaining." + msgstr "卷 %s 仅剩余 %s 的硬盘空间。" + +-#: ../plugins/housekeeping/gsd-disk-space.c:647 ++#: plugins/housekeeping/gsd-disk-space.c:649 + msgid "Low Disk Space" + msgstr "磁盘空间不足" + +-#: ../plugins/housekeeping/gsd-disk-space.c:649 ++#: plugins/housekeeping/gsd-disk-space.c:651 + #, c-format + msgid "" + "This computer has only %s disk space remaining. You may free up some space " + "by emptying the trash." + msgstr "此计算机仅剩余 %s 的磁盘空间,请清空回收站释放一部分空间" + +-#: ../plugins/housekeeping/gsd-disk-space.c:652 ++#: plugins/housekeeping/gsd-disk-space.c:654 + #, c-format + msgid "This computer has only %s disk space remaining." + msgstr "此计算机仅剩余 %s 的硬盘空间。" + +-#: ../plugins/media-keys/gsd-media-keys-manager.c:2138 ++#: plugins/media-keys/gsd-media-keys-manager.c:2288 + msgid "Bluetooth disabled" + msgstr "已禁用蓝牙" + +-#: ../plugins/media-keys/gsd-media-keys-manager.c:2141 ++#: plugins/media-keys/gsd-media-keys-manager.c:2291 + msgid "Bluetooth enabled" + msgstr "已启用蓝牙" + +-#: ../plugins/media-keys/gsd-media-keys-manager.c:2145 ++#: plugins/media-keys/gsd-media-keys-manager.c:2295 + msgid "Airplane mode enabled" + msgstr "已启用飞行模式" + +-#: ../plugins/media-keys/gsd-media-keys-manager.c:2148 ++#: plugins/media-keys/gsd-media-keys-manager.c:2298 + msgid "Airplane mode disabled" + msgstr "已禁用飞行模式" + +-#: ../plugins/media-keys/gsd-media-keys-manager.c:2176 ++#: plugins/media-keys/gsd-media-keys-manager.c:2326 + msgid "Hardware Airplane Mode" + msgstr "硬件飞行模式" + + #. Translators: this is a filename used for screencast + #. * recording, where "%d" and "%t" date and time, e.g. + #. * "Screencast from 07-17-2013 10:00:46 PM.webm" +-#: ../plugins/media-keys/gsd-media-keys-manager.c:2236 ++#: plugins/media-keys/gsd-media-keys-manager.c:2392 + #, no-c-format + msgid "Screencast from %d %t.webm" + msgstr "%d 屏幕视频 %t.webm" + +-#: ../plugins/media-keys/gsd-screenshot-utils.c:82 ++#: plugins/media-keys/gsd-screenshot-utils.c:82 + msgid "Unable to capture a screenshot" + msgstr "无法获得屏幕截图" + +-#: ../plugins/media-keys/gsd-screenshot-utils.c:113 +-#: ../plugins/media-keys/gsd-screenshot-utils.c:155 ++#: plugins/media-keys/gsd-screenshot-utils.c:113 ++#: plugins/media-keys/gsd-screenshot-utils.c:155 + msgid "Screenshot taken" + msgstr "已截图" + + #. translators: this is the name of the file that gets made up + #. * with the screenshot +-#: ../plugins/media-keys/gsd-screenshot-utils.c:306 ++#: plugins/media-keys/gsd-screenshot-utils.c:306 + #, c-format + msgid "Screenshot from %s" + msgstr "%s 的屏幕截图" + +-#. translators: +-#. * The device has been disabled +-#: ../plugins/media-keys/gvc/gvc-mixer-control.c:1866 +-msgid "Disabled" +-msgstr "禁用" +- +-#. translators: +-#. * The number of sound outputs on a particular device +-#: ../plugins/media-keys/gvc/gvc-mixer-control.c:1873 +-#, c-format +-msgid "%u Output" +-msgid_plural "%u Outputs" +-msgstr[0] "%u 输出" +- +-#. translators: +-#. * The number of sound inputs on a particular device +-#: ../plugins/media-keys/gvc/gvc-mixer-control.c:1883 +-#, c-format +-msgid "%u Input" +-msgid_plural "%u Inputs" +-msgstr[0] "%u 输入" +- +-#: ../plugins/media-keys/gvc/gvc-mixer-control.c:2738 +-msgid "System Sounds" +-msgstr "系统声音" +- +-#: ../plugins/media-keys/shortcuts-list.h:45 ++#: plugins/media-keys/shortcuts-list.h:46 ++#: plugins/media-keys/shortcuts-list.h:47 + msgid "Touchpad toggle" + msgstr "触摸板开关" + +-#: ../plugins/media-keys/shortcuts-list.h:46 ++#: plugins/media-keys/shortcuts-list.h:48 + msgid "Touchpad On" + msgstr "触摸板开" + +-#: ../plugins/media-keys/shortcuts-list.h:47 ++#: plugins/media-keys/shortcuts-list.h:49 + msgid "Touchpad Off" + msgstr "触摸板关" + +-#: ../plugins/media-keys/shortcuts-list.h:51 +-#: ../plugins/media-keys/shortcuts-list.h:52 +-msgid "Microphone Mute" +-msgstr "话筒静音" +- +-#: ../plugins/media-keys/shortcuts-list.h:53 ++#: plugins/media-keys/shortcuts-list.h:56 + msgid "Quiet Volume Mute" + msgstr "安静 静音" + +-#: ../plugins/media-keys/shortcuts-list.h:54 ++#: plugins/media-keys/shortcuts-list.h:57 + msgid "Quiet Volume Down" + msgstr "安静 音量降低" + +-#: ../plugins/media-keys/shortcuts-list.h:55 ++#: plugins/media-keys/shortcuts-list.h:58 + msgid "Quiet Volume Up" + msgstr "安静 音量升高" + +-#: ../plugins/media-keys/shortcuts-list.h:56 ++#: plugins/media-keys/shortcuts-list.h:59 + msgid "Precise Volume Down" + msgstr "精确音量降低" + +-#: ../plugins/media-keys/shortcuts-list.h:57 ++#: plugins/media-keys/shortcuts-list.h:60 + msgid "Precise Volume Up" + msgstr "精确音量升高" + +-#: ../plugins/media-keys/shortcuts-list.h:67 ++#: plugins/media-keys/shortcuts-list.h:70 + msgid "Lock Screen" + msgstr "锁住屏幕" + +-#: ../plugins/media-keys/shortcuts-list.h:69 ++#: plugins/media-keys/shortcuts-list.h:72 + msgid "Help" + msgstr "帮助" + +-#: ../plugins/media-keys/shortcuts-list.h:83 ++#: plugins/media-keys/shortcuts-list.h:89 + msgid "Rewind" + msgstr "上一曲" + +-#: ../plugins/media-keys/shortcuts-list.h:84 ++#: plugins/media-keys/shortcuts-list.h:90 + msgid "Forward" + msgstr "下一曲" + +-#: ../plugins/media-keys/shortcuts-list.h:85 ++#: plugins/media-keys/shortcuts-list.h:91 + msgid "Repeat" + msgstr "重复" + +-#: ../plugins/media-keys/shortcuts-list.h:86 ++#: plugins/media-keys/shortcuts-list.h:92 + msgid "Random Play" + msgstr "随机播放" + +-#: ../plugins/media-keys/shortcuts-list.h:87 ++#: plugins/media-keys/shortcuts-list.h:93 + msgid "Orientation Lock" + msgstr "方向锁定" + +-#: ../plugins/media-keys/shortcuts-list.h:96 ++#: plugins/media-keys/shortcuts-list.h:102 + msgid "Power Off" + msgstr "电源关闭" + + #. the kernel / Xorg names really are like this... + #. translators: "Sleep" means putting the machine to sleep, either through hibernate or suspend +-#: ../plugins/media-keys/shortcuts-list.h:99 ++#: plugins/media-keys/shortcuts-list.h:105 + msgid "Sleep" + msgstr "睡眠" + +-#: ../plugins/media-keys/shortcuts-list.h:100 ++#: plugins/media-keys/shortcuts-list.h:106 + msgid "Suspend" + msgstr "挂起" + +-#: ../plugins/media-keys/shortcuts-list.h:101 ++#: plugins/media-keys/shortcuts-list.h:107 + msgid "Hibernate" + msgstr "休眠" + +-#: ../plugins/media-keys/shortcuts-list.h:102 ++#: plugins/media-keys/shortcuts-list.h:108 + msgid "Brightness Up" + msgstr "亮度增加" + +-#: ../plugins/media-keys/shortcuts-list.h:103 ++#: plugins/media-keys/shortcuts-list.h:109 + msgid "Brightness Down" + msgstr "亮度减少" + +-#: ../plugins/media-keys/shortcuts-list.h:104 ++#: plugins/media-keys/shortcuts-list.h:110 + msgid "Keyboard Brightness Up" + msgstr "键盘亮度增加" + +-#: ../plugins/media-keys/shortcuts-list.h:105 ++#: plugins/media-keys/shortcuts-list.h:111 + msgid "Keyboard Brightness Down" + msgstr "键盘亮度降低" + +-#: ../plugins/media-keys/shortcuts-list.h:106 ++#: plugins/media-keys/shortcuts-list.h:112 + msgid "Keyboard Brightness Toggle" + msgstr "键盘照明开关" + +-#: ../plugins/media-keys/shortcuts-list.h:107 ++#: plugins/media-keys/shortcuts-list.h:113 + msgid "Battery Status" + msgstr "电池电量状态" + +-#: ../plugins/media-keys/shortcuts-list.h:108 +-#: ../plugins/media-keys/shortcuts-list.h:109 +-#: ../plugins/media-keys/shortcuts-list.h:110 ++#: plugins/media-keys/shortcuts-list.h:114 ++#: plugins/media-keys/shortcuts-list.h:115 ++#: plugins/media-keys/shortcuts-list.h:116 + msgid "Toggle Airplane Mode" + msgstr "切换飞行模式" + +-#: ../plugins/media-keys/shortcuts-list.h:111 ++#: plugins/media-keys/shortcuts-list.h:117 + msgid "Toggle Bluetooth" + msgstr "切换蓝牙开关" + +-#: ../plugins/power/gpm-common.c:100 ++#: plugins/power/gpm-common.c:92 + msgid "Unknown time" + msgstr "未知时间" + +-#: ../plugins/power/gpm-common.c:105 ++#: plugins/power/gpm-common.c:97 + #, c-format + msgid "%i minute" + msgid_plural "%i minutes" + msgstr[0] "%i 分钟" + +-#: ../plugins/power/gpm-common.c:115 ++#: plugins/power/gpm-common.c:107 + #, c-format + msgid "%i hour" + msgid_plural "%i hours" +@@ -1375,202 +1255,194 @@ msgstr[0] "%i 小时" + + #. TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes" + #. * Swap order with "%2$s %2$i %1$s %1$i if needed +-#: ../plugins/power/gpm-common.c:121 ++#: plugins/power/gpm-common.c:113 + #, c-format + msgid "%i %s %i %s" + msgstr "%i %s %i %s" + +-#: ../plugins/power/gpm-common.c:122 ++#: plugins/power/gpm-common.c:114 + msgid "hour" + msgid_plural "hours" + msgstr[0] "小时" + +-#: ../plugins/power/gpm-common.c:123 ++#: plugins/power/gpm-common.c:115 + msgid "minute" + msgid_plural "minutes" + msgstr[0] "分钟" + + #. TRANSLATORS: this is the sound description +-#: ../plugins/power/gpm-common.c:948 ../plugins/power/gsd-power-manager.c:685 +-#: ../plugins/power/gsd-power-manager.c:782 ++#: plugins/power/gpm-common.c:438 plugins/power/gsd-power-manager.c:717 ++#: plugins/power/gsd-power-manager.c:814 + msgid "Battery is critically low" + msgstr "电池电量严重不足" + + #. TRANSLATORS: this is the notification application name +-#: ../plugins/power/gsd-power-manager.c:323 ++#: plugins/power/gsd-power-manager.c:347 + msgid "Power" + msgstr "电源" + + #. TRANSLATORS: UPS is now discharging +-#: ../plugins/power/gsd-power-manager.c:355 ++#: plugins/power/gsd-power-manager.c:387 + msgid "UPS Discharging" + msgstr "UPS 正在放电" + + #. TRANSLATORS: tell the user how much time they have got +-#: ../plugins/power/gsd-power-manager.c:360 ++#: plugins/power/gsd-power-manager.c:392 + #, c-format + msgid "%s of UPS backup power remaining" + msgstr "剩余 %s 的 UPS 备用电量" + +-#: ../plugins/power/gsd-power-manager.c:363 ++#: plugins/power/gsd-power-manager.c:395 + msgid "Unknown amount of UPS backup power remaining" + msgstr "UPS 剩余备用电量未知" + + #. TRANSLATORS: laptop battery low, and we only have one battery +-#: ../plugins/power/gsd-power-manager.c:438 ++#: plugins/power/gsd-power-manager.c:470 + msgid "Battery low" + msgstr "电池电量低" + + #. TRANSLATORS: laptop battery low, and we have more than one kind of battery +-#: ../plugins/power/gsd-power-manager.c:441 ++#: plugins/power/gsd-power-manager.c:473 + msgid "Laptop battery low" + msgstr "笔记本电池电量低" + + #. TRANSLATORS: tell the user how much time they have got +-#: ../plugins/power/gsd-power-manager.c:448 ++#: plugins/power/gsd-power-manager.c:480 + #, c-format + msgid "Approximately %s remaining (%.0f%%)" + msgstr "约剩余 %s (%.0f%%)" + + #. TRANSLATORS: UPS is starting to get a little low +-#: ../plugins/power/gsd-power-manager.c:453 ++#: plugins/power/gsd-power-manager.c:485 + msgid "UPS low" + msgstr "UPS 电量低" + + #. TRANSLATORS: tell the user how much time they have got +-#: ../plugins/power/gsd-power-manager.c:459 ++#: plugins/power/gsd-power-manager.c:491 + #, c-format + msgid "Approximately %s of remaining UPS backup power (%.0f%%)" + msgstr "UPS 备用电量约剩余 %s (%.0f%%)" + + #. TRANSLATORS: mouse is getting a little low + #. TRANSLATORS: the mouse battery is very low +-#: ../plugins/power/gsd-power-manager.c:464 +-#: ../plugins/power/gsd-power-manager.c:598 ++#: plugins/power/gsd-power-manager.c:496 plugins/power/gsd-power-manager.c:630 + msgid "Mouse battery low" + msgstr "鼠标电池电量低" + + #. TRANSLATORS: tell user more details +-#: ../plugins/power/gsd-power-manager.c:467 ++#: plugins/power/gsd-power-manager.c:499 + #, c-format + msgid "Wireless mouse is low in power (%.0f%%)" + msgstr "无线鼠标电量低(%.0f%%)" + + #. TRANSLATORS: keyboard is getting a little low + #. TRANSLATORS: the keyboard battery is very low +-#: ../plugins/power/gsd-power-manager.c:471 +-#: ../plugins/power/gsd-power-manager.c:606 ++#: plugins/power/gsd-power-manager.c:503 plugins/power/gsd-power-manager.c:638 + msgid "Keyboard battery low" + msgstr "键盘电池电量低" + + #. TRANSLATORS: tell user more details +-#: ../plugins/power/gsd-power-manager.c:474 ++#: plugins/power/gsd-power-manager.c:506 + #, c-format + msgid "Wireless keyboard is low in power (%.0f%%)" + msgstr "无线键盘电量低(%.0f%%)" + + #. TRANSLATORS: PDA is getting a little low + #. TRANSLATORS: the PDA battery is very low +-#: ../plugins/power/gsd-power-manager.c:478 +-#: ../plugins/power/gsd-power-manager.c:615 ++#: plugins/power/gsd-power-manager.c:510 plugins/power/gsd-power-manager.c:647 + msgid "PDA battery low" + msgstr "PDA 电池电量低" + + #. TRANSLATORS: tell user more details +-#: ../plugins/power/gsd-power-manager.c:481 ++#: plugins/power/gsd-power-manager.c:513 + #, c-format + msgid "PDA is low in power (%.0f%%)" + msgstr "PDA 电量低(%.0f%%)" + + #. TRANSLATORS: cell phone (mobile) is getting a little low + #. TRANSLATORS: the cell battery is very low +-#: ../plugins/power/gsd-power-manager.c:485 +-#: ../plugins/power/gsd-power-manager.c:625 +-#: ../plugins/power/gsd-power-manager.c:634 ++#: plugins/power/gsd-power-manager.c:517 plugins/power/gsd-power-manager.c:657 ++#: plugins/power/gsd-power-manager.c:666 + msgid "Cell phone battery low" + msgstr "手机电池电量低" + + #. TRANSLATORS: tell user more details +-#: ../plugins/power/gsd-power-manager.c:488 ++#: plugins/power/gsd-power-manager.c:520 + #, c-format + msgid "Cell phone is low in power (%.0f%%)" + msgstr "手机电量低(%.0f%%)" + + #. TRANSLATORS: media player, e.g. mp3 is getting a little low +-#: ../plugins/power/gsd-power-manager.c:492 ++#: plugins/power/gsd-power-manager.c:524 + msgid "Media player battery low" + msgstr "媒体播放器电池电量低" + + #. TRANSLATORS: tell user more details +-#: ../plugins/power/gsd-power-manager.c:495 ++#: plugins/power/gsd-power-manager.c:527 + #, c-format + msgid "Media player is low in power (%.0f%%)" + msgstr "媒体播放器电量低(%.0f%%)" + + #. TRANSLATORS: graphics tablet, e.g. wacom is getting a little low + #. TRANSLATORS: the cell battery is very low +-#: ../plugins/power/gsd-power-manager.c:499 +-#: ../plugins/power/gsd-power-manager.c:643 ++#: plugins/power/gsd-power-manager.c:531 plugins/power/gsd-power-manager.c:675 + msgid "Tablet battery low" + msgstr "数位板电池电量低" + + #. TRANSLATORS: tell user more details +-#: ../plugins/power/gsd-power-manager.c:502 ++#: plugins/power/gsd-power-manager.c:534 + #, c-format + msgid "Tablet is low in power (%.0f%%)" + msgstr "数位板电量低(%.0f%%)" + + #. TRANSLATORS: computer, e.g. ipad is getting a little low + #. TRANSLATORS: the cell battery is very low +-#: ../plugins/power/gsd-power-manager.c:506 +-#: ../plugins/power/gsd-power-manager.c:652 ++#: plugins/power/gsd-power-manager.c:538 plugins/power/gsd-power-manager.c:684 + msgid "Attached computer battery low" + msgstr "连接的计算机电池电量低" + + #. TRANSLATORS: tell user more details +-#: ../plugins/power/gsd-power-manager.c:509 ++#: plugins/power/gsd-power-manager.c:541 + #, c-format + msgid "Attached computer is low in power (%.0f%%)" + msgstr "连接的计算机电量低(%.0f%%)" + + #. TRANSLATORS: this is the sound description +-#: ../plugins/power/gsd-power-manager.c:530 ++#: plugins/power/gsd-power-manager.c:562 + msgid "Battery is low" + msgstr "电池电量低" + + #. TRANSLATORS: laptop battery critically low, and only have one kind of battery +-#: ../plugins/power/gsd-power-manager.c:562 ++#: plugins/power/gsd-power-manager.c:594 + msgid "Battery critically low" + msgstr "电池电量严重不足" + + #. TRANSLATORS: laptop battery critically low, and we have more than one type of battery + #. TRANSLATORS: laptop battery is really, really, low +-#: ../plugins/power/gsd-power-manager.c:565 +-#: ../plugins/power/gsd-power-manager.c:712 ++#: plugins/power/gsd-power-manager.c:597 plugins/power/gsd-power-manager.c:744 + msgid "Laptop battery critically low" + msgstr "笔记本电池电量严重不足" + + #. TRANSLATORS: give the user a ultimatum +-#: ../plugins/power/gsd-power-manager.c:574 ++#: plugins/power/gsd-power-manager.c:606 + #, c-format + msgid "Computer will hibernate very soon unless it is plugged in." + msgstr "如果不插入,计算机将很快休眠。" + + #. TRANSLATORS: give the user a ultimatum +-#: ../plugins/power/gsd-power-manager.c:578 ++#: plugins/power/gsd-power-manager.c:610 + #, c-format + msgid "Computer will shutdown very soon unless it is plugged in." + msgstr "如果不插入,计算机将很快关机。" + + #. TRANSLATORS: the UPS is very low + #. TRANSLATORS: UPS is really, really, low +-#: ../plugins/power/gsd-power-manager.c:586 +-#: ../plugins/power/gsd-power-manager.c:737 ++#: plugins/power/gsd-power-manager.c:618 plugins/power/gsd-power-manager.c:769 + msgid "UPS critically low" + msgstr "UPS 电量严重不足" + + #. TRANSLATORS: give the user a ultimatum +-#: ../plugins/power/gsd-power-manager.c:592 ++#: plugins/power/gsd-power-manager.c:624 + #, c-format + msgid "" + "Approximately %s of remaining UPS power (%.0f%%). Restore AC power to your " +@@ -1578,7 +1450,7 @@ msgid "" + msgstr "UPS 电量约剩余 %s(%.0f%%)。请恢复计算机的交流供电,以免丢失数据。" + + #. TRANSLATORS: the device is just going to stop working +-#: ../plugins/power/gsd-power-manager.c:601 ++#: plugins/power/gsd-power-manager.c:633 + #, c-format + msgid "" + "Wireless mouse is very low in power (%.0f%%). This device will soon stop " +@@ -1586,7 +1458,7 @@ msgid "" + msgstr "无线鼠标电量非常低(%.0f%%)。如果不充电,此设备将很快停止工作。" + + #. TRANSLATORS: the device is just going to stop working +-#: ../plugins/power/gsd-power-manager.c:609 ++#: plugins/power/gsd-power-manager.c:641 + #, c-format + msgid "" + "Wireless keyboard is very low in power (%.0f%%). This device will soon stop " +@@ -1594,7 +1466,7 @@ msgid "" + msgstr "无线键盘电量非常低(%.0f%%)。如果不充电,此设备将很快停止工作。" + + #. TRANSLATORS: the device is just going to stop working +-#: ../plugins/power/gsd-power-manager.c:618 ++#: plugins/power/gsd-power-manager.c:650 + #, c-format + msgid "" + "PDA is very low in power (%.0f%%). This device will soon stop functioning if " +@@ -1602,7 +1474,7 @@ msgid "" + msgstr "PDA 电量非常低(%.0f%%)。如果不充电,此设备将很快停止工作。" + + #. TRANSLATORS: the device is just going to stop working +-#: ../plugins/power/gsd-power-manager.c:628 ++#: plugins/power/gsd-power-manager.c:660 + #, c-format + msgid "" + "Cell phone is very low in power (%.0f%%). This device will soon stop " +@@ -1610,7 +1482,7 @@ msgid "" + msgstr "手机电量非常低(%.0f%%)。如果不充电,此设备将很快停止工作。" + + #. TRANSLATORS: the device is just going to stop working +-#: ../plugins/power/gsd-power-manager.c:637 ++#: plugins/power/gsd-power-manager.c:669 + #, c-format + msgid "" + "Media player is very low in power (%.0f%%). This device will soon stop " +@@ -1618,7 +1490,7 @@ msgid "" + msgstr "媒体播放器电量非常低(%.0f%%)。如果不充电,此设备将很快停止工作。" + + #. TRANSLATORS: the device is just going to stop working +-#: ../plugins/power/gsd-power-manager.c:646 ++#: plugins/power/gsd-power-manager.c:678 + #, c-format + msgid "" + "Tablet is very low in power (%.0f%%). This device will soon stop functioning " +@@ -1626,7 +1498,7 @@ msgid "" + msgstr "数位板电量非常低(%.0f%%)。如果不充电,此设备将很快停止工作。" + + #. TRANSLATORS: the device is just going to stop working +-#: ../plugins/power/gsd-power-manager.c:655 ++#: plugins/power/gsd-power-manager.c:687 + #, c-format + msgid "" + "Attached computer is very low in power (%.0f%%). The device will soon " +@@ -1634,351 +1506,470 @@ msgid "" + msgstr "连接的计算机电量非常低(%.0f%%)。如果不充电,此设备将很快停止工作。" + + #. TRANSLATORS: computer will hibernate +-#: ../plugins/power/gsd-power-manager.c:720 ++#: plugins/power/gsd-power-manager.c:752 + msgid "" + "The battery is below the critical level and this computer is about to " + "hibernate." + msgstr "电池电量水平已经超过了严重的界限,此计算机即将休眠。" + + #. TRANSLATORS: computer will just shutdown +-#: ../plugins/power/gsd-power-manager.c:725 ++#: plugins/power/gsd-power-manager.c:757 + msgid "" + "The battery is below the critical level and this computer is about to " + "shutdown." + msgstr "电池电量水平已经超过了严重的界限,此计算机即将关机。" + + #. TRANSLATORS: computer will hibernate +-#: ../plugins/power/gsd-power-manager.c:745 ++#: plugins/power/gsd-power-manager.c:777 + msgid "" + "UPS is below the critical level and this computer is about to hibernate." + msgstr "UPS 电量水平已经超过了严重的界限,此计算机即将休眠。" + + #. TRANSLATORS: computer will just shutdown +-#: ../plugins/power/gsd-power-manager.c:750 ++#: plugins/power/gsd-power-manager.c:782 + msgid "UPS is below the critical level and this computer is about to shutdown." + msgstr "UPS 电量水平已经超过了严重的界限,此计算机即将关机。" + + #. TRANSLATORS: this is the sound description +-#: ../plugins/power/gsd-power-manager.c:1251 ++#: plugins/power/gsd-power-manager.c:1260 + msgid "Lid has been opened" + msgstr "盖子已打开" + + #. TRANSLATORS: this is the sound description +-#: ../plugins/power/gsd-power-manager.c:1289 ++#: plugins/power/gsd-power-manager.c:1294 + msgid "Lid has been closed" + msgstr "盖子已合上" + + #. TRANSLATORS: this is the sound description +-#: ../plugins/power/gsd-power-manager.c:1882 ++#: plugins/power/gsd-power-manager.c:1856 + msgid "On battery power" + msgstr "电池供电" + + #. TRANSLATORS: this is the sound description +-#: ../plugins/power/gsd-power-manager.c:1887 ++#: plugins/power/gsd-power-manager.c:1861 + msgid "On AC power" + msgstr "电源供电" + +-#: ../plugins/power/gsd-power-manager.c:2079 ++#: plugins/power/gsd-power-manager.c:2051 + msgid "Automatic logout" + msgstr "自动注销" + +-#: ../plugins/power/gsd-power-manager.c:2079 ++#: plugins/power/gsd-power-manager.c:2051 + msgid "You will soon log out because of inactivity." + msgstr "因为长时间未活动,您即将被注销。" + +-#: ../plugins/power/gsd-power-manager.c:2084 ++#: plugins/power/gsd-power-manager.c:2056 + msgid "Automatic suspend" + msgstr "自动挂起" + +-#: ../plugins/power/gsd-power-manager.c:2084 +-#: ../plugins/power/gsd-power-manager.c:2089 ++#: plugins/power/gsd-power-manager.c:2056 ++#: plugins/power/gsd-power-manager.c:2061 + msgid "Computer will suspend very soon because of inactivity." + msgstr "由于长时间未活动,计算机将很快挂起。" + +-#: ../plugins/power/gsd-power-manager.c:2089 ++#: plugins/power/gsd-power-manager.c:2061 + msgid "Automatic hibernation" + msgstr "自动休眠" + + #. SECURITY: + #. - A normal active user on the local machine does not need permission + #. to change the backlight brightness. +-#. +-#: ../plugins/power/org.gnome.settings-daemon.plugins.power.policy.in.in.h:5 ++#: plugins/power/org.gnome.settings-daemon.plugins.power.policy.in.in:21 + msgid "Modify the laptop brightness" + msgstr "更改笔记本亮度" + +-#: ../plugins/power/org.gnome.settings-daemon.plugins.power.policy.in.in.h:6 ++#: plugins/power/org.gnome.settings-daemon.plugins.power.policy.in.in:22 + msgid "Authentication is required to modify the laptop brightness" + msgstr "更改笔记本亮度需要认证" + + #. Translators: We are configuring new printer +-#: ../plugins/print-notifications/gsd-printer.c:890 ++#: plugins/print-notifications/gsd-printer.c:890 + msgid "Configuring new printer" + msgstr "配置新的打印机" + + #. Translators: Just wait +-#: ../plugins/print-notifications/gsd-printer.c:892 ++#: plugins/print-notifications/gsd-printer.c:892 + msgid "Please wait…" + msgstr "请稍候…" + + #. Translators: We have no driver installed for this printer +-#: ../plugins/print-notifications/gsd-printer.c:919 ++#: plugins/print-notifications/gsd-printer.c:919 + msgid "Missing printer driver" + msgstr "未找到打印机驱动" + + #. Translators: We have no driver installed for the device +-#: ../plugins/print-notifications/gsd-printer.c:928 ++#: plugins/print-notifications/gsd-printer.c:928 + #, c-format + msgid "No printer driver for %s." + msgstr "找不到 %s 的打印驱动。" + + #. Translators: We have no driver installed for this printer +-#: ../plugins/print-notifications/gsd-printer.c:933 ++#: plugins/print-notifications/gsd-printer.c:933 + msgid "No driver for this printer." + msgstr "找不到打印机的驱动。" + +-#: ../plugins/print-notifications/gsd-printer.c:1031 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:270 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:748 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:838 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:881 ++#: plugins/print-notifications/gsd-printer.c:1031 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:290 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:538 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:920 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:1011 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:1055 + msgid "Printers" + msgstr "打印机" + + #. Translators: The printer is low on toner (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:346 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:374 + #, c-format + msgid "Printer “%s” is low on toner." + msgstr "打印机“%s”的墨粉已不多。" + + #. Translators: The printer has no toner left (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:350 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:378 + #, c-format + msgid "Printer “%s” has no toner left." + msgstr "打印机“%s”已经无墨粉。" + + #. Translators: The printer is in the process of connecting to a shared network output device (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:354 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:382 + #, c-format + msgid "Printer “%s” may not be connected." + msgstr "打印机“%s”可能没有连接。" + + #. Translators: One or more covers on the printer are open (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:358 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:386 + #, c-format + msgid "The cover is open on printer “%s”." + msgstr "打印机“%s”的机盖处于打开状态。" + + #. Translators: A filter or backend is not installed (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:362 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:390 + #, c-format + msgid "There is a missing print filter for printer “%s”." + msgstr "打印机“%s”的打印过滤功能缺失。" + + #. Translators: One or more doors on the printer are open (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:367 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:395 + #, c-format + msgid "The door is open on printer “%s”." + msgstr "打印机“%s”的机盖处于打开状态。" + + #. Translators: "marker" is one color bin of the printer +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:371 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:399 + #, c-format + msgid "Printer “%s” is low on a marker supply." + msgstr "打印机“%s”的标记墨量少。" + + #. Translators: "marker" is one color bin of the printer +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:375 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:403 + #, c-format + msgid "Printer “%s” is out of a marker supply." + msgstr "打印机“%s”标记墨已用完。" + + #. Translators: At least one input tray is low on media (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:379 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:407 + #, c-format + msgid "Printer “%s” is low on paper." + msgstr "打印机“%s”的纸张量少。" + + #. Translators: At least one input tray is empty (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:383 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:411 + #, c-format + msgid "Printer “%s” is out of paper." + msgstr "打印机“%s”缺纸。" + + #. Translators: The printer is offline (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:387 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:415 + #, c-format + msgid "Printer “%s” is currently off-line." + msgstr "打印机“%s”当前离线。" + + #. Translators: The printer has detected an error (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:391 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:419 + #, c-format + msgid "There is a problem on printer “%s”." + msgstr "打印机“%s”上有错误。" + ++#. Translators: The printer has a job to print but the printer needs authentication to continue with the print ++#: plugins/print-notifications/gsd-print-notifications-manager.c:531 ++#, c-format ++msgid "%s Requires Authentication" ++msgstr "%s 需要认证" ++ ++#. Translators: A printer needs credentials to continue printing a job ++#: plugins/print-notifications/gsd-print-notifications-manager.c:533 ++#, c-format ++msgid "Credentials required in order to print" ++msgstr "打印所需的凭证" ++ + #. Translators: The printer is low on toner (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:439 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:600 + msgid "Toner low" + msgstr "墨已不多" + + #. Translators: The printer has no toner left (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:441 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:602 + msgid "Toner empty" + msgstr "缺墨" + + #. Translators: The printer is in the process of connecting to a shared network output device (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:443 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:604 + msgid "Not connected?" + msgstr "没有连接?" + + #. Translators: One or more covers on the printer are open (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:445 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:606 + msgid "Cover open" + msgstr "有机盖打开" + + #. Translators: A filter or backend is not installed (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:447 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:608 + msgid "Printer configuration error" + msgstr "打印机配置错误" + + #. Translators: One or more doors on the printer are open (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:449 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:610 + msgid "Door open" + msgstr "仓门打开" + + #. Translators: "marker" is one color bin of the printer +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:451 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:612 + msgid "Marker supply low" + msgstr "标记墨量低" + + #. Translators: "marker" is one color bin of the printer +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:453 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:614 + msgid "Out of a marker supply" + msgstr "标记墨已用完" + + #. Translators: At least one input tray is low on media (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:455 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:616 + msgid "Paper low" + msgstr "纸张量少" + + #. Translators: At least one input tray is empty (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:457 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:618 + msgid "Out of paper" + msgstr "缺纸" + + #. Translators: The printer is offline (same as in system-config-printer) +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:459 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:620 + msgid "Printer off-line" + msgstr "没有连接打印机" + + #. Translators: The printer has detected an error (same as in system-config-printer) + #. Translators: This is a title of an error notification for a printer +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:461 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:824 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:622 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:997 + msgid "Printer error" + msgstr "打印机错误" + + #. Translators: New printer has been added +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:509 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:670 + msgid "Printer added" + msgstr "打印机已添加" + + #. Translators: A print job has been stopped +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:526 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:564 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:687 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:725 + msgctxt "print job state" + msgid "Printing stopped" + msgstr "打印已暂停" + + #. Translators: "print-job xy" on a printer +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:528 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:534 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:540 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:546 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:558 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:566 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:574 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:582 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:590 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:603 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:689 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:695 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:701 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:707 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:719 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:727 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:735 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:743 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:751 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:775 + #, c-format + msgctxt "print job" + msgid "“%s” on %s" + msgstr "%2$s 上的“%1$s”" + + #. Translators: A print job has been canceled +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:532 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:572 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:693 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:733 + msgctxt "print job state" + msgid "Printing canceled" + msgstr "打印已取消" + + #. Translators: A print job has been aborted +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:538 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:580 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:699 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:741 + msgctxt "print job state" + msgid "Printing aborted" + msgstr "打印中止" + + #. Translators: A print job has been completed +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:544 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:588 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:705 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:749 + msgctxt "print job state" + msgid "Printing completed" + msgstr "打印完成" + + #. Translators: A job is printing +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:556 +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:601 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:717 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:773 + msgctxt "print job state" + msgid "Printing" + msgstr "正在打印" + + #. Translators: This is a title of a report notification for a printer +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:818 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:991 + msgid "Printer report" + msgstr "打印机报告" + + #. Translators: This is a title of a warning notification for a printer +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:821 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:994 + msgid "Printer warning" + msgstr "打印机警告" + + #. Translators: "Printer 'MyPrinterName': 'Description of the report/warning/error from a PPD file'." +-#: ../plugins/print-notifications/gsd-print-notifications-manager.c:831 ++#: plugins/print-notifications/gsd-print-notifications-manager.c:1004 + #, c-format + msgid "Printer “%s”: “%s”." + msgstr "打印机“%s”:“%s”。" + +-#: ../plugins/smartcard/gsd-smartcard-service.c:224 ++#: plugins/smartcard/gsd-smartcard-service.c:288 + msgid "User was not logged in with smartcard." + msgstr "用户未使用智能卡登录。" + ++#: plugins/subman/gsd-subscription-manager.c:1044 ++msgid "Subscription Has Expired" ++msgstr "订阅已过期。" ++ ++#: plugins/subman/gsd-subscription-manager.c:1045 ++msgid "Add or renew a subscription to continue receiving software updates." ++msgstr "添加或更新订阅以继续接收软件更新。" ++ ++#: plugins/subman/gsd-subscription-manager.c:1047 ++#: plugins/subman/gsd-subscription-manager.c:1063 ++#: plugins/subman/gsd-subscription-manager.c:1075 ++msgid "Subscription" ++msgstr "订阅" ++ ++#: plugins/subman/gsd-subscription-manager.c:1052 ++msgid "Subscribe System…" ++msgstr "订阅系统......" ++ ++#: plugins/subman/gsd-subscription-manager.c:1060 ++msgid "Registration Successful" ++msgstr "注册成功" ++ ++#: plugins/subman/gsd-subscription-manager.c:1061 ++msgid "The system has been registered and software updates have been enabled." ++msgstr "系统已注册,软件更新已启用。" ++ ++#: plugins/subman/gsd-subscription-manager.c:1072 ++msgid "System Not Registered" ++msgstr "系统未注册" ++ ++#: plugins/subman/gsd-subscription-manager.c:1073 ++msgid "Please register your system to receive software updates." ++msgstr "请注册您的系统以接收软件更新。" ++ ++#: plugins/subman/gsd-subscription-manager.c:1080 ++msgid "Register System…" ++msgstr "注册系统......" ++ ++#: plugins/subman/org.gnome.settings-daemon.plugins.subman.policy.in.in:17 ++msgid "Register the system" ++msgstr "注册系统" ++ ++#: plugins/subman/org.gnome.settings-daemon.plugins.subman.policy.in.in:18 ++msgid "Authentication is required to register the system" ++msgstr "注册系统需要认证" ++ + #. SECURITY: + #. - A normal active user on the local machine does not need permission + #. to change the LED setting for a Wacom tablet +-#. +-#: ../plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in.h:5 ++#: plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in:20 + msgid "Modify the lit LED for a Wacom tablet" + msgstr "修改 Wacom 数位板的 lit LED" + +-#: ../plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in.h:6 ++#: plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in:21 + msgid "Authentication is required to modify the lit LED for a Wacom tablet" + msgstr "修改 Wacom 数位板的 lit LED 需要认证" + + #. SECURITY: + #. - A normal active user on the local machine does not need permission + #. to change the OLED images for a Wacom tablet +-#. +-#: ../plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in.h:11 ++#: plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in:35 + msgid "Modify the OLED image for a Wacom tablet" + msgstr "修改 Wacom 数位板的 OLED 图像" + +-#: ../plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in.h:12 ++#: plugins/wacom/org.gnome.settings-daemon.plugins.wacom.policy.in.in:36 + msgid "Authentication is required to modify the OLED image for a Wacom tablet" + msgstr "修改 Wacom 数位板的 OLED 图像需要认证" + ++#~ msgid "Slow Keys Turned On" ++#~ msgstr "迟缓按键已打开" ++ ++#~ msgid "Slow Keys Turned Off" ++#~ msgstr "迟缓按键已关闭" ++ ++#~ msgid "" ++#~ "You just held down the Shift key for 8 seconds. This is the shortcut for " ++#~ "the Slow Keys feature, which affects the way your keyboard works." ++#~ msgstr "" ++#~ "您已经按下了 Shift 键 8 秒。这是迟缓按键功能的快捷键,这将影响您键盘工作的" ++#~ "方式。" ++ ++#~ msgid "Universal Access" ++#~ msgstr "通用访问" ++ ++#~ msgid "Turn Off" ++#~ msgstr "关闭" ++ ++#~ msgid "Turn On" ++#~ msgstr "打开" ++ ++#~ msgid "Leave On" ++#~ msgstr "保持打开" ++ ++#~ msgid "Leave Off" ++#~ msgstr "保持关闭" ++ ++#~ msgid "Sticky Keys Turned On" ++#~ msgstr "粘滞键已打开" ++ ++#~ msgid "Sticky Keys Turned Off" ++#~ msgstr "粘滞键已关闭" ++ ++#~ msgid "" ++#~ "You just pressed the Shift key 5 times in a row. This is the shortcut " ++#~ "for the Sticky Keys feature, which affects the way your keyboard works." ++#~ msgstr "" ++#~ "您刚刚连续按了五次 Shift 键。这是粘滞键特性的快捷键,这将影响您键盘的工作" ++#~ "方式。" ++ ++#~ msgid "" ++#~ "You just pressed two keys at once, or pressed the Shift key 5 times in a " ++#~ "row. This turns off the Sticky Keys feature, which affects the way your " ++#~ "keyboard works." ++#~ msgstr "" ++#~ "您刚刚同时按下了两个键,或连续按了五次 Shift 键。这是取消粘滞键特性的快捷" ++#~ "键,这将影响您键盘的工作方式。" ++ ++#~ msgid "Disabled" ++#~ msgstr "禁用" ++ ++#~ msgid "%u Output" ++#~ msgid_plural "%u Outputs" ++#~ msgstr[0] "%u 输出" ++ ++#~ msgid "%u Input" ++#~ msgid_plural "%u Inputs" ++#~ msgstr[0] "%u 输入" ++ ++#~ msgid "System Sounds" ++#~ msgstr "系统声音" ++ + #~ msgid "File for default configuration for RandR" + #~ msgstr "RandR 默认配置文件" + +@@ -3040,7 +3031,6 @@ msgstr "修改 Wacom 数位板的 OLED 图像需要认证" + #~ msgid "encountered unexpected error while waiting for smartcard events" + #~ msgstr "等待智能卡事件时遇到意外错误" + +-#, fuzzy + #~ msgid "Configure device" + #~ msgstr "忽略设备" + +@@ -3082,7 +3072,6 @@ msgstr "修改 Wacom 数位板的 OLED 图像需要认证" + #~ msgid "Binding to select the next input source" + #~ msgstr "选择下一输入源的键绑定。" + +-#, fuzzy + #~ msgid "Switch input source backward" + #~ msgstr "切换输入源" + +@@ -3098,11 +3087,9 @@ msgstr "修改 Wacom 数位板的 OLED 图像需要认证" + #~ msgid "_Turn On" + #~ msgstr "打开(_T)" + +-#, fuzzy + #~ msgid "_Leave On" + #~ msgstr "保持打开(_L)" + +-#, fuzzy + #~ msgid "_Leave Off" + #~ msgstr "保持关闭(_L)" + +@@ -3917,7 +3904,6 @@ msgstr "修改 Wacom 数位板的 OLED 图像需要认证" + #~ msgid "GConf key %s set to type %s but its expected type was %s\n" + #~ msgstr "GConf 键 %s 被设为 %s 类型,但是期望的类型是 %s\n" + +-#, fuzzy + #~ msgid "Keyboard Layout \"%s\"" + #~ msgstr "键盘布局" + +@@ -3928,9 +3914,6 @@ msgstr "修改 Wacom 数位板的 OLED 图像需要认证" + #~ "无法将机器转入休眠。\n" + #~ "请检查机器是否已正确配置。" + +-#~ msgid "Binding to suspend the computer." +-#~ msgstr "挂起计算机的键绑定。" +- + #~ msgid "GNOME Volume Control" + #~ msgstr "GNOME 音量控制" + +@@ -3967,5 +3950,3 @@ msgstr "修改 Wacom 数位板的 OLED 图像需要认证" + #~ "\n" + #~ "此对话中将无法使用屏幕保护功能。" + +-#~ msgid "Screensaver plugin" +-#~ msgstr "屏保插件" +-- +2.29.2 + diff --git a/SPECS/gnome-settings-daemon.spec b/SPECS/gnome-settings-daemon.spec index c389739..2a92e7f 100644 --- a/SPECS/gnome-settings-daemon.spec +++ b/SPECS/gnome-settings-daemon.spec @@ -6,9 +6,13 @@ %global libgweather_version 3.9.5 %global geoclue_version 2.3.1 +%if %{undefined centos} +%bcond_without subman +%endif + Name: gnome-settings-daemon Version: 3.32.0 -Release: 11%{?dist} +Release: 14%{?dist} Summary: The daemon sharing settings from GNOME to GTK+/KDE applications License: GPLv2+ @@ -21,6 +25,7 @@ BuildRequires: gcc BuildRequires: cups-devel BuildRequires: gettext BuildRequires: perl-interpreter +BuildRequires: git BuildRequires: pkgconfig(alsa) BuildRequires: pkgconfig(colord) >= 1.0.2 BuildRequires: pkgconfig(fontconfig) @@ -32,6 +37,9 @@ BuildRequires: pkgconfig(gsettings-desktop-schemas) >= %{gsettings_desktop_sche BuildRequires: pkgconfig(gtk+-3.0) >= %{gtk3_version} BuildRequires: pkgconfig(gudev-1.0) BuildRequires: pkgconfig(gweather-3.0) >= %{libgweather_version} +%if %{with subman} +BuildRequires: pkgconfig(json-glib-1.0) +%endif BuildRequires: pkgconfig(lcms2) >= 2.2 BuildRequires: pkgconfig(libcanberra-gtk3) BuildRequires: pkgconfig(libgeoclue-2.0) @@ -75,14 +83,40 @@ Conflicts: gnome-session < 3.27.90 # older gdm, gnome-session and gnome-shell releases that expect the functionality Conflicts: gnome-shell < 3.25.4 +# account plugin Patch00001: 0001-account-first-cut-at-account-plugin.patch Patch00002: 0002-account-reshow-the-notification-when-screen-unlocks.patch Patch00003: 0003-account-display-nag-screen-periodically.patch Patch00004: 0004-account-don-t-poll-more-frequently-than-notification.patch -Patch00005: 0001-smartcard-Cancel-cancellable-when-stopping.patch -Patch00006: 0001-xsettings-Add-an-entry-for-the-overlay-scrolling-set.patch -Patch10001: 0001-housekeeping-Add-a-GPU-memory-usage-notification.patch +Patch10001: 0001-smartcard-Cancel-cancellable-when-stopping.patch + +Patch20001: 0001-xsettings-Add-an-entry-for-the-overlay-scrolling-set.patch + +# Handle org.gnome.Shell.Screencast Stopped signal (#1705392) +Patch30001: 0001-media-keys-Mark-screen-cast-as-stopped-if-it-was-sig.patch + +Patch40001: 0001-housekeeping-Add-a-GPU-memory-usage-notification.patch + +# subscription manager integration +Patch50001: 0001-subman-Add-a-new-plugin-to-provide-system-subscripti.patch +Patch50002: 0002-subman-Add-InstalledProducts-dbus-property-for-g-c-c.patch +Patch50003: 0003-subman-Increase-RHSM-dbus-call-timeouts.patch +Patch50004: 0004-subman-Drop-userlang-field.patch +Patch50005: 0005-subman-Use-user-locale-for-registration-subscription.patch +Patch50006: 0006-subman-Handle-subscription-manager-giving-invalid-st.patch +Patch50007: 0007-subman-Force-re-subscribe-if-the-admin-already-subsc.patch +Patch50008: 0008-subman-Don-t-send-secrets-through-command-line.patch +Patch50009: 0009-subman-Don-t-treat-failure-to-attach-as-fatal.patch +Patch50010: 0010-subman-Add-new-no-installed-products-state.patch +Patch50011: 0011-subman-Fix-some-build-warnings.patch +Patch50012: 0012-subman-Add-DBus-API-to-subscribe-for-updates-on-alre.patch +Patch50013: 0013-subman-Improve-subscription-status-handling.patch +Patch50014: 0014-subman-Drop-LAST-from-status-enum.patch +Patch50015: 0015-subman-Clean-up-notification-behavior.patch +Patch50016: 0016-subman-Update-POTFILES.in.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1876291 +Patch50017: 0017-Update-translations.patch %description A daemon to share settings from GNOME to other applications. It also @@ -97,17 +131,7 @@ The %{name}-devel package contains libraries and header files for developing applications that use %{name}. %prep -%setup -q - -%patch00001 -p 1 -%patch00002 -p 1 -%patch00003 -p 1 -%patch00004 -p 1 -%patch00005 -p 1 -%patch00006 -p 1 - -%patch10001 -p 1 - +%autosetup -S git %build %meson @@ -204,6 +228,12 @@ mkdir $RPM_BUILD_ROOT%{_libdir}/gnome-settings-daemon-3.0/gtk-modules %{_sysconfdir}/xdg/autostart/org.gnome.SettingsDaemon.Sharing.desktop %{_datadir}/glib-2.0/schemas/org.gnome.settings-daemon.plugins.sharing.gschema.xml +%{_sysconfdir}/xdg/autostart/org.gnome.SettingsDaemon.Subscription.desktop +%{_libexecdir}/gsd-subman +%{_libexecdir}/gsd-subman-helper +%{_datadir}/polkit-1/actions/org.gnome.settings-daemon.plugins.subman.policy +%{_datadir}/polkit-1/rules.d/org.gnome.settings-daemon.plugins.subman.rules + %{_libdir}/gnome-settings-daemon-3.0/libgsd.so /usr/lib/udev/rules.d/*.rules @@ -218,6 +248,18 @@ mkdir $RPM_BUILD_ROOT%{_libdir}/gnome-settings-daemon-3.0/gtk-modules %{_libdir}/pkgconfig/gnome-settings-daemon.pc %changelog +* Mon Mar 01 2021 Kalev Lember - 3.32.0-14 +- Update fr, ja, zh_CN translations +- Resolves: #1876291 + +* Thu Jan 21 2021 Ray Strode - 3.32.0-13 +- Add back subscription-manager plugin + Related: #1870837 + +* Tue Jan 05 2021 Jonas Ådahl - 3.32.0-12 +- Handle org.gnome.Shell.Screencast Stopped signal + Related: #1705392 + * Wed Sep 02 2020 Ray Strode - 3.32.0-11 - Remove subman plugin for now Resolves: #1872457