From d918b02c1f3637a0084b8dff7e73929254fc7906 Mon Sep 17 00:00:00 2001 From: Andrea Azzarone Date: Wed, 21 Mar 2018 18:52:51 +0100 Subject: online-accounts: Complete account removal in cc_goa_panel_finalize() When removing an online account, gnome-control-center gives the user the possibility to undo the action showing an "undo notification". Right now if you close the gnome-control-center window, without dismissing the notification, the online account will not be properly removed. https://gitlab.gnome.org/GNOME/gnome-control-center/issues/25 --- panels/online-accounts/cc-online-accounts-panel.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/panels/online-accounts/cc-online-accounts-panel.c b/panels/online-accounts/cc-online-accounts-panel.c index 835810003..3177a4d27 100644 --- a/panels/online-accounts/cc-online-accounts-panel.c +++ b/panels/online-accounts/cc-online-accounts-panel.c @@ -402,6 +402,22 @@ cc_goa_panel_finalize (GObject *object) { CcGoaPanel *panel = CC_GOA_PANEL (object); + if (panel->removed_object != NULL) + { + g_autoptr(GError) error = NULL; + goa_account_call_remove_sync (goa_object_peek_account (panel->removed_object), + NULL, /* GCancellable */ + &error); + + if (error != NULL) + { + g_warning ("Error removing account: %s (%s, %d)", + error->message, + g_quark_to_string (error->domain), + error->code); + } + } + g_clear_object (&panel->client); G_OBJECT_CLASS (cc_goa_panel_parent_class)->finalize (object); -- cgit v1.2.1 From adf5a42f01e112ec5c294b52ffb838c9177c61f5 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 24 Nov 2017 15:39:38 +0100 Subject: display: Show insensitive apply button for invalid configurations When the user creates temporary invalid configurations the dialog used to hide the apply button as if no change had been done so far. Change this to show the normal "Apply"/"Cancel" titlebar but make the "Apply" button insensitive and modify the title to indicate the error. Unfortunately we don't currently get the reason in a way that we could translate it. Ideally we would special case common error scenarios and present the user with a better explanation or even correct the mistake. See https://bugzilla.gnome.org/show_bug.cgi?id=790891 for the related mutter bug. https://bugzilla.gnome.org/show_bug.cgi?id=790792 --- panels/display/cc-display-panel.c | 82 ++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/panels/display/cc-display-panel.c b/panels/display/cc-display-panel.c index 2f372fd7e..13f5332e9 100644 --- a/panels/display/cc-display-panel.c +++ b/panels/display/cc-display-panel.c @@ -87,6 +87,8 @@ struct _CcDisplayPanelPrivate GtkWidget *main_titlebar; GtkWidget *apply_titlebar; + GtkWidget *apply_titlebar_apply; + GtkWidget *apply_titlebar_warning; }; typedef struct @@ -283,6 +285,8 @@ reset_titlebar (CcDisplayPanel *self) } g_clear_object (&priv->apply_titlebar); + g_clear_object (&priv->apply_titlebar_apply); + g_clear_object (&priv->apply_titlebar_warning); } static void @@ -2590,47 +2594,59 @@ on_toplevel_key_press (GtkWidget *button, } static void -show_apply_titlebar (CcDisplayPanel *panel) +show_apply_titlebar (CcDisplayPanel *panel, gboolean is_applicable) { CcDisplayPanelPrivate *priv = panel->priv; - GtkWidget *header, *button, *toplevel; GtkSizeGroup *size_group; - if (priv->apply_titlebar) - return; + if (!priv->apply_titlebar) + { + GtkWidget *header, *button, *toplevel; + priv->apply_titlebar = header = gtk_header_bar_new (); - priv->apply_titlebar = header = gtk_header_bar_new (); - gtk_header_bar_set_title (GTK_HEADER_BAR (header), _("Apply Changes?")); + size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL); - size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL); + button = gtk_button_new_with_mnemonic (_("_Cancel")); + gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button); + gtk_size_group_add_widget (size_group, button); + g_signal_connect_object (button, "clicked", G_CALLBACK (on_screen_changed), + panel, G_CONNECT_SWAPPED); - button = gtk_button_new_with_mnemonic (_("_Cancel")); - gtk_header_bar_pack_start (GTK_HEADER_BAR (header), button); - gtk_size_group_add_widget (size_group, button); - g_signal_connect_object (button, "clicked", G_CALLBACK (on_screen_changed), - panel, G_CONNECT_SWAPPED); + toplevel = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel))); + g_signal_connect_object (toplevel, "key-press-event", G_CALLBACK (on_toplevel_key_press), + button, G_CONNECT_SWAPPED); - toplevel = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel))); - g_signal_connect_object (toplevel, "key-press-event", G_CALLBACK (on_toplevel_key_press), - button, G_CONNECT_SWAPPED); + priv->apply_titlebar_apply = button = gtk_button_new_with_mnemonic (_("_Apply")); + gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button); + gtk_size_group_add_widget (size_group, button); + g_signal_connect_object (button, "clicked", G_CALLBACK (apply_current_configuration), + panel, G_CONNECT_SWAPPED); + gtk_style_context_add_class (gtk_widget_get_style_context (button), + GTK_STYLE_CLASS_SUGGESTED_ACTION); - button = gtk_button_new_with_mnemonic (_("_Apply")); - gtk_header_bar_pack_end (GTK_HEADER_BAR (header), button); - gtk_size_group_add_widget (size_group, button); - g_signal_connect_object (button, "clicked", G_CALLBACK (apply_current_configuration), - panel, G_CONNECT_SWAPPED); - gtk_style_context_add_class (gtk_widget_get_style_context (button), - GTK_STYLE_CLASS_SUGGESTED_ACTION); + gtk_widget_show_all (header); + g_object_unref (size_group); - gtk_widget_show_all (header); - g_object_unref (size_group); + header = gtk_window_get_titlebar (GTK_WINDOW (toplevel)); + if (header) + priv->main_titlebar = g_object_ref (header); - header = gtk_window_get_titlebar (GTK_WINDOW (toplevel)); - if (header) - priv->main_titlebar = g_object_ref (header); + gtk_window_set_titlebar (GTK_WINDOW (toplevel), priv->apply_titlebar); + g_object_ref (priv->apply_titlebar); + g_object_ref (priv->apply_titlebar_apply); + } - gtk_window_set_titlebar (GTK_WINDOW (toplevel), priv->apply_titlebar); - g_object_ref (priv->apply_titlebar); + if (is_applicable) + { + gtk_header_bar_set_title (GTK_HEADER_BAR (priv->apply_titlebar), _("Apply Changes?")); + gtk_header_bar_set_subtitle (GTK_HEADER_BAR (priv->apply_titlebar), NULL); + } + else + { + gtk_header_bar_set_title (GTK_HEADER_BAR (priv->apply_titlebar), _("Changes Cannot be Applied")); + gtk_header_bar_set_subtitle (GTK_HEADER_BAR (priv->apply_titlebar), _("This could be due to hardware limitations.")); + } + gtk_widget_set_sensitive (priv->apply_titlebar_apply, is_applicable); } static void @@ -2640,12 +2656,6 @@ update_apply_button (CcDisplayPanel *panel) gboolean config_equal; CcDisplayConfig *applied_config; - if (!cc_display_config_is_applicable (priv->current_config)) - { - reset_titlebar (panel); - return; - } - applied_config = cc_display_config_manager_get_current (priv->manager); config_equal = cc_display_config_equal (priv->current_config, @@ -2655,7 +2665,7 @@ update_apply_button (CcDisplayPanel *panel) if (config_equal) reset_titlebar (panel); else - show_apply_titlebar (panel); + show_apply_titlebar (panel, cc_display_config_is_applicable (priv->current_config)); } static void -- cgit v1.2.1 From 0d16cd3feb2400b5b31e206ac5a140aea5298b66 Mon Sep 17 00:00:00 2001 From: Andrea Azzarone Date: Fri, 30 Mar 2018 11:19:56 +0000 Subject: keyboard: Make "Set Shortcut" button accessible Set 'can-focus' property to True for change_custom_shortcut_button, fixing keyboard navigation in the shortcut editor dialog. https://gitlab.gnome.org/GNOME/gnome-control-center/issues/45 --- panels/keyboard/shortcut-editor.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/panels/keyboard/shortcut-editor.ui b/panels/keyboard/shortcut-editor.ui index 74898ab79..081552955 100644 --- a/panels/keyboard/shortcut-editor.ui +++ b/panels/keyboard/shortcut-editor.ui @@ -255,7 +255,7 @@ True - False + True Set Shortcut… -- cgit v1.2.1 From 1367a8c083c2b3fa0db848fe6ae0cba3b9b7c25f Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 28 Mar 2018 16:39:13 -0300 Subject: window: Profile panel creation times --- shell/cc-window.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/shell/cc-window.c b/shell/cc-window.c index f7593dc55..09f5721b1 100644 --- a/shell/cc-window.c +++ b/shell/cc-window.c @@ -20,6 +20,8 @@ * Author: Thomas Wood */ +#define G_LOG_DOMAIN "cc-window" + #include #include "cc-window.h" @@ -31,6 +33,7 @@ #include #include #include +#include #include "cc-panel.h" #include "cc-shell.h" @@ -117,14 +120,21 @@ activate_panel (CcWindow *self, const gchar *name, GIcon *gicon) { + g_autoptr (GTimer) timer = NULL; GtkWidget *box, *title_widget; const gchar *icon_name; + gdouble ellapsed_time; if (!id) return FALSE; + timer = g_timer_new (); + g_settings_set_string (self->settings, "last-panel", id); + /* Begin the profile */ + g_timer_start (timer); + self->current_panel = GTK_WIDGET (cc_panel_loader_load_by_name (CC_SHELL (self), id, parameters)); cc_shell_set_active_panel (CC_SHELL (self), CC_PANEL (self->current_panel)); gtk_widget_show (self->current_panel); @@ -156,6 +166,13 @@ activate_panel (CcWindow *self, self->current_panel_box = box; + /* Finish profiling */ + g_timer_stop (timer); + + ellapsed_time = g_timer_elapsed (timer, NULL); + + g_debug ("Time to open panel '%s': %lfs", name, ellapsed_time); + return TRUE; } @@ -779,4 +796,4 @@ cc_window_set_search_item (CcWindow *center, gtk_search_bar_set_search_mode (GTK_SEARCH_BAR (center->search_bar), TRUE); gtk_entry_set_text (GTK_ENTRY (center->search_entry), search); gtk_editable_set_position (GTK_EDITABLE (center->search_entry), -1); -} \ No newline at end of file +} -- cgit v1.2.1 From 083e7bdae65e41ecc6f41f112af5fab7505295c4 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 17:48:08 -0300 Subject: object-storage: Introduce CcObjectStorage CcObjectStorage is a cache for GObjects. It is meant to store objects that are too expensive to be often created, such as NMClient, GoaClient or D-Bus proxies. CcObjectStorage has a very strict usage pattern. It is a programming error to add an object that is already stored, and so it is to retrieve an object that was not stored. Stored objects are meant to be kept alive during the whole lifetime of GNOME Settings, and CcObjectStorage takes a reference on every stored object to achieve that. If objects are destroyed while they are cached, it means we have a reference mismanagement somewhere. In this sense, CcObjectStorage will act Sam Sheepdog taking care of sneaky wolves trying to steal their sheep-references. Next patches will make various panels and objects around GNOME Settings adopt this new API, and make sure they always disconnect when destroyed. --- shell/cc-application.c | 13 ++ shell/cc-object-storage.c | 438 ++++++++++++++++++++++++++++++++++++++++++++++ shell/cc-object-storage.h | 65 +++++++ shell/meson.build | 1 + 4 files changed, 517 insertions(+) create mode 100644 shell/cc-object-storage.c create mode 100644 shell/cc-object-storage.h diff --git a/shell/cc-application.c b/shell/cc-application.c index 8beb61714..144cbeeb6 100644 --- a/shell/cc-application.c +++ b/shell/cc-application.c @@ -26,6 +26,7 @@ #include #include "cc-application.h" +#include "cc-object-storage.h" #include "cc-panel-loader.h" #include "cc-shell-log.h" #include "cc-window.h" @@ -264,6 +265,15 @@ cc_application_startup (GApplication *application) self->window = cc_window_new (GTK_APPLICATION (application)); } +static void +cc_application_finalize (GObject *object) +{ + /* Destroy the object storage cache when finalizing */ + cc_object_storage_destroy (); + + G_OBJECT_CLASS (cc_application_parent_class)->finalize (object); +} + static GObject * cc_application_constructor (GType type, guint n_construct_params, @@ -289,6 +299,7 @@ cc_application_class_init (CcApplicationClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); GApplicationClass *application_class = G_APPLICATION_CLASS (klass); + object_class->finalize = cc_application_finalize; object_class->constructor = cc_application_constructor; application_class->activate = cc_application_activate; application_class->startup = cc_application_startup; @@ -299,6 +310,8 @@ cc_application_class_init (CcApplicationClass *klass) static void cc_application_init (CcApplication *self) { + cc_object_storage_initialize (); + g_application_add_main_option_entries (G_APPLICATION (self), all_options); } diff --git a/shell/cc-object-storage.c b/shell/cc-object-storage.c new file mode 100644 index 000000000..0e708dc3b --- /dev/null +++ b/shell/cc-object-storage.c @@ -0,0 +1,438 @@ +/* cc-object-storage.h + * + * Copyright 2018 Georges Basile Stavracas Neto + * + * 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 . + */ + +#define G_LOG_DOMAIN "cc-object-storage" + +#include "cc-object-storage.h" + +struct _CcObjectStorage +{ + GObject parent_instance; + + GHashTable *id_to_object; +}; + +G_DEFINE_TYPE (CcObjectStorage, cc_object_storage, G_TYPE_OBJECT) + +/* Singleton instance */ +CcObjectStorage *_instance = NULL; + +/* GTask API to create a new D-Bus proxy */ +typedef struct +{ + GBusType bus_type; + GDBusProxyFlags flags; + gchar *name; + gchar *path; + gchar *interface; + gboolean cached; +} TaskData; + +static TaskData* +task_data_new (GBusType bus_type, + GDBusProxyFlags flags, + const gchar *name, + const gchar *path, + const gchar *interface) +{ + TaskData *data = g_slice_new (TaskData); + data->bus_type = bus_type; + data->flags =flags; + data->name = g_strdup (name); + data->path = g_strdup (path); + data->interface = g_strdup (interface); + data->cached = FALSE; + + return data; +} + +static void +task_data_free (TaskData *data) +{ + g_free (data->name); + g_free (data->path); + g_free (data->interface); + g_slice_free (TaskData, data); +} + +static void +create_dbus_proxy_in_thread_cb (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GError) local_error = NULL; + TaskData *data = task_data; + + proxy = g_dbus_proxy_new_for_bus_sync (data->bus_type, + data->flags, + NULL, + data->name, + data->path, + data->interface, + cancellable, + &local_error); + + if (local_error) + { + g_task_return_error (task, local_error); + return; + } + + g_task_return_pointer (task, g_object_ref (g_steal_pointer (&proxy)), g_object_unref); +} + +static void +cc_object_storage_finalize (GObject *object) +{ + CcObjectStorage *self = (CcObjectStorage *)object; + + g_debug ("Destroying cached objects"); + + g_clear_pointer (&self->id_to_object, g_hash_table_destroy); + + G_OBJECT_CLASS (cc_object_storage_parent_class)->finalize (object); +} + +static void +cc_object_storage_class_init (CcObjectStorageClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = cc_object_storage_finalize; +} + +static void +cc_object_storage_init (CcObjectStorage *self) +{ + self->id_to_object = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); +} + +/** + * cc_object_storage_has_object: + * @key: the unique string identifier of the object + * + * Checks whether there is an object associated with @key. + * + * Returns: %TRUE if the object is stored, %FALSE otherwise. + */ +gboolean +cc_object_storage_has_object (const gchar *key) +{ + g_assert (CC_IS_OBJECT_STORAGE (_instance)); + g_assert (key != NULL); + + return g_hash_table_contains (_instance->id_to_object, key); +} + +/** + * cc_object_storage_add_object: + * @key: the unique string identifier of the object + * @object: (type GObject): the object to be stored + * + * Adds @object to the object storage. It is a programming error to try to + * add an object that was already added. + * + * @object must be a GObject. + * + * Always check if the object is stored with cc_object_storage_has_object() + * before calling this function. + */ +void +cc_object_storage_add_object (const gchar *key, + gpointer object) +{ + /* Trying to add an object that was already added is a hard error. Each + * object must be added once, and only once, over the entire lifetime + * of the application. + */ + g_assert (CC_IS_OBJECT_STORAGE (_instance)); + g_assert (key != NULL); + g_assert (G_IS_OBJECT (object)); + g_assert (!g_hash_table_contains (_instance->id_to_object, key)); + + g_debug ("Adding object %s (%s → %p) to the storage", + g_type_name (G_OBJECT_TYPE (object)), + key, + object); + + g_hash_table_insert (_instance->id_to_object, g_strdup (key), g_object_ref (object)); +} + +/** + * cc_object_storage_get_object: + * @key: the unique string identifier of the object + * + * Retrieves the object associated with @key. It is a programming error to + * try to retrieve an object before adding it. + * + * Always check if the object is stored with cc_object_storage_has_object() + * before calling this function. + * + * Returns: (transfer full): the GObject associated with @key. + */ +gpointer +cc_object_storage_get_object (const gchar *key) +{ + /* Trying to peek an object that was not yet added is a hard error. Users + * of this API need to first check if the object is available with + * cc_object_storage_has_object(). + */ + g_assert (CC_IS_OBJECT_STORAGE (_instance)); + g_assert (key != NULL); + g_assert (g_hash_table_contains (_instance->id_to_object, key)); + + return g_object_ref (g_hash_table_lookup (_instance->id_to_object, key)); +} + +/** + * cc_object_storage_create_dbus_proxy_sync: + * @name: the D-Bus name + * @flags: the D-Bus proxy flags + * @path: the D-Bus object path + * @interface: the D-Bus interface name + * @cancellable: (nullable): #GCancellable to cancel the operation + * @error: (nullable): return location for a #GError + * + * Synchronously create a #GDBusProxy with @name, @path and @interface, + * stores it in the cache, and returns the newly created proxy. + * + * If a proxy with that signature is already created, it will be used + * instead of creating a new one. + * + * Returns: (transfer full)(nullable): the new #GDBusProxy. + */ +gpointer +cc_object_storage_create_dbus_proxy_sync (GBusType bus_type, + GDBusProxyFlags flags, + const gchar *name, + const gchar *path, + const gchar *interface, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GError) local_error = NULL; + g_autofree gchar *key = NULL; + + g_assert (CC_IS_OBJECT_STORAGE (_instance)); + g_assert (name && *name); + g_assert (path && *path); + g_assert (interface && *interface); + g_assert (!error || !*error); + + key = g_strdup_printf ("CcObjectStorage::dbus-proxy(%s,%s,%s)", name, path, interface); + + /* Check if a DBus proxy with that signature is already available; if it is, + * return that instead of a new one. + */ + if (g_hash_table_contains (_instance->id_to_object, key)) + return cc_object_storage_get_object (key); + + proxy = g_dbus_proxy_new_for_bus_sync (bus_type, + flags, + NULL, + name, + path, + interface, + cancellable, + &local_error); + + if (local_error) + { + g_propagate_error (error, local_error); + return NULL; + } + + /* Store the newly created D-Bus proxy */ + cc_object_storage_add_object (key, proxy); + + return g_steal_pointer (&proxy); +} + + +/** + * cc_object_storage_create_dbus_proxy: + * @name: the D-Bus name + * @flags: the D-Bus proxy flags + * @path: the D-Bus object path + * @interface: the D-Bus interface name + * @cancellable: (nullable): #GCancellable to cancel the operation + * @callback: callback for when the async operation is finished + * @user_data: user data for @callback + * + * Asynchronously create a #GDBusProxy with @name, @path and @interface. + * + * If a proxy with that signature is already created, it will be used instead of + * creating a new one. + * + * It is a programming error to create the an identical proxy while asynchronously + * creating one. Not cancelling this operation will result in an assertion failure + * when calling cc_object_storage_create_dbus_proxy_finish(). + */ +void +cc_object_storage_create_dbus_proxy (GBusType bus_type, + GDBusProxyFlags flags, + const gchar *name, + const gchar *path, + const gchar *interface, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_autoptr(GTask) task = NULL; + g_autofree gchar *key = NULL; + TaskData *data = NULL; + + g_assert (CC_IS_OBJECT_STORAGE (_instance)); + g_assert (name && *name); + g_assert (path && *path); + g_assert (interface && *interface); + g_assert (!cancellable || G_IS_CANCELLABLE (cancellable)); + + data = task_data_new (bus_type, flags, name, path, interface); + + task = g_task_new (_instance, cancellable, callback, user_data); + g_task_set_source_tag (task, cc_object_storage_create_dbus_proxy); + g_task_set_task_data (task, data, (GDestroyNotify) task_data_free); + + /* Check if the D-Bus proxy is already created */ + key = g_strdup_printf ("CcObjectStorage::dbus-proxy(%s,%s,%s)", name, path, interface); + + if (g_hash_table_contains (_instance->id_to_object, key)) + { + /* Mark this GTask as already cached, so we can call the right assertions + * on the callback + * */ + data->cached = TRUE; + + g_debug ("Found in cache the D-Bus proxy %s", key); + + g_task_return_pointer (task, cc_object_storage_get_object (key), g_object_unref); + return; + } + + g_task_run_in_thread (task, create_dbus_proxy_in_thread_cb); +} + +/** + * cc_object_storage_create_dbus_proxy_finish: + * @result: + * @error: (nullable): return location for a #GError + * + * Finishes a D-Bus proxy creation started by cc_object_storage_create_dbus_proxy(). + * + * Synchronously create a #GDBusProxy with @name, @path and @interface, + * stores it in the cache, and returns the newly created proxy. + * + * If a proxy with that signature is already created, it will be used + * instead of creating a new one. + * + * Returns: (transfer full)(nullable): the new #GDBusProxy. + */ +gpointer +cc_object_storage_create_dbus_proxy_finish (GAsyncResult *result, + GError **error) +{ + g_autoptr(GDBusProxy) proxy = NULL; + g_autoptr(GError) local_error = NULL; + g_autofree gchar *key = NULL; + TaskData *task_data; + GTask *task; + + task = G_TASK (result); + + g_assert (task && G_TASK (result)); + g_assert (!error || !*error); + + task_data = g_task_get_task_data (task); + + key = g_strdup_printf ("CcObjectStorage::dbus-proxy(%s,%s,%s)", + task_data->name, + task_data->path, + task_data->interface); + + /* Either we have the object stored right when trying to create it - in which case, + * task_data->cached == TRUE and cc_object_storage_has_object (key) == TRUE - or we + * didn't have a cached proxy before, and we shouldn't have it now. + * + * This is to force consumers of this code to *never* try to create the same D-Bus + * proxy asynchronously multiple times. Trying to do so is considered a programming + * error. + */ + g_assert (task_data != NULL); + g_assert (task_data->cached == cc_object_storage_has_object (key)); + + /* Retrieve the newly created proxy */ + proxy = g_task_propagate_pointer (task, &local_error); + + /* If the proxy is not cached, do the normal caching routine */ + if (local_error) + { + g_propagate_error (error, local_error); + return NULL; + } + + /* If the proxy is already cached, destroy the newly created and used the cached proxy + * instead. + */ + if (cc_object_storage_has_object (key)) + return cc_object_storage_get_object (key); + + /* Store the newly created D-Bus proxy */ + cc_object_storage_add_object (key, proxy); + + return g_steal_pointer (&proxy); +} + +/** + * cc_object_storage_init: + * + * Initializes the single CcObjectStorage. This must be called only once, + * and before every other method of this object. + */ +void +cc_object_storage_initialize (void) +{ + g_assert (_instance == NULL); + + if (g_once_init_enter (&_instance)) + { + CcObjectStorage *instance = g_object_new (CC_TYPE_OBJECT_STORAGE, NULL); + + g_debug ("Initializing object storage"); + + g_once_init_leave (&_instance, instance); + } +} + +/** + * cc_object_storage_destroy: + * + * Destroys the instance of #CcObjectStorage. This must be called only + * once during the application lifetime. It is a programming error to + * call this function multiple times + */ +void +cc_object_storage_destroy (void) +{ + g_assert (_instance != NULL); + + g_clear_object (&_instance); +} diff --git a/shell/cc-object-storage.h b/shell/cc-object-storage.h new file mode 100644 index 000000000..efea0e294 --- /dev/null +++ b/shell/cc-object-storage.h @@ -0,0 +1,65 @@ +/* cc-object-storage.h + * + * Copyright 2018 Georges Basile Stavracas Neto + * + * 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 . + */ + +#pragma once + +#include +#include + +G_BEGIN_DECLS + +/* Default storage keys */ +#define CC_OBJECT_NMCLIENT "CcObjectStorage::nm-client" + + +#define CC_TYPE_OBJECT_STORAGE (cc_object_storage_get_type()) + +G_DECLARE_FINAL_TYPE (CcObjectStorage, cc_object_storage, CC, OBJECT_STORAGE, GObject) + +gboolean cc_object_storage_has_object (const gchar *key); + +void cc_object_storage_add_object (const gchar *key, + gpointer object); + +gpointer cc_object_storage_get_object (const gchar *key); + +gpointer cc_object_storage_create_dbus_proxy_sync (GBusType bus_type, + GDBusProxyFlags flags, + const gchar *name, + const gchar *path, + const gchar *interface, + GCancellable *cancellable, + GError **error); + +void cc_object_storage_create_dbus_proxy (GBusType bus_type, + GDBusProxyFlags flags, + const gchar *name, + const gchar *path, + const gchar *interface, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gpointer cc_object_storage_create_dbus_proxy_finish (GAsyncResult *result, + GError **error); + +void cc_object_storage_initialize (void); + +void cc_object_storage_destroy (void); + +G_END_DECLS diff --git a/shell/meson.build b/shell/meson.build index d9364521b..0946ada74 100644 --- a/shell/meson.build +++ b/shell/meson.build @@ -46,6 +46,7 @@ common_sources = files( 'cc-application.c', 'cc-editable-entry.c', 'cc-hostname-entry.c', + 'cc-object-storage.c', 'cc-panel-loader.c', 'cc-panel.c', 'cc-shell-category-view.c', -- cgit v1.2.1 From d6535f82f03894b15d13bbaf6b2a0a027e7209f8 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 17:59:12 -0300 Subject: bluetooth: Cache the D-Bus proxy --- panels/bluetooth/cc-bluetooth-panel.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/panels/bluetooth/cc-bluetooth-panel.c b/panels/bluetooth/cc-bluetooth-panel.c index 36c58bf4d..5a60d70c8 100644 --- a/panels/bluetooth/cc-bluetooth-panel.c +++ b/panels/bluetooth/cc-bluetooth-panel.c @@ -24,6 +24,7 @@ #include #include +#include #include #include "cc-bluetooth-panel.h" @@ -310,20 +311,18 @@ cc_bluetooth_panel_init (CcBluetoothPanel *self) self->cancellable = g_cancellable_new (); /* RFKill */ - self->rfkill = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Rfkill", - "/org/gnome/SettingsDaemon/Rfkill", - "org.gnome.SettingsDaemon.Rfkill", - NULL, NULL); - self->properties = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Rfkill", - "/org/gnome/SettingsDaemon/Rfkill", - "org.freedesktop.DBus.Properties", - NULL, NULL); + self->rfkill = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Rfkill", + "/org/gnome/SettingsDaemon/Rfkill", + "org.gnome.SettingsDaemon.Rfkill", + NULL, NULL); + self->properties = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Rfkill", + "/org/gnome/SettingsDaemon/Rfkill", + "org.freedesktop.DBus.Properties", + NULL, NULL); self->stack = gtk_stack_new (); gtk_stack_set_homogeneous (GTK_STACK (self->stack), TRUE); @@ -343,10 +342,10 @@ cc_bluetooth_panel_init (CcBluetoothPanel *self) gtk_container_add (GTK_CONTAINER (self), self->stack); airplane_mode_changed (NULL, NULL, NULL, self); - g_signal_connect (self->rfkill, "g-properties-changed", - G_CALLBACK (airplane_mode_changed), self); - g_signal_connect_swapped (G_OBJECT (self->widget), "adapter-status-changed", - G_CALLBACK (cc_bluetooth_panel_update_power), self); + g_signal_connect_object (self->rfkill, "g-properties-changed", + G_CALLBACK (airplane_mode_changed), self, 0); + g_signal_connect_object (G_OBJECT (self->widget), "adapter-status-changed", + G_CALLBACK (cc_bluetooth_panel_update_power), self, G_CONNECT_SWAPPED); g_signal_connect (G_OBJECT (WID ("switch_bluetooth")), "notify::active", G_CALLBACK (power_callback), self); -- cgit v1.2.1 From 8e56ea35f38898deb3b5858211c64ba2ce0e0e93 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 17:59:41 -0300 Subject: color: Cache D-Bus proxies --- panels/color/cc-color-calibrate.c | 48 +++++++++++++++++++-------------------- panels/color/cc-color-panel.c | 1 - 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/panels/color/cc-color-calibrate.c b/panels/color/cc-color-calibrate.c index d21ad058f..9357eee72 100644 --- a/panels/color/cc-color-calibrate.c +++ b/panels/color/cc-color-calibrate.c @@ -28,6 +28,8 @@ #include #include +#include "shell/cc-object-storage.h" + #define GNOME_DESKTOP_USE_UNSTABLE_API #include @@ -884,14 +886,13 @@ cc_color_calibrate_setup (CcColorCalibrate *calibrate, g_return_val_if_fail (calibrate->priv->device_kind != CD_SENSOR_CAP_UNKNOWN, FALSE); /* use logind to disable system state idle */ - priv->proxy_inhibit = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.login1", - "/org/freedesktop/login1", - "org.freedesktop.login1.Manager", - NULL, - error); + priv->proxy_inhibit = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.login1", + "/org/freedesktop/login1", + "org.freedesktop.login1.Manager", + NULL, + error); if (priv->proxy_inhibit == NULL) { ret = FALSE; @@ -899,27 +900,26 @@ cc_color_calibrate_setup (CcColorCalibrate *calibrate, } /* start the calibration session daemon */ - priv->proxy_helper = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - CD_SESSION_DBUS_SERVICE, - CD_SESSION_DBUS_PATH, - CD_SESSION_DBUS_INTERFACE_DISPLAY, - NULL, - error); + priv->proxy_helper = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + CD_SESSION_DBUS_SERVICE, + CD_SESSION_DBUS_PATH, + CD_SESSION_DBUS_INTERFACE_DISPLAY, + NULL, + error); if (priv->proxy_helper == NULL) { ret = FALSE; goto out; } - g_signal_connect (priv->proxy_helper, - "g-properties-changed", - G_CALLBACK (cc_color_calibrate_property_changed_cb), - calibrate); - g_signal_connect (priv->proxy_helper, - "g-signal", - G_CALLBACK (cc_color_calibrate_signal_cb), - calibrate); + g_signal_connect_object (priv->proxy_helper, + "g-properties-changed", + G_CALLBACK (cc_color_calibrate_property_changed_cb), + calibrate, 0); + g_signal_connect_object (priv->proxy_helper, + "g-signal", + G_CALLBACK (cc_color_calibrate_signal_cb), + calibrate, 0); out: return ret; } diff --git a/panels/color/cc-color-panel.c b/panels/color/cc-color-panel.c index d901b623e..e7957deba 100644 --- a/panels/color/cc-color-panel.c +++ b/panels/color/cc-color-panel.c @@ -49,7 +49,6 @@ struct _CcColorPanelPrivate GPtrArray *devices; GPtrArray *sensors; GCancellable *cancellable; - GDBusProxy *proxy; GSettings *settings; GSettings *settings_colord; GtkBuilder *builder; -- cgit v1.2.1 From cbf0dc99daf59af5111bc449ecaec64d0c0e204b Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:00:11 -0300 Subject: display: Cache the D-Bus proxy --- panels/display/cc-display-panel.c | 24 +++++++++--------- panels/display/cc-night-light-dialog.c | 46 +++++++++++++++++----------------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/panels/display/cc-display-panel.c b/panels/display/cc-display-panel.c index 13f5332e9..550376776 100644 --- a/panels/display/cc-display-panel.c +++ b/panels/display/cc-display-panel.c @@ -29,6 +29,7 @@ #include #include +#include "shell/cc-object-storage.h" #include "shell/list-box-helper.h" #include @@ -3117,7 +3118,7 @@ shell_proxy_ready (GObject *source, GDBusProxy *proxy; GError *error = NULL; - proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + proxy = cc_object_storage_create_dbus_proxy_finish (res, &error); if (!proxy) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -3336,17 +3337,16 @@ cc_display_panel_init (CcDisplayPanel *self) g_signal_connect (self, "map", G_CALLBACK (mapped_cb), NULL); self->priv->shell_cancellable = g_cancellable_new (); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | - G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NULL, - "org.gnome.Shell", - "/org/gnome/Shell", - "org.gnome.Shell", - self->priv->shell_cancellable, - (GAsyncReadyCallback) shell_proxy_ready, - self); + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "org.gnome.Shell", + "/org/gnome/Shell", + "org.gnome.Shell", + self->priv->shell_cancellable, + (GAsyncReadyCallback) shell_proxy_ready, + self); g_bus_get (G_BUS_TYPE_SESSION, self->priv->shell_cancellable, diff --git a/panels/display/cc-night-light-dialog.c b/panels/display/cc-night-light-dialog.c index a2bbc683e..1d03ba393 100644 --- a/panels/display/cc-night-light-dialog.c +++ b/panels/display/cc-night-light-dialog.c @@ -27,6 +27,8 @@ #include "cc-night-light-dialog.h" #include "cc-night-light-widget.h" +#include "shell/cc-object-storage.h" + struct _CcNightLightDialog { GObject parent; GtkBuilder *builder; @@ -385,14 +387,14 @@ dialog_got_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_da { CcNightLightDialog *self = (CcNightLightDialog *) user_data; g_autoptr(GError) error = NULL; - self->proxy_color = g_dbus_proxy_new_for_bus_finish (res, &error); + self->proxy_color = cc_object_storage_create_dbus_proxy_finish (res, &error); if (self->proxy_color == NULL) { g_warning ("failed to connect to g-s-d: %s", error->message); return; } - g_signal_connect (self->proxy_color, "g-properties-changed", - G_CALLBACK (dialog_color_properties_changed_cb), self); + g_signal_connect_object (self->proxy_color, "g-properties-changed", + G_CALLBACK (dialog_color_properties_changed_cb), self, 0); dialog_update_state (self); self->timer_id = g_timeout_add_seconds (10, dialog_tick_cb, self); } @@ -402,7 +404,7 @@ dialog_got_proxy_props_cb (GObject *source_object, GAsyncResult *res, gpointer u { CcNightLightDialog *self = (CcNightLightDialog *) user_data; g_autoptr(GError) error = NULL; - self->proxy_color_props = g_dbus_proxy_new_for_bus_finish (res, &error); + self->proxy_color_props = cc_object_storage_create_dbus_proxy_finish (res, &error); if (self->proxy_color_props == NULL) { g_warning ("failed to connect to g-s-d: %s", error->message); @@ -669,25 +671,23 @@ cc_night_light_dialog_init (CcNightLightDialog *self) gtk_box_pack_start (box, self->night_light_widget, FALSE, FALSE, 0); gtk_widget_show (self->night_light_widget); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Color", - "/org/gnome/SettingsDaemon/Color", - "org.gnome.SettingsDaemon.Color", - self->cancellable, - dialog_got_proxy_cb, - self); - - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Color", - "/org/gnome/SettingsDaemon/Color", - "org.freedesktop.DBus.Properties", - self->cancellable, - dialog_got_proxy_props_cb, - self); + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Color", + "/org/gnome/SettingsDaemon/Color", + "org.gnome.SettingsDaemon.Color", + self->cancellable, + dialog_got_proxy_cb, + self); + + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Color", + "/org/gnome/SettingsDaemon/Color", + "org.freedesktop.DBus.Properties", + self->cancellable, + dialog_got_proxy_props_cb, + self); /* clock settings_display */ self->settings_clock = g_settings_new (CLOCK_SCHEMA); -- cgit v1.2.1 From 250eb01931e5ebb6196c2ee57b3cf12a0dfe9b4b Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:00:43 -0300 Subject: network: Cache D-Bus proxies and objects --- panels/network/cc-network-panel.c | 32 +++++++++++++------- panels/network/cc-wifi-panel.c | 63 +++++++++++++++++++++++---------------- 2 files changed, 58 insertions(+), 37 deletions(-) diff --git a/panels/network/cc-network-panel.c b/panels/network/cc-network-panel.c index 51ea823f7..405b538cf 100644 --- a/panels/network/cc-network-panel.c +++ b/panels/network/cc-network-panel.c @@ -23,6 +23,8 @@ #include #include +#include "shell/cc-object-storage.h" + #include "cc-network-panel.h" #include "cc-network-resources.h" @@ -876,16 +878,24 @@ cc_network_panel_init (CcNetworkPanel *panel) /* add the virtual proxy device */ panel_add_proxy_device (panel); + /* Create and store a NMClient instance if it doesn't exist yet */ + if (!cc_object_storage_has_object (CC_OBJECT_NMCLIENT)) { + NMClient *client = nm_client_new (NULL, NULL); + cc_object_storage_add_object (CC_OBJECT_NMCLIENT, client); + g_object_unref (client); + } + /* use NetworkManager client */ - panel->client = nm_client_new (NULL, NULL); - g_signal_connect (panel->client, "notify::nm-running" , - G_CALLBACK (manager_running), panel); - g_signal_connect (panel->client, "notify::active-connections", - G_CALLBACK (active_connections_changed), panel); - g_signal_connect (panel->client, "device-added", - G_CALLBACK (device_added_cb), panel); - g_signal_connect (panel->client, "device-removed", - G_CALLBACK (device_removed_cb), panel); + panel->client = cc_object_storage_get_object (CC_OBJECT_NMCLIENT); + + g_signal_connect_object (panel->client, "notify::nm-running" , + G_CALLBACK (manager_running), panel, 0); + g_signal_connect_object (panel->client, "notify::active-connections", + G_CALLBACK (active_connections_changed), panel, 0); + g_signal_connect_object (panel->client, "device-added", + G_CALLBACK (device_added_cb), panel, 0); + g_signal_connect_object (panel->client, "device-removed", + G_CALLBACK (device_removed_cb), panel, 0); /* Setup ModemManager client */ system_bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); @@ -907,8 +917,8 @@ cc_network_panel_init (CcNetworkPanel *panel) } /* add remote settings such as VPN settings as virtual devices */ - g_signal_connect (panel->client, NM_CLIENT_CONNECTION_ADDED, - G_CALLBACK (notify_connection_added_cb), panel); + g_signal_connect_object (panel->client, NM_CLIENT_CONNECTION_ADDED, + G_CALLBACK (notify_connection_added_cb), panel, 0); toplevel = gtk_widget_get_toplevel (GTK_WIDGET (panel)); g_signal_connect_after (toplevel, "map", G_CALLBACK (on_toplevel_map), panel); diff --git a/panels/network/cc-wifi-panel.c b/panels/network/cc-wifi-panel.c index 2c1cd17b7..64321752c 100644 --- a/panels/network/cc-wifi-panel.c +++ b/panels/network/cc-wifi-panel.c @@ -23,6 +23,7 @@ #include "net-device-wifi.h" #include "network-dialogs.h" +#include "shell/cc-object-storage.h" #include "shell/list-box-helper.h" #include @@ -421,7 +422,7 @@ rfkill_proxy_acquired_cb (GObject *source_object, GError *error; error = NULL; - proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + proxy = cc_object_storage_create_dbus_proxy_finish (res, &error); if (error) { @@ -618,37 +619,47 @@ cc_wifi_panel_init (CcWifiPanel *self) self->cancellable = g_cancellable_new (); self->devices = g_ptr_array_new_with_free_func (g_object_unref); - /* Load NetworkManager */ - self->client = nm_client_new (NULL, NULL); - - g_signal_connect (self->client, - "device-added", - G_CALLBACK (device_added_cb), - self); - - g_signal_connect (self->client, - "device-removed", - G_CALLBACK (device_removed_cb), - self); + /* Create and store a NMClient instance if it doesn't exist yet */ + if (!cc_object_storage_has_object (CC_OBJECT_NMCLIENT)) + { + NMClient *client = nm_client_new (NULL, NULL); + cc_object_storage_add_object (CC_OBJECT_NMCLIENT, client); + g_object_unref (client); + } - g_signal_connect (self->client, - "notify::wireless-enabled", - G_CALLBACK (wireless_enabled_cb), - self); + /* Load NetworkManager */ + self->client = cc_object_storage_get_object (CC_OBJECT_NMCLIENT); + + g_signal_connect_object (self->client, + "device-added", + G_CALLBACK (device_added_cb), + self, + 0); + + g_signal_connect_object (self->client, + "device-removed", + G_CALLBACK (device_removed_cb), + self, + 0); + + g_signal_connect_object (self->client, + "notify::wireless-enabled", + G_CALLBACK (wireless_enabled_cb), + self, + 0); /* Load Wi-Fi devices */ load_wifi_devices (self); /* Acquire Airplane Mode proxy */ - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Rfkill", - "/org/gnome/SettingsDaemon/Rfkill", - "org.gnome.SettingsDaemon.Rfkill", - self->cancellable, - rfkill_proxy_acquired_cb, - self); + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Rfkill", + "/org/gnome/SettingsDaemon/Rfkill", + "org.gnome.SettingsDaemon.Rfkill", + self->cancellable, + rfkill_proxy_acquired_cb, + self); /* Handle comment-line arguments after loading devices */ handle_argv (self); -- cgit v1.2.1 From 35f948f5fbdf784ff20a4b0cc4775c7fc1fbe413 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:01:15 -0300 Subject: common: Cache D-Bus proxy --- panels/common/cc-common-language.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/panels/common/cc-common-language.c b/panels/common/cc-common-language.c index 028213acb..4ea4f06ad 100644 --- a/panels/common/cc-common-language.c +++ b/panels/common/cc-common-language.c @@ -33,6 +33,7 @@ #include #include "cc-common-language.h" +#include "shell/cc-object-storage.h" static char *get_lang_for_user_object_path (const char *path); @@ -175,14 +176,13 @@ get_lang_for_user_object_path (const char *path) GVariant *props; char *lang; - user = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.Accounts", - path, - "org.freedesktop.Accounts.User", - NULL, - &error); + user = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.Accounts", + path, + "org.freedesktop.Accounts.User", + NULL, + &error); if (user == NULL) { g_warning ("Failed to get proxy for user '%s': %s", path, error->message); -- cgit v1.2.1 From e46d505182c087858ecf52609c3802be5d285dfe Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:01:44 -0300 Subject: info: Cache D-Bus proxies --- panels/info/cc-info-overview-panel.c | 42 +++++++++++++++++------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/panels/info/cc-info-overview-panel.c b/panels/info/cc-info-overview-panel.c index 411c1c905..4301090f9 100644 --- a/panels/info/cc-info-overview-panel.c +++ b/panels/info/cc-info-overview-panel.c @@ -22,6 +22,7 @@ #include #include "shell/cc-hostname-entry.h" +#include "shell/cc-object-storage.h" #include "cc-info-resources.h" #include "info-cleanup.h" @@ -235,13 +236,12 @@ get_renderer_from_session (void) char *renderer; g_autoptr(GError) error = NULL; - session_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SessionManager", - "/org/gnome/SessionManager", - "org.gnome.SessionManager", - NULL, &error); + session_proxy = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SessionManager", + "/org/gnome/SessionManager", + "org.gnome.SessionManager", + NULL, &error); if (error != NULL) { g_warning ("Unable to connect to create a proxy for org.gnome.SessionManager: %s", @@ -302,13 +302,12 @@ has_dual_gpu (void) gboolean ret; g_autoptr(GError) error = NULL; - switcheroo_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "net.hadess.SwitcherooControl", - "/net/hadess/SwitcherooControl", - "net.hadess.SwitcherooControl", - NULL, &error); + switcheroo_proxy = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "net.hadess.SwitcherooControl", + "/net/hadess/SwitcherooControl", + "net.hadess.SwitcherooControl", + NULL, &error); if (switcheroo_proxy == NULL) { g_debug ("Unable to connect to create a proxy for net.hadess.SwitcherooControl: %s", @@ -720,14 +719,13 @@ info_overview_panel_setup_virt (CcInfoOverviewPanel *self) g_autoptr(GVariant) variant = NULL; GVariant *inner; - systemd_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.systemd1", - "/org/freedesktop/systemd1", - "org.freedesktop.systemd1", - NULL, - &error); + systemd_proxy = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.systemd1", + "/org/freedesktop/systemd1", + "org.freedesktop.systemd1", + NULL, + &error); if (systemd_proxy == NULL) { -- cgit v1.2.1 From 77ac09aa04c26a88b3c75466ab3c8432b3682b0c Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:02:44 -0300 Subject: notification: Cache D-Bus proxy --- panels/notifications/cc-notifications-panel.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/panels/notifications/cc-notifications-panel.c b/panels/notifications/cc-notifications-panel.c index 1265b5b6f..0b1b834ca 100644 --- a/panels/notifications/cc-notifications-panel.c +++ b/panels/notifications/cc-notifications-panel.c @@ -25,6 +25,7 @@ #include #include +#include "shell/cc-object-storage.h" #include "shell/list-box-helper.h" #include "cc-notifications-panel.h" #include "cc-notifications-resources.h" @@ -150,7 +151,7 @@ on_perm_store_ready (GObject *source_object, GDBusProxy *proxy; GError *error = NULL; - proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + proxy = cc_object_storage_create_dbus_proxy_finish (res, &error); if (proxy == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -241,15 +242,14 @@ cc_notifications_panel_init (CcNotificationsPanel *panel) gtk_widget_show (w); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.impl.portal.PermissionStore", - "/org/freedesktop/impl/portal/PermissionStore", - "org.freedesktop.impl.portal.PermissionStore", - panel->apps_load_cancellable, - on_perm_store_ready, - panel); + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.impl.portal.PermissionStore", + "/org/freedesktop/impl/portal/PermissionStore", + "org.freedesktop.impl.portal.PermissionStore", + panel->apps_load_cancellable, + on_perm_store_ready, + panel); } static const char * -- cgit v1.2.1 From eb62419b4bd989b5a39f9fe8f37209edf9f8c606 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:03:13 -0300 Subject: power: Cache D-Bus proxies and NMClient --- panels/power/cc-power-panel.c | 134 +++++++++++++++++++++++------------------- 1 file changed, 75 insertions(+), 59 deletions(-) diff --git a/panels/power/cc-power-panel.c b/panels/power/cc-power-panel.c index f9b67a458..b78c17a49 100644 --- a/panels/power/cc-power-panel.c +++ b/panels/power/cc-power-panel.c @@ -29,6 +29,7 @@ #include #endif +#include "shell/cc-object-storage.h" #include "shell/list-box-helper.h" #include "cc-power-panel.h" #include "cc-power-resources.h" @@ -1083,7 +1084,7 @@ got_screen_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_da CcPowerPanel *self; GDBusProxy *screen_proxy; - screen_proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + screen_proxy = cc_object_storage_create_dbus_proxy_finish (res, &error); if (screen_proxy == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -1096,8 +1097,8 @@ got_screen_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_da self->priv->screen_proxy = screen_proxy; /* we want to change the bar if the user presses brightness buttons */ - g_signal_connect (screen_proxy, "g-properties-changed", - G_CALLBACK (on_screen_property_change), self); + g_signal_connect_object (screen_proxy, "g-properties-changed", + G_CALLBACK (on_screen_property_change), self, 0); sync_screen_brightness (self); als_enabled_state_changed (self); @@ -1120,7 +1121,7 @@ got_kbd_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) CcPowerPanel *self; GDBusProxy *kbd_proxy; - kbd_proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + kbd_proxy = cc_object_storage_create_dbus_proxy_finish (res, &error); if (kbd_proxy == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -1133,8 +1134,8 @@ got_kbd_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) self->priv->kbd_proxy = kbd_proxy; /* we want to change the bar if the user presses brightness buttons */ - g_signal_connect (kbd_proxy, "g-properties-changed", - G_CALLBACK (on_kbd_property_change), self); + g_signal_connect_object (kbd_proxy, "g-properties-changed", + G_CALLBACK (on_kbd_property_change), self, 0); sync_kbd_brightness (self); } @@ -1440,13 +1441,31 @@ nm_device_changed (NMClient *client, gtk_widget_set_visible (priv->mobile_row, has_mobile_devices (priv->nm_client)); } +static void +setup_nm_client (CcPowerPanel *self, + NMClient *client) +{ + CcPowerPanelPrivate *priv = self->priv; + + priv->nm_client = client; + + g_signal_connect_object (priv->nm_client, "notify", + G_CALLBACK (nm_client_state_changed), self, 0); + g_signal_connect_object (priv->nm_client, "device-added", + G_CALLBACK (nm_device_changed), self, 0); + g_signal_connect_object (priv->nm_client, "device-removed", + G_CALLBACK (nm_device_changed), self, 0); + + nm_client_state_changed (priv->nm_client, NULL, self); + nm_device_changed (priv->nm_client, NULL, self); +} + static void nm_client_ready_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) { CcPowerPanel *self; - CcPowerPanelPrivate *priv; NMClient *client; GError *error = NULL; @@ -1467,18 +1486,12 @@ nm_client_ready_cb (GObject *source_object, } self = user_data; - priv = self->priv; - priv->nm_client = client; - g_signal_connect (priv->nm_client, "notify", - G_CALLBACK (nm_client_state_changed), self); - g_signal_connect (priv->nm_client, "device-added", - G_CALLBACK (nm_device_changed), self); - g_signal_connect (priv->nm_client, "device-removed", - G_CALLBACK (nm_device_changed), self); + /* Setup the client */ + setup_nm_client (self, client); - nm_client_state_changed (priv->nm_client, NULL, self); - nm_device_changed (priv->nm_client, NULL, self); + /* Store the object in the cache too */ + cc_object_storage_add_object (CC_OBJECT_NMCLIENT, client); } #endif @@ -1648,13 +1661,12 @@ iio_proxy_appeared_cb (GDBusConnection *connection, GError *error = NULL; self->priv->iio_proxy = - g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "net.hadess.SensorProxy", - "/net/hadess/SensorProxy", - "net.hadess.SensorProxy", - NULL, &error); + cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "net.hadess.SensorProxy", + "/net/hadess/SensorProxy", + "net.hadess.SensorProxy", + NULL, &error); if (error != NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -1887,29 +1899,35 @@ add_power_saving_section (CcPowerPanel *self) g_signal_connect (G_OBJECT (priv->mobile_switch), "notify::active", G_CALLBACK (mobile_switch_changed), self); - nm_client_new_async (priv->cancellable, nm_client_ready_cb, self); + /* Create and store a NMClient instance if it doesn't exist yet */ + if (cc_object_storage_has_object (CC_OBJECT_NMCLIENT)) + setup_nm_client (self, cc_object_storage_get_object (CC_OBJECT_NMCLIENT)); + else + nm_client_new_async (priv->cancellable, nm_client_ready_cb, self); g_signal_connect (G_OBJECT (priv->wifi_switch), "notify::active", G_CALLBACK (wifi_switch_changed), self); #endif #ifdef HAVE_BLUETOOTH - priv->bt_rfkill = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Rfkill", - "/org/gnome/SettingsDaemon/Rfkill", - "org.gnome.SettingsDaemon.Rfkill", - NULL, NULL); + + priv->bt_rfkill = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Rfkill", + "/org/gnome/SettingsDaemon/Rfkill", + "org.gnome.SettingsDaemon.Rfkill", + NULL, + NULL); + if (priv->bt_rfkill) { - priv->bt_properties = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Rfkill", - "/org/gnome/SettingsDaemon/Rfkill", - "org.freedesktop.DBus.Properties", - NULL, NULL); + priv->bt_properties = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Rfkill", + "/org/gnome/SettingsDaemon/Rfkill", + "org.freedesktop.DBus.Properties", + NULL, + NULL); } row = no_prelight_row_new (); @@ -1944,8 +1962,8 @@ add_power_saving_section (CcPowerPanel *self) gtk_widget_show_all (box); gtk_widget_set_no_show_all (row, TRUE); priv->bt_row = row; - g_signal_connect_swapped (G_OBJECT (priv->bt_rfkill), "g-properties-changed", - G_CALLBACK (bt_powered_state_changed), self); + g_signal_connect_object (priv->bt_rfkill, "g-properties-changed", + G_CALLBACK (bt_powered_state_changed), self, G_CONNECT_SWAPPED); g_signal_connect (G_OBJECT (priv->bt_switch), "notify::active", G_CALLBACK (bt_switch_changed), self); @@ -2509,24 +2527,22 @@ cc_power_panel_init (CcPowerPanel *self) priv->cancellable = g_cancellable_new (); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Power", - "/org/gnome/SettingsDaemon/Power", - "org.gnome.SettingsDaemon.Power.Screen", - priv->cancellable, - got_screen_proxy_cb, - self); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SettingsDaemon.Power", - "/org/gnome/SettingsDaemon/Power", - "org.gnome.SettingsDaemon.Power.Keyboard", - priv->cancellable, - got_kbd_proxy_cb, - self); + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Power", + "/org/gnome/SettingsDaemon/Power", + "org.gnome.SettingsDaemon.Power.Screen", + priv->cancellable, + got_screen_proxy_cb, + self); + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SettingsDaemon.Power", + "/org/gnome/SettingsDaemon/Power", + "org.gnome.SettingsDaemon.Power.Keyboard", + priv->cancellable, + got_kbd_proxy_cb, + self); priv->chassis_type = get_chassis_type (priv->cancellable); -- cgit v1.2.1 From 28ad1d1602d50bccd915cd44b114ca4ef6bba6c0 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:03:57 -0300 Subject: printers: Cache CUPS D-Bus proxy --- panels/printers/cc-printers-panel.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/panels/printers/cc-printers-panel.c b/panels/printers/cc-printers-panel.c index 55a1682b4..4815c4520 100644 --- a/panels/printers/cc-printers-panel.c +++ b/panels/printers/cc-printers-panel.c @@ -18,6 +18,8 @@ #include +#include "shell/cc-object-storage.h" + #include "cc-printers-panel.h" #include "cc-printers-resources.h" #include "pp-printer.h" @@ -608,14 +610,13 @@ attach_to_cups_notifier_cb (GObject *source_object, priv->subscription_renewal_id = g_timeout_add_seconds (RENEW_INTERVAL, renew_subscription, self); - priv->cups_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - 0, - NULL, - CUPS_DBUS_NAME, - CUPS_DBUS_PATH, - CUPS_DBUS_INTERFACE, - NULL, - &error); + priv->cups_proxy = cc_object_storage_create_dbus_proxy_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + CUPS_DBUS_NAME, + CUPS_DBUS_PATH, + CUPS_DBUS_INTERFACE, + NULL, + &error); if (!priv->cups_proxy) { -- cgit v1.2.1 From 754434fa0dab020046ff4a198ba259c3b6d6d7d5 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:04:28 -0300 Subject: privacy: Cache D-Bus proxies --- panels/privacy/cc-privacy-panel.c | 50 +++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/panels/privacy/cc-privacy-panel.c b/panels/privacy/cc-privacy-panel.c index 428dafef7..daa050a41 100644 --- a/panels/privacy/cc-privacy-panel.c +++ b/panels/privacy/cc-privacy-panel.c @@ -18,6 +18,7 @@ * Author: Matthias Clasen */ +#include "shell/cc-object-storage.h" #include "shell/list-box-helper.h" #include "cc-privacy-panel.h" #include "cc-privacy-resources.h" @@ -463,7 +464,7 @@ on_gclue_manager_ready (GObject *source_object, GDBusProxy *proxy; GError *error = NULL; - proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + proxy = cc_object_storage_create_dbus_proxy_finish (res, &error); if (proxy == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -475,10 +476,11 @@ on_gclue_manager_ready (GObject *source_object, self = user_data; self->priv->gclue_manager = proxy; - g_signal_connect (self->priv->gclue_manager, - "g-properties-changed", - G_CALLBACK (on_gclue_manager_props_changed), - self); + g_signal_connect_object (self->priv->gclue_manager, + "g-properties-changed", + G_CALLBACK (on_gclue_manager_props_changed), + self, + 0); update_location_label (self); } @@ -783,7 +785,7 @@ on_perm_store_ready (GObject *source_object, GVariant *params; GError *error = NULL; - proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + proxy = cc_object_storage_create_dbus_proxy_finish (res, &error); if (proxy == NULL) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -842,25 +844,23 @@ add_location (CcPrivacyPanel *self) g_free, g_object_unref); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.GeoClue2", - "/org/freedesktop/GeoClue2/Manager", - "org.freedesktop.GeoClue2.Manager", - priv->cancellable, - on_gclue_manager_ready, - self); - - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.impl.portal.PermissionStore", - "/org/freedesktop/impl/portal/PermissionStore", - "org.freedesktop.impl.portal.PermissionStore", - priv->cancellable, - on_perm_store_ready, - self); + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.GeoClue2", + "/org/freedesktop/GeoClue2/Manager", + "org.freedesktop.GeoClue2.Manager", + priv->cancellable, + on_gclue_manager_ready, + self); + + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.freedesktop.impl.portal.PermissionStore", + "/org/freedesktop/impl/portal/PermissionStore", + "org.freedesktop.impl.portal.PermissionStore", + priv->cancellable, + on_perm_store_ready, + self); } static void -- cgit v1.2.1 From 10dfbb526e102676016fb9af3d252f8559b7e125 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 27 Mar 2018 18:04:48 -0300 Subject: region: Cache D-Bus proxy --- panels/region/cc-region-panel.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/panels/region/cc-region-panel.c b/panels/region/cc-region-panel.c index 48c0d7ac0..232c3faad 100644 --- a/panels/region/cc-region-panel.c +++ b/panels/region/cc-region-panel.c @@ -26,6 +26,7 @@ #include #include +#include "shell/cc-object-storage.h" #include "shell/list-box-helper.h" #include "cc-region-panel.h" #include "cc-region-resources.h" @@ -1796,7 +1797,7 @@ session_proxy_ready (GObject *source, GDBusProxy *proxy; GError *error = NULL; - proxy = g_dbus_proxy_new_for_bus_finish (res, &error); + proxy = cc_object_storage_create_dbus_proxy_finish (res, &error); if (!proxy) { if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -1832,15 +1833,14 @@ cc_region_panel_init (CcRegionPanel *self) priv->cancellable = g_cancellable_new (); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.SessionManager", - "/org/gnome/SessionManager", - "org.gnome.SessionManager", - priv->cancellable, - session_proxy_ready, - self); + cc_object_storage_create_dbus_proxy (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SessionManager", + "/org/gnome/SessionManager", + "org.gnome.SessionManager", + priv->cancellable, + session_proxy_ready, + self); setup_login_button (self); setup_language_section (self); -- cgit v1.2.1 From 85296f1ebada9670702be7c4de5f6160b90a9470 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 28 Mar 2018 10:44:46 -0300 Subject: trivial: Code style improvements --- shell/cc-window.c | 51 +++++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/shell/cc-window.c b/shell/cc-window.c index 09f5721b1..fea3cf567 100644 --- a/shell/cc-window.c +++ b/shell/cc-window.c @@ -305,12 +305,15 @@ set_active_panel_from_id (CcShell *shell, GVariant *parameters, GError **error) { + g_autoptr(GIcon) gicon = NULL; + g_autofree gchar *name = NULL; GtkTreeIter iter; - gboolean iter_valid; - gchar *name = NULL; - GIcon *gicon = NULL; - CcWindow *self = CC_WINDOW (shell); GtkWidget *old_panel; + CcWindow *self; + gboolean iter_valid; + gboolean activated; + + self = CC_WINDOW (shell); /* When loading the same panel again, just set its parameters */ if (g_strcmp0 (self->current_panel_id, start_id) == 0) @@ -349,26 +352,25 @@ set_active_panel_from_id (CcShell *shell, if (!name) { g_warning ("Could not find settings panel \"%s\"", start_id); + return TRUE; } - else if (!activate_panel (CC_WINDOW (shell), start_id, parameters, name, gicon)) - { - /* Failed to activate the panel for some reason, - * let's keep the old panel around instead */ - } - else - { - /* Successful activation */ - g_free (self->current_panel_id); - self->current_panel_id = g_strdup (start_id); - if (old_panel) - gtk_container_remove (GTK_CONTAINER (self->stack), old_panel); + /* Activate the panel */ + activated = activate_panel (CC_WINDOW (shell), start_id, parameters, name, gicon); - cc_panel_list_set_active_panel (CC_PANEL_LIST (self->panel_list), start_id); - } + /* Failed to activate the panel for some reason, let's keep the old + * panel around instead */ + if (!activated) + return TRUE; + + /* Successful activation */ + g_free (self->current_panel_id); + self->current_panel_id = g_strdup (start_id); - g_clear_pointer (&name, g_free); - g_clear_object (&gicon); + if (old_panel) + gtk_container_remove (GTK_CONTAINER (self->stack), old_panel); + + cc_panel_list_set_active_panel (CC_PANEL_LIST (self->panel_list), start_id); return TRUE; } @@ -387,13 +389,10 @@ set_active_panel (CcWindow *shell, /* set the new panel */ if (panel) - { - shell->active_panel = g_object_ref (panel); - } + shell->active_panel = g_object_ref (panel); else - { - shell_show_overview_page (shell); - } + shell_show_overview_page (shell); + g_object_notify (G_OBJECT (shell), "active-panel"); } } -- cgit v1.2.1 From 1187f147af7a63583ff3acc62cf2cfe9fa7e8882 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Fri, 6 Apr 2018 23:18:26 -0300 Subject: log: Reimplement logging and debugging This commit replaces the old rudimentary log handler by a shinier version of it. It also introduces the debugging macros that I usually add to the apps, including the CC_TRACE_MSG() macro for tracing. --- meson.build | 8 ++ meson_options.txt | 1 + shell/cc-application.c | 6 +- shell/cc-debug.h.in | 229 +++++++++++++++++++++++++++++++++++++++++++++++++ shell/cc-log.c | 107 +++++++++++++++++++++++ shell/cc-log.h | 25 ++++++ shell/cc-shell-log.c | 62 ------------- shell/cc-shell-log.h | 32 ------- shell/meson.build | 13 ++- 9 files changed, 386 insertions(+), 97 deletions(-) create mode 100644 shell/cc-debug.h.in create mode 100644 shell/cc-log.c create mode 100644 shell/cc-log.h delete mode 100644 shell/cc-shell-log.c delete mode 100644 shell/cc-shell-log.h diff --git a/meson.build b/meson.build index 20aeb9fc1..dfc14f106 100644 --- a/meson.build +++ b/meson.build @@ -25,6 +25,9 @@ host_is_linux_not_s390 = host_is_linux and not host_machine.cpu().contains('s390 cc = meson.get_compiler('c') +# Tracing +enable_tracing = get_option('tracing') + config_h = configuration_data() # defines @@ -269,5 +272,10 @@ output += '** NetworkManager (Network panel): ' + host_is_linux.to_string() + '\ output += '** wacom (Wacom tablet panel): ' + host_is_linux_not_s390.to_string() + '\n' output += '** Wayland: ' + enable_wayland.to_string() + '\n' output += '** gnome-session libexecdir: ' + gnome_session_libexecdir + '\n' + +if enable_tracing + output += '** Tracing enabled \n' +endif + output += 'End options' message(output) diff --git a/meson_options.txt b/meson_options.txt index 7498af4d6..a01c11553 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -2,4 +2,5 @@ option('cheese', type: 'boolean', value: true, description: 'build with cheese w option('documentation', type: 'boolean', value: false, description: 'build documentation') option('gnome_session_libexecdir', type: 'string', value: '', description: 'Directory for gnome-session\'s libexecdir') option('ibus', type: 'boolean', value: true, description: 'build with IBus support') +option('tracing', type: 'boolean', value: false, description: 'add extra debugging information') option('wayland', type: 'boolean', value: true, description: 'build with Wayland support') diff --git a/shell/cc-application.c b/shell/cc-application.c index 144cbeeb6..3f828f3a6 100644 --- a/shell/cc-application.c +++ b/shell/cc-application.c @@ -26,9 +26,9 @@ #include #include "cc-application.h" +#include "cc-log.h" #include "cc-object-storage.h" #include "cc-panel-loader.h" -#include "cc-shell-log.h" #include "cc-window.h" #if defined(HAVE_WACOM) || defined(HAVE_CHEESE) @@ -158,7 +158,9 @@ cc_application_command_line (GApplication *application, options = g_application_command_line_get_options_dict (command_line); debug = g_variant_dict_contains (options, "verbose"); - cc_shell_log_set_debug (debug); + + if (debug) + cc_log_init (); gtk_window_present (GTK_WINDOW (self->window)); diff --git a/shell/cc-debug.h.in b/shell/cc-debug.h.in new file mode 100644 index 000000000..72962970d --- /dev/null +++ b/shell/cc-debug.h.in @@ -0,0 +1,229 @@ +/* cc-debug.h.in + * + * Copyright © 2018 Georges Basile Stavracas Neto + * + * 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 . + */ + +#pragma once + +#include + +/** + * SECTION:cc-debug + * @short_description: Debugging macros + * @title:Debugging + * @stability:stable + * + * Macros used for tracing and debugging code. These + * are only valid when Calendar is compiled with tracing + * suppoer (pass `--enable-tracing` to the configure + * script to do that). + */ + +G_BEGIN_DECLS + +#ifndef CC_ENABLE_TRACE +# define CC_ENABLE_TRACE @ENABLE_TRACING@ +#endif +#if CC_ENABLE_TRACE != 1 +# undef CC_ENABLE_TRACE +#endif + +/** + * CC_LOG_LEVEL_TRACE: (skip) + */ +#ifndef CC_LOG_LEVEL_TRACE +# define CC_LOG_LEVEL_TRACE ((GLogLevelFlags)(1 << G_LOG_LEVEL_USER_SHIFT)) +#endif + +#ifdef CC_ENABLE_TRACE + +/** + * CC_TRACE_MSG: + * @fmt: printf-like format of the message + * @...: arguments for @fmt + * + * Prints a trace message. + */ +# define CC_TRACE_MSG(fmt, ...) \ + g_log(G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, " MSG: %s():%d: " fmt, \ + G_STRFUNC, __LINE__, ##__VA_ARGS__) + +/** + * CC_PROBE: + * + * Prints a probing message. Put this macro in the code when + * you want to check the program reaches a certain section + * of code. + */ +# define CC_PROBE \ + g_log(G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, "PROBE: %s():%d", \ + G_STRFUNC, __LINE__) + +/** + * CC_TODO: + * @_msg: the message to print + * + * Prints a TODO message. + */ +# define CC_TODO(_msg) \ + g_log(G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, " TODO: %s():%d: %s", \ + G_STRFUNC, __LINE__, _msg) + +/** + * CC_ENTRY: + * + * Prints an entry message. This shouldn't be used in + * critical functions. Place this at the beggining of + * the function, before any assertion. + */ +# define CC_ENTRY \ + g_log(G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, "ENTRY: %s():%d", \ + G_STRFUNC, __LINE__) + +/** + * CC_EXIT: + * + * Prints an exit message. This shouldn't be used in + * critical functions. Place this at the end of + * the function, after any relevant code. If the + * function returns something, use CC_RETURN() + * instead. + */ +# define CC_EXIT \ + G_STMT_START { \ + g_log(G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, " EXIT: %s():%d", \ + G_STRFUNC, __LINE__); \ + return; \ + } G_STMT_END + +/** + * CC_GOTO: + * @_l: goto tag + * + * Logs a goto jump. + */ +# define CC_GOTO(_l) \ + G_STMT_START { \ + g_log(G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, " GOTO: %s():%d ("#_l")",\ + G_STRFUNC, __LINE__); \ + goto _l; \ + } G_STMT_END + +/** + * CC_RETURN: + * @_r: the return value. + * + * Prints an exit message, and returns @_r. See #CC_EXIT. + */ +# define CC_RETURN(_r) \ + G_STMT_START { \ + g_log(G_LOG_DOMAIN, CC_LOG_LEVEL_TRACE, " EXIT: %s():%d ", \ + G_STRFUNC, __LINE__); \ + return _r; \ + } G_STMT_END + +#else + +/** + * CC_TODO: + * @_msg: the message to print + * + * Prints a TODO message. + */ +# define CC_TODO(_msg) + +/** + * CC_PROBE: + * + * Prints a probing message. + */ +# define CC_PROBE + +/** + * CC_TRACE_MSG: + * @fmt: printf-like format of the message + * @...: arguments for @fmt + * + * Prints a trace message. + */ +# define CC_TRACE_MSG(fmt, ...) + +/** + * CC_ENTRY: + * + * Prints a probing message. This shouldn't be used in + * critical functions. Place this at the beggining of + * the function, before any assertion. + */ +# define CC_ENTRY + +/** + * CC_GOTO: + * @_l: goto tag + * + * Logs a goto jump. + */ +# define CC_GOTO(_l) goto _l + +/** + * CC_EXIT: + * + * Prints an exit message. This shouldn't be used in + * critical functions. Place this at the end of + * the function, after any relevant code. If the + * function returns somethin, use CC_RETURN() + * instead. + */ +# define CC_EXIT return + +/** + * CC_RETURN: + * @_r: the return value. + * + * Prints an exit message, and returns @_r. See #CC_EXIT. + */ +# define CC_RETURN(_r) return _r +#endif + +/** + * _CC_BUG: (skip) + */ +#define _CC_BUG(Component, Description, File, Line, Func, ...) \ + G_STMT_START { \ + g_printerr ("-----------------------------------------------------------------\n"); \ + g_printerr ("You've found a bug in Calendar or one of its dependent libraries.\n"); \ + g_printerr ("Please help us help you by filing a bug report at:\n"); \ + g_printerr ("\n"); \ + g_printerr ("@BUGREPORT_URL@&component=%s\n", Component); \ + g_printerr ("\n"); \ + g_printerr ("%s:%d in function %s()\n", File, Line, Func); \ + g_printerr ("\n"); \ + g_printerr (Description"\n", ##__VA_ARGS__); \ + g_printerr ("-----------------------------------------------------------------\n"); \ + } G_STMT_END + +/** + * CC_BUG: + * @Component: the component + * @Description: the description + * @...: extra arguments + * + * Logs a bug-friendly message. + */ +#define CC_BUG(Component, Description, ...) \ + _CC_BUG(Component, Description, __FILE__, __LINE__, G_STRFUNC, ##__VA_ARGS__) + +G_END_DECLS diff --git a/shell/cc-log.c b/shell/cc-log.c new file mode 100644 index 000000000..5f6645cbe --- /dev/null +++ b/shell/cc-log.c @@ -0,0 +1,107 @@ +/* cc-shell-log.c + * + * Copyright © 2018 Georges Basile Stavracas Neto + * + * 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 "cc-debug.h" +#include "cc-log.h" + +#include +#include + +G_LOCK_DEFINE_STATIC (channel_lock); + +GIOChannel *standard_channel = NULL; + +static const gchar* ignored_domains[] = +{ + "GdkPixbuf", + NULL +}; + +static const gchar * +log_level_str (GLogLevelFlags log_level) +{ + switch (((gulong)log_level & G_LOG_LEVEL_MASK)) + { + case G_LOG_LEVEL_ERROR: return " \033[1;31mERROR\033[0m"; + case G_LOG_LEVEL_CRITICAL: return "\033[1;35mCRITICAL\033[0m"; + case G_LOG_LEVEL_WARNING: return " \033[1;33mWARNING\033[0m"; + case G_LOG_LEVEL_MESSAGE: return " \033[1;34mMESSAGE\033[0m"; + case G_LOG_LEVEL_INFO: return " \033[1;32mINFO\033[0m"; + case G_LOG_LEVEL_DEBUG: return " \033[1;32mDEBUG\033[0m"; + case CC_LOG_LEVEL_TRACE: return " \033[1;36mTRACE\033[0m"; + default: return " UNKNOWN"; + } +} + +static void +log_handler (const gchar *domain, + GLogLevelFlags log_level, + const gchar *message, + gpointer user_data) +{ + GTimeVal tv; + struct tm tt; + time_t t; + const gchar *level; + gchar ftime[32]; + gchar *buffer; + + /* Skip ignored log domains */ + if (domain && g_strv_contains (ignored_domains, domain)) + return; + + level = log_level_str (log_level); + g_get_current_time (&tv); + t = (time_t) tv.tv_sec; + tt = *localtime (&t); + strftime (ftime, sizeof (ftime), "%H:%M:%S", &tt); + buffer = g_strdup_printf ("%s.%04ld %24s: %s: %s\n", + ftime, + tv.tv_usec / 1000, + domain, + level, + message); + + /* Safely write to the channel */ + G_LOCK (channel_lock); + + g_io_channel_write_chars (standard_channel, buffer, -1, NULL, NULL); + g_io_channel_flush (standard_channel, NULL); + + G_UNLOCK (channel_lock); + + g_free (buffer); +} + +void +cc_log_init (void) +{ + static gsize initialized = FALSE; + + if (g_once_init_enter (&initialized)) + { + standard_channel = g_io_channel_unix_new (STDOUT_FILENO); + + g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); + + g_log_set_default_handler (log_handler, NULL); + + g_once_init_leave (&initialized, TRUE); + } +} + diff --git a/shell/cc-log.h b/shell/cc-log.h new file mode 100644 index 000000000..2d04c0ba7 --- /dev/null +++ b/shell/cc-log.h @@ -0,0 +1,25 @@ +/* cc-log.h + * + * Copyright © 2018 Georges Basile Stavracas Neto + * + * 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 . + */ + +#pragma once + +G_BEGIN_DECLS + +void cc_log_init (void); + +G_END_DECLS diff --git a/shell/cc-shell-log.c b/shell/cc-shell-log.c deleted file mode 100644 index 14a122722..000000000 --- a/shell/cc-shell-log.c +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2009 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - */ - - -#include "config.h" - -#include -#include - -#include "cc-shell-log.h" - -static int log_levels = G_LOG_LEVEL_CRITICAL | - G_LOG_LEVEL_ERROR | - G_LOG_LEVEL_WARNING | - G_LOG_LEVEL_MESSAGE | - G_LOG_LEVEL_INFO | - G_LOG_LEVEL_DEBUG; - -static void -cc_shell_log_default_handler (const gchar *log_domain, - GLogLevelFlags log_level, - const gchar *message, - gpointer unused_data) -{ - if ((log_level & log_levels) == 0) - return; - - g_log_default_handler (log_domain, log_level, message, unused_data); -} - -void -cc_shell_log_init (void) -{ - g_log_set_default_handler (cc_shell_log_default_handler, NULL); -} - -void -cc_shell_log_set_debug (gboolean debug) -{ - - if (debug) { - g_setenv ("G_MESSAGES_DEBUG", "all", TRUE); - log_levels |= (G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_INFO); - g_debug ("Enabling debugging"); - } -} diff --git a/shell/cc-shell-log.h b/shell/cc-shell-log.h deleted file mode 100644 index 132a19dcf..000000000 --- a/shell/cc-shell-log.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2009 Red Hat, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - */ - -#ifndef __CC_SHELL_LOG_H -#define __CC_SHELL_LOG_H - -#include - -G_BEGIN_DECLS - -void cc_shell_log_init (void); -void cc_shell_log_set_debug (gboolean debug); - -G_END_DECLS - -#endif /* __CC_SHELL_LOG_H */ diff --git a/shell/meson.build b/shell/meson.build index 0946ada74..62270358c 100644 --- a/shell/meson.build +++ b/shell/meson.build @@ -46,12 +46,12 @@ common_sources = files( 'cc-application.c', 'cc-editable-entry.c', 'cc-hostname-entry.c', + 'cc-log.c', 'cc-object-storage.c', 'cc-panel-loader.c', 'cc-panel.c', 'cc-shell-category-view.c', 'cc-shell-item-view.c', - 'cc-shell-log.c', 'cc-shell.c', 'hostname-helper.c', 'list-box-helper.c', @@ -91,6 +91,17 @@ if host_is_linux_not_s390 shell_deps += wacom_deps endif +# Debug +debug_conf = configuration_data() +debug_conf.set('BUGREPORT_URL', 'http://bugzilla.gnome.org/enter_bug.cgi?product=' + meson.project_name()) +debug_conf.set10('ENABLE_TRACING', enable_tracing) + +sources += configure_file( + input: 'cc-debug.h.in', + output: 'cc-debug.h', + configuration: debug_conf +) + executable( meson.project_name(), sources, -- cgit v1.2.1 From 4571a38004ea265e6798d6a97615fcf0a7677165 Mon Sep 17 00:00:00 2001 From: Changwoo Ryu Date: Sat, 7 Apr 2018 04:38:36 +0000 Subject: Update Korean translation (cherry picked from commit c1861239916c1cff3626c9345574d0a7d5d79c54) --- po/ko.po | 492 +++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 260 insertions(+), 232 deletions(-) diff --git a/po/ko.po b/po/ko.po index cf0b89665..49d9c2f84 100644 --- a/po/ko.po +++ b/po/ko.po @@ -29,8 +29,8 @@ msgstr "" "Project-Id-Version: gnome-control-center\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-control-center/" "issues\n" -"POT-Creation-Date: 2018-02-20 09:14+0000\n" -"PO-Revision-Date: 2018-02-22 16:34+0900\n" +"POT-Creation-Date: 2018-03-26 22:21+0000\n" +"PO-Revision-Date: 2018-04-06 17:53+0900\n" "Last-Translator: Changwoo Ryu \n" "Language-Team: GNOME Korea \n" "Language: ko\n" @@ -124,12 +124,12 @@ msgstr "이미지 파일을 %s 폴더에 놓으면 여기 나타납니다" #: panels/background/cc-background-chooser-dialog.c:560 #: panels/color/cc-color-panel.c:225 panels/color/cc-color-panel.c:963 #: panels/color/color-calibrate.ui:25 panels/color/color.ui:657 -#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2594 +#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2597 #: panels/network/connection-editor/connection-editor.ui:15 #: panels/network/connection-editor/vpn-helpers.c:181 #: panels/network/connection-editor/vpn-helpers.c:310 -#: panels/network/net-device-wifi.c:1371 panels/network/net-device-wifi.c:1451 -#: panels/network/net-device-wifi.c:1690 panels/network/network-wifi.ui:24 +#: panels/network/net-device-wifi.c:1411 panels/network/net-device-wifi.c:1491 +#: panels/network/net-device-wifi.c:1736 panels/network/network-wifi.ui:24 #: panels/printers/new-printer-dialog.ui:45 #: panels/printers/pp-details-dialog.c:331 #: panels/privacy/cc-privacy-panel.c:1053 panels/region/format-chooser.ui:25 @@ -140,10 +140,10 @@ msgstr "이미지 파일을 %s 폴더에 놓으면 여기 나타납니다" #: panels/user-accounts/data/join-dialog.ui:20 #: panels/user-accounts/data/password-dialog.ui:21 #: panels/user-accounts/um-fingerprint-dialog.c:261 -#: panels/user-accounts/um-photo-dialog.c:102 -#: panels/user-accounts/um-photo-dialog.c:229 -#: panels/user-accounts/um-user-panel.c:635 -#: panels/user-accounts/um-user-panel.c:653 +#: panels/user-accounts/um-photo-dialog.c:103 +#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-user-panel.c:634 +#: panels/user-accounts/um-user-panel.c:652 msgid "_Cancel" msgstr "취소(_C)" @@ -178,12 +178,13 @@ msgstr "배경" msgid "Change your background image to a wallpaper or photo" msgstr "배경을 이미지나 사진으로 바꿉니다" -#: panels/background/gnome-background-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/background/gnome-background-panel.desktop.in.in:7 msgid "preferences-desktop-wallpaper" msgstr "preferences-desktop-wallpaper" -#. Translators: those are keywords for the background control-center panel -#: panels/background/gnome-background-panel.desktop.in.in:14 +#. Translators: Search terms to find the Background panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/background/gnome-background-panel.desktop.in.in:15 msgid "Wallpaper;Screen;Desktop;" msgstr "Wallpaper;배경;Screen;화면;Desktop;바탕 화면;" @@ -233,12 +234,13 @@ msgstr "블루투스" msgid "Turn Bluetooth on and off and connect your devices" msgstr "블루투스를 켜거나 끄고 블루투스 장치에 연결합니다" -#: panels/bluetooth/gnome-bluetooth-panel.desktop.in.in:5 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/bluetooth/gnome-bluetooth-panel.desktop.in.in:6 msgid "bluetooth" -msgstr "블루투스" +msgstr "bluetooth" -#. Translators: those are keywords for the bluetooth control-center panel -#: panels/bluetooth/gnome-bluetooth-panel.desktop.in.in:18 +#. Translators: Search terms to find the Bluetooth panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/bluetooth/gnome-bluetooth-panel.desktop.in.in:19 msgid "share;sharing;bluetooth;obex;" msgstr "share;sharing;공유;bluetooth;블루투스;obex;" @@ -873,12 +875,13 @@ msgid "" "Calibrate the color of your devices, such as displays, cameras or printers" msgstr "디스플레이, 카메라, 프린터같은 장치의 색을 보정합니다" -#: panels/color/gnome-color-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/color/gnome-color-panel.desktop.in.in:7 msgid "preferences-color" msgstr "preferences-color" -#. Translators: those are keywords for the color control-center panel -#: panels/color/gnome-color-panel.desktop.in.in:18 +#. Translators: Search terms to find the Color panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/color/gnome-color-panel.desktop.in.in:19 msgid "Color;ICC;Profile;Calibrate;Printer;Display;" msgstr "" "Color;색;ICC;Profile;프로파일;Calibrate;보정;Printer;프린터;Display;디스플레" @@ -1096,12 +1099,13 @@ msgstr "오전 / 오후" msgid "Change the date and time, including time zone" msgstr "날짜와 시각(표준 시간대 포함)을 바꿉니다" -#: panels/datetime/gnome-datetime-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/datetime/gnome-datetime-panel.desktop.in.in:7 msgid "preferences-system-time" msgstr "preferences-system-time" -#. Translators: those are keywords for the date and time control-center panel -#: panels/datetime/gnome-datetime-panel.desktop.in.in:14 +#. Translators: Search terms to find the Date and Time panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/datetime/gnome-datetime-panel.desktop.in.in:15 msgid "Clock;Timezone;Location;" msgstr "Clock;시계;Timezone;시간대;Location;위치;" @@ -1113,58 +1117,58 @@ msgstr "시스템의 날짜와 시간 설정을 바꿉니다" msgid "To change time or date settings, you need to authenticate." msgstr "시간 또는 날짜 설정을 바꾸려면 인증이 필요합니다." -#: panels/display/cc-display-panel.c:729 +#: panels/display/cc-display-panel.c:732 msgctxt "Display rotation" msgid "Landscape" msgstr "가로" -#: panels/display/cc-display-panel.c:732 +#: panels/display/cc-display-panel.c:735 msgctxt "Display rotation" msgid "Portrait Right" msgstr "세로 오른쪽" -#: panels/display/cc-display-panel.c:735 +#: panels/display/cc-display-panel.c:738 msgctxt "Display rotation" msgid "Portrait Left" msgstr "세로 왼쪽" -#: panels/display/cc-display-panel.c:738 +#: panels/display/cc-display-panel.c:741 msgctxt "Display rotation" msgid "Landscape (flipped)" msgstr "가로 (뒤집힘)" #. Translators: This option sets orientation of print (portrait, landscape...) -#: panels/display/cc-display-panel.c:805 +#: panels/display/cc-display-panel.c:808 #: panels/printers/pp-options-dialog.c:558 msgid "Orientation" msgstr "방향" -#: panels/display/cc-display-panel.c:870 panels/display/cc-display-panel.c:1673 +#: panels/display/cc-display-panel.c:873 panels/display/cc-display-panel.c:1676 #: panels/printers/pp-options-dialog.c:87 msgid "Resolution" msgstr "해상도" -#: panels/display/cc-display-panel.c:958 +#: panels/display/cc-display-panel.c:961 msgid "Refresh Rate" msgstr "주사율" -#: panels/display/cc-display-panel.c:1095 +#: panels/display/cc-display-panel.c:1098 msgid "Scale" msgstr "크기 조정" -#: panels/display/cc-display-panel.c:1148 +#: panels/display/cc-display-panel.c:1151 msgid "Adjust for TV" msgstr "TV에 맞게 조정" -#: panels/display/cc-display-panel.c:1410 +#: panels/display/cc-display-panel.c:1413 msgid "Primary Display" msgstr "주요 디스플레이" -#: panels/display/cc-display-panel.c:1439 +#: panels/display/cc-display-panel.c:1442 msgid "Display Arrangement" msgstr "디스플레이 배치" -#: panels/display/cc-display-panel.c:1440 +#: panels/display/cc-display-panel.c:1443 msgid "" "Drag displays to match your setup. The top bar is placed on the primary " "display." @@ -1172,41 +1176,41 @@ msgstr "" "설정에 맞는 디스플레이를 끌어 놓으십시오. 화면 위 표시 막대는 주요 디스플레이" "에서 표시됩니다." -#: panels/display/cc-display-panel.c:1863 +#: panels/display/cc-display-panel.c:1866 msgid "Display Mode" msgstr "디스플레이 모드" -#: panels/display/cc-display-panel.c:1879 +#: panels/display/cc-display-panel.c:1882 msgid "Join Displays" msgstr "디스플레이 연결" -#: panels/display/cc-display-panel.c:1882 +#: panels/display/cc-display-panel.c:1885 msgid "Mirror" msgstr "동일 화면" -#: panels/display/cc-display-panel.c:1885 +#: panels/display/cc-display-panel.c:1888 msgid "Single Display" msgstr "단일 디스플레이" -#: panels/display/cc-display-panel.c:2590 +#: panels/display/cc-display-panel.c:2593 msgid "Apply Changes?" msgstr "변경 사항을 적용하시겠습니까?" -#: panels/display/cc-display-panel.c:2604 +#: panels/display/cc-display-panel.c:2607 #: panels/network/connection-editor/connection-editor.ui:24 #: panels/network/network-wifi.ui:38 msgid "_Apply" msgstr "적용(_A)" -#: panels/display/cc-display-panel.c:2979 +#: panels/display/cc-display-panel.c:2982 #, c-format msgid "%.2lf Hz" msgstr "%.2lf Hz" #. TRANSLATORS: the state of the night light setting -#: panels/display/cc-display-panel.c:3195 +#: panels/display/cc-display-panel.c:3198 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1988 panels/power/cc-power-panel.c:1995 +#: panels/power/cc-power-panel.c:1994 panels/power/cc-power-panel.c:2001 #: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 #: panels/universal-access/cc-ua-panel.c:333 #: panels/universal-access/cc-ua-panel.c:714 @@ -1216,9 +1220,9 @@ msgstr "%.2lf Hz" msgid "On" msgstr "켬" -#: panels/display/cc-display-panel.c:3195 panels/network/net-proxy.c:54 +#: panels/display/cc-display-panel.c:3198 panels/network/net-proxy.c:54 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1982 panels/power/cc-power-panel.c:1993 +#: panels/power/cc-power-panel.c:1988 panels/power/cc-power-panel.c:1999 #: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 #: panels/universal-access/cc-ua-panel.c:333 #: panels/universal-access/cc-ua-panel.c:714 @@ -1232,11 +1236,11 @@ msgstr "켬" msgid "Off" msgstr "끔" -#: panels/display/cc-display-panel.c:3216 +#: panels/display/cc-display-panel.c:3219 msgid "_Night Light" msgstr "야간 모드(_N)" -#: panels/display/cc-display-panel.c:3281 +#: panels/display/cc-display-panel.c:3284 msgid "Could not get screen information" msgstr "화면 정보를 읽어 올 수 없습니다" @@ -1310,12 +1314,13 @@ msgstr "디스플레이" msgid "Choose how to use connected monitors and projectors" msgstr "연결한 모니터와 프로젝터 사용법을 정합니다" -#: panels/display/gnome-display-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/display/gnome-display-panel.desktop.in.in:7 msgid "preferences-desktop-display" msgstr "preferences-desktop-display" -#. Translators: those are keywords for the display control-center panel -#: panels/display/gnome-display-panel.desktop.in.in:18 +#. Translators: Search terms to find the Displays panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/display/gnome-display-panel.desktop.in.in:19 msgid "" "Panel;Projector;xrandr;Screen;Resolution;Refresh;Monitor;Night;Light;Blue;" "redshift;color;sunset;sunrise;" @@ -1453,12 +1458,13 @@ msgstr "기본 프로그램" msgid "Configure Default Applications" msgstr "기본 프로그램 설정" -#: panels/info/gnome-default-apps-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/info/gnome-default-apps-panel.desktop.in.in:7 msgid "starred" msgstr "starred" -#. Translators: those are keywords for the Default Applications panel -#: panels/info/gnome-default-apps-panel.desktop.in.in:18 +#. Translators: Search terms to find the Default Applications panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/info/gnome-default-apps-panel.desktop.in.in:19 msgid "default;application;preferred;media;" msgstr "" "default;기본;기본값;application;프로그램;앱;애플리케이션;preferred;media;미디" @@ -1472,14 +1478,17 @@ msgstr "정보" msgid "View information about your system" msgstr "시스템의 정보를 봅니다" -#: panels/info/gnome-info-overview-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/info/gnome-info-overview-panel.desktop.in.in:7 msgid "help-about" msgstr "help-about" -#. Translators: those are keywords for the System Information panel +#. Translators: Search terms to find the About panel. +#. Do NOT translate or localize the semicolons! +#. The list MUST also end with a semicolon! #. "Preferred Applications" is the old name for the preference, so make #. sure that you use the same "translation" for those keywords -#: panels/info/gnome-info-overview-panel.desktop.in.in:20 +#: panels/info/gnome-info-overview-panel.desktop.in.in:23 msgid "" "device;system;information;memory;processor;version;default;application;" "preferred;cd;dvd;usb;audio;video;disc;removable;media;autorun;" @@ -1497,12 +1506,13 @@ msgstr "이동식 미디어" msgid "Configure Removable Media settings" msgstr "이동식 미디어 설정" -#: panels/info/gnome-removable-media-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/info/gnome-removable-media-panel.desktop.in.in:7 msgid "media-removable" msgstr "media-removable" -#. Translators: those are keywords for the Removable Media panel -#: panels/info/gnome-removable-media-panel.desktop.in.in:18 +#. Translators: Search terms to find the Removable Media panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/info/gnome-removable-media-panel.desktop.in.in:19 msgid "" "device;system;default;application;preferred;cd;dvd;usb;audio;video;disc;" "removable;media;autorun;" @@ -1681,8 +1691,8 @@ msgstr "실행 아이콘" msgid "Launch help browser" msgstr "도움말 보기 실행" -#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:223 -#: shell/cc-window.c:761 shell/gnome-control-center.desktop.in.in:3 +#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:222 +#: shell/cc-window.c:760 shell/gnome-control-center.desktop.in.in:3 #: shell/window.ui:125 msgid "Settings" msgstr "설정" @@ -1891,12 +1901,13 @@ msgstr "키보드" msgid "View and change keyboard shortcuts and set your typing preferences" msgstr "키보드 바로 가기를 보거나 바꾸고 키보드 타이핑을 설정합니다" -#: panels/keyboard/gnome-keyboard-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/keyboard/gnome-keyboard-panel.desktop.in.in:7 msgid "input-keyboard" msgstr "input-keyboard" -#. Translators: those are keywords for the keyboard control-center panel -#: panels/keyboard/gnome-keyboard-panel.desktop.in.in:18 +#. Translators: Search terms to find the Keyboard panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/keyboard/gnome-keyboard-panel.desktop.in.in:19 msgid "" "Shortcut;Workspace;Window;Resize;Zoom;Contrast;Input;Source;Lock;Volume;" msgstr "" @@ -1927,9 +1938,7 @@ msgstr "다르게 검색해 보십시오" #: panels/keyboard/shortcut-editor.ui:68 panels/keyboard/shortcut-editor.ui:318 msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "" -"키보드 바로가기 입력에서 Esc를 누르면 취소하고, 백스페이스를 누르면 초기화합" -"니다." +msgstr "키보드 바로 가기 입력에서 Esc를 누르면 취소하고, 백스페이스를 누르면 초기화합니다." #: panels/keyboard/shortcut-editor.ui:156 panels/printers/details-dialog.ui:38 #: panels/sound/gvc-mixer-dialog.c:1480 @@ -1987,12 +1996,13 @@ msgid "" msgstr "" "마우스 및 터치패드 민감도를 바꾸고 오른손잡이용인지 왼손잡이용인지 설정합니다" -#: panels/mouse/gnome-mouse-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/mouse/gnome-mouse-panel.desktop.in.in:7 msgid "input-mouse" msgstr "input-mouse" -#. Translators: those are keywords for the mouse and touchpad control-center panel -#: panels/mouse/gnome-mouse-panel.desktop.in.in:18 +#. Translators: Search terms to find the Mouse and Touchpad panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/mouse/gnome-mouse-panel.desktop.in.in:19 msgid "Trackpad;Pointer;Click;Tap;Double;Button;Trackball;Scroll;" msgstr "" "Trackpad;트랙패드;Pointer;포인터;Click;클릭;누르기;Tap;두드리기;Double;더블;" @@ -2105,8 +2115,8 @@ msgstr "네트워크 프록시" #. * window for vpn connections, it is also used to display #. * vpn connections in the device list. #. -#: panels/network/cc-network-panel.c:715 panels/network/net-vpn.c:192 -#: panels/network/net-vpn.c:321 +#: panels/network/cc-network-panel.c:715 panels/network/net-vpn.c:167 +#: panels/network/net-vpn.c:296 #, c-format msgid "%s VPN" msgstr "%s VPN(가상사설망)" @@ -2119,9 +2129,9 @@ msgstr "앗, 뭔가 잘못됐습니다. 소프트웨어 공급자에게 연락 msgid "NetworkManager needs to be running." msgstr "NetworkManager가 동작해야 합니다." -#: panels/network/cc-wifi-panel.c:212 +#: panels/network/cc-wifi-panel.c:213 #: panels/network/gnome-wifi-panel.desktop.in.in:3 -#: panels/network/network-wifi.ui:1766 +#: panels/network/network-wifi.ui:1769 msgid "Wi-Fi" msgstr "와이파이" @@ -2172,31 +2182,31 @@ msgstr "프로파일 %d" #. TRANSLATORS: this WEP WiFi security #: panels/network/connection-editor/ce-page-details.c:56 -#: panels/network/net-device-wifi.c:231 panels/network/net-device-wifi.c:453 +#: panels/network/net-device-wifi.c:235 panels/network/net-device-wifi.c:468 msgid "WEP" msgstr "WEP" #. TRANSLATORS: this WPA WiFi security #: panels/network/connection-editor/ce-page-details.c:60 -#: panels/network/net-device-wifi.c:235 panels/network/net-device-wifi.c:458 +#: panels/network/net-device-wifi.c:239 panels/network/net-device-wifi.c:473 #: panels/network/network-wifi.ui:593 msgid "WPA" msgstr "WPA" #. TRANSLATORS: this WPA WiFi security #: panels/network/connection-editor/ce-page-details.c:64 -#: panels/network/net-device-wifi.c:239 +#: panels/network/net-device-wifi.c:243 msgid "WPA2" msgstr "WPA2" #. TRANSLATORS: this Enterprise WiFi security #: panels/network/connection-editor/ce-page-details.c:69 -#: panels/network/net-device-wifi.c:244 +#: panels/network/net-device-wifi.c:248 msgid "Enterprise" msgstr "기업용" #: panels/network/connection-editor/ce-page-details.c:74 -#: panels/network/net-device-wifi.c:249 panels/network/net-device-wifi.c:443 +#: panels/network/net-device-wifi.c:253 panels/network/net-device-wifi.c:458 msgctxt "Wifi security" msgid "None" msgstr "없음" @@ -2208,7 +2218,7 @@ msgstr "안 함" #: panels/network/connection-editor/ce-page-details.c:110 #: panels/network/net-device-ethernet.c:121 -#: panels/network/net-device-wifi.c:552 +#: panels/network/net-device-wifi.c:567 #, c-format msgid "%i day ago" msgid_plural "%i days ago" @@ -2216,37 +2226,37 @@ msgstr[0] " %i일 전" #. Translators: network device speed #: panels/network/connection-editor/ce-page-details.c:225 -#: panels/network/net-device-ethernet.c:50 panels/network/net-device-wifi.c:608 +#: panels/network/net-device-ethernet.c:50 panels/network/net-device-wifi.c:646 #, c-format msgid "%d Mb/s" msgstr "%d Mb/s" #: panels/network/connection-editor/ce-page-details.c:251 -#: panels/network/net-device-wifi.c:637 +#: panels/network/net-device-wifi.c:675 msgctxt "Signal strength" msgid "None" msgstr "없음" #: panels/network/connection-editor/ce-page-details.c:253 -#: panels/network/net-device-wifi.c:639 +#: panels/network/net-device-wifi.c:677 msgctxt "Signal strength" msgid "Weak" msgstr "약함" #: panels/network/connection-editor/ce-page-details.c:255 -#: panels/network/net-device-wifi.c:641 +#: panels/network/net-device-wifi.c:679 msgctxt "Signal strength" msgid "Ok" msgstr "좋음" #: panels/network/connection-editor/ce-page-details.c:257 -#: panels/network/net-device-wifi.c:643 +#: panels/network/net-device-wifi.c:681 msgctxt "Signal strength" msgid "Good" msgstr "좋음" #: panels/network/connection-editor/ce-page-details.c:259 -#: panels/network/net-device-wifi.c:645 +#: panels/network/net-device-wifi.c:683 msgctxt "Signal strength" msgid "Excellent" msgstr "최상" @@ -2264,7 +2274,7 @@ msgid "Remove VPN" msgstr "VPN(가상사설망) 제거" #: panels/network/connection-editor/ce-page-details.c:334 -#: panels/network/network-wifi.ui:1456 shell/cc-window.c:215 +#: panels/network/network-wifi.ui:1456 shell/cc-window.c:214 #: shell/panel-list.ui:103 msgid "Details" msgstr "자세히 보기" @@ -2601,7 +2611,7 @@ msgstr "가져올 파일을 선택하십시오" #: panels/network/connection-editor/vpn-helpers.c:182 #: panels/printers/pp-details-dialog.c:332 #: panels/sharing/cc-sharing-panel.c:385 -#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-photo-dialog.c:231 msgid "_Open" msgstr "열기(_O)" @@ -2666,12 +2676,13 @@ msgstr "네트워크" msgid "Control how you connect to the Internet" msgstr "어떻게 인터넷에 연결할지 정합니다" -#: panels/network/gnome-network-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/network/gnome-network-panel.desktop.in.in:7 msgid "network-workgroup" msgstr "network-workgroup" -#. Translators: those are keywords for the network control-center panel -#: panels/network/gnome-network-panel.desktop.in.in:18 +#. Translators: Search terms to find the Network panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/network/gnome-network-panel.desktop.in.in:19 msgid "" "Network;Wireless;Wi-Fi;Wifi;IP;LAN;Proxy;WAN;Broadband;Modem;Bluetooth;vpn;" "DNS;" @@ -2684,12 +2695,13 @@ msgstr "" msgid "Control how you connect to Wi-Fi networks" msgstr "어떻게 와이파이 네트워크에 연결할지 정합니다" -#: panels/network/gnome-wifi-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/network/gnome-wifi-panel.desktop.in.in:7 msgid "network-wireless" msgstr "network-wireless" -#. Translators: those are keywords for the wi-fi control-center panel -#: panels/network/gnome-wifi-panel.desktop.in.in:18 +#. Translators: Search terms to find the Wi-Fi panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/network/gnome-wifi-panel.desktop.in.in:19 msgid "Network;Wireless;Wi-Fi;Wifi;IP;LAN;Broadband;DNS;" msgstr "" "Network;네트워크;Wireless;무선;Wi-Fi;Wifi;와이파이;IP;LAN;랜;Proxy;프록시;" @@ -2697,17 +2709,17 @@ msgstr "" "망;;DNS;네임서버;" #: panels/network/net-device-ethernet.c:107 -#: panels/network/net-device-wifi.c:538 +#: panels/network/net-device-wifi.c:553 msgid "never" msgstr "안 함" #: panels/network/net-device-ethernet.c:117 -#: panels/network/net-device-wifi.c:548 +#: panels/network/net-device-wifi.c:563 msgid "today" msgstr "오늘" #: panels/network/net-device-ethernet.c:119 -#: panels/network/net-device-wifi.c:550 +#: panels/network/net-device-wifi.c:565 msgid "yesterday" msgstr "어제" @@ -2732,7 +2744,7 @@ msgid "Wired" msgstr "유선" #: panels/network/net-device-ethernet.c:344 -#: panels/network/net-device-wifi.c:1849 panels/network/network-ethernet.ui:120 +#: panels/network/net-device-wifi.c:1895 panels/network/network-ethernet.ui:120 #: panels/network/network-mobile.ui:394 panels/network/network-simple.ui:75 #: panels/network/network-vpn.ui:79 msgid "Options…" @@ -2742,64 +2754,64 @@ msgstr "옵션…" msgid "Add new connection" msgstr "새 연결 추가" -#: panels/network/net-device-wifi.c:1328 +#: panels/network/net-device-wifi.c:1368 #, c-format msgid "Switching on the wireless hotspot will disconnect you from %s." msgstr "무선 핫스팟을 전환하면 %s의 연결이 끊어집니다." -#: panels/network/net-device-wifi.c:1332 +#: panels/network/net-device-wifi.c:1372 msgid "" "It is not possible to access the Internet through your wireless while the " "hotspot is active." msgstr "핫스팟이 동작할 때는 무선으로 인터넷에 연결할 수 없습니다." -#: panels/network/net-device-wifi.c:1339 +#: panels/network/net-device-wifi.c:1379 msgid "Turn On Wi-Fi Hotspot?" msgstr "와이파이 핫스팟을 켜시겠습니까?" -#: panels/network/net-device-wifi.c:1361 +#: panels/network/net-device-wifi.c:1401 msgid "" "Wi-Fi hotspots are usually used to share an additional Internet connection " "over Wi-Fi." msgstr "와이파이 핫스팟은 인터넷 연결을 와이파이를 통해 공유할 때 사용됩니다." -#: panels/network/net-device-wifi.c:1372 +#: panels/network/net-device-wifi.c:1412 msgid "_Turn On" msgstr "켜기(_T)" -#: panels/network/net-device-wifi.c:1449 +#: panels/network/net-device-wifi.c:1489 msgid "Stop hotspot and disconnect any users?" msgstr "핫스팟을 중지하고 연결 중인 사용자를 끊으시겠습니까?" -#: panels/network/net-device-wifi.c:1452 +#: panels/network/net-device-wifi.c:1492 msgid "_Stop Hotspot" msgstr "핫스팟 중지(_S)" -#: panels/network/net-device-wifi.c:1552 +#: panels/network/net-device-wifi.c:1592 msgid "System policy prohibits use as a Hotspot" msgstr "시스템 정책이 핫스팟 사용을 막습니다" -#: panels/network/net-device-wifi.c:1555 +#: panels/network/net-device-wifi.c:1595 msgid "Wireless device does not support Hotspot mode" msgstr "무선 장치에서 핫스팟 모드를 지원하지 않습니다" -#: panels/network/net-device-wifi.c:1687 +#: panels/network/net-device-wifi.c:1733 msgid "" "Network details for the selected networks, including passwords and any " "custom configuration will be lost." msgstr "" "선택한 네트워크의 상세 정보(암호 및 기타 사용자 설정 정보 포함)가 지워집니다." -#: panels/network/net-device-wifi.c:1691 panels/network/network-wifi.ui:1362 +#: panels/network/net-device-wifi.c:1737 panels/network/network-wifi.ui:1362 msgid "_Forget" msgstr "저장 지우기(_F)" -#: panels/network/net-device-wifi.c:2000 panels/network/net-device-wifi.c:2007 +#: panels/network/net-device-wifi.c:2046 panels/network/net-device-wifi.c:2053 msgid "Known Wi-Fi Networks" msgstr "알려진 와이파이 네트워크" #. translators: This is the label for the "Forget wireless network" functionality -#: panels/network/net-device-wifi.c:2040 +#: panels/network/net-device-wifi.c:2086 msgctxt "Wi-Fi Network" msgid "_Forget" msgstr "지우기(_F)" @@ -3015,19 +3027,19 @@ msgctxt "Wi-Fi passkey" msgid "Password" msgstr "암호" -#: panels/network/network-wifi.ui:1796 +#: panels/network/network-wifi.ui:1799 msgid "Turn Wi-Fi off" msgstr "와이파이 끄기" -#: panels/network/network-wifi.ui:1828 +#: panels/network/network-wifi.ui:1831 msgid "_Connect to Hidden Network…" msgstr "숨겨진 네트워크에 연결(_C)…" -#: panels/network/network-wifi.ui:1838 +#: panels/network/network-wifi.ui:1841 msgid "_Turn On Wi-Fi Hotspot…" msgstr "와이파이 핫스팟 켜기(_T)…" -#: panels/network/network-wifi.ui:1848 +#: panels/network/network-wifi.ui:1851 msgid "_Known Wi-Fi Networks" msgstr "알려진 와이파이 네트워크(_K)" @@ -3336,23 +3348,23 @@ msgstr "펌웨어 없음" msgid "Cable unplugged" msgstr "케이블 분리됨" -#: panels/network/wireless-security/eap-method.c:57 +#: panels/network/wireless-security/eap-method.c:69 msgid "undefined error in 802.1X security (wpa-eap)" msgstr "802.1X 보안에 (WPA-EAP) 정의하지 않은 오류" -#: panels/network/wireless-security/eap-method.c:233 +#: panels/network/wireless-security/eap-method.c:245 msgid "no file selected" msgstr "파일을 선택하지 않았습니다" -#: panels/network/wireless-security/eap-method.c:264 +#: panels/network/wireless-security/eap-method.c:276 msgid "unspecified error validating eap-method file" msgstr "EAP-METHOD 파일을 검증하는 중 지정하지 않은 오류" -#: panels/network/wireless-security/eap-method.c:439 +#: panels/network/wireless-security/eap-method.c:451 msgid "DER, PEM, or PKCS#12 private keys (*.der, *.pem, *.p12, *.key)" msgstr "DER, PEM 또는 PKCS#12 형식 개인 키(*.der, *.pem, *.p12, *.key)" -#: panels/network/wireless-security/eap-method.c:442 +#: panels/network/wireless-security/eap-method.c:454 msgid "DER or PEM certificates (*.der, *.pem, *.crt, *.cer)" msgstr "DER 또는 PEM 형식 인증서(*.der, *.pem, *.crt, *.cer)" @@ -3731,12 +3743,13 @@ msgstr "알림" msgid "Control which notifications are displayed and what they show" msgstr "어떤 알림을 표시할지 및 무엇을 표시할지 설정합니다" -#: panels/notifications/gnome-notifications-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/notifications/gnome-notifications-panel.desktop.in.in:7 msgid "preferences-system-notifications" msgstr "preferences-system-notifications" -#. Translators: those are keywords for the notifications control-center panel -#: panels/notifications/gnome-notifications-panel.desktop.in.in:19 +#. Translators: Search terms to find the Notifications panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/notifications/gnome-notifications-panel.desktop.in.in:20 msgid "Notifications;Banner;Message;Tray;Popup;" msgstr "" "Notifications;알림;Banner;안내판;Message;메시지;Tray;트레이;Popup;팝업;" @@ -3762,19 +3775,19 @@ msgstr "기타" #. translators: This is the title of the "Show Account" dialog. The #. * %s is the name of the provider. e.g., 'Google'. -#: panels/online-accounts/cc-online-accounts-panel.c:551 +#: panels/online-accounts/cc-online-accounts-panel.c:596 #, c-format msgid "%s Account" msgstr "%s 계정" -#: panels/online-accounts/cc-online-accounts-panel.c:843 +#: panels/online-accounts/cc-online-accounts-panel.c:888 msgid "Error removing account" msgstr "계정 제거 오류" #. Translators: The %s is the username (eg., debarshi.ray@gmail.com #. * or rishi). #. -#: panels/online-accounts/cc-online-accounts-panel.c:908 +#: panels/online-accounts/cc-online-accounts-panel.c:953 #, c-format msgid "%s removed" msgstr "%s 제거함" @@ -3787,13 +3800,16 @@ msgstr "온라인 계정" msgid "Connect to your online accounts and decide what to use them for" msgstr "온라인 계정에 연결하고 그 계정을 어디에 이용할지 설정합니다" -#: panels/online-accounts/gnome-online-accounts-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/online-accounts/gnome-online-accounts-panel.desktop.in.in:7 msgid "goa-panel" msgstr "goa-panel" -#. Translators: those are keywords for the online-accounts control-center panel +#. Translators: Search terms to find the Online Accounts panel. +#. Do NOT translate or localize the semicolons! +#. The list MUST also end with a semicolon! #. For ReadItLater and Pocket, see http://en.wikipedia.org/wiki/Pocket_(application) -#: panels/online-accounts/gnome-online-accounts-panel.desktop.in.in:19 +#: panels/online-accounts/gnome-online-accounts-panel.desktop.in.in:22 msgid "" "Google;Facebook;Twitter;Yahoo;Web;Online;Chat;Calendar;Mail;Contact;ownCloud;" "Kerberos;IMAP;SMTP;Pocket;ReadItLater;" @@ -3952,7 +3968,7 @@ msgstr "게임 입력 장치" #. TRANSLATORS: secondary battery, misc #: panels/power/cc-power-panel.c:564 panels/power/cc-power-panel.c:804 -#: panels/power/cc-power-panel.c:2374 +#: panels/power/cc-power-panel.c:2380 msgid "Battery" msgstr "배터리" @@ -3996,100 +4012,100 @@ msgstr "방전됨" msgid "Batteries" msgstr "배터리" -#: panels/power/cc-power-panel.c:1236 +#: panels/power/cc-power-panel.c:1242 msgid "When _idle" msgstr "입력이 없을 때(_I)" -#: panels/power/cc-power-panel.c:1690 +#: panels/power/cc-power-panel.c:1696 msgid "Power Saving" msgstr "절전" -#: panels/power/cc-power-panel.c:1721 +#: panels/power/cc-power-panel.c:1727 msgid "_Screen brightness" msgstr "화면 밝기(_S)" -#: panels/power/cc-power-panel.c:1740 +#: panels/power/cc-power-panel.c:1746 msgid "Automatic brightness" msgstr "자동 밝기 조절" -#: panels/power/cc-power-panel.c:1760 +#: panels/power/cc-power-panel.c:1766 msgid "_Keyboard brightness" msgstr "키보드 밝기 조절(_K)" -#: panels/power/cc-power-panel.c:1770 +#: panels/power/cc-power-panel.c:1776 msgid "_Dim screen when inactive" msgstr "입력이 없으면 화면 어둡게(_D)" -#: panels/power/cc-power-panel.c:1795 +#: panels/power/cc-power-panel.c:1801 msgid "_Blank screen" msgstr "빈 화면(_B)" -#: panels/power/cc-power-panel.c:1832 +#: panels/power/cc-power-panel.c:1838 msgid "_Wi-Fi" msgstr "와이파이(_W)" -#: panels/power/cc-power-panel.c:1837 +#: panels/power/cc-power-panel.c:1843 msgid "Turn off Wi-Fi to save power." msgstr "전기 사용을 줄이려면 와이파이를 끄십시오." -#: panels/power/cc-power-panel.c:1862 +#: panels/power/cc-power-panel.c:1868 msgid "_Mobile broadband" msgstr "휴대전화 네트워크(_M)" -#: panels/power/cc-power-panel.c:1867 +#: panels/power/cc-power-panel.c:1873 msgid "Turn off mobile broadband (3G, 4G, LTE, etc.) to save power." msgstr "전기 사용을 줄이려면 휴대전화 네트워크를(3G, 4G, LTE 등) 끄십시오." -#: panels/power/cc-power-panel.c:1920 +#: panels/power/cc-power-panel.c:1926 msgid "_Bluetooth" msgstr "블루투스(_B)" -#: panels/power/cc-power-panel.c:1925 +#: panels/power/cc-power-panel.c:1931 msgid "Turn off Bluetooth to save power." msgstr "전기 사용을 줄이려면 블루투스를 끄십시오." -#: panels/power/cc-power-panel.c:1984 +#: panels/power/cc-power-panel.c:1990 msgid "When on battery power" msgstr "배터리 전원 사용할 때" -#: panels/power/cc-power-panel.c:1986 +#: panels/power/cc-power-panel.c:1992 msgid "When plugged in" msgstr "전원이 연결되었을 때" -#: panels/power/cc-power-panel.c:2081 +#: panels/power/cc-power-panel.c:2087 msgid "Suspend" msgstr "대기 모드" -#: panels/power/cc-power-panel.c:2082 +#: panels/power/cc-power-panel.c:2088 msgid "Power Off" msgstr "전원 끄기" -#: panels/power/cc-power-panel.c:2083 +#: panels/power/cc-power-panel.c:2089 msgid "Hibernate" msgstr "최대 절전" -#: panels/power/cc-power-panel.c:2084 +#: panels/power/cc-power-panel.c:2090 msgid "Nothing" msgstr "아무것도 하지 않기" #. Frame header -#: panels/power/cc-power-panel.c:2198 +#: panels/power/cc-power-panel.c:2204 msgid "Suspend & Power Button" msgstr "대기 모드 및 전원 단추" -#: panels/power/cc-power-panel.c:2237 +#: panels/power/cc-power-panel.c:2243 msgid "_Automatic suspend" msgstr "자동 대기 모드(_A)" -#: panels/power/cc-power-panel.c:2238 +#: panels/power/cc-power-panel.c:2244 msgid "Automatic suspend" msgstr "자동 대기 모드" -#: panels/power/cc-power-panel.c:2305 +#: panels/power/cc-power-panel.c:2311 msgid "_When the Power Button is pressed" msgstr "전원 단추를 눌렀을 때(_W)" -#: panels/power/cc-power-panel.c:2424 shell/cc-window.c:219 +#: panels/power/cc-power-panel.c:2430 shell/cc-window.c:218 #: shell/panel-list.ui:45 msgid "Devices" msgstr "장치" @@ -4102,12 +4118,13 @@ msgstr "전원" msgid "View your battery status and change power saving settings" msgstr "배터리 상태를 보고 절전 설정을 바꿉니다" -#: panels/power/gnome-power-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/power/gnome-power-panel.desktop.in.in:7 msgid "gnome-power-manager" msgstr "gnome-power-manager" -#. Translators: those are keywords for the power control-center panel -#: panels/power/gnome-power-panel.desktop.in.in:18 +#. Translators: Search terms to find the Power panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/power/gnome-power-panel.desktop.in.in:19 msgid "" "Power;Sleep;Suspend;Hibernate;Battery;Brightness;Dim;Blank;Monitor;DPMS;Idle;" msgstr "" @@ -4223,18 +4240,18 @@ msgid "Authentication Required" msgstr "인증 필요" #. Translators: %s is the printer name -#: panels/printers/cc-printers-panel.c:791 +#: panels/printers/cc-printers-panel.c:808 #, c-format msgid "Printer “%s” has been deleted" msgstr "“%s” 프린터를 삭제했습니다" #. Translators: Addition of the new printer failed. -#: panels/printers/cc-printers-panel.c:1036 +#: panels/printers/cc-printers-panel.c:1053 msgid "Failed to add new printer." msgstr "새 프린터 추가에 실패했습니다." #. Translators: The XML file containing user interface can not be loaded -#: panels/printers/cc-printers-panel.c:1371 +#: panels/printers/cc-printers-panel.c:1388 #, c-format msgid "Could not load ui: %s" msgstr "UI를 읽어들일 수 없습니다: %s" @@ -4273,12 +4290,13 @@ msgstr "프린터" msgid "Add printers, view printer jobs and decide how you want to print" msgstr "프린터 추가, 인쇄 작업 보기, 어떻게 인쇄할지 설정" -#: panels/printers/gnome-printers-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/printers/gnome-printers-panel.desktop.in.in:7 msgid "printer" -msgstr "프린터" +msgstr "printer" -#. Translators: those are keywords for the printing control-center panel -#: panels/printers/gnome-printers-panel.desktop.in.in:15 +#. Translators: Search terms to find the Printers panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/printers/gnome-printers-panel.desktop.in.in:16 msgid "Printer;Queue;Print;Paper;Ink;Toner;" msgstr "" "Printer;프린터;Queue;대기열;Print;인쇄;Paper;용지;종이;Ink;잉크;Toner;토너;" @@ -4369,7 +4387,7 @@ msgid "Select Printer Driver" msgstr "프린터 드라이버 선택" #: panels/printers/ppd-selection-dialog.ui:40 -#: panels/user-accounts/um-photo-dialog.c:104 +#: panels/user-accounts/um-photo-dialog.c:105 msgid "Select" msgstr "선택" @@ -4426,69 +4444,69 @@ msgid "Reverse portrait" msgstr "가로 방향 뒤집기" #. Translators: Job's state (job is waiting to be printed) -#: panels/printers/pp-jobs-dialog.c:243 +#: panels/printers/pp-jobs-dialog.c:234 msgctxt "print job" msgid "Pending" msgstr "대기" #. Translators: Job's state (job is held for printing) -#: panels/printers/pp-jobs-dialog.c:249 +#: panels/printers/pp-jobs-dialog.c:240 msgctxt "print job" msgid "Paused" msgstr "일시 중지 상태" #. Translators: Job's state (job needs authentication to proceed further) -#: panels/printers/pp-jobs-dialog.c:254 +#: panels/printers/pp-jobs-dialog.c:245 msgctxt "print job" msgid "Authentication required" msgstr "인증 필요" #. Translators: Job's state (job is currently printing) -#: panels/printers/pp-jobs-dialog.c:259 +#: panels/printers/pp-jobs-dialog.c:250 msgctxt "print job" msgid "Processing" msgstr "처리 중" #. Translators: Job's state (job has been stopped) -#: panels/printers/pp-jobs-dialog.c:263 +#: panels/printers/pp-jobs-dialog.c:254 msgctxt "print job" msgid "Stopped" msgstr "중지" #. Translators: Job's state (job has been canceled) -#: panels/printers/pp-jobs-dialog.c:267 +#: panels/printers/pp-jobs-dialog.c:258 msgctxt "print job" msgid "Canceled" msgstr "취소" #. Translators: Job's state (job has aborted due to error) -#: panels/printers/pp-jobs-dialog.c:271 +#: panels/printers/pp-jobs-dialog.c:262 msgctxt "print job" msgid "Aborted" msgstr "중지됨" #. Translators: Job's state (job has completed successfully) -#: panels/printers/pp-jobs-dialog.c:275 +#: panels/printers/pp-jobs-dialog.c:266 msgctxt "print job" msgid "Completed" msgstr "완료" #. Translators: This label shows how many jobs of this printer needs to be authenticated to be printed. -#: panels/printers/pp-jobs-dialog.c:399 +#: panels/printers/pp-jobs-dialog.c:390 #, c-format msgid "%u Job Requires Authentication" msgid_plural "%u Jobs Require Authentication" msgstr[0] "작업 %u개에 인증이 필요합니다" #. Translators: This is the printer name for which we are showing the active jobs -#: panels/printers/pp-jobs-dialog.c:617 +#: panels/printers/pp-jobs-dialog.c:620 #, c-format msgctxt "Printer jobs dialog title" msgid "%s — Active Jobs" msgstr "%s — 활성 작업" #. Translators: The printer needs authentication info to print. -#: panels/printers/pp-jobs-dialog.c:622 +#: panels/printers/pp-jobs-dialog.c:625 #, c-format msgid "Enter credentials to print from %s." msgstr "%s에서 인쇄하려면 인증 정보가 필요합니다." @@ -4938,12 +4956,13 @@ msgid "Protect your personal information and control what others might see" msgstr "개인 정보를 보호하고, 다른 사람이 볼 수 있는 사항을 설정합니다" #. FIXME -#: panels/privacy/gnome-privacy-panel.desktop.in.in:7 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/privacy/gnome-privacy-panel.desktop.in.in:8 msgid "preferences-system-privacy" msgstr "preferences-system-privacy" -#. Translators: those are keywords for the privacy control-center panel -#: panels/privacy/gnome-privacy-panel.desktop.in.in:19 +#. Translators: Search terms to find the Privacy panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/privacy/gnome-privacy-panel.desktop.in.in:20 msgid "" "screen;lock;diagnostics;crash;private;recent;temporary;tmp;index;name;" "network;identity;" @@ -5178,12 +5197,13 @@ msgid "" "Select your display language, formats, keyboard layouts and input sources" msgstr "표시할 언어, 여러가지 형식, 키보드 배치, 입력 소스를 선택합니다." -#: panels/region/gnome-region-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/region/gnome-region-panel.desktop.in.in:7 msgid "preferences-desktop-locale" msgstr "preferences-desktop-locale" -#. Translators: those are keywords for the region control-center panel -#: panels/region/gnome-region-panel.desktop.in.in:18 +#. Translators: Search terms to find the Region and Language panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/region/gnome-region-panel.desktop.in.in:19 msgid "Language;Layout;Keyboard;Input;" msgstr "Language;언어;Layout;배치;Keyboard;키보드;Input;입력;" @@ -5314,12 +5334,13 @@ msgid "" "Control which applications show search results in the Activities Overview" msgstr "어떤 프로그램에서 활동 내역에 검색 결과를 표시할지 설정합니다." -#: panels/search/gnome-search-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/search/gnome-search-panel.desktop.in.in:7 msgid "preferences-system-search" msgstr "preferences-system-search" -#. Translators: those are keywords for the search control-center panel -#: panels/search/gnome-search-panel.desktop.in.in:18 +#. Translators: Search terms to find the Search panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/search/gnome-search-panel.desktop.in.in:19 msgid "Search;Find;Index;Hide;Privacy;Results;" msgstr "" "Search;검색;Find;찾기;Index;인덱스;색인;Hide;숨기기;Privacy;개인;정보;사생활;" @@ -5424,12 +5445,13 @@ msgstr "공유" msgid "Control what you want to share with others" msgstr "다른 사람과 공유할 사항을 정합니다" -#: panels/sharing/gnome-sharing-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/sharing/gnome-sharing-panel.desktop.in.in:7 msgid "preferences-system-sharing" msgstr "preferences-system-sharing" -#. Translators: those are keywords for the sharing control-center panel -#: panels/sharing/gnome-sharing-panel.desktop.in.in:15 +#. Translators: Search terms to find the Sharing panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/sharing/gnome-sharing-panel.desktop.in.in:16 msgid "" "share;sharing;ssh;host;name;remote;desktop;media;audio;video;pictures;photos;" "movies;server;renderer;" @@ -5534,12 +5556,13 @@ msgstr "소리" msgid "Change sound levels, inputs, outputs, and alert sounds" msgstr "사운드 음량과, 입력, 출력, 경고음을 바꿉니다" -#: panels/sound/data/gnome-sound-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/sound/data/gnome-sound-panel.desktop.in.in:7 msgid "multimedia-volume-control" msgstr "multimedia-volume-control" -#. Translators: those are keywords for the sound control-center panel -#: panels/sound/data/gnome-sound-panel.desktop.in.in:19 +#. Translators: Search terms to find the Sound panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/sound/data/gnome-sound-panel.desktop.in.in:20 msgid "Card;Microphone;Volume;Fade;Balance;Bluetooth;Headset;Audio;" msgstr "" "Card;카드;Microphone;마이크;Volume;볼륨;음량;Fade;페이드;Balance;균형;밸런스;" @@ -5769,13 +5792,14 @@ msgstr[0] "%d픽셀" msgid "Make it easier to see, hear, type, point and click" msgstr "보기, 듣기, 타이핑, 누르기 편의 사항" -#: panels/universal-access/gnome-universal-access-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/universal-access/gnome-universal-access-panel.desktop.in.in:7 msgid "preferences-desktop-accessibility" msgstr "preferences-desktop-accessibility" # 원문이 'Mouse' 키워드 중복 -#. Translators: those are keywords for the universal access control-center panel -#: panels/universal-access/gnome-universal-access-panel.desktop.in.in:18 +#. Translators: Search terms to find the Universal Access panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/universal-access/gnome-universal-access-panel.desktop.in.in:19 msgid "" "Keyboard;Mouse;a11y;Accessibility;Contrast;Zoom;Screen;Reader;text;font;size;" "AccessX;Sticky;Keys;Slow;Bounce;Mouse;Double;click;Delay;Assist;Repeat;Blink;" @@ -6406,12 +6430,13 @@ msgstr "사용자" msgid "Add or remove users and change your password" msgstr "사용자 추가/제거 및 암호 바꾸기" -#: panels/user-accounts/data/gnome-user-accounts-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/user-accounts/data/gnome-user-accounts-panel.desktop.in.in:7 msgid "system-users" msgstr "system-users" -#. Translators: those are keywords for the user accounts control-center panel -#: panels/user-accounts/data/gnome-user-accounts-panel.desktop.in.in:19 +#. Translators: Search terms to find the Users panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/user-accounts/data/gnome-user-accounts-panel.desktop.in.in:20 msgid "Login;Name;Fingerprint;Avatar;Logo;Face;Password;" msgstr "" "Login;로그인;Name;이름;Fingerprint;지문;Avatar;아바타;Logo;로고;Face;얼굴;" @@ -6850,7 +6875,7 @@ msgstr "%s — %s" #. Translators: This is a time format string in the style of "22:58". #. It indicates a login time which follows a date. #: panels/user-accounts/um-history-dialog.c:177 -#: panels/user-accounts/um-user-panel.c:767 +#: panels/user-accounts/um-user-panel.c:766 msgctxt "login date-time" msgid "%k:%M" msgstr "%k:%M" @@ -6858,7 +6883,7 @@ msgstr "%k:%M" #. Translators: This indicates a login date-time. #. The first %s is a date, and the second %s a time. #: panels/user-accounts/um-history-dialog.c:180 -#: panels/user-accounts/um-user-panel.c:771 +#: panels/user-accounts/um-user-panel.c:770 #, c-format msgctxt "login date-time" msgid "%s, %s" @@ -6895,7 +6920,7 @@ msgstr "암호를 바꿀 수 없습니다" msgid "The passwords do not match." msgstr "암호가 다릅니다." -#: panels/user-accounts/um-photo-dialog.c:226 +#: panels/user-accounts/um-photo-dialog.c:227 msgid "Browse for more pictures" msgstr "다른 사진 찾아보기" @@ -6923,41 +6948,41 @@ msgstr "암호가 잘못되었으니 다시 시도해주십시오" msgid "Couldn’t connect to the %s domain: %s" msgstr "%s 도메인에 연결할 수 없습니다: %s" -#: panels/user-accounts/um-user-panel.c:201 +#: panels/user-accounts/um-user-panel.c:200 msgid "Your account" msgstr "내 계정" -#: panels/user-accounts/um-user-panel.c:381 +#: panels/user-accounts/um-user-panel.c:380 msgid "Failed to delete user" msgstr "사용자 삭제에 실패했습니다" -#: panels/user-accounts/um-user-panel.c:439 -#: panels/user-accounts/um-user-panel.c:498 -#: panels/user-accounts/um-user-panel.c:550 +#: panels/user-accounts/um-user-panel.c:438 +#: panels/user-accounts/um-user-panel.c:497 +#: panels/user-accounts/um-user-panel.c:549 msgid "Failed to revoke remotely managed user" msgstr "원격에서 관리하는 사용자를 철회하는데 실패했습니다" -#: panels/user-accounts/um-user-panel.c:604 +#: panels/user-accounts/um-user-panel.c:603 msgid "You cannot delete your own account." msgstr "자기 계정은 삭제할 수 없습니다." -#: panels/user-accounts/um-user-panel.c:613 +#: panels/user-accounts/um-user-panel.c:612 #, c-format msgid "%s is still logged in" msgstr "%s 사용자가 아직 로그인 중입니다" -#: panels/user-accounts/um-user-panel.c:617 +#: panels/user-accounts/um-user-panel.c:616 msgid "" "Deleting a user while they are logged in can leave the system in an " "inconsistent state." msgstr "로그인 중인 사용자를 삭제하면 시스템이 불안정한 상태가 될 수 있습니다." -#: panels/user-accounts/um-user-panel.c:626 +#: panels/user-accounts/um-user-panel.c:625 #, c-format msgid "Do you want to keep %s’s files?" msgstr "%s 사용자의 파일을 유지하시겠습니까?" -#: panels/user-accounts/um-user-panel.c:630 +#: panels/user-accounts/um-user-panel.c:629 msgid "" "It is possible to keep the home directory, mail spool and temporary files " "around when deleting a user account." @@ -6965,47 +6990,47 @@ msgstr "" "사용자 계정을 삭제할 때 홈 디렉터리, 메일 스풀, 임시 파일을 유지할 수 있습니" "다." -#: panels/user-accounts/um-user-panel.c:633 +#: panels/user-accounts/um-user-panel.c:632 msgid "_Delete Files" msgstr "파일 삭제(_D)" -#: panels/user-accounts/um-user-panel.c:634 +#: panels/user-accounts/um-user-panel.c:633 msgid "_Keep Files" msgstr "파일 유지(_K)" -#: panels/user-accounts/um-user-panel.c:648 +#: panels/user-accounts/um-user-panel.c:647 #, c-format msgid "Are you sure you want to revoke remotely managed %s’s account?" msgstr "정말로 원격에서 관리하는 %s의 계정을 철회하시겠습니까?" -#: panels/user-accounts/um-user-panel.c:652 +#: panels/user-accounts/um-user-panel.c:651 msgid "_Delete" msgstr "삭제(_D)" -#: panels/user-accounts/um-user-panel.c:702 +#: panels/user-accounts/um-user-panel.c:701 msgctxt "Password mode" msgid "Account disabled" msgstr "계정 사용 중지됨" -#: panels/user-accounts/um-user-panel.c:710 +#: panels/user-accounts/um-user-panel.c:709 msgctxt "Password mode" msgid "To be set at next login" msgstr "다음 로그인에 설정 예정" -#: panels/user-accounts/um-user-panel.c:713 +#: panels/user-accounts/um-user-panel.c:712 msgctxt "Password mode" msgid "None" msgstr "없음" -#: panels/user-accounts/um-user-panel.c:760 +#: panels/user-accounts/um-user-panel.c:759 msgid "Logged in" msgstr "로그인함" -#: panels/user-accounts/um-user-panel.c:1107 +#: panels/user-accounts/um-user-panel.c:1106 msgid "Failed to contact the accounts service" msgstr "계정 서비스 연결에 실패했습니다" -#: panels/user-accounts/um-user-panel.c:1109 +#: panels/user-accounts/um-user-panel.c:1108 msgid "Please make sure that the AccountService is installed and enabled." msgstr "AccountService를 설치하고 사용 표시했는지 확인하십시오." @@ -7013,7 +7038,7 @@ msgstr "AccountService를 설치하고 사용 표시했는지 확인하십시오 #. * We split the line in 2 here to "make it look good", as there's #. * no good way to do this in GTK+ for tooltips. See: #. * https://bugzilla.gnome.org/show_bug.cgi?id=657168 -#: panels/user-accounts/um-user-panel.c:1141 +#: panels/user-accounts/um-user-panel.c:1140 msgid "" "To make changes,\n" "click the * icon first" @@ -7021,12 +7046,12 @@ msgstr "" "바꾸려면,\n" "먼저 * 아이콘을 누르십시오" -#: panels/user-accounts/um-user-panel.c:1181 +#: panels/user-accounts/um-user-panel.c:1180 msgid "Create a user account" msgstr "새 사용자 계정 만들기" -#: panels/user-accounts/um-user-panel.c:1192 -#: panels/user-accounts/um-user-panel.c:1371 +#: panels/user-accounts/um-user-panel.c:1191 +#: panels/user-accounts/um-user-panel.c:1370 msgid "" "To create a user account,\n" "click the * icon first" @@ -7034,12 +7059,12 @@ msgstr "" "사용자 계정을 만드려면,\n" "먼저 * 아이콘을 누르십시오" -#: panels/user-accounts/um-user-panel.c:1202 +#: panels/user-accounts/um-user-panel.c:1201 msgid "Delete the selected user account" msgstr "선택한 사용자 계정 삭제" -#: panels/user-accounts/um-user-panel.c:1214 -#: panels/user-accounts/um-user-panel.c:1376 +#: panels/user-accounts/um-user-panel.c:1213 +#: panels/user-accounts/um-user-panel.c:1375 msgid "" "To delete the selected user account,\n" "click the * icon first" @@ -7170,12 +7195,13 @@ msgid "Set button mappings and adjust stylus sensitivity for graphics tablets" msgstr "" "그래픽 디지타이저의 단추 매핑을 설정하고 스타일러스의 민감도를 조정합니다" -#: panels/wacom/gnome-wacom-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/wacom/gnome-wacom-panel.desktop.in.in:7 msgid "input-tablet" msgstr "input-tablet" -#. Translators: those are keywords for the wacom tablet control-center panel -#: panels/wacom/gnome-wacom-panel.desktop.in.in:18 +#. Translators: Search terms to find the Wacom Tablet panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/wacom/gnome-wacom-panel.desktop.in.in:19 msgid "Tablet;Wacom;Stylus;Eraser;Mouse;" msgstr "" "Tablet;태블릿;디지타이저;Wacom;와콤;Stylus;스타일러스;Eraser;지우개;Mouse;마" @@ -7357,11 +7383,13 @@ msgstr "도움말" msgid "Quit" msgstr "끝내기" -#: shell/gnome-control-center.desktop.in.in:4 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: shell/gnome-control-center.desktop.in.in:5 msgid "gnome-control-center" msgstr "gnome-control-center" -#: shell/gnome-control-center.desktop.in.in:15 +#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: shell/gnome-control-center.desktop.in.in:17 msgid "Preferences;Settings;" msgstr "Preferences;기본 설정;Settings;설정;" -- cgit v1.2.1 From 02b0d5931cf3ef1c055c6d864dd58dfd481bbead Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Sat, 7 Apr 2018 18:49:39 -0300 Subject: debug: Fix copy-pasta mistake Now people now where did I copied it from! --- shell/cc-debug.h.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/cc-debug.h.in b/shell/cc-debug.h.in index 72962970d..226f82e03 100644 --- a/shell/cc-debug.h.in +++ b/shell/cc-debug.h.in @@ -27,7 +27,7 @@ * @stability:stable * * Macros used for tracing and debugging code. These - * are only valid when Calendar is compiled with tracing + * are only valid when Settings is compiled with tracing * suppoer (pass `--enable-tracing` to the configure * script to do that). */ @@ -204,7 +204,7 @@ G_BEGIN_DECLS #define _CC_BUG(Component, Description, File, Line, Func, ...) \ G_STMT_START { \ g_printerr ("-----------------------------------------------------------------\n"); \ - g_printerr ("You've found a bug in Calendar or one of its dependent libraries.\n"); \ + g_printerr ("You've found a bug in Settings or one of its dependent libraries.\n"); \ g_printerr ("Please help us help you by filing a bug report at:\n"); \ g_printerr ("\n"); \ g_printerr ("@BUGREPORT_URL@&component=%s\n", Component); \ -- cgit v1.2.1 From 8879cd476a8c828326d437ddf00243e165999428 Mon Sep 17 00:00:00 2001 From: Felipe Borges Date: Mon, 9 Apr 2018 11:42:35 +0200 Subject: printers: Fix crash when panel is closed quickly Fix a user-after-free while testing the connectivity to a cups server. This is similar to the fix in commit 1d72a0b. This is an addition to the changes introduced in commit 2ff5cfd which allowed the connection testing to be cancellable. Fixes #51 Fixes https://bugzilla.gnome.org/794632 --- panels/printers/cc-printers-panel.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/panels/printers/cc-printers-panel.c b/panels/printers/cc-printers-panel.c index 4815c4520..877028863 100644 --- a/panels/printers/cc-printers-panel.c +++ b/panels/printers/cc-printers-panel.c @@ -1230,14 +1230,13 @@ connection_test_cb (GObject *source_object, gpointer user_data) { CcPrintersPanelPrivate *priv; - CcPrintersPanel *self = (CcPrintersPanel*) user_data; + CcPrintersPanel *self; gboolean success; PpCups *cups = PP_CUPS (source_object); g_autoptr(GError) error = NULL; - priv = self->priv; - success = pp_cups_connection_test_finish (cups, result, &error); + g_object_unref (cups); if (error != NULL) { @@ -1245,15 +1244,18 @@ connection_test_cb (GObject *source_object, { g_warning ("Could not test connection: %s", error->message); } + + return; } + self = CC_PRINTERS_PANEL (user_data); + priv = self->priv; + if (!success) { priv->cups_status_check_id = g_timeout_add_seconds (CUPS_STATUS_CHECK_INTERVAL, cups_status_check, self); } - - g_object_unref (cups); } static void -- cgit v1.2.1 From 51a1229111e4de5fc7755251674a3eb292e2a76c Mon Sep 17 00:00:00 2001 From: Christian Kellner Date: Tue, 10 Apr 2018 09:43:22 +0200 Subject: shell: Don't set per-panel icon The control center app is considered one single application with a single icon to represent it. Therefore get rid of per-panel icons. --- shell/cc-window.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/shell/cc-window.c b/shell/cc-window.c index fea3cf567..22c7b546b 100644 --- a/shell/cc-window.c +++ b/shell/cc-window.c @@ -122,7 +122,6 @@ activate_panel (CcWindow *self, { g_autoptr (GTimer) timer = NULL; GtkWidget *box, *title_widget; - const gchar *icon_name; gdouble ellapsed_time; if (!id) @@ -154,12 +153,8 @@ activate_panel (CcWindow *self, gtk_stack_set_visible_child_name (GTK_STACK (self->stack), id); /* set the title of the window */ - icon_name = get_icon_name_from_g_icon (gicon); - gtk_window_set_role (GTK_WINDOW (self), id); gtk_header_bar_set_title (GTK_HEADER_BAR (self->panel_headerbar), name); - gtk_window_set_default_icon_name (icon_name); - gtk_window_set_icon_name (GTK_WINDOW (self), icon_name); title_widget = cc_panel_get_title_widget (CC_PANEL (self->current_panel)); gtk_header_bar_set_custom_title (GTK_HEADER_BAR (self->panel_headerbar), title_widget); -- cgit v1.2.1 From 2889ab03b23446f45a9ba0d4befdd47553b7a083 Mon Sep 17 00:00:00 2001 From: Christian Kellner Date: Tue, 10 Apr 2018 09:47:48 +0200 Subject: shell: Icon name helper returns symbolic name The helper function to get the icon name from a GIcon directly returns the symbolic icon now. This makes it in turn possible to also directly check if the theme has the icon with the symbolic name instead of checking of for the full colored one and then deriving the symbolic name from that. The latter (old) practice will fail if there is a symbolic icon in the theme that has no full color icon (like e.g. thunderbolt). --- shell/cc-window.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/shell/cc-window.c b/shell/cc-window.c index 22c7b546b..c0fc19446 100644 --- a/shell/cc-window.c +++ b/shell/cc-window.c @@ -91,8 +91,8 @@ enum }; /* Auxiliary methods */ -static const gchar * -get_icon_name_from_g_icon (GIcon *gicon) +static gchar * +get_symbolic_icon_name_from_g_icon (GIcon *gicon) { const gchar * const *names; GtkIconTheme *icon_theme; @@ -106,8 +106,11 @@ get_icon_name_from_g_icon (GIcon *gicon) for (i = 0; names[i] != NULL; i++) { - if (gtk_icon_theme_has_icon (icon_theme, names[i])) - return names[i]; + g_autofree gchar *name = NULL; + name = g_strdup_printf ("%s-symbolic", names[i]); + + if (gtk_icon_theme_has_icon (icon_theme, name)) + return g_steal_pointer (&name); } return NULL; @@ -265,9 +268,8 @@ setup_model (CcWindow *shell) g_autofree gchar *name = NULL; g_autofree gchar *description = NULL; g_autofree gchar *id = NULL; - g_autofree gchar *symbolic_icon = NULL; + g_autofree gchar *icon_name = NULL; g_autofree GStrv keywords = NULL; - const gchar *icon_name; gtk_tree_model_get (model, &iter, COL_CATEGORY, &category, @@ -278,8 +280,7 @@ setup_model (CcWindow *shell) COL_KEYWORDS, &keywords, -1); - icon_name = get_icon_name_from_g_icon (icon); - symbolic_icon = g_strdup_printf ("%s-symbolic", icon_name); + icon_name = get_symbolic_icon_name_from_g_icon (icon); cc_panel_list_add_panel (CC_PANEL_LIST (shell->panel_list), category, @@ -287,7 +288,7 @@ setup_model (CcWindow *shell) name, description, keywords, - symbolic_icon); + icon_name); valid = gtk_tree_model_iter_next (model, &iter); } -- cgit v1.2.1 From ef9d460e72b6c67786bbb3f7ec9c6ee7e960d954 Mon Sep 17 00:00:00 2001 From: Stas Solovey Date: Thu, 12 Apr 2018 11:48:12 +0000 Subject: Update Russian translation (cherry picked from commit 665912175b4c5c99cb40a0c1b50b93971146b37b) --- po/ru.po | 258 +++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 128 insertions(+), 130 deletions(-) diff --git a/po/ru.po b/po/ru.po index 52762fdd8..9e897b0b0 100644 --- a/po/ru.po +++ b/po/ru.po @@ -24,8 +24,8 @@ msgstr "" "Project-Id-Version: ru\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-control-center/" "issues\n" -"POT-Creation-Date: 2018-02-23 19:10+0000\n" -"PO-Revision-Date: 2018-03-05 16:11+0300\n" +"POT-Creation-Date: 2018-03-26 22:21+0000\n" +"PO-Revision-Date: 2018-04-12 14:35+0300\n" "Last-Translator: Stas Solovey \n" "Language-Team: Русский \n" "Language: ru\n" @@ -120,7 +120,7 @@ msgstr "Можно добавить изображения в папку %s и #: panels/background/cc-background-chooser-dialog.c:560 #: panels/color/cc-color-panel.c:225 panels/color/cc-color-panel.c:963 #: panels/color/color-calibrate.ui:25 panels/color/color.ui:657 -#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2594 +#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2597 #: panels/network/connection-editor/connection-editor.ui:15 #: panels/network/connection-editor/vpn-helpers.c:181 #: panels/network/connection-editor/vpn-helpers.c:310 @@ -136,10 +136,10 @@ msgstr "Можно добавить изображения в папку %s и #: panels/user-accounts/data/join-dialog.ui:20 #: panels/user-accounts/data/password-dialog.ui:21 #: panels/user-accounts/um-fingerprint-dialog.c:261 -#: panels/user-accounts/um-photo-dialog.c:102 -#: panels/user-accounts/um-photo-dialog.c:229 -#: panels/user-accounts/um-user-panel.c:635 -#: panels/user-accounts/um-user-panel.c:653 +#: panels/user-accounts/um-photo-dialog.c:103 +#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-user-panel.c:634 +#: panels/user-accounts/um-user-panel.c:652 msgid "_Cancel" msgstr "_Отменить" @@ -918,12 +918,12 @@ msgstr "Вчера" #. Translators: This is a date format string in the style of "Feb 24". #: panels/common/cc-util.c:138 msgid "%b %e" -msgstr "%e %b." +msgstr "%-d %b" #. Translators: This is a date format string in the style of "Feb 24, 2013". #: panels/common/cc-util.c:143 msgid "%b %e, %Y" -msgstr "%e %b. %Y" +msgstr "%-d %b %Y" #: panels/common/language-chooser.ui:5 msgid "Language" @@ -944,17 +944,15 @@ msgstr "Месяц" msgid "Year" msgstr "Год" -# fix даты #. Translators: This is the full date and time format used in 12-hour mode. #: panels/datetime/cc-datetime-panel.c:333 msgid "%e %B %Y, %l:%M %p" -msgstr "%e %b. %Y, %l:%M %p" +msgstr "%-d %B %Y, %-l∶%M %p" -# fix даты #. Translators: This is the full date and time format used in 24-hour mode. #: panels/datetime/cc-datetime-panel.c:338 msgid "%e %B %Y, %R" -msgstr "%e %b. %Y, %R" +msgstr "%-d %B %Y, %R" #. Translators: "city, country" #: panels/datetime/cc-datetime-panel.c:503 @@ -980,7 +978,7 @@ msgstr "UTC%:::z" #. Translators: This is the time format used in 12-hour mode. #: panels/datetime/cc-datetime-panel.c:542 msgid "%l:%M %p" -msgstr "%l:%M %p" +msgstr "%-l∶%M %p" #. Translators: This is the time format used in 24-hour mode. #: panels/datetime/cc-datetime-panel.c:547 @@ -1123,58 +1121,58 @@ msgstr "Изменить системное время и дату" msgid "To change time or date settings, you need to authenticate." msgstr "Для изменения времени или даты требуется аутентификация." -#: panels/display/cc-display-panel.c:729 +#: panels/display/cc-display-panel.c:732 msgctxt "Display rotation" msgid "Landscape" msgstr "Ландшафтная" -#: panels/display/cc-display-panel.c:732 +#: panels/display/cc-display-panel.c:735 msgctxt "Display rotation" msgid "Portrait Right" msgstr "Портретная справа" -#: panels/display/cc-display-panel.c:735 +#: panels/display/cc-display-panel.c:738 msgctxt "Display rotation" msgid "Portrait Left" msgstr "Портретная слева" -#: panels/display/cc-display-panel.c:738 +#: panels/display/cc-display-panel.c:741 msgctxt "Display rotation" msgid "Landscape (flipped)" msgstr "Ландшафтная (перевернутая)" #. Translators: This option sets orientation of print (portrait, landscape...) -#: panels/display/cc-display-panel.c:805 +#: panels/display/cc-display-panel.c:808 #: panels/printers/pp-options-dialog.c:558 msgid "Orientation" msgstr "Ориентация" -#: panels/display/cc-display-panel.c:870 panels/display/cc-display-panel.c:1673 +#: panels/display/cc-display-panel.c:873 panels/display/cc-display-panel.c:1676 #: panels/printers/pp-options-dialog.c:87 msgid "Resolution" msgstr "Разрешение" -#: panels/display/cc-display-panel.c:958 +#: panels/display/cc-display-panel.c:961 msgid "Refresh Rate" msgstr "Частота обновления" -#: panels/display/cc-display-panel.c:1095 +#: panels/display/cc-display-panel.c:1098 msgid "Scale" msgstr "Масштаб" -#: panels/display/cc-display-panel.c:1148 +#: panels/display/cc-display-panel.c:1151 msgid "Adjust for TV" msgstr "Отрегулировать для ТВ" -#: panels/display/cc-display-panel.c:1410 +#: panels/display/cc-display-panel.c:1413 msgid "Primary Display" msgstr "Основной дисплей" -#: panels/display/cc-display-panel.c:1439 +#: panels/display/cc-display-panel.c:1442 msgid "Display Arrangement" msgstr "Расположение дисплея" -#: panels/display/cc-display-panel.c:1440 +#: panels/display/cc-display-panel.c:1443 msgid "" "Drag displays to match your setup. The top bar is placed on the primary " "display." @@ -1182,41 +1180,41 @@ msgstr "" "Перетащите дисплеи в соответствии с нужной конфигурацией. Верхняя панель " "помещается на основной дисплей." -#: panels/display/cc-display-panel.c:1863 +#: panels/display/cc-display-panel.c:1866 msgid "Display Mode" msgstr "Режим дисплея" -#: panels/display/cc-display-panel.c:1879 +#: panels/display/cc-display-panel.c:1882 msgid "Join Displays" msgstr "Объединить дисплеи" -#: panels/display/cc-display-panel.c:1882 +#: panels/display/cc-display-panel.c:1885 msgid "Mirror" msgstr "Зеркальное отображение" -#: panels/display/cc-display-panel.c:1885 +#: panels/display/cc-display-panel.c:1888 msgid "Single Display" msgstr "Один дисплей" -#: panels/display/cc-display-panel.c:2590 +#: panels/display/cc-display-panel.c:2593 msgid "Apply Changes?" msgstr "Применить изменения?" -#: panels/display/cc-display-panel.c:2604 +#: panels/display/cc-display-panel.c:2607 #: panels/network/connection-editor/connection-editor.ui:24 #: panels/network/network-wifi.ui:38 msgid "_Apply" msgstr "_Применить" -#: panels/display/cc-display-panel.c:2979 +#: panels/display/cc-display-panel.c:2982 #, c-format msgid "%.2lf Hz" msgstr "%.2lf Гц" #. TRANSLATORS: the state of the night light setting -#: panels/display/cc-display-panel.c:3195 +#: panels/display/cc-display-panel.c:3198 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1991 panels/power/cc-power-panel.c:1998 +#: panels/power/cc-power-panel.c:1994 panels/power/cc-power-panel.c:2001 #: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 #: panels/universal-access/cc-ua-panel.c:333 #: panels/universal-access/cc-ua-panel.c:714 @@ -1226,9 +1224,9 @@ msgstr "%.2lf Гц" msgid "On" msgstr "Включено" -#: panels/display/cc-display-panel.c:3195 panels/network/net-proxy.c:54 +#: panels/display/cc-display-panel.c:3198 panels/network/net-proxy.c:54 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1985 panels/power/cc-power-panel.c:1996 +#: panels/power/cc-power-panel.c:1988 panels/power/cc-power-panel.c:1999 #: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 #: panels/universal-access/cc-ua-panel.c:333 #: panels/universal-access/cc-ua-panel.c:714 @@ -1242,11 +1240,11 @@ msgstr "Включено" msgid "Off" msgstr "Выключено" -#: panels/display/cc-display-panel.c:3216 +#: panels/display/cc-display-panel.c:3219 msgid "_Night Light" msgstr "_Ночная подсветка" -#: panels/display/cc-display-panel.c:3281 +#: panels/display/cc-display-panel.c:3284 msgid "Could not get screen information" msgstr "Не удалось получить информацию об экране" @@ -1693,8 +1691,8 @@ msgstr "Запуск приложений" msgid "Launch help browser" msgstr "Запустить справочный браузер" -#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:223 -#: shell/cc-window.c:761 shell/gnome-control-center.desktop.in.in:3 +#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:222 +#: shell/cc-window.c:760 shell/gnome-control-center.desktop.in.in:3 #: shell/window.ui:125 msgid "Settings" msgstr "Параметры" @@ -2118,8 +2116,8 @@ msgstr "Прокси" #. * window for vpn connections, it is also used to display #. * vpn connections in the device list. #. -#: panels/network/cc-network-panel.c:715 panels/network/net-vpn.c:192 -#: panels/network/net-vpn.c:321 +#: panels/network/cc-network-panel.c:715 panels/network/net-vpn.c:167 +#: panels/network/net-vpn.c:296 #, c-format msgid "%s VPN" msgstr "VPN %s" @@ -2136,7 +2134,7 @@ msgstr "NetworkManager должен быть запущен." #: panels/network/cc-wifi-panel.c:213 #: panels/network/gnome-wifi-panel.desktop.in.in:3 -#: panels/network/network-wifi.ui:1766 +#: panels/network/network-wifi.ui:1769 msgid "Wi-Fi" msgstr "Wi-Fi" @@ -2281,7 +2279,7 @@ msgid "Remove VPN" msgstr "Удалить VPN" #: panels/network/connection-editor/ce-page-details.c:334 -#: panels/network/network-wifi.ui:1456 shell/cc-window.c:215 +#: panels/network/network-wifi.ui:1456 shell/cc-window.c:214 #: shell/panel-list.ui:103 msgid "Details" msgstr "Подробности" @@ -2618,7 +2616,7 @@ msgstr "Выберите файл для импортирования" #: panels/network/connection-editor/vpn-helpers.c:182 #: panels/printers/pp-details-dialog.c:332 #: panels/sharing/cc-sharing-panel.c:385 -#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-photo-dialog.c:231 msgid "_Open" msgstr "_Открыть" @@ -3040,19 +3038,19 @@ msgctxt "Wi-Fi passkey" msgid "Password" msgstr "Пароль" -#: panels/network/network-wifi.ui:1796 +#: panels/network/network-wifi.ui:1799 msgid "Turn Wi-Fi off" msgstr "Выключить Wi-Fi" -#: panels/network/network-wifi.ui:1828 +#: panels/network/network-wifi.ui:1831 msgid "_Connect to Hidden Network…" msgstr "_Подключиться к скрытой сети…" -#: panels/network/network-wifi.ui:1838 +#: panels/network/network-wifi.ui:1841 msgid "_Turn On Wi-Fi Hotspot…" msgstr "_Включить точку доступа Wi-Fi…" -#: panels/network/network-wifi.ui:1848 +#: panels/network/network-wifi.ui:1851 msgid "_Known Wi-Fi Networks" msgstr "_Известные сети Wi-Fi" @@ -3361,23 +3359,23 @@ msgstr "Отсутствует прошивка" msgid "Cable unplugged" msgstr "Кабель не подключён" -#: panels/network/wireless-security/eap-method.c:57 +#: panels/network/wireless-security/eap-method.c:69 msgid "undefined error in 802.1X security (wpa-eap)" msgstr "неизвестная ошибка в безопасности 802.1X (wpa-eap)" -#: panels/network/wireless-security/eap-method.c:233 +#: panels/network/wireless-security/eap-method.c:245 msgid "no file selected" msgstr "файлы не выбраны" -#: panels/network/wireless-security/eap-method.c:264 +#: panels/network/wireless-security/eap-method.c:276 msgid "unspecified error validating eap-method file" msgstr "неизвестная ошибка проверки файла ЕАР-методом" -#: panels/network/wireless-security/eap-method.c:439 +#: panels/network/wireless-security/eap-method.c:451 msgid "DER, PEM, or PKCS#12 private keys (*.der, *.pem, *.p12, *.key)" msgstr "DER, PEM, или приватные ключи PKCS#12 (*.der, *.pem, *.p12, *.key)" -#: panels/network/wireless-security/eap-method.c:442 +#: panels/network/wireless-security/eap-method.c:454 msgid "DER or PEM certificates (*.der, *.pem, *.crt, *.cer)" msgstr "Сертификаты DER или PEM (*.der, *.pem, *.crt, *.cer)" @@ -3796,19 +3794,19 @@ msgstr "Другое" #. translators: This is the title of the "Show Account" dialog. The #. * %s is the name of the provider. e.g., 'Google'. -#: panels/online-accounts/cc-online-accounts-panel.c:551 +#: panels/online-accounts/cc-online-accounts-panel.c:596 #, c-format msgid "%s Account" msgstr "Учётная запись %s" -#: panels/online-accounts/cc-online-accounts-panel.c:843 +#: panels/online-accounts/cc-online-accounts-panel.c:888 msgid "Error removing account" msgstr "Ошибка при удалении учётной записи" #. Translators: The %s is the username (eg., debarshi.ray@gmail.com #. * or rishi). #. -#: panels/online-accounts/cc-online-accounts-panel.c:908 +#: panels/online-accounts/cc-online-accounts-panel.c:953 #, c-format msgid "%s removed" msgstr "%s удалён" @@ -3998,7 +3996,7 @@ msgstr "Игровое устройство ввода" #. TRANSLATORS: secondary battery, misc #: panels/power/cc-power-panel.c:564 panels/power/cc-power-panel.c:804 -#: panels/power/cc-power-panel.c:2377 +#: panels/power/cc-power-panel.c:2380 msgid "Battery" msgstr "Батарея" @@ -4042,102 +4040,102 @@ msgstr "Полностью разряжена" msgid "Batteries" msgstr "Батареи" -#: panels/power/cc-power-panel.c:1239 +#: panels/power/cc-power-panel.c:1242 msgid "When _idle" msgstr "При п_ростое" -#: panels/power/cc-power-panel.c:1693 +#: panels/power/cc-power-panel.c:1696 msgid "Power Saving" msgstr "Энергосбережение" -#: panels/power/cc-power-panel.c:1724 +#: panels/power/cc-power-panel.c:1727 msgid "_Screen brightness" msgstr "Яркость _экрана" -#: panels/power/cc-power-panel.c:1743 +#: panels/power/cc-power-panel.c:1746 msgid "Automatic brightness" msgstr "Автоматическая регулировка яркости" -#: panels/power/cc-power-panel.c:1763 +#: panels/power/cc-power-panel.c:1766 msgid "_Keyboard brightness" msgstr "Яркость подсветки _клавиатуры" -#: panels/power/cc-power-panel.c:1773 +#: panels/power/cc-power-panel.c:1776 msgid "_Dim screen when inactive" msgstr "У_меньшать яркость экрана при простое" -#: panels/power/cc-power-panel.c:1798 +#: panels/power/cc-power-panel.c:1801 msgid "_Blank screen" msgstr "_Выключение экрана" -#: panels/power/cc-power-panel.c:1835 +#: panels/power/cc-power-panel.c:1838 msgid "_Wi-Fi" msgstr "_Wi-Fi" -#: panels/power/cc-power-panel.c:1840 +#: panels/power/cc-power-panel.c:1843 msgid "Turn off Wi-Fi to save power." msgstr "Выключите Wi-Fi для уменьшения энергопотребления." -#: panels/power/cc-power-panel.c:1865 +#: panels/power/cc-power-panel.c:1868 msgid "_Mobile broadband" msgstr "_Мобильный Интернет" -#: panels/power/cc-power-panel.c:1870 +#: panels/power/cc-power-panel.c:1873 msgid "Turn off mobile broadband (3G, 4G, LTE, etc.) to save power." msgstr "" "Выключите адаптер мобильного широкополосного доступа (3G, 4G, WiMax и т.д.) " "для уменьшения энергопотребления." -#: panels/power/cc-power-panel.c:1923 +#: panels/power/cc-power-panel.c:1926 msgid "_Bluetooth" msgstr "_Bluetooth" -#: panels/power/cc-power-panel.c:1928 +#: panels/power/cc-power-panel.c:1931 msgid "Turn off Bluetooth to save power." msgstr "Выключите Bluetooth для уменьшения энергопотребления." -#: panels/power/cc-power-panel.c:1987 +#: panels/power/cc-power-panel.c:1990 msgid "When on battery power" msgstr "При работе от батареи" -#: panels/power/cc-power-panel.c:1989 +#: panels/power/cc-power-panel.c:1992 msgid "When plugged in" msgstr "При подключении" -#: panels/power/cc-power-panel.c:2084 +#: panels/power/cc-power-panel.c:2087 msgid "Suspend" msgstr "Перевести в режим ожидания" -#: panels/power/cc-power-panel.c:2085 +#: panels/power/cc-power-panel.c:2088 msgid "Power Off" msgstr "Выключить" -#: panels/power/cc-power-panel.c:2086 +#: panels/power/cc-power-panel.c:2089 msgid "Hibernate" msgstr "Перевести в режим гибернации" -#: panels/power/cc-power-panel.c:2087 +#: panels/power/cc-power-panel.c:2090 msgid "Nothing" msgstr "Ничего не делать" #. Frame header -#: panels/power/cc-power-panel.c:2201 +#: panels/power/cc-power-panel.c:2204 msgid "Suspend & Power Button" msgstr "Режим ожидания и кнопка выключения" -#: panels/power/cc-power-panel.c:2240 +#: panels/power/cc-power-panel.c:2243 msgid "_Automatic suspend" msgstr "_Автоматический режим ожидания" -#: panels/power/cc-power-panel.c:2241 +#: panels/power/cc-power-panel.c:2244 msgid "Automatic suspend" msgstr "Автоматический режим ожидания" -#: panels/power/cc-power-panel.c:2308 +#: panels/power/cc-power-panel.c:2311 msgid "_When the Power Button is pressed" msgstr "_При нажатии кнопки выключения" -#: panels/power/cc-power-panel.c:2427 shell/cc-window.c:219 +#: panels/power/cc-power-panel.c:2430 shell/cc-window.c:218 #: shell/panel-list.ui:45 msgid "Devices" msgstr "Устройства" @@ -4288,18 +4286,18 @@ msgid "Authentication Required" msgstr "Требуется аутентификация" #. Translators: %s is the printer name -#: panels/printers/cc-printers-panel.c:791 +#: panels/printers/cc-printers-panel.c:808 #, c-format msgid "Printer “%s” has been deleted" msgstr "Принтер «%s» удалён" #. Translators: Addition of the new printer failed. -#: panels/printers/cc-printers-panel.c:1036 +#: panels/printers/cc-printers-panel.c:1053 msgid "Failed to add new printer." msgstr "Не удалось добавить новый принтер." #. Translators: The XML file containing user interface can not be loaded -#: panels/printers/cc-printers-panel.c:1371 +#: panels/printers/cc-printers-panel.c:1388 #, c-format msgid "Could not load ui: %s" msgstr "Не удалось загрузить интерфейс пользователя: %s" @@ -4436,7 +4434,7 @@ msgid "Select Printer Driver" msgstr "Выберите драйвер принтера" #: panels/printers/ppd-selection-dialog.ui:40 -#: panels/user-accounts/um-photo-dialog.c:104 +#: panels/user-accounts/um-photo-dialog.c:105 msgid "Select" msgstr "Выбрать" @@ -4493,55 +4491,55 @@ msgid "Reverse portrait" msgstr "Перевёрнутая портретная" #. Translators: Job's state (job is waiting to be printed) -#: panels/printers/pp-jobs-dialog.c:243 +#: panels/printers/pp-jobs-dialog.c:234 msgctxt "print job" msgid "Pending" msgstr "Ожидание" #. Translators: Job's state (job is held for printing) -#: panels/printers/pp-jobs-dialog.c:249 +#: panels/printers/pp-jobs-dialog.c:240 msgctxt "print job" msgid "Paused" msgstr "Приостановлено" #. Translators: Job's state (job needs authentication to proceed further) -#: panels/printers/pp-jobs-dialog.c:254 +#: panels/printers/pp-jobs-dialog.c:245 msgctxt "print job" msgid "Authentication required" msgstr "Требуется аутентификация" #. Translators: Job's state (job is currently printing) -#: panels/printers/pp-jobs-dialog.c:259 +#: panels/printers/pp-jobs-dialog.c:250 msgctxt "print job" msgid "Processing" msgstr "Выполняется" #. Translators: Job's state (job has been stopped) -#: panels/printers/pp-jobs-dialog.c:263 +#: panels/printers/pp-jobs-dialog.c:254 msgctxt "print job" msgid "Stopped" msgstr "Остановлено" #. Translators: Job's state (job has been canceled) -#: panels/printers/pp-jobs-dialog.c:267 +#: panels/printers/pp-jobs-dialog.c:258 msgctxt "print job" msgid "Canceled" msgstr "Отменено" #. Translators: Job's state (job has aborted due to error) -#: panels/printers/pp-jobs-dialog.c:271 +#: panels/printers/pp-jobs-dialog.c:262 msgctxt "print job" msgid "Aborted" msgstr "Прервано" #. Translators: Job's state (job has completed successfully) -#: panels/printers/pp-jobs-dialog.c:275 +#: panels/printers/pp-jobs-dialog.c:266 msgctxt "print job" msgid "Completed" msgstr "Выполнено" #. Translators: This label shows how many jobs of this printer needs to be authenticated to be printed. -#: panels/printers/pp-jobs-dialog.c:399 +#: panels/printers/pp-jobs-dialog.c:390 #, c-format msgid "%u Job Requires Authentication" msgid_plural "%u Jobs Require Authentication" @@ -4550,14 +4548,14 @@ msgstr[1] "%u задания требуют аутентификацию" msgstr[2] "%u заданий требуют аутентификацию" #. Translators: This is the printer name for which we are showing the active jobs -#: panels/printers/pp-jobs-dialog.c:617 +#: panels/printers/pp-jobs-dialog.c:620 #, c-format msgctxt "Printer jobs dialog title" msgid "%s — Active Jobs" msgstr "Текущие задания — %s" #. Translators: The printer needs authentication info to print. -#: panels/printers/pp-jobs-dialog.c:622 +#: panels/printers/pp-jobs-dialog.c:625 #, c-format msgid "Enter credentials to print from %s." msgstr "Введите учётные данные для печати из %s." @@ -6930,14 +6928,14 @@ msgstr "На прошлой неделе" #: panels/user-accounts/um-history-dialog.c:83 msgctxt "login history week label" msgid "%b %e" -msgstr "%e %b." +msgstr "%-d %b" #. Translators: This is a date format string in the style of "Feb 24, 2013", #. shown as the last day of a week on login history dialog. #: panels/user-accounts/um-history-dialog.c:88 msgctxt "login history week label" msgid "%b %e, %Y" -msgstr "%e %b. %Y" +msgstr "%-d %b %Y" #. Translators: This indicates a week label on a login history. #. The first %s is the first day of a week, and the second %s the last day. @@ -6950,7 +6948,7 @@ msgstr "%s — %s" #. Translators: This is a time format string in the style of "22:58". #. It indicates a login time which follows a date. #: panels/user-accounts/um-history-dialog.c:177 -#: panels/user-accounts/um-user-panel.c:767 +#: panels/user-accounts/um-user-panel.c:766 msgctxt "login date-time" msgid "%k:%M" msgstr "%k:%M" @@ -6958,7 +6956,7 @@ msgstr "%k:%M" #. Translators: This indicates a login date-time. #. The first %s is a date, and the second %s a time. #: panels/user-accounts/um-history-dialog.c:180 -#: panels/user-accounts/um-user-panel.c:771 +#: panels/user-accounts/um-user-panel.c:770 #, c-format msgctxt "login date-time" msgid "%s, %s" @@ -6995,7 +6993,7 @@ msgstr "Не удалось изменить пароль" msgid "The passwords do not match." msgstr "Пароли не совпадают." -#: panels/user-accounts/um-photo-dialog.c:226 +#: panels/user-accounts/um-photo-dialog.c:227 msgid "Browse for more pictures" msgstr "Найти дополнительные изображения" @@ -7023,30 +7021,30 @@ msgstr "Неправильный пароль, попробуйте ещё ра msgid "Couldn’t connect to the %s domain: %s" msgstr "Не удалось подключиться к домену %s: %s" -#: panels/user-accounts/um-user-panel.c:201 +#: panels/user-accounts/um-user-panel.c:200 msgid "Your account" msgstr "Ваша учётная запись" -#: panels/user-accounts/um-user-panel.c:381 +#: panels/user-accounts/um-user-panel.c:380 msgid "Failed to delete user" msgstr "Не удалось удалить пользователя" -#: panels/user-accounts/um-user-panel.c:439 -#: panels/user-accounts/um-user-panel.c:498 -#: panels/user-accounts/um-user-panel.c:550 +#: panels/user-accounts/um-user-panel.c:438 +#: panels/user-accounts/um-user-panel.c:497 +#: panels/user-accounts/um-user-panel.c:549 msgid "Failed to revoke remotely managed user" msgstr "Не удалось аннулировать удалённого пользователя" -#: panels/user-accounts/um-user-panel.c:604 +#: panels/user-accounts/um-user-panel.c:603 msgid "You cannot delete your own account." msgstr "Нельзя удалить собственную учётную запись." -#: panels/user-accounts/um-user-panel.c:613 +#: panels/user-accounts/um-user-panel.c:612 #, c-format msgid "%s is still logged in" msgstr "%s всё ещё находится в системе" -#: panels/user-accounts/um-user-panel.c:617 +#: panels/user-accounts/um-user-panel.c:616 msgid "" "Deleting a user while they are logged in can leave the system in an " "inconsistent state." @@ -7054,12 +7052,12 @@ msgstr "" "Удаление пользователя, с незавершённым сеансом, может привести систему в " "противоречивое состояние." -#: panels/user-accounts/um-user-panel.c:626 +#: panels/user-accounts/um-user-panel.c:625 #, c-format msgid "Do you want to keep %s’s files?" msgstr "Хотите сохранить файлы пользователя %s?" -#: panels/user-accounts/um-user-panel.c:630 +#: panels/user-accounts/um-user-panel.c:629 msgid "" "It is possible to keep the home directory, mail spool and temporary files " "around when deleting a user account." @@ -7067,47 +7065,47 @@ msgstr "" "Можно сохранить домашнюю папку, почтовый ящик и временные файлы при удалении " "учётной записи пользователя." -#: panels/user-accounts/um-user-panel.c:633 +#: panels/user-accounts/um-user-panel.c:632 msgid "_Delete Files" msgstr "_Удалить файлы" -#: panels/user-accounts/um-user-panel.c:634 +#: panels/user-accounts/um-user-panel.c:633 msgid "_Keep Files" msgstr "_Сохранить файлы" -#: panels/user-accounts/um-user-panel.c:648 +#: panels/user-accounts/um-user-panel.c:647 #, c-format msgid "Are you sure you want to revoke remotely managed %s’s account?" msgstr "Действительно аннулировать удалённую учётную запись %s?" -#: panels/user-accounts/um-user-panel.c:652 +#: panels/user-accounts/um-user-panel.c:651 msgid "_Delete" msgstr "_Удалить" -#: panels/user-accounts/um-user-panel.c:702 +#: panels/user-accounts/um-user-panel.c:701 msgctxt "Password mode" msgid "Account disabled" msgstr "Учётная запись отключена" -#: panels/user-accounts/um-user-panel.c:710 +#: panels/user-accounts/um-user-panel.c:709 msgctxt "Password mode" msgid "To be set at next login" msgstr "Установить при следующем входе в систему" -#: panels/user-accounts/um-user-panel.c:713 +#: panels/user-accounts/um-user-panel.c:712 msgctxt "Password mode" msgid "None" msgstr "Нет" -#: panels/user-accounts/um-user-panel.c:760 +#: panels/user-accounts/um-user-panel.c:759 msgid "Logged in" msgstr "Авторизованный" -#: panels/user-accounts/um-user-panel.c:1107 +#: panels/user-accounts/um-user-panel.c:1106 msgid "Failed to contact the accounts service" msgstr "Не удалось связаться со службой учётных записей" -#: panels/user-accounts/um-user-panel.c:1109 +#: panels/user-accounts/um-user-panel.c:1108 msgid "Please make sure that the AccountService is installed and enabled." msgstr "Убедитесь, что AccountService установлен и включён." @@ -7115,7 +7113,7 @@ msgstr "Убедитесь, что AccountService установлен и вкл #. * We split the line in 2 here to "make it look good", as there's #. * no good way to do this in GTK+ for tooltips. See: #. * https://bugzilla.gnome.org/show_bug.cgi?id=657168 -#: panels/user-accounts/um-user-panel.c:1141 +#: panels/user-accounts/um-user-panel.c:1140 msgid "" "To make changes,\n" "click the * icon first" @@ -7123,12 +7121,12 @@ msgstr "" "Чтобы изменить,\n" "сначала нажмите на значок *" -#: panels/user-accounts/um-user-panel.c:1181 +#: panels/user-accounts/um-user-panel.c:1180 msgid "Create a user account" msgstr "Создать учётную запись пользователя" -#: panels/user-accounts/um-user-panel.c:1192 -#: panels/user-accounts/um-user-panel.c:1371 +#: panels/user-accounts/um-user-panel.c:1191 +#: panels/user-accounts/um-user-panel.c:1370 msgid "" "To create a user account,\n" "click the * icon first" @@ -7136,12 +7134,12 @@ msgstr "" "Чтобы создать учётную запись пользователя,\n" "сначала нажмите на значок *" -#: panels/user-accounts/um-user-panel.c:1202 +#: panels/user-accounts/um-user-panel.c:1201 msgid "Delete the selected user account" msgstr "Удалить выбранную учётную запись пользователя" -#: panels/user-accounts/um-user-panel.c:1214 -#: panels/user-accounts/um-user-panel.c:1376 +#: panels/user-accounts/um-user-panel.c:1213 +#: panels/user-accounts/um-user-panel.c:1375 msgid "" "To delete the selected user account,\n" "click the * icon first" -- cgit v1.2.1 From 47f241b10ccfc59cb879b15e09f7c9759131a096 Mon Sep 17 00:00:00 2001 From: Christian Kellner Date: Mon, 26 Mar 2018 16:18:30 +0200 Subject: thunderbolt: new panel for device management Thunderbolt devices need to be approved before they can be used. This is done via the boltd system daemon and gnome-shell. The new panel enables the user to manage thunderbolt devices, i.e.: - forget devices that have previously been authorized - authorize currently unauthorize devices Additionally authorization of devices an be temporarily disabled to ensure no evil device will gain access to the computers resources. File starting with "bolt-" are copied from bolt's source tree and currently correspond to the bolt upstream commit with the id f22b1cd6104bdc2b33a95d9896b50f29a141b8d8 They can be updated from bolt via the update-from-bolt.sh script. --- meson.build | 3 + panels/meson.build | 1 + panels/thunderbolt/bolt-client.c | 697 +++++++++++++++ panels/thunderbolt/bolt-client.h | 107 +++ panels/thunderbolt/bolt-device.c | 604 +++++++++++++ panels/thunderbolt/bolt-device.h | 87 ++ panels/thunderbolt/bolt-enums.c | 395 +++++++++ panels/thunderbolt/bolt-enums.h | 249 ++++++ panels/thunderbolt/bolt-error.c | 99 +++ panels/thunderbolt/bolt-error.h | 55 ++ panels/thunderbolt/bolt-names.h | 50 ++ panels/thunderbolt/bolt-proxy.c | 514 +++++++++++ panels/thunderbolt/bolt-proxy.h | 97 +++ panels/thunderbolt/bolt-str.c | 117 +++ panels/thunderbolt/bolt-str.h | 43 + panels/thunderbolt/bolt-time.c | 44 + panels/thunderbolt/bolt-time.h | 32 + panels/thunderbolt/cc-bolt-device-dialog.c | 476 ++++++++++ panels/thunderbolt/cc-bolt-device-dialog.h | 45 + panels/thunderbolt/cc-bolt-device-dialog.ui | 359 ++++++++ panels/thunderbolt/cc-bolt-device-entry.c | 218 +++++ panels/thunderbolt/cc-bolt-device-entry.h | 34 + panels/thunderbolt/cc-bolt-device-entry.ui | 49 ++ panels/thunderbolt/cc-bolt-panel.c | 958 +++++++++++++++++++++ panels/thunderbolt/cc-bolt-panel.ui | 594 +++++++++++++ .../gnome-thunderbolt-panel.desktop.in.in | 17 + panels/thunderbolt/meson.build | 74 ++ panels/thunderbolt/thunderbolt.gresource.xml | 9 + panels/thunderbolt/update-from-bolt.sh | 50 ++ shell/cc-panel-list.c | 1 + shell/cc-panel-loader.c | 6 + 31 files changed, 6084 insertions(+) create mode 100644 panels/thunderbolt/bolt-client.c create mode 100644 panels/thunderbolt/bolt-client.h create mode 100644 panels/thunderbolt/bolt-device.c create mode 100644 panels/thunderbolt/bolt-device.h create mode 100644 panels/thunderbolt/bolt-enums.c create mode 100644 panels/thunderbolt/bolt-enums.h create mode 100644 panels/thunderbolt/bolt-error.c create mode 100644 panels/thunderbolt/bolt-error.h create mode 100644 panels/thunderbolt/bolt-names.h create mode 100644 panels/thunderbolt/bolt-proxy.c create mode 100644 panels/thunderbolt/bolt-proxy.h create mode 100644 panels/thunderbolt/bolt-str.c create mode 100644 panels/thunderbolt/bolt-str.h create mode 100644 panels/thunderbolt/bolt-time.c create mode 100644 panels/thunderbolt/bolt-time.h create mode 100644 panels/thunderbolt/cc-bolt-device-dialog.c create mode 100644 panels/thunderbolt/cc-bolt-device-dialog.h create mode 100644 panels/thunderbolt/cc-bolt-device-dialog.ui create mode 100644 panels/thunderbolt/cc-bolt-device-entry.c create mode 100644 panels/thunderbolt/cc-bolt-device-entry.h create mode 100644 panels/thunderbolt/cc-bolt-device-entry.ui create mode 100644 panels/thunderbolt/cc-bolt-panel.c create mode 100644 panels/thunderbolt/cc-bolt-panel.ui create mode 100644 panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in create mode 100644 panels/thunderbolt/meson.build create mode 100644 panels/thunderbolt/thunderbolt.gresource.xml create mode 100755 panels/thunderbolt/update-from-bolt.sh diff --git a/meson.build b/meson.build index dfc14f106..fb74d04d1 100644 --- a/meson.build +++ b/meson.build @@ -206,6 +206,7 @@ if host_is_linux_not_s390 description: 'Define to 1 if libwacom provides definition for 3D styli') else message('Bluetooth and Wacom panels will not be built (no USB support on this platform)') + message('Thunderbolt panel will not be built (not supported on this platform)') endif config_h.set('BUILD_BLUETOOTH', host_is_linux_not_s390, description: 'Define to 1 to build the Bluetooth panel') @@ -215,6 +216,8 @@ config_h.set('BUILD_WACOM', host_is_linux_not_s390, description: 'Define to 1 to build the Wacom panel') config_h.set('HAVE_WACOM', host_is_linux_not_s390, description: 'Define to 1 if Wacom is supportted') +config_h.set('BUILD_THUNDERBOLT', host_is_linux_not_s390, + description: 'Define to 1 to build the Thunderbolt panel') # Check for info panel gnome_session_libexecdir = get_option('gnome_session_libexecdir') diff --git a/panels/meson.build b/panels/meson.build index d671c4775..37a343642 100644 --- a/panels/meson.build +++ b/panels/meson.build @@ -28,6 +28,7 @@ endif if host_is_linux_not_s390 panels += [ 'bluetooth', + 'thunderbolt', 'wacom' ] endif diff --git a/panels/thunderbolt/bolt-client.c b/panels/thunderbolt/bolt-client.c new file mode 100644 index 000000000..0ebc360b1 --- /dev/null +++ b/panels/thunderbolt/bolt-client.c @@ -0,0 +1,697 @@ +/* + * Copyright © 2017 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Christian J. Kellner + */ + +#include "bolt-client.h" + +#include "bolt-device.h" +#include "bolt-error.h" +#include "bolt-names.h" + +#include + +static void handle_dbus_device_added (GObject *self, + GDBusProxy *bus_proxy, + GVariant *params); +static void handle_dbus_device_removed (GObject *self, + GDBusProxy *bus_proxy, + GVariant *params); + +struct _BoltClient +{ + BoltProxy parent; +}; + +enum { + PROP_0, + + /* D-Bus Props */ + PROP_VERSION, + PROP_PROBING, + PROP_SECURITY, + PROP_AUTHMODE, + + PROP_LAST +}; + +static GParamSpec *props[PROP_LAST] = {NULL, }; + +enum { + SIGNAL_DEVICE_ADDED, + SIGNAL_DEVICE_REMOVED, + SIGNAL_LAST +}; + +static guint signals[SIGNAL_LAST] = {0}; + + +G_DEFINE_TYPE (BoltClient, + bolt_client, + BOLT_TYPE_PROXY); + + +static void +bolt_client_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + if (bolt_proxy_get_dbus_property (object, pspec, value)) + return; + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +} + +static const BoltProxySignal * +bolt_client_get_dbus_signals (guint *n) +{ + static BoltProxySignal dbus_signals[] = { + {"DeviceAdded", handle_dbus_device_added}, + {"DeviceRemoved", handle_dbus_device_removed}, + }; + + *n = G_N_ELEMENTS (dbus_signals); + + return dbus_signals; +} + + +static void +bolt_client_class_init (BoltClientClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + BoltProxyClass *proxy_class = BOLT_PROXY_CLASS (klass); + + gobject_class->get_property = bolt_client_get_property; + + proxy_class->get_dbus_signals = bolt_client_get_dbus_signals; + + props[PROP_VERSION] + = g_param_spec_uint ("version", + "Version", NULL, + 0, G_MAXUINT, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME); + + props[PROP_PROBING] + = g_param_spec_boolean ("probing", + "Probing", NULL, + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME); + + props[PROP_SECURITY] + = g_param_spec_enum ("security-level", + "SecurityLevel", NULL, + BOLT_TYPE_SECURITY, + BOLT_SECURITY_UNKNOWN, + G_PARAM_READABLE | + G_PARAM_STATIC_NAME); + + props[PROP_AUTHMODE] = + g_param_spec_flags ("auth-mode", "AuthMode", NULL, + BOLT_TYPE_AUTH_MODE, + BOLT_AUTH_ENABLED, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (gobject_class, + PROP_LAST, + props); + + /* signals */ + signals[SIGNAL_DEVICE_ADDED] = + g_signal_new ("device-added", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, + 1, G_TYPE_STRING); + + signals[SIGNAL_DEVICE_REMOVED] = + g_signal_new ("device-removed", + G_TYPE_FROM_CLASS (gobject_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, + 1, G_TYPE_STRING); +} + + +static void +bolt_client_init (BoltClient *cli) +{ +} + +/* dbus signals */ + +static void +handle_dbus_device_added (GObject *self, GDBusProxy *bus_proxy, GVariant *params) +{ + BoltClient *cli = BOLT_CLIENT (self); + const char *opath = NULL; + + g_variant_get_child (params, 0, "&o", &opath); + g_signal_emit (cli, signals[SIGNAL_DEVICE_ADDED], 0, opath); +} + +static void +handle_dbus_device_removed (GObject *self, GDBusProxy *bus_proxy, GVariant *params) +{ + BoltClient *cli = BOLT_CLIENT (self); + const char *opath = NULL; + + g_variant_get_child (params, 0, "&o", &opath); + g_signal_emit (cli, signals[SIGNAL_DEVICE_REMOVED], 0, opath); +} + +/* public methods */ + +BoltClient * +bolt_client_new (GError **error) +{ + BoltClient *cli; + GDBusConnection *bus; + + bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, error); + if (bus == NULL) + { + g_prefix_error (error, "Error connecting to D-Bus: "); + return FALSE; + } + + cli = g_initable_new (BOLT_TYPE_CLIENT, + NULL, error, + "g-flags", G_DBUS_PROXY_FLAGS_NONE, + "g-connection", bus, + "g-name", BOLT_DBUS_NAME, + "g-object-path", BOLT_DBUS_PATH, + "g-interface-name", BOLT_DBUS_INTERFACE, + NULL); + + g_object_unref (bus); + + return cli; +} + +static void +got_the_client (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + g_autoptr(GError) error = NULL; + GTask *task = user_data; + GObject *obj; + + obj = g_async_initable_new_finish (G_ASYNC_INITABLE (source), res, &error); + + if (obj == NULL) + { + g_task_return_error (task, error); + return; + } + + g_task_return_pointer (task, obj, g_object_unref); + g_object_unref (task); +} + +static void +got_the_bus (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + g_autoptr(GError) error = NULL; + GTask *task = user_data; + GCancellable *cancellable; + GDBusConnection *bus; + + bus = g_bus_get_finish (res, &error); + if (bus == NULL) + { + g_prefix_error (&error, "could not connect to D-Bus: "); + g_task_return_error (task, error); + return; + } + + cancellable = g_task_get_cancellable (task); + g_async_initable_new_async (BOLT_TYPE_CLIENT, + G_PRIORITY_DEFAULT, + cancellable, + got_the_client, task, + "g-flags", G_DBUS_PROXY_FLAGS_NONE, + "g-connection", bus, + "g-name", BOLT_DBUS_NAME, + "g-object-path", BOLT_DBUS_PATH, + "g-interface-name", BOLT_DBUS_INTERFACE, + NULL); + g_object_unref (bus); +} + +void +bolt_client_new_async (GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (NULL, cancellable, callback, user_data); + g_bus_get (G_BUS_TYPE_SYSTEM, cancellable, got_the_bus, task); +} + +BoltClient * +bolt_client_new_finish (GAsyncResult *res, + GError **error) +{ + g_return_val_if_fail (G_IS_TASK (res), NULL); + + return g_task_propagate_pointer (G_TASK (res), error); +} + +GPtrArray * +bolt_client_list_devices (BoltClient *client, + GCancellable *cancel, + GError **error) +{ + g_autoptr(GVariant) val = NULL; + g_autoptr(GPtrArray) devices = NULL; + g_autoptr(GVariantIter) iter = NULL; + GDBusConnection *bus = NULL; + const char *d; + + g_return_val_if_fail (BOLT_IS_CLIENT (client), NULL); + + val = g_dbus_proxy_call_sync (G_DBUS_PROXY (client), + "ListDevices", + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + cancel, + error); + if (val == NULL) + return NULL; + + bus = g_dbus_proxy_get_connection (G_DBUS_PROXY (client)); + + devices = g_ptr_array_new_with_free_func (g_object_unref); + + g_variant_get (val, "(ao)", &iter); + while (g_variant_iter_loop (iter, "&o", &d, NULL)) + { + BoltDevice *dev; + + dev = bolt_device_new_for_object_path (bus, d, cancel, error); + if (dev == NULL) + return NULL; + + g_ptr_array_add (devices, dev); + } + + return g_steal_pointer (&devices); +} + +BoltDevice * +bolt_client_get_device (BoltClient *client, + const char *uid, + GCancellable *cancel, + GError **error) +{ + g_autoptr(GVariant) val = NULL; + g_autoptr(GError) err = NULL; + BoltDevice *dev = NULL; + GDBusConnection *bus = NULL; + const char *opath = NULL; + + g_return_val_if_fail (BOLT_IS_CLIENT (client), NULL); + + val = g_dbus_proxy_call_sync (G_DBUS_PROXY (client), + "DeviceByUid", + g_variant_new ("(s)", uid), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancel, + &err); + + if (val == NULL) + { + bolt_error_propagate_stripped (error, &err); + return NULL; + } + + bus = g_dbus_proxy_get_connection (G_DBUS_PROXY (client)); + g_variant_get (val, "(&o)", &opath); + + if (opath == NULL) + return NULL; + + dev = bolt_device_new_for_object_path (bus, opath, cancel, error); + return dev; +} + +BoltDevice * +bolt_client_enroll_device (BoltClient *client, + const char *uid, + BoltPolicy policy, + BoltAuthCtrl flags, + GError **error) +{ + g_autoptr(GVariant) val = NULL; + g_autoptr(GError) err = NULL; + g_autofree char *fstr = NULL; + BoltDevice *dev = NULL; + GDBusConnection *bus = NULL; + GVariant *params = NULL; + const char *opath = NULL; + const char *pstr; + + g_return_val_if_fail (BOLT_IS_CLIENT (client), NULL); + + pstr = bolt_enum_to_string (BOLT_TYPE_POLICY, policy, error); + if (pstr == NULL) + return NULL; + + fstr = bolt_flags_to_string (BOLT_TYPE_AUTH_CTRL, flags, error); + if (fstr == NULL) + return NULL; + + params = g_variant_new ("(sss)", uid, pstr, fstr); + val = g_dbus_proxy_call_sync (G_DBUS_PROXY (client), + "EnrollDevice", + params, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + + if (val == NULL) + { + bolt_error_propagate_stripped (error, &err); + return NULL; + } + + bus = g_dbus_proxy_get_connection (G_DBUS_PROXY (client)); + g_variant_get (val, "(&o)", &opath); + + if (opath == NULL) + return NULL; + + dev = bolt_device_new_for_object_path (bus, opath, NULL, error); + return dev; +} + +void +bolt_client_enroll_device_async (BoltClient *client, + const char *uid, + BoltPolicy policy, + BoltAuthCtrl flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_autofree char *fstr = NULL; + GError *err = NULL; + GVariant *params; + const char *pstr; + + g_return_if_fail (BOLT_IS_CLIENT (client)); + g_return_if_fail (uid != NULL); + + pstr = bolt_enum_to_string (BOLT_TYPE_POLICY, policy, &err); + if (pstr == NULL) + { + g_task_report_error (client, callback, user_data, NULL, err); + return; + } + + fstr = bolt_flags_to_string (BOLT_TYPE_AUTH_CTRL, flags, &err); + if (fstr == NULL) + { + g_task_report_error (client, callback, user_data, NULL, err); + return; + } + + params = g_variant_new ("(sss)", uid, pstr, fstr); + g_dbus_proxy_call (G_DBUS_PROXY (client), + "EnrollDevice", + params, + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + callback, + user_data); +} + +gboolean +bolt_client_enroll_device_finish (BoltClient *client, + GAsyncResult *res, + char **path, + GError **error) +{ + GVariant *val = NULL; + + g_autoptr(GError) err = NULL; + + g_return_val_if_fail (BOLT_IS_CLIENT (client), FALSE); + + val = g_dbus_proxy_call_finish (G_DBUS_PROXY (client), res, &err); + if (val == NULL) + { + bolt_error_propagate_stripped (error, &err); + return FALSE; + } + + if (path != NULL) + g_variant_get (val, "(o)", path); + + return TRUE; +} + +gboolean +bolt_client_forget_device (BoltClient *client, + const char *uid, + GError **error) +{ + g_autoptr(GVariant) val = NULL; + g_autoptr(GError) err = NULL; + + g_return_val_if_fail (BOLT_IS_CLIENT (client), FALSE); + + val = g_dbus_proxy_call_sync (G_DBUS_PROXY (client), + "ForgetDevice", + g_variant_new ("(s)", uid), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &err); + + if (val == NULL) + { + bolt_error_propagate_stripped (error, &err); + return FALSE; + } + + return TRUE; +} + +void +bolt_client_forget_device_async (BoltClient *client, + const char *uid, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail (BOLT_IS_CLIENT (client)); + + g_dbus_proxy_call (G_DBUS_PROXY (client), + "ForgetDevice", + g_variant_new ("(s)", uid), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + callback, + user_data); +} + +gboolean +bolt_client_forget_device_finish (BoltClient *client, + GAsyncResult *res, + GError **error) +{ + g_autoptr(GVariant) val = NULL; + g_autoptr(GError) err = NULL; + + g_return_val_if_fail (BOLT_IS_CLIENT (client), FALSE); + + val = g_dbus_proxy_call_finish (G_DBUS_PROXY (client), res, &err); + if (val == NULL) + { + bolt_error_propagate_stripped (error, &err); + return FALSE; + } + + return TRUE; +} + +/* getter */ +guint +bolt_client_get_version (BoltClient *client) +{ + const char *key; + guint val = 0; + gboolean ok; + + g_return_val_if_fail (BOLT_IS_CLIENT (client), val); + + key = g_param_spec_get_name (props[PROP_VERSION]); + ok = bolt_proxy_get_property_uint32 (BOLT_PROXY (client), key, &val); + + if (!ok) + g_warning ("failed to get property '%s'", key); + + return val; +} + +gboolean +bolt_client_is_probing (BoltClient *client) +{ + const char *key; + gboolean val = FALSE; + gboolean ok; + + g_return_val_if_fail (BOLT_IS_CLIENT (client), val); + + key = g_param_spec_get_name (props[PROP_PROBING]); + ok = bolt_proxy_get_property_bool (BOLT_PROXY (client), key, &val); + + if (!ok) + g_warning ("failed to get enum property '%s'", key); + + return val; +} + +BoltSecurity +bolt_client_get_security (BoltClient *client) +{ + const char *key; + gboolean ok; + gint val = BOLT_SECURITY_UNKNOWN; + + g_return_val_if_fail (BOLT_IS_CLIENT (client), val); + + key = g_param_spec_get_name (props[PROP_SECURITY]); + ok = bolt_proxy_get_property_enum (BOLT_PROXY (client), key, &val); + + if (!ok) + g_warning ("failed to get enum property '%s'", key); + + return val; +} + +BoltAuthMode +bolt_client_get_authmode (BoltClient *client) +{ + const char *key; + gboolean ok; + guint val = BOLT_AUTH_DISABLED; + + g_return_val_if_fail (BOLT_IS_CLIENT (client), val); + + key = g_param_spec_get_name (props[PROP_AUTHMODE]); + ok = bolt_proxy_get_property_flags (BOLT_PROXY (client), key, &val); + + if (!ok) + g_warning ("failed to get enum property '%s'", key); + + return val; +} + +void +bolt_client_set_authmode_async (BoltClient *client, + BoltAuthMode mode, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_autofree char *str = NULL; + GError *err = NULL; + GParamSpec *pspec; + GParamSpecFlags *flags_pspec; + GFlagsClass *flags_class; + + pspec = props[PROP_AUTHMODE]; + flags_pspec = G_PARAM_SPEC_FLAGS (pspec); + flags_class = flags_pspec->flags_class; + str = bolt_flags_class_to_string (flags_class, mode, &err); + + if (str == NULL) + { + g_task_report_error (client, callback, user_data, NULL, err); + return; + } + + bolt_proxy_set_property_async (BOLT_PROXY (client), + g_param_spec_get_nick (pspec), + g_variant_new ("s", str), + cancellable, + callback, + user_data); +} + +gboolean +bolt_client_set_authmode_finish (BoltClient *client, + GAsyncResult *res, + GError **error) +{ + return bolt_proxy_set_property_finish (res, error); +} + +/* utility functions */ +static gint +device_sort_by_syspath (gconstpointer ap, + gconstpointer bp, + gpointer data) +{ + BoltDevice *a = BOLT_DEVICE (*((BoltDevice **) ap)); + BoltDevice *b = BOLT_DEVICE (*((BoltDevice **) bp)); + gint sort_order = GPOINTER_TO_INT (data); + const char *pa; + const char *pb; + + pa = bolt_device_get_syspath (a); + pb = bolt_device_get_syspath (b); + + return sort_order * g_strcmp0 (pa, pb); +} + +void +bolt_devices_sort_by_syspath (GPtrArray *devices, + gboolean reverse) +{ + gpointer sort_order = GINT_TO_POINTER (reverse ? -1 : 1); + + if (devices == NULL) + return; + + g_ptr_array_sort_with_data (devices, + device_sort_by_syspath, + sort_order); +} diff --git a/panels/thunderbolt/bolt-client.h b/panels/thunderbolt/bolt-client.h new file mode 100644 index 000000000..853823011 --- /dev/null +++ b/panels/thunderbolt/bolt-client.h @@ -0,0 +1,107 @@ +/* + * Copyright © 2017 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Christian J. Kellner + */ + +#pragma once + +#include "bolt-enums.h" +#include "bolt-device.h" +#include "bolt-proxy.h" + +G_BEGIN_DECLS + +#define BOLT_TYPE_CLIENT bolt_client_get_type () +G_DECLARE_FINAL_TYPE (BoltClient, bolt_client, BOLT, CLIENT, BoltProxy); + +BoltClient * bolt_client_new (GError **error); + +void bolt_client_new_async (GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +BoltClient * bolt_client_new_finish (GAsyncResult *res, + GError **error); + +GPtrArray * bolt_client_list_devices (BoltClient *client, + GCancellable *cancellable, + GError **error); + +BoltDevice * bolt_client_get_device (BoltClient *client, + const char *uid, + GCancellable *cancellable, + GError **error); + +BoltDevice * bolt_client_enroll_device (BoltClient *client, + const char *uid, + BoltPolicy policy, + BoltAuthCtrl flags, + GError **error); + +void bolt_client_enroll_device_async (BoltClient *client, + const char *uid, + BoltPolicy policy, + BoltAuthCtrl flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean bolt_client_enroll_device_finish (BoltClient *client, + GAsyncResult *res, + char **path, + GError **error); + +gboolean bolt_client_forget_device (BoltClient *client, + const char *uid, + GError **error); + +void bolt_client_forget_device_async (BoltClient *client, + const char *uid, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean bolt_client_forget_device_finish (BoltClient *client, + GAsyncResult *res, + GError **error); + +/* getter */ +guint bolt_client_get_version (BoltClient *client); + +gboolean bolt_client_is_probing (BoltClient *client); + +BoltSecurity bolt_client_get_security (BoltClient *client); + +BoltAuthMode bolt_client_get_authmode (BoltClient *client); + +/* setter */ + +void bolt_client_set_authmode_async (BoltClient *client, + BoltAuthMode mode, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean bolt_client_set_authmode_finish (BoltClient *client, + GAsyncResult *res, + GError **error); + +/* utility functions */ +void bolt_devices_sort_by_syspath (GPtrArray *devices, + gboolean reverse); + +G_END_DECLS diff --git a/panels/thunderbolt/bolt-device.c b/panels/thunderbolt/bolt-device.c new file mode 100644 index 000000000..b316950d3 --- /dev/null +++ b/panels/thunderbolt/bolt-device.c @@ -0,0 +1,604 @@ +/* + * Copyright © 2017 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Christian J. Kellner + */ + +#include "config.h" + +#include "bolt-device.h" + +#include "bolt-enums.h" +#include "bolt-error.h" +#include "bolt-names.h" + +#include + +struct _BoltDevice +{ + BoltProxy parent; +}; + +enum { + PROP_0, + + /* D-Bus Props */ + PROP_UID, + PROP_NAME, + PROP_VENDOR, + PROP_TYPE, + PROP_STATUS, + PROP_AUTHFLAGS, + PROP_PARENT, + PROP_SYSPATH, + PROP_CONNTIME, + PROP_AUTHTIME, + + PROP_STORED, + PROP_POLICY, + PROP_KEY, + PROP_STORETIME, + PROP_LABEL, + + PROP_LAST +}; + +static GParamSpec *props[PROP_LAST] = {NULL, }; + +G_DEFINE_TYPE (BoltDevice, + bolt_device, + BOLT_TYPE_PROXY); + +static void +bolt_device_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + if (bolt_proxy_get_dbus_property (object, pspec, value)) + return; +} + + + +static void +bolt_device_class_init (BoltDeviceClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->get_property = bolt_device_get_property; + + props[PROP_UID] = + g_param_spec_string ("uid", + "Uid", NULL, + "unknown", + G_PARAM_READABLE | + G_PARAM_STATIC_NICK); + + props[PROP_NAME] = + g_param_spec_string ("name", + "Name", NULL, + "unknown", + G_PARAM_READABLE | + G_PARAM_STATIC_NICK); + + props[PROP_VENDOR] = + g_param_spec_string ("vendor", + "Vendor", NULL, + "unknown", + G_PARAM_READABLE | + G_PARAM_STATIC_NICK); + + props[PROP_TYPE] = + g_param_spec_enum ("type", + "Type", NULL, + BOLT_TYPE_DEVICE_TYPE, + BOLT_DEVICE_PERIPHERAL, + G_PARAM_READABLE | + G_PARAM_STATIC_NICK); + + props[PROP_STATUS] = + g_param_spec_enum ("status", + "Status", NULL, + BOLT_TYPE_STATUS, + BOLT_STATUS_DISCONNECTED, + G_PARAM_READABLE | + G_PARAM_STATIC_NICK); + + props[PROP_AUTHFLAGS] = + g_param_spec_flags ("authflags", + "AuthFlags", NULL, + BOLT_TYPE_AUTH_FLAGS, + BOLT_AUTH_NONE, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + props[PROP_PARENT] = + g_param_spec_string ("parent", + "Parent", NULL, + "unknown", + G_PARAM_READABLE | + G_PARAM_STATIC_NICK); + + props[PROP_SYSPATH] = + g_param_spec_string ("syspath", + "SysfsPath", NULL, + "unknown", + G_PARAM_READABLE | + G_PARAM_STATIC_NICK); + + props[PROP_CONNTIME] = + g_param_spec_uint64 ("conntime", + "ConnectTime", NULL, + 0, G_MAXUINT64, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + props[PROP_AUTHTIME] = + g_param_spec_uint64 ("authtime", + "AuthorizeTime", NULL, + 0, G_MAXUINT64, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + props[PROP_STORED] = + g_param_spec_boolean ("stored", + "Stored", NULL, + FALSE, + G_PARAM_READABLE | + G_PARAM_STATIC_NICK); + + props[PROP_POLICY] = + g_param_spec_enum ("policy", + "Policy", NULL, + BOLT_TYPE_POLICY, + BOLT_POLICY_DEFAULT, + G_PARAM_READABLE | + G_PARAM_STATIC_NICK); + + props[PROP_KEY] = + g_param_spec_enum ("key", + "Key", NULL, + BOLT_TYPE_KEY_STATE, + BOLT_KEY_MISSING, + G_PARAM_READABLE | + G_PARAM_STATIC_NICK); + + props[PROP_STORETIME] = + g_param_spec_uint64 ("storetime", + "StoreTime", NULL, + 0, G_MAXUINT64, 0, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + props[PROP_LABEL] = + g_param_spec_string ("label", + "Label", NULL, + NULL, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (gobject_class, + PROP_LAST, + props); + +} + +static void +bolt_device_init (BoltDevice *mgr) +{ +} + +/* public methods */ + +BoltDevice * +bolt_device_new_for_object_path (GDBusConnection *bus, + const char *path, + GCancellable *cancel, + GError **error) +{ + BoltDevice *dev; + + dev = g_initable_new (BOLT_TYPE_DEVICE, + cancel, error, + "g-flags", G_DBUS_PROXY_FLAGS_NONE, + "g-connection", bus, + "g-name", BOLT_DBUS_NAME, + "g-object-path", path, + "g-interface-name", BOLT_DBUS_DEVICE_INTERFACE, + NULL); + + return dev; +} + +gboolean +bolt_device_authorize (BoltDevice *dev, + BoltAuthCtrl flags, + GCancellable *cancel, + GError **error) +{ + g_autoptr(GError) err = NULL; + g_autofree char *fstr = NULL; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), FALSE); + + fstr = bolt_flags_to_string (BOLT_TYPE_AUTH_CTRL, flags, error); + if (fstr == NULL) + return FALSE; + + g_dbus_proxy_call_sync (G_DBUS_PROXY (dev), + "Authorize", + g_variant_new ("(s)", fstr), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancel, + &err); + + if (err != NULL) + return bolt_error_propagate_stripped (error, &err); + + return TRUE; +} + +void +bolt_device_authorize_async (BoltDevice *dev, + BoltAuthCtrl flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GError *err = NULL; + g_autofree char *fstr = NULL; + + g_return_if_fail (BOLT_IS_DEVICE (dev)); + + fstr = bolt_flags_to_string (BOLT_TYPE_AUTH_CTRL, flags, &err); + if (fstr == NULL) + { + g_task_report_error (dev, callback, user_data, NULL, err); + return; + } + + g_dbus_proxy_call (G_DBUS_PROXY (dev), + "Authorize", + g_variant_new ("(s)", fstr), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + callback, + user_data); +} + +gboolean +bolt_device_authorize_finish (BoltDevice *dev, + GAsyncResult *res, + GError **error) +{ + g_autoptr(GError) err = NULL; + g_autoptr(GVariant) val = NULL; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), FALSE); + + val = g_dbus_proxy_call_finish (G_DBUS_PROXY (dev), res, &err); + if (val == NULL) + { + bolt_error_propagate_stripped (error, &err); + return FALSE; + } + + return TRUE; +} + +const char * +bolt_device_get_uid (BoltDevice *dev) +{ + const char *key; + const char *str; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), NULL); + + key = g_param_spec_get_name (props[PROP_UID]); + str = bolt_proxy_get_property_string (BOLT_PROXY (dev), key); + + return str; +} + +const char * +bolt_device_get_name (BoltDevice *dev) +{ + const char *key; + const char *str; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), NULL); + + key = g_param_spec_get_name (props[PROP_NAME]); + str = bolt_proxy_get_property_string (BOLT_PROXY (dev), key); + + return str; +} + +const char * +bolt_device_get_vendor (BoltDevice *dev) +{ + const char *key; + const char *str; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), NULL); + + key = g_param_spec_get_name (props[PROP_VENDOR]); + str = bolt_proxy_get_property_string (BOLT_PROXY (dev), key); + + return str; +} + +BoltDeviceType +bolt_device_get_device_type (BoltDevice *dev) +{ + const char *key; + gboolean ok; + gint val = BOLT_DEVICE_PERIPHERAL; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), val); + + key = g_param_spec_get_name (props[PROP_TYPE]); + ok = bolt_proxy_get_property_enum (BOLT_PROXY (dev), key, &val); + + if (!ok) + g_warning ("failed to get enum property '%s'", key); + + return val; +} + +BoltStatus +bolt_device_get_status (BoltDevice *dev) +{ + const char *key; + gboolean ok; + gint val = BOLT_STATUS_UNKNOWN; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), val); + + key = g_param_spec_get_name (props[PROP_STATUS]); + ok = bolt_proxy_get_property_enum (BOLT_PROXY (dev), key, &val); + + if (!ok) + g_warning ("failed to get enum property '%s'", key); + + return val; +} + +BoltAuthFlags +bolt_device_get_authflags (BoltDevice *dev) +{ + const char *key; + gboolean ok; + guint val = BOLT_AUTH_NONE; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), val); + + key = g_param_spec_get_name (props[PROP_AUTHFLAGS]); + ok = bolt_proxy_get_property_flags (BOLT_PROXY (dev), key, &val); + + if (!ok) + g_warning ("failed to get enum property '%s'", key); + + return val; +} + +const char * +bolt_device_get_parent (BoltDevice *dev) +{ + const char *key; + const char *str; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), NULL); + + key = g_param_spec_get_name (props[PROP_PARENT]); + str = bolt_proxy_get_property_string (BOLT_PROXY (dev), key); + + return str; +} + +const char * +bolt_device_get_syspath (BoltDevice *dev) +{ + const char *key; + const char *str; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), NULL); + + key = g_param_spec_get_name (props[PROP_SYSPATH]); + str = bolt_proxy_get_property_string (BOLT_PROXY (dev), key); + + return str; +} + +guint64 +bolt_device_get_conntime (BoltDevice *dev) +{ + const char *key; + guint64 val = 0; + gboolean ok; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), val); + + key = g_param_spec_get_name (props[PROP_CONNTIME]); + ok = bolt_proxy_get_property_uint64 (BOLT_PROXY (dev), key, &val); + + if (!ok) + g_warning ("failed to get enum property '%s'", key); + + return val; +} + +guint64 +bolt_device_get_authtime (BoltDevice *dev) +{ + const char *key; + guint64 val = 0; + gboolean ok; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), val); + + key = g_param_spec_get_name (props[PROP_AUTHTIME]); + ok = bolt_proxy_get_property_uint64 (BOLT_PROXY (dev), key, &val); + + if (!ok) + g_warning ("failed to get enum property '%s'", key); + + return val; +} + +gboolean +bolt_device_is_stored (BoltDevice *dev) +{ + const char *key; + gboolean val = FALSE; + gboolean ok; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), val); + + key = g_param_spec_get_name (props[PROP_STORED]); + ok = bolt_proxy_get_property_bool (BOLT_PROXY (dev), key, &val); + + if (!ok) + g_warning ("failed to get enum property '%s'", key); + + return val; +} + +BoltPolicy +bolt_device_get_policy (BoltDevice *dev) +{ + const char *key; + gboolean ok; + gint val = BOLT_POLICY_DEFAULT; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), val); + + key = g_param_spec_get_name (props[PROP_POLICY]); + ok = bolt_proxy_get_property_enum (BOLT_PROXY (dev), key, &val); + + if (!ok) + g_warning ("failed to get enum property '%s'", key); + + return val; +} + +BoltKeyState +bolt_device_get_keystate (BoltDevice *dev) +{ + const char *key; + gboolean ok; + gint val = BOLT_KEY_MISSING; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), val); + + key = g_param_spec_get_name (props[PROP_KEY]); + ok = bolt_proxy_get_property_enum (BOLT_PROXY (dev), key, &val); + + if (!ok) + g_warning ("failed to get enum property '%s'", key); + + return val; +} + +guint64 +bolt_device_get_storetime (BoltDevice *dev) +{ + const char *key; + guint64 val = 0; + gboolean ok; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), val); + + key = g_param_spec_get_name (props[PROP_STORETIME]); + ok = bolt_proxy_get_property_uint64 (BOLT_PROXY (dev), key, &val); + + if (!ok) + g_warning ("failed to get enum property '%s'", key); + + return val; +} + +const char * +bolt_device_get_label (BoltDevice *dev) +{ + const char *key; + const char *str; + + g_return_val_if_fail (BOLT_IS_DEVICE (dev), NULL); + + key = g_param_spec_get_name (props[PROP_LABEL]); + str = bolt_proxy_get_property_string (BOLT_PROXY (dev), key); + + return str; +} + +char * +bolt_device_get_display_name (BoltDevice *dev) +{ + const char *label; + const char *name; + const char *vendor; + + label = bolt_device_get_label (dev); + if (label != NULL) + return g_strdup (label); + + name = bolt_device_get_name (dev); + vendor = bolt_device_get_vendor (dev); + + return g_strdup_printf ("%s %s", vendor, name); +} + +guint64 +bolt_device_get_timestamp (BoltDevice *dev) +{ + BoltStatus status; + guint64 timestamp = 0; + + status = bolt_device_get_status (dev); + + switch (status) + { + case BOLT_STATUS_AUTHORIZING: + case BOLT_STATUS_AUTH_ERROR: + case BOLT_STATUS_CONNECTING: + case BOLT_STATUS_CONNECTED: + timestamp = bolt_device_get_conntime (dev); + break; + + case BOLT_STATUS_DISCONNECTED: + /* implicit: device is stored */ + timestamp = bolt_device_get_storetime (dev); + break; + + case BOLT_STATUS_AUTHORIZED: + case BOLT_STATUS_AUTHORIZED_DPONLY: + case BOLT_STATUS_AUTHORIZED_NEWKEY: + case BOLT_STATUS_AUTHORIZED_SECURE: + timestamp = bolt_device_get_authtime (dev); + break; + + case BOLT_STATUS_UNKNOWN: + timestamp = 0; + break; + } + + return timestamp; +} diff --git a/panels/thunderbolt/bolt-device.h b/panels/thunderbolt/bolt-device.h new file mode 100644 index 000000000..ffd09f9a8 --- /dev/null +++ b/panels/thunderbolt/bolt-device.h @@ -0,0 +1,87 @@ +/* + * Copyright © 2017 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Christian J. Kellner + */ + +#pragma once + +#include "bolt-enums.h" +#include "bolt-proxy.h" + +G_BEGIN_DECLS + +#define BOLT_TYPE_DEVICE bolt_device_get_type () +G_DECLARE_FINAL_TYPE (BoltDevice, bolt_device, BOLT, DEVICE, BoltProxy); + +BoltDevice * bolt_device_new_for_object_path (GDBusConnection *bus, + const char *path, + GCancellable *cancellable, + GError **error); + +gboolean bolt_device_authorize (BoltDevice *dev, + BoltAuthCtrl flags, + GCancellable *cancellable, + GError **error); + +void bolt_device_authorize_async (BoltDevice *dev, + BoltAuthCtrl flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean bolt_device_authorize_finish (BoltDevice *dev, + GAsyncResult *res, + GError **error); + +/* getter */ +const char * bolt_device_get_uid (BoltDevice *dev); + +const char * bolt_device_get_name (BoltDevice *dev); + +const char * bolt_device_get_vendor (BoltDevice *dev); + +BoltDeviceType bolt_device_get_device_type (BoltDevice *dev); + +BoltStatus bolt_device_get_status (BoltDevice *dev); + +BoltAuthFlags bolt_device_get_authflags (BoltDevice *dev); + +const char * bolt_device_get_parent (BoltDevice *dev); + +const char * bolt_device_get_syspath (BoltDevice *dev); + +guint64 bolt_device_get_conntime (BoltDevice *dev); + +guint64 bolt_device_get_authtime (BoltDevice *dev); + +gboolean bolt_device_is_stored (BoltDevice *dev); + +BoltPolicy bolt_device_get_policy (BoltDevice *dev); + +BoltKeyState bolt_device_get_keystate (BoltDevice *dev); + +guint64 bolt_device_get_storetime (BoltDevice *dev); + +const char * bolt_device_get_label (BoltDevice *dev); + +/* derived getter */ +char * bolt_device_get_display_name (BoltDevice *dev); + +guint64 bolt_device_get_timestamp (BoltDevice *dev); + +G_END_DECLS diff --git a/panels/thunderbolt/bolt-enums.c b/panels/thunderbolt/bolt-enums.c new file mode 100644 index 000000000..de77737f8 --- /dev/null +++ b/panels/thunderbolt/bolt-enums.c @@ -0,0 +1,395 @@ +/* + * Copyright © 2017 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Christian J. Kellner + */ + +#include "config.h" + +#include "bolt-enums.h" +#include "bolt-error.h" + +#include + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (GEnumClass, g_type_class_unref); +G_DEFINE_AUTOPTR_CLEANUP_FUNC (GFlagsClass, g_type_class_unref); + +gboolean +bolt_enum_class_validate (GEnumClass *enum_class, + gint value, + GError **error) +{ + const char *name; + gboolean oob; + + if (enum_class == NULL) + { + name = g_type_name_from_class ((GTypeClass *) enum_class); + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "could not determine enum class for '%s'", + name); + + return FALSE; + } + + oob = value < enum_class->minimum || value > enum_class->maximum; + + if (oob) + { + name = g_type_name_from_class ((GTypeClass *) enum_class); + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "enum value '%d' is out of bounds for '%s'", + value, name); + return FALSE; + } + + return TRUE; +} + +gboolean +bolt_enum_validate (GType enum_type, + gint value, + GError **error) +{ + g_autoptr(GEnumClass) klass = g_type_class_ref (enum_type); + return bolt_enum_class_validate (klass, value, error); +} + +const char * +bolt_enum_to_string (GType enum_type, + gint value, + GError **error) +{ + g_autoptr(GEnumClass) klass = NULL; + GEnumValue *ev; + + klass = g_type_class_ref (enum_type); + + if (!bolt_enum_class_validate (klass, value, error)) + return NULL; + + ev = g_enum_get_value (klass, value); + return ev->value_nick; +} + +gint +bolt_enum_from_string (GType enum_type, + const char *string, + GError **error) +{ + g_autoptr(GEnumClass) klass = NULL; + const char *name; + GEnumValue *ev; + + klass = g_type_class_ref (enum_type); + + if (klass == NULL) + { + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "could not determine enum class"); + return -1; + } + + if (string == NULL) + { + name = g_type_name_from_class ((GTypeClass *) klass); + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "empty string passed for enum class for '%s'", + name); + return -1; + } + + ev = g_enum_get_value_by_nick (klass, string); + + if (ev == NULL) + { + name = g_type_name (enum_type); + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "invalid string '%s' for enum '%s'", string, name); + return -1; + } + + return ev->value; +} + +char * +bolt_flags_class_to_string (GFlagsClass *flags_class, + guint value, + GError **error) +{ + g_autoptr(GString) str = NULL; + const char *name; + GFlagsValue *fv; + + if (flags_class == NULL) + { + name = g_type_name_from_class ((GTypeClass *) flags_class); + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "could not determine flags class for '%s'", + name); + + return FALSE; + } + + fv = g_flags_get_first_value (flags_class, value); + if (fv == NULL) + { + if (value == 0) + return g_strdup (""); + + name = g_type_name_from_class ((GTypeClass *) flags_class); + + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "invalid value '%u' for flags '%s'", value, name); + return NULL; + } + + value &= ~fv->value; + str = g_string_new (fv->value_nick); + + while (value != 0 && + (fv = g_flags_get_first_value (flags_class, value)) != NULL) + { + g_string_append (str, " | "); + g_string_append (str, fv->value_nick); + + value &= ~fv->value; + } + + if (value != 0) + { + name = g_type_name_from_class ((GTypeClass *) flags_class); + + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "unhandled value '%u' for flags '%s'", value, name); + return NULL; + } + + return g_string_free (g_steal_pointer (&str), FALSE); +} + +gboolean +bolt_flags_class_from_string (GFlagsClass *flags_class, + const char *string, + guint *flags_out, + GError **error) +{ + g_auto(GStrv) vals = NULL; + const char *name; + guint flags = 0; + + if (flags_class == NULL) + { + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "could not determine flags class"); + + return FALSE; + } + + if (string == NULL) + { + name = g_type_name_from_class ((GTypeClass *) flags_class); + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "empty string passed for flags class for '%s'", + name); + return FALSE; + } + + vals = g_strsplit (string, "|", -1); + + for (guint i = 0; vals[i]; i++) + { + GFlagsValue *fv; + char *nick; + + nick = g_strstrip (vals[i]); + fv = g_flags_get_value_by_nick (flags_class, nick); + + if (fv == NULL) + { + name = g_type_name_from_class ((GTypeClass *) flags_class); + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, + "invalid flag '%s' for flags '%s'", string, name); + + return FALSE; + } + + flags |= fv->value; + } + + if (flags_out != NULL) + *flags_out = flags; + + return TRUE; +} + +char * +bolt_flags_to_string (GType flags_type, + guint value, + GError **error) +{ + g_autoptr(GFlagsClass) klass = NULL; + + klass = g_type_class_ref (flags_type); + return bolt_flags_class_to_string (klass, value, error); +} + +gboolean +bolt_flags_from_string (GType flags_type, + const char *string, + guint *flags_out, + GError **error) +{ + g_autoptr(GFlagsClass) klass = NULL; + + klass = g_type_class_ref (flags_type); + return bolt_flags_class_from_string (klass, string, flags_out, error); +} + +gboolean +bolt_flags_update (guint from, + guint *to, + guint mask) +{ + guint val; + gboolean chg; + + g_return_val_if_fail (to != NULL, FALSE); + + val = *to & ~mask; /* clear all bits in mask */ + val = val | (from & mask); /* set all bits in from and mask */ + chg = *to != val; + *to = val; + + return chg; +} + +const char * +bolt_status_to_string (BoltStatus status) +{ + return bolt_enum_to_string (BOLT_TYPE_STATUS, status, NULL); +} + +gboolean +bolt_status_is_authorized (BoltStatus status) +{ + return status == BOLT_STATUS_AUTHORIZED || + status == BOLT_STATUS_AUTHORIZED_SECURE || + status == BOLT_STATUS_AUTHORIZED_NEWKEY; +} + +gboolean +bolt_status_is_pending (BoltStatus status) +{ + return status == BOLT_STATUS_AUTH_ERROR || + status == BOLT_STATUS_CONNECTED; +} + +gboolean +bolt_status_validate (BoltStatus status) +{ + return bolt_enum_validate (BOLT_TYPE_STATUS, status, NULL); +} + +gboolean +bolt_status_is_connected (BoltStatus status) +{ + return status > BOLT_STATUS_DISCONNECTED; +} + +BoltSecurity +bolt_security_from_string (const char *str) +{ + return bolt_enum_from_string (BOLT_TYPE_SECURITY, str, NULL); +} + +const char * +bolt_security_to_string (BoltSecurity security) +{ + return bolt_enum_to_string (BOLT_TYPE_SECURITY, security, NULL); +} + +gboolean +bolt_security_validate (BoltSecurity security) +{ + return bolt_enum_validate (BOLT_TYPE_SECURITY, security, NULL); +} + +gboolean +bolt_security_allows_pcie (BoltSecurity security) +{ + gboolean pcie = FALSE; + + switch (security) + { + case BOLT_SECURITY_NONE: + case BOLT_SECURITY_USER: + case BOLT_SECURITY_SECURE: + pcie = TRUE; + break; + + case BOLT_SECURITY_DPONLY: + case BOLT_SECURITY_USBONLY: + case BOLT_SECURITY_UNKNOWN: + pcie = FALSE; + break; + } + + return pcie; +} + +BoltPolicy +bolt_policy_from_string (const char *str) +{ + return bolt_enum_from_string (BOLT_TYPE_POLICY, str, NULL); +} + +const char * +bolt_policy_to_string (BoltPolicy policy) +{ + return bolt_enum_to_string (BOLT_TYPE_POLICY, policy, NULL); +} + +gboolean +bolt_policy_validate (BoltPolicy policy) +{ + return bolt_enum_validate (BOLT_TYPE_POLICY, policy, NULL); +} + +BoltDeviceType +bolt_device_type_from_string (const char *str) +{ + return bolt_enum_from_string (BOLT_TYPE_DEVICE_TYPE, str, NULL); +} + +const char * +bolt_device_type_to_string (BoltDeviceType type) +{ + return bolt_enum_to_string (BOLT_TYPE_DEVICE_TYPE, type, NULL); +} + +gboolean +bolt_device_type_validate (BoltDeviceType type) +{ + return bolt_enum_validate (BOLT_TYPE_DEVICE_TYPE, type, NULL); +} + +gboolean +bolt_device_type_is_host (BoltDeviceType type) +{ + return type == BOLT_DEVICE_HOST; +} diff --git a/panels/thunderbolt/bolt-enums.h b/panels/thunderbolt/bolt-enums.h new file mode 100644 index 000000000..6e2953fa2 --- /dev/null +++ b/panels/thunderbolt/bolt-enums.h @@ -0,0 +1,249 @@ +/* + * Copyright © 2017 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Christian J. Kellner + */ + +#pragma once + +#include "bolt-names.h" +#include "bolt-enum-types.h" + + +gboolean bolt_enum_validate (GType enum_type, + gint value, + GError **error); + +gboolean bolt_enum_class_validate (GEnumClass *enum_class, + gint value, + GError **error); + +const char * bolt_enum_to_string (GType enum_type, + gint value, + GError **error); + +gint bolt_enum_from_string (GType enum_type, + const char *string, + GError **error); + + +char * bolt_flags_class_to_string (GFlagsClass *flags_class, + guint value, + GError **error); + +gboolean bolt_flags_class_from_string (GFlagsClass *flags_class, + const char *string, + guint *flags_out, + GError **error); + +char * bolt_flags_to_string (GType flags_type, + guint value, + GError **error); + +gboolean bolt_flags_from_string (GType flags_type, + const char *string, + guint *flags_out, + GError **error); + +gboolean bolt_flags_update (guint from, + guint *to, + guint mask); + +#define bolt_flag_isset(flags_, flag_) (!!(flags_ & flag_)) +#define bolt_flag_isclear(flags_, flag_) (!(flags_ & flag_)) + +/** + * BoltStatus: + * @BOLT_STATUS_UNKNOWN: Device is in an unknown state (should normally not happen). + * @BOLT_STATUS_DISCONNECTED: Device is not connected. + * @BOLT_STATUS_CONNECTING: Device is currently being connected. + * @BOLT_STATUS_CONNECTED: Device is connected, but not authorized. + * @BOLT_STATUS_AUTHORIZING: Device is currently authorizing. + * @BOLT_STATUS_AUTH_ERROR: Failed to authorize a device via a key. + * @BOLT_STATUS_AUTHORIZED: Device connected and authorized. + * @BOLT_STATUS_AUTHORIZED_SECURE: Device connected and securely authorized via a key (deprecated). + * @BOLT_STATUS_AUTHORIZED_NEWKEY: Device connected and authorized via a new key (deprecated). + * @BOLT_STATUS_AUTHORIZED_DPONLY: Device authorized but with thunderbolt disabled (deprecated). + * + * The current status of the device. + */ +typedef enum { + + BOLT_STATUS_UNKNOWN = -1, + BOLT_STATUS_DISCONNECTED = 0, + BOLT_STATUS_CONNECTING, + BOLT_STATUS_CONNECTED, + BOLT_STATUS_AUTHORIZING, + BOLT_STATUS_AUTH_ERROR, + BOLT_STATUS_AUTHORIZED, + + /* deprecated, do not use */ + BOLT_STATUS_AUTHORIZED_SECURE, + BOLT_STATUS_AUTHORIZED_NEWKEY, + BOLT_STATUS_AUTHORIZED_DPONLY + +} BoltStatus; + +const char * bolt_status_to_string (BoltStatus status); +gboolean bolt_status_is_authorized (BoltStatus status); +gboolean bolt_status_is_connected (BoltStatus status); +gboolean bolt_status_is_pending (BoltStatus status); +gboolean bolt_status_validate (BoltStatus status); + +/** + * BoltAuthFlags: + * @BOLT_AUTH_NONE: No specific authorization. + * @BOLT_AUTH_NOPCIE: PCIe tunnels are *not* authorized. + * @BOLT_AUTH_SECURE: Device is securely authorized. + * @BOLT_AUTH_NOKEY: Device does *not* support key verification. + * @BOLT_AUTH_BOOT: Device was already authorized during pre-boot. + * + * More specific information about device authorization. + */ +typedef enum { /*< flags >*/ + + BOLT_AUTH_NONE = 0, + BOLT_AUTH_NOPCIE = 1 << 0, + BOLT_AUTH_SECURE = 1 << 1, + BOLT_AUTH_NOKEY = 1 << 2, + BOLT_AUTH_BOOT = 1 << 3, + +} BoltAuthFlags; + +/** + * BoltKeyState: + * @BOLT_KEY_UNKNOWN: unknown key state + * @BOLT_KEY_MISSING: no key + * @BOLT_KEY_HAVE: key exists + * @BOLT_KEY_NEW: key is new + * + * The state of the key. + */ + +typedef enum { + + BOLT_KEY_UNKNOWN = -1, + BOLT_KEY_MISSING = 0, + BOLT_KEY_HAVE = 1, + BOLT_KEY_NEW = 2 + +} BoltKeyState; + +/** + * BoltSecurity: + * @BOLT_SECURITY_UNKNOWN : Unknown security. + * @BOLT_SECURITY_NONE : No security, all devices are automatically connected. + * @BOLT_SECURITY_DPONLY : Display Port only devices only. + * @BOLT_SECURITY_USER : User needs to authorize devices. + * @BOLT_SECURITY_SECURE : User needs to authorize devices. Authorization can + * be done via key exchange to verify the device identity. + * @BOLT_SECURITY_USBONLY : Only create a PCIe tunnel to the USB controller in a + * connected thunderbolt dock, allowing no downstream PCIe tunnels. + * + * The security level of the thunderbolt domain. + */ +typedef enum { + + BOLT_SECURITY_UNKNOWN = -1, + BOLT_SECURITY_NONE = 0, + BOLT_SECURITY_DPONLY = 1, + BOLT_SECURITY_USER = '1', + BOLT_SECURITY_SECURE = '2', + BOLT_SECURITY_USBONLY = 4, + +} BoltSecurity; + + +BoltSecurity bolt_security_from_string (const char *str); +const char * bolt_security_to_string (BoltSecurity security); +gboolean bolt_security_validate (BoltSecurity security); +gboolean bolt_security_allows_pcie (BoltSecurity security); + +/** + * BoltPolicy: + * @BOLT_POLICY_UNKNOWN: Unknown policy. + * @BOLT_POLICY_DEFAULT: Default policy. + * @BOLT_POLICY_MANUAL: Manual authorization of the device. + * @BOLT_POLICY_AUTO: Connect the device automatically, + * with the best possible security level supported + * by the domain controller. + * + * What do to for connected devices. + */ +typedef enum { + + BOLT_POLICY_UNKNOWN = -1, + BOLT_POLICY_DEFAULT = 0, + BOLT_POLICY_MANUAL = 1, + BOLT_POLICY_AUTO = 2, + +} BoltPolicy; + + +BoltPolicy bolt_policy_from_string (const char *str); +const char * bolt_policy_to_string (BoltPolicy policy); +gboolean bolt_policy_validate (BoltPolicy policy); + +/** + * BoltAuthCtrl: + * @BOLT_AUTHCTRL_NONE: No authorization flags. + * + * Control authorization. + */ +typedef enum { /*< flags >*/ + + BOLT_AUTHCTRL_NONE = 0 + +} BoltAuthCtrl; + +/** + * BoltDeviceType: + * @BOLT_DEVICE_UNKNOWN_TYPE: Unknown device type + * @BOLT_DEVICE_HOST: The device representing the host + * @BOLT_DEVICE_PERIPHERAL: A generic thunderbolt peripheral + * + * The type of the device. + */ +typedef enum { + + BOLT_DEVICE_UNKNOWN_TYPE = -1, + BOLT_DEVICE_HOST = 0, + BOLT_DEVICE_PERIPHERAL + +} BoltDeviceType; + +BoltDeviceType bolt_device_type_from_string (const char *str); +const char * bolt_device_type_to_string (BoltDeviceType type); +gboolean bolt_device_type_validate (BoltDeviceType type); +gboolean bolt_device_type_is_host (BoltDeviceType type); + +/** + * BoltAuthMode: + * @BOLT_AUTH_DISABLED: Authorization is disabled + * @BOLT_AUTH_ENABLED: Authorization is enabled. + * + * Control authorization. + */ +typedef enum { /*< flags >*/ + + BOLT_AUTH_DISABLED = 0, + BOLT_AUTH_ENABLED = 1 + +} BoltAuthMode; + +#define bolt_auth_mode_is_enabled(auth) ((auth & BOLT_AUTH_ENABLED) != 0) +#define bolt_auth_mode_is_disabled(auth) (!bolt_auth_mode_is_enabled (auth)) diff --git a/panels/thunderbolt/bolt-error.c b/panels/thunderbolt/bolt-error.c new file mode 100644 index 000000000..37d844e4a --- /dev/null +++ b/panels/thunderbolt/bolt-error.c @@ -0,0 +1,99 @@ +/* + * Copyright © 2017 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Christian J. Kellner + */ + +#include "config.h" + +#include "bolt-error.h" + +#include "bolt-names.h" + +#include + +/** + * SECTION:bolt-error + * @Title: Error codes + * + */ + +static const GDBusErrorEntry bolt_error_entries[] = { + {BOLT_ERROR_FAILED, BOLT_DBUS_NAME ".Error.Failed"}, + {BOLT_ERROR_UDEV, BOLT_DBUS_NAME ".Error.UDev"}, +}; + + +GQuark +bolt_error_quark (void) +{ + static volatile gsize quark_volatile = 0; + + g_dbus_error_register_error_domain ("bolt-error-quark", + &quark_volatile, + bolt_error_entries, + G_N_ELEMENTS (bolt_error_entries)); + return (GQuark) quark_volatile; +} + +gboolean +bolt_err_notfound (const GError *error) +{ + return g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) || + g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) || + g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND) || + g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND); +} + +gboolean +bolt_err_exists (const GError *error) +{ + return g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS) || + g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_EXIST); +} + +gboolean +bolt_err_inval (const GError *error) +{ + return g_error_matches (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE); +} + +gboolean +bolt_err_cancelled (const GError *error) +{ + return g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED); +} + +gboolean +bolt_error_propagate_stripped (GError **dest, + GError **source) +{ + GError *src; + + g_return_val_if_fail (source != NULL, FALSE); + + src = *source; + + if (src == NULL) + return TRUE; + + if (g_dbus_error_is_remote_error (src)) + g_dbus_error_strip_remote_error (src); + + g_propagate_error (dest, g_steal_pointer (source)); + return FALSE; +} diff --git a/panels/thunderbolt/bolt-error.h b/panels/thunderbolt/bolt-error.h new file mode 100644 index 000000000..39b3eee98 --- /dev/null +++ b/panels/thunderbolt/bolt-error.h @@ -0,0 +1,55 @@ +/* + * Copyright © 2017 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Christian J. Kellner + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +/** + * BoltError: + * @BOLT_ERROR_FAILED: Generic error code + * @BOLT_ERROR_UDEV: UDev error + * + * Error codes used inside Bolt. + */ +enum { + BOLT_ERROR_FAILED = 0, + BOLT_ERROR_UDEV, + BOLT_ERROR_NOKEY, + BOLT_ERROR_BADKEY, + BOLT_ERROR_CFG, +} BoltError; + + +GQuark bolt_error_quark (void); +#define BOLT_ERROR (bolt_error_quark ()) + +/* helper function to check for certain error types */ +gboolean bolt_err_notfound (const GError *error); +gboolean bolt_err_exists (const GError *error); +gboolean bolt_err_inval (const GError *error); +gboolean bolt_err_cancelled (const GError *error); + +gboolean bolt_error_propagate_stripped (GError **dest, + GError **source); + +G_END_DECLS diff --git a/panels/thunderbolt/bolt-names.h b/panels/thunderbolt/bolt-names.h new file mode 100644 index 000000000..2c0a97b24 --- /dev/null +++ b/panels/thunderbolt/bolt-names.h @@ -0,0 +1,50 @@ +/* + * Copyright © 2018 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Christian J. Kellner + */ + +#pragma once + +/* D-Bus API revision (here for the lack of a better place) */ +#define BOLT_DBUS_API_VERSION 1U + +/* logging */ + +#define BOLT_LOG_DEVICE_UID "BOLT_DEVICE_UID" +#define BOLT_LOG_DEVICE_NAME "BOLT_DEVICE_NAME" +#define BOLT_LOG_DEVICE_STATE "BOLT_DEVICE_STATE" + +#define BOLT_LOG_ERROR_DOMAIN "ERROR_DOMAIN" +#define BOLT_LOG_ERROR_CODE "ERROR_CODE" +#define BOLT_LOG_ERROR_MESSAGE "ERROR_MESSAGE" + +#define BOLT_LOG_TOPIC "BOLT_TOPIC" +#define BOLT_LOG_VERSION "BOLT_VERSION" +#define BOLT_LOG_CONTEXT "BOLT_LOG_CONTEXT" + +/* logging - message ids */ +#define BOLT_LOG_MSG_ID_STARTUP "dd11929c788e48bdbb6276fb5f26b08a" + + +/* dbus */ + +#define BOLT_DBUS_NAME "org.freedesktop.bolt" +#define BOLT_DBUS_PATH "/org/freedesktop/bolt" +#define BOLT_DBUS_INTERFACE "org.freedesktop.bolt1.Manager" + +#define BOLT_DBUS_DEVICE_INTERFACE "org.freedesktop.bolt1.Device" diff --git a/panels/thunderbolt/bolt-proxy.c b/panels/thunderbolt/bolt-proxy.c new file mode 100644 index 000000000..e044c871f --- /dev/null +++ b/panels/thunderbolt/bolt-proxy.c @@ -0,0 +1,514 @@ +/* + * Copyright © 2017 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Christian J. Kellner + */ + +#include "bolt-proxy.h" + +#include "bolt-enums.h" +#include "bolt-error.h" +#include "bolt-names.h" +#include "bolt-str.h" + +static void bolt_proxy_handle_props_changed (GDBusProxy *proxy, + GVariant *changed_properties, + GStrv invalidated_properties, + gpointer user_data); + +static void bolt_proxy_handle_dbus_signal (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *params, + gpointer user_data); + +G_DEFINE_TYPE (BoltProxy, bolt_proxy, G_TYPE_DBUS_PROXY); + + +static void +bolt_proxy_constructed (GObject *object) +{ + G_OBJECT_CLASS (bolt_proxy_parent_class)->constructed (object); + + g_signal_connect (object, "g-properties-changed", + G_CALLBACK (bolt_proxy_handle_props_changed), object); + + g_signal_connect (object, "g-signal", + G_CALLBACK (bolt_proxy_handle_dbus_signal), object); +} + +static const BoltProxySignal * +bolt_proxy_get_dbus_signals (guint *n) +{ + *n = 0; + return NULL; +} + +static void +bolt_proxy_class_init (BoltProxyClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->constructed = bolt_proxy_constructed; + + klass->get_dbus_signals = bolt_proxy_get_dbus_signals; + +} + +static void +bolt_proxy_init (BoltProxy *object) +{ +} + +static void +bolt_proxy_handle_props_changed (GDBusProxy *proxy, + GVariant *changed_properties, + GStrv invalidated_properties, + gpointer user_data) +{ + g_autoptr(GVariantIter) iter = NULL; + gboolean handled; + GParamSpec **pp; + const char *key; + guint n; + + pp = g_object_class_list_properties (G_OBJECT_GET_CLASS (proxy), &n); + + g_variant_get (changed_properties, "a{sv}", &iter); + while (g_variant_iter_next (iter, "{&sv}", &key, NULL)) + { + handled = FALSE; + for (guint i = 0; !handled && i < n; i++) + { + GParamSpec *pspec = pp[i]; + const char *nick; + const char *name; + + nick = g_param_spec_get_nick (pspec); + name = g_param_spec_get_name (pspec); + + handled = bolt_streq (nick, key); + + if (handled) + g_object_notify (G_OBJECT (user_data), name); + } + } + + g_free (pp); +} + +static void +bolt_proxy_handle_dbus_signal (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *params, + gpointer user_data) +{ + const BoltProxySignal *ps; + guint n; + + if (signal_name == NULL) + return; + + ps = BOLT_PROXY_GET_CLASS (proxy)->get_dbus_signals (&n); + + for (guint i = 0; i < n; i++) + { + const BoltProxySignal *sig = &ps[i]; + + if (g_str_equal (sig->theirs, signal_name)) + { + sig->handle (G_OBJECT (proxy), proxy, params); + break; + } + } + +} + +/* public methods */ + +gboolean +bolt_proxy_get_dbus_property (GObject *proxy, + GParamSpec *spec, + GValue *value) +{ + g_autoptr(GVariant) val = NULL; + const GVariantType *vt; + gboolean handled = FALSE; + const char *nick; + + nick = g_param_spec_get_nick (spec); + val = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), nick); + + if (val == NULL) + return FALSE; + + vt = g_variant_get_type (val); + + if (g_variant_type_equal (vt, G_VARIANT_TYPE_STRING) && + G_IS_PARAM_SPEC_ENUM (spec)) + { + GParamSpecEnum *enum_spec = G_PARAM_SPEC_ENUM (spec); + GEnumValue *ev; + const char *str; + + str = g_variant_get_string (val, NULL); + ev = g_enum_get_value_by_nick (enum_spec->enum_class, str); + + handled = ev != NULL; + + if (handled) + g_value_set_enum (value, ev->value); + else + g_value_set_enum (value, enum_spec->default_value); + } + else if (g_variant_type_equal (vt, G_VARIANT_TYPE_STRING) && + G_IS_PARAM_SPEC_FLAGS (spec)) + { + GParamSpecFlags *flags_spec = G_PARAM_SPEC_FLAGS (spec); + GFlagsClass *flags_class = flags_spec->flags_class; + const char *str; + guint v; + + str = g_variant_get_string (val, NULL); + handled = bolt_flags_class_from_string (flags_class, str, &v, NULL); + + if (handled) + g_value_set_flags (value, v); + else + g_value_set_flags (value, flags_spec->default_value); + } + else + { + g_dbus_gvariant_to_gvalue (val, value); + } + + return handled; +} + +gboolean +bolt_proxy_has_name_owner (BoltProxy *proxy) +{ + const char *name_owner; + + g_return_val_if_fail (proxy != NULL, FALSE); + g_return_val_if_fail (BOLT_IS_PROXY (proxy), FALSE); + + name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (proxy)); + + return name_owner != NULL; +} + +static GParamSpec * +find_property (BoltProxy *proxy, + const char *name, + GError **error) +{ + GParamSpec *res = NULL; + GParamSpec **pp; + guint n; + + pp = g_object_class_list_properties (G_OBJECT_GET_CLASS (proxy), &n); + + for (guint i = 0; i < n; i++) + { + GParamSpec *pspec = pp[i]; + + if (bolt_streq (pspec->name, name)) + { + res = pspec; + break; + } + } + + if (pp == NULL) + g_set_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_PROPERTY, + "could not find property '%s'", name); + + g_free (pp); + return res; +} + +static GVariant * +bolt_proxy_get_cached_property (BoltProxy *proxy, + const char *name) +{ + const char *bus_name = NULL; + GParamSpec *pspec; + GVariant *var; + + g_return_val_if_fail (BOLT_IS_PROXY (proxy), NULL); + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (proxy), name); + + if (pspec == NULL) + return NULL; + + bus_name = g_param_spec_get_nick (pspec); + var = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), bus_name); + + return var; +} + +gboolean +bolt_proxy_get_property_bool (BoltProxy *proxy, + const char *name, + gboolean *value) +{ + g_autoptr(GVariant) var = NULL; + + var = bolt_proxy_get_cached_property (proxy, name); + + if (var == NULL) + return FALSE; + else if (value) + *value = g_variant_get_boolean (var); + + return TRUE; +} + +gboolean +bolt_proxy_get_property_enum (BoltProxy *proxy, + const char *name, + gint *value) +{ + g_autoptr(GVariant) var = NULL; + const char *str = NULL; + const char *bus_name = NULL; + GParamSpec *pspec; + GEnumValue *ev; + + g_return_val_if_fail (BOLT_IS_PROXY (proxy), FALSE); + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (proxy), name); + + if (pspec == NULL) + return FALSE; + + bus_name = g_param_spec_get_nick (pspec); + var = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), bus_name); + if (var == NULL) + return FALSE; + + str = g_variant_get_string (var, NULL); + + if (str == NULL) + return FALSE; + + ev = g_enum_get_value_by_nick (G_PARAM_SPEC_ENUM (pspec)->enum_class, str); + + if (ev == NULL) + return FALSE; + + if (value) + *value = ev->value; + + return TRUE; +} + +gboolean +bolt_proxy_get_property_flags (BoltProxy *proxy, + const char *name, + guint *value) +{ + g_autoptr(GVariant) var = NULL; + const char *str = NULL; + const char *bus_name = NULL; + GFlagsClass *flags_class; + GParamSpec *pspec; + guint v; + gboolean ok; + + g_return_val_if_fail (BOLT_IS_PROXY (proxy), FALSE); + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (proxy), name); + + if (pspec == NULL || !G_IS_PARAM_SPEC_FLAGS (pspec)) + return FALSE; + + bus_name = g_param_spec_get_nick (pspec); + var = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (proxy), bus_name); + if (var == NULL) + return FALSE; + + str = g_variant_get_string (var, NULL); + + if (str == NULL) + return FALSE; + + flags_class = G_PARAM_SPEC_FLAGS (pspec)->flags_class; + ok = bolt_flags_class_from_string (flags_class, str, &v, NULL); + + if (ok && value) + *value = v; + + return ok; +} + +gboolean +bolt_proxy_get_property_uint32 (BoltProxy *proxy, + const char *name, + guint *value) +{ + g_autoptr(GVariant) var = NULL; + + var = bolt_proxy_get_cached_property (proxy, name); + + if (var == NULL) + return FALSE; + else if (value) + *value = g_variant_get_uint32 (var); + + return TRUE; +} + +gboolean +bolt_proxy_get_property_int64 (BoltProxy *proxy, + const char *name, + gint64 *value) +{ + g_autoptr(GVariant) var = NULL; + + var = bolt_proxy_get_cached_property (proxy, name); + + if (var == NULL) + return FALSE; + else if (value) + *value = g_variant_get_int64 (var); + + return TRUE; +} + +gboolean +bolt_proxy_get_property_uint64 (BoltProxy *proxy, + const char *name, + guint64 *value) +{ + g_autoptr(GVariant) var = NULL; + + var = bolt_proxy_get_cached_property (proxy, name); + + if (var == NULL) + return FALSE; + else if (value) + *value = g_variant_get_uint64 (var); + + return TRUE; +} + +const char * +bolt_proxy_get_property_string (BoltProxy *proxy, + const char *name) +{ + g_autoptr(GVariant) var = NULL; + const char *val = NULL; + + var = bolt_proxy_get_cached_property (proxy, name); + + if (var != NULL) + val = g_variant_get_string (var, NULL); + + if (val && *val == '\0') + val = NULL; + + return val; +} + +gboolean +bolt_proxy_set_property (BoltProxy *proxy, + const char *name, + GVariant *value, + GCancellable *cancellable, + GError **error) +{ + GParamSpec *pp; + const char *iface; + gboolean ok = FALSE; + GVariant *res; + + pp = find_property (proxy, name, NULL); + if (pp != NULL) + name = g_param_spec_get_nick (pp); + + iface = g_dbus_proxy_get_interface_name (G_DBUS_PROXY (proxy)); + + res = g_dbus_proxy_call_sync (G_DBUS_PROXY (proxy), + "org.freedesktop.DBus.Properties.Set", + g_variant_new ("(ssv)", + iface, + name, + value), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + error); + + if (res) + { + g_variant_unref (res); + ok = TRUE; + } + + return ok; +} + +void +bolt_proxy_set_property_async (BoltProxy *proxy, + const char *name, + GVariant *value, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GParamSpec *pp; + const char *iface; + + pp = find_property (proxy, name, NULL); + + if (pp != NULL) + name = g_param_spec_get_nick (pp); + + iface = g_dbus_proxy_get_interface_name (G_DBUS_PROXY (proxy)); + + g_dbus_proxy_call (G_DBUS_PROXY (proxy), + "org.freedesktop.DBus.Properties.Set", + g_variant_new ("(ssv)", + iface, + name, + value), + G_DBUS_CALL_FLAGS_NONE, + -1, + cancellable, + callback, + user_data); +} + +gboolean +bolt_proxy_set_property_finish (GAsyncResult *res, + GError **error) +{ + BoltProxy *proxy; + GVariant *val = NULL; + + proxy = (BoltProxy *) g_async_result_get_source_object (res); + val = g_dbus_proxy_call_finish (G_DBUS_PROXY (proxy), res, error); + + if (val == NULL) + return FALSE; + + g_variant_unref (val); + return TRUE; +} diff --git a/panels/thunderbolt/bolt-proxy.h b/panels/thunderbolt/bolt-proxy.h new file mode 100644 index 000000000..c05eb8c88 --- /dev/null +++ b/panels/thunderbolt/bolt-proxy.h @@ -0,0 +1,97 @@ +/* + * Copyright © 2017 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Christian J. Kellner + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +typedef struct BoltProxySignal +{ + + const char *theirs; + void (*handle)(GObject *self, + GDBusProxy *bus_proxy, + GVariant *params); + +} BoltProxySignal; + +#define BOLT_TYPE_PROXY (bolt_proxy_get_type ()) +G_DECLARE_DERIVABLE_TYPE (BoltProxy, bolt_proxy, BOLT, PROXY, GDBusProxy) + +struct _BoltProxyClass +{ + GDBusProxyClass parent; + + /* virtuals */ + const BoltProxySignal * (*get_dbus_signals) (guint *n); +}; + +gboolean bolt_proxy_get_dbus_property (GObject *proxy, + GParamSpec *spec, + GValue *value); + +gboolean bolt_proxy_has_name_owner (BoltProxy *proxy); + +gboolean bolt_proxy_get_property_bool (BoltProxy *proxy, + const char *name, + gboolean *value); + +gboolean bolt_proxy_get_property_enum (BoltProxy *proxy, + const char *name, + gint *value); + +gboolean bolt_proxy_get_property_flags (BoltProxy *proxy, + const char *name, + guint *value); + +gboolean bolt_proxy_get_property_uint32 (BoltProxy *proxy, + const char *name, + guint *value); + +gboolean bolt_proxy_get_property_int64 (BoltProxy *proxy, + const char *name, + gint64 *value); + +gboolean bolt_proxy_get_property_uint64 (BoltProxy *proxy, + const char *name, + guint64 *value); + +const char * bolt_proxy_get_property_string (BoltProxy *proxy, + const char *name); + +gboolean bolt_proxy_set_property (BoltProxy *proxy, + const char *name, + GVariant *value, + GCancellable *cancellable, + GError **error); + +void bolt_proxy_set_property_async (BoltProxy *proxy, + const char *name, + GVariant *value, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean bolt_proxy_set_property_finish (GAsyncResult *res, + GError **error); + +G_END_DECLS diff --git a/panels/thunderbolt/bolt-str.c b/panels/thunderbolt/bolt-str.c new file mode 100644 index 000000000..fe0580d48 --- /dev/null +++ b/panels/thunderbolt/bolt-str.c @@ -0,0 +1,117 @@ +/* + * Copyright © 2017 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Christian J. Kellner + */ + +#include "config.h" + +#include "bolt-str.h" + +#include + +typedef void (* zero_fn_t) (void *s, + size_t n); +void +bolt_erase_n (void *data, gsize n) +{ +#if !HAVE_FN_EXPLICIT_BZERO + #warning no explicit bzero, using fallback + static volatile zero_fn_t explicit_bzero = bzero; +#endif + + explicit_bzero (data, n); +} + +void +bolt_str_erase (char *str) +{ + if (str == NULL) + return; + + bolt_erase_n (str, strlen (str)); +} + +void +bolt_str_erase_clear (char **str) +{ + g_return_if_fail (str != NULL); + if (*str == NULL) + return; + + bolt_str_erase (*str); + g_free (*str); + *str = NULL; +} + +GStrv +bolt_strv_from_ptr_array (GPtrArray **array) +{ + GPtrArray *a; + + if (array == NULL || *array == NULL) + return NULL; + + a = *array; + + if (a->len == 0 || a->pdata[a->len - 1] != NULL) + g_ptr_array_add (a, NULL); + + *array = NULL; + return (GStrv) g_ptr_array_free (a, FALSE); +} + +char * +bolt_strdup_validate (const char *string) +{ + g_autofree char *str = NULL; + gboolean ok; + gsize l; + + if (string == NULL) + return NULL; + + str = g_strdup (string); + str = g_strstrip (str); + + l = strlen (str); + if (l == 0) + return NULL; + + ok = g_utf8_validate (str, l, NULL); + + if (!ok) + return NULL; + + return g_steal_pointer (&str); +} + +char * +bolt_strstrip (char *string) +{ + char *str; + + if (string == NULL) + return NULL; + + str = g_strstrip (string); + + if (strlen (str) == 0) + g_clear_pointer (&str, g_free); + + return str; +} diff --git a/panels/thunderbolt/bolt-str.h b/panels/thunderbolt/bolt-str.h new file mode 100644 index 000000000..ecf95a7ed --- /dev/null +++ b/panels/thunderbolt/bolt-str.h @@ -0,0 +1,43 @@ +/* + * Copyright © 2017 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Christian J. Kellner + */ + +#pragma once + +#include +#include + +G_BEGIN_DECLS + +void bolt_erase_n (void *data, + gsize n); +void bolt_str_erase (char *str); +void bolt_str_erase_clear (char **str); + +#define bolt_streq(s1, s2) (g_strcmp0 (s1, s2) == 0) + +GStrv bolt_strv_from_ptr_array (GPtrArray **array); + +#define bolt_yesno(val) val ? "yes" : "no" + +char *bolt_strdup_validate (const char *string); + +char *bolt_strstrip (char *string); + +G_END_DECLS diff --git a/panels/thunderbolt/bolt-time.c b/panels/thunderbolt/bolt-time.c new file mode 100644 index 000000000..606aed69a --- /dev/null +++ b/panels/thunderbolt/bolt-time.c @@ -0,0 +1,44 @@ +/* + * Copyright © 2018 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Christian J. Kellner + */ + +#include "config.h" + +#include "bolt-time.h" + +char * +bolt_epoch_format (guint64 seconds, const char *format) +{ + g_autoptr(GDateTime) dt = NULL; + + dt = g_date_time_new_from_unix_utc ((gint64) seconds); + + if (dt == NULL) + return NULL; + + return g_date_time_format (dt, format); +} + +guint64 +bolt_now_in_seconds (void) +{ + gint64 now = g_get_real_time (); + + return (guint64) now / G_USEC_PER_SEC; +} diff --git a/panels/thunderbolt/bolt-time.h b/panels/thunderbolt/bolt-time.h new file mode 100644 index 000000000..fc3ed9741 --- /dev/null +++ b/panels/thunderbolt/bolt-time.h @@ -0,0 +1,32 @@ +/* + * Copyright © 2018 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + * + * Authors: + * Christian J. Kellner + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +char * bolt_epoch_format (guint64 seconds, + const char *format); + +guint64 bolt_now_in_seconds (void); + +G_END_DECLS diff --git a/panels/thunderbolt/cc-bolt-device-dialog.c b/panels/thunderbolt/cc-bolt-device-dialog.c new file mode 100644 index 000000000..11469d46c --- /dev/null +++ b/panels/thunderbolt/cc-bolt-device-dialog.c @@ -0,0 +1,476 @@ +/* Copyright (C) 2018 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Authors: Christian J. Kellner + * + */ + +#include + +#include + +#include "bolt-device.h" +#include "bolt-error.h" +#include "bolt-time.h" + +#include "cc-thunderbolt-resources.h" + +#include "cc-bolt-device-dialog.h" + +struct _CcBoltDeviceDialog +{ + GtkDialog parent; + + BoltClient *client; + BoltDevice *device; + GCancellable *cancel; + + /* main ui */ + GtkHeaderBar *header_bar; + + /* notifications */ + GtkLabel *notify_label; + GtkRevealer *notify_revealer; + + /* device details */ + GtkLabel *name_label; + GtkLabel *status_label; + GtkLabel *uuid_label; + + GtkLabel *time_title; + GtkLabel *time_label; + + /* actions */ + GtkWidget *button_box; + GtkSpinner *spinner; + GtkButton *connect_button; + GtkButton *forget_button; +}; + +static void on_notify_button_clicked_cb (GtkButton *button, + CcBoltDeviceDialog *panel); + +static void on_forget_button_clicked_cb (CcBoltDeviceDialog *dialog); +static void on_connect_button_clicked_cb (CcBoltDeviceDialog *dialog); + +G_DEFINE_TYPE (CcBoltDeviceDialog, cc_bolt_device_dialog, GTK_TYPE_DIALOG); + +#define RESOURCE_UI "/org/gnome/control-center/thunderbolt/cc-bolt-device-dialog.ui" + +static const char * +status_to_string_for_ui (BoltDevice *dev) +{ + BoltStatus status; + BoltAuthFlags aflags; + gboolean nopcie; + + status = bolt_device_get_status (dev); + aflags = bolt_device_get_authflags(dev); + nopcie = bolt_flag_isset (aflags, BOLT_AUTH_NOPCIE); + + switch (status) + { + case BOLT_STATUS_DISCONNECTED: + return C_("Thunderbolt Device Status", "Disconnected"); + + case BOLT_STATUS_CONNECTING: + return C_("Thunderbolt Device Status", "Connecting"); + + case BOLT_STATUS_CONNECTED: + return C_("Thunderbolt Device Status", "Connected"); + + case BOLT_STATUS_AUTH_ERROR: + return C_("Thunderbolt Device Status", "Authorization Error"); + + case BOLT_STATUS_AUTHORIZING: + return C_("Thunderbolt Device Status", "Authorizing"); + + case BOLT_STATUS_AUTHORIZED: + case BOLT_STATUS_AUTHORIZED_NEWKEY: + case BOLT_STATUS_AUTHORIZED_SECURE: + case BOLT_STATUS_AUTHORIZED_DPONLY: + if (nopcie) + return C_("Thunderbolt Device Status", "Reduced Functionality"); + else + return C_("Thunderbolt Device Status", "Connected & Authorized"); + + case BOLT_STATUS_UNKNOWN: + break; /* use default return value, i.e. Unknown */ + } + + return C_("Thunderbolt Device Status", "Unknown"); +} + +static void +dialog_update_from_device (CcBoltDeviceDialog *dialog) +{ + g_autofree char *generated = NULL; + g_autofree char *timestr = NULL; + const char *label; + const char *uuid; + const char *status_brief; + BoltStatus status; + gboolean stored; + BoltDevice *dev; + guint timestamp; + + if (gtk_widget_in_destruction (GTK_WIDGET (dialog))) + return; + + dev = dialog->device; + + uuid = bolt_device_get_uid (dev); + label = bolt_device_get_label (dev); + + stored = bolt_device_is_stored (dev); + status = bolt_device_get_status (dev); + + if (label == NULL) + { + const char *name = bolt_device_get_name (dev); + const char *vendor = bolt_device_get_vendor (dev); + + generated = g_strdup_printf ("%s %s", name, vendor); + label = generated; + } + + gtk_label_set_label (dialog->name_label, label); + gtk_header_bar_set_title (dialog->header_bar, label); + + status_brief = status_to_string_for_ui (dev); + gtk_label_set_label (dialog->status_label, status_brief); + gtk_widget_set_visible (GTK_WIDGET (dialog->forget_button), stored); + + /* while we are having an ongoing operation we are setting the buttons + * to be in-sensitive. In that case, if the button was visible + * before it will be hidden when the operation is finished by the + * dialog_operation_done() function */ + if (gtk_widget_is_sensitive (GTK_WIDGET (dialog->connect_button))) + gtk_widget_set_visible (GTK_WIDGET (dialog->connect_button), + status == BOLT_STATUS_CONNECTED); + + gtk_label_set_label (dialog->uuid_label, uuid); + + if (bolt_status_is_authorized (status)) + { + /* Translators: The time point the device was authorized. */ + gtk_label_set_label (dialog->time_title, _("Authorized at:")); + timestamp = bolt_device_get_authtime (dev); + } + else if (bolt_status_is_connected (status)) + { + /* Translators: The time point the device was connected. */ + gtk_label_set_label (dialog->time_title, _("Connected at:")); + timestamp = bolt_device_get_conntime (dev); + } + else + { + /* Translators: The time point the device was enrolled, + * i.e. authorized and stored in the device database. */ + gtk_label_set_label (dialog->time_title, _("Enrolled at:")); + timestamp = bolt_device_get_storetime (dev); + } + + timestr = bolt_epoch_format (timestamp, "%c"); + gtk_label_set_label (dialog->time_label, timestr); + +} + +static void +on_device_notify_cb (GObject *gobject, + GParamSpec *pspec, + gpointer user_data) +{ + CcBoltDeviceDialog *dialog = CC_BOLT_DEVICE_DIALOG (user_data); + + dialog_update_from_device (dialog); +} + +static void +dialog_operation_start (CcBoltDeviceDialog *dialog) +{ + gtk_widget_set_sensitive (GTK_WIDGET (dialog->connect_button), FALSE); + gtk_widget_set_sensitive (GTK_WIDGET (dialog->forget_button), FALSE); + gtk_spinner_start (dialog->spinner); +} + +static void +dialog_operation_done (CcBoltDeviceDialog *dialog, + GtkWidget *sender, + GError *error) +{ + GtkWidget *cb = GTK_WIDGET (dialog->connect_button); + GtkWidget *fb = GTK_WIDGET (dialog->forget_button); + + /* don' do anything if we are being destroyed */ + if (gtk_widget_in_destruction (GTK_WIDGET (dialog))) + return; + + /* also don't do anything if the op was canceled */ + if (error != NULL && bolt_err_cancelled (error)) + return; + + gtk_spinner_stop (dialog->spinner); + + if (error != NULL) + { + gtk_label_set_label (dialog->notify_label, error->message); + gtk_revealer_set_reveal_child (dialog->notify_revealer, TRUE); + + /* set the *other* button to sensitive */ + gtk_widget_set_sensitive (cb, cb != sender); + gtk_widget_set_sensitive (fb, fb != sender); + } + else + { + gtk_widget_set_visible (sender, FALSE); + gtk_widget_set_sensitive (cb, TRUE); + gtk_widget_set_sensitive (fb, TRUE); + } +} + +static void +dialog_authorize_done (CcBoltDeviceDialog *dialog, + gboolean ok, + GError *error) +{ + if (!ok) + g_prefix_error (&error, _("Failed to authorize device: ")); + + dialog_operation_done (dialog, GTK_WIDGET (dialog->connect_button), error); +} + +static void +on_device_authorized (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + g_autoptr(GError) err = NULL; + CcBoltDeviceDialog *dialog = CC_BOLT_DEVICE_DIALOG (user_data); + gboolean ok; + + ok = bolt_device_authorize_finish (BOLT_DEVICE (source), res, &err); + dialog_authorize_done (dialog, ok, err); +} + +static void +on_device_enrolled (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + g_autoptr(GError) err = NULL; + CcBoltDeviceDialog *dialog = CC_BOLT_DEVICE_DIALOG (user_data); + gboolean ok; + + ok = bolt_client_enroll_device_finish (dialog->client, res, NULL, &err); + dialog_authorize_done (dialog, ok, err); +} + +static void +on_connect_button_clicked_cb (CcBoltDeviceDialog *dialog) +{ + BoltDevice *device = dialog->device; + gboolean stored; + + g_return_if_fail (device != NULL); + + dialog_operation_start (dialog); + + stored = bolt_device_is_stored (device); + if (stored) + { + bolt_device_authorize_async (device, + BOLT_AUTHCTRL_NONE, + dialog->cancel, + on_device_authorized, + dialog); + } + else + { + const char *uid = bolt_device_get_uid (device); + + bolt_client_enroll_device_async (dialog->client, + uid, + BOLT_POLICY_DEFAULT, + BOLT_AUTHCTRL_NONE, + dialog->cancel, + on_device_enrolled, + dialog); + } + +} + +static void +on_forget_device_done (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + g_autoptr(GError) err = NULL; + CcBoltDeviceDialog *dialog = CC_BOLT_DEVICE_DIALOG (user_data); + gboolean ok; + + ok = bolt_client_forget_device_finish (dialog->client, res, &err); + + if (!ok) + g_prefix_error (&err, _("Failed to forget device: ")); + + dialog_operation_done (dialog, GTK_WIDGET (dialog->forget_button), err); +} + +static void +on_forget_button_clicked_cb (CcBoltDeviceDialog *dialog) +{ + const char *uid = NULL; + + g_return_if_fail (dialog->device != NULL); + + uid = bolt_device_get_uid (dialog->device); + dialog_operation_start (dialog); + + bolt_client_forget_device_async (dialog->client, + uid, + dialog->cancel, + on_forget_device_done, + dialog); +} + +static void +on_notify_button_clicked_cb (GtkButton *button, + CcBoltDeviceDialog *dialog) +{ + gtk_revealer_set_reveal_child (dialog->notify_revealer, FALSE); +} + + +static void +cc_bolt_device_dialog_finalize (GObject *object) +{ + CcBoltDeviceDialog *dialog = CC_BOLT_DEVICE_DIALOG (object); + + g_clear_object (&dialog->device); + g_cancellable_cancel (dialog->cancel); + g_clear_object (&dialog->cancel); + g_clear_object (&dialog->client); + + G_OBJECT_CLASS (cc_bolt_device_dialog_parent_class)->finalize (object); +} + +static void +cc_bolt_device_dialog_class_init (CcBoltDeviceDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->finalize = cc_bolt_device_dialog_finalize; + + gtk_widget_class_set_template_from_resource (widget_class, RESOURCE_UI); + gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, header_bar); + + gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, notify_label); + gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, notify_revealer); + + gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, name_label); + gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, status_label); + + gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, uuid_label); + gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, time_title); + gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, time_label); + + gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, button_box); + gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, spinner); + gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, connect_button); + gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceDialog, forget_button); + + gtk_widget_class_bind_template_callback (widget_class, on_notify_button_clicked_cb); + gtk_widget_class_bind_template_callback (widget_class, on_connect_button_clicked_cb); + gtk_widget_class_bind_template_callback (widget_class, on_forget_button_clicked_cb); +} + +static void +cc_bolt_device_dialog_init (CcBoltDeviceDialog *dialog) +{ + g_resources_register (cc_thunderbolt_get_resource ()); + gtk_widget_init_template (GTK_WIDGET (dialog)); +} + +/* public functions */ +CcBoltDeviceDialog * +cc_bolt_device_dialog_new (void) +{ + CcBoltDeviceDialog *dialog; + + dialog = g_object_new (CC_TYPE_BOLT_DEVICE_DIALOG, + "use-header-bar", TRUE, + NULL); + return dialog; +} + +void +cc_bolt_device_dialog_set_client (CcBoltDeviceDialog *dialog, + BoltClient *client) +{ + g_clear_object (&dialog->client); + dialog->client = g_object_ref (client); +} + +void +cc_bolt_device_dialog_set_device (CcBoltDeviceDialog *dialog, + BoltDevice *device) +{ + if (device == dialog->device) + return; + + if (dialog->device) + { + g_cancellable_cancel (dialog->cancel); + g_clear_object (&dialog->cancel); + dialog->cancel = g_cancellable_new (); + + g_signal_handlers_disconnect_by_func (dialog->device, + G_CALLBACK (on_device_notify_cb), + dialog); + g_clear_object (&dialog->device); + } + + if (device == NULL) + return; + + dialog->device = g_object_ref (device); + g_signal_connect_object (dialog->device, + "notify", + G_CALLBACK (on_device_notify_cb), + dialog, + 0); + + /* reset the sensitivity of the buttons, because + * dialog_update_from_device, because it can't know */ + gtk_widget_set_sensitive (GTK_WIDGET (dialog->connect_button), TRUE); + gtk_widget_set_sensitive (GTK_WIDGET (dialog->forget_button), TRUE); + + dialog_update_from_device (dialog); +} + +BoltDevice * +cc_bolt_device_dialog_peek_device (CcBoltDeviceDialog *dialog) +{ + return dialog->device; +} + +gboolean +cc_bolt_device_dialog_device_equal (CcBoltDeviceDialog *dialog, + BoltDevice *device) +{ + return dialog->device != NULL && device == dialog->device; +} diff --git a/panels/thunderbolt/cc-bolt-device-dialog.h b/panels/thunderbolt/cc-bolt-device-dialog.h new file mode 100644 index 000000000..d2c44c858 --- /dev/null +++ b/panels/thunderbolt/cc-bolt-device-dialog.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2018 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Authors: Christian J. Kellner + * + */ + +#pragma once + +#include + +#include "bolt-client.h" +#include "bolt-device.h" + +G_BEGIN_DECLS + +#define CC_TYPE_BOLT_DEVICE_DIALOG cc_bolt_device_dialog_get_type () +G_DECLARE_FINAL_TYPE (CcBoltDeviceDialog, cc_bolt_device_dialog, CC, BOLT_DEVICE_DIALOG, GtkDialog); + + +CcBoltDeviceDialog * cc_bolt_device_dialog_new (void); + +void cc_bolt_device_dialog_set_client (CcBoltDeviceDialog *dialog, + BoltClient *client); + +void cc_bolt_device_dialog_set_device (CcBoltDeviceDialog *dialog, + BoltDevice *device); +BoltDevice * cc_bolt_device_dialog_peek_device (CcBoltDeviceDialog *dialog); + +gboolean cc_bolt_device_dialog_device_equal (CcBoltDeviceDialog *dialog, + BoltDevice *device); + +G_END_DECLS diff --git a/panels/thunderbolt/cc-bolt-device-dialog.ui b/panels/thunderbolt/cc-bolt-device-dialog.ui new file mode 100644 index 000000000..cd19796db --- /dev/null +++ b/panels/thunderbolt/cc-bolt-device-dialog.ui @@ -0,0 +1,359 @@ + + + + + + diff --git a/panels/thunderbolt/cc-bolt-device-entry.c b/panels/thunderbolt/cc-bolt-device-entry.c new file mode 100644 index 000000000..1e6d6e75a --- /dev/null +++ b/panels/thunderbolt/cc-bolt-device-entry.c @@ -0,0 +1,218 @@ +/* Copyright (C) 2018 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Authors: Christian J. Kellner + * + */ + +#include + +#include "bolt-str.h" + +#include "cc-bolt-device-entry.h" + +#include "cc-thunderbolt-resources.h" + +#include + +struct _CcBoltDeviceEntry +{ + GtkListBoxRow parent; + + BoltDevice *device; + + /* main ui */ + GtkLabel *name_label; + GtkLabel *status_label; +}; + +static const char * device_status_to_brief_for_ui (BoltDevice *dev); + +enum +{ + SIGNAL_STATUS_CHANGED, + SIGNAL_LAST +}; + +static guint signals[SIGNAL_LAST] = {0}; + +G_DEFINE_TYPE (CcBoltDeviceEntry, cc_bolt_device_entry, GTK_TYPE_LIST_BOX_ROW); + +#define RESOURCE_UI "/org/gnome/control-center/thunderbolt/cc-bolt-device-entry.ui" + +static void +entry_set_name (CcBoltDeviceEntry *entry) +{ + g_autofree char *name = NULL; + BoltDevice *dev = entry->device; + + g_return_if_fail (dev != NULL); + + name = bolt_device_get_display_name (dev); + + gtk_label_set_label (entry->name_label, name); +} + +static void +entry_update_status (CcBoltDeviceEntry *entry) +{ + const char *brief; + BoltStatus status; + + status = bolt_device_get_status (entry->device); + brief = device_status_to_brief_for_ui (entry->device); + + gtk_label_set_label (entry->status_label, brief); + + g_signal_emit (entry, + signals[SIGNAL_STATUS_CHANGED], + 0, + status); +} + +static void +on_device_notify_cb (GObject *gobject, + GParamSpec *pspec, + gpointer user_data) +{ + CcBoltDeviceEntry *entry = CC_BOLT_DEVICE_ENTRY (user_data); + const char *what; + + what = g_param_spec_get_name (pspec); + + if (bolt_streq (what, "status")) + entry_update_status (entry); + else if (bolt_streq (what, "label") || + bolt_streq (what, "name") || + bolt_streq (what, "vendor")) + entry_set_name (entry); +} + +/* device helpers */ + +static const char * +device_status_to_brief_for_ui (BoltDevice *dev) +{ + BoltStatus status; + BoltAuthFlags aflags; + gboolean nopcie; + + status = bolt_device_get_status (dev); + aflags = bolt_device_get_authflags(dev); + nopcie = bolt_flag_isset (aflags, BOLT_AUTH_NOPCIE); + + switch (status) + { + case BOLT_STATUS_DISCONNECTED: + return C_("Thunderbolt Device Status", "Disconnected"); + + case BOLT_STATUS_CONNECTING: + return C_("Thunderbolt Device Status", "Connecting"); + + case BOLT_STATUS_CONNECTED: + case BOLT_STATUS_AUTHORIZED_DPONLY: + return C_("Thunderbolt Device Status", "Connected"); + + case BOLT_STATUS_AUTH_ERROR: + return C_("Thunderbolt Device Status", "Error"); + + case BOLT_STATUS_AUTHORIZING: + return C_("Thunderbolt Device Status", "Authorizing"); + + case BOLT_STATUS_AUTHORIZED: + case BOLT_STATUS_AUTHORIZED_NEWKEY: + case BOLT_STATUS_AUTHORIZED_SECURE: + if (nopcie) + return C_("Thunderbolt Device Status", "Connected"); + else + return C_("Thunderbolt Device Status", "Authorized"); + + case BOLT_STATUS_UNKNOWN: + break; /* use function default */ + } + + return C_("Thunderbolt Device Status", "Unknown"); +} + +static void +cc_bolt_device_entry_finalize (GObject *object) +{ + CcBoltDeviceEntry *entry = CC_BOLT_DEVICE_ENTRY (object); + + g_clear_object (&entry->device); + + G_OBJECT_CLASS (cc_bolt_device_entry_parent_class)->finalize (object); +} + +static void +cc_bolt_device_entry_class_init (CcBoltDeviceEntryClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->finalize = cc_bolt_device_entry_finalize; + + gtk_widget_class_set_template_from_resource (widget_class, RESOURCE_UI); + gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceEntry, name_label); + gtk_widget_class_bind_template_child (widget_class, CcBoltDeviceEntry, status_label); + + signals[SIGNAL_STATUS_CHANGED] = + g_signal_new ("status-changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + NULL, + G_TYPE_NONE, + 1, BOLT_TYPE_STATUS); +} + +static void +cc_bolt_device_entry_init (CcBoltDeviceEntry *entry) +{ + g_resources_register (cc_thunderbolt_get_resource ()); + gtk_widget_init_template (GTK_WIDGET (entry)); +} + +/* public function */ + +CcBoltDeviceEntry * +cc_bolt_device_entry_new (BoltDevice *device) +{ + CcBoltDeviceEntry *entry; + + entry = g_object_new (CC_TYPE_BOLT_DEVICE_ENTRY, NULL); + entry->device = g_object_ref (device); + + entry_set_name (entry); + entry_update_status (entry); + + g_signal_connect_object (entry->device, + "notify", + G_CALLBACK (on_device_notify_cb), + entry, + 0); + + return entry; +} + +BoltDevice * +cc_bolt_device_entry_get_device (CcBoltDeviceEntry *entry) +{ + g_return_val_if_fail (entry != NULL, NULL); + g_return_val_if_fail (CC_IS_BOLT_DEVICE_ENTRY (entry), NULL); + + return entry->device; +} diff --git a/panels/thunderbolt/cc-bolt-device-entry.h b/panels/thunderbolt/cc-bolt-device-entry.h new file mode 100644 index 000000000..f93cee5f8 --- /dev/null +++ b/panels/thunderbolt/cc-bolt-device-entry.h @@ -0,0 +1,34 @@ +/* Copyright (C) 2018 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Authors: Christian J. Kellner + * + */ + +#pragma once + +#include +#include "bolt-device.h" + +G_BEGIN_DECLS + +#define CC_TYPE_BOLT_DEVICE_ENTRY cc_bolt_device_entry_get_type () +G_DECLARE_FINAL_TYPE (CcBoltDeviceEntry, cc_bolt_device_entry, CC, BOLT_DEVICE_ENTRY, GtkListBoxRow); + + +CcBoltDeviceEntry * cc_bolt_device_entry_new (BoltDevice *device); +BoltDevice * cc_bolt_device_entry_get_device (CcBoltDeviceEntry *entry); + +G_END_DECLS diff --git a/panels/thunderbolt/cc-bolt-device-entry.ui b/panels/thunderbolt/cc-bolt-device-entry.ui new file mode 100644 index 000000000..37f865333 --- /dev/null +++ b/panels/thunderbolt/cc-bolt-device-entry.ui @@ -0,0 +1,49 @@ + + + + + + diff --git a/panels/thunderbolt/cc-bolt-panel.c b/panels/thunderbolt/cc-bolt-panel.c new file mode 100644 index 000000000..e67e3625e --- /dev/null +++ b/panels/thunderbolt/cc-bolt-panel.c @@ -0,0 +1,958 @@ +/* Copyright (C) 2018 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Authors: Christian J. Kellner + * + */ + +#include + +#include +#include + +#include +#include + +#include "cc-bolt-device-dialog.h" +#include "cc-bolt-device-entry.h" + +#include "bolt-client.h" +#include "bolt-str.h" + +#include "cc-thunderbolt-resources.h" + +#define CC_TYPE_BOLT_PANEL cc_bolt_panel_get_type () +G_DECLARE_FINAL_TYPE (CcBoltPanel, cc_bolt_panel, CC, BOLT_PANEL, CcPanel); + +struct _CcBoltPanel +{ + CcPanel parent; + + BoltClient *client; + GCancellable *cancel; + + /* headerbar menu */ + GtkBox *headerbar_box; + GtkLockButton *lock_button; + + /* main ui */ + GtkStack *container; + + /* empty state */ + GtkLabel *notb_caption; + GtkLabel *notb_details; + + /* notifications */ + GtkLabel *notification_label; + GtkRevealer *notification_revealer; + + /* authmode */ + GtkSwitch *authmode_switch; + GtkSpinner *authmode_spinner; + GtkStack *authmode_mode; + + /* device list */ + GHashTable *devices; + + GtkStack *devices_stack; + GtkBox *devices_box; + GtkBox *pending_box; + + GtkListBox *devices_list; + GtkListBox *pending_list; + + /* device details dialog */ + CcBoltDeviceDialog *device_dialog; + + /* polkit integration */ + GPermission *permission; +}; + +/* initialization */ +static void bolt_client_ready (GObject *source, + GAsyncResult *res, + gpointer user_data); + +/* panel functions */ +static void cc_bolt_panel_set_no_thunderbolt (CcBoltPanel *panel, + const char *custom_msg); + +static void cc_bolt_panel_name_owner_changed (CcBoltPanel *panel); + +static CcBoltDeviceEntry * cc_bolt_panel_add_device (CcBoltPanel *panel, + BoltDevice *dev); + +static void cc_bolt_panel_del_device_entry (CcBoltPanel *panel, + CcBoltDeviceEntry *entry); + +static void cc_bolt_panel_authmode_sync (CcBoltPanel *panel); + +static void cc_panel_list_box_migrate (CcBoltPanel *panel, + GtkListBox *from, + GtkListBox *to, + CcBoltDeviceEntry *entry); + +/* bolt client signals */ +static void on_bolt_name_owner_changed_cb (GObject *object, + GParamSpec *pspec, + gpointer user_data); + +static void on_bolt_device_added_cb (BoltClient *cli, + const char *path, + CcBoltPanel *panel); + +static void on_bolt_device_removed_cb (BoltClient *cli, + const char *opath, + CcBoltPanel *panel); + +static void on_bolt_notify_authmode_cb (GObject *gobject, + GParamSpec *pspec, + gpointer user_data); + +/* panel signals */ +static gboolean on_authmode_state_set_cb (CcBoltPanel *panel, + gboolean state, + GtkSwitch *toggle); + +static void on_device_entry_row_activated_cb (CcBoltPanel *panel, + GtkListBoxRow *row); + +static gboolean on_device_dialog_delete_event_cb (GtkWidget *widget, + GdkEvent *event, + CcBoltPanel *panel); + +static void on_device_entry_status_changed_cb (CcBoltDeviceEntry *entry, + BoltStatus new_status, + CcBoltPanel *panel); + +static void on_notification_button_clicked_cb (GtkButton *button, + CcBoltPanel *panel); + + +/* polkit */ +static void on_permission_ready (GObject *source_object, + GAsyncResult *res, + gpointer user_data); + +static void on_permission_notify_cb (GPermission *permission, + GParamSpec *pspec, + CcBoltPanel *panel); + +/* device related helpers helpers */ +static gint device_entries_sort_by_recency (GtkListBoxRow *a_row, + GtkListBoxRow *b_row, + gpointer user_data); + +static gint device_entries_sort_by_syspath (GtkListBoxRow *a_row, + GtkListBoxRow *b_row, + gpointer user_data); + +#define RESOURCE_PANEL_UI "/org/gnome/control-center/thunderbolt/cc-bolt-panel.ui" + +CC_PANEL_REGISTER (CcBoltPanel, cc_bolt_panel); + +static void +bolt_client_ready (GObject *source, + GAsyncResult *res, + gpointer user_data) +{ + g_autoptr(GError) err = NULL; + g_autoptr(CcBoltPanel) panel = NULL; + BoltClient *client; + + panel = CC_BOLT_PANEL (user_data); + client = bolt_client_new_finish (res, &err); + + if (client == NULL) + { + const char *text; + + /* operation got cancelled because the panel got destroyed */ + if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED) || + g_error_matches (err, G_IO_ERROR, G_IO_ERROR_FAILED_HANDLED)) + return; + + g_warning ("Could not create client: %s", err->message); + text = _("The thunderbolt subsystem (boltd) is not installed or " + "not setup properly."); + + gtk_label_set_label (panel->notb_details, text); + gtk_stack_set_visible_child_name (panel->container, "no-thunderbolt"); + + return; + } + + g_signal_connect_object (client, "notify::g-name-owner", + G_CALLBACK (on_bolt_name_owner_changed_cb), + panel, 0); + + g_signal_connect_object (client, "device-added", + G_CALLBACK (on_bolt_device_added_cb), + panel, 0); + + g_signal_connect_object (client, "device-removed", + G_CALLBACK (on_bolt_device_removed_cb), + panel, 0); + + g_signal_connect_object (client, "notify::auth-mode", + G_CALLBACK (on_bolt_notify_authmode_cb), + panel, 0); + + panel->client = client; + + cc_bolt_device_dialog_set_client (panel->device_dialog, client); + + cc_bolt_panel_authmode_sync (panel); + + g_object_bind_property (panel->authmode_switch, "active", + panel->devices_box, "sensitive", + G_BINDING_SYNC_CREATE); + + g_object_bind_property (panel->authmode_switch, "active", + panel->pending_box, "sensitive", + G_BINDING_SYNC_CREATE); + + gtk_stack_set_visible_child_name (panel->devices_stack, "no-devices"); + cc_bolt_panel_name_owner_changed (panel); +} + +static gboolean +devices_table_transfer_entry (GHashTable *from, + GHashTable *to, + gconstpointer key) +{ + gpointer k, v; + gboolean found; + + found = g_hash_table_lookup_extended (from, key, &k, &v); + + if (found) + { + g_hash_table_steal (from, key); + g_hash_table_insert (to, k, v); + } + + return found; +} + +static void +devices_table_clear_entries (GHashTable *table, + CcBoltPanel *panel) +{ + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init (&iter, table); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + CcBoltDeviceEntry *entry = value; + + cc_bolt_panel_del_device_entry (panel, entry); + g_hash_table_iter_remove (&iter); + } +} + +static void +devices_table_synchronize (CcBoltPanel *panel) +{ + g_autoptr(GError) err = NULL; + g_autoptr(GPtrArray) devices = NULL; + g_autoptr(GHashTable) old = NULL; + + devices = bolt_client_list_devices (panel->client, panel->cancel, &err); + + if (devices == NULL) + { + g_warning ("Could not list devices: %s", err->message); + devices = g_ptr_array_new_with_free_func (g_object_unref); + } + + old = panel->devices; + panel->devices = g_hash_table_new (g_str_hash, g_str_equal); + + for (guint i = 0; i < devices->len; i++) + { + BoltDevice *dev = g_ptr_array_index (devices, i); + const char *path; + gboolean found; + + path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (dev)); + found = devices_table_transfer_entry (old, panel->devices, path); + + if (found) + continue; + + cc_bolt_panel_add_device (panel, dev); + } + + devices_table_clear_entries (old, panel); + gtk_stack_set_visible_child_name (panel->container, "devices-listing"); +} + +static gboolean +list_box_sync_visible (GtkListBox *lstbox) +{ + g_autoptr(GList) children = NULL; + gboolean show; + + children = gtk_container_get_children (GTK_CONTAINER (lstbox)); + show = g_list_length (children) > 0; + + gtk_widget_set_visible (GTK_WIDGET (lstbox), show); + + return show; +} + +static GtkWidget * +cc_bolt_panel_box_for_listbox (CcBoltPanel *panel, + GtkListBox *lstbox) +{ + if ((gpointer) lstbox == panel->devices_list) + return GTK_WIDGET (panel->devices_box); + else if ((gpointer) lstbox == panel->pending_list) + return GTK_WIDGET (panel->pending_box); + + g_return_val_if_reached (NULL); +} + +static CcBoltDeviceEntry * +cc_bolt_panel_add_device (CcBoltPanel *panel, + BoltDevice *dev) +{ + CcBoltDeviceEntry *entry; + BoltDeviceType type; + BoltStatus status; + const char *path; + + type = bolt_device_get_device_type (dev); + + if (type != BOLT_DEVICE_PERIPHERAL) + return FALSE; + + entry = cc_bolt_device_entry_new (dev); + path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (dev)); + + /* add to the list box */ + gtk_widget_show_all (GTK_WIDGET (entry)); + + status = bolt_device_get_status (dev); + + if (bolt_status_is_pending (status)) + { + gtk_container_add (GTK_CONTAINER (panel->pending_list), GTK_WIDGET (entry)); + gtk_widget_show_all (GTK_WIDGET (panel->pending_list)); + gtk_widget_show_all (GTK_WIDGET (panel->pending_box)); + } + else + { + gtk_container_add (GTK_CONTAINER (panel->devices_list), GTK_WIDGET (entry)); + gtk_widget_show_all (GTK_WIDGET (panel->devices_list)); + gtk_widget_show_all (GTK_WIDGET (panel->devices_box)); + } + + g_signal_connect_object (entry, "status-changed", + G_CALLBACK (on_device_entry_status_changed_cb), + panel, 0); + + gtk_stack_set_visible_child_name (panel->devices_stack, "have-devices"); + g_hash_table_insert (panel->devices, (gpointer) path, entry); + return entry; +} + +static void +cc_bolt_panel_del_device_entry (CcBoltPanel *panel, + CcBoltDeviceEntry *entry) +{ + BoltDevice *dev; + GtkWidget *box; + GtkWidget *p; + gboolean show; + + dev = cc_bolt_device_entry_get_device (entry); + if (cc_bolt_device_dialog_device_equal (panel->device_dialog, dev)) + { + gtk_widget_hide (GTK_WIDGET (panel->device_dialog)); + cc_bolt_device_dialog_set_device (panel->device_dialog, NULL); + } + + p = gtk_widget_get_parent (GTK_WIDGET (entry)); + gtk_widget_destroy (GTK_WIDGET (entry)); + + box = cc_bolt_panel_box_for_listbox (panel, GTK_LIST_BOX (p)); + show = list_box_sync_visible (GTK_LIST_BOX (p)); + gtk_widget_set_visible (box, show); + + if (!gtk_widget_is_visible (GTK_WIDGET (panel->pending_list)) && + !gtk_widget_is_visible (GTK_WIDGET (panel->devices_list))) + gtk_stack_set_visible_child_name (panel->devices_stack, "no-devices"); +} + +static void +cc_bolt_panel_authmode_sync (CcBoltPanel *panel) +{ + BoltClient *client = panel->client; + BoltAuthMode mode; + gboolean enabled; + const char *name; + + mode = bolt_client_get_authmode (client); + + enabled = (mode & BOLT_AUTH_ENABLED) != 0; + + g_signal_handlers_block_by_func (panel->authmode_switch, + on_authmode_state_set_cb, + panel); + + gtk_switch_set_state (panel->authmode_switch, enabled); + + g_signal_handlers_unblock_by_func (panel->authmode_switch, + on_authmode_state_set_cb, + panel); + + name = enabled ? "enabled" : "disabled"; + gtk_stack_set_visible_child_name (panel->authmode_mode, name); +} + +static void +cc_panel_list_box_migrate (CcBoltPanel *panel, + GtkListBox *from, + GtkListBox *to, + CcBoltDeviceEntry *entry) +{ + GtkWidget *from_box; + GtkWidget *to_box; + gboolean show; + GtkWidget *target; + + target = GTK_WIDGET (entry); + + gtk_container_remove (GTK_CONTAINER (from), target); + gtk_container_add (GTK_CONTAINER (to), target); + gtk_widget_show_all (GTK_WIDGET (to)); + + from_box = cc_bolt_panel_box_for_listbox (panel, from); + to_box = cc_bolt_panel_box_for_listbox (panel, to); + + show = list_box_sync_visible (from); + gtk_widget_set_visible (from_box, show); + gtk_widget_set_visible (to_box, TRUE); +} + +/* bolt client signals */ +static void +cc_bolt_panel_set_no_thunderbolt (CcBoltPanel *panel, + const char *msg) +{ + if (msg == NULL) + msg = _("Thunderbolt could not be detected.\n" + "Either the system lacks Thunderbolt support, " + "it has been disabled in the BIOS or is set to " + "an unsupported security level in the BIOS."); + + gtk_label_set_label (panel->notb_details, msg); + gtk_stack_set_visible_child_name (panel->container, "no-thunderbolt"); +} + +static void +cc_bolt_panel_name_owner_changed (CcBoltPanel *panel) +{ + BoltClient *client = panel->client; + BoltSecurity sl; + gboolean notb = TRUE; + const char *text = NULL; + const char *name_owner; + + name_owner = g_dbus_proxy_get_name_owner (G_DBUS_PROXY (panel->client)); + + if (name_owner == NULL) + { + cc_bolt_panel_set_no_thunderbolt (panel, NULL); + devices_table_clear_entries (panel->devices, panel); + gtk_widget_hide (GTK_WIDGET (panel->headerbar_box)); + return; + } + + gtk_stack_set_visible_child_name (panel->container, "loading"); + + sl = bolt_client_get_security (client); + + switch (sl) + { + case BOLT_SECURITY_NONE: + case BOLT_SECURITY_SECURE: + case BOLT_SECURITY_USER: + /* we fetch the device list and show them here */ + notb = FALSE; + break; + + case BOLT_SECURITY_DPONLY: + case BOLT_SECURITY_USBONLY: + text = _("Thunderbolt support has been disabled in the BIOS."); + break; + + case BOLT_SECURITY_UNKNOWN: + text = NULL; + break; + } + + if (notb) + { + /* security level is unknown or un-handled */ + cc_bolt_panel_set_no_thunderbolt (panel, text); + return; + } + + if (panel->permission) + gtk_widget_show (GTK_WIDGET (panel->headerbar_box)); + else + polkit_permission_new ("org.freedesktop.bolt.manage", + NULL, + panel->cancel, + on_permission_ready, + g_object_ref (panel)); + + devices_table_synchronize (panel); +} + +/* bolt client signals */ +static void +on_bolt_name_owner_changed_cb (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + CcBoltPanel *panel = CC_BOLT_PANEL (user_data); + + cc_bolt_panel_name_owner_changed (panel); +} + +static void +on_bolt_device_added_cb (BoltClient *cli, + const char *path, + CcBoltPanel *panel) +{ + g_autoptr(GError) err = NULL; + GDBusConnection *bus; + BoltDevice *dev; + gboolean found; + + found = g_hash_table_contains (panel->devices, path); + + if (found) + return; + + bus = g_dbus_proxy_get_connection (G_DBUS_PROXY (panel->client)); + dev = bolt_device_new_for_object_path (bus, path, panel->cancel, &err); + + if (dev == NULL) + { + g_warning ("Could not create proxy for %s", path); + return; + } + + cc_bolt_panel_add_device (panel, dev); +} + +static void +on_bolt_device_removed_cb (BoltClient *cli, + const char *path, + CcBoltPanel *panel) +{ + CcBoltDeviceEntry *entry; + + entry = g_hash_table_lookup (panel->devices, path); + + if (entry == NULL) + return; + + cc_bolt_panel_del_device_entry (panel, entry); + g_hash_table_remove (panel->devices, path); +} + +static void +on_bolt_notify_authmode_cb (GObject *gobject, + GParamSpec *pspec, + gpointer user_data) +{ + CcBoltPanel *panel = CC_BOLT_PANEL (user_data); + + cc_bolt_panel_authmode_sync (panel); +} + +/* panel signals */ + +static void +on_authmode_ready (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + g_autoptr(GError) error = NULL; + CcBoltPanel *panel = CC_BOLT_PANEL (user_data); + gboolean ok; + + ok = bolt_client_set_authmode_finish (BOLT_CLIENT (source_object), res, &error); + if (!ok) + { + g_autofree char *text; + + g_warning ("Could not set authmode: %s", error->message); + + text = g_strdup_printf (_("Error switching direct mode: %s"), error->message); + gtk_label_set_markup (panel->notification_label, text); + gtk_revealer_set_reveal_child (panel->notification_revealer, TRUE); + + /* make sure we are reflecting the correct state */ + cc_bolt_panel_authmode_sync (panel); + } + + gtk_spinner_stop (panel->authmode_spinner); + gtk_widget_set_sensitive (GTK_WIDGET (panel->authmode_switch), TRUE); +} + +static gboolean +on_authmode_state_set_cb (CcBoltPanel *panel, + gboolean enable, + GtkSwitch *toggle) +{ + BoltClient *client = panel->client; + BoltAuthMode mode; + + gtk_widget_set_sensitive (GTK_WIDGET (panel->authmode_switch), FALSE); + gtk_spinner_start (panel->authmode_spinner); + + mode = bolt_client_get_authmode (client); + + if (enable) + mode = mode | BOLT_AUTH_ENABLED; + else + mode = mode & ~BOLT_AUTH_ENABLED; + + bolt_client_set_authmode_async (client, mode, NULL, on_authmode_ready, panel); + + return TRUE; +} + +static void +on_device_entry_row_activated_cb (CcBoltPanel *panel, + GtkListBoxRow *row) +{ + CcBoltDeviceEntry *entry; + BoltDevice *device; + + if (!CC_IS_BOLT_DEVICE_ENTRY (row)) + return; + + entry = CC_BOLT_DEVICE_ENTRY (row); + device = cc_bolt_device_entry_get_device (entry); + + cc_bolt_device_dialog_set_device (panel->device_dialog, device); + gtk_window_resize (GTK_WINDOW (panel->device_dialog), 1, 1); + gtk_widget_show (GTK_WIDGET (panel->device_dialog)); +} + +static gboolean +on_device_dialog_delete_event_cb (GtkWidget *widget, + GdkEvent *event, + CcBoltPanel *panel) +{ + CcBoltDeviceDialog *dialog; + + dialog = CC_BOLT_DEVICE_DIALOG (widget); + + cc_bolt_device_dialog_set_device (dialog, NULL); + gtk_widget_hide (widget); + + return TRUE; +} + +static void +on_device_entry_status_changed_cb (CcBoltDeviceEntry *entry, + BoltStatus new_status, + CcBoltPanel *panel) +{ + GtkListBox *from = NULL; + GtkListBox *to = NULL; + GtkWidget *p; + gboolean is_pending; + gboolean parent_pending; + + /* if we are doing some active work, then lets not change + * the list the entry is in; otherwise we might just hop + * from one box to the other and back again. + */ + if (new_status == BOLT_STATUS_CONNECTING || + new_status == BOLT_STATUS_AUTHORIZING) + return; + + is_pending = bolt_status_is_pending (new_status); + + p = gtk_widget_get_parent (GTK_WIDGET (entry)); + parent_pending = (gpointer) p == panel->pending_list; + + /* */ + if (is_pending && !parent_pending) + { + from = panel->devices_list; + to = panel->pending_list; + } + else if (!is_pending && parent_pending) + { + from = panel->pending_list; + to = panel->devices_list; + } + + if (from && to) + cc_panel_list_box_migrate (panel, from, to, entry); +} + + +static void +on_notification_button_clicked_cb (GtkButton *button, + CcBoltPanel *panel) +{ + gtk_revealer_set_reveal_child (panel->notification_revealer, FALSE); +} + +/* polkit */ + +static void +on_permission_ready (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + g_autoptr(GError) err = NULL; + g_autoptr(CcBoltPanel) panel = user_data; + GPermission *permission; + gboolean is_allowed; + const char *name; + + permission = polkit_permission_new_finish (res, &err); + panel->permission = permission; + + if (panel->permission == NULL) + { + g_warning ("Could not get polkit permissions: %s", err->message); + return; + } + + g_signal_connect_object (permission, + "notify", + G_CALLBACK (on_permission_notify_cb), + panel, + G_CONNECT_AFTER); + + is_allowed = g_permission_get_allowed (permission); + gtk_widget_set_sensitive (GTK_WIDGET (panel->authmode_switch), is_allowed); + gtk_lock_button_set_permission (panel->lock_button, permission); + + name = gtk_stack_get_visible_child_name (panel->container); + + gtk_widget_set_visible (GTK_WIDGET (panel->headerbar_box), + bolt_streq (name, "devices-listing")); +} + +static void +on_permission_notify_cb (GPermission *permission, + GParamSpec *pspec, + CcBoltPanel *panel) +{ + gboolean is_allowed = g_permission_get_allowed (permission); + + gtk_widget_set_sensitive (GTK_WIDGET (panel->authmode_switch), is_allowed); +} + +static gint +device_entries_sort_by_recency (GtkListBoxRow *a_row, + GtkListBoxRow *b_row, + gpointer user_data) +{ + CcBoltDeviceEntry *a_entry = CC_BOLT_DEVICE_ENTRY (a_row); + CcBoltDeviceEntry *b_entry = CC_BOLT_DEVICE_ENTRY (b_row); + BoltDevice *a = cc_bolt_device_entry_get_device (a_entry); + BoltDevice *b = cc_bolt_device_entry_get_device (b_entry); + BoltStatus status; + gint64 a_ts, b_ts; + gint64 score; + + a_ts = (gint64) bolt_device_get_timestamp (a); + b_ts = (gint64) bolt_device_get_timestamp (b); + + score = b_ts - a_ts; + + if (score != 0) + return score; + + status = bolt_device_get_status (a); + + if (bolt_status_is_connected (status)) + { + const char *a_path; + const char *b_path; + + a_path = bolt_device_get_syspath (a); + b_path = bolt_device_get_syspath (b); + + return g_strcmp0 (a_path, b_path); + } + else + { + const char *a_name; + const char *b_name; + + a_name = bolt_device_get_name (a); + b_name = bolt_device_get_name (b); + + return g_strcmp0 (a_name, b_name); + } + + return 0; +} + +static gint +device_entries_sort_by_syspath (GtkListBoxRow *a_row, + GtkListBoxRow *b_row, + gpointer user_data) +{ + CcBoltDeviceEntry *a_entry = CC_BOLT_DEVICE_ENTRY (a_row); + CcBoltDeviceEntry *b_entry = CC_BOLT_DEVICE_ENTRY (b_row); + BoltDevice *a = cc_bolt_device_entry_get_device (a_entry); + BoltDevice *b = cc_bolt_device_entry_get_device (b_entry); + + const char *a_path; + const char *b_path; + + a_path = bolt_device_get_syspath (a); + b_path = bolt_device_get_syspath (b); + + return g_strcmp0 (a_path, b_path); +} + +static void +cc_bolt_panel_finalize (GObject *object) +{ + CcBoltPanel *panel = CC_BOLT_PANEL (object); + + g_clear_object (&panel->client); + g_clear_pointer (&panel->devices, g_hash_table_unref); + g_clear_object (&panel->permission); + + G_OBJECT_CLASS (cc_bolt_panel_parent_class)->finalize (object); +} + +static void +cc_bolt_panel_dispose (GObject *object) +{ + CcBoltPanel *panel = CC_BOLT_PANEL (object); + + /* cancel any ongoing operation */ + g_cancellable_cancel (panel->cancel); + + /* Must be destroyed in dispose, not finalize. */ + g_clear_pointer (&panel->device_dialog, gtk_widget_destroy); + + G_OBJECT_CLASS (cc_bolt_panel_parent_class)->dispose (object); +} + +static void +cc_bolt_panel_constructed (GObject *object) +{ + CcBoltPanel *panel = CC_BOLT_PANEL (object); + GtkWindow *parent; + CcShell *shell; + + parent = GTK_WINDOW (cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (panel)))); + gtk_window_set_transient_for (GTK_WINDOW (panel->device_dialog), parent); + + G_OBJECT_CLASS (cc_bolt_panel_parent_class)->constructed (object); + + shell = cc_panel_get_shell (CC_PANEL (panel)); + cc_shell_embed_widget_in_header (shell, GTK_WIDGET (panel->headerbar_box)); +} + +static void +cc_bolt_panel_class_init (CcBoltPanelClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->constructed = cc_bolt_panel_constructed; + object_class->dispose = cc_bolt_panel_dispose; + object_class->finalize = cc_bolt_panel_finalize; + + gtk_widget_class_set_template_from_resource (widget_class, RESOURCE_PANEL_UI); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, headerbar_box); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, lock_button); + + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, container); + + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, notb_caption); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, notb_details); + + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, notification_label); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, notification_revealer); + + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, authmode_mode); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, authmode_switch); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, authmode_spinner); + + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, devices_stack); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, devices_box); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, pending_box); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, devices_list); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, pending_list); + + gtk_widget_class_bind_template_callback (widget_class, on_notification_button_clicked_cb); + gtk_widget_class_bind_template_callback (widget_class, on_authmode_state_set_cb); + gtk_widget_class_bind_template_callback (widget_class, on_device_entry_row_activated_cb); +} + +static void +cc_bolt_panel_init (CcBoltPanel *panel) +{ + g_resources_register (cc_thunderbolt_get_resource ()); + gtk_widget_init_template (GTK_WIDGET (panel)); + + gtk_stack_set_visible_child_name (panel->container, "loading"); + + gtk_list_box_set_header_func (panel->devices_list, + cc_list_box_update_header_func, + NULL, NULL); + + gtk_list_box_set_header_func (panel->pending_list, + cc_list_box_update_header_func, + NULL, NULL); + + gtk_list_box_set_sort_func (panel->devices_list, + device_entries_sort_by_recency, + panel, + NULL); + + gtk_list_box_set_sort_func (panel->pending_list, + device_entries_sort_by_syspath, + panel, + NULL); + + panel->devices = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + + panel->device_dialog = cc_bolt_device_dialog_new (); + g_signal_connect_object (panel->device_dialog, "delete-event", + G_CALLBACK (on_device_dialog_delete_event_cb), + panel, 0); + + panel->cancel = g_cancellable_new (); + bolt_client_new_async (panel->cancel, + bolt_client_ready, + g_object_ref (panel)); + +} diff --git a/panels/thunderbolt/cc-bolt-panel.ui b/panels/thunderbolt/cc-bolt-panel.ui new file mode 100644 index 000000000..5ec674860 --- /dev/null +++ b/panels/thunderbolt/cc-bolt-panel.ui @@ -0,0 +1,594 @@ + + + + + + + + + False + False + 6 + end + + + True + + + + + diff --git a/panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in b/panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in new file mode 100644 index 000000000..db2477e45 --- /dev/null +++ b/panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in @@ -0,0 +1,17 @@ +[Desktop Entry] +Name=Thunderbolt +Comment=Manage Thunderbolt devices +Exec=gnome-control-center thunderbolt +Icon=thunderbolt +Terminal=false +Type=Application +NoDisplay=true +StartupNotify=true +Categories=GNOME;GTK;Settings;X-GNOME-Settings-Panel;HardwareSettings;X-GNOME-DevicesSettings;X-GNOME-ConnectivitySettings; +OnlyShowIn=GNOME;Unity; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gnome-control-center +X-GNOME-Bugzilla-Component=thunderbolt +X-GNOME-Bugzilla-Version=@VERSION@ +# Translators: those are keywords for the thunderbolt control-center panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +Keywords=Thunderbolt; diff --git a/panels/thunderbolt/meson.build b/panels/thunderbolt/meson.build new file mode 100644 index 000000000..e85566157 --- /dev/null +++ b/panels/thunderbolt/meson.build @@ -0,0 +1,74 @@ +panels_list += cappletname + +desktop = 'gnome-@0@-panel.desktop'.format(cappletname) +desktop_in = configure_file( + input: desktop + '.in.in', + output: desktop + '.in', + configuration: desktop_conf +) + +i18n.merge_file( + desktop, + type: 'desktop', + input: desktop_in, + output: desktop, + po_dir: po_dir, + install: true, + install_dir: control_center_desktopdir +) + +sources = files( + 'bolt-client.c', + 'bolt-device.c', + 'bolt-enums.c', + 'bolt-error.c', + 'bolt-proxy.c', + 'bolt-str.c', + 'bolt-time.c', + 'cc-bolt-panel.c', + 'cc-bolt-device-dialog.c', + 'cc-bolt-device-entry.c', +) + +enum_headers = [ + 'bolt-enums.h', + 'bolt-error.h' +] + +sources += gnome.mkenums_simple( + 'bolt-enum-types', + sources: enum_headers) + +resource_data = files( + 'cc-bolt-device-dialog.ui', + 'cc-bolt-device-entry.ui', + 'cc-bolt-panel.ui' +) + +sources += gnome.compile_resources( + 'cc-' + cappletname + '-resources', + cappletname + '.gresource.xml', + source_dir: '.', + c_name: 'cc_' + cappletname, + dependencies: resource_data, + export: true +) + +deps = common_deps + [ + gnome_desktop_dep, + polkit_gobject_dep, + m_dep, +] + +cflags += [ + '-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir), + '-DBINDIR="@0@"'.format(control_center_bindir) +] + +panels_libs += static_library( + cappletname, + sources: sources, + include_directories: top_inc, + dependencies: deps, + c_args: cflags +) diff --git a/panels/thunderbolt/thunderbolt.gresource.xml b/panels/thunderbolt/thunderbolt.gresource.xml new file mode 100644 index 000000000..8953d6243 --- /dev/null +++ b/panels/thunderbolt/thunderbolt.gresource.xml @@ -0,0 +1,9 @@ + + + + cc-bolt-device-dialog.ui + cc-bolt-device-entry.ui + cc-bolt-panel.ui + + + diff --git a/panels/thunderbolt/update-from-bolt.sh b/panels/thunderbolt/update-from-bolt.sh new file mode 100755 index 000000000..8b22f0831 --- /dev/null +++ b/panels/thunderbolt/update-from-bolt.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +if [ $# -ne 1 ]; then + echo "$0: usage: " + exit 1 +fi + +boltsrc="$1" + +function die() { + echo $* + exit 1 +} + +function copyone() { + dst=$1 + src="$boltsrc/$dst" + + search=(common cli) + for base in ${search[*]} + do + path="$boltsrc/$base/$dst" + if [ -f $path ]; then + src=$path + break; + fi + done + + if [ ! -f $src ]; then + echo -e "$dst \t[ skipped ] $src (ENOENT)" + elif cmp -s $src $dst; then + echo -e "$dst \t[ unchanged ]" + else + cp $src $dst || die "$dst [failed] source: $src" + echo -e "$dst \t[ updated ] $src" + git add $dst + fi +} + +names=(client device enums error names proxy str time) + +for fn in ${names[*]} +do + header="bolt-$fn.h" + source="bolt-$fn.c" + + copyone $header + copyone $source +done + diff --git a/shell/cc-panel-list.c b/shell/cc-panel-list.c index 0fd093cf9..99d8a9114 100644 --- a/shell/cc-panel-list.c +++ b/shell/cc-panel-list.c @@ -276,6 +276,7 @@ static const gchar * const panel_order[] = { "wifi", "mobile-broadband", "bluetooth", + "thunderbolt", "background", "notifications", "search", diff --git a/shell/cc-panel-loader.c b/shell/cc-panel-loader.c index df3a8020c..55492ef98 100644 --- a/shell/cc-panel-loader.c +++ b/shell/cc-panel-loader.c @@ -54,6 +54,9 @@ extern GType cc_region_panel_get_type (void); extern GType cc_search_panel_get_type (void); extern GType cc_sharing_panel_get_type (void); extern GType cc_sound_panel_get_type (void); +#ifdef BUILD_THUNDERBOLT +extern GType cc_bolt_panel_get_type (void); +#endif /* BUILD_THUNDERBOLT */ extern GType cc_ua_panel_get_type (void); extern GType cc_user_panel_get_type (void); #ifdef BUILD_WACOM @@ -99,6 +102,9 @@ static struct { PANEL_TYPE("search", cc_search_panel_get_type ), PANEL_TYPE("sharing", cc_sharing_panel_get_type ), PANEL_TYPE("sound", cc_sound_panel_get_type ), +#ifdef BUILD_THUNDERBOLT + PANEL_TYPE("thunderbolt", cc_bolt_panel_get_type ), +#endif PANEL_TYPE("universal-access", cc_ua_panel_get_type ), PANEL_TYPE("user-accounts", cc_user_panel_get_type ), #ifdef BUILD_WACOM -- cgit v1.2.1 From 25a302ae98012b17ea7638c7002d938f74d59370 Mon Sep 17 00:00:00 2001 From: Christian Kellner Date: Fri, 13 Apr 2018 16:03:21 +0200 Subject: thunderbolt: move to the 'Devices' page The 'Devices' page is a fitting place for the thunderbolt, being an IO technology. It is expected that people that need to go to that page will be sent there via a gnome-shell notification, so there is no need for it to be on the main page. Ok'ed by the design team (jimmac). --- panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in | 2 +- shell/cc-panel-list.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in b/panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in index db2477e45..abd317341 100644 --- a/panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in +++ b/panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in @@ -7,7 +7,7 @@ Terminal=false Type=Application NoDisplay=true StartupNotify=true -Categories=GNOME;GTK;Settings;X-GNOME-Settings-Panel;HardwareSettings;X-GNOME-DevicesSettings;X-GNOME-ConnectivitySettings; +Categories=GNOME;GTK;Settings;X-GNOME-Settings-Panel;HardwareSettings;X-GNOME-DevicesSettings; OnlyShowIn=GNOME;Unity; X-GNOME-Bugzilla-Bugzilla=GNOME X-GNOME-Bugzilla-Product=gnome-control-center diff --git a/shell/cc-panel-list.c b/shell/cc-panel-list.c index 99d8a9114..f5b83509d 100644 --- a/shell/cc-panel-list.c +++ b/shell/cc-panel-list.c @@ -276,7 +276,6 @@ static const gchar * const panel_order[] = { "wifi", "mobile-broadband", "bluetooth", - "thunderbolt", "background", "notifications", "search", @@ -295,6 +294,7 @@ static const gchar * const panel_order[] = { "mouse", "printers", "removable-media", + "thunderbolt", "wacom", "color", -- cgit v1.2.1 From fc9c8cb70b02e55921c9d532917028cb61e93967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Dr=C4=85g?= Date: Fri, 13 Apr 2018 18:49:18 +0200 Subject: Update POTFILES.in --- po/POTFILES.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/po/POTFILES.in b/po/POTFILES.in index dfd8ccff0..ec73d670b 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -183,6 +183,11 @@ panels/sound/gvc-mixer-dialog.c panels/sound/gvc-sound-theme-chooser.c panels/sound/gvc-speaker-test.c panels/sound/sound-theme-file-utils.c +panels/thunderbolt/cc-bolt-device-dialog.c +panels/thunderbolt/cc-bolt-device-dialog.ui +panels/thunderbolt/cc-bolt-device-entry.c +panels/thunderbolt/cc-bolt-panel.c +panels/thunderbolt/cc-bolt-panel.ui panels/universal-access/cc-ua-panel.c panels/universal-access/gnome-universal-access-panel.desktop.in.in panels/universal-access/uap.ui -- cgit v1.2.1 From da0172274f796baabf681a2e6a4f0b227febcd6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Dr=C4=85g?= Date: Fri, 13 Apr 2018 18:51:53 +0200 Subject: thunderbolt: add a translator comment to the .desktop file --- panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in | 1 + 1 file changed, 1 insertion(+) diff --git a/panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in b/panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in index abd317341..12ba0330c 100644 --- a/panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in +++ b/panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in @@ -2,6 +2,7 @@ Name=Thunderbolt Comment=Manage Thunderbolt devices Exec=gnome-control-center thunderbolt +# Translators: Do NOT translate or transliterate this text (this is an icon file name)! Icon=thunderbolt Terminal=false Type=Application -- cgit v1.2.1 From 8d2fb2199e4eae63e435de7a647a70b0bd8d2c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Dr=C4=85g?= Date: Fri, 13 Apr 2018 18:54:57 +0200 Subject: thunderbolt: fix grammar in a translatable string --- panels/thunderbolt/cc-bolt-panel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/panels/thunderbolt/cc-bolt-panel.c b/panels/thunderbolt/cc-bolt-panel.c index e67e3625e..82fe1d9b7 100644 --- a/panels/thunderbolt/cc-bolt-panel.c +++ b/panels/thunderbolt/cc-bolt-panel.c @@ -185,8 +185,8 @@ bolt_client_ready (GObject *source, return; g_warning ("Could not create client: %s", err->message); - text = _("The thunderbolt subsystem (boltd) is not installed or " - "not setup properly."); + text = _("The Thunderbolt subsystem (boltd) is not installed or " + "not set up properly."); gtk_label_set_label (panel->notb_details, text); gtk_stack_set_visible_child_name (panel->container, "no-thunderbolt"); -- cgit v1.2.1 From 685b35cf9b9fa0d666498a875b0915e6e1765dc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Dr=C4=85g?= Date: Fri, 13 Apr 2018 18:57:31 +0200 Subject: Update POTFILES.in --- po/POTFILES.in | 1 + 1 file changed, 1 insertion(+) diff --git a/po/POTFILES.in b/po/POTFILES.in index ec73d670b..e3c1d2ae2 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -188,6 +188,7 @@ panels/thunderbolt/cc-bolt-device-dialog.ui panels/thunderbolt/cc-bolt-device-entry.c panels/thunderbolt/cc-bolt-panel.c panels/thunderbolt/cc-bolt-panel.ui +panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in panels/universal-access/cc-ua-panel.c panels/universal-access/gnome-universal-access-panel.desktop.in.in panels/universal-access/uap.ui -- cgit v1.2.1 From 958bb8fe6b10bd965d7ad4668238a0b56dec163f Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Sat, 14 Apr 2018 19:26:12 -0300 Subject: thunderbolt: Fix coding style Not everything was fixed, but why bother. --- panels/thunderbolt/cc-bolt-device-dialog.h | 2 +- panels/thunderbolt/cc-bolt-device-dialog.ui | 584 ++++++++-------- panels/thunderbolt/cc-bolt-device-entry.c | 10 +- panels/thunderbolt/cc-bolt-device-entry.ui | 14 +- panels/thunderbolt/cc-bolt-panel.c | 231 ++++--- panels/thunderbolt/cc-bolt-panel.h | 30 + panels/thunderbolt/cc-bolt-panel.ui | 1000 +++++++++++++-------------- 7 files changed, 951 insertions(+), 920 deletions(-) create mode 100644 panels/thunderbolt/cc-bolt-panel.h diff --git a/panels/thunderbolt/cc-bolt-device-dialog.h b/panels/thunderbolt/cc-bolt-device-dialog.h index d2c44c858..bd91eac71 100644 --- a/panels/thunderbolt/cc-bolt-device-dialog.h +++ b/panels/thunderbolt/cc-bolt-device-dialog.h @@ -27,8 +27,8 @@ G_BEGIN_DECLS #define CC_TYPE_BOLT_DEVICE_DIALOG cc_bolt_device_dialog_get_type () -G_DECLARE_FINAL_TYPE (CcBoltDeviceDialog, cc_bolt_device_dialog, CC, BOLT_DEVICE_DIALOG, GtkDialog); +G_DECLARE_FINAL_TYPE (CcBoltDeviceDialog, cc_bolt_device_dialog, CC, BOLT_DEVICE_DIALOG, GtkDialog); CcBoltDeviceDialog * cc_bolt_device_dialog_new (void); diff --git a/panels/thunderbolt/cc-bolt-device-dialog.ui b/panels/thunderbolt/cc-bolt-device-dialog.ui index cd19796db..584915a31 100644 --- a/panels/thunderbolt/cc-bolt-device-dialog.ui +++ b/panels/thunderbolt/cc-bolt-device-dialog.ui @@ -14,9 +14,9 @@ True False True - Device Identifier - - False + Device Identifier + + False @@ -25,334 +25,334 @@ True False vertical - 24 - 0 - - + 24 + 0 + + True False - True - False - center - start - slide-down - - + True + False + center + start + slide-down + + True False - True - False - 12 - - + True + False + 12 + + True False True - True - - - - + True + + + + True True none + handler="on_notify_button_clicked_cb" + object="CcBoltDeviceDialog" + swapped="no" /> - True - False - window-close-symbolic + True + False + window-close-symbolic - - + + - - + + - + - True - False - True - vertical + True + False + True + vertical - - - True - False - 72 - 72 - 24 - 0 - 12 - 24 - - - True - False - end - False - False - Name: - right - 1 - name_label - - - 0 - 0 - - - - - True - False - True - Device identifier - True - end - 0 - - - 1 - 0 - - - - - True - False - end - False - False - Status: - right - 1 - status_label - - - 0 - 1 - - - - - True - False - center - True - Status - end - 0 - - - 1 - 1 - - + + + True + False + 72 + 72 + 24 + 0 + 12 + 24 + + + True + False + end + False + False + Name: + right + 1 + name_label + + + 0 + 0 + + + + + True + False + True + Device identifier + True + end + 0 + + + 1 + 0 + + + + + True + False + end + False + False + Status: + right + 1 + status_label + + + 0 + 1 + + + + + True + False + center + True + Status + end + 0 + + + 1 + 1 + + - - - True - False - end - False - False - UUID: - right - 1 - uuid_label - - - 0 - 2 - - - - - True - False - center - True - Status - end - 0 - - - 1 - 2 - - + + + True + False + end + False + False + UUID: + right + 1 + uuid_label + + + 0 + 2 + + + + + True + False + center + True + Status + end + 0 + + + 1 + 2 + + - - - True - False - end - False - False - Timestamp: - right - 1 - time_label - - - 0 - 3 - - - - - True - False - center - True - Status - end - 0 - - - 1 - 3 - - + + + True + False + end + False + False + Timestamp: + right + 1 + time_label + + + 0 + 3 + + + + + True + False + center + True + Status + end + 0 + + + 1 + 3 + + - - - True - True - 1 - 1 - - - - - - - - - - - - - - - - - - - - - - True - False - horizontal - 12 - 72 - 72 - 36 - 0 - fill - - - True - center - center - False - - + + + True + True + 1 + 1 + + + + + + + + + + + + + + + + + + + + + + True + False + horizontal + 12 + 72 + 72 + 36 + 0 + fill + + + True + center + center + False + + - - - Authorize and Connect - True - True - True - True - fill + + + Authorize and Connect + True + True + True + True + fill - - - - - True - True - - + + + + + True + True + + - - - Forget Device - True - True - True - False - fill - - - - - True - True - - - - - True - False - - - + + + Forget Device + True + True + True + False + fill + + + + + True + True + + + + + True + False + + + - - True - True - 2 - + + True + True + 2 + - - - - - - + + + + + + - - - - - - + + + + + + - - - + + + - - + + diff --git a/panels/thunderbolt/cc-bolt-device-entry.c b/panels/thunderbolt/cc-bolt-device-entry.c index 1e6d6e75a..27beaddea 100644 --- a/panels/thunderbolt/cc-bolt-device-entry.c +++ b/panels/thunderbolt/cc-bolt-device-entry.c @@ -27,6 +27,8 @@ #include +#define RESOURCE_UI "/org/gnome/control-center/thunderbolt/cc-bolt-device-entry.ui" + struct _CcBoltDeviceEntry { GtkListBoxRow parent; @@ -40,17 +42,15 @@ struct _CcBoltDeviceEntry static const char * device_status_to_brief_for_ui (BoltDevice *dev); +G_DEFINE_TYPE (CcBoltDeviceEntry, cc_bolt_device_entry, GTK_TYPE_LIST_BOX_ROW); + enum { SIGNAL_STATUS_CHANGED, SIGNAL_LAST }; -static guint signals[SIGNAL_LAST] = {0}; - -G_DEFINE_TYPE (CcBoltDeviceEntry, cc_bolt_device_entry, GTK_TYPE_LIST_BOX_ROW); - -#define RESOURCE_UI "/org/gnome/control-center/thunderbolt/cc-bolt-device-entry.ui" +static guint signals[SIGNAL_LAST] = { 0, }; static void entry_set_name (CcBoltDeviceEntry *entry) diff --git a/panels/thunderbolt/cc-bolt-device-entry.ui b/panels/thunderbolt/cc-bolt-device-entry.ui index 37f865333..d1ada1856 100644 --- a/panels/thunderbolt/cc-bolt-device-entry.ui +++ b/panels/thunderbolt/cc-bolt-device-entry.ui @@ -16,13 +16,13 @@ 2 - end - True + end + True True True Device Name 0.0 - center + center 0 @@ -30,13 +30,13 @@ - + True False Status - end - center - 1.0 + end + center + 1.0 1 diff --git a/panels/thunderbolt/cc-bolt-panel.c b/panels/thunderbolt/cc-bolt-panel.c index 82fe1d9b7..a162a1f19 100644 --- a/panels/thunderbolt/cc-bolt-panel.c +++ b/panels/thunderbolt/cc-bolt-panel.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Red Hat, Inc +/* Copyright © 2018 Red Hat, Inc * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,53 +31,51 @@ #include "bolt-client.h" #include "bolt-str.h" +#include "cc-bolt-panel.h" #include "cc-thunderbolt-resources.h" -#define CC_TYPE_BOLT_PANEL cc_bolt_panel_get_type () -G_DECLARE_FINAL_TYPE (CcBoltPanel, cc_bolt_panel, CC, BOLT_PANEL, CcPanel); - struct _CcBoltPanel { - CcPanel parent; + CcPanel parent; - BoltClient *client; - GCancellable *cancel; + BoltClient *client; + GCancellable *cancel; /* headerbar menu */ - GtkBox *headerbar_box; - GtkLockButton *lock_button; + GtkBox *headerbar_box; + GtkLockButton *lock_button; /* main ui */ - GtkStack *container; + GtkStack *container; /* empty state */ - GtkLabel *notb_caption; - GtkLabel *notb_details; + GtkLabel *notb_caption; + GtkLabel *notb_details; /* notifications */ - GtkLabel *notification_label; - GtkRevealer *notification_revealer; + GtkLabel *notification_label; + GtkRevealer *notification_revealer; /* authmode */ - GtkSwitch *authmode_switch; - GtkSpinner *authmode_spinner; - GtkStack *authmode_mode; + GtkSwitch *authmode_switch; + GtkSpinner *authmode_spinner; + GtkStack *authmode_mode; /* device list */ - GHashTable *devices; + GHashTable *devices; - GtkStack *devices_stack; - GtkBox *devices_box; - GtkBox *pending_box; + GtkStack *devices_stack; + GtkBox *devices_box; + GtkBox *pending_box; - GtkListBox *devices_list; - GtkListBox *pending_list; + GtkListBox *devices_list; + GtkListBox *pending_list; /* device details dialog */ CcBoltDeviceDialog *device_dialog; /* polkit integration */ - GPermission *permission; + GPermission *permission; }; /* initialization */ @@ -87,7 +85,7 @@ static void bolt_client_ready (GObject *source, /* panel functions */ static void cc_bolt_panel_set_no_thunderbolt (CcBoltPanel *panel, - const char *custom_msg); + const char *custom_msg); static void cc_bolt_panel_name_owner_changed (CcBoltPanel *panel); @@ -150,17 +148,6 @@ static void on_permission_notify_cb (GPermission *permission, GParamSpec *pspec, CcBoltPanel *panel); -/* device related helpers helpers */ -static gint device_entries_sort_by_recency (GtkListBoxRow *a_row, - GtkListBoxRow *b_row, - gpointer user_data); - -static gint device_entries_sort_by_syspath (GtkListBoxRow *a_row, - GtkListBoxRow *b_row, - gpointer user_data); - -#define RESOURCE_PANEL_UI "/org/gnome/control-center/thunderbolt/cc-bolt-panel.ui" - CC_PANEL_REGISTER (CcBoltPanel, cc_bolt_panel); static void @@ -194,21 +181,29 @@ bolt_client_ready (GObject *source, return; } - g_signal_connect_object (client, "notify::g-name-owner", + g_signal_connect_object (client, + "notify::g-name-owner", G_CALLBACK (on_bolt_name_owner_changed_cb), - panel, 0); + panel, + 0); - g_signal_connect_object (client, "device-added", + g_signal_connect_object (client, + "device-added", G_CALLBACK (on_bolt_device_added_cb), - panel, 0); + panel, + 0); - g_signal_connect_object (client, "device-removed", + g_signal_connect_object (client, + "device-removed", G_CALLBACK (on_bolt_device_removed_cb), - panel, 0); + panel, + 0); - g_signal_connect_object (client, "notify::auth-mode", + g_signal_connect_object (client, + "notify::auth-mode", G_CALLBACK (on_bolt_notify_authmode_cb), - panel, 0); + panel, + 0); panel->client = client; @@ -216,13 +211,17 @@ bolt_client_ready (GObject *source, cc_bolt_panel_authmode_sync (panel); - g_object_bind_property (panel->authmode_switch, "active", - panel->devices_box, "sensitive", - G_BINDING_SYNC_CREATE); + g_object_bind_property (panel->authmode_switch, + "active", + panel->devices_box, + "sensitive", + G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); - g_object_bind_property (panel->authmode_switch, "active", - panel->pending_box, "sensitive", - G_BINDING_SYNC_CREATE); + g_object_bind_property (panel->authmode_switch, + "active", + panel->pending_box, + "sensitive", + G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); gtk_stack_set_visible_child_name (panel->devices_stack, "no-devices"); cc_bolt_panel_name_owner_changed (panel); @@ -267,13 +266,14 @@ devices_table_clear_entries (GHashTable *table, static void devices_table_synchronize (CcBoltPanel *panel) { - g_autoptr(GError) err = NULL; - g_autoptr(GPtrArray) devices = NULL; g_autoptr(GHashTable) old = NULL; + g_autoptr(GPtrArray) devices = NULL; + g_autoptr(GError) err = NULL; + guint i; devices = bolt_client_list_devices (panel->client, panel->cancel, &err); - if (devices == NULL) + if (!devices) { g_warning ("Could not list devices: %s", err->message); devices = g_ptr_array_new_with_free_func (g_object_unref); @@ -282,7 +282,7 @@ devices_table_synchronize (CcBoltPanel *panel) old = panel->devices; panel->devices = g_hash_table_new (g_str_hash, g_str_equal); - for (guint i = 0; i < devices->len; i++) + for (i = 0; i < devices->len; i++) { BoltDevice *dev = g_ptr_array_index (devices, i); const char *path; @@ -362,12 +362,15 @@ cc_bolt_panel_add_device (CcBoltPanel *panel, gtk_widget_show_all (GTK_WIDGET (panel->devices_box)); } - g_signal_connect_object (entry, "status-changed", + g_signal_connect_object (entry, + "status-changed", G_CALLBACK (on_device_entry_status_changed_cb), - panel, 0); + panel, + 0); gtk_stack_set_visible_child_name (panel->devices_stack, "have-devices"); g_hash_table_insert (panel->devices, (gpointer) path, entry); + return entry; } @@ -396,7 +399,9 @@ cc_bolt_panel_del_device_entry (CcBoltPanel *panel, if (!gtk_widget_is_visible (GTK_WIDGET (panel->pending_list)) && !gtk_widget_is_visible (GTK_WIDGET (panel->devices_list))) - gtk_stack_set_visible_child_name (panel->devices_stack, "no-devices"); + { + gtk_stack_set_visible_child_name (panel->devices_stack, "no-devices"); + } } static void @@ -408,18 +413,13 @@ cc_bolt_panel_authmode_sync (CcBoltPanel *panel) const char *name; mode = bolt_client_get_authmode (client); - enabled = (mode & BOLT_AUTH_ENABLED) != 0; - g_signal_handlers_block_by_func (panel->authmode_switch, - on_authmode_state_set_cb, - panel); + g_signal_handlers_block_by_func (panel->authmode_switch, on_authmode_state_set_cb, panel); gtk_switch_set_state (panel->authmode_switch, enabled); - g_signal_handlers_unblock_by_func (panel->authmode_switch, - on_authmode_state_set_cb, - panel); + g_signal_handlers_unblock_by_func (panel->authmode_switch, on_authmode_state_set_cb, panel); name = enabled ? "enabled" : "disabled"; gtk_stack_set_visible_child_name (panel->authmode_mode, name); @@ -453,13 +453,15 @@ cc_panel_list_box_migrate (CcBoltPanel *panel, /* bolt client signals */ static void cc_bolt_panel_set_no_thunderbolt (CcBoltPanel *panel, - const char *msg) + const char *msg) { - if (msg == NULL) - msg = _("Thunderbolt could not be detected.\n" - "Either the system lacks Thunderbolt support, " - "it has been disabled in the BIOS or is set to " - "an unsupported security level in the BIOS."); + if (!msg) + { + msg = _("Thunderbolt could not be detected.\n" + "Either the system lacks Thunderbolt support, " + "it has been disabled in the BIOS or is set to " + "an unsupported security level in the BIOS."); + } gtk_label_set_label (panel->notb_details, msg); gtk_stack_set_visible_child_name (panel->container, "no-thunderbolt"); @@ -515,13 +517,17 @@ cc_bolt_panel_name_owner_changed (CcBoltPanel *panel) } if (panel->permission) - gtk_widget_show (GTK_WIDGET (panel->headerbar_box)); + { + gtk_widget_show (GTK_WIDGET (panel->headerbar_box)); + } else - polkit_permission_new ("org.freedesktop.bolt.manage", - NULL, - panel->cancel, - on_permission_ready, - g_object_ref (panel)); + { + polkit_permission_new ("org.freedesktop.bolt.manage", + NULL, + panel->cancel, + on_permission_ready, + g_object_ref (panel)); + } devices_table_synchronize (panel); } @@ -532,9 +538,7 @@ on_bolt_name_owner_changed_cb (GObject *object, GParamSpec *pspec, gpointer user_data) { - CcBoltPanel *panel = CC_BOLT_PANEL (user_data); - - cc_bolt_panel_name_owner_changed (panel); + cc_bolt_panel_name_owner_changed (CC_BOLT_PANEL (user_data)); } static void @@ -555,7 +559,7 @@ on_bolt_device_added_cb (BoltClient *cli, bus = g_dbus_proxy_get_connection (G_DBUS_PROXY (panel->client)); dev = bolt_device_new_for_object_path (bus, path, panel->cancel, &err); - if (dev == NULL) + if (!dev) { g_warning ("Could not create proxy for %s", path); return; @@ -573,7 +577,7 @@ on_bolt_device_removed_cb (BoltClient *cli, entry = g_hash_table_lookup (panel->devices, path); - if (entry == NULL) + if (!entry) return; cc_bolt_panel_del_device_entry (panel, entry); @@ -585,9 +589,7 @@ on_bolt_notify_authmode_cb (GObject *gobject, GParamSpec *pspec, gpointer user_data) { - CcBoltPanel *panel = CC_BOLT_PANEL (user_data); - - cc_bolt_panel_authmode_sync (panel); + cc_bolt_panel_authmode_sync (CC_BOLT_PANEL (user_data)); } /* panel signals */ @@ -691,8 +693,7 @@ on_device_entry_status_changed_cb (CcBoltDeviceEntry *entry, * the list the entry is in; otherwise we might just hop * from one box to the other and back again. */ - if (new_status == BOLT_STATUS_CONNECTING || - new_status == BOLT_STATUS_AUTHORIZING) + if (new_status == BOLT_STATUS_CONNECTING || new_status == BOLT_STATUS_AUTHORIZING) return; is_pending = bolt_status_is_pending (new_status); @@ -731,8 +732,8 @@ on_permission_ready (GObject *source_object, GAsyncResult *res, gpointer user_data) { - g_autoptr(GError) err = NULL; g_autoptr(CcBoltPanel) panel = user_data; + g_autoptr(GError) err = NULL; GPermission *permission; gboolean is_allowed; const char *name; @@ -740,7 +741,7 @@ on_permission_ready (GObject *source_object, permission = polkit_permission_new_finish (res, &err); panel->permission = permission; - if (panel->permission == NULL) + if (!panel->permission) { g_warning ("Could not get polkit permissions: %s", err->message); return; @@ -773,9 +774,9 @@ on_permission_notify_cb (GPermission *permission, } static gint -device_entries_sort_by_recency (GtkListBoxRow *a_row, - GtkListBoxRow *b_row, - gpointer user_data) +device_entries_sort_by_recency_cb (GtkListBoxRow *a_row, + GtkListBoxRow *b_row, + gpointer user_data) { CcBoltDeviceEntry *a_entry = CC_BOLT_DEVICE_ENTRY (a_row); CcBoltDeviceEntry *b_entry = CC_BOLT_DEVICE_ENTRY (b_row); @@ -820,9 +821,9 @@ device_entries_sort_by_recency (GtkListBoxRow *a_row, } static gint -device_entries_sort_by_syspath (GtkListBoxRow *a_row, - GtkListBoxRow *b_row, - gpointer user_data) +device_entries_sort_by_syspath_cb (GtkListBoxRow *a_row, + GtkListBoxRow *b_row, + gpointer user_data) { CcBoltDeviceEntry *a_entry = CC_BOLT_DEVICE_ENTRY (a_row); CcBoltDeviceEntry *b_entry = CC_BOLT_DEVICE_ENTRY (b_row); @@ -838,6 +839,8 @@ device_entries_sort_by_syspath (GtkListBoxRow *a_row, return g_strcmp0 (a_path, b_path); } +/* GObject overrides */ + static void cc_bolt_panel_finalize (GObject *object) { @@ -890,26 +893,22 @@ cc_bolt_panel_class_init (CcBoltPanelClass *klass) object_class->dispose = cc_bolt_panel_dispose; object_class->finalize = cc_bolt_panel_finalize; - gtk_widget_class_set_template_from_resource (widget_class, RESOURCE_PANEL_UI); - gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, headerbar_box); - gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, lock_button); + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/thunderbolt/cc-bolt-panel.ui"); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, authmode_mode); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, authmode_spinner); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, authmode_switch); gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, container); - + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, devices_list); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, devices_box); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, devices_stack); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, headerbar_box); + gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, lock_button); gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, notb_caption); gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, notb_details); - gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, notification_label); gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, notification_revealer); - - gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, authmode_mode); - gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, authmode_switch); - gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, authmode_spinner); - - gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, devices_stack); - gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, devices_box); gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, pending_box); - gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, devices_list); gtk_widget_class_bind_template_child (widget_class, CcBoltPanel, pending_list); gtk_widget_class_bind_template_callback (widget_class, on_notification_button_clicked_cb); @@ -921,38 +920,40 @@ static void cc_bolt_panel_init (CcBoltPanel *panel) { g_resources_register (cc_thunderbolt_get_resource ()); + gtk_widget_init_template (GTK_WIDGET (panel)); gtk_stack_set_visible_child_name (panel->container, "loading"); gtk_list_box_set_header_func (panel->devices_list, cc_list_box_update_header_func, - NULL, NULL); + NULL, + NULL); gtk_list_box_set_header_func (panel->pending_list, cc_list_box_update_header_func, - NULL, NULL); + NULL, + NULL); gtk_list_box_set_sort_func (panel->devices_list, - device_entries_sort_by_recency, + device_entries_sort_by_recency_cb, panel, NULL); gtk_list_box_set_sort_func (panel->pending_list, - device_entries_sort_by_syspath, + device_entries_sort_by_syspath_cb, panel, NULL); panel->devices = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); panel->device_dialog = cc_bolt_device_dialog_new (); - g_signal_connect_object (panel->device_dialog, "delete-event", + g_signal_connect_object (panel->device_dialog, + "delete-event", G_CALLBACK (on_device_dialog_delete_event_cb), panel, 0); panel->cancel = g_cancellable_new (); - bolt_client_new_async (panel->cancel, - bolt_client_ready, - g_object_ref (panel)); + bolt_client_new_async (panel->cancel, bolt_client_ready, g_object_ref (panel)); } diff --git a/panels/thunderbolt/cc-bolt-panel.h b/panels/thunderbolt/cc-bolt-panel.h new file mode 100644 index 000000000..5901044e8 --- /dev/null +++ b/panels/thunderbolt/cc-bolt-panel.h @@ -0,0 +1,30 @@ +/* Copyright © 2018 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Authors: Christian J. Kellner + * + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +#define CC_TYPE_BOLT_PANEL cc_bolt_panel_get_type () + +G_DECLARE_FINAL_TYPE (CcBoltPanel, cc_bolt_panel, CC, BOLT_PANEL, CcPanel); + +G_END_DECLS diff --git a/panels/thunderbolt/cc-bolt-panel.ui b/panels/thunderbolt/cc-bolt-panel.ui index 5ec674860..226353c64 100644 --- a/panels/thunderbolt/cc-bolt-panel.ui +++ b/panels/thunderbolt/cc-bolt-panel.ui @@ -31,7 +31,7 @@ True False True - True + True @@ -40,9 +40,9 @@ True none + handler="on_notification_button_clicked_cb" + object="CcBoltPanel" + swapped="no" /> True @@ -62,518 +62,518 @@ - - + + True False False crossfade - - + + - True - False - True - center - center - vertical - 10 - 18 - - - True - True - True - - - - - loading + True + False + True + center + center + vertical + 10 + 18 + + + True + True + True + + + + + loading - + - + - + - True - False - True - center - center - vertical - 10 - 18 - - - True - False - 12 - 6 - 12 - 12 - 12 - 24 - - - - True - False - thunderbolt-symbolic - 96 - 0 - - - - 0 - 0 - 2 - - - - - - True - False - True - 0 - No Thunderbolt support - - - - - - - 1 - 0 - - - - - - True - False - True - 40 - True - 0 - 0 - True - Could not connect to the thunderbolt subsystem. - - - 1 - 1 - - - - - + True + False + True + center + center + vertical + 10 + 18 + + + True + False + 12 + 6 + 12 + 12 + 12 + 24 + + + + True + False + thunderbolt-symbolic + 96 + 0 + + + + 0 + 0 + 2 + + + + + + True + False + True + 0 + No Thunderbolt support + + + + + + + 1 + 0 + + + + + + True + False + True + 40 + True + 0 + 0 + True + Could not connect to the thunderbolt subsystem. + + + 1 + 1 + + + + + - no-thunderbolt + no-thunderbolt - - - - True - False - never - - - - True - False - none - - - - True - False - horizontal - start - - - - - True - False - True - - - - - - - True - False - True - 32 - 32 - 32 - 18 - 18 - vertical - - - - - True - False - horizontal - 12 - - - True - False - vertical - 6 - - - True - False - False - start - 0.0 - Direct Access - authmode_switch - - - - - - - - - True - False - crossfade - True - - - - True - False - start - 0 - False - False - Allow direct access to devices such as docks and external GPUs. - True - True - 0.0 - 0.0 - 45 - - - enabled - - - - - - True - False - start - 0 - False - False - Only USB and Display Port devices can attach. - True - True - 0.0 - 0.0 - 45 - - - disabled - - - - - - - - True - True - 0 - - - - - True - False - horizontal - 6 - center - start - - - - True - False - - - - - - True - True - end - start - True - - - - - - False - False - 1 - end - - - - - - - - - True - False - crossfade - - - - True - False - vertical - 32 - - - - - False - False - vertical - 12 - - - - - True - True - start - 6 - - - True - False - dialog-warning-symbolic - 1 - 0 - 0.0 - - - False - False - 0 - - - - - True - Pending Devices - 0.0 - - - - - - False - False - 1 - - - - - True - True - - - False - False - 2 - - - - - - - - - True - start - False - - - - True - none - True - - - - - - - - - - - - False - False - vertical - 12 - - - - - True - True - start - 6 - - - True - Devices - 0.0 - - - - - - - - True - True - - - - - - - - - True - start - False - - - - True - none - True - - - - - - - - - - - - have-devices - - - - - - - True - True - start - vertical - 6 - - - True - Devices - 0.0 - - - - - - - - True - No devices attached - 0.0 - - - - - no-devices - - - - - - - - - - - - - - True - False - True - - - - - - - - - - - devices-listing - - - - - - - - + + + + True + False + never + + + + True + False + none + + + + True + False + horizontal + start + + + + + True + False + True + + + + + + + True + False + True + 32 + 32 + 32 + 18 + 18 + vertical + + + + + True + False + horizontal + 12 + + + True + False + vertical + 6 + + + True + False + False + start + 0.0 + Direct Access + authmode_switch + + + + + + + + + True + False + crossfade + True + + + + True + False + start + 0 + False + False + Allow direct access to devices such as docks and external GPUs. + True + True + 0.0 + 0.0 + 45 + + + enabled + + + + + + True + False + start + 0 + False + False + Only USB and Display Port devices can attach. + True + True + 0.0 + 0.0 + 45 + + + disabled + + + + + + + + True + True + 0 + + + + + True + False + horizontal + 6 + center + start + + + + True + False + + + + + + True + True + end + start + True + + + + + + False + False + 1 + end + + + + + + + + + True + False + crossfade + + + + True + False + vertical + 32 + + + + + False + False + vertical + 12 + + + + + True + True + start + 6 + + + True + False + dialog-warning-symbolic + 1 + 0 + 0.0 + + + False + False + 0 + + + + + True + Pending Devices + 0.0 + + + + + + False + False + 1 + + + + + True + True + + + False + False + 2 + + + + + + + + + True + start + False + + + + True + none + True + + + + + + + + + + + + False + False + vertical + 12 + + + + + True + True + start + 6 + + + True + Devices + 0.0 + + + + + + + + True + True + + + + + + + + + True + start + False + + + + True + none + True + + + + + + + + + + + + have-devices + + + + + + + True + True + start + vertical + 6 + + + True + Devices + 0.0 + + + + + + + + True + No devices attached + 0.0 + + + + + no-devices + + + + + + + + + + + + + + True + False + True + + + + + + + + + + + devices-listing + + + + + + + + -- cgit v1.2.1 From 132163759f50e634b2d9ac868962a4ffd5d7021f Mon Sep 17 00:00:00 2001 From: gogo Date: Mon, 16 Apr 2018 12:25:12 +0000 Subject: Update Croatian translation --- po/hr.po | 981 ++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 590 insertions(+), 391 deletions(-) diff --git a/po/hr.po b/po/hr.po index 480fe5037..c7cfcf500 100644 --- a/po/hr.po +++ b/po/hr.po @@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: gnome-control-center 2.0\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-control-center/" "issues\n" -"POT-Creation-Date: 2018-02-20 09:14+0000\n" -"PO-Revision-Date: 2018-02-20 12:18+0100\n" +"POT-Creation-Date: 2018-04-13 16:58+0000\n" +"PO-Revision-Date: 2018-04-16 14:24+0200\n" "Last-Translator: gogo \n" "Language-Team: Croatian \n" "Language: hr\n" @@ -102,14 +102,14 @@ msgid "You can add images to your %s folder and they will show up here" msgstr "Možete dodati slike u vašu %s mapu i zatim će se prikazati ovdje gore" #: panels/background/cc-background-chooser-dialog.c:560 -#: panels/color/cc-color-panel.c:225 panels/color/cc-color-panel.c:963 +#: panels/color/cc-color-panel.c:224 panels/color/cc-color-panel.c:962 #: panels/color/color-calibrate.ui:25 panels/color/color.ui:657 -#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2594 +#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2610 #: panels/network/connection-editor/connection-editor.ui:15 #: panels/network/connection-editor/vpn-helpers.c:181 #: panels/network/connection-editor/vpn-helpers.c:310 -#: panels/network/net-device-wifi.c:1371 panels/network/net-device-wifi.c:1451 -#: panels/network/net-device-wifi.c:1690 panels/network/network-wifi.ui:24 +#: panels/network/net-device-wifi.c:1411 panels/network/net-device-wifi.c:1491 +#: panels/network/net-device-wifi.c:1736 panels/network/network-wifi.ui:24 #: panels/printers/new-printer-dialog.ui:45 #: panels/printers/pp-details-dialog.c:331 #: panels/privacy/cc-privacy-panel.c:1053 panels/region/format-chooser.ui:25 @@ -120,10 +120,10 @@ msgstr "Možete dodati slike u vašu %s mapu i zatim će se prikazati ovdje gore #: panels/user-accounts/data/join-dialog.ui:20 #: panels/user-accounts/data/password-dialog.ui:21 #: panels/user-accounts/um-fingerprint-dialog.c:261 -#: panels/user-accounts/um-photo-dialog.c:102 -#: panels/user-accounts/um-photo-dialog.c:229 -#: panels/user-accounts/um-user-panel.c:635 -#: panels/user-accounts/um-user-panel.c:653 +#: panels/user-accounts/um-photo-dialog.c:103 +#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-user-panel.c:634 +#: panels/user-accounts/um-user-panel.c:652 msgid "_Cancel" msgstr "_Odustani" @@ -158,48 +158,49 @@ msgstr "Pozadina" msgid "Change your background image to a wallpaper or photo" msgstr "Promijenite vašu pozadinsku sliku u sliku pozadine ili fotografiju" -#: panels/background/gnome-background-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/background/gnome-background-panel.desktop.in.in:7 msgid "preferences-desktop-wallpaper" msgstr "osobitosti-pozadine-radne površine" -#. Translators: those are keywords for the background control-center panel -#: panels/background/gnome-background-panel.desktop.in.in:14 +#. Translators: Search terms to find the Background panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/background/gnome-background-panel.desktop.in.in:15 msgid "Wallpaper;Screen;Desktop;" msgstr "Slika pozadine;Zaslon;Radna površina;" -#: panels/bluetooth/cc-bluetooth-panel.c:265 +#: panels/bluetooth/cc-bluetooth-panel.c:266 msgid "Turn Off Airplane Mode" msgstr "Isključi način rada u zrakoplovu" -#: panels/bluetooth/cc-bluetooth-panel.c:330 +#: panels/bluetooth/cc-bluetooth-panel.c:329 msgid "No Bluetooth Found" msgstr "Nema pronađenih Bluetooth uređaja" -#: panels/bluetooth/cc-bluetooth-panel.c:330 +#: panels/bluetooth/cc-bluetooth-panel.c:329 msgid "Plug in a dongle to use Bluetooth." msgstr "Priključite uređaj kako bi mogli koristiti Bluetooth." -#: panels/bluetooth/cc-bluetooth-panel.c:331 +#: panels/bluetooth/cc-bluetooth-panel.c:330 msgid "Bluetooth Turned Off" msgstr "Bluetooth je isključen" -#: panels/bluetooth/cc-bluetooth-panel.c:331 +#: panels/bluetooth/cc-bluetooth-panel.c:330 msgid "Turn on to connect devices and receive file transfers." msgstr "Uključite za povezivanje uređaja i prijenos datoteka." -#: panels/bluetooth/cc-bluetooth-panel.c:332 +#: panels/bluetooth/cc-bluetooth-panel.c:331 msgid "Airplane Mode is on" msgstr "Način rada u zrakoplovu je uključen" -#: panels/bluetooth/cc-bluetooth-panel.c:332 +#: panels/bluetooth/cc-bluetooth-panel.c:331 msgid "Bluetooth is disabled when airplane mode is on." msgstr "Bluetooth je onemogućen kada je način rada u zrakoplovu uključen." -#: panels/bluetooth/cc-bluetooth-panel.c:333 +#: panels/bluetooth/cc-bluetooth-panel.c:332 msgid "Hardware Airplane Mode is on" msgstr "Hardverski način rada u zrakoplovu je uključen" -#: panels/bluetooth/cc-bluetooth-panel.c:333 +#: panels/bluetooth/cc-bluetooth-panel.c:332 msgid "Turn off the Airplane mode switch to enable Bluetooth." msgstr "Isključite način rada u zrakoplovu kako bi mogli kristiti Bluetooth." @@ -213,17 +214,18 @@ msgstr "Bluetooth" msgid "Turn Bluetooth on and off and connect your devices" msgstr "Uključite ili isključite Bluetooth i povežite svoje uređaje" -#: panels/bluetooth/gnome-bluetooth-panel.desktop.in.in:5 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/bluetooth/gnome-bluetooth-panel.desktop.in.in:6 msgid "bluetooth" msgstr "bluetooth" -#. Translators: those are keywords for the bluetooth control-center panel -#: panels/bluetooth/gnome-bluetooth-panel.desktop.in.in:18 +#. Translators: Search terms to find the Bluetooth panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/bluetooth/gnome-bluetooth-panel.desktop.in.in:19 msgid "share;sharing;bluetooth;obex;" msgstr "dijeli;dijeljenje;bluetooth;obex;" #. TRANSLATORS: The user has to attach the sensor to the screen -#: panels/color/cc-color-calibrate.c:361 +#: panels/color/cc-color-calibrate.c:363 msgid "Place your calibration device over the square and press “Start”" msgstr "" "Smjestite vaš uređaj za kalibraciju preko četverokuta i pritisnite ”Pokreni”" @@ -231,7 +233,7 @@ msgstr "" #. TRANSLATORS: Some calibration devices need the user to move a #. * dial or switch manually. We also show a picture showing them #. * what to do... -#: panels/color/cc-color-calibrate.c:367 +#: panels/color/cc-color-calibrate.c:369 msgid "" "Move your calibration device to the calibrate position and press “Continue”" msgstr "" @@ -241,7 +243,7 @@ msgstr "" #. TRANSLATORS: Some calibration devices need the user to move a #. * dial or switch manually. We also show a picture showing them #. * what to do... -#: panels/color/cc-color-calibrate.c:373 +#: panels/color/cc-color-calibrate.c:375 msgid "" "Move your calibration device to the surface position and press “Continue”" msgstr "" @@ -251,54 +253,54 @@ msgstr "" #. TRANSLATORS: on some hardware e.g. Lenovo W700 the sensor #. * is built into the palmrest and we need to fullscreen the #. * sample widget and shut the lid. -#: panels/color/cc-color-calibrate.c:379 +#: panels/color/cc-color-calibrate.c:381 msgid "Shut the laptop lid" msgstr "Spusti zaslon prijenosnika" #. TRANSLATORS: We suck, the calibation failed and we have no #. * good idea why or any suggestions -#: panels/color/cc-color-calibrate.c:410 +#: panels/color/cc-color-calibrate.c:412 msgid "An internal error occurred that could not be recovered." msgstr "Dogodila se unutrašnja greška koja se ne može oporaviti." #. TRANSLATORS: Some required-at-runtime tools were not #. * installed, which should only affect insane distros -#: panels/color/cc-color-calibrate.c:415 +#: panels/color/cc-color-calibrate.c:417 msgid "Tools required for calibration are not installed." msgstr "Alati potrebni za kalibraciju nisu instalirani." #. TRANSLATORS: The profile failed for some reason -#: panels/color/cc-color-calibrate.c:421 +#: panels/color/cc-color-calibrate.c:423 msgid "The profile could not be generated." msgstr "Profil se ne može stvoriti." #. TRANSLATORS: The user specified a whitepoint that was #. * unobtainable with the hardware they've got -- see #. * https://en.wikipedia.org/wiki/White_point for details -#: panels/color/cc-color-calibrate.c:427 +#: panels/color/cc-color-calibrate.c:429 msgid "The target whitepoint was not obtainable." msgstr "Odredišna bijela točka je dostižna." #. TRANSLATORS: the display calibration process is finished -#: panels/color/cc-color-calibrate.c:467 +#: panels/color/cc-color-calibrate.c:469 msgid "Complete!" msgstr "Završeno!" #. TRANSLATORS: the display calibration failed, and we also show #. * the translated (or untranslated) error string after this -#: panels/color/cc-color-calibrate.c:475 +#: panels/color/cc-color-calibrate.c:477 msgid "Calibration failed!" msgstr "Kalibracija nije uspjela!" #. TRANSLATORS: The user can now remove the sensor from the screen -#: panels/color/cc-color-calibrate.c:482 +#: panels/color/cc-color-calibrate.c:484 msgid "You can remove the calibration device." msgstr "Možete ukloniti uređaj za kalibraciju." #. TRANSLATORS: The user has to be careful not to knock the #. * display off the screen (although we do cope if this is #. * detected early enough) -#: panels/color/cc-color-calibrate.c:553 +#: panels/color/cc-color-calibrate.c:556 msgid "Do not disturb the calibration device while in progress" msgstr "Nemojte ometati uređaj tijekom kalibracije" @@ -360,48 +362,48 @@ msgstr "Nije kalibriran" #. TRANSLATORS: this is a profile prefix to signify the #. * profile has been auto-generated for this hardware -#: panels/color/cc-color-panel.c:141 +#: panels/color/cc-color-panel.c:140 msgid "Default: " msgstr "Uobičajeno: " #. TRANSLATORS: this is a profile prefix to signify the #. * profile his a standard space like AdobeRGB -#: panels/color/cc-color-panel.c:149 +#: panels/color/cc-color-panel.c:148 msgid "Colorspace: " msgstr "Raspon boja: " #. TRANSLATORS: this is a profile prefix to signify the #. * profile is a test profile -#: panels/color/cc-color-panel.c:156 +#: panels/color/cc-color-panel.c:155 msgid "Test profile: " msgstr "Testni profil: " #. TRANSLATORS: an ICC profile is a file containing colorspace data -#: panels/color/cc-color-panel.c:223 +#: panels/color/cc-color-panel.c:222 msgid "Select ICC Profile File" msgstr "Odaberi ICC datoteku profila" -#: panels/color/cc-color-panel.c:226 +#: panels/color/cc-color-panel.c:225 msgid "_Import" msgstr "_Uvezi" #. TRANSLATORS: filter name on the file->open dialog -#: panels/color/cc-color-panel.c:237 +#: panels/color/cc-color-panel.c:236 msgid "Supported ICC profiles" msgstr "Podržani ICC profili" #. TRANSLATORS: filter name on the file->open dialog -#: panels/color/cc-color-panel.c:244 +#: panels/color/cc-color-panel.c:243 #: panels/network/wireless-security/eap-method-fast.c:417 msgid "All files" msgstr "Sve datoteke" -#: panels/color/cc-color-panel.c:583 +#: panels/color/cc-color-panel.c:582 msgid "Screen" msgstr "Zaslon" #. TRANSLATORS: this is when the upload of the profile failed -#: panels/color/cc-color-panel.c:908 +#: panels/color/cc-color-panel.c:907 #, c-format msgid "Failed to upload file: %s" msgstr "Neuspjelo slanje datoteke: %s" @@ -409,40 +411,40 @@ msgstr "Neuspjelo slanje datoteke: %s" #. TRANSLATORS: these are instructions on how to recover #. * the ICC profile on the native operating system and are #. * only shown when the user uses a LiveCD to calibrate -#: panels/color/cc-color-panel.c:922 +#: panels/color/cc-color-panel.c:921 msgid "The profile has been uploaded to:" msgstr "Profil je poslan na:" -#: panels/color/cc-color-panel.c:924 +#: panels/color/cc-color-panel.c:923 msgid "Write down this URL." msgstr "Zapišite ovaj URL." -#: panels/color/cc-color-panel.c:925 +#: panels/color/cc-color-panel.c:924 msgid "Restart this computer and boot your normal operating system." msgstr "" "Ponovno pokrenite ovo računalo i pokrenite vaš uobičajeni operativni sustav." -#: panels/color/cc-color-panel.c:926 +#: panels/color/cc-color-panel.c:925 msgid "Type the URL into your browser to download and install the profile." msgstr "Upišite URL u vaš preglednik za preuzimanje i instalaciju profila." #. TRANSLATORS: this is the dialog to save the ICC profile -#: panels/color/cc-color-panel.c:960 +#: panels/color/cc-color-panel.c:959 msgid "Save Profile" msgstr "Spremi profil" -#: panels/color/cc-color-panel.c:964 +#: panels/color/cc-color-panel.c:963 #: panels/network/connection-editor/vpn-helpers.c:311 msgid "_Save" msgstr "_Spremi" #. TRANSLATORS: this is when the button is sensitive -#: panels/color/cc-color-panel.c:1325 +#: panels/color/cc-color-panel.c:1324 msgid "Create a color profile for the selected device" msgstr "Napravi profil boje za odabrani uređaj" #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1340 panels/color/cc-color-panel.c:1364 +#: panels/color/cc-color-panel.c:1339 panels/color/cc-color-panel.c:1363 msgid "" "The measuring instrument is not detected. Please check it is turned on and " "correctly connected." @@ -450,12 +452,12 @@ msgstr "" "Mjerni uređaj nije pronađen. Provjerite je li uključen i ispravno spojen." #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1374 +#: panels/color/cc-color-panel.c:1373 msgid "The measuring instrument does not support printer profiling." msgstr "Mjerni uređaj ne podržava profiliranje pisača." #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1385 +#: panels/color/cc-color-panel.c:1384 msgid "The device type is not currently supported." msgstr "Vrsta uređaja trenutno nije podržana." @@ -861,12 +863,13 @@ msgid "" "Calibrate the color of your devices, such as displays, cameras or printers" msgstr "Kalibrirajte boju vašeg uređaja, poput zalona, kamera i pisača" -#: panels/color/gnome-color-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/color/gnome-color-panel.desktop.in.in:7 msgid "preferences-color" msgstr "osobitosti-boje" -#. Translators: those are keywords for the color control-center panel -#: panels/color/gnome-color-panel.desktop.in.in:18 +#. Translators: Search terms to find the Color panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/color/gnome-color-panel.desktop.in.in:19 msgid "Color;ICC;Profile;Calibrate;Printer;Display;" msgstr "Boja;ICC;Profil;Kalibriraj;Pisač;Zaslon;" @@ -1081,12 +1084,13 @@ msgstr "12-satno" msgid "Change the date and time, including time zone" msgstr "Promijenite datum i vrijeme, uključujući vremensku zonu" -#: panels/datetime/gnome-datetime-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/datetime/gnome-datetime-panel.desktop.in.in:7 msgid "preferences-system-time" msgstr "osobitosti-vremena-sustava" -#. Translators: those are keywords for the date and time control-center panel -#: panels/datetime/gnome-datetime-panel.desktop.in.in:14 +#. Translators: Search terms to find the Date and Time panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/datetime/gnome-datetime-panel.desktop.in.in:15 msgid "Clock;Timezone;Location;" msgstr "Sat;vremenska zona;lokacija;" @@ -1098,58 +1102,58 @@ msgstr "Promijeni postavke vremena i datuma sustava" msgid "To change time or date settings, you need to authenticate." msgstr "Morate se ovjeriti kako bi promijenili postavke vremena ili datuma." -#: panels/display/cc-display-panel.c:729 +#: panels/display/cc-display-panel.c:739 msgctxt "Display rotation" msgid "Landscape" msgstr "Položeno" -#: panels/display/cc-display-panel.c:732 +#: panels/display/cc-display-panel.c:742 msgctxt "Display rotation" msgid "Portrait Right" msgstr "Uspravno desno" -#: panels/display/cc-display-panel.c:735 +#: panels/display/cc-display-panel.c:745 msgctxt "Display rotation" msgid "Portrait Left" msgstr "Uspravno lijevo" -#: panels/display/cc-display-panel.c:738 +#: panels/display/cc-display-panel.c:748 msgctxt "Display rotation" msgid "Landscape (flipped)" msgstr "Obrnuto položeno" #. Translators: This option sets orientation of print (portrait, landscape...) -#: panels/display/cc-display-panel.c:805 +#: panels/display/cc-display-panel.c:816 #: panels/printers/pp-options-dialog.c:558 msgid "Orientation" msgstr "Orijentacija" -#: panels/display/cc-display-panel.c:870 panels/display/cc-display-panel.c:1673 +#: panels/display/cc-display-panel.c:885 panels/display/cc-display-panel.c:1691 #: panels/printers/pp-options-dialog.c:87 msgid "Resolution" msgstr "Razlučivost" -#: panels/display/cc-display-panel.c:958 +#: panels/display/cc-display-panel.c:974 msgid "Refresh Rate" msgstr "Frekvencija" -#: panels/display/cc-display-panel.c:1095 +#: panels/display/cc-display-panel.c:1111 msgid "Scale" msgstr "Prilagodba veličine" -#: panels/display/cc-display-panel.c:1148 +#: panels/display/cc-display-panel.c:1164 msgid "Adjust for TV" msgstr "Prilagodi za TV" -#: panels/display/cc-display-panel.c:1410 +#: panels/display/cc-display-panel.c:1427 msgid "Primary Display" msgstr "Glavni zaslon" -#: panels/display/cc-display-panel.c:1439 +#: panels/display/cc-display-panel.c:1456 msgid "Display Arrangement" msgstr "Razmještaj zaslona" -#: panels/display/cc-display-panel.c:1440 +#: panels/display/cc-display-panel.c:1457 msgid "" "Drag displays to match your setup. The top bar is placed on the primary " "display." @@ -1157,59 +1161,67 @@ msgstr "" "Povlačite zaslone kako bi se prilagodili vašim postavkama. Gornja traka je " "smještena na glavnom zaslonu." -#: panels/display/cc-display-panel.c:1863 +#: panels/display/cc-display-panel.c:1881 msgid "Display Mode" msgstr "Način rada zalona" -#: panels/display/cc-display-panel.c:1879 +#: panels/display/cc-display-panel.c:1897 msgid "Join Displays" msgstr "Spojeni zasloni" -#: panels/display/cc-display-panel.c:1882 +#: panels/display/cc-display-panel.c:1900 msgid "Mirror" msgstr "Zrcalo" -#: panels/display/cc-display-panel.c:1885 +#: panels/display/cc-display-panel.c:1903 msgid "Single Display" msgstr "Jednostruki zaslon" -#: panels/display/cc-display-panel.c:2590 -msgid "Apply Changes?" -msgstr "Primijeni promjene?" - -#: panels/display/cc-display-panel.c:2604 +#: panels/display/cc-display-panel.c:2620 #: panels/network/connection-editor/connection-editor.ui:24 #: panels/network/network-wifi.ui:38 msgid "_Apply" msgstr "_Primijeni" -#: panels/display/cc-display-panel.c:2979 +#: panels/display/cc-display-panel.c:2642 +msgid "Apply Changes?" +msgstr "Primijeni promjene?" + +#: panels/display/cc-display-panel.c:2647 +msgid "Changes Cannot be Applied" +msgstr "" + +#: panels/display/cc-display-panel.c:2648 +msgid "This could be due to hardware limitations." +msgstr "" + +#: panels/display/cc-display-panel.c:3003 #, c-format msgid "%.2lf Hz" msgstr "%.2lf Hz" #. TRANSLATORS: the state of the night light setting -#: panels/display/cc-display-panel.c:3195 +#: panels/display/cc-display-panel.c:3219 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1988 panels/power/cc-power-panel.c:1995 -#: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 -#: panels/universal-access/cc-ua-panel.c:333 -#: panels/universal-access/cc-ua-panel.c:714 -#: panels/universal-access/cc-ua-panel.c:727 -#: panels/universal-access/cc-ua-panel.c:739 -#: panels/universal-access/cc-ua-panel.c:910 +#: panels/power/cc-power-panel.c:2012 panels/power/cc-power-panel.c:2019 +#: panels/privacy/cc-privacy-panel.c:191 panels/privacy/cc-privacy-panel.c:258 +#: panels/universal-access/cc-ua-panel.c:334 +#: panels/universal-access/cc-ua-panel.c:715 +#: panels/universal-access/cc-ua-panel.c:728 +#: panels/universal-access/cc-ua-panel.c:740 +#: panels/universal-access/cc-ua-panel.c:911 msgid "On" msgstr "Uključeno" -#: panels/display/cc-display-panel.c:3195 panels/network/net-proxy.c:54 +#: panels/display/cc-display-panel.c:3219 panels/network/net-proxy.c:54 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1982 panels/power/cc-power-panel.c:1993 -#: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 -#: panels/universal-access/cc-ua-panel.c:333 -#: panels/universal-access/cc-ua-panel.c:714 -#: panels/universal-access/cc-ua-panel.c:727 -#: panels/universal-access/cc-ua-panel.c:739 -#: panels/universal-access/cc-ua-panel.c:910 panels/universal-access/uap.ui:334 +#: panels/power/cc-power-panel.c:2006 panels/power/cc-power-panel.c:2017 +#: panels/privacy/cc-privacy-panel.c:191 panels/privacy/cc-privacy-panel.c:258 +#: panels/universal-access/cc-ua-panel.c:334 +#: panels/universal-access/cc-ua-panel.c:715 +#: panels/universal-access/cc-ua-panel.c:728 +#: panels/universal-access/cc-ua-panel.c:740 +#: panels/universal-access/cc-ua-panel.c:911 panels/universal-access/uap.ui:334 #: panels/universal-access/uap.ui:380 panels/universal-access/uap.ui:426 #: panels/universal-access/uap.ui:532 panels/universal-access/uap.ui:685 #: panels/universal-access/uap.ui:731 panels/universal-access/uap.ui:777 @@ -1217,11 +1229,11 @@ msgstr "Uključeno" msgid "Off" msgstr "Isključeno" -#: panels/display/cc-display-panel.c:3216 +#: panels/display/cc-display-panel.c:3240 msgid "_Night Light" msgstr "_Noćno svjetlo" -#: panels/display/cc-display-panel.c:3281 +#: panels/display/cc-display-panel.c:3305 msgid "Could not get screen information" msgstr "Nemoguće dobivanje informacije zaslona" @@ -1261,7 +1273,7 @@ msgstr "Zalazak prema izlasku sunca" #: panels/network/connection-editor/ip6-page.ui:83 #: panels/network/net-proxy.c:56 panels/network/network-proxy.ui:113 #: panels/network/network-wifi.ui:777 panels/network/network-wifi.ui:1054 -#: panels/privacy/cc-privacy-panel.c:217 +#: panels/privacy/cc-privacy-panel.c:218 msgid "Manual" msgstr "Ručno" @@ -1295,12 +1307,13 @@ msgstr "Zasloni" msgid "Choose how to use connected monitors and projectors" msgstr "Odaberite kako koristiti monitore i projektore" -#: panels/display/gnome-display-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/display/gnome-display-panel.desktop.in.in:7 msgid "preferences-desktop-display" msgstr "osobitosti-zaslona-radne površine" -#. Translators: those are keywords for the display control-center panel -#: panels/display/gnome-display-panel.desktop.in.in:18 +#. Translators: Search terms to find the Displays panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/display/gnome-display-panel.desktop.in.in:19 msgid "" "Panel;Projector;xrandr;Screen;Resolution;Refresh;Monitor;Night;Light;Blue;" "redshift;color;sunset;sunrise;" @@ -1309,8 +1322,8 @@ msgstr "" "crveni pomak; boja;zalazak;izlazak;" #. TRANSLATORS: AP type -#: panels/info/cc-info-overview-panel.c:374 -#: panels/info/cc-info-overview-panel.c:457 panels/network/panel-common.c:123 +#: panels/info/cc-info-overview-panel.c:373 +#: panels/info/cc-info-overview-panel.c:456 panels/network/panel-common.c:123 msgid "Unknown" msgstr "Nepoznato" @@ -1318,24 +1331,24 @@ msgstr "Nepoznato" #. * example: #. * "Fedora 25 (Workstation Edition); Build ID: xyz" or #. * "Ubuntu 16.04 LTS; Build ID: jki" -#: panels/info/cc-info-overview-panel.c:465 +#: panels/info/cc-info-overview-panel.c:464 #, c-format msgid "%s; Build ID: %s" msgstr "%s; ID izgradnje: %s" #. translators: This is the type of architecture for the OS -#: panels/info/cc-info-overview-panel.c:482 +#: panels/info/cc-info-overview-panel.c:481 #, c-format msgid "64-bit" msgstr "64-bitni" #. translators: This is the type of architecture for the OS -#: panels/info/cc-info-overview-panel.c:485 +#: panels/info/cc-info-overview-panel.c:484 #, c-format msgid "32-bit" msgstr "32-bitni" -#: panels/info/cc-info-overview-panel.c:775 +#: panels/info/cc-info-overview-panel.c:773 #, c-format msgid "Version %s" msgstr "Inačica %s" @@ -1438,12 +1451,13 @@ msgstr "Zadane aplikacije" msgid "Configure Default Applications" msgstr "Prilagodite zadane aplikacije" -#: panels/info/gnome-default-apps-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/info/gnome-default-apps-panel.desktop.in.in:7 msgid "starred" msgstr "označeno" -#. Translators: those are keywords for the Default Applications panel -#: panels/info/gnome-default-apps-panel.desktop.in.in:18 +#. Translators: Search terms to find the Default Applications panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/info/gnome-default-apps-panel.desktop.in.in:19 msgid "default;application;preferred;media;" msgstr "zadano;aplikacija;poželjno;medij;" @@ -1455,14 +1469,17 @@ msgstr "O sustavu" msgid "View information about your system" msgstr "Prikaži informacije ovog sustava" -#: panels/info/gnome-info-overview-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/info/gnome-info-overview-panel.desktop.in.in:7 msgid "help-about" msgstr "pomoć-o sustavu" -#. Translators: those are keywords for the System Information panel +#. Translators: Search terms to find the About panel. +#. Do NOT translate or localize the semicolons! +#. The list MUST also end with a semicolon! #. "Preferred Applications" is the old name for the preference, so make #. sure that you use the same "translation" for those keywords -#: panels/info/gnome-info-overview-panel.desktop.in.in:20 +#: panels/info/gnome-info-overview-panel.desktop.in.in:23 msgid "" "device;system;information;memory;processor;version;default;application;" "preferred;cd;dvd;usb;audio;video;disc;removable;media;autorun;" @@ -1478,12 +1495,13 @@ msgstr "Prijenosni mediji" msgid "Configure Removable Media settings" msgstr "Prilagodite prijenosne medije" -#: panels/info/gnome-removable-media-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/info/gnome-removable-media-panel.desktop.in.in:7 msgid "media-removable" msgstr "prijenosni-mediji" -#. Translators: those are keywords for the Removable Media panel -#: panels/info/gnome-removable-media-panel.desktop.in.in:18 +#. Translators: Search terms to find the Removable Media panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/info/gnome-removable-media-panel.desktop.in.in:19 msgid "" "device;system;default;application;preferred;cd;dvd;usb;audio;video;disc;" "removable;media;autorun;" @@ -1661,8 +1679,8 @@ msgstr "Pokretači" msgid "Launch help browser" msgstr "Pokreni preglednik pomoći" -#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:223 -#: shell/cc-window.c:761 shell/gnome-control-center.desktop.in.in:3 +#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:237 +#: shell/cc-window.c:773 shell/gnome-control-center.desktop.in.in:3 #: shell/window.ui:125 msgid "Settings" msgstr "Postavke" @@ -1771,7 +1789,7 @@ msgstr "Uključi ili isključi visoki kontrast" #: panels/keyboard/cc-keyboard-manager.c:506 #: panels/keyboard/cc-keyboard-manager.c:514 -#: panels/keyboard/cc-keyboard-manager.c:822 +#: panels/keyboard/cc-keyboard-manager.c:821 msgid "Custom Shortcuts" msgstr "Prilagođeni prečaci" @@ -1782,7 +1800,7 @@ msgstr "Prilagođeni prečaci" #. * The device has been disabled #: panels/keyboard/cc-keyboard-option.c:263 #: panels/keyboard/cc-keyboard-option.c:382 -#: panels/keyboard/keyboard-shortcuts.c:435 +#: panels/keyboard/keyboard-shortcuts.c:434 #: panels/keyboard/shortcut-editor.ui:96 panels/network/network-proxy.ui:123 #: panels/network/network-wifi.ui:782 panels/network/network-wifi.ui:1059 #: panels/user-accounts/um-fingerprint-dialog.c:211 @@ -1872,12 +1890,13 @@ msgid "View and change keyboard shortcuts and set your typing preferences" msgstr "" "Pogledajte i promijenite prečace tipkovnice i postavite osobitosti tipkanja" -#: panels/keyboard/gnome-keyboard-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/keyboard/gnome-keyboard-panel.desktop.in.in:7 msgid "input-keyboard" msgstr "način unosa-tipkovnice" -#. Translators: those are keywords for the keyboard control-center panel -#: panels/keyboard/gnome-keyboard-panel.desktop.in.in:18 +#. Translators: Search terms to find the Keyboard panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/keyboard/gnome-keyboard-panel.desktop.in.in:19 msgid "" "Shortcut;Workspace;Window;Resize;Zoom;Contrast;Input;Source;Lock;Volume;" msgstr "" @@ -1966,12 +1985,13 @@ msgid "" msgstr "" "Promijenite osjetljivost touchpada i miša i odaberite lijevu ili desnu ruku" -#: panels/mouse/gnome-mouse-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/mouse/gnome-mouse-panel.desktop.in.in:7 msgid "input-mouse" msgstr "način unosa-miša" -#. Translators: those are keywords for the mouse and touchpad control-center panel -#: panels/mouse/gnome-mouse-panel.desktop.in.in:18 +#. Translators: Search terms to find the Mouse and Touchpad panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/mouse/gnome-mouse-panel.desktop.in.in:19 msgid "Trackpad;Pointer;Click;Tap;Double;Button;Trackball;Scroll;" msgstr "" "Klizna površina;Pokazivač;Klik;Dodir;Dvostruk;Tipka;Klizna kugla;Pomakni;" @@ -2075,7 +2095,7 @@ msgid "Single click, secondary button" msgstr "Jednostruki klik, druga tipka" #. add proxy to device list -#: panels/network/cc-network-panel.c:579 +#: panels/network/cc-network-panel.c:581 msgid "Network proxy" msgstr "Mrežni proxy" @@ -2083,24 +2103,24 @@ msgstr "Mrežni proxy" #. * window for vpn connections, it is also used to display #. * vpn connections in the device list. #. -#: panels/network/cc-network-panel.c:715 panels/network/net-vpn.c:192 -#: panels/network/net-vpn.c:321 +#: panels/network/cc-network-panel.c:717 panels/network/net-vpn.c:167 +#: panels/network/net-vpn.c:296 #, c-format msgid "%s VPN" msgstr "%s VPN" -#: panels/network/cc-network-panel.c:779 panels/network/wifi.ui:282 +#: panels/network/cc-network-panel.c:781 panels/network/wifi.ui:282 msgid "Oops, something has gone wrong. Please contact your software vendor." msgstr "" "Ups, nešto je pošlo po krivu. Kontaktirajte svojeg dobavljača softvera." -#: panels/network/cc-network-panel.c:785 +#: panels/network/cc-network-panel.c:787 msgid "NetworkManager needs to be running." msgstr "Mrežni upravitelj mora biti pokrenut." -#: panels/network/cc-wifi-panel.c:212 +#: panels/network/cc-wifi-panel.c:214 #: panels/network/gnome-wifi-panel.desktop.in.in:3 -#: panels/network/network-wifi.ui:1766 +#: panels/network/network-wifi.ui:1769 msgid "Wi-Fi" msgstr "Bežična mreža" @@ -2151,31 +2171,31 @@ msgstr "Profil %d" #. TRANSLATORS: this WEP WiFi security #: panels/network/connection-editor/ce-page-details.c:56 -#: panels/network/net-device-wifi.c:231 panels/network/net-device-wifi.c:453 +#: panels/network/net-device-wifi.c:235 panels/network/net-device-wifi.c:468 msgid "WEP" msgstr "WEP" #. TRANSLATORS: this WPA WiFi security #: panels/network/connection-editor/ce-page-details.c:60 -#: panels/network/net-device-wifi.c:235 panels/network/net-device-wifi.c:458 +#: panels/network/net-device-wifi.c:239 panels/network/net-device-wifi.c:473 #: panels/network/network-wifi.ui:593 msgid "WPA" msgstr "WPA" #. TRANSLATORS: this WPA WiFi security #: panels/network/connection-editor/ce-page-details.c:64 -#: panels/network/net-device-wifi.c:239 +#: panels/network/net-device-wifi.c:243 msgid "WPA2" msgstr "WPA2" #. TRANSLATORS: this Enterprise WiFi security #: panels/network/connection-editor/ce-page-details.c:69 -#: panels/network/net-device-wifi.c:244 +#: panels/network/net-device-wifi.c:248 msgid "Enterprise" msgstr "Poslovanje" #: panels/network/connection-editor/ce-page-details.c:74 -#: panels/network/net-device-wifi.c:249 panels/network/net-device-wifi.c:443 +#: panels/network/net-device-wifi.c:253 panels/network/net-device-wifi.c:458 msgctxt "Wifi security" msgid "None" msgstr "Nepoznata" @@ -2187,7 +2207,7 @@ msgstr "Nikada" #: panels/network/connection-editor/ce-page-details.c:110 #: panels/network/net-device-ethernet.c:121 -#: panels/network/net-device-wifi.c:552 +#: panels/network/net-device-wifi.c:567 #, c-format msgid "%i day ago" msgid_plural "%i days ago" @@ -2197,37 +2217,37 @@ msgstr[2] "prije %i dana" #. Translators: network device speed #: panels/network/connection-editor/ce-page-details.c:225 -#: panels/network/net-device-ethernet.c:50 panels/network/net-device-wifi.c:608 +#: panels/network/net-device-ethernet.c:50 panels/network/net-device-wifi.c:646 #, c-format msgid "%d Mb/s" msgstr "%d Mb/s" #: panels/network/connection-editor/ce-page-details.c:251 -#: panels/network/net-device-wifi.c:637 +#: panels/network/net-device-wifi.c:675 msgctxt "Signal strength" msgid "None" msgstr "Nepoznata" #: panels/network/connection-editor/ce-page-details.c:253 -#: panels/network/net-device-wifi.c:639 +#: panels/network/net-device-wifi.c:677 msgctxt "Signal strength" msgid "Weak" msgstr "Slaba" #: panels/network/connection-editor/ce-page-details.c:255 -#: panels/network/net-device-wifi.c:641 +#: panels/network/net-device-wifi.c:679 msgctxt "Signal strength" msgid "Ok" msgstr "U redu" #: panels/network/connection-editor/ce-page-details.c:257 -#: panels/network/net-device-wifi.c:643 +#: panels/network/net-device-wifi.c:681 msgctxt "Signal strength" msgid "Good" msgstr "Dobra" #: panels/network/connection-editor/ce-page-details.c:259 -#: panels/network/net-device-wifi.c:645 +#: panels/network/net-device-wifi.c:683 msgctxt "Signal strength" msgid "Excellent" msgstr "Izvrsna" @@ -2245,7 +2265,7 @@ msgid "Remove VPN" msgstr "Ukloni VPN" #: panels/network/connection-editor/ce-page-details.c:334 -#: panels/network/network-wifi.ui:1456 shell/cc-window.c:215 +#: panels/network/network-wifi.ui:1456 shell/cc-window.c:229 #: shell/panel-list.ui:103 msgid "Details" msgstr "Pojedinosti" @@ -2380,7 +2400,7 @@ msgstr "Prikladno za povezivanja s naplatom ili ograničenjem podataka." #: panels/network/connection-editor/ip6-page.ui:291 #: panels/network/net-proxy.c:58 panels/network/network-proxy.ui:103 #: panels/network/wireless-security/eap-method-peap.ui:22 -#: panels/privacy/cc-privacy-panel.c:217 +#: panels/privacy/cc-privacy-panel.c:218 msgid "Automatic" msgstr "Automatski" @@ -2580,7 +2600,7 @@ msgstr "Odaberi datoteku za uvoz" #: panels/network/connection-editor/vpn-helpers.c:182 #: panels/printers/pp-details-dialog.c:332 #: panels/sharing/cc-sharing-panel.c:385 -#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-photo-dialog.c:231 msgid "_Open" msgstr "_Otvori" @@ -2645,12 +2665,13 @@ msgstr "Mreža" msgid "Control how you connect to the Internet" msgstr "Upravljajte načinom povezivanja na Internet" -#: panels/network/gnome-network-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/network/gnome-network-panel.desktop.in.in:7 msgid "network-workgroup" msgstr "mrežna-radna grupa" -#. Translators: those are keywords for the network control-center panel -#: panels/network/gnome-network-panel.desktop.in.in:18 +#. Translators: Search terms to find the Network panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/network/gnome-network-panel.desktop.in.in:19 msgid "" "Network;Wireless;Wi-Fi;Wifi;IP;LAN;Proxy;WAN;Broadband;Modem;Bluetooth;vpn;" "DNS;" @@ -2662,27 +2683,28 @@ msgstr "" msgid "Control how you connect to Wi-Fi networks" msgstr "Upravljajte načinom povezivanja na bežične mreže" -#: panels/network/gnome-wifi-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/network/gnome-wifi-panel.desktop.in.in:7 msgid "network-wireless" msgstr "bežična-mreža" -#. Translators: those are keywords for the wi-fi control-center panel -#: panels/network/gnome-wifi-panel.desktop.in.in:18 +#. Translators: Search terms to find the Wi-Fi panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/network/gnome-wifi-panel.desktop.in.in:19 msgid "Network;Wireless;Wi-Fi;Wifi;IP;LAN;Broadband;DNS;" msgstr "Mreža;Bežično;Bežična mreža;IP;Žično;Širokopojasni internet;DNS;" #: panels/network/net-device-ethernet.c:107 -#: panels/network/net-device-wifi.c:538 +#: panels/network/net-device-wifi.c:553 msgid "never" msgstr "nikada" #: panels/network/net-device-ethernet.c:117 -#: panels/network/net-device-wifi.c:548 +#: panels/network/net-device-wifi.c:563 msgid "today" msgstr "danas" #: panels/network/net-device-ethernet.c:119 -#: panels/network/net-device-wifi.c:550 +#: panels/network/net-device-wifi.c:565 msgid "yesterday" msgstr "jučer" @@ -2707,7 +2729,7 @@ msgid "Wired" msgstr "Žična mreža" #: panels/network/net-device-ethernet.c:344 -#: panels/network/net-device-wifi.c:1849 panels/network/network-ethernet.ui:120 +#: panels/network/net-device-wifi.c:1895 panels/network/network-ethernet.ui:120 #: panels/network/network-mobile.ui:394 panels/network/network-simple.ui:75 #: panels/network/network-vpn.ui:79 msgid "Options…" @@ -2717,12 +2739,12 @@ msgstr "Mogućnosti…" msgid "Add new connection" msgstr "Dodaj novu mrežu" -#: panels/network/net-device-wifi.c:1328 +#: panels/network/net-device-wifi.c:1368 #, c-format msgid "Switching on the wireless hotspot will disconnect you from %s." msgstr "Prebacivanje na bežičnu pristupnu točku odspojiti će vas s %s." -#: panels/network/net-device-wifi.c:1332 +#: panels/network/net-device-wifi.c:1372 msgid "" "It is not possible to access the Internet through your wireless while the " "hotspot is active." @@ -2730,11 +2752,11 @@ msgstr "" "Pristup Internetu nije moguć putem vašeg bežičnog povezivanja dok je " "pristupna točka aktivna." -#: panels/network/net-device-wifi.c:1339 +#: panels/network/net-device-wifi.c:1379 msgid "Turn On Wi-Fi Hotspot?" msgstr "Uključi bežičnu pristupnu točku?" -#: panels/network/net-device-wifi.c:1361 +#: panels/network/net-device-wifi.c:1401 msgid "" "Wi-Fi hotspots are usually used to share an additional Internet connection " "over Wi-Fi." @@ -2742,27 +2764,27 @@ msgstr "" "Bežične pristupne točke uobičajeno se koriste za dijeljenje dodatnog " "pristupa internetu putem bežične mreže." -#: panels/network/net-device-wifi.c:1372 +#: panels/network/net-device-wifi.c:1412 msgid "_Turn On" msgstr "_Uključi" -#: panels/network/net-device-wifi.c:1449 +#: panels/network/net-device-wifi.c:1489 msgid "Stop hotspot and disconnect any users?" msgstr "Zaustaviti pristupnu točku i odspojiti sve korisnike?" -#: panels/network/net-device-wifi.c:1452 +#: panels/network/net-device-wifi.c:1492 msgid "_Stop Hotspot" msgstr "_Zaustavi pristupnu točku" -#: panels/network/net-device-wifi.c:1552 +#: panels/network/net-device-wifi.c:1592 msgid "System policy prohibits use as a Hotspot" msgstr "Pravila sustava ne dopuštaju korištenje kao pristupne točke" -#: panels/network/net-device-wifi.c:1555 +#: panels/network/net-device-wifi.c:1595 msgid "Wireless device does not support Hotspot mode" msgstr "Bežični uređaj ne podržava način pristupne točke" -#: panels/network/net-device-wifi.c:1687 +#: panels/network/net-device-wifi.c:1733 msgid "" "Network details for the selected networks, including passwords and any " "custom configuration will be lost." @@ -2770,16 +2792,16 @@ msgstr "" "Mrežne pojedinosti za odabrane mreže, uključujući lozinke i sve prilagođene " "postavke će biti izgubljene." -#: panels/network/net-device-wifi.c:1691 panels/network/network-wifi.ui:1362 +#: panels/network/net-device-wifi.c:1737 panels/network/network-wifi.ui:1362 msgid "_Forget" msgstr "_Zaboravi" -#: panels/network/net-device-wifi.c:2000 panels/network/net-device-wifi.c:2007 +#: panels/network/net-device-wifi.c:2046 panels/network/net-device-wifi.c:2053 msgid "Known Wi-Fi Networks" msgstr "Poznate bežične mreže" #. translators: This is the label for the "Forget wireless network" functionality -#: panels/network/net-device-wifi.c:2040 +#: panels/network/net-device-wifi.c:2086 msgctxt "Wi-Fi Network" msgid "_Forget" msgstr "_Zaboravi" @@ -2998,19 +3020,19 @@ msgctxt "Wi-Fi passkey" msgid "Password" msgstr "Lozinka" -#: panels/network/network-wifi.ui:1796 +#: panels/network/network-wifi.ui:1799 msgid "Turn Wi-Fi off" msgstr "Isključi bežičnu mrežu" -#: panels/network/network-wifi.ui:1828 +#: panels/network/network-wifi.ui:1831 msgid "_Connect to Hidden Network…" msgstr "_Poveži se na skrivenu mrežu…" -#: panels/network/network-wifi.ui:1838 +#: panels/network/network-wifi.ui:1841 msgid "_Turn On Wi-Fi Hotspot…" msgstr "_Uključi bežičnu pristupnu točku…" -#: panels/network/network-wifi.ui:1848 +#: panels/network/network-wifi.ui:1851 msgid "_Known Wi-Fi Networks" msgstr "_Poznate bežične mreže" @@ -3319,23 +3341,23 @@ msgstr "Nedostaje firmver" msgid "Cable unplugged" msgstr "Kabel je odspojen" -#: panels/network/wireless-security/eap-method.c:57 +#: panels/network/wireless-security/eap-method.c:69 msgid "undefined error in 802.1X security (wpa-eap)" msgstr "neodređena greška u 802.1x sigurnosti (wpa-eap)" -#: panels/network/wireless-security/eap-method.c:233 +#: panels/network/wireless-security/eap-method.c:245 msgid "no file selected" msgstr "nema odabrane datoteke" -#: panels/network/wireless-security/eap-method.c:264 +#: panels/network/wireless-security/eap-method.c:276 msgid "unspecified error validating eap-method file" msgstr "neodređena greška provjeravanja datoteke eap-načina" -#: panels/network/wireless-security/eap-method.c:439 +#: panels/network/wireless-security/eap-method.c:451 msgid "DER, PEM, or PKCS#12 private keys (*.der, *.pem, *.p12, *.key)" msgstr "DER, PEM, ili PKCS#12 privatni ključevi (*.der, *.pem, *.p12, *.key)" -#: panels/network/wireless-security/eap-method.c:442 +#: panels/network/wireless-security/eap-method.c:454 msgid "DER or PEM certificates (*.der, *.pem, *.crt, *.cer)" msgstr "DER ili PEM vjerodajnice (*.der, *.pem, *.crt, *.cer)" @@ -3719,12 +3741,13 @@ msgstr "Obavijesti" msgid "Control which notifications are displayed and what they show" msgstr "Upravljajte koje će poruke biti prikazane i što će prikazivati" -#: panels/notifications/gnome-notifications-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/notifications/gnome-notifications-panel.desktop.in.in:7 msgid "preferences-system-notifications" msgstr "osobitosti-obavijesti-sustava" -#. Translators: those are keywords for the notifications control-center panel -#: panels/notifications/gnome-notifications-panel.desktop.in.in:19 +#. Translators: Search terms to find the Notifications panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/notifications/gnome-notifications-panel.desktop.in.in:20 msgid "Notifications;Banner;Message;Tray;Popup;" msgstr "Obavijesti;Transparent;Poruka;Statusna traka;Skočni prozor;" @@ -3749,19 +3772,19 @@ msgstr "Ostalo" #. translators: This is the title of the "Show Account" dialog. The #. * %s is the name of the provider. e.g., 'Google'. -#: panels/online-accounts/cc-online-accounts-panel.c:551 +#: panels/online-accounts/cc-online-accounts-panel.c:612 #, c-format msgid "%s Account" msgstr "%s račun" -#: panels/online-accounts/cc-online-accounts-panel.c:843 +#: panels/online-accounts/cc-online-accounts-panel.c:904 msgid "Error removing account" msgstr "Greška pri uklanjanju računa" #. Translators: The %s is the username (eg., debarshi.ray@gmail.com #. * or rishi). #. -#: panels/online-accounts/cc-online-accounts-panel.c:908 +#: panels/online-accounts/cc-online-accounts-panel.c:969 #, c-format msgid "%s removed" msgstr "%s je uklonjen" @@ -3775,13 +3798,16 @@ msgid "Connect to your online accounts and decide what to use them for" msgstr "" "Povežite se sa svojim mrežnim računima i odredite za što ih želite koristiti" -#: panels/online-accounts/gnome-online-accounts-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/online-accounts/gnome-online-accounts-panel.desktop.in.in:7 msgid "goa-panel" msgstr "goa-panel" -#. Translators: those are keywords for the online-accounts control-center panel +#. Translators: Search terms to find the Online Accounts panel. +#. Do NOT translate or localize the semicolons! +#. The list MUST also end with a semicolon! #. For ReadItLater and Pocket, see http://en.wikipedia.org/wiki/Pocket_(application) -#: panels/online-accounts/gnome-online-accounts-panel.desktop.in.in:19 +#: panels/online-accounts/gnome-online-accounts-panel.desktop.in.in:22 msgid "" "Google;Facebook;Twitter;Yahoo;Web;Online;Chat;Calendar;Mail;Contact;ownCloud;" "Kerberos;IMAP;SMTP;Pocket;ReadItLater;" @@ -3811,11 +3837,11 @@ msgstr "Dodaj račun" msgid "Remove Account" msgstr "Ukloni račun" -#: panels/power/cc-power-panel.c:253 +#: panels/power/cc-power-panel.c:254 msgid "Unknown time" msgstr "Nepoznato vrijeme" -#: panels/power/cc-power-panel.c:259 +#: panels/power/cc-power-panel.c:260 #, c-format msgid "%i minute" msgid_plural "%i minutes" @@ -3823,7 +3849,7 @@ msgstr[0] "%i minuta" msgstr[1] "%i minute" msgstr[2] "%i minuta" -#: panels/power/cc-power-panel.c:271 +#: panels/power/cc-power-panel.c:272 #, c-format msgid "%i hour" msgid_plural "%i hours" @@ -3833,19 +3859,19 @@ msgstr[2] "%i sati" #. TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes" #. * Swap order with "%2$s %2$i %1$s %1$i if needed -#: panels/power/cc-power-panel.c:279 +#: panels/power/cc-power-panel.c:280 #, c-format msgid "%i %s %i %s" msgstr "%i %s %i %s" -#: panels/power/cc-power-panel.c:280 +#: panels/power/cc-power-panel.c:281 msgid "hour" msgid_plural "hours" msgstr[0] "sat" msgstr[1] "sata" msgstr[2] "sati" -#: panels/power/cc-power-panel.c:281 +#: panels/power/cc-power-panel.c:282 msgid "minute" msgid_plural "minutes" msgstr[0] "minuta" @@ -3853,240 +3879,241 @@ msgstr[1] "minute" msgstr[2] "minuta" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:300 +#: panels/power/cc-power-panel.c:301 #, c-format msgid "%s until fully charged" msgstr "%s do potpune napunjenosti" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:307 +#: panels/power/cc-power-panel.c:308 #, c-format msgid "Caution: %s remaining" msgstr "Upozorenje: %s preostalo" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:312 +#: panels/power/cc-power-panel.c:313 #, c-format msgid "%s remaining" msgstr "%s preostalo" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:317 panels/power/cc-power-panel.c:345 +#: panels/power/cc-power-panel.c:318 panels/power/cc-power-panel.c:346 msgid "Fully charged" msgstr "Potpuno napunjeno" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:321 panels/power/cc-power-panel.c:349 +#: panels/power/cc-power-panel.c:322 panels/power/cc-power-panel.c:350 msgid "Empty" msgstr "Prazna" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:336 +#: panels/power/cc-power-panel.c:337 msgid "Charging" msgstr "Punjenje" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:341 +#: panels/power/cc-power-panel.c:342 msgid "Discharging" msgstr "Pražnjenje" -#: panels/power/cc-power-panel.c:464 +#: panels/power/cc-power-panel.c:465 msgctxt "Battery name" msgid "Main" msgstr "Glavna" -#: panels/power/cc-power-panel.c:466 +#: panels/power/cc-power-panel.c:467 msgctxt "Battery name" msgid "Extra" msgstr "Dodatna" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:537 +#: panels/power/cc-power-panel.c:538 msgid "Wireless mouse" msgstr "Bežični miš" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:540 +#: panels/power/cc-power-panel.c:541 msgid "Wireless keyboard" msgstr "Bežična tipkovnica" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:543 +#: panels/power/cc-power-panel.c:544 msgid "Uninterruptible power supply" msgstr "Neprekinuta opskrba energijom (UPS)" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:546 +#: panels/power/cc-power-panel.c:547 msgid "Personal digital assistant" msgstr "Osobni digitalni pomagač (PDA)" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:549 +#: panels/power/cc-power-panel.c:550 msgid "Cellphone" msgstr "Mobitel" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:552 +#: panels/power/cc-power-panel.c:553 msgid "Media player" msgstr "Medijski reproduktor" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:555 panels/wacom/cc-wacom-panel.c:793 +#: panels/power/cc-power-panel.c:556 panels/wacom/cc-wacom-panel.c:793 msgid "Tablet" msgstr "Tablet" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:558 +#: panels/power/cc-power-panel.c:559 msgid "Computer" msgstr "Računalo" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:561 +#: panels/power/cc-power-panel.c:562 msgid "Gaming input device" msgstr "Uređaj za igranje" #. TRANSLATORS: secondary battery, misc -#: panels/power/cc-power-panel.c:564 panels/power/cc-power-panel.c:804 -#: panels/power/cc-power-panel.c:2374 +#: panels/power/cc-power-panel.c:565 panels/power/cc-power-panel.c:805 +#: panels/power/cc-power-panel.c:2398 msgid "Battery" msgstr "Baterija" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:618 +#: panels/power/cc-power-panel.c:619 msgctxt "Battery power" msgid "Charging" msgstr "Punjenje" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:625 +#: panels/power/cc-power-panel.c:626 msgctxt "Battery power" msgid "Caution" msgstr "Upozorenje" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:630 +#: panels/power/cc-power-panel.c:631 msgctxt "Battery power" msgid "Low" msgstr "Niska" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:635 +#: panels/power/cc-power-panel.c:636 msgctxt "Battery power" msgid "Good" msgstr "Dobra" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:640 +#: panels/power/cc-power-panel.c:641 msgctxt "Battery power" msgid "Fully charged" msgstr "Potpuno napunjeno" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:644 +#: panels/power/cc-power-panel.c:645 msgctxt "Battery power" msgid "Empty" msgstr "Prazna" -#: panels/power/cc-power-panel.c:802 +#: panels/power/cc-power-panel.c:803 msgid "Batteries" msgstr "Baterije" -#: panels/power/cc-power-panel.c:1236 +#: panels/power/cc-power-panel.c:1243 msgid "When _idle" msgstr "Pri _mirovanju" -#: panels/power/cc-power-panel.c:1690 +#: panels/power/cc-power-panel.c:1708 msgid "Power Saving" msgstr "Štednja energije" -#: panels/power/cc-power-panel.c:1721 +#: panels/power/cc-power-panel.c:1739 msgid "_Screen brightness" msgstr "_Svjetlina zaslona" -#: panels/power/cc-power-panel.c:1740 +#: panels/power/cc-power-panel.c:1758 msgid "Automatic brightness" msgstr "Automatska svjetlina" -#: panels/power/cc-power-panel.c:1760 +#: panels/power/cc-power-panel.c:1778 msgid "_Keyboard brightness" msgstr "_Svjetlina tipkovnice" -#: panels/power/cc-power-panel.c:1770 +#: panels/power/cc-power-panel.c:1788 msgid "_Dim screen when inactive" msgstr "_Zatamni zaslon kada je neaktivan" -#: panels/power/cc-power-panel.c:1795 +#: panels/power/cc-power-panel.c:1813 msgid "_Blank screen" msgstr "_Zatamni zaslon" -#: panels/power/cc-power-panel.c:1832 +#: panels/power/cc-power-panel.c:1850 msgid "_Wi-Fi" msgstr "_Bežična mreža" -#: panels/power/cc-power-panel.c:1837 +#: panels/power/cc-power-panel.c:1855 msgid "Turn off Wi-Fi to save power." msgstr "Isključi bežičnu mrežu u svrhu štednje energije." -#: panels/power/cc-power-panel.c:1862 +#: panels/power/cc-power-panel.c:1880 msgid "_Mobile broadband" msgstr "_Mobilni širokopojasni internet" -#: panels/power/cc-power-panel.c:1867 +#: panels/power/cc-power-panel.c:1885 msgid "Turn off mobile broadband (3G, 4G, LTE, etc.) to save power." msgstr "" "Isključi mobilni širokopojasni internet (3G, 4G, LTE, itd.) u svrhu štednje " "energije." -#: panels/power/cc-power-panel.c:1920 +#: panels/power/cc-power-panel.c:1944 msgid "_Bluetooth" msgstr "_Bluetooth" -#: panels/power/cc-power-panel.c:1925 +#: panels/power/cc-power-panel.c:1949 msgid "Turn off Bluetooth to save power." msgstr "Isključi Bluetooth u svrhu štednje energije." -#: panels/power/cc-power-panel.c:1984 +#: panels/power/cc-power-panel.c:2008 msgid "When on battery power" msgstr "Na bateriji" -#: panels/power/cc-power-panel.c:1986 +#: panels/power/cc-power-panel.c:2010 msgid "When plugged in" msgstr "Na napajanju" -#: panels/power/cc-power-panel.c:2081 +#: panels/power/cc-power-panel.c:2105 msgid "Suspend" msgstr "Suspendiraj" -#: panels/power/cc-power-panel.c:2082 +#: panels/power/cc-power-panel.c:2106 msgid "Power Off" msgstr "Isključi" -#: panels/power/cc-power-panel.c:2083 +#: panels/power/cc-power-panel.c:2107 msgid "Hibernate" msgstr "Hiberniraj" -#: panels/power/cc-power-panel.c:2084 +#: panels/power/cc-power-panel.c:2108 msgid "Nothing" msgstr "Ništa" #. Frame header -#: panels/power/cc-power-panel.c:2198 +#: panels/power/cc-power-panel.c:2222 msgid "Suspend & Power Button" msgstr "Suspenzija i tipka isključivanja" -#: panels/power/cc-power-panel.c:2237 +#: panels/power/cc-power-panel.c:2261 msgid "_Automatic suspend" msgstr "_Automatska suspenzija" -#: panels/power/cc-power-panel.c:2238 +#: panels/power/cc-power-panel.c:2262 msgid "Automatic suspend" msgstr "Automatska suspenzija" -#: panels/power/cc-power-panel.c:2305 +#: panels/power/cc-power-panel.c:2329 msgid "_When the Power Button is pressed" msgstr "_Kada je tipka isključivanja pritisnuta" -#: panels/power/cc-power-panel.c:2424 shell/cc-window.c:219 +#: panels/power/cc-power-panel.c:2448 panels/thunderbolt/cc-bolt-panel.ui:466 +#: panels/thunderbolt/cc-bolt-panel.ui:525 shell/cc-window.c:233 #: shell/panel-list.ui:45 msgid "Devices" msgstr "Uređaji" @@ -4100,12 +4127,13 @@ msgid "View your battery status and change power saving settings" msgstr "" "Pogledajte svoje stanje baterije i promijenite postavke štednje energije" -#: panels/power/gnome-power-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/power/gnome-power-panel.desktop.in.in:7 msgid "gnome-power-manager" msgstr "gnome-upravitelj-energijom" -#. Translators: those are keywords for the power control-center panel -#: panels/power/gnome-power-panel.desktop.in.in:18 +#. Translators: Search terms to find the Power panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/power/gnome-power-panel.desktop.in.in:19 msgid "" "Power;Sleep;Suspend;Hibernate;Battery;Brightness;Dim;Blank;Monitor;DPMS;Idle;" msgstr "" @@ -4221,18 +4249,18 @@ msgid "Authentication Required" msgstr "Potrebna je ovjera" #. Translators: %s is the printer name -#: panels/printers/cc-printers-panel.c:791 +#: panels/printers/cc-printers-panel.c:809 #, c-format msgid "Printer “%s” has been deleted" msgstr "Pisač “%s” je obrisan" #. Translators: Addition of the new printer failed. -#: panels/printers/cc-printers-panel.c:1036 +#: panels/printers/cc-printers-panel.c:1054 msgid "Failed to add new printer." msgstr "Neuspjelo dodavanje novoga pisača." #. Translators: The XML file containing user interface can not be loaded -#: panels/printers/cc-printers-panel.c:1371 +#: panels/printers/cc-printers-panel.c:1391 #, c-format msgid "Could not load ui: %s" msgstr "Nemoguće učitati kor. sučelje: %s" @@ -4272,12 +4300,13 @@ msgid "Add printers, view printer jobs and decide how you want to print" msgstr "" "Dodajte pisače, pogledajte zadatke ispisivanja i odredite kakav ispis želite" -#: panels/printers/gnome-printers-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/printers/gnome-printers-panel.desktop.in.in:7 msgid "printer" msgstr "pisač" -#. Translators: those are keywords for the printing control-center panel -#: panels/printers/gnome-printers-panel.desktop.in.in:15 +#. Translators: Search terms to find the Printers panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/printers/gnome-printers-panel.desktop.in.in:16 msgid "Printer;Queue;Print;Paper;Ink;Toner;" msgstr "Pisač;Red;Ispis;Papir;Tinta;Toner;" @@ -4370,7 +4399,7 @@ msgid "Select Printer Driver" msgstr "Odaberi upravljački program za pisač" #: panels/printers/ppd-selection-dialog.ui:40 -#: panels/user-accounts/um-photo-dialog.c:104 +#: panels/user-accounts/um-photo-dialog.c:105 msgid "Select" msgstr "Odaberi" @@ -4427,55 +4456,55 @@ msgid "Reverse portrait" msgstr "Obrnuto uspravno" #. Translators: Job's state (job is waiting to be printed) -#: panels/printers/pp-jobs-dialog.c:243 +#: panels/printers/pp-jobs-dialog.c:234 msgctxt "print job" msgid "Pending" msgstr "Na čekanju" #. Translators: Job's state (job is held for printing) -#: panels/printers/pp-jobs-dialog.c:249 +#: panels/printers/pp-jobs-dialog.c:240 msgctxt "print job" msgid "Paused" msgstr "Pauzirano" #. Translators: Job's state (job needs authentication to proceed further) -#: panels/printers/pp-jobs-dialog.c:254 +#: panels/printers/pp-jobs-dialog.c:245 msgctxt "print job" msgid "Authentication required" msgstr "Potrebna je ovjera" #. Translators: Job's state (job is currently printing) -#: panels/printers/pp-jobs-dialog.c:259 +#: panels/printers/pp-jobs-dialog.c:250 msgctxt "print job" msgid "Processing" msgstr "Obrada" #. Translators: Job's state (job has been stopped) -#: panels/printers/pp-jobs-dialog.c:263 +#: panels/printers/pp-jobs-dialog.c:254 msgctxt "print job" msgid "Stopped" msgstr "Zaustavljen" #. Translators: Job's state (job has been canceled) -#: panels/printers/pp-jobs-dialog.c:267 +#: panels/printers/pp-jobs-dialog.c:258 msgctxt "print job" msgid "Canceled" msgstr "Otkazan" #. Translators: Job's state (job has aborted due to error) -#: panels/printers/pp-jobs-dialog.c:271 +#: panels/printers/pp-jobs-dialog.c:262 msgctxt "print job" msgid "Aborted" msgstr "Prekinut" #. Translators: Job's state (job has completed successfully) -#: panels/printers/pp-jobs-dialog.c:275 +#: panels/printers/pp-jobs-dialog.c:266 msgctxt "print job" msgid "Completed" msgstr "Završen" #. Translators: This label shows how many jobs of this printer needs to be authenticated to be printed. -#: panels/printers/pp-jobs-dialog.c:399 +#: panels/printers/pp-jobs-dialog.c:390 #, c-format msgid "%u Job Requires Authentication" msgid_plural "%u Jobs Require Authentication" @@ -4484,14 +4513,14 @@ msgstr[1] "%u zadatka zahtijevaju ovjeru" msgstr[2] "%u zadataka zahtijeva ovjeru" #. Translators: This is the printer name for which we are showing the active jobs -#: panels/printers/pp-jobs-dialog.c:617 +#: panels/printers/pp-jobs-dialog.c:620 #, c-format msgctxt "Printer jobs dialog title" msgid "%s — Active Jobs" msgstr "%s — aktivnih zadataka" #. Translators: The printer needs authentication info to print. -#: panels/printers/pp-jobs-dialog.c:622 +#: panels/printers/pp-jobs-dialog.c:625 #, c-format msgid "Enter credentials to print from %s." msgstr "Upišite korisničko ime i lozinku za ispis sa %s." @@ -4859,25 +4888,25 @@ msgstr "" "Nažalost! Usluga ispisa\n" "sustava nije dostupna." -#: panels/privacy/cc-privacy-panel.c:387 panels/privacy/privacy.ui:280 +#: panels/privacy/cc-privacy-panel.c:388 panels/privacy/privacy.ui:280 msgid "Screen Lock" msgstr "Zaključavanje zaslona" -#: panels/privacy/cc-privacy-panel.c:438 +#: panels/privacy/cc-privacy-panel.c:439 msgid "In use" msgstr "Koristi se" -#: panels/privacy/cc-privacy-panel.c:443 +#: panels/privacy/cc-privacy-panel.c:444 msgctxt "Location services status" msgid "On" msgstr "Uključeno" -#: panels/privacy/cc-privacy-panel.c:444 +#: panels/privacy/cc-privacy-panel.c:445 msgctxt "Location services status" msgid "Off" msgstr "Isključeno" -#: panels/privacy/cc-privacy-panel.c:823 panels/privacy/privacy.ui:745 +#: panels/privacy/cc-privacy-panel.c:825 panels/privacy/privacy.ui:745 msgid "Location Services" msgstr "Usluge lokacije" @@ -4946,12 +4975,13 @@ msgstr "" "vidjeti" #. FIXME -#: panels/privacy/gnome-privacy-panel.desktop.in.in:7 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/privacy/gnome-privacy-panel.desktop.in.in:8 msgid "preferences-system-privacy" msgstr "osobitosti-privatnosti-sustava" -#. Translators: those are keywords for the privacy control-center panel -#: panels/privacy/gnome-privacy-panel.desktop.in.in:19 +#. Translators: Search terms to find the Privacy panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/privacy/gnome-privacy-panel.desktop.in.in:20 msgid "" "screen;lock;diagnostics;crash;private;recent;temporary;tmp;index;name;" "network;identity;" @@ -5137,11 +5167,11 @@ msgctxt "Input Source" msgid "Other" msgstr "Ostalo" -#: panels/region/cc-region-panel.c:881 +#: panels/region/cc-region-panel.c:882 msgid "No input source selected" msgstr "Nema odabranih načina unosa" -#: panels/region/cc-region-panel.c:1773 +#: panels/region/cc-region-panel.c:1774 msgid "Login _Screen" msgstr "Zaslon _prijave" @@ -5187,12 +5217,13 @@ msgid "" msgstr "" "Odaberite vaš jezik prikaza, formate, rasporede tipkovnice i ulazne izvore" -#: panels/region/gnome-region-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/region/gnome-region-panel.desktop.in.in:7 msgid "preferences-desktop-locale" msgstr "osobitosti-lokalizacije-radne površine" -#. Translators: those are keywords for the region control-center panel -#: panels/region/gnome-region-panel.desktop.in.in:18 +#. Translators: Search terms to find the Region and Language panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/region/gnome-region-panel.desktop.in.in:19 msgid "Language;Layout;Keyboard;Input;" msgstr "Jezik;Raspored;Tipkovnica;ulaz;" @@ -5324,12 +5355,13 @@ msgstr "" "Upravljajte koje će aplikacije prikazati rezultate pretrage u pregledu " "aktivnosti" -#: panels/search/gnome-search-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/search/gnome-search-panel.desktop.in.in:7 msgid "preferences-system-search" msgstr "osobitosti-pretrage-sustava" -#. Translators: those are keywords for the search control-center panel -#: panels/search/gnome-search-panel.desktop.in.in:18 +#. Translators: Search terms to find the Search panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/search/gnome-search-panel.desktop.in.in:19 msgid "Search;Find;Index;Hide;Privacy;Results;" msgstr "Pretraga;Pretraži;Sadržaj;Sakrij;Privatnost;Rezultati;" @@ -5432,12 +5464,13 @@ msgstr "Dijeljenje" msgid "Control what you want to share with others" msgstr "Postavite što želite dijeliti s ostalim korisnicima" -#: panels/sharing/gnome-sharing-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/sharing/gnome-sharing-panel.desktop.in.in:7 msgid "preferences-system-sharing" msgstr "osobitosti-dijeljenja-sustava" -#. Translators: those are keywords for the sharing control-center panel -#: panels/sharing/gnome-sharing-panel.desktop.in.in:15 +#. Translators: Search terms to find the Sharing panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/sharing/gnome-sharing-panel.desktop.in.in:16 msgid "" "share;sharing;ssh;host;name;remote;desktop;media;audio;video;pictures;photos;" "movies;server;renderer;" @@ -5541,12 +5574,13 @@ msgstr "Zvuk" msgid "Change sound levels, inputs, outputs, and alert sounds" msgstr "Promijenite glasnoću zvuka, ulaze, izlaze i zvukove upozorenja" -#: panels/sound/data/gnome-sound-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/sound/data/gnome-sound-panel.desktop.in.in:7 msgid "multimedia-volume-control" msgstr "upravljanje-glasnoćom zvuka-multimedije" -#. Translators: those are keywords for the sound control-center panel -#: panels/sound/data/gnome-sound-panel.desktop.in.in:19 +#. Translators: Search terms to find the Sound panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/sound/data/gnome-sound-panel.desktop.in.in:20 msgid "Card;Microphone;Volume;Fade;Balance;Bluetooth;Headset;Audio;" msgstr "" "Kartica;Mikrofon;Glasnoća zvuka;Isčezni;Uravnoteženje;Bluetooth;Slušalice s " @@ -5739,34 +5773,200 @@ msgstr "Dubokotonac" msgid "Custom" msgstr "Prilagođeno" +#: panels/thunderbolt/cc-bolt-device-dialog.c:86 +#: panels/thunderbolt/cc-bolt-device-entry.c:119 +msgctxt "Thunderbolt Device Status" +msgid "Disconnected" +msgstr "Odspojeno" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:89 +#: panels/thunderbolt/cc-bolt-device-entry.c:122 +msgctxt "Thunderbolt Device Status" +msgid "Connecting" +msgstr "Povezivanje" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:92 +#: panels/thunderbolt/cc-bolt-device-entry.c:126 +#: panels/thunderbolt/cc-bolt-device-entry.c:138 +msgctxt "Thunderbolt Device Status" +msgid "Connected" +msgstr "Povezano" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:95 +msgctxt "Thunderbolt Device Status" +msgid "Authorization Error" +msgstr "Greška ovjere" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:98 +#: panels/thunderbolt/cc-bolt-device-entry.c:132 +msgctxt "Thunderbolt Device Status" +msgid "Authorizing" +msgstr "Odobravanje" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:105 +msgctxt "Thunderbolt Device Status" +msgid "Reduced Functionality" +msgstr "Smanjena funkcionalnost" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:107 +msgctxt "Thunderbolt Device Status" +msgid "Connected & Authorized" +msgstr "Povezano i odobreno" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:113 +#: panels/thunderbolt/cc-bolt-device-entry.c:146 +msgctxt "Thunderbolt Device Status" +msgid "Unknown" +msgstr "Nepoznato" + +#. Translators: The time point the device was authorized. +#: panels/thunderbolt/cc-bolt-device-dialog.c:169 +msgid "Authorized at:" +msgstr "Odobreno na:" + +#. Translators: The time point the device was connected. +#: panels/thunderbolt/cc-bolt-device-dialog.c:175 +msgid "Connected at:" +msgstr "Povezano na:" + +#. Translators: The time point the device was enrolled, +#. * i.e. authorized and stored in the device database. +#: panels/thunderbolt/cc-bolt-device-dialog.c:182 +msgid "Enrolled at:" +msgstr "Upisano:" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:250 +msgid "Failed to authorize device: " +msgstr "Neuspjelo odobravanje uređaja: " + +#: panels/thunderbolt/cc-bolt-device-dialog.c:327 +msgid "Failed to forget device: " +msgstr "Neuspjelo zaboravljanje uređaja: " + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:109 +msgid "Name:" +msgstr "Naziv:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:141 +msgid "Status:" +msgstr "Stanje:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:174 +msgid "UUID:" +msgstr "UUID:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:280 +msgid "Authorize and Connect" +msgstr "Odobri i poveži" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:303 +msgid "Forget Device" +msgstr "Zaboravi uređaj" + +#: panels/thunderbolt/cc-bolt-device-entry.c:129 +msgctxt "Thunderbolt Device Status" +msgid "Error" +msgstr "Greška" + +#: panels/thunderbolt/cc-bolt-device-entry.c:140 +msgctxt "Thunderbolt Device Status" +msgid "Authorized" +msgstr "Odobreno" + +#: panels/thunderbolt/cc-bolt-panel.c:188 +msgid "" +"The Thunderbolt subsystem (boltd) is not installed or not set up properly." +msgstr "Thunderbolt podsustav (boltd) nije instaliran ili podešen ispravno." + +#: panels/thunderbolt/cc-bolt-panel.c:459 +msgid "" +"Thunderbolt could not be detected.\n" +"Either the system lacks Thunderbolt support, it has been disabled in the " +"BIOS or is set to an unsupported security level in the BIOS." +msgstr "" +"Thunderbolt se ne može otkriti.\n" +"Ili sustav nema podršku za Thunderbolt, jer je onemogućena u BIOSU ili je " +"postavljena nepodržana razina sigurnosti u BIOSU." + +#: panels/thunderbolt/cc-bolt-panel.c:502 +msgid "Thunderbolt support has been disabled in the BIOS." +msgstr "Thunderbolt podrška je onemogućena u BIOSU." + +#: panels/thunderbolt/cc-bolt-panel.c:611 +#, c-format +msgid "Error switching direct mode: %s" +msgstr "Greška prebacivanja izravnog načina :%s" + +#: panels/thunderbolt/cc-bolt-panel.ui:143 +msgid "No Thunderbolt support" +msgstr "Nema Thunderbolt podrške" + +#: panels/thunderbolt/cc-bolt-panel.ui:246 +msgid "Direct Access" +msgstr "Izravan pristup" + +#: panels/thunderbolt/cc-bolt-panel.ui:269 +msgid "Allow direct access to devices such as docks and external GPUs." +msgstr "Dopusti izravan pristup uređajima poput dokova i vanjskih GPU-ova." + +#: panels/thunderbolt/cc-bolt-panel.ui:289 +msgid "Only USB and Display Port devices can attach." +msgstr "Samo USB i Display Port uređaji se mogu spojiti." + +#: panels/thunderbolt/cc-bolt-panel.ui:397 +msgid "Pending Devices" +msgstr "Uređaji na čekanju" + +#: panels/thunderbolt/cc-bolt-panel.ui:535 +msgid "No devices attached" +msgstr "Nema spojenih uređaja" + +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:3 +msgid "Thunderbolt" +msgstr "Thunderbolt" + +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:4 +msgid "Manage Thunderbolt devices" +msgstr "Upravljaj Thunderbolt uređajima" + +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:7 +msgid "thunderbolt" +msgstr "thunderbolt" + +#. Translators: those are keywords for the thunderbolt control-center panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:19 +msgid "Thunderbolt;" +msgstr "Thunderbolt;" + #. translators: the labels will read: #. * Cursor Size: Default -#: panels/universal-access/cc-ua-panel.c:353 +#: panels/universal-access/cc-ua-panel.c:354 msgctxt "cursor size" msgid "Default" msgstr "Uobičajena" -#: panels/universal-access/cc-ua-panel.c:356 +#: panels/universal-access/cc-ua-panel.c:357 msgctxt "cursor size" msgid "Medium" msgstr "Srednja" -#: panels/universal-access/cc-ua-panel.c:359 +#: panels/universal-access/cc-ua-panel.c:360 msgctxt "cursor size" msgid "Large" msgstr "Velika" -#: panels/universal-access/cc-ua-panel.c:362 +#: panels/universal-access/cc-ua-panel.c:363 msgctxt "cursor size" msgid "Larger" msgstr "Veća" -#: panels/universal-access/cc-ua-panel.c:365 +#: panels/universal-access/cc-ua-panel.c:366 msgctxt "cursor size" msgid "Largest" msgstr "Najveća" -#: panels/universal-access/cc-ua-panel.c:369 +#: panels/universal-access/cc-ua-panel.c:370 #, c-format msgid "%d pixel" msgid_plural "%d pixels" @@ -5778,12 +5978,13 @@ msgstr[2] "%d piksela" msgid "Make it easier to see, hear, type, point and click" msgstr "Make it easier to see, hear, type, point and click" -#: panels/universal-access/gnome-universal-access-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/universal-access/gnome-universal-access-panel.desktop.in.in:7 msgid "preferences-desktop-accessibility" msgstr "osobitosti-pristupačnosti-radne površine" -#. Translators: those are keywords for the universal access control-center panel -#: panels/universal-access/gnome-universal-access-panel.desktop.in.in:18 +#. Translators: Search terms to find the Universal Access panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/universal-access/gnome-universal-access-panel.desktop.in.in:19 msgid "" "Keyboard;Mouse;a11y;Accessibility;Contrast;Zoom;Screen;Reader;text;font;size;" "AccessX;Sticky;Keys;Slow;Bounce;Mouse;Double;click;Delay;Assist;Repeat;Blink;" @@ -5813,7 +6014,7 @@ msgid "C_ursor Size" msgstr "V_eličina pokazivača" #: panels/universal-access/uap.ui:316 -#: panels/universal-access/zoom-options.ui:98 +#: panels/universal-access/zoom-options.ui:99 msgid "_Zoom" msgstr "_Uvećanje" @@ -6107,27 +6308,27 @@ msgctxt "dwell click threshold" msgid "Large" msgstr "Velika" -#: panels/universal-access/zoom-options.c:333 +#: panels/universal-access/zoom-options.c:338 msgctxt "Distance" msgid "Short" msgstr "Kratko" -#: panels/universal-access/zoom-options.c:334 +#: panels/universal-access/zoom-options.c:339 msgctxt "Distance" msgid "¼ Screen" msgstr "¼ zaslona" -#: panels/universal-access/zoom-options.c:335 +#: panels/universal-access/zoom-options.c:340 msgctxt "Distance" msgid "½ Screen" msgstr "½ zaslona" -#: panels/universal-access/zoom-options.c:336 +#: panels/universal-access/zoom-options.c:341 msgctxt "Distance" msgid "¾ Screen" msgstr "¾ zaslona" -#: panels/universal-access/zoom-options.c:337 +#: panels/universal-access/zoom-options.c:342 msgctxt "Distance" msgid "Long" msgstr "Dugo" @@ -6152,134 +6353,134 @@ msgstr "Lijeva polovina" msgid "Right Half" msgstr "Desna polovina" -#: panels/universal-access/zoom-options.ui:77 +#: panels/universal-access/zoom-options.ui:78 msgid "Zoom Options" msgstr "Mogućnosti približenja/udaljenja" -#: panels/universal-access/zoom-options.ui:186 +#: panels/universal-access/zoom-options.ui:188 msgid "_Magnification:" msgstr "_Uvećavanje:" -#: panels/universal-access/zoom-options.ui:250 +#: panels/universal-access/zoom-options.ui:252 msgid "_Follow mouse cursor" msgstr "_Prati pokazivač miša" -#: panels/universal-access/zoom-options.ui:270 +#: panels/universal-access/zoom-options.ui:272 msgid "_Screen part:" msgstr "_Dio zaslona:" -#: panels/universal-access/zoom-options.ui:332 +#: panels/universal-access/zoom-options.ui:334 msgid "Magnifier _extends outside of screen" msgstr "_Povećalo se proteže van zaslona" -#: panels/universal-access/zoom-options.ui:351 +#: panels/universal-access/zoom-options.ui:353 msgid "_Keep magnifier cursor centered" msgstr "_Drži pokazivač povećala u središtu" -#: panels/universal-access/zoom-options.ui:370 +#: panels/universal-access/zoom-options.ui:372 msgid "Magnifier cursor _pushes contents around" msgstr "Pokazivač povećala _gura sadržaj okolo" -#: panels/universal-access/zoom-options.ui:389 +#: panels/universal-access/zoom-options.ui:391 msgid "Magnifier cursor moves with _contents" msgstr "Pokazivač povećala se pomiče sa _sadržajem" -#: panels/universal-access/zoom-options.ui:423 +#: panels/universal-access/zoom-options.ui:425 msgid "Magnifier Position:" msgstr "Položaj povećala:" -#: panels/universal-access/zoom-options.ui:444 +#: panels/universal-access/zoom-options.ui:446 msgid "Magnifier" msgstr "Povećalo" -#: panels/universal-access/zoom-options.ui:490 +#: panels/universal-access/zoom-options.ui:493 msgid "_Thickness:" msgstr "_Debljina:" -#: panels/universal-access/zoom-options.ui:516 +#: panels/universal-access/zoom-options.ui:519 msgctxt "universal access, thickness" msgid "Thin" msgstr "Tanko" -#: panels/universal-access/zoom-options.ui:548 +#: panels/universal-access/zoom-options.ui:551 msgctxt "universal access, thickness" msgid "Thick" msgstr "Debelo" -#: panels/universal-access/zoom-options.ui:574 +#: panels/universal-access/zoom-options.ui:577 msgid "_Length:" msgstr "_Duljina:" #. The color of the accessibility crosshair -#: panels/universal-access/zoom-options.ui:626 +#: panels/universal-access/zoom-options.ui:629 msgid "Co_lor:" msgstr "Bo_ja:" -#: panels/universal-access/zoom-options.ui:690 +#: panels/universal-access/zoom-options.ui:693 msgid "_Crosshairs:" msgstr "_Nišan:" -#: panels/universal-access/zoom-options.ui:741 +#: panels/universal-access/zoom-options.ui:744 msgid "_Overlaps mouse cursor" msgstr "_Preklapa pokazivač miša" -#: panels/universal-access/zoom-options.ui:779 +#: panels/universal-access/zoom-options.ui:782 msgid "Crosshairs" msgstr "Nišan" -#: panels/universal-access/zoom-options.ui:827 +#: panels/universal-access/zoom-options.ui:831 msgid "_White on black:" msgstr "_Bijelo na crno:" -#: panels/universal-access/zoom-options.ui:850 +#: panels/universal-access/zoom-options.ui:854 msgid "_Brightness:" msgstr "_Svjetlina:" -#: panels/universal-access/zoom-options.ui:874 +#: panels/universal-access/zoom-options.ui:878 msgid "_Contrast:" msgstr "_Kontrast:" #. The contrast scale goes from Color to None (grayscale) -#: panels/universal-access/zoom-options.ui:897 +#: panels/universal-access/zoom-options.ui:901 msgctxt "universal access, contrast" msgid "Co_lor" msgstr "Bo_ja" -#: panels/universal-access/zoom-options.ui:925 +#: panels/universal-access/zoom-options.ui:929 msgctxt "universal access, color" msgid "None" msgstr "Nepoznata" -#: panels/universal-access/zoom-options.ui:957 +#: panels/universal-access/zoom-options.ui:961 msgctxt "universal access, color" msgid "Full" msgstr "Potpuna" -#: panels/universal-access/zoom-options.ui:1023 +#: panels/universal-access/zoom-options.ui:1027 msgctxt "universal access, brightness" msgid "Low" msgstr "Niska" -#: panels/universal-access/zoom-options.ui:1056 +#: panels/universal-access/zoom-options.ui:1060 msgctxt "universal access, brightness" msgid "High" msgstr "Visoka" -#: panels/universal-access/zoom-options.ui:1087 +#: panels/universal-access/zoom-options.ui:1091 msgctxt "universal access, contrast" msgid "Low" msgstr "Niska" -#: panels/universal-access/zoom-options.ui:1120 +#: panels/universal-access/zoom-options.ui:1124 msgctxt "universal access, contrast" msgid "High" msgstr "Visoka" -#: panels/universal-access/zoom-options.ui:1156 +#: panels/universal-access/zoom-options.ui:1160 msgid "Color Effects:" msgstr "Efekti boje:" -#: panels/universal-access/zoom-options.ui:1181 +#: panels/universal-access/zoom-options.ui:1185 msgid "Color Effects" msgstr "Efekti boje" @@ -6420,12 +6621,13 @@ msgstr "Korisnici" msgid "Add or remove users and change your password" msgstr "Dodajte ili uklonite korisnike i promijenite svoju lozinku" -#: panels/user-accounts/data/gnome-user-accounts-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/user-accounts/data/gnome-user-accounts-panel.desktop.in.in:7 msgid "system-users" msgstr "korisnici-sustava" -#. Translators: those are keywords for the user accounts control-center panel -#: panels/user-accounts/data/gnome-user-accounts-panel.desktop.in.in:19 +#. Translators: Search terms to find the Users panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/user-accounts/data/gnome-user-accounts-panel.desktop.in.in:20 msgid "Login;Name;Fingerprint;Avatar;Logo;Face;Password;" msgstr "Prijava;Ime;Otisak prsta;Avatar;Logo;Lice;Lozinka;" @@ -6868,7 +7070,7 @@ msgstr "%s — %s" #. Translators: This is a time format string in the style of "22:58". #. It indicates a login time which follows a date. #: panels/user-accounts/um-history-dialog.c:177 -#: panels/user-accounts/um-user-panel.c:767 +#: panels/user-accounts/um-user-panel.c:766 msgctxt "login date-time" msgid "%k:%M" msgstr "%k:%M" @@ -6876,7 +7078,7 @@ msgstr "%k:%M" #. Translators: This indicates a login date-time. #. The first %s is a date, and the second %s a time. #: panels/user-accounts/um-history-dialog.c:180 -#: panels/user-accounts/um-user-panel.c:771 +#: panels/user-accounts/um-user-panel.c:770 #, c-format msgctxt "login date-time" msgid "%s, %s" @@ -6913,7 +7115,7 @@ msgstr "Lozinka ne može biti promijenjena" msgid "The passwords do not match." msgstr "Lozinka se ne podudara." -#: panels/user-accounts/um-photo-dialog.c:226 +#: panels/user-accounts/um-photo-dialog.c:227 msgid "Browse for more pictures" msgstr "Potraži još slika" @@ -6941,30 +7143,30 @@ msgstr "Neispravna lozinka, pokušajte ponovno" msgid "Couldn’t connect to the %s domain: %s" msgstr "Nemoguće povezivanje s %s domenom: %s" -#: panels/user-accounts/um-user-panel.c:201 +#: panels/user-accounts/um-user-panel.c:200 msgid "Your account" msgstr "Vaš račun" -#: panels/user-accounts/um-user-panel.c:381 +#: panels/user-accounts/um-user-panel.c:380 msgid "Failed to delete user" msgstr "Neuspjelo brisanje korisnika" -#: panels/user-accounts/um-user-panel.c:439 -#: panels/user-accounts/um-user-panel.c:498 -#: panels/user-accounts/um-user-panel.c:550 +#: panels/user-accounts/um-user-panel.c:438 +#: panels/user-accounts/um-user-panel.c:497 +#: panels/user-accounts/um-user-panel.c:549 msgid "Failed to revoke remotely managed user" msgstr "Nemoguće je opozvati udaljeno upravljanog korisnika" -#: panels/user-accounts/um-user-panel.c:604 +#: panels/user-accounts/um-user-panel.c:603 msgid "You cannot delete your own account." msgstr "Ne možete obrisati vlastiti račun." -#: panels/user-accounts/um-user-panel.c:613 +#: panels/user-accounts/um-user-panel.c:612 #, c-format msgid "%s is still logged in" msgstr "%s je još prijavljen" -#: panels/user-accounts/um-user-panel.c:617 +#: panels/user-accounts/um-user-panel.c:616 msgid "" "Deleting a user while they are logged in can leave the system in an " "inconsistent state." @@ -6972,12 +7174,12 @@ msgstr "" "Brisanje korisnika dok su prijavljeni može ostaviti sustav u neupotrebljivom " "stanju." -#: panels/user-accounts/um-user-panel.c:626 +#: panels/user-accounts/um-user-panel.c:625 #, c-format msgid "Do you want to keep %s’s files?" msgstr "Želite li zadržati %s's datoteke?" -#: panels/user-accounts/um-user-panel.c:630 +#: panels/user-accounts/um-user-panel.c:629 msgid "" "It is possible to keep the home directory, mail spool and temporary files " "around when deleting a user account." @@ -6985,47 +7187,47 @@ msgstr "" "Moguće je očuvati osobnu mapu, e-poštu i privremene datoteke kada se briše " "korisnički račun." -#: panels/user-accounts/um-user-panel.c:633 +#: panels/user-accounts/um-user-panel.c:632 msgid "_Delete Files" msgstr "_Obriši datoteke" -#: panels/user-accounts/um-user-panel.c:634 +#: panels/user-accounts/um-user-panel.c:633 msgid "_Keep Files" msgstr "_Zadrži datoteke" -#: panels/user-accounts/um-user-panel.c:648 +#: panels/user-accounts/um-user-panel.c:647 #, c-format msgid "Are you sure you want to revoke remotely managed %s’s account?" msgstr "Sigurno želite opozvati udaljeno upravljani %s's račun?" -#: panels/user-accounts/um-user-panel.c:652 +#: panels/user-accounts/um-user-panel.c:651 msgid "_Delete" msgstr "_Obriši" -#: panels/user-accounts/um-user-panel.c:702 +#: panels/user-accounts/um-user-panel.c:701 msgctxt "Password mode" msgid "Account disabled" msgstr "Račun onemogućen" -#: panels/user-accounts/um-user-panel.c:710 +#: panels/user-accounts/um-user-panel.c:709 msgctxt "Password mode" msgid "To be set at next login" msgstr "Biti će postavljen kod sljedeće prijave" -#: panels/user-accounts/um-user-panel.c:713 +#: panels/user-accounts/um-user-panel.c:712 msgctxt "Password mode" msgid "None" msgstr "Nepoznata" -#: panels/user-accounts/um-user-panel.c:760 +#: panels/user-accounts/um-user-panel.c:759 msgid "Logged in" msgstr "Prijavljeni" -#: panels/user-accounts/um-user-panel.c:1107 +#: panels/user-accounts/um-user-panel.c:1106 msgid "Failed to contact the accounts service" msgstr "Neuspjelo kontaktiranje usluge računa" -#: panels/user-accounts/um-user-panel.c:1109 +#: panels/user-accounts/um-user-panel.c:1108 msgid "Please make sure that the AccountService is installed and enabled." msgstr "Pobrinite se da je AccountService instaliran i omogućen." @@ -7033,7 +7235,7 @@ msgstr "Pobrinite se da je AccountService instaliran i omogućen." #. * We split the line in 2 here to "make it look good", as there's #. * no good way to do this in GTK+ for tooltips. See: #. * https://bugzilla.gnome.org/show_bug.cgi?id=657168 -#: panels/user-accounts/um-user-panel.c:1141 +#: panels/user-accounts/um-user-panel.c:1140 msgid "" "To make changes,\n" "click the * icon first" @@ -7041,12 +7243,12 @@ msgstr "" "Kako bi napravili promjene\n" "prvo kliknite * ikonu" -#: panels/user-accounts/um-user-panel.c:1181 +#: panels/user-accounts/um-user-panel.c:1180 msgid "Create a user account" msgstr "Napravite korisnički račun" -#: panels/user-accounts/um-user-panel.c:1192 -#: panels/user-accounts/um-user-panel.c:1371 +#: panels/user-accounts/um-user-panel.c:1191 +#: panels/user-accounts/um-user-panel.c:1370 msgid "" "To create a user account,\n" "click the * icon first" @@ -7054,12 +7256,12 @@ msgstr "" "Kako biste napravili korisnički račun,\n" "najprije kliknite na ikonu *" -#: panels/user-accounts/um-user-panel.c:1202 +#: panels/user-accounts/um-user-panel.c:1201 msgid "Delete the selected user account" msgstr "Obrišite odabrani korisnički račun" -#: panels/user-accounts/um-user-panel.c:1214 -#: panels/user-accounts/um-user-panel.c:1376 +#: panels/user-accounts/um-user-panel.c:1213 +#: panels/user-accounts/um-user-panel.c:1375 msgid "" "To delete the selected user account,\n" "click the * icon first" @@ -7193,12 +7395,13 @@ msgid "Set button mappings and adjust stylus sensitivity for graphics tablets" msgstr "" "Postavi tipke mapiranja i prilagodi osjetljivost pisaljke grafičkih tableta" -#: panels/wacom/gnome-wacom-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/wacom/gnome-wacom-panel.desktop.in.in:7 msgid "input-tablet" msgstr "način unosa-tableta" -#. Translators: those are keywords for the wacom tablet control-center panel -#: panels/wacom/gnome-wacom-panel.desktop.in.in:18 +#. Translators: Search terms to find the Wacom Tablet panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/wacom/gnome-wacom-panel.desktop.in.in:19 msgid "Tablet;Wacom;Stylus;Eraser;Mouse;" msgstr "Tablet;Wacom;Pisaljka;Gumica;Miš;" @@ -7334,35 +7537,35 @@ msgstr "" "Središte upravljanja je GNOME glavno sučelje za podešavanje vaše radne " "površine." -#: shell/cc-application.c:47 +#: shell/cc-application.c:60 msgid "Display version number" msgstr "Prikaži broj inačice" -#: shell/cc-application.c:48 +#: shell/cc-application.c:61 msgid "Enable verbose mode" msgstr "Omogući opširni opisni način rada" -#: shell/cc-application.c:49 +#: shell/cc-application.c:62 msgid "Show the overview" msgstr "Prikaži pregled" -#: shell/cc-application.c:50 +#: shell/cc-application.c:63 msgid "Search for the string" msgstr "Pretraživanje niza" -#: shell/cc-application.c:51 +#: shell/cc-application.c:64 msgid "List possible panel names and exit" msgstr "Prikaži moguće nazive panela i izađi" -#: shell/cc-application.c:52 +#: shell/cc-application.c:65 msgid "Panel to display" msgstr "Panel za prikaz" -#: shell/cc-application.c:52 +#: shell/cc-application.c:65 msgid "[PANEL] [ARGUMENT…]" msgstr "[PANEL] [ARGUMENT…]" -#: shell/cc-application.c:117 +#: shell/cc-application.c:136 msgid "Available panels:" msgstr "Dostupni paneli:" @@ -7374,11 +7577,13 @@ msgstr "Pomoć" msgid "Quit" msgstr "Zatvori" -#: shell/gnome-control-center.desktop.in.in:4 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: shell/gnome-control-center.desktop.in.in:5 msgid "gnome-control-center" msgstr "gnome-središte-upravljanja" -#: shell/gnome-control-center.desktop.in.in:15 +#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: shell/gnome-control-center.desktop.in.in:17 msgid "Preferences;Settings;" msgstr "Osobitosti;Postavke;" @@ -7634,12 +7839,6 @@ msgstr "Zvukovi sustava" #~ msgid "_Method" #~ msgstr "_Način" -#~ msgid "Add Device" -#~ msgstr "Dodaj uređaj" - -#~ msgid "Remove Device" -#~ msgstr "Ukloni uređaj" - #~ msgid "VPN Type" #~ msgstr "VPN vrsta" -- cgit v1.2.1 From 897e91ee6d908bc00ea7a62f400630156a8dff7e Mon Sep 17 00:00:00 2001 From: gogo Date: Mon, 16 Apr 2018 12:27:44 +0000 Subject: Update Croatian translation --- po/hr.po | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/po/hr.po b/po/hr.po index c7cfcf500..d1706aaba 100644 --- a/po/hr.po +++ b/po/hr.po @@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: gnome-control-center 2.0\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-control-center/" "issues\n" -"POT-Creation-Date: 2018-04-13 16:58+0000\n" -"PO-Revision-Date: 2018-04-16 14:24+0200\n" +"POT-Creation-Date: 2018-04-16 12:25+0000\n" +"PO-Revision-Date: 2018-04-16 14:27+0200\n" "Last-Translator: gogo \n" "Language-Team: Croatian \n" "Language: hr\n" @@ -1189,11 +1189,11 @@ msgstr "Primijeni promjene?" #: panels/display/cc-display-panel.c:2647 msgid "Changes Cannot be Applied" -msgstr "" +msgstr "Promjene se ne mogu primijeniti" #: panels/display/cc-display-panel.c:2648 msgid "This could be due to hardware limitations." -msgstr "" +msgstr "To može biti uzrokovano ograničenjem hardvera." #: panels/display/cc-display-panel.c:3003 #, c-format @@ -5873,12 +5873,12 @@ msgctxt "Thunderbolt Device Status" msgid "Authorized" msgstr "Odobreno" -#: panels/thunderbolt/cc-bolt-panel.c:188 +#: panels/thunderbolt/cc-bolt-panel.c:175 msgid "" "The Thunderbolt subsystem (boltd) is not installed or not set up properly." msgstr "Thunderbolt podsustav (boltd) nije instaliran ili podešen ispravno." -#: panels/thunderbolt/cc-bolt-panel.c:459 +#: panels/thunderbolt/cc-bolt-panel.c:460 msgid "" "Thunderbolt could not be detected.\n" "Either the system lacks Thunderbolt support, it has been disabled in the " @@ -5888,11 +5888,11 @@ msgstr "" "Ili sustav nema podršku za Thunderbolt, jer je onemogućena u BIOSU ili je " "postavljena nepodržana razina sigurnosti u BIOSU." -#: panels/thunderbolt/cc-bolt-panel.c:502 +#: panels/thunderbolt/cc-bolt-panel.c:504 msgid "Thunderbolt support has been disabled in the BIOS." msgstr "Thunderbolt podrška je onemogućena u BIOSU." -#: panels/thunderbolt/cc-bolt-panel.c:611 +#: panels/thunderbolt/cc-bolt-panel.c:613 #, c-format msgid "Error switching direct mode: %s" msgstr "Greška prebacivanja izravnog načina :%s" -- cgit v1.2.1 From 37a6b940cb83d97b808da77f397e34100beb263f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1igo=20Mart=C3=ADnez?= Date: Sat, 14 Apr 2018 23:06:40 +0200 Subject: build: Fix `USER_DIR_MODE` value in config.h meson defines `USER_DIR_MODE` with a raw octal value to be used as the default permissions when creating the user's configuration directory. However, meson does not support raw octal values[0], so the define misses the initial `0` value. Due to this, the directory is created with wrong permissions. This has been changed to use the octal value as a string in meson, so the definition has the proper value. Fixes #49 [0] https://github.com/mesonbuild/meson/issues/2047 --- meson.build | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index fb74d04d1..ae1a897b3 100644 --- a/meson.build +++ b/meson.build @@ -44,7 +44,9 @@ foreach define: set_defines config_h.set_quoted(define[0], define[1]) endforeach -config_h.set('USER_DIR_MODE', 0700, +# meson does not support octal values, so it must be handled as a +# string. See: https://github.com/mesonbuild/meson/issues/2047 +config_h.set('USER_DIR_MODE', '0700', description: 'Permissions for creating the user\'s config, cache and data directories') # compiler flags -- cgit v1.2.1 From e1593b3c02919b3409b9aa8d2abb1da772e58278 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Sat, 31 Mar 2018 17:06:43 +0200 Subject: shell: Remove CcEditableEntry, it is not used anywhere --- panels/printers/pp-details-dialog.c | 1 - shell/cc-editable-entry.c | 644 ------------------------------------ shell/cc-editable-entry.h | 83 ----- shell/meson.build | 1 - 4 files changed, 729 deletions(-) delete mode 100644 shell/cc-editable-entry.c delete mode 100644 shell/cc-editable-entry.h diff --git a/panels/printers/pp-details-dialog.c b/panels/printers/pp-details-dialog.c index 5db3798ad..d5a56f168 100644 --- a/panels/printers/pp-details-dialog.c +++ b/panels/printers/pp-details-dialog.c @@ -33,7 +33,6 @@ #include #include -#include "cc-editable-entry.h" #include "pp-details-dialog.h" #include "pp-ppd-selection-dialog.h" #include "pp-printer.h" diff --git a/shell/cc-editable-entry.c b/shell/cc-editable-entry.c deleted file mode 100644 index 8c81fc112..000000000 --- a/shell/cc-editable-entry.c +++ /dev/null @@ -1,644 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright 2009-2010 Red Hat, Inc, - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - * Written by: Matthias Clasen - */ - -#include -#include "cc-editable-entry.h" - -#define EMPTY_TEXT "\xe2\x80\x94" - -struct _CcEditableEntryPrivate { - GtkStack *stack; - GtkLabel *label; - GtkButton *button; - GtkEntry *entry; - - gchar *text; - gboolean editable; - gboolean selectable; - gint weight; - gboolean weight_set; - gdouble scale; - gboolean scale_set; - gint width_chars; - gint max_width_chars; - PangoEllipsizeMode ellipsize; - - gboolean in_stop_editing; -}; - -#define CC_EDITABLE_ENTRY_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CC_TYPE_EDITABLE_ENTRY, CcEditableEntryPrivate)) - -enum { - PROP_0, - PROP_TEXT, - PROP_EDITABLE, - PROP_SELECTABLE, - PROP_SCALE, - PROP_SCALE_SET, - PROP_WEIGHT, - PROP_WEIGHT_SET, - PROP_WIDTH_CHARS, - PROP_MAX_WIDTH_CHARS, - PROP_ELLIPSIZE -}; - -enum { - EDITING_DONE, - LAST_SIGNAL -}; - -#define PAGE_LABEL "_label" -#define PAGE_BUTTON "_button" -#define PAGE_ENTRY "_entry" - -static guint signals [LAST_SIGNAL] = { 0, }; - -G_DEFINE_TYPE (CcEditableEntry, cc_editable_entry, GTK_TYPE_BIN); - -void -cc_editable_entry_set_text (CcEditableEntry *e, - const gchar *text) -{ - CcEditableEntryPrivate *priv; - gchar *tmp; - GtkWidget *label; - - priv = e->priv; - - tmp = g_strdup (text); - g_free (priv->text); - priv->text = tmp; - - gtk_entry_set_text (priv->entry, tmp); - - if (tmp == NULL || tmp[0] == '\0') - tmp = EMPTY_TEXT; - - gtk_label_set_text (priv->label, tmp); - label = gtk_bin_get_child (GTK_BIN (priv->button)); - gtk_label_set_text (GTK_LABEL (label), tmp); - - g_object_notify (G_OBJECT (e), "text"); -} - -const gchar * -cc_editable_entry_get_text (CcEditableEntry *e) -{ - return e->priv->text; -} - -void -cc_editable_entry_set_editable (CcEditableEntry *e, - gboolean editable) -{ - CcEditableEntryPrivate *priv; - - priv = e->priv; - - if (priv->editable != editable) { - priv->editable = editable; - - gtk_stack_set_visible_child_name (e->priv->stack, editable ? PAGE_BUTTON : PAGE_LABEL); - - g_object_notify (G_OBJECT (e), "editable"); - } -} - -gboolean -cc_editable_entry_get_editable (CcEditableEntry *e) -{ - return e->priv->editable; -} - -void -cc_editable_entry_set_selectable (CcEditableEntry *e, - gboolean selectable) -{ - CcEditableEntryPrivate *priv; - - priv = e->priv; - - if (priv->selectable != selectable) { - priv->selectable = selectable; - - gtk_label_set_selectable (priv->label, selectable); - - g_object_notify (G_OBJECT (e), "selectable"); - } -} - -gboolean -cc_editable_entry_get_selectable (CcEditableEntry *e) -{ - return e->priv->selectable; -} - - -static void -update_fonts (CcEditableEntry *e) -{ - PangoAttrList *attrs; - PangoAttribute *attr; - GtkWidget *label; - - CcEditableEntryPrivate *priv = e->priv; - - attrs = pango_attr_list_new (); - if (priv->scale_set) { - attr = pango_attr_scale_new (priv->scale); - pango_attr_list_insert (attrs, attr); - } - if (priv->weight_set) { - attr = pango_attr_weight_new (priv->weight); - pango_attr_list_insert (attrs, attr); - } - - gtk_label_set_attributes (priv->label, attrs); - - label = gtk_bin_get_child (GTK_BIN (priv->button)); - gtk_label_set_attributes (GTK_LABEL (label), attrs); - gtk_entry_set_attributes (priv->entry, attrs); - - pango_attr_list_unref (attrs); -} - -void -cc_editable_entry_set_weight (CcEditableEntry *e, - gint weight) -{ - CcEditableEntryPrivate *priv = e->priv; - - if (priv->weight == weight && priv->weight_set) - return; - - priv->weight = weight; - priv->weight_set = TRUE; - - update_fonts (e); - - g_object_notify (G_OBJECT (e), "weight"); - g_object_notify (G_OBJECT (e), "weight-set"); -} - -gint -cc_editable_entry_get_weight (CcEditableEntry *e) -{ - return e->priv->weight; -} - -void -cc_editable_entry_set_scale (CcEditableEntry *e, - gdouble scale) -{ - CcEditableEntryPrivate *priv = e->priv; - - if (priv->scale == scale && priv->scale_set) - return; - - priv->scale = scale; - priv->scale_set = TRUE; - - update_fonts (e); - - g_object_notify (G_OBJECT (e), "scale"); - g_object_notify (G_OBJECT (e), "scale-set"); -} - -gdouble -cc_editable_entry_get_scale (CcEditableEntry *e) -{ - return e->priv->scale; -} - -void -cc_editable_entry_set_width_chars (CcEditableEntry *e, - gint n_chars) -{ - CcEditableEntryPrivate *priv = e->priv; - GtkWidget *label; - - if (priv->width_chars != n_chars) { - label = gtk_bin_get_child (GTK_BIN (priv->button)); - - gtk_entry_set_width_chars (priv->entry, n_chars); - gtk_label_set_width_chars (priv->label, n_chars); - gtk_label_set_width_chars (GTK_LABEL (label), n_chars); - - priv->width_chars = n_chars; - g_object_notify (G_OBJECT (e), "width-chars"); - gtk_widget_queue_resize (GTK_WIDGET (priv->entry)); - gtk_widget_queue_resize (GTK_WIDGET (priv->label)); - gtk_widget_queue_resize (GTK_WIDGET (label)); - } -} - -gint -cc_editable_entry_get_width_chars (CcEditableEntry *e) -{ - return e->priv->width_chars; -} - -void -cc_editable_entry_set_max_width_chars (CcEditableEntry *e, - gint n_chars) -{ - CcEditableEntryPrivate *priv = e->priv; - GtkWidget *label; - - if (priv->max_width_chars != n_chars) { - label = gtk_bin_get_child (GTK_BIN (priv->button)); - gtk_label_set_max_width_chars (priv->label, n_chars); - gtk_label_set_max_width_chars (GTK_LABEL (label), n_chars); - - priv->max_width_chars = n_chars; - g_object_notify (G_OBJECT (e), "max-width-chars"); - gtk_widget_queue_resize (GTK_WIDGET (priv->entry)); - gtk_widget_queue_resize (GTK_WIDGET (priv->label)); - gtk_widget_queue_resize (GTK_WIDGET (label)); - } -} - -gint -cc_editable_entry_get_max_width_chars (CcEditableEntry *e) -{ - return e->priv->max_width_chars; -} - -void -cc_editable_entry_set_ellipsize (CcEditableEntry *e, - PangoEllipsizeMode mode) -{ - CcEditableEntryPrivate *priv = e->priv; - GtkWidget *label; - - if ((PangoEllipsizeMode) priv->ellipsize != mode) { - label = gtk_bin_get_child (GTK_BIN (priv->button)); - gtk_label_set_ellipsize (priv->label, mode); - gtk_label_set_ellipsize (GTK_LABEL (label), mode); - - priv->ellipsize = mode; - g_object_notify (G_OBJECT (e), "ellipsize"); - gtk_widget_queue_resize (GTK_WIDGET (priv->label)); - gtk_widget_queue_resize (GTK_WIDGET (label)); - } -} - -PangoEllipsizeMode -cc_editable_entry_get_ellipsize (CcEditableEntry *e) -{ - return e->priv->ellipsize; -} - -static void -cc_editable_entry_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - CcEditableEntry *e = CC_EDITABLE_ENTRY (object); - - switch (prop_id) { - case PROP_TEXT: - cc_editable_entry_set_text (e, g_value_get_string (value)); - break; - case PROP_EDITABLE: - cc_editable_entry_set_editable (e, g_value_get_boolean (value)); - break; - case PROP_SELECTABLE: - cc_editable_entry_set_selectable (e, g_value_get_boolean (value)); - break; - case PROP_WEIGHT: - cc_editable_entry_set_weight (e, g_value_get_int (value)); - break; - case PROP_WEIGHT_SET: - e->priv->weight_set = g_value_get_boolean (value); - break; - case PROP_SCALE: - cc_editable_entry_set_scale (e, g_value_get_double (value)); - break; - case PROP_SCALE_SET: - e->priv->scale_set = g_value_get_boolean (value); - break; - case PROP_WIDTH_CHARS: - cc_editable_entry_set_width_chars (e, g_value_get_int (value)); - break; - case PROP_MAX_WIDTH_CHARS: - cc_editable_entry_set_max_width_chars (e, g_value_get_int (value)); - break; - case PROP_ELLIPSIZE: - cc_editable_entry_set_ellipsize (e, g_value_get_enum (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -cc_editable_entry_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - CcEditableEntry *e = CC_EDITABLE_ENTRY (object); - - switch (prop_id) { - case PROP_TEXT: - g_value_set_string (value, - cc_editable_entry_get_text (e)); - break; - case PROP_EDITABLE: - g_value_set_boolean (value, - cc_editable_entry_get_editable (e)); - break; - case PROP_SELECTABLE: - g_value_set_boolean (value, - cc_editable_entry_get_selectable (e)); - break; - case PROP_WEIGHT: - g_value_set_int (value, - cc_editable_entry_get_weight (e)); - break; - case PROP_WEIGHT_SET: - g_value_set_boolean (value, e->priv->weight_set); - break; - case PROP_SCALE: - g_value_set_double (value, - cc_editable_entry_get_scale (e)); - break; - case PROP_SCALE_SET: - g_value_set_boolean (value, e->priv->scale_set); - break; - case PROP_WIDTH_CHARS: - g_value_set_int (value, - cc_editable_entry_get_width_chars (e)); - break; - case PROP_MAX_WIDTH_CHARS: - g_value_set_int (value, - cc_editable_entry_get_max_width_chars (e)); - break; - case PROP_ELLIPSIZE: - g_value_set_enum (value, - cc_editable_entry_get_ellipsize (e)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -cc_editable_entry_finalize (GObject *object) -{ - CcEditableEntry *e = (CcEditableEntry*)object; - - g_free (e->priv->text); - - G_OBJECT_CLASS (cc_editable_entry_parent_class)->finalize (object); -} - -static void -cc_editable_entry_class_init (CcEditableEntryClass *class) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (class); - - object_class->set_property = cc_editable_entry_set_property; - object_class->get_property = cc_editable_entry_get_property; - object_class->finalize = cc_editable_entry_finalize; - - signals[EDITING_DONE] = - g_signal_new ("editing-done", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (CcEditableEntryClass, editing_done), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - g_object_class_install_property (object_class, PROP_TEXT, - g_param_spec_string ("text", - "Text", "The text of the button", - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_EDITABLE, - g_param_spec_boolean ("editable", - "Editable", "Whether the text can be edited", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_SELECTABLE, - g_param_spec_boolean ("selectable", - "Selectable", "Whether the text can be selected by mouse", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_WEIGHT, - g_param_spec_int ("weight", - "Font Weight", "The font weight to use", - 0, G_MAXINT, PANGO_WEIGHT_NORMAL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_WEIGHT_SET, - g_param_spec_boolean ("weight-set", - "Font Weight Set", "Whether a font weight is set", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_SCALE, - g_param_spec_double ("scale", - "Font Scale", "The font scale to use", - 0.0, G_MAXDOUBLE, 1.0, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_SCALE_SET, - g_param_spec_boolean ("scale-set", - "Font Scale Set", "Whether a font scale is set", - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_WIDTH_CHARS, - g_param_spec_int ("width-chars", - "Width In Characters", "The desired width of the editable entry, in characters", - -1, G_MAXINT, -1, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_MAX_WIDTH_CHARS, - g_param_spec_int ("max-width-chars", - "Maximum Width In Characters","The desired maximum width of the editable entry, in characters", - -1, G_MAXINT, -1, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_ELLIPSIZE, - g_param_spec_enum ("ellipsize", - "Ellipsize", "The preferred place to ellipsize the string, if the editable entry does not have enough room to display the entire string", - PANGO_TYPE_ELLIPSIZE_MODE, PANGO_ELLIPSIZE_NONE, - G_PARAM_READWRITE)); - - g_type_class_add_private (class, sizeof (CcEditableEntryPrivate)); -} - -static void -start_editing (CcEditableEntry *e) -{ - gtk_stack_set_visible_child_name (e->priv->stack, PAGE_ENTRY); - gtk_widget_grab_focus (GTK_WIDGET (e->priv->entry)); -} - -static void -stop_editing (CcEditableEntry *e) -{ - gboolean has_focus; - - /* Avoid launching another "editing-done" signal - * caused by the notebook page change */ - if (e->priv->in_stop_editing) - return; - - e->priv->in_stop_editing = TRUE; - has_focus = gtk_widget_has_focus (GTK_WIDGET (e->priv->entry)); - gtk_stack_set_visible_child_name (e->priv->stack, PAGE_BUTTON); - if (has_focus) - gtk_widget_grab_focus (GTK_WIDGET (e->priv->button)); - - cc_editable_entry_set_text (e, gtk_entry_get_text (e->priv->entry)); - g_signal_emit (e, signals[EDITING_DONE], 0); - e->priv->in_stop_editing = FALSE; -} - -static void -cancel_editing (CcEditableEntry *e) -{ - gtk_entry_set_text (e->priv->entry, cc_editable_entry_get_text (e)); - gtk_stack_set_visible_child_name (e->priv->stack, PAGE_BUTTON); - gtk_widget_grab_focus (GTK_WIDGET (e->priv->button)); -} - -static void -button_clicked (GtkWidget *widget, - CcEditableEntry *e) -{ - start_editing (e); -} - -static void -entry_activated (GtkWidget *widget, - CcEditableEntry *e) -{ - stop_editing (e); -} - -static gboolean -entry_focus_out (GtkWidget *widget, - GdkEventFocus *event, - CcEditableEntry *e) -{ - stop_editing (e); - return FALSE; -} - -static gboolean -entry_key_press (GtkWidget *widget, - GdkEventKey *event, - CcEditableEntry *e) -{ - if (event->keyval == GDK_KEY_Escape) { - cancel_editing (e); - } - return FALSE; -} - -static void -update_button_padding (CcEditableEntry *e, gpointer user_data) -{ - CcEditableEntryPrivate *priv = e->priv; - GtkStyleContext *context; - GtkStateFlags state; - GtkBorder padding, border; - gint margin; - - context = gtk_widget_get_style_context (GTK_WIDGET (priv->button)); - state = gtk_style_context_get_state (context); - - gtk_style_context_get_padding (context, state, &padding); - gtk_style_context_get_border (context, state, &border); - - margin = padding.left + border.left; - gtk_widget_set_margin_start (GTK_WIDGET (priv->label), margin); - gtk_widget_set_margin_end (GTK_WIDGET (priv->label), margin); -} - -static void -cc_editable_entry_init (CcEditableEntry *e) -{ - CcEditableEntryPrivate *priv; - - priv = e->priv = CC_EDITABLE_ENTRY_GET_PRIVATE (e); - - priv->weight = PANGO_WEIGHT_NORMAL; - priv->weight_set = FALSE; - priv->scale = 1.0; - priv->scale_set = FALSE; - priv->width_chars = -1; - priv->max_width_chars = -1; - priv->ellipsize = PANGO_ELLIPSIZE_NONE; - priv->stack = GTK_STACK (gtk_stack_new ()); - - /* Label */ - priv->label = (GtkLabel*)gtk_label_new (EMPTY_TEXT); - g_object_set (G_OBJECT (priv->label), "xalign", 0.0, NULL); - gtk_stack_add_named (priv->stack, GTK_WIDGET (priv->label), PAGE_LABEL); - - /* Button */ - priv->button = (GtkButton*)gtk_button_new_with_label (EMPTY_TEXT); - gtk_widget_set_receives_default ((GtkWidget*)priv->button, TRUE); - gtk_button_set_relief (priv->button, GTK_RELIEF_NONE); - g_object_set (G_OBJECT (gtk_bin_get_child (GTK_BIN (priv->button))), "xalign", 0.0, NULL); - - gtk_stack_add_named (priv->stack, GTK_WIDGET (priv->button), PAGE_BUTTON); - g_signal_connect (priv->button, "clicked", G_CALLBACK (button_clicked), e); - - /* Entry */ - priv->entry = (GtkEntry*)gtk_entry_new (); - gtk_stack_add_named (priv->stack, GTK_WIDGET (priv->entry), PAGE_ENTRY); - - g_signal_connect (priv->entry, "activate", G_CALLBACK (entry_activated), e); - g_signal_connect (priv->entry, "focus-out-event", G_CALLBACK (entry_focus_out), e); - g_signal_connect (priv->entry, "key-press-event", G_CALLBACK (entry_key_press), e); - - g_signal_connect (e, "style-updated", G_CALLBACK (update_button_padding), NULL); - - gtk_container_add (GTK_CONTAINER (e), (GtkWidget*)priv->stack); - - gtk_widget_show ((GtkWidget*)priv->stack); - gtk_widget_show ((GtkWidget*)priv->label); - gtk_widget_show ((GtkWidget*)priv->button); - gtk_widget_show ((GtkWidget*)priv->entry); - - gtk_stack_set_visible_child_name (e->priv->stack, PAGE_LABEL); -} - -GtkWidget * -cc_editable_entry_new (void) -{ - return (GtkWidget *) g_object_new (CC_TYPE_EDITABLE_ENTRY, NULL); -} diff --git a/shell/cc-editable-entry.h b/shell/cc-editable-entry.h deleted file mode 100644 index 9d61c5480..000000000 --- a/shell/cc-editable-entry.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright 2009-2010 Red Hat, Inc, - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - * Written by: Matthias Clasen - */ - -#ifndef _CC_EDITABLE_ENTRY_H_ -#define _CC_EDITABLE_ENTRY_H_ - -#include - -G_BEGIN_DECLS - -#define CC_TYPE_EDITABLE_ENTRY cc_editable_entry_get_type() - -#define CC_EDITABLE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CC_TYPE_EDITABLE_ENTRY, CcEditableEntry)) -#define CC_EDITABLE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CC_TYPE_EDITABLE_ENTRY, CcEditableEntryClass)) -#define CC_IS_EDITABLE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CC_TYPE_EDITABLE_ENTRY)) -#define CC_IS_EDITABLE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CC_TYPE_EDITABLE_ENTRY)) -#define CC_EDITABLE_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CC_TYPE_EDITABLE_ENTRY, CcEditableEntryClass)) - -typedef struct _CcEditableEntry CcEditableEntry; -typedef struct _CcEditableEntryClass CcEditableEntryClass; -typedef struct _CcEditableEntryPrivate CcEditableEntryPrivate; - -struct _CcEditableEntry -{ - GtkAlignment parent; - - CcEditableEntryPrivate *priv; -}; - -struct _CcEditableEntryClass -{ - GtkAlignmentClass parent_class; - - void (* editing_done) (CcEditableEntry *entry); -}; - -GType cc_editable_entry_get_type (void) G_GNUC_CONST; -GtkWidget *cc_editable_entry_new (void); -void cc_editable_entry_set_text (CcEditableEntry *entry, - const gchar *text); -const gchar *cc_editable_entry_get_text (CcEditableEntry *entry); -void cc_editable_entry_set_editable (CcEditableEntry *entry, - gboolean editable); -gboolean cc_editable_entry_get_editable (CcEditableEntry *entry); -void cc_editable_entry_set_selectable (CcEditableEntry *entry, - gboolean selectable); -gboolean cc_editable_entry_get_selectable (CcEditableEntry *entry); -void cc_editable_entry_set_weight (CcEditableEntry *entry, - gint weight); -gint cc_editable_entry_get_weight (CcEditableEntry *entry); -void cc_editable_entry_set_scale (CcEditableEntry *entry, - gdouble scale); -gdouble cc_editable_entry_get_scale (CcEditableEntry *entry); -void cc_editable_entry_set_width_chars (CcEditableEntry *entry, - gint n_chars); -gint cc_editable_entry_get_width_chars (CcEditableEntry *entry); -void cc_editable_entry_set_max_width_chars (CcEditableEntry *entry, - gint n_chars); -gint cc_editable_entry_get_max_width_chars (CcEditableEntry *entry); -void cc_editable_entry_set_ellipsize (CcEditableEntry *entry, - PangoEllipsizeMode mode); -PangoEllipsizeMode cc_editable_entry_get_ellipsize (CcEditableEntry *entry); - -G_END_DECLS - -#endif /* _CC_EDITABLE_ENTRY_H_ */ diff --git a/shell/meson.build b/shell/meson.build index 62270358c..d092ccb7c 100644 --- a/shell/meson.build +++ b/shell/meson.build @@ -44,7 +44,6 @@ libshell = static_library( common_sources = files( 'cc-application.c', - 'cc-editable-entry.c', 'cc-hostname-entry.c', 'cc-log.c', 'cc-object-storage.c', -- cgit v1.2.1 From c2f601a9d442a756e5e82f13bff3934c27b9fb09 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 6 Apr 2018 13:38:40 +0200 Subject: Move common panel code from shell/ to panel/common This creates a new static library called libwidget which the shell links against. --- panels/color/cc-color-panel.c | 2 +- panels/color/meson.build | 2 +- panels/common/cc-hostname-entry.c | 288 +++++++++++++++++++++ panels/common/cc-hostname-entry.h | 33 +++ panels/common/cc-language-chooser.c | 2 +- panels/common/hostname-helper.c | 221 ++++++++++++++++ panels/common/hostname-helper.h | 21 ++ panels/common/hostnames-test.txt | 11 + panels/common/list-box-helper.c | 153 +++++++++++ panels/common/list-box-helper.h | 37 +++ panels/common/meson.build | 40 +++ panels/common/ssids-test.txt | 3 + panels/common/test-hostname.c | 136 ++++++++++ panels/datetime/cc-datetime-panel.c | 2 +- panels/datetime/meson.build | 2 +- panels/display/cc-display-panel.c | 2 +- panels/display/meson.build | 2 +- panels/info/cc-info-overview-panel.c | 2 +- panels/info/meson.build | 2 +- panels/mouse/gnome-mouse-properties.c | 2 +- panels/network/cc-wifi-panel.c | 2 +- panels/network/connection-editor/ce-page-ip4.c | 2 +- panels/network/connection-editor/ce-page-ip6.c | 2 +- panels/network/connection-editor/meson.build | 2 +- .../connection-editor/net-connection-editor.c | 2 +- panels/network/meson.build | 2 +- panels/network/net-device-ethernet.c | 2 +- panels/network/net-device-wifi.c | 4 +- panels/notifications/cc-edit-dialog.c | 2 +- panels/notifications/cc-notifications-panel.c | 2 +- panels/notifications/meson.build | 2 +- panels/online-accounts/cc-online-accounts-panel.c | 2 +- panels/online-accounts/meson.build | 2 +- panels/power/cc-power-panel.c | 2 +- panels/power/meson.build | 2 +- panels/printers/pp-jobs-dialog.c | 2 +- panels/privacy/cc-privacy-panel.c | 2 +- panels/region/cc-format-chooser.c | 2 +- panels/region/cc-input-chooser.c | 2 +- panels/region/cc-region-panel.c | 2 +- panels/search/cc-search-locations-dialog.c | 2 +- panels/search/cc-search-panel.c | 2 +- panels/search/meson.build | 2 +- panels/sharing/cc-sharing-networks.c | 2 +- panels/sharing/cc-sharing-panel.c | 4 +- panels/sharing/meson.build | 2 +- panels/thunderbolt/cc-bolt-panel.c | 2 +- panels/thunderbolt/meson.build | 2 +- panels/universal-access/cc-ua-panel.c | 2 +- panels/universal-access/meson.build | 2 +- shell/cc-hostname-entry.c | 288 --------------------- shell/cc-hostname-entry.h | 33 --- shell/hostname-helper.c | 221 ---------------- shell/hostname-helper.h | 21 -- shell/hostnames-test.txt | 11 - shell/list-box-helper.c | 153 ----------- shell/list-box-helper.h | 37 --- shell/meson.build | 33 +-- shell/ssids-test.txt | 3 - shell/test-hostname.c | 136 ---------- 60 files changed, 989 insertions(+), 974 deletions(-) create mode 100644 panels/common/cc-hostname-entry.c create mode 100644 panels/common/cc-hostname-entry.h create mode 100644 panels/common/hostname-helper.c create mode 100644 panels/common/hostname-helper.h create mode 100644 panels/common/hostnames-test.txt create mode 100644 panels/common/list-box-helper.c create mode 100644 panels/common/list-box-helper.h create mode 100644 panels/common/ssids-test.txt create mode 100644 panels/common/test-hostname.c delete mode 100644 shell/cc-hostname-entry.c delete mode 100644 shell/cc-hostname-entry.h delete mode 100644 shell/hostname-helper.c delete mode 100644 shell/hostname-helper.h delete mode 100644 shell/hostnames-test.txt delete mode 100644 shell/list-box-helper.c delete mode 100644 shell/list-box-helper.h delete mode 100644 shell/ssids-test.txt delete mode 100644 shell/test-hostname.c diff --git a/panels/color/cc-color-panel.c b/panels/color/cc-color-panel.c index e7957deba..e9a65cf58 100644 --- a/panels/color/cc-color-panel.c +++ b/panels/color/cc-color-panel.c @@ -26,7 +26,7 @@ #include #include -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "cc-color-calibrate.h" #include "cc-color-cell-renderer-text.h" #include "cc-color-panel.h" diff --git a/panels/color/meson.build b/panels/color/meson.build index 36bd4be7d..54766a807 100644 --- a/panels/color/meson.build +++ b/panels/color/meson.build @@ -55,7 +55,7 @@ cflags += [ panels_libs += static_library( cappletname, sources: sources, - include_directories: top_inc, + include_directories: [ top_inc, common_inc ], dependencies: deps, c_args: cflags ) diff --git a/panels/common/cc-hostname-entry.c b/panels/common/cc-hostname-entry.c new file mode 100644 index 000000000..0b0d6d10c --- /dev/null +++ b/panels/common/cc-hostname-entry.c @@ -0,0 +1,288 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2013 Intel, Inc + * Copyright (C) 2011,2012 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + + +#include "cc-hostname-entry.h" +#include "hostname-helper.h" + +#include + +struct _CcHostnameEntry +{ + GtkEntry parent; + + GDBusProxy *hostnamed_proxy; + guint set_hostname_timeout_source_id; +}; + +G_DEFINE_TYPE (CcHostnameEntry, cc_hostname_entry, GTK_TYPE_ENTRY) + +#define SET_HOSTNAME_TIMEOUT 1 + +static void +cc_hostname_entry_set_hostname (CcHostnameEntry *self) +{ + char *hostname; + GVariant *variant; + GError *error = NULL; + const gchar *text; + + text = gtk_entry_get_text (GTK_ENTRY (self)); + + g_debug ("Setting PrettyHostname to '%s'", text); + variant = g_dbus_proxy_call_sync (self->hostnamed_proxy, + "SetPrettyHostname", + g_variant_new ("(sb)", text, FALSE), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, &error); + if (variant == NULL) + { + g_warning ("Could not set PrettyHostname: %s", error->message); + g_error_free (error); + error = NULL; + } + else + { + g_variant_unref (variant); + } + + /* Set the static hostname */ + hostname = pretty_hostname_to_static (text, FALSE); + g_assert (hostname); + + g_debug ("Setting StaticHostname to '%s'", hostname); + variant = g_dbus_proxy_call_sync (self->hostnamed_proxy, + "SetStaticHostname", + g_variant_new ("(sb)", hostname, FALSE), + G_DBUS_CALL_FLAGS_NONE, + -1, NULL, &error); + if (variant == NULL) + { + g_warning ("Could not set StaticHostname: %s", error->message); + g_error_free (error); + } + else + { + g_variant_unref (variant); + } + g_free (hostname); +} + +static char * +get_hostname_property (CcHostnameEntry *self, + const char *property) +{ + GVariant *variant; + char *str; + + if (!self->hostnamed_proxy) + return g_strdup (""); + + variant = g_dbus_proxy_get_cached_property (self->hostnamed_proxy, + property); + if (!variant) + { + GError *error = NULL; + GVariant *inner; + + /* Work around systemd-hostname not sending us back + * the property value when changing values */ + variant = g_dbus_proxy_call_sync (self->hostnamed_proxy, + "org.freedesktop.DBus.Properties.Get", + g_variant_new ("(ss)", "org.freedesktop.hostname1", property), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (variant == NULL) + { + g_warning ("Failed to get property '%s': %s", property, error->message); + g_error_free (error); + return NULL; + } + + g_variant_get (variant, "(v)", &inner); + str = g_variant_dup_string (inner, NULL); + g_variant_unref (variant); + } + else + { + str = g_variant_dup_string (variant, NULL); + g_variant_unref (variant); + } + + return str; +} + +static char * +cc_hostname_entry_get_display_hostname (CcHostnameEntry *self) +{ + char *str; + + str = get_hostname_property (self, "PrettyHostname"); + + /* Empty strings means that we need to fallback */ + if (str != NULL && + *str == '\0') + { + g_free (str); + str = get_hostname_property (self, "Hostname"); + } + + return str; +} + +static gboolean +set_hostname_timeout (CcHostnameEntry *self) +{ + self->set_hostname_timeout_source_id = 0; + + cc_hostname_entry_set_hostname (self); + + return FALSE; +} + +static void +remove_hostname_timeout (CcHostnameEntry *self) +{ + if (self->set_hostname_timeout_source_id) + g_source_remove (self->set_hostname_timeout_source_id); + + self->set_hostname_timeout_source_id = 0; +} + +static void +reset_hostname_timeout (CcHostnameEntry *self) +{ + remove_hostname_timeout (self); + + self->set_hostname_timeout_source_id = g_timeout_add_seconds (SET_HOSTNAME_TIMEOUT, + (GSourceFunc) set_hostname_timeout, + self); +} + +static void +text_changed_cb (CcHostnameEntry *entry) +{ + reset_hostname_timeout (entry); +} + +static void +cc_hostname_entry_dispose (GObject *object) +{ + CcHostnameEntry *self = CC_HOSTNAME_ENTRY (object); + + if (self->set_hostname_timeout_source_id) + { + remove_hostname_timeout (self); + set_hostname_timeout (self); + } + + g_clear_object (&self->hostnamed_proxy); + + G_OBJECT_CLASS (cc_hostname_entry_parent_class)->dispose (object); +} + +static void +cc_hostname_entry_constructed (GObject *object) +{ + CcHostnameEntry *self = CC_HOSTNAME_ENTRY (object); + GPermission *permission; + GError *error = NULL; + char *str; + + permission = polkit_permission_new_sync ("org.freedesktop.hostname1.set-static-hostname", + NULL, NULL, NULL); + + /* Is hostnamed installed? */ + if (permission == NULL) + { + g_debug ("Will not show hostname, hostnamed not installed"); + + gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE); + + return; + } + + if (g_permission_get_allowed (permission)) + gtk_widget_set_sensitive (GTK_WIDGET (self), TRUE); + else + { + g_debug ("Not allowed to change the hostname"); + gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE); + } + + gtk_widget_set_sensitive (GTK_WIDGET (self), + g_permission_get_allowed (permission)); + + self->hostnamed_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + "org.freedesktop.hostname1", + "/org/freedesktop/hostname1", + "org.freedesktop.hostname1", + NULL, + &error); + + /* This could only happen if the policy file was installed + * but not hostnamed, which points to a system bug */ + if (self->hostnamed_proxy == NULL) + { + g_debug ("Couldn't get hostnamed to start, bailing: %s", error->message); + g_error_free (error); + return; + } + + str = cc_hostname_entry_get_display_hostname (CC_HOSTNAME_ENTRY (self)); + + if (str != NULL) + gtk_entry_set_text (GTK_ENTRY (self), str); + else + gtk_entry_set_text (GTK_ENTRY (self), ""); + g_free (str); + + g_signal_connect (G_OBJECT (self), "changed", G_CALLBACK (text_changed_cb), self); +} + +static void +cc_hostname_entry_class_init (CcHostnameEntryClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructed = cc_hostname_entry_constructed; + object_class->dispose = cc_hostname_entry_dispose; +} + +static void +cc_hostname_entry_init (CcHostnameEntry *self) +{ +} + +CcHostnameEntry * +cc_hostname_entry_new (void) +{ + return g_object_new (CC_TYPE_HOSTNAME_ENTRY, NULL); +} + +gchar* +cc_hostname_entry_get_hostname (CcHostnameEntry *entry) +{ + return get_hostname_property (entry, "Hostname"); +} diff --git a/panels/common/cc-hostname-entry.h b/panels/common/cc-hostname-entry.h new file mode 100644 index 000000000..a48177961 --- /dev/null +++ b/panels/common/cc-hostname-entry.h @@ -0,0 +1,33 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2013 Intel, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +#define CC_TYPE_HOSTNAME_ENTRY (cc_hostname_entry_get_type()) + +G_DECLARE_FINAL_TYPE (CcHostnameEntry, cc_hostname_entry, CC, HOSTNAME_ENTRY, GtkEntry) + +CcHostnameEntry *cc_hostname_entry_new (void); +gchar* cc_hostname_entry_get_hostname (CcHostnameEntry *entry); + +G_END_DECLS diff --git a/panels/common/cc-language-chooser.c b/panels/common/cc-language-chooser.c index 961df5a0a..f0d2ecedc 100644 --- a/panels/common/cc-language-chooser.c +++ b/panels/common/cc-language-chooser.c @@ -29,7 +29,7 @@ #include #include -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "cc-common-language.h" #include "cc-util.h" diff --git a/panels/common/hostname-helper.c b/panels/common/hostname-helper.c new file mode 100644 index 000000000..df596975e --- /dev/null +++ b/panels/common/hostname-helper.c @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2011 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include +#include +#include + +#include "hostname-helper.h" + +static char * +allowed_chars (void) +{ + GString *s; + char i; + + s = g_string_new (NULL); + for (i = 'a'; i <= 'z'; i++) + g_string_append_c (s, i); + for (i = 'A'; i <= 'Z'; i++) + g_string_append_c (s, i); + for (i = '0'; i <= '9'; i++) + g_string_append_c (s, i); + g_string_append_c (s, '-'); + + return g_string_free (s, FALSE); +} + +static char * +remove_leading_dashes (char *input) +{ + char *start; + + for (start = input; *start && (*start == '-'); start++) + ; + + g_memmove (input, start, strlen (start) + 1); + + return input; +} + +static gboolean +is_empty (const char *input) +{ + if (input == NULL || + *input == '\0') + return TRUE; + return FALSE; +} + +static char * +remove_trailing_dashes (char *input) +{ + int len; + + len = strlen (input); + while (len--) { + if (input[len] == '-') + input[len] = '\0'; + else + break; + } + return input; +} + +static char * +remove_apostrophes (char *input) +{ + char *apo; + + while ((apo = strchr (input, '\'')) != NULL) + g_memmove (apo, apo + 1, strlen (apo)); + return input; +} + +static char * +remove_duplicate_dashes (char *input) +{ + char *dashes; + + while ((dashes = strstr (input, "--")) != NULL) + g_memmove (dashes, dashes + 1, strlen (dashes)); + return input; +} + +#define CHECK if (is_empty (result)) goto bail + +char * +pretty_hostname_to_static (const char *pretty, + gboolean for_display) +{ + char *result; + char *valid_chars; + char *composed; + + g_return_val_if_fail (pretty != NULL, NULL); + g_return_val_if_fail (g_utf8_validate (pretty, -1, NULL), NULL); + + g_debug ("Input: '%s'", pretty); + + composed = g_utf8_normalize (pretty, -1, G_NORMALIZE_ALL_COMPOSE); + g_debug ("\tcomposed: '%s'", composed); + /* Transform the pretty hostname to ASCII */ + result = g_str_to_ascii (composed, NULL); + g_debug ("\ttranslit: '%s'", result); + g_free (composed); + + CHECK; + + /* Remove apostrophes */ + result = remove_apostrophes (result); + g_debug ("\tapostrophes: '%s'", result); + + CHECK; + + /* Remove all the not-allowed chars */ + valid_chars = allowed_chars (); + result = g_strcanon (result, valid_chars, '-'); + g_free (valid_chars); + g_debug ("\tcanon: '%s'", result); + + CHECK; + + /* Remove the leading dashes */ + result = remove_leading_dashes (result); + g_debug ("\tleading: '%s'", result); + + CHECK; + + /* Remove trailing dashes */ + result = remove_trailing_dashes (result); + g_debug ("\ttrailing: '%s'", result); + + CHECK; + + /* Remove duplicate dashes */ + result = remove_duplicate_dashes (result); + g_debug ("\tduplicate: '%s'", result); + + CHECK; + + /* Lower case */ + if (!for_display) { + char *tmp; + + tmp = g_ascii_strdown (result, -1); + g_free (result); + result = tmp; + } + + return result; + +bail: + g_free (result); + return g_strdup ("localhost"); +} +#undef CHECK + +/* Max length of an SSID in bytes */ +#define SSID_MAX_LEN 32 +char * +pretty_hostname_to_ssid (const char *pretty) +{ + const char *p, *prev; + char *ret = NULL; + + if (pretty == NULL || *pretty == '\0') { + pretty = g_get_host_name (); + if (g_strcmp0 (pretty, "localhost") == 0) + pretty = NULL; + } + + if (pretty == NULL) { + /* translators: This is the default hotspot name, need to be less than 32-bytes */ + ret = g_strdup (C_("hotspot", "Hotspot")); + g_assert (strlen (ret) <= SSID_MAX_LEN); + return ret; + } + + g_return_val_if_fail (g_utf8_validate (pretty, -1, NULL), NULL); + + p = pretty; + prev = NULL; + while ((p = g_utf8_find_next_char (p, NULL)) != NULL) { + if (p == prev) + break; + + if (p - pretty > SSID_MAX_LEN) { + ret = g_strndup (pretty, prev - pretty); + break; + } + if (p - pretty == SSID_MAX_LEN) { + ret = g_strndup (pretty, p - pretty); + break; + } + + if (*p == '\0') + break; + + prev = p; + } + + if (ret == NULL) + ret = g_strdup (pretty); + + return ret; +} diff --git a/panels/common/hostname-helper.h b/panels/common/hostname-helper.h new file mode 100644 index 000000000..9f96c12f9 --- /dev/null +++ b/panels/common/hostname-helper.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2011 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +char *pretty_hostname_to_static (const char *pretty, + gboolean for_display); +char *pretty_hostname_to_ssid (const char *pretty); diff --git a/panels/common/hostnames-test.txt b/panels/common/hostnames-test.txt new file mode 100644 index 000000000..5a31ce28b --- /dev/null +++ b/panels/common/hostnames-test.txt @@ -0,0 +1,11 @@ +# Pretty hostname, tab, display hostname, tab, real hostname +Lennart's PC Lennarts-PC lennarts-pc +Müllers Computer Mullers-Computer mullers-computer +Voran! Voran voran +Es war einmal ein Männlein Es-war-einmal-ein-Mannlein es-war-einmal-ein-mannlein +Jawoll. Ist doch wahr! Jawoll-Ist-doch-wahr jawoll-ist-doch-wahr +レナート localhost localhost +!!! localhost localhost +...zack!!! zack!... zack-zack zack-zack +Bãstien's computer... Foo-bar Bastiens-computer-Foo-bar bastiens-computer-foo-bar + localhost localhost diff --git a/panels/common/list-box-helper.c b/panels/common/list-box-helper.c new file mode 100644 index 000000000..415cdde94 --- /dev/null +++ b/panels/common/list-box-helper.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2014 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include "list-box-helper.h" + +#define MAX_ROWS_VISIBLE 5 + +struct _CcListBoxRow +{ + GtkListBoxRow parent_instance; +}; +G_DEFINE_TYPE (CcListBoxRow, cc_list_box_row, GTK_TYPE_LIST_BOX_ROW) +enum +{ + BOX_ROW_ACTIVATED, + LAST_BOX_ROW_SIGNAL +}; +static guint cc_list_box_row_signals[LAST_BOX_ROW_SIGNAL] = { 0 }; +static void +cc_list_box_row_class_init (CcListBoxRowClass *klass) +{ + cc_list_box_row_signals[BOX_ROW_ACTIVATED] = + g_signal_new ("activated", + CC_TYPE_LIST_BOX_ROW, + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); +} +static void cc_list_box_row_init (CcListBoxRow *self) {} + +struct _CcListBox +{ + GtkListBox parent_instance; +}; +G_DEFINE_TYPE (CcListBox, cc_list_box, GTK_TYPE_LIST_BOX) +static void +cc_list_box_row_activated (GtkListBox *box, GtkListBoxRow *row) +{ + if (CC_IS_LIST_BOX_ROW (row)) + g_signal_emit (row, cc_list_box_row_signals[BOX_ROW_ACTIVATED], 0); +} +static void +cc_list_box_class_init (CcListBoxClass *klass) +{ + GtkListBoxClass *parent_class = GTK_LIST_BOX_CLASS (klass); + parent_class->row_activated = cc_list_box_row_activated; +} +static void cc_list_box_init (CcListBox *self) {} + + +void +cc_list_box_update_header_func (GtkListBoxRow *row, + GtkListBoxRow *before, + gpointer user_data) +{ + GtkWidget *current; + + if (before == NULL) + { + gtk_list_box_row_set_header (row, NULL); + return; + } + + current = gtk_list_box_row_get_header (row); + if (current == NULL) + { + current = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); + gtk_widget_show (current); + gtk_list_box_row_set_header (row, current); + } +} + +void +cc_list_box_adjust_scrolling (GtkListBox *listbox) +{ + GtkWidget *scrolled_window; + GList *children; + guint n_rows, num_max_rows; + + scrolled_window = g_object_get_data (G_OBJECT (listbox), "cc-scrolling-scrolled-window"); + if (!scrolled_window) + return; + + children = gtk_container_get_children (GTK_CONTAINER (listbox)); + n_rows = g_list_length (children); + + num_max_rows = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (listbox), "cc-max-rows-visible")); + + if (n_rows >= num_max_rows) + { + gint total_row_height = 0; + GList *l; + guint i; + + for (l = children, i = 0; l != NULL && i < num_max_rows; l = l->next, i++) { + gint row_height; + gtk_widget_get_preferred_height (GTK_WIDGET (l->data), &row_height, NULL); + total_row_height += row_height; + } + + gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (scrolled_window), total_row_height); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + } + else + { + gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (scrolled_window), -1); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), + GTK_POLICY_NEVER, GTK_POLICY_NEVER); + } + + g_list_free (children); +} + +void +cc_list_box_setup_scrolling (GtkListBox *listbox, + guint num_max_rows) +{ + GtkWidget *parent; + GtkWidget *scrolled_window; + + parent = gtk_widget_get_parent (GTK_WIDGET (listbox)); + scrolled_window = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_show (scrolled_window); + + g_object_ref (listbox); + gtk_container_remove (GTK_CONTAINER (parent), GTK_WIDGET (listbox)); + gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (listbox)); + g_object_unref (listbox); + + gtk_container_add (GTK_CONTAINER (parent), scrolled_window); + + if (num_max_rows == 0) + num_max_rows = MAX_ROWS_VISIBLE; + + g_object_set_data (G_OBJECT (listbox), "cc-scrolling-scrolled-window", scrolled_window); + g_object_set_data (G_OBJECT (listbox), "cc-max-rows-visible", GUINT_TO_POINTER (num_max_rows)); +} diff --git a/panels/common/list-box-helper.h b/panels/common/list-box-helper.h new file mode 100644 index 000000000..c2a0acc97 --- /dev/null +++ b/panels/common/list-box-helper.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2014 Red Hat, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + */ + +#include + +#define CC_TYPE_LIST_BOX_ROW (cc_list_box_row_get_type ()) +G_DECLARE_FINAL_TYPE (CcListBoxRow, cc_list_box_row, CC, LIST_BOX_ROW, GtkListBoxRow) + +#define CC_TYPE_LIST_BOX (cc_list_box_get_type ()) +G_DECLARE_FINAL_TYPE (CcListBox, cc_list_box, CC, LIST_BOX, GtkListBox) + +void +cc_list_box_update_header_func (GtkListBoxRow *row, + GtkListBoxRow *before, + gpointer user_data); + +void +cc_list_box_adjust_scrolling (GtkListBox *listbox); + +void +cc_list_box_setup_scrolling (GtkListBox *listbox, + guint num_rows); diff --git a/panels/common/meson.build b/panels/common/meson.build index 561f42cf7..42594360f 100644 --- a/panels/common/meson.build +++ b/panels/common/meson.build @@ -24,6 +24,23 @@ common_sources += gnome.mkenums( vtail: ' { 0, NULL, NULL }\n };\n etype = g_@type@_register_static ("@EnumName@", values);\n }\n return etype;\n}\n' ) +sources = files( + 'cc-hostname-entry.c', + 'hostname-helper.c', + 'list-box-helper.c', +) + +libwidgets = static_library( + 'widgets', + sources: sources, + include_directories: top_inc, + dependencies: common_deps + [ polkit_gobject_dep ] +) +libwidgets_dep = declare_dependency( + include_directories: common_inc, + link_with: libwidgets +) + sources = common_sources + files( 'cc-common-language.c', 'cc-language-chooser.c', @@ -121,3 +138,26 @@ run_target( script_name, command: script ) + + +test_unit = 'test-hostname' + +sources = files( + 'hostname-helper.c', + test_unit + '.c' +) + +cflags = [ + '-DTEST_SRCDIR="@0@"'.format(meson.current_source_dir()), + '-DTEST_TOPSRCDIR="@0@"'.format(meson.source_root()) +] + +exe = executable( + test_unit, + sources, + include_directories: top_inc, + dependencies: [ common_deps, libwidgets_dep ], + c_args: cflags +) + +test(test_unit, exe) diff --git a/panels/common/ssids-test.txt b/panels/common/ssids-test.txt new file mode 100644 index 000000000..0545437cf --- /dev/null +++ b/panels/common/ssids-test.txt @@ -0,0 +1,3 @@ +GNOME GNOME +0123456789abcdefghijklmnopqrstuvwxyz 0123456789abcdefghijklmnopqrstuv +レナート レナート diff --git a/panels/common/test-hostname.c b/panels/common/test-hostname.c new file mode 100644 index 000000000..4e14f715a --- /dev/null +++ b/panels/common/test-hostname.c @@ -0,0 +1,136 @@ +#include "config.h" + +#include +#include +#include + +#include "hostname-helper.h" + +static void +test_hostname (void) +{ + char *contents; + char *result; + guint i; + char **lines; + + if (g_file_get_contents (TEST_SRCDIR "/hostnames-test.txt", &contents, NULL, NULL) == FALSE) { + g_warning ("Failed to load '%s'", TEST_SRCDIR "/hostnames-test.txt"); + g_test_fail (); + return; + } + + lines = g_strsplit (contents, "\n", -1); + if (lines == NULL) { + g_warning ("Test file is empty"); + g_test_fail (); + return; + } + + for (i = 0; lines[i] != NULL; i++) { + char *utf8; + char **items; + + if (*lines[i] == '#') + continue; + if (*lines[i] == '\0') + break; + + items = g_strsplit (lines[i], "\t", -1); + utf8 = g_locale_from_utf8 (items[0], -1, NULL, NULL, NULL); + result = pretty_hostname_to_static (items[0], FALSE); + if (g_strcmp0 (result, items[2]) != 0) { + g_error ("Result for '%s' doesn't match '%s' (got: '%s')", + utf8, items[2], result); + g_test_fail (); + } else { + g_debug ("Result for '%s' matches '%s'", + utf8, result); + } + g_free (result); + g_free (utf8); + + result = pretty_hostname_to_static (items[0], TRUE); + utf8 = g_locale_from_utf8 (items[0], -1, NULL, NULL, NULL); + if (g_strcmp0 (result, items[1]) != 0) { + g_error ("Result for '%s' doesn't match '%s' (got: '%s')", + utf8, items[1], result); + g_test_fail (); + } else { + g_debug ("Result for '%s' matches '%s'", + utf8, result); + } + g_free (result); + g_free (utf8); + + g_strfreev (items); + } + + g_strfreev (lines); + g_free (contents); +} + +static void +test_ssid (void) +{ + char *contents; + guint i; + char **lines; + + if (g_file_get_contents (TEST_SRCDIR "/ssids-test.txt", &contents, NULL, NULL) == FALSE) { + g_warning ("Failed to load '%s'", TEST_SRCDIR "/ssids-test.txt"); + g_test_fail (); + return; + } + + lines = g_strsplit (contents, "\n", -1); + if (lines == NULL) { + g_warning ("Test file is empty"); + g_test_fail (); + return; + } + + for (i = 0; lines[i] != NULL; i++) { + char *ssid; + char **items; + + if (*lines[i] == '#') + continue; + if (*lines[i] == '\0') + break; + + items = g_strsplit (lines[i], "\t", -1); + ssid = pretty_hostname_to_ssid (items[0]); + g_assert_cmpstr (ssid, ==, items[1]); + g_free (ssid); + g_strfreev (items); + } + + g_strfreev (lines); + g_free (contents); +} + +int main (int argc, char **argv) +{ + char *locale; + + /* Running in some locales will + * break the tests as "ü" will be transliterated to + * "ue" in de_DE, and 'u"' in the C locale. + * + * Work around that by forcing en_US with UTF-8 in + * our tests + * https://bugzilla.gnome.org/show_bug.cgi?id=650342 */ + locale = setlocale (LC_ALL, "en_US.UTF-8"); + if (locale == NULL) { + g_debug("Missing en_US.UTF-8 locale, ignoring test."); + return 0; + } + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/common/hostname", test_hostname); + g_test_add_func ("/common/ssid", test_ssid); + + return g_test_run (); +} diff --git a/panels/datetime/cc-datetime-panel.c b/panels/datetime/cc-datetime-panel.c index 2ea385188..15f3dd8c3 100644 --- a/panels/datetime/cc-datetime-panel.c +++ b/panels/datetime/cc-datetime-panel.c @@ -25,7 +25,7 @@ #include #include -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "cc-timezone-map.h" #include "timedated.h" #include "date-endian.h" diff --git a/panels/datetime/meson.build b/panels/datetime/meson.build index ba82618f2..8a96844be 100644 --- a/panels/datetime/meson.build +++ b/panels/datetime/meson.build @@ -186,7 +186,7 @@ cflags += [ panels_libs += static_library( cappletname, sources: sources + resources, - include_directories: top_inc, + include_directories: [ top_inc, common_inc ], dependencies: deps, c_args: cflags ) diff --git a/panels/display/cc-display-panel.c b/panels/display/cc-display-panel.c index 550376776..9488ca80b 100644 --- a/panels/display/cc-display-panel.c +++ b/panels/display/cc-display-panel.c @@ -30,7 +30,7 @@ #include #include "shell/cc-object-storage.h" -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include #include "cc-display-config-manager-dbus.h" diff --git a/panels/display/meson.build b/panels/display/meson.build index ee33b4355..d341758f8 100644 --- a/panels/display/meson.build +++ b/panels/display/meson.build @@ -58,7 +58,7 @@ cflags += [ panels_libs += static_library( cappletname, sources: sources, - include_directories: top_inc, + include_directories: [ top_inc, common_inc ], dependencies: deps, c_args: cflags ) diff --git a/panels/info/cc-info-overview-panel.c b/panels/info/cc-info-overview-panel.c index 4301090f9..19f785a36 100644 --- a/panels/info/cc-info-overview-panel.c +++ b/panels/info/cc-info-overview-panel.c @@ -21,8 +21,8 @@ #include -#include "shell/cc-hostname-entry.h" #include "shell/cc-object-storage.h" +#include "cc-hostname-entry.h" #include "cc-info-resources.h" #include "info-cleanup.h" diff --git a/panels/info/meson.build b/panels/info/meson.build index 13015b96c..6b41706bc 100644 --- a/panels/info/meson.build +++ b/panels/info/meson.build @@ -67,7 +67,7 @@ deps = common_deps + [ panels_libs += static_library( cappletname, sources: sources, - include_directories: top_inc, + include_directories: [ top_inc, common_inc ], dependencies: deps, c_args: cflags ) diff --git a/panels/mouse/gnome-mouse-properties.c b/panels/mouse/gnome-mouse-properties.c index 4d0920b2d..2a22b4815 100644 --- a/panels/mouse/gnome-mouse-properties.c +++ b/panels/mouse/gnome-mouse-properties.c @@ -35,7 +35,7 @@ #include "gnome-mouse-properties.h" #include "gsd-input-helper.h" #include "gsd-device-manager.h" -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "cc-mouse-caps-helper.h" #include diff --git a/panels/network/cc-wifi-panel.c b/panels/network/cc-wifi-panel.c index 64321752c..d785bad0d 100644 --- a/panels/network/cc-wifi-panel.c +++ b/panels/network/cc-wifi-panel.c @@ -24,7 +24,7 @@ #include "network-dialogs.h" #include "shell/cc-object-storage.h" -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include #include diff --git a/panels/network/connection-editor/ce-page-ip4.c b/panels/network/connection-editor/ce-page-ip4.c index 400dc433d..100a3b4e3 100644 --- a/panels/network/connection-editor/ce-page-ip4.c +++ b/panels/network/connection-editor/ce-page-ip4.c @@ -28,7 +28,7 @@ #include #include -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "ce-page-ip4.h" #include "ui-helpers.h" diff --git a/panels/network/connection-editor/ce-page-ip6.c b/panels/network/connection-editor/ce-page-ip6.c index 995197504..35653f3a1 100644 --- a/panels/network/connection-editor/ce-page-ip6.c +++ b/panels/network/connection-editor/ce-page-ip6.c @@ -28,7 +28,7 @@ #include #include -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "ce-page-ip6.h" #include "ui-helpers.h" diff --git a/panels/network/connection-editor/meson.build b/panels/network/connection-editor/meson.build index 616bafdb1..9ba9b3784 100644 --- a/panels/network/connection-editor/meson.build +++ b/panels/network/connection-editor/meson.build @@ -40,7 +40,7 @@ sources += gnome.compile_resources( libconnection_editor = static_library( name, sources: sources, - include_directories: [top_inc, wireless_security_inc], + include_directories: [top_inc, common_inc, wireless_security_inc], dependencies: deps, c_args: cflags, link_with: libwireless_security diff --git a/panels/network/connection-editor/net-connection-editor.c b/panels/network/connection-editor/net-connection-editor.c index 1b268044a..556b57fb8 100644 --- a/panels/network/connection-editor/net-connection-editor.c +++ b/panels/network/connection-editor/net-connection-editor.c @@ -26,7 +26,7 @@ #include -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "net-connection-editor.h" #include "net-connection-editor-resources.h" #include "ce-page-details.h" diff --git a/panels/network/meson.build b/panels/network/meson.build index 8036d79f8..0325c5afd 100644 --- a/panels/network/meson.build +++ b/panels/network/meson.build @@ -72,7 +72,7 @@ cflags += '-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir) panels_libs += static_library( cappletname, sources: sources, - include_directories: top_inc, + include_directories: [top_inc, common_inc], dependencies: deps, c_args: cflags, link_with: libconnection_editor diff --git a/panels/network/net-device-ethernet.c b/panels/network/net-device-ethernet.c index 603ad6c86..0412facaf 100644 --- a/panels/network/net-device-ethernet.c +++ b/panels/network/net-device-ethernet.c @@ -28,7 +28,7 @@ #include "panel-common.h" -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "connection-editor/net-connection-editor.h" #include "connection-editor/ce-page.h" diff --git a/panels/network/net-device-wifi.c b/panels/network/net-device-wifi.c index 313e9ab8c..5b9a77a1f 100644 --- a/panels/network/net-device-wifi.c +++ b/panels/network/net-device-wifi.c @@ -29,8 +29,8 @@ #include #include -#include "shell/list-box-helper.h" -#include "shell/hostname-helper.h" +#include "list-box-helper.h" +#include "hostname-helper.h" #include "network-dialogs.h" #include "panel-common.h" diff --git a/panels/notifications/cc-edit-dialog.c b/panels/notifications/cc-edit-dialog.c index 778c18c86..bdac5a4f9 100644 --- a/panels/notifications/cc-edit-dialog.c +++ b/panels/notifications/cc-edit-dialog.c @@ -26,7 +26,7 @@ #include #include -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "cc-notifications-panel.h" #include "cc-edit-dialog.h" diff --git a/panels/notifications/cc-notifications-panel.c b/panels/notifications/cc-notifications-panel.c index 0b1b834ca..9baa5a80e 100644 --- a/panels/notifications/cc-notifications-panel.c +++ b/panels/notifications/cc-notifications-panel.c @@ -26,7 +26,7 @@ #include #include "shell/cc-object-storage.h" -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "cc-notifications-panel.h" #include "cc-notifications-resources.h" #include "cc-edit-dialog.h" diff --git a/panels/notifications/meson.build b/panels/notifications/meson.build index 97a623fcb..55adee3b5 100644 --- a/panels/notifications/meson.build +++ b/panels/notifications/meson.build @@ -40,7 +40,7 @@ cflags += '-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir) panels_libs += static_library( cappletname, sources: sources, - include_directories: top_inc, + include_directories: [ top_inc, common_inc ], dependencies: common_deps, c_args: cflags ) diff --git a/panels/online-accounts/cc-online-accounts-panel.c b/panels/online-accounts/cc-online-accounts-panel.c index 3177a4d27..a89d249c0 100644 --- a/panels/online-accounts/cc-online-accounts-panel.c +++ b/panels/online-accounts/cc-online-accounts-panel.c @@ -32,7 +32,7 @@ #include "cc-online-accounts-panel.h" #include "cc-online-accounts-resources.h" -#include "shell/list-box-helper.h" +#include "list-box-helper.h" struct _CcGoaPanel { diff --git a/panels/online-accounts/meson.build b/panels/online-accounts/meson.build index eea6f89ec..1f899e881 100644 --- a/panels/online-accounts/meson.build +++ b/panels/online-accounts/meson.build @@ -39,7 +39,7 @@ cflags += '-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir) panels_libs += static_library( cappletname, sources: sources, - include_directories: top_inc, + include_directories: [ top_inc, common_inc ], dependencies: deps, c_args: cflags ) diff --git a/panels/power/cc-power-panel.c b/panels/power/cc-power-panel.c index b78c17a49..85013105c 100644 --- a/panels/power/cc-power-panel.c +++ b/panels/power/cc-power-panel.c @@ -30,7 +30,7 @@ #endif #include "shell/cc-object-storage.h" -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "cc-power-panel.h" #include "cc-power-resources.h" diff --git a/panels/power/meson.build b/panels/power/meson.build index 9a27e93bd..d4091eaa1 100644 --- a/panels/power/meson.build +++ b/panels/power/meson.build @@ -47,7 +47,7 @@ endif panels_libs += static_library( cappletname, sources: sources, - include_directories: top_inc, + include_directories: [ top_inc, common_inc ], dependencies: deps, c_args: cflags ) diff --git a/panels/printers/pp-jobs-dialog.c b/panels/printers/pp-jobs-dialog.c index dfab7eb42..f1331d6d6 100644 --- a/panels/printers/pp-jobs-dialog.c +++ b/panels/printers/pp-jobs-dialog.c @@ -31,7 +31,7 @@ #include -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "pp-jobs-dialog.h" #include "pp-utils.h" #include "pp-job.h" diff --git a/panels/privacy/cc-privacy-panel.c b/panels/privacy/cc-privacy-panel.c index daa050a41..8735e33d0 100644 --- a/panels/privacy/cc-privacy-panel.c +++ b/panels/privacy/cc-privacy-panel.c @@ -19,7 +19,7 @@ */ #include "shell/cc-object-storage.h" -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "cc-privacy-panel.h" #include "cc-privacy-resources.h" #include "cc-util.h" diff --git a/panels/region/cc-format-chooser.c b/panels/region/cc-format-chooser.c index 4998de99d..2fed3f10e 100644 --- a/panels/region/cc-format-chooser.c +++ b/panels/region/cc-format-chooser.c @@ -27,7 +27,7 @@ #include #include -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "cc-common-language.h" #include "cc-util.h" diff --git a/panels/region/cc-input-chooser.c b/panels/region/cc-input-chooser.c index a5156ccbf..9f882cdb3 100644 --- a/panels/region/cc-input-chooser.c +++ b/panels/region/cc-input-chooser.c @@ -22,7 +22,7 @@ #define GNOME_DESKTOP_USE_UNSTABLE_API #include -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "cc-common-language.h" #include "cc-util.h" #include "cc-input-chooser.h" diff --git a/panels/region/cc-region-panel.c b/panels/region/cc-region-panel.c index 232c3faad..5fdb35a25 100644 --- a/panels/region/cc-region-panel.c +++ b/panels/region/cc-region-panel.c @@ -27,7 +27,7 @@ #include #include "shell/cc-object-storage.h" -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "cc-region-panel.h" #include "cc-region-resources.h" #include "cc-language-chooser.h" diff --git a/panels/search/cc-search-locations-dialog.c b/panels/search/cc-search-locations-dialog.c index 3d2ec8a47..132754722 100644 --- a/panels/search/cc-search-locations-dialog.c +++ b/panels/search/cc-search-locations-dialog.c @@ -19,7 +19,7 @@ */ #include "cc-search-locations-dialog.h" -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include diff --git a/panels/search/cc-search-panel.c b/panels/search/cc-search-panel.c index 67e722556..7c5051ae2 100644 --- a/panels/search/cc-search-panel.c +++ b/panels/search/cc-search-panel.c @@ -21,7 +21,7 @@ #include "cc-search-panel.h" #include "cc-search-locations-dialog.h" #include "cc-search-resources.h" -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include #include diff --git a/panels/search/meson.build b/panels/search/meson.build index 0081674c4..f8663fb65 100644 --- a/panels/search/meson.build +++ b/panels/search/meson.build @@ -43,7 +43,7 @@ cflags += [ panels_libs += static_library( cappletname, sources: sources, - include_directories: top_inc, + include_directories: [ top_inc, common_inc ], dependencies: common_deps, c_args: cflags ) diff --git a/panels/sharing/cc-sharing-networks.c b/panels/sharing/cc-sharing-networks.c index d703af5bc..d97f811ea 100644 --- a/panels/sharing/cc-sharing-networks.c +++ b/panels/sharing/cc-sharing-networks.c @@ -26,7 +26,7 @@ #include "cc-sharing-networks.h" #include "org.gnome.SettingsDaemon.Sharing.h" #include "gsd-sharing-enums.h" -#include "shell/list-box-helper.h" +#include "list-box-helper.h" struct _CcSharingNetworksPrivate { GtkWidget *listbox; diff --git a/panels/sharing/cc-sharing-panel.c b/panels/sharing/cc-sharing-panel.c index 8b35c9a31..1352f7e8f 100644 --- a/panels/sharing/cc-sharing-panel.c +++ b/panels/sharing/cc-sharing-panel.c @@ -20,9 +20,9 @@ */ #include "cc-sharing-panel.h" -#include "shell/cc-hostname-entry.h" +#include "cc-hostname-entry.h" -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "cc-sharing-resources.h" #include "vino-preferences.h" #include "cc-remote-login.h" diff --git a/panels/sharing/meson.build b/panels/sharing/meson.build index 5caac36c0..236458171 100644 --- a/panels/sharing/meson.build +++ b/panels/sharing/meson.build @@ -78,7 +78,7 @@ cflags += [ panels_libs += static_library( cappletname, sources: sources, - include_directories: top_inc, + include_directories: [ top_inc, common_inc ], dependencies: common_deps, c_args: cflags ) diff --git a/panels/thunderbolt/cc-bolt-panel.c b/panels/thunderbolt/cc-bolt-panel.c index a162a1f19..a4face5b3 100644 --- a/panels/thunderbolt/cc-bolt-panel.c +++ b/panels/thunderbolt/cc-bolt-panel.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include diff --git a/panels/thunderbolt/meson.build b/panels/thunderbolt/meson.build index e85566157..17e125b5f 100644 --- a/panels/thunderbolt/meson.build +++ b/panels/thunderbolt/meson.build @@ -68,7 +68,7 @@ cflags += [ panels_libs += static_library( cappletname, sources: sources, - include_directories: top_inc, + include_directories: [top_inc, common_inc], dependencies: deps, c_args: cflags ) diff --git a/panels/universal-access/cc-ua-panel.c b/panels/universal-access/cc-ua-panel.c index 23e7d8a56..7a56ee1f3 100644 --- a/panels/universal-access/cc-ua-panel.c +++ b/panels/universal-access/cc-ua-panel.c @@ -27,7 +27,7 @@ #include #include -#include "shell/list-box-helper.h" +#include "list-box-helper.h" #include "cc-ua-panel.h" #include "cc-ua-resources.h" diff --git a/panels/universal-access/meson.build b/panels/universal-access/meson.build index d7983f200..119143654 100644 --- a/panels/universal-access/meson.build +++ b/panels/universal-access/meson.build @@ -47,7 +47,7 @@ cflags += '-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir) panels_libs += static_library( cappletname, sources: sources, - include_directories: top_inc, + include_directories: [ top_inc, common_inc ], dependencies: deps, c_args: cflags ) diff --git a/shell/cc-hostname-entry.c b/shell/cc-hostname-entry.c deleted file mode 100644 index 0b0d6d10c..000000000 --- a/shell/cc-hostname-entry.c +++ /dev/null @@ -1,288 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2013 Intel, Inc - * Copyright (C) 2011,2012 Red Hat, Inc - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - */ - - -#include "cc-hostname-entry.h" -#include "hostname-helper.h" - -#include - -struct _CcHostnameEntry -{ - GtkEntry parent; - - GDBusProxy *hostnamed_proxy; - guint set_hostname_timeout_source_id; -}; - -G_DEFINE_TYPE (CcHostnameEntry, cc_hostname_entry, GTK_TYPE_ENTRY) - -#define SET_HOSTNAME_TIMEOUT 1 - -static void -cc_hostname_entry_set_hostname (CcHostnameEntry *self) -{ - char *hostname; - GVariant *variant; - GError *error = NULL; - const gchar *text; - - text = gtk_entry_get_text (GTK_ENTRY (self)); - - g_debug ("Setting PrettyHostname to '%s'", text); - variant = g_dbus_proxy_call_sync (self->hostnamed_proxy, - "SetPrettyHostname", - g_variant_new ("(sb)", text, FALSE), - G_DBUS_CALL_FLAGS_NONE, - -1, NULL, &error); - if (variant == NULL) - { - g_warning ("Could not set PrettyHostname: %s", error->message); - g_error_free (error); - error = NULL; - } - else - { - g_variant_unref (variant); - } - - /* Set the static hostname */ - hostname = pretty_hostname_to_static (text, FALSE); - g_assert (hostname); - - g_debug ("Setting StaticHostname to '%s'", hostname); - variant = g_dbus_proxy_call_sync (self->hostnamed_proxy, - "SetStaticHostname", - g_variant_new ("(sb)", hostname, FALSE), - G_DBUS_CALL_FLAGS_NONE, - -1, NULL, &error); - if (variant == NULL) - { - g_warning ("Could not set StaticHostname: %s", error->message); - g_error_free (error); - } - else - { - g_variant_unref (variant); - } - g_free (hostname); -} - -static char * -get_hostname_property (CcHostnameEntry *self, - const char *property) -{ - GVariant *variant; - char *str; - - if (!self->hostnamed_proxy) - return g_strdup (""); - - variant = g_dbus_proxy_get_cached_property (self->hostnamed_proxy, - property); - if (!variant) - { - GError *error = NULL; - GVariant *inner; - - /* Work around systemd-hostname not sending us back - * the property value when changing values */ - variant = g_dbus_proxy_call_sync (self->hostnamed_proxy, - "org.freedesktop.DBus.Properties.Get", - g_variant_new ("(ss)", "org.freedesktop.hostname1", property), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (variant == NULL) - { - g_warning ("Failed to get property '%s': %s", property, error->message); - g_error_free (error); - return NULL; - } - - g_variant_get (variant, "(v)", &inner); - str = g_variant_dup_string (inner, NULL); - g_variant_unref (variant); - } - else - { - str = g_variant_dup_string (variant, NULL); - g_variant_unref (variant); - } - - return str; -} - -static char * -cc_hostname_entry_get_display_hostname (CcHostnameEntry *self) -{ - char *str; - - str = get_hostname_property (self, "PrettyHostname"); - - /* Empty strings means that we need to fallback */ - if (str != NULL && - *str == '\0') - { - g_free (str); - str = get_hostname_property (self, "Hostname"); - } - - return str; -} - -static gboolean -set_hostname_timeout (CcHostnameEntry *self) -{ - self->set_hostname_timeout_source_id = 0; - - cc_hostname_entry_set_hostname (self); - - return FALSE; -} - -static void -remove_hostname_timeout (CcHostnameEntry *self) -{ - if (self->set_hostname_timeout_source_id) - g_source_remove (self->set_hostname_timeout_source_id); - - self->set_hostname_timeout_source_id = 0; -} - -static void -reset_hostname_timeout (CcHostnameEntry *self) -{ - remove_hostname_timeout (self); - - self->set_hostname_timeout_source_id = g_timeout_add_seconds (SET_HOSTNAME_TIMEOUT, - (GSourceFunc) set_hostname_timeout, - self); -} - -static void -text_changed_cb (CcHostnameEntry *entry) -{ - reset_hostname_timeout (entry); -} - -static void -cc_hostname_entry_dispose (GObject *object) -{ - CcHostnameEntry *self = CC_HOSTNAME_ENTRY (object); - - if (self->set_hostname_timeout_source_id) - { - remove_hostname_timeout (self); - set_hostname_timeout (self); - } - - g_clear_object (&self->hostnamed_proxy); - - G_OBJECT_CLASS (cc_hostname_entry_parent_class)->dispose (object); -} - -static void -cc_hostname_entry_constructed (GObject *object) -{ - CcHostnameEntry *self = CC_HOSTNAME_ENTRY (object); - GPermission *permission; - GError *error = NULL; - char *str; - - permission = polkit_permission_new_sync ("org.freedesktop.hostname1.set-static-hostname", - NULL, NULL, NULL); - - /* Is hostnamed installed? */ - if (permission == NULL) - { - g_debug ("Will not show hostname, hostnamed not installed"); - - gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE); - - return; - } - - if (g_permission_get_allowed (permission)) - gtk_widget_set_sensitive (GTK_WIDGET (self), TRUE); - else - { - g_debug ("Not allowed to change the hostname"); - gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE); - } - - gtk_widget_set_sensitive (GTK_WIDGET (self), - g_permission_get_allowed (permission)); - - self->hostnamed_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.freedesktop.hostname1", - "/org/freedesktop/hostname1", - "org.freedesktop.hostname1", - NULL, - &error); - - /* This could only happen if the policy file was installed - * but not hostnamed, which points to a system bug */ - if (self->hostnamed_proxy == NULL) - { - g_debug ("Couldn't get hostnamed to start, bailing: %s", error->message); - g_error_free (error); - return; - } - - str = cc_hostname_entry_get_display_hostname (CC_HOSTNAME_ENTRY (self)); - - if (str != NULL) - gtk_entry_set_text (GTK_ENTRY (self), str); - else - gtk_entry_set_text (GTK_ENTRY (self), ""); - g_free (str); - - g_signal_connect (G_OBJECT (self), "changed", G_CALLBACK (text_changed_cb), self); -} - -static void -cc_hostname_entry_class_init (CcHostnameEntryClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->constructed = cc_hostname_entry_constructed; - object_class->dispose = cc_hostname_entry_dispose; -} - -static void -cc_hostname_entry_init (CcHostnameEntry *self) -{ -} - -CcHostnameEntry * -cc_hostname_entry_new (void) -{ - return g_object_new (CC_TYPE_HOSTNAME_ENTRY, NULL); -} - -gchar* -cc_hostname_entry_get_hostname (CcHostnameEntry *entry) -{ - return get_hostname_property (entry, "Hostname"); -} diff --git a/shell/cc-hostname-entry.h b/shell/cc-hostname-entry.h deleted file mode 100644 index a48177961..000000000 --- a/shell/cc-hostname-entry.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2013 Intel, Inc - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - */ - -#pragma once - -#include - -G_BEGIN_DECLS - -#define CC_TYPE_HOSTNAME_ENTRY (cc_hostname_entry_get_type()) - -G_DECLARE_FINAL_TYPE (CcHostnameEntry, cc_hostname_entry, CC, HOSTNAME_ENTRY, GtkEntry) - -CcHostnameEntry *cc_hostname_entry_new (void); -gchar* cc_hostname_entry_get_hostname (CcHostnameEntry *entry); - -G_END_DECLS diff --git a/shell/hostname-helper.c b/shell/hostname-helper.c deleted file mode 100644 index df596975e..000000000 --- a/shell/hostname-helper.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (C) 2011 Red Hat, Inc - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - */ - -#include -#include -#include - -#include "hostname-helper.h" - -static char * -allowed_chars (void) -{ - GString *s; - char i; - - s = g_string_new (NULL); - for (i = 'a'; i <= 'z'; i++) - g_string_append_c (s, i); - for (i = 'A'; i <= 'Z'; i++) - g_string_append_c (s, i); - for (i = '0'; i <= '9'; i++) - g_string_append_c (s, i); - g_string_append_c (s, '-'); - - return g_string_free (s, FALSE); -} - -static char * -remove_leading_dashes (char *input) -{ - char *start; - - for (start = input; *start && (*start == '-'); start++) - ; - - g_memmove (input, start, strlen (start) + 1); - - return input; -} - -static gboolean -is_empty (const char *input) -{ - if (input == NULL || - *input == '\0') - return TRUE; - return FALSE; -} - -static char * -remove_trailing_dashes (char *input) -{ - int len; - - len = strlen (input); - while (len--) { - if (input[len] == '-') - input[len] = '\0'; - else - break; - } - return input; -} - -static char * -remove_apostrophes (char *input) -{ - char *apo; - - while ((apo = strchr (input, '\'')) != NULL) - g_memmove (apo, apo + 1, strlen (apo)); - return input; -} - -static char * -remove_duplicate_dashes (char *input) -{ - char *dashes; - - while ((dashes = strstr (input, "--")) != NULL) - g_memmove (dashes, dashes + 1, strlen (dashes)); - return input; -} - -#define CHECK if (is_empty (result)) goto bail - -char * -pretty_hostname_to_static (const char *pretty, - gboolean for_display) -{ - char *result; - char *valid_chars; - char *composed; - - g_return_val_if_fail (pretty != NULL, NULL); - g_return_val_if_fail (g_utf8_validate (pretty, -1, NULL), NULL); - - g_debug ("Input: '%s'", pretty); - - composed = g_utf8_normalize (pretty, -1, G_NORMALIZE_ALL_COMPOSE); - g_debug ("\tcomposed: '%s'", composed); - /* Transform the pretty hostname to ASCII */ - result = g_str_to_ascii (composed, NULL); - g_debug ("\ttranslit: '%s'", result); - g_free (composed); - - CHECK; - - /* Remove apostrophes */ - result = remove_apostrophes (result); - g_debug ("\tapostrophes: '%s'", result); - - CHECK; - - /* Remove all the not-allowed chars */ - valid_chars = allowed_chars (); - result = g_strcanon (result, valid_chars, '-'); - g_free (valid_chars); - g_debug ("\tcanon: '%s'", result); - - CHECK; - - /* Remove the leading dashes */ - result = remove_leading_dashes (result); - g_debug ("\tleading: '%s'", result); - - CHECK; - - /* Remove trailing dashes */ - result = remove_trailing_dashes (result); - g_debug ("\ttrailing: '%s'", result); - - CHECK; - - /* Remove duplicate dashes */ - result = remove_duplicate_dashes (result); - g_debug ("\tduplicate: '%s'", result); - - CHECK; - - /* Lower case */ - if (!for_display) { - char *tmp; - - tmp = g_ascii_strdown (result, -1); - g_free (result); - result = tmp; - } - - return result; - -bail: - g_free (result); - return g_strdup ("localhost"); -} -#undef CHECK - -/* Max length of an SSID in bytes */ -#define SSID_MAX_LEN 32 -char * -pretty_hostname_to_ssid (const char *pretty) -{ - const char *p, *prev; - char *ret = NULL; - - if (pretty == NULL || *pretty == '\0') { - pretty = g_get_host_name (); - if (g_strcmp0 (pretty, "localhost") == 0) - pretty = NULL; - } - - if (pretty == NULL) { - /* translators: This is the default hotspot name, need to be less than 32-bytes */ - ret = g_strdup (C_("hotspot", "Hotspot")); - g_assert (strlen (ret) <= SSID_MAX_LEN); - return ret; - } - - g_return_val_if_fail (g_utf8_validate (pretty, -1, NULL), NULL); - - p = pretty; - prev = NULL; - while ((p = g_utf8_find_next_char (p, NULL)) != NULL) { - if (p == prev) - break; - - if (p - pretty > SSID_MAX_LEN) { - ret = g_strndup (pretty, prev - pretty); - break; - } - if (p - pretty == SSID_MAX_LEN) { - ret = g_strndup (pretty, p - pretty); - break; - } - - if (*p == '\0') - break; - - prev = p; - } - - if (ret == NULL) - ret = g_strdup (pretty); - - return ret; -} diff --git a/shell/hostname-helper.h b/shell/hostname-helper.h deleted file mode 100644 index 9f96c12f9..000000000 --- a/shell/hostname-helper.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2011 Red Hat, Inc - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - */ - -char *pretty_hostname_to_static (const char *pretty, - gboolean for_display); -char *pretty_hostname_to_ssid (const char *pretty); diff --git a/shell/hostnames-test.txt b/shell/hostnames-test.txt deleted file mode 100644 index 5a31ce28b..000000000 --- a/shell/hostnames-test.txt +++ /dev/null @@ -1,11 +0,0 @@ -# Pretty hostname, tab, display hostname, tab, real hostname -Lennart's PC Lennarts-PC lennarts-pc -Müllers Computer Mullers-Computer mullers-computer -Voran! Voran voran -Es war einmal ein Männlein Es-war-einmal-ein-Mannlein es-war-einmal-ein-mannlein -Jawoll. Ist doch wahr! Jawoll-Ist-doch-wahr jawoll-ist-doch-wahr -レナート localhost localhost -!!! localhost localhost -...zack!!! zack!... zack-zack zack-zack -Bãstien's computer... Foo-bar Bastiens-computer-Foo-bar bastiens-computer-foo-bar - localhost localhost diff --git a/shell/list-box-helper.c b/shell/list-box-helper.c deleted file mode 100644 index 415cdde94..000000000 --- a/shell/list-box-helper.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2014 Red Hat, Inc - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - */ - -#include "list-box-helper.h" - -#define MAX_ROWS_VISIBLE 5 - -struct _CcListBoxRow -{ - GtkListBoxRow parent_instance; -}; -G_DEFINE_TYPE (CcListBoxRow, cc_list_box_row, GTK_TYPE_LIST_BOX_ROW) -enum -{ - BOX_ROW_ACTIVATED, - LAST_BOX_ROW_SIGNAL -}; -static guint cc_list_box_row_signals[LAST_BOX_ROW_SIGNAL] = { 0 }; -static void -cc_list_box_row_class_init (CcListBoxRowClass *klass) -{ - cc_list_box_row_signals[BOX_ROW_ACTIVATED] = - g_signal_new ("activated", - CC_TYPE_LIST_BOX_ROW, - G_SIGNAL_RUN_LAST, - 0, NULL, NULL, NULL, - G_TYPE_NONE, 0); -} -static void cc_list_box_row_init (CcListBoxRow *self) {} - -struct _CcListBox -{ - GtkListBox parent_instance; -}; -G_DEFINE_TYPE (CcListBox, cc_list_box, GTK_TYPE_LIST_BOX) -static void -cc_list_box_row_activated (GtkListBox *box, GtkListBoxRow *row) -{ - if (CC_IS_LIST_BOX_ROW (row)) - g_signal_emit (row, cc_list_box_row_signals[BOX_ROW_ACTIVATED], 0); -} -static void -cc_list_box_class_init (CcListBoxClass *klass) -{ - GtkListBoxClass *parent_class = GTK_LIST_BOX_CLASS (klass); - parent_class->row_activated = cc_list_box_row_activated; -} -static void cc_list_box_init (CcListBox *self) {} - - -void -cc_list_box_update_header_func (GtkListBoxRow *row, - GtkListBoxRow *before, - gpointer user_data) -{ - GtkWidget *current; - - if (before == NULL) - { - gtk_list_box_row_set_header (row, NULL); - return; - } - - current = gtk_list_box_row_get_header (row); - if (current == NULL) - { - current = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); - gtk_widget_show (current); - gtk_list_box_row_set_header (row, current); - } -} - -void -cc_list_box_adjust_scrolling (GtkListBox *listbox) -{ - GtkWidget *scrolled_window; - GList *children; - guint n_rows, num_max_rows; - - scrolled_window = g_object_get_data (G_OBJECT (listbox), "cc-scrolling-scrolled-window"); - if (!scrolled_window) - return; - - children = gtk_container_get_children (GTK_CONTAINER (listbox)); - n_rows = g_list_length (children); - - num_max_rows = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (listbox), "cc-max-rows-visible")); - - if (n_rows >= num_max_rows) - { - gint total_row_height = 0; - GList *l; - guint i; - - for (l = children, i = 0; l != NULL && i < num_max_rows; l = l->next, i++) { - gint row_height; - gtk_widget_get_preferred_height (GTK_WIDGET (l->data), &row_height, NULL); - total_row_height += row_height; - } - - gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (scrolled_window), total_row_height); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - } - else - { - gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (scrolled_window), -1); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), - GTK_POLICY_NEVER, GTK_POLICY_NEVER); - } - - g_list_free (children); -} - -void -cc_list_box_setup_scrolling (GtkListBox *listbox, - guint num_max_rows) -{ - GtkWidget *parent; - GtkWidget *scrolled_window; - - parent = gtk_widget_get_parent (GTK_WIDGET (listbox)); - scrolled_window = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_show (scrolled_window); - - g_object_ref (listbox); - gtk_container_remove (GTK_CONTAINER (parent), GTK_WIDGET (listbox)); - gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (listbox)); - g_object_unref (listbox); - - gtk_container_add (GTK_CONTAINER (parent), scrolled_window); - - if (num_max_rows == 0) - num_max_rows = MAX_ROWS_VISIBLE; - - g_object_set_data (G_OBJECT (listbox), "cc-scrolling-scrolled-window", scrolled_window); - g_object_set_data (G_OBJECT (listbox), "cc-max-rows-visible", GUINT_TO_POINTER (num_max_rows)); -} diff --git a/shell/list-box-helper.h b/shell/list-box-helper.h deleted file mode 100644 index c2a0acc97..000000000 --- a/shell/list-box-helper.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2014 Red Hat, Inc - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see . - * - */ - -#include - -#define CC_TYPE_LIST_BOX_ROW (cc_list_box_row_get_type ()) -G_DECLARE_FINAL_TYPE (CcListBoxRow, cc_list_box_row, CC, LIST_BOX_ROW, GtkListBoxRow) - -#define CC_TYPE_LIST_BOX (cc_list_box_get_type ()) -G_DECLARE_FINAL_TYPE (CcListBox, cc_list_box, CC, LIST_BOX, GtkListBox) - -void -cc_list_box_update_header_func (GtkListBoxRow *row, - GtkListBoxRow *before, - gpointer user_data); - -void -cc_list_box_adjust_scrolling (GtkListBox *listbox); - -void -cc_list_box_setup_scrolling (GtkListBox *listbox, - guint num_rows); diff --git a/shell/meson.build b/shell/meson.build index d092ccb7c..942595127 100644 --- a/shell/meson.build +++ b/shell/meson.build @@ -42,9 +42,8 @@ libshell = static_library( c_args: cflags ) -common_sources = files( +sources = files( 'cc-application.c', - 'cc-hostname-entry.c', 'cc-log.c', 'cc-object-storage.c', 'cc-panel-loader.c', @@ -52,8 +51,6 @@ common_sources = files( 'cc-shell-category-view.c', 'cc-shell-item-view.c', 'cc-shell.c', - 'hostname-helper.c', - 'list-box-helper.c', 'main.c' ) @@ -63,14 +60,14 @@ resource_data = files( 'window.ui' ) -common_sources += gnome.compile_resources( +sources += gnome.compile_resources( 'resources', meson.project_name() + '.gresource.xml', dependencies: resource_data, export: true ) -sources = common_sources + files( +sources += files( 'cc-panel-list.c', 'cc-window.c' ) @@ -78,7 +75,7 @@ sources = common_sources + files( shell_deps = common_deps + [ libdevice_dep, liblanguage_dep, - polkit_gobject_dep, + libwidgets_dep, x11_dep ] @@ -122,27 +119,5 @@ libpanel_loader = static_library( c_args: cflags + ['-DCC_PANEL_LOADER_NO_GTYPES'] ) -test_unit = 'test-hostname' - -sources = files( - 'hostname-helper.c', - test_unit + '.c' -) - -cflags += [ - '-DTEST_SRCDIR="@0@"'.format(meson.current_source_dir()), - '-DTEST_TOPSRCDIR="@0@"'.format(meson.source_root()) -] - -exe = executable( - test_unit, - sources, - include_directories: top_inc, - dependencies: common_deps, - c_args: cflags -) - -test(test_unit, exe) - install_data ('org.gnome.ControlCenter.gschema.xml', install_dir: control_center_schemadir) diff --git a/shell/ssids-test.txt b/shell/ssids-test.txt deleted file mode 100644 index 0545437cf..000000000 --- a/shell/ssids-test.txt +++ /dev/null @@ -1,3 +0,0 @@ -GNOME GNOME -0123456789abcdefghijklmnopqrstuvwxyz 0123456789abcdefghijklmnopqrstuv -レナート レナート diff --git a/shell/test-hostname.c b/shell/test-hostname.c deleted file mode 100644 index 3df293051..000000000 --- a/shell/test-hostname.c +++ /dev/null @@ -1,136 +0,0 @@ -#include "config.h" - -#include -#include -#include - -#include "hostname-helper.h" - -static void -test_hostname (void) -{ - char *contents; - char *result; - guint i; - char **lines; - - if (g_file_get_contents (TEST_SRCDIR "/hostnames-test.txt", &contents, NULL, NULL) == FALSE) { - g_warning ("Failed to load '%s'", TEST_SRCDIR "/hostnames-test.txt"); - g_test_fail (); - return; - } - - lines = g_strsplit (contents, "\n", -1); - if (lines == NULL) { - g_warning ("Test file is empty"); - g_test_fail (); - return; - } - - for (i = 0; lines[i] != NULL; i++) { - char *utf8; - char **items; - - if (*lines[i] == '#') - continue; - if (*lines[i] == '\0') - break; - - items = g_strsplit (lines[i], "\t", -1); - utf8 = g_locale_from_utf8 (items[0], -1, NULL, NULL, NULL); - result = pretty_hostname_to_static (items[0], FALSE); - if (g_strcmp0 (result, items[2]) != 0) { - g_error ("Result for '%s' doesn't match '%s' (got: '%s')", - utf8, items[2], result); - g_test_fail (); - } else { - g_debug ("Result for '%s' matches '%s'", - utf8, result); - } - g_free (result); - g_free (utf8); - - result = pretty_hostname_to_static (items[0], TRUE); - utf8 = g_locale_from_utf8 (items[0], -1, NULL, NULL, NULL); - if (g_strcmp0 (result, items[1]) != 0) { - g_error ("Result for '%s' doesn't match '%s' (got: '%s')", - utf8, items[1], result); - g_test_fail (); - } else { - g_debug ("Result for '%s' matches '%s'", - utf8, result); - } - g_free (result); - g_free (utf8); - - g_strfreev (items); - } - - g_strfreev (lines); - g_free (contents); -} - -static void -test_ssid (void) -{ - char *contents; - guint i; - char **lines; - - if (g_file_get_contents (TEST_SRCDIR "/ssids-test.txt", &contents, NULL, NULL) == FALSE) { - g_warning ("Failed to load '%s'", TEST_SRCDIR "/ssids-test.txt"); - g_test_fail (); - return; - } - - lines = g_strsplit (contents, "\n", -1); - if (lines == NULL) { - g_warning ("Test file is empty"); - g_test_fail (); - return; - } - - for (i = 0; lines[i] != NULL; i++) { - char *ssid; - char **items; - - if (*lines[i] == '#') - continue; - if (*lines[i] == '\0') - break; - - items = g_strsplit (lines[i], "\t", -1); - ssid = pretty_hostname_to_ssid (items[0]); - g_assert_cmpstr (ssid, ==, items[1]); - g_free (ssid); - g_strfreev (items); - } - - g_strfreev (lines); - g_free (contents); -} - -int main (int argc, char **argv) -{ - char *locale; - - /* Running in some locales will - * break the tests as "ü" will be transliterated to - * "ue" in de_DE, and 'u"' in the C locale. - * - * Work around that by forcing en_US with UTF-8 in - * our tests - * https://bugzilla.gnome.org/show_bug.cgi?id=650342 */ - locale = setlocale (LC_ALL, "en_US.UTF-8"); - if (locale == NULL) { - g_debug("Missing en_US.UTF-8 locale, ignoring test."); - return 0; - } - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - g_test_init (&argc, &argv, NULL); - - g_test_add_func ("/shell/hostname", test_hostname); - g_test_add_func ("/shell/ssid", test_ssid); - - return g_test_run (); -} -- cgit v1.2.1 From d2d4980ce8595691c7bdeafc8dcc6e2ea7ceb1db Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 6 Apr 2018 13:46:47 +0200 Subject: Move panel/common tests into new tests subdirectory --- meson.build | 2 + panels/common/hostnames-test.txt | 11 ---- panels/common/meson.build | 22 ------- panels/common/ssids-test.txt | 3 - panels/common/test-hostname.c | 136 --------------------------------------- tests/common/hostnames-test.txt | 11 ++++ tests/common/meson.build | 23 +++++++ tests/common/ssids-test.txt | 3 + tests/common/test-hostname.c | 136 +++++++++++++++++++++++++++++++++++++++ tests/meson.build | 1 + 10 files changed, 176 insertions(+), 172 deletions(-) delete mode 100644 panels/common/hostnames-test.txt delete mode 100644 panels/common/ssids-test.txt delete mode 100644 panels/common/test-hostname.c create mode 100644 tests/common/hostnames-test.txt create mode 100644 tests/common/meson.build create mode 100644 tests/common/ssids-test.txt create mode 100644 tests/common/test-hostname.c create mode 100644 tests/meson.build diff --git a/meson.build b/meson.build index ae1a897b3..1b947ab01 100644 --- a/meson.build +++ b/meson.build @@ -255,6 +255,8 @@ subdir('panels') subdir('shell') subdir('search-provider') +subdir('tests') + if get_option('documentation') subdir('man') endif diff --git a/panels/common/hostnames-test.txt b/panels/common/hostnames-test.txt deleted file mode 100644 index 5a31ce28b..000000000 --- a/panels/common/hostnames-test.txt +++ /dev/null @@ -1,11 +0,0 @@ -# Pretty hostname, tab, display hostname, tab, real hostname -Lennart's PC Lennarts-PC lennarts-pc -Müllers Computer Mullers-Computer mullers-computer -Voran! Voran voran -Es war einmal ein Männlein Es-war-einmal-ein-Mannlein es-war-einmal-ein-mannlein -Jawoll. Ist doch wahr! Jawoll-Ist-doch-wahr jawoll-ist-doch-wahr -レナート localhost localhost -!!! localhost localhost -...zack!!! zack!... zack-zack zack-zack -Bãstien's computer... Foo-bar Bastiens-computer-Foo-bar bastiens-computer-foo-bar - localhost localhost diff --git a/panels/common/meson.build b/panels/common/meson.build index 42594360f..e9451e6d6 100644 --- a/panels/common/meson.build +++ b/panels/common/meson.build @@ -139,25 +139,3 @@ run_target( command: script ) - -test_unit = 'test-hostname' - -sources = files( - 'hostname-helper.c', - test_unit + '.c' -) - -cflags = [ - '-DTEST_SRCDIR="@0@"'.format(meson.current_source_dir()), - '-DTEST_TOPSRCDIR="@0@"'.format(meson.source_root()) -] - -exe = executable( - test_unit, - sources, - include_directories: top_inc, - dependencies: [ common_deps, libwidgets_dep ], - c_args: cflags -) - -test(test_unit, exe) diff --git a/panels/common/ssids-test.txt b/panels/common/ssids-test.txt deleted file mode 100644 index 0545437cf..000000000 --- a/panels/common/ssids-test.txt +++ /dev/null @@ -1,3 +0,0 @@ -GNOME GNOME -0123456789abcdefghijklmnopqrstuvwxyz 0123456789abcdefghijklmnopqrstuv -レナート レナート diff --git a/panels/common/test-hostname.c b/panels/common/test-hostname.c deleted file mode 100644 index 4e14f715a..000000000 --- a/panels/common/test-hostname.c +++ /dev/null @@ -1,136 +0,0 @@ -#include "config.h" - -#include -#include -#include - -#include "hostname-helper.h" - -static void -test_hostname (void) -{ - char *contents; - char *result; - guint i; - char **lines; - - if (g_file_get_contents (TEST_SRCDIR "/hostnames-test.txt", &contents, NULL, NULL) == FALSE) { - g_warning ("Failed to load '%s'", TEST_SRCDIR "/hostnames-test.txt"); - g_test_fail (); - return; - } - - lines = g_strsplit (contents, "\n", -1); - if (lines == NULL) { - g_warning ("Test file is empty"); - g_test_fail (); - return; - } - - for (i = 0; lines[i] != NULL; i++) { - char *utf8; - char **items; - - if (*lines[i] == '#') - continue; - if (*lines[i] == '\0') - break; - - items = g_strsplit (lines[i], "\t", -1); - utf8 = g_locale_from_utf8 (items[0], -1, NULL, NULL, NULL); - result = pretty_hostname_to_static (items[0], FALSE); - if (g_strcmp0 (result, items[2]) != 0) { - g_error ("Result for '%s' doesn't match '%s' (got: '%s')", - utf8, items[2], result); - g_test_fail (); - } else { - g_debug ("Result for '%s' matches '%s'", - utf8, result); - } - g_free (result); - g_free (utf8); - - result = pretty_hostname_to_static (items[0], TRUE); - utf8 = g_locale_from_utf8 (items[0], -1, NULL, NULL, NULL); - if (g_strcmp0 (result, items[1]) != 0) { - g_error ("Result for '%s' doesn't match '%s' (got: '%s')", - utf8, items[1], result); - g_test_fail (); - } else { - g_debug ("Result for '%s' matches '%s'", - utf8, result); - } - g_free (result); - g_free (utf8); - - g_strfreev (items); - } - - g_strfreev (lines); - g_free (contents); -} - -static void -test_ssid (void) -{ - char *contents; - guint i; - char **lines; - - if (g_file_get_contents (TEST_SRCDIR "/ssids-test.txt", &contents, NULL, NULL) == FALSE) { - g_warning ("Failed to load '%s'", TEST_SRCDIR "/ssids-test.txt"); - g_test_fail (); - return; - } - - lines = g_strsplit (contents, "\n", -1); - if (lines == NULL) { - g_warning ("Test file is empty"); - g_test_fail (); - return; - } - - for (i = 0; lines[i] != NULL; i++) { - char *ssid; - char **items; - - if (*lines[i] == '#') - continue; - if (*lines[i] == '\0') - break; - - items = g_strsplit (lines[i], "\t", -1); - ssid = pretty_hostname_to_ssid (items[0]); - g_assert_cmpstr (ssid, ==, items[1]); - g_free (ssid); - g_strfreev (items); - } - - g_strfreev (lines); - g_free (contents); -} - -int main (int argc, char **argv) -{ - char *locale; - - /* Running in some locales will - * break the tests as "ü" will be transliterated to - * "ue" in de_DE, and 'u"' in the C locale. - * - * Work around that by forcing en_US with UTF-8 in - * our tests - * https://bugzilla.gnome.org/show_bug.cgi?id=650342 */ - locale = setlocale (LC_ALL, "en_US.UTF-8"); - if (locale == NULL) { - g_debug("Missing en_US.UTF-8 locale, ignoring test."); - return 0; - } - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - g_test_init (&argc, &argv, NULL); - - g_test_add_func ("/common/hostname", test_hostname); - g_test_add_func ("/common/ssid", test_ssid); - - return g_test_run (); -} diff --git a/tests/common/hostnames-test.txt b/tests/common/hostnames-test.txt new file mode 100644 index 000000000..5a31ce28b --- /dev/null +++ b/tests/common/hostnames-test.txt @@ -0,0 +1,11 @@ +# Pretty hostname, tab, display hostname, tab, real hostname +Lennart's PC Lennarts-PC lennarts-pc +Müllers Computer Mullers-Computer mullers-computer +Voran! Voran voran +Es war einmal ein Männlein Es-war-einmal-ein-Mannlein es-war-einmal-ein-mannlein +Jawoll. Ist doch wahr! Jawoll-Ist-doch-wahr jawoll-ist-doch-wahr +レナート localhost localhost +!!! localhost localhost +...zack!!! zack!... zack-zack zack-zack +Bãstien's computer... Foo-bar Bastiens-computer-Foo-bar bastiens-computer-foo-bar + localhost localhost diff --git a/tests/common/meson.build b/tests/common/meson.build new file mode 100644 index 000000000..7fb2cdc23 --- /dev/null +++ b/tests/common/meson.build @@ -0,0 +1,23 @@ + + +test_unit = 'test-hostname' + +sources = files( + test_unit + '.c' +) + +cflags = [ + '-DTEST_SRCDIR="@0@"'.format(meson.current_source_dir()), + '-DTEST_TOPSRCDIR="@0@"'.format(meson.source_root()) +] + +exe = executable( + test_unit, + sources, + include_directories: [ top_inc, common_inc ], + dependencies: common_deps + [libwidgets_dep], + c_args: cflags, +) + +test(test_unit, exe) + diff --git a/tests/common/ssids-test.txt b/tests/common/ssids-test.txt new file mode 100644 index 000000000..0545437cf --- /dev/null +++ b/tests/common/ssids-test.txt @@ -0,0 +1,3 @@ +GNOME GNOME +0123456789abcdefghijklmnopqrstuvwxyz 0123456789abcdefghijklmnopqrstuv +レナート レナート diff --git a/tests/common/test-hostname.c b/tests/common/test-hostname.c new file mode 100644 index 000000000..4e14f715a --- /dev/null +++ b/tests/common/test-hostname.c @@ -0,0 +1,136 @@ +#include "config.h" + +#include +#include +#include + +#include "hostname-helper.h" + +static void +test_hostname (void) +{ + char *contents; + char *result; + guint i; + char **lines; + + if (g_file_get_contents (TEST_SRCDIR "/hostnames-test.txt", &contents, NULL, NULL) == FALSE) { + g_warning ("Failed to load '%s'", TEST_SRCDIR "/hostnames-test.txt"); + g_test_fail (); + return; + } + + lines = g_strsplit (contents, "\n", -1); + if (lines == NULL) { + g_warning ("Test file is empty"); + g_test_fail (); + return; + } + + for (i = 0; lines[i] != NULL; i++) { + char *utf8; + char **items; + + if (*lines[i] == '#') + continue; + if (*lines[i] == '\0') + break; + + items = g_strsplit (lines[i], "\t", -1); + utf8 = g_locale_from_utf8 (items[0], -1, NULL, NULL, NULL); + result = pretty_hostname_to_static (items[0], FALSE); + if (g_strcmp0 (result, items[2]) != 0) { + g_error ("Result for '%s' doesn't match '%s' (got: '%s')", + utf8, items[2], result); + g_test_fail (); + } else { + g_debug ("Result for '%s' matches '%s'", + utf8, result); + } + g_free (result); + g_free (utf8); + + result = pretty_hostname_to_static (items[0], TRUE); + utf8 = g_locale_from_utf8 (items[0], -1, NULL, NULL, NULL); + if (g_strcmp0 (result, items[1]) != 0) { + g_error ("Result for '%s' doesn't match '%s' (got: '%s')", + utf8, items[1], result); + g_test_fail (); + } else { + g_debug ("Result for '%s' matches '%s'", + utf8, result); + } + g_free (result); + g_free (utf8); + + g_strfreev (items); + } + + g_strfreev (lines); + g_free (contents); +} + +static void +test_ssid (void) +{ + char *contents; + guint i; + char **lines; + + if (g_file_get_contents (TEST_SRCDIR "/ssids-test.txt", &contents, NULL, NULL) == FALSE) { + g_warning ("Failed to load '%s'", TEST_SRCDIR "/ssids-test.txt"); + g_test_fail (); + return; + } + + lines = g_strsplit (contents, "\n", -1); + if (lines == NULL) { + g_warning ("Test file is empty"); + g_test_fail (); + return; + } + + for (i = 0; lines[i] != NULL; i++) { + char *ssid; + char **items; + + if (*lines[i] == '#') + continue; + if (*lines[i] == '\0') + break; + + items = g_strsplit (lines[i], "\t", -1); + ssid = pretty_hostname_to_ssid (items[0]); + g_assert_cmpstr (ssid, ==, items[1]); + g_free (ssid); + g_strfreev (items); + } + + g_strfreev (lines); + g_free (contents); +} + +int main (int argc, char **argv) +{ + char *locale; + + /* Running in some locales will + * break the tests as "ü" will be transliterated to + * "ue" in de_DE, and 'u"' in the C locale. + * + * Work around that by forcing en_US with UTF-8 in + * our tests + * https://bugzilla.gnome.org/show_bug.cgi?id=650342 */ + locale = setlocale (LC_ALL, "en_US.UTF-8"); + if (locale == NULL) { + g_debug("Missing en_US.UTF-8 locale, ignoring test."); + return 0; + } + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/common/hostname", test_hostname); + g_test_add_func ("/common/ssid", test_ssid); + + return g_test_run (); +} diff --git a/tests/meson.build b/tests/meson.build new file mode 100644 index 000000000..1361dd315 --- /dev/null +++ b/tests/meson.build @@ -0,0 +1 @@ +subdir('common') -- cgit v1.2.1 From a9d8ec57475f05249c017427f1372a50a7645a7b Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Sat, 31 Mar 2018 18:24:01 +0200 Subject: Move printers panel tests into tests folder --- panels/printers/canonicalization-test.txt | 16 ---- panels/printers/meson.build | 26 +------ panels/printers/shift-test.txt | 9 --- panels/printers/test-canonicalization.c | 119 ------------------------------ panels/printers/test-shift.c | 95 ------------------------ tests/meson.build | 1 + tests/printers/canonicalization-test.txt | 16 ++++ tests/printers/meson.build | 22 ++++++ tests/printers/shift-test.txt | 9 +++ tests/printers/test-canonicalization.c | 119 ++++++++++++++++++++++++++++++ tests/printers/test-shift.c | 95 ++++++++++++++++++++++++ 11 files changed, 264 insertions(+), 263 deletions(-) delete mode 100644 panels/printers/canonicalization-test.txt delete mode 100644 panels/printers/shift-test.txt delete mode 100644 panels/printers/test-canonicalization.c delete mode 100644 panels/printers/test-shift.c create mode 100644 tests/printers/canonicalization-test.txt create mode 100644 tests/printers/meson.build create mode 100644 tests/printers/shift-test.txt create mode 100644 tests/printers/test-canonicalization.c create mode 100644 tests/printers/test-shift.c diff --git a/panels/printers/canonicalization-test.txt b/panels/printers/canonicalization-test.txt deleted file mode 100644 index 10ceee17d..000000000 --- a/panels/printers/canonicalization-test.txt +++ /dev/null @@ -1,16 +0,0 @@ -# already_present_printer1, space, already_present_printer2, ...., tab, -# new device id, tab, -# new device make and model, tab, -# new device original name, tab, -# new device info, tab, -# canonicalized name -# - stripped leading and trailing spaces -# - characters not in ALLOWED_CHARACTERS replaced by '-' -# - everything behind strings in residues removed -# - leading and trailing '-' removed -# - recurring '-' merged -# - indexed if the name is already in any of given lists -Canon-BJ-30 Canon-BJ-30-2 Canon BJ-30 - CUPS+Gutenprint v5.2.9 Simplified Canon-BJ-30-3 -Canon-BJ-30 HP Business Inkjet 1000, hpcups 3.14.6 HP-Business-Inkjet-1000 - ...A---strange;;printer ;;;;info A-strange-printer-info -HP-Something MFG:HP;MDL:Officejet 7300 series; HP Officejet 7300 series Officejet 7300 series Officejet-7300 diff --git a/panels/printers/meson.build b/panels/printers/meson.build index 6be8590c7..e3d1e8414 100644 --- a/panels/printers/meson.build +++ b/panels/printers/meson.build @@ -66,34 +66,12 @@ deps = common_deps + [ cflags += '-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir) -panels_libs += static_library( +printers_panel_lib = static_library( cappletname, sources: sources, include_directories: [top_inc, common_inc, shell_inc], dependencies: deps, c_args: cflags ) +panels_libs += [ printers_panel_lib ] -test_units = [ - 'test-canonicalization', - 'test-shift' -] - -sources = files( - 'pp-print-device.c', - 'pp-utils.c' -) - -cflags += '-DTEST_SRCDIR="@0@"'.format(meson.current_source_dir()) - -foreach unit: test_units - exe = executable( - unit, - [unit + '.c'] + sources, - include_directories: top_inc, - dependencies: deps, - c_args: cflags - ) - - test(unit, exe) -endforeach diff --git a/panels/printers/shift-test.txt b/panels/printers/shift-test.txt deleted file mode 100644 index b9eced439..000000000 --- a/panels/printers/shift-test.txt +++ /dev/null @@ -1,9 +0,0 @@ -# String, tab, string shifted by 1 position left -Canon anon --JetDirect JetDirect -localhost ocalhost -Šípková Růženka ípková Růženka - space space -[][ ][ -…... ... - diff --git a/panels/printers/test-canonicalization.c b/panels/printers/test-canonicalization.c deleted file mode 100644 index d5556600f..000000000 --- a/panels/printers/test-canonicalization.c +++ /dev/null @@ -1,119 +0,0 @@ -#include "config.h" - -#include -#include -#include - -#include "pp-utils.h" - -static void -test_canonicalization (gconstpointer data) -{ - const char *contents = data; - guint i, j; - char **lines; - - lines = g_strsplit (contents, "\n", -1); - if (lines == NULL) - { - g_warning ("Test file is empty"); - g_test_fail (); - return; - } - - for (i = 0; lines[i] != NULL; i++) - { - char **items; - - if (*lines[i] == '#') - continue; - - if (*lines[i] == '\0') - break; - - items = g_strsplit (lines[i], "\t", -1); - if (g_strv_length (items) == 6) - { - PpPrintDevice *device; - gchar **already_present_printers; - gchar *canonicalized_name; - GList *devices = NULL; - - already_present_printers = g_strsplit (items[0], " ", -1); - - for (j = 0; already_present_printers[j] != NULL; j++) - devices = g_list_append (devices, g_strdup (already_present_printers[j])); - - device = g_object_new (PP_TYPE_PRINT_DEVICE, - "device-id", items[1], - "device-make-and-model", items[2], - "device-original-name", items[3], - "device-info", items[4], - NULL); - - canonicalized_name = - canonicalize_device_name (devices, NULL, NULL, 0, device); - - if (g_strcmp0 (canonicalized_name, items[5]) != 0) - { - g_error ("Result for ('%s', '%s', '%s', '%s') doesn't match '%s' (got: '%s')", - items[1], items[2], items[3], items[4], items[5], canonicalized_name); - g_test_fail (); - } - else - { - g_debug ("Result for ('%s', '%s', '%s', '%s') matches '%s'", - items[1], items[2], items[3], items[4], canonicalized_name); - } - - g_free (canonicalized_name); - g_object_unref (device); - g_list_free_full (devices, (GDestroyNotify) g_free); - g_strfreev (already_present_printers); - } - else - { - g_warning ("Line number %u has not correct number of items!", i); - g_test_fail (); - } - - g_strfreev (items); - } - - g_strfreev (lines); -} - -int -main (int argc, char **argv) -{ - char *locale; - char *contents; - - /* Running in some locales will - * break the tests as "ü" will be transliterated to - * "ue" in de_DE, and 'u"' in the C locale. - * - * Work around that by forcing en_US with UTF-8 in - * our tests - * https://bugzilla.gnome.org/show_bug.cgi?id=650342 */ - - locale = setlocale (LC_ALL, "en_US.UTF-8"); - if (locale == NULL) - { - g_debug("Missing en_US.UTF-8 locale, ignoring test."); - return 0; - } - - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - g_test_init (&argc, &argv, NULL); - - if (g_file_get_contents (TEST_SRCDIR "/canonicalization-test.txt", &contents, NULL, NULL) == FALSE) - { - g_warning ("Failed to load '%s'", TEST_SRCDIR "/canonicalization-test.txt"); - return 1; - } - - g_test_add_data_func ("/printers/canonicalization", contents, test_canonicalization); - - return g_test_run (); -} diff --git a/panels/printers/test-shift.c b/panels/printers/test-shift.c deleted file mode 100644 index e85fe9af3..000000000 --- a/panels/printers/test-shift.c +++ /dev/null @@ -1,95 +0,0 @@ -#include "config.h" - -#include -#include -#include - -#include "pp-utils.h" - -static void -test_shift (gconstpointer data) -{ - const char *contents = data; - guint i; - char *str; - char **lines; - - lines = g_strsplit (contents, "\n", -1); - if (lines == NULL) - { - g_warning ("Test file is empty"); - g_test_fail (); - return; - } - - for (i = 0; lines[i] != NULL; i++) - { - char **items; - char *utf8; - - if (*lines[i] == '#') - continue; - - if (*lines[i] == '\0') - break; - - items = g_strsplit (lines[i], "\t", -1); - str = g_strdup (items[0]); - shift_string_left (str); - utf8 = g_locale_from_utf8 (items[0], -1, NULL, NULL, NULL); - if (g_strcmp0 (str, items[1]) != 0) - { - g_error ("Result for '%s' doesn't match '%s' (got: '%s')", - utf8, items[1], str); - g_test_fail (); - } - else - { - g_debug ("Result for '%s' matches '%s'", - utf8, str); - } - - g_free (str); - g_free (utf8); - - g_strfreev (items); - } - - g_strfreev (lines); - -} - -int -main (int argc, char **argv) -{ - char *locale; - char *contents; - - /* Running in some locales will - * break the tests as "ü" will be transliterated to - * "ue" in de_DE, and 'u"' in the C locale. - * - * Work around that by forcing en_US with UTF-8 in - * our tests - * https://bugzilla.gnome.org/show_bug.cgi?id=650342 */ - - locale = setlocale (LC_ALL, "en_US.UTF-8"); - if (locale == NULL) - { - g_debug("Missing en_US.UTF-8 locale, ignoring test."); - return 0; - } - - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - g_test_init (&argc, &argv, NULL); - - if (g_file_get_contents (TEST_SRCDIR "/shift-test.txt", &contents, NULL, NULL) == FALSE) - { - g_warning ("Failed to load '%s'", TEST_SRCDIR "/shift-test.txt"); - return 1; - } - - g_test_add_data_func ("/printers/shift", contents, test_shift); - - return g_test_run (); -} diff --git a/tests/meson.build b/tests/meson.build index 1361dd315..a3dfffaff 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1 +1,2 @@ subdir('common') +subdir('printers') diff --git a/tests/printers/canonicalization-test.txt b/tests/printers/canonicalization-test.txt new file mode 100644 index 000000000..10ceee17d --- /dev/null +++ b/tests/printers/canonicalization-test.txt @@ -0,0 +1,16 @@ +# already_present_printer1, space, already_present_printer2, ...., tab, +# new device id, tab, +# new device make and model, tab, +# new device original name, tab, +# new device info, tab, +# canonicalized name +# - stripped leading and trailing spaces +# - characters not in ALLOWED_CHARACTERS replaced by '-' +# - everything behind strings in residues removed +# - leading and trailing '-' removed +# - recurring '-' merged +# - indexed if the name is already in any of given lists +Canon-BJ-30 Canon-BJ-30-2 Canon BJ-30 - CUPS+Gutenprint v5.2.9 Simplified Canon-BJ-30-3 +Canon-BJ-30 HP Business Inkjet 1000, hpcups 3.14.6 HP-Business-Inkjet-1000 + ...A---strange;;printer ;;;;info A-strange-printer-info +HP-Something MFG:HP;MDL:Officejet 7300 series; HP Officejet 7300 series Officejet 7300 series Officejet-7300 diff --git a/tests/printers/meson.build b/tests/printers/meson.build new file mode 100644 index 000000000..be7fecbd2 --- /dev/null +++ b/tests/printers/meson.build @@ -0,0 +1,22 @@ + +test_units = [ + 'test-canonicalization', + 'test-shift' +] + +includes = [top_inc, include_directories('../../panels/printers')] +cflags = '-DTEST_SRCDIR="@0@"'.format(meson.current_source_dir()) + +foreach unit: test_units + exe = executable( + unit, + [unit + '.c'], + include_directories: includes, + dependencies: common_deps, + link_with: [printers_panel_lib], + c_args: cflags + ) + + test(unit, exe) +endforeach + diff --git a/tests/printers/shift-test.txt b/tests/printers/shift-test.txt new file mode 100644 index 000000000..b9eced439 --- /dev/null +++ b/tests/printers/shift-test.txt @@ -0,0 +1,9 @@ +# String, tab, string shifted by 1 position left +Canon anon +-JetDirect JetDirect +localhost ocalhost +Šípková Růženka ípková Růženka + space space +[][ ][ +…... ... + diff --git a/tests/printers/test-canonicalization.c b/tests/printers/test-canonicalization.c new file mode 100644 index 000000000..d5556600f --- /dev/null +++ b/tests/printers/test-canonicalization.c @@ -0,0 +1,119 @@ +#include "config.h" + +#include +#include +#include + +#include "pp-utils.h" + +static void +test_canonicalization (gconstpointer data) +{ + const char *contents = data; + guint i, j; + char **lines; + + lines = g_strsplit (contents, "\n", -1); + if (lines == NULL) + { + g_warning ("Test file is empty"); + g_test_fail (); + return; + } + + for (i = 0; lines[i] != NULL; i++) + { + char **items; + + if (*lines[i] == '#') + continue; + + if (*lines[i] == '\0') + break; + + items = g_strsplit (lines[i], "\t", -1); + if (g_strv_length (items) == 6) + { + PpPrintDevice *device; + gchar **already_present_printers; + gchar *canonicalized_name; + GList *devices = NULL; + + already_present_printers = g_strsplit (items[0], " ", -1); + + for (j = 0; already_present_printers[j] != NULL; j++) + devices = g_list_append (devices, g_strdup (already_present_printers[j])); + + device = g_object_new (PP_TYPE_PRINT_DEVICE, + "device-id", items[1], + "device-make-and-model", items[2], + "device-original-name", items[3], + "device-info", items[4], + NULL); + + canonicalized_name = + canonicalize_device_name (devices, NULL, NULL, 0, device); + + if (g_strcmp0 (canonicalized_name, items[5]) != 0) + { + g_error ("Result for ('%s', '%s', '%s', '%s') doesn't match '%s' (got: '%s')", + items[1], items[2], items[3], items[4], items[5], canonicalized_name); + g_test_fail (); + } + else + { + g_debug ("Result for ('%s', '%s', '%s', '%s') matches '%s'", + items[1], items[2], items[3], items[4], canonicalized_name); + } + + g_free (canonicalized_name); + g_object_unref (device); + g_list_free_full (devices, (GDestroyNotify) g_free); + g_strfreev (already_present_printers); + } + else + { + g_warning ("Line number %u has not correct number of items!", i); + g_test_fail (); + } + + g_strfreev (items); + } + + g_strfreev (lines); +} + +int +main (int argc, char **argv) +{ + char *locale; + char *contents; + + /* Running in some locales will + * break the tests as "ü" will be transliterated to + * "ue" in de_DE, and 'u"' in the C locale. + * + * Work around that by forcing en_US with UTF-8 in + * our tests + * https://bugzilla.gnome.org/show_bug.cgi?id=650342 */ + + locale = setlocale (LC_ALL, "en_US.UTF-8"); + if (locale == NULL) + { + g_debug("Missing en_US.UTF-8 locale, ignoring test."); + return 0; + } + + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + g_test_init (&argc, &argv, NULL); + + if (g_file_get_contents (TEST_SRCDIR "/canonicalization-test.txt", &contents, NULL, NULL) == FALSE) + { + g_warning ("Failed to load '%s'", TEST_SRCDIR "/canonicalization-test.txt"); + return 1; + } + + g_test_add_data_func ("/printers/canonicalization", contents, test_canonicalization); + + return g_test_run (); +} diff --git a/tests/printers/test-shift.c b/tests/printers/test-shift.c new file mode 100644 index 000000000..e85fe9af3 --- /dev/null +++ b/tests/printers/test-shift.c @@ -0,0 +1,95 @@ +#include "config.h" + +#include +#include +#include + +#include "pp-utils.h" + +static void +test_shift (gconstpointer data) +{ + const char *contents = data; + guint i; + char *str; + char **lines; + + lines = g_strsplit (contents, "\n", -1); + if (lines == NULL) + { + g_warning ("Test file is empty"); + g_test_fail (); + return; + } + + for (i = 0; lines[i] != NULL; i++) + { + char **items; + char *utf8; + + if (*lines[i] == '#') + continue; + + if (*lines[i] == '\0') + break; + + items = g_strsplit (lines[i], "\t", -1); + str = g_strdup (items[0]); + shift_string_left (str); + utf8 = g_locale_from_utf8 (items[0], -1, NULL, NULL, NULL); + if (g_strcmp0 (str, items[1]) != 0) + { + g_error ("Result for '%s' doesn't match '%s' (got: '%s')", + utf8, items[1], str); + g_test_fail (); + } + else + { + g_debug ("Result for '%s' matches '%s'", + utf8, str); + } + + g_free (str); + g_free (utf8); + + g_strfreev (items); + } + + g_strfreev (lines); + +} + +int +main (int argc, char **argv) +{ + char *locale; + char *contents; + + /* Running in some locales will + * break the tests as "ü" will be transliterated to + * "ue" in de_DE, and 'u"' in the C locale. + * + * Work around that by forcing en_US with UTF-8 in + * our tests + * https://bugzilla.gnome.org/show_bug.cgi?id=650342 */ + + locale = setlocale (LC_ALL, "en_US.UTF-8"); + if (locale == NULL) + { + g_debug("Missing en_US.UTF-8 locale, ignoring test."); + return 0; + } + + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + g_test_init (&argc, &argv, NULL); + + if (g_file_get_contents (TEST_SRCDIR "/shift-test.txt", &contents, NULL, NULL) == FALSE) + { + g_warning ("Failed to load '%s'", TEST_SRCDIR "/shift-test.txt"); + return 1; + } + + g_test_add_data_func ("/printers/shift", contents, test_shift); + + return g_test_run (); +} -- cgit v1.2.1 From 3c76d52e8e5d48c34bb9244829d17903a1007c94 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 3 Apr 2018 17:32:24 +0200 Subject: Move info panel test to tests subdirectory --- panels/info/info-cleanup-test.txt | 8 ---- panels/info/meson.build | 22 +---------- panels/info/test-info-cleanup.c | 81 --------------------------------------- tests/info/info-cleanup-test.txt | 8 ++++ tests/info/meson.build | 21 ++++++++++ tests/info/test-info-cleanup.c | 81 +++++++++++++++++++++++++++++++++++++++ tests/meson.build | 1 + 7 files changed, 113 insertions(+), 109 deletions(-) delete mode 100644 panels/info/info-cleanup-test.txt delete mode 100644 panels/info/test-info-cleanup.c create mode 100644 tests/info/info-cleanup-test.txt create mode 100644 tests/info/meson.build create mode 100644 tests/info/test-info-cleanup.c diff --git a/panels/info/info-cleanup-test.txt b/panels/info/info-cleanup-test.txt deleted file mode 100644 index 29f4e79fc..000000000 --- a/panels/info/info-cleanup-test.txt +++ /dev/null @@ -1,8 +0,0 @@ -Intel(R) Core(TM) i5-4590T CPU @ 2.00GHz Intel® Core i5-4590T CPU @ 2.00GHz -Intel(R) Ivybridge Mobile Intel® Ivybridge Mobile -Intel(R) Ivybridge Mobile Intel® Ivybridge Mobile -Gallium 0.4 on AMD KAVERI AMD® Kaveri -AMD KAVERI (DRM 2.48.0 / 4.9.0-0.rc4.git2.2.fc26.x86_64, LLVM3) AMD® Kaveri -AMD KAVERI (DRM 2.48.0 / 4.9.0-0.rc4.git2.2.fc26.x86_64, LLVM3 AMD® Kaveri -Gallium 0.4 on AMD KAVERI (DRM 2.48.0 / 4.9.0-0.rc4.git2.2.fc26.x86_64, LLVM3) AMD® Kaveri -Gallium 0.4 on AMD KAVERI (DRM 2.48.0 / 4.9.0-0.rc4.git2.2.fc26.x86_64, LLVM3 AMD® Kaveri diff --git a/panels/info/meson.build b/panels/info/meson.build index 6b41706bc..dc1c11cb2 100644 --- a/panels/info/meson.build +++ b/panels/info/meson.build @@ -64,32 +64,14 @@ deps = common_deps + [ dependency('libgtop-2.0') ] -panels_libs += static_library( +info_panel_lib = static_library( cappletname, sources: sources, include_directories: [ top_inc, common_inc ], dependencies: deps, c_args: cflags ) - -test_name = 'test-info-cleanup' - -sources = files( - 'info-cleanup.c', - test_name + '.c' -) - -cflags += ['-DTEST_SRCDIR="@0@"'.format(meson.current_source_dir())] - -exe = executable( - test_name, - sources, - include_directories: top_inc, - dependencies: deps, - c_args: cflags -) - -test(name, exe) +panels_libs += info_panel_lib # FIXME: workaround for updating different sources code input_dir = join_paths(meson.source_root(), '..', 'gnome-settings-daemon', 'plugins', 'housekeeping') diff --git a/panels/info/test-info-cleanup.c b/panels/info/test-info-cleanup.c deleted file mode 100644 index 3e6bebd2e..000000000 --- a/panels/info/test-info-cleanup.c +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- - * - * Copyright (C) 2010 Red Hat, Inc - * Copyright (C) 2008 William Jon McCann - * - * 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 - -#include -#include -#include "info-cleanup.h" - -static void -test_info (void) -{ - g_autofree gchar *contents = NULL; - guint i; - g_auto(GStrv) lines = NULL; - - if (g_file_get_contents (TEST_SRCDIR "/info-cleanup-test.txt", &contents, NULL, NULL) == FALSE) { - g_warning ("Failed to load '%s'", TEST_SRCDIR "/info-cleanup-test.txt"); - g_test_fail (); - return; - } - - lines = g_strsplit (contents, "\n", -1); - if (lines == NULL) { - g_warning ("Test file is empty"); - g_test_fail (); - return; - } - - for (i = 0; lines[i] != NULL; i++) { - g_auto(GStrv) items = NULL; - g_autofree gchar *utf8 = NULL; - g_autofree gchar *result = NULL; - - if (*lines[i] == '#') - continue; - if (*lines[i] == '\0') - break; - - items = g_strsplit (lines[i], "\t", -1); - utf8 = g_locale_from_utf8 (items[0], -1, NULL, NULL, NULL); - result = info_cleanup (items[0]); - if (g_strcmp0 (result, items[1]) != 0) { - g_error ("Result for '%s' doesn't match '%s' (got: '%s')", - utf8, items[1], result); - g_test_fail (); - } else { - g_debug ("Result for '%s' matches '%s'", - utf8, result); - } - } -} - -int main (int argc, char **argv) -{ - setlocale (LC_ALL, ""); - g_test_init (&argc, &argv, NULL); - - g_setenv ("G_DEBUG", "fatal_warnings", FALSE); - - g_test_add_func ("/info/info", test_info); - - return g_test_run (); -} diff --git a/tests/info/info-cleanup-test.txt b/tests/info/info-cleanup-test.txt new file mode 100644 index 000000000..29f4e79fc --- /dev/null +++ b/tests/info/info-cleanup-test.txt @@ -0,0 +1,8 @@ +Intel(R) Core(TM) i5-4590T CPU @ 2.00GHz Intel® Core i5-4590T CPU @ 2.00GHz +Intel(R) Ivybridge Mobile Intel® Ivybridge Mobile +Intel(R) Ivybridge Mobile Intel® Ivybridge Mobile +Gallium 0.4 on AMD KAVERI AMD® Kaveri +AMD KAVERI (DRM 2.48.0 / 4.9.0-0.rc4.git2.2.fc26.x86_64, LLVM3) AMD® Kaveri +AMD KAVERI (DRM 2.48.0 / 4.9.0-0.rc4.git2.2.fc26.x86_64, LLVM3 AMD® Kaveri +Gallium 0.4 on AMD KAVERI (DRM 2.48.0 / 4.9.0-0.rc4.git2.2.fc26.x86_64, LLVM3) AMD® Kaveri +Gallium 0.4 on AMD KAVERI (DRM 2.48.0 / 4.9.0-0.rc4.git2.2.fc26.x86_64, LLVM3 AMD® Kaveri diff --git a/tests/info/meson.build b/tests/info/meson.build new file mode 100644 index 000000000..a495ced94 --- /dev/null +++ b/tests/info/meson.build @@ -0,0 +1,21 @@ + +test_units = [ + 'test-info-cleanup' +] + +includes = [top_inc, include_directories('../../panels/info')] +cflags = '-DTEST_SRCDIR="@0@"'.format(meson.current_source_dir()) + +foreach unit: test_units + exe = executable( + unit, + [unit + '.c'], + include_directories: includes, + dependencies: common_deps, + link_with: [info_panel_lib], + c_args: cflags + ) + + test(unit, exe) +endforeach + diff --git a/tests/info/test-info-cleanup.c b/tests/info/test-info-cleanup.c new file mode 100644 index 000000000..3e6bebd2e --- /dev/null +++ b/tests/info/test-info-cleanup.c @@ -0,0 +1,81 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2010 Red Hat, Inc + * Copyright (C) 2008 William Jon McCann + * + * 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 + +#include +#include +#include "info-cleanup.h" + +static void +test_info (void) +{ + g_autofree gchar *contents = NULL; + guint i; + g_auto(GStrv) lines = NULL; + + if (g_file_get_contents (TEST_SRCDIR "/info-cleanup-test.txt", &contents, NULL, NULL) == FALSE) { + g_warning ("Failed to load '%s'", TEST_SRCDIR "/info-cleanup-test.txt"); + g_test_fail (); + return; + } + + lines = g_strsplit (contents, "\n", -1); + if (lines == NULL) { + g_warning ("Test file is empty"); + g_test_fail (); + return; + } + + for (i = 0; lines[i] != NULL; i++) { + g_auto(GStrv) items = NULL; + g_autofree gchar *utf8 = NULL; + g_autofree gchar *result = NULL; + + if (*lines[i] == '#') + continue; + if (*lines[i] == '\0') + break; + + items = g_strsplit (lines[i], "\t", -1); + utf8 = g_locale_from_utf8 (items[0], -1, NULL, NULL, NULL); + result = info_cleanup (items[0]); + if (g_strcmp0 (result, items[1]) != 0) { + g_error ("Result for '%s' doesn't match '%s' (got: '%s')", + utf8, items[1], result); + g_test_fail (); + } else { + g_debug ("Result for '%s' matches '%s'", + utf8, result); + } + } +} + +int main (int argc, char **argv) +{ + setlocale (LC_ALL, ""); + g_test_init (&argc, &argv, NULL); + + g_setenv ("G_DEBUG", "fatal_warnings", FALSE); + + g_test_add_func ("/info/info", test_info); + + return g_test_run (); +} diff --git a/tests/meson.build b/tests/meson.build index a3dfffaff..91b8d8c68 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,2 +1,3 @@ subdir('common') subdir('printers') +subdir('info') -- cgit v1.2.1 From b15be07738da3a5bb3bc29376569ac210f5f8519 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 3 Apr 2018 19:26:57 +0200 Subject: Move datetime tests into tests subdirectory --- panels/datetime/meson.build | 23 +------- panels/datetime/test-endianess.c | 65 --------------------- panels/datetime/test-timezone-gfx.c | 61 -------------------- panels/datetime/test-timezone.c | 108 ----------------------------------- tests/datetime/meson.build | 26 +++++++++ tests/datetime/test-endianess.c | 65 +++++++++++++++++++++ tests/datetime/test-timezone-gfx.c | 64 +++++++++++++++++++++ tests/datetime/test-timezone.c | 111 ++++++++++++++++++++++++++++++++++++ tests/meson.build | 1 + 9 files changed, 269 insertions(+), 255 deletions(-) delete mode 100644 panels/datetime/test-endianess.c delete mode 100644 panels/datetime/test-timezone-gfx.c delete mode 100644 panels/datetime/test-timezone.c create mode 100644 tests/datetime/meson.build create mode 100644 tests/datetime/test-endianess.c create mode 100644 tests/datetime/test-timezone-gfx.c create mode 100644 tests/datetime/test-timezone.c diff --git a/panels/datetime/meson.build b/panels/datetime/meson.build index 8a96844be..5073f263d 100644 --- a/panels/datetime/meson.build +++ b/panels/datetime/meson.build @@ -183,33 +183,14 @@ cflags += [ '-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir) ] -panels_libs += static_library( +datetime_panel_lib = static_library( cappletname, sources: sources + resources, include_directories: [ top_inc, common_inc ], dependencies: deps, c_args: cflags ) - -test_cflags = '-DSRCDIR="@0@"'.format(meson.current_source_dir()) - -test_units = [ - #['test-timezone', ['cc-timezone-map.c', 'tz.c'] + resources, [m_dep], []], - ['test-timezone-gfx', ['tz.c'] + resources, [m_dep], [test_cflags]], - ['test-endianess', ['date-endian.c'], [], []] -] - -foreach unit: test_units - exe = executable( - unit[0], - [unit[0] + '.c'] + unit[1], - include_directories: top_inc, - dependencies: deps + unit[2], - c_args: cflags + unit[3] - ) - - test(unit[0], exe) -endforeach +panels_libs += datetime_panel_lib subdir('po-timezones') subdir('icons') diff --git a/panels/datetime/test-endianess.c b/panels/datetime/test-endianess.c deleted file mode 100644 index 06b26131b..000000000 --- a/panels/datetime/test-endianess.c +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include -#include "date-endian.h" - -static int verbose = 0; - -static void -print_endianess (const char *lang) -{ - DateEndianess endianess; - - if (lang != NULL) { - setlocale (LC_TIME, lang); - endianess = date_endian_get_for_lang (lang, verbose); - } else { - endianess = date_endian_get_default (verbose); - } - if (verbose) - g_print ("\t\t%s\n", date_endian_to_string (endianess)); -} - -static void -test_endianess (void) -{ - GDir *dir; - const char *name; - - dir = g_dir_open ("/usr/share/i18n/locales/", 0, NULL); - if (dir == NULL) { - /* Try with /usr/share/locale/ - * https://bugzilla.gnome.org/show_bug.cgi?id=646780 */ - dir = g_dir_open ("/usr/share/locale/", 0, NULL); - if (dir == NULL) { - g_assert_not_reached (); - } - } - - while ((name = g_dir_read_name (dir)) != NULL) - print_endianess (name); -} - -int main (int argc, char **argv) -{ - setlocale (LC_ALL, ""); - bind_textdomain_codeset ("libc", "UTF-8"); - - g_test_init (&argc, &argv, NULL); - - g_setenv ("G_DEBUG", "fatal_warnings", FALSE); - - if (argv[1] != NULL) { - verbose = 1; - - if (g_str_equal (argv[1], "-c")) - print_endianess (NULL); - else - print_endianess (argv[1]); - return 0; - } - - g_test_add_func ("/datetime/endianess", test_endianess); - - return g_test_run (); -} diff --git a/panels/datetime/test-timezone-gfx.c b/panels/datetime/test-timezone-gfx.c deleted file mode 100644 index 2beda3f7c..000000000 --- a/panels/datetime/test-timezone-gfx.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include - -#include "tz.h" - -static void -test_timezone_gfx (gconstpointer data) -{ - const char *pixmap_dir = data; - g_autoptr(TzDB) db = NULL; - GPtrArray *locs; - guint i; - - db = tz_load_db (); - locs = tz_get_locations (db); - for (i = 0; i < locs->len ; i++) { - TzLocation *loc = locs->pdata[i]; - TzInfo *info; - g_autofree gchar *filename = NULL; - g_autofree gchar *path = NULL; - gdouble selected_offset; - char buf[16]; - - info = tz_info_from_location (loc); - selected_offset = tz_location_get_utc_offset (loc) - / (60.0*60.0) + ((info->daylight) ? -1.0 : 0.0); - - filename = g_strdup_printf ("timezone_%s.png", - g_ascii_formatd (buf, sizeof (buf), - "%g", selected_offset)); - path = g_build_filename (pixmap_dir, filename, NULL); - - if (g_file_test (path, G_FILE_TEST_IS_REGULAR) == FALSE) { - g_message ("File '%s' missing for zone '%s'", filename, loc->zone); - g_test_fail (); - } - } -} - -int main (int argc, char **argv) -{ - char *pixmap_dir; - - setlocale (LC_ALL, ""); - g_test_init (&argc, &argv, NULL); - - g_setenv ("G_DEBUG", "fatal_warnings", FALSE); - - if (argc == 2) { - pixmap_dir = g_strdup (argv[1]); - } else if (argc == 1) { - pixmap_dir = g_strdup (SRCDIR "/data/"); - } else { - g_message ("Usage: %s [PIXMAP DIRECTORY]", argv[0]); - return 1; - } - - g_test_add_data_func ("/datetime/timezone-gfx", pixmap_dir, test_timezone_gfx); - - return g_test_run (); -} diff --git a/panels/datetime/test-timezone.c b/panels/datetime/test-timezone.c deleted file mode 100644 index ca9860118..000000000 --- a/panels/datetime/test-timezone.c +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include -#include "cc-timezone-map.h" - -#define TZ_DIR "/usr/share/zoneinfo/" - -static GList * -get_timezone_list (GList *tzs, - const char *top_path, - const char *subpath) -{ - GDir *dir; - char *fullpath; - const char *name; - - if (subpath == NULL) - fullpath = g_strdup (top_path); - else - fullpath = g_build_filename (top_path, subpath, NULL); - dir = g_dir_open (fullpath, 0, NULL); - if (dir == NULL) { - g_warning ("Could not open %s", fullpath); - return NULL; - } - while ((name = g_dir_read_name (dir)) != NULL) { - g_autofree gchar *path = NULL; - - if (g_str_has_suffix (name, ".tab")) - continue; - - if (subpath != NULL) - path = g_build_filename (top_path, subpath, name, NULL); - else - path = g_build_filename (top_path, name, NULL); - if (g_file_test (path, G_FILE_TEST_IS_DIR)) { - if (subpath == NULL) { - tzs = get_timezone_list (tzs, top_path, name); - } else { - g_autofree gchar *new_subpath = NULL; - new_subpath = g_strdup_printf ("%s/%s", subpath, name); - tzs = get_timezone_list (tzs, top_path, new_subpath); - } - } else if (g_file_test (path, G_FILE_TEST_IS_REGULAR)) { - if (subpath == NULL) - tzs = g_list_prepend (tzs, g_strdup (name)); - else { - char *tz; - tz = g_strdup_printf ("%s/%s", subpath, name); - tzs = g_list_prepend (tzs, tz); - } - } - } - g_dir_close (dir); - - return tzs; -} - -static void -test_timezone (void) -{ - CcTimezoneMap *map; - TzDB *tz_db; - GList *tzs, *l; - GHashTable *ht; - - ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - map = cc_timezone_map_new (); - tz_db = tz_load_db (); - tzs = get_timezone_list (NULL, TZ_DIR, NULL); - for (l = tzs; l != NULL; l = l->next) { - const gchar *timezone = l->data; - g_autofree gchar *clean_tz = NULL; - - clean_tz = tz_info_get_clean_name (tz_db, timezone); - - if (cc_timezone_map_set_timezone (map, clean_tz) == FALSE) { - if (g_hash_table_lookup (ht, clean_tz) == NULL) { - if (g_strcmp0 (clean_tz, timezone) == 0) - g_print ("Failed to locate timezone '%s'\n", timezone); - else - g_print ("Failed to locate timezone '%s' (original name: '%s')\n", clean_tz, timezone); - g_hash_table_insert (ht, g_strdup (clean_tz), GINT_TO_POINTER (TRUE)); - g_test_fail (); - } - /* We don't warn for those two, we'll just fallback - * in the panel code */ - if (!g_str_equal (clean_tz, "posixrules") && - !g_str_equal (clean_tz, "Factory")) - g_test_fail (); - } - } - g_list_free_full (tzs, g_free); - tz_db_free (tz_db); - g_hash_table_destroy (ht); -} - -int main (int argc, char **argv) -{ - setlocale (LC_ALL, ""); - gtk_init (NULL, NULL); - g_test_init (&argc, &argv, NULL); - - g_setenv ("G_DEBUG", "fatal_warnings", FALSE); - - g_test_add_func ("/datetime/timezone", test_timezone); - - return g_test_run (); -} diff --git a/tests/datetime/meson.build b/tests/datetime/meson.build new file mode 100644 index 000000000..738651c6d --- /dev/null +++ b/tests/datetime/meson.build @@ -0,0 +1,26 @@ + +test_units = [ + #'test-timezone', + 'test-timezone-gfx', + 'test-endianess', +] + +includes = [top_inc, include_directories('../../panels/datetime')] +cflags = [ + '-DTEST_SRCDIR="@0@"'.format(meson.current_source_dir()), + '-DSRCDIR="@0@"'.format(meson.source_root() + '/panels/datetime') +] + +foreach unit: test_units + exe = executable( + unit, + [unit + '.c'], + include_directories: includes, + dependencies: common_deps + [m_dep], + link_with: [datetime_panel_lib], + c_args: cflags + ) + + test(unit, exe) +endforeach + diff --git a/tests/datetime/test-endianess.c b/tests/datetime/test-endianess.c new file mode 100644 index 000000000..06b26131b --- /dev/null +++ b/tests/datetime/test-endianess.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include "date-endian.h" + +static int verbose = 0; + +static void +print_endianess (const char *lang) +{ + DateEndianess endianess; + + if (lang != NULL) { + setlocale (LC_TIME, lang); + endianess = date_endian_get_for_lang (lang, verbose); + } else { + endianess = date_endian_get_default (verbose); + } + if (verbose) + g_print ("\t\t%s\n", date_endian_to_string (endianess)); +} + +static void +test_endianess (void) +{ + GDir *dir; + const char *name; + + dir = g_dir_open ("/usr/share/i18n/locales/", 0, NULL); + if (dir == NULL) { + /* Try with /usr/share/locale/ + * https://bugzilla.gnome.org/show_bug.cgi?id=646780 */ + dir = g_dir_open ("/usr/share/locale/", 0, NULL); + if (dir == NULL) { + g_assert_not_reached (); + } + } + + while ((name = g_dir_read_name (dir)) != NULL) + print_endianess (name); +} + +int main (int argc, char **argv) +{ + setlocale (LC_ALL, ""); + bind_textdomain_codeset ("libc", "UTF-8"); + + g_test_init (&argc, &argv, NULL); + + g_setenv ("G_DEBUG", "fatal_warnings", FALSE); + + if (argv[1] != NULL) { + verbose = 1; + + if (g_str_equal (argv[1], "-c")) + print_endianess (NULL); + else + print_endianess (argv[1]); + return 0; + } + + g_test_add_func ("/datetime/endianess", test_endianess); + + return g_test_run (); +} diff --git a/tests/datetime/test-timezone-gfx.c b/tests/datetime/test-timezone-gfx.c new file mode 100644 index 000000000..a8f704627 --- /dev/null +++ b/tests/datetime/test-timezone-gfx.c @@ -0,0 +1,64 @@ +#include +#include + +#include "cc-datetime-resources.h" +#include "tz.h" + +static void +test_timezone_gfx (gconstpointer data) +{ + const char *pixmap_dir = data; + g_autoptr(TzDB) db = NULL; + GPtrArray *locs; + guint i; + + db = tz_load_db (); + locs = tz_get_locations (db); + for (i = 0; i < locs->len ; i++) { + TzLocation *loc = locs->pdata[i]; + TzInfo *info; + g_autofree gchar *filename = NULL; + g_autofree gchar *path = NULL; + gdouble selected_offset; + char buf[16]; + + info = tz_info_from_location (loc); + selected_offset = tz_location_get_utc_offset (loc) + / (60.0*60.0) + ((info->daylight) ? -1.0 : 0.0); + + filename = g_strdup_printf ("timezone_%s.png", + g_ascii_formatd (buf, sizeof (buf), + "%g", selected_offset)); + path = g_build_filename (pixmap_dir, filename, NULL); + + if (g_file_test (path, G_FILE_TEST_IS_REGULAR) == FALSE) { + g_message ("File '%s' missing for zone '%s'", filename, loc->zone); + g_test_fail (); + } + } +} + +int main (int argc, char **argv) +{ + char *pixmap_dir; + + setlocale (LC_ALL, ""); + g_test_init (&argc, &argv, NULL); + + g_setenv ("G_DEBUG", "fatal_warnings", FALSE); + + g_resources_register (cc_datetime_get_resource ()); + + if (argc == 2) { + pixmap_dir = g_strdup (argv[1]); + } else if (argc == 1) { + pixmap_dir = g_strdup (SRCDIR "/data/"); + } else { + g_message ("Usage: %s [PIXMAP DIRECTORY]", argv[0]); + return 1; + } + + g_test_add_data_func ("/datetime/timezone-gfx", pixmap_dir, test_timezone_gfx); + + return g_test_run (); +} diff --git a/tests/datetime/test-timezone.c b/tests/datetime/test-timezone.c new file mode 100644 index 000000000..436f536b5 --- /dev/null +++ b/tests/datetime/test-timezone.c @@ -0,0 +1,111 @@ +#include +#include +#include "cc-datetime-resources.h" +#include "cc-timezone-map.h" + +#define TZ_DIR "/usr/share/zoneinfo/" + +static GList * +get_timezone_list (GList *tzs, + const char *top_path, + const char *subpath) +{ + GDir *dir; + char *fullpath; + const char *name; + + if (subpath == NULL) + fullpath = g_strdup (top_path); + else + fullpath = g_build_filename (top_path, subpath, NULL); + dir = g_dir_open (fullpath, 0, NULL); + if (dir == NULL) { + g_warning ("Could not open %s", fullpath); + return NULL; + } + while ((name = g_dir_read_name (dir)) != NULL) { + g_autofree gchar *path = NULL; + + if (g_str_has_suffix (name, ".tab")) + continue; + + if (subpath != NULL) + path = g_build_filename (top_path, subpath, name, NULL); + else + path = g_build_filename (top_path, name, NULL); + if (g_file_test (path, G_FILE_TEST_IS_DIR)) { + if (subpath == NULL) { + tzs = get_timezone_list (tzs, top_path, name); + } else { + g_autofree gchar *new_subpath = NULL; + new_subpath = g_strdup_printf ("%s/%s", subpath, name); + tzs = get_timezone_list (tzs, top_path, new_subpath); + } + } else if (g_file_test (path, G_FILE_TEST_IS_REGULAR)) { + if (subpath == NULL) + tzs = g_list_prepend (tzs, g_strdup (name)); + else { + char *tz; + tz = g_strdup_printf ("%s/%s", subpath, name); + tzs = g_list_prepend (tzs, tz); + } + } + } + g_dir_close (dir); + + return tzs; +} + +static void +test_timezone (void) +{ + CcTimezoneMap *map; + TzDB *tz_db; + GList *tzs, *l; + GHashTable *ht; + + ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + map = cc_timezone_map_new (); + tz_db = tz_load_db (); + tzs = get_timezone_list (NULL, TZ_DIR, NULL); + for (l = tzs; l != NULL; l = l->next) { + const gchar *timezone = l->data; + g_autofree gchar *clean_tz = NULL; + + clean_tz = tz_info_get_clean_name (tz_db, timezone); + + if (cc_timezone_map_set_timezone (map, clean_tz) == FALSE) { + if (g_hash_table_lookup (ht, clean_tz) == NULL) { + if (g_strcmp0 (clean_tz, timezone) == 0) + g_print ("Failed to locate timezone '%s'\n", timezone); + else + g_print ("Failed to locate timezone '%s' (original name: '%s')\n", clean_tz, timezone); + g_hash_table_insert (ht, g_strdup (clean_tz), GINT_TO_POINTER (TRUE)); + g_test_fail (); + } + /* We don't warn for those two, we'll just fallback + * in the panel code */ + if (!g_str_equal (clean_tz, "posixrules") && + !g_str_equal (clean_tz, "Factory")) + g_test_fail (); + } + } + g_list_free_full (tzs, g_free); + tz_db_free (tz_db); + g_hash_table_destroy (ht); +} + +int main (int argc, char **argv) +{ + setlocale (LC_ALL, ""); + gtk_init (NULL, NULL); + g_test_init (&argc, &argv, NULL); + + g_resources_register (cc_datetime_get_resource ()); + + g_setenv ("G_DEBUG", "fatal_warnings", FALSE); + + g_test_add_func ("/datetime/timezone", test_timezone); + + return g_test_run (); +} diff --git a/tests/meson.build b/tests/meson.build index 91b8d8c68..49229a305 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,3 +1,4 @@ subdir('common') +subdir('datetime') subdir('printers') subdir('info') -- cgit v1.2.1 From 79013788fda1ea192c589e0b251bad244b2a9156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Dr=C4=85g?= Date: Tue, 17 Apr 2018 16:56:51 +0200 Subject: Update POTFILES.in --- po/POTFILES.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index e3c1d2ae2..a05df8a7f 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -20,6 +20,7 @@ panels/color/gnome-color-panel.desktop.in.in panels/common/cc-common-language.c panels/common/cc-language-chooser.c panels/common/cc-util.c +panels/common/hostname-helper.c panels/common/language-chooser.ui panels/datetime/big.ui panels/datetime/cc-datetime-panel.c @@ -232,7 +233,6 @@ shell/cc-application.c shell/cc-window.c shell/gnome-control-center.desktop.in.in shell/help-overlay.ui -shell/hostname-helper.c shell/org.gnome.ControlCenter.gschema.xml shell/panel-list.ui shell/window.ui -- cgit v1.2.1 From 9214a966defc991efb92c415491454319997844c Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Tue, 17 Apr 2018 12:18:25 -0300 Subject: trivial: Improve meson file This commit only improves the style of the main Meson file, and makes the output message a bit more friendlier. --- meson.build | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/meson.build b/meson.build index 1b947ab01..a2d484442 100644 --- a/meson.build +++ b/meson.build @@ -1,8 +1,8 @@ project( 'gnome-control-center', 'c', - version: '3.29.0', - license: 'GPL2+', - meson_version: '>= 0.43.0' + version : '3.29.0', + license : 'GPL2+', + meson_version : '>= 0.43.0' ) control_center_prefix = get_option('prefix') @@ -254,7 +254,6 @@ subdir('po') subdir('panels') subdir('shell') subdir('search-provider') - subdir('tests') if get_option('documentation') @@ -271,18 +270,19 @@ meson.add_install_script( control_center_datadir ) -output = meson.project_name() + ' was configured with the following options:\n' -output += '** gnome-bluetooth (Bluetooth panel): ' + host_is_linux_not_s390.to_string() + '\n' -output += '** Cheese (Users panel webcam support): ' + enable_cheese.to_string() + '\n' -output += '** IBus (Region panel IBus support): ' + enable_ibus.to_string() + '\n' -output += '** NetworkManager (Network panel): ' + host_is_linux.to_string() + '\n' -output += '** wacom (Wacom tablet panel): ' + host_is_linux_not_s390.to_string() + '\n' -output += '** Wayland: ' + enable_wayland.to_string() + '\n' -output += '** gnome-session libexecdir: ' + gnome_session_libexecdir + '\n' - -if enable_tracing - output += '** Tracing enabled \n' -endif +output = '' +output += '\n ' + meson.project_name() + ' - ' + meson.project_version() + '\n' +output += ' ===================================\n' +output += ' Options \n' +output += ' Documentation .............................. ' + get_option('documentation').to_string() + '\n' +output += ' Tracing .................................... ' + enable_tracing.to_string() + '\n' +output += ' gnome-session libexecdir ................... ' + gnome_session_libexecdir + '\n' +output += ' Panels \n' +output += ' GNOME Bluetooth (Bluetooth panel) .......... ' + host_is_linux_not_s390.to_string() + '\n' +output += ' Cheese (Users panel webcam support) ........ ' + enable_cheese.to_string() + '\n' +output += ' IBus (Region panel IBus support) ........... ' + enable_ibus.to_string() + '\n' +output += ' NetworkManager (Network panel) ............. ' + host_is_linux.to_string() + '\n' +output += ' Wacom (Wacom tablet panel) ................. ' + host_is_linux_not_s390.to_string() + '\n' +output += ' Wayland .................................... ' + enable_wayland.to_string() + '\n' -output += 'End options' message(output) -- cgit v1.2.1 From 6c447dc14a2a3a98d25e8a71fb3d5e08ae8b6fe6 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Thu, 19 Apr 2018 04:04:48 +0200 Subject: power: Don't show approximate percentages When there's a battery-level property (new in UPower 0.99.5), don't show the percentage, as it's a rough approximation of the truth. https://bugzilla.gnome.org/show_bug.cgi?id=780360 --- panels/power/cc-power-panel.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/panels/power/cc-power-panel.c b/panels/power/cc-power-panel.c index 85013105c..565ee2772 100644 --- a/panels/power/cc-power-panel.c +++ b/panels/power/cc-power-panel.c @@ -568,6 +568,18 @@ kind_to_description (UpDeviceKind kind) g_assert_not_reached (); } +static UpDeviceLevel +get_battery_level (UpDevice *device) +{ + UpDeviceLevel battery_level; + + if (!g_object_class_find_property (G_OBJECT_CLASS (G_OBJECT_GET_CLASS (device)), "battery-level")) + return UP_DEVICE_LEVEL_NONE; + + g_object_get (device, "battery-level", &battery_level, NULL); + return battery_level; +} + static void add_device (CcPowerPanel *panel, UpDevice *device) { @@ -582,9 +594,9 @@ add_device (CcPowerPanel *panel, UpDevice *device) GString *description; gdouble percentage; gchar *name; - gchar *s; gboolean show_caution = FALSE; gboolean is_present; + UpDeviceLevel battery_level; name = NULL; g_object_get (device, @@ -594,6 +606,7 @@ add_device (CcPowerPanel *panel, UpDevice *device) "model", &name, "is-present", &is_present, NULL); + battery_level = get_battery_level (device); if (!is_present) { @@ -668,9 +681,20 @@ add_device (CcPowerPanel *panel, UpDevice *device) box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12); gtk_widget_set_margin_start (box2, 20); gtk_widget_set_margin_end (box2, 20); - s = g_strdup_printf ("%d%%", (int)percentage); - widget = gtk_label_new (s); - g_free (s); + + if (battery_level == UP_DEVICE_LEVEL_NONE) + { + gchar *s; + + s = g_strdup_printf ("%d%%", (int)(percentage + 0.5)); + widget = gtk_label_new (s); + g_free (s); + } + else + { + widget = gtk_label_new (""); + } + gtk_widget_set_halign (widget, GTK_ALIGN_END); gtk_style_context_add_class (gtk_widget_get_style_context (widget), GTK_STYLE_CLASS_DIM_LABEL); gtk_box_pack_start (GTK_BOX (box2), widget, FALSE, TRUE, 0); -- cgit v1.2.1 From f26d21682a4d3da63d3d71bd90f8f0d943ea4cbf Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 14 Feb 2018 11:36:28 +0100 Subject: power: Automatically add values to drop-down when necessary When a setting is set to a value that's not in the list of options, add that custom value to the drop-down for the duration of the run, so as to avoid the last item being selected and causing confusion. https://bugzilla.gnome.org/show_bug.cgi?id=793448 --- panels/power/cc-power-panel.c | 63 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/panels/power/cc-power-panel.c b/panels/power/cc-power-panel.c index 565ee2772..7b7c4a24d 100644 --- a/panels/power/cc-power-panel.c +++ b/panels/power/cc-power-panel.c @@ -1188,6 +1188,51 @@ combo_time_changed_cb (GtkWidget *widget, CcPowerPanel *self) g_settings_set_int (self->priv->gsd_settings, key, value); } +/* Copied from src/properties/bacon-video-widget-properties.c + * in totem */ +static char * +time_to_string_text (gint64 msecs) +{ + char *secs, *mins, *hours, *string; + int sec, min, hour, _time; + + _time = (int) (msecs / 1000); + sec = _time % 60; + _time = _time - sec; + min = (_time % (60*60)) / 60; + _time = _time - (min * 60); + hour = _time / (60*60); + + hours = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%d hour", "%d hours", hour), hour); + + mins = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%d minute", + "%d minutes", min), min); + + secs = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%d second", + "%d seconds", sec), sec); + + if (hour > 0) + { + /* 5 hours 2 minutes 12 seconds */ + string = g_strdup_printf (C_("time", "%s %s %s"), hours, mins, secs); + } else if (min > 0) { + /* 2 minutes 12 seconds */ + string = g_strdup_printf (C_("time", "%s %s"), mins, secs); + } else if (sec > 0) { + /* 10 seconds */ + string = g_strdup (secs); + } else { + /* 0 seconds */ + string = g_strdup (_("0 seconds")); + } + + g_free (hours); + g_free (mins); + g_free (secs); + + return string; +} + static void set_value_for_combo (GtkComboBox *combo_box, gint value) { @@ -1209,11 +1254,27 @@ set_value_for_combo (GtkComboBox *combo_box, gint value) gtk_tree_model_get (model, &iter, ACTION_MODEL_VALUE, &value_tmp, -1); - if (value == value_tmp) + if (value_tmp == value) { gtk_combo_box_set_active_iter (combo_box, &iter); return; } + else if (value_tmp > value) + { + GtkTreeIter new; + char *text; + + /* This is an unlisted value, add it to the drop-down */ + gtk_list_store_insert_before (GTK_LIST_STORE (model), &new, &iter); + text = time_to_string_text (value * 1000); + gtk_list_store_set (GTK_LIST_STORE (model), &new, + ACTION_MODEL_TEXT, text, + ACTION_MODEL_VALUE, value, + -1); + g_free (text); + gtk_combo_box_set_active_iter (combo_box, &new); + return; + } last = iter; } while (gtk_tree_model_iter_next (model, &iter)); -- cgit v1.2.1 From 666bccd861d313ca6a83aa245309d7f1be5dac10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C8=98erb=C4=83nescu?= Date: Sun, 22 Apr 2018 09:57:17 +0000 Subject: Update Romanian translation --- po/ro.po | 534 ++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 271 insertions(+), 263 deletions(-) diff --git a/po/ro.po b/po/ro.po index d79e9a235..edeb16369 100644 --- a/po/ro.po +++ b/po/ro.po @@ -17,17 +17,17 @@ msgstr "" "Project-Id-Version: gnome-control-center\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-control-center/" "issues\n" -"POT-Creation-Date: 2018-03-08 11:52+0000\n" -"PO-Revision-Date: 2018-03-03 14:01+0200\n" -"Last-Translator: Daniel Șerbănescu \n" +"POT-Creation-Date: 2018-04-13 14:19+0000\n" +"PO-Revision-Date: 2018-04-18 13:30+0300\n" +"Last-Translator: Florentina Mușat \n" "Language-Team: Gnome Romanian Translation Team\n" "Language: ro\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " -"20)) ? 1 : 2);;\n" -"X-Generator: Virtaal 0.7.1\n" +"20)) ? 1 : 2);\n" +"X-Generator: Poedit 2.0.6\n" "X-Launchpad-Export-Date: 2014-07-13 17:08+0000\n" "X-Project-Style: gnome\n" @@ -113,9 +113,9 @@ msgid "You can add images to your %s folder and they will show up here" msgstr "Puteți adăuga imagini în directorul %s și acestea vor fi afișate aici" #: panels/background/cc-background-chooser-dialog.c:560 -#: panels/color/cc-color-panel.c:225 panels/color/cc-color-panel.c:963 +#: panels/color/cc-color-panel.c:224 panels/color/cc-color-panel.c:962 #: panels/color/color-calibrate.ui:25 panels/color/color.ui:657 -#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2594 +#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2610 #: panels/network/connection-editor/connection-editor.ui:15 #: panels/network/connection-editor/vpn-helpers.c:181 #: panels/network/connection-editor/vpn-helpers.c:310 @@ -131,8 +131,8 @@ msgstr "Puteți adăuga imagini în directorul %s și acestea vor fi afișate ai #: panels/user-accounts/data/join-dialog.ui:20 #: panels/user-accounts/data/password-dialog.ui:21 #: panels/user-accounts/um-fingerprint-dialog.c:261 -#: panels/user-accounts/um-photo-dialog.c:102 -#: panels/user-accounts/um-photo-dialog.c:229 +#: panels/user-accounts/um-photo-dialog.c:103 +#: panels/user-accounts/um-photo-dialog.c:230 #: panels/user-accounts/um-user-panel.c:634 #: panels/user-accounts/um-user-panel.c:652 msgid "_Cancel" @@ -179,39 +179,39 @@ msgstr "preferences-desktop-wallpaper" msgid "Wallpaper;Screen;Desktop;" msgstr "Wallpaper;Screen;Desktop;Tapet;Ecran;" -#: panels/bluetooth/cc-bluetooth-panel.c:265 +#: panels/bluetooth/cc-bluetooth-panel.c:266 msgid "Turn Off Airplane Mode" msgstr "Închide modul Avion" -#: panels/bluetooth/cc-bluetooth-panel.c:330 +#: panels/bluetooth/cc-bluetooth-panel.c:329 msgid "No Bluetooth Found" msgstr "Nu a fost găsit adaptor Bluetooth" -#: panels/bluetooth/cc-bluetooth-panel.c:330 +#: panels/bluetooth/cc-bluetooth-panel.c:329 msgid "Plug in a dongle to use Bluetooth." msgstr "Introduceți un dispozitiv pentru a folosi Bluetooth." -#: panels/bluetooth/cc-bluetooth-panel.c:331 +#: panels/bluetooth/cc-bluetooth-panel.c:330 msgid "Bluetooth Turned Off" msgstr "Bluetooth este oprit" -#: panels/bluetooth/cc-bluetooth-panel.c:331 +#: panels/bluetooth/cc-bluetooth-panel.c:330 msgid "Turn on to connect devices and receive file transfers." msgstr "Deschideți pentru a putea conecta dispozitive și transfera fișiere." -#: panels/bluetooth/cc-bluetooth-panel.c:332 +#: panels/bluetooth/cc-bluetooth-panel.c:331 msgid "Airplane Mode is on" msgstr "Mod avion este pornit" -#: panels/bluetooth/cc-bluetooth-panel.c:332 +#: panels/bluetooth/cc-bluetooth-panel.c:331 msgid "Bluetooth is disabled when airplane mode is on." msgstr "Bluetooth este dezactivat când modul avion este pornit." -#: panels/bluetooth/cc-bluetooth-panel.c:333 +#: panels/bluetooth/cc-bluetooth-panel.c:332 msgid "Hardware Airplane Mode is on" msgstr "Mod hardware avion este pornit" -#: panels/bluetooth/cc-bluetooth-panel.c:333 +#: panels/bluetooth/cc-bluetooth-panel.c:332 msgid "Turn off the Airplane mode switch to enable Bluetooth." msgstr "Opriți modul avion pentru a putea activa Bluetooth." @@ -236,7 +236,7 @@ msgid "share;sharing;bluetooth;obex;" msgstr "share;sharing;bluetooth;obex;partajează;partajare;" #. TRANSLATORS: The user has to attach the sensor to the screen -#: panels/color/cc-color-calibrate.c:361 +#: panels/color/cc-color-calibrate.c:363 msgid "Place your calibration device over the square and press “Start”" msgstr "" "Plasați dispozitivul de calibrare deasupra pătratului și apăsați „Start”" @@ -244,7 +244,7 @@ msgstr "" #. TRANSLATORS: Some calibration devices need the user to move a #. * dial or switch manually. We also show a picture showing them #. * what to do... -#: panels/color/cc-color-calibrate.c:367 +#: panels/color/cc-color-calibrate.c:369 msgid "" "Move your calibration device to the calibrate position and press “Continue”" msgstr "" @@ -254,7 +254,7 @@ msgstr "" #. TRANSLATORS: Some calibration devices need the user to move a #. * dial or switch manually. We also show a picture showing them #. * what to do... -#: panels/color/cc-color-calibrate.c:373 +#: panels/color/cc-color-calibrate.c:375 msgid "" "Move your calibration device to the surface position and press “Continue”" msgstr "" @@ -264,54 +264,54 @@ msgstr "" #. TRANSLATORS: on some hardware e.g. Lenovo W700 the sensor #. * is built into the palmrest and we need to fullscreen the #. * sample widget and shut the lid. -#: panels/color/cc-color-calibrate.c:379 +#: panels/color/cc-color-calibrate.c:381 msgid "Shut the laptop lid" msgstr "Închideți capacul laptopului" #. TRANSLATORS: We suck, the calibation failed and we have no #. * good idea why or any suggestions -#: panels/color/cc-color-calibrate.c:410 +#: panels/color/cc-color-calibrate.c:412 msgid "An internal error occurred that could not be recovered." msgstr "A apărut o eroare internă nerecuperabilă." #. TRANSLATORS: Some required-at-runtime tools were not #. * installed, which should only affect insane distros -#: panels/color/cc-color-calibrate.c:415 +#: panels/color/cc-color-calibrate.c:417 msgid "Tools required for calibration are not installed." msgstr "Uneltele pentru calibrare nu sunt instalate." #. TRANSLATORS: The profile failed for some reason -#: panels/color/cc-color-calibrate.c:421 +#: panels/color/cc-color-calibrate.c:423 msgid "The profile could not be generated." msgstr "Nu s-a putut genera profilul." #. TRANSLATORS: The user specified a whitepoint that was #. * unobtainable with the hardware they've got -- see #. * https://en.wikipedia.org/wiki/White_point for details -#: panels/color/cc-color-calibrate.c:427 +#: panels/color/cc-color-calibrate.c:429 msgid "The target whitepoint was not obtainable." msgstr "Nu s-a putut găsi punctul de țintă alb." #. TRANSLATORS: the display calibration process is finished -#: panels/color/cc-color-calibrate.c:467 +#: panels/color/cc-color-calibrate.c:469 msgid "Complete!" msgstr "Gata!" #. TRANSLATORS: the display calibration failed, and we also show #. * the translated (or untranslated) error string after this -#: panels/color/cc-color-calibrate.c:475 +#: panels/color/cc-color-calibrate.c:477 msgid "Calibration failed!" msgstr "Calibrare eșuată!" #. TRANSLATORS: The user can now remove the sensor from the screen -#: panels/color/cc-color-calibrate.c:482 +#: panels/color/cc-color-calibrate.c:484 msgid "You can remove the calibration device." msgstr "Puteți deconecta dispozitivul de calibrare." #. TRANSLATORS: The user has to be careful not to knock the #. * display off the screen (although we do cope if this is #. * detected early enough) -#: panels/color/cc-color-calibrate.c:554 +#: panels/color/cc-color-calibrate.c:556 msgid "Do not disturb the calibration device while in progress" msgstr "Nu deranjați dispozitivul în timpul calibrării" @@ -373,48 +373,48 @@ msgstr "Necalibrat" #. TRANSLATORS: this is a profile prefix to signify the #. * profile has been auto-generated for this hardware -#: panels/color/cc-color-panel.c:141 +#: panels/color/cc-color-panel.c:140 msgid "Default: " msgstr "Implicit: " #. TRANSLATORS: this is a profile prefix to signify the #. * profile his a standard space like AdobeRGB -#: panels/color/cc-color-panel.c:149 +#: panels/color/cc-color-panel.c:148 msgid "Colorspace: " msgstr "Spațiu culoare: " #. TRANSLATORS: this is a profile prefix to signify the #. * profile is a test profile -#: panels/color/cc-color-panel.c:156 +#: panels/color/cc-color-panel.c:155 msgid "Test profile: " msgstr "Profil de test: " #. TRANSLATORS: an ICC profile is a file containing colorspace data -#: panels/color/cc-color-panel.c:223 +#: panels/color/cc-color-panel.c:222 msgid "Select ICC Profile File" msgstr "Selectați un fișier profil ICC" -#: panels/color/cc-color-panel.c:226 +#: panels/color/cc-color-panel.c:225 msgid "_Import" msgstr "_Importă" #. TRANSLATORS: filter name on the file->open dialog -#: panels/color/cc-color-panel.c:237 +#: panels/color/cc-color-panel.c:236 msgid "Supported ICC profiles" msgstr "Profile ICC recunoscute" #. TRANSLATORS: filter name on the file->open dialog -#: panels/color/cc-color-panel.c:244 +#: panels/color/cc-color-panel.c:243 #: panels/network/wireless-security/eap-method-fast.c:417 msgid "All files" msgstr "Toate fișierele" -#: panels/color/cc-color-panel.c:583 +#: panels/color/cc-color-panel.c:582 msgid "Screen" msgstr "Ecran" #. TRANSLATORS: this is when the upload of the profile failed -#: panels/color/cc-color-panel.c:908 +#: panels/color/cc-color-panel.c:907 #, c-format msgid "Failed to upload file: %s" msgstr "Eșec la încărcarea fișierului: %s" @@ -422,39 +422,39 @@ msgstr "Eșec la încărcarea fișierului: %s" #. TRANSLATORS: these are instructions on how to recover #. * the ICC profile on the native operating system and are #. * only shown when the user uses a LiveCD to calibrate -#: panels/color/cc-color-panel.c:922 +#: panels/color/cc-color-panel.c:921 msgid "The profile has been uploaded to:" msgstr "Profilul a fost încărcat în:" -#: panels/color/cc-color-panel.c:924 +#: panels/color/cc-color-panel.c:923 msgid "Write down this URL." msgstr "Scrieți acest URL." -#: panels/color/cc-color-panel.c:925 +#: panels/color/cc-color-panel.c:924 msgid "Restart this computer and boot your normal operating system." msgstr "Reporniți calculatorul și intrați în sistemul de operare obișnuit." -#: panels/color/cc-color-panel.c:926 +#: panels/color/cc-color-panel.c:925 msgid "Type the URL into your browser to download and install the profile." msgstr "Scrieți URL-ul în navigator pentru a descărca și instala profilul." #. TRANSLATORS: this is the dialog to save the ICC profile -#: panels/color/cc-color-panel.c:960 +#: panels/color/cc-color-panel.c:959 msgid "Save Profile" msgstr "Salvare profil" -#: panels/color/cc-color-panel.c:964 +#: panels/color/cc-color-panel.c:963 #: panels/network/connection-editor/vpn-helpers.c:311 msgid "_Save" msgstr "_Salvare" #. TRANSLATORS: this is when the button is sensitive -#: panels/color/cc-color-panel.c:1325 +#: panels/color/cc-color-panel.c:1324 msgid "Create a color profile for the selected device" msgstr "Creează un profil de culoare pentru dispozitivul ales" #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1340 panels/color/cc-color-panel.c:1364 +#: panels/color/cc-color-panel.c:1339 panels/color/cc-color-panel.c:1363 msgid "" "The measuring instrument is not detected. Please check it is turned on and " "correctly connected." @@ -463,12 +463,12 @@ msgstr "" "conectat." #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1374 +#: panels/color/cc-color-panel.c:1373 msgid "The measuring instrument does not support printer profiling." msgstr "Instrumentul de măsură nu suportă profilarea pentru imprimante." #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1385 +#: panels/color/cc-color-panel.c:1384 msgid "The device type is not currently supported." msgstr "Tipul de dispozitiv nu este recunoscut." @@ -1120,58 +1120,58 @@ msgstr "Modifică data și ora sistemului" msgid "To change time or date settings, you need to authenticate." msgstr "Pentru a schimba data sau ora, trebuie să vă autentificați." -#: panels/display/cc-display-panel.c:729 +#: panels/display/cc-display-panel.c:739 msgctxt "Display rotation" msgid "Landscape" msgstr "Peisaj" -#: panels/display/cc-display-panel.c:732 +#: panels/display/cc-display-panel.c:742 msgctxt "Display rotation" msgid "Portrait Right" msgstr "Portret dreapta" -#: panels/display/cc-display-panel.c:735 +#: panels/display/cc-display-panel.c:745 msgctxt "Display rotation" msgid "Portrait Left" msgstr "Portret stânga" -#: panels/display/cc-display-panel.c:738 +#: panels/display/cc-display-panel.c:748 msgctxt "Display rotation" msgid "Landscape (flipped)" msgstr "Peisaj (inversat)" #. Translators: This option sets orientation of print (portrait, landscape...) -#: panels/display/cc-display-panel.c:805 +#: panels/display/cc-display-panel.c:816 #: panels/printers/pp-options-dialog.c:558 msgid "Orientation" msgstr "Orientare" -#: panels/display/cc-display-panel.c:870 panels/display/cc-display-panel.c:1673 +#: panels/display/cc-display-panel.c:885 panels/display/cc-display-panel.c:1691 #: panels/printers/pp-options-dialog.c:87 msgid "Resolution" msgstr "Rezoluție" -#: panels/display/cc-display-panel.c:958 +#: panels/display/cc-display-panel.c:974 msgid "Refresh Rate" msgstr "Rata de reîmprospătare" -#: panels/display/cc-display-panel.c:1095 +#: panels/display/cc-display-panel.c:1111 msgid "Scale" msgstr "Scalează" -#: panels/display/cc-display-panel.c:1148 +#: panels/display/cc-display-panel.c:1164 msgid "Adjust for TV" msgstr "Reglează pentru TV" -#: panels/display/cc-display-panel.c:1410 +#: panels/display/cc-display-panel.c:1427 msgid "Primary Display" msgstr "Afișaj primar" -#: panels/display/cc-display-panel.c:1439 +#: panels/display/cc-display-panel.c:1456 msgid "Display Arrangement" msgstr "Aranjamentul afișajelor" -#: panels/display/cc-display-panel.c:1440 +#: panels/display/cc-display-panel.c:1457 msgid "" "Drag displays to match your setup. The top bar is placed on the primary " "display." @@ -1179,59 +1179,67 @@ msgstr "" "Trageți afișaje potrivit situației dumneavoastră. Bara de sus este plasată " "pe afișajul primar." -#: panels/display/cc-display-panel.c:1863 +#: panels/display/cc-display-panel.c:1881 msgid "Display Mode" msgstr "Modul de afișaj" -#: panels/display/cc-display-panel.c:1879 +#: panels/display/cc-display-panel.c:1897 msgid "Join Displays" msgstr "Unește afișaje" -#: panels/display/cc-display-panel.c:1882 +#: panels/display/cc-display-panel.c:1900 msgid "Mirror" msgstr "Oglindire" -#: panels/display/cc-display-panel.c:1885 +#: panels/display/cc-display-panel.c:1903 msgid "Single Display" msgstr "Afișaj singular" -#: panels/display/cc-display-panel.c:2590 -msgid "Apply Changes?" -msgstr "Aplicați modificările?" - -#: panels/display/cc-display-panel.c:2604 +#: panels/display/cc-display-panel.c:2620 #: panels/network/connection-editor/connection-editor.ui:24 #: panels/network/network-wifi.ui:38 msgid "_Apply" msgstr "_Aplică" -#: panels/display/cc-display-panel.c:2979 +#: panels/display/cc-display-panel.c:2642 +msgid "Apply Changes?" +msgstr "Aplicați modificările?" + +#: panels/display/cc-display-panel.c:2647 +msgid "Changes Cannot be Applied" +msgstr "Nu se pot aplica modificările" + +#: panels/display/cc-display-panel.c:2648 +msgid "This could be due to hardware limitations." +msgstr "Aceasta poate fi din cauza limitărilor de hardware." + +#: panels/display/cc-display-panel.c:3003 #, c-format msgid "%.2lf Hz" msgstr "%.2lf Hz" #. TRANSLATORS: the state of the night light setting -#: panels/display/cc-display-panel.c:3195 +#: panels/display/cc-display-panel.c:3219 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1994 panels/power/cc-power-panel.c:2001 -#: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 -#: panels/universal-access/cc-ua-panel.c:333 -#: panels/universal-access/cc-ua-panel.c:714 -#: panels/universal-access/cc-ua-panel.c:727 -#: panels/universal-access/cc-ua-panel.c:739 -#: panels/universal-access/cc-ua-panel.c:910 +#: panels/power/cc-power-panel.c:2012 panels/power/cc-power-panel.c:2019 +#: panels/privacy/cc-privacy-panel.c:191 panels/privacy/cc-privacy-panel.c:258 +#: panels/universal-access/cc-ua-panel.c:334 +#: panels/universal-access/cc-ua-panel.c:715 +#: panels/universal-access/cc-ua-panel.c:728 +#: panels/universal-access/cc-ua-panel.c:740 +#: panels/universal-access/cc-ua-panel.c:911 msgid "On" msgstr "Pornit" -#: panels/display/cc-display-panel.c:3195 panels/network/net-proxy.c:54 +#: panels/display/cc-display-panel.c:3219 panels/network/net-proxy.c:54 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1988 panels/power/cc-power-panel.c:1999 -#: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 -#: panels/universal-access/cc-ua-panel.c:333 -#: panels/universal-access/cc-ua-panel.c:714 -#: panels/universal-access/cc-ua-panel.c:727 -#: panels/universal-access/cc-ua-panel.c:739 -#: panels/universal-access/cc-ua-panel.c:910 panels/universal-access/uap.ui:334 +#: panels/power/cc-power-panel.c:2006 panels/power/cc-power-panel.c:2017 +#: panels/privacy/cc-privacy-panel.c:191 panels/privacy/cc-privacy-panel.c:258 +#: panels/universal-access/cc-ua-panel.c:334 +#: panels/universal-access/cc-ua-panel.c:715 +#: panels/universal-access/cc-ua-panel.c:728 +#: panels/universal-access/cc-ua-panel.c:740 +#: panels/universal-access/cc-ua-panel.c:911 panels/universal-access/uap.ui:334 #: panels/universal-access/uap.ui:380 panels/universal-access/uap.ui:426 #: panels/universal-access/uap.ui:532 panels/universal-access/uap.ui:685 #: panels/universal-access/uap.ui:731 panels/universal-access/uap.ui:777 @@ -1239,11 +1247,11 @@ msgstr "Pornit" msgid "Off" msgstr "Oprit" -#: panels/display/cc-display-panel.c:3216 +#: panels/display/cc-display-panel.c:3240 msgid "_Night Light" msgstr "Lumină _nocturnă" -#: panels/display/cc-display-panel.c:3281 +#: panels/display/cc-display-panel.c:3305 msgid "Could not get screen information" msgstr "Nu s-au putut obține informații despre ecran" @@ -1283,7 +1291,7 @@ msgstr "Apus la răsărit" #: panels/network/connection-editor/ip6-page.ui:83 #: panels/network/net-proxy.c:56 panels/network/network-proxy.ui:113 #: panels/network/network-wifi.ui:777 panels/network/network-wifi.ui:1054 -#: panels/privacy/cc-privacy-panel.c:217 +#: panels/privacy/cc-privacy-panel.c:218 msgid "Manual" msgstr "Manual" @@ -1333,8 +1341,8 @@ msgstr "" "Albastru;culoare;apus;răsărit;" #. TRANSLATORS: AP type -#: panels/info/cc-info-overview-panel.c:374 -#: panels/info/cc-info-overview-panel.c:457 panels/network/panel-common.c:123 +#: panels/info/cc-info-overview-panel.c:373 +#: panels/info/cc-info-overview-panel.c:456 panels/network/panel-common.c:123 msgid "Unknown" msgstr "Necunoscut" @@ -1342,24 +1350,24 @@ msgstr "Necunoscut" #. * example: #. * "Fedora 25 (Workstation Edition); Build ID: xyz" or #. * "Ubuntu 16.04 LTS; Build ID: jki" -#: panels/info/cc-info-overview-panel.c:465 +#: panels/info/cc-info-overview-panel.c:464 #, c-format msgid "%s; Build ID: %s" msgstr "%s; ID-ul compilării: %s" #. translators: This is the type of architecture for the OS -#: panels/info/cc-info-overview-panel.c:482 +#: panels/info/cc-info-overview-panel.c:481 #, c-format msgid "64-bit" msgstr "64-biți" #. translators: This is the type of architecture for the OS -#: panels/info/cc-info-overview-panel.c:485 +#: panels/info/cc-info-overview-panel.c:484 #, c-format msgid "32-bit" msgstr "32-biți" -#: panels/info/cc-info-overview-panel.c:775 +#: panels/info/cc-info-overview-panel.c:773 #, c-format msgid "Version %s" msgstr "Versiunea %s" @@ -1427,7 +1435,7 @@ msgstr "disc HD DVD gol" #: panels/info/cc-info-removable-media-panel.c:445 msgid "Blu-ray video disc" -msgstr "disc video Blu-ray" +msgstr "Disc video Blu-ray" #: panels/info/cc-info-removable-media-panel.c:446 msgid "e-book reader" @@ -1435,7 +1443,7 @@ msgstr "cititor de cărți electronice" #: panels/info/cc-info-removable-media-panel.c:447 msgid "HD DVD video disc" -msgstr "disc video HD DVD" +msgstr "Disc video HD DVD" #: panels/info/cc-info-removable-media-panel.c:448 msgid "Picture CD" @@ -1694,8 +1702,8 @@ msgstr "Lansatori" msgid "Launch help browser" msgstr "Lansează navigatorul de ajutor" -#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:223 -#: shell/cc-window.c:762 shell/gnome-control-center.desktop.in.in:3 +#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:237 +#: shell/cc-window.c:773 shell/gnome-control-center.desktop.in.in:3 #: shell/window.ui:125 msgid "Settings" msgstr "Configurări" @@ -1804,7 +1812,7 @@ msgstr "Activează sau dezactivează contrastul puternic" #: panels/keyboard/cc-keyboard-manager.c:506 #: panels/keyboard/cc-keyboard-manager.c:514 -#: panels/keyboard/cc-keyboard-manager.c:822 +#: panels/keyboard/cc-keyboard-manager.c:821 msgid "Custom Shortcuts" msgstr "Scurtături personalizate" @@ -1815,7 +1823,7 @@ msgstr "Scurtături personalizate" #. * The device has been disabled #: panels/keyboard/cc-keyboard-option.c:263 #: panels/keyboard/cc-keyboard-option.c:382 -#: panels/keyboard/keyboard-shortcuts.c:435 +#: panels/keyboard/keyboard-shortcuts.c:434 #: panels/keyboard/shortcut-editor.ui:96 panels/network/network-proxy.ui:123 #: panels/network/network-wifi.ui:782 panels/network/network-wifi.ui:1059 #: panels/user-accounts/um-fingerprint-dialog.c:211 @@ -1920,7 +1928,7 @@ msgstr "" "Scurtătură;Scurtături;Fereastră;Redimensionează;Sursă;Blochează;Volum;" #: panels/keyboard/gnome-keyboard-panel.ui:67 panels/region/input-options.ui:68 -#: shell/cc-application.c:252 +#: shell/cc-application.c:255 msgid "Keyboard Shortcuts" msgstr "Scurtături tastatură" @@ -2113,7 +2121,7 @@ msgid "Single click, secondary button" msgstr "Un clic, buton secundar" #. add proxy to device list -#: panels/network/cc-network-panel.c:579 +#: panels/network/cc-network-panel.c:581 msgid "Network proxy" msgstr "Proxy rețea" @@ -2121,23 +2129,23 @@ msgstr "Proxy rețea" #. * window for vpn connections, it is also used to display #. * vpn connections in the device list. #. -#: panels/network/cc-network-panel.c:715 panels/network/net-vpn.c:192 -#: panels/network/net-vpn.c:321 +#: panels/network/cc-network-panel.c:717 panels/network/net-vpn.c:167 +#: panels/network/net-vpn.c:296 #, c-format msgid "%s VPN" msgstr "%s VPN" -#: panels/network/cc-network-panel.c:779 panels/network/wifi.ui:282 +#: panels/network/cc-network-panel.c:781 panels/network/wifi.ui:282 msgid "Oops, something has gone wrong. Please contact your software vendor." msgstr "" "Ups, ceva nu a funcționat corect. Vă rugăm să contactați distribuitorul de " "software." -#: panels/network/cc-network-panel.c:785 +#: panels/network/cc-network-panel.c:787 msgid "NetworkManager needs to be running." msgstr "NetworkManager trebuie să funcționeze." -#: panels/network/cc-wifi-panel.c:213 +#: panels/network/cc-wifi-panel.c:214 #: panels/network/gnome-wifi-panel.desktop.in.in:3 #: panels/network/network-wifi.ui:1769 msgid "Wi-Fi" @@ -2284,7 +2292,7 @@ msgid "Remove VPN" msgstr "Elimină VPN" #: panels/network/connection-editor/ce-page-details.c:334 -#: panels/network/network-wifi.ui:1456 shell/cc-window.c:215 +#: panels/network/network-wifi.ui:1456 shell/cc-window.c:229 #: shell/panel-list.ui:103 msgid "Details" msgstr "Detalii" @@ -2419,7 +2427,7 @@ msgstr "Adecvat pentru conexiuni care au limite sau taxe pentru date." #: panels/network/connection-editor/ip6-page.ui:291 #: panels/network/net-proxy.c:58 panels/network/network-proxy.ui:103 #: panels/network/wireless-security/eap-method-peap.ui:22 -#: panels/privacy/cc-privacy-panel.c:217 +#: panels/privacy/cc-privacy-panel.c:218 msgid "Automatic" msgstr "Automat" @@ -2619,7 +2627,7 @@ msgstr "Selectează fișierul de importat" #: panels/network/connection-editor/vpn-helpers.c:182 #: panels/printers/pp-details-dialog.c:332 #: panels/sharing/cc-sharing-panel.c:385 -#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-photo-dialog.c:231 msgid "_Open" msgstr "_Deschide" @@ -3358,23 +3366,23 @@ msgstr "Lipsă firmware" msgid "Cable unplugged" msgstr "Cablu neconectat" -#: panels/network/wireless-security/eap-method.c:57 +#: panels/network/wireless-security/eap-method.c:69 msgid "undefined error in 802.1X security (wpa-eap)" msgstr "eroare nespecificată în securitatea 802.1X (wpa-eap)" -#: panels/network/wireless-security/eap-method.c:233 +#: panels/network/wireless-security/eap-method.c:245 msgid "no file selected" msgstr "niciun fișier selectat" -#: panels/network/wireless-security/eap-method.c:264 +#: panels/network/wireless-security/eap-method.c:276 msgid "unspecified error validating eap-method file" msgstr "eroare nespecificată la validarea fișierului metodă eap" -#: panels/network/wireless-security/eap-method.c:439 +#: panels/network/wireless-security/eap-method.c:451 msgid "DER, PEM, or PKCS#12 private keys (*.der, *.pem, *.p12, *.key)" msgstr "DER, PEM, sau chei private PKCS#12 (*.der, *.pem, *.p12, *.key)" -#: panels/network/wireless-security/eap-method.c:442 +#: panels/network/wireless-security/eap-method.c:454 msgid "DER or PEM certificates (*.der, *.pem, *.crt, *.cer)" msgstr "Certificate DER sau PEM (*.der, *.pem, *.crt, *.cer)" @@ -3792,19 +3800,19 @@ msgstr "Altele" #. translators: This is the title of the "Show Account" dialog. The #. * %s is the name of the provider. e.g., 'Google'. -#: panels/online-accounts/cc-online-accounts-panel.c:596 +#: panels/online-accounts/cc-online-accounts-panel.c:612 #, c-format msgid "%s Account" msgstr "Cont %s" -#: panels/online-accounts/cc-online-accounts-panel.c:888 +#: panels/online-accounts/cc-online-accounts-panel.c:904 msgid "Error removing account" msgstr "Eroare la eliminarea contului" #. Translators: The %s is the username (eg., debarshi.ray@gmail.com #. * or rishi). #. -#: panels/online-accounts/cc-online-accounts-panel.c:953 +#: panels/online-accounts/cc-online-accounts-panel.c:969 #, c-format msgid "%s removed" msgstr "%s eliminat" @@ -3858,41 +3866,41 @@ msgstr "Adaugă un cont" msgid "Remove Account" msgstr "Ștergere cont" -#: panels/power/cc-power-panel.c:253 +#: panels/power/cc-power-panel.c:254 msgid "Unknown time" msgstr "Timp necunoscut" -#: panels/power/cc-power-panel.c:259 +#: panels/power/cc-power-panel.c:260 #, c-format msgid "%i minute" msgid_plural "%i minutes" -msgstr[0] "un minut" +msgstr[0] "%i minut" msgstr[1] "%i minute" msgstr[2] "%i de minute" -#: panels/power/cc-power-panel.c:271 +#: panels/power/cc-power-panel.c:272 #, c-format msgid "%i hour" msgid_plural "%i hours" -msgstr[0] "o oră" +msgstr[0] "%i oră" msgstr[1] "%i ore" msgstr[2] "%i de ore" #. TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes" #. * Swap order with "%2$s %2$i %1$s %1$i if needed -#: panels/power/cc-power-panel.c:279 +#: panels/power/cc-power-panel.c:280 #, c-format msgid "%i %s %i %s" msgstr "%i %s %i %s" -#: panels/power/cc-power-panel.c:280 +#: panels/power/cc-power-panel.c:281 msgid "hour" msgid_plural "hours" msgstr[0] "oră" msgstr[1] "ore" msgstr[2] "de ore" -#: panels/power/cc-power-panel.c:281 +#: panels/power/cc-power-panel.c:282 msgid "minute" msgid_plural "minutes" msgstr[0] "minut" @@ -3900,239 +3908,239 @@ msgstr[1] "minute" msgstr[2] "de minute" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:300 +#: panels/power/cc-power-panel.c:301 #, c-format msgid "%s until fully charged" msgstr "%s până e încărcată complet" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:307 +#: panels/power/cc-power-panel.c:308 #, c-format msgid "Caution: %s remaining" msgstr "Atenție: au mai rămas %s" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:312 +#: panels/power/cc-power-panel.c:313 #, c-format msgid "%s remaining" msgstr "au mai rămas %s" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:317 panels/power/cc-power-panel.c:345 +#: panels/power/cc-power-panel.c:318 panels/power/cc-power-panel.c:346 msgid "Fully charged" msgstr "Complet încărcat" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:321 panels/power/cc-power-panel.c:349 +#: panels/power/cc-power-panel.c:322 panels/power/cc-power-panel.c:350 msgid "Empty" msgstr "Descărcată complet" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:336 +#: panels/power/cc-power-panel.c:337 msgid "Charging" msgstr "Se încarcă" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:341 +#: panels/power/cc-power-panel.c:342 msgid "Discharging" msgstr "Se descarcă" -#: panels/power/cc-power-panel.c:464 +#: panels/power/cc-power-panel.c:465 msgctxt "Battery name" msgid "Main" msgstr "Principal" -#: panels/power/cc-power-panel.c:466 +#: panels/power/cc-power-panel.c:467 msgctxt "Battery name" msgid "Extra" msgstr "Extra" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:537 +#: panels/power/cc-power-panel.c:538 msgid "Wireless mouse" msgstr "Mouse fără fir" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:540 +#: panels/power/cc-power-panel.c:541 msgid "Wireless keyboard" msgstr "Tastatură fără fir" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:543 +#: panels/power/cc-power-panel.c:544 msgid "Uninterruptible power supply" msgstr "Sursă de curent neîntreruptibilă" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:546 +#: panels/power/cc-power-panel.c:547 msgid "Personal digital assistant" msgstr "Asistent personal digital" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:549 +#: panels/power/cc-power-panel.c:550 msgid "Cellphone" msgstr "Telefon celular" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:552 +#: panels/power/cc-power-panel.c:553 msgid "Media player" msgstr "Player media" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:555 panels/wacom/cc-wacom-panel.c:793 +#: panels/power/cc-power-panel.c:556 panels/wacom/cc-wacom-panel.c:793 msgid "Tablet" msgstr "Tabletă" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:558 +#: panels/power/cc-power-panel.c:559 msgid "Computer" msgstr "Calculator" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:561 +#: panels/power/cc-power-panel.c:562 msgid "Gaming input device" msgstr "Dispozitiv de intrare pentru jocuri" #. TRANSLATORS: secondary battery, misc -#: panels/power/cc-power-panel.c:564 panels/power/cc-power-panel.c:804 -#: panels/power/cc-power-panel.c:2380 +#: panels/power/cc-power-panel.c:565 panels/power/cc-power-panel.c:805 +#: panels/power/cc-power-panel.c:2398 msgid "Battery" msgstr "Baterie" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:618 +#: panels/power/cc-power-panel.c:619 msgctxt "Battery power" msgid "Charging" msgstr "Se încarcă" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:625 +#: panels/power/cc-power-panel.c:626 msgctxt "Battery power" msgid "Caution" msgstr "Atenție" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:630 +#: panels/power/cc-power-panel.c:631 msgctxt "Battery power" msgid "Low" msgstr "Scăzută" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:635 +#: panels/power/cc-power-panel.c:636 msgctxt "Battery power" msgid "Good" msgstr "Bună" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:640 +#: panels/power/cc-power-panel.c:641 msgctxt "Battery power" msgid "Fully charged" msgstr "Complet încărcat" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:644 +#: panels/power/cc-power-panel.c:645 msgctxt "Battery power" msgid "Empty" msgstr "Descărcată complet" -#: panels/power/cc-power-panel.c:802 +#: panels/power/cc-power-panel.c:803 msgid "Batteries" msgstr "Baterii" -#: panels/power/cc-power-panel.c:1242 +#: panels/power/cc-power-panel.c:1243 msgid "When _idle" msgstr "Când e _inactiv" -#: panels/power/cc-power-panel.c:1696 +#: panels/power/cc-power-panel.c:1708 msgid "Power Saving" msgstr "Economisire de energie" -#: panels/power/cc-power-panel.c:1727 +#: panels/power/cc-power-panel.c:1739 msgid "_Screen brightness" msgstr "Luminozitate ec_ran" -#: panels/power/cc-power-panel.c:1746 +#: panels/power/cc-power-panel.c:1758 msgid "Automatic brightness" msgstr "Luminozitate automată" -#: panels/power/cc-power-panel.c:1766 +#: panels/power/cc-power-panel.c:1778 msgid "_Keyboard brightness" msgstr "Luminozitate _tastatură" -#: panels/power/cc-power-panel.c:1776 +#: panels/power/cc-power-panel.c:1788 msgid "_Dim screen when inactive" msgstr "_Diminuează luminozitatea la inactivitate" -#: panels/power/cc-power-panel.c:1801 +#: panels/power/cc-power-panel.c:1813 msgid "_Blank screen" msgstr "Ecran _gol" -#: panels/power/cc-power-panel.c:1838 +#: panels/power/cc-power-panel.c:1850 msgid "_Wi-Fi" msgstr "_Wi-Fi" -#: panels/power/cc-power-panel.c:1843 +#: panels/power/cc-power-panel.c:1855 msgid "Turn off Wi-Fi to save power." msgstr "Închide Wi-Fi pentru a economisi energia." -#: panels/power/cc-power-panel.c:1868 +#: panels/power/cc-power-panel.c:1880 msgid "_Mobile broadband" msgstr "Internet _mobil de bandă largă" -#: panels/power/cc-power-panel.c:1873 +#: panels/power/cc-power-panel.c:1885 msgid "Turn off mobile broadband (3G, 4G, LTE, etc.) to save power." msgstr "" "Închide internetul mobil (3G, 4G, LTE, etc.) pentru a economisi energie." -#: panels/power/cc-power-panel.c:1926 +#: panels/power/cc-power-panel.c:1944 msgid "_Bluetooth" msgstr "_Bluetooth" -#: panels/power/cc-power-panel.c:1931 +#: panels/power/cc-power-panel.c:1949 msgid "Turn off Bluetooth to save power." msgstr "Închide Bluetooth pentru a economisi energia." -#: panels/power/cc-power-panel.c:1990 +#: panels/power/cc-power-panel.c:2008 msgid "When on battery power" msgstr "Când funcționează pe baterie" -#: panels/power/cc-power-panel.c:1992 +#: panels/power/cc-power-panel.c:2010 msgid "When plugged in" msgstr "Alimentat de la rețea" -#: panels/power/cc-power-panel.c:2087 +#: panels/power/cc-power-panel.c:2105 msgid "Suspend" msgstr "Suspendă" -#: panels/power/cc-power-panel.c:2088 +#: panels/power/cc-power-panel.c:2106 msgid "Power Off" msgstr "Oprește" -#: panels/power/cc-power-panel.c:2089 +#: panels/power/cc-power-panel.c:2107 msgid "Hibernate" msgstr "Hibernează" -#: panels/power/cc-power-panel.c:2090 +#: panels/power/cc-power-panel.c:2108 msgid "Nothing" msgstr "Nimic" #. Frame header -#: panels/power/cc-power-panel.c:2204 +#: panels/power/cc-power-panel.c:2222 msgid "Suspend & Power Button" msgstr "Buton de suspendare și oprire" -#: panels/power/cc-power-panel.c:2243 +#: panels/power/cc-power-panel.c:2261 msgid "_Automatic suspend" msgstr "Suspendare _automată" -#: panels/power/cc-power-panel.c:2244 +#: panels/power/cc-power-panel.c:2262 msgid "Automatic suspend" msgstr "Suspendare automată" -#: panels/power/cc-power-panel.c:2311 +#: panels/power/cc-power-panel.c:2329 msgid "_When the Power Button is pressed" msgstr "_Când butonul de oprire este apăsat" -#: panels/power/cc-power-panel.c:2430 shell/cc-window.c:219 +#: panels/power/cc-power-panel.c:2448 shell/cc-window.c:233 #: shell/panel-list.ui:45 msgid "Devices" msgstr "Dispozitive" @@ -4163,11 +4171,11 @@ msgstr "20 de minute" #: panels/power/power.ui:21 msgid "25 minutes" -msgstr "25 minute" +msgstr "25 de minute" #: panels/power/power.ui:29 msgid "45 minutes" -msgstr "45 minute" +msgstr "45 de minute" #: panels/power/power.ui:33 panels/privacy/privacy.ui:42 #: panels/privacy/privacy.ui:56 @@ -4266,18 +4274,18 @@ msgid "Authentication Required" msgstr "Necesită autentificare" #. Translators: %s is the printer name -#: panels/printers/cc-printers-panel.c:808 +#: panels/printers/cc-printers-panel.c:809 #, c-format msgid "Printer “%s” has been deleted" msgstr "Imprimanta „%s” a fost ștearsă" #. Translators: Addition of the new printer failed. -#: panels/printers/cc-printers-panel.c:1053 +#: panels/printers/cc-printers-panel.c:1054 msgid "Failed to add new printer." msgstr "Nu s-a putut adăuga imprimanta nouă." #. Translators: The XML file containing user interface can not be loaded -#: panels/printers/cc-printers-panel.c:1388 +#: panels/printers/cc-printers-panel.c:1391 #, c-format msgid "Could not load ui: %s" msgstr "Nu s-a putut încărca interfața cu utilizatorul: %s" @@ -4417,7 +4425,7 @@ msgid "Select Printer Driver" msgstr "Selectați driverul imprimantei" #: panels/printers/ppd-selection-dialog.ui:40 -#: panels/user-accounts/um-photo-dialog.c:104 +#: panels/user-accounts/um-photo-dialog.c:105 msgid "Select" msgstr "Selectează" @@ -4907,25 +4915,25 @@ msgstr "" "Ne pare rău! Se pare că serviciul\n" "de tipărire al sistemului nu este disponibil." -#: panels/privacy/cc-privacy-panel.c:387 panels/privacy/privacy.ui:280 +#: panels/privacy/cc-privacy-panel.c:388 panels/privacy/privacy.ui:280 msgid "Screen Lock" msgstr "Blocare ecran" -#: panels/privacy/cc-privacy-panel.c:438 +#: panels/privacy/cc-privacy-panel.c:439 msgid "In use" msgstr "În uz" -#: panels/privacy/cc-privacy-panel.c:443 +#: panels/privacy/cc-privacy-panel.c:444 msgctxt "Location services status" msgid "On" msgstr "Pornit" -#: panels/privacy/cc-privacy-panel.c:444 +#: panels/privacy/cc-privacy-panel.c:445 msgctxt "Location services status" msgid "Off" msgstr "Oprit" -#: panels/privacy/cc-privacy-panel.c:823 panels/privacy/privacy.ui:745 +#: panels/privacy/cc-privacy-panel.c:825 panels/privacy/privacy.ui:745 msgid "Location Services" msgstr "Servicii de locație" @@ -4955,11 +4963,11 @@ msgstr "Toate fișierele temporare vor fi șterse permanent." #: panels/privacy/cc-privacy-panel.c:1102 msgid "_Purge Temporary Files" -msgstr "_Purjează fișierele temporare" +msgstr "Șterge fișierele tem_porare" #: panels/privacy/cc-privacy-panel.c:1124 panels/privacy/privacy.ui:432 msgid "Purge Trash & Temporary Files" -msgstr "Purjare gunoi și fișiere temporare" +msgstr "Golește gunoiul și șterge fișierele temporare" #: panels/privacy/cc-privacy-panel.c:1164 panels/privacy/privacy.ui:637 msgid "Software Usage" @@ -5118,7 +5126,7 @@ msgstr "Gol_ește gunoiul…" #: panels/privacy/privacy.ui:606 msgid "_Purge Temporary Files…" -msgstr "_Purjează fișierele temporare…" +msgstr "Șterge fișierele tem_porare…" #: panels/privacy/privacy.ui:654 msgid "" @@ -5129,12 +5137,11 @@ msgid "" "All the information we collect is made anonymous, and we will never share " "your data with third parties." msgstr "" -"Dacă ne trimiteți informații despre cum folosiți software-ul, aceasta ne " -"ajută să vă facem niște recomandări mai precise. Ne ajută și la " -"îmbunătățirea software-ului.\n" +"Trimiterea de informații despre ce software utilizați ne ajută să furnizăm " +"recomandări mai precise. Ne ajută și la îmbunătățirea software-ului.\n" "\n" -"Toată informația colectată este anonomizată și nu o vom împărtăși niciodată " -"cu terți." +"Toate informațiile colectate sunt anonime, și nu le vom partaja niciodată cu " +"părți terțe." #: panels/privacy/privacy.ui:681 msgid "_Send software usage statistics" @@ -5187,11 +5194,11 @@ msgctxt "Input Source" msgid "Other" msgstr "Altele" -#: panels/region/cc-region-panel.c:881 +#: panels/region/cc-region-panel.c:882 msgid "No input source selected" msgstr "Nicio sursă de intrare selectată" -#: panels/region/cc-region-panel.c:1773 +#: panels/region/cc-region-panel.c:1774 msgid "Login _Screen" msgstr "_Ecran de autentificare" @@ -5538,7 +5545,7 @@ msgstr "Autentifica_re la distanță" #: panels/sharing/sharing.ui:272 msgid "Some services are disabled because of no network access." -msgstr "Unele servicii sunt dezactivate din lipsa accesului la rețea" +msgstr "Unele servicii sunt dezactivate din lipsa accesului la rețea." #: panels/sharing/sharing.ui:286 panels/sharing/sharing.ui:413 msgid "File Sharing" @@ -5800,32 +5807,32 @@ msgstr "Personalizat" #. translators: the labels will read: #. * Cursor Size: Default -#: panels/universal-access/cc-ua-panel.c:353 +#: panels/universal-access/cc-ua-panel.c:354 msgctxt "cursor size" msgid "Default" msgstr "Implicită" -#: panels/universal-access/cc-ua-panel.c:356 +#: panels/universal-access/cc-ua-panel.c:357 msgctxt "cursor size" msgid "Medium" msgstr "Medie" -#: panels/universal-access/cc-ua-panel.c:359 +#: panels/universal-access/cc-ua-panel.c:360 msgctxt "cursor size" msgid "Large" msgstr "Mare" -#: panels/universal-access/cc-ua-panel.c:362 +#: panels/universal-access/cc-ua-panel.c:363 msgctxt "cursor size" msgid "Larger" msgstr "Mai mare" -#: panels/universal-access/cc-ua-panel.c:365 +#: panels/universal-access/cc-ua-panel.c:366 msgctxt "cursor size" msgid "Largest" msgstr "Cel mai mare" -#: panels/universal-access/cc-ua-panel.c:369 +#: panels/universal-access/cc-ua-panel.c:370 #, c-format msgid "%d pixel" msgid_plural "%d pixels" @@ -5836,7 +5843,7 @@ msgstr[2] "%d de pixeli" #: panels/universal-access/gnome-universal-access-panel.desktop.in.in:4 msgid "Make it easier to see, hear, type, point and click" msgstr "" -"Interfața mai ușor de văzut, auzit și de utilizat cu tastatura și mausul." +"Facilitează vederea, auzul, tastatul, mutatul mausului și apăsarea clicului" #. Translators: Do NOT translate or transliterate this text (this is an icon file name)! #: panels/universal-access/gnome-universal-access-panel.desktop.in.in:7 @@ -5856,7 +5863,7 @@ msgstr "" #: panels/universal-access/uap.ui:89 msgid "_Always Show Universal Access Menu" -msgstr "_Arată întotdeauna meniul „Acces Universal”" +msgstr "_Arată întotdeauna meniul de acces universal" #: panels/universal-access/uap.ui:131 msgid "Seeing" @@ -5875,7 +5882,7 @@ msgid "C_ursor Size" msgstr "Dimenisunea c_ursorului" #: panels/universal-access/uap.ui:316 -#: panels/universal-access/zoom-options.ui:98 +#: panels/universal-access/zoom-options.ui:99 msgid "_Zoom" msgstr "_Zoom" @@ -5939,7 +5946,7 @@ msgstr "Dimensiunea cursorului" msgid "" "Cursor size can be combined with zoom to make it easier to see the cursor." msgstr "" -"Dimenisunea cursorului poate fi combinată cu zoom pentru a face ecranul mai " +"Dimensiunea cursorului poate fi combinată cu zoom pentru a face ecranul mai " "lizibil." #: panels/universal-access/uap.ui:1105 @@ -5948,7 +5955,8 @@ msgstr "Cititor de ecran" #: panels/universal-access/uap.ui:1122 msgid "The screen reader reads displayed text as you move the focus." -msgstr "Cititorul de ecran afișează textul afișat în fereastra activă" +msgstr "" +"Cititorul de ecran citește textul afișat în timp ce mutați focalizarea." #: panels/universal-access/uap.ui:1155 msgid "_Screen Reader" @@ -6043,7 +6051,7 @@ msgstr "Taste _lente" msgid "Puts a delay between when a key is pressed and when it is accepted" msgstr "" "Introduce o întârziere între momentul în care o tastă este apăsată și cel în " -"care este acceptată." +"care este acceptată" #: panels/universal-access/uap.ui:1988 panels/universal-access/uap.ui:2201 #: panels/universal-access/uap.ui:2538 @@ -6170,27 +6178,27 @@ msgctxt "dwell click threshold" msgid "Large" msgstr "Mare" -#: panels/universal-access/zoom-options.c:339 +#: panels/universal-access/zoom-options.c:338 msgctxt "Distance" msgid "Short" msgstr "Scurtă" -#: panels/universal-access/zoom-options.c:340 +#: panels/universal-access/zoom-options.c:339 msgctxt "Distance" msgid "¼ Screen" msgstr "¼ de ecran" -#: panels/universal-access/zoom-options.c:341 +#: panels/universal-access/zoom-options.c:340 msgctxt "Distance" msgid "½ Screen" msgstr "½ de ecran" -#: panels/universal-access/zoom-options.c:342 +#: panels/universal-access/zoom-options.c:341 msgctxt "Distance" msgid "¾ Screen" msgstr "¾ de ecran" -#: panels/universal-access/zoom-options.c:343 +#: panels/universal-access/zoom-options.c:342 msgctxt "Distance" msgid "Long" msgstr "Lungă" @@ -6215,134 +6223,134 @@ msgstr "Jumătatea stângă" msgid "Right Half" msgstr "Jumătatea dreaptă" -#: panels/universal-access/zoom-options.ui:77 +#: panels/universal-access/zoom-options.ui:78 msgid "Zoom Options" msgstr "Opțiuni zoom" -#: panels/universal-access/zoom-options.ui:187 +#: panels/universal-access/zoom-options.ui:188 msgid "_Magnification:" msgstr "_Mărire:" -#: panels/universal-access/zoom-options.ui:251 +#: panels/universal-access/zoom-options.ui:252 msgid "_Follow mouse cursor" msgstr "_Urmărește cursorul mausului" -#: panels/universal-access/zoom-options.ui:271 +#: panels/universal-access/zoom-options.ui:272 msgid "_Screen part:" msgstr "Parte _ecran:" -#: panels/universal-access/zoom-options.ui:333 +#: panels/universal-access/zoom-options.ui:334 msgid "Magnifier _extends outside of screen" msgstr "Lupa se _extinde peste marginile ecranului" -#: panels/universal-access/zoom-options.ui:352 +#: panels/universal-access/zoom-options.ui:353 msgid "_Keep magnifier cursor centered" msgstr "_Păstrează centrat cursorul lupei" -#: panels/universal-access/zoom-options.ui:371 +#: panels/universal-access/zoom-options.ui:372 msgid "Magnifier cursor _pushes contents around" msgstr "Cursorul lupei îm_pinge conținutul" -#: panels/universal-access/zoom-options.ui:390 +#: panels/universal-access/zoom-options.ui:391 msgid "Magnifier cursor moves with _contents" msgstr "Cursorul lupei se mișcă odată cu _conținutul" -#: panels/universal-access/zoom-options.ui:424 +#: panels/universal-access/zoom-options.ui:425 msgid "Magnifier Position:" msgstr "Poziție lupă:" -#: panels/universal-access/zoom-options.ui:445 +#: panels/universal-access/zoom-options.ui:446 msgid "Magnifier" msgstr "Lupă" -#: panels/universal-access/zoom-options.ui:492 +#: panels/universal-access/zoom-options.ui:493 msgid "_Thickness:" msgstr "_Grosime:" -#: panels/universal-access/zoom-options.ui:518 +#: panels/universal-access/zoom-options.ui:519 msgctxt "universal access, thickness" msgid "Thin" msgstr "Subțire" -#: panels/universal-access/zoom-options.ui:550 +#: panels/universal-access/zoom-options.ui:551 msgctxt "universal access, thickness" msgid "Thick" msgstr "Gros" -#: panels/universal-access/zoom-options.ui:576 +#: panels/universal-access/zoom-options.ui:577 msgid "_Length:" msgstr "_Lungime:" #. The color of the accessibility crosshair -#: panels/universal-access/zoom-options.ui:628 +#: panels/universal-access/zoom-options.ui:629 msgid "Co_lor:" msgstr "Cu_loare:" -#: panels/universal-access/zoom-options.ui:692 +#: panels/universal-access/zoom-options.ui:693 msgid "_Crosshairs:" msgstr "Țin_tă:" -#: panels/universal-access/zoom-options.ui:743 +#: panels/universal-access/zoom-options.ui:744 msgid "_Overlaps mouse cursor" msgstr "Suprapune peste curs_orul mausului" -#: panels/universal-access/zoom-options.ui:781 +#: panels/universal-access/zoom-options.ui:782 msgid "Crosshairs" msgstr "Țintă" -#: panels/universal-access/zoom-options.ui:830 +#: panels/universal-access/zoom-options.ui:831 msgid "_White on black:" msgstr "_Alb pe negru:" -#: panels/universal-access/zoom-options.ui:853 +#: panels/universal-access/zoom-options.ui:854 msgid "_Brightness:" msgstr "_Luminozitate:" -#: panels/universal-access/zoom-options.ui:877 +#: panels/universal-access/zoom-options.ui:878 msgid "_Contrast:" msgstr "_Contrast:" #. The contrast scale goes from Color to None (grayscale) -#: panels/universal-access/zoom-options.ui:900 +#: panels/universal-access/zoom-options.ui:901 msgctxt "universal access, contrast" msgid "Co_lor" msgstr "Cu_loare" -#: panels/universal-access/zoom-options.ui:928 +#: panels/universal-access/zoom-options.ui:929 msgctxt "universal access, color" msgid "None" msgstr "Niciuna" -#: panels/universal-access/zoom-options.ui:960 +#: panels/universal-access/zoom-options.ui:961 msgctxt "universal access, color" msgid "Full" msgstr "Completă" -#: panels/universal-access/zoom-options.ui:1026 +#: panels/universal-access/zoom-options.ui:1027 msgctxt "universal access, brightness" msgid "Low" msgstr "Scăzută" -#: panels/universal-access/zoom-options.ui:1059 +#: panels/universal-access/zoom-options.ui:1060 msgctxt "universal access, brightness" msgid "High" msgstr "Ridicată" -#: panels/universal-access/zoom-options.ui:1090 +#: panels/universal-access/zoom-options.ui:1091 msgctxt "universal access, contrast" msgid "Low" msgstr "Scăzut" -#: panels/universal-access/zoom-options.ui:1123 +#: panels/universal-access/zoom-options.ui:1124 msgctxt "universal access, contrast" msgid "High" msgstr "Ridicat" -#: panels/universal-access/zoom-options.ui:1159 +#: panels/universal-access/zoom-options.ui:1160 msgid "Color Effects:" msgstr "Efecte de culoare:" -#: panels/universal-access/zoom-options.ui:1184 +#: panels/universal-access/zoom-options.ui:1185 msgid "Color Effects" msgstr "Efecte de culoare" @@ -6603,7 +6611,7 @@ msgstr "Pentru modificarea datelor utilizatorilor trebuie să vă autentificați #: panels/user-accounts/pw-utils.c:81 msgctxt "Password hint" msgid "The new password needs to be different from the old one." -msgstr "Noua parolă nu conține suficiente caractere diferite" +msgstr "Noua parolă trebuie să fie diferită de parola veche." #: panels/user-accounts/pw-utils.c:83 msgctxt "Password hint" @@ -6982,7 +6990,7 @@ msgstr "Parola nu a putut fi schimbată" msgid "The passwords do not match." msgstr "Parolele nu se potrivesc." -#: panels/user-accounts/um-photo-dialog.c:226 +#: panels/user-accounts/um-photo-dialog.c:227 msgid "Browse for more pictures" msgstr "Răsfoiește pentru mai multe imagini" @@ -7156,7 +7164,7 @@ msgid "" "digits and the following characters: . - _" msgstr "" "Numele de utilizator poate conține numai litere mari și mici de la a la z, " -"cifre și oricare din caracterele: „.”, „-” și „_”" +"cifre și următoarele caractere: . - _" #: panels/user-accounts/um-utils.c:509 msgid "This will be used to name your home folder and can’t be changed." @@ -7406,43 +7414,43 @@ msgstr "" "Centrul de control este interfața principală GNOME pentru configurări ale " "calculatorului dumneavoastră." -#: shell/cc-application.c:59 +#: shell/cc-application.c:60 msgid "Display version number" msgstr "Afișează număr versiune" -#: shell/cc-application.c:60 +#: shell/cc-application.c:61 msgid "Enable verbose mode" msgstr "Activează modul volubil" -#: shell/cc-application.c:61 +#: shell/cc-application.c:62 msgid "Show the overview" msgstr "Afișează prezentarea generală" -#: shell/cc-application.c:62 +#: shell/cc-application.c:63 msgid "Search for the string" msgstr "Caută un șir" -#: shell/cc-application.c:63 +#: shell/cc-application.c:64 msgid "List possible panel names and exit" msgstr "Listează nume posibile pentru panouri și apoi închide fereastra" -#: shell/cc-application.c:64 +#: shell/cc-application.c:65 msgid "Panel to display" msgstr "Panou de afișat" -#: shell/cc-application.c:64 +#: shell/cc-application.c:65 msgid "[PANEL] [ARGUMENT…]" msgstr "[PANEL] [ARGUMENT…]" -#: shell/cc-application.c:135 +#: shell/cc-application.c:136 msgid "Available panels:" msgstr "Panouri disponibile:" -#: shell/cc-application.c:253 +#: shell/cc-application.c:256 msgid "Help" msgstr "Ajutor" -#: shell/cc-application.c:254 +#: shell/cc-application.c:257 msgid "Quit" msgstr "Ieșire" @@ -8393,8 +8401,8 @@ msgstr "Sunete de sistem" #~ "Select a monitor to change its properties; drag it to rearrange its " #~ "placement." #~ msgstr "" -#~ "Selectați un monitor pentru a-i schimba proprietățile; trageți-l pentru a-l " -#~ "rearanja." +#~ "Selectați un monitor pentru a-i schimba proprietățile; trageți-l pentru a-" +#~ "l rearanja." #~ msgid "%a %R" #~ msgstr "%a %R" -- cgit v1.2.1 From c6f3b6859a8f9cf3f280146703d809baa263eda0 Mon Sep 17 00:00:00 2001 From: Daniel Mustieles Date: Mon, 23 Apr 2018 16:12:54 +0200 Subject: Updated Spanish translation --- po/es.po | 1097 ++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 675 insertions(+), 422 deletions(-) diff --git a/po/es.po b/po/es.po index b59dcd872..748fd6b42 100644 --- a/po/es.po +++ b/po/es.po @@ -20,8 +20,8 @@ msgstr "" "Project-Id-Version: gnome-control-center master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-control-center/" "issues\n" -"POT-Creation-Date: 2018-02-20 09:14+0000\n" -"PO-Revision-Date: 2018-02-21 17:01+0100\n" +"POT-Creation-Date: 2018-04-19 13:00+0000\n" +"PO-Revision-Date: 2018-04-23 15:03+0200\n" "Last-Translator: Daniel Mustieles \n" "Language-Team: es \n" "Language: es\n" @@ -113,16 +113,16 @@ msgid "You can add images to your %s folder and they will show up here" msgstr "Puede añadir imágenes a su carpeta %s y se mostrarán aquí" #: panels/background/cc-background-chooser-dialog.c:560 -#: panels/color/cc-color-panel.c:225 panels/color/cc-color-panel.c:963 +#: panels/color/cc-color-panel.c:224 panels/color/cc-color-panel.c:962 #: panels/color/color-calibrate.ui:25 panels/color/color.ui:657 -#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2594 +#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2610 #: panels/network/connection-editor/connection-editor.ui:15 #: panels/network/connection-editor/vpn-helpers.c:181 #: panels/network/connection-editor/vpn-helpers.c:310 -#: panels/network/net-device-wifi.c:1371 panels/network/net-device-wifi.c:1451 -#: panels/network/net-device-wifi.c:1690 panels/network/network-wifi.ui:24 +#: panels/network/net-device-wifi.c:1411 panels/network/net-device-wifi.c:1491 +#: panels/network/net-device-wifi.c:1736 panels/network/network-wifi.ui:24 #: panels/printers/new-printer-dialog.ui:45 -#: panels/printers/pp-details-dialog.c:331 +#: panels/printers/pp-details-dialog.c:330 #: panels/privacy/cc-privacy-panel.c:1053 panels/region/format-chooser.ui:25 #: panels/region/input-chooser.ui:13 #: panels/search/cc-search-locations-dialog.c:642 @@ -131,10 +131,10 @@ msgstr "Puede añadir imágenes a su carpeta %s y se mostrarán aquí" #: panels/user-accounts/data/join-dialog.ui:20 #: panels/user-accounts/data/password-dialog.ui:21 #: panels/user-accounts/um-fingerprint-dialog.c:261 -#: panels/user-accounts/um-photo-dialog.c:102 -#: panels/user-accounts/um-photo-dialog.c:229 -#: panels/user-accounts/um-user-panel.c:635 -#: panels/user-accounts/um-user-panel.c:653 +#: panels/user-accounts/um-photo-dialog.c:103 +#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-user-panel.c:634 +#: panels/user-accounts/um-user-panel.c:652 msgid "_Cancel" msgstr "_Cancelar" @@ -169,49 +169,50 @@ msgstr "Fondo" msgid "Change your background image to a wallpaper or photo" msgstr "Cambiar la imagen de fondo de escritorio por un tapiz o una foto" -#: panels/background/gnome-background-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/background/gnome-background-panel.desktop.in.in:7 msgid "preferences-desktop-wallpaper" msgstr "preferences-desktop-wallpaper" -#. Translators: those are keywords for the background control-center panel -#: panels/background/gnome-background-panel.desktop.in.in:14 +#. Translators: Search terms to find the Background panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/background/gnome-background-panel.desktop.in.in:15 msgid "Wallpaper;Screen;Desktop;" msgstr "Fondo de pantalla;Pantalla;Escritorio;" -#: panels/bluetooth/cc-bluetooth-panel.c:265 +#: panels/bluetooth/cc-bluetooth-panel.c:266 msgid "Turn Off Airplane Mode" msgstr "Apagar el modo avión" -#: panels/bluetooth/cc-bluetooth-panel.c:330 +#: panels/bluetooth/cc-bluetooth-panel.c:329 msgid "No Bluetooth Found" msgstr "No se encontraron adaptadores Bluetooth" -#: panels/bluetooth/cc-bluetooth-panel.c:330 +#: panels/bluetooth/cc-bluetooth-panel.c:329 msgid "Plug in a dongle to use Bluetooth." msgstr "Conectar a un dongle para usar el Bluetooth." -#: panels/bluetooth/cc-bluetooth-panel.c:331 +#: panels/bluetooth/cc-bluetooth-panel.c:330 msgid "Bluetooth Turned Off" msgstr "Bluetooth apagado" -#: panels/bluetooth/cc-bluetooth-panel.c:331 +#: panels/bluetooth/cc-bluetooth-panel.c:330 msgid "Turn on to connect devices and receive file transfers." msgstr "" "Encender para conectar dispositivos y recibir transferencias de archivos." -#: panels/bluetooth/cc-bluetooth-panel.c:332 +#: panels/bluetooth/cc-bluetooth-panel.c:331 msgid "Airplane Mode is on" msgstr "El modo avión está activado" -#: panels/bluetooth/cc-bluetooth-panel.c:332 +#: panels/bluetooth/cc-bluetooth-panel.c:331 msgid "Bluetooth is disabled when airplane mode is on." msgstr "El Bluetooth está apagado cuando el modo avión está activado." -#: panels/bluetooth/cc-bluetooth-panel.c:333 +#: panels/bluetooth/cc-bluetooth-panel.c:332 msgid "Hardware Airplane Mode is on" msgstr "El hardware en modo avión está activado" -#: panels/bluetooth/cc-bluetooth-panel.c:333 +#: panels/bluetooth/cc-bluetooth-panel.c:332 msgid "Turn off the Airplane mode switch to enable Bluetooth." msgstr "Apague el modo avión para activar el Bluetooth." @@ -225,17 +226,18 @@ msgstr "Bluetooth" msgid "Turn Bluetooth on and off and connect your devices" msgstr "Activar y desactivar Bluetooth y conectar sus dispositivos" -#: panels/bluetooth/gnome-bluetooth-panel.desktop.in.in:5 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/bluetooth/gnome-bluetooth-panel.desktop.in.in:6 msgid "bluetooth" msgstr "bluetooth" -#. Translators: those are keywords for the bluetooth control-center panel -#: panels/bluetooth/gnome-bluetooth-panel.desktop.in.in:18 +#. Translators: Search terms to find the Bluetooth panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/bluetooth/gnome-bluetooth-panel.desktop.in.in:19 msgid "share;sharing;bluetooth;obex;" msgstr "compartir;compartición;bluetooth;obex;" #. TRANSLATORS: The user has to attach the sensor to the screen -#: panels/color/cc-color-calibrate.c:361 +#: panels/color/cc-color-calibrate.c:363 msgid "Place your calibration device over the square and press “Start”" msgstr "" "Coloque su dispositivo de calibración sobre el cuadrado y pulse «Iniciar»" @@ -243,7 +245,7 @@ msgstr "" #. TRANSLATORS: Some calibration devices need the user to move a #. * dial or switch manually. We also show a picture showing them #. * what to do... -#: panels/color/cc-color-calibrate.c:367 +#: panels/color/cc-color-calibrate.c:369 msgid "" "Move your calibration device to the calibrate position and press “Continue”" msgstr "" @@ -253,7 +255,7 @@ msgstr "" #. TRANSLATORS: Some calibration devices need the user to move a #. * dial or switch manually. We also show a picture showing them #. * what to do... -#: panels/color/cc-color-calibrate.c:373 +#: panels/color/cc-color-calibrate.c:375 msgid "" "Move your calibration device to the surface position and press “Continue”" msgstr "" @@ -263,54 +265,54 @@ msgstr "" #. TRANSLATORS: on some hardware e.g. Lenovo W700 the sensor #. * is built into the palmrest and we need to fullscreen the #. * sample widget and shut the lid. -#: panels/color/cc-color-calibrate.c:379 +#: panels/color/cc-color-calibrate.c:381 msgid "Shut the laptop lid" msgstr "Apagar la tapa del portátil" #. TRANSLATORS: We suck, the calibation failed and we have no #. * good idea why or any suggestions -#: panels/color/cc-color-calibrate.c:410 +#: panels/color/cc-color-calibrate.c:412 msgid "An internal error occurred that could not be recovered." msgstr "Ocurrió un error interno y no se pudo recuperar." #. TRANSLATORS: Some required-at-runtime tools were not #. * installed, which should only affect insane distros -#: panels/color/cc-color-calibrate.c:415 +#: panels/color/cc-color-calibrate.c:417 msgid "Tools required for calibration are not installed." msgstr "Las herramientas requeridas para la calibración no están instaladas." #. TRANSLATORS: The profile failed for some reason -#: panels/color/cc-color-calibrate.c:421 +#: panels/color/cc-color-calibrate.c:423 msgid "The profile could not be generated." msgstr "No se puede generar el perfil." #. TRANSLATORS: The user specified a whitepoint that was #. * unobtainable with the hardware they've got -- see #. * https://en.wikipedia.org/wiki/White_point for details -#: panels/color/cc-color-calibrate.c:427 +#: panels/color/cc-color-calibrate.c:429 msgid "The target whitepoint was not obtainable." msgstr "No se pudo obtener el punto blanco del objetivo." #. TRANSLATORS: the display calibration process is finished -#: panels/color/cc-color-calibrate.c:467 +#: panels/color/cc-color-calibrate.c:469 msgid "Complete!" msgstr "Completado" #. TRANSLATORS: the display calibration failed, and we also show #. * the translated (or untranslated) error string after this -#: panels/color/cc-color-calibrate.c:475 +#: panels/color/cc-color-calibrate.c:477 msgid "Calibration failed!" msgstr "Falló la configuración." #. TRANSLATORS: The user can now remove the sensor from the screen -#: panels/color/cc-color-calibrate.c:482 +#: panels/color/cc-color-calibrate.c:484 msgid "You can remove the calibration device." msgstr "Puede quitar el dispositivo de calibración." #. TRANSLATORS: The user has to be careful not to knock the #. * display off the screen (although we do cope if this is #. * detected early enough) -#: panels/color/cc-color-calibrate.c:553 +#: panels/color/cc-color-calibrate.c:556 msgid "Do not disturb the calibration device while in progress" msgstr "No interrumpir al dispositivo de calibración cuando está en progreso" @@ -372,48 +374,48 @@ msgstr "Sin calibrar" #. TRANSLATORS: this is a profile prefix to signify the #. * profile has been auto-generated for this hardware -#: panels/color/cc-color-panel.c:141 +#: panels/color/cc-color-panel.c:140 msgid "Default: " msgstr "Predeterminado: " #. TRANSLATORS: this is a profile prefix to signify the #. * profile his a standard space like AdobeRGB -#: panels/color/cc-color-panel.c:149 +#: panels/color/cc-color-panel.c:148 msgid "Colorspace: " msgstr "Espacio de color: " #. TRANSLATORS: this is a profile prefix to signify the #. * profile is a test profile -#: panels/color/cc-color-panel.c:156 +#: panels/color/cc-color-panel.c:155 msgid "Test profile: " msgstr "Perfil de color: " #. TRANSLATORS: an ICC profile is a file containing colorspace data -#: panels/color/cc-color-panel.c:223 +#: panels/color/cc-color-panel.c:222 msgid "Select ICC Profile File" msgstr "Seleccionar archivo de perfil ICC" -#: panels/color/cc-color-panel.c:226 +#: panels/color/cc-color-panel.c:225 msgid "_Import" msgstr "_Importar" #. TRANSLATORS: filter name on the file->open dialog -#: panels/color/cc-color-panel.c:237 +#: panels/color/cc-color-panel.c:236 msgid "Supported ICC profiles" msgstr "Perfiles ICC soportados" #. TRANSLATORS: filter name on the file->open dialog -#: panels/color/cc-color-panel.c:244 +#: panels/color/cc-color-panel.c:243 #: panels/network/wireless-security/eap-method-fast.c:417 msgid "All files" msgstr "Todos los archivos" -#: panels/color/cc-color-panel.c:583 +#: panels/color/cc-color-panel.c:582 msgid "Screen" msgstr "Pantalla" #. TRANSLATORS: this is when the upload of the profile failed -#: panels/color/cc-color-panel.c:908 +#: panels/color/cc-color-panel.c:907 #, c-format msgid "Failed to upload file: %s" msgstr "Falló al subir el archivo: %s" @@ -421,39 +423,39 @@ msgstr "Falló al subir el archivo: %s" #. TRANSLATORS: these are instructions on how to recover #. * the ICC profile on the native operating system and are #. * only shown when the user uses a LiveCD to calibrate -#: panels/color/cc-color-panel.c:922 +#: panels/color/cc-color-panel.c:921 msgid "The profile has been uploaded to:" msgstr "El perfil se ha subido a:" -#: panels/color/cc-color-panel.c:924 +#: panels/color/cc-color-panel.c:923 msgid "Write down this URL." msgstr "Anote este URL." -#: panels/color/cc-color-panel.c:925 +#: panels/color/cc-color-panel.c:924 msgid "Restart this computer and boot your normal operating system." msgstr "Reinicie el equipo y arranque su sistema operativo normal." -#: panels/color/cc-color-panel.c:926 +#: panels/color/cc-color-panel.c:925 msgid "Type the URL into your browser to download and install the profile." msgstr "Escriba el URL en su navegador para descargar e instalar el perfil." #. TRANSLATORS: this is the dialog to save the ICC profile -#: panels/color/cc-color-panel.c:960 +#: panels/color/cc-color-panel.c:959 msgid "Save Profile" msgstr "Guardar perfil" -#: panels/color/cc-color-panel.c:964 +#: panels/color/cc-color-panel.c:963 #: panels/network/connection-editor/vpn-helpers.c:311 msgid "_Save" msgstr "_Guardar" #. TRANSLATORS: this is when the button is sensitive -#: panels/color/cc-color-panel.c:1325 +#: panels/color/cc-color-panel.c:1324 msgid "Create a color profile for the selected device" msgstr "Crear un perfil de color para el dispositivo seleccionado" #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1340 panels/color/cc-color-panel.c:1364 +#: panels/color/cc-color-panel.c:1339 panels/color/cc-color-panel.c:1363 msgid "" "The measuring instrument is not detected. Please check it is turned on and " "correctly connected." @@ -462,12 +464,12 @@ msgstr "" "correctamente conectado." #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1374 +#: panels/color/cc-color-panel.c:1373 msgid "The measuring instrument does not support printer profiling." msgstr "El instrumento de medida no soporta perfilado de impresoras." #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1385 +#: panels/color/cc-color-panel.c:1384 msgid "The device type is not currently supported." msgstr "El tipo de dispositivo actualmente no está soportado." @@ -877,12 +879,13 @@ msgid "" msgstr "" "Calibrar el color de sus dispositivos, como pantallas, cámaras o impresoras" -#: panels/color/gnome-color-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/color/gnome-color-panel.desktop.in.in:7 msgid "preferences-color" msgstr "preferences-color" -#. Translators: those are keywords for the color control-center panel -#: panels/color/gnome-color-panel.desktop.in.in:18 +#. Translators: Search terms to find the Color panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/color/gnome-color-panel.desktop.in.in:19 msgid "Color;ICC;Profile;Calibrate;Printer;Display;" msgstr "Color;ICC;Perfil;Calibrado;Impresora;Pantalla;" @@ -919,6 +922,12 @@ msgstr "%e de %b" msgid "%b %e, %Y" msgstr "%e de %b, %Y" +#. translators: This is the default hotspot name, need to be less than 32-bytes +#: panels/common/hostname-helper.c:189 +msgctxt "hotspot" +msgid "Hotspot" +msgstr "Hotspot" + #: panels/common/language-chooser.ui:5 msgid "Language" msgstr "Idioma" @@ -1097,12 +1106,13 @@ msgstr "AM / PM" msgid "Change the date and time, including time zone" msgstr "Cambiar la fecha y la hora, incluyendo la zona horaria" -#: panels/datetime/gnome-datetime-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/datetime/gnome-datetime-panel.desktop.in.in:7 msgid "preferences-system-time" msgstr "preferences-system-time" -#. Translators: those are keywords for the date and time control-center panel -#: panels/datetime/gnome-datetime-panel.desktop.in.in:14 +#. Translators: Search terms to find the Date and Time panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/datetime/gnome-datetime-panel.desktop.in.in:15 msgid "Clock;Timezone;Location;" msgstr "Reloj;Zona horaria;Ubicación;" @@ -1115,59 +1125,59 @@ msgid "To change time or date settings, you need to authenticate." msgstr "" "Para cambiar la configuración de la fecha o de la hora, debe autenticarse." -#: panels/display/cc-display-panel.c:729 +#: panels/display/cc-display-panel.c:739 msgctxt "Display rotation" msgid "Landscape" msgstr "Horizontal" -#: panels/display/cc-display-panel.c:732 +#: panels/display/cc-display-panel.c:742 msgctxt "Display rotation" msgid "Portrait Right" msgstr "Vertical derecha" -#: panels/display/cc-display-panel.c:735 +#: panels/display/cc-display-panel.c:745 msgctxt "Display rotation" msgid "Portrait Left" msgstr "Vertical izquierda" -#: panels/display/cc-display-panel.c:738 +#: panels/display/cc-display-panel.c:748 msgctxt "Display rotation" msgid "Landscape (flipped)" msgstr "Horizontal (dada la vuelta)" #. Translators: This option sets orientation of print (portrait, landscape...) -#: panels/display/cc-display-panel.c:805 +#: panels/display/cc-display-panel.c:816 #: panels/printers/pp-options-dialog.c:558 msgid "Orientation" msgstr "Orientación" -#: panels/display/cc-display-panel.c:870 -#: panels/display/cc-display-panel.c:1673 +#: panels/display/cc-display-panel.c:885 +#: panels/display/cc-display-panel.c:1691 #: panels/printers/pp-options-dialog.c:87 msgid "Resolution" msgstr "Resolución" -#: panels/display/cc-display-panel.c:958 +#: panels/display/cc-display-panel.c:974 msgid "Refresh Rate" msgstr "Tasa de refresco" -#: panels/display/cc-display-panel.c:1095 +#: panels/display/cc-display-panel.c:1111 msgid "Scale" msgstr "Escala" -#: panels/display/cc-display-panel.c:1148 +#: panels/display/cc-display-panel.c:1164 msgid "Adjust for TV" msgstr "Ajustes para TV" -#: panels/display/cc-display-panel.c:1410 +#: panels/display/cc-display-panel.c:1427 msgid "Primary Display" msgstr "Pantalla primaria" -#: panels/display/cc-display-panel.c:1439 +#: panels/display/cc-display-panel.c:1456 msgid "Display Arrangement" msgstr "Distribución de las pantallas" -#: panels/display/cc-display-panel.c:1440 +#: panels/display/cc-display-panel.c:1457 msgid "" "Drag displays to match your setup. The top bar is placed on the primary " "display." @@ -1175,59 +1185,67 @@ msgstr "" "Arrastre las pantallas para que coincidan con su configuración. La barra " "superior se mostrará en la pantalla primaria." -#: panels/display/cc-display-panel.c:1863 +#: panels/display/cc-display-panel.c:1881 msgid "Display Mode" msgstr "Modo de la pantalla" -#: panels/display/cc-display-panel.c:1879 +#: panels/display/cc-display-panel.c:1897 msgid "Join Displays" msgstr "Unir pantallas" -#: panels/display/cc-display-panel.c:1882 +#: panels/display/cc-display-panel.c:1900 msgid "Mirror" msgstr "Espejo" -#: panels/display/cc-display-panel.c:1885 +#: panels/display/cc-display-panel.c:1903 msgid "Single Display" msgstr "Pantalla única" -#: panels/display/cc-display-panel.c:2590 -msgid "Apply Changes?" -msgstr "¿Aplicar los cambios?" - -#: panels/display/cc-display-panel.c:2604 +#: panels/display/cc-display-panel.c:2620 #: panels/network/connection-editor/connection-editor.ui:24 #: panels/network/network-wifi.ui:38 msgid "_Apply" msgstr "_Aplicar" -#: panels/display/cc-display-panel.c:2979 +#: panels/display/cc-display-panel.c:2642 +msgid "Apply Changes?" +msgstr "¿Aplicar los cambios?" + +#: panels/display/cc-display-panel.c:2647 +msgid "Changes Cannot be Applied" +msgstr "No se pueden aplicar los cambios" + +#: panels/display/cc-display-panel.c:2648 +msgid "This could be due to hardware limitations." +msgstr "Esto puede deber a limitaciones hardware." + +#: panels/display/cc-display-panel.c:3003 #, c-format msgid "%.2lf Hz" msgstr "%.2lf Hz" #. TRANSLATORS: the state of the night light setting -#: panels/display/cc-display-panel.c:3195 +#: panels/display/cc-display-panel.c:3219 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1988 panels/power/cc-power-panel.c:1995 -#: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 -#: panels/universal-access/cc-ua-panel.c:333 -#: panels/universal-access/cc-ua-panel.c:714 -#: panels/universal-access/cc-ua-panel.c:727 -#: panels/universal-access/cc-ua-panel.c:739 -#: panels/universal-access/cc-ua-panel.c:910 +#: panels/power/cc-power-panel.c:2097 panels/power/cc-power-panel.c:2104 +#: panels/privacy/cc-privacy-panel.c:191 panels/privacy/cc-privacy-panel.c:258 +#: panels/universal-access/cc-ua-panel.c:334 +#: panels/universal-access/cc-ua-panel.c:715 +#: panels/universal-access/cc-ua-panel.c:728 +#: panels/universal-access/cc-ua-panel.c:740 +#: panels/universal-access/cc-ua-panel.c:911 msgid "On" msgstr "Encendido" -#: panels/display/cc-display-panel.c:3195 panels/network/net-proxy.c:54 +#: panels/display/cc-display-panel.c:3219 panels/network/net-proxy.c:54 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1982 panels/power/cc-power-panel.c:1993 -#: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 -#: panels/universal-access/cc-ua-panel.c:333 -#: panels/universal-access/cc-ua-panel.c:714 -#: panels/universal-access/cc-ua-panel.c:727 -#: panels/universal-access/cc-ua-panel.c:739 -#: panels/universal-access/cc-ua-panel.c:910 +#: panels/power/cc-power-panel.c:2091 panels/power/cc-power-panel.c:2102 +#: panels/privacy/cc-privacy-panel.c:191 panels/privacy/cc-privacy-panel.c:258 +#: panels/universal-access/cc-ua-panel.c:334 +#: panels/universal-access/cc-ua-panel.c:715 +#: panels/universal-access/cc-ua-panel.c:728 +#: panels/universal-access/cc-ua-panel.c:740 +#: panels/universal-access/cc-ua-panel.c:911 #: panels/universal-access/uap.ui:334 panels/universal-access/uap.ui:380 #: panels/universal-access/uap.ui:426 panels/universal-access/uap.ui:532 #: panels/universal-access/uap.ui:685 panels/universal-access/uap.ui:731 @@ -1235,11 +1253,11 @@ msgstr "Encendido" msgid "Off" msgstr "Apagado" -#: panels/display/cc-display-panel.c:3216 +#: panels/display/cc-display-panel.c:3240 msgid "_Night Light" msgstr "Luz _nocturna" -#: panels/display/cc-display-panel.c:3281 +#: panels/display/cc-display-panel.c:3305 msgid "Could not get screen information" msgstr "No se pudo obtener la información de la pantalla" @@ -1279,7 +1297,7 @@ msgstr "Desde el amanecer hasta la puesta del sol" #: panels/network/connection-editor/ip6-page.ui:83 #: panels/network/net-proxy.c:56 panels/network/network-proxy.ui:113 #: panels/network/network-wifi.ui:777 panels/network/network-wifi.ui:1054 -#: panels/privacy/cc-privacy-panel.c:217 +#: panels/privacy/cc-privacy-panel.c:218 msgid "Manual" msgstr "Manual" @@ -1313,12 +1331,13 @@ msgstr "Pantallas" msgid "Choose how to use connected monitors and projectors" msgstr "Elegir cómo usar las pantallas y los proyectores conectados" -#: panels/display/gnome-display-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/display/gnome-display-panel.desktop.in.in:7 msgid "preferences-desktop-display" msgstr "preferences-desktop-display" -#. Translators: those are keywords for the display control-center panel -#: panels/display/gnome-display-panel.desktop.in.in:18 +#. Translators: Search terms to find the Displays panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/display/gnome-display-panel.desktop.in.in:19 msgid "" "Panel;Projector;xrandr;Screen;Resolution;Refresh;Monitor;Night;Light;Blue;" "redshift;color;sunset;sunrise;" @@ -1327,8 +1346,8 @@ msgstr "" "color;amanecer;atardecer;ocaso;" #. TRANSLATORS: AP type -#: panels/info/cc-info-overview-panel.c:374 -#: panels/info/cc-info-overview-panel.c:457 panels/network/panel-common.c:123 +#: panels/info/cc-info-overview-panel.c:373 +#: panels/info/cc-info-overview-panel.c:456 panels/network/panel-common.c:123 msgid "Unknown" msgstr "Desconocido" @@ -1336,24 +1355,24 @@ msgstr "Desconocido" #. * example: #. * "Fedora 25 (Workstation Edition); Build ID: xyz" or #. * "Ubuntu 16.04 LTS; Build ID: jki" -#: panels/info/cc-info-overview-panel.c:465 +#: panels/info/cc-info-overview-panel.c:464 #, c-format msgid "%s; Build ID: %s" msgstr "%s; ID de construcción: %s" #. translators: This is the type of architecture for the OS -#: panels/info/cc-info-overview-panel.c:482 +#: panels/info/cc-info-overview-panel.c:481 #, c-format msgid "64-bit" msgstr "64 bits" #. translators: This is the type of architecture for the OS -#: panels/info/cc-info-overview-panel.c:485 +#: panels/info/cc-info-overview-panel.c:484 #, c-format msgid "32-bit" msgstr "32 bits" -#: panels/info/cc-info-overview-panel.c:775 +#: panels/info/cc-info-overview-panel.c:773 #, c-format msgid "Version %s" msgstr "Versión %s" @@ -1457,12 +1476,13 @@ msgstr "Aplicaciones predeterminadas" msgid "Configure Default Applications" msgstr "Configurar aplicaciones predeterminadas" -#: panels/info/gnome-default-apps-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/info/gnome-default-apps-panel.desktop.in.in:7 msgid "starred" msgstr "destacado" -#. Translators: those are keywords for the Default Applications panel -#: panels/info/gnome-default-apps-panel.desktop.in.in:18 +#. Translators: Search terms to find the Default Applications panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/info/gnome-default-apps-panel.desktop.in.in:19 msgid "default;application;preferred;media;" msgstr "predeterminado;aplicación;preferida;medios;" @@ -1474,14 +1494,17 @@ msgstr "Acerca de" msgid "View information about your system" msgstr "Ver información sobre su sistema" -#: panels/info/gnome-info-overview-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/info/gnome-info-overview-panel.desktop.in.in:7 msgid "help-about" msgstr "help-about" -#. Translators: those are keywords for the System Information panel +#. Translators: Search terms to find the About panel. +#. Do NOT translate or localize the semicolons! +#. The list MUST also end with a semicolon! #. "Preferred Applications" is the old name for the preference, so make #. sure that you use the same "translation" for those keywords -#: panels/info/gnome-info-overview-panel.desktop.in.in:20 +#: panels/info/gnome-info-overview-panel.desktop.in.in:23 msgid "" "device;system;information;memory;processor;version;default;application;" "preferred;cd;dvd;usb;audio;video;disc;removable;media;autorun;" @@ -1498,12 +1521,13 @@ msgstr "Soportes extraíbles" msgid "Configure Removable Media settings" msgstr "Configurar soportes extraíbles" -#: panels/info/gnome-removable-media-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/info/gnome-removable-media-panel.desktop.in.in:7 msgid "media-removable" msgstr "media-removable" -#. Translators: those are keywords for the Removable Media panel -#: panels/info/gnome-removable-media-panel.desktop.in.in:18 +#. Translators: Search terms to find the Removable Media panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/info/gnome-removable-media-panel.desktop.in.in:19 msgid "" "device;system;default;application;preferred;cd;dvd;usb;audio;video;disc;" "removable;media;autorun;" @@ -1683,8 +1707,8 @@ msgstr "Lanzadores" msgid "Launch help browser" msgstr "Lanzar el visor de ayuda" -#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:223 -#: shell/cc-window.c:761 shell/gnome-control-center.desktop.in.in:3 +#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:237 +#: shell/cc-window.c:773 shell/gnome-control-center.desktop.in.in:3 #: shell/window.ui:125 msgid "Settings" msgstr "Configuración" @@ -1793,7 +1817,7 @@ msgstr "Contraste alto activado o desactivado" #: panels/keyboard/cc-keyboard-manager.c:506 #: panels/keyboard/cc-keyboard-manager.c:514 -#: panels/keyboard/cc-keyboard-manager.c:822 +#: panels/keyboard/cc-keyboard-manager.c:821 msgid "Custom Shortcuts" msgstr "Combinación personalizada" @@ -1804,7 +1828,7 @@ msgstr "Combinación personalizada" #. * The device has been disabled #: panels/keyboard/cc-keyboard-option.c:263 #: panels/keyboard/cc-keyboard-option.c:382 -#: panels/keyboard/keyboard-shortcuts.c:435 +#: panels/keyboard/keyboard-shortcuts.c:434 #: panels/keyboard/shortcut-editor.ui:96 panels/network/network-proxy.ui:123 #: panels/network/network-wifi.ui:782 panels/network/network-wifi.ui:1059 #: panels/user-accounts/um-fingerprint-dialog.c:211 @@ -1894,12 +1918,13 @@ msgstr "" "Ver y cambiar los atajos del teclado y establecer sus preferencias de " "escritura" -#: panels/keyboard/gnome-keyboard-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/keyboard/gnome-keyboard-panel.desktop.in.in:7 msgid "input-keyboard" msgstr "input-keyboard" -#. Translators: those are keywords for the keyboard control-center panel -#: panels/keyboard/gnome-keyboard-panel.desktop.in.in:18 +#. Translators: Search terms to find the Keyboard panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/keyboard/gnome-keyboard-panel.desktop.in.in:19 msgid "" "Shortcut;Workspace;Window;Resize;Zoom;Contrast;Input;Source;Lock;Volume;" msgstr "" @@ -1990,12 +2015,13 @@ msgstr "" "Cambiar la sensibilidad de su ratón o su «touchpad» y configurarlos para " "zurdos o diestros" -#: panels/mouse/gnome-mouse-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/mouse/gnome-mouse-panel.desktop.in.in:7 msgid "input-mouse" msgstr "input-mouse" -#. Translators: those are keywords for the mouse and touchpad control-center panel -#: panels/mouse/gnome-mouse-panel.desktop.in.in:18 +#. Translators: Search terms to find the Mouse and Touchpad panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/mouse/gnome-mouse-panel.desktop.in.in:19 msgid "Trackpad;Pointer;Click;Tap;Double;Button;Trackball;Scroll;" msgstr "" "trackpad;puntero;pulsar;pulsación;doble;botón;trackball;desplazamiento;" @@ -2100,7 +2126,7 @@ msgid "Single click, secondary button" msgstr "Una sola pulsación, botón secundario" #. add proxy to device list -#: panels/network/cc-network-panel.c:579 +#: panels/network/cc-network-panel.c:581 msgid "Network proxy" msgstr "Proxy de la red" @@ -2108,23 +2134,23 @@ msgstr "Proxy de la red" #. * window for vpn connections, it is also used to display #. * vpn connections in the device list. #. -#: panels/network/cc-network-panel.c:715 panels/network/net-vpn.c:192 -#: panels/network/net-vpn.c:321 +#: panels/network/cc-network-panel.c:717 panels/network/net-vpn.c:167 +#: panels/network/net-vpn.c:296 #, c-format msgid "%s VPN" msgstr "VPN «%s»" -#: panels/network/cc-network-panel.c:779 panels/network/wifi.ui:282 +#: panels/network/cc-network-panel.c:781 panels/network/wifi.ui:282 msgid "Oops, something has gone wrong. Please contact your software vendor." msgstr "Algo ha fallado. Contacte con el fabricante del software." -#: panels/network/cc-network-panel.c:785 +#: panels/network/cc-network-panel.c:787 msgid "NetworkManager needs to be running." msgstr "NetworkManager debe estar en ejecución." -#: panels/network/cc-wifi-panel.c:212 +#: panels/network/cc-wifi-panel.c:214 #: panels/network/gnome-wifi-panel.desktop.in.in:3 -#: panels/network/network-wifi.ui:1766 +#: panels/network/network-wifi.ui:1769 msgid "Wi-Fi" msgstr "Inalámbrica" @@ -2175,31 +2201,31 @@ msgstr "Perfil %d" #. TRANSLATORS: this WEP WiFi security #: panels/network/connection-editor/ce-page-details.c:56 -#: panels/network/net-device-wifi.c:231 panels/network/net-device-wifi.c:453 +#: panels/network/net-device-wifi.c:235 panels/network/net-device-wifi.c:468 msgid "WEP" msgstr "WEP" #. TRANSLATORS: this WPA WiFi security #: panels/network/connection-editor/ce-page-details.c:60 -#: panels/network/net-device-wifi.c:235 panels/network/net-device-wifi.c:458 +#: panels/network/net-device-wifi.c:239 panels/network/net-device-wifi.c:473 #: panels/network/network-wifi.ui:593 msgid "WPA" msgstr "WPA" #. TRANSLATORS: this WPA WiFi security #: panels/network/connection-editor/ce-page-details.c:64 -#: panels/network/net-device-wifi.c:239 +#: panels/network/net-device-wifi.c:243 msgid "WPA2" msgstr "WPA2" #. TRANSLATORS: this Enterprise WiFi security #: panels/network/connection-editor/ce-page-details.c:69 -#: panels/network/net-device-wifi.c:244 +#: panels/network/net-device-wifi.c:248 msgid "Enterprise" msgstr "Empresa" #: panels/network/connection-editor/ce-page-details.c:74 -#: panels/network/net-device-wifi.c:249 panels/network/net-device-wifi.c:443 +#: panels/network/net-device-wifi.c:253 panels/network/net-device-wifi.c:458 msgctxt "Wifi security" msgid "None" msgstr "Ninguna" @@ -2211,7 +2237,7 @@ msgstr "Nunca" #: panels/network/connection-editor/ce-page-details.c:110 #: panels/network/net-device-ethernet.c:121 -#: panels/network/net-device-wifi.c:552 +#: panels/network/net-device-wifi.c:567 #, c-format msgid "%i day ago" msgid_plural "%i days ago" @@ -2221,37 +2247,37 @@ msgstr[1] "hace %i días" #. Translators: network device speed #: panels/network/connection-editor/ce-page-details.c:225 #: panels/network/net-device-ethernet.c:50 -#: panels/network/net-device-wifi.c:608 +#: panels/network/net-device-wifi.c:646 #, c-format msgid "%d Mb/s" msgstr "%d Mb/s" #: panels/network/connection-editor/ce-page-details.c:251 -#: panels/network/net-device-wifi.c:637 +#: panels/network/net-device-wifi.c:675 msgctxt "Signal strength" msgid "None" msgstr "Ninguna" #: panels/network/connection-editor/ce-page-details.c:253 -#: panels/network/net-device-wifi.c:639 +#: panels/network/net-device-wifi.c:677 msgctxt "Signal strength" msgid "Weak" msgstr "Débil" #: panels/network/connection-editor/ce-page-details.c:255 -#: panels/network/net-device-wifi.c:641 +#: panels/network/net-device-wifi.c:679 msgctxt "Signal strength" msgid "Ok" msgstr "Aceptar" #: panels/network/connection-editor/ce-page-details.c:257 -#: panels/network/net-device-wifi.c:643 +#: panels/network/net-device-wifi.c:681 msgctxt "Signal strength" msgid "Good" msgstr "Buena" #: panels/network/connection-editor/ce-page-details.c:259 -#: panels/network/net-device-wifi.c:645 +#: panels/network/net-device-wifi.c:683 msgctxt "Signal strength" msgid "Excellent" msgstr "Excelente" @@ -2269,7 +2295,7 @@ msgid "Remove VPN" msgstr "Quitar VPN" #: panels/network/connection-editor/ce-page-details.c:334 -#: panels/network/network-wifi.ui:1456 shell/cc-window.c:215 +#: panels/network/network-wifi.ui:1456 shell/cc-window.c:229 #: shell/panel-list.ui:103 msgid "Details" msgstr "Detalles" @@ -2404,7 +2430,7 @@ msgstr "Adecuado para conexiones que consumen o limitan los datos." #: panels/network/connection-editor/ip6-page.ui:291 #: panels/network/net-proxy.c:58 panels/network/network-proxy.ui:103 #: panels/network/wireless-security/eap-method-peap.ui:22 -#: panels/privacy/cc-privacy-panel.c:217 +#: panels/privacy/cc-privacy-panel.c:218 msgid "Automatic" msgstr "Automático" @@ -2602,9 +2628,9 @@ msgid "Select file to import" msgstr "Seleccione el archivo que importar" #: panels/network/connection-editor/vpn-helpers.c:182 -#: panels/printers/pp-details-dialog.c:332 +#: panels/printers/pp-details-dialog.c:331 #: panels/sharing/cc-sharing-panel.c:385 -#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-photo-dialog.c:231 msgid "_Open" msgstr "_Abrir" @@ -2669,12 +2695,13 @@ msgstr "Red" msgid "Control how you connect to the Internet" msgstr "Controlar cómo se conecta a Internet" -#: panels/network/gnome-network-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/network/gnome-network-panel.desktop.in.in:7 msgid "network-workgroup" msgstr "network-workgroup" -#. Translators: those are keywords for the network control-center panel -#: panels/network/gnome-network-panel.desktop.in.in:18 +#. Translators: Search terms to find the Network panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/network/gnome-network-panel.desktop.in.in:19 msgid "" "Network;Wireless;Wi-Fi;Wifi;IP;LAN;Proxy;WAN;Broadband;Modem;Bluetooth;vpn;" "DNS;" @@ -2686,27 +2713,28 @@ msgstr "" msgid "Control how you connect to Wi-Fi networks" msgstr "Controlar cómo se conecta a redes inalámbricas" -#: panels/network/gnome-wifi-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/network/gnome-wifi-panel.desktop.in.in:7 msgid "network-wireless" msgstr "network-wireless" -#. Translators: those are keywords for the wi-fi control-center panel -#: panels/network/gnome-wifi-panel.desktop.in.in:18 +#. Translators: Search terms to find the Wi-Fi panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/network/gnome-wifi-panel.desktop.in.in:19 msgid "Network;Wireless;Wi-Fi;Wifi;IP;LAN;Broadband;DNS;" msgstr "Red;Inalámbrica;Wireless;Wi-Fi;Wifi;IP;LAN;Banda;ancha;DNS;" #: panels/network/net-device-ethernet.c:107 -#: panels/network/net-device-wifi.c:538 +#: panels/network/net-device-wifi.c:553 msgid "never" msgstr "nunca" #: panels/network/net-device-ethernet.c:117 -#: panels/network/net-device-wifi.c:548 +#: panels/network/net-device-wifi.c:563 msgid "today" msgstr "hoy" #: panels/network/net-device-ethernet.c:119 -#: panels/network/net-device-wifi.c:550 +#: panels/network/net-device-wifi.c:565 msgid "yesterday" msgstr "ayer" @@ -2731,7 +2759,7 @@ msgid "Wired" msgstr "Cableada" #: panels/network/net-device-ethernet.c:344 -#: panels/network/net-device-wifi.c:1849 +#: panels/network/net-device-wifi.c:1895 #: panels/network/network-ethernet.ui:120 panels/network/network-mobile.ui:394 #: panels/network/network-simple.ui:75 panels/network/network-vpn.ui:79 msgid "Options…" @@ -2741,12 +2769,12 @@ msgstr "Opciones…" msgid "Add new connection" msgstr "Añadir una conexión nueva" -#: panels/network/net-device-wifi.c:1328 +#: panels/network/net-device-wifi.c:1368 #, c-format msgid "Switching on the wireless hotspot will disconnect you from %s." msgstr "Cambiar al «hotspot» inalámbrico le desconectará de %s." -#: panels/network/net-device-wifi.c:1332 +#: panels/network/net-device-wifi.c:1372 msgid "" "It is not possible to access the Internet through your wireless while the " "hotspot is active." @@ -2754,11 +2782,11 @@ msgstr "" "No es posible acceder a Internet usando la conexión inalámbrica mientras el " "«hotspot» está activado." -#: panels/network/net-device-wifi.c:1339 +#: panels/network/net-device-wifi.c:1379 msgid "Turn On Wi-Fi Hotspot?" msgstr "¿Activar el punto de acceso inalámbrico?" -#: panels/network/net-device-wifi.c:1361 +#: panels/network/net-device-wifi.c:1401 msgid "" "Wi-Fi hotspots are usually used to share an additional Internet connection " "over Wi-Fi." @@ -2766,27 +2794,27 @@ msgstr "" "Los puntos de acceso inalámbricos se usan habitualmente para compartir una " "conexión a Internet adicional mediante Wi-Fi." -#: panels/network/net-device-wifi.c:1372 +#: panels/network/net-device-wifi.c:1412 msgid "_Turn On" msgstr "_Activar" -#: panels/network/net-device-wifi.c:1449 +#: panels/network/net-device-wifi.c:1489 msgid "Stop hotspot and disconnect any users?" msgstr "¿Detener el «hotspot» y desconectar a los usuarios?" -#: panels/network/net-device-wifi.c:1452 +#: panels/network/net-device-wifi.c:1492 msgid "_Stop Hotspot" msgstr "_Detener «hotspot»" -#: panels/network/net-device-wifi.c:1552 +#: panels/network/net-device-wifi.c:1592 msgid "System policy prohibits use as a Hotspot" msgstr "La política del sistema prohíbe usarlo como punto de acceso" -#: panels/network/net-device-wifi.c:1555 +#: panels/network/net-device-wifi.c:1595 msgid "Wireless device does not support Hotspot mode" msgstr "El dispositivo inalámbrico no soporta el modo de punto de acceso" -#: panels/network/net-device-wifi.c:1687 +#: panels/network/net-device-wifi.c:1733 msgid "" "Network details for the selected networks, including passwords and any " "custom configuration will be lost." @@ -2794,16 +2822,16 @@ msgstr "" "Se perderán los detalles de las redes seleccionadas, incluyendo la " "contraseña y cualquier configuración personalizada." -#: panels/network/net-device-wifi.c:1691 panels/network/network-wifi.ui:1362 +#: panels/network/net-device-wifi.c:1737 panels/network/network-wifi.ui:1362 msgid "_Forget" msgstr "_Olvidar" -#: panels/network/net-device-wifi.c:2000 panels/network/net-device-wifi.c:2007 +#: panels/network/net-device-wifi.c:2046 panels/network/net-device-wifi.c:2053 msgid "Known Wi-Fi Networks" msgstr "Redes inalámbricas conocidas" #. translators: This is the label for the "Forget wireless network" functionality -#: panels/network/net-device-wifi.c:2040 +#: panels/network/net-device-wifi.c:2086 msgctxt "Wi-Fi Network" msgid "_Forget" msgstr "_Olvidar" @@ -3022,19 +3050,19 @@ msgctxt "Wi-Fi passkey" msgid "Password" msgstr "Contraseña" -#: panels/network/network-wifi.ui:1796 +#: panels/network/network-wifi.ui:1799 msgid "Turn Wi-Fi off" msgstr "Apagar la Wi-Fi" -#: panels/network/network-wifi.ui:1828 +#: panels/network/network-wifi.ui:1831 msgid "_Connect to Hidden Network…" msgstr "Conectar a una red oculta…" -#: panels/network/network-wifi.ui:1838 +#: panels/network/network-wifi.ui:1841 msgid "_Turn On Wi-Fi Hotspot…" msgstr "_Activar el punto de acceso inalámbrico…" -#: panels/network/network-wifi.ui:1848 +#: panels/network/network-wifi.ui:1851 msgid "_Known Wi-Fi Networks" msgstr "Redes inalámbricas _conocidas" @@ -3343,23 +3371,23 @@ msgstr "falta el «firmware»" msgid "Cable unplugged" msgstr "Cable desconectado" -#: panels/network/wireless-security/eap-method.c:57 +#: panels/network/wireless-security/eap-method.c:69 msgid "undefined error in 802.1X security (wpa-eap)" msgstr "error no definido en la seguridad 802.1X (wpa-eap)" -#: panels/network/wireless-security/eap-method.c:233 +#: panels/network/wireless-security/eap-method.c:245 msgid "no file selected" msgstr "no se ha seleccionado ningún archivo" -#: panels/network/wireless-security/eap-method.c:264 +#: panels/network/wireless-security/eap-method.c:276 msgid "unspecified error validating eap-method file" msgstr "error no especificado al validar el archivo del método eap" -#: panels/network/wireless-security/eap-method.c:439 +#: panels/network/wireless-security/eap-method.c:451 msgid "DER, PEM, or PKCS#12 private keys (*.der, *.pem, *.p12, *.key)" msgstr "Claves privadas DER, PEM, o PKCS#12 (*.der, *.pem, *.p12, *.key)" -#: panels/network/wireless-security/eap-method.c:442 +#: panels/network/wireless-security/eap-method.c:454 msgid "DER or PEM certificates (*.der, *.pem, *.crt, *.cer)" msgstr "Certificados DER o PEM (*.der, *.pem, *.crt, *.cer)" @@ -3750,12 +3778,13 @@ msgstr "Notificaciones" msgid "Control which notifications are displayed and what they show" msgstr "Controlar qué notificaciones se muestran" -#: panels/notifications/gnome-notifications-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/notifications/gnome-notifications-panel.desktop.in.in:7 msgid "preferences-system-notifications" msgstr "preferences-system-notifications" -#. Translators: those are keywords for the notifications control-center panel -#: panels/notifications/gnome-notifications-panel.desktop.in.in:19 +#. Translators: Search terms to find the Notifications panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/notifications/gnome-notifications-panel.desktop.in.in:20 msgid "Notifications;Banner;Message;Tray;Popup;" msgstr "notificaciones;banner;mensaje;bandeja;emergente;" @@ -3780,19 +3809,19 @@ msgstr "Otra" #. translators: This is the title of the "Show Account" dialog. The #. * %s is the name of the provider. e.g., 'Google'. -#: panels/online-accounts/cc-online-accounts-panel.c:551 +#: panels/online-accounts/cc-online-accounts-panel.c:612 #, c-format msgid "%s Account" msgstr "Cuenta de %s" -#: panels/online-accounts/cc-online-accounts-panel.c:843 +#: panels/online-accounts/cc-online-accounts-panel.c:904 msgid "Error removing account" msgstr "Error al quitar la cuenta" #. Translators: The %s is the username (eg., debarshi.ray@gmail.com #. * or rishi). #. -#: panels/online-accounts/cc-online-accounts-panel.c:908 +#: panels/online-accounts/cc-online-accounts-panel.c:969 #, c-format msgid "%s removed" msgstr "%s eliminado" @@ -3805,13 +3834,16 @@ msgstr "Cuentas en línea" msgid "Connect to your online accounts and decide what to use them for" msgstr "Conectarse a sus cuentas en línea y decidir para qué usarlas" -#: panels/online-accounts/gnome-online-accounts-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/online-accounts/gnome-online-accounts-panel.desktop.in.in:7 msgid "goa-panel" msgstr "goa-panel" -#. Translators: those are keywords for the online-accounts control-center panel +#. Translators: Search terms to find the Online Accounts panel. +#. Do NOT translate or localize the semicolons! +#. The list MUST also end with a semicolon! #. For ReadItLater and Pocket, see http://en.wikipedia.org/wiki/Pocket_(application) -#: panels/online-accounts/gnome-online-accounts-panel.desktop.in.in:19 +#: panels/online-accounts/gnome-online-accounts-panel.desktop.in.in:22 msgid "" "Google;Facebook;Twitter;Yahoo;Web;Online;Chat;Calendar;Mail;Contact;ownCloud;" "Kerberos;IMAP;SMTP;Pocket;ReadItLater;" @@ -3841,18 +3873,18 @@ msgstr "Añadir una cuenta" msgid "Remove Account" msgstr "Quitar cuenta" -#: panels/power/cc-power-panel.c:253 +#: panels/power/cc-power-panel.c:254 msgid "Unknown time" msgstr "Tiempo desconocido" -#: panels/power/cc-power-panel.c:259 +#: panels/power/cc-power-panel.c:260 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "%i minuto" msgstr[1] "%i minutos" -#: panels/power/cc-power-panel.c:271 +#: panels/power/cc-power-panel.c:272 #, c-format msgid "%i hour" msgid_plural "%i hours" @@ -3861,256 +3893,305 @@ msgstr[1] "%i horas" #. TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes" #. * Swap order with "%2$s %2$i %1$s %1$i if needed -#: panels/power/cc-power-panel.c:279 +#: panels/power/cc-power-panel.c:280 #, c-format msgid "%i %s %i %s" msgstr "%i %s %i %s" -#: panels/power/cc-power-panel.c:280 +#: panels/power/cc-power-panel.c:281 msgid "hour" msgid_plural "hours" msgstr[0] "hora" msgstr[1] "horas" -#: panels/power/cc-power-panel.c:281 +#: panels/power/cc-power-panel.c:282 msgid "minute" msgid_plural "minutes" msgstr[0] "minuto" msgstr[1] "minutos" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:300 +#: panels/power/cc-power-panel.c:301 #, c-format msgid "%s until fully charged" msgstr "%s hasta que se cargue del todo" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:307 +#: panels/power/cc-power-panel.c:308 #, c-format msgid "Caution: %s remaining" msgstr "Advertencia: quedan %s" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:312 +#: panels/power/cc-power-panel.c:313 #, c-format msgid "%s remaining" msgstr "%s restante" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:317 panels/power/cc-power-panel.c:345 +#: panels/power/cc-power-panel.c:318 panels/power/cc-power-panel.c:346 msgid "Fully charged" msgstr "Cargada completamente" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:321 panels/power/cc-power-panel.c:349 +#: panels/power/cc-power-panel.c:322 panels/power/cc-power-panel.c:350 msgid "Empty" msgstr "Vacía" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:336 +#: panels/power/cc-power-panel.c:337 msgid "Charging" msgstr "Cargando" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:341 +#: panels/power/cc-power-panel.c:342 msgid "Discharging" msgstr "Descargando" -#: panels/power/cc-power-panel.c:464 +#: panels/power/cc-power-panel.c:465 msgctxt "Battery name" msgid "Main" msgstr "Principal" -#: panels/power/cc-power-panel.c:466 +#: panels/power/cc-power-panel.c:467 msgctxt "Battery name" msgid "Extra" msgstr "Adicional" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:537 +#: panels/power/cc-power-panel.c:538 msgid "Wireless mouse" msgstr "Ratón inalámbrico" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:540 +#: panels/power/cc-power-panel.c:541 msgid "Wireless keyboard" msgstr "Teclado inalámbrico" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:543 +#: panels/power/cc-power-panel.c:544 msgid "Uninterruptible power supply" msgstr "Fuente de alimentación no interrumplible" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:546 +#: panels/power/cc-power-panel.c:547 msgid "Personal digital assistant" msgstr "Asistente digital personal" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:549 +#: panels/power/cc-power-panel.c:550 msgid "Cellphone" msgstr "Teléfono móvil" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:552 +#: panels/power/cc-power-panel.c:553 msgid "Media player" msgstr "Reproductor multimedia" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:555 panels/wacom/cc-wacom-panel.c:793 +#: panels/power/cc-power-panel.c:556 panels/wacom/cc-wacom-panel.c:793 msgid "Tablet" msgstr "Tableta" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:558 +#: panels/power/cc-power-panel.c:559 msgid "Computer" msgstr "Equipo" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:561 +#: panels/power/cc-power-panel.c:562 msgid "Gaming input device" msgstr "Mando de juegos" #. TRANSLATORS: secondary battery, misc -#: panels/power/cc-power-panel.c:564 panels/power/cc-power-panel.c:804 -#: panels/power/cc-power-panel.c:2374 +#: panels/power/cc-power-panel.c:565 panels/power/cc-power-panel.c:829 +#: panels/power/cc-power-panel.c:2483 msgid "Battery" msgstr "Batería" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:618 +#: panels/power/cc-power-panel.c:632 msgctxt "Battery power" msgid "Charging" msgstr "Cargando" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:625 +#: panels/power/cc-power-panel.c:639 msgctxt "Battery power" msgid "Caution" msgstr "Precaución" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:630 +#: panels/power/cc-power-panel.c:644 msgctxt "Battery power" msgid "Low" msgstr "Baja" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:635 +#: panels/power/cc-power-panel.c:649 msgctxt "Battery power" msgid "Good" msgstr "Bien" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:640 +#: panels/power/cc-power-panel.c:654 msgctxt "Battery power" msgid "Fully charged" msgstr "Cargada completamente" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:644 +#: panels/power/cc-power-panel.c:658 msgctxt "Battery power" msgid "Empty" msgstr "Vacía" -#: panels/power/cc-power-panel.c:802 +#: panels/power/cc-power-panel.c:827 msgid "Batteries" msgstr "Baterías" -#: panels/power/cc-power-panel.c:1236 +#: panels/power/cc-power-panel.c:1206 +#, c-format +#| msgid "%i hour" +#| msgid_plural "%i hours" +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d hora" +msgstr[1] "%d horas" + +#: panels/power/cc-power-panel.c:1208 +#, c-format +#| msgid "%i minute" +#| msgid_plural "%i minutes" +msgid "%d minute" +msgid_plural "%d minutes" +msgstr[0] "%d minuto" +msgstr[1] "%d minutos" + +#: panels/power/cc-power-panel.c:1211 +#, c-format +#| msgid "30 seconds" +msgid "%d second" +msgid_plural "%d seconds" +msgstr[0] "%d segundo" +msgstr[1] "%d segundos" + +#. 5 hours 2 minutes 12 seconds +#: panels/power/cc-power-panel.c:1217 +#, c-format +#| msgid "%i %s %i %s" +msgctxt "time" +msgid "%s %s %s" +msgstr "%s %s %s" + +#. 2 minutes 12 seconds +#: panels/power/cc-power-panel.c:1220 +#, c-format +#| msgid "%i %s %i %s" +msgctxt "time" +msgid "%s %s" +msgstr "%s %s" + +#. 0 seconds +#: panels/power/cc-power-panel.c:1226 +#| msgid "30 seconds" +msgid "0 seconds" +msgstr "0 seconds" + +#: panels/power/cc-power-panel.c:1328 msgid "When _idle" msgstr "Cuando esté _inactivo" -#: panels/power/cc-power-panel.c:1690 +#: panels/power/cc-power-panel.c:1793 msgid "Power Saving" msgstr "Ahorro de energía" -#: panels/power/cc-power-panel.c:1721 +#: panels/power/cc-power-panel.c:1824 msgid "_Screen brightness" msgstr "_Brillo de la pantalla" -#: panels/power/cc-power-panel.c:1740 +#: panels/power/cc-power-panel.c:1843 msgid "Automatic brightness" msgstr "Brillo automático" -#: panels/power/cc-power-panel.c:1760 +#: panels/power/cc-power-panel.c:1863 msgid "_Keyboard brightness" msgstr "_Brillo del teclado" -#: panels/power/cc-power-panel.c:1770 +#: panels/power/cc-power-panel.c:1873 msgid "_Dim screen when inactive" msgstr "_Oscurecer la pantalla cuando esté inactiva" -#: panels/power/cc-power-panel.c:1795 +#: panels/power/cc-power-panel.c:1898 msgid "_Blank screen" msgstr "_Apagar la pantalla" -#: panels/power/cc-power-panel.c:1832 +#: panels/power/cc-power-panel.c:1935 msgid "_Wi-Fi" msgstr "_Wi-Fi" -#: panels/power/cc-power-panel.c:1837 +#: panels/power/cc-power-panel.c:1940 msgid "Turn off Wi-Fi to save power." msgstr "Apagar la Wi-Fi para ahorrar energía." -#: panels/power/cc-power-panel.c:1862 +#: panels/power/cc-power-panel.c:1965 msgid "_Mobile broadband" msgstr "Banda ancha _móvil" -#: panels/power/cc-power-panel.c:1867 +#: panels/power/cc-power-panel.c:1970 msgid "Turn off mobile broadband (3G, 4G, LTE, etc.) to save power." msgstr "Apagar la banda ancha móvil (3G, 4G, LTE, etc.) para ahorrar energía." -#: panels/power/cc-power-panel.c:1920 +#: panels/power/cc-power-panel.c:2029 msgid "_Bluetooth" msgstr "_Bluetooth" -#: panels/power/cc-power-panel.c:1925 +#: panels/power/cc-power-panel.c:2034 msgid "Turn off Bluetooth to save power." msgstr "Apagar el Bluetooth para ahorrar energía." -#: panels/power/cc-power-panel.c:1984 +#: panels/power/cc-power-panel.c:2093 msgid "When on battery power" msgstr "En modo batería" -#: panels/power/cc-power-panel.c:1986 +#: panels/power/cc-power-panel.c:2095 msgid "When plugged in" msgstr "Cuando está conectado a la red" -#: panels/power/cc-power-panel.c:2081 +#: panels/power/cc-power-panel.c:2190 msgid "Suspend" msgstr "Suspender" -#: panels/power/cc-power-panel.c:2082 +#: panels/power/cc-power-panel.c:2191 msgid "Power Off" msgstr "Apagar" -#: panels/power/cc-power-panel.c:2083 +#: panels/power/cc-power-panel.c:2192 msgid "Hibernate" msgstr "Hibernar" -#: panels/power/cc-power-panel.c:2084 +#: panels/power/cc-power-panel.c:2193 msgid "Nothing" msgstr "Nada" #. Frame header -#: panels/power/cc-power-panel.c:2198 +#: panels/power/cc-power-panel.c:2307 msgid "Suspend & Power Button" msgstr "Botón de suspender y apagar" -#: panels/power/cc-power-panel.c:2237 +#: panels/power/cc-power-panel.c:2346 msgid "_Automatic suspend" msgstr "Suspender _automáticamente" -#: panels/power/cc-power-panel.c:2238 +#: panels/power/cc-power-panel.c:2347 msgid "Automatic suspend" msgstr "Suspender automáticamente" -#: panels/power/cc-power-panel.c:2305 +#: panels/power/cc-power-panel.c:2414 msgid "_When the Power Button is pressed" msgstr "Al pulsar el b_otón de encendido" -#: panels/power/cc-power-panel.c:2424 shell/cc-window.c:219 +#: panels/power/cc-power-panel.c:2533 panels/thunderbolt/cc-bolt-panel.ui:466 +#: panels/thunderbolt/cc-bolt-panel.ui:525 shell/cc-window.c:233 #: shell/panel-list.ui:45 msgid "Devices" msgstr "Dispositivos" @@ -4124,12 +4205,13 @@ msgid "View your battery status and change power saving settings" msgstr "" "Ver el estado de la batería y cambiar la configuración de ahorro de energía" -#: panels/power/gnome-power-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/power/gnome-power-panel.desktop.in.in:7 msgid "gnome-power-manager" msgstr "gnome-power-manager" -#. Translators: those are keywords for the power control-center panel -#: panels/power/gnome-power-panel.desktop.in.in:18 +#. Translators: Search terms to find the Power panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/power/gnome-power-panel.desktop.in.in:19 msgid "" "Power;Sleep;Suspend;Hibernate;Battery;Brightness;Dim;Blank;Monitor;DPMS;Idle;" msgstr "" @@ -4245,18 +4327,18 @@ msgid "Authentication Required" msgstr "Se requiere autenticación" #. Translators: %s is the printer name -#: panels/printers/cc-printers-panel.c:791 +#: panels/printers/cc-printers-panel.c:809 #, c-format msgid "Printer “%s” has been deleted" msgstr "Se ha eliminado la impresora «%s»" #. Translators: Addition of the new printer failed. -#: panels/printers/cc-printers-panel.c:1036 +#: panels/printers/cc-printers-panel.c:1054 msgid "Failed to add new printer." msgstr "Falló al añadir una impresora nueva." #. Translators: The XML file containing user interface can not be loaded -#: panels/printers/cc-printers-panel.c:1371 +#: panels/printers/cc-printers-panel.c:1391 #, c-format msgid "Could not load ui: %s" msgstr "No se pudo cargar la IU: %s" @@ -4297,18 +4379,18 @@ msgstr "" "Añadir impresoras, ver los trabajos de la impresora y decidir cuál quiere " "imprimir" -#: panels/printers/gnome-printers-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/printers/gnome-printers-panel.desktop.in.in:7 msgid "printer" msgstr "impresora" -#. Translators: those are keywords for the printing control-center panel -#: panels/printers/gnome-printers-panel.desktop.in.in:15 +#. Translators: Search terms to find the Printers panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/printers/gnome-printers-panel.desktop.in.in:16 msgid "Printer;Queue;Print;Paper;Ink;Toner;" msgstr "Impresora;Cola;Imprimir;Papel;Tinta;Tóner;" #. Translators: This is a windows domain used with SMB protocol. #: panels/printers/jobs-dialog.ui:44 -#| msgid "_Domain" msgid "Domain" msgstr "Dominio" @@ -4324,7 +4406,6 @@ msgstr "Limpiar todos" #. Translators: This button pop up authentication dialog for print jobs which need credentials. #: panels/printers/jobs-dialog.ui:225 -#| msgid "Authenticate" msgid "_Authenticate" msgstr "_Autenticar" @@ -4371,21 +4452,21 @@ msgid "Test Page" msgstr "Página de prueba" #. Translators: This is the title of the dialog. %s is the printer name. -#: panels/printers/pp-details-dialog.c:135 -#: panels/printers/pp-details-dialog.c:435 +#: panels/printers/pp-details-dialog.c:134 +#: panels/printers/pp-details-dialog.c:434 #, c-format msgid "%s Details" msgstr "Detalles de %s" -#: panels/printers/pp-details-dialog.c:184 +#: panels/printers/pp-details-dialog.c:183 msgid "No suitable driver found" msgstr "No se ha encontrado ningún controlador adecuado" -#: panels/printers/pp-details-dialog.c:328 +#: panels/printers/pp-details-dialog.c:327 msgid "Select PPD File" msgstr "Seleccionar archivo PPD" -#: panels/printers/pp-details-dialog.c:337 +#: panels/printers/pp-details-dialog.c:336 msgid "" "PostScript Printer Description files (*.ppd, *.PPD, *.ppd.gz, *.PPD.gz, *." "PPD.GZ)" @@ -4398,7 +4479,7 @@ msgid "Select Printer Driver" msgstr "Seleccionar el controlador de la impresora" #: panels/printers/ppd-selection-dialog.ui:40 -#: panels/user-accounts/um-photo-dialog.c:104 +#: panels/user-accounts/um-photo-dialog.c:105 msgid "Select" msgstr "Seleccionar" @@ -4455,74 +4536,71 @@ msgid "Reverse portrait" msgstr "Vertical invertido" #. Translators: Job's state (job is waiting to be printed) -#: panels/printers/pp-jobs-dialog.c:243 +#: panels/printers/pp-jobs-dialog.c:234 msgctxt "print job" msgid "Pending" msgstr "Pendiente" #. Translators: Job's state (job is held for printing) -#: panels/printers/pp-jobs-dialog.c:249 +#: panels/printers/pp-jobs-dialog.c:240 msgctxt "print job" msgid "Paused" msgstr "Pausado" #. Translators: Job's state (job needs authentication to proceed further) -#: panels/printers/pp-jobs-dialog.c:254 -#| msgid "Authentication required" +#: panels/printers/pp-jobs-dialog.c:245 msgctxt "print job" msgid "Authentication required" msgstr "Autenticación requerida" #. Translators: Job's state (job is currently printing) -#: panels/printers/pp-jobs-dialog.c:259 +#: panels/printers/pp-jobs-dialog.c:250 msgctxt "print job" msgid "Processing" msgstr "Procesando" #. Translators: Job's state (job has been stopped) -#: panels/printers/pp-jobs-dialog.c:263 +#: panels/printers/pp-jobs-dialog.c:254 msgctxt "print job" msgid "Stopped" msgstr "Detenido" #. Translators: Job's state (job has been canceled) -#: panels/printers/pp-jobs-dialog.c:267 +#: panels/printers/pp-jobs-dialog.c:258 msgctxt "print job" msgid "Canceled" msgstr "Cancelado" #. Translators: Job's state (job has aborted due to error) -#: panels/printers/pp-jobs-dialog.c:271 +#: panels/printers/pp-jobs-dialog.c:262 msgctxt "print job" msgid "Aborted" msgstr "Abortado" #. Translators: Job's state (job has completed successfully) -#: panels/printers/pp-jobs-dialog.c:275 +#: panels/printers/pp-jobs-dialog.c:266 msgctxt "print job" msgid "Completed" msgstr "Completado" #. Translators: This label shows how many jobs of this printer needs to be authenticated to be printed. -#: panels/printers/pp-jobs-dialog.c:399 +#: panels/printers/pp-jobs-dialog.c:390 #, c-format -#| msgid "Server requires authentication" msgid "%u Job Requires Authentication" msgid_plural "%u Jobs Require Authentication" msgstr[0] "%u trabajo requiere autenticación" msgstr[1] "%u trabajos requieren autenticación" #. Translators: This is the printer name for which we are showing the active jobs -#: panels/printers/pp-jobs-dialog.c:617 +#: panels/printers/pp-jobs-dialog.c:620 #, c-format msgctxt "Printer jobs dialog title" msgid "%s — Active Jobs" msgstr "%s - trabajos activos" #. Translators: The printer needs authentication info to print. -#: panels/printers/pp-jobs-dialog.c:622 +#: panels/printers/pp-jobs-dialog.c:625 #, c-format -#| msgid "Enter username and password to view printers on %s." msgid "Enter credentials to print from %s." msgstr "Introduzca las credenciales para imprimir desde %s." @@ -4889,25 +4967,25 @@ msgstr "" "El servicio del sistema de impresión\n" "parece no estar disponible." -#: panels/privacy/cc-privacy-panel.c:387 panels/privacy/privacy.ui:280 +#: panels/privacy/cc-privacy-panel.c:388 panels/privacy/privacy.ui:280 msgid "Screen Lock" msgstr "Bloqueo de pantalla" -#: panels/privacy/cc-privacy-panel.c:438 +#: panels/privacy/cc-privacy-panel.c:439 msgid "In use" msgstr "En uso" -#: panels/privacy/cc-privacy-panel.c:443 +#: panels/privacy/cc-privacy-panel.c:444 msgctxt "Location services status" msgid "On" msgstr "Activado" -#: panels/privacy/cc-privacy-panel.c:444 +#: panels/privacy/cc-privacy-panel.c:445 msgctxt "Location services status" msgid "Off" msgstr "Desactivado" -#: panels/privacy/cc-privacy-panel.c:823 panels/privacy/privacy.ui:745 +#: panels/privacy/cc-privacy-panel.c:825 panels/privacy/privacy.ui:745 msgid "Location Services" msgstr "Servicios de ubicación" @@ -4974,12 +5052,13 @@ msgid "Protect your personal information and control what others might see" msgstr "Proteger su información personal y controlar qué pueden ver otros" #. FIXME -#: panels/privacy/gnome-privacy-panel.desktop.in.in:7 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/privacy/gnome-privacy-panel.desktop.in.in:8 msgid "preferences-system-privacy" msgstr "preferences-system-privacy" -#. Translators: those are keywords for the privacy control-center panel -#: panels/privacy/gnome-privacy-panel.desktop.in.in:19 +#. Translators: Search terms to find the Privacy panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/privacy/gnome-privacy-panel.desktop.in.in:20 msgid "" "screen;lock;diagnostics;crash;private;recent;temporary;tmp;index;name;" "network;identity;" @@ -5166,11 +5245,11 @@ msgctxt "Input Source" msgid "Other" msgstr "Otra" -#: panels/region/cc-region-panel.c:881 +#: panels/region/cc-region-panel.c:882 msgid "No input source selected" msgstr "No se ha seleccionado ninguna fuente de entrada" -#: panels/region/cc-region-panel.c:1773 +#: panels/region/cc-region-panel.c:1774 msgid "Login _Screen" msgstr "Pantalla de inicio de _sesión" @@ -5217,12 +5296,13 @@ msgstr "" "Seleccione su idioma, formatos, distribuciones de teclado y fuentes de " "entrada" -#: panels/region/gnome-region-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/region/gnome-region-panel.desktop.in.in:7 msgid "preferences-desktop-locale" msgstr "preferences-desktop-locale" -#. Translators: those are keywords for the region control-center panel -#: panels/region/gnome-region-panel.desktop.in.in:18 +#. Translators: Search terms to find the Region and Language panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/region/gnome-region-panel.desktop.in.in:19 msgid "Language;Layout;Keyboard;Input;" msgstr "Idioma;Distribución;Teclado;Entrada;" @@ -5357,12 +5437,13 @@ msgstr "" "Controlar qué aplicaciones muestran resultados de búsqueda en la vista de " "actividades" -#: panels/search/gnome-search-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/search/gnome-search-panel.desktop.in.in:7 msgid "preferences-system-search" msgstr "preferences-system-search" -#. Translators: those are keywords for the search control-center panel -#: panels/search/gnome-search-panel.desktop.in.in:18 +#. Translators: Search terms to find the Search panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/search/gnome-search-panel.desktop.in.in:19 msgid "Search;Find;Index;Hide;Privacy;Results;" msgstr "buscar;búsqueda;índice;ocultar;privacidad;resultados;" @@ -5466,12 +5547,13 @@ msgstr "Compartir" msgid "Control what you want to share with others" msgstr "Controla qué quiere compartir con otros" -#: panels/sharing/gnome-sharing-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/sharing/gnome-sharing-panel.desktop.in.in:7 msgid "preferences-system-sharing" msgstr "preferences-system-sharing" -#. Translators: those are keywords for the sharing control-center panel -#: panels/sharing/gnome-sharing-panel.desktop.in.in:15 +#. Translators: Search terms to find the Sharing panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/sharing/gnome-sharing-panel.desktop.in.in:16 msgid "" "share;sharing;ssh;host;name;remote;desktop;media;audio;video;pictures;photos;" "movies;server;renderer;" @@ -5577,12 +5659,13 @@ msgstr "Sonido" msgid "Change sound levels, inputs, outputs, and alert sounds" msgstr "Cambiar el volumen de entrada y salida de sonido y las alertas sonoras" -#: panels/sound/data/gnome-sound-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/sound/data/gnome-sound-panel.desktop.in.in:7 msgid "multimedia-volume-control" msgstr "multimedia-volume-control" -#. Translators: those are keywords for the sound control-center panel -#: panels/sound/data/gnome-sound-panel.desktop.in.in:19 +#. Translators: Search terms to find the Sound panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/sound/data/gnome-sound-panel.desktop.in.in:20 msgid "Card;Microphone;Volume;Fade;Balance;Bluetooth;Headset;Audio;" msgstr "" "tarjeta;micrófono;volumen;desvanecer;balance;bluetooth;cascos;auriculares;" @@ -5775,34 +5858,223 @@ msgstr "Subwoofer" msgid "Custom" msgstr "Personalizado" +#: panels/thunderbolt/cc-bolt-device-dialog.c:86 +#: panels/thunderbolt/cc-bolt-device-entry.c:119 +#| msgid "Disconnected" +msgctxt "Thunderbolt Device Status" +msgid "Disconnected" +msgstr "Desconectado" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:89 +#: panels/thunderbolt/cc-bolt-device-entry.c:122 +#| msgid "Connecting" +msgctxt "Thunderbolt Device Status" +msgid "Connecting" +msgstr "Conectando" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:92 +#: panels/thunderbolt/cc-bolt-device-entry.c:126 +#: panels/thunderbolt/cc-bolt-device-entry.c:138 +#| msgid "Connected" +msgctxt "Thunderbolt Device Status" +msgid "Connected" +msgstr "Conectado" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:95 +#| msgid "Authentication required" +msgctxt "Thunderbolt Device Status" +msgid "Authorization Error" +msgstr "Error de autorización" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:98 +#: panels/thunderbolt/cc-bolt-device-entry.c:132 +msgctxt "Thunderbolt Device Status" +msgid "Authorizing" +msgstr "Autorizando" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:105 +msgctxt "Thunderbolt Device Status" +msgid "Reduced Functionality" +msgstr "Funcionalidad reducida" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:107 +#| msgid "Connected Devices" +msgctxt "Thunderbolt Device Status" +msgid "Connected & Authorized" +msgstr "Conectado y autorizado" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:113 +#: panels/thunderbolt/cc-bolt-device-entry.c:146 +#| msgid "Unknown" +msgctxt "Thunderbolt Device Status" +msgid "Unknown" +msgstr "Desconocido" + +#. Translators: The time point the device was authorized. +#: panels/thunderbolt/cc-bolt-device-dialog.c:169 +msgid "Authorized at:" +msgstr "Autorizado a las:" + +#. Translators: The time point the device was connected. +#: panels/thunderbolt/cc-bolt-device-dialog.c:175 +#| msgid "Connected" +msgid "Connected at:" +msgstr "Conectado a las:" + +#. Translators: The time point the device was enrolled, +#. * i.e. authorized and stored in the device database. +#: panels/thunderbolt/cc-bolt-device-dialog.c:182 +#| msgid "_Enroll" +msgid "Enrolled at:" +msgstr "Unido a las:" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:250 +#| msgid "Failed to upload file: %s" +msgid "Failed to authorize device: " +msgstr "Falló al autorizar el dispositivo: " + +#: panels/thunderbolt/cc-bolt-device-dialog.c:327 +#| msgid "Failed to upload file: %s" +msgid "Failed to forget device: " +msgstr "Falló al olvidar el dispositivo: " + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:109 +#| msgid "_Name:" +msgid "Name:" +msgstr "Nombre:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:141 +msgid "Status:" +msgstr "Estado:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:174 +msgid "UUID:" +msgstr "UUID:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:280 +#| msgid "Automatic _Connect" +msgid "Authorize and Connect" +msgstr "Autorizar y conectar" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:303 +#| msgid "Remove Device" +msgid "Forget Device" +msgstr "Olvidar dispositivo" + +#: panels/thunderbolt/cc-bolt-device-entry.c:129 +#| msgid "Mirror" +msgctxt "Thunderbolt Device Status" +msgid "Error" +msgstr "Error" + +#: panels/thunderbolt/cc-bolt-device-entry.c:140 +#| msgid "Authenticated" +msgctxt "Thunderbolt Device Status" +msgid "Authorized" +msgstr "Autorizado" + +#: panels/thunderbolt/cc-bolt-panel.c:175 +msgid "" +"The Thunderbolt subsystem (boltd) is not installed or not set up properly." +msgstr "" +"El subsistema de Thunderbolt (boltd) no está instalado o no se ha " +"configurado correctamente." + +#: panels/thunderbolt/cc-bolt-panel.c:460 +msgid "" +"Thunderbolt could not be detected.\n" +"Either the system lacks Thunderbolt support, it has been disabled in the " +"BIOS or is set to an unsupported security level in the BIOS." +msgstr "" +"No se pudo detectar Thunderbolt.\n" +"El sistema carece de soporte para Thunderbolt, se ha desactivado en la BIOS " +"o se ha configurado con un nivel de seguridad no soportado en la BIOS." + +#: panels/thunderbolt/cc-bolt-panel.c:504 +msgid "Thunderbolt support has been disabled in the BIOS." +msgstr "El soporte de Thunderbolt se ha desactivado en la BIOS." + +#: panels/thunderbolt/cc-bolt-panel.c:613 +#, c-format +#| msgid "Error setting default mailer: %s" +msgid "Error switching direct mode: %s" +msgstr "Error al cambiar al modo directo: %s" + +#: panels/thunderbolt/cc-bolt-panel.ui:143 +msgid "No Thunderbolt support" +msgstr "Si soporte para Thunderbolt" + +#: panels/thunderbolt/cc-bolt-panel.ui:246 +#| msgid "Universal Access" +msgid "Direct Access" +msgstr "Acceso directo" + +#: panels/thunderbolt/cc-bolt-panel.ui:269 +msgid "Allow direct access to devices such as docks and external GPUs." +msgstr "Permitir el acceso a dispositivos como soportes y GPU externas." + +#: panels/thunderbolt/cc-bolt-panel.ui:289 +msgid "Only USB and Display Port devices can attach." +msgstr "Sólo se pueden conectar dispositivos USB y Display Port" + +#: panels/thunderbolt/cc-bolt-panel.ui:397 +#| msgid "Getting devices..." +msgid "Pending Devices" +msgstr "Dispositivos pendientes" + +#: panels/thunderbolt/cc-bolt-panel.ui:535 +msgid "No devices attached" +msgstr "No hay dispositivos conectados" + +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:3 +#| msgid "Thunderbird" +msgid "Thunderbolt" +msgstr "Thunderbolt" + +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:4 +msgid "Manage Thunderbolt devices" +msgstr "Gestionar dispositivos Thunderbolt" + +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:7 +#| msgid "Thunderbird" +msgid "thunderbolt" +msgstr "thunderbolt" + +#. Translators: those are keywords for the thunderbolt control-center panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:19 +#| msgid "Thunderbird" +msgid "Thunderbolt;" +msgstr "Thunderbolt;" + #. translators: the labels will read: #. * Cursor Size: Default -#: panels/universal-access/cc-ua-panel.c:353 +#: panels/universal-access/cc-ua-panel.c:354 msgctxt "cursor size" msgid "Default" msgstr "Predeterminado" -#: panels/universal-access/cc-ua-panel.c:356 +#: panels/universal-access/cc-ua-panel.c:357 msgctxt "cursor size" msgid "Medium" msgstr "Mediano" -#: panels/universal-access/cc-ua-panel.c:359 +#: panels/universal-access/cc-ua-panel.c:360 msgctxt "cursor size" msgid "Large" msgstr "Grande" -#: panels/universal-access/cc-ua-panel.c:362 +#: panels/universal-access/cc-ua-panel.c:363 msgctxt "cursor size" msgid "Larger" msgstr "Más grande" -#: panels/universal-access/cc-ua-panel.c:365 +#: panels/universal-access/cc-ua-panel.c:366 msgctxt "cursor size" msgid "Largest" msgstr "El más grande" -#: panels/universal-access/cc-ua-panel.c:369 +#: panels/universal-access/cc-ua-panel.c:370 #, c-format msgid "%d pixel" msgid_plural "%d pixels" @@ -5813,12 +6085,13 @@ msgstr[1] "%d píxeles" msgid "Make it easier to see, hear, type, point and click" msgstr "Hacer más sencillo de ver, escuchar, escribir y apuntar y pulsar" -#: panels/universal-access/gnome-universal-access-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/universal-access/gnome-universal-access-panel.desktop.in.in:7 msgid "preferences-desktop-accessibility" msgstr "preferences-desktop-accessibility" -#. Translators: those are keywords for the universal access control-center panel -#: panels/universal-access/gnome-universal-access-panel.desktop.in.in:18 +#. Translators: Search terms to find the Universal Access panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/universal-access/gnome-universal-access-panel.desktop.in.in:19 msgid "" "Keyboard;Mouse;a11y;Accessibility;Contrast;Zoom;Screen;Reader;text;font;size;" "AccessX;Sticky;Keys;Slow;Bounce;Mouse;Double;click;Delay;Assist;Repeat;Blink;" @@ -5848,7 +6121,7 @@ msgid "C_ursor Size" msgstr "T_amaño del cursor" #: panels/universal-access/uap.ui:316 -#: panels/universal-access/zoom-options.ui:98 +#: panels/universal-access/zoom-options.ui:99 msgid "_Zoom" msgstr "_Ampliación" @@ -6142,27 +6415,27 @@ msgctxt "dwell click threshold" msgid "Large" msgstr "Grande" -#: panels/universal-access/zoom-options.c:333 +#: panels/universal-access/zoom-options.c:338 msgctxt "Distance" msgid "Short" msgstr "Corta" -#: panels/universal-access/zoom-options.c:334 +#: panels/universal-access/zoom-options.c:339 msgctxt "Distance" msgid "¼ Screen" msgstr "¼ de pantalla" -#: panels/universal-access/zoom-options.c:335 +#: panels/universal-access/zoom-options.c:340 msgctxt "Distance" msgid "½ Screen" msgstr "½ pantalla" -#: panels/universal-access/zoom-options.c:336 +#: panels/universal-access/zoom-options.c:341 msgctxt "Distance" msgid "¾ Screen" msgstr "¾ de pantalla" -#: panels/universal-access/zoom-options.c:337 +#: panels/universal-access/zoom-options.c:342 msgctxt "Distance" msgid "Long" msgstr "Larga" @@ -6187,134 +6460,134 @@ msgstr "Mitad izquierda" msgid "Right Half" msgstr "Mitad derecha" -#: panels/universal-access/zoom-options.ui:77 +#: panels/universal-access/zoom-options.ui:78 msgid "Zoom Options" msgstr "Opciones de ampliación" -#: panels/universal-access/zoom-options.ui:186 +#: panels/universal-access/zoom-options.ui:188 msgid "_Magnification:" msgstr "_Magnificación:" -#: panels/universal-access/zoom-options.ui:250 +#: panels/universal-access/zoom-options.ui:252 msgid "_Follow mouse cursor" msgstr "_Seguir el cursor del ratón" -#: panels/universal-access/zoom-options.ui:270 +#: panels/universal-access/zoom-options.ui:272 msgid "_Screen part:" msgstr "_Parte de la pantalla:" -#: panels/universal-access/zoom-options.ui:332 +#: panels/universal-access/zoom-options.ui:334 msgid "Magnifier _extends outside of screen" msgstr "El magnificador se _extiende fuera de la pantalla" -#: panels/universal-access/zoom-options.ui:351 +#: panels/universal-access/zoom-options.ui:353 msgid "_Keep magnifier cursor centered" msgstr "_Mantener centrado el cursor del magnificador" -#: panels/universal-access/zoom-options.ui:370 +#: panels/universal-access/zoom-options.ui:372 msgid "Magnifier cursor _pushes contents around" msgstr "El cursor del magnificador _empuja el contenido a su alrededor" -#: panels/universal-access/zoom-options.ui:389 +#: panels/universal-access/zoom-options.ui:391 msgid "Magnifier cursor moves with _contents" msgstr "El cursor del magnificador se mueve con el _contenido" -#: panels/universal-access/zoom-options.ui:423 +#: panels/universal-access/zoom-options.ui:425 msgid "Magnifier Position:" msgstr "Posición del magnificador:" -#: panels/universal-access/zoom-options.ui:444 +#: panels/universal-access/zoom-options.ui:446 msgid "Magnifier" msgstr "Magnificador" -#: panels/universal-access/zoom-options.ui:490 +#: panels/universal-access/zoom-options.ui:493 msgid "_Thickness:" msgstr "_Grosor:" -#: panels/universal-access/zoom-options.ui:516 +#: panels/universal-access/zoom-options.ui:519 msgctxt "universal access, thickness" msgid "Thin" msgstr "Fino" -#: panels/universal-access/zoom-options.ui:548 +#: panels/universal-access/zoom-options.ui:551 msgctxt "universal access, thickness" msgid "Thick" msgstr "Grueso" -#: panels/universal-access/zoom-options.ui:574 +#: panels/universal-access/zoom-options.ui:577 msgid "_Length:" msgstr "_Longitud:" #. The color of the accessibility crosshair -#: panels/universal-access/zoom-options.ui:626 +#: panels/universal-access/zoom-options.ui:629 msgid "Co_lor:" msgstr "Co_lor:" -#: panels/universal-access/zoom-options.ui:690 +#: panels/universal-access/zoom-options.ui:693 msgid "_Crosshairs:" msgstr "_Cruces:" -#: panels/universal-access/zoom-options.ui:741 +#: panels/universal-access/zoom-options.ui:744 msgid "_Overlaps mouse cursor" msgstr "_Solapa el cursor del ratón" -#: panels/universal-access/zoom-options.ui:779 +#: panels/universal-access/zoom-options.ui:782 msgid "Crosshairs" msgstr "Cruces" -#: panels/universal-access/zoom-options.ui:827 +#: panels/universal-access/zoom-options.ui:831 msgid "_White on black:" msgstr "_Blanco sobre negro:" -#: panels/universal-access/zoom-options.ui:850 +#: panels/universal-access/zoom-options.ui:854 msgid "_Brightness:" msgstr "_Brillo:" -#: panels/universal-access/zoom-options.ui:874 +#: panels/universal-access/zoom-options.ui:878 msgid "_Contrast:" msgstr "_Contraste:" #. The contrast scale goes from Color to None (grayscale) -#: panels/universal-access/zoom-options.ui:897 +#: panels/universal-access/zoom-options.ui:901 msgctxt "universal access, contrast" msgid "Co_lor" msgstr "Co_lor" -#: panels/universal-access/zoom-options.ui:925 +#: panels/universal-access/zoom-options.ui:929 msgctxt "universal access, color" msgid "None" msgstr "Ninguno" -#: panels/universal-access/zoom-options.ui:957 +#: panels/universal-access/zoom-options.ui:961 msgctxt "universal access, color" msgid "Full" msgstr "Completo" -#: panels/universal-access/zoom-options.ui:1023 +#: panels/universal-access/zoom-options.ui:1027 msgctxt "universal access, brightness" msgid "Low" msgstr "Bajo" -#: panels/universal-access/zoom-options.ui:1056 +#: panels/universal-access/zoom-options.ui:1060 msgctxt "universal access, brightness" msgid "High" msgstr "Alto" -#: panels/universal-access/zoom-options.ui:1087 +#: panels/universal-access/zoom-options.ui:1091 msgctxt "universal access, contrast" msgid "Low" msgstr "Bajo" -#: panels/universal-access/zoom-options.ui:1120 +#: panels/universal-access/zoom-options.ui:1124 msgctxt "universal access, contrast" msgid "High" msgstr "Alto" -#: panels/universal-access/zoom-options.ui:1156 +#: panels/universal-access/zoom-options.ui:1160 msgid "Color Effects:" msgstr "Efectos de color:" -#: panels/universal-access/zoom-options.ui:1181 +#: panels/universal-access/zoom-options.ui:1185 msgid "Color Effects" msgstr "Efectos de color" @@ -6457,12 +6730,13 @@ msgstr "Usuarios" msgid "Add or remove users and change your password" msgstr "Añadir o quitar usuarios y cambiar su contraseña" -#: panels/user-accounts/data/gnome-user-accounts-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/user-accounts/data/gnome-user-accounts-panel.desktop.in.in:7 msgid "system-users" msgstr "system-users" -#. Translators: those are keywords for the user accounts control-center panel -#: panels/user-accounts/data/gnome-user-accounts-panel.desktop.in.in:19 +#. Translators: Search terms to find the Users panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/user-accounts/data/gnome-user-accounts-panel.desktop.in.in:20 msgid "Login;Name;Fingerprint;Avatar;Logo;Face;Password;" msgstr "inicio;sesión;nombre;huella;avatar;logo;cara;contraseña;" @@ -6909,7 +7183,7 @@ msgstr "%s — %s" #. Translators: This is a time format string in the style of "22:58". #. It indicates a login time which follows a date. #: panels/user-accounts/um-history-dialog.c:177 -#: panels/user-accounts/um-user-panel.c:767 +#: panels/user-accounts/um-user-panel.c:766 msgctxt "login date-time" msgid "%k:%M" msgstr "%k:%M" @@ -6917,7 +7191,7 @@ msgstr "%k:%M" #. Translators: This indicates a login date-time. #. The first %s is a date, and the second %s a time. #: panels/user-accounts/um-history-dialog.c:180 -#: panels/user-accounts/um-user-panel.c:771 +#: panels/user-accounts/um-user-panel.c:770 #, c-format msgctxt "login date-time" msgid "%s, %s" @@ -6954,7 +7228,7 @@ msgstr "No se pudo cambiar la contraseña" msgid "The passwords do not match." msgstr "Las contraseñas no coinciden." -#: panels/user-accounts/um-photo-dialog.c:226 +#: panels/user-accounts/um-photo-dialog.c:227 msgid "Browse for more pictures" msgstr "Examinar para buscar más imágenes" @@ -6982,30 +7256,30 @@ msgstr "Contraseña no válida, inténtelo de nuevo" msgid "Couldn’t connect to the %s domain: %s" msgstr "No se pudo conectar al dominio %s: %s" -#: panels/user-accounts/um-user-panel.c:201 +#: panels/user-accounts/um-user-panel.c:200 msgid "Your account" msgstr "Su cuenta" -#: panels/user-accounts/um-user-panel.c:381 +#: panels/user-accounts/um-user-panel.c:380 msgid "Failed to delete user" msgstr "Falló al eliminar el usuario" -#: panels/user-accounts/um-user-panel.c:439 -#: panels/user-accounts/um-user-panel.c:498 -#: panels/user-accounts/um-user-panel.c:550 +#: panels/user-accounts/um-user-panel.c:438 +#: panels/user-accounts/um-user-panel.c:497 +#: panels/user-accounts/um-user-panel.c:549 msgid "Failed to revoke remotely managed user" msgstr "Falló al revocar remotamente el usuario gestionado" -#: panels/user-accounts/um-user-panel.c:604 +#: panels/user-accounts/um-user-panel.c:603 msgid "You cannot delete your own account." msgstr "No puede eliminar su propia cuenta." -#: panels/user-accounts/um-user-panel.c:613 +#: panels/user-accounts/um-user-panel.c:612 #, c-format msgid "%s is still logged in" msgstr "%s aún está registrado en el sistema" -#: panels/user-accounts/um-user-panel.c:617 +#: panels/user-accounts/um-user-panel.c:616 msgid "" "Deleting a user while they are logged in can leave the system in an " "inconsistent state." @@ -7013,12 +7287,12 @@ msgstr "" "Eliminar un usuario mientras está registrado en el sistema puede dejar el " "sistema en un estado inconsistente." -#: panels/user-accounts/um-user-panel.c:626 +#: panels/user-accounts/um-user-panel.c:625 #, c-format msgid "Do you want to keep %s’s files?" msgstr "¿Quiere mantener los archivos de %s?" -#: panels/user-accounts/um-user-panel.c:630 +#: panels/user-accounts/um-user-panel.c:629 msgid "" "It is possible to keep the home directory, mail spool and temporary files " "around when deleting a user account." @@ -7026,48 +7300,48 @@ msgstr "" "Es posible mantener la carpeta personal, el «spool» del correo y los " "archivos temporales al eliminar una cuenta de usuario." -#: panels/user-accounts/um-user-panel.c:633 +#: panels/user-accounts/um-user-panel.c:632 msgid "_Delete Files" msgstr "_Eliminar archivos" -#: panels/user-accounts/um-user-panel.c:634 +#: panels/user-accounts/um-user-panel.c:633 msgid "_Keep Files" msgstr "_Mantener archivos" -#: panels/user-accounts/um-user-panel.c:648 +#: panels/user-accounts/um-user-panel.c:647 #, c-format msgid "Are you sure you want to revoke remotely managed %s’s account?" msgstr "" "¿Está seguro de que quiere revocar remotamente la cuenta gestionada de %s?" -#: panels/user-accounts/um-user-panel.c:652 +#: panels/user-accounts/um-user-panel.c:651 msgid "_Delete" msgstr "_Eliminar" -#: panels/user-accounts/um-user-panel.c:702 +#: panels/user-accounts/um-user-panel.c:701 msgctxt "Password mode" msgid "Account disabled" msgstr "Cuenta desactivada" -#: panels/user-accounts/um-user-panel.c:710 +#: panels/user-accounts/um-user-panel.c:709 msgctxt "Password mode" msgid "To be set at next login" msgstr "Para configurar en el siguiente inicio de sesión" -#: panels/user-accounts/um-user-panel.c:713 +#: panels/user-accounts/um-user-panel.c:712 msgctxt "Password mode" msgid "None" msgstr "Ninguno" -#: panels/user-accounts/um-user-panel.c:760 +#: panels/user-accounts/um-user-panel.c:759 msgid "Logged in" msgstr "Sesión iniciada" -#: panels/user-accounts/um-user-panel.c:1107 +#: panels/user-accounts/um-user-panel.c:1106 msgid "Failed to contact the accounts service" msgstr "Falló al contactar con el servicio de cuentas" -#: panels/user-accounts/um-user-panel.c:1109 +#: panels/user-accounts/um-user-panel.c:1108 msgid "Please make sure that the AccountService is installed and enabled." msgstr "Asegúrese de que el servicio de cuentas está instalado y activado." @@ -7075,7 +7349,7 @@ msgstr "Asegúrese de que el servicio de cuentas está instalado y activado." #. * We split the line in 2 here to "make it look good", as there's #. * no good way to do this in GTK+ for tooltips. See: #. * https://bugzilla.gnome.org/show_bug.cgi?id=657168 -#: panels/user-accounts/um-user-panel.c:1141 +#: panels/user-accounts/um-user-panel.c:1140 msgid "" "To make changes,\n" "click the * icon first" @@ -7083,12 +7357,12 @@ msgstr "" "Para realizar los cambios\n" "pulse primero el icono *" -#: panels/user-accounts/um-user-panel.c:1181 +#: panels/user-accounts/um-user-panel.c:1180 msgid "Create a user account" msgstr "Crear una cuenta de usuario" -#: panels/user-accounts/um-user-panel.c:1192 -#: panels/user-accounts/um-user-panel.c:1371 +#: panels/user-accounts/um-user-panel.c:1191 +#: panels/user-accounts/um-user-panel.c:1370 msgid "" "To create a user account,\n" "click the * icon first" @@ -7096,12 +7370,12 @@ msgstr "" "Para crear un usuario\n" "pulse primero el icono *" -#: panels/user-accounts/um-user-panel.c:1202 +#: panels/user-accounts/um-user-panel.c:1201 msgid "Delete the selected user account" msgstr "Quitar la cuenta de usuario seleccionada" -#: panels/user-accounts/um-user-panel.c:1214 -#: panels/user-accounts/um-user-panel.c:1376 +#: panels/user-accounts/um-user-panel.c:1213 +#: panels/user-accounts/um-user-panel.c:1375 msgid "" "To delete the selected user account,\n" "click the * icon first" @@ -7235,12 +7509,13 @@ msgstr "" "Establecer el mapeado de botones y ajustar la sensibilidad del lápiz para " "tabletas gráficas" -#: panels/wacom/gnome-wacom-panel.desktop.in.in:6 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/wacom/gnome-wacom-panel.desktop.in.in:7 msgid "input-tablet" msgstr "input-tablet" -#. Translators: those are keywords for the wacom tablet control-center panel -#: panels/wacom/gnome-wacom-panel.desktop.in.in:18 +#. Translators: Search terms to find the Wacom Tablet panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/wacom/gnome-wacom-panel.desktop.in.in:19 msgid "Tablet;Wacom;Stylus;Eraser;Mouse;" msgstr "Tableta;Wacom;Stylus;Borrador;Ratón;" @@ -7376,35 +7651,35 @@ msgstr "" "El centro de control es la interfaz principal de GNOME para la configuración " "de diversos aspectos de su escritorio." -#: shell/cc-application.c:47 +#: shell/cc-application.c:60 msgid "Display version number" msgstr "Mostrar el número de versión" -#: shell/cc-application.c:48 +#: shell/cc-application.c:61 msgid "Enable verbose mode" msgstr "Activar el modo detallado" -#: shell/cc-application.c:49 +#: shell/cc-application.c:62 msgid "Show the overview" msgstr "Mostrar la visión general" -#: shell/cc-application.c:50 +#: shell/cc-application.c:63 msgid "Search for the string" msgstr "Buscar la cadena" -#: shell/cc-application.c:51 +#: shell/cc-application.c:64 msgid "List possible panel names and exit" msgstr "Listar todos los nombres de paneles posibles y salir" -#: shell/cc-application.c:52 +#: shell/cc-application.c:65 msgid "Panel to display" msgstr "Panel que mostrar" -#: shell/cc-application.c:52 +#: shell/cc-application.c:65 msgid "[PANEL] [ARGUMENT…]" msgstr "[PANEL] [ARGUMENTO…]" -#: shell/cc-application.c:117 +#: shell/cc-application.c:136 msgid "Available panels:" msgstr "Paneles disponibles:" @@ -7416,11 +7691,13 @@ msgstr "Ayuda" msgid "Quit" msgstr "Salir" -#: shell/gnome-control-center.desktop.in.in:4 +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: shell/gnome-control-center.desktop.in.in:5 msgid "gnome-control-center" msgstr "gnome-control-center" -#: shell/gnome-control-center.desktop.in.in:15 +#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: shell/gnome-control-center.desktop.in.in:17 msgid "Preferences;Settings;" msgstr "Preferencias;Configuración;" @@ -7454,12 +7731,6 @@ msgctxt "shortcut window" msgid "Cancel search" msgstr "Cancelar búsqueda" -#. translators: This is the default hotspot name, need to be less than 32-bytes -#: shell/hostname-helper.c:189 -msgctxt "hotspot" -msgid "Hotspot" -msgstr "Hotspot" - #: shell/org.gnome.ControlCenter.gschema.xml:5 msgid "The identifier for the last Settings panel to be opened" msgstr "El identificador del último panel de Configuración que abrir" @@ -7869,9 +8140,6 @@ msgstr "Sonidos del sistema" #~ msgid "Add Device" #~ msgstr "Añadir dispositivo" -#~ msgid "Remove Device" -#~ msgstr "Quitar dispositivo" - #~ msgid "VPN Type" #~ msgstr "Tipo de VPN" @@ -8212,9 +8480,6 @@ msgstr "Sonidos del sistema" #~ msgid "_Sign In" #~ msgstr "Iniciar _sesión" -#~ msgid "_Name:" -#~ msgstr "_Nombre:" - #~ msgid "C_ommand:" #~ msgstr "C_omando:" @@ -9350,9 +9615,6 @@ msgstr "Sonidos del sistema" #~ msgid "_Settings…" #~ msgstr "_Configuración…" -#~ msgid "Disconnected" -#~ msgstr "Desconectada" - #~ msgid "Unspecified" #~ msgstr "Sin especificar" @@ -9652,9 +9914,6 @@ msgstr "Sonidos del sistema" #~ msgid "_Search by Address" #~ msgstr "Bu_scar por dirección" -#~ msgid "Getting devices..." -#~ msgstr "Obteniendo dispositivos…" - #~ msgid "" #~ "FirewallD is not running. Network printer detection needs services mdns, " #~ "ipp, ipp-client and samba-client enabled on firewall." @@ -10548,9 +10807,6 @@ msgstr "Sonidos del sistema" #~ msgid "Error setting default browser: %s" #~ msgstr "Error al establecer el navegador predeterminado: %s" -#~ msgid "Error setting default mailer: %s" -#~ msgstr "Error al establecer el programa de correo-e predeterminado: %s" - #~ msgid "Could not load the main interface" #~ msgstr "No es posible cargar el interfaz principal" @@ -10858,9 +11114,6 @@ msgstr "Sonidos del sistema" #~ msgid "Sylpheed-Claws" #~ msgstr "Sylpheed-Claws" -#~ msgid "Thunderbird" -#~ msgstr "Thunderbird" - #~ msgid "_Include Top Menu Bar" #~ msgstr "_Incluir barra de menú superior" -- cgit v1.2.1 From 3cf277eb6814157484763d40e2792494cb55ff20 Mon Sep 17 00:00:00 2001 From: Ondrej Holy Date: Tue, 24 Apr 2018 13:54:41 +0200 Subject: user-accounts: Port UmAccountDialog to GTask https://gitlab.gnome.org/GNOME/gnome-control-center/issues/20 --- panels/user-accounts/um-account-dialog.c | 38 +++++++++++++------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/panels/user-accounts/um-account-dialog.c b/panels/user-accounts/um-account-dialog.c index 9ca2c6d9d..d40622d68 100644 --- a/panels/user-accounts/um-account-dialog.c +++ b/panels/user-accounts/um-account-dialog.c @@ -70,7 +70,7 @@ static void um_account_dialog_response (GtkDialog *dialog, struct _UmAccountDialog { GtkDialog parent; GtkWidget *stack; - GSimpleAsyncResult *async; + GTask *task; GCancellable *cancellable; GPermission *permission; GtkSpinner *spinner; @@ -181,14 +181,13 @@ static void complete_dialog (UmAccountDialog *self, ActUser *user) { - if (user != NULL) { - g_simple_async_result_set_op_res_gpointer (self->async, - g_object_ref (user), - g_object_unref); - } - - g_simple_async_result_complete_in_idle (self->async); gtk_widget_hide (GTK_WIDGET (self)); + + if (user != NULL) + g_object_ref (user); + + g_task_return_pointer (self->task, user, g_object_unref); + g_clear_object (&self->task); } static void @@ -1599,15 +1598,15 @@ um_account_dialog_show (UmAccountDialog *self, g_return_if_fail (UM_IS_ACCOUNT_DIALOG (self)); /* Make sure not already doing an operation */ - g_return_if_fail (self->async == NULL); - - self->async = g_simple_async_result_new (G_OBJECT (self), callback, user_data, - um_account_dialog_show); + g_return_if_fail (self->task == NULL); if (self->cancellable) g_object_unref (self->cancellable); self->cancellable = g_cancellable_new (); + self->task = g_task_new (G_OBJECT (self), self->cancellable, callback, user_data); + g_task_set_source_tag (self->task, um_account_dialog_show); + g_clear_object (&self->permission); self->permission = permission ? g_object_ref (permission) : NULL; @@ -1626,17 +1625,10 @@ ActUser * um_account_dialog_finish (UmAccountDialog *self, GAsyncResult *result) { - ActUser *user; - g_return_val_if_fail (UM_IS_ACCOUNT_DIALOG (self), NULL); - g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), - um_account_dialog_show), NULL); - g_return_val_if_fail (result == G_ASYNC_RESULT (self->async), NULL); - - user = g_simple_async_result_get_op_res_gpointer (self->async); - if (user != NULL) - g_object_ref (user); + g_return_val_if_fail (g_task_is_valid (result, G_OBJECT (self)), NULL); + g_return_val_if_fail (g_async_result_is_tagged (result, um_account_dialog_show), NULL); + g_return_val_if_fail (result == G_ASYNC_RESULT (self->task), NULL); - g_clear_object (&self->async); - return user; + return g_task_propagate_pointer (self->task, NULL); } -- cgit v1.2.1 From 85f267bfa7045f41640da7feaac440327101ae74 Mon Sep 17 00:00:00 2001 From: Ondrej Holy Date: Tue, 24 Apr 2018 15:14:08 +0200 Subject: user-accounts: Port UmRealmManager to GTask https://gitlab.gnome.org/GNOME/gnome-control-center/issues/20 --- panels/user-accounts/um-account-dialog.c | 4 +- panels/user-accounts/um-realm-manager.c | 263 ++++++++++--------------------- panels/user-accounts/um-realm-manager.h | 3 +- 3 files changed, 87 insertions(+), 183 deletions(-) diff --git a/panels/user-accounts/um-account-dialog.c b/panels/user-accounts/um-account-dialog.c index d40622d68..91ac55a7a 100644 --- a/panels/user-accounts/um-account-dialog.c +++ b/panels/user-accounts/um-account-dialog.c @@ -894,7 +894,7 @@ on_join_login (GObject *source, return; } - um_realm_login_finish (result, &creds, &error); + creds = um_realm_login_finish (result, &error); /* Logged in as admin successfully, use creds to join domain */ if (error == NULL) { @@ -1000,7 +1000,7 @@ on_realm_login (GObject *source, return; } - um_realm_login_finish (result, &creds, &error); + creds = um_realm_login_finish (result, &error); /* * User login is valid, but cannot authenticate right now (eg: user needs diff --git a/panels/user-accounts/um-realm-manager.c b/panels/user-accounts/um-realm-manager.c index 26391486f..36fe48206 100644 --- a/panels/user-accounts/um-realm-manager.c +++ b/panels/user-accounts/um-realm-manager.c @@ -166,42 +166,25 @@ on_realm_diagnostics (GDBusConnection *connection, } } -typedef struct { - GCancellable *cancellable; - UmRealmManager *manager; -} NewClosure; - -static void -new_closure_free (gpointer data) -{ - NewClosure *closure = data; - g_clear_object (&closure->cancellable); - g_clear_object (&closure->manager); - g_slice_free (NewClosure, closure); -} - static void on_provider_new (GObject *source, GAsyncResult *result, gpointer user_data) { - GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data); - NewClosure *closure = g_simple_async_result_get_op_res_gpointer (async); + GTask *task = G_TASK (user_data); + UmRealmManager *manager = g_task_get_task_data (task); GError *error = NULL; - UmRealmProvider *provider; - - provider = um_realm_provider_proxy_new_finish (result, &error); - closure->manager->provider = provider; + manager->provider = um_realm_provider_proxy_new_finish (result, &error); if (error == NULL) { - g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (closure->manager->provider), -1); + g_dbus_proxy_set_default_timeout (G_DBUS_PROXY (manager->provider), -1); g_debug ("Created realm manager"); + g_task_return_pointer (task, g_object_ref (manager), g_object_unref); } else { - g_simple_async_result_take_error (async, error); + g_task_return_error (task, error); } - g_simple_async_result_complete (async); - g_object_unref (async); + g_object_unref (task); } static void @@ -209,8 +192,8 @@ on_manager_new (GObject *source, GAsyncResult *result, gpointer user_data) { - GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data); - NewClosure *closure = g_simple_async_result_get_op_res_gpointer (async); + GTask *task = G_TASK (user_data); + UmRealmManager *manager; GDBusConnection *connection; GError *error = NULL; GObject *object; @@ -218,7 +201,7 @@ on_manager_new (GObject *source, object = g_async_initable_new_finish (G_ASYNC_INITABLE (source), result, &error); if (error == NULL) { - closure->manager = UM_REALM_MANAGER (object); + manager = UM_REALM_MANAGER (object); connection = g_dbus_object_manager_client_get_connection (G_DBUS_OBJECT_MANAGER_CLIENT (object)); g_debug ("Connected to realmd"); @@ -233,20 +216,20 @@ on_manager_new (GObject *source, on_realm_diagnostics, NULL, NULL); - closure->manager->diagnostics_sig = sig; + manager->diagnostics_sig = sig; + + g_task_set_task_data (task, manager, g_object_unref); um_realm_provider_proxy_new (connection, G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, "org.freedesktop.realmd", "/org/freedesktop/realmd", - closure->cancellable, - on_provider_new, g_object_ref (async)); + g_task_get_cancellable (task), + on_provider_new, task); } else { - g_simple_async_result_take_error (async, error); - g_simple_async_result_complete (async); + g_task_return_error (task, error); + g_object_unref (task); } - - g_object_unref (async); } void @@ -254,61 +237,37 @@ um_realm_manager_new (GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { - GSimpleAsyncResult *async; - NewClosure *closure; + GTask *task; g_debug ("Connecting to realmd..."); - async = g_simple_async_result_new (NULL, callback, user_data, - um_realm_manager_new); - closure = g_slice_new (NewClosure); - closure->cancellable = cancellable ? g_object_ref (cancellable) : NULL; - g_simple_async_result_set_op_res_gpointer (async, closure, new_closure_free); + task = g_task_new (NULL, cancellable, callback, user_data); + g_task_set_source_tag (task, um_realm_manager_new); g_async_initable_new_async (UM_TYPE_REALM_MANAGER, G_PRIORITY_DEFAULT, - cancellable, on_manager_new, g_object_ref (async), + cancellable, on_manager_new, task, "flags", G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE, "name", "org.freedesktop.realmd", "bus-type", G_BUS_TYPE_SYSTEM, "object-path", "/org/freedesktop/realmd", "get-proxy-type-func", um_realm_object_manager_client_get_proxy_type, NULL); - - g_object_unref (async); } UmRealmManager * um_realm_manager_new_finish (GAsyncResult *result, GError **error) { - GSimpleAsyncResult *async; - NewClosure *closure; - - g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, - um_realm_manager_new), NULL); + g_return_val_if_fail (g_task_is_valid (result, NULL), NULL); + g_return_val_if_fail (g_async_result_is_tagged (result, um_realm_manager_new), NULL); - async = G_SIMPLE_ASYNC_RESULT (result); - if (g_simple_async_result_propagate_error (async, error)) - return NULL; - - closure = g_simple_async_result_get_op_res_gpointer (async); - return g_object_ref (closure->manager); + return g_task_propagate_pointer (G_TASK (result), error); } -typedef struct { - GDBusObjectManager *manager; - GCancellable *cancellable; - GList *realms; -} DiscoverClosure; - static void -discover_closure_free (gpointer data) +realms_free (gpointer data) { - DiscoverClosure *discover = data; - g_object_unref (discover->manager); - g_clear_object (&discover->cancellable); - g_list_free_full (discover->realms, g_object_unref); - g_slice_free (DiscoverClosure, discover); + g_list_free_full (data, g_object_unref); } static void @@ -316,26 +275,27 @@ on_provider_discover (GObject *source, GAsyncResult *result, gpointer user_data) { - GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data); - DiscoverClosure *discover = g_simple_async_result_get_op_res_gpointer (async); + GTask *task = G_TASK (user_data); + UmRealmManager *manager = g_task_get_source_object (task); GDBusObject *object; GError *error = NULL; gboolean no_membership = FALSE; gchar **realms; gint relevance; gint i; + GList *kerberos_realms = NULL; um_realm_provider_call_discover_finish (UM_REALM_PROVIDER (source), &relevance, &realms, result, &error); if (error == NULL) { for (i = 0; realms[i]; i++) { - object = g_dbus_object_manager_get_object (discover->manager, realms[i]); + object = g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER (manager), realms[i]); if (object == NULL) { g_warning ("Realm is not in object manager: %s", realms[i]); } else { if (is_realm_with_kerberos_and_membership (object)) { g_debug ("Discovered realm: %s", realms[i]); - discover->realms = g_list_prepend (discover->realms, object); + kerberos_realms = g_list_prepend (kerberos_realms, object); } else { g_debug ("Realm does not support kerberos membership: %s", realms[i]); no_membership = TRUE; @@ -345,16 +305,21 @@ on_provider_discover (GObject *source, } g_strfreev (realms); - if (!discover->realms && no_membership) { - g_simple_async_result_set_error (async, UM_REALM_ERROR, UM_REALM_ERROR_GENERIC, - _("Cannot automatically join this type of domain")); + if (!kerberos_realms && no_membership) { + g_task_return_new_error (task, UM_REALM_ERROR, UM_REALM_ERROR_GENERIC, + _("Cannot automatically join this type of domain")); + } else if (!kerberos_realms) { + g_task_return_new_error (task, UM_REALM_ERROR, UM_REALM_ERROR_GENERIC, + _("No such domain or realm found")); + } else { + kerberos_realms = g_list_reverse (kerberos_realms); + g_task_return_pointer (task, kerberos_realms, realms_free); } } else { - g_simple_async_result_take_error (async, error); + g_task_return_error (task, error); } - g_simple_async_result_complete (async); - g_object_unref (async); + g_object_unref (task); } void @@ -364,8 +329,7 @@ um_realm_manager_discover (UmRealmManager *self, GAsyncReadyCallback callback, gpointer user_data) { - GSimpleAsyncResult *res; - DiscoverClosure *discover; + GTask *task; GVariant *options; g_return_if_fail (UM_IS_REALM_MANAGER (self)); @@ -374,19 +338,13 @@ um_realm_manager_discover (UmRealmManager *self, g_debug ("Discovering realms for: %s", input); - res = g_simple_async_result_new (G_OBJECT (self), callback, user_data, - um_realm_manager_discover); - discover = g_slice_new0 (DiscoverClosure); - discover->manager = g_object_ref (self); - discover->cancellable = cancellable ? g_object_ref (cancellable) : NULL; - g_simple_async_result_set_op_res_gpointer (res, discover, discover_closure_free); + task = g_task_new (G_OBJECT (self), cancellable, callback, user_data); + g_task_set_source_tag (task, um_realm_manager_discover); options = g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0); um_realm_provider_call_discover (self->provider, input, options, cancellable, - on_provider_discover, g_object_ref (res)); - - g_object_unref (res); + on_provider_discover, task); } GList * @@ -394,29 +352,12 @@ um_realm_manager_discover_finish (UmRealmManager *self, GAsyncResult *result, GError **error) { - GSimpleAsyncResult *async; - DiscoverClosure *discover; - GList *realms; - g_return_val_if_fail (UM_IS_REALM_MANAGER (self), NULL); - g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self), - um_realm_manager_discover), NULL); + g_return_val_if_fail (g_task_is_valid (result, G_OBJECT (self)), NULL); + g_return_val_if_fail (g_async_result_is_tagged (result, um_realm_manager_discover), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); - async = G_SIMPLE_ASYNC_RESULT (result); - if (g_simple_async_result_propagate_error (async, error)) - return NULL; - - discover = g_simple_async_result_get_op_res_gpointer (async); - if (!discover->realms) { - g_set_error (error, UM_REALM_ERROR, UM_REALM_ERROR_GENERIC, - _("No such domain or realm found")); - return NULL; - } - - realms = g_list_reverse (discover->realms); - discover->realms = NULL; - return realms; + return g_task_propagate_pointer (G_TASK (result), error); } GList * @@ -516,20 +457,6 @@ find_supported_credentials (UmRealmKerberosMembership *membership, return NULL; } -static void -on_realm_join_complete (GObject *source, - GAsyncResult *result, - gpointer user_data) -{ - GSimpleAsyncResult *async = G_SIMPLE_ASYNC_RESULT (user_data); - - g_debug ("Completed Join() method call"); - - g_simple_async_result_set_op_res_gpointer (async, g_object_ref (result), g_object_unref); - g_simple_async_result_complete_in_idle (async); - g_object_unref (async); -} - static gboolean realm_join_as_owner (UmRealmObject *realm, const gchar *owner, @@ -541,7 +468,6 @@ realm_join_as_owner (UmRealmObject *realm, gpointer user_data) { UmRealmKerberosMembership *membership; - GSimpleAsyncResult *async; GVariant *contents; GVariant *options; GVariant *option; @@ -558,9 +484,6 @@ realm_join_as_owner (UmRealmObject *realm, return FALSE; } - async = g_simple_async_result_new (G_OBJECT (realm), callback, user_data, - realm_join_as_owner); - if (g_str_equal (type, "ccache")) { g_debug ("Using a kerberos credential cache to join the realm"); contents = g_variant_new_from_data (G_VARIANT_TYPE ("ay"), @@ -583,10 +506,7 @@ realm_join_as_owner (UmRealmObject *realm, g_debug ("Calling the Join() method with %s credentials", owner); um_realm_kerberos_membership_call_join (membership, creds, options, - cancellable, on_realm_join_complete, - g_object_ref (async)); - - g_object_unref (async); + cancellable, callback, user_data); g_object_unref (membership); return TRUE; @@ -640,7 +560,6 @@ um_realm_join_finish (UmRealmObject *realm, UmRealmKerberosMembership *membership; GError *call_error = NULL; gchar *dbus_error; - GAsyncResult *async; g_return_val_if_fail (UM_REALM_IS_OBJECT (realm), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); @@ -648,12 +567,13 @@ um_realm_join_finish (UmRealmObject *realm, membership = um_realm_object_get_kerberos_membership (realm); g_return_val_if_fail (membership != NULL, FALSE); - async = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (result)); - um_realm_kerberos_membership_call_join_finish (membership, async, &call_error); + um_realm_kerberos_membership_call_join_finish (membership, result, &call_error); g_object_unref (membership); - if (call_error == NULL) + if (call_error == NULL) { + g_debug ("Completed Join() method call"); return TRUE; + } dbus_error = g_dbus_error_get_remote_error (call_error); if (dbus_error == NULL) { @@ -683,7 +603,6 @@ typedef struct { gchar *realm; gchar *user; gchar *password; - GBytes *credentials; } LoginClosure; static void @@ -694,7 +613,6 @@ login_closure_free (gpointer data) g_free (login->realm); g_free (login->user); g_free (login->password); - g_bytes_unref (login->credentials); g_slice_free (LoginClosure, login); } @@ -763,11 +681,12 @@ login_perform_kinit (krb5_context k5, } static void -kinit_thread_func (GSimpleAsyncResult *async, - GObject *object, +kinit_thread_func (GTask *task, + gpointer object, + gpointer task_data, GCancellable *cancellable) { - LoginClosure *login = g_simple_async_result_get_op_res_gpointer (async); + LoginClosure *login = task_data; krb5_context k5 = NULL; krb5_error_code code; GError *error = NULL; @@ -799,40 +718,41 @@ kinit_thread_func (GSimpleAsyncResult *async, if (filename != NULL) { g_file_get_contents (filename, &contents, &length, &error); if (error == NULL) { - login->credentials = g_bytes_new_take (contents, length); g_debug ("Read in credential cache: %s", filename); } else { g_warning ("Couldn't read credential cache: %s: %s", filename, error->message); g_error_free (error); } + + g_task_return_pointer (task, g_bytes_new_take (contents, length), (GDestroyNotify) g_bytes_unref); } break; case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN: case KRB5KDC_ERR_POLICY: - g_simple_async_result_set_error (async, UM_REALM_ERROR, UM_REALM_ERROR_BAD_LOGIN, - _("Cannot log in as %s at the %s domain"), - login->user, login->domain); + g_task_return_new_error (task, UM_REALM_ERROR, UM_REALM_ERROR_BAD_LOGIN, + _("Cannot log in as %s at the %s domain"), + login->user, login->domain); break; case KRB5KDC_ERR_PREAUTH_FAILED: case KRB5KRB_AP_ERR_BAD_INTEGRITY: - g_simple_async_result_set_error (async, UM_REALM_ERROR, UM_REALM_ERROR_BAD_PASSWORD, - _("Invalid password, please try again")); + g_task_return_new_error (task, UM_REALM_ERROR, UM_REALM_ERROR_BAD_PASSWORD, + _("Invalid password, please try again")); break; case KRB5_PREAUTH_FAILED: case KRB5KDC_ERR_KEY_EXP: case KRB5KDC_ERR_CLIENT_REVOKED: case KRB5KDC_ERR_ETYPE_NOSUPP: case KRB5_PROG_ETYPE_NOSUPP: - g_simple_async_result_set_error (async, UM_REALM_ERROR, UM_REALM_ERROR_CANNOT_AUTH, - _("Cannot log in as %s at the %s domain"), - login->user, login->domain); + g_task_return_new_error (task, UM_REALM_ERROR, UM_REALM_ERROR_CANNOT_AUTH, + _("Cannot log in as %s at the %s domain"), + login->user, login->domain); break; default: - g_simple_async_result_set_error (async, UM_REALM_ERROR, UM_REALM_ERROR_GENERIC, - _("Couldn’t connect to the %s domain: %s"), - login->domain, krb5_get_error_message (k5, code)); + g_task_return_new_error (task, UM_REALM_ERROR, UM_REALM_ERROR_GENERIC, + _("Couldn’t connect to the %s domain: %s"), + login->domain, krb5_get_error_message (k5, code)); break; } @@ -844,6 +764,8 @@ kinit_thread_func (GSimpleAsyncResult *async, if (k5) krb5_free_context (k5); + + g_object_unref (task); } void @@ -854,7 +776,7 @@ um_realm_login (UmRealmObject *realm, GAsyncReadyCallback callback, gpointer user_data) { - GSimpleAsyncResult *async; + GTask *task; LoginClosure *login; UmRealmKerberos *kerberos; @@ -866,46 +788,29 @@ um_realm_login (UmRealmObject *realm, kerberos = um_realm_object_get_kerberos (realm); g_return_if_fail (kerberos != NULL); - async = g_simple_async_result_new (NULL, callback, user_data, - um_realm_login); + task = g_task_new (NULL, cancellable, callback, user_data); + g_task_set_source_tag (task, um_realm_login); + login = g_slice_new0 (LoginClosure); login->domain = g_strdup (um_realm_kerberos_get_domain_name (kerberos)); login->realm = g_strdup (um_realm_kerberos_get_realm_name (kerberos)); login->user = g_strdup (user); login->password = g_strdup (password); - g_simple_async_result_set_op_res_gpointer (async, login, login_closure_free); + g_task_set_task_data (task, login, login_closure_free); - g_simple_async_result_set_handle_cancellation (async, TRUE); - g_simple_async_result_run_in_thread (async, kinit_thread_func, - G_PRIORITY_DEFAULT, cancellable); + g_task_set_return_on_cancel (task, TRUE); + g_task_run_in_thread (task, kinit_thread_func); - g_object_unref (async); g_object_unref (kerberos); } -gboolean +GBytes * um_realm_login_finish (GAsyncResult *result, - GBytes **credentials, GError **error) { - GSimpleAsyncResult *async; - LoginClosure *login; - - g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, - um_realm_login), FALSE); + g_return_val_if_fail (g_task_is_valid (result, NULL), FALSE); + g_return_val_if_fail (g_async_result_is_tagged (result, um_realm_login), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - async = G_SIMPLE_ASYNC_RESULT (result); - if (g_simple_async_result_propagate_error (async, error)) - return FALSE; - - login = g_simple_async_result_get_op_res_gpointer (async); - if (credentials) { - if (login->credentials) - *credentials = g_bytes_ref (login->credentials); - else - *credentials = NULL; - } - - return TRUE; + return g_task_propagate_pointer (G_TASK (result), error); } diff --git a/panels/user-accounts/um-realm-manager.h b/panels/user-accounts/um-realm-manager.h index 2bf61e6cb..34d67a635 100644 --- a/panels/user-accounts/um-realm-manager.h +++ b/panels/user-accounts/um-realm-manager.h @@ -70,8 +70,7 @@ void um_realm_login (UmRealmObject *realm, GAsyncReadyCallback callback, gpointer user_data); -gboolean um_realm_login_finish (GAsyncResult *result, - GBytes **credentials, +GBytes * um_realm_login_finish (GAsyncResult *result, GError **error); gboolean um_realm_join_as_user (UmRealmObject *realm, -- cgit v1.2.1 From 00a74afc20eb25477f785d90d70d02e687c99805 Mon Sep 17 00:00:00 2001 From: Jonathan Kang Date: Wed, 18 Apr 2018 16:55:10 +0800 Subject: sharing: set end margin for labels in Networks list box Currently if a network connection's name is long enough, there will be no space between the name label widget and the switch button widget next to it. Fix that by setting the end margin of label widget as 6 to keep some space between those two widgets. --- panels/sharing/cc-sharing-networks.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/panels/sharing/cc-sharing-networks.c b/panels/sharing/cc-sharing-networks.c index d97f811ea..672ac98d6 100644 --- a/panels/sharing/cc-sharing-networks.c +++ b/panels/sharing/cc-sharing-networks.c @@ -232,6 +232,7 @@ cc_sharing_networks_new_row (const char *uuid, /* Label */ w = gtk_label_new (network_name); + gtk_widget_set_margin_end (w, 12); gtk_container_add (GTK_CONTAINER (box), w); /* Remove button */ @@ -273,6 +274,7 @@ cc_sharing_networks_new_current_row (CcSharingNetworks *self) /* Label */ w = gtk_label_new (""); gtk_container_add (GTK_CONTAINER (box), w); + gtk_widget_set_margin_end (w, 12); self->priv->current_label = w; w = gtk_switch_new (); -- cgit v1.2.1 From 256b4a45c0ffd11cd54e80f09d20c6d7d17202be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20=C8=98erb=C4=83nescu?= Date: Mon, 30 Apr 2018 05:59:15 +0000 Subject: Update Romanian translation --- po/ro.po | 364 +++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 282 insertions(+), 82 deletions(-) diff --git a/po/ro.po b/po/ro.po index edeb16369..2acd53354 100644 --- a/po/ro.po +++ b/po/ro.po @@ -17,9 +17,10 @@ msgstr "" "Project-Id-Version: gnome-control-center\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-control-center/" "issues\n" -"POT-Creation-Date: 2018-04-13 14:19+0000\n" -"PO-Revision-Date: 2018-04-18 13:30+0300\n" -"Last-Translator: Florentina Mușat \n" +"POT-Creation-Date: 2018-04-26 16:26+0000\n" +"PO-Revision-Date: 2018-04-27 00:50+0300\n" +"Last-Translator: Florentina Mușat \n" "Language-Team: Gnome Romanian Translation Team\n" "Language: ro\n" "MIME-Version: 1.0\n" @@ -27,7 +28,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " "20)) ? 1 : 2);\n" -"X-Generator: Poedit 2.0.6\n" +"X-Generator: Poedit 2.0.7\n" "X-Launchpad-Export-Date: 2014-07-13 17:08+0000\n" "X-Project-Style: gnome\n" @@ -122,7 +123,7 @@ msgstr "Puteți adăuga imagini în directorul %s și acestea vor fi afișate ai #: panels/network/net-device-wifi.c:1411 panels/network/net-device-wifi.c:1491 #: panels/network/net-device-wifi.c:1736 panels/network/network-wifi.ui:24 #: panels/printers/new-printer-dialog.ui:45 -#: panels/printers/pp-details-dialog.c:331 +#: panels/printers/pp-details-dialog.c:330 #: panels/privacy/cc-privacy-panel.c:1053 panels/region/format-chooser.ui:25 #: panels/region/input-chooser.ui:13 #: panels/search/cc-search-locations-dialog.c:642 @@ -924,6 +925,12 @@ msgstr "%b %e" msgid "%b %e, %Y" msgstr "%b %e, %Y" +#. translators: This is the default hotspot name, need to be less than 32-bytes +#: panels/common/hostname-helper.c:189 +msgctxt "hotspot" +msgid "Hotspot" +msgstr "Hotspot" + #: panels/common/language-chooser.ui:5 msgid "Language" msgstr "Limba" @@ -1221,7 +1228,7 @@ msgstr "%.2lf Hz" #. TRANSLATORS: the state of the night light setting #: panels/display/cc-display-panel.c:3219 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:2012 panels/power/cc-power-panel.c:2019 +#: panels/power/cc-power-panel.c:2097 panels/power/cc-power-panel.c:2104 #: panels/privacy/cc-privacy-panel.c:191 panels/privacy/cc-privacy-panel.c:258 #: panels/universal-access/cc-ua-panel.c:334 #: panels/universal-access/cc-ua-panel.c:715 @@ -1233,7 +1240,7 @@ msgstr "Pornit" #: panels/display/cc-display-panel.c:3219 panels/network/net-proxy.c:54 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:2006 panels/power/cc-power-panel.c:2017 +#: panels/power/cc-power-panel.c:2091 panels/power/cc-power-panel.c:2102 #: panels/privacy/cc-privacy-panel.c:191 panels/privacy/cc-privacy-panel.c:258 #: panels/universal-access/cc-ua-panel.c:334 #: panels/universal-access/cc-ua-panel.c:715 @@ -2625,7 +2632,7 @@ msgid "Select file to import" msgstr "Selectează fișierul de importat" #: panels/network/connection-editor/vpn-helpers.c:182 -#: panels/printers/pp-details-dialog.c:332 +#: panels/printers/pp-details-dialog.c:331 #: panels/sharing/cc-sharing-panel.c:385 #: panels/user-accounts/um-photo-dialog.c:231 msgid "_Open" @@ -4001,146 +4008,190 @@ msgid "Gaming input device" msgstr "Dispozitiv de intrare pentru jocuri" #. TRANSLATORS: secondary battery, misc -#: panels/power/cc-power-panel.c:565 panels/power/cc-power-panel.c:805 -#: panels/power/cc-power-panel.c:2398 +#: panels/power/cc-power-panel.c:565 panels/power/cc-power-panel.c:829 +#: panels/power/cc-power-panel.c:2483 msgid "Battery" msgstr "Baterie" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:619 +#: panels/power/cc-power-panel.c:632 msgctxt "Battery power" msgid "Charging" msgstr "Se încarcă" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:626 +#: panels/power/cc-power-panel.c:639 msgctxt "Battery power" msgid "Caution" msgstr "Atenție" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:631 +#: panels/power/cc-power-panel.c:644 msgctxt "Battery power" msgid "Low" msgstr "Scăzută" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:636 +#: panels/power/cc-power-panel.c:649 msgctxt "Battery power" msgid "Good" msgstr "Bună" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:641 +#: panels/power/cc-power-panel.c:654 msgctxt "Battery power" msgid "Fully charged" msgstr "Complet încărcat" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:645 +#: panels/power/cc-power-panel.c:658 msgctxt "Battery power" msgid "Empty" msgstr "Descărcată complet" -#: panels/power/cc-power-panel.c:803 +#: panels/power/cc-power-panel.c:827 msgid "Batteries" msgstr "Baterii" -#: panels/power/cc-power-panel.c:1243 +#: panels/power/cc-power-panel.c:1206 +#, c-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d oră" +msgstr[1] "%d ore" +msgstr[2] "%d de ore" + +#: panels/power/cc-power-panel.c:1208 +#, c-format +msgid "%d minute" +msgid_plural "%d minutes" +msgstr[0] "%d minut" +msgstr[1] "%d minute" +msgstr[2] "%d de minute" + +#: panels/power/cc-power-panel.c:1211 +#, c-format +msgid "%d second" +msgid_plural "%d seconds" +msgstr[0] "%d secundă" +msgstr[1] "%d secunde" +msgstr[2] "%d de secunde" + +#. 5 hours 2 minutes 12 seconds +#: panels/power/cc-power-panel.c:1217 +#, c-format +msgctxt "time" +msgid "%s %s %s" +msgstr "%s %s %s" + +#. 2 minutes 12 seconds +#: panels/power/cc-power-panel.c:1220 +#, c-format +msgctxt "time" +msgid "%s %s" +msgstr "%s %s" + +#. 0 seconds +#: panels/power/cc-power-panel.c:1226 +msgid "0 seconds" +msgstr "0 secunde" + +#: panels/power/cc-power-panel.c:1328 msgid "When _idle" msgstr "Când e _inactiv" -#: panels/power/cc-power-panel.c:1708 +#: panels/power/cc-power-panel.c:1793 msgid "Power Saving" msgstr "Economisire de energie" -#: panels/power/cc-power-panel.c:1739 +#: panels/power/cc-power-panel.c:1824 msgid "_Screen brightness" msgstr "Luminozitate ec_ran" -#: panels/power/cc-power-panel.c:1758 +#: panels/power/cc-power-panel.c:1843 msgid "Automatic brightness" msgstr "Luminozitate automată" -#: panels/power/cc-power-panel.c:1778 +#: panels/power/cc-power-panel.c:1863 msgid "_Keyboard brightness" msgstr "Luminozitate _tastatură" -#: panels/power/cc-power-panel.c:1788 +#: panels/power/cc-power-panel.c:1873 msgid "_Dim screen when inactive" msgstr "_Diminuează luminozitatea la inactivitate" -#: panels/power/cc-power-panel.c:1813 +#: panels/power/cc-power-panel.c:1898 msgid "_Blank screen" msgstr "Ecran _gol" -#: panels/power/cc-power-panel.c:1850 +#: panels/power/cc-power-panel.c:1935 msgid "_Wi-Fi" msgstr "_Wi-Fi" -#: panels/power/cc-power-panel.c:1855 +#: panels/power/cc-power-panel.c:1940 msgid "Turn off Wi-Fi to save power." msgstr "Închide Wi-Fi pentru a economisi energia." -#: panels/power/cc-power-panel.c:1880 +#: panels/power/cc-power-panel.c:1965 msgid "_Mobile broadband" msgstr "Internet _mobil de bandă largă" -#: panels/power/cc-power-panel.c:1885 +#: panels/power/cc-power-panel.c:1970 msgid "Turn off mobile broadband (3G, 4G, LTE, etc.) to save power." msgstr "" "Închide internetul mobil (3G, 4G, LTE, etc.) pentru a economisi energie." -#: panels/power/cc-power-panel.c:1944 +#: panels/power/cc-power-panel.c:2029 msgid "_Bluetooth" msgstr "_Bluetooth" -#: panels/power/cc-power-panel.c:1949 +#: panels/power/cc-power-panel.c:2034 msgid "Turn off Bluetooth to save power." msgstr "Închide Bluetooth pentru a economisi energia." -#: panels/power/cc-power-panel.c:2008 +#: panels/power/cc-power-panel.c:2093 msgid "When on battery power" msgstr "Când funcționează pe baterie" -#: panels/power/cc-power-panel.c:2010 +#: panels/power/cc-power-panel.c:2095 msgid "When plugged in" msgstr "Alimentat de la rețea" -#: panels/power/cc-power-panel.c:2105 +#: panels/power/cc-power-panel.c:2190 msgid "Suspend" msgstr "Suspendă" -#: panels/power/cc-power-panel.c:2106 +#: panels/power/cc-power-panel.c:2191 msgid "Power Off" msgstr "Oprește" -#: panels/power/cc-power-panel.c:2107 +#: panels/power/cc-power-panel.c:2192 msgid "Hibernate" msgstr "Hibernează" -#: panels/power/cc-power-panel.c:2108 +#: panels/power/cc-power-panel.c:2193 msgid "Nothing" msgstr "Nimic" #. Frame header -#: panels/power/cc-power-panel.c:2222 +#: panels/power/cc-power-panel.c:2307 msgid "Suspend & Power Button" msgstr "Buton de suspendare și oprire" -#: panels/power/cc-power-panel.c:2261 +#: panels/power/cc-power-panel.c:2346 msgid "_Automatic suspend" msgstr "Suspendare _automată" -#: panels/power/cc-power-panel.c:2262 +#: panels/power/cc-power-panel.c:2347 msgid "Automatic suspend" msgstr "Suspendare automată" -#: panels/power/cc-power-panel.c:2329 +#: panels/power/cc-power-panel.c:2414 msgid "_When the Power Button is pressed" msgstr "_Când butonul de oprire este apăsat" -#: panels/power/cc-power-panel.c:2448 shell/cc-window.c:233 +#: panels/power/cc-power-panel.c:2533 panels/thunderbolt/cc-bolt-panel.ui:466 +#: panels/thunderbolt/cc-bolt-panel.ui:525 shell/cc-window.c:233 #: shell/panel-list.ui:45 msgid "Devices" msgstr "Dispozitive" @@ -4398,21 +4449,21 @@ msgid "Test Page" msgstr "Pagină de test" #. Translators: This is the title of the dialog. %s is the printer name. -#: panels/printers/pp-details-dialog.c:135 -#: panels/printers/pp-details-dialog.c:435 +#: panels/printers/pp-details-dialog.c:134 +#: panels/printers/pp-details-dialog.c:434 #, c-format msgid "%s Details" msgstr "Detalii %s" -#: panels/printers/pp-details-dialog.c:184 +#: panels/printers/pp-details-dialog.c:183 msgid "No suitable driver found" msgstr "Nu s-a găsit un driver potrivit" -#: panels/printers/pp-details-dialog.c:328 +#: panels/printers/pp-details-dialog.c:327 msgid "Select PPD File" msgstr "Specificați fișierul PPD" -#: panels/printers/pp-details-dialog.c:337 +#: panels/printers/pp-details-dialog.c:336 msgid "" "PostScript Printer Description files (*.ppd, *.PPD, *.ppd.gz, *.PPD.gz, *." "PPD.GZ)" @@ -5805,6 +5856,174 @@ msgstr "Subwoofer" msgid "Custom" msgstr "Personalizat" +#: panels/thunderbolt/cc-bolt-device-dialog.c:86 +#: panels/thunderbolt/cc-bolt-device-entry.c:119 +msgctxt "Thunderbolt Device Status" +msgid "Disconnected" +msgstr "Deconectat" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:89 +#: panels/thunderbolt/cc-bolt-device-entry.c:122 +msgctxt "Thunderbolt Device Status" +msgid "Connecting" +msgstr "Se conectează" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:92 +#: panels/thunderbolt/cc-bolt-device-entry.c:126 +#: panels/thunderbolt/cc-bolt-device-entry.c:138 +msgctxt "Thunderbolt Device Status" +msgid "Connected" +msgstr "Conectat" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:95 +msgctxt "Thunderbolt Device Status" +msgid "Authorization Error" +msgstr "Eroare de autorizare" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:98 +#: panels/thunderbolt/cc-bolt-device-entry.c:132 +msgctxt "Thunderbolt Device Status" +msgid "Authorizing" +msgstr "Autorizare" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:105 +msgctxt "Thunderbolt Device Status" +msgid "Reduced Functionality" +msgstr "Funcționalitate redusă" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:107 +msgctxt "Thunderbolt Device Status" +msgid "Connected & Authorized" +msgstr "Conectat și autorizat" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:113 +#: panels/thunderbolt/cc-bolt-device-entry.c:146 +msgctxt "Thunderbolt Device Status" +msgid "Unknown" +msgstr "Necunoscut" + +#. Translators: The time point the device was authorized. +#: panels/thunderbolt/cc-bolt-device-dialog.c:169 +msgid "Authorized at:" +msgstr "Autorizat la:" + +#. Translators: The time point the device was connected. +#: panels/thunderbolt/cc-bolt-device-dialog.c:175 +msgid "Connected at:" +msgstr "Conectat la:" + +#. Translators: The time point the device was enrolled, +#. * i.e. authorized and stored in the device database. +#: panels/thunderbolt/cc-bolt-device-dialog.c:182 +msgid "Enrolled at:" +msgstr "Înscris la:" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:250 +msgid "Failed to authorize device: " +msgstr "Nu s-a putut autoriza dispozitivul: " + +#: panels/thunderbolt/cc-bolt-device-dialog.c:327 +msgid "Failed to forget device: " +msgstr "Nu s-a putut uita dispozitivul: " + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:109 +msgid "Name:" +msgstr "Nume:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:141 +msgid "Status:" +msgstr "Stare:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:174 +msgid "UUID:" +msgstr "UUID:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:280 +msgid "Authorize and Connect" +msgstr "Autorizează și conectează" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:303 +msgid "Forget Device" +msgstr "Uită dispozitivul" + +#: panels/thunderbolt/cc-bolt-device-entry.c:129 +msgctxt "Thunderbolt Device Status" +msgid "Error" +msgstr "Eroare" + +#: panels/thunderbolt/cc-bolt-device-entry.c:140 +msgctxt "Thunderbolt Device Status" +msgid "Authorized" +msgstr "Autorizat" + +#: panels/thunderbolt/cc-bolt-panel.c:175 +msgid "" +"The Thunderbolt subsystem (boltd) is not installed or not set up properly." +msgstr "" +"Subsistemul Thunderbolt (boltd) nu este instalat sau configurat corect." + +#: panels/thunderbolt/cc-bolt-panel.c:460 +msgid "" +"Thunderbolt could not be detected.\n" +"Either the system lacks Thunderbolt support, it has been disabled in the " +"BIOS or is set to an unsupported security level in the BIOS." +msgstr "" +"Nu s-a putut detecta Thunderbolt.\n" +"Fie sistemul nu are suport pentru Thunderbolt, a fost dezactivat în BIOS sau " +"este stabilit la un nivel de securitate nesuportat în BIOS." + +#: panels/thunderbolt/cc-bolt-panel.c:504 +msgid "Thunderbolt support has been disabled in the BIOS." +msgstr "Suportul pentru Thunderbolt a fost dezactivat în BIOS." + +#: panels/thunderbolt/cc-bolt-panel.c:613 +#, c-format +msgid "Error switching direct mode: %s" +msgstr "Eroare la comutarea modului direct: %s" + +#: panels/thunderbolt/cc-bolt-panel.ui:143 +msgid "No Thunderbolt support" +msgstr "Nu este suport pentru Thunderbolt" + +#: panels/thunderbolt/cc-bolt-panel.ui:246 +msgid "Direct Access" +msgstr "Acces direct" + +#: panels/thunderbolt/cc-bolt-panel.ui:269 +msgid "Allow direct access to devices such as docks and external GPUs." +msgstr "" +"Permite accesul direct la dispozitive precum docurile și GPU-urile externe." + +#: panels/thunderbolt/cc-bolt-panel.ui:289 +msgid "Only USB and Display Port devices can attach." +msgstr "Doar dispozitivele USB sau port de afișaj pot atașa." + +#: panels/thunderbolt/cc-bolt-panel.ui:397 +msgid "Pending Devices" +msgstr "Dispozitive în așteptare" + +#: panels/thunderbolt/cc-bolt-panel.ui:535 +msgid "No devices attached" +msgstr "Nu sunt dispozitive atașate" + +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:3 +msgid "Thunderbolt" +msgstr "Thunderbolt" + +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:4 +msgid "Manage Thunderbolt devices" +msgstr "Administrează dispozitive Thunderbolt" + +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:7 +msgid "thunderbolt" +msgstr "thunderbolt" + +#. Translators: those are keywords for the thunderbolt control-center panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:19 +msgid "Thunderbolt;" +msgstr "Thunderbolt;" + #. translators: the labels will read: #. * Cursor Size: Default #: panels/universal-access/cc-ua-panel.c:354 @@ -6767,29 +6986,29 @@ msgstr "Eroare necunoscută" msgid "Should match the web address of your login provider." msgstr "Trebuie să potriviți adresele web a furnizorului de logare." -#: panels/user-accounts/um-account-dialog.c:229 +#: panels/user-accounts/um-account-dialog.c:228 msgid "Failed to add account" msgstr "Eșec la adăugarea contului" -#: panels/user-accounts/um-account-dialog.c:462 +#: panels/user-accounts/um-account-dialog.c:461 msgid "Passwords do not match." msgstr "Parolele nu se potrivesc." -#: panels/user-accounts/um-account-dialog.c:717 -#: panels/user-accounts/um-account-dialog.c:763 -#: panels/user-accounts/um-account-dialog.c:784 +#: panels/user-accounts/um-account-dialog.c:716 +#: panels/user-accounts/um-account-dialog.c:762 +#: panels/user-accounts/um-account-dialog.c:783 msgid "Failed to register account" msgstr "Eșec la înregistrarea contului" -#: panels/user-accounts/um-account-dialog.c:907 +#: panels/user-accounts/um-account-dialog.c:906 msgid "No supported way to authenticate with this domain" msgstr "Nici o metodă suportată pentru autentificarea cu acest domeniu" -#: panels/user-accounts/um-account-dialog.c:980 +#: panels/user-accounts/um-account-dialog.c:979 msgid "Failed to join domain" msgstr "Eșec la înregistrarea domeniului" -#: panels/user-accounts/um-account-dialog.c:1041 +#: panels/user-accounts/um-account-dialog.c:1040 msgid "" "That login name didn’t work.\n" "Please try again." @@ -6797,7 +7016,7 @@ msgstr "" "Numele de autentificare nu a funcționat.\n" "Încercați din nou." -#: panels/user-accounts/um-account-dialog.c:1048 +#: panels/user-accounts/um-account-dialog.c:1047 msgid "" "That login password didn’t work.\n" "Please try again." @@ -6805,11 +7024,11 @@ msgstr "" "Parola de autentificare nu a funcționat.\n" "Încercați din nou." -#: panels/user-accounts/um-account-dialog.c:1056 +#: panels/user-accounts/um-account-dialog.c:1055 msgid "Failed to log into domain" msgstr "Eșec la conectarea în domeniu" -#: panels/user-accounts/um-account-dialog.c:1114 +#: panels/user-accounts/um-account-dialog.c:1113 msgid "Unable to find the domain. Maybe you misspelled it?" msgstr "Nu se poate găsi domeniul. Poate l-ați scris greșit?" @@ -6994,26 +7213,25 @@ msgstr "Parolele nu se potrivesc." msgid "Browse for more pictures" msgstr "Răsfoiește pentru mai multe imagini" -#: panels/user-accounts/um-realm-manager.c:350 +#: panels/user-accounts/um-realm-manager.c:310 msgid "Cannot automatically join this type of domain" msgstr "Nu se poate conecta automat la acest tip de domeniu" -#: panels/user-accounts/um-realm-manager.c:413 -#, c-format +#: panels/user-accounts/um-realm-manager.c:313 msgid "No such domain or realm found" msgstr "Nu este găsit niciun domeniu și nicio valoare reală" -#: panels/user-accounts/um-realm-manager.c:815 -#: panels/user-accounts/um-realm-manager.c:829 +#: panels/user-accounts/um-realm-manager.c:735 +#: panels/user-accounts/um-realm-manager.c:749 #, c-format msgid "Cannot log in as %s at the %s domain" msgstr "Nu se poate realiza conectarea ca %s în domeniul %s" -#: panels/user-accounts/um-realm-manager.c:821 +#: panels/user-accounts/um-realm-manager.c:741 msgid "Invalid password, please try again" msgstr "Parola nu este validă, încercați din nou" -#: panels/user-accounts/um-realm-manager.c:834 +#: panels/user-accounts/um-realm-manager.c:754 #, c-format msgid "Couldn’t connect to the %s domain: %s" msgstr "Nu se poate realiza conectarea la domeniul %s: %s" @@ -7494,12 +7712,6 @@ msgctxt "shortcut window" msgid "Cancel search" msgstr "Anulează căutarea" -#. translators: This is the default hotspot name, need to be less than 32-bytes -#: shell/hostname-helper.c:189 -msgctxt "hotspot" -msgid "Hotspot" -msgstr "Hotspot" - #: shell/org.gnome.ControlCenter.gschema.xml:5 msgid "The identifier for the last Settings panel to be opened" msgstr "Identificatorul ultimului panou de configurări de deschis" @@ -7722,12 +7934,6 @@ msgstr "Sunete de sistem" #~ msgid "_Method" #~ msgstr "_Metodă" -#~ msgid "Add Device" -#~ msgstr "Adaugă dispozitiv" - -#~ msgid "Remove Device" -#~ msgstr "Șterge dispozitiv" - #~ msgid "VPN Type" #~ msgstr "Tip de VPN" @@ -7749,9 +7955,6 @@ msgstr "Sunete de sistem" #~ msgid "Shortcut;Repeat;Blink;" #~ msgstr "Shortcut;Repeat;Blink;Scurtatură;" -#~ msgid "_Name:" -#~ msgstr "_Nume:" - #~ msgid "Add Shortcut" #~ msgstr "Adaugă scurtătură" @@ -8750,9 +8953,6 @@ msgstr "Sunete de sistem" #~ msgid "Mesh" #~ msgstr "Mesh" -#~ msgid "Disconnected" -#~ msgstr "Deconectat" - #~ msgid "Power management settings" #~ msgstr "Configurări administrare consum" -- cgit v1.2.1 From f547d9129d6d69c0eacd24cef7cda7eca09d6106 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Wed, 25 Apr 2018 10:32:10 +0200 Subject: shell: Only try to select an existing panel on startup When selecting the panel on startup based on the "last-panel" settings, we need to make sure that the panel exists. Note that this is a special case which does not use the internal set_active_panel_from_id API. Using it is currently not possible because the API does not report back the error and we would end up not selecting any panel. --- shell/cc-shell-model.c | 24 ++++++++++++++++++++++++ shell/cc-shell-model.h | 3 +++ shell/cc-window.c | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/shell/cc-shell-model.c b/shell/cc-shell-model.c index 55f3e3c82..2a69d6a12 100644 --- a/shell/cc-shell-model.c +++ b/shell/cc-shell-model.c @@ -327,6 +327,30 @@ cc_shell_model_add_item (CcShellModel *model, g_strfreev (keywords); } +gboolean +cc_shell_model_has_panel (CcShellModel *model, + const char *id) +{ + GtkTreeIter iter; + gboolean valid; + + g_assert (id); + + valid = gtk_tree_model_get_iter_first (model, &iter); + while (valid) + { + g_autofree gchar *panel_id = NULL; + + gtk_tree_model_get (model, &iter, COL_ID, &panel_id, -1); + if (g_str_equal (id, panel_id)) + return TRUE; + + valid = gtk_tree_model_iter_next (model, &iter); + } + + return FALSE; +} + gboolean cc_shell_model_iter_matches_search (CcShellModel *model, GtkTreeIter *iter, diff --git a/shell/cc-shell-model.h b/shell/cc-shell-model.h index 259407109..4ba8342e5 100644 --- a/shell/cc-shell-model.h +++ b/shell/cc-shell-model.h @@ -98,6 +98,9 @@ void cc_shell_model_add_item (CcShellModel *model, GAppInfo *appinfo, const char *id); +gboolean cc_shell_model_has_panel (CcShellModel *model, + const char *id); + gboolean cc_shell_model_iter_matches_search (CcShellModel *model, GtkTreeIter *iter, const char *term); diff --git a/shell/cc-window.c b/shell/cc-window.c index c0fc19446..c05712475 100644 --- a/shell/cc-window.c +++ b/shell/cc-window.c @@ -756,7 +756,7 @@ cc_window_init (CcWindow *self) /* After everything is loaded, select the last used panel, if any, * or the first visible panel */ id = g_settings_get_string (self->settings, "last-panel"); - if (id != NULL && *id != '\0') + if (id != NULL && cc_shell_model_has_panel (self->store, id)) cc_panel_list_set_active_panel (CC_PANEL_LIST (self->panel_list), id); else cc_panel_list_activate (CC_PANEL_LIST (self->panel_list)); -- cgit v1.2.1 From ec50cbcdff340fbb97ab50916c9e225273be2aa9 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Wed, 28 Mar 2018 01:35:28 +0200 Subject: network: Ensure devices are removed from UI when disappearing The "removed" callback from NMObject is never called when the object is simply finalised because the UI drops the reference. Explicitly call the handler so that UI elements are removed. --- panels/network/cc-network-panel.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/panels/network/cc-network-panel.c b/panels/network/cc-network-panel.c index 405b538cf..a03ab56da 100644 --- a/panels/network/cc-network-panel.c +++ b/panels/network/cc-network-panel.c @@ -556,6 +556,8 @@ panel_remove_device (CcNetworkPanel *panel, NMDevice *device) if (object == NULL) return; + /* NMObject will not fire the "removed" signal, so handle the UI removal explicitly */ + object_removed_cb (object, panel); g_ptr_array_remove (panel->devices, object); /* update vpn widgets */ -- cgit v1.2.1 From e91266a8f0643de1166bc81431e0c7bb22782614 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Wed, 28 Mar 2018 01:36:52 +0200 Subject: network: Fix crash on connection change after device removal When a device is removed the callback handler could still be called because it was connected using g_signal_connect rather than g_signal_connect_object. This fixes crashes in the UI after a device has been removed again. --- panels/network/net-device-ethernet.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/panels/network/net-device-ethernet.c b/panels/network/net-device-ethernet.c index 0412facaf..afb544352 100644 --- a/panels/network/net-device-ethernet.c +++ b/panels/network/net-device-ethernet.c @@ -551,8 +551,8 @@ device_ethernet_constructed (GObject *object) G_CALLBACK (add_profile), device); client = net_object_get_client (NET_OBJECT (object)); - g_signal_connect (client, NM_CLIENT_CONNECTION_ADDED, - G_CALLBACK (client_connection_added_cb), object); + g_signal_connect_object (client, NM_CLIENT_CONNECTION_ADDED, + G_CALLBACK (client_connection_added_cb), object, 0); g_signal_connect_object (client, NM_CLIENT_CONNECTION_REMOVED, G_CALLBACK (connection_removed), device, 0); -- cgit v1.2.1 From aec8c911bb039769c0058695664f9c564a291cb6 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 17 Apr 2018 17:58:55 +0200 Subject: shell: Add static shell library for testing purposes Export shell functionality which panels may require for testing purposes into a static library. --- shell/meson.build | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/shell/meson.build b/shell/meson.build index 942595127..241b140ca 100644 --- a/shell/meson.build +++ b/shell/meson.build @@ -119,5 +119,27 @@ libpanel_loader = static_library( c_args: cflags + ['-DCC_PANEL_LOADER_NO_GTYPES'] ) +# libshell_test +sources = files( + 'cc-panel.c', + 'cc-shell.c', + 'cc-log.c', + 'cc-object-storage.c', +) +libtestshell = static_library( + 'testshell', + sources, + include_directories: top_inc, + dependencies: common_deps + [ libwidgets_dep ], + c_args: cflags, + link_with: panels_libs +) +libtestshell_dep = declare_dependency( + include_directories: top_inc, + link_with: libtestshell +) +libtestshell_deps = common_deps + [ libwidgets_dep, libtestshell_dep ] + + install_data ('org.gnome.ControlCenter.gschema.xml', install_dir: control_center_schemadir) -- cgit v1.2.1 From 2ebdb532cf3b82ec4a683faaa1c1cc8ad8138404 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Wed, 4 Apr 2018 11:58:54 +0200 Subject: tests/network: Copy files from network manager for network panel testing This copies a number of files from network manager in preparation of adding network panel tests. --- tests/network/nm-utils/README | 17 + tests/network/nm-utils/gsystem-local-alloc.h | 208 +++ tests/network/nm-utils/nm-dbus-compat.h | 74 ++ tests/network/nm-utils/nm-default.h | 316 +++++ tests/network/nm-utils/nm-glib.h | 125 ++ tests/network/nm-utils/nm-hash-utils.h | 0 tests/network/nm-utils/nm-macros-internal.h | 1384 ++++++++++++++++++++ tests/network/nm-utils/nm-shared-utils.h | 0 tests/network/nm-utils/nm-test-libnm-utils.h | 105 ++ tests/network/nm-utils/nm-test-utils-impl.c | 457 +++++++ tests/network/nm-utils/nm-test-utils.h | 0 .../nm-utils/test-networkmanager-service.py | 1341 +++++++++++++++++++ 12 files changed, 4027 insertions(+) create mode 100644 tests/network/nm-utils/README create mode 100644 tests/network/nm-utils/gsystem-local-alloc.h create mode 100644 tests/network/nm-utils/nm-dbus-compat.h create mode 100644 tests/network/nm-utils/nm-default.h create mode 100644 tests/network/nm-utils/nm-glib.h create mode 100644 tests/network/nm-utils/nm-hash-utils.h create mode 100644 tests/network/nm-utils/nm-macros-internal.h create mode 100644 tests/network/nm-utils/nm-shared-utils.h create mode 100644 tests/network/nm-utils/nm-test-libnm-utils.h create mode 100644 tests/network/nm-utils/nm-test-utils-impl.c create mode 100644 tests/network/nm-utils/nm-test-utils.h create mode 100755 tests/network/nm-utils/test-networkmanager-service.py diff --git a/tests/network/nm-utils/README b/tests/network/nm-utils/README new file mode 100644 index 000000000..2b613ed5e --- /dev/null +++ b/tests/network/nm-utils/README @@ -0,0 +1,17 @@ +These files are either copied from NetworkManager or just empty files. The +files live in the nn-utils subdirectory as that makes the relative +includes that they contain work fine. + +The test-networkmanager-service.py is also from NetworkManager. It is +however extended for our use here. + +gsystem-local-alloc.h: shared/nm-utils/gsystem-local-alloc.h +nm-glib.h: shared/nm-utils/nm-glib.h +nm-macros-internal.h: shared/nm-utils/nm-macros-internal.h +nm-default.h: shared/nm-default.h +nm-dbus-compat.h: shared/nm-dbus-compat.h +nm-default.h: shared/nm-default.h +nm-test-utils-impl.c: shared/nm-test-utils-impl.c +nm-shared-utils.h: empty +nm-test-libnm-utils.h: empty +nm-hash-utils.h: empty diff --git a/tests/network/nm-utils/gsystem-local-alloc.h b/tests/network/nm-utils/gsystem-local-alloc.h new file mode 100644 index 000000000..51b625197 --- /dev/null +++ b/tests/network/nm-utils/gsystem-local-alloc.h @@ -0,0 +1,208 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- + * + * Copyright (C) 2012 Colin Walters . + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GSYSTEM_LOCAL_ALLOC_H__ +#define __GSYSTEM_LOCAL_ALLOC_H__ + +#include + +G_BEGIN_DECLS + +#define GS_DEFINE_CLEANUP_FUNCTION(Type, name, func) \ + static inline void name (void *v) \ + { \ + func (*(Type*)v); \ + } + +#define GS_DEFINE_CLEANUP_FUNCTION0(Type, name, func) \ + static inline void name (void *v) \ + { \ + if (*(Type*)v) \ + func (*(Type*)v); \ + } + +/* These functions shouldn't be invoked directly; + * they are stubs that: + * 1) Take a pointer to the location (typically itself a pointer). + * 2) Provide %NULL-safety where it doesn't exist already (e.g. g_object_unref) + */ + +/** + * gs_free: + * + * Call g_free() on a variable location when it goes out of scope. + */ +#define gs_free __attribute__ ((cleanup(gs_local_free))) +GS_DEFINE_CLEANUP_FUNCTION(void*, gs_local_free, g_free) + +/** + * gs_unref_object: + * + * Call g_object_unref() on a variable location when it goes out of + * scope. Note that unlike g_object_unref(), the variable may be + * %NULL. + */ +#define gs_unref_object __attribute__ ((cleanup(gs_local_obj_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GObject*, gs_local_obj_unref, g_object_unref) + +/** + * gs_unref_variant: + * + * Call g_variant_unref() on a variable location when it goes out of + * scope. Note that unlike g_variant_unref(), the variable may be + * %NULL. + */ +#define gs_unref_variant __attribute__ ((cleanup(gs_local_variant_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GVariant*, gs_local_variant_unref, g_variant_unref) + +/** + * gs_free_variant_iter: + * + * Call g_variant_iter_free() on a variable location when it goes out of + * scope. + */ +#define gs_free_variant_iter __attribute__ ((cleanup(gs_local_variant_iter_free))) +GS_DEFINE_CLEANUP_FUNCTION0(GVariantIter*, gs_local_variant_iter_free, g_variant_iter_free) + +/** + * gs_free_variant_builder: + * + * Call g_variant_builder_unref() on a variable location when it goes out of + * scope. + */ +#define gs_unref_variant_builder __attribute__ ((cleanup(gs_local_variant_builder_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GVariantBuilder*, gs_local_variant_builder_unref, g_variant_builder_unref) + +/** + * gs_unref_array: + * + * Call g_array_unref() on a variable location when it goes out of + * scope. Note that unlike g_array_unref(), the variable may be + * %NULL. + + */ +#define gs_unref_array __attribute__ ((cleanup(gs_local_array_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GArray*, gs_local_array_unref, g_array_unref) + +/** + * gs_unref_ptrarray: + * + * Call g_ptr_array_unref() on a variable location when it goes out of + * scope. Note that unlike g_ptr_array_unref(), the variable may be + * %NULL. + + */ +#define gs_unref_ptrarray __attribute__ ((cleanup(gs_local_ptrarray_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GPtrArray*, gs_local_ptrarray_unref, g_ptr_array_unref) + +/** + * gs_unref_hashtable: + * + * Call g_hash_table_unref() on a variable location when it goes out + * of scope. Note that unlike g_hash_table_unref(), the variable may + * be %NULL. + */ +#define gs_unref_hashtable __attribute__ ((cleanup(gs_local_hashtable_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GHashTable*, gs_local_hashtable_unref, g_hash_table_unref) + +/** + * gs_free_list: + * + * Call g_list_free() on a variable location when it goes out + * of scope. + */ +#define gs_free_list __attribute__ ((cleanup(gs_local_free_list))) +GS_DEFINE_CLEANUP_FUNCTION(GList*, gs_local_free_list, g_list_free) + +/** + * gs_free_slist: + * + * Call g_slist_free() on a variable location when it goes out + * of scope. + */ +#define gs_free_slist __attribute__ ((cleanup(gs_local_free_slist))) +GS_DEFINE_CLEANUP_FUNCTION(GSList*, gs_local_free_slist, g_slist_free) + +/** + * gs_free_checksum: + * + * Call g_checksum_free() on a variable location when it goes out + * of scope. Note that unlike g_checksum_free(), the variable may + * be %NULL. + */ +#define gs_free_checksum __attribute__ ((cleanup(gs_local_checksum_free))) +GS_DEFINE_CLEANUP_FUNCTION0(GChecksum*, gs_local_checksum_free, g_checksum_free) + +/** + * gs_unref_bytes: + * + * Call g_bytes_unref() on a variable location when it goes out + * of scope. Note that unlike g_bytes_unref(), the variable may + * be %NULL. + */ +#define gs_unref_bytes __attribute__ ((cleanup(gs_local_bytes_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GBytes*, gs_local_bytes_unref, g_bytes_unref) + +/** + * gs_strfreev: + * + * Call g_strfreev() on a variable location when it goes out of scope. + */ +#define gs_strfreev __attribute__ ((cleanup(gs_local_strfreev))) +GS_DEFINE_CLEANUP_FUNCTION(char**, gs_local_strfreev, g_strfreev) + +/** + * gs_free_error: + * + * Call g_error_free() on a variable location when it goes out of scope. + */ +#define gs_free_error __attribute__ ((cleanup(gs_local_free_error))) +GS_DEFINE_CLEANUP_FUNCTION0(GError*, gs_local_free_error, g_error_free) + +/** + * gs_unref_keyfile: + * + * Call g_key_file_unref() on a variable location when it goes out of scope. + */ +#define gs_unref_keyfile __attribute__ ((cleanup(gs_local_keyfile_unref))) +GS_DEFINE_CLEANUP_FUNCTION0(GKeyFile*, gs_local_keyfile_unref, g_key_file_unref) + +static inline void +gs_cleanup_close_fdp (int *fdp) +{ + int fd; + + g_assert (fdp); + + fd = *fdp; + if (fd != -1) + (void) close (fd); +} + +/** + * gs_fd_close: + * + * Call close() on a variable location when it goes out of scope. + */ +#define gs_fd_close __attribute__((cleanup(gs_cleanup_close_fdp))) + +G_END_DECLS + +#endif diff --git a/tests/network/nm-utils/nm-dbus-compat.h b/tests/network/nm-utils/nm-dbus-compat.h new file mode 100644 index 000000000..dd97b5fd6 --- /dev/null +++ b/tests/network/nm-utils/nm-dbus-compat.h @@ -0,0 +1,74 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * 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. + * + * Copyright 2015 Red Hat, Inc. + */ + +#ifndef __NM_DBUS_COMPAT_H__ +#define __NM_DBUS_COMPAT_H__ + +/* Copied from */ + +/* Bus names */ + +/** The bus name used to talk to the bus itself. */ +#define DBUS_SERVICE_DBUS "org.freedesktop.DBus" + +/* Paths */ +/** The object path used to talk to the bus itself. */ +#define DBUS_PATH_DBUS "/org/freedesktop/DBus" +/** The object path used in local/in-process-generated messages. */ +#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local" + +/* Interfaces, these #define don't do much other than + * catch typos at compile time + */ +/** The interface exported by the object with #DBUS_SERVICE_DBUS and #DBUS_PATH_DBUS */ +#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus" +/** The interface supported by introspectable objects */ +#define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable" +/** The interface supported by objects with properties */ +#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties" +/** The interface supported by most dbus peers */ +#define DBUS_INTERFACE_PEER "org.freedesktop.DBus.Peer" + +/** This is a special interface whose methods can only be invoked + * by the local implementation (messages from remote apps aren't + * allowed to specify this interface). + */ +#define DBUS_INTERFACE_LOCAL "org.freedesktop.DBus.Local" + +/* Owner flags */ +#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */ +#define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 /**< Request to replace the current primary owner */ +#define DBUS_NAME_FLAG_DO_NOT_QUEUE 0x4 /**< If we can not become the primary owner do not place us in the queue */ + +/* Replies to request for a name */ +#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 /**< Service has become the primary owner of the requested name */ +#define DBUS_REQUEST_NAME_REPLY_IN_QUEUE 2 /**< Service could not become the primary owner and has been placed in the queue */ +#define DBUS_REQUEST_NAME_REPLY_EXISTS 3 /**< Service is already in the queue */ +#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4 /**< Service is already the primary owner */ + +/* Replies to releasing a name */ +#define DBUS_RELEASE_NAME_REPLY_RELEASED 1 /**< Service was released from the given name */ +#define DBUS_RELEASE_NAME_REPLY_NON_EXISTENT 2 /**< The given name does not exist on the bus */ +#define DBUS_RELEASE_NAME_REPLY_NOT_OWNER 3 /**< Service is not an owner of the given name */ + +/* Replies to service starts */ +#define DBUS_START_REPLY_SUCCESS 1 /**< Service was auto started */ +#define DBUS_START_REPLY_ALREADY_RUNNING 2 /**< Service was already running */ + +#endif /* __NM_DBUS_COMPAT_H__ */ diff --git a/tests/network/nm-utils/nm-default.h b/tests/network/nm-utils/nm-default.h new file mode 100644 index 000000000..b9be4768c --- /dev/null +++ b/tests/network/nm-utils/nm-default.h @@ -0,0 +1,316 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * (C) Copyright 2015 Red Hat, Inc. + */ + +#ifndef __NM_DEFAULT_H__ +#define __NM_DEFAULT_H__ + +#define NM_NETWORKMANAGER_COMPILATION_WITH_GLIB (1 << 0) +#define NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_LIB (1 << 1) +#define NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG (1 << 2) +#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM (1 << 3) +#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE (1 << 4) +#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE (1 << 5) +#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL (1 << 6) +#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE (1 << 7) +#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_UTIL (1 << 8) +#define NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB (1 << 9) +#define NM_NETWORKMANAGER_COMPILATION_WITH_DAEMON (1 << 10) +#define NM_NETWORKMANAGER_COMPILATION_WITH_SYSTEMD (1 << 11) + +#define NM_NETWORKMANAGER_COMPILATION_LIBNM_CORE ( 0 \ + | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB \ + | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_LIB \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_PRIVATE \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL \ + ) + +#define NM_NETWORKMANAGER_COMPILATION_LIBNM ( 0 \ + | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB \ + | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_LIB \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL \ + ) + +#define NM_NETWORKMANAGER_COMPILATION_LIBNM_UTIL ( 0 \ + | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB \ + | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_LIB \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_UTIL \ + ) + +#define NM_NETWORKMANAGER_COMPILATION_LIBNM_GLIB ( 0 \ + | NM_NETWORKMANAGER_COMPILATION_LIBNM_UTIL \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB \ + ) + +#define NM_NETWORKMANAGER_COMPILATION_CLIENT ( 0 \ + | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB \ + | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE \ + ) + +#define NM_NETWORKMANAGER_COMPILATION_DAEMON ( 0 \ + | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB \ + | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE \ + | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL \ + | NM_NETWORKMANAGER_COMPILATION_WITH_DAEMON \ + ) + +#define NM_NETWORKMANAGER_COMPILATION_SYSTEMD ( 0 \ + | NM_NETWORKMANAGER_COMPILATION_DAEMON \ + | NM_NETWORKMANAGER_COMPILATION_WITH_SYSTEMD \ + ) + +#define NM_NETWORKMANAGER_COMPILATION_GLIB ( 0 \ + | NM_NETWORKMANAGER_COMPILATION_WITH_GLIB \ + ) + +#ifndef NETWORKMANAGER_COMPILATION +#error Define NETWORKMANAGER_COMPILATION accordingly +#endif + +#ifndef G_LOG_DOMAIN +#if defined(NETWORKMANAGER_COMPILATION_TEST) +#define G_LOG_DOMAIN "test" +#elif NETWORKMANAGER_COMPILATION & NM_NETWORKMANAGER_COMPILATION_WITH_DAEMON +#define G_LOG_DOMAIN "NetworkManager" +#else +#error Need to define G_LOG_DOMAIN +#endif +#elif defined (NETWORKMANAGER_COMPILATION_TEST) || (NETWORKMANAGER_COMPILATION & NM_NETWORKMANAGER_COMPILATION_WITH_DAEMON) +#error Do not define G_LOG_DOMAIN with NM_NETWORKMANAGER_COMPILATION_WITH_DAEMON +#endif + +/*****************************************************************************/ + +/* always include these headers for our internal source files. */ + +#ifndef ___CONFIG_H__ +#define ___CONFIG_H__ +#include +#endif + +/* for internal compilation we don't want the deprecation macros + * to be in effect. Define the widest range of versions to effectively + * disable deprecation checks */ +#define NM_VERSION_MIN_REQUIRED NM_VERSION_0_9_8 + +#ifndef NM_MORE_ASSERTS +#define NM_MORE_ASSERTS 0 +#endif + +#if NM_MORE_ASSERTS == 0 +/* The cast macros like NM_TYPE() are implemented via G_TYPE_CHECK_INSTANCE_CAST() + * and _G_TYPE_CIC(). The latter, by default performs runtime checks of the type + * by calling g_type_check_instance_cast(). + * This check has a certain overhead without being helpful. + * + * Example 1: + * static void foo (NMType *obj) + * { + * access_obj_without_check (obj); + * } + * foo ((NMType *) obj); + * // There is no runtime check and passing an invalid pointer + * // leads to a crash. + * + * Example 2: + * static void foo (NMType *obj) + * { + * access_obj_without_check (obj); + * } + * foo (NM_TYPE (obj)); + * // There is a runtime check which prints a g_warning(), but that doesn't + * // avoid the crash as NM_TYPE() cannot do anything then passing on the + * // invalid pointer. + * + * Example 3: + * static void foo (NMType *obj) + * { + * g_return_if_fail (NM_IS_TYPE (obj)); + * access_obj_without_check (obj); + * } + * foo ((NMType *) obj); + * // There is a runtime check which prints a g_critical() which also avoids + * // the crash. That is actually helpful to catch bugs and avoid crashes. + * + * Example 4: + * static void foo (NMType *obj) + * { + * g_return_if_fail (NM_IS_TYPE (obj)); + * access_obj_without_check (obj); + * } + * foo (NM_TYPE (obj)); + * // The runtime check is performed twice, with printing a g_warning() and + * // a g_critical() and avoiding the crash. + * + * Example 3 is how it should be done. Type checks in NM_TYPE() are pointless. + * Disable them for our production builds. + */ +#ifndef G_DISABLE_CAST_CHECKS +#define G_DISABLE_CAST_CHECKS +#endif +#endif + +#if NM_MORE_ASSERTS == 0 +#ifndef G_DISABLE_CAST_CHECKS +/* Unless compiling with G_DISABLE_CAST_CHECKS, glib performs type checking + * during G_VARIANT_TYPE() via g_variant_type_checked_(). This is not necesary + * because commonly this cast is needed during something like + * + * g_variant_builder_init (&props, G_VARIANT_TYPE ("a{sv}")); + * + * Note that in if the variant type would be invalid, the check still + * wouldn't make the buggy code magically work. Instead of passing a + * bogus type string (bad), it would pass %NULL to g_variant_builder_init() + * (also bad). + * + * Also, a function like g_variant_builder_init() already validates + * the input type via something like + * + * g_return_if_fail (g_variant_type_is_container (type)); + * + * So, by having G_VARIANT_TYPE() also validate the type, we validate + * twice, whereas the first validation is rather pointless because it + * doesn't prevent the function to be called with invalid arguments. + * + * Just patch G_VARIANT_TYPE() to perform no check. + */ +#undef G_VARIANT_TYPE +#define G_VARIANT_TYPE(type_string) ((const GVariantType *) (type_string)) +#endif +#endif + +#include + +/*****************************************************************************/ + +#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_GLIB + +#include + +#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG +#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_LIB +#error Cannot define NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_PROG and NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_LIB +#endif +#include +#elif (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_LIB +#include +#endif + +/*****************************************************************************/ + +#if NM_MORE_ASSERTS == 0 + +/* glib assertions (g_return_*(), g_assert*()) contain a textual representation + * of the checked statement. This part of the assertion blows up the size of the + * binary. Unless we compile a debug-build with NM_MORE_ASSERTS, drop these + * parts. Note that the failed assertion still prints the file and line where the + * assertion fails. That shall suffice. */ + +static inline void +_nm_g_return_if_fail_warning (const char *log_domain, + const char *file, + int line) +{ + char file_buf[256 + 15]; + + g_snprintf (file_buf, sizeof (file_buf), "((%s:%d))", file, line); + g_return_if_fail_warning (log_domain, file_buf, ""); +} + +#define g_return_if_fail_warning(log_domain, pretty_function, expression) \ + _nm_g_return_if_fail_warning (log_domain, __FILE__, __LINE__) + +#define g_assertion_message_expr(domain, file, line, func, expr) \ + g_assertion_message_expr(domain, file, line, "", (expr) ? "" : NULL) + +#undef g_return_val_if_reached +#define g_return_val_if_reached(val) \ + G_STMT_START { \ + g_log (G_LOG_DOMAIN, \ + G_LOG_LEVEL_CRITICAL, \ + "file %s: line %d (%s): should not be reached", \ + __FILE__, \ + __LINE__, \ + ""); \ + return (val); \ + } G_STMT_END + +#undef g_return_if_reached +#define g_return_if_reached() \ + G_STMT_START { \ + g_log (G_LOG_DOMAIN, \ + G_LOG_LEVEL_CRITICAL, \ + "file %s: line %d (%s): should not be reached", \ + __FILE__, \ + __LINE__, \ + ""); \ + return; \ + } G_STMT_END + +#define NM_ASSERT_G_RETURN_EXPR(expr) "" +#define NM_ASSERT_NO_MSG 1 + +#else + +#define NM_ASSERT_G_RETURN_EXPR(expr) ""expr"" +#define NM_ASSERT_NO_MSG 0 + +#endif + +/*****************************************************************************/ + +#include "nm-utils/nm-macros-internal.h" +#include "nm-utils/nm-shared-utils.h" + +#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_UTIL +/* no hash-utils in legacy code. */ +#else +#include "nm-utils/nm-hash-utils.h" +#endif + +/*****************************************************************************/ + +#if (NETWORKMANAGER_COMPILATION) & (NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_UTIL) +#include "nm-version.h" +#endif + +/*****************************************************************************/ + +#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_DAEMON +#include "nm-types.h" +#include "nm-logging.h" +#endif + +#if ((NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM) && !((NETWORKMANAGER_COMPILATION) & (NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_PRIVATE | NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_CORE_INTERNAL)) +#include "NetworkManager.h" +#endif + +#endif /* NM_NETWORKMANAGER_COMPILATION_WITH_GLIB */ + +/*****************************************************************************/ + +#endif /* __NM_DEFAULT_H__ */ diff --git a/tests/network/nm-utils/nm-glib.h b/tests/network/nm-utils/nm-glib.h new file mode 100644 index 000000000..f1498dc4e --- /dev/null +++ b/tests/network/nm-utils/nm-glib.h @@ -0,0 +1,125 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * 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. + * + * Copyright 2008 - 2018 Red Hat, Inc. + */ + +#ifndef __NM_GLIB_H__ +#define __NM_GLIB_H__ + + +#include +#include + +#include "gsystem-local-alloc.h" + +#ifdef __clang__ + +#undef G_GNUC_BEGIN_IGNORE_DEPRECATIONS +#undef G_GNUC_END_IGNORE_DEPRECATIONS + +#define G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") + +#define G_GNUC_END_IGNORE_DEPRECATIONS \ + _Pragma("clang diagnostic pop") + +#endif + +/* g_assert_cmpmem() is only available since glib 2.46. */ +#if !GLIB_CHECK_VERSION (2, 45, 7) +#define g_assert_cmpmem(m1, l1, m2, l2) G_STMT_START {\ + gconstpointer __m1 = m1, __m2 = m2; \ + int __l1 = l1, __l2 = l2; \ + if (__l1 != __l2) \ + g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #l1 " (len(" #m1 ")) == " #l2 " (len(" #m2 "))", __l1, "==", __l2, 'i'); \ + else if (memcmp (__m1, __m2, __l1) != 0) \ + g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + "assertion failed (" #m1 " == " #m2 ")"); \ + } G_STMT_END +#endif + +/* Rumtime check for glib version. First do a compile time check which + * (if satisfied) shortcuts the runtime check. */ +static inline gboolean +nm_glib_check_version (guint major, guint minor, guint micro) +{ + return GLIB_CHECK_VERSION (major, minor, micro) + || ( ( glib_major_version > major) + || ( glib_major_version == major + && glib_minor_version > minor) + || ( glib_major_version == major + && glib_minor_version == minor + && glib_micro_version < micro)); +} + +#if !GLIB_CHECK_VERSION(2, 44, 0) +static inline gpointer +g_steal_pointer (gpointer pp) +{ + gpointer *ptr = (gpointer *) pp; + gpointer ref; + + ref = *ptr; + *ptr = NULL; + + return ref; +} + +/* type safety */ +#define g_steal_pointer(pp) \ + (0 ? (*(pp)) : (g_steal_pointer) (pp)) +#endif + + +static inline gboolean +_nm_g_strv_contains (const gchar * const *strv, + const gchar *str) +{ +#if !GLIB_CHECK_VERSION(2, 44, 0) + g_return_val_if_fail (strv != NULL, FALSE); + g_return_val_if_fail (str != NULL, FALSE); + + for (; *strv != NULL; strv++) { + if (g_str_equal (str, *strv)) + return TRUE; + } + + return FALSE; +#else + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + return g_strv_contains (strv, str); + G_GNUC_END_IGNORE_DEPRECATIONS +#endif +} +#define g_strv_contains _nm_g_strv_contains + +#if !GLIB_CHECK_VERSION (2, 56, 0) +#define g_object_ref(Obj) ((typeof(Obj)) g_object_ref (Obj)) +#define g_object_ref_sink(Obj) ((typeof(Obj)) g_object_ref_sink (Obj)) +#endif + +#ifndef g_autofree +/* we still don't rely on recent glib to provide g_autofree. Hence, we continue + * to use our gs_* free macros that we took from libgsystem. + * + * To ease migration towards g_auto*, add a compat define for g_autofree. */ +#define g_autofree gs_free +#endif + +#endif /* __NM_GLIB_H__ */ diff --git a/tests/network/nm-utils/nm-hash-utils.h b/tests/network/nm-utils/nm-hash-utils.h new file mode 100644 index 000000000..e69de29bb diff --git a/tests/network/nm-utils/nm-macros-internal.h b/tests/network/nm-utils/nm-macros-internal.h new file mode 100644 index 000000000..2e3940fd7 --- /dev/null +++ b/tests/network/nm-utils/nm-macros-internal.h @@ -0,0 +1,1384 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * (C) Copyright 2014 Red Hat, Inc. + */ + +#ifndef __NM_MACROS_INTERNAL_H__ +#define __NM_MACROS_INTERNAL_H__ + +#include +#include +#include + +#define _nm_packed __attribute__ ((packed)) +#define _nm_unused __attribute__ ((unused)) +#define _nm_pure __attribute__ ((pure)) +#define _nm_const __attribute__ ((const)) +#define _nm_printf(a,b) __attribute__ ((__format__ (__printf__, a, b))) +#define _nm_align(s) __attribute__ ((aligned (s))) +#define _nm_alignof(type) __alignof (type) +#define _nm_alignas(type) _nm_align (_nm_alignof (type)) + +#if __GNUC__ >= 7 +#define _nm_fallthrough __attribute__ ((fallthrough)) +#else +#define _nm_fallthrough +#endif + +/*****************************************************************************/ + +#ifdef thread_local +#define _nm_thread_local thread_local +/* + * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__ + * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769 + */ +#elif __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16)) +#define _nm_thread_local _Thread_local +#else +#define _nm_thread_local __thread +#endif + +/*****************************************************************************/ + +#include "nm-glib.h" + +/*****************************************************************************/ + +#define nm_offsetofend(t,m) (G_STRUCT_OFFSET (t,m) + sizeof (((t *) NULL)->m)) + +#define nm_auto(fcn) __attribute__ ((cleanup(fcn))) + +static inline int nm_close (int fd); + +/** + * nm_auto_free: + * + * Call free() on a variable location when it goes out of scope. + */ +#define nm_auto_free nm_auto(_nm_auto_free_impl) +GS_DEFINE_CLEANUP_FUNCTION(void*, _nm_auto_free_impl, free) + +static inline void +nm_free_secret (char *secret) +{ + if (secret) { + memset (secret, 0, strlen (secret)); + g_free (secret); + } +} + +static inline void +_nm_auto_free_secret_impl (char **v) +{ + nm_free_secret (*v); +} + +/** + * nm_auto_free_secret: + * + * Call g_free() on a variable location when it goes out of scope. + * Also, previously, calls memset(loc, 0, strlen(loc)) to clear out + * the secret. + */ +#define nm_auto_free_secret nm_auto(_nm_auto_free_secret_impl) + +static inline void +_nm_auto_unset_gvalue_impl (GValue *v) +{ + g_value_unset (v); +} +#define nm_auto_unset_gvalue nm_auto(_nm_auto_unset_gvalue_impl) + +static inline void +_nm_auto_unref_gtypeclass (gpointer v) +{ + if (v && *((gpointer *) v)) + g_type_class_unref (*((gpointer *) v)); +} +#define nm_auto_unref_gtypeclass nm_auto(_nm_auto_unref_gtypeclass) + +static inline void +_nm_auto_free_gstring_impl (GString **str) +{ + if (*str) + g_string_free (*str, TRUE); +} +#define nm_auto_free_gstring nm_auto(_nm_auto_free_gstring_impl) + +static inline void +_nm_auto_close_impl (int *pfd) +{ + if (*pfd >= 0) { + int errsv = errno; + + (void) nm_close (*pfd); + errno = errsv; + } +} +#define nm_auto_close nm_auto(_nm_auto_close_impl) + +static inline void +_nm_auto_fclose_impl (FILE **pfd) +{ + if (*pfd) { + int errsv = errno; + + (void) fclose (*pfd); + errno = errsv; + } +} +#define nm_auto_fclose nm_auto(_nm_auto_fclose_impl) + +static inline void +_nm_auto_protect_errno (int *p_saved_errno) +{ + errno = *p_saved_errno; +} +#define NM_AUTO_PROTECT_ERRNO(errsv_saved) nm_auto(_nm_auto_protect_errno) _nm_unused const int errsv_saved = (errno) + +/*****************************************************************************/ + +/* http://stackoverflow.com/a/11172679 */ +#define _NM_UTILS_MACRO_FIRST(...) __NM_UTILS_MACRO_FIRST_HELPER(__VA_ARGS__, throwaway) +#define __NM_UTILS_MACRO_FIRST_HELPER(first, ...) first + +#define _NM_UTILS_MACRO_REST(...) __NM_UTILS_MACRO_REST_HELPER(__NM_UTILS_MACRO_REST_NUM(__VA_ARGS__), __VA_ARGS__) +#define __NM_UTILS_MACRO_REST_HELPER(qty, ...) __NM_UTILS_MACRO_REST_HELPER2(qty, __VA_ARGS__) +#define __NM_UTILS_MACRO_REST_HELPER2(qty, ...) __NM_UTILS_MACRO_REST_HELPER_##qty(__VA_ARGS__) +#define __NM_UTILS_MACRO_REST_HELPER_ONE(first) +#define __NM_UTILS_MACRO_REST_HELPER_TWOORMORE(first, ...) , __VA_ARGS__ +#define __NM_UTILS_MACRO_REST_NUM(...) \ + __NM_UTILS_MACRO_REST_SELECT_30TH(__VA_ARGS__, \ + TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\ + TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\ + TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\ + TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\ + TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE, TWOORMORE,\ + TWOORMORE, TWOORMORE, TWOORMORE, ONE, throwaway) +#define __NM_UTILS_MACRO_REST_SELECT_30TH(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, ...) a30 + +/*****************************************************************************/ + +/* http://stackoverflow.com/a/2124385/354393 */ + +#define NM_NARG(...) \ + _NM_NARG(__VA_ARGS__,_NM_NARG_RSEQ_N()) +#define _NM_NARG(...) \ + _NM_NARG_ARG_N(__VA_ARGS__) +#define _NM_NARG_ARG_N( \ + _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ + _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ + _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ + _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ + _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ + _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ + _61,_62,_63,N,...) N +#define _NM_NARG_RSEQ_N() \ + 63,62,61,60, \ + 59,58,57,56,55,54,53,52,51,50, \ + 49,48,47,46,45,44,43,42,41,40, \ + 39,38,37,36,35,34,33,32,31,30, \ + 29,28,27,26,25,24,23,22,21,20, \ + 19,18,17,16,15,14,13,12,11,10, \ + 9,8,7,6,5,4,3,2,1,0 + +/*****************************************************************************/ + +#if defined (__GNUC__) +#define _NM_PRAGMA_WARNING_DO(warning) G_STRINGIFY(GCC diagnostic ignored warning) +#elif defined (__clang__) +#define _NM_PRAGMA_WARNING_DO(warning) G_STRINGIFY(clang diagnostic ignored warning) +#endif + +/* you can only suppress a specific warning that the compiler + * understands. Otherwise you will get another compiler warning + * about invalid pragma option. + * It's not that bad however, because gcc and clang often have the + * same name for the same warning. */ + +#if defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define NM_PRAGMA_WARNING_DISABLE(warning) \ + _Pragma("GCC diagnostic push") \ + _Pragma(_NM_PRAGMA_WARNING_DO(warning)) +#elif defined (__clang__) +#define NM_PRAGMA_WARNING_DISABLE(warning) \ + _Pragma("clang diagnostic push") \ + _Pragma(_NM_PRAGMA_WARNING_DO("-Wunknown-warning-option")) \ + _Pragma(_NM_PRAGMA_WARNING_DO(warning)) +#else +#define NM_PRAGMA_WARNING_DISABLE(warning) +#endif + +#if defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define NM_PRAGMA_WARNING_REENABLE \ + _Pragma("GCC diagnostic pop") +#elif defined (__clang__) +#define NM_PRAGMA_WARNING_REENABLE \ + _Pragma("clang diagnostic pop") +#else +#define NM_PRAGMA_WARNING_REENABLE +#endif + +/*****************************************************************************/ + +/** + * NM_G_ERROR_MSG: + * @error: (allow-none): the #GError instance + * + * All functions must follow the convention that when they + * return a failure, they must also set the GError to a valid + * message. For external API however, we want to be extra + * careful before accessing the error instance. Use NM_G_ERROR_MSG() + * which is safe to use on NULL. + * + * Returns: the error message. + **/ +static inline const char * +NM_G_ERROR_MSG (GError *error) +{ + return error ? (error->message ? : "(null)") : "(no-error)"; \ +} + +/*****************************************************************************/ + +/* macro to return strlen() of a compile time string. */ +#define NM_STRLEN(str) ( sizeof ("" str) - 1 ) + +/* returns the length of a NULL terminated array of pointers, + * like g_strv_length() does. The difference is: + * - it operats on arrays of pointers (of any kind, requiring no cast). + * - it accepts NULL to return zero. */ +#define NM_PTRARRAY_LEN(array) \ + ({ \ + typeof (*(array)) *const _array = (array); \ + gsize _n = 0; \ + \ + if (_array) { \ + _nm_unused gconstpointer _type_check_is_pointer = _array[0]; \ + \ + while (_array[_n]) \ + _n++; \ + } \ + _n; \ + }) + +/* Note: @value is only evaluated when *out_val is present. + * Thus, + * NM_SET_OUT (out_str, g_strdup ("hallo")); + * does the right thing. + */ +#define NM_SET_OUT(out_val, value) \ + G_STMT_START { \ + typeof(*(out_val)) *_out_val = (out_val); \ + \ + if (_out_val) { \ + *_out_val = (value); \ + } \ + } G_STMT_END + +/*****************************************************************************/ + +#ifndef _NM_CC_SUPPORT_AUTO_TYPE +#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9 ))) +#define _NM_CC_SUPPORT_AUTO_TYPE 1 +#else +#define _NM_CC_SUPPORT_AUTO_TYPE 0 +#endif +#endif + +#ifndef _NM_CC_SUPPORT_GENERIC +#if (defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9 ))) || (defined (__clang__)) +#define _NM_CC_SUPPORT_GENERIC 1 +#else +#define _NM_CC_SUPPORT_GENERIC 0 +#endif +#endif + +#if _NM_CC_SUPPORT_AUTO_TYPE +#define _nm_auto_type __auto_type +#endif + +#if _NM_CC_SUPPORT_GENERIC +#define _NM_CONSTCAST_FULL_1(type, obj_expr, obj) \ + (_Generic ((obj_expr), \ + const void *const: ((const type *) (obj)), \ + const void * : ((const type *) (obj)), \ + void *const: (( type *) (obj)), \ + void * : (( type *) (obj)), \ + const type *const: ((const type *) (obj)), \ + const type * : ((const type *) (obj)), \ + type *const: (( type *) (obj)), \ + type * : (( type *) (obj)))) +#define _NM_CONSTCAST_FULL_2(type, obj_expr, obj, alias_type2) \ + (_Generic ((obj_expr), \ + const void *const: ((const type *) (obj)), \ + const void * : ((const type *) (obj)), \ + void *const: (( type *) (obj)), \ + void * : (( type *) (obj)), \ + const alias_type2 *const: ((const type *) (obj)), \ + const alias_type2 * : ((const type *) (obj)), \ + alias_type2 *const: (( type *) (obj)), \ + alias_type2 * : (( type *) (obj)), \ + const type *const: ((const type *) (obj)), \ + const type * : ((const type *) (obj)), \ + type *const: (( type *) (obj)), \ + type * : (( type *) (obj)))) +#define _NM_CONSTCAST_FULL_3(type, obj_expr, obj, alias_type2, alias_type3) \ + (_Generic ((obj_expr), \ + const void *const: ((const type *) (obj)), \ + const void * : ((const type *) (obj)), \ + void *const: (( type *) (obj)), \ + void * : (( type *) (obj)), \ + const alias_type2 *const: ((const type *) (obj)), \ + const alias_type2 * : ((const type *) (obj)), \ + alias_type2 *const: (( type *) (obj)), \ + alias_type2 * : (( type *) (obj)), \ + const alias_type3 *const: ((const type *) (obj)), \ + const alias_type3 * : ((const type *) (obj)), \ + alias_type3 *const: (( type *) (obj)), \ + alias_type3 * : (( type *) (obj)), \ + const type *const: ((const type *) (obj)), \ + const type * : ((const type *) (obj)), \ + type *const: (( type *) (obj)), \ + type * : (( type *) (obj)))) +#define _NM_CONSTCAST_FULL_4(type, obj_expr, obj, alias_type2, alias_type3, alias_type4) \ + (_Generic ((obj_expr), \ + const void *const: ((const type *) (obj)), \ + const void * : ((const type *) (obj)), \ + void *const: (( type *) (obj)), \ + void * : (( type *) (obj)), \ + const alias_type2 *const: ((const type *) (obj)), \ + const alias_type2 * : ((const type *) (obj)), \ + alias_type2 *const: (( type *) (obj)), \ + alias_type2 * : (( type *) (obj)), \ + const alias_type3 *const: ((const type *) (obj)), \ + const alias_type3 * : ((const type *) (obj)), \ + alias_type3 *const: (( type *) (obj)), \ + alias_type3 * : (( type *) (obj)), \ + const alias_type4 *const: ((const type *) (obj)), \ + const alias_type4 * : ((const type *) (obj)), \ + alias_type4 *const: (( type *) (obj)), \ + alias_type4 * : (( type *) (obj)), \ + const type *const: ((const type *) (obj)), \ + const type * : ((const type *) (obj)), \ + type *const: (( type *) (obj)), \ + type * : (( type *) (obj)))) +#define _NM_CONSTCAST_FULL_x(type, obj_expr, obj, n, ...) (_NM_CONSTCAST_FULL_##n (type, obj_expr, obj, ##__VA_ARGS__)) +#define _NM_CONSTCAST_FULL_y(type, obj_expr, obj, n, ...) (_NM_CONSTCAST_FULL_x (type, obj_expr, obj, n, ##__VA_ARGS__)) +#define NM_CONSTCAST_FULL( type, obj_expr, obj, ...) (_NM_CONSTCAST_FULL_y (type, obj_expr, obj, NM_NARG (dummy, ##__VA_ARGS__), ##__VA_ARGS__)) +#else +#define NM_CONSTCAST_FULL( type, obj_expr, obj, ...) ((type *) (obj)) +#endif + +#define NM_CONSTCAST(type, obj, ...) \ + NM_CONSTCAST_FULL(type, (obj), (obj), ##__VA_ARGS__) + +#if _NM_CC_SUPPORT_GENERIC +#define NM_UNCONST_PTR(type, arg) \ + _Generic ((arg), \ + const type *: ((type *) (arg)), \ + type *: ((type *) (arg))) +#else +#define NM_UNCONST_PTR(type, arg) \ + ((type *) (arg)) +#endif + +#if _NM_CC_SUPPORT_GENERIC +#define NM_UNCONST_PPTR(type, arg) \ + _Generic ((arg), \ + const type * *: ((type **) (arg)), \ + type * *: ((type **) (arg)), \ + const type *const*: ((type **) (arg)), \ + type *const*: ((type **) (arg))) +#else +#define NM_UNCONST_PPTR(type, arg) \ + ((type **) (arg)) +#endif + +#define NM_GOBJECT_CAST(type, obj, is_check, ...) \ + ({ \ + const void *_obj = (obj); \ + \ + nm_assert (_obj || (is_check (_obj))); \ + NM_CONSTCAST_FULL (type, (obj), _obj, GObject, ##__VA_ARGS__); \ + }) + +#define NM_GOBJECT_CAST_NON_NULL(type, obj, is_check, ...) \ + ({ \ + const void *_obj = (obj); \ + \ + nm_assert (is_check (_obj)); \ + NM_CONSTCAST_FULL (type, (obj), _obj, GObject, ##__VA_ARGS__); \ + }) + +#if _NM_CC_SUPPORT_GENERIC +/* returns @value, if the type of @value matches @type. + * This requires support for C11 _Generic(). If no support is + * present, this returns @value directly. + * + * It's useful to check the let the compiler ensure that @value is + * of a certain type. */ +#define _NM_ENSURE_TYPE(type, value) (_Generic ((value), type: (value))) +#else +#define _NM_ENSURE_TYPE(type, value) (value) +#endif + +#if _NM_CC_SUPPORT_GENERIC +#define NM_PROPAGATE_CONST(test_expr, ptr) \ + (_Generic ((test_expr), \ + const typeof (*(test_expr)) *: ((const typeof (*(ptr)) *) (ptr)), \ + default: (_Generic ((test_expr), \ + typeof (*(test_expr)) *: (ptr))))) +#else +#define NM_PROPAGATE_CONST(test_expr, ptr) (ptr) +#endif + +/*****************************************************************************/ + +#define _NM_IN_SET_EVAL_1( op, _x, y) (_x == (y)) +#define _NM_IN_SET_EVAL_2( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_1 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_3( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_2 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_4( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_3 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_5( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_4 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_6( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_5 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_7( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_6 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_8( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_7 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_9( op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_8 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_10(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_9 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_11(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_10 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_12(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_11 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_13(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_12 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_14(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_13 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_15(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_14 (op, _x, __VA_ARGS__) +#define _NM_IN_SET_EVAL_16(op, _x, y, ...) (_x == (y)) op _NM_IN_SET_EVAL_15 (op, _x, __VA_ARGS__) + +#define _NM_IN_SET_EVAL_N2(op, _x, n, ...) (_NM_IN_SET_EVAL_##n(op, _x, __VA_ARGS__)) +#define _NM_IN_SET_EVAL_N(op, type, x, n, ...) \ + ({ \ + type _x = (x); \ + \ + /* trigger a -Wenum-compare warning */ \ + nm_assert (TRUE || _x == (x)); \ + \ + !!_NM_IN_SET_EVAL_N2(op, _x, n, __VA_ARGS__); \ + }) + +#define _NM_IN_SET(op, type, x, ...) _NM_IN_SET_EVAL_N(op, type, x, NM_NARG (__VA_ARGS__), __VA_ARGS__) + +/* Beware that this does short-circuit evaluation (use "||" instead of "|") + * which has a possibly unexpected non-function-like behavior. + * Use NM_IN_SET_SE if you need all arguments to be evaluted. */ +#define NM_IN_SET(x, ...) _NM_IN_SET(||, typeof (x), x, __VA_ARGS__) + +/* "SE" stands for "side-effect". Contrary to NM_IN_SET(), this does not do + * short-circuit evaluation, which can make a difference if the arguments have + * side-effects. */ +#define NM_IN_SET_SE(x, ...) _NM_IN_SET(|, typeof (x), x, __VA_ARGS__) + +/* the *_TYPED forms allow to explicitly select the type of "x". This is useful + * if "x" doesn't support typeof (bitfields) or you want to gracefully convert + * a type using automatic type conversion rules (but not forcing the conversion + * with a cast). */ +#define NM_IN_SET_TYPED(type, x, ...) _NM_IN_SET(||, type, x, __VA_ARGS__) +#define NM_IN_SET_SE_TYPED(type, x, ...) _NM_IN_SET(|, type, x, __VA_ARGS__) + +/*****************************************************************************/ + +static inline gboolean +_NM_IN_STRSET_streq (const char *x, const char *s) +{ + return s && strcmp (x, s) == 0; +} + +#define _NM_IN_STRSET_EVAL_1( op, _x, y) _NM_IN_STRSET_streq (_x, y) +#define _NM_IN_STRSET_EVAL_2( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_1 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_3( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_2 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_4( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_3 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_5( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_4 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_6( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_5 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_7( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_6 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_8( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_7 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_9( op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_8 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_10(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_9 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_11(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_10 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_12(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_11 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_13(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_12 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_14(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_13 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_15(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_14 (op, _x, __VA_ARGS__) +#define _NM_IN_STRSET_EVAL_16(op, _x, y, ...) _NM_IN_STRSET_streq (_x, y) op _NM_IN_STRSET_EVAL_15 (op, _x, __VA_ARGS__) + +#define _NM_IN_STRSET_EVAL_N2(op, _x, n, ...) (_NM_IN_STRSET_EVAL_##n(op, _x, __VA_ARGS__)) +#define _NM_IN_STRSET_EVAL_N(op, x, n, ...) \ + ({ \ + const char *_x = (x); \ + ( ((_x == NULL) && _NM_IN_SET_EVAL_N2 (op, ((const char *) NULL), n, __VA_ARGS__)) \ + || ((_x != NULL) && _NM_IN_STRSET_EVAL_N2 (op, _x, n, __VA_ARGS__)) \ + ); \ + }) + +/* Beware that this does short-circuit evaluation (use "||" instead of "|") + * which has a possibly unexpected non-function-like behavior. + * Use NM_IN_STRSET_SE if you need all arguments to be evaluted. */ +#define NM_IN_STRSET(x, ...) _NM_IN_STRSET_EVAL_N(||, x, NM_NARG (__VA_ARGS__), __VA_ARGS__) + +/* "SE" stands for "side-effect". Contrary to NM_IN_STRSET(), this does not do + * short-circuit evaluation, which can make a difference if the arguments have + * side-effects. */ +#define NM_IN_STRSET_SE(x, ...) _NM_IN_STRSET_EVAL_N(|, x, NM_NARG (__VA_ARGS__), __VA_ARGS__) + +#define NM_STRCHAR_ALL(str, ch_iter, predicate) \ + ({ \ + gboolean _val = TRUE; \ + const char *_str = (str); \ + \ + if (_str) { \ + for (;;) { \ + const char ch_iter = _str[0]; \ + \ + if (ch_iter != '\0') { \ + if (predicate) {\ + _str++; \ + continue; \ + } \ + _val = FALSE; \ + } \ + break; \ + } \ + } \ + _val; \ + }) + +#define NM_STRCHAR_ANY(str, ch_iter, predicate) \ + ({ \ + gboolean _val = FALSE; \ + const char *_str = (str); \ + \ + if (_str) { \ + for (;;) { \ + const char ch_iter = _str[0]; \ + \ + if (ch_iter != '\0') { \ + if (predicate) { \ + ; \ + } else { \ + _str++; \ + continue; \ + } \ + _val = TRUE; \ + } \ + break; \ + } \ + } \ + _val; \ + }) + +/*****************************************************************************/ + +/* NM_CACHED_QUARK() returns the GQuark for @string, but caches + * it in a static variable to speed up future lookups. + * + * @string must be a string literal. + */ +#define NM_CACHED_QUARK(string) \ + ({ \ + static GQuark _nm_cached_quark = 0; \ + \ + (G_LIKELY (_nm_cached_quark != 0) \ + ? _nm_cached_quark \ + : (_nm_cached_quark = g_quark_from_static_string (""string""))); \ + }) + +/* NM_CACHED_QUARK_FCN() is essentially the same as G_DEFINE_QUARK + * with two differences: + * - @string must be a quoted string-literal + * - @fcn must be the full function name, while G_DEFINE_QUARK() appends + * "_quark" to the function name. + * Both properties of G_DEFINE_QUARK() are non favorable, because you can no + * longer grep for string/fcn -- unless you are aware that you are searching + * for G_DEFINE_QUARK() and omit quotes / append _quark(). With NM_CACHED_QUARK_FCN(), + * ctags/cscope can locate the use of @fcn (though it doesn't recognize that + * NM_CACHED_QUARK_FCN() defines it). + */ +#define NM_CACHED_QUARK_FCN(string, fcn) \ +GQuark \ +fcn (void) \ +{ \ + return NM_CACHED_QUARK (string); \ +} + +/*****************************************************************************/ + +#define nm_streq(s1, s2) (strcmp (s1, s2) == 0) +#define nm_streq0(s1, s2) (g_strcmp0 (s1, s2) == 0) + +/*****************************************************************************/ + +static inline GString * +nm_gstring_prepare (GString **l) +{ + if (*l) + g_string_set_size (*l, 0); + else + *l = g_string_sized_new (30); + return *l; +} + +static inline const char * +nm_str_not_empty (const char *str) +{ + return str && str[0] ? str : NULL; +} + +static inline char * +nm_strdup_not_empty (const char *str) +{ + return str && str[0] ? g_strdup (str) : NULL; +} + +static inline char * +nm_str_realloc (char *str) +{ + gs_free char *s = str; + + /* Returns a new clone of @str and frees @str. The point is that @str + * possibly points to a larger chunck of memory. We want to freshly allocate + * a buffer. + * + * We could use realloc(), but that might not do anything or leave + * @str in its memory pool for chunks of a different size (bad for + * fragmentation). + * + * This is only useful when we want to keep the buffer around for a long + * time and want to re-allocate a more optimal buffer. */ + + return g_strdup (s); +} + +/*****************************************************************************/ + +#define NM_PRINT_FMT_QUOTED(cond, prefix, str, suffix, str_else) \ + (cond) ? (prefix) : "", \ + (cond) ? (str) : (str_else), \ + (cond) ? (suffix) : "" +#define NM_PRINT_FMT_QUOTE_STRING(arg) NM_PRINT_FMT_QUOTED((arg), "\"", (arg), "\"", "(null)") + +/*****************************************************************************/ + +/* glib/C provides the following kind of assertions: + * - assert() -- disable with NDEBUG + * - g_return_if_fail() -- disable with G_DISABLE_CHECKS + * - g_assert() -- disable with G_DISABLE_ASSERT + * but they are all enabled by default and usually even production builds have + * these kind of assertions enabled. It also means, that disabling assertions + * is an untested configuration, and might have bugs. + * + * Add our own assertion macro nm_assert(), which is disabled by default and must + * be explicitly enabled. They are useful for more expensive checks or checks that + * depend less on runtime conditions (that is, are generally expected to be true). */ + +#ifndef NM_MORE_ASSERTS +#define NM_MORE_ASSERTS 0 +#endif + +#if NM_MORE_ASSERTS +#define nm_assert(cond) G_STMT_START { g_assert (cond); } G_STMT_END +#define nm_assert_se(cond) G_STMT_START { if (G_LIKELY (cond)) { ; } else { g_assert (FALSE && (cond)); } } G_STMT_END +#define nm_assert_not_reached() G_STMT_START { g_assert_not_reached (); } G_STMT_END +#else +#define nm_assert(cond) G_STMT_START { if (FALSE) { if (cond) { } } } G_STMT_END +#define nm_assert_se(cond) G_STMT_START { if (G_LIKELY (cond)) { ; } } G_STMT_END +#define nm_assert_not_reached() G_STMT_START { ; } G_STMT_END +#endif + +/*****************************************************************************/ + +#define NM_GOBJECT_PROPERTIES_DEFINE_BASE(...) \ +typedef enum { \ + _PROPERTY_ENUMS_0, \ + __VA_ARGS__ \ + _PROPERTY_ENUMS_LAST, \ +} _PropertyEnums; \ +static GParamSpec *obj_properties[_PROPERTY_ENUMS_LAST] = { NULL, } + +#define NM_GOBJECT_PROPERTIES_DEFINE(obj_type, ...) \ +NM_GOBJECT_PROPERTIES_DEFINE_BASE (__VA_ARGS__); \ +static inline void \ +_notify (obj_type *obj, _PropertyEnums prop) \ +{ \ + nm_assert (G_IS_OBJECT (obj)); \ + nm_assert ((gsize) prop < G_N_ELEMENTS (obj_properties)); \ + g_object_notify_by_pspec ((GObject *) obj, obj_properties[prop]); \ +} + +/*****************************************************************************/ + +#define _NM_GET_PRIVATE(self, type, is_check, ...) (&(NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__)->_priv)) +#if _NM_CC_SUPPORT_AUTO_TYPE +#define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) \ + ({ \ + _nm_auto_type _self = NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__); \ + \ + NM_PROPAGATE_CONST (_self, _self->_priv); \ + }) +#else +#define _NM_GET_PRIVATE_PTR(self, type, is_check, ...) (NM_GOBJECT_CAST_NON_NULL (type, (self), is_check, ##__VA_ARGS__)->_priv) +#endif + +/*****************************************************************************/ + +static inline gpointer +nm_g_object_ref (gpointer obj) +{ + /* g_object_ref() doesn't accept NULL. */ + if (obj) + g_object_ref (obj); + return obj; +} +#define nm_g_object_ref(obj) ((typeof (obj)) nm_g_object_ref (obj)) + +static inline void +nm_g_object_unref (gpointer obj) +{ + /* g_object_unref() doesn't accept NULL. Usully, we workaround that + * by using g_clear_object(), but sometimes that is not convinient + * (for example as as destroy function for a hash table that can contain + * NULL values). */ + if (obj) + g_object_unref (obj); +} + +/* Assigns GObject @obj to destination @pdst, and takes an additional ref. + * The previous value of @pdst is unrefed. + * + * It makes sure to first increase the ref-count of @obj, and handles %NULL + * @obj correctly. + * */ +#define nm_g_object_ref_set(pp, obj) \ + ({ \ + typeof (*(pp)) *const _pp = (pp); \ + typeof (**_pp) *const _obj = (obj); \ + typeof (**_pp) *_p; \ + gboolean _changed = FALSE; \ + \ + if ( _pp \ + && ((_p = *_pp) != _obj)) { \ + if (_obj) { \ + nm_assert (G_IS_OBJECT (_obj)); \ + g_object_ref (_obj); \ + } \ + if (_p) { \ + nm_assert (G_IS_OBJECT (_p)); \ + *_pp = NULL; \ + g_object_unref (_p); \ + } \ + *_pp = _obj; \ + _changed = TRUE; \ + } \ + _changed; \ + }) + +#define nm_clear_pointer(pp, destroy) \ + ({ \ + typeof (*(pp)) *_pp = (pp); \ + typeof (*_pp) _p; \ + gboolean _changed = FALSE; \ + \ + if ( _pp \ + && (_p = *_pp)) { \ + _nm_unused gconstpointer _p_check_is_pointer = _p; \ + \ + *_pp = NULL; \ + /* g_clear_pointer() assigns @destroy first to a local variable, so that + * you can call "g_clear_pointer (pp, (GDestroyNotify) destroy);" without + * gcc emitting a warning. We don't do that, hence, you cannot cast + * "destroy" first. + * + * On the upside: you are not supposed to cast fcn, because the pointer + * types are preserved. If you really need a cast, you should cast @pp. + * But that is hardly ever necessary. */ \ + (destroy) (_p); \ + \ + _changed = TRUE; \ + } \ + _changed; \ + }) + +/* basically, replaces + * g_clear_pointer (&location, g_free) + * with + * nm_clear_g_free (&location) + * + * Another advantage is that by using a macro and typeof(), it is more + * typesafe and gives you for example a compiler warning when pp is a const + * pointer or points to a const-pointer. + */ +#define nm_clear_g_free(pp) \ + nm_clear_pointer (pp, g_free) + +#define nm_clear_g_object(pp) \ + nm_clear_pointer (pp, g_object_unref) + +static inline gboolean +nm_clear_g_source (guint *id) +{ + guint v; + + if ( id + && (v = *id)) { + *id = 0; + g_source_remove (v); + return TRUE; + } + return FALSE; +} + +static inline gboolean +nm_clear_g_signal_handler (gpointer self, gulong *id) +{ + gulong v; + + if ( id + && (v = *id)) { + *id = 0; + g_signal_handler_disconnect (self, v); + return TRUE; + } + return FALSE; +} + +static inline gboolean +nm_clear_g_variant (GVariant **variant) +{ + GVariant *v; + + if ( variant + && (v = *variant)) { + *variant = NULL; + g_variant_unref (v); + return TRUE; + } + return FALSE; +} + +static inline gboolean +nm_clear_g_cancellable (GCancellable **cancellable) +{ + GCancellable *v; + + if ( cancellable + && (v = *cancellable)) { + *cancellable = NULL; + g_cancellable_cancel (v); + g_object_unref (v); + return TRUE; + } + return FALSE; +} + +/*****************************************************************************/ + +/* Determine whether @x is a power of two (@x being an integer type). + * Basically, this returns TRUE, if @x has exactly one bit set. + * For negative values and zero, this always returns FALSE. */ +#define nm_utils_is_power_of_two(x) ({ \ + typeof(x) __x = (x); \ + \ + ( (__x > ((typeof(__x)) 0)) \ + && ((__x & (__x - (((typeof(__x)) 1)))) == ((typeof(__x)) 0))); \ + }) + +/*****************************************************************************/ + +#define NM_UTILS_LOOKUP_DEFAULT(v) return (v) +#define NM_UTILS_LOOKUP_DEFAULT_WARN(v) g_return_val_if_reached (v) +#define NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT(v) { nm_assert_not_reached (); return (v); } +#define NM_UTILS_LOOKUP_ITEM(v, n) (void) 0; case v: return (n); (void) 0 +#define NM_UTILS_LOOKUP_STR_ITEM(v, n) NM_UTILS_LOOKUP_ITEM(v, ""n"") +#define NM_UTILS_LOOKUP_ITEM_IGNORE(v) (void) 0; case v: break; (void) 0 +#define NM_UTILS_LOOKUP_ITEM_IGNORE_OTHER() (void) 0; default: break; (void) 0 + +#define _NM_UTILS_LOOKUP_DEFINE(scope, fcn_name, lookup_type, result_type, unknown_val, ...) \ +scope result_type \ +fcn_name (lookup_type val) \ +{ \ + switch (val) { \ + (void) 0, \ + __VA_ARGS__ \ + (void) 0; \ + }; \ + { unknown_val; } \ +} + +#define NM_UTILS_LOOKUP_STR_DEFINE(fcn_name, lookup_type, unknown_val, ...) \ + _NM_UTILS_LOOKUP_DEFINE (, fcn_name, lookup_type, const char *, unknown_val, __VA_ARGS__) +#define NM_UTILS_LOOKUP_STR_DEFINE_STATIC(fcn_name, lookup_type, unknown_val, ...) \ + _NM_UTILS_LOOKUP_DEFINE (static, fcn_name, lookup_type, const char *, unknown_val, __VA_ARGS__) + +/* Call the string-lookup-table function @fcn_name. If the function returns + * %NULL, the numeric index is converted to string using a alloca() buffer. + * Beware: this macro uses alloca(). */ +#define NM_UTILS_LOOKUP_STR(fcn_name, idx) \ + ({ \ + typeof (idx) _idx = (idx); \ + const char *_s; \ + \ + _s = fcn_name (_idx); \ + if (!_s) { \ + _s = g_alloca (30); \ + \ + g_snprintf ((char *) _s, 30, "(%lld)", (long long) _idx); \ + } \ + _s; \ + }) + +/*****************************************************************************/ + +/* check if @flags has exactly one flag (@check) set. You should call this + * only with @check being a compile time constant and a power of two. */ +#define NM_FLAGS_HAS(flags, check) \ + ( G_STATIC_ASSERT_EXPR ((check) > 0 && ((check) & ((check) - 1)) == 0), NM_FLAGS_ANY ((flags), (check)) ) + +#define NM_FLAGS_ANY(flags, check) ( ( ((flags) & (check)) != 0 ) ? TRUE : FALSE ) +#define NM_FLAGS_ALL(flags, check) ( ( ((flags) & (check)) == (check) ) ? TRUE : FALSE ) + +#define NM_FLAGS_SET(flags, val) ({ \ + const typeof(flags) _flags = (flags); \ + const typeof(flags) _val = (val); \ + \ + _flags | _val; \ + }) + +#define NM_FLAGS_UNSET(flags, val) ({ \ + const typeof(flags) _flags = (flags); \ + const typeof(flags) _val = (val); \ + \ + _flags & (~_val); \ + }) + +#define NM_FLAGS_ASSIGN(flags, val, assign) ({ \ + const typeof(flags) _flags = (flags); \ + const typeof(flags) _val = (val); \ + \ + (assign) \ + ? _flags | (_val) \ + : _flags & (~_val); \ + }) + +/*****************************************************************************/ + +#define _NM_BACKPORT_SYMBOL_IMPL(VERSION, RETURN_TYPE, ORIG_FUNC, VERSIONED_FUNC, ARGS_TYPED, ARGS) \ +RETURN_TYPE VERSIONED_FUNC ARGS_TYPED; \ +RETURN_TYPE VERSIONED_FUNC ARGS_TYPED \ +{ \ + return ORIG_FUNC ARGS; \ +} \ +RETURN_TYPE ORIG_FUNC ARGS_TYPED; \ +__asm__(".symver "G_STRINGIFY(VERSIONED_FUNC)", "G_STRINGIFY(ORIG_FUNC)"@"G_STRINGIFY(VERSION)) + +#define NM_BACKPORT_SYMBOL(VERSION, RETURN_TYPE, FUNC, ARGS_TYPED, ARGS) \ +_NM_BACKPORT_SYMBOL_IMPL(VERSION, RETURN_TYPE, FUNC, _##FUNC##_##VERSION, ARGS_TYPED, ARGS) + +/*****************************************************************************/ + +#define nm_str_skip_leading_spaces(str) \ + ({ \ + typeof (*(str)) *_str = (str); \ + _nm_unused const char *_str_type_check = _str; \ + \ + if (_str) { \ + while (g_ascii_isspace (_str[0])) \ + _str++; \ + } \ + _str; \ + }) + +static inline char * +nm_strstrip (char *str) +{ + /* g_strstrip doesn't like NULL. */ + return str ? g_strstrip (str) : NULL; +} + +static inline const char * +nm_strstrip_avoid_copy (const char *str, char **str_free) +{ + gsize l; + char *s; + + nm_assert (str_free && !*str_free); + + if (!str) + return NULL; + + str = nm_str_skip_leading_spaces (str); + l = strlen (str); + if ( l == 0 + || !g_ascii_isspace (str[l - 1])) + return str; + while ( l > 0 + && g_ascii_isspace (str[l - 1])) + l--; + + s = g_new (char, l + 1); + memcpy (s, str, l); + s[l] = '\0'; + *str_free = s; + return s; +} + +/* g_ptr_array_sort()'s compare function takes pointers to the + * value. Thus, you cannot use strcmp directly. You can use + * nm_strcmp_p(). + * + * Like strcmp(), this function is not forgiving to accept %NULL. */ +static inline int +nm_strcmp_p (gconstpointer a, gconstpointer b) +{ + const char *s1 = *((const char **) a); + const char *s2 = *((const char **) b); + + return strcmp (s1, s2); +} + +/* like nm_strcmp_p(), suitable for g_ptr_array_sort_with_data(). + * g_ptr_array_sort() just casts nm_strcmp_p() to a function of different + * signature. I guess, in glib there are knowledgeable people that ensure + * that this additional argument doesn't cause problems due to different ABI + * for every architecture that glib supports. + * For NetworkManager, we'd rather avoid such stunts. + **/ +static inline int +nm_strcmp_p_with_data (gconstpointer a, gconstpointer b, gpointer user_data) +{ + const char *s1 = *((const char **) a); + const char *s2 = *((const char **) b); + + return strcmp (s1, s2); +} + +static inline int +nm_cmp_uint32_p_with_data (gconstpointer p_a, gconstpointer p_b, gpointer user_data) +{ + const guint32 a = *((const guint32 *) p_a); + const guint32 b = *((const guint32 *) p_b); + + if (a < b) + return -1; + if (a > b) + return 1; + return 0; +} + +static inline int +nm_cmp_int2ptr_p_with_data (gconstpointer p_a, gconstpointer p_b, gpointer user_data) +{ + /* p_a and p_b are two pointers to a pointer, where the pointer is + * interpreted as a integer using GPOINTER_TO_INT(). + * + * That is the case of a hash-table that uses GINT_TO_POINTER() to + * convert integers as pointers, and the resulting keys-as-array + * array. */ + const int a = GPOINTER_TO_INT (*((gconstpointer *) p_a)); + const int b = GPOINTER_TO_INT (*((gconstpointer *) p_b)); + + if (a < b) + return -1; + if (a > b) + return 1; + return 0; +} + +/*****************************************************************************/ + +/* Taken from systemd's UNIQ_T and UNIQ macros. */ + +#define NM_UNIQ_T(x, uniq) G_PASTE(__unique_prefix_, G_PASTE(x, uniq)) +#define NM_UNIQ __COUNTER__ + +/*****************************************************************************/ + +/* glib's MIN()/MAX() macros don't have function-like behavior, in that they evaluate + * the argument possibly twice. + * + * Taken from systemd's MIN()/MAX() macros. */ + +#define NM_MIN(a, b) __NM_MIN(NM_UNIQ, a, NM_UNIQ, b) +#define __NM_MIN(aq, a, bq, b) \ + ({ \ + typeof (a) NM_UNIQ_T(A, aq) = (a); \ + typeof (b) NM_UNIQ_T(B, bq) = (b); \ + ((NM_UNIQ_T(A, aq) < NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : NM_UNIQ_T(B, bq)); \ + }) + +#define NM_MAX(a, b) __NM_MAX(NM_UNIQ, a, NM_UNIQ, b) +#define __NM_MAX(aq, a, bq, b) \ + ({ \ + typeof (a) NM_UNIQ_T(A, aq) = (a); \ + typeof (b) NM_UNIQ_T(B, bq) = (b); \ + ((NM_UNIQ_T(A, aq) > NM_UNIQ_T(B, bq)) ? NM_UNIQ_T(A, aq) : NM_UNIQ_T(B, bq)); \ + }) + +#define NM_CLAMP(x, low, high) __NM_CLAMP(NM_UNIQ, x, NM_UNIQ, low, NM_UNIQ, high) +#define __NM_CLAMP(xq, x, lowq, low, highq, high) \ + ({ \ + typeof(x)NM_UNIQ_T(X,xq) = (x); \ + typeof(low) NM_UNIQ_T(LOW,lowq) = (low); \ + typeof(high) NM_UNIQ_T(HIGH,highq) = (high); \ + \ + ( (NM_UNIQ_T(X,xq) > NM_UNIQ_T(HIGH,highq)) \ + ? NM_UNIQ_T(HIGH,highq) \ + : (NM_UNIQ_T(X,xq) < NM_UNIQ_T(LOW,lowq)) \ + ? NM_UNIQ_T(LOW,lowq) \ + : NM_UNIQ_T(X,xq)); \ + }) + +/*****************************************************************************/ + +static inline guint +nm_encode_version (guint major, guint minor, guint micro) +{ + /* analog to the preprocessor macro NM_ENCODE_VERSION(). */ + return (major << 16) | (minor << 8) | micro; +} + +static inline void +nm_decode_version (guint version, guint *major, guint *minor, guint *micro) +{ + *major = (version & 0xFFFF0000u) >> 16; + *minor = (version & 0x0000FF00u) >> 8; + *micro = (version & 0x000000FFu); +} + +/*****************************************************************************/ + +/* taken from systemd's DECIMAL_STR_MAX() + * + * Returns the number of chars needed to format variables of the + * specified type as a decimal string. Adds in extra space for a + * negative '-' prefix (hence works correctly on signed + * types). Includes space for the trailing NUL. */ +#define NM_DECIMAL_STR_MAX(type) \ + (2+(sizeof(type) <= 1 ? 3 : \ + sizeof(type) <= 2 ? 5 : \ + sizeof(type) <= 4 ? 10 : \ + sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)]))) + +/*****************************************************************************/ + +/* if @str is NULL, return "(null)". Otherwise, allocate a buffer using + * alloca() of and fill it with @str. @str will be quoted with double quote. + * If @str is longer then @trunc_at, the string is truncated and the closing + * quote is instead '^' to indicate truncation. + * + * Thus, the maximum stack allocated buffer will be @trunc_at+3. */ +#define nm_strquote_a(trunc_at, str) \ + ({ \ + const char *const _str = (str); \ + \ + (_str \ + ? ({ \ + const gsize _trunc_at = (trunc_at); \ + const gsize _strlen_trunc = NM_MIN (strlen (_str), _trunc_at); \ + char *_buf; \ + \ + _buf = g_alloca (_strlen_trunc + 3); \ + _buf[0] = '"'; \ + memcpy (&_buf[1], _str, _strlen_trunc); \ + _buf[_strlen_trunc + 1] = _str[_strlen_trunc] ? '^' : '"'; \ + _buf[_strlen_trunc + 2] = '\0'; \ + _buf; \ + }) \ + : "(null)"); \ + }) + +#define nm_sprintf_buf(buf, format, ...) \ + ({ \ + char * _buf = (buf); \ + int _buf_len; \ + \ + /* some static assert trying to ensure that the buffer is statically allocated. + * It disallows a buffer size of sizeof(gpointer) to catch that. */ \ + G_STATIC_ASSERT (G_N_ELEMENTS (buf) == sizeof (buf) && sizeof (buf) != sizeof (char *)); \ + _buf_len = g_snprintf (_buf, sizeof (buf), \ + ""format"", ##__VA_ARGS__); \ + nm_assert (_buf_len < sizeof (buf)); \ + _buf; \ + }) + +#define nm_sprintf_bufa(n_elements, format, ...) \ + ({ \ + char *_buf; \ + int _buf_len; \ + typeof (n_elements) _n_elements = (n_elements); \ + \ + _buf = g_alloca (_n_elements); \ + _buf_len = g_snprintf (_buf, _n_elements, \ + ""format"", ##__VA_ARGS__); \ + nm_assert (_buf_len < _n_elements); \ + _buf; \ + }) + +/* aims to alloca() a buffer and fill it with printf(format, name). + * Note that format must not contain any format specifier except + * "%s". + * If the resulting string would be too large for stack allocation, + * it allocates a buffer with g_malloc() and assigns it to *p_val_to_free. */ +#define nm_construct_name_a(format, name, p_val_to_free) \ + ({ \ + const char *const _name = (name); \ + char **const _p_val_to_free = (p_val_to_free); \ + const gsize _name_len = strlen (_name); \ + char *_buf2; \ + \ + nm_assert (_p_val_to_free && !*_p_val_to_free); \ + if (NM_STRLEN (format) + _name_len < 200) \ + _buf2 = nm_sprintf_bufa (NM_STRLEN (format) + _name_len, format, _name); \ + else { \ + _buf2 = g_strdup_printf (format, _name); \ + *_p_val_to_free = _buf2; \ + } \ + (const char *) _buf2; \ + }) + +/*****************************************************************************/ + +/** + * The boolean type _Bool is C99 while we mostly stick to C89. However, _Bool is too + * convinient to miss and is effectively available in gcc and clang. So, just use it. + * + * Usually, one would include "stdbool.h" to get the "bool" define which aliases + * _Bool. We provide this define here, because we want to make use of it anywhere. + * (also, stdbool.h is again C99). + * + * Using _Bool has advantages over gboolean: + * + * - commonly _Bool is one byte large, instead of gboolean's 4 bytes (because gboolean + * is a typedef for gint). Especially when having boolean fields in a struct, we can + * thereby easily save some space. + * + * - _Bool type guarantees that two "true" expressions compare equal. E.g. the follwing + * will not work: + * gboolean v1 = 1; + * gboolean v2 = 2; + * g_assert_cmpint (v1, ==, v2); // will fail + * For that, we often to use !! to coerce gboolean values to 0 or 1: + * g_assert_cmpint (!!v2, ==, TRUE); + * With _Bool type, this will be handled properly by the compiler. + * + * - For structs, we might want to safe even more space and use bitfields: + * struct s1 { + * gboolean v1:1; + * }; + * But the problem here is that gboolean is signed, so that + * v1 will be either 0 or -1 (not 1, TRUE). Thus, the following + * fails: + * struct s1 s = { .v1 = TRUE, }; + * g_assert_cmpint (s1.v1, ==, TRUE); + * It will however work just fine with bool/_Bool while retaining the + * notion of having a boolean value. + * + * Also, add the defines for "true" and "false". Those are nicely highlighted by the editor + * as special types, contrary to glib's "TRUE"/"FALSE". + */ + +#ifndef bool +#define bool _Bool +#define true 1 +#define false 0 +#endif + + +#ifdef _G_BOOLEAN_EXPR +/* g_assert() uses G_LIKELY(), which in turn uses _G_BOOLEAN_EXPR(). + * As glib's implementation uses a local variable _g_boolean_var_, + * we cannot do + * g_assert (some_macro ()); + * where some_macro() itself expands to ({g_assert(); ...}). + * In other words, you cannot have a g_assert() inside a g_assert() + * without getting a -Werror=shadow failure. + * + * Workaround that by re-defining _G_BOOLEAN_EXPR() + **/ +#undef _G_BOOLEAN_EXPR +#define __NM_G_BOOLEAN_EXPR_IMPL(v, expr) \ + ({ \ + int NM_UNIQ_T(V, v); \ + \ + if (expr) \ + NM_UNIQ_T(V, v) = 1; \ + else \ + NM_UNIQ_T(V, v) = 0; \ + NM_UNIQ_T(V, v); \ + }) +#define _G_BOOLEAN_EXPR(expr) __NM_G_BOOLEAN_EXPR_IMPL (NM_UNIQ, expr) +#endif + +/*****************************************************************************/ + +/** + * nm_steal_int: + * @p_val: pointer to an int type. + * + * Returns: *p_val and sets *p_val to zero the same time. + * Accepts %NULL, in which case also numeric 0 will be returned. + */ +#define nm_steal_int(p_val) \ + ({ \ + typeof (p_val) const _p_val = (p_val); \ + typeof (*_p_val) _val = 0; \ + \ + if ( _p_val \ + && (_val = *_p_val)) { \ + *_p_val = 0; \ + } \ + _val; \ + }) + +static inline int +nm_steal_fd (int *p_fd) +{ + int fd; + + if ( p_fd + && ((fd = *p_fd) >= 0)) { + *p_fd = -1; + return fd; + } + return -1; +} + +/** + * nm_close: + * + * Like close() but throws an assertion if the input fd is + * invalid. Closing an invalid fd is a programming error, so + * it's better to catch it early. + */ +static inline int +nm_close (int fd) +{ + int r; + + r = close (fd); + nm_assert (r != -1 || fd < 0 || errno != EBADF); + return r; +} + +#endif /* __NM_MACROS_INTERNAL_H__ */ diff --git a/tests/network/nm-utils/nm-shared-utils.h b/tests/network/nm-utils/nm-shared-utils.h new file mode 100644 index 000000000..e69de29bb diff --git a/tests/network/nm-utils/nm-test-libnm-utils.h b/tests/network/nm-utils/nm-test-libnm-utils.h new file mode 100644 index 000000000..2ea781b80 --- /dev/null +++ b/tests/network/nm-utils/nm-test-libnm-utils.h @@ -0,0 +1,105 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + * Copyright 2014 - 2015 Red Hat, Inc. + */ + +#include "NetworkManager.h" + +#include "nm-test-utils.h" + +#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB +#include "nm-dbus-glib-types.h" +#endif + +/*****************************************************************************/ + +typedef struct { + GDBusConnection *bus; + GDBusProxy *proxy; + GPid pid; + int keepalive_fd; +#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB + struct { + DBusGConnection *bus; + } libdbus; +#endif +} NMTstcServiceInfo; + +NMTstcServiceInfo *nmtstc_service_init (void); +void nmtstc_service_cleanup (NMTstcServiceInfo *info); + +static inline void _nmtstc_auto_service_cleanup (NMTstcServiceInfo **info) +{ + if (info && *info) { + nmtstc_service_cleanup (*info); + *info = NULL; + } +} + +#define NMTSTC_SERVICE_INFO_SETUP(sinfo) \ + NM_PRAGMA_WARNING_DISABLE ("-Wunused-variable") \ + __attribute__ ((cleanup(_nmtstc_auto_service_cleanup))) NMTstcServiceInfo *sinfo = nmtstc_service_init (); \ + NM_PRAGMA_WARNING_REENABLE + +/*****************************************************************************/ + +#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB + +#include "nm-client.h" +#include "nm-remote-settings.h" + +NMClient *nmtstc_nm_client_new (void); +NMRemoteSettings *nmtstc_nm_remote_settings_new (void); + +#else + +NMDevice *nmtstc_service_add_device (NMTstcServiceInfo *info, + NMClient *client, + const char *method, + const char *ifname); + +NMDevice * nmtstc_service_add_wired_device (NMTstcServiceInfo *sinfo, + NMClient *client, + const char *ifname, + const char *hwaddr, + const char **subchannels); + +#endif + +/*****************************************************************************/ + +void nmtstc_service_add_connection (NMTstcServiceInfo *sinfo, + NMConnection *connection, + gboolean verify_connection, + char **out_path); + +void nmtstc_service_add_connection_variant (NMTstcServiceInfo *sinfo, + GVariant *connection, + gboolean verify_connection, + char **out_path); + +void nmtstc_service_update_connection (NMTstcServiceInfo *sinfo, + const char *path, + NMConnection *connection, + gboolean verify_connection); + +void nmtstc_service_update_connection_variant (NMTstcServiceInfo *sinfo, + const char *path, + GVariant *connection, + gboolean verify_connection); + diff --git a/tests/network/nm-utils/nm-test-utils-impl.c b/tests/network/nm-utils/nm-test-utils-impl.c new file mode 100644 index 000000000..998d792a2 --- /dev/null +++ b/tests/network/nm-utils/nm-test-utils-impl.c @@ -0,0 +1,457 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * 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, 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. + * + * Copyright 2010 - 2015 Red Hat, Inc. + * + */ + +#include "nm-default.h" + +#include + +#include "NetworkManager.h" +#include "nm-dbus-compat.h" + +#include "nm-test-libnm-utils.h" + +/*****************************************************************************/ + +static gboolean +name_exists (GDBusConnection *c, const char *name) +{ + GVariant *reply; + gboolean exists = FALSE; + + reply = g_dbus_connection_call_sync (c, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetNameOwner", + g_variant_new ("(s)", name), + NULL, + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, + NULL, + NULL); + if (reply != NULL) { + exists = TRUE; + g_variant_unref (reply); + } + + return exists; +} + +#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB +static DBusGProxy * +_libdbus_create_proxy_test (DBusGConnection *bus) +{ + DBusGProxy *proxy; + + proxy = dbus_g_proxy_new_for_name (bus, + NM_DBUS_SERVICE, + NM_DBUS_PATH, + "org.freedesktop.NetworkManager.LibnmGlibTest"); + g_assert (proxy); + + dbus_g_proxy_set_default_timeout (proxy, G_MAXINT); + + return proxy; +} +#endif + +NMTstcServiceInfo * +nmtstc_service_init (void) +{ + NMTstcServiceInfo *info; + const char *args[] = { TEST_NM_PYTHON, TEST_NM_SERVICE, NULL }; + GError *error = NULL; + int i; + + info = g_malloc0 (sizeof (*info)); + + info->bus = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + g_assert_no_error (error); + + /* Spawn the test service. info->keepalive_fd will be a pipe to the service's + * stdin; if it closes, the service will exit immediately. We use this to + * make sure the service exits if the test program crashes. + */ + g_spawn_async_with_pipes (NULL, (char **) args, NULL, + G_SPAWN_SEARCH_PATH, + NULL, NULL, + &info->pid, &info->keepalive_fd, NULL, NULL, &error); + g_assert_no_error (error); + + /* Wait until the service is registered on the bus */ + for (i = 1000; i > 0; i--) { + if (name_exists (info->bus, "org.freedesktop.NetworkManager")) + break; + g_usleep (G_USEC_PER_SEC / 50); + } + g_assert (i > 0); + + /* Grab a proxy to our fake NM service to trigger tests */ + info->proxy = g_dbus_proxy_new_sync (info->bus, + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS | + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + NULL, + NM_DBUS_SERVICE, + NM_DBUS_PATH, + "org.freedesktop.NetworkManager.LibnmGlibTest", + NULL, &error); + g_assert_no_error (error); + +#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB + info->libdbus.bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + g_assert_no_error (error); + g_assert (info->libdbus.bus); +#endif + return info; +} + +void +nmtstc_service_cleanup (NMTstcServiceInfo *info) +{ + int i; + + g_object_unref (info->proxy); + kill (info->pid, SIGTERM); + + /* Wait until the bus notices the service is gone */ + for (i = 100; i > 0; i--) { + if (!name_exists (info->bus, "org.freedesktop.NetworkManager")) + break; + g_usleep (G_USEC_PER_SEC / 50); + } + g_assert (i > 0); + + g_object_unref (info->bus); + nm_close (info->keepalive_fd); + +#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB + g_clear_pointer (&info->libdbus.bus, dbus_g_connection_unref); +#endif + + memset (info, 0, sizeof (*info)); + g_free (info); +} + +#if !((NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB) +typedef struct { + GMainLoop *loop; + const char *ifname; + char *path; + NMDevice *device; +} AddDeviceInfo; + +static void +device_added_cb (NMClient *client, + NMDevice *device, + gpointer user_data) +{ + AddDeviceInfo *info = user_data; + + g_assert (device); + g_assert_cmpstr (nm_object_get_path (NM_OBJECT (device)), ==, info->path); + g_assert_cmpstr (nm_device_get_iface (device), ==, info->ifname); + + info->device = device; + g_main_loop_quit (info->loop); +} + +static gboolean +timeout (gpointer user_data) +{ + g_assert_not_reached (); + return G_SOURCE_REMOVE; +} + +static GVariant * +call_add_wired_device (GDBusProxy *proxy, const char *ifname, const char *hwaddr, + const char **subchannels, GError **error) +{ + const char *empty[] = { NULL }; + + if (!hwaddr) + hwaddr = "/"; + if (!subchannels) + subchannels = empty; + + return g_dbus_proxy_call_sync (proxy, + "AddWiredDevice", + g_variant_new ("(ss^as)", ifname, hwaddr, subchannels), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + error); +} + +static GVariant * +call_add_device (GDBusProxy *proxy, const char *method, const char *ifname, GError **error) +{ + return g_dbus_proxy_call_sync (proxy, + method, + g_variant_new ("(s)", ifname), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + error); +} + +static NMDevice * +add_device_common (NMTstcServiceInfo *sinfo, NMClient *client, + const char *method, const char *ifname, + const char *hwaddr, const char **subchannels) +{ + AddDeviceInfo info; + GError *error = NULL; + GVariant *ret; + guint timeout_id; + + if (g_strcmp0 (method, "AddWiredDevice") == 0) + ret = call_add_wired_device (sinfo->proxy, ifname, hwaddr, subchannels, &error); + else + ret = call_add_device (sinfo->proxy, method, ifname, &error); + + g_assert_no_error (error); + g_assert (ret); + g_assert_cmpstr (g_variant_get_type_string (ret), ==, "(o)"); + g_variant_get (ret, "(o)", &info.path); + g_variant_unref (ret); + + /* Wait for libnm to find the device */ + info.ifname = ifname; + info.loop = g_main_loop_new (NULL, FALSE); + g_signal_connect (client, "device-added", + G_CALLBACK (device_added_cb), &info); + timeout_id = g_timeout_add_seconds (5, timeout, NULL); + g_main_loop_run (info.loop); + + g_source_remove (timeout_id); + g_signal_handlers_disconnect_by_func (client, device_added_cb, &info); + g_free (info.path); + g_main_loop_unref (info.loop); + + return info.device; +} + +NMDevice * +nmtstc_service_add_device (NMTstcServiceInfo *sinfo, NMClient *client, + const char *method, const char *ifname) +{ + return add_device_common (sinfo, client, method, ifname, NULL, NULL); +} + +NMDevice * +nmtstc_service_add_wired_device (NMTstcServiceInfo *sinfo, NMClient *client, + const char *ifname, const char *hwaddr, + const char **subchannels) +{ + return add_device_common (sinfo, client, "AddWiredDevice", ifname, hwaddr, subchannels); +} +#endif + +void +nmtstc_service_add_connection (NMTstcServiceInfo *sinfo, + NMConnection *connection, + gboolean verify_connection, + char **out_path) +{ +#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB + gs_unref_hashtable GHashTable *new_settings = NULL; + gboolean success; + gs_free_error GError *error = NULL; + gs_free char *path = NULL; + gs_unref_object DBusGProxy *proxy = NULL; + + g_assert (sinfo); + g_assert (NM_IS_CONNECTION (connection)); + + new_settings = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); + + proxy = _libdbus_create_proxy_test (sinfo->libdbus.bus); + + success = dbus_g_proxy_call (proxy, + "AddConnection", + &error, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, new_settings, + G_TYPE_BOOLEAN, verify_connection, + G_TYPE_INVALID, + DBUS_TYPE_G_OBJECT_PATH, &path, + G_TYPE_INVALID); + g_assert_no_error (error); + g_assert (success); + + g_assert (path && *path); + + if (out_path) + *out_path = g_strdup (path); +#else + nmtstc_service_add_connection_variant (sinfo, + nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL), + verify_connection, + out_path); +#endif +} + +void +nmtstc_service_add_connection_variant (NMTstcServiceInfo *sinfo, + GVariant *connection, + gboolean verify_connection, + char **out_path) +{ + GVariant *result; + GError *error = NULL; + + g_assert (sinfo); + g_assert (G_IS_DBUS_PROXY (sinfo->proxy)); + g_assert (g_variant_is_of_type (connection, G_VARIANT_TYPE ("a{sa{sv}}"))); + + result = g_dbus_proxy_call_sync (sinfo->proxy, + "AddConnection", + g_variant_new ("(vb)", connection, verify_connection), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error (error); + g_assert (g_variant_is_of_type (result, G_VARIANT_TYPE ("(o)"))); + if (out_path) + g_variant_get (result, "(o)", out_path); + g_variant_unref (result); +} + +void +nmtstc_service_update_connection (NMTstcServiceInfo *sinfo, + const char *path, + NMConnection *connection, + gboolean verify_connection) +{ + if (!path) + path = nm_connection_get_path (connection); + g_assert (path); + +#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB + { + gs_unref_hashtable GHashTable *new_settings = NULL; + gboolean success; + gs_free_error GError *error = NULL; + gs_unref_object DBusGProxy *proxy = NULL; + + g_assert (sinfo); + g_assert (NM_IS_CONNECTION (connection)); + + new_settings = nm_connection_to_hash (connection, NM_SETTING_HASH_FLAG_ALL); + + proxy = _libdbus_create_proxy_test (sinfo->libdbus.bus); + + success = dbus_g_proxy_call (proxy, + "UpdateConnection", + &error, + DBUS_TYPE_G_OBJECT_PATH, path, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, new_settings, + G_TYPE_BOOLEAN, verify_connection, + G_TYPE_INVALID, + G_TYPE_INVALID); + g_assert_no_error (error); + g_assert (success); + } +#else + nmtstc_service_update_connection_variant (sinfo, + path, + nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL), + verify_connection); +#endif +} + +void +nmtstc_service_update_connection_variant (NMTstcServiceInfo *sinfo, + const char *path, + GVariant *connection, + gboolean verify_connection) +{ + GVariant *result; + GError *error = NULL; + + g_assert (sinfo); + g_assert (G_IS_DBUS_PROXY (sinfo->proxy)); + g_assert (g_variant_is_of_type (connection, G_VARIANT_TYPE ("a{sa{sv}}"))); + g_assert (path && path[0] == '/'); + + result = g_dbus_proxy_call_sync (sinfo->proxy, + "UpdateConnection", + g_variant_new ("(ovb)", path, connection, verify_connection), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error (error); + g_assert (g_variant_is_of_type (result, G_VARIANT_TYPE ("()"))); + g_variant_unref (result); +} + +/*****************************************************************************/ + +#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_LIBNM_GLIB +NMClient * +nmtstc_nm_client_new (void) +{ + NMClient *client; + DBusGConnection *bus; + GError *error = NULL; + gboolean success; + + bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + g_assert_no_error (error); + g_assert (bus); + + client = g_object_new (NM_TYPE_CLIENT, + NM_OBJECT_DBUS_CONNECTION, bus, + NM_OBJECT_DBUS_PATH, NM_DBUS_PATH, + NULL); + g_assert (client != NULL); + + dbus_g_connection_unref (bus); + + success = g_initable_init (G_INITABLE (client), NULL, &error); + g_assert_no_error (error); + g_assert (success == TRUE); + + return client; +} + +NMRemoteSettings * +nmtstc_nm_remote_settings_new (void) +{ + NMRemoteSettings *settings; + DBusGConnection *bus; + GError *error = NULL; + + bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error); + g_assert_no_error (error); + g_assert (bus); + + settings = nm_remote_settings_new (bus); + g_assert (settings); + + dbus_g_connection_unref (bus); + + return settings; +} +#endif + +/*****************************************************************************/ diff --git a/tests/network/nm-utils/nm-test-utils.h b/tests/network/nm-utils/nm-test-utils.h new file mode 100644 index 000000000..e69de29bb diff --git a/tests/network/nm-utils/test-networkmanager-service.py b/tests/network/nm-utils/test-networkmanager-service.py new file mode 100755 index 000000000..68097778e --- /dev/null +++ b/tests/network/nm-utils/test-networkmanager-service.py @@ -0,0 +1,1341 @@ +#!/usr/bin/env python +# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + +from __future__ import print_function + +from gi.repository import GLib +import sys +import dbus +import dbus.service +import dbus.mainloop.glib +import random +import collections +import uuid + +mainloop = GLib.MainLoop() + +# NM State +NM_STATE_UNKNOWN = 0 +NM_STATE_ASLEEP = 10 +NM_STATE_DISCONNECTED = 20 +NM_STATE_DISCONNECTING = 30 +NM_STATE_CONNECTING = 40 +NM_STATE_CONNECTED_LOCAL = 50 +NM_STATE_CONNECTED_SITE = 60 +NM_STATE_CONNECTED_GLOBAL = 70 + +# Device state +NM_DEVICE_STATE_UNKNOWN = 0 +NM_DEVICE_STATE_UNMANAGED = 10 +NM_DEVICE_STATE_UNAVAILABLE = 20 +NM_DEVICE_STATE_DISCONNECTED = 30 +NM_DEVICE_STATE_PREPARE = 40 +NM_DEVICE_STATE_CONFIG = 50 +NM_DEVICE_STATE_NEED_AUTH = 60 +NM_DEVICE_STATE_IP_CONFIG = 70 +NM_DEVICE_STATE_IP_CHECK = 80 +NM_DEVICE_STATE_SECONDARIES = 90 +NM_DEVICE_STATE_ACTIVATED = 100 +NM_DEVICE_STATE_DEACTIVATING = 110 +NM_DEVICE_STATE_FAILED = 120 + +# Device type +NM_DEVICE_TYPE_UNKNOWN = 0 +NM_DEVICE_TYPE_ETHERNET = 1 +NM_DEVICE_TYPE_WIFI = 2 +NM_DEVICE_TYPE_UNUSED1 = 3 +NM_DEVICE_TYPE_UNUSED2 = 4 +NM_DEVICE_TYPE_BT = 5 +NM_DEVICE_TYPE_OLPC_MESH = 6 +NM_DEVICE_TYPE_WIMAX = 7 +NM_DEVICE_TYPE_MODEM = 8 +NM_DEVICE_TYPE_INFINIBAND = 9 +NM_DEVICE_TYPE_BOND = 10 +NM_DEVICE_TYPE_VLAN = 11 +NM_DEVICE_TYPE_ADSL = 12 +NM_DEVICE_TYPE_BRIDGE = 13 +NM_DEVICE_TYPE_GENERIC = 14 +NM_DEVICE_TYPE_TEAM = 15 + +# AC state +NM_ACTIVE_CONNECTION_STATE_UNKNOWN = 0 +NM_ACTIVE_CONNECTION_STATE_ACTIVATING = 1 +NM_ACTIVE_CONNECTION_STATE_ACTIVATED = 2 +NM_ACTIVE_CONNECTION_STATE_DEACTIVATING = 3 +NM_ACTIVE_CONNECTION_STATE_DEACTIVATED = 4 + +######################################################### +IFACE_DBUS = 'org.freedesktop.DBus' + +class UnknownInterfaceException(dbus.DBusException): + _dbus_error_name = IFACE_DBUS + '.UnknownInterface' + +class UnknownPropertyException(dbus.DBusException): + _dbus_error_name = IFACE_DBUS + '.UnknownProperty' + +def to_path_array(src): + array = dbus.Array([], signature=dbus.Signature('o')) + for o in src: + array.append(to_path(o)) + return array + +def to_path(src): + if src: + return dbus.ObjectPath(src.path) + return dbus.ObjectPath("/") + +class ExportedObj(dbus.service.Object): + + DBusInterface = collections.namedtuple('DBusInterface', ['dbus_iface', 'get_props_func', 'prop_changed_func']) + + def __init__(self, bus, object_path): + dbus.service.Object.__init__(self, bus, object_path) + self._bus = bus + self.path = object_path + self.__ensure_dbus_ifaces() + object_manager.add_object(self) + + def __ensure_dbus_ifaces(self): + if not hasattr(self, '_ExportedObj__dbus_ifaces'): + self.__dbus_ifaces = {} + + def add_dbus_interface(self, dbus_iface, get_props_func, prop_changed_func): + self.__ensure_dbus_ifaces() + self.__dbus_ifaces[dbus_iface] = ExportedObj.DBusInterface(dbus_iface, get_props_func, prop_changed_func) + + def __dbus_interface_get(self, dbus_iface): + if dbus_iface not in self.__dbus_ifaces: + raise UnknownInterfaceException() + return self.__dbus_ifaces[dbus_iface] + + def _dbus_property_get(self, dbus_iface, propname = None): + props = self.__dbus_interface_get(dbus_iface).get_props_func() + if propname is None: + return props + if propname not in props: + raise UnknownPropertyException() + return props[propname] + + def _dbus_property_notify(self, dbus_iface, propname): + prop = self._dbus_property_get(dbus_iface, propname) + self.__dbus_interface_get(dbus_iface).prop_changed_func(self, { propname: prop }) + ExportedObj.PropertiesChanged(self, dbus_iface, { propname: prop }, []) + + @dbus.service.signal(dbus.PROPERTIES_IFACE, signature='sa{sv}as') + def PropertiesChanged(self, iface, changed, invalidated): + pass + + @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}') + def GetAll(self, dbus_iface): + return self._dbus_property_get(dbus_iface) + + @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v') + def Get(self, dbus_iface, name): + return self._dbus_property_get(dbus_iface, name) + + def get_managed_ifaces(self): + my_ifaces = {} + for iface in self.__dbus_ifaces: + my_ifaces[iface] = self.__dbus_ifaces[iface].get_props_func() + return self.path, my_ifaces + + def remove_from_connection(self): + object_manager.remove_object(self) + dbus.service.Object.remove_from_connection(self) + +################################################################### +IFACE_DEVICE = 'org.freedesktop.NetworkManager.Device' + +class NotSoftwareException(dbus.DBusException): + _dbus_error_name = IFACE_DEVICE + '.NotSoftware' + +PD_UDI = "Udi" +PD_IFACE = "Interface" +PD_DRIVER = "Driver" +PD_STATE = "State" +PD_ACTIVE_CONNECTION = "ActiveConnection" +PD_IP4_CONFIG = "Ip4Config" +PD_IP6_CONFIG = "Ip6Config" +PD_DHCP4_CONFIG = "Dhcp4Config" +PD_DHCP6_CONFIG = "Dhcp6Config" +PD_MANAGED = "Managed" +PD_AUTOCONNECT = "Autoconnect" +PD_DEVICE_TYPE = "DeviceType" +PD_AVAILABLE_CONNECTIONS = "AvailableConnections" + +class Device(ExportedObj): + counter = 1 + + def __init__(self, bus, iface, devtype): + object_path = "/org/freedesktop/NetworkManager/Devices/%d" % Device.counter + Device.counter = Device.counter + 1 + + self.iface = iface + self.udi = "/sys/devices/virtual/%s" % iface + self.devtype = devtype + self.active_connection = None + self.state = NM_DEVICE_STATE_UNAVAILABLE + self.ip4_config = None + self.ip6_config = None + self.dhcp4_config = None + self.dhcp6_config = None + self.available_connections = [] + + self.add_dbus_interface(IFACE_DEVICE, self.__get_props, Device.PropertiesChanged) + ExportedObj.__init__(self, bus, object_path) + + # Properties interface + def __get_props(self): + props = {} + props[PD_UDI] = self.udi + props[PD_IFACE] = self.iface + props[PD_DRIVER] = "virtual" + props[PD_STATE] = dbus.UInt32(self.state) + props[PD_ACTIVE_CONNECTION] = to_path(self.active_connection) + props[PD_IP4_CONFIG] = to_path(self.ip4_config) + props[PD_IP6_CONFIG] = to_path(self.ip6_config) + props[PD_DHCP4_CONFIG] = to_path(self.dhcp4_config) + props[PD_DHCP6_CONFIG] = to_path(self.dhcp6_config) + props[PD_MANAGED] = True + props[PD_AUTOCONNECT] = True + props[PD_DEVICE_TYPE] = dbus.UInt32(self.devtype) + props[PD_AVAILABLE_CONNECTIONS] = to_path_array(self.available_connections) + return props + + # methods + @dbus.service.method(dbus_interface=IFACE_DEVICE, in_signature='', out_signature='') + def Disconnect(self): + pass + + @dbus.service.method(dbus_interface=IFACE_DEVICE, in_signature='', out_signature='') + def Delete(self): + # We don't currently support any software device types, so... + raise NotSoftwareException() + pass + + def __notify(self, propname): + self._dbus_property_notify(IFACE_DEVICE, propname) + + @dbus.service.signal(IFACE_DEVICE, signature='a{sv}') + def PropertiesChanged(self, changed): + pass + + def set_active_connection(self, ac): + self.active_connection = ac + self.__notify(PD_ACTIVE_CONNECTION) + +################################################################### + +def random_mac(): + return '%02X:%02X:%02X:%02X:%02X:%02X' % ( + random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), + random.randint(0, 255), random.randint(0, 255), random.randint(0, 255) + ) + +################################################################### +IFACE_WIRED = 'org.freedesktop.NetworkManager.Device.Wired' + +PE_HW_ADDRESS = "HwAddress" +PE_PERM_HW_ADDRESS = "PermHwAddress" +PE_SPEED = "Speed" +PE_CARRIER = "Carrier" +PE_S390_SUBCHANNELS = "S390Subchannels" + +class WiredDevice(Device): + def __init__(self, bus, iface, mac, subchannels): + + if mac is None: + self.mac = random_mac() + else: + self.mac = mac + self.carrier = False + self.s390_subchannels = subchannels + + self.add_dbus_interface(IFACE_WIRED, self.__get_props, WiredDevice.PropertiesChanged) + Device.__init__(self, bus, iface, NM_DEVICE_TYPE_ETHERNET) + + # Properties interface + def __get_props(self): + props = {} + props[PE_HW_ADDRESS] = self.mac + props[PE_PERM_HW_ADDRESS] = self.mac + props[PE_SPEED] = dbus.UInt32(100) + props[PE_CARRIER] = self.carrier + props[PE_S390_SUBCHANNELS] = self.s390_subchannels + return props + + def __notify(self, propname): + self._dbus_property_notify(IFACE_WIRED, propname) + + @dbus.service.signal(IFACE_WIRED, signature='a{sv}') + def PropertiesChanged(self, changed): + pass + +################################################################### +IFACE_VLAN = 'org.freedesktop.NetworkManager.Device.Vlan' + +PV_HW_ADDRESS = "HwAddress" +PV_CARRIER = "Carrier" +PV_VLAN_ID = "VlanId" + +class VlanDevice(Device): + def __init__(self, bus, iface): + self.mac = random_mac() + self.carrier = False + self.vlan_id = 1 + + self.add_dbus_interface(IFACE_VLAN, self.__get_props, VlanDevice.PropertiesChanged) + Device.__init__(self, bus, iface, NM_DEVICE_TYPE_VLAN) + + # Properties interface + def __get_props(self): + props = {} + props[PV_HW_ADDRESS] = self.mac + props[PV_CARRIER] = self.carrier + props[PV_VLAN_ID] = dbus.UInt32(self.vlan_id) + return props + + @dbus.service.signal(IFACE_VLAN, signature='a{sv}') + def PropertiesChanged(self, changed): + pass + +################################################################### +IFACE_WIFI_AP = 'org.freedesktop.NetworkManager.AccessPoint' + +PP_FLAGS = "Flags" +PP_WPA_FLAGS = "WpaFlags" +PP_RSN_FLAGS = "RsnFlags" +PP_SSID = "Ssid" +PP_FREQUENCY = "Frequency" +PP_HW_ADDRESS = "HwAddress" +PP_MODE = "Mode" +PP_MAX_BITRATE = "MaxBitrate" +PP_STRENGTH = "Strength" + +class WifiAp(ExportedObj): + counter = 0 + + def __init__(self, bus, ssid, mac, flags, wpaf, rsnf, freq): + path = "/org/freedesktop/NetworkManager/AccessPoint/%d" % WifiAp.counter + WifiAp.counter = WifiAp.counter + 1 + + self.ssid = ssid + if mac: + self.bssid = mac + else: + self.bssid = random_mac() + self.flags = flags + self.wpaf = wpaf + self.rsnf = rsnf + self.freq = freq + self.strength = random.randint(0, 100) + self.strength_id = GLib.timeout_add_seconds(10, self.strength_cb, None) + + self.add_dbus_interface(IFACE_WIFI_AP, self.__get_props, WifiAp.PropertiesChanged) + ExportedObj.__init__(self, bus, path) + + def __del__(self): + if self.strength_id > 0: + GLib.source_remove(self.strength_id) + self.strength_id = 0 + + def strength_cb(self, ignored): + self.strength = random.randint(0, 100) + self.__notify(PP_STRENGTH) + return True + + # Properties interface + def __get_props(self): + props = {} + props[PP_FLAGS] = dbus.UInt32(self.flags) + props[PP_WPA_FLAGS] = dbus.UInt32(self.wpaf) + props[PP_RSN_FLAGS] = dbus.UInt32(self.rsnf) + props[PP_SSID] = dbus.ByteArray(self.ssid.encode('utf-8')) + props[PP_FREQUENCY] = dbus.UInt32(self.freq) + props[PP_HW_ADDRESS] = self.bssid + props[PP_MODE] = dbus.UInt32(2) # NM_802_11_MODE_INFRA + props[PP_MAX_BITRATE] = dbus.UInt32(54000) + props[PP_STRENGTH] = dbus.Byte(self.strength) + return props + + def __notify(self, propname): + self._dbus_property_notify(IFACE_WIFI_AP, propname) + + @dbus.service.signal(IFACE_WIFI_AP, signature='a{sv}') + def PropertiesChanged(self, changed): + pass + +################################################################### +IFACE_WIFI = 'org.freedesktop.NetworkManager.Device.Wireless' + +class ApNotFoundException(dbus.DBusException): + _dbus_error_name = IFACE_WIFI + '.AccessPointNotFound' + +PW_HW_ADDRESS = "HwAddress" +PW_PERM_HW_ADDRESS = "PermHwAddress" +PW_MODE = "Mode" +PW_BITRATE = "Bitrate" +PW_ACCESS_POINTS = "AccessPoints" +PW_ACTIVE_ACCESS_POINT = "ActiveAccessPoint" +PW_WIRELESS_CAPABILITIES = "WirelessCapabilities" + +class WifiDevice(Device): + def __init__(self, bus, iface): + self.mac = random_mac() + self.aps = [] + self.active_ap = None + + self.add_dbus_interface(IFACE_WIFI, self.__get_props, WifiDevice.PropertiesChanged) + Device.__init__(self, bus, iface, NM_DEVICE_TYPE_WIFI) + + # methods + @dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='', out_signature='ao') + def GetAccessPoints(self): + # only include non-hidden APs + return to_path_array([a for a in self.aps if a.ssid]) + + @dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='', out_signature='ao') + def GetAllAccessPoints(self): + # include all APs including hidden ones + return to_path_array(self.aps) + + @dbus.service.method(dbus_interface=IFACE_WIFI, in_signature='a{sv}', out_signature='') + def RequestScan(self, props): + pass + + @dbus.service.signal(IFACE_WIFI, signature='o') + def AccessPointAdded(self, ap_path): + pass + + def add_ap(self, ap): + self.aps.append(ap) + self.__notify(PW_ACCESS_POINTS) + self.AccessPointAdded(to_path(ap)) + + @dbus.service.signal(IFACE_WIFI, signature='o') + def AccessPointRemoved(self, ap_path): + pass + + def remove_ap(self, ap): + self.aps.remove(ap) + self.__notify(PW_ACCESS_POINTS) + self.AccessPointRemoved(to_path(ap)) + + # Properties interface + def __get_props(self): + props = {} + props[PW_HW_ADDRESS] = self.mac + props[PW_PERM_HW_ADDRESS] = self.mac + props[PW_MODE] = dbus.UInt32(3) # NM_802_11_MODE_INFRA + props[PW_BITRATE] = dbus.UInt32(21000) + props[PW_WIRELESS_CAPABILITIES] = dbus.UInt32(0xFF) + props[PW_ACCESS_POINTS] = to_path_array(self.aps) + props[PW_ACTIVE_ACCESS_POINT] = to_path(self.active_ap) + return props + + def __notify(self, propname): + self._dbus_property_notify(IFACE_WIFI, propname) + + @dbus.service.signal(IFACE_WIFI, signature='a{sv}') + def PropertiesChanged(self, changed): + pass + + # test functions + def add_test_ap(self, ssid, mac): + ap = WifiAp(self._bus, ssid, mac, 0x1, 0x1cc, 0x1cc, 2412) + self.add_ap(ap) + return ap + + def remove_ap_by_path(self, path): + for ap in self.aps: + if ap.path == path: + self.remove_ap(ap) + return + raise ApNotFoundException("AP %s not found" % path) + + +################################################################### +IFACE_WIMAX_NSP = 'org.freedesktop.NetworkManager.WiMax.Nsp' + +PN_NAME = "Name" +PN_SIGNAL_QUALITY = "SignalQuality" +PN_NETWORK_TYPE = "NetworkType" + +class WimaxNsp(ExportedObj): + counter = 0 + + def __init__(self, bus, name): + path = "/org/freedesktop/NetworkManager/Nsp/%d" % WimaxNsp.counter + WimaxNsp.counter = WimaxNsp.counter + 1 + + self.name = name + self.strength = random.randint(0, 100) + self.strength_id = GLib.timeout_add_seconds(10, self.strength_cb, None) + + self.add_dbus_interface(IFACE_WIMAX_NSP, self.__get_props, WimaxNsp.PropertiesChanged) + ExportedObj.__init__(self, bus, path) + + def __del__(self): + if self.strength_id > 0: + GLib.source_remove(self.strength_id) + self.strength_id = 0 + + def strength_cb(self, ignored): + self.strength = random.randint(0, 100) + self.__notify(PN_SIGNAL_QUALITY) + return True + + # Properties interface + def __get_props(self): + props = {} + props[PN_NAME] = self.name + props[PN_SIGNAL_QUALITY] = dbus.UInt32(self.strength) + props[PN_NETWORK_TYPE] = dbus.UInt32(0x1) # NM_WIMAX_NSP_NETWORK_TYPE_HOME + return props + + def __notify(self, propname): + self._dbus_property_notify(IFACE_WIMAX_NSP, propname) + + @dbus.service.signal(IFACE_WIMAX_NSP, signature='a{sv}') + def PropertiesChanged(self, changed): + pass + +################################################################### +IFACE_WIMAX = 'org.freedesktop.NetworkManager.Device.WiMax' + +class NspNotFoundException(dbus.DBusException): + _dbus_error_name = IFACE_WIMAX + '.NspNotFound' + +PX_NSPS = "Nsps" +PX_HW_ADDRESS = "HwAddress" +PX_CENTER_FREQUENCY = "CenterFrequency" +PX_RSSI = "Rssi" +PX_CINR = "Cinr" +PX_TX_POWER = "TxPower" +PX_BSID = "Bsid" +PX_ACTIVE_NSP = "ActiveNsp" + +class WimaxDevice(Device): + def __init__(self, bus, iface): + self.mac = random_mac() + self.bsid = random_mac() + self.nsps = [] + self.active_nsp = None + + self.add_dbus_interface(IFACE_WIMAX, self.__get_props, WimaxDevice.PropertiesChanged) + Device.__init__(self, bus, iface, NM_DEVICE_TYPE_WIMAX) + + # methods + @dbus.service.method(dbus_interface=IFACE_WIMAX, in_signature='', out_signature='ao') + def GetNspList(self): + # include all APs including hidden ones + return to_path_array(self.nsps) + + @dbus.service.signal(IFACE_WIMAX, signature='o') + def NspAdded(self, nsp_path): + pass + + def add_nsp(self, nsp): + self.nsps.append(nsp) + self.__notify(PX_NSPS) + self.NspAdded(to_path(nsp)) + + @dbus.service.signal(IFACE_WIMAX, signature='o') + def NspRemoved(self, nsp_path): + pass + + def remove_nsp(self, nsp): + self.nsps.remove(nsp) + self.__notify(PX_NSPS) + self.NspRemoved(to_path(nsp)) + + # Properties interface + def __get_props(self): + props = {} + props[PX_HW_ADDRESS] = self.mac + props[PX_CENTER_FREQUENCY] = dbus.UInt32(2525) + props[PX_RSSI] = dbus.Int32(-48) + props[PX_CINR] = dbus.Int32(24) + props[PX_TX_POWER] = dbus.Int32(9) + props[PX_BSID] = self.bsid + props[PX_NSPS] = to_path_array(self.nsps) + props[PX_ACTIVE_NSP] = to_path(self.active_nsp) + return props + + def __notify(self, propname): + self._dbus_property_notify(IFACE_WIMAX, propname) + + @dbus.service.signal(IFACE_WIMAX, signature='a{sv}') + def PropertiesChanged(self, changed): + pass + + # test functions + def add_test_nsp(self, name): + nsp = WimaxNsp(self._bus, name) + self.add_nsp(nsp) + return nsp + + def remove_nsp_by_path(self, path): + for nsp in self.nsps: + if nsp.path == path: + self.remove_nsp(nsp) + return + raise NspNotFoundException("NSP %s not found" % path) + +################################################################### +IFACE_ACTIVE_CONNECTION = 'org.freedesktop.NetworkManager.Connection.Active' + +PAC_CONNECTION = "Connection" +PAC_SPECIFIC_OBJECT = "SpecificObject" +PAC_ID = "Id" +PAC_UUID = "Uuid" +PAC_TYPE = "Type" +PAC_DEVICES = "Devices" +PAC_STATE = "State" +PAC_DEFAULT = "Default" +PAC_IP4CONFIG = "Ip4Config" +PAC_DHCP4CONFIG = "Dhcp4Config" +PAC_DEFAULT6 = "Default6" +PAC_IP6CONFIG = "Ip6Config" +PAC_DHCP6CONFIG = "Dhcp6Config" +PAC_VPN = "Vpn" +PAC_MASTER = "Master" + +class ActiveConnection(ExportedObj): + counter = 1 + + def __init__(self, bus, device, connection, specific_object): + object_path = "/org/freedesktop/NetworkManager/ActiveConnection/%d" % ActiveConnection.counter + ActiveConnection.counter = ActiveConnection.counter + 1 + + self.device = device + self.conn = connection + self.specific_object = specific_object + self.state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN + self.default = False + self.ip4config = None + self.dhcp4config = None + self.default6 = False + self.ip6config = None + self.dhcp6config = None + self.vpn = False + self.master = None + + self.add_dbus_interface(IFACE_ACTIVE_CONNECTION, self.__get_props, ActiveConnection.PropertiesChanged) + ExportedObj.__init__(self, bus, object_path) + + # Properties interface + def __get_props(self): + props = {} + props[PAC_CONNECTION] = to_path(self.conn) + props[PAC_SPECIFIC_OBJECT] = to_path(self.specific_object) + conn_settings = self.conn.GetSettings() + s_con = conn_settings['connection'] + props[PAC_ID] = s_con['id'] + props[PAC_UUID] = s_con['uuid'] + props[PAC_TYPE] = s_con['type'] + props[PAC_DEVICES] = to_path_array([self.device]) + props[PAC_STATE] = dbus.UInt32(self.state) + props[PAC_DEFAULT] = self.default + props[PAC_IP4CONFIG] = to_path(self.ip4config) + props[PAC_DHCP4CONFIG] = to_path(self.dhcp4config) + props[PAC_DEFAULT6] = self.default6 + props[PAC_IP6CONFIG] = to_path(self.ip6config) + props[PAC_DHCP6CONFIG] = to_path(self.dhcp6config) + props[PAC_VPN] = self.vpn + props[PAC_MASTER] = to_path(self.master) + return props + + @dbus.service.signal(IFACE_ACTIVE_CONNECTION, signature='a{sv}') + def PropertiesChanged(self, changed): + pass + +################################################################### +IFACE_TEST = 'org.freedesktop.NetworkManager.LibnmGlibTest' +IFACE_NM = 'org.freedesktop.NetworkManager' + +class PermissionDeniedException(dbus.DBusException): + _dbus_error_name = IFACE_NM + '.PermissionDenied' + +class UnknownDeviceException(dbus.DBusException): + _dbus_error_name = IFACE_NM + '.UnknownDevice' + +class UnknownConnectionException(dbus.DBusException): + _dbus_error_name = IFACE_NM + '.UnknownConnection' + +PM_DEVICES = 'Devices' +PM_ALL_DEVICES = 'AllDevices' +PM_NETWORKING_ENABLED = 'NetworkingEnabled' +PM_WWAN_ENABLED = 'WwanEnabled' +PM_WWAN_HARDWARE_ENABLED = 'WwanHardwareEnabled' +PM_WIRELESS_ENABLED = 'WirelessEnabled' +PM_WIRELESS_HARDWARE_ENABLED = 'WirelessHardwareEnabled' +PM_WIMAX_ENABLED = 'WimaxEnabled' +PM_WIMAX_HARDWARE_ENABLED = 'WimaxHardwareEnabled' +PM_ACTIVE_CONNECTIONS = 'ActiveConnections' +PM_PRIMARY_CONNECTION = 'PrimaryConnection' +PM_ACTIVATING_CONNECTION = 'ActivatingConnection' +PM_STARTUP = 'Startup' +PM_STATE = 'State' +PM_VERSION = 'Version' +PM_CONNECTIVITY = 'Connectivity' + +def set_device_ac_cb(device, ac): + device.set_active_connection(ac) + +class NetworkManager(ExportedObj): + def __init__(self, bus, object_path): + self._bus = bus; + self.devices = [] + self.active_connections = [] + self.primary_connection = None + self.activating_connection = None + self.state = NM_STATE_DISCONNECTED + self.connectivity = 1 + + self.add_dbus_interface(IFACE_NM, self.__get_props, NetworkManager.PropertiesChanged) + ExportedObj.__init__(self, bus, object_path) + + @dbus.service.signal(IFACE_NM, signature='u') + def StateChanged(self, new_state): + pass + + def set_state(self, new_state): + self.state = new_state + self.__notify(PM_STATE) + self.StateChanged(dbus.UInt32(self.state)) + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='ao') + def GetDevices(self): + return to_path_array(self.devices) + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='ao') + def GetAllDevices(self): + return to_path_array(self.devices) + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='s', out_signature='o') + def GetDeviceByIpIface(self, ip_iface): + for d in self.devices: + # ignore iface/ip_iface distinction for now + if d.iface == ip_iface: + return to_path(d) + raise UnknownDeviceException("No device found for the requested iface.") + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='ooo', out_signature='o') + def ActivateConnection(self, conpath, devpath, specific_object): + try: + connection = settings.get_connection(conpath) + except Exception as e: + raise UnknownConnectionException("Connection not found") + + hash = connection.GetSettings() + s_con = hash['connection'] + + device = None + for d in self.devices: + if d.path == devpath: + device = d + break + if not device and s_con['type'] == 'vlan': + ifname = s_con['interface-name'] + device = VlanDevice(self._bus, ifname) + self.add_device(device) + if not device: + raise UnknownDeviceException("No device found for the requested iface.") + + # See if we need secrets. For the moment, we only support WPA + if '802-11-wireless-security' in hash: + s_wsec = hash['802-11-wireless-security'] + if (s_wsec['key-mgmt'] == 'wpa-psk' and 'psk' not in s_wsec): + secrets = agent_manager.get_secrets(hash, conpath, '802-11-wireless-security') + if secrets is None: + raise NoSecretsException("No secret agent available") + if '802-11-wireless-security' not in secrets: + raise NoSecretsException("No secrets provided") + s_wsec = secrets['802-11-wireless-security'] + if 'psk' not in s_wsec: + raise NoSecretsException("No secrets provided") + + ac = ActiveConnection(self._bus, device, connection, None) + self.active_connections.append(ac) + self.__notify(PM_ACTIVE_CONNECTIONS) + + if s_con['id'] == 'object-creation-failed-test': + self.active_connections.remove(ac) + self.__notify(PM_ACTIVE_CONNECTIONS) + ac.remove_from_connection() + else: + GLib.timeout_add(50, set_device_ac_cb, device, ac) + + return to_path(ac) + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='a{sa{sv}}oo', out_signature='oo') + def AddAndActivateConnection(self, connection, devpath, specific_object): + device = None + for d in self.devices: + if d.path == devpath: + device = d + break + if not device: + raise UnknownDeviceException("No device found for the requested iface.") + + conpath = settings.AddConnection(connection) + return (conpath, self.ActivateConnection(conpath, devpath, specific_object)) + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='o', out_signature='') + def DeactivateConnection(self, active_connection): + pass + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='b', out_signature='') + def Sleep(self, do_sleep): + if do_sleep: + self.state = NM_STATE_ASLEEP + else: + self.state = NM_STATE_DISCONNECTED + self.__notify(PM_STATE) + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='b', out_signature='') + def Enable(self, do_enable): + pass + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='a{ss}') + def GetPermissions(self): + return { "org.freedesktop.NetworkManager.enable-disable-network": "yes", + "org.freedesktop.NetworkManager.sleep-wake": "no", + "org.freedesktop.NetworkManager.enable-disable-wifi": "yes", + "org.freedesktop.NetworkManager.enable-disable-wwan": "yes", + "org.freedesktop.NetworkManager.enable-disable-wimax": "yes", + "org.freedesktop.NetworkManager.network-control": "yes", + "org.freedesktop.NetworkManager.wifi.share.protected": "yes", + "org.freedesktop.NetworkManager.wifi.share.open": "yes", + "org.freedesktop.NetworkManager.settings.modify.own": "yes", + "org.freedesktop.NetworkManager.settings.modify.system": "yes", + "org.freedesktop.NetworkManager.settings.modify.hostname": "yes", + "org.freedesktop.NetworkManager.settings.modify.global-dns": "no", + "org.freedesktop.NetworkManager.reload": "no", + } + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='ss', out_signature='') + def SetLogging(self, level, domains): + pass + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='ss') + def GetLogging(self): + return ("info", "HW,RFKILL,CORE,DEVICE,WIFI,ETHER") + + @dbus.service.method(dbus_interface=IFACE_NM, in_signature='', out_signature='u') + def CheckConnectivity(self): + raise PermissionDeniedException("You fail") + + @dbus.service.signal(IFACE_NM, signature='o') + def DeviceAdded(self, devpath): + pass + + def add_device(self, device): + self.devices.append(device) + self.__notify(PM_DEVICES) + self.__notify(PM_ALL_DEVICES) + self.DeviceAdded(to_path(device)) + + @dbus.service.signal(IFACE_NM, signature='o') + def DeviceRemoved(self, devpath): + pass + + def remove_device(self, device): + self.devices.remove(device) + self.__notify(PM_DEVICES) + self.__notify(PM_ALL_DEVICES) + self.DeviceRemoved(to_path(device)) + + ################# D-Bus Properties interface + def __get_props(self): + props = {} + props[PM_DEVICES] = to_path_array(self.devices) + props[PM_ALL_DEVICES] = to_path_array(self.devices) + props[PM_NETWORKING_ENABLED] = True + props[PM_WWAN_ENABLED] = True + props[PM_WWAN_HARDWARE_ENABLED] = True + props[PM_WIRELESS_ENABLED] = True + props[PM_WIRELESS_HARDWARE_ENABLED] = True + props[PM_WIMAX_ENABLED] = True + props[PM_WIMAX_HARDWARE_ENABLED] = True + props[PM_ACTIVE_CONNECTIONS] = to_path_array(self.active_connections) + props[PM_PRIMARY_CONNECTION] = to_path(self.primary_connection) + props[PM_ACTIVATING_CONNECTION] = to_path(self.activating_connection) + props[PM_STARTUP] = False + props[PM_STATE] = dbus.UInt32(self.state) + props[PM_VERSION] = "0.9.9.0" + props[PM_CONNECTIVITY] = dbus.UInt32(self.connectivity) + return props + + def __notify(self, propname): + self._dbus_property_notify(IFACE_NM, propname) + + @dbus.service.signal(IFACE_NM, signature='a{sv}') + def PropertiesChanged(self, changed): + pass + + ################# Testing methods + @dbus.service.method(IFACE_TEST, in_signature='', out_signature='') + def Quit(self): + mainloop.quit() + + @dbus.service.method(IFACE_TEST, in_signature='ssas', out_signature='o') + def AddWiredDevice(self, ifname, mac, subchannels): + for d in self.devices: + if d.iface == ifname: + raise PermissionDeniedException("Device already added") + dev = WiredDevice(self._bus, ifname, mac, subchannels) + self.add_device(dev) + return to_path(dev) + + @dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o') + def AddWifiDevice(self, ifname): + for d in self.devices: + if d.iface == ifname: + raise PermissionDeniedException("Device already added") + dev = WifiDevice(self._bus, ifname) + self.add_device(dev) + return to_path(dev) + + @dbus.service.method(IFACE_TEST, in_signature='s', out_signature='o') + def AddWimaxDevice(self, ifname): + for d in self.devices: + if d.iface == ifname: + raise PermissionDeniedException("Device already added") + dev = WimaxDevice(self._bus, ifname) + self.add_device(dev) + return to_path(dev) + + @dbus.service.method(IFACE_TEST, in_signature='o', out_signature='') + def RemoveDevice(self, path): + for d in self.devices: + if d.path == path: + self.remove_device(d) + return + raise UnknownDeviceException("Device not found") + + @dbus.service.method(IFACE_TEST, in_signature='sss', out_signature='o') + def AddWifiAp(self, ifname, ssid, mac): + for d in self.devices: + if d.iface == ifname: + return to_path(d.add_test_ap(ssid, mac)) + raise UnknownDeviceException("Device not found") + + @dbus.service.method(IFACE_TEST, in_signature='so', out_signature='') + def RemoveWifiAp(self, ifname, ap_path): + for d in self.devices: + if d.iface == ifname: + d.remove_ap_by_path(ap_path) + return + raise UnknownDeviceException("Device not found") + + @dbus.service.method(IFACE_TEST, in_signature='ss', out_signature='o') + def AddWimaxNsp(self, ifname, name): + for d in self.devices: + if d.iface == ifname: + return to_path(d.add_test_nsp(name)) + raise UnknownDeviceException("Device not found") + + @dbus.service.method(IFACE_TEST, in_signature='so', out_signature='') + def RemoveWimaxNsp(self, ifname, nsp_path): + for d in self.devices: + if d.iface == ifname: + d.remove_nsp_by_path(nsp_path) + return + raise UnknownDeviceException("Device not found") + + @dbus.service.method(IFACE_TEST, in_signature='', out_signature='') + def AutoRemoveNextConnection(self): + settings.auto_remove_next_connection() + + @dbus.service.method(dbus_interface=IFACE_TEST, in_signature='a{sa{sv}}b', out_signature='o') + def AddConnection(self, connection, verify_connection): + return settings.add_connection(connection, verify_connection) + + @dbus.service.method(dbus_interface=IFACE_TEST, in_signature='sa{sa{sv}}b', out_signature='') + def UpdateConnection(self, path, connection, verify_connection): + return settings.update_connection(connection, path, verify_connection) + + @dbus.service.method(dbus_interface=IFACE_TEST, in_signature='', out_signature='') + def Restart(self): + bus.release_name("org.freedesktop.NetworkManager") + bus.request_name("org.freedesktop.NetworkManager") + + +################################################################### +IFACE_CONNECTION = 'org.freedesktop.NetworkManager.Settings.Connection' + +class InvalidPropertyException(dbus.DBusException): + _dbus_error_name = IFACE_CONNECTION + '.InvalidProperty' + +class MissingPropertyException(dbus.DBusException): + _dbus_error_name = IFACE_CONNECTION + '.MissingProperty' + +class InvalidSettingException(dbus.DBusException): + _dbus_error_name = IFACE_CONNECTION + '.InvalidSetting' + +class MissingSettingException(dbus.DBusException): + _dbus_error_name = IFACE_CONNECTION + '.MissingSetting' + +class Connection(ExportedObj): + def __init__(self, bus, object_path, settings, remove_func, verify_connection=True): + + if self.get_uuid(settings) is None: + if 'connection' not in settings: + settings['connection'] = { } + settings['connection']['uuid'] = uuid.uuid4() + self.verify(settings, verify_strict=verify_connection) + + self.path = object_path + self.settings = settings + self.remove_func = remove_func + self.visible = True + self.props = {} + self.props['Unsaved'] = False + + self.add_dbus_interface(IFACE_CONNECTION, self.__get_props, None) + ExportedObj.__init__(self, bus, object_path) + + def get_uuid(self, settings=None): + if settings is None: + settings = self.settings + if 'connection' in settings: + s_con = settings['connection'] + if 'uuid' in s_con: + return s_con['uuid'] + return None + + def verify(self, settings=None, verify_strict=True): + if settings is None: + settings = self.settings; + if 'connection' not in settings: + raise MissingSettingException('connection: setting is required') + s_con = settings['connection'] + if 'type' not in s_con: + raise MissingPropertyException('connection.type: property is required') + if 'uuid' not in s_con: + raise MissingPropertyException('connection.uuid: property is required') + if 'id' not in s_con: + raise MissingPropertyException('connection.id: property is required') + + if not verify_strict: + return; + t = s_con['type'] + if t not in ['802-3-ethernet', '802-11-wireless', 'vlan', 'wimax']: + raise InvalidPropertyException('connection.type: unsupported connection type "%s"' % (t)) + + def update_connection(self, settings, verify_connection): + self.verify(settings, verify_strict=verify_connection) + + old_uuid = self.get_uuid() + new_uuid = self.get_uuid(settings) + if old_uuid != new_uuid: + raise InvalidPropertyException('connection.uuid: cannot change the uuid from %s to %s' % (old_uuid, new_uuid)) + + self.settings = settings; + self.Updated() + + def __get_props(self): + return self.props + + def __notify(self, propname): + self._dbus_property_notify(IFACE_CONNECTION, propname) + + # Connection methods + @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='a{sa{sv}}') + def GetSettings(self): + if not self.visible: + raise PermissionDeniedException() + return self.settings + + @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='b', out_signature='') + def SetVisible(self, vis): + self.visible = vis + self.Updated() + + @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='', out_signature='') + def Delete(self): + self.remove_func(self) + self.Removed() + self.remove_from_connection() + + @dbus.service.method(dbus_interface=IFACE_CONNECTION, in_signature='a{sa{sv}}', out_signature='') + def Update(self, settings): + self.update_connection(settings, TRUE) + + @dbus.service.signal(IFACE_CONNECTION, signature='') + def Removed(self): + pass + + @dbus.service.signal(IFACE_CONNECTION, signature='') + def Updated(self): + pass + +################################################################### +IFACE_SETTINGS = 'org.freedesktop.NetworkManager.Settings' + +class InvalidHostnameException(dbus.DBusException): + _dbus_error_name = IFACE_SETTINGS + '.InvalidHostname' + +class Settings(ExportedObj): + def __init__(self, bus, object_path): + self.connections = {} + self.bus = bus + self.counter = 1 + self.remove_next_connection = False + self.props = {} + self.props['Hostname'] = "foobar.baz" + self.props['CanModify'] = True + self.props['Connections'] = dbus.Array([], 'o') + + self.add_dbus_interface(IFACE_SETTINGS, self.__get_props, Settings.PropertiesChanged) + ExportedObj.__init__(self, bus, object_path) + + def auto_remove_next_connection(self): + self.remove_next_connection = True; + + def get_connection(self, path): + return self.connections[path] + + @dbus.service.method(dbus_interface=IFACE_SETTINGS, in_signature='', out_signature='ao') + def ListConnections(self): + return self.connections.keys() + + @dbus.service.method(dbus_interface=IFACE_SETTINGS, in_signature='a{sa{sv}}', out_signature='o') + def AddConnection(self, settings): + return self.add_connection(settings) + + def add_connection(self, settings, verify_connection=True): + path = "/org/freedesktop/NetworkManager/Settings/Connection/{0}".format(self.counter) + con = Connection(self.bus, path, settings, self.delete_connection, verify_connection) + + uuid = con.get_uuid() + if uuid in [c.get_uuid() for c in self.connections.values()]: + raise InvalidSettingException('cannot add duplicate connection with uuid %s' % (uuid)) + + self.counter = self.counter + 1 + self.connections[path] = con + self.props['Connections'] = dbus.Array(self.connections.keys(), 'o') + self.NewConnection(path) + self.__notify('Connections') + + if self.remove_next_connection: + self.remove_next_connection = False + self.connections[path].Delete() + + return path + + def update_connection(self, connection, path=None, verify_connection=True): + if path is None: + path = connection.path + if path not in self.connections: + raise UnknownConnectionException('Connection not found') + con = self.connections[path] + con.update_connection(connection, verify_connection) + + def delete_connection(self, connection): + del self.connections[connection.path] + self.props['Connections'] = dbus.Array(self.connections.keys(), 'o') + self.__notify('Connections') + + @dbus.service.method(dbus_interface=IFACE_SETTINGS, in_signature='s', out_signature='') + def SaveHostname(self, hostname): + # Arbitrary requirement to test error handling + if hostname.find('.') == -1: + raise InvalidHostnameException() + self.props['Hostname'] = hostname + self.__notify('Hostname') + + def __get_props(self): + return self.props + + def __notify(self, propname): + self._dbus_property_notify(IFACE_SETTINGS, propname) + + @dbus.service.signal(IFACE_SETTINGS, signature='o') + def NewConnection(self, path): + pass + + @dbus.service.signal(IFACE_SETTINGS, signature='a{sv}') + def PropertiesChanged(self, path): + pass + + @dbus.service.method(IFACE_SETTINGS, in_signature='', out_signature='') + def Quit(self): + mainloop.quit() + +################################################################### +IFACE_AGENT_MANAGER = 'org.freedesktop.NetworkManager.AgentManager' +IFACE_AGENT = 'org.freedesktop.NetworkManager.SecretAgent' + +PATH_SECRET_AGENT = '/org/freedesktop/NetworkManager/SecretAgent' + +FLAG_ALLOW_INTERACTION = 0x1 +FLAG_REQUEST_NEW = 0x2 +FLAG_USER_REQUESTED = 0x4 + +class NoSecretsException(dbus.DBusException): + _dbus_error_name = IFACE_AGENT_MANAGER + '.NoSecrets' + +class UserCanceledException(dbus.DBusException): + _dbus_error_name = IFACE_AGENT_MANAGER + '.UserCanceled' + +class AgentManager(dbus.service.Object): + def __init__(self, bus, object_path): + dbus.service.Object.__init__(self, bus, object_path) + self.agents = {} + self.bus = bus + + @dbus.service.method(dbus_interface=IFACE_AGENT_MANAGER, + in_signature='s', out_signature='', + sender_keyword='sender') + def Register(self, name, sender=None): + self.RegisterWithCapabilities(name, 0, sender) + + @dbus.service.method(dbus_interface=IFACE_AGENT_MANAGER, + in_signature='su', out_signature='', + sender_keyword='sender') + def RegisterWithCapabilities(self, name, caps, sender=None): + self.agents[sender] = self.bus.get_object(sender, PATH_SECRET_AGENT) + + @dbus.service.method(dbus_interface=IFACE_AGENT_MANAGER, + in_signature='', out_signature='', + sender_keyword='sender') + def Unregister(self, sender=None): + del self.agents[sender] + + def get_secrets(self, connection, path, setting_name): + if len(self.agents) == 0: + return None + + secrets = {} + for sender in self.agents: + agent = self.agents[sender] + try: + secrets = agent.GetSecrets(connection, path, setting_name, + dbus.Array([], 's'), + FLAG_ALLOW_INTERACTION | FLAG_USER_REQUESTED, + dbus_interface=IFACE_AGENT) + break + except dbus.DBusException as e: + if e.get_dbus_name() == IFACE_AGENT + '.UserCanceled': + raise UserCanceledException('User canceled') + continue + return secrets + +################################################################### +IFACE_OBJECT_MANAGER = 'org.freedesktop.DBus.ObjectManager' + +PATH_OBJECT_MANAGER = '/org/freedesktop' + +class ObjectManager(dbus.service.Object): + def __init__(self, bus, object_path): + dbus.service.Object.__init__(self, bus, object_path) + self.objs = [] + self.bus = bus + + @dbus.service.method(dbus_interface=IFACE_OBJECT_MANAGER, + in_signature='', out_signature='a{oa{sa{sv}}}', + sender_keyword='sender') + def GetManagedObjects(self, sender=None): + managed_objects = {} + for obj in self.objs: + name, ifaces = obj.get_managed_ifaces() + managed_objects[name] = ifaces + return managed_objects + + def add_object(self, obj): + self.objs.append(obj) + name, ifaces = obj.get_managed_ifaces() + self.InterfacesAdded(name, ifaces) + + def remove_object(self, obj): + self.objs.remove(obj) + name, ifaces = obj.get_managed_ifaces() + self.InterfacesRemoved(name, ifaces.keys()) + + @dbus.service.signal(IFACE_OBJECT_MANAGER, signature='oa{sa{sv}}') + def InterfacesAdded(self, name, ifaces): + pass + + @dbus.service.signal(IFACE_OBJECT_MANAGER, signature='oas') + def InterfacesRemoved(self, name, ifaces): + pass + +################################################################### +IFACE_DNS_MANAGER = 'org.freedesktop.NetworkManager.DnsManager' + +class DnsManager(ExportedObj): + def __init__(self, bus, object_path): + self.props = {} + self.props['Mode'] = "dnsmasq" + self.props['RcManager'] = "symlink" + self.props['Configuration'] = dbus.Array([ + dbus.Dictionary( + { 'nameservers' : dbus.Array(['1.2.3.4', '5.6.7.8'], 's'), + 'priority' : dbus.Int32(100) }, + 'sv') ], + 'a{sv}') + + self.add_dbus_interface(IFACE_DNS_MANAGER, self.__get_props, None) + ExportedObj.__init__(self, bus, object_path) + + @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}') + def GetAll(self, iface): + if iface != IFACE_DNS_MANAGER: + raise UnknownInterfaceException() + return self.props + + @dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v') + def Get(self, iface, name): + if iface != IFACE_DNS_MANAGER: + raise UnknownInterfaceException() + if not name in self.props.keys(): + raise UnknownPropertyException() + return self.props[name] + + def __get_props(self): + return self.props + +################################################################### +def stdin_cb(io, condition): + mainloop.quit() + +def quit_cb(user_data): + mainloop.quit() + +def main(): + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + + random.seed() + + global manager, settings, agent_manager, dns_manager, object_manager, bus + + bus = dbus.SessionBus() + object_manager = ObjectManager(bus, "/org/freedesktop") + manager = NetworkManager(bus, "/org/freedesktop/NetworkManager") + settings = Settings(bus, "/org/freedesktop/NetworkManager/Settings") + agent_manager = AgentManager(bus, "/org/freedesktop/NetworkManager/AgentManager") + dns_manager = DnsManager(bus, "/org/freedesktop/NetworkManager/DnsManager") + + if not bus.request_name("org.freedesktop.NetworkManager"): + sys.exit(1) + + # Watch stdin; if it closes, assume our parent has crashed, and exit + io = GLib.IOChannel(0) + io.add_watch(GLib.IOCondition.HUP, stdin_cb) + + # also quit after inactivity to ensure we don't stick around if the above fails somehow + GLib.timeout_add_seconds(20, quit_cb, None) + + try: + mainloop.run() + except Exception as e: + pass + + sys.exit(0) + +if __name__ == '__main__': + main() + -- cgit v1.2.1 From 9bab137bb4fd46c021ca10607a08c3fb45bfeeac Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Wed, 4 Apr 2018 22:40:39 +0200 Subject: tests/network: Add status and carrier setting to NM test service This adds a bit of new functionality to the test service to set the status and reason for the status change as well as whether the carrier is connected. --- .../nm-utils/test-networkmanager-service.py | 106 ++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/tests/network/nm-utils/test-networkmanager-service.py b/tests/network/nm-utils/test-networkmanager-service.py index 68097778e..0dca42733 100755 --- a/tests/network/nm-utils/test-networkmanager-service.py +++ b/tests/network/nm-utils/test-networkmanager-service.py @@ -39,6 +39,71 @@ NM_DEVICE_STATE_ACTIVATED = 100 NM_DEVICE_STATE_DEACTIVATING = 110 NM_DEVICE_STATE_FAILED = 120 +# Device state reason +NM_DEVICE_STATE_REASON_NONE = 0 +NM_DEVICE_STATE_REASON_UNKNOWN = 1 +NM_DEVICE_STATE_REASON_NOW_MANAGED = 2 +NM_DEVICE_STATE_REASON_NOW_UNMANAGED = 3 +NM_DEVICE_STATE_REASON_CONFIG_FAILED = 4 +NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE = 5 +NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED = 6 +NM_DEVICE_STATE_REASON_NO_SECRETS = 7 +NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT = 8 +NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED = 9 +NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED = 10 +NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT = 11 +NM_DEVICE_STATE_REASON_PPP_START_FAILED = 12 +NM_DEVICE_STATE_REASON_PPP_DISCONNECT = 13 +NM_DEVICE_STATE_REASON_PPP_FAILED = 14 +NM_DEVICE_STATE_REASON_DHCP_START_FAILED = 15 +NM_DEVICE_STATE_REASON_DHCP_ERROR = 16 +NM_DEVICE_STATE_REASON_DHCP_FAILED = 17 +NM_DEVICE_STATE_REASON_SHARED_START_FAILED = 18 +NM_DEVICE_STATE_REASON_SHARED_FAILED = 19 +NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED = 20 +NM_DEVICE_STATE_REASON_AUTOIP_ERROR = 21 +NM_DEVICE_STATE_REASON_AUTOIP_FAILED = 22 +NM_DEVICE_STATE_REASON_MODEM_BUSY = 23 +NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE = 24 +NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER = 25 +NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT = 26 +NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED = 27 +NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED = 28 +NM_DEVICE_STATE_REASON_GSM_APN_FAILED = 29 +NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING = 30 +NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED = 31 +NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT = 32 +NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED = 33 +NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED = 34 +NM_DEVICE_STATE_REASON_FIRMWARE_MISSING = 35 +NM_DEVICE_STATE_REASON_REMOVED = 36 +NM_DEVICE_STATE_REASON_SLEEPING = 37 +NM_DEVICE_STATE_REASON_CONNECTION_REMOVED = 38 +NM_DEVICE_STATE_REASON_USER_REQUESTED = 39 +NM_DEVICE_STATE_REASON_CARRIER = 40 +NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED = 41 +NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE = 42 +NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND = 43 +NM_DEVICE_STATE_REASON_BT_FAILED = 44 +NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED = 45 +NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED = 46 +NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED = 47 +NM_DEVICE_STATE_REASON_GSM_SIM_WRONG = 48 +NM_DEVICE_STATE_REASON_INFINIBAND_MODE = 49 +NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED = 50 +NM_DEVICE_STATE_REASON_BR2684_FAILED = 51 +NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE = 52 +NM_DEVICE_STATE_REASON_SSID_NOT_FOUND = 53 +NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED = 54 +NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED = 55 +NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED = 56 +NM_DEVICE_STATE_REASON_MODEM_FAILED = 57 +NM_DEVICE_STATE_REASON_MODEM_AVAILABLE = 58 +NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT = 59 +NM_DEVICE_STATE_REASON_NEW_ACTIVATION = 60 +NM_DEVICE_STATE_REASON_PARENT_CHANGED = 61 +NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED = 62 + # Device type NM_DEVICE_TYPE_UNKNOWN = 0 NM_DEVICE_TYPE_ETHERNET = 1 @@ -153,6 +218,7 @@ PD_UDI = "Udi" PD_IFACE = "Interface" PD_DRIVER = "Driver" PD_STATE = "State" +PD_STATE_REASON = "StateReason" PD_ACTIVE_CONNECTION = "ActiveConnection" PD_IP4_CONFIG = "Ip4Config" PD_IP6_CONFIG = "Ip6Config" @@ -175,6 +241,7 @@ class Device(ExportedObj): self.devtype = devtype self.active_connection = None self.state = NM_DEVICE_STATE_UNAVAILABLE + self.reason = NM_DEVICE_STATE_REASON_NONE self.ip4_config = None self.ip6_config = None self.dhcp4_config = None @@ -191,6 +258,7 @@ class Device(ExportedObj): props[PD_IFACE] = self.iface props[PD_DRIVER] = "virtual" props[PD_STATE] = dbus.UInt32(self.state) + props[PD_STATE_REASON] = dbus.Struct((dbus.UInt32(self.state), dbus.UInt32(self.reason)), signature='uu') props[PD_ACTIVE_CONNECTION] = to_path(self.active_connection) props[PD_IP4_CONFIG] = to_path(self.ip4_config) props[PD_IP6_CONFIG] = to_path(self.ip6_config) @@ -224,6 +292,13 @@ class Device(ExportedObj): self.active_connection = ac self.__notify(PD_ACTIVE_CONNECTION) + def set_state_reason(self, state, reason): + self.state = state + self.reason = reason + self.__notify(PD_STATE) + self.__notify(PD_STATE_REASON) + + ################################################################### def random_mac(): @@ -249,6 +324,7 @@ class WiredDevice(Device): else: self.mac = mac self.carrier = False + self.speed = 100 self.s390_subchannels = subchannels self.add_dbus_interface(IFACE_WIRED, self.__get_props, WiredDevice.PropertiesChanged) @@ -259,7 +335,7 @@ class WiredDevice(Device): props = {} props[PE_HW_ADDRESS] = self.mac props[PE_PERM_HW_ADDRESS] = self.mac - props[PE_SPEED] = dbus.UInt32(100) + props[PE_SPEED] = dbus.UInt32(self.speed) props[PE_CARRIER] = self.carrier props[PE_S390_SUBCHANNELS] = self.s390_subchannels return props @@ -271,6 +347,18 @@ class WiredDevice(Device): def PropertiesChanged(self, changed): pass + def set_wired_speed(self, speed): + if speed > 0: + self.speed = speed + self.carrier = True + self.__notify(PE_SPEED) + self.__notify(PE_CARRIER) + else: + self.speed = 100 + self.carrier = False + self.__notify(PE_CARRIER) + self.__notify(PE_SPEED) + ################################################################### IFACE_VLAN = 'org.freedesktop.NetworkManager.Device.Vlan' @@ -957,6 +1045,22 @@ class NetworkManager(ExportedObj): def UpdateConnection(self, path, connection, verify_connection): return settings.update_connection(connection, path, verify_connection) + @dbus.service.method(dbus_interface=IFACE_TEST, in_signature='suu', out_signature='') + def SetDeviceState(self, path, state, reason): + for d in self.devices: + if d.path == path: + d.set_state_reason(state, reason) + return + raise UnknownDeviceException("Device not found") + + @dbus.service.method(dbus_interface=IFACE_TEST, in_signature='su', out_signature='') + def SetWiredSpeed(self, path, speed): + for d in self.devices: + if d.path == path: + d.set_wired_speed(speed) + return + raise UnknownDeviceException("Device not found") + @dbus.service.method(dbus_interface=IFACE_TEST, in_signature='', out_signature='') def Restart(self): bus.release_name("org.freedesktop.NetworkManager") -- cgit v1.2.1 From 466d91afd3af3893fa556e38ed54c2a7f0144def Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Wed, 4 Apr 2018 22:41:43 +0200 Subject: tests/network: Fix deprecation warning in NM test service This just fixes a simple deprecation warning in the NetworkManager test service. --- tests/network/nm-utils/test-networkmanager-service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/network/nm-utils/test-networkmanager-service.py b/tests/network/nm-utils/test-networkmanager-service.py index 0dca42733..9dd95bb77 100755 --- a/tests/network/nm-utils/test-networkmanager-service.py +++ b/tests/network/nm-utils/test-networkmanager-service.py @@ -1428,7 +1428,7 @@ def main(): # Watch stdin; if it closes, assume our parent has crashed, and exit io = GLib.IOChannel(0) - io.add_watch(GLib.IOCondition.HUP, stdin_cb) + GLib.io_add_watch(io, GLib.PRIORITY_LOW, GLib.IOCondition.HUP, stdin_cb) # also quit after inactivity to ensure we don't stick around if the above fails somehow GLib.timeout_add_seconds(20, quit_cb, None) -- cgit v1.2.1 From fc072d65a801f7982a7fe034a2cf8f499ea92ba5 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 6 Apr 2018 17:28:06 +0200 Subject: ci: Add dbusmock and Xvfb dependency This is in preparation for testing which requires an X server. mesa-dri-drivers is required for the OpenGL software renderer. --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 711923889..ffa4b559a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,6 +14,7 @@ variables: libsoup-devel libwacom-devel libX11-devel libXi-devel libxml2-devel libxslt libXxf86misc-devel meson ModemManager-glib-devel NetworkManager-libnm-devel polkit-devel pulseaudio-libs-devel upower-devel + python3-dbusmock xorg-x11-server-Xvfb mesa-dri-drivers before_script: -- cgit v1.2.1 From 8c9be792f25ce4d636e55d0872944936e45517a4 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 6 Apr 2018 16:59:37 +0200 Subject: tests: Add dbusmock helper starting X server and system/session busses This helper has been submitted for inclusion in dbusmock. If it cannot live there in some form, then we should try to find a home in the GNOME project for it. --- tests/shared/x11session.py | 101 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 tests/shared/x11session.py diff --git a/tests/shared/x11session.py b/tests/shared/x11session.py new file mode 100644 index 000000000..87e964943 --- /dev/null +++ b/tests/shared/x11session.py @@ -0,0 +1,101 @@ +# Copyright © 2018 Red Hat, Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# Authors: Benjamin Berg + +import os +import sys +import subprocess +from dbusmock import DBusTestCase + +# Intended to be shared across projects, submitted for inclusion into +# dbusmock but might need to live elsewhere +# The pull request contains python 2 compatibility code. +# https://github.com/martinpitt/python-dbusmock/pull/44 + +class X11SessionTestCase(DBusTestCase): + #: The display the X server is running on + X_display = -1 + #: The X server to start + Xserver = 'Xvfb' + #: Further parameters for the X server + Xserver_args = ['-screen', '0', '1280x1024x24', '+extension', 'GLX'] + #: Where to redirect the X stdout and stderr to. Set to None for debugging + #: purposes if the X server is failing for some reason. + Xserver_output = subprocess.DEVNULL + + @classmethod + def setUpClass(klass): + klass.start_xorg() + klass.start_system_bus() + klass.start_session_bus() + + @classmethod + def start_xorg(klass): + r, w = os.pipe() + + # Xvfb seems to randomly crash in some workloads if "-noreset" is not given. + # https://bugzilla.redhat.com/show_bug.cgi?id=1565847 + klass.xorg = subprocess.Popen([klass.Xserver, '-displayfd', "%d" % w, '-noreset'] + klass.Xserver_args, + pass_fds=(w,), + stdout=klass.Xserver_output, + stderr=subprocess.STDOUT) + os.close(w) + + # The X server will write "%d\n", we need to make sure to read the "\n". + # If the server dies we get zero bytes reads as EOF is reached. + display = b'' + while True: + tmp = os.read(r, 1024) + display += tmp + + # Break out if the read was empty or the line feed was read + if not tmp or tmp[-1] == b'\n': + break + + os.close(r) + + try: + display = int(display.strip()) + except ValueError: + # This should never happen, the X server didn't return a proper integer. + # Most likely it died for some odd reason. + # Note: Set Xserver_output to None to debug Xvfb startup issues. + klass.stop_xorg() + raise AssertionError('X server reported back no or an invalid display number (%s)' % (display)) + + klass.X_display = display + # Export information into our environment for tests to use + os.environ['DISPLAY'] = ":%d" % klass.X_display + os.environ['WAYLAND'] = '' + + # Server should still be up and running at this point + assert klass.xorg.poll() is None + + return klass.X_display + + @classmethod + def stop_xorg(klass): + if hasattr(klass, 'xorg'): + klass.X_display = -1 + klass.xorg.terminate() + klass.xorg.wait() + del klass.xorg + + @classmethod + def tearDownClass(klass): + DBusTestCase.tearDownClass() + + klass.stop_xorg() -- cgit v1.2.1 From 7630bf963e7e29faddc178f9c7ec9b93d6669249 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 6 Apr 2018 17:01:29 +0200 Subject: tests: Add helper for glib based test binaries This makes running glib based tests inside a dbusmock environment easier and more beautiful (i.e. output is supressed unless an error occurs). This helper has been submitted for inclusion in dbusmock. If it cannot$ live there in some form, then we should try to find a home in the GNOME$ project for it.$ --- tests/shared/gtest.py | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 tests/shared/gtest.py diff --git a/tests/shared/gtest.py b/tests/shared/gtest.py new file mode 100644 index 000000000..bb7130daf --- /dev/null +++ b/tests/shared/gtest.py @@ -0,0 +1,113 @@ +#!/usr/bin/python3 +# Copyright © 2018 Red Hat, Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# Authors: Benjamin Berg + +import os +import sys +import subprocess +import functools + +class _GTestSingleProp(object): + """Property which creates a bound method for calling the specified test.""" + def __init__(self, test): + self.test = test + + @staticmethod + def __func(self, test): + self._gtest_single(test) + + def __get__(self, obj, cls): + bound_method = self.__func.__get__(obj, cls) + partial_method = functools.partial(bound_method, self.test) + partial_method.__doc__ = bound_method.__doc__ + + return partial_method + + +class _GTestMeta(type): + def __new__(cls, name, bases, namespace, **kwds): + result = type.__new__(cls, name, bases, dict(namespace)) + + if result.g_test_exe is not None: + try: + _GTestMeta.make_tests(result.g_test_exe, result) + except Exception as e: + print('') + print(e) + print('Error generating separate test funcs, will call binary once.') + result.test_all = result._gtest_all + + return result + + @staticmethod + def make_tests(exe, result): + env = os.environ.copy() + env['G_MESSAGES_DEBUG'] = '' + test = subprocess.Popen([exe, '-l'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, env=env) + stdout, stderr = test.communicate() + + if test.returncode != 0: + raise AssertionError('Execution of GTest executable to query the tests returned non-zero exit code!') + + stdout = stdout.decode('utf-8') + + for i, test in enumerate(stdout.split('\n')): + if not test: + continue + + # Number it and make sure the function name is prefixed with 'test'. + # Keep the rest as is, we don't care about the fact that the function + # names cannot be typed in. + name = 'test_%03d_' % (i + 1) + test + setattr(result, name, _GTestSingleProp(test)) + + +class GTest(metaclass = _GTestMeta): + """Helper class to run GLib test. A test function will be created for each + test from the executable. + + Use by using this class as a mixin and setting g_test_exe to an appropriate + value. + """ + + #: The GTest based executable + g_test_exe = None + #: Timeout when running a single test + g_test_single_timeout = None + #: Timeout when running all tests in one go + g_test_all_timeout = None + + def _gtest_single(self, test): + assert(test) + p = subprocess.Popen([self.g_test_exe, '-q', '-p', test], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + try: + stdout, stderr = p.communicate(timeout=self.g_test_single_timeout) + except subprocess.TimeoutExpired: + p.kill() + stdout, stderr = p.communicate() + stdout += b'\n\nTest was aborted due to timeout' + + try: + stdout = stdout.decode('utf-8') + except UnicodeDecodeError: + pass + + if p.returncode != 0: + self.fail(stdout) + + def _gtest_all(self): + subprocess.check_call([self.g_test_exe], timeout=self.g_test_all_timeout) -- cgit v1.2.1 From f655e46ce792311730fbed6ac8482dbfa6101bba Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Fri, 6 Apr 2018 17:19:58 +0200 Subject: tests/network: Add basic testing of network panel This adds tests for the network panel based on the test service found in NetworkManager. Another possible solution may be to use the one from dbusmock, however NetworkManager already has readily available code to write tests in C which makes checking the widget hierarchy easier. --- .gitignore | 1 + meson.build | 5 + panels/network/meson.build | 3 +- tests/meson.build | 1 + tests/network/cc-test-window.c | 203 +++++++++++++++++++ tests/network/cc-test-window.h | 35 ++++ tests/network/meson.build | 30 +++ tests/network/nmtst-helpers.h | 297 ++++++++++++++++++++++++++++ tests/network/test-network-panel.c | 382 ++++++++++++++++++++++++++++++++++++ tests/network/test-network-panel.py | 44 +++++ 10 files changed, 1000 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 tests/network/cc-test-window.c create mode 100644 tests/network/cc-test-window.h create mode 100644 tests/network/meson.build create mode 100644 tests/network/nmtst-helpers.h create mode 100644 tests/network/test-network-panel.c create mode 100644 tests/network/test-network-panel.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..bee8a64b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__ diff --git a/meson.build b/meson.build index a2d484442..16911d990 100644 --- a/meson.build +++ b/meson.build @@ -30,6 +30,11 @@ enable_tracing = get_option('tracing') config_h = configuration_data() +py3 = import('python3') +python = py3.find_python() + +config_h.set_quoted('TEST_NM_PYTHON', python.path()) + # defines set_defines = [ # package diff --git a/panels/network/meson.build b/panels/network/meson.build index 0325c5afd..2ec4fbf71 100644 --- a/panels/network/meson.build +++ b/panels/network/meson.build @@ -69,7 +69,7 @@ sources += gnome.compile_resources( cflags += '-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir) -panels_libs += static_library( +network_panel_lib = static_library( cappletname, sources: sources, include_directories: [top_inc, common_inc], @@ -77,3 +77,4 @@ panels_libs += static_library( c_args: cflags, link_with: libconnection_editor ) +panels_libs += network_panel_lib diff --git a/tests/meson.build b/tests/meson.build index 49229a305..41adee9e1 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -1,4 +1,5 @@ subdir('common') subdir('datetime') +subdir('network') subdir('printers') subdir('info') diff --git a/tests/network/cc-test-window.c b/tests/network/cc-test-window.c new file mode 100644 index 000000000..dcda579b3 --- /dev/null +++ b/tests/network/cc-test-window.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2009, 2010 Intel, Inc. + * Copyright (c) 2010, 2018 Red Hat, Inc. + * Copyright (c) 2016 Endless, Inc. + * + * The Control Center is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * The Control Center is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with the Control Center; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Benjamin Berg + */ + +#define G_LOG_DOMAIN "cc-test-window" + +#include + +#include "cc-test-window.h" + +#include +#include +#include +#include +#include + +#include "shell/cc-panel.h" +#include "shell/cc-shell.h" +#include "cc-util.h" + + +struct _CcTestWindow +{ + GtkWindow parent; + + GtkWidget *main_box; + + GtkWidget *header; + CcPanel *active_panel; +}; + +static void cc_shell_iface_init (CcShellInterface *iface); + +G_DEFINE_TYPE_WITH_CODE (CcTestWindow, cc_test_window, GTK_TYPE_WINDOW, + G_IMPLEMENT_INTERFACE (CC_TYPE_SHELL, cc_shell_iface_init)) + +enum +{ + PROP_0, + PROP_ACTIVE_PANEL +}; + + + +static void +set_active_panel (CcTestWindow *shell, + CcPanel *panel) +{ + g_assert (CC_IS_SHELL (shell)); + g_assert (CC_IS_PANEL (panel)); + + /* Only allow setting to a non NULL value once. */ + g_assert (shell->active_panel == NULL); + + if (panel) + { + shell->active_panel = g_object_ref (panel); + gtk_container_add_with_properties (GTK_CONTAINER (shell->main_box), GTK_WIDGET (panel), + "pack-type", GTK_PACK_END, + "expand", TRUE, + "fill", TRUE, + NULL); + } +} + +/* CcShell implementation */ +static gboolean +cc_test_window_set_active_panel_from_id (CcShell *shell, + const gchar *start_id, + GVariant *parameters, + GError **error) +{ + /* Not implemented */ + g_assert_not_reached (); +} + +static void +cc_test_window_embed_widget_in_header (CcShell *shell, + GtkWidget *widget) +{ + CcTestWindow *self = CC_TEST_WINDOW (shell); + + /* add to main box */ + gtk_container_add_with_properties (GTK_CONTAINER (self->main_box), GTK_WIDGET (widget), + "pack-type", GTK_PACK_START, + "expand", FALSE, + "fill", TRUE, + NULL); + gtk_widget_show (widget); +} + +static GtkWidget * +cc_test_window_get_toplevel (CcShell *shell) +{ + return GTK_WIDGET (shell); +} + +static void +cc_shell_iface_init (CcShellInterface *iface) +{ + iface->set_active_panel_from_id = cc_test_window_set_active_panel_from_id; + iface->embed_widget_in_header = cc_test_window_embed_widget_in_header; + iface->get_toplevel = cc_test_window_get_toplevel; +} + +/* GObject Implementation */ +static void +cc_test_window_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + CcTestWindow *self = CC_TEST_WINDOW (object); + + switch (property_id) + { + case PROP_ACTIVE_PANEL: + g_value_set_object (value, self->active_panel); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +cc_test_window_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + CcTestWindow *shell = CC_TEST_WINDOW (object); + + switch (property_id) + { + case PROP_ACTIVE_PANEL: + set_active_panel (shell, g_value_get_object (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + } +} + +static void +cc_test_window_dispose (GObject *object) +{ + CcTestWindow *self = CC_TEST_WINDOW (object); + + g_clear_object (&self->active_panel); + + G_OBJECT_CLASS (cc_test_window_parent_class)->dispose (object); +} + +static void +cc_test_window_class_init (CcTestWindowClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = cc_test_window_get_property; + object_class->set_property = cc_test_window_set_property; + object_class->dispose = cc_test_window_dispose; + + g_object_class_override_property (object_class, PROP_ACTIVE_PANEL, "active-panel"); +} + +static void +cc_test_window_init (CcTestWindow *self) +{ + gtk_widget_set_size_request (GTK_WIDGET (self), 500, 800); + + self->main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5); + + gtk_container_add (GTK_CONTAINER (self), self->main_box); +} + +CcTestWindow * +cc_test_window_new (void) +{ + return g_object_new (CC_TYPE_TEST_WINDOW, + "resizable", TRUE, + "title", "Test Settings", + "window-position", GTK_WIN_POS_CENTER, + NULL); +} diff --git a/tests/network/cc-test-window.h b/tests/network/cc-test-window.h new file mode 100644 index 000000000..abbdb61a0 --- /dev/null +++ b/tests/network/cc-test-window.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010 Intel, Inc. + * Copyright (c) 2018 Red Hat, Inc. + * + * The Control Center is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * The Control Center is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with the Control Center; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Benjamin Berg + */ + +#pragma once + +#include +#include "shell/cc-shell.h" + +G_BEGIN_DECLS + +#define CC_TYPE_TEST_WINDOW (cc_test_window_get_type ()) + +G_DECLARE_FINAL_TYPE (CcTestWindow, cc_test_window, CC, TEST_WINDOW, GtkWindow) + +CcTestWindow *cc_test_window_new (void); + +G_END_DECLS diff --git a/tests/network/meson.build b/tests/network/meson.build new file mode 100644 index 000000000..4378ea72a --- /dev/null +++ b/tests/network/meson.build @@ -0,0 +1,30 @@ + + +includes = [top_inc, include_directories('../../panels/network', 'nm-utils')] +cflags = [ + '-DTEST_SRCDIR="@0@"'.format(meson.current_source_dir()), + '-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_WITH_GLIB', + '-DNETWORKMANAGER_COMPILATION_TEST', + '-DTEST_NM_SERVICE="@0@"'.format(join_paths(meson.source_root(), 'tests', 'network', 'nm-utils', 'test-networkmanager-service.py')), +] + +exe = executable( + 'test-network-panel', + ['test-network-panel.c', 'cc-test-window.c', 'nm-utils/nm-test-utils-impl.c'], + include_directories: includes + [common_inc], + dependencies: common_deps + network_manager_deps + [libtestshell_dep], + link_with: [network_panel_lib], + c_args: cflags +) + +envs = [ + 'G_MESSAGES_DEBUG=all', + 'BUILDDIR=' + meson.current_build_dir(), + 'TOP_BUILDDIR=' + meson.build_root() +] + +test('test-network-panel', + find_program('test-network-panel.py'), + env: envs, + timeout: 10 +) diff --git a/tests/network/nmtst-helpers.h b/tests/network/nmtst-helpers.h new file mode 100644 index 000000000..868da36e3 --- /dev/null +++ b/tests/network/nmtst-helpers.h @@ -0,0 +1,297 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * 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, 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. + * + * Copyright 2010 - 2014, 2018 Red Hat, Inc. + * + */ + +/* Static functions to help with testing */ + + +/* nmtst_create_minimal_connection is copied from nm-test-utils.h. */ + +static inline NMConnection * +nmtst_create_minimal_connection (const char *id, const char *uuid, const char *type, NMSettingConnection **out_s_con) +{ + NMConnection *con; + NMSetting *s_base = NULL; + NMSettingConnection *s_con; + gs_free char *uuid_free = NULL; + + g_assert (id); + + if (uuid) + g_assert (nm_utils_is_uuid (uuid)); + else + uuid = uuid_free = nm_utils_uuid_generate (); + + if (type) { + GType type_g; + + type_g = nm_setting_lookup_type (type); + + g_assert (type_g != G_TYPE_INVALID); + + s_base = g_object_new (type_g, NULL); + g_assert (NM_IS_SETTING (s_base)); + } + + con = nm_simple_connection_new (); + + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + + g_object_set (s_con, + NM_SETTING_CONNECTION_ID, id, + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, type, + NULL); + nm_connection_add_setting (con, NM_SETTING (s_con)); + + if (s_base) + nm_connection_add_setting (con, s_base); + + if (out_s_con) + *out_s_con = s_con; + return con; +} + + +typedef struct { + GMainLoop *loop; + NMDevice *device; + NMClient *client; + + NMActiveConnection *ac; + + const gchar * const *client_props; + const gchar * const *device_props; + + int client_remaining; + int device_remaining; + int other_remaining; +} EventWaitInfo; + + +#define WAIT_CHECK_REMAINING() \ + if (info->client_remaining == 0 && info->device_remaining == 0 && info->other_remaining == 0) { \ + g_debug ("Got expected events, quitting mainloop"); \ + g_main_loop_quit (info->loop); \ + } \ + if (info->client_remaining < 0 || info->device_remaining < 0 || info->other_remaining < 0) { \ + g_error ("Pending events are negative: client: %d, device: %d, other: %d", info->client_remaining, info->device_remaining, info->other_remaining); \ + g_assert_not_reached (); \ + } + +#define WAIT_DECL() \ + EventWaitInfo info = {0}; \ + gint _timeout_id; +#define WAIT_DEVICE(_device, count, ...) \ + info.device = (_device); \ + info.device_remaining = (count); \ + { const gchar * const *props = (const char const *[]){ __VA_ARGS__, NULL }; \ + info.device_props = props; } \ + g_signal_connect ((_device), "notify", G_CALLBACK (device_notify_cb), &info); +#define WAIT_CLIENT(_client, count, ...) \ + info.client = (_client); \ + info.client_remaining = (count); \ + info.client_props = (const char *[]) {__VA_ARGS__, NULL}; \ + g_signal_connect ((_client), "notify", G_CALLBACK (client_notify_cb), &info); + +#define WAIT_DESTROY() \ + g_source_remove (_timeout_id); \ + if (info.device) \ + g_signal_handlers_disconnect_by_func (info.device, G_CALLBACK (device_notify_cb), &info); \ + if (info.client) \ + g_signal_handlers_disconnect_by_func (info.client, G_CALLBACK (client_notify_cb), &info); \ + g_main_loop_unref (info.loop); + +#define WAIT_FINISHED(timeout) \ + info.loop = g_main_loop_new (NULL, FALSE); \ + _timeout_id = g_timeout_add_seconds ((timeout), timeout_cb, &info); \ + g_main_loop_run (info.loop); \ + WAIT_DESTROY() + +static gboolean +timeout_cb (gpointer user_data) +{ + EventWaitInfo *info = user_data; + + if (info) + g_error ("Pending events are: client: %d, device: %d, other: %d", info->client_remaining, info->device_remaining, info->other_remaining); \ + g_assert_not_reached (); + return G_SOURCE_REMOVE; +} + +static void +device_notify_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data) +{ + EventWaitInfo *info = user_data; + + g_assert (device == info->device); + + if (!g_strv_contains (info->device_props, g_param_spec_get_name (pspec))) { + g_debug ("Ignoring notification for device property %s", g_param_spec_get_name (pspec)); + return; + } + + g_debug ("Counting notification for device property %s", g_param_spec_get_name (pspec)); + + info->device_remaining--; + WAIT_CHECK_REMAINING() +} + +static void +client_notify_cb (NMClient *client, GParamSpec *pspec, gpointer user_data) +{ + EventWaitInfo *info = user_data; + + g_assert (client == info->client); + + if (!g_strv_contains (info->client_props, g_param_spec_get_name (pspec))) { + g_debug ("Ignoring notification for client property %s", g_param_spec_get_name (pspec)); + return; + } + + g_debug ("Counting notification for client property %s", g_param_spec_get_name (pspec)); + + info->client_remaining--; + WAIT_CHECK_REMAINING() +} + +static void +nmtst_set_device_state (NMTstcServiceInfo *sinfo, NMDevice *device, NMDeviceState state, NMDeviceStateReason reason) +{ + GError *error = NULL; + WAIT_DECL() + + g_debug ("Setting device %s state to %d with reason %d", nm_device_get_iface (device), state, reason); + + g_dbus_proxy_call_sync (sinfo->proxy, + "SetDeviceState", + g_variant_new ("(suu)", nm_object_get_path (NM_OBJECT (device)), state, reason), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error (error); + + WAIT_DEVICE(device, 1, "state-reason") + WAIT_FINISHED(5) +} + +static void +nmtst_set_wired_speed (NMTstcServiceInfo *sinfo, NMDevice *device, guint32 speed) +{ + GError *error = NULL; + WAIT_DECL() + + g_debug ("Setting device %s speed to %d", nm_device_get_iface (device), speed); + + g_dbus_proxy_call_sync (sinfo->proxy, + "SetWiredSpeed", + g_variant_new ("(su)", nm_object_get_path (NM_OBJECT (device)), speed), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + + g_assert_no_error (error); + + WAIT_DEVICE(device, 2, "speed", "carrier") + WAIT_FINISHED(5) +} + + +static void +device_removed_cb (NMClient *client, + NMDevice *device, + gpointer user_data) +{ + EventWaitInfo *info = user_data; + + g_assert (device); + g_assert (device == info->device); + + info->other_remaining--; + WAIT_CHECK_REMAINING() +} + +static void +nmtst_remove_device (NMTstcServiceInfo *sinfo, NMClient *client, NMDevice *device) +{ + GError *error = NULL; + WAIT_DECL() + + g_object_ref (device); + + g_dbus_proxy_call_sync (sinfo->proxy, + "RemoveDevice", + g_variant_new ("(s)", nm_object_get_path (NM_OBJECT (device))), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + 3000, + NULL, + &error); + g_assert_no_error (error); + + info.device = device; + info.client = client; + info.other_remaining = 1; + g_signal_connect (client, "device-removed", + G_CALLBACK (device_removed_cb), &info); + + WAIT_FINISHED(5) + + g_object_unref(device); + g_signal_handlers_disconnect_by_func (client, device_removed_cb, &info); +} + +static void +add_and_activate_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + NMClient *client = NM_CLIENT (object); + EventWaitInfo *info = user_data; + GError *error = NULL; + + info->ac = nm_client_add_and_activate_connection_finish (client, result, &error); + g_assert_no_error (error); + g_assert (info->ac != NULL); + + info->other_remaining--; + WAIT_CHECK_REMAINING() +} + +static NMActiveConnection* +nmtst_add_and_activate_connection (NMTstcServiceInfo *sinfo, NMClient *client, NMDevice *device, NMConnection *conn) +{ + WAIT_DECL() + + nm_client_add_and_activate_connection_async (client, conn, device, NULL, + NULL, add_and_activate_cb, &info); + + info.other_remaining = 1; + WAIT_CLIENT(client, 1, NM_CLIENT_ACTIVE_CONNECTIONS); + WAIT_DEVICE(device, 1, NM_DEVICE_ACTIVE_CONNECTION); + + g_object_unref (conn); + + WAIT_FINISHED(5) + + g_assert (info.ac != NULL); + + return info.ac; +} diff --git a/tests/network/test-network-panel.c b/tests/network/test-network-panel.c new file mode 100644 index 000000000..9b3c0cab4 --- /dev/null +++ b/tests/network/test-network-panel.c @@ -0,0 +1,382 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (c) 2010-2014, 2018 Red Hat, Inc. + * + * The Control Center is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * The Control Center is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with the Control Center; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Benjamin Berg + */ + +#define G_LOG_DOMAIN "test-network-panel" + +#include "nm-macros-internal.h" + +#include +#include +#include + +#include "nm-test-libnm-utils.h" + +#include +#include +#include +#include + +#include "cc-test-window.h" +#include "shell/cc-object-storage.h" + +#include "nmtst-helpers.h" + +typedef struct { + NMTstcServiceInfo *sinfo; + NMClient *client; + + NMDevice *main_ether; + + GtkWidget *shell; + CcPanel *panel; +} NetworkPanelFixture; + + +extern GType cc_network_panel_get_type (void); + +static void +fixture_set_up_empty (NetworkPanelFixture *fixture, + gconstpointer user_data) +{ + g_autoptr(GError) error = NULL; + + cc_object_storage_initialize (); + + /* Bring up the libnm service. */ + fixture->sinfo = nmtstc_service_init (); + + fixture->client = nm_client_new (NULL, &error); + g_assert_no_error (error); + + fixture->shell = GTK_WIDGET (cc_test_window_new ()); + + fixture->panel = g_object_new (cc_network_panel_get_type (), + "shell", CC_SHELL (fixture->shell), + NULL); + + g_object_ref (fixture->panel); + cc_shell_set_active_panel (CC_SHELL (fixture->shell), fixture->panel); + + gtk_widget_show_all (fixture->shell); +} + +static void +fixture_tear_down (NetworkPanelFixture *fixture, + gconstpointer user_data) +{ + g_clear_object (&fixture->panel); + g_clear_pointer (&fixture->shell, gtk_widget_destroy); + + cc_object_storage_destroy (); + + g_clear_pointer (&fixture->sinfo, nmtstc_service_cleanup); +} + +static void +fixture_set_up_wired (NetworkPanelFixture *fixture, + gconstpointer user_data) +{ + NMDevice *second; + + fixture_set_up_empty (fixture, user_data); + + fixture->main_ether = nmtstc_service_add_wired_device (fixture->sinfo, + fixture->client, + "eth1000", + "52:54:00:ab:db:23", + NULL); + + /* Add/remove one to catch issues with signal disconnects. */ + second = nmtstc_service_add_wired_device (fixture->sinfo, + fixture->client, + "eth1001", + "52:54:00:ab:db:24", + NULL); + nmtst_remove_device (fixture->sinfo, fixture->client, second); +} + +/*****************************************************************************/ + +static void +test_device_add (NetworkPanelFixture *fixture, + gconstpointer user_data) +{ + const gchar *device_path; + + /* Tell the test service to add a new device. + * We use some weird numbers so that the devices will not exist on the + * host system. */ + fixture->main_ether = nmtstc_service_add_wired_device (fixture->sinfo, + fixture->client, + "eth1000", + "52:54:00:ab:db:23", + NULL); + device_path = nm_object_get_path (NM_OBJECT (fixture->main_ether)); + g_debug("Device added: %s\n", device_path); + + g_assert (gtk_test_find_label(fixture->shell, "Wired") != NULL); +} + +static void +test_second_device_add (NetworkPanelFixture *fixture, + gconstpointer user_data) +{ + NMDevice *device; + const gchar *device_path; + + test_device_add (fixture, user_data); + + device = nmtstc_service_add_wired_device (fixture->sinfo, + fixture->client, + "eth1001", + "52:54:00:ab:db:24", + NULL); + device_path = nm_object_get_path (NM_OBJECT (device)); + g_debug("Second device added: %s\n", device_path); + + g_assert_null (gtk_test_find_label (fixture->shell, "Wired")); + g_assert_nonnull (gtk_test_find_label (fixture->shell, "Ethernet (eth1000)")); + g_assert_nonnull (gtk_test_find_label (fixture->shell, "Ethernet (eth1001)")); +} + +static void +test_second_device_add_remove (NetworkPanelFixture *fixture, + gconstpointer user_data) +{ + NMDevice *device; + const gchar *device_path; + + test_device_add (fixture, user_data); + + device = nmtstc_service_add_wired_device (fixture->sinfo, + fixture->client, + "eth1001", + "52:54:00:ab:db:24", + NULL); + device_path = nm_object_get_path (NM_OBJECT (device)); + g_debug("Second device added: %s\n", device_path); + + nmtst_remove_device (fixture->sinfo, fixture->client, device); + g_debug("Second device removed again\n"); + + g_assert_nonnull (gtk_test_find_label (fixture->shell, "Wired")); + g_assert_null (gtk_test_find_label (fixture->shell, "Ethernet (eth1000)")); + g_assert_null (gtk_test_find_label (fixture->shell, "Ethernet (eth1001)")); +} + +/*****************************************************************************/ + +static void +add_cb (GObject *object, + GAsyncResult *result, + gpointer user_data) +{ + NMClient *client = NM_CLIENT (object); + EventWaitInfo *info = user_data; + NMRemoteConnection *remote_conn; + g_autoptr(GError) error = NULL; + + remote_conn = nm_client_add_connection_finish (client, result, &error); + g_assert_no_error (error); + g_assert_nonnull (remote_conn); + g_object_unref (remote_conn); + + info->other_remaining--; + WAIT_CHECK_REMAINING() +} + +static void +test_connection_add (NetworkPanelFixture *fixture, + gconstpointer user_data) +{ + NMConnection *conn; + g_autoptr(GError) error = NULL; + WAIT_DECL() + + conn = nmtst_create_minimal_connection ("test-inactive", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + nm_device_connection_compatible (fixture->main_ether, conn, &error); + g_assert_no_error (error); + + nm_client_add_connection_async (fixture->client, conn, TRUE, NULL, add_cb, &info); + + info.other_remaining = 1; + WAIT_CLIENT(fixture->client, 1, NM_CLIENT_CONNECTIONS); + + g_object_unref (conn); + + WAIT_FINISHED(5) + + /* We have one (non-active) connection only, so we get a special case */ + g_assert_nonnull (gtk_test_find_label (fixture->shell, "Cable unplugged")); +} + +/*****************************************************************************/ + +static void +test_unconnected_carrier_plug (NetworkPanelFixture *fixture, + gconstpointer user_data) +{ + nmtst_set_wired_speed (fixture->sinfo, fixture->main_ether, 1234); + nmtst_set_device_state (fixture->sinfo, fixture->main_ether, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_CARRIER); + + g_assert_nonnull (gtk_test_find_label (fixture->shell, "1234 Mb/s")); +} + + +/*****************************************************************************/ + + +static void +test_connection_add_activate (NetworkPanelFixture *fixture, + gconstpointer user_data) +{ + NMConnection *conn; + NMActiveConnection *active_conn = NULL; + g_autoptr(GError) error = NULL; + GtkWidget *label, *sw; + + /* First set us into disconnected state with a carrier. */ + nmtst_set_wired_speed (fixture->sinfo, fixture->main_ether, 1234); + nmtst_set_device_state (fixture->sinfo, fixture->main_ether, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_CARRIER); + + conn = nmtst_create_minimal_connection ("test-active", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + + nm_device_connection_compatible (fixture->main_ether, conn, &error); + g_assert_no_error (error); + + active_conn = nmtst_add_and_activate_connection (fixture->sinfo, fixture->client, fixture->main_ether, conn); + g_object_unref (active_conn); + + label = gtk_test_find_label (fixture->shell, "1234 Mb/s"); + sw = gtk_test_find_sibling (label, GTK_TYPE_SWITCH); + g_assert_nonnull (sw); + g_assert_false (gtk_switch_get_state (GTK_SWITCH (sw))); + + /* Now set the state to connected and check the switch state */ + nmtst_set_device_state (fixture->sinfo, fixture->main_ether, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_NONE); + g_assert_true (gtk_switch_get_state (GTK_SWITCH (sw))); + + /* Let's toggle the switch back and check we get events */ + gtk_switch_set_active (GTK_SWITCH (sw), FALSE); + + /* Only one connection, so a generic label. */ + g_assert_nonnull (gtk_test_find_label (fixture->shell, "Connected - 1234 Mb/s")); +} + +static void +test_connection_multi_add_activate (NetworkPanelFixture *fixture, + gconstpointer user_data) +{ + NMConnection *conn; + GtkWidget *sw; + g_autoptr(GError) error = NULL; + + /* Add a single connection (just chainging up to other test). */ + test_connection_add (fixture, user_data); + + /* Basically same as test_connection_add_activate but with different assertions. */ + nmtst_set_wired_speed (fixture->sinfo, fixture->main_ether, 1234); + nmtst_set_device_state (fixture->sinfo, fixture->main_ether, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_REASON_CARRIER); + + conn = nmtst_create_minimal_connection ("test-active", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL); + + nm_device_connection_compatible (fixture->main_ether, conn, &error); + g_assert_no_error (error); + + g_object_unref (nmtst_add_and_activate_connection (fixture->sinfo, fixture->client, fixture->main_ether, conn)); + + g_assert_nonnull (gtk_test_find_label (fixture->shell, "test-inactive")); + g_assert_nonnull (gtk_test_find_label (fixture->shell, "test-active")); + g_assert_null (gtk_test_find_label (fixture->shell, "52:54:00:ab:db:23")); + + /* We have no switch if there are multiple connections */ + sw = gtk_test_find_sibling (gtk_test_find_label (fixture->shell, "test-active"), GTK_TYPE_SWITCH); + if (sw) + g_assert_false (gtk_widget_is_visible (sw)); + + /* Now set the state to connected and check the switch state */ + nmtst_set_device_state (fixture->sinfo, fixture->main_ether, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_NONE); + + /* Hardware address is shown at this point */ + g_assert_nonnull (gtk_test_find_label (fixture->shell, "52:54:00:ab:db:23")); +} + +int +main (int argc, char **argv) +{ + g_setenv ("GSETTINGS_BACKEND", "memory", TRUE); + g_setenv ("LIBNM_USE_SESSION_BUS", "1", TRUE); + g_setenv ("LC_ALL", "C", TRUE); + + gtk_test_init (&argc, &argv, NULL); + + g_test_add ("/network-panel-wired/device-add", + NetworkPanelFixture, + NULL, + fixture_set_up_empty, + test_device_add, + fixture_tear_down); + + g_test_add ("/network-panel-wired/second-device-add", + NetworkPanelFixture, + NULL, + fixture_set_up_empty, + test_second_device_add, + fixture_tear_down); + + g_test_add ("/network-panel-wired/second-device-add-remove", + NetworkPanelFixture, + NULL, + fixture_set_up_empty, + test_second_device_add_remove, + fixture_tear_down); + + g_test_add ("/network-panel-wired/unconnected-carrier-plug", + NetworkPanelFixture, + NULL, + fixture_set_up_wired, + test_unconnected_carrier_plug, + fixture_tear_down); + + g_test_add ("/network-panel-wired/connection-add", + NetworkPanelFixture, + NULL, + fixture_set_up_wired, + test_connection_add, + fixture_tear_down); + + g_test_add ("/network-panel-wired/connection-add-activate", + NetworkPanelFixture, + NULL, + fixture_set_up_wired, + test_connection_add_activate, + fixture_tear_down); + + g_test_add ("/network-panel-wired/connection-multi-add-activate", + NetworkPanelFixture, + NULL, + fixture_set_up_wired, + test_connection_multi_add_activate, + fixture_tear_down); + + return g_test_run (); +} + diff --git a/tests/network/test-network-panel.py b/tests/network/test-network-panel.py new file mode 100644 index 000000000..f91958a7a --- /dev/null +++ b/tests/network/test-network-panel.py @@ -0,0 +1,44 @@ +#!/usr/bin/python3 +# Copyright © 2018 Red Hat, Inc +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# Authors: Benjamin Berg + +import os +import sys +import unittest + +try: + import dbusmock +except ImportError: + sys.stderr.write('You need python-dbusmock (http://pypi.python.org/pypi/python-dbusmock) for this test suite.\n') + sys.exit(1) + +# Add the shared directory to the search path +sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'shared')) + +from gtest import GTest +from x11session import X11SessionTestCase + +BUILDDIR = os.environ.get('BUILDDIR', os.path.join(os.path.dirname(__file__))) + + +class PanelTestCase(X11SessionTestCase, GTest): + g_test_exe = os.path.join(BUILDDIR, 'test-network-panel') + + +if __name__ == '__main__': + # avoid writing to stderr + unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2)) -- cgit v1.2.1 From 37b06c126a6005f7124827f9d7088508266a8a50 Mon Sep 17 00:00:00 2001 From: Benjamin Berg Date: Tue, 17 Apr 2018 18:53:56 +0200 Subject: ci: Do not run install for testing There is no need to install g-c-c to run the tests, and in fact, we should ensure that this is the case as it simplifies testing for e.g. distributions. --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ffa4b559a..9d661ea57 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -46,7 +46,6 @@ test: script: - meson . _build - ninja -C _build - - ninja -C _build install - meson test -C _build --verbose --no-stdsplit -- cgit v1.2.1 From 4b91361d9834dadf87793953f54700a9acecce02 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 2 May 2018 18:55:25 -0300 Subject: project: Add issue templates --- .gitlab/issue_templates/Bug.md | 8 ++++++++ .gitlab/issue_templates/Epic.md | 41 ++++++++++++++++++++++++++++++++++++++ .gitlab/issue_templates/Feature.md | 17 ++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 .gitlab/issue_templates/Bug.md create mode 100644 .gitlab/issue_templates/Epic.md create mode 100644 .gitlab/issue_templates/Feature.md diff --git a/.gitlab/issue_templates/Bug.md b/.gitlab/issue_templates/Bug.md new file mode 100644 index 000000000..416478e1d --- /dev/null +++ b/.gitlab/issue_templates/Bug.md @@ -0,0 +1,8 @@ +Detailed description of the issue. Put as much information as you can, potentially +with images showing the issue. + +Steps to reproduce: + +1. Open GNOME Settings +2. Change X to something else +3. ... diff --git a/.gitlab/issue_templates/Epic.md b/.gitlab/issue_templates/Epic.md new file mode 100644 index 000000000..aa7c6a3b5 --- /dev/null +++ b/.gitlab/issue_templates/Epic.md @@ -0,0 +1,41 @@ +# Current problems + + +# Goals & use cases + + +# Requirements + + +# Relevant art + + +# Proposal & plan + + +/label ~"1. Epic" diff --git a/.gitlab/issue_templates/Feature.md b/.gitlab/issue_templates/Feature.md new file mode 100644 index 000000000..d76486658 --- /dev/null +++ b/.gitlab/issue_templates/Feature.md @@ -0,0 +1,17 @@ +Detailed description of the feature. Put as much information as you can. + +Proposed Mockups: + +(Add mockups of the proposed feature) + +## Design Tasks + +* [ ] design tasks + +## Development Tasks + +* [ ] development tasks + +## QA Tasks + +* [ ] qa (quality assurance) tasks -- cgit v1.2.1 From 16f06665dd1670b55b350b85db75770c762d98b9 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 2 May 2018 22:34:23 -0300 Subject: window, shell-model: Silence warnings A fallback from the previous commit. --- shell/cc-shell-model.c | 6 +++--- shell/cc-window.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/shell/cc-shell-model.c b/shell/cc-shell-model.c index 2a69d6a12..220063075 100644 --- a/shell/cc-shell-model.c +++ b/shell/cc-shell-model.c @@ -336,16 +336,16 @@ cc_shell_model_has_panel (CcShellModel *model, g_assert (id); - valid = gtk_tree_model_get_iter_first (model, &iter); + valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter); while (valid) { g_autofree gchar *panel_id = NULL; - gtk_tree_model_get (model, &iter, COL_ID, &panel_id, -1); + gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, COL_ID, &panel_id, -1); if (g_str_equal (id, panel_id)) return TRUE; - valid = gtk_tree_model_iter_next (model, &iter); + valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter); } return FALSE; diff --git a/shell/cc-window.c b/shell/cc-window.c index c05712475..f8dbc0ffb 100644 --- a/shell/cc-window.c +++ b/shell/cc-window.c @@ -756,7 +756,7 @@ cc_window_init (CcWindow *self) /* After everything is loaded, select the last used panel, if any, * or the first visible panel */ id = g_settings_get_string (self->settings, "last-panel"); - if (id != NULL && cc_shell_model_has_panel (self->store, id)) + if (id != NULL && cc_shell_model_has_panel (CC_SHELL_MODEL (self->store), id)) cc_panel_list_set_active_panel (CC_PANEL_LIST (self->panel_list), id); else cc_panel_list_activate (CC_PANEL_LIST (self->panel_list)); -- cgit v1.2.1 From 70b346d8b522b1a9a85e2c7a4232af4c19c74082 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 2 May 2018 23:00:31 -0300 Subject: project: Add coding style and contribution guidelines And also update the README file. --- README | 53 -------------- README.md | 40 +++++++++++ docs/CONTRIBUTING.md | 71 ++++++++++++++++++ docs/HACKING.md | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 311 insertions(+), 53 deletions(-) delete mode 100644 README create mode 100644 README.md create mode 100644 docs/CONTRIBUTING.md create mode 100644 docs/HACKING.md diff --git a/README b/README deleted file mode 100644 index d9646c7a3..000000000 --- a/README +++ /dev/null @@ -1,53 +0,0 @@ -GNOME Control Center -==================== - -About - - -The control center is GNOME's main interface for configuration of various -aspects of your desktop. - -Installation - - -See the file 'INSTALL' - -How to report bugs - - -Bugs should be reported to the GNOME bug tracking system under the product -gnome-control-center. It is available at http://bugzilla.gnome.org. - -In the report please include the following information - - - Operating system and version - For Linux, version of the C library - How to reproduce the bug if possible - If the bug was a crash, include the exact text that was printed out - A stacktrace where possible [see below] - -How to get a stack trace - - -If the crash is reproducible, it is possible to get a stack trace and -attach it to the bug report. The following steps are used to obtain a -stack trace - - - Run the program in gdb [the GNU debugger] or any other debugger - ie. gdb gnome-keyboard-properties - Start the program - ie. (gdb) run - Reproduce the crash and the program will exit to the gdb prompt - Get the back trace - ie. (gdb) bt full - -Once you have the backtrace, copy and paste this either into the -'Comments' field or attach a file with it included. - - -Patches - - -Patches should be submitted to bugzilla.gnome.org or emailed to the -gnomecc-list@gnome.org list. If using bugzilla, attach -the patch to a new bug report [or preferably, check to see if there is -already a bug report that corresponds to your patch]. Bug reports -containing patches should include the 'PATCH' keyword. - -See https://wiki.gnome.org/Newcomers/CodeContributionWorkflow for how to -create patches. diff --git a/README.md b/README.md new file mode 100644 index 000000000..3de9100bc --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +GNOME Settings +==================== + +GNOME Settings is GNOME's main interface for configuration of various aspects of +your desktop. + +## Contributing + +See `docs/CONTRIBUTING.md` for details on the contribution process, and `docs/HACKING.md` +for the coding style guidelines. + +## Reporting Bugs + +Bugs should be reported to the GNOME bug tracking system under the product +gnome-control-center. It is available at https://gitlab.gnome.org. + +In the report please include the following information - + + Operating system and version + For Linux, version of the C library + How to reproduce the bug if possible + If the bug was a crash, include the exact text that was printed out + A stacktrace where possible [see below] + +### How to get a stack trace + +If the crash is reproducible, it is possible to get a stack trace and +attach it to the bug report. The following steps are used to obtain a +stack trace - + + Run the program in gdb [the GNU debugger] or any other debugger + ie. gdb gnome-keyboard-properties + Start the program + ie. (gdb) run + Reproduce the crash and the program will exit to the gdb prompt + Get the back trace + ie. (gdb) bt full + +Once you have the backtrace, copy and paste this either into the +'Comments' field or attach a file with it included. \ No newline at end of file diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md new file mode 100644 index 000000000..7e054da29 --- /dev/null +++ b/docs/CONTRIBUTING.md @@ -0,0 +1,71 @@ +# Contributing + +When contributing to the development of GNOME Settings, please first discuss the change you wish to +make via issue, email, or any other method with the maintainers before making a change. + +Please note we have a Code of Conduct, please follow it in all your interactions with the project. + +## Pull Request Process + +1. Ensure your code compiles and doesn't break anything. Run `meson test -C ` before creating + the pull request. +2. If you're adding new API, it must be properly documented. +3. The commit message is formatted as follows: + ``` + component: + ‌ + A paragraph explaining the problem and its context. +‌ + Another one explaining how you solved that. +‌ + + ``` +4. You may merge the pull request in once you have the sign-off of the maintainers, or if you + do not have permission to do that, you may request the second reviewer to merge it for you. + +## Code of Conduct + +GNOME Settings is a project developed based on GNOME Code of Conduct. You can read it below: + +### Summary + +GNOME creates software for a better world. We achieve this by behaving well towards +each other. + +Therefore this document suggests what we consider ideal behaviour, so you know what +to expect when getting involved in GNOME. This is who we are and what we want to be. +There is no official enforcement of these principles, and this should not be interpreted +like a legal document. + +### Advice + + * **Be respectful and considerate**: Disagreement is no excuse for poor behaviour or personal + attacks. Remember that a community where people feel uncomfortable is not a productive one. + + * **Be patient and generous**: If someone asks for help it is because they need it. Do politely + suggest specific documentation or more appropriate venues where appropriate, but avoid + aggressive or vague responses such as "RTFM". + + * **Assume people mean well**: Remember that decisions are often a difficult choice between + competing priorities. If you disagree, please do so politely. If something seems outrageous, + check that you did not misinterpret it. Ask for clarification, but do not assume the worst. + + * **Try to be concise**: Avoid repeating what has been said already. Making a conversation larger + makes it difficult to follow, and people often feel personally attacked if they receive multiple + messages telling them the same thing. + + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and +orientation. + +### Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ \ No newline at end of file diff --git a/docs/HACKING.md b/docs/HACKING.md new file mode 100644 index 000000000..aa798d44e --- /dev/null +++ b/docs/HACKING.md @@ -0,0 +1,200 @@ +# Style + +GNOME Settings has a coding style based on GTK Coding Style, but with a few more +rules. Please read them carefully and, if in doubt, ask a maintainer for directions. + +## General + +The most important rule is: **see the surrounding code, and copy its style**. + +Another rule that applies to function declarations is that all parameters are +aligned by the last '*'. There are plenty of examples below. + +## Header (.h) files + +It is organized by the following structure: + + 1. GPL header + 2. Local includes + 3. System includes + 4. `G_BEGIN_DECLS` + 5. `#defines` + 6. `G_DECLARE_{FINAL,DERIVABLE}_TYPE` + 7. Public API + 8. `G_END_DECLS` + +The following style rules apply: + + * The '*' and the type come together, without any spaces in between. + * Function names are aligned by the widest return value. + * Parenthesis after function name is aligned by the widest function name + * The last '*' in parameters are aligned by the widest parameter type + * No new line at the end of the file + +As an example, this is how a header file should look like (extracted from +the `cc-object-storage.h` file): + +```c +/* cc-object-storage.h + * + * Copyright 2018 Georges Basile Stavracas Neto + * + * 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 . + */ + +#pragma once + +#include +#include + +G_BEGIN_DECLS + +/* Default storage keys */ +#define CC_OBJECT_NMCLIENT "CcObjectStorage::nm-client" + + +#define CC_TYPE_OBJECT_STORAGE (cc_object_storage_get_type()) + +G_DECLARE_FINAL_TYPE (CcObjectStorage, cc_object_storage, CC, OBJECT_STORAGE, GObject) + +gboolean cc_object_storage_has_object (const gchar *key); + +void cc_object_storage_add_object (const gchar *key, + gpointer object); + +gpointer cc_object_storage_get_object (const gchar *key); + +gpointer cc_object_storage_create_dbus_proxy_sync (GBusType bus_type, + GDBusProxyFlags flags, + const gchar *name, + const gchar *path, + const gchar *interface, + GCancellable *cancellable, + GError **error); + +void cc_object_storage_create_dbus_proxy (GBusType bus_type, + GDBusProxyFlags flags, + const gchar *name, + const gchar *path, + const gchar *interface, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +G_END_DECLS +``` + +## Source code + +The source file keeps an order of methods. The order will be as following: + + 1. GPL header + 2. Structures + 3. Function prototypes + 4. G_DEFINE_TYPE() + 5. Enums + 6. Static variables + 7. Auxiliary methods + 8. Callbacks + 9. Interface implementations + 10. Parent class overrides + 11. class_init and init + 12. Public API + +### Structures + +The structures must have the first pointer asterisk aligned one space after the +widest type name. For example: + +```c +typedef struct +{ + GBusType bus_type; + GDBusProxyFlags flags; + gchar *name; + gchar *path; + gchar *interface; + gboolean cached; +} TaskData; + +``` + +### Function Prototypes + +Function prototypes must be formatted just like in header files. + +### Auxiliary Methods + +Auxiliary method names must have a verb in the dictionary form, and should always +perform an action over something. They don't have the `cc_` prefix. For example: + +```c +static void +execute_something_on_data (Foo *data, + Bar *bar) +{ + /* ... */ +} +``` + +### Callbacks + + * Callbacks always have the `_cb` suffix + * Signal callbacks always have the `on_` prefix + * Callback names must have the name of the signal in the past + +For example: + +```c +static void +on_foo_size_allocated_cb (GtkWidget *widget, + GtkAllocation *allocation, + gpointer user_data) +{ + /* ... */ +} +``` + +### Line Splitting + +Line splitting works following the GTK code style, but legibility comes over above +all. If a function call looks unbalanced following the GTK style, it is fine to +slightly escape the rules. + +For example, this feels extremelly unbalanced: + +```c +foo_bar_do_somthing_sync (a, + 1, + object, + data, + something + cancellable, + &error); +``` + +Notice the empty space before the arguments, and how empty and odd it looks. In +comparison, it will look better if written like this: + +```c +foo_bar_do_somthing_sync (a, 1, object, data, + something + cancellable, + &error); +``` + +# Contributing guidelines + +See CONTRIBUTIONS.md file for the contribution guidelines, and the Code of Conduct +that contributors are expected to follow. \ No newline at end of file -- cgit v1.2.1 From 3228632d55fb0dffae3015022dfb814d0bdb13c9 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 2 May 2018 23:01:18 -0300 Subject: project: Update DOAP file The maintainers listed there aren't maintaining it anymore, and shouldn't be pinged about Settings. Please let me know if any of you want your maintainership status back again. --- gnome-control-center.doap | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) diff --git a/gnome-control-center.doap b/gnome-control-center.doap index 08b1f9f87..a7ca2e001 100644 --- a/gnome-control-center.doap +++ b/gnome-control-center.doap @@ -4,36 +4,15 @@ xmlns:gnome="http://api.gnome.org/doap-extensions#" xmlns="http://usefulinc.com/ns/doap#"> - gnome-control-center + GNOME Settings GNOME's main interface to configure various aspects of the desktop GNOME's main interface to configure various aspects of the desktop - + C - - - Rui Matos - - rtcm - - - - - Richard Hughes - - rhughes - - - - - Olivier Fourdan - - ofourdan - - Georges Basile Stavracas Neto -- cgit v1.2.1 From 36af5e51d13b035eb3eb6b7d196d8924996ce344 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 2 May 2018 23:11:48 -0300 Subject: shell-model: Remove boilerplate and update code style --- shell/cc-shell-model.c | 37 +++++++++++++------------- shell/cc-shell-model.h | 70 ++++++++++++-------------------------------------- 2 files changed, 34 insertions(+), 73 deletions(-) diff --git a/shell/cc-shell-model.c b/shell/cc-shell-model.c index 220063075..4dcddba45 100644 --- a/shell/cc-shell-model.c +++ b/shell/cc-shell-model.c @@ -19,23 +19,25 @@ * Author: Thomas Wood */ +#include "cc-shell-model.h" +#include "cc-util.h" + #include #include -#include "cc-shell-model.h" -#include "cc-util.h" - #define GNOME_SETTINGS_PANEL_ID_KEY "X-GNOME-Settings-Panel" #define GNOME_SETTINGS_PANEL_CATEGORY GNOME_SETTINGS_PANEL_ID_KEY #define GNOME_SETTINGS_PANEL_ID_KEYWORDS "Keywords" -struct _CcShellModelPrivate +struct _CcShellModel { - gchar **sort_terms; + GtkListStore parent; + + GStrv sort_terms; }; -G_DEFINE_TYPE_WITH_PRIVATE (CcShellModel, cc_shell_model, GTK_TYPE_LIST_STORE) +G_DEFINE_TYPE (CcShellModel, cc_shell_model, GTK_TYPE_LIST_STORE) static gint sort_by_name (GtkTreeModel *model, @@ -224,20 +226,19 @@ cc_shell_model_sort_func (GtkTreeModel *model, gpointer data) { CcShellModel *self = data; - CcShellModelPrivate *priv = self->priv; - if (!priv->sort_terms || !priv->sort_terms[0]) + if (!self->sort_terms || !self->sort_terms[0]) return sort_by_name (model, a, b); else - return sort_with_terms (model, a, b, priv->sort_terms); + return sort_with_terms (model, a, b, self->sort_terms); } static void cc_shell_model_finalize (GObject *object) { - CcShellModelPrivate *priv = CC_SHELL_MODEL (object)->priv;; + CcShellModel *self = CC_SHELL_MODEL (object); - g_strfreev (priv->sort_terms); + g_clear_pointer (&self->sort_terms, g_strfreev); G_OBJECT_CLASS (cc_shell_model_parent_class)->finalize (object); } @@ -245,9 +246,8 @@ cc_shell_model_finalize (GObject *object) static void cc_shell_model_class_init (CcShellModelClass *klass) { - GObjectClass *gobject_class; + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - gobject_class = G_OBJECT_CLASS (klass); gobject_class->finalize = cc_shell_model_finalize; } @@ -257,8 +257,6 @@ cc_shell_model_init (CcShellModel *self) GType types[] = {G_TYPE_STRING, G_TYPE_STRING, G_TYPE_APP_INFO, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_ICON, G_TYPE_STRV}; - self->priv = cc_shell_model_get_instance_private (self); - gtk_list_store_set_column_types (GTK_LIST_STORE (self), N_COLS, types); @@ -390,13 +388,14 @@ void cc_shell_model_set_sort_terms (CcShellModel *self, gchar **terms) { - CcShellModelPrivate *priv = self->priv; + g_return_if_fail (CC_IS_SHELL_MODEL (self)); - g_strfreev (priv->sort_terms); - priv->sort_terms = g_strdupv (terms); + g_clear_pointer (&self->sort_terms, g_strfreev); + self->sort_terms = g_strdupv (terms); /* trigger a re-sort */ gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (self), cc_shell_model_sort_func, - self, NULL); + self, + NULL); } diff --git a/shell/cc-shell-model.h b/shell/cc-shell-model.h index 4ba8342e5..b0fe50ff6 100644 --- a/shell/cc-shell-model.h +++ b/shell/cc-shell-model.h @@ -18,9 +18,7 @@ * Author: Thomas Wood */ - -#ifndef _CC_SHELL_MODEL_H -#define _CC_SHELL_MODEL_H +#pragma once #include @@ -28,31 +26,10 @@ G_BEGIN_DECLS #define CC_TYPE_SHELL_MODEL cc_shell_model_get_type() -#define CC_SHELL_MODEL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - CC_TYPE_SHELL_MODEL, CcShellModel)) - -#define CC_SHELL_MODEL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), \ - CC_TYPE_SHELL_MODEL, CcShellModelClass)) - -#define CC_IS_SHELL_MODEL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - CC_TYPE_SHELL_MODEL)) - -#define CC_IS_SHELL_MODEL_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - CC_TYPE_SHELL_MODEL)) +G_DECLARE_FINAL_TYPE (CcShellModel, cc_shell_model, CC, SHELL_MODEL, GtkListStore) -#define CC_SHELL_MODEL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - CC_TYPE_SHELL_MODEL, CcShellModelClass)) - -typedef struct _CcShellModel CcShellModel; -typedef struct _CcShellModelClass CcShellModelClass; -typedef struct _CcShellModelPrivate CcShellModelPrivate; - -typedef enum { +typedef enum +{ CC_CATEGORY_CONNECTIVITY, CC_CATEGORY_PERSONALIZATION, CC_CATEGORY_ACCOUNT, @@ -77,37 +54,22 @@ enum N_COLS }; -struct _CcShellModel -{ - GtkListStore parent; - CcShellModelPrivate *priv; -}; - -struct _CcShellModelClass -{ - GtkListStoreClass parent_class; -}; +CcShellModel* cc_shell_model_new (void); -GType cc_shell_model_get_type (void) G_GNUC_CONST; +void cc_shell_model_add_item (CcShellModel *model, + CcPanelCategory category, + GAppInfo *appinfo, + const char *id); -CcShellModel *cc_shell_model_new (void); +gboolean cc_shell_model_has_panel (CcShellModel *model, + const char *id); -void cc_shell_model_add_item (CcShellModel *model, - CcPanelCategory category, - GAppInfo *appinfo, - const char *id); +gboolean cc_shell_model_iter_matches_search (CcShellModel *model, + GtkTreeIter *iter, + const char *term); -gboolean cc_shell_model_has_panel (CcShellModel *model, - const char *id); - -gboolean cc_shell_model_iter_matches_search (CcShellModel *model, - GtkTreeIter *iter, - const char *term); - -void cc_shell_model_set_sort_terms (CcShellModel *model, - gchar **terms); +void cc_shell_model_set_sort_terms (CcShellModel *model, + GStrv terms); G_END_DECLS - -#endif /* _CC_SHELL_MODEL_H */ -- cgit v1.2.1 From af0186aaf99cb6add6b5a3c85828e8a4d6e49fd5 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Thu, 3 May 2018 00:45:29 -0300 Subject: project: Update meson files I probably have OCD. Seeing these files with this poor alignment gives me physical pain. --- data/icons/meson.build | 4 +- man/meson.build | 12 +++--- meson.build | 2 +- panels/wacom/meson.build | 54 +++++++++++++-------------- search-provider/meson.build | 30 +++++++-------- shell/meson.build | 90 +++++++++++++++++++++++---------------------- tests/common/meson.build | 10 ++--- tests/datetime/meson.build | 14 +++---- tests/info/meson.build | 12 +++--- tests/network/meson.build | 19 +++++----- tests/printers/meson.build | 12 +++--- 11 files changed, 129 insertions(+), 130 deletions(-) diff --git a/data/icons/meson.build b/data/icons/meson.build index 0f9a7eb54..a6a6c221f 100644 --- a/data/icons/meson.build +++ b/data/icons/meson.build @@ -1,4 +1,4 @@ install_subdir( - 'hicolor', - install_dir: control_center_icondir + 'hicolor', + install_dir : control_center_icondir ) diff --git a/man/meson.build b/man/meson.build index cab3fa945..1e9e08971 100644 --- a/man/meson.build +++ b/man/meson.build @@ -17,10 +17,10 @@ xsltproc_cmd = [ output = meson.project_name() + '.1' custom_target( - output, - input: meson.project_name() + '.xml', - output: output, - command: xsltproc_cmd, - install: true, - install_dir: join_paths(control_center_mandir, 'man1') + output, + input : meson.project_name() + '.xml', + output : output, + command : xsltproc_cmd, + install : true, + install_dir : join_paths(control_center_mandir, 'man1') ) diff --git a/meson.build b/meson.build index 16911d990..2e7a36d3c 100644 --- a/meson.build +++ b/meson.build @@ -65,7 +65,6 @@ optimized_src = ''' ''' control_center_optimized = get_option('buildtype').contains('optimized') and cc.compiles(optimized_src) -message('whether_optimization is enabled: ' + control_center_optimized.to_string()) if control_center_optimized common_flags += '-Wp,-D_FORTIFY_SOURCE=2' @@ -282,6 +281,7 @@ output += ' Options \n' output += ' Documentation .............................. ' + get_option('documentation').to_string() + '\n' output += ' Tracing .................................... ' + enable_tracing.to_string() + '\n' output += ' gnome-session libexecdir ................... ' + gnome_session_libexecdir + '\n' +output += ' Optimized .................................. ' + control_center_optimized.to_string() + '\n' output += ' Panels \n' output += ' GNOME Bluetooth (Bluetooth panel) .......... ' + host_is_linux_not_s390.to_string() + '\n' output += ' Cheese (Users panel webcam support) ........ ' + enable_cheese.to_string() + '\n' diff --git a/panels/wacom/meson.build b/panels/wacom/meson.build index d323a818a..e206b00e9 100644 --- a/panels/wacom/meson.build +++ b/panels/wacom/meson.build @@ -15,19 +15,19 @@ panels_list += cappletname desktop = 'gnome-@0@-panel.desktop'.format(cappletname) desktop_in = configure_file( - input: desktop + '.in.in', - output: desktop + '.in', - configuration: desktop_conf + input : desktop + '.in.in', + output : desktop + '.in', + configuration : desktop_conf ) i18n.merge_file( - desktop, - type: 'desktop', - input: desktop_in, - output: desktop, - po_dir: po_dir, - install: true, - install_dir: control_center_desktopdir + desktop, + type : 'desktop', + input : desktop_in, + output : desktop, + po_dir : po_dir, + install : true, + install_dir : control_center_desktopdir ) common_sources = files( @@ -62,10 +62,10 @@ resource_data = files( common_sources += gnome.compile_resources( 'cc-' + cappletname + '-resources', cappletname + '.gresource.xml', - source_dir: '.', - c_name: 'cc_' + cappletname, - dependencies: resource_data, - export: true + source_dir : '.', + c_name : 'cc_' + cappletname, + dependencies : resource_data, + export : true ) sources = common_sources + files( @@ -82,13 +82,11 @@ incs = [ panels_libs += static_library( cappletname + '-properties', - sources: sources, - include_directories: incs, - dependencies: deps, - c_args: cflags, - link_with: [ - libwacom_calibrator - ] + sources : sources, + include_directories : incs, + dependencies : deps, + c_args : cflags, + link_with : [ libwacom_calibrator ] ) name = 'test-wacom' @@ -96,12 +94,10 @@ name = 'test-wacom' sources = common_sources + files(name + '.c') executable( - name, - sources, - include_directories: incs, - dependencies: deps, - c_args: test_cflags, - link_with: [ - libwacom_calibrator_test - ] + name, + sources, + include_directories : incs, + dependencies : deps, + c_args : test_cflags, + link_with : [ libwacom_calibrator_test ] ) diff --git a/search-provider/meson.build b/search-provider/meson.build index ef24b2f01..294464c5d 100644 --- a/search-provider/meson.build +++ b/search-provider/meson.build @@ -4,11 +4,11 @@ service_conf.set('libexecdir', control_center_libexecdir) service = 'org.gnome.ControlCenter.SearchProvider.service' configure_file( - input: service + '.in', - output: service, - install: true, - install_dir: join_paths(control_center_datadir, 'dbus-1', 'services'), - configuration: service_conf + input : service + '.in', + output : service, + install : true, + install_dir : join_paths(control_center_datadir, 'dbus-1', 'services'), + configuration : service_conf ) install_data( @@ -26,8 +26,8 @@ sources = files( sources += gnome.gdbus_codegen( 'cc-shell-search-provider-generated', 'org.gnome.ShellSearchProvider2.xml', - interface_prefix: 'org.gnome.', - namespace: 'Cc' + interface_prefix : 'org.gnome.', + namespace : 'Cc' ) cflags = '-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir) @@ -38,12 +38,12 @@ libs = [ ] executable( - meson.project_name() + '-search-provider', - sources, - include_directories: top_inc, - dependencies: shell_deps, - c_args: cflags, - link_with: libs, - install: true, - install_dir: control_center_libexecdir + 'gnome-control-center-search-provider', + sources, + include_directories : top_inc, + dependencies : shell_deps, + c_args : cflags, + link_with : libs, + install : true, + install_dir : control_center_libexecdir ) diff --git a/shell/meson.build b/shell/meson.build index 241b140ca..73b18f84e 100644 --- a/shell/meson.build +++ b/shell/meson.build @@ -7,39 +7,39 @@ service_conf.set('bindir', control_center_bindir) service = 'org.gnome.ControlCenter.service' configure_file( - input: service + '.in', - output: service, - install: true, - install_dir: join_paths(control_center_datadir, 'dbus-1', 'services'), - configuration: service_conf + input : service + '.in', + output : service, + install : true, + install_dir : join_paths(control_center_datadir, 'dbus-1', 'services'), + configuration : service_conf ) desktop = 'gnome-control-center.desktop' desktop_in = configure_file( - input: desktop + '.in.in', - output: desktop + '.in', - configuration: desktop_conf + input : desktop + '.in.in', + output : desktop + '.in', + configuration : desktop_conf ) i18n.merge_file( - desktop, - type: 'desktop', - input: desktop_in, - output: desktop, - po_dir: po_dir, - install: true, - install_dir: control_center_desktopdir + desktop, + type : 'desktop', + input : desktop_in, + output : desktop, + po_dir : po_dir, + install : true, + install_dir : control_center_desktopdir ) cflags = ['-DGNOMELOCALEDIR="@0@"'.format(control_center_localedir)] libshell = static_library( - 'shell', - sources: 'cc-shell-model.c', - include_directories: [top_inc, common_inc], - dependencies: common_deps, - c_args: cflags + 'shell', + sources : 'cc-shell-model.c', + include_directories : [top_inc, common_inc], + dependencies : common_deps, + c_args : cflags ) sources = files( @@ -93,30 +93,30 @@ debug_conf.set('BUGREPORT_URL', 'http://bugzilla.gnome.org/enter_bug.cgi?product debug_conf.set10('ENABLE_TRACING', enable_tracing) sources += configure_file( - input: 'cc-debug.h.in', - output: 'cc-debug.h', - configuration: debug_conf + input : 'cc-debug.h.in', + output : 'cc-debug.h', + configuration : debug_conf ) executable( meson.project_name(), - sources, - include_directories: top_inc, - dependencies: shell_deps, - c_args: cflags, - link_with: panels_libs + [libshell], - install: true + sources, + include_directories : top_inc, + dependencies : shell_deps, + c_args : cflags, + link_with : panels_libs + [libshell], + install : true ) # Because it is confusing and somewhat problematic to directly add and compile # cc-panel-loader.o by another directory (i.e. the shell search provider), we # have to create a library and link it there, just like libshell.la. libpanel_loader = static_library( - 'panel_loader', - sources: 'cc-panel-loader.c', - include_directories: top_inc, - dependencies: common_deps, - c_args: cflags + ['-DCC_PANEL_LOADER_NO_GTYPES'] + 'panel_loader', + sources : 'cc-panel-loader.c', + include_directories : top_inc, + dependencies : common_deps, + c_args : cflags + ['-DCC_PANEL_LOADER_NO_GTYPES'] ) # libshell_test @@ -127,19 +127,21 @@ sources = files( 'cc-object-storage.c', ) libtestshell = static_library( - 'testshell', - sources, - include_directories: top_inc, - dependencies: common_deps + [ libwidgets_dep ], - c_args: cflags, - link_with: panels_libs + 'testshell', + sources, + include_directories : top_inc, + dependencies : common_deps + [ libwidgets_dep ], + c_args : cflags, + link_with : panels_libs ) libtestshell_dep = declare_dependency( - include_directories: top_inc, - link_with: libtestshell + include_directories : top_inc, + link_with : libtestshell ) libtestshell_deps = common_deps + [ libwidgets_dep, libtestshell_dep ] -install_data ('org.gnome.ControlCenter.gschema.xml', - install_dir: control_center_schemadir) +install_data ( + 'org.gnome.ControlCenter.gschema.xml', + install_dir : control_center_schemadir +) diff --git a/tests/common/meson.build b/tests/common/meson.build index 7fb2cdc23..4d982f029 100644 --- a/tests/common/meson.build +++ b/tests/common/meson.build @@ -12,11 +12,11 @@ cflags = [ ] exe = executable( - test_unit, - sources, - include_directories: [ top_inc, common_inc ], - dependencies: common_deps + [libwidgets_dep], - c_args: cflags, + test_unit, + sources, + include_directories : [ top_inc, common_inc ], + dependencies : common_deps + [libwidgets_dep], + c_args : cflags, ) test(test_unit, exe) diff --git a/tests/datetime/meson.build b/tests/datetime/meson.build index 738651c6d..b1dd514b4 100644 --- a/tests/datetime/meson.build +++ b/tests/datetime/meson.build @@ -1,6 +1,6 @@ test_units = [ - #'test-timezone', + 'test-timezone', 'test-timezone-gfx', 'test-endianess', ] @@ -13,12 +13,12 @@ cflags = [ foreach unit: test_units exe = executable( - unit, - [unit + '.c'], - include_directories: includes, - dependencies: common_deps + [m_dep], - link_with: [datetime_panel_lib], - c_args: cflags + unit, + [unit + '.c'], + include_directories : includes, + dependencies : common_deps + [m_dep], + link_with : [datetime_panel_lib], + c_args : cflags ) test(unit, exe) diff --git a/tests/info/meson.build b/tests/info/meson.build index a495ced94..202e9e34e 100644 --- a/tests/info/meson.build +++ b/tests/info/meson.build @@ -8,12 +8,12 @@ cflags = '-DTEST_SRCDIR="@0@"'.format(meson.current_source_dir()) foreach unit: test_units exe = executable( - unit, - [unit + '.c'], - include_directories: includes, - dependencies: common_deps, - link_with: [info_panel_lib], - c_args: cflags + unit, + [unit + '.c'], + include_directories : includes, + dependencies : common_deps, + link_with : [info_panel_lib], + c_args : cflags ) test(unit, exe) diff --git a/tests/network/meson.build b/tests/network/meson.build index 4378ea72a..5c929232b 100644 --- a/tests/network/meson.build +++ b/tests/network/meson.build @@ -11,20 +11,21 @@ cflags = [ exe = executable( 'test-network-panel', ['test-network-panel.c', 'cc-test-window.c', 'nm-utils/nm-test-utils-impl.c'], - include_directories: includes + [common_inc], - dependencies: common_deps + network_manager_deps + [libtestshell_dep], - link_with: [network_panel_lib], - c_args: cflags + include_directories : includes + [common_inc], + dependencies : common_deps + network_manager_deps + [libtestshell_dep], + link_with : [network_panel_lib], + c_args : cflags ) envs = [ 'G_MESSAGES_DEBUG=all', - 'BUILDDIR=' + meson.current_build_dir(), - 'TOP_BUILDDIR=' + meson.build_root() + 'BUILDDIR=' + meson.current_build_dir(), + 'TOP_BUILDDIR=' + meson.build_root() ] -test('test-network-panel', +test( + 'test-network-panel', find_program('test-network-panel.py'), - env: envs, - timeout: 10 + env : envs, + timeout : 10 ) diff --git a/tests/printers/meson.build b/tests/printers/meson.build index be7fecbd2..bbf43ab0c 100644 --- a/tests/printers/meson.build +++ b/tests/printers/meson.build @@ -9,12 +9,12 @@ cflags = '-DTEST_SRCDIR="@0@"'.format(meson.current_source_dir()) foreach unit: test_units exe = executable( - unit, - [unit + '.c'], - include_directories: includes, - dependencies: common_deps, - link_with: [printers_panel_lib], - c_args: cflags + unit, + [unit + '.c'], + include_directories : includes, + dependencies : common_deps, + link_with : [printers_panel_lib], + c_args : cflags ) test(unit, exe) -- cgit v1.2.1 From 2efd5442d5cae072db2e4e1749bd9759a3464ea0 Mon Sep 17 00:00:00 2001 From: Fabio Tomat Date: Fri, 4 May 2018 12:16:04 +0000 Subject: Update Friulian translation --- po/fur.po | 837 +++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 523 insertions(+), 314 deletions(-) diff --git a/po/fur.po b/po/fur.po index 7cc4bb2dc..138e54354 100644 --- a/po/fur.po +++ b/po/fur.po @@ -9,8 +9,8 @@ msgstr "" "Project-Id-Version: gnome-control-center master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-control-center/" "issues\n" -"POT-Creation-Date: 2018-02-23 19:10+0000\n" -"PO-Revision-Date: 2018-02-24 06:09+0100\n" +"POT-Creation-Date: 2018-04-19 13:00+0000\n" +"PO-Revision-Date: 2018-05-04 14:15+0200\n" "Last-Translator: Fabio Tomat \n" "Language-Team: Friulian \n" "Language: fur\n" @@ -18,7 +18,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.0.3\n" +"X-Generator: Poedit 2.0.7\n" #: panels/background/background.ui:49 msgid "_Background" @@ -103,16 +103,16 @@ msgstr "" "Al è pussibil zontâ imagjins ae tô cartele %s e a vegnaran mostradis a chi" #: panels/background/cc-background-chooser-dialog.c:560 -#: panels/color/cc-color-panel.c:225 panels/color/cc-color-panel.c:963 +#: panels/color/cc-color-panel.c:224 panels/color/cc-color-panel.c:962 #: panels/color/color-calibrate.ui:25 panels/color/color.ui:657 -#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2594 +#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2610 #: panels/network/connection-editor/connection-editor.ui:15 #: panels/network/connection-editor/vpn-helpers.c:181 #: panels/network/connection-editor/vpn-helpers.c:310 #: panels/network/net-device-wifi.c:1411 panels/network/net-device-wifi.c:1491 #: panels/network/net-device-wifi.c:1736 panels/network/network-wifi.ui:24 #: panels/printers/new-printer-dialog.ui:45 -#: panels/printers/pp-details-dialog.c:331 +#: panels/printers/pp-details-dialog.c:330 #: panels/privacy/cc-privacy-panel.c:1053 panels/region/format-chooser.ui:25 #: panels/region/input-chooser.ui:13 #: panels/search/cc-search-locations-dialog.c:642 @@ -121,10 +121,10 @@ msgstr "" #: panels/user-accounts/data/join-dialog.ui:20 #: panels/user-accounts/data/password-dialog.ui:21 #: panels/user-accounts/um-fingerprint-dialog.c:261 -#: panels/user-accounts/um-photo-dialog.c:102 -#: panels/user-accounts/um-photo-dialog.c:229 -#: panels/user-accounts/um-user-panel.c:635 -#: panels/user-accounts/um-user-panel.c:653 +#: panels/user-accounts/um-photo-dialog.c:103 +#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-user-panel.c:634 +#: panels/user-accounts/um-user-panel.c:652 msgid "_Cancel" msgstr "_Anule" @@ -169,39 +169,39 @@ msgstr "preferences-desktop-wallpaper" msgid "Wallpaper;Screen;Desktop;" msgstr "Rivestiment;Sfont;Scrivanie;Desktop;" -#: panels/bluetooth/cc-bluetooth-panel.c:265 +#: panels/bluetooth/cc-bluetooth-panel.c:266 msgid "Turn Off Airplane Mode" msgstr "Distude Modalitât Avion" -#: panels/bluetooth/cc-bluetooth-panel.c:330 +#: panels/bluetooth/cc-bluetooth-panel.c:329 msgid "No Bluetooth Found" msgstr "Nissun Bluetooth cjatât" -#: panels/bluetooth/cc-bluetooth-panel.c:330 +#: panels/bluetooth/cc-bluetooth-panel.c:329 msgid "Plug in a dongle to use Bluetooth." msgstr "Tache une clâf par doprâ il Bluetooth." -#: panels/bluetooth/cc-bluetooth-panel.c:331 +#: panels/bluetooth/cc-bluetooth-panel.c:330 msgid "Bluetooth Turned Off" msgstr "Bluetooth distudât" -#: panels/bluetooth/cc-bluetooth-panel.c:331 +#: panels/bluetooth/cc-bluetooth-panel.c:330 msgid "Turn on to connect devices and receive file transfers." msgstr "Impie par coneti dispositîfs e ricevi trasferiments file." -#: panels/bluetooth/cc-bluetooth-panel.c:332 +#: panels/bluetooth/cc-bluetooth-panel.c:331 msgid "Airplane Mode is on" msgstr "Modalitât Avion impiade" -#: panels/bluetooth/cc-bluetooth-panel.c:332 +#: panels/bluetooth/cc-bluetooth-panel.c:331 msgid "Bluetooth is disabled when airplane mode is on." msgstr "Il Bluetooth nol è abilitât cuant che la modalitât avion e je impiade." -#: panels/bluetooth/cc-bluetooth-panel.c:333 +#: panels/bluetooth/cc-bluetooth-panel.c:332 msgid "Hardware Airplane Mode is on" msgstr "Modalitât avion hardware impiade" -#: panels/bluetooth/cc-bluetooth-panel.c:333 +#: panels/bluetooth/cc-bluetooth-panel.c:332 msgid "Turn off the Airplane mode switch to enable Bluetooth." msgstr "Distude il cric de modalitât Avion par abilitâ il Bluetooth." @@ -226,7 +226,7 @@ msgid "share;sharing;bluetooth;obex;" msgstr "condividi;condivision;bluetooth;obex;" #. TRANSLATORS: The user has to attach the sensor to the screen -#: panels/color/cc-color-calibrate.c:361 +#: panels/color/cc-color-calibrate.c:363 msgid "Place your calibration device over the square and press “Start”" msgstr "" "Place il tô dispositîf di calibrazion parsore dal cuadrât e sclice «Start»" @@ -234,7 +234,7 @@ msgstr "" #. TRANSLATORS: Some calibration devices need the user to move a #. * dial or switch manually. We also show a picture showing them #. * what to do... -#: panels/color/cc-color-calibrate.c:367 +#: panels/color/cc-color-calibrate.c:369 msgid "" "Move your calibration device to the calibrate position and press “Continue”" msgstr "" @@ -244,7 +244,7 @@ msgstr "" #. TRANSLATORS: Some calibration devices need the user to move a #. * dial or switch manually. We also show a picture showing them #. * what to do... -#: panels/color/cc-color-calibrate.c:373 +#: panels/color/cc-color-calibrate.c:375 msgid "" "Move your calibration device to the surface position and press “Continue”" msgstr "" @@ -254,54 +254,54 @@ msgstr "" #. TRANSLATORS: on some hardware e.g. Lenovo W700 the sensor #. * is built into the palmrest and we need to fullscreen the #. * sample widget and shut the lid. -#: panels/color/cc-color-calibrate.c:379 +#: panels/color/cc-color-calibrate.c:381 msgid "Shut the laptop lid" msgstr "Siere il tapon (visôr) dal portatil" #. TRANSLATORS: We suck, the calibation failed and we have no #. * good idea why or any suggestions -#: panels/color/cc-color-calibrate.c:410 +#: panels/color/cc-color-calibrate.c:412 msgid "An internal error occurred that could not be recovered." msgstr "Al è vignût fûr un erôr interni impussibil di recuperâ." #. TRANSLATORS: Some required-at-runtime tools were not #. * installed, which should only affect insane distros -#: panels/color/cc-color-calibrate.c:415 +#: panels/color/cc-color-calibrate.c:417 msgid "Tools required for calibration are not installed." msgstr "I struments necessaris pe calibradure no son instalâts." #. TRANSLATORS: The profile failed for some reason -#: panels/color/cc-color-calibrate.c:421 +#: panels/color/cc-color-calibrate.c:423 msgid "The profile could not be generated." msgstr "Impussibil gjenerâ il profîl." #. TRANSLATORS: The user specified a whitepoint that was #. * unobtainable with the hardware they've got -- see #. * https://en.wikipedia.org/wiki/White_point for details -#: panels/color/cc-color-calibrate.c:427 +#: panels/color/cc-color-calibrate.c:429 msgid "The target whitepoint was not obtainable." msgstr "Impussibil vê il pont blanc prefissât." #. TRANSLATORS: the display calibration process is finished -#: panels/color/cc-color-calibrate.c:467 +#: panels/color/cc-color-calibrate.c:469 msgid "Complete!" msgstr "Completât!" #. TRANSLATORS: the display calibration failed, and we also show #. * the translated (or untranslated) error string after this -#: panels/color/cc-color-calibrate.c:475 +#: panels/color/cc-color-calibrate.c:477 msgid "Calibration failed!" msgstr "Calibrazion falide!" #. TRANSLATORS: The user can now remove the sensor from the screen -#: panels/color/cc-color-calibrate.c:482 +#: panels/color/cc-color-calibrate.c:484 msgid "You can remove the calibration device." msgstr "Al è pussibil gjavâ il dispositîf di calibrazion." #. TRANSLATORS: The user has to be careful not to knock the #. * display off the screen (although we do cope if this is #. * detected early enough) -#: panels/color/cc-color-calibrate.c:553 +#: panels/color/cc-color-calibrate.c:556 msgid "Do not disturb the calibration device while in progress" msgstr "No sta disturbâ il dispositîf di calibrazion intant che al lavore" @@ -363,48 +363,48 @@ msgstr "No calibrât" #. TRANSLATORS: this is a profile prefix to signify the #. * profile has been auto-generated for this hardware -#: panels/color/cc-color-panel.c:141 +#: panels/color/cc-color-panel.c:140 msgid "Default: " msgstr "Predefinît: " #. TRANSLATORS: this is a profile prefix to signify the #. * profile his a standard space like AdobeRGB -#: panels/color/cc-color-panel.c:149 +#: panels/color/cc-color-panel.c:148 msgid "Colorspace: " msgstr "Spazi colôr: " #. TRANSLATORS: this is a profile prefix to signify the #. * profile is a test profile -#: panels/color/cc-color-panel.c:156 +#: panels/color/cc-color-panel.c:155 msgid "Test profile: " -msgstr "Profîl di test: " +msgstr "Profîl di prove: " #. TRANSLATORS: an ICC profile is a file containing colorspace data -#: panels/color/cc-color-panel.c:223 +#: panels/color/cc-color-panel.c:222 msgid "Select ICC Profile File" msgstr "Selezionâ file profîl ICC" -#: panels/color/cc-color-panel.c:226 +#: panels/color/cc-color-panel.c:225 msgid "_Import" msgstr "_Impuarte" #. TRANSLATORS: filter name on the file->open dialog -#: panels/color/cc-color-panel.c:237 +#: panels/color/cc-color-panel.c:236 msgid "Supported ICC profiles" msgstr "Profîi ICC supuartâts" #. TRANSLATORS: filter name on the file->open dialog -#: panels/color/cc-color-panel.c:244 +#: panels/color/cc-color-panel.c:243 #: panels/network/wireless-security/eap-method-fast.c:417 msgid "All files" msgstr "Ducj i file" -#: panels/color/cc-color-panel.c:583 +#: panels/color/cc-color-panel.c:582 msgid "Screen" msgstr "Schermi" #. TRANSLATORS: this is when the upload of the profile failed -#: panels/color/cc-color-panel.c:908 +#: panels/color/cc-color-panel.c:907 #, c-format msgid "Failed to upload file: %s" msgstr "Falît tal cjariâ il file: %s" @@ -412,40 +412,40 @@ msgstr "Falît tal cjariâ il file: %s" #. TRANSLATORS: these are instructions on how to recover #. * the ICC profile on the native operating system and are #. * only shown when the user uses a LiveCD to calibrate -#: panels/color/cc-color-panel.c:922 +#: panels/color/cc-color-panel.c:921 msgid "The profile has been uploaded to:" msgstr "Il profîl al è stât cjariât su:" -#: panels/color/cc-color-panel.c:924 +#: panels/color/cc-color-panel.c:923 msgid "Write down this URL." msgstr "Cjape note di cheste URL." -#: panels/color/cc-color-panel.c:925 +#: panels/color/cc-color-panel.c:924 msgid "Restart this computer and boot your normal operating system." msgstr "" "Torne invie il computer e eseguìs il boot dal abituâl sisteme operatîf." -#: panels/color/cc-color-panel.c:926 +#: panels/color/cc-color-panel.c:925 msgid "Type the URL into your browser to download and install the profile." msgstr "Scrîf l'URL tal browser par scjariâ e instalâ il profîl." #. TRANSLATORS: this is the dialog to save the ICC profile -#: panels/color/cc-color-panel.c:960 +#: panels/color/cc-color-panel.c:959 msgid "Save Profile" msgstr "Salve Profîl" -#: panels/color/cc-color-panel.c:964 +#: panels/color/cc-color-panel.c:963 #: panels/network/connection-editor/vpn-helpers.c:311 msgid "_Save" msgstr "_Salve" #. TRANSLATORS: this is when the button is sensitive -#: panels/color/cc-color-panel.c:1325 +#: panels/color/cc-color-panel.c:1324 msgid "Create a color profile for the selected device" msgstr "Cree un profîl di colôr pal dispositîf selezionât" #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1340 panels/color/cc-color-panel.c:1364 +#: panels/color/cc-color-panel.c:1339 panels/color/cc-color-panel.c:1363 msgid "" "The measuring instrument is not detected. Please check it is turned on and " "correctly connected." @@ -454,12 +454,12 @@ msgstr "" "tacât te juste maniere." #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1374 +#: panels/color/cc-color-panel.c:1373 msgid "The measuring instrument does not support printer profiling." msgstr "Il strument di misure nol supuarte il profiling de stampant." #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1385 +#: panels/color/cc-color-panel.c:1384 msgid "The device type is not currently supported." msgstr "Il gjenar di dispositîf nol è al moment supuartât." @@ -869,7 +869,6 @@ msgstr "" #. Translators: Do NOT translate or transliterate this text (this is an icon file name)! #: panels/color/gnome-color-panel.desktop.in.in:7 -#| msgid "Preferences" msgid "preferences-color" msgstr "preferences-color" @@ -911,6 +910,12 @@ msgstr "%e %b" msgid "%b %e, %Y" msgstr "%e %b %Y" +#. translators: This is the default hotspot name, need to be less than 32-bytes +#: panels/common/hostname-helper.c:189 +msgctxt "hotspot" +msgid "Hotspot" +msgstr "Hotspot" + #: panels/common/language-chooser.ui:5 msgid "Language" msgstr "Lenghe" @@ -1108,58 +1113,58 @@ msgid "To change time or date settings, you need to authenticate." msgstr "" "Par cambiâ lis impostazions de ore e de date al è necessari autenticâsi." -#: panels/display/cc-display-panel.c:729 +#: panels/display/cc-display-panel.c:739 msgctxt "Display rotation" msgid "Landscape" msgstr "Orizontâl" -#: panels/display/cc-display-panel.c:732 +#: panels/display/cc-display-panel.c:742 msgctxt "Display rotation" msgid "Portrait Right" msgstr "Verticâl diestre" -#: panels/display/cc-display-panel.c:735 +#: panels/display/cc-display-panel.c:745 msgctxt "Display rotation" msgid "Portrait Left" msgstr "Verticâl çampe" -#: panels/display/cc-display-panel.c:738 +#: panels/display/cc-display-panel.c:748 msgctxt "Display rotation" msgid "Landscape (flipped)" msgstr "Orizontâl (invertît)" #. Translators: This option sets orientation of print (portrait, landscape...) -#: panels/display/cc-display-panel.c:805 +#: panels/display/cc-display-panel.c:816 #: panels/printers/pp-options-dialog.c:558 msgid "Orientation" msgstr "Orientament" -#: panels/display/cc-display-panel.c:870 panels/display/cc-display-panel.c:1673 +#: panels/display/cc-display-panel.c:885 panels/display/cc-display-panel.c:1691 #: panels/printers/pp-options-dialog.c:87 msgid "Resolution" msgstr "Risoluzion" -#: panels/display/cc-display-panel.c:958 +#: panels/display/cc-display-panel.c:974 msgid "Refresh Rate" msgstr "Frecuence di inzornament" -#: panels/display/cc-display-panel.c:1095 +#: panels/display/cc-display-panel.c:1111 msgid "Scale" msgstr "Scjale" -#: panels/display/cc-display-panel.c:1148 +#: panels/display/cc-display-panel.c:1164 msgid "Adjust for TV" msgstr "Juste par TV" -#: panels/display/cc-display-panel.c:1410 +#: panels/display/cc-display-panel.c:1427 msgid "Primary Display" msgstr "Visôr primari" -#: panels/display/cc-display-panel.c:1439 +#: panels/display/cc-display-panel.c:1456 msgid "Display Arrangement" msgstr "Disposizion dai visôrs" -#: panels/display/cc-display-panel.c:1440 +#: panels/display/cc-display-panel.c:1457 msgid "" "Drag displays to match your setup. The top bar is placed on the primary " "display." @@ -1167,59 +1172,67 @@ msgstr "" "Strissine i visôrs par fâ in mût che a corispuindin ae to configurazion. La " "sbare superiôr e je metude tal visôr primari." -#: panels/display/cc-display-panel.c:1863 +#: panels/display/cc-display-panel.c:1881 msgid "Display Mode" msgstr "Modalitât visôr" -#: panels/display/cc-display-panel.c:1879 +#: panels/display/cc-display-panel.c:1897 msgid "Join Displays" msgstr "Unìs visôrs" -#: panels/display/cc-display-panel.c:1882 +#: panels/display/cc-display-panel.c:1900 msgid "Mirror" msgstr "Duplicât" -#: panels/display/cc-display-panel.c:1885 +#: panels/display/cc-display-panel.c:1903 msgid "Single Display" msgstr "Visôr ugnul" -#: panels/display/cc-display-panel.c:2590 -msgid "Apply Changes?" -msgstr "Aplicâ lis modifichis?" - -#: panels/display/cc-display-panel.c:2604 +#: panels/display/cc-display-panel.c:2620 #: panels/network/connection-editor/connection-editor.ui:24 #: panels/network/network-wifi.ui:38 msgid "_Apply" msgstr "_Apliche" -#: panels/display/cc-display-panel.c:2979 +#: panels/display/cc-display-panel.c:2642 +msgid "Apply Changes?" +msgstr "Aplicâ lis modifichis?" + +#: panels/display/cc-display-panel.c:2647 +msgid "Changes Cannot be Applied" +msgstr "Lis modifichis no puedin jessi aplicadis" + +#: panels/display/cc-display-panel.c:2648 +msgid "This could be due to hardware limitations." +msgstr "Chest al podarès jessi par vie di limitazions hardware." + +#: panels/display/cc-display-panel.c:3003 #, c-format msgid "%.2lf Hz" msgstr "%.2lf Hz" #. TRANSLATORS: the state of the night light setting -#: panels/display/cc-display-panel.c:3195 +#: panels/display/cc-display-panel.c:3219 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1991 panels/power/cc-power-panel.c:1998 -#: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 -#: panels/universal-access/cc-ua-panel.c:333 -#: panels/universal-access/cc-ua-panel.c:714 -#: panels/universal-access/cc-ua-panel.c:727 -#: panels/universal-access/cc-ua-panel.c:739 -#: panels/universal-access/cc-ua-panel.c:910 +#: panels/power/cc-power-panel.c:2097 panels/power/cc-power-panel.c:2104 +#: panels/privacy/cc-privacy-panel.c:191 panels/privacy/cc-privacy-panel.c:258 +#: panels/universal-access/cc-ua-panel.c:334 +#: panels/universal-access/cc-ua-panel.c:715 +#: panels/universal-access/cc-ua-panel.c:728 +#: panels/universal-access/cc-ua-panel.c:740 +#: panels/universal-access/cc-ua-panel.c:911 msgid "On" msgstr "Impiât" -#: panels/display/cc-display-panel.c:3195 panels/network/net-proxy.c:54 +#: panels/display/cc-display-panel.c:3219 panels/network/net-proxy.c:54 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1985 panels/power/cc-power-panel.c:1996 -#: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 -#: panels/universal-access/cc-ua-panel.c:333 -#: panels/universal-access/cc-ua-panel.c:714 -#: panels/universal-access/cc-ua-panel.c:727 -#: panels/universal-access/cc-ua-panel.c:739 -#: panels/universal-access/cc-ua-panel.c:910 panels/universal-access/uap.ui:334 +#: panels/power/cc-power-panel.c:2091 panels/power/cc-power-panel.c:2102 +#: panels/privacy/cc-privacy-panel.c:191 panels/privacy/cc-privacy-panel.c:258 +#: panels/universal-access/cc-ua-panel.c:334 +#: panels/universal-access/cc-ua-panel.c:715 +#: panels/universal-access/cc-ua-panel.c:728 +#: panels/universal-access/cc-ua-panel.c:740 +#: panels/universal-access/cc-ua-panel.c:911 panels/universal-access/uap.ui:334 #: panels/universal-access/uap.ui:380 panels/universal-access/uap.ui:426 #: panels/universal-access/uap.ui:532 panels/universal-access/uap.ui:685 #: panels/universal-access/uap.ui:731 panels/universal-access/uap.ui:777 @@ -1227,11 +1240,11 @@ msgstr "Impiât" msgid "Off" msgstr "Distudât" -#: panels/display/cc-display-panel.c:3216 +#: panels/display/cc-display-panel.c:3240 msgid "_Night Light" msgstr "Lûs _noturne" -#: panels/display/cc-display-panel.c:3281 +#: panels/display/cc-display-panel.c:3305 msgid "Could not get screen information" msgstr "Impussibil vê informazions sul schermi" @@ -1271,7 +1284,7 @@ msgstr "Tramont a cricâ dì" #: panels/network/connection-editor/ip6-page.ui:83 #: panels/network/net-proxy.c:56 panels/network/network-proxy.ui:113 #: panels/network/network-wifi.ui:777 panels/network/network-wifi.ui:1054 -#: panels/privacy/cc-privacy-panel.c:217 +#: panels/privacy/cc-privacy-panel.c:218 msgid "Manual" msgstr "Manuâl" @@ -1320,8 +1333,8 @@ msgstr "" "colôr;tramont;cricâ;" #. TRANSLATORS: AP type -#: panels/info/cc-info-overview-panel.c:374 -#: panels/info/cc-info-overview-panel.c:457 panels/network/panel-common.c:123 +#: panels/info/cc-info-overview-panel.c:373 +#: panels/info/cc-info-overview-panel.c:456 panels/network/panel-common.c:123 msgid "Unknown" msgstr "No cognossût" @@ -1329,24 +1342,24 @@ msgstr "No cognossût" #. * example: #. * "Fedora 25 (Workstation Edition); Build ID: xyz" or #. * "Ubuntu 16.04 LTS; Build ID: jki" -#: panels/info/cc-info-overview-panel.c:465 +#: panels/info/cc-info-overview-panel.c:464 #, c-format msgid "%s; Build ID: %s" msgstr "%s; ID di costruzion: %s" #. translators: This is the type of architecture for the OS -#: panels/info/cc-info-overview-panel.c:482 +#: panels/info/cc-info-overview-panel.c:481 #, c-format msgid "64-bit" msgstr "64-bit" #. translators: This is the type of architecture for the OS -#: panels/info/cc-info-overview-panel.c:485 +#: panels/info/cc-info-overview-panel.c:484 #, c-format msgid "32-bit" msgstr "32-bit" -#: panels/info/cc-info-overview-panel.c:775 +#: panels/info/cc-info-overview-panel.c:773 #, c-format msgid "Version %s" msgstr "Version %s" @@ -1677,8 +1690,8 @@ msgstr "Inviadôrs" msgid "Launch help browser" msgstr "Fâs partî il visualizadôr di manuâi" -#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:223 -#: shell/cc-window.c:761 shell/gnome-control-center.desktop.in.in:3 +#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:237 +#: shell/cc-window.c:773 shell/gnome-control-center.desktop.in.in:3 #: shell/window.ui:125 msgid "Settings" msgstr "Impostazions" @@ -1787,7 +1800,7 @@ msgstr "Ative o disative il contrast elevât" #: panels/keyboard/cc-keyboard-manager.c:506 #: panels/keyboard/cc-keyboard-manager.c:514 -#: panels/keyboard/cc-keyboard-manager.c:822 +#: panels/keyboard/cc-keyboard-manager.c:821 msgid "Custom Shortcuts" msgstr "Scurtis personalizadis" @@ -1798,7 +1811,7 @@ msgstr "Scurtis personalizadis" #. * The device has been disabled #: panels/keyboard/cc-keyboard-option.c:263 #: panels/keyboard/cc-keyboard-option.c:382 -#: panels/keyboard/keyboard-shortcuts.c:435 +#: panels/keyboard/keyboard-shortcuts.c:434 #: panels/keyboard/shortcut-editor.ui:96 panels/network/network-proxy.ui:123 #: panels/network/network-wifi.ui:782 panels/network/network-wifi.ui:1059 #: panels/user-accounts/um-fingerprint-dialog.c:211 @@ -1972,7 +1985,7 @@ msgstr "Met" #: panels/mouse/cc-mouse-panel.c:82 panels/wacom/cc-wacom-panel.c:402 msgid "Test Your _Settings" -msgstr "Test _impostazions" +msgstr "Prove lis _impostazions" #: panels/mouse/gnome-mouse-panel.desktop.in.in:3 msgid "Mouse & Touchpad" @@ -2096,7 +2109,7 @@ msgid "Single click, secondary button" msgstr "Clic singul, boton secondari" #. add proxy to device list -#: panels/network/cc-network-panel.c:579 +#: panels/network/cc-network-panel.c:581 msgid "Network proxy" msgstr "Proxy di rêt" @@ -2104,25 +2117,25 @@ msgstr "Proxy di rêt" #. * window for vpn connections, it is also used to display #. * vpn connections in the device list. #. -#: panels/network/cc-network-panel.c:715 panels/network/net-vpn.c:192 -#: panels/network/net-vpn.c:321 +#: panels/network/cc-network-panel.c:717 panels/network/net-vpn.c:167 +#: panels/network/net-vpn.c:296 #, c-format msgid "%s VPN" msgstr "VPN %s" -#: panels/network/cc-network-panel.c:779 panels/network/wifi.ui:282 +#: panels/network/cc-network-panel.c:781 panels/network/wifi.ui:282 msgid "Oops, something has gone wrong. Please contact your software vendor." msgstr "" "Orpo, al semee che alc al sedi lât par stuart. Contate il furnidôr di " "software." -#: panels/network/cc-network-panel.c:785 +#: panels/network/cc-network-panel.c:787 msgid "NetworkManager needs to be running." msgstr "NetworkManager al à di jessi in esecuzion." -#: panels/network/cc-wifi-panel.c:213 +#: panels/network/cc-wifi-panel.c:214 #: panels/network/gnome-wifi-panel.desktop.in.in:3 -#: panels/network/network-wifi.ui:1766 +#: panels/network/network-wifi.ui:1769 msgid "Wi-Fi" msgstr "Wi-Fi" @@ -2266,7 +2279,7 @@ msgid "Remove VPN" msgstr "Gjave VPN" #: panels/network/connection-editor/ce-page-details.c:334 -#: panels/network/network-wifi.ui:1456 shell/cc-window.c:215 +#: panels/network/network-wifi.ui:1456 shell/cc-window.c:229 #: shell/panel-list.ui:103 msgid "Details" msgstr "Detais" @@ -2401,7 +2414,7 @@ msgstr "Indicât par conessions cun adebit o limits di dâts." #: panels/network/connection-editor/ip6-page.ui:291 #: panels/network/net-proxy.c:58 panels/network/network-proxy.ui:103 #: panels/network/wireless-security/eap-method-peap.ui:22 -#: panels/privacy/cc-privacy-panel.c:217 +#: panels/privacy/cc-privacy-panel.c:218 msgid "Automatic" msgstr "Automatic" @@ -2599,9 +2612,9 @@ msgid "Select file to import" msgstr "Selezione un file di impuartâ" #: panels/network/connection-editor/vpn-helpers.c:182 -#: panels/printers/pp-details-dialog.c:332 +#: panels/printers/pp-details-dialog.c:331 #: panels/sharing/cc-sharing-panel.c:385 -#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-photo-dialog.c:231 msgid "_Open" msgstr "_Vierç" @@ -3021,19 +3034,19 @@ msgctxt "Wi-Fi passkey" msgid "Password" msgstr "Password" -#: panels/network/network-wifi.ui:1796 +#: panels/network/network-wifi.ui:1799 msgid "Turn Wi-Fi off" msgstr "Distude Wi-Fi" -#: panels/network/network-wifi.ui:1828 +#: panels/network/network-wifi.ui:1831 msgid "_Connect to Hidden Network…" msgstr "_Conet a rêt platade…" -#: panels/network/network-wifi.ui:1838 +#: panels/network/network-wifi.ui:1841 msgid "_Turn On Wi-Fi Hotspot…" msgstr "_Impie hotspot Wi-Fi…" -#: panels/network/network-wifi.ui:1848 +#: panels/network/network-wifi.ui:1851 msgid "_Known Wi-Fi Networks" msgstr "Rêts Wi-Fi _cognossudis" @@ -3342,23 +3355,23 @@ msgstr "Firmware mancjant" msgid "Cable unplugged" msgstr "Fil stacât" -#: panels/network/wireless-security/eap-method.c:57 +#: panels/network/wireless-security/eap-method.c:69 msgid "undefined error in 802.1X security (wpa-eap)" msgstr "erôr no definît inte sigurece 802.1X (wpa-eap)" -#: panels/network/wireless-security/eap-method.c:233 +#: panels/network/wireless-security/eap-method.c:245 msgid "no file selected" msgstr "nissun file selezionât" -#: panels/network/wireless-security/eap-method.c:264 +#: panels/network/wireless-security/eap-method.c:276 msgid "unspecified error validating eap-method file" msgstr "erôr no specificât tal validâ il file dal metodi eap" -#: panels/network/wireless-security/eap-method.c:439 +#: panels/network/wireless-security/eap-method.c:451 msgid "DER, PEM, or PKCS#12 private keys (*.der, *.pem, *.p12, *.key)" msgstr "Clâfs privadis DER, PEM, o PKCS#12 (*.der, *.pem, *.p12, *.key)" -#: panels/network/wireless-security/eap-method.c:442 +#: panels/network/wireless-security/eap-method.c:454 msgid "DER or PEM certificates (*.der, *.pem, *.crt, *.cer)" msgstr "Certificâts DER o PEM (*.der, *.pem, *.crt, *.cer)" @@ -3747,7 +3760,6 @@ msgstr "Controle cualis notifichis mostrâ e ce che a mostrin" #. Translators: Do NOT translate or transliterate this text (this is an icon file name)! #: panels/notifications/gnome-notifications-panel.desktop.in.in:7 -#| msgid "Preferences;Settings;" msgid "preferences-system-notifications" msgstr "preferences-system-notifications" @@ -3777,19 +3789,19 @@ msgstr "Altri" #. translators: This is the title of the "Show Account" dialog. The #. * %s is the name of the provider. e.g., 'Google'. -#: panels/online-accounts/cc-online-accounts-panel.c:551 +#: panels/online-accounts/cc-online-accounts-panel.c:612 #, c-format msgid "%s Account" msgstr "Account di %s" -#: panels/online-accounts/cc-online-accounts-panel.c:843 +#: panels/online-accounts/cc-online-accounts-panel.c:904 msgid "Error removing account" msgstr "Erôr tal gjava l'account" #. Translators: The %s is the username (eg., debarshi.ray@gmail.com #. * or rishi). #. -#: panels/online-accounts/cc-online-accounts-panel.c:908 +#: panels/online-accounts/cc-online-accounts-panel.c:969 #, c-format msgid "%s removed" msgstr "%s gjavât" @@ -3842,18 +3854,18 @@ msgstr "Zonte un account" msgid "Remove Account" msgstr "Gjave account" -#: panels/power/cc-power-panel.c:253 +#: panels/power/cc-power-panel.c:254 msgid "Unknown time" msgstr "Timp no cognossût" -#: panels/power/cc-power-panel.c:259 +#: panels/power/cc-power-panel.c:260 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "%i minût" msgstr[1] "%i minûts" -#: panels/power/cc-power-panel.c:271 +#: panels/power/cc-power-panel.c:272 #, c-format msgid "%i hour" msgid_plural "%i hours" @@ -3862,256 +3874,300 @@ msgstr[1] "%i oris" #. TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes" #. * Swap order with "%2$s %2$i %1$s %1$i if needed -#: panels/power/cc-power-panel.c:279 +#: panels/power/cc-power-panel.c:280 #, c-format msgid "%i %s %i %s" msgstr "%i %s e %i %s" -#: panels/power/cc-power-panel.c:280 +#: panels/power/cc-power-panel.c:281 msgid "hour" msgid_plural "hours" msgstr[0] "ore" msgstr[1] "oris" -#: panels/power/cc-power-panel.c:281 +#: panels/power/cc-power-panel.c:282 msgid "minute" msgid_plural "minutes" msgstr[0] "minût" msgstr[1] "minûts" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:300 +#: panels/power/cc-power-panel.c:301 #, c-format msgid "%s until fully charged" msgstr "%s ae cjarie plene" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:307 +#: panels/power/cc-power-panel.c:308 #, c-format msgid "Caution: %s remaining" msgstr "Atenzion: ancjemò %s" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:312 +#: panels/power/cc-power-panel.c:313 #, c-format msgid "%s remaining" msgstr "ancjemò %s" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:317 panels/power/cc-power-panel.c:345 +#: panels/power/cc-power-panel.c:318 panels/power/cc-power-panel.c:346 msgid "Fully charged" msgstr "Cjarie" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:321 panels/power/cc-power-panel.c:349 +#: panels/power/cc-power-panel.c:322 panels/power/cc-power-panel.c:350 msgid "Empty" msgstr "Scjarie" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:336 +#: panels/power/cc-power-panel.c:337 msgid "Charging" msgstr "In cjarie" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:341 +#: panels/power/cc-power-panel.c:342 msgid "Discharging" msgstr "In scjarie" -#: panels/power/cc-power-panel.c:464 +#: panels/power/cc-power-panel.c:465 msgctxt "Battery name" msgid "Main" msgstr "Principâl" -#: panels/power/cc-power-panel.c:466 +#: panels/power/cc-power-panel.c:467 msgctxt "Battery name" msgid "Extra" msgstr "Adizionâl" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:537 +#: panels/power/cc-power-panel.c:538 msgid "Wireless mouse" msgstr "Mouse cence fîl" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:540 +#: panels/power/cc-power-panel.c:541 msgid "Wireless keyboard" msgstr "Tastiere cence fîl" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:543 +#: panels/power/cc-power-panel.c:544 msgid "Uninterruptible power supply" msgstr "UPS" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:546 +#: panels/power/cc-power-panel.c:547 msgid "Personal digital assistant" msgstr "PDA" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:549 +#: panels/power/cc-power-panel.c:550 msgid "Cellphone" msgstr "Celulâr" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:552 +#: panels/power/cc-power-panel.c:553 msgid "Media player" msgstr "Letôr multimediâl" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:555 panels/wacom/cc-wacom-panel.c:793 +#: panels/power/cc-power-panel.c:556 panels/wacom/cc-wacom-panel.c:793 msgid "Tablet" msgstr "Tablet" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:558 +#: panels/power/cc-power-panel.c:559 msgid "Computer" msgstr "Computer" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:561 +#: panels/power/cc-power-panel.c:562 msgid "Gaming input device" msgstr "Dispositîf di input par zuiâ" #. TRANSLATORS: secondary battery, misc -#: panels/power/cc-power-panel.c:564 panels/power/cc-power-panel.c:804 -#: panels/power/cc-power-panel.c:2377 +#: panels/power/cc-power-panel.c:565 panels/power/cc-power-panel.c:829 +#: panels/power/cc-power-panel.c:2483 msgid "Battery" msgstr "Batarie" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:618 +#: panels/power/cc-power-panel.c:632 msgctxt "Battery power" msgid "Charging" msgstr "In cjarie" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:625 +#: panels/power/cc-power-panel.c:639 msgctxt "Battery power" msgid "Caution" msgstr "Atenzion" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:630 +#: panels/power/cc-power-panel.c:644 msgctxt "Battery power" msgid "Low" msgstr "Basse" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:635 +#: panels/power/cc-power-panel.c:649 msgctxt "Battery power" msgid "Good" msgstr "Buine" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:640 +#: panels/power/cc-power-panel.c:654 msgctxt "Battery power" msgid "Fully charged" msgstr "Cjarie" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:644 +#: panels/power/cc-power-panel.c:658 msgctxt "Battery power" msgid "Empty" msgstr "Scjarie" -#: panels/power/cc-power-panel.c:802 +#: panels/power/cc-power-panel.c:827 msgid "Batteries" msgstr "Batariis" -#: panels/power/cc-power-panel.c:1239 +#: panels/power/cc-power-panel.c:1206 +#, c-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d ore" +msgstr[1] "%d oris" + +#: panels/power/cc-power-panel.c:1208 +#, c-format +#| msgid "%i minute" +#| msgid_plural "%i minutes" +msgid "%d minute" +msgid_plural "%d minutes" +msgstr[0] "%d minût" +msgstr[1] "%d minûts" + +#: panels/power/cc-power-panel.c:1211 +#, c-format +#| msgid "30 seconds" +msgid "%d second" +msgid_plural "%d seconds" +msgstr[0] "%d secont" +msgstr[1] "%d seconts" + +#. 5 hours 2 minutes 12 seconds +#: panels/power/cc-power-panel.c:1217 +#, c-format +msgctxt "time" +msgid "%s %s %s" +msgstr "%s %s e %s" + +#. 2 minutes 12 seconds +#: panels/power/cc-power-panel.c:1220 +#, c-format +msgctxt "time" +msgid "%s %s" +msgstr "%s e %s" + +#. 0 seconds +#: panels/power/cc-power-panel.c:1226 +msgid "0 seconds" +msgstr "0 seconts" + +#: panels/power/cc-power-panel.c:1328 msgid "When _idle" msgstr "Cuant _inatîf" -#: panels/power/cc-power-panel.c:1693 +#: panels/power/cc-power-panel.c:1793 msgid "Power Saving" msgstr "Risparmi energjetic" -#: panels/power/cc-power-panel.c:1724 +#: panels/power/cc-power-panel.c:1824 msgid "_Screen brightness" msgstr "Luminositât dal _schermi" -#: panels/power/cc-power-panel.c:1743 +#: panels/power/cc-power-panel.c:1843 msgid "Automatic brightness" msgstr "Luminositât automatiche" -#: panels/power/cc-power-panel.c:1763 +#: panels/power/cc-power-panel.c:1863 msgid "_Keyboard brightness" msgstr "Luminositât de _tastiere" -#: panels/power/cc-power-panel.c:1773 +#: panels/power/cc-power-panel.c:1873 msgid "_Dim screen when inactive" msgstr "_Scurî il schermi cuant che al è inatîf" -#: panels/power/cc-power-panel.c:1798 +#: panels/power/cc-power-panel.c:1898 msgid "_Blank screen" msgstr "Schermi _neri" -#: panels/power/cc-power-panel.c:1835 +#: panels/power/cc-power-panel.c:1935 msgid "_Wi-Fi" msgstr "_Wi-Fi" -#: panels/power/cc-power-panel.c:1840 +#: panels/power/cc-power-panel.c:1940 msgid "Turn off Wi-Fi to save power." msgstr "Distude Wi-Fi par sparagnâ curint." -#: panels/power/cc-power-panel.c:1865 +#: panels/power/cc-power-panel.c:1965 msgid "_Mobile broadband" msgstr "Bande largje _mobil" -#: panels/power/cc-power-panel.c:1870 +#: panels/power/cc-power-panel.c:1970 msgid "Turn off mobile broadband (3G, 4G, LTE, etc.) to save power." msgstr "Distude bande largje mobil (3G, 4G, LTE, ecc.) par sparagnâ energjie." -#: panels/power/cc-power-panel.c:1923 +#: panels/power/cc-power-panel.c:2029 msgid "_Bluetooth" msgstr "_Bluetooth" -#: panels/power/cc-power-panel.c:1928 +#: panels/power/cc-power-panel.c:2034 msgid "Turn off Bluetooth to save power." msgstr "Distude il Bluetooth par sparagnâ curint." -#: panels/power/cc-power-panel.c:1987 +#: panels/power/cc-power-panel.c:2093 msgid "When on battery power" msgstr "Cuant che si dopre la batarie" -#: panels/power/cc-power-panel.c:1989 +#: panels/power/cc-power-panel.c:2095 msgid "When plugged in" msgstr "Cuant che al è alimentât" -#: panels/power/cc-power-panel.c:2084 +#: panels/power/cc-power-panel.c:2190 msgid "Suspend" msgstr "Sospindi" -#: panels/power/cc-power-panel.c:2085 +#: panels/power/cc-power-panel.c:2191 msgid "Power Off" msgstr "Distudâ" -#: panels/power/cc-power-panel.c:2086 +#: panels/power/cc-power-panel.c:2192 msgid "Hibernate" msgstr "Ibernâ" -#: panels/power/cc-power-panel.c:2087 +#: panels/power/cc-power-panel.c:2193 msgid "Nothing" msgstr "Nissune azion" #. Frame header -#: panels/power/cc-power-panel.c:2201 +#: panels/power/cc-power-panel.c:2307 msgid "Suspend & Power Button" msgstr "Sospension e boton par distudâ" -#: panels/power/cc-power-panel.c:2240 +#: panels/power/cc-power-panel.c:2346 msgid "_Automatic suspend" msgstr "Sospension _Automatiche" -#: panels/power/cc-power-panel.c:2241 +#: panels/power/cc-power-panel.c:2347 msgid "Automatic suspend" msgstr "Sospension automatiche" -#: panels/power/cc-power-panel.c:2308 +#: panels/power/cc-power-panel.c:2414 msgid "_When the Power Button is pressed" msgstr "_Cuant che si frache il boton Distude" -#: panels/power/cc-power-panel.c:2427 shell/cc-window.c:219 +#: panels/power/cc-power-panel.c:2533 panels/thunderbolt/cc-bolt-panel.ui:466 +#: panels/thunderbolt/cc-bolt-panel.ui:525 shell/cc-window.c:233 #: shell/panel-list.ui:45 msgid "Devices" msgstr "Dispositîfs" @@ -4246,18 +4302,18 @@ msgid "Authentication Required" msgstr "Autenticazion necessarie" #. Translators: %s is the printer name -#: panels/printers/cc-printers-panel.c:791 +#: panels/printers/cc-printers-panel.c:809 #, c-format msgid "Printer “%s” has been deleted" msgstr "La stampant “%s” e je stade eliminade" #. Translators: Addition of the new printer failed. -#: panels/printers/cc-printers-panel.c:1036 +#: panels/printers/cc-printers-panel.c:1054 msgid "Failed to add new printer." msgstr "Zonte de gnove stampant falide." #. Translators: The XML file containing user interface can not be loaded -#: panels/printers/cc-printers-panel.c:1371 +#: panels/printers/cc-printers-panel.c:1391 #, c-format msgid "Could not load ui: %s" msgstr "Impussibil cjariâ la interface: %s" @@ -4364,24 +4420,24 @@ msgstr "" #. Translators: Name of job which makes printer to print test page #: panels/printers/options-dialog.ui:22 panels/printers/pp-options-dialog.c:893 msgid "Test Page" -msgstr "Pagjine di test" +msgstr "Pagjine di prove" #. Translators: This is the title of the dialog. %s is the printer name. -#: panels/printers/pp-details-dialog.c:135 -#: panels/printers/pp-details-dialog.c:435 +#: panels/printers/pp-details-dialog.c:134 +#: panels/printers/pp-details-dialog.c:434 #, c-format msgid "%s Details" msgstr "Detais di %s" -#: panels/printers/pp-details-dialog.c:184 +#: panels/printers/pp-details-dialog.c:183 msgid "No suitable driver found" msgstr "Nissun driver adat cjatât" -#: panels/printers/pp-details-dialog.c:328 +#: panels/printers/pp-details-dialog.c:327 msgid "Select PPD File" msgstr "Selezione file PPD" -#: panels/printers/pp-details-dialog.c:337 +#: panels/printers/pp-details-dialog.c:336 msgid "" "PostScript Printer Description files (*.ppd, *.PPD, *.ppd.gz, *.PPD.gz, *." "PPD.GZ)" @@ -4394,7 +4450,7 @@ msgid "Select Printer Driver" msgstr "Selezione driver stampant" #: panels/printers/ppd-selection-dialog.ui:40 -#: panels/user-accounts/um-photo-dialog.c:104 +#: panels/user-accounts/um-photo-dialog.c:105 msgid "Select" msgstr "Selezione" @@ -4451,71 +4507,70 @@ msgid "Reverse portrait" msgstr "Verticâl invertît" #. Translators: Job's state (job is waiting to be printed) -#: panels/printers/pp-jobs-dialog.c:243 +#: panels/printers/pp-jobs-dialog.c:234 msgctxt "print job" msgid "Pending" msgstr "In atese" #. Translators: Job's state (job is held for printing) -#: panels/printers/pp-jobs-dialog.c:249 +#: panels/printers/pp-jobs-dialog.c:240 msgctxt "print job" msgid "Paused" msgstr "In pause" #. Translators: Job's state (job needs authentication to proceed further) -#: panels/printers/pp-jobs-dialog.c:254 +#: panels/printers/pp-jobs-dialog.c:245 msgctxt "print job" msgid "Authentication required" msgstr "Autenticazion necessarie" #. Translators: Job's state (job is currently printing) -#: panels/printers/pp-jobs-dialog.c:259 +#: panels/printers/pp-jobs-dialog.c:250 msgctxt "print job" msgid "Processing" msgstr "In elaborazion" #. Translators: Job's state (job has been stopped) -#: panels/printers/pp-jobs-dialog.c:263 +#: panels/printers/pp-jobs-dialog.c:254 msgctxt "print job" msgid "Stopped" msgstr "Fermât" #. Translators: Job's state (job has been canceled) -#: panels/printers/pp-jobs-dialog.c:267 +#: panels/printers/pp-jobs-dialog.c:258 msgctxt "print job" msgid "Canceled" msgstr "Anulât" #. Translators: Job's state (job has aborted due to error) -#: panels/printers/pp-jobs-dialog.c:271 +#: panels/printers/pp-jobs-dialog.c:262 msgctxt "print job" msgid "Aborted" msgstr "Interot" #. Translators: Job's state (job has completed successfully) -#: panels/printers/pp-jobs-dialog.c:275 +#: panels/printers/pp-jobs-dialog.c:266 msgctxt "print job" msgid "Completed" msgstr "Finît" #. Translators: This label shows how many jobs of this printer needs to be authenticated to be printed. -#: panels/printers/pp-jobs-dialog.c:399 +#: panels/printers/pp-jobs-dialog.c:390 #, c-format -#| msgid "Server requires authentication" msgid "%u Job Requires Authentication" msgid_plural "%u Jobs Require Authentication" msgstr[0] "%u lavôr al domande autenticazion" msgstr[1] "%u lavôrs a domandin autenticazion" #. Translators: This is the printer name for which we are showing the active jobs -#: panels/printers/pp-jobs-dialog.c:617 +#: panels/printers/pp-jobs-dialog.c:620 #, c-format msgctxt "Printer jobs dialog title" msgid "%s — Active Jobs" msgstr "%s — Lavôrs Atîfs" #. Translators: The printer needs authentication info to print. -#: panels/printers/pp-jobs-dialog.c:622 +#: panels/printers/pp-jobs-dialog.c:625 #, c-format msgid "Enter credentials to print from %s." msgstr "Inserìs lis credenziâls par stampâ di %s." @@ -4653,7 +4708,7 @@ msgstr "Avanzadis" #. Translators: Name of job which makes printer to print test page #: panels/printers/pp-options-dialog.c:908 msgid "Test page" -msgstr "Pagjine di test" +msgstr "Pagjine di prove" #. Translators: this is an option of "Paper Source" #: panels/printers/pp-ppd-option-widget.c:76 @@ -4881,25 +4936,25 @@ msgstr "" "Il servizi di sisteme pe stampe\n" "nol semee jessi disponibil." -#: panels/privacy/cc-privacy-panel.c:387 panels/privacy/privacy.ui:280 +#: panels/privacy/cc-privacy-panel.c:388 panels/privacy/privacy.ui:280 msgid "Screen Lock" msgstr "Bloc schermi" -#: panels/privacy/cc-privacy-panel.c:438 +#: panels/privacy/cc-privacy-panel.c:439 msgid "In use" msgstr "In ûs" -#: panels/privacy/cc-privacy-panel.c:443 +#: panels/privacy/cc-privacy-panel.c:444 msgctxt "Location services status" msgid "On" msgstr "On" -#: panels/privacy/cc-privacy-panel.c:444 +#: panels/privacy/cc-privacy-panel.c:445 msgctxt "Location services status" msgid "Off" msgstr "Off" -#: panels/privacy/cc-privacy-panel.c:823 panels/privacy/privacy.ui:745 +#: panels/privacy/cc-privacy-panel.c:825 panels/privacy/privacy.ui:745 msgid "Location Services" msgstr "Servizis su la posizion" @@ -5161,11 +5216,11 @@ msgctxt "Input Source" msgid "Other" msgstr "Altri" -#: panels/region/cc-region-panel.c:881 +#: panels/region/cc-region-panel.c:882 msgid "No input source selected" msgstr "Nissune sorzint input selezionade" -#: panels/region/cc-region-panel.c:1773 +#: panels/region/cc-region-panel.c:1774 msgid "Login _Screen" msgstr "_Schermade di acès" @@ -5665,7 +5720,7 @@ msgstr "_Profîl:" #: panels/sound/gvc-mixer-dialog.c:255 msgid "_Test Speakers" -msgstr "_Test cassis" +msgstr "_Prove cassis" #: panels/sound/gvc-mixer-dialog.c:424 msgid "Peak detect" @@ -5678,7 +5733,7 @@ msgstr "Dispositîf" #: panels/sound/gvc-mixer-dialog.c:1562 #, c-format msgid "Speaker Testing for %s" -msgstr "Test cassis par %s" +msgstr "Prove cassis par %s" #: panels/sound/gvc-mixer-dialog.c:1617 msgid "_Output volume:" @@ -5738,7 +5793,7 @@ msgstr "Preferencis sun" #: panels/sound/gvc-sound-theme-chooser.c:460 #: panels/sound/gvc-sound-theme-chooser.c:472 msgid "Testing event sound" -msgstr "Test event sonôr" +msgstr "Prove event sonôr" #: panels/sound/gvc-sound-theme-chooser.c:544 #: panels/wacom/wacom-stylus-page.ui:25 @@ -5759,7 +5814,7 @@ msgstr "Ferme" #: panels/sound/gvc-speaker-test.c:229 panels/sound/gvc-speaker-test.c:341 msgid "Test" -msgstr "Test" +msgstr "Prove" #: panels/sound/gvc-speaker-test.c:237 msgid "Subwoofer" @@ -5769,34 +5824,203 @@ msgstr "Subwoofer" msgid "Custom" msgstr "Personalizât" +#: panels/thunderbolt/cc-bolt-device-dialog.c:86 +#: panels/thunderbolt/cc-bolt-device-entry.c:119 +msgctxt "Thunderbolt Device Status" +msgid "Disconnected" +msgstr "Daûr a disconeti" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:89 +#: panels/thunderbolt/cc-bolt-device-entry.c:122 +msgctxt "Thunderbolt Device Status" +msgid "Connecting" +msgstr "Daûr a coneti" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:92 +#: panels/thunderbolt/cc-bolt-device-entry.c:126 +#: panels/thunderbolt/cc-bolt-device-entry.c:138 +msgctxt "Thunderbolt Device Status" +msgid "Connected" +msgstr "Conetût" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:95 +msgctxt "Thunderbolt Device Status" +msgid "Authorization Error" +msgstr "Erôr di autorizazion" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:98 +#: panels/thunderbolt/cc-bolt-device-entry.c:132 +msgctxt "Thunderbolt Device Status" +msgid "Authorizing" +msgstr "Daûr a autorizâ" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:105 +msgctxt "Thunderbolt Device Status" +msgid "Reduced Functionality" +msgstr "Funzionalitât ridote" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:107 +msgctxt "Thunderbolt Device Status" +msgid "Connected & Authorized" +msgstr "Conetût e autorizât" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:113 +#: panels/thunderbolt/cc-bolt-device-entry.c:146 +msgctxt "Thunderbolt Device Status" +msgid "Unknown" +msgstr "No cognossût" + +#. Translators: The time point the device was authorized. +#: panels/thunderbolt/cc-bolt-device-dialog.c:169 +msgid "Authorized at:" +msgstr "Autorizât aes:" + +#. Translators: The time point the device was connected. +#: panels/thunderbolt/cc-bolt-device-dialog.c:175 +msgid "Connected at:" +msgstr "Conetût aes:" + +#. Translators: The time point the device was enrolled, +#. * i.e. authorized and stored in the device database. +#: panels/thunderbolt/cc-bolt-device-dialog.c:182 +msgid "Enrolled at:" +msgstr "Regjistrât aes:" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:250 +msgid "Failed to authorize device: " +msgstr "No i è rivâts a autorizâ il dispositîf: " + +#: panels/thunderbolt/cc-bolt-device-dialog.c:327 +msgid "Failed to forget device: " +msgstr "No si è rivâts a dismenteâ il dispositîf: " + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:109 +msgid "Name:" +msgstr "Non:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:141 +msgid "Status:" +msgstr "Stât:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:174 +msgid "UUID:" +msgstr "UUID:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:280 +msgid "Authorize and Connect" +msgstr "Autorize e conet" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:303 +msgid "Forget Device" +msgstr "Dismentee dispositîf" + +#: panels/thunderbolt/cc-bolt-device-entry.c:129 +msgctxt "Thunderbolt Device Status" +msgid "Error" +msgstr "Erôr" + +#: panels/thunderbolt/cc-bolt-device-entry.c:140 +msgctxt "Thunderbolt Device Status" +msgid "Authorized" +msgstr "Autorizât" + +#: panels/thunderbolt/cc-bolt-panel.c:175 +msgid "" +"The Thunderbolt subsystem (boltd) is not installed or not set up properly." +msgstr "" +"Il sot-sisteme Thunderbolt (boltd) nol è instalât o nol è stât configurât in " +"maniere adate." + +#: panels/thunderbolt/cc-bolt-panel.c:460 +msgid "" +"Thunderbolt could not be detected.\n" +"Either the system lacks Thunderbolt support, it has been disabled in the " +"BIOS or is set to an unsupported security level in the BIOS." +msgstr "" +"Nol è stât pussibil rilevât Thunderbolt.\n" +"O al mancje tal sisteme il supuart par Thunderbolt, o al è stât disabilitât " +"tal BIOS o al è stât configurât tal BIOS a un nivel di sigurece no supuartât." + +#: panels/thunderbolt/cc-bolt-panel.c:504 +msgid "Thunderbolt support has been disabled in the BIOS." +msgstr "Il supuart a Thunderbolt al è stât disabilitât tal BIOS." + +#: panels/thunderbolt/cc-bolt-panel.c:613 +#, c-format +msgid "Error switching direct mode: %s" +msgstr "Erôr tal passâ ae modalitât direte: %s" + +#: panels/thunderbolt/cc-bolt-panel.ui:143 +msgid "No Thunderbolt support" +msgstr "Nissun supuart par Thunderbolt" + +#: panels/thunderbolt/cc-bolt-panel.ui:246 +msgid "Direct Access" +msgstr "Acès diret" + +#: panels/thunderbolt/cc-bolt-panel.ui:269 +msgid "Allow direct access to devices such as docks and external GPUs." +msgstr "" +"Permet l'acès diret a dispositîfs come supuarts (docks) e GPU esternis." + +#: panels/thunderbolt/cc-bolt-panel.ui:289 +msgid "Only USB and Display Port devices can attach." +msgstr "Dome i dispositîfs USB e Display Port a puedin tacâsi." + +#: panels/thunderbolt/cc-bolt-panel.ui:397 +msgid "Pending Devices" +msgstr "Dispositîf in pîts in spiete" + +#: panels/thunderbolt/cc-bolt-panel.ui:535 +msgid "No devices attached" +msgstr "Nissun dispositîf tacât" + +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:3 +msgid "Thunderbolt" +msgstr "Thunderbolt" + +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:4 +msgid "Manage Thunderbolt devices" +msgstr "Gjestìs i dispositîfs Thunderbolt" + +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:7 +msgid "thunderbolt" +msgstr "thunderbolt" + +#. Translators: those are keywords for the thunderbolt control-center panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:19 +msgid "Thunderbolt;" +msgstr "Thunderbolt;" + #. translators: the labels will read: #. * Cursor Size: Default -#: panels/universal-access/cc-ua-panel.c:353 +#: panels/universal-access/cc-ua-panel.c:354 msgctxt "cursor size" msgid "Default" msgstr "Predefinide" -#: panels/universal-access/cc-ua-panel.c:356 +#: panels/universal-access/cc-ua-panel.c:357 msgctxt "cursor size" msgid "Medium" msgstr "Medie" -#: panels/universal-access/cc-ua-panel.c:359 +#: panels/universal-access/cc-ua-panel.c:360 msgctxt "cursor size" msgid "Large" msgstr "Grant" -#: panels/universal-access/cc-ua-panel.c:362 +#: panels/universal-access/cc-ua-panel.c:363 msgctxt "cursor size" msgid "Larger" msgstr "Plui grant" -#: panels/universal-access/cc-ua-panel.c:365 +#: panels/universal-access/cc-ua-panel.c:366 msgctxt "cursor size" msgid "Largest" msgstr "Il plui grant" -#: panels/universal-access/cc-ua-panel.c:369 +#: panels/universal-access/cc-ua-panel.c:370 #, c-format msgid "%d pixel" msgid_plural "%d pixels" @@ -5843,7 +6067,7 @@ msgid "C_ursor Size" msgstr "Dimension c_ursôr" #: panels/universal-access/uap.ui:316 -#: panels/universal-access/zoom-options.ui:98 +#: panels/universal-access/zoom-options.ui:99 msgid "_Zoom" msgstr "_Ingrandiment" @@ -6134,27 +6358,27 @@ msgctxt "dwell click threshold" msgid "Large" msgstr "Grant" -#: panels/universal-access/zoom-options.c:333 +#: panels/universal-access/zoom-options.c:338 msgctxt "Distance" msgid "Short" msgstr "Curt" -#: panels/universal-access/zoom-options.c:334 +#: panels/universal-access/zoom-options.c:339 msgctxt "Distance" msgid "¼ Screen" msgstr "¼ di schermi" -#: panels/universal-access/zoom-options.c:335 +#: panels/universal-access/zoom-options.c:340 msgctxt "Distance" msgid "½ Screen" msgstr "½ schermi" -#: panels/universal-access/zoom-options.c:336 +#: panels/universal-access/zoom-options.c:341 msgctxt "Distance" msgid "¾ Screen" msgstr "¾ di schermi" -#: panels/universal-access/zoom-options.c:337 +#: panels/universal-access/zoom-options.c:342 msgctxt "Distance" msgid "Long" msgstr "Lungje" @@ -6179,134 +6403,134 @@ msgstr "Metât çampe" msgid "Right Half" msgstr "Metât diestre" -#: panels/universal-access/zoom-options.ui:77 +#: panels/universal-access/zoom-options.ui:78 msgid "Zoom Options" msgstr "Opzions di ingrandiment" -#: panels/universal-access/zoom-options.ui:186 +#: panels/universal-access/zoom-options.ui:188 msgid "_Magnification:" msgstr "In_grandiment:" -#: panels/universal-access/zoom-options.ui:250 +#: panels/universal-access/zoom-options.ui:252 msgid "_Follow mouse cursor" msgstr "_Cor daûr dal cursôr dal mouse" -#: panels/universal-access/zoom-options.ui:270 +#: panels/universal-access/zoom-options.ui:272 msgid "_Screen part:" msgstr "Part di _schermi:" -#: panels/universal-access/zoom-options.ui:332 +#: panels/universal-access/zoom-options.ui:334 msgid "Magnifier _extends outside of screen" msgstr "L'ingranditôr si _slargje fûr dal visôr" -#: panels/universal-access/zoom-options.ui:351 +#: panels/universal-access/zoom-options.ui:353 msgid "_Keep magnifier cursor centered" msgstr "_Tegnî il cursôr dal ingranditôr tal mieç" -#: panels/universal-access/zoom-options.ui:370 +#: panels/universal-access/zoom-options.ui:372 msgid "Magnifier cursor _pushes contents around" msgstr "Il cursôr dal ingranditôr al _sburte il contignût" -#: panels/universal-access/zoom-options.ui:389 +#: panels/universal-access/zoom-options.ui:391 msgid "Magnifier cursor moves with _contents" msgstr "Il cursôr dal ingranditôr si sposte cui _contignûts" -#: panels/universal-access/zoom-options.ui:423 +#: panels/universal-access/zoom-options.ui:425 msgid "Magnifier Position:" msgstr "Posizion dal ingranditôr:" -#: panels/universal-access/zoom-options.ui:444 +#: panels/universal-access/zoom-options.ui:446 msgid "Magnifier" msgstr "Ingranditôr" -#: panels/universal-access/zoom-options.ui:490 +#: panels/universal-access/zoom-options.ui:493 msgid "_Thickness:" msgstr "_Spessôr:" -#: panels/universal-access/zoom-options.ui:516 +#: panels/universal-access/zoom-options.ui:519 msgctxt "universal access, thickness" msgid "Thin" msgstr "Fin" -#: panels/universal-access/zoom-options.ui:548 +#: panels/universal-access/zoom-options.ui:551 msgctxt "universal access, thickness" msgid "Thick" msgstr "Spes" -#: panels/universal-access/zoom-options.ui:574 +#: panels/universal-access/zoom-options.ui:577 msgid "_Length:" msgstr "_Lungjece:" #. The color of the accessibility crosshair -#: panels/universal-access/zoom-options.ui:626 +#: panels/universal-access/zoom-options.ui:629 msgid "Co_lor:" msgstr "Co_lôr:" -#: panels/universal-access/zoom-options.ui:690 +#: panels/universal-access/zoom-options.ui:693 msgid "_Crosshairs:" msgstr "S_mire:" -#: panels/universal-access/zoom-options.ui:741 +#: panels/universal-access/zoom-options.ui:744 msgid "_Overlaps mouse cursor" msgstr "_Al sta parsore dal cursôr dal mouse" -#: panels/universal-access/zoom-options.ui:779 +#: panels/universal-access/zoom-options.ui:782 msgid "Crosshairs" msgstr "Smiris" -#: panels/universal-access/zoom-options.ui:827 +#: panels/universal-access/zoom-options.ui:831 msgid "_White on black:" msgstr "Blanc su _neri:" -#: panels/universal-access/zoom-options.ui:850 +#: panels/universal-access/zoom-options.ui:854 msgid "_Brightness:" msgstr "L_uminositât:" -#: panels/universal-access/zoom-options.ui:874 +#: panels/universal-access/zoom-options.ui:878 msgid "_Contrast:" msgstr "_Contrast:" #. The contrast scale goes from Color to None (grayscale) -#: panels/universal-access/zoom-options.ui:897 +#: panels/universal-access/zoom-options.ui:901 msgctxt "universal access, contrast" msgid "Co_lor" msgstr "Co_lôr" -#: panels/universal-access/zoom-options.ui:925 +#: panels/universal-access/zoom-options.ui:929 msgctxt "universal access, color" msgid "None" msgstr "Nissun" -#: panels/universal-access/zoom-options.ui:957 +#: panels/universal-access/zoom-options.ui:961 msgctxt "universal access, color" msgid "Full" msgstr "Plen" -#: panels/universal-access/zoom-options.ui:1023 +#: panels/universal-access/zoom-options.ui:1027 msgctxt "universal access, brightness" msgid "Low" msgstr "Basse" -#: panels/universal-access/zoom-options.ui:1056 +#: panels/universal-access/zoom-options.ui:1060 msgctxt "universal access, brightness" msgid "High" msgstr "Alte" -#: panels/universal-access/zoom-options.ui:1087 +#: panels/universal-access/zoom-options.ui:1091 msgctxt "universal access, contrast" msgid "Low" msgstr "Ridot" -#: panels/universal-access/zoom-options.ui:1120 +#: panels/universal-access/zoom-options.ui:1124 msgctxt "universal access, contrast" msgid "High" msgstr "Elevât" -#: panels/universal-access/zoom-options.ui:1156 +#: panels/universal-access/zoom-options.ui:1160 msgid "Color Effects:" msgstr "Efiets colôr:" -#: panels/universal-access/zoom-options.ui:1181 +#: panels/universal-access/zoom-options.ui:1185 msgid "Color Effects" msgstr "Efiets colôr" @@ -6898,7 +7122,7 @@ msgstr "%s — %s" #. Translators: This is a time format string in the style of "22:58". #. It indicates a login time which follows a date. #: panels/user-accounts/um-history-dialog.c:177 -#: panels/user-accounts/um-user-panel.c:767 +#: panels/user-accounts/um-user-panel.c:766 msgctxt "login date-time" msgid "%k:%M" msgstr "%H:%M" @@ -6906,7 +7130,7 @@ msgstr "%H:%M" #. Translators: This indicates a login date-time. #. The first %s is a date, and the second %s a time. #: panels/user-accounts/um-history-dialog.c:180 -#: panels/user-accounts/um-user-panel.c:771 +#: panels/user-accounts/um-user-panel.c:770 #, c-format msgctxt "login date-time" msgid "%s, %s" @@ -6943,7 +7167,7 @@ msgstr "Impussibil cambiâ la password" msgid "The passwords do not match." msgstr "Lis password no corispuindin." -#: panels/user-accounts/um-photo-dialog.c:226 +#: panels/user-accounts/um-photo-dialog.c:227 msgid "Browse for more pictures" msgstr "Esplore altris imagjins" @@ -6971,30 +7195,30 @@ msgstr "Password no valide, prove di gnûf" msgid "Couldn’t connect to the %s domain: %s" msgstr "Impussibil tacâsi al domini %s: %s" -#: panels/user-accounts/um-user-panel.c:201 +#: panels/user-accounts/um-user-panel.c:200 msgid "Your account" msgstr "Il to account" -#: panels/user-accounts/um-user-panel.c:381 +#: panels/user-accounts/um-user-panel.c:380 msgid "Failed to delete user" msgstr "Eliminazion utent falide" -#: panels/user-accounts/um-user-panel.c:439 -#: panels/user-accounts/um-user-panel.c:498 -#: panels/user-accounts/um-user-panel.c:550 +#: panels/user-accounts/um-user-panel.c:438 +#: panels/user-accounts/um-user-panel.c:497 +#: panels/user-accounts/um-user-panel.c:549 msgid "Failed to revoke remotely managed user" msgstr "Revoche dal utent gjestît di rimot falide" -#: panels/user-accounts/um-user-panel.c:604 +#: panels/user-accounts/um-user-panel.c:603 msgid "You cannot delete your own account." msgstr "Nol è permetût eliminâ il propri account." -#: panels/user-accounts/um-user-panel.c:613 +#: panels/user-accounts/um-user-panel.c:612 #, c-format msgid "%s is still logged in" msgstr "%s nol à ancjemò terminât la session" -#: panels/user-accounts/um-user-panel.c:617 +#: panels/user-accounts/um-user-panel.c:616 msgid "" "Deleting a user while they are logged in can leave the system in an " "inconsistent state." @@ -7002,12 +7226,12 @@ msgstr "" "Eliminâ un utent intant che la sô session e je ancjemò in cors, al pues " "lassâ il sisteme in stât incoerent." -#: panels/user-accounts/um-user-panel.c:626 +#: panels/user-accounts/um-user-panel.c:625 #, c-format msgid "Do you want to keep %s’s files?" msgstr "Tignî i file di %s?" -#: panels/user-accounts/um-user-panel.c:630 +#: panels/user-accounts/um-user-panel.c:629 msgid "" "It is possible to keep the home directory, mail spool and temporary files " "around when deleting a user account." @@ -7015,47 +7239,47 @@ msgstr "" "Al è pussibil tegnî la cartele home, la code di pueste e i varis file " "temporanis cuant che si elimine un account utent." -#: panels/user-accounts/um-user-panel.c:633 +#: panels/user-accounts/um-user-panel.c:632 msgid "_Delete Files" msgstr "_Scancele file" -#: panels/user-accounts/um-user-panel.c:634 +#: panels/user-accounts/um-user-panel.c:633 msgid "_Keep Files" msgstr "_Ten file" -#: panels/user-accounts/um-user-panel.c:648 +#: panels/user-accounts/um-user-panel.c:647 #, c-format msgid "Are you sure you want to revoke remotely managed %s’s account?" msgstr "Sigûrs di revocâ l'account di %s gjestît di rimot?" -#: panels/user-accounts/um-user-panel.c:652 +#: panels/user-accounts/um-user-panel.c:651 msgid "_Delete" msgstr "_Elimine" -#: panels/user-accounts/um-user-panel.c:702 +#: panels/user-accounts/um-user-panel.c:701 msgctxt "Password mode" msgid "Account disabled" msgstr "Account disabilitât" -#: panels/user-accounts/um-user-panel.c:710 +#: panels/user-accounts/um-user-panel.c:709 msgctxt "Password mode" msgid "To be set at next login" msgstr "Di stabilî al prossim acès" -#: panels/user-accounts/um-user-panel.c:713 +#: panels/user-accounts/um-user-panel.c:712 msgctxt "Password mode" msgid "None" msgstr "Nissun" -#: panels/user-accounts/um-user-panel.c:760 +#: panels/user-accounts/um-user-panel.c:759 msgid "Logged in" msgstr "Acès eseguît" -#: panels/user-accounts/um-user-panel.c:1107 +#: panels/user-accounts/um-user-panel.c:1106 msgid "Failed to contact the accounts service" msgstr "Comunicazion cun servizi account falide" -#: panels/user-accounts/um-user-panel.c:1109 +#: panels/user-accounts/um-user-panel.c:1108 msgid "Please make sure that the AccountService is installed and enabled." msgstr "Sigurâsi che AccountService al sedi instalât e abilitât." @@ -7063,7 +7287,7 @@ msgstr "Sigurâsi che AccountService al sedi instalât e abilitât." #. * We split the line in 2 here to "make it look good", as there's #. * no good way to do this in GTK+ for tooltips. See: #. * https://bugzilla.gnome.org/show_bug.cgi?id=657168 -#: panels/user-accounts/um-user-panel.c:1141 +#: panels/user-accounts/um-user-panel.c:1140 msgid "" "To make changes,\n" "click the * icon first" @@ -7071,12 +7295,12 @@ msgstr "" "Par aplicâ cambiaments,\n" "fâs prime clic su la icone *" -#: panels/user-accounts/um-user-panel.c:1181 +#: panels/user-accounts/um-user-panel.c:1180 msgid "Create a user account" msgstr "Cree un account utent" -#: panels/user-accounts/um-user-panel.c:1192 -#: panels/user-accounts/um-user-panel.c:1371 +#: panels/user-accounts/um-user-panel.c:1191 +#: panels/user-accounts/um-user-panel.c:1370 msgid "" "To create a user account,\n" "click the * icon first" @@ -7084,12 +7308,12 @@ msgstr "" "Par creâ un account utent,\n" "fas prime clic su la icone *" -#: panels/user-accounts/um-user-panel.c:1202 +#: panels/user-accounts/um-user-panel.c:1201 msgid "Delete the selected user account" msgstr "Elimine l'account utent selezionât" -#: panels/user-accounts/um-user-panel.c:1214 -#: panels/user-accounts/um-user-panel.c:1376 +#: panels/user-accounts/um-user-panel.c:1213 +#: panels/user-accounts/um-user-panel.c:1375 msgid "" "To delete the selected user account,\n" "click the * icon first" @@ -7367,35 +7591,35 @@ msgstr "" "Il centri di control GNOME e je la interface principâl par configurâ diviers " "aspiets dal to scritori." -#: shell/cc-application.c:47 +#: shell/cc-application.c:60 msgid "Display version number" msgstr "Mostre numar version" -#: shell/cc-application.c:48 +#: shell/cc-application.c:61 msgid "Enable verbose mode" msgstr "Abilite modalitât lungje/fetose" -#: shell/cc-application.c:49 +#: shell/cc-application.c:62 msgid "Show the overview" msgstr "Mostre la panoramiche" -#: shell/cc-application.c:50 +#: shell/cc-application.c:63 msgid "Search for the string" msgstr "Cîr la stringhe" -#: shell/cc-application.c:51 +#: shell/cc-application.c:64 msgid "List possible panel names and exit" msgstr "Liste i nons dai panei disponibii e jes" -#: shell/cc-application.c:52 +#: shell/cc-application.c:65 msgid "Panel to display" msgstr "Panel di mostrâ" -#: shell/cc-application.c:52 +#: shell/cc-application.c:65 msgid "[PANEL] [ARGUMENT…]" msgstr "[PANEL] [ARGOMENT…]" -#: shell/cc-application.c:117 +#: shell/cc-application.c:136 msgid "Available panels:" msgstr "Panei disponibii:" @@ -7447,12 +7671,6 @@ msgctxt "shortcut window" msgid "Cancel search" msgstr "Anule ricercje" -#. translators: This is the default hotspot name, need to be less than 32-bytes -#: shell/hostname-helper.c:189 -msgctxt "hotspot" -msgid "Hotspot" -msgstr "Hotspot" - #: shell/org.gnome.ControlCenter.gschema.xml:5 msgid "The identifier for the last Settings panel to be opened" msgstr "L'identificadôr pal ultin panel di Impostazions di vierzi" @@ -7665,12 +7883,6 @@ msgstr "Suns di sisteme" #~ msgid "_Method" #~ msgstr "_Maniere" -#~ msgid "Add Device" -#~ msgstr "Zonte dispositîf" - -#~ msgid "Remove Device" -#~ msgstr "Gjave dispositîf" - #~ msgid "VPN Type" #~ msgstr "Gjenar di VPN" @@ -8001,9 +8213,6 @@ msgstr "Suns di sisteme" #~ msgid "_Sign In" #~ msgstr "_Jentre" -#~ msgid "_Name:" -#~ msgstr "_Non:" - #~ msgid "Add Shortcut" #~ msgstr "Zonte scurte" -- cgit v1.2.1 From 3d134b93b4b9026d5162db8b7ecd456a6ec68221 Mon Sep 17 00:00:00 2001 From: Marek Cernocky Date: Fri, 4 May 2018 14:25:03 +0200 Subject: Updated Czech translation --- po/cs.po | 810 ++++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 516 insertions(+), 294 deletions(-) diff --git a/po/cs.po b/po/cs.po index 7d6c2cc51..48f972fbb 100644 --- a/po/cs.po +++ b/po/cs.po @@ -24,8 +24,8 @@ msgstr "" "Project-Id-Version: gnome-control-center\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-control-center/" "issues\n" -"POT-Creation-Date: 2018-02-23 19:10+0000\n" -"PO-Revision-Date: 2018-02-26 19:26+0100\n" +"POT-Creation-Date: 2018-04-19 13:00+0000\n" +"PO-Revision-Date: 2018-05-04 14:13+0200\n" "Last-Translator: Marek Černocký \n" "Language-Team: čeština \n" "Language: cs\n" @@ -118,16 +118,16 @@ msgid "You can add images to your %s folder and they will show up here" msgstr "Můžete obrázky přidat do své složky %s a potom se zde objeví" #: panels/background/cc-background-chooser-dialog.c:560 -#: panels/color/cc-color-panel.c:225 panels/color/cc-color-panel.c:963 +#: panels/color/cc-color-panel.c:224 panels/color/cc-color-panel.c:962 #: panels/color/color-calibrate.ui:25 panels/color/color.ui:657 -#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2594 +#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2610 #: panels/network/connection-editor/connection-editor.ui:15 #: panels/network/connection-editor/vpn-helpers.c:181 #: panels/network/connection-editor/vpn-helpers.c:310 #: panels/network/net-device-wifi.c:1411 panels/network/net-device-wifi.c:1491 #: panels/network/net-device-wifi.c:1736 panels/network/network-wifi.ui:24 #: panels/printers/new-printer-dialog.ui:45 -#: panels/printers/pp-details-dialog.c:331 +#: panels/printers/pp-details-dialog.c:330 #: panels/privacy/cc-privacy-panel.c:1053 panels/region/format-chooser.ui:25 #: panels/region/input-chooser.ui:13 #: panels/search/cc-search-locations-dialog.c:642 @@ -136,10 +136,10 @@ msgstr "Můžete obrázky přidat do své složky %s a potom se zde objeví" #: panels/user-accounts/data/join-dialog.ui:20 #: panels/user-accounts/data/password-dialog.ui:21 #: panels/user-accounts/um-fingerprint-dialog.c:261 -#: panels/user-accounts/um-photo-dialog.c:102 -#: panels/user-accounts/um-photo-dialog.c:229 -#: panels/user-accounts/um-user-panel.c:635 -#: panels/user-accounts/um-user-panel.c:653 +#: panels/user-accounts/um-photo-dialog.c:103 +#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-user-panel.c:634 +#: panels/user-accounts/um-user-panel.c:652 msgid "_Cancel" msgstr "_Zrušit" @@ -184,39 +184,39 @@ msgstr "preferences-desktop-wallpaper" msgid "Wallpaper;Screen;Desktop;" msgstr "tapeta;obrazovka;plocha;" -#: panels/bluetooth/cc-bluetooth-panel.c:265 +#: panels/bluetooth/cc-bluetooth-panel.c:266 msgid "Turn Off Airplane Mode" msgstr "Vypnout režim „letadlo“" -#: panels/bluetooth/cc-bluetooth-panel.c:330 +#: panels/bluetooth/cc-bluetooth-panel.c:329 msgid "No Bluetooth Found" msgstr "Nebylo nalezeno žádné Bluetooth" -#: panels/bluetooth/cc-bluetooth-panel.c:330 +#: panels/bluetooth/cc-bluetooth-panel.c:329 msgid "Plug in a dongle to use Bluetooth." msgstr "Připojte adaptér, aby šlo používat Bluetooth." -#: panels/bluetooth/cc-bluetooth-panel.c:331 +#: panels/bluetooth/cc-bluetooth-panel.c:330 msgid "Bluetooth Turned Off" msgstr "Bluetooth vypnuto" -#: panels/bluetooth/cc-bluetooth-panel.c:331 +#: panels/bluetooth/cc-bluetooth-panel.c:330 msgid "Turn on to connect devices and receive file transfers." msgstr "Zapnout, aby se připojila zařízení a obdržela přenosy souborů." -#: panels/bluetooth/cc-bluetooth-panel.c:332 +#: panels/bluetooth/cc-bluetooth-panel.c:331 msgid "Airplane Mode is on" msgstr "Režim „letadlo“ je zapnutý" -#: panels/bluetooth/cc-bluetooth-panel.c:332 +#: panels/bluetooth/cc-bluetooth-panel.c:331 msgid "Bluetooth is disabled when airplane mode is on." msgstr "Když je zapnutý režim „letadlo“, je Bluetooth zakázané." -#: panels/bluetooth/cc-bluetooth-panel.c:333 +#: panels/bluetooth/cc-bluetooth-panel.c:332 msgid "Hardware Airplane Mode is on" msgstr "Hardwarový režim „letadlo“ je zapnutý" -#: panels/bluetooth/cc-bluetooth-panel.c:333 +#: panels/bluetooth/cc-bluetooth-panel.c:332 msgid "Turn off the Airplane mode switch to enable Bluetooth." msgstr "Vypněte přepínač režimu „letadlo“, aby se povolilo Bluetooth." @@ -241,14 +241,14 @@ msgid "share;sharing;bluetooth;obex;" msgstr "sdílet;sdílení;bluetooth;obex;" #. TRANSLATORS: The user has to attach the sensor to the screen -#: panels/color/cc-color-calibrate.c:361 +#: panels/color/cc-color-calibrate.c:363 msgid "Place your calibration device over the square and press “Start”" msgstr "Umístěte kalibrační zařízení na čtverec a zmáčkněte „Začít“" #. TRANSLATORS: Some calibration devices need the user to move a #. * dial or switch manually. We also show a picture showing them #. * what to do... -#: panels/color/cc-color-calibrate.c:367 +#: panels/color/cc-color-calibrate.c:369 msgid "" "Move your calibration device to the calibrate position and press “Continue”" msgstr "" @@ -257,7 +257,7 @@ msgstr "" #. TRANSLATORS: Some calibration devices need the user to move a #. * dial or switch manually. We also show a picture showing them #. * what to do... -#: panels/color/cc-color-calibrate.c:373 +#: panels/color/cc-color-calibrate.c:375 msgid "" "Move your calibration device to the surface position and press “Continue”" msgstr "" @@ -266,54 +266,54 @@ msgstr "" #. TRANSLATORS: on some hardware e.g. Lenovo W700 the sensor #. * is built into the palmrest and we need to fullscreen the #. * sample widget and shut the lid. -#: panels/color/cc-color-calibrate.c:379 +#: panels/color/cc-color-calibrate.c:381 msgid "Shut the laptop lid" msgstr "Zavřete víko notebooku" #. TRANSLATORS: We suck, the calibation failed and we have no #. * good idea why or any suggestions -#: panels/color/cc-color-calibrate.c:410 +#: panels/color/cc-color-calibrate.c:412 msgid "An internal error occurred that could not be recovered." msgstr "Došlo k vnitřní chybě, z které už se nelze obnovit." #. TRANSLATORS: Some required-at-runtime tools were not #. * installed, which should only affect insane distros -#: panels/color/cc-color-calibrate.c:415 +#: panels/color/cc-color-calibrate.c:417 msgid "Tools required for calibration are not installed." msgstr "Nástroje vyžadované pro kalibraci nejsou nainstalované." #. TRANSLATORS: The profile failed for some reason -#: panels/color/cc-color-calibrate.c:421 +#: panels/color/cc-color-calibrate.c:423 msgid "The profile could not be generated." msgstr "Profil nemohl být vygenerován." #. TRANSLATORS: The user specified a whitepoint that was #. * unobtainable with the hardware they've got -- see #. * https://en.wikipedia.org/wiki/White_point for details -#: panels/color/cc-color-calibrate.c:427 +#: panels/color/cc-color-calibrate.c:429 msgid "The target whitepoint was not obtainable." msgstr "Cílový bílý bod nebyl dosažitelný." #. TRANSLATORS: the display calibration process is finished -#: panels/color/cc-color-calibrate.c:467 +#: panels/color/cc-color-calibrate.c:469 msgid "Complete!" msgstr "Dokončeno!" #. TRANSLATORS: the display calibration failed, and we also show #. * the translated (or untranslated) error string after this -#: panels/color/cc-color-calibrate.c:475 +#: panels/color/cc-color-calibrate.c:477 msgid "Calibration failed!" msgstr "Kalibrace selhala!" #. TRANSLATORS: The user can now remove the sensor from the screen -#: panels/color/cc-color-calibrate.c:482 +#: panels/color/cc-color-calibrate.c:484 msgid "You can remove the calibration device." msgstr "Můžete oddělat kalibrační zařízení." #. TRANSLATORS: The user has to be careful not to knock the #. * display off the screen (although we do cope if this is #. * detected early enough) -#: panels/color/cc-color-calibrate.c:553 +#: panels/color/cc-color-calibrate.c:556 msgid "Do not disturb the calibration device while in progress" msgstr "Nestrkejte do kalibračního zařízení během procesu kalibrace" @@ -375,48 +375,48 @@ msgstr "Nezkalibrováno" #. TRANSLATORS: this is a profile prefix to signify the #. * profile has been auto-generated for this hardware -#: panels/color/cc-color-panel.c:141 +#: panels/color/cc-color-panel.c:140 msgid "Default: " msgstr "Výchozí:" #. TRANSLATORS: this is a profile prefix to signify the #. * profile his a standard space like AdobeRGB -#: panels/color/cc-color-panel.c:149 +#: panels/color/cc-color-panel.c:148 msgid "Colorspace: " msgstr "Prostor barev:" #. TRANSLATORS: this is a profile prefix to signify the #. * profile is a test profile -#: panels/color/cc-color-panel.c:156 +#: panels/color/cc-color-panel.c:155 msgid "Test profile: " msgstr "Testovací profil: " #. TRANSLATORS: an ICC profile is a file containing colorspace data -#: panels/color/cc-color-panel.c:223 +#: panels/color/cc-color-panel.c:222 msgid "Select ICC Profile File" msgstr "Výběr souboru s profilem ICC" -#: panels/color/cc-color-panel.c:226 +#: panels/color/cc-color-panel.c:225 msgid "_Import" msgstr "_Importovat" #. TRANSLATORS: filter name on the file->open dialog -#: panels/color/cc-color-panel.c:237 +#: panels/color/cc-color-panel.c:236 msgid "Supported ICC profiles" msgstr "Podporované profily ICC" #. TRANSLATORS: filter name on the file->open dialog -#: panels/color/cc-color-panel.c:244 +#: panels/color/cc-color-panel.c:243 #: panels/network/wireless-security/eap-method-fast.c:417 msgid "All files" msgstr "Všechny soubory" -#: panels/color/cc-color-panel.c:583 +#: panels/color/cc-color-panel.c:582 msgid "Screen" msgstr "Obrazovka" #. TRANSLATORS: this is when the upload of the profile failed -#: panels/color/cc-color-panel.c:908 +#: panels/color/cc-color-panel.c:907 #, c-format msgid "Failed to upload file: %s" msgstr "Selhalo odeslání souboru: %s" @@ -424,40 +424,40 @@ msgstr "Selhalo odeslání souboru: %s" #. TRANSLATORS: these are instructions on how to recover #. * the ICC profile on the native operating system and are #. * only shown when the user uses a LiveCD to calibrate -#: panels/color/cc-color-panel.c:922 +#: panels/color/cc-color-panel.c:921 msgid "The profile has been uploaded to:" msgstr "Profil byl odeslán na:" -#: panels/color/cc-color-panel.c:924 +#: panels/color/cc-color-panel.c:923 msgid "Write down this URL." msgstr "Zapište si tuto adresu URL." -#: panels/color/cc-color-panel.c:925 +#: panels/color/cc-color-panel.c:924 msgid "Restart this computer and boot your normal operating system." msgstr "Restartujte tento počítač a zaveďte svůj normální operační systém." -#: panels/color/cc-color-panel.c:926 +#: panels/color/cc-color-panel.c:925 msgid "Type the URL into your browser to download and install the profile." msgstr "" "Zadejte adresu URL do svého prohlížeče, aby se stáhl a nainstaloval profil." #. TRANSLATORS: this is the dialog to save the ICC profile -#: panels/color/cc-color-panel.c:960 +#: panels/color/cc-color-panel.c:959 msgid "Save Profile" msgstr "Uložit profil" -#: panels/color/cc-color-panel.c:964 +#: panels/color/cc-color-panel.c:963 #: panels/network/connection-editor/vpn-helpers.c:311 msgid "_Save" msgstr "_Uložit" #. TRANSLATORS: this is when the button is sensitive -#: panels/color/cc-color-panel.c:1325 +#: panels/color/cc-color-panel.c:1324 msgid "Create a color profile for the selected device" msgstr "Vytvořit barevný profil pro vybrané zařízení" #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1340 panels/color/cc-color-panel.c:1364 +#: panels/color/cc-color-panel.c:1339 panels/color/cc-color-panel.c:1363 msgid "" "The measuring instrument is not detected. Please check it is turned on and " "correctly connected." @@ -466,12 +466,12 @@ msgstr "" "a zapnutá." #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1374 +#: panels/color/cc-color-panel.c:1373 msgid "The measuring instrument does not support printer profiling." msgstr "Měřící sonda nepodporuje profilování tiskáren." #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1385 +#: panels/color/cc-color-panel.c:1384 msgid "The device type is not currently supported." msgstr "Typ zařízení není v současnosti podporován." @@ -920,6 +920,12 @@ msgstr "%e. %B" msgid "%b %e, %Y" msgstr "%e. %B %Y" +#. translators: This is the default hotspot name, need to be less than 32-bytes +#: panels/common/hostname-helper.c:189 +msgctxt "hotspot" +msgid "Hotspot" +msgstr "Přístupový bod" + #: panels/common/language-chooser.ui:5 msgid "Language" msgstr "Jazyk" @@ -1116,58 +1122,58 @@ msgstr "Změnit nastavení systémového času a data" msgid "To change time or date settings, you need to authenticate." msgstr "Abyste mohli měnit nastavení času a data, musíte se autentizovat." -#: panels/display/cc-display-panel.c:729 +#: panels/display/cc-display-panel.c:739 msgctxt "Display rotation" msgid "Landscape" msgstr "Na šířku" -#: panels/display/cc-display-panel.c:732 +#: panels/display/cc-display-panel.c:742 msgctxt "Display rotation" msgid "Portrait Right" msgstr "Na výšku vpravo" -#: panels/display/cc-display-panel.c:735 +#: panels/display/cc-display-panel.c:745 msgctxt "Display rotation" msgid "Portrait Left" msgstr "Na výšku vlevo" -#: panels/display/cc-display-panel.c:738 +#: panels/display/cc-display-panel.c:748 msgctxt "Display rotation" msgid "Landscape (flipped)" msgstr "Na šířku (překlopené)" #. Translators: This option sets orientation of print (portrait, landscape...) -#: panels/display/cc-display-panel.c:805 +#: panels/display/cc-display-panel.c:816 #: panels/printers/pp-options-dialog.c:558 msgid "Orientation" msgstr "Orientace" -#: panels/display/cc-display-panel.c:870 panels/display/cc-display-panel.c:1673 +#: panels/display/cc-display-panel.c:885 panels/display/cc-display-panel.c:1691 #: panels/printers/pp-options-dialog.c:87 msgid "Resolution" msgstr "Rozlišení" -#: panels/display/cc-display-panel.c:958 +#: panels/display/cc-display-panel.c:974 msgid "Refresh Rate" msgstr "Obnovovací frekvence" -#: panels/display/cc-display-panel.c:1095 +#: panels/display/cc-display-panel.c:1111 msgid "Scale" msgstr "Škálování" -#: panels/display/cc-display-panel.c:1148 +#: panels/display/cc-display-panel.c:1164 msgid "Adjust for TV" msgstr "Přizpůsobit televizi" -#: panels/display/cc-display-panel.c:1410 +#: panels/display/cc-display-panel.c:1427 msgid "Primary Display" msgstr "Hlavní displej" -#: panels/display/cc-display-panel.c:1439 +#: panels/display/cc-display-panel.c:1456 msgid "Display Arrangement" msgstr "Uspořádání displejů" -#: panels/display/cc-display-panel.c:1440 +#: panels/display/cc-display-panel.c:1457 msgid "" "Drag displays to match your setup. The top bar is placed on the primary " "display." @@ -1175,59 +1181,67 @@ msgstr "" "Přesuňte displeje tak, aby odpovídaly vašemu rozestavení. Horní pruh je v " "místě hlavního displeje." -#: panels/display/cc-display-panel.c:1863 +#: panels/display/cc-display-panel.c:1881 msgid "Display Mode" msgstr "Režim displeje" -#: panels/display/cc-display-panel.c:1879 +#: panels/display/cc-display-panel.c:1897 msgid "Join Displays" msgstr "Sloučit displeje" -#: panels/display/cc-display-panel.c:1882 +#: panels/display/cc-display-panel.c:1900 msgid "Mirror" msgstr "Duplikovat" -#: panels/display/cc-display-panel.c:1885 +#: panels/display/cc-display-panel.c:1903 msgid "Single Display" msgstr "Samostatný displej" -#: panels/display/cc-display-panel.c:2590 -msgid "Apply Changes?" -msgstr "Použít změny?" - -#: panels/display/cc-display-panel.c:2604 +#: panels/display/cc-display-panel.c:2620 #: panels/network/connection-editor/connection-editor.ui:24 #: panels/network/network-wifi.ui:38 msgid "_Apply" msgstr "_Použít" -#: panels/display/cc-display-panel.c:2979 +#: panels/display/cc-display-panel.c:2642 +msgid "Apply Changes?" +msgstr "Použít změny?" + +#: panels/display/cc-display-panel.c:2647 +msgid "Changes Cannot be Applied" +msgstr "Změny nelze použít" + +#: panels/display/cc-display-panel.c:2648 +msgid "This could be due to hardware limitations." +msgstr "Může to být dáno omezeními hardwaru." + +#: panels/display/cc-display-panel.c:3003 #, c-format msgid "%.2lf Hz" msgstr "%.2lf Hz" #. TRANSLATORS: the state of the night light setting -#: panels/display/cc-display-panel.c:3195 +#: panels/display/cc-display-panel.c:3219 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1991 panels/power/cc-power-panel.c:1998 -#: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 -#: panels/universal-access/cc-ua-panel.c:333 -#: panels/universal-access/cc-ua-panel.c:714 -#: panels/universal-access/cc-ua-panel.c:727 -#: panels/universal-access/cc-ua-panel.c:739 -#: panels/universal-access/cc-ua-panel.c:910 +#: panels/power/cc-power-panel.c:2097 panels/power/cc-power-panel.c:2104 +#: panels/privacy/cc-privacy-panel.c:191 panels/privacy/cc-privacy-panel.c:258 +#: panels/universal-access/cc-ua-panel.c:334 +#: panels/universal-access/cc-ua-panel.c:715 +#: panels/universal-access/cc-ua-panel.c:728 +#: panels/universal-access/cc-ua-panel.c:740 +#: panels/universal-access/cc-ua-panel.c:911 msgid "On" msgstr "Zapnuto" -#: panels/display/cc-display-panel.c:3195 panels/network/net-proxy.c:54 +#: panels/display/cc-display-panel.c:3219 panels/network/net-proxy.c:54 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1985 panels/power/cc-power-panel.c:1996 -#: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 -#: panels/universal-access/cc-ua-panel.c:333 -#: panels/universal-access/cc-ua-panel.c:714 -#: panels/universal-access/cc-ua-panel.c:727 -#: panels/universal-access/cc-ua-panel.c:739 -#: panels/universal-access/cc-ua-panel.c:910 panels/universal-access/uap.ui:334 +#: panels/power/cc-power-panel.c:2091 panels/power/cc-power-panel.c:2102 +#: panels/privacy/cc-privacy-panel.c:191 panels/privacy/cc-privacy-panel.c:258 +#: panels/universal-access/cc-ua-panel.c:334 +#: panels/universal-access/cc-ua-panel.c:715 +#: panels/universal-access/cc-ua-panel.c:728 +#: panels/universal-access/cc-ua-panel.c:740 +#: panels/universal-access/cc-ua-panel.c:911 panels/universal-access/uap.ui:334 #: panels/universal-access/uap.ui:380 panels/universal-access/uap.ui:426 #: panels/universal-access/uap.ui:532 panels/universal-access/uap.ui:685 #: panels/universal-access/uap.ui:731 panels/universal-access/uap.ui:777 @@ -1235,11 +1249,11 @@ msgstr "Zapnuto" msgid "Off" msgstr "Vypnuto" -#: panels/display/cc-display-panel.c:3216 +#: panels/display/cc-display-panel.c:3240 msgid "_Night Light" msgstr "_Noční světlo" -#: panels/display/cc-display-panel.c:3281 +#: panels/display/cc-display-panel.c:3305 msgid "Could not get screen information" msgstr "Nelze získat informace o obrazovce" @@ -1279,7 +1293,7 @@ msgstr "Od soumraku do rozbřesku" #: panels/network/connection-editor/ip6-page.ui:83 #: panels/network/net-proxy.c:56 panels/network/network-proxy.ui:113 #: panels/network/network-wifi.ui:777 panels/network/network-wifi.ui:1054 -#: panels/privacy/cc-privacy-panel.c:217 +#: panels/privacy/cc-privacy-panel.c:218 msgid "Manual" msgstr "Ruční" @@ -1329,8 +1343,8 @@ msgstr "" "východ;západ;slunce;" #. TRANSLATORS: AP type -#: panels/info/cc-info-overview-panel.c:374 -#: panels/info/cc-info-overview-panel.c:457 panels/network/panel-common.c:123 +#: panels/info/cc-info-overview-panel.c:373 +#: panels/info/cc-info-overview-panel.c:456 panels/network/panel-common.c:123 msgid "Unknown" msgstr "Není známo" @@ -1338,24 +1352,24 @@ msgstr "Není známo" #. * example: #. * "Fedora 25 (Workstation Edition); Build ID: xyz" or #. * "Ubuntu 16.04 LTS; Build ID: jki" -#: panels/info/cc-info-overview-panel.c:465 +#: panels/info/cc-info-overview-panel.c:464 #, c-format msgid "%s; Build ID: %s" msgstr "%s; ID sestavení: %s" #. translators: This is the type of architecture for the OS -#: panels/info/cc-info-overview-panel.c:482 +#: panels/info/cc-info-overview-panel.c:481 #, c-format msgid "64-bit" msgstr "64bitový" #. translators: This is the type of architecture for the OS -#: panels/info/cc-info-overview-panel.c:485 +#: panels/info/cc-info-overview-panel.c:484 #, c-format msgid "32-bit" msgstr "32bitový" -#: panels/info/cc-info-overview-panel.c:775 +#: panels/info/cc-info-overview-panel.c:773 #, c-format msgid "Version %s" msgstr "Verze %s" @@ -1690,8 +1704,8 @@ msgstr "Spouštěče" msgid "Launch help browser" msgstr "Spustit prohlížeč nápovědy" -#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:223 -#: shell/cc-window.c:761 shell/gnome-control-center.desktop.in.in:3 +#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:237 +#: shell/cc-window.c:773 shell/gnome-control-center.desktop.in.in:3 #: shell/window.ui:125 msgid "Settings" msgstr "Nastavení" @@ -1800,7 +1814,7 @@ msgstr "Zapnout nebo vypnout vysoký kontrast" #: panels/keyboard/cc-keyboard-manager.c:506 #: panels/keyboard/cc-keyboard-manager.c:514 -#: panels/keyboard/cc-keyboard-manager.c:822 +#: panels/keyboard/cc-keyboard-manager.c:821 msgid "Custom Shortcuts" msgstr "Vlastní zkratky" @@ -1811,7 +1825,7 @@ msgstr "Vlastní zkratky" #. * The device has been disabled #: panels/keyboard/cc-keyboard-option.c:263 #: panels/keyboard/cc-keyboard-option.c:382 -#: panels/keyboard/keyboard-shortcuts.c:435 +#: panels/keyboard/keyboard-shortcuts.c:434 #: panels/keyboard/shortcut-editor.ui:96 panels/network/network-proxy.ui:123 #: panels/network/network-wifi.ui:782 panels/network/network-wifi.ui:1059 #: panels/user-accounts/um-fingerprint-dialog.c:211 @@ -2110,7 +2124,7 @@ msgid "Single click, secondary button" msgstr "Kliknutí, vedlejší tlačítko" #. add proxy to device list -#: panels/network/cc-network-panel.c:579 +#: panels/network/cc-network-panel.c:581 msgid "Network proxy" msgstr "Proxy sítě" @@ -2118,23 +2132,23 @@ msgstr "Proxy sítě" #. * window for vpn connections, it is also used to display #. * vpn connections in the device list. #. -#: panels/network/cc-network-panel.c:715 panels/network/net-vpn.c:192 -#: panels/network/net-vpn.c:321 +#: panels/network/cc-network-panel.c:717 panels/network/net-vpn.c:167 +#: panels/network/net-vpn.c:296 #, c-format msgid "%s VPN" msgstr "VPN %s" -#: panels/network/cc-network-panel.c:779 panels/network/wifi.ui:282 +#: panels/network/cc-network-panel.c:781 panels/network/wifi.ui:282 msgid "Oops, something has gone wrong. Please contact your software vendor." msgstr "Problém, něco se stalo špatně. Kontaktujte prosím vyrobce softwaru." -#: panels/network/cc-network-panel.c:785 +#: panels/network/cc-network-panel.c:787 msgid "NetworkManager needs to be running." msgstr "Je zapotřebí, aby běžel program NetworkManager." -#: panels/network/cc-wifi-panel.c:213 +#: panels/network/cc-wifi-panel.c:214 #: panels/network/gnome-wifi-panel.desktop.in.in:3 -#: panels/network/network-wifi.ui:1766 +#: panels/network/network-wifi.ui:1769 msgid "Wi-Fi" msgstr "Wi-Fi" @@ -2283,7 +2297,7 @@ msgid "Remove VPN" msgstr "Odebrat VPN" #: panels/network/connection-editor/ce-page-details.c:334 -#: panels/network/network-wifi.ui:1456 shell/cc-window.c:215 +#: panels/network/network-wifi.ui:1456 shell/cc-window.c:229 #: shell/panel-list.ui:103 msgid "Details" msgstr "Podrobnosti" @@ -2418,7 +2432,7 @@ msgstr "Určeno pro připojení, u kterých jsou přenosy účtované nebo omeze #: panels/network/connection-editor/ip6-page.ui:291 #: panels/network/net-proxy.c:58 panels/network/network-proxy.ui:103 #: panels/network/wireless-security/eap-method-peap.ui:22 -#: panels/privacy/cc-privacy-panel.c:217 +#: panels/privacy/cc-privacy-panel.c:218 msgid "Automatic" msgstr "Automatické" @@ -2616,9 +2630,9 @@ msgid "Select file to import" msgstr "Vybrat soubor pro import" #: panels/network/connection-editor/vpn-helpers.c:182 -#: panels/printers/pp-details-dialog.c:332 +#: panels/printers/pp-details-dialog.c:331 #: panels/sharing/cc-sharing-panel.c:385 -#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-photo-dialog.c:231 msgid "_Open" msgstr "_Otevřít" @@ -3041,19 +3055,19 @@ msgctxt "Wi-Fi passkey" msgid "Password" msgstr "Heslo" -#: panels/network/network-wifi.ui:1796 +#: panels/network/network-wifi.ui:1799 msgid "Turn Wi-Fi off" msgstr "Zapnout Wi-Fi" -#: panels/network/network-wifi.ui:1828 +#: panels/network/network-wifi.ui:1831 msgid "_Connect to Hidden Network…" msgstr "Přip_ojit se ke skryté síti…" -#: panels/network/network-wifi.ui:1838 +#: panels/network/network-wifi.ui:1841 msgid "_Turn On Wi-Fi Hotspot…" msgstr "Zapnou_t bezdrátový přístupový bod…" -#: panels/network/network-wifi.ui:1848 +#: panels/network/network-wifi.ui:1851 msgid "_Known Wi-Fi Networks" msgstr "Známé sítě Wi-_Fi" @@ -3362,23 +3376,23 @@ msgstr "Schází firmware" msgid "Cable unplugged" msgstr "Odpojen kabel" -#: panels/network/wireless-security/eap-method.c:57 +#: panels/network/wireless-security/eap-method.c:69 msgid "undefined error in 802.1X security (wpa-eap)" msgstr "nedefinovaná chyba v zabezpečení 802.1X (wpa-eap)" -#: panels/network/wireless-security/eap-method.c:233 +#: panels/network/wireless-security/eap-method.c:245 msgid "no file selected" msgstr "není vybrán žádný soubor" -#: panels/network/wireless-security/eap-method.c:264 +#: panels/network/wireless-security/eap-method.c:276 msgid "unspecified error validating eap-method file" msgstr "blíže neurčená chyba při ověřování souboru s metodou eap" -#: panels/network/wireless-security/eap-method.c:439 +#: panels/network/wireless-security/eap-method.c:451 msgid "DER, PEM, or PKCS#12 private keys (*.der, *.pem, *.p12, *.key)" msgstr "Soukromé klíče DER, PEM, nebo PKCS#12 (*.der, *.pem, *.p12, *.key)" -#: panels/network/wireless-security/eap-method.c:442 +#: panels/network/wireless-security/eap-method.c:454 msgid "DER or PEM certificates (*.der, *.pem, *.crt, *.cer)" msgstr "Certifikáty DER nebo PEM (*.der, *.pem, *.crt, *.cer)" @@ -3799,19 +3813,19 @@ msgstr "Jiný" #. translators: This is the title of the "Show Account" dialog. The #. * %s is the name of the provider. e.g., 'Google'. -#: panels/online-accounts/cc-online-accounts-panel.c:551 +#: panels/online-accounts/cc-online-accounts-panel.c:612 #, c-format msgid "%s Account" msgstr "Účet %s" -#: panels/online-accounts/cc-online-accounts-panel.c:843 +#: panels/online-accounts/cc-online-accounts-panel.c:904 msgid "Error removing account" msgstr "Chyba při odebírání účtu" #. Translators: The %s is the username (eg., debarshi.ray@gmail.com #. * or rishi). #. -#: panels/online-accounts/cc-online-accounts-panel.c:908 +#: panels/online-accounts/cc-online-accounts-panel.c:969 #, c-format msgid "%s removed" msgstr "%s byl odebrán" @@ -3863,11 +3877,11 @@ msgstr "Přidat účet" msgid "Remove Account" msgstr "Odebrat účet" -#: panels/power/cc-power-panel.c:253 +#: panels/power/cc-power-panel.c:254 msgid "Unknown time" msgstr "Neznámý čas" -#: panels/power/cc-power-panel.c:259 +#: panels/power/cc-power-panel.c:260 #, c-format msgid "%i minute" msgid_plural "%i minutes" @@ -3875,7 +3889,7 @@ msgstr[0] "%i minuta" msgstr[1] "%i minuty" msgstr[2] "%i minut" -#: panels/power/cc-power-panel.c:271 +#: panels/power/cc-power-panel.c:272 #, c-format msgid "%i hour" msgid_plural "%i hours" @@ -3885,19 +3899,19 @@ msgstr[2] "%i hodin" #. TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes" #. * Swap order with "%2$s %2$i %1$s %1$i if needed -#: panels/power/cc-power-panel.c:279 +#: panels/power/cc-power-panel.c:280 #, c-format msgid "%i %s %i %s" msgstr "%i %s %i %s" -#: panels/power/cc-power-panel.c:280 +#: panels/power/cc-power-panel.c:281 msgid "hour" msgid_plural "hours" msgstr[0] "hodina" msgstr[1] "hodiny" msgstr[2] "hodin" -#: panels/power/cc-power-panel.c:281 +#: panels/power/cc-power-panel.c:282 msgid "minute" msgid_plural "minutes" msgstr[0] "minuta" @@ -3905,240 +3919,284 @@ msgstr[1] "minuty" msgstr[2] "minut" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:300 +#: panels/power/cc-power-panel.c:301 #, c-format msgid "%s until fully charged" msgstr "%s do plného nabití" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:307 +#: panels/power/cc-power-panel.c:308 #, c-format msgid "Caution: %s remaining" msgstr "Pozor, zbývá %s" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:312 +#: panels/power/cc-power-panel.c:313 #, c-format msgid "%s remaining" msgstr "Zbývá %s" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:317 panels/power/cc-power-panel.c:345 +#: panels/power/cc-power-panel.c:318 panels/power/cc-power-panel.c:346 msgid "Fully charged" msgstr "Plně nabito" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:321 panels/power/cc-power-panel.c:349 +#: panels/power/cc-power-panel.c:322 panels/power/cc-power-panel.c:350 msgid "Empty" msgstr "Vybitá" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:336 +#: panels/power/cc-power-panel.c:337 msgid "Charging" msgstr "Nabíjí se" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:341 +#: panels/power/cc-power-panel.c:342 msgid "Discharging" msgstr "Vybíjí se" -#: panels/power/cc-power-panel.c:464 +#: panels/power/cc-power-panel.c:465 msgctxt "Battery name" msgid "Main" msgstr "Hlavní" -#: panels/power/cc-power-panel.c:466 +#: panels/power/cc-power-panel.c:467 msgctxt "Battery name" msgid "Extra" msgstr "Přídavná" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:537 +#: panels/power/cc-power-panel.c:538 msgid "Wireless mouse" msgstr "Bezdrátová myš" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:540 +#: panels/power/cc-power-panel.c:541 msgid "Wireless keyboard" msgstr "Bezdrátová klávesnice" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:543 +#: panels/power/cc-power-panel.c:544 msgid "Uninterruptible power supply" msgstr "Záložní zdroj napájení" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:546 +#: panels/power/cc-power-panel.c:547 msgid "Personal digital assistant" msgstr "Osobní digitální asistent (PDA)" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:549 +#: panels/power/cc-power-panel.c:550 msgid "Cellphone" msgstr "Mobilní telefon" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:552 +#: panels/power/cc-power-panel.c:553 msgid "Media player" msgstr "Multimediální přehrávač" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:555 panels/wacom/cc-wacom-panel.c:793 +#: panels/power/cc-power-panel.c:556 panels/wacom/cc-wacom-panel.c:793 msgid "Tablet" msgstr "Tablet" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:558 +#: panels/power/cc-power-panel.c:559 msgid "Computer" msgstr "Počítač" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:561 +#: panels/power/cc-power-panel.c:562 msgid "Gaming input device" msgstr "Herní vstupní zařízení" #. TRANSLATORS: secondary battery, misc -#: panels/power/cc-power-panel.c:564 panels/power/cc-power-panel.c:804 -#: panels/power/cc-power-panel.c:2377 +#: panels/power/cc-power-panel.c:565 panels/power/cc-power-panel.c:829 +#: panels/power/cc-power-panel.c:2483 msgid "Battery" msgstr "Baterie" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:618 +#: panels/power/cc-power-panel.c:632 msgctxt "Battery power" msgid "Charging" msgstr "Nabíjí se" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:625 +#: panels/power/cc-power-panel.c:639 msgctxt "Battery power" msgid "Caution" msgstr "Pozor" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:630 +#: panels/power/cc-power-panel.c:644 msgctxt "Battery power" msgid "Low" msgstr "Nízká" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:635 +#: panels/power/cc-power-panel.c:649 msgctxt "Battery power" msgid "Good" msgstr "Dobrá" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:640 +#: panels/power/cc-power-panel.c:654 msgctxt "Battery power" msgid "Fully charged" msgstr "Plně nabitá" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:644 +#: panels/power/cc-power-panel.c:658 msgctxt "Battery power" msgid "Empty" msgstr "Vybitá" -#: panels/power/cc-power-panel.c:802 +#: panels/power/cc-power-panel.c:827 msgid "Batteries" msgstr "Baterie" -#: panels/power/cc-power-panel.c:1239 +#: panels/power/cc-power-panel.c:1206 +#, c-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d hodiny" +msgstr[1] "%d hodin" +msgstr[2] "%d hodin" + +#: panels/power/cc-power-panel.c:1208 +#, c-format +msgid "%d minute" +msgid_plural "%d minutes" +msgstr[0] "%d minuty" +msgstr[1] "%d minut" +msgstr[2] "%d minut" + +#: panels/power/cc-power-panel.c:1211 +#, c-format +msgid "%d second" +msgid_plural "%d seconds" +msgstr[0] "%d sekundy" +msgstr[1] "%d sekund" +msgstr[2] "%d sekund" + +#. 5 hours 2 minutes 12 seconds +#: panels/power/cc-power-panel.c:1217 +#, c-format +msgctxt "time" +msgid "%s %s %s" +msgstr "%s %s %s" + +#. 2 minutes 12 seconds +#: panels/power/cc-power-panel.c:1220 +#, c-format +msgctxt "time" +msgid "%s %s" +msgstr "%s %s" + +#. 0 seconds +#: panels/power/cc-power-panel.c:1226 +msgid "0 seconds" +msgstr "0 sekund" + +#: panels/power/cc-power-panel.c:1328 msgid "When _idle" msgstr "Při _nečinnosti" -#: panels/power/cc-power-panel.c:1693 +#: panels/power/cc-power-panel.c:1793 msgid "Power Saving" msgstr "Šetření energií" -#: panels/power/cc-power-panel.c:1724 +#: panels/power/cc-power-panel.c:1824 msgid "_Screen brightness" msgstr "_Jas obrazovky" -#: panels/power/cc-power-panel.c:1743 +#: panels/power/cc-power-panel.c:1843 msgid "Automatic brightness" msgstr "Automatický jas" -#: panels/power/cc-power-panel.c:1763 +#: panels/power/cc-power-panel.c:1863 msgid "_Keyboard brightness" msgstr "_Jas klávesnice" -#: panels/power/cc-power-panel.c:1773 +#: panels/power/cc-power-panel.c:1873 msgid "_Dim screen when inactive" msgstr "_Ztlumit jas obrazovky při neaktivitě" -#: panels/power/cc-power-panel.c:1798 +#: panels/power/cc-power-panel.c:1898 msgid "_Blank screen" -msgstr "_Vypnout obrazovku" +msgstr "_Vypnout obrazovku po uplynutí" -#: panels/power/cc-power-panel.c:1835 +#: panels/power/cc-power-panel.c:1935 msgid "_Wi-Fi" msgstr "_Wi-Fi" -#: panels/power/cc-power-panel.c:1840 +#: panels/power/cc-power-panel.c:1940 msgid "Turn off Wi-Fi to save power." msgstr "Vypněte Wi-Fi, když chcete šetřit energii." -#: panels/power/cc-power-panel.c:1865 +#: panels/power/cc-power-panel.c:1965 msgid "_Mobile broadband" msgstr "_Mobilní připojení" -#: panels/power/cc-power-panel.c:1870 +#: panels/power/cc-power-panel.c:1970 msgid "Turn off mobile broadband (3G, 4G, LTE, etc.) to save power." msgstr "" "Vypnout mobilní širokopásmová zařízení (3G, 4G, LTE atd.), aby se šetřila " "energie." -#: panels/power/cc-power-panel.c:1923 +#: panels/power/cc-power-panel.c:2029 msgid "_Bluetooth" msgstr "_Bluetooth" -#: panels/power/cc-power-panel.c:1928 +#: panels/power/cc-power-panel.c:2034 msgid "Turn off Bluetooth to save power." msgstr "Vypněte Bluetooth, když chcete šetřit energii." -#: panels/power/cc-power-panel.c:1987 +#: panels/power/cc-power-panel.c:2093 msgid "When on battery power" msgstr "Při napájení z baterie" -#: panels/power/cc-power-panel.c:1989 +#: panels/power/cc-power-panel.c:2095 msgid "When plugged in" msgstr "Při napájení ze sítě" -#: panels/power/cc-power-panel.c:2084 +#: panels/power/cc-power-panel.c:2190 msgid "Suspend" msgstr "Uspat do paměti" -#: panels/power/cc-power-panel.c:2085 +#: panels/power/cc-power-panel.c:2191 msgid "Power Off" msgstr "Vypnout" -#: panels/power/cc-power-panel.c:2086 +#: panels/power/cc-power-panel.c:2192 msgid "Hibernate" msgstr "Uspat na disk" -#: panels/power/cc-power-panel.c:2087 +#: panels/power/cc-power-panel.c:2193 msgid "Nothing" msgstr "Nic nedělat" #. Frame header -#: panels/power/cc-power-panel.c:2201 +#: panels/power/cc-power-panel.c:2307 msgid "Suspend & Power Button" msgstr "Uspávání a vypínací tlačítko" -#: panels/power/cc-power-panel.c:2240 +#: panels/power/cc-power-panel.c:2346 msgid "_Automatic suspend" msgstr "_Automaticky uspat" -#: panels/power/cc-power-panel.c:2241 +#: panels/power/cc-power-panel.c:2347 msgid "Automatic suspend" msgstr "Automaticky uspat" -#: panels/power/cc-power-panel.c:2308 +#: panels/power/cc-power-panel.c:2414 msgid "_When the Power Button is pressed" msgstr "_Když je zmáčknuto vypínací tlačítko" -#: panels/power/cc-power-panel.c:2427 shell/cc-window.c:219 +#: panels/power/cc-power-panel.c:2533 panels/thunderbolt/cc-bolt-panel.ui:466 +#: panels/thunderbolt/cc-bolt-panel.ui:525 shell/cc-window.c:233 #: shell/panel-list.ui:45 msgid "Devices" msgstr "Zařízení" @@ -4273,18 +4331,18 @@ msgid "Authentication Required" msgstr "Požadováno ověření totožnosti" #. Translators: %s is the printer name -#: panels/printers/cc-printers-panel.c:791 +#: panels/printers/cc-printers-panel.c:809 #, c-format msgid "Printer “%s” has been deleted" msgstr "Tiskárna „%s“ byla odebrána" #. Translators: Addition of the new printer failed. -#: panels/printers/cc-printers-panel.c:1036 +#: panels/printers/cc-printers-panel.c:1054 msgid "Failed to add new printer." msgstr "Selhalo přidání nové tiskárny." #. Translators: The XML file containing user interface can not be loaded -#: panels/printers/cc-printers-panel.c:1371 +#: panels/printers/cc-printers-panel.c:1391 #, c-format msgid "Could not load ui: %s" msgstr "Nelze načíst uživatelské rozhraní: %s" @@ -4397,21 +4455,21 @@ msgid "Test Page" msgstr "Testovací stránka" #. Translators: This is the title of the dialog. %s is the printer name. -#: panels/printers/pp-details-dialog.c:135 -#: panels/printers/pp-details-dialog.c:435 +#: panels/printers/pp-details-dialog.c:134 +#: panels/printers/pp-details-dialog.c:434 #, c-format msgid "%s Details" msgstr "Podrobnosti o tiskárně %s" -#: panels/printers/pp-details-dialog.c:184 +#: panels/printers/pp-details-dialog.c:183 msgid "No suitable driver found" msgstr "Nenalezen vyhovující ovladač" -#: panels/printers/pp-details-dialog.c:328 +#: panels/printers/pp-details-dialog.c:327 msgid "Select PPD File" msgstr "Vyberte soubor PPD" -#: panels/printers/pp-details-dialog.c:337 +#: panels/printers/pp-details-dialog.c:336 msgid "" "PostScript Printer Description files (*.ppd, *.PPD, *.ppd.gz, *.PPD.gz, *." "PPD.GZ)" @@ -4424,7 +4482,7 @@ msgid "Select Printer Driver" msgstr "Vyberte ovladač tiskárny" #: panels/printers/ppd-selection-dialog.ui:40 -#: panels/user-accounts/um-photo-dialog.c:104 +#: panels/user-accounts/um-photo-dialog.c:105 msgid "Select" msgstr "Vybrat" @@ -4481,55 +4539,55 @@ msgid "Reverse portrait" msgstr "Obráceně na výšku" #. Translators: Job's state (job is waiting to be printed) -#: panels/printers/pp-jobs-dialog.c:243 +#: panels/printers/pp-jobs-dialog.c:234 msgctxt "print job" msgid "Pending" msgstr "Čeká" #. Translators: Job's state (job is held for printing) -#: panels/printers/pp-jobs-dialog.c:249 +#: panels/printers/pp-jobs-dialog.c:240 msgctxt "print job" msgid "Paused" msgstr "Pozastaveno" #. Translators: Job's state (job needs authentication to proceed further) -#: panels/printers/pp-jobs-dialog.c:254 +#: panels/printers/pp-jobs-dialog.c:245 msgctxt "print job" msgid "Authentication required" msgstr "Požadováno ověření" #. Translators: Job's state (job is currently printing) -#: panels/printers/pp-jobs-dialog.c:259 +#: panels/printers/pp-jobs-dialog.c:250 msgctxt "print job" msgid "Processing" msgstr "Zpracovává se" #. Translators: Job's state (job has been stopped) -#: panels/printers/pp-jobs-dialog.c:263 +#: panels/printers/pp-jobs-dialog.c:254 msgctxt "print job" msgid "Stopped" msgstr "Zastaveno" #. Translators: Job's state (job has been canceled) -#: panels/printers/pp-jobs-dialog.c:267 +#: panels/printers/pp-jobs-dialog.c:258 msgctxt "print job" msgid "Canceled" msgstr "Zrušeno" #. Translators: Job's state (job has aborted due to error) -#: panels/printers/pp-jobs-dialog.c:271 +#: panels/printers/pp-jobs-dialog.c:262 msgctxt "print job" msgid "Aborted" msgstr "Přerušeno" #. Translators: Job's state (job has completed successfully) -#: panels/printers/pp-jobs-dialog.c:275 +#: panels/printers/pp-jobs-dialog.c:266 msgctxt "print job" msgid "Completed" msgstr "Dokončeno" #. Translators: This label shows how many jobs of this printer needs to be authenticated to be printed. -#: panels/printers/pp-jobs-dialog.c:399 +#: panels/printers/pp-jobs-dialog.c:390 #, c-format msgid "%u Job Requires Authentication" msgid_plural "%u Jobs Require Authentication" @@ -4538,14 +4596,14 @@ msgstr[1] "%u úlohy vyžadují ověření" msgstr[2] "%u úloh vyžaduje ověření" #. Translators: This is the printer name for which we are showing the active jobs -#: panels/printers/pp-jobs-dialog.c:617 +#: panels/printers/pp-jobs-dialog.c:620 #, c-format msgctxt "Printer jobs dialog title" msgid "%s — Active Jobs" msgstr "%s – aktivní úlohy" #. Translators: The printer needs authentication info to print. -#: panels/printers/pp-jobs-dialog.c:622 +#: panels/printers/pp-jobs-dialog.c:625 #, c-format msgid "Enter credentials to print from %s." msgstr "Zadejte pověření pro tisk z tiskárny %s." @@ -4913,25 +4971,25 @@ msgstr "" "Bohužel to vypadá, že systémová\n" "služba tisku není dostupná." -#: panels/privacy/cc-privacy-panel.c:387 panels/privacy/privacy.ui:280 +#: panels/privacy/cc-privacy-panel.c:388 panels/privacy/privacy.ui:280 msgid "Screen Lock" msgstr "Zamykání obrazovky" -#: panels/privacy/cc-privacy-panel.c:438 +#: panels/privacy/cc-privacy-panel.c:439 msgid "In use" msgstr "Používá se" -#: panels/privacy/cc-privacy-panel.c:443 +#: panels/privacy/cc-privacy-panel.c:444 msgctxt "Location services status" msgid "On" msgstr "Zapnuto" -#: panels/privacy/cc-privacy-panel.c:444 +#: panels/privacy/cc-privacy-panel.c:445 msgctxt "Location services status" msgid "Off" msgstr "Vypnuto" -#: panels/privacy/cc-privacy-panel.c:823 panels/privacy/privacy.ui:745 +#: panels/privacy/cc-privacy-panel.c:825 panels/privacy/privacy.ui:745 msgid "Location Services" msgstr "Služby určování polohy" @@ -5191,11 +5249,11 @@ msgctxt "Input Source" msgid "Other" msgstr "Další" -#: panels/region/cc-region-panel.c:881 +#: panels/region/cc-region-panel.c:882 msgid "No input source selected" msgstr "Není vybrán žádný vstupní zdroj" -#: panels/region/cc-region-panel.c:1773 +#: panels/region/cc-region-panel.c:1774 msgid "Login _Screen" msgstr "Při_hlašovací obrazovka" @@ -5801,34 +5859,204 @@ msgstr "Subwoofer" msgid "Custom" msgstr "Vlastní" +#: panels/thunderbolt/cc-bolt-device-dialog.c:86 +#: panels/thunderbolt/cc-bolt-device-entry.c:119 +msgctxt "Thunderbolt Device Status" +msgid "Disconnected" +msgstr "Odpojeno" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:89 +#: panels/thunderbolt/cc-bolt-device-entry.c:122 +msgctxt "Thunderbolt Device Status" +msgid "Connecting" +msgstr "Připojuje se" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:92 +#: panels/thunderbolt/cc-bolt-device-entry.c:126 +#: panels/thunderbolt/cc-bolt-device-entry.c:138 +msgctxt "Thunderbolt Device Status" +msgid "Connected" +msgstr "Připojeno" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:95 +msgctxt "Thunderbolt Device Status" +msgid "Authorization Error" +msgstr "Chyba ověřování" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:98 +#: panels/thunderbolt/cc-bolt-device-entry.c:132 +msgctxt "Thunderbolt Device Status" +msgid "Authorizing" +msgstr "Ověřuje se" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:105 +msgctxt "Thunderbolt Device Status" +msgid "Reduced Functionality" +msgstr "Omezená funkcionalita" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:107 +msgctxt "Thunderbolt Device Status" +msgid "Connected & Authorized" +msgstr "Připojeno a ověřeno" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:113 +#: panels/thunderbolt/cc-bolt-device-entry.c:146 +msgctxt "Thunderbolt Device Status" +msgid "Unknown" +msgstr "Neznámý" + +#. Translators: The time point the device was authorized. +#: panels/thunderbolt/cc-bolt-device-dialog.c:169 +msgid "Authorized at:" +msgstr "Ověřeno:" + +#. Translators: The time point the device was connected. +#: panels/thunderbolt/cc-bolt-device-dialog.c:175 +msgid "Connected at:" +msgstr "Připojeno:" + +#. Translators: The time point the device was enrolled, +#. * i.e. authorized and stored in the device database. +#: panels/thunderbolt/cc-bolt-device-dialog.c:182 +msgid "Enrolled at:" +msgstr "Registrováno:" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:250 +msgid "Failed to authorize device: " +msgstr "Selhalo ověření zařízení: " + +#: panels/thunderbolt/cc-bolt-device-dialog.c:327 +msgid "Failed to forget device: " +msgstr "Zapomenutí zařízení selhalo: " + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:109 +msgid "Name:" +msgstr "Název:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:141 +msgid "Status:" +msgstr "Stav:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:174 +msgid "UUID:" +msgstr "UUID:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:280 +msgid "Authorize and Connect" +msgstr "Ověřit a připojit" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:303 +msgid "Forget Device" +msgstr "Zapomenout zařízení" + +#: panels/thunderbolt/cc-bolt-device-entry.c:129 +msgctxt "Thunderbolt Device Status" +msgid "Error" +msgstr "Chyba" + +#: panels/thunderbolt/cc-bolt-device-entry.c:140 +msgctxt "Thunderbolt Device Status" +msgid "Authorized" +msgstr "Ověřeno" + +#: panels/thunderbolt/cc-bolt-panel.c:175 +msgid "" +"The Thunderbolt subsystem (boltd) is not installed or not set up properly." +msgstr "" +"Subsystém Thunderbolt (boltd) není nainstalovaný, nebo není správně " +"nastavený." + +#: panels/thunderbolt/cc-bolt-panel.c:460 +msgid "" +"Thunderbolt could not be detected.\n" +"Either the system lacks Thunderbolt support, it has been disabled in the " +"BIOS or is set to an unsupported security level in the BIOS." +msgstr "" +"Thunderbolt se nezdařilo nalézt.\n" +"Buď systém postrádá podporu pro Thunderbolt, nebo je vypnutá přes BIOS, nebo " +"je v něm nastavená nepodporovaná úroveň zabezpečení." + +#: panels/thunderbolt/cc-bolt-panel.c:504 +msgid "Thunderbolt support has been disabled in the BIOS." +msgstr "Podpora pro Thunderbolt je vypnutá přes BIOS." + +#: panels/thunderbolt/cc-bolt-panel.c:613 +#, c-format +msgid "Error switching direct mode: %s" +msgstr "Chyba při přepínání přímého režimu: %s" + +#: panels/thunderbolt/cc-bolt-panel.ui:143 +msgid "No Thunderbolt support" +msgstr "Bez podpory pro Thunderbolt" + +#: panels/thunderbolt/cc-bolt-panel.ui:246 +msgid "Direct Access" +msgstr "Přímý přístup" + +#: panels/thunderbolt/cc-bolt-panel.ui:269 +msgid "Allow direct access to devices such as docks and external GPUs." +msgstr "" +"Umožňuje přímý přístup k zařízením, jako jsou dokovací stanice nebo externí " +"GPU." + +#: panels/thunderbolt/cc-bolt-panel.ui:289 +msgid "Only USB and Display Port devices can attach." +msgstr "Připojeny mohou být jen zařízení USB a Display Port." + +#: panels/thunderbolt/cc-bolt-panel.ui:397 +msgid "Pending Devices" +msgstr "Čekající zařízení" + +#: panels/thunderbolt/cc-bolt-panel.ui:535 +msgid "No devices attached" +msgstr "Nejsou připojena žádná zařízení" + +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:3 +msgid "Thunderbolt" +msgstr "Thunderbolt" + +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:4 +msgid "Manage Thunderbolt devices" +msgstr "Spravujte zařízení Thunderbolt" + +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:7 +msgid "thunderbolt" +msgstr "thunderbolt" + +#. Translators: those are keywords for the thunderbolt control-center panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:19 +msgid "Thunderbolt;" +msgstr "Thunderbolt;" + #. translators: the labels will read: #. * Cursor Size: Default -#: panels/universal-access/cc-ua-panel.c:353 +#: panels/universal-access/cc-ua-panel.c:354 msgctxt "cursor size" msgid "Default" msgstr "Výchozí" -#: panels/universal-access/cc-ua-panel.c:356 +#: panels/universal-access/cc-ua-panel.c:357 msgctxt "cursor size" msgid "Medium" msgstr "Střední" -#: panels/universal-access/cc-ua-panel.c:359 +#: panels/universal-access/cc-ua-panel.c:360 msgctxt "cursor size" msgid "Large" msgstr "Velký" -#: panels/universal-access/cc-ua-panel.c:362 +#: panels/universal-access/cc-ua-panel.c:363 msgctxt "cursor size" msgid "Larger" msgstr "Větší" -#: panels/universal-access/cc-ua-panel.c:365 +#: panels/universal-access/cc-ua-panel.c:366 msgctxt "cursor size" msgid "Largest" msgstr "Největší" -#: panels/universal-access/cc-ua-panel.c:369 +#: panels/universal-access/cc-ua-panel.c:370 #, c-format msgid "%d pixel" msgid_plural "%d pixels" @@ -5878,7 +6106,7 @@ msgid "C_ursor Size" msgstr "Velikost k_urzoru" #: panels/universal-access/uap.ui:316 -#: panels/universal-access/zoom-options.ui:98 +#: panels/universal-access/zoom-options.ui:99 msgid "_Zoom" msgstr "_Přiblížení" @@ -6169,27 +6397,27 @@ msgctxt "dwell click threshold" msgid "Large" msgstr "Vysoký" -#: panels/universal-access/zoom-options.c:333 +#: panels/universal-access/zoom-options.c:338 msgctxt "Distance" msgid "Short" msgstr "Krátká" -#: panels/universal-access/zoom-options.c:334 +#: panels/universal-access/zoom-options.c:339 msgctxt "Distance" msgid "¼ Screen" msgstr "¼ obrazovky" -#: panels/universal-access/zoom-options.c:335 +#: panels/universal-access/zoom-options.c:340 msgctxt "Distance" msgid "½ Screen" msgstr "½ obrazovky" -#: panels/universal-access/zoom-options.c:336 +#: panels/universal-access/zoom-options.c:341 msgctxt "Distance" msgid "¾ Screen" msgstr "¾ obrazovky" -#: panels/universal-access/zoom-options.c:337 +#: panels/universal-access/zoom-options.c:342 msgctxt "Distance" msgid "Long" msgstr "Dlouhá" @@ -6214,134 +6442,134 @@ msgstr "Levá polovina" msgid "Right Half" msgstr "Pravá polovina" -#: panels/universal-access/zoom-options.ui:77 +#: panels/universal-access/zoom-options.ui:78 msgid "Zoom Options" msgstr "Volby přiblížení" -#: panels/universal-access/zoom-options.ui:186 +#: panels/universal-access/zoom-options.ui:188 msgid "_Magnification:" msgstr "Zvětšení _lupou:" -#: panels/universal-access/zoom-options.ui:250 +#: panels/universal-access/zoom-options.ui:252 msgid "_Follow mouse cursor" msgstr "_Následovat ukazatel myši" -#: panels/universal-access/zoom-options.ui:270 +#: panels/universal-access/zoom-options.ui:272 msgid "_Screen part:" msgstr "Část o_brazovky:" -#: panels/universal-access/zoom-options.ui:332 +#: panels/universal-access/zoom-options.ui:334 msgid "Magnifier _extends outside of screen" msgstr "Lupa se rozšiřuj_e mimo obrazovku" -#: panels/universal-access/zoom-options.ui:351 +#: panels/universal-access/zoom-options.ui:353 msgid "_Keep magnifier cursor centered" msgstr "Udržovat u_kazatel lupy na středu" -#: panels/universal-access/zoom-options.ui:370 +#: panels/universal-access/zoom-options.ui:372 msgid "Magnifier cursor _pushes contents around" msgstr "Ukazatel lu_py odsouvá okolní obsah" -#: panels/universal-access/zoom-options.ui:389 +#: panels/universal-access/zoom-options.ui:391 msgid "Magnifier cursor moves with _contents" msgstr "Ukazatel lupy se přesouvá s o_bsahem" -#: panels/universal-access/zoom-options.ui:423 +#: panels/universal-access/zoom-options.ui:425 msgid "Magnifier Position:" msgstr "Poloha lupy:" -#: panels/universal-access/zoom-options.ui:444 +#: panels/universal-access/zoom-options.ui:446 msgid "Magnifier" msgstr "Lupa" -#: panels/universal-access/zoom-options.ui:490 +#: panels/universal-access/zoom-options.ui:493 msgid "_Thickness:" msgstr "_Tloušťka:" -#: panels/universal-access/zoom-options.ui:516 +#: panels/universal-access/zoom-options.ui:519 msgctxt "universal access, thickness" msgid "Thin" msgstr "Tenký" -#: panels/universal-access/zoom-options.ui:548 +#: panels/universal-access/zoom-options.ui:551 msgctxt "universal access, thickness" msgid "Thick" msgstr "Tlustý" -#: panels/universal-access/zoom-options.ui:574 +#: panels/universal-access/zoom-options.ui:577 msgid "_Length:" msgstr "Dé_lka:" #. The color of the accessibility crosshair -#: panels/universal-access/zoom-options.ui:626 +#: panels/universal-access/zoom-options.ui:629 msgid "Co_lor:" msgstr "_Barva:" -#: panels/universal-access/zoom-options.ui:690 +#: panels/universal-access/zoom-options.ui:693 msgid "_Crosshairs:" msgstr "Zaměřovací _kříž:" -#: panels/universal-access/zoom-options.ui:741 +#: panels/universal-access/zoom-options.ui:744 msgid "_Overlaps mouse cursor" msgstr "Překrývat ukazat_el myši" -#: panels/universal-access/zoom-options.ui:779 +#: panels/universal-access/zoom-options.ui:782 msgid "Crosshairs" msgstr "Zaměřovací kříž" -#: panels/universal-access/zoom-options.ui:827 +#: panels/universal-access/zoom-options.ui:831 msgid "_White on black:" msgstr "_Bílá na černém:" -#: panels/universal-access/zoom-options.ui:850 +#: panels/universal-access/zoom-options.ui:854 msgid "_Brightness:" msgstr "_Jas:" -#: panels/universal-access/zoom-options.ui:874 +#: panels/universal-access/zoom-options.ui:878 msgid "_Contrast:" msgstr "_Kontrast:" #. The contrast scale goes from Color to None (grayscale) -#: panels/universal-access/zoom-options.ui:897 +#: panels/universal-access/zoom-options.ui:901 msgctxt "universal access, contrast" msgid "Co_lor" msgstr "_Barva" -#: panels/universal-access/zoom-options.ui:925 +#: panels/universal-access/zoom-options.ui:929 msgctxt "universal access, color" msgid "None" msgstr "Žádná" -#: panels/universal-access/zoom-options.ui:957 +#: panels/universal-access/zoom-options.ui:961 msgctxt "universal access, color" msgid "Full" msgstr "Plná" -#: panels/universal-access/zoom-options.ui:1023 +#: panels/universal-access/zoom-options.ui:1027 msgctxt "universal access, brightness" msgid "Low" msgstr "Nízký" -#: panels/universal-access/zoom-options.ui:1056 +#: panels/universal-access/zoom-options.ui:1060 msgctxt "universal access, brightness" msgid "High" msgstr "Vysoký" -#: panels/universal-access/zoom-options.ui:1087 +#: panels/universal-access/zoom-options.ui:1091 msgctxt "universal access, contrast" msgid "Low" msgstr "Nízký" -#: panels/universal-access/zoom-options.ui:1120 +#: panels/universal-access/zoom-options.ui:1124 msgctxt "universal access, contrast" msgid "High" msgstr "Vysoký" -#: panels/universal-access/zoom-options.ui:1156 +#: panels/universal-access/zoom-options.ui:1160 msgid "Color Effects:" msgstr "Ovlivnění barev:" -#: panels/universal-access/zoom-options.ui:1181 +#: panels/universal-access/zoom-options.ui:1185 msgid "Color Effects" msgstr "Ovlivnění barev" @@ -6934,7 +7162,7 @@ msgstr "%s — %s" #. Translators: This is a time format string in the style of "22:58". #. It indicates a login time which follows a date. #: panels/user-accounts/um-history-dialog.c:177 -#: panels/user-accounts/um-user-panel.c:767 +#: panels/user-accounts/um-user-panel.c:766 msgctxt "login date-time" msgid "%k:%M" msgstr "%k:%M" @@ -6942,7 +7170,7 @@ msgstr "%k:%M" #. Translators: This indicates a login date-time. #. The first %s is a date, and the second %s a time. #: panels/user-accounts/um-history-dialog.c:180 -#: panels/user-accounts/um-user-panel.c:771 +#: panels/user-accounts/um-user-panel.c:770 #, c-format msgctxt "login date-time" msgid "%s, %s" @@ -6979,7 +7207,7 @@ msgstr "Heslo nelze změnit" msgid "The passwords do not match." msgstr "Hesla si neodpovídají." -#: panels/user-accounts/um-photo-dialog.c:226 +#: panels/user-accounts/um-photo-dialog.c:227 msgid "Browse for more pictures" msgstr "Procházet další obrázky" @@ -7007,30 +7235,30 @@ msgstr "Neplatné heslo, zkuste to, prosím, znovu" msgid "Couldn’t connect to the %s domain: %s" msgstr "Nelze se připojit k doméně „%s“: %s" -#: panels/user-accounts/um-user-panel.c:201 +#: panels/user-accounts/um-user-panel.c:200 msgid "Your account" msgstr "Váš účet" -#: panels/user-accounts/um-user-panel.c:381 +#: panels/user-accounts/um-user-panel.c:380 msgid "Failed to delete user" msgstr "Selhalo smazání účtu" -#: panels/user-accounts/um-user-panel.c:439 -#: panels/user-accounts/um-user-panel.c:498 -#: panels/user-accounts/um-user-panel.c:550 +#: panels/user-accounts/um-user-panel.c:438 +#: panels/user-accounts/um-user-panel.c:497 +#: panels/user-accounts/um-user-panel.c:549 msgid "Failed to revoke remotely managed user" msgstr "Selhalo zneplatnění vzdáleně spravovaného uživatele" -#: panels/user-accounts/um-user-panel.c:604 +#: panels/user-accounts/um-user-panel.c:603 msgid "You cannot delete your own account." msgstr "Nemůžete smazat svůj vlastní účet." -#: panels/user-accounts/um-user-panel.c:613 +#: panels/user-accounts/um-user-panel.c:612 #, c-format msgid "%s is still logged in" msgstr "Uživatel %s je doposud přihlášen" -#: panels/user-accounts/um-user-panel.c:617 +#: panels/user-accounts/um-user-panel.c:616 msgid "" "Deleting a user while they are logged in can leave the system in an " "inconsistent state." @@ -7038,12 +7266,12 @@ msgstr "" "Smazání účtu, zatímco je dotyčný uživatel přihlášen, může přivést systém do " "nekonzistentního stavu." -#: panels/user-accounts/um-user-panel.c:626 +#: panels/user-accounts/um-user-panel.c:625 #, c-format msgid "Do you want to keep %s’s files?" msgstr "Chcete zachovat soubory uživatele %s?" -#: panels/user-accounts/um-user-panel.c:630 +#: panels/user-accounts/um-user-panel.c:629 msgid "" "It is possible to keep the home directory, mail spool and temporary files " "around when deleting a user account." @@ -7051,47 +7279,47 @@ msgstr "" "Je možné zachovat domovskou složku, poštovní schránku a dočasné soubory, i " "když bude uživatelský účet smazán." -#: panels/user-accounts/um-user-panel.c:633 +#: panels/user-accounts/um-user-panel.c:632 msgid "_Delete Files" msgstr "O_dstranit soubory" -#: panels/user-accounts/um-user-panel.c:634 +#: panels/user-accounts/um-user-panel.c:633 msgid "_Keep Files" msgstr "Zacho_vat soubory" -#: panels/user-accounts/um-user-panel.c:648 +#: panels/user-accounts/um-user-panel.c:647 #, c-format msgid "Are you sure you want to revoke remotely managed %s’s account?" msgstr "Opravdu chcete zneplatnit vzdáleně spravovaný účet uživatele %s?" -#: panels/user-accounts/um-user-panel.c:652 +#: panels/user-accounts/um-user-panel.c:651 msgid "_Delete" msgstr "O_dstranit" -#: panels/user-accounts/um-user-panel.c:702 +#: panels/user-accounts/um-user-panel.c:701 msgctxt "Password mode" msgid "Account disabled" msgstr "Účet zakázán" -#: panels/user-accounts/um-user-panel.c:710 +#: panels/user-accounts/um-user-panel.c:709 msgctxt "Password mode" msgid "To be set at next login" msgstr "Bude nastaveno při příštím přihlášení" -#: panels/user-accounts/um-user-panel.c:713 +#: panels/user-accounts/um-user-panel.c:712 msgctxt "Password mode" msgid "None" msgstr "Žádné" -#: panels/user-accounts/um-user-panel.c:760 +#: panels/user-accounts/um-user-panel.c:759 msgid "Logged in" msgstr "právě přihlášený" -#: panels/user-accounts/um-user-panel.c:1107 +#: panels/user-accounts/um-user-panel.c:1106 msgid "Failed to contact the accounts service" msgstr "Selhalo kontaktování účtovací služby" -#: panels/user-accounts/um-user-panel.c:1109 +#: panels/user-accounts/um-user-panel.c:1108 msgid "Please make sure that the AccountService is installed and enabled." msgstr "" "Zkontrolujte prosím, že je účtovací služba AccountService nainstalovaná a " @@ -7101,7 +7329,7 @@ msgstr "" #. * We split the line in 2 here to "make it look good", as there's #. * no good way to do this in GTK+ for tooltips. See: #. * https://bugzilla.gnome.org/show_bug.cgi?id=657168 -#: panels/user-accounts/um-user-panel.c:1141 +#: panels/user-accounts/um-user-panel.c:1140 msgid "" "To make changes,\n" "click the * icon first" @@ -7109,12 +7337,12 @@ msgstr "" "Abyste mohli provést změny,\n" "klikněte nejprve na ikonu *" -#: panels/user-accounts/um-user-panel.c:1181 +#: panels/user-accounts/um-user-panel.c:1180 msgid "Create a user account" msgstr "Vytvořit uživatelský účet" -#: panels/user-accounts/um-user-panel.c:1192 -#: panels/user-accounts/um-user-panel.c:1371 +#: panels/user-accounts/um-user-panel.c:1191 +#: panels/user-accounts/um-user-panel.c:1370 msgid "" "To create a user account,\n" "click the * icon first" @@ -7122,12 +7350,12 @@ msgstr "" "Pro vytvoření uživatelského účtu\n" "nejprve klikněte na ikonu *" -#: panels/user-accounts/um-user-panel.c:1202 +#: panels/user-accounts/um-user-panel.c:1201 msgid "Delete the selected user account" msgstr "Odstranit vybraný uživatelský účet" -#: panels/user-accounts/um-user-panel.c:1214 -#: panels/user-accounts/um-user-panel.c:1376 +#: panels/user-accounts/um-user-panel.c:1213 +#: panels/user-accounts/um-user-panel.c:1375 msgid "" "To delete the selected user account,\n" "click the * icon first" @@ -7404,35 +7632,35 @@ msgstr "" "Ovládací centrum je hlavní rozhraní GNOME pro nastavení různých vlastností " "vašeho pracovního prostředí." -#: shell/cc-application.c:47 +#: shell/cc-application.c:60 msgid "Display version number" msgstr "Zobrazit číslo verze" -#: shell/cc-application.c:48 +#: shell/cc-application.c:61 msgid "Enable verbose mode" msgstr "Zapnout podrobný režim" -#: shell/cc-application.c:49 +#: shell/cc-application.c:62 msgid "Show the overview" msgstr "Zobrazit přehled" -#: shell/cc-application.c:50 +#: shell/cc-application.c:63 msgid "Search for the string" msgstr "Hledat řetězec" -#: shell/cc-application.c:51 +#: shell/cc-application.c:64 msgid "List possible panel names and exit" msgstr "Vypsat všechny možné názvy panelů a skončit" -#: shell/cc-application.c:52 +#: shell/cc-application.c:65 msgid "Panel to display" msgstr "Panel, který se má zobrazit" -#: shell/cc-application.c:52 +#: shell/cc-application.c:65 msgid "[PANEL] [ARGUMENT…]" msgstr "[PANEL] [ARGUMENT…]" -#: shell/cc-application.c:117 +#: shell/cc-application.c:136 msgid "Available panels:" msgstr "Dostupné panely:" @@ -7484,12 +7712,6 @@ msgctxt "shortcut window" msgid "Cancel search" msgstr "Zrušit vyhledávání" -#. translators: This is the default hotspot name, need to be less than 32-bytes -#: shell/hostname-helper.c:189 -msgctxt "hotspot" -msgid "Hotspot" -msgstr "Přístupový bod" - #: shell/org.gnome.ControlCenter.gschema.xml:5 msgid "The identifier for the last Settings panel to be opened" msgstr "Identifikátor naposledy otevřeného panelu Nastavení" -- cgit v1.2.1 From 7b74bfbbe63b954bd571dfe51ea908f8eb3c923c Mon Sep 17 00:00:00 2001 From: Fabio Tomat Date: Sat, 5 May 2018 14:54:47 +0000 Subject: Update Friulian translation --- po/fur.po | 54 +++++++++++++++++++++++++----------------------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/po/fur.po b/po/fur.po index 138e54354..bff8e60ec 100644 --- a/po/fur.po +++ b/po/fur.po @@ -9,8 +9,8 @@ msgstr "" "Project-Id-Version: gnome-control-center master\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-control-center/" "issues\n" -"POT-Creation-Date: 2018-04-19 13:00+0000\n" -"PO-Revision-Date: 2018-05-04 14:15+0200\n" +"POT-Creation-Date: 2018-05-04 12:16+0000\n" +"PO-Revision-Date: 2018-05-05 16:53+0200\n" "Last-Translator: Fabio Tomat \n" "Language-Team: Friulian \n" "Language: fur\n" @@ -1500,7 +1500,7 @@ msgstr "" #: panels/info/gnome-removable-media-panel.desktop.in.in:3 msgid "Removable Media" -msgstr "Dispositîfs rimovibil" +msgstr "Dispositîfs estraibii" #: panels/info/gnome-removable-media-panel.desktop.in.in:4 msgid "Configure Removable Media settings" @@ -2109,7 +2109,7 @@ msgid "Single click, secondary button" msgstr "Clic singul, boton secondari" #. add proxy to device list -#: panels/network/cc-network-panel.c:581 +#: panels/network/cc-network-panel.c:583 msgid "Network proxy" msgstr "Proxy di rêt" @@ -2117,19 +2117,19 @@ msgstr "Proxy di rêt" #. * window for vpn connections, it is also used to display #. * vpn connections in the device list. #. -#: panels/network/cc-network-panel.c:717 panels/network/net-vpn.c:167 +#: panels/network/cc-network-panel.c:719 panels/network/net-vpn.c:167 #: panels/network/net-vpn.c:296 #, c-format msgid "%s VPN" msgstr "VPN %s" -#: panels/network/cc-network-panel.c:781 panels/network/wifi.ui:282 +#: panels/network/cc-network-panel.c:783 panels/network/wifi.ui:282 msgid "Oops, something has gone wrong. Please contact your software vendor." msgstr "" "Orpo, al semee che alc al sedi lât par stuart. Contate il furnidôr di " "software." -#: panels/network/cc-network-panel.c:787 +#: panels/network/cc-network-panel.c:789 msgid "NetworkManager needs to be running." msgstr "NetworkManager al à di jessi in esecuzion." @@ -4039,8 +4039,6 @@ msgstr[1] "%d oris" #: panels/power/cc-power-panel.c:1208 #, c-format -#| msgid "%i minute" -#| msgid_plural "%i minutes" msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d minût" @@ -4048,7 +4046,6 @@ msgstr[1] "%d minûts" #: panels/power/cc-power-panel.c:1211 #, c-format -#| msgid "30 seconds" msgid "%d second" msgid_plural "%d seconds" msgstr[0] "%d secont" @@ -5446,7 +5443,7 @@ msgid "Preferences" msgstr "Preferencis" #. Label -#: panels/sharing/cc-sharing-networks.c:305 +#: panels/sharing/cc-sharing-networks.c:307 msgid "No networks selected for sharing" msgstr "Nissune rêt selezionade pe condivision" @@ -6945,29 +6942,29 @@ msgstr "Erôr no cognossût" msgid "Should match the web address of your login provider." msgstr "Al varès di corispuindi ae direzion web dal to furnidôr di acès." -#: panels/user-accounts/um-account-dialog.c:229 +#: panels/user-accounts/um-account-dialog.c:228 msgid "Failed to add account" msgstr "Zonte dal account falide" -#: panels/user-accounts/um-account-dialog.c:462 +#: panels/user-accounts/um-account-dialog.c:461 msgid "Passwords do not match." msgstr "Lis password no corispuindin." -#: panels/user-accounts/um-account-dialog.c:717 -#: panels/user-accounts/um-account-dialog.c:763 -#: panels/user-accounts/um-account-dialog.c:784 +#: panels/user-accounts/um-account-dialog.c:716 +#: panels/user-accounts/um-account-dialog.c:762 +#: panels/user-accounts/um-account-dialog.c:783 msgid "Failed to register account" msgstr "Regjistrazion account falide" -#: panels/user-accounts/um-account-dialog.c:907 +#: panels/user-accounts/um-account-dialog.c:906 msgid "No supported way to authenticate with this domain" msgstr "Nissun mût supuartât par autenticâsi cun chest domini" -#: panels/user-accounts/um-account-dialog.c:980 +#: panels/user-accounts/um-account-dialog.c:979 msgid "Failed to join domain" msgstr "Falît a unîsi al domini" -#: panels/user-accounts/um-account-dialog.c:1041 +#: panels/user-accounts/um-account-dialog.c:1040 msgid "" "That login name didn’t work.\n" "Please try again." @@ -6975,7 +6972,7 @@ msgstr "" "Non di acès no valit.\n" "Prove une altre volte." -#: panels/user-accounts/um-account-dialog.c:1048 +#: panels/user-accounts/um-account-dialog.c:1047 msgid "" "That login password didn’t work.\n" "Please try again." @@ -6983,11 +6980,11 @@ msgstr "" "Password no valide.\n" "Prove une altre volte." -#: panels/user-accounts/um-account-dialog.c:1056 +#: panels/user-accounts/um-account-dialog.c:1055 msgid "Failed to log into domain" msgstr "Acès al domini falît" -#: panels/user-accounts/um-account-dialog.c:1114 +#: panels/user-accounts/um-account-dialog.c:1113 msgid "Unable to find the domain. Maybe you misspelled it?" msgstr "Impussibil cjatâ il domini. Isal stât scrit mâl?" @@ -7171,26 +7168,25 @@ msgstr "Lis password no corispuindin." msgid "Browse for more pictures" msgstr "Esplore altris imagjins" -#: panels/user-accounts/um-realm-manager.c:350 +#: panels/user-accounts/um-realm-manager.c:310 msgid "Cannot automatically join this type of domain" msgstr "Impussibil unîsi in automatic a chest gjenar di domini" -#: panels/user-accounts/um-realm-manager.c:413 -#, c-format +#: panels/user-accounts/um-realm-manager.c:313 msgid "No such domain or realm found" msgstr "Nissun domini o ream cjatâts" -#: panels/user-accounts/um-realm-manager.c:815 -#: panels/user-accounts/um-realm-manager.c:829 +#: panels/user-accounts/um-realm-manager.c:735 +#: panels/user-accounts/um-realm-manager.c:749 #, c-format msgid "Cannot log in as %s at the %s domain" msgstr "Impussibil acedi come %s al domini %s" -#: panels/user-accounts/um-realm-manager.c:821 +#: panels/user-accounts/um-realm-manager.c:741 msgid "Invalid password, please try again" msgstr "Password no valide, prove di gnûf" -#: panels/user-accounts/um-realm-manager.c:834 +#: panels/user-accounts/um-realm-manager.c:754 #, c-format msgid "Couldn’t connect to the %s domain: %s" msgstr "Impussibil tacâsi al domini %s: %s" -- cgit v1.2.1 From 283bc923353fcf7eb738a4e61edb72c287be1f73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Kelemen?= Date: Sat, 5 May 2018 15:38:10 +0000 Subject: Update Hungarian translation --- po/hu.po | 861 +++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 539 insertions(+), 322 deletions(-) diff --git a/po/hu.po b/po/hu.po index 9fddf1c2e..3c4174b09 100644 --- a/po/hu.po +++ b/po/hu.po @@ -8,7 +8,7 @@ # Andras Timar , 2001, 2002, 2003. # Gabor Sari , 2003. # Laszlo Dvornik , 2004. -# Gabor Kelemen , 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2015, 2016, 2017. +# Gabor Kelemen , 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2015, 2016, 2017, 2018. # Mate ORY , 2006. # Richard Somloi , 2011, 2012. # Peter Trombitas , 2012. @@ -16,18 +16,18 @@ msgid "" msgstr "" "Project-Id-Version: gnome-control-center master\n" -"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-control-center/" -"issues\n" -"POT-Creation-Date: 2018-02-23 19:10+0000\n" -"PO-Revision-Date: 2018-02-25 20:45+0100\n" -"Last-Translator: Balázs Úr \n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-control-center/issu" +"es\n" +"POT-Creation-Date: 2018-05-03 08:07+0000\n" +"PO-Revision-Date: 2018-05-05 17:37+0100\n" +"Last-Translator: Gabor Kelemen \n" "Language-Team: Hungarian \n" "Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Lokalize 1.2\n" +"X-Generator: Lokalize 2.0\n" #: panels/background/background.ui:49 msgid "_Background" @@ -111,16 +111,16 @@ msgid "You can add images to your %s folder and they will show up here" msgstr "A %s mappába felvett képek itt megjelennek" #: panels/background/cc-background-chooser-dialog.c:560 -#: panels/color/cc-color-panel.c:225 panels/color/cc-color-panel.c:963 +#: panels/color/cc-color-panel.c:224 panels/color/cc-color-panel.c:962 #: panels/color/color-calibrate.ui:25 panels/color/color.ui:657 -#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2594 +#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2610 #: panels/network/connection-editor/connection-editor.ui:15 #: panels/network/connection-editor/vpn-helpers.c:181 #: panels/network/connection-editor/vpn-helpers.c:310 #: panels/network/net-device-wifi.c:1411 panels/network/net-device-wifi.c:1491 #: panels/network/net-device-wifi.c:1736 panels/network/network-wifi.ui:24 #: panels/printers/new-printer-dialog.ui:45 -#: panels/printers/pp-details-dialog.c:331 +#: panels/printers/pp-details-dialog.c:330 #: panels/privacy/cc-privacy-panel.c:1053 panels/region/format-chooser.ui:25 #: panels/region/input-chooser.ui:13 #: panels/search/cc-search-locations-dialog.c:642 @@ -129,10 +129,10 @@ msgstr "A %s mappába felvett képek itt megjelennek" #: panels/user-accounts/data/join-dialog.ui:20 #: panels/user-accounts/data/password-dialog.ui:21 #: panels/user-accounts/um-fingerprint-dialog.c:261 -#: panels/user-accounts/um-photo-dialog.c:102 -#: panels/user-accounts/um-photo-dialog.c:229 -#: panels/user-accounts/um-user-panel.c:635 -#: panels/user-accounts/um-user-panel.c:653 +#: panels/user-accounts/um-photo-dialog.c:103 +#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-user-panel.c:634 +#: panels/user-accounts/um-user-panel.c:652 msgid "_Cancel" msgstr "Mé_gse" @@ -177,39 +177,39 @@ msgstr "preferences-desktop-wallpaper" msgid "Wallpaper;Screen;Desktop;" msgstr "Háttérkép;Képernyő;Asztal;" -#: panels/bluetooth/cc-bluetooth-panel.c:265 +#: panels/bluetooth/cc-bluetooth-panel.c:266 msgid "Turn Off Airplane Mode" msgstr "Repülőgép üzemmód kikapcsolása" -#: panels/bluetooth/cc-bluetooth-panel.c:330 +#: panels/bluetooth/cc-bluetooth-panel.c:329 msgid "No Bluetooth Found" msgstr "Nem található Bluetooth" -#: panels/bluetooth/cc-bluetooth-panel.c:330 +#: panels/bluetooth/cc-bluetooth-panel.c:329 msgid "Plug in a dongle to use Bluetooth." msgstr "Csatlakoztasson egy kulcsot a Bluetooth használatához." -#: panels/bluetooth/cc-bluetooth-panel.c:331 +#: panels/bluetooth/cc-bluetooth-panel.c:330 msgid "Bluetooth Turned Off" msgstr "Bluetooth kikapcsolva" -#: panels/bluetooth/cc-bluetooth-panel.c:331 +#: panels/bluetooth/cc-bluetooth-panel.c:330 msgid "Turn on to connect devices and receive file transfers." msgstr "Kapcsolja be eszközök csatlakoztatásához és fájlátvitelek fogadásához." -#: panels/bluetooth/cc-bluetooth-panel.c:332 +#: panels/bluetooth/cc-bluetooth-panel.c:331 msgid "Airplane Mode is on" msgstr "Repülőgép üzemmód be" -#: panels/bluetooth/cc-bluetooth-panel.c:332 +#: panels/bluetooth/cc-bluetooth-panel.c:331 msgid "Bluetooth is disabled when airplane mode is on." msgstr "A Bluetooth ki van kapcsolva repülőgép üzemmódban." -#: panels/bluetooth/cc-bluetooth-panel.c:333 +#: panels/bluetooth/cc-bluetooth-panel.c:332 msgid "Hardware Airplane Mode is on" msgstr "Hardver repülőgép üzemmódja be" -#: panels/bluetooth/cc-bluetooth-panel.c:333 +#: panels/bluetooth/cc-bluetooth-panel.c:332 msgid "Turn off the Airplane mode switch to enable Bluetooth." msgstr "" "Kapcsolja ki a Repülőgép üzemmód kapcsolót a Bluetooth bekapcsolásához." @@ -235,7 +235,7 @@ msgid "share;sharing;bluetooth;obex;" msgstr "share;megosztás;bluetooth;obex;" #. TRANSLATORS: The user has to attach the sensor to the screen -#: panels/color/cc-color-calibrate.c:361 +#: panels/color/cc-color-calibrate.c:363 msgid "Place your calibration device over the square and press “Start”" msgstr "" "Helyezze a kalibrációs eszköz a négyzetre, és nyomja meg a „Kezdés” gombot" @@ -243,7 +243,7 @@ msgstr "" #. TRANSLATORS: Some calibration devices need the user to move a #. * dial or switch manually. We also show a picture showing them #. * what to do... -#: panels/color/cc-color-calibrate.c:367 +#: panels/color/cc-color-calibrate.c:369 msgid "" "Move your calibration device to the calibrate position and press “Continue”" msgstr "" @@ -253,7 +253,7 @@ msgstr "" #. TRANSLATORS: Some calibration devices need the user to move a #. * dial or switch manually. We also show a picture showing them #. * what to do... -#: panels/color/cc-color-calibrate.c:373 +#: panels/color/cc-color-calibrate.c:375 msgid "" "Move your calibration device to the surface position and press “Continue”" msgstr "" @@ -262,54 +262,54 @@ msgstr "" #. TRANSLATORS: on some hardware e.g. Lenovo W700 the sensor #. * is built into the palmrest and we need to fullscreen the #. * sample widget and shut the lid. -#: panels/color/cc-color-calibrate.c:379 +#: panels/color/cc-color-calibrate.c:381 msgid "Shut the laptop lid" msgstr "Zárja le a laptop fedelét" #. TRANSLATORS: We suck, the calibation failed and we have no #. * good idea why or any suggestions -#: panels/color/cc-color-calibrate.c:410 +#: panels/color/cc-color-calibrate.c:412 msgid "An internal error occurred that could not be recovered." msgstr "Belső hiba történt, a folytatás nem lehetséges." #. TRANSLATORS: Some required-at-runtime tools were not #. * installed, which should only affect insane distros -#: panels/color/cc-color-calibrate.c:415 +#: panels/color/cc-color-calibrate.c:417 msgid "Tools required for calibration are not installed." msgstr "A kalibráláshoz szükséges eszközök nincsenek telepítve." #. TRANSLATORS: The profile failed for some reason -#: panels/color/cc-color-calibrate.c:421 +#: panels/color/cc-color-calibrate.c:423 msgid "The profile could not be generated." msgstr "A profil nem állítható elő." #. TRANSLATORS: The user specified a whitepoint that was #. * unobtainable with the hardware they've got -- see #. * https://en.wikipedia.org/wiki/White_point for details -#: panels/color/cc-color-calibrate.c:427 +#: panels/color/cc-color-calibrate.c:429 msgid "The target whitepoint was not obtainable." msgstr "A cél fehér pont nem szerezhető be." #. TRANSLATORS: the display calibration process is finished -#: panels/color/cc-color-calibrate.c:467 +#: panels/color/cc-color-calibrate.c:469 msgid "Complete!" msgstr "Kész!" #. TRANSLATORS: the display calibration failed, and we also show #. * the translated (or untranslated) error string after this -#: panels/color/cc-color-calibrate.c:475 +#: panels/color/cc-color-calibrate.c:477 msgid "Calibration failed!" msgstr "A kalibrálás sikertelen!" #. TRANSLATORS: The user can now remove the sensor from the screen -#: panels/color/cc-color-calibrate.c:482 +#: panels/color/cc-color-calibrate.c:484 msgid "You can remove the calibration device." msgstr "Eltávolíthatja a kalibrálóeszközt." #. TRANSLATORS: The user has to be careful not to knock the #. * display off the screen (although we do cope if this is #. * detected early enough) -#: panels/color/cc-color-calibrate.c:553 +#: panels/color/cc-color-calibrate.c:556 msgid "Do not disturb the calibration device while in progress" msgstr "Ne zavarja a kalibrálóeszközt a folyamat során" @@ -371,48 +371,48 @@ msgstr "Nem kalibrált" #. TRANSLATORS: this is a profile prefix to signify the #. * profile has been auto-generated for this hardware -#: panels/color/cc-color-panel.c:141 +#: panels/color/cc-color-panel.c:140 msgid "Default: " msgstr "Alapértelmezett: " #. TRANSLATORS: this is a profile prefix to signify the #. * profile his a standard space like AdobeRGB -#: panels/color/cc-color-panel.c:149 +#: panels/color/cc-color-panel.c:148 msgid "Colorspace: " msgstr "Színtér: " #. TRANSLATORS: this is a profile prefix to signify the #. * profile is a test profile -#: panels/color/cc-color-panel.c:156 +#: panels/color/cc-color-panel.c:155 msgid "Test profile: " msgstr "Tesztprofil: " #. TRANSLATORS: an ICC profile is a file containing colorspace data -#: panels/color/cc-color-panel.c:223 +#: panels/color/cc-color-panel.c:222 msgid "Select ICC Profile File" msgstr "Válasszon ICC profilfájlt" -#: panels/color/cc-color-panel.c:226 +#: panels/color/cc-color-panel.c:225 msgid "_Import" msgstr "_Importálás" #. TRANSLATORS: filter name on the file->open dialog -#: panels/color/cc-color-panel.c:237 +#: panels/color/cc-color-panel.c:236 msgid "Supported ICC profiles" msgstr "Támogatott ICC profilok" #. TRANSLATORS: filter name on the file->open dialog -#: panels/color/cc-color-panel.c:244 +#: panels/color/cc-color-panel.c:243 #: panels/network/wireless-security/eap-method-fast.c:417 msgid "All files" msgstr "Minden fájl" -#: panels/color/cc-color-panel.c:583 +#: panels/color/cc-color-panel.c:582 msgid "Screen" msgstr "Képernyő" #. TRANSLATORS: this is when the upload of the profile failed -#: panels/color/cc-color-panel.c:908 +#: panels/color/cc-color-panel.c:907 #, c-format msgid "Failed to upload file: %s" msgstr "A fájl feltöltése meghiúsult: %s" @@ -420,42 +420,42 @@ msgstr "A fájl feltöltése meghiúsult: %s" #. TRANSLATORS: these are instructions on how to recover #. * the ICC profile on the native operating system and are #. * only shown when the user uses a LiveCD to calibrate -#: panels/color/cc-color-panel.c:922 +#: panels/color/cc-color-panel.c:921 msgid "The profile has been uploaded to:" msgstr "A profil feltöltve ide:" -#: panels/color/cc-color-panel.c:924 +#: panels/color/cc-color-panel.c:923 msgid "Write down this URL." msgstr "Írja le ezt az URL-címet." -#: panels/color/cc-color-panel.c:925 +#: panels/color/cc-color-panel.c:924 msgid "Restart this computer and boot your normal operating system." msgstr "" "Indítsa újra a számítógépet, és indítsa el az általában használt operációs " "rendszerét." -#: panels/color/cc-color-panel.c:926 +#: panels/color/cc-color-panel.c:925 msgid "Type the URL into your browser to download and install the profile." msgstr "" "Írja be az URL-címet a böngészőjébe a profil letöltéséhez és telepítéséhez." #. TRANSLATORS: this is the dialog to save the ICC profile -#: panels/color/cc-color-panel.c:960 +#: panels/color/cc-color-panel.c:959 msgid "Save Profile" msgstr "Profil mentése" -#: panels/color/cc-color-panel.c:964 +#: panels/color/cc-color-panel.c:963 #: panels/network/connection-editor/vpn-helpers.c:311 msgid "_Save" msgstr "M_entés" #. TRANSLATORS: this is when the button is sensitive -#: panels/color/cc-color-panel.c:1325 +#: panels/color/cc-color-panel.c:1324 msgid "Create a color profile for the selected device" msgstr "Színprofil létrehozása a kiválasztott eszközhöz" #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1340 panels/color/cc-color-panel.c:1364 +#: panels/color/cc-color-panel.c:1339 panels/color/cc-color-panel.c:1363 msgid "" "The measuring instrument is not detected. Please check it is turned on and " "correctly connected." @@ -464,12 +464,12 @@ msgstr "" "megfelelően van-e csatlakoztatva." #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1374 +#: panels/color/cc-color-panel.c:1373 msgid "The measuring instrument does not support printer profiling." msgstr "A mérőkészülék nem támogatja a nyomtatóprofilozást." #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1385 +#: panels/color/cc-color-panel.c:1384 msgid "The device type is not currently supported." msgstr "Az eszköztípus jelenleg nem támogatott." @@ -915,6 +915,12 @@ msgstr "%b. %e." msgid "%b %e, %Y" msgstr "%Y. %b. %e." +#. translators: This is the default hotspot name, need to be less than 32-bytes +#: panels/common/hostname-helper.c:189 +msgctxt "hotspot" +msgid "Hotspot" +msgstr "Hotspot" + #: panels/common/language-chooser.ui:5 msgid "Language" msgstr "Nyelv" @@ -1111,58 +1117,58 @@ msgstr "Rendszer dátum- és időbeállításainak módosítása" msgid "To change time or date settings, you need to authenticate." msgstr "Hitelesítés szükséges a dátum- és időbeállítások módosításához." -#: panels/display/cc-display-panel.c:729 +#: panels/display/cc-display-panel.c:739 msgctxt "Display rotation" msgid "Landscape" msgstr "Fekvő" -#: panels/display/cc-display-panel.c:732 +#: panels/display/cc-display-panel.c:742 msgctxt "Display rotation" msgid "Portrait Right" msgstr "Álló (jobbra)" -#: panels/display/cc-display-panel.c:735 +#: panels/display/cc-display-panel.c:745 msgctxt "Display rotation" msgid "Portrait Left" msgstr "Álló (balra)" -#: panels/display/cc-display-panel.c:738 +#: panels/display/cc-display-panel.c:748 msgctxt "Display rotation" msgid "Landscape (flipped)" msgstr "Fekvő (fordított)" #. Translators: This option sets orientation of print (portrait, landscape...) -#: panels/display/cc-display-panel.c:805 +#: panels/display/cc-display-panel.c:816 #: panels/printers/pp-options-dialog.c:558 msgid "Orientation" msgstr "Tájolás" -#: panels/display/cc-display-panel.c:870 panels/display/cc-display-panel.c:1673 +#: panels/display/cc-display-panel.c:885 panels/display/cc-display-panel.c:1691 #: panels/printers/pp-options-dialog.c:87 msgid "Resolution" msgstr "Felbontás" -#: panels/display/cc-display-panel.c:958 +#: panels/display/cc-display-panel.c:974 msgid "Refresh Rate" msgstr "Frissítés gyakorisága" -#: panels/display/cc-display-panel.c:1095 +#: panels/display/cc-display-panel.c:1111 msgid "Scale" msgstr "Méretezés" -#: panels/display/cc-display-panel.c:1148 +#: panels/display/cc-display-panel.c:1164 msgid "Adjust for TV" msgstr "TV-hez igazítás" -#: panels/display/cc-display-panel.c:1410 +#: panels/display/cc-display-panel.c:1427 msgid "Primary Display" msgstr "Elsődleges kijelző" -#: panels/display/cc-display-panel.c:1439 +#: panels/display/cc-display-panel.c:1456 msgid "Display Arrangement" msgstr "Elrendezés megjelenítése" -#: panels/display/cc-display-panel.c:1440 +#: panels/display/cc-display-panel.c:1457 msgid "" "Drag displays to match your setup. The top bar is placed on the primary " "display." @@ -1170,59 +1176,67 @@ msgstr "" "Húzza a kijelzőket az elrendezésnek megfelelően. A felső sáv csak az " "elsődleges kijelzőre kerül." -#: panels/display/cc-display-panel.c:1863 +#: panels/display/cc-display-panel.c:1881 msgid "Display Mode" msgstr "Megjelenítés módja" -#: panels/display/cc-display-panel.c:1879 +#: panels/display/cc-display-panel.c:1897 msgid "Join Displays" msgstr "Kijelzők egyesítése" -#: panels/display/cc-display-panel.c:1882 +#: panels/display/cc-display-panel.c:1900 msgid "Mirror" msgstr "Tükrözés" -#: panels/display/cc-display-panel.c:1885 +#: panels/display/cc-display-panel.c:1903 msgid "Single Display" msgstr "Másodlagos kijelző" -#: panels/display/cc-display-panel.c:2590 -msgid "Apply Changes?" -msgstr "Módosítások alkalmazása?" - -#: panels/display/cc-display-panel.c:2604 +#: panels/display/cc-display-panel.c:2620 #: panels/network/connection-editor/connection-editor.ui:24 #: panels/network/network-wifi.ui:38 msgid "_Apply" msgstr "_Alkalmaz" -#: panels/display/cc-display-panel.c:2979 +#: panels/display/cc-display-panel.c:2642 +msgid "Apply Changes?" +msgstr "Módosítások alkalmazása?" + +#: panels/display/cc-display-panel.c:2647 +msgid "Changes Cannot be Applied" +msgstr "A módosítások nem alkalmazhatóak" + +#: panels/display/cc-display-panel.c:2648 +msgid "This could be due to hardware limitations." +msgstr "Ez hardveres korlátozások miatt is lehet." + +#: panels/display/cc-display-panel.c:3003 #, c-format msgid "%.2lf Hz" msgstr "%.2lf Hz" #. TRANSLATORS: the state of the night light setting -#: panels/display/cc-display-panel.c:3195 +#: panels/display/cc-display-panel.c:3219 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1991 panels/power/cc-power-panel.c:1998 -#: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 -#: panels/universal-access/cc-ua-panel.c:333 -#: panels/universal-access/cc-ua-panel.c:714 -#: panels/universal-access/cc-ua-panel.c:727 -#: panels/universal-access/cc-ua-panel.c:739 -#: panels/universal-access/cc-ua-panel.c:910 +#: panels/power/cc-power-panel.c:2097 panels/power/cc-power-panel.c:2104 +#: panels/privacy/cc-privacy-panel.c:191 panels/privacy/cc-privacy-panel.c:258 +#: panels/universal-access/cc-ua-panel.c:334 +#: panels/universal-access/cc-ua-panel.c:715 +#: panels/universal-access/cc-ua-panel.c:728 +#: panels/universal-access/cc-ua-panel.c:740 +#: panels/universal-access/cc-ua-panel.c:911 msgid "On" msgstr "Be" -#: panels/display/cc-display-panel.c:3195 panels/network/net-proxy.c:54 +#: panels/display/cc-display-panel.c:3219 panels/network/net-proxy.c:54 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1985 panels/power/cc-power-panel.c:1996 -#: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 -#: panels/universal-access/cc-ua-panel.c:333 -#: panels/universal-access/cc-ua-panel.c:714 -#: panels/universal-access/cc-ua-panel.c:727 -#: panels/universal-access/cc-ua-panel.c:739 -#: panels/universal-access/cc-ua-panel.c:910 panels/universal-access/uap.ui:334 +#: panels/power/cc-power-panel.c:2091 panels/power/cc-power-panel.c:2102 +#: panels/privacy/cc-privacy-panel.c:191 panels/privacy/cc-privacy-panel.c:258 +#: panels/universal-access/cc-ua-panel.c:334 +#: panels/universal-access/cc-ua-panel.c:715 +#: panels/universal-access/cc-ua-panel.c:728 +#: panels/universal-access/cc-ua-panel.c:740 +#: panels/universal-access/cc-ua-panel.c:911 panels/universal-access/uap.ui:334 #: panels/universal-access/uap.ui:380 panels/universal-access/uap.ui:426 #: panels/universal-access/uap.ui:532 panels/universal-access/uap.ui:685 #: panels/universal-access/uap.ui:731 panels/universal-access/uap.ui:777 @@ -1230,11 +1244,11 @@ msgstr "Be" msgid "Off" msgstr "Ki" -#: panels/display/cc-display-panel.c:3216 +#: panels/display/cc-display-panel.c:3240 msgid "_Night Light" msgstr "Éjszakai _fény" -#: panels/display/cc-display-panel.c:3281 +#: panels/display/cc-display-panel.c:3305 msgid "Could not get screen information" msgstr "A képernyő-információk nem kérhetők le" @@ -1274,7 +1288,7 @@ msgstr "Napnyugtától napkeltéig" #: panels/network/connection-editor/ip6-page.ui:83 #: panels/network/net-proxy.c:56 panels/network/network-proxy.ui:113 #: panels/network/network-wifi.ui:777 panels/network/network-wifi.ui:1054 -#: panels/privacy/cc-privacy-panel.c:217 +#: panels/privacy/cc-privacy-panel.c:218 msgid "Manual" msgstr "Kézi" @@ -1323,8 +1337,8 @@ msgstr "" "redshift;szín;napkelte;napnyugta;" #. TRANSLATORS: AP type -#: panels/info/cc-info-overview-panel.c:374 -#: panels/info/cc-info-overview-panel.c:457 panels/network/panel-common.c:123 +#: panels/info/cc-info-overview-panel.c:373 +#: panels/info/cc-info-overview-panel.c:456 panels/network/panel-common.c:123 msgid "Unknown" msgstr "Ismeretlen" @@ -1332,24 +1346,24 @@ msgstr "Ismeretlen" #. * example: #. * "Fedora 25 (Workstation Edition); Build ID: xyz" or #. * "Ubuntu 16.04 LTS; Build ID: jki" -#: panels/info/cc-info-overview-panel.c:465 +#: panels/info/cc-info-overview-panel.c:464 #, c-format msgid "%s; Build ID: %s" msgstr "%s; Összeállítás-azonosító: %s" #. translators: This is the type of architecture for the OS -#: panels/info/cc-info-overview-panel.c:482 +#: panels/info/cc-info-overview-panel.c:481 #, c-format msgid "64-bit" msgstr "64 bites" #. translators: This is the type of architecture for the OS -#: panels/info/cc-info-overview-panel.c:485 +#: panels/info/cc-info-overview-panel.c:484 #, c-format msgid "32-bit" msgstr "32 bites" -#: panels/info/cc-info-overview-panel.c:775 +#: panels/info/cc-info-overview-panel.c:773 #, c-format msgid "Version %s" msgstr "%s verzió" @@ -1682,8 +1696,8 @@ msgstr "Parancsikonok" msgid "Launch help browser" msgstr "Súgóböngésző indítása" -#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:223 -#: shell/cc-window.c:761 shell/gnome-control-center.desktop.in.in:3 +#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:237 +#: shell/cc-window.c:773 shell/gnome-control-center.desktop.in.in:3 #: shell/window.ui:125 msgid "Settings" msgstr "Beállítások" @@ -1792,7 +1806,7 @@ msgstr "Nagy kontraszt be- vagy kikapcsolása" #: panels/keyboard/cc-keyboard-manager.c:506 #: panels/keyboard/cc-keyboard-manager.c:514 -#: panels/keyboard/cc-keyboard-manager.c:822 +#: panels/keyboard/cc-keyboard-manager.c:821 msgid "Custom Shortcuts" msgstr "Egyéni gyorsbillentyűk" @@ -1803,7 +1817,7 @@ msgstr "Egyéni gyorsbillentyűk" #. * The device has been disabled #: panels/keyboard/cc-keyboard-option.c:263 #: panels/keyboard/cc-keyboard-option.c:382 -#: panels/keyboard/keyboard-shortcuts.c:435 +#: panels/keyboard/keyboard-shortcuts.c:434 #: panels/keyboard/shortcut-editor.ui:96 panels/network/network-proxy.ui:123 #: panels/network/network-wifi.ui:782 panels/network/network-wifi.ui:1059 #: panels/user-accounts/um-fingerprint-dialog.c:211 @@ -2101,7 +2115,7 @@ msgid "Single click, secondary button" msgstr "Egy kattintás, másodlagos gomb" #. add proxy to device list -#: panels/network/cc-network-panel.c:579 +#: panels/network/cc-network-panel.c:583 msgid "Network proxy" msgstr "Hálózati proxy" @@ -2109,23 +2123,23 @@ msgstr "Hálózati proxy" #. * window for vpn connections, it is also used to display #. * vpn connections in the device list. #. -#: panels/network/cc-network-panel.c:715 panels/network/net-vpn.c:192 -#: panels/network/net-vpn.c:321 +#: panels/network/cc-network-panel.c:719 panels/network/net-vpn.c:167 +#: panels/network/net-vpn.c:296 #, c-format msgid "%s VPN" msgstr "%s VPN" -#: panels/network/cc-network-panel.c:779 panels/network/wifi.ui:282 +#: panels/network/cc-network-panel.c:783 panels/network/wifi.ui:282 msgid "Oops, something has gone wrong. Please contact your software vendor." msgstr "Hoppá, valami elromlott. Lépjen kapcsolatba a szoftver szállítójával." -#: panels/network/cc-network-panel.c:785 +#: panels/network/cc-network-panel.c:789 msgid "NetworkManager needs to be running." msgstr "A Hálózatkezelőnek futnia kell." -#: panels/network/cc-wifi-panel.c:213 +#: panels/network/cc-wifi-panel.c:214 #: panels/network/gnome-wifi-panel.desktop.in.in:3 -#: panels/network/network-wifi.ui:1766 +#: panels/network/network-wifi.ui:1769 msgid "Wi-Fi" msgstr "Wi-Fi" @@ -2269,7 +2283,7 @@ msgid "Remove VPN" msgstr "VPN eltávolítása" #: panels/network/connection-editor/ce-page-details.c:334 -#: panels/network/network-wifi.ui:1456 shell/cc-window.c:215 +#: panels/network/network-wifi.ui:1456 shell/cc-window.c:229 #: shell/panel-list.ui:103 msgid "Details" msgstr "Részletek" @@ -2406,7 +2420,7 @@ msgstr "" #: panels/network/connection-editor/ip6-page.ui:291 #: panels/network/net-proxy.c:58 panels/network/network-proxy.ui:103 #: panels/network/wireless-security/eap-method-peap.ui:22 -#: panels/privacy/cc-privacy-panel.c:217 +#: panels/privacy/cc-privacy-panel.c:218 msgid "Automatic" msgstr "Automatikus" @@ -2604,9 +2618,9 @@ msgid "Select file to import" msgstr "Válassza ki az importálandó fájlt" #: panels/network/connection-editor/vpn-helpers.c:182 -#: panels/printers/pp-details-dialog.c:332 +#: panels/printers/pp-details-dialog.c:331 #: panels/sharing/cc-sharing-panel.c:385 -#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-photo-dialog.c:231 msgid "_Open" msgstr "_Megnyitás" @@ -3027,19 +3041,19 @@ msgctxt "Wi-Fi passkey" msgid "Password" msgstr "Jelszó" -#: panels/network/network-wifi.ui:1796 +#: panels/network/network-wifi.ui:1799 msgid "Turn Wi-Fi off" msgstr "Wi-Fi kikapcsolása" -#: panels/network/network-wifi.ui:1828 +#: panels/network/network-wifi.ui:1831 msgid "_Connect to Hidden Network…" msgstr "Kapcsolódás _rejtett hálózathoz…" -#: panels/network/network-wifi.ui:1838 +#: panels/network/network-wifi.ui:1841 msgid "_Turn On Wi-Fi Hotspot…" msgstr "Wi-Fi hotspot be_kapcsolása…" -#: panels/network/network-wifi.ui:1848 +#: panels/network/network-wifi.ui:1851 msgid "_Known Wi-Fi Networks" msgstr "_Ismert Wi-Fi hálózatok" @@ -3349,23 +3363,23 @@ msgstr "Hiányzó firmware" msgid "Cable unplugged" msgstr "Kábel kihúzva" -#: panels/network/wireless-security/eap-method.c:57 +#: panels/network/wireless-security/eap-method.c:69 msgid "undefined error in 802.1X security (wpa-eap)" msgstr "meghatározatlan hiba a 802.1X biztonságban (wpa-eap)" -#: panels/network/wireless-security/eap-method.c:233 +#: panels/network/wireless-security/eap-method.c:245 msgid "no file selected" msgstr "nincs fájl kiválasztva" -#: panels/network/wireless-security/eap-method.c:264 +#: panels/network/wireless-security/eap-method.c:276 msgid "unspecified error validating eap-method file" msgstr "meghatározatlan hiba az eap-method fájl ellenőrzése közben" -#: panels/network/wireless-security/eap-method.c:439 +#: panels/network/wireless-security/eap-method.c:451 msgid "DER, PEM, or PKCS#12 private keys (*.der, *.pem, *.p12, *.key)" msgstr "DER, PEM vagy PKCS#12 személyes kulcsok (*.der, *.pem, *.p12, *.key)" -#: panels/network/wireless-security/eap-method.c:442 +#: panels/network/wireless-security/eap-method.c:454 msgid "DER or PEM certificates (*.der, *.pem, *.crt, *.cer)" msgstr "DER vagy PEM tanúsítványok (*.der, *.pem, *.crt, *.cer)" @@ -3782,19 +3796,19 @@ msgstr "Egyéb" #. translators: This is the title of the "Show Account" dialog. The #. * %s is the name of the provider. e.g., 'Google'. -#: panels/online-accounts/cc-online-accounts-panel.c:551 +#: panels/online-accounts/cc-online-accounts-panel.c:612 #, c-format msgid "%s Account" msgstr "%s fiók" -#: panels/online-accounts/cc-online-accounts-panel.c:843 +#: panels/online-accounts/cc-online-accounts-panel.c:904 msgid "Error removing account" msgstr "Hiba a fiók eltávolításakor" #. Translators: The %s is the username (eg., debarshi.ray@gmail.com #. * or rishi). #. -#: panels/online-accounts/cc-online-accounts-panel.c:908 +#: panels/online-accounts/cc-online-accounts-panel.c:969 #, c-format msgid "%s removed" msgstr "%s eltávolítva" @@ -3845,18 +3859,18 @@ msgstr "Fiók hozzáadása" msgid "Remove Account" msgstr "Fiók eltávolítása" -#: panels/power/cc-power-panel.c:253 +#: panels/power/cc-power-panel.c:254 msgid "Unknown time" msgstr "Ismeretlen idő" -#: panels/power/cc-power-panel.c:259 +#: panels/power/cc-power-panel.c:260 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "%i perc" msgstr[1] "%i perc" -#: panels/power/cc-power-panel.c:271 +#: panels/power/cc-power-panel.c:272 #, c-format msgid "%i hour" msgid_plural "%i hours" @@ -3865,258 +3879,299 @@ msgstr[1] "%i óra" #. TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes" #. * Swap order with "%2$s %2$i %1$s %1$i if needed -#: panels/power/cc-power-panel.c:279 +#: panels/power/cc-power-panel.c:280 #, c-format msgid "%i %s %i %s" msgstr "%i %s, %i %s" -#: panels/power/cc-power-panel.c:280 +#: panels/power/cc-power-panel.c:281 msgid "hour" msgid_plural "hours" msgstr[0] "óra" msgstr[1] "óra" -#: panels/power/cc-power-panel.c:281 +#: panels/power/cc-power-panel.c:282 msgid "minute" msgid_plural "minutes" msgstr[0] "perc" msgstr[1] "perc" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:300 +#: panels/power/cc-power-panel.c:301 #, c-format msgid "%s until fully charged" msgstr "%s a teljes feltöltésig" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:307 +#: panels/power/cc-power-panel.c:308 #, c-format msgid "Caution: %s remaining" msgstr "Figyelem: %s van hátra" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:312 +#: panels/power/cc-power-panel.c:313 #, c-format msgid "%s remaining" msgstr "%s van hátra" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:317 panels/power/cc-power-panel.c:345 +#: panels/power/cc-power-panel.c:318 panels/power/cc-power-panel.c:346 msgid "Fully charged" msgstr "Teljesen feltöltve" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:321 panels/power/cc-power-panel.c:349 +#: panels/power/cc-power-panel.c:322 panels/power/cc-power-panel.c:350 msgid "Empty" msgstr "Lemerült" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:336 +#: panels/power/cc-power-panel.c:337 msgid "Charging" msgstr "Töltés" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:341 +#: panels/power/cc-power-panel.c:342 msgid "Discharging" msgstr "Kisülés" -#: panels/power/cc-power-panel.c:464 +#: panels/power/cc-power-panel.c:465 msgctxt "Battery name" msgid "Main" msgstr "Elsődleges" -#: panels/power/cc-power-panel.c:466 +#: panels/power/cc-power-panel.c:467 msgctxt "Battery name" msgid "Extra" msgstr "Extra" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:537 +#: panels/power/cc-power-panel.c:538 msgid "Wireless mouse" msgstr "Vezeték nélküli egér" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:540 +#: panels/power/cc-power-panel.c:541 msgid "Wireless keyboard" msgstr "Vezeték nélküli billentyűzet" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:543 +#: panels/power/cc-power-panel.c:544 msgid "Uninterruptible power supply" msgstr "Szünetmentes tápegység (UPS)" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:546 +#: panels/power/cc-power-panel.c:547 msgid "Personal digital assistant" msgstr "Személyes digitális asszisztens" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:549 +#: panels/power/cc-power-panel.c:550 msgid "Cellphone" msgstr "Mobiltelefon" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:552 +#: panels/power/cc-power-panel.c:553 msgid "Media player" msgstr "Médialejátszó" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:555 panels/wacom/cc-wacom-panel.c:793 +#: panels/power/cc-power-panel.c:556 panels/wacom/cc-wacom-panel.c:793 msgid "Tablet" msgstr "Táblagép" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:558 +#: panels/power/cc-power-panel.c:559 msgid "Computer" msgstr "Számítógép" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:561 +#: panels/power/cc-power-panel.c:562 msgid "Gaming input device" msgstr "Bemeneti eszköz játékokhoz" #. TRANSLATORS: secondary battery, misc -#: panels/power/cc-power-panel.c:564 panels/power/cc-power-panel.c:804 -#: panels/power/cc-power-panel.c:2377 +#: panels/power/cc-power-panel.c:565 panels/power/cc-power-panel.c:829 +#: panels/power/cc-power-panel.c:2483 msgid "Battery" msgstr "Akkumulátor" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:618 +#: panels/power/cc-power-panel.c:632 msgctxt "Battery power" msgid "Charging" msgstr "Töltés" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:625 +#: panels/power/cc-power-panel.c:639 msgctxt "Battery power" msgid "Caution" msgstr "Figyelem" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:630 +#: panels/power/cc-power-panel.c:644 msgctxt "Battery power" msgid "Low" msgstr "Alacsony" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:635 +#: panels/power/cc-power-panel.c:649 msgctxt "Battery power" msgid "Good" msgstr "Jó" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:640 +#: panels/power/cc-power-panel.c:654 msgctxt "Battery power" msgid "Fully charged" msgstr "Teljesen feltöltve" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:644 +#: panels/power/cc-power-panel.c:658 msgctxt "Battery power" msgid "Empty" msgstr "Üres" -#: panels/power/cc-power-panel.c:802 +#: panels/power/cc-power-panel.c:827 msgid "Batteries" msgstr "Akkumulátorok" -#: panels/power/cc-power-panel.c:1239 +#: panels/power/cc-power-panel.c:1206 +#, c-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d óra" +msgstr[1] "%d óra" + +#: panels/power/cc-power-panel.c:1208 +#, c-format +msgid "%d minute" +msgid_plural "%d minutes" +msgstr[0] "%d perc" +msgstr[1] "%d perc" + +#: panels/power/cc-power-panel.c:1211 +#, c-format +msgid "%d second" +msgid_plural "%d seconds" +msgstr[0] "%d másodperc" +msgstr[1] "%d másodperc" + +#. 5 hours 2 minutes 12 seconds +#: panels/power/cc-power-panel.c:1217 +#, c-format +msgctxt "time" +msgid "%s %s %s" +msgstr "%s %s %s" + +#. 2 minutes 12 seconds +#: panels/power/cc-power-panel.c:1220 +#, c-format +msgctxt "time" +msgid "%s %s" +msgstr "%s %s" + +#. 0 seconds +#: panels/power/cc-power-panel.c:1226 +msgid "0 seconds" +msgstr "0 másodperc" + +#: panels/power/cc-power-panel.c:1328 msgid "When _idle" msgstr "Ü_resjáratban" -#: panels/power/cc-power-panel.c:1693 +#: panels/power/cc-power-panel.c:1793 msgid "Power Saving" msgstr "Energiatakarékosság" -#: panels/power/cc-power-panel.c:1724 +#: panels/power/cc-power-panel.c:1824 msgid "_Screen brightness" msgstr "_Képernyő fényereje" -#: panels/power/cc-power-panel.c:1743 +#: panels/power/cc-power-panel.c:1843 msgid "Automatic brightness" msgstr "Automatikus fényerő" -#: panels/power/cc-power-panel.c:1763 +#: panels/power/cc-power-panel.c:1863 msgid "_Keyboard brightness" msgstr "Billentyűzet _fényereje" -#: panels/power/cc-power-panel.c:1773 +#: panels/power/cc-power-panel.c:1873 msgid "_Dim screen when inactive" msgstr "Képer_nyő elhalványítása, ha inaktív" -#: panels/power/cc-power-panel.c:1798 +#: panels/power/cc-power-panel.c:1898 msgid "_Blank screen" msgstr "Képernyő _elsötétítése" -#: panels/power/cc-power-panel.c:1835 +#: panels/power/cc-power-panel.c:1935 msgid "_Wi-Fi" msgstr "_Wi-Fi" -#: panels/power/cc-power-panel.c:1840 +#: panels/power/cc-power-panel.c:1940 msgid "Turn off Wi-Fi to save power." msgstr "Wi-Fi kikapcsolása az energiatakarékosság érdekében." -#: panels/power/cc-power-panel.c:1865 +#: panels/power/cc-power-panel.c:1965 msgid "_Mobile broadband" msgstr "_Mobil széles sáv" -#: panels/power/cc-power-panel.c:1870 +#: panels/power/cc-power-panel.c:1970 msgid "Turn off mobile broadband (3G, 4G, LTE, etc.) to save power." msgstr "" "Mobil széles sáv (3G, 4G, LTE stb.) kikapcsolása az energiatakarékosság " "érdekében." -#: panels/power/cc-power-panel.c:1923 +#: panels/power/cc-power-panel.c:2029 msgid "_Bluetooth" msgstr "Bl_uetooth" -#: panels/power/cc-power-panel.c:1928 +#: panels/power/cc-power-panel.c:2034 msgid "Turn off Bluetooth to save power." msgstr "Bluetooth kikapcsolása az energiatakarékosság érdekében." -#: panels/power/cc-power-panel.c:1987 +#: panels/power/cc-power-panel.c:2093 msgid "When on battery power" msgstr "Akkumulátoron" -#: panels/power/cc-power-panel.c:1989 +#: panels/power/cc-power-panel.c:2095 msgid "When plugged in" msgstr "Ha csatlakoztatva van" -#: panels/power/cc-power-panel.c:2084 +#: panels/power/cc-power-panel.c:2190 msgid "Suspend" msgstr "Felfüggesztés" -#: panels/power/cc-power-panel.c:2085 +#: panels/power/cc-power-panel.c:2191 msgid "Power Off" msgstr "Kikapcsolás" -#: panels/power/cc-power-panel.c:2086 +#: panels/power/cc-power-panel.c:2192 msgid "Hibernate" msgstr "Hibernálás" -#: panels/power/cc-power-panel.c:2087 +#: panels/power/cc-power-panel.c:2193 msgid "Nothing" msgstr "Ne tegyen semmit" #. Frame header -#: panels/power/cc-power-panel.c:2201 +#: panels/power/cc-power-panel.c:2307 msgid "Suspend & Power Button" msgstr "Felfüggesztés és kikapcsolás gombok" -#: panels/power/cc-power-panel.c:2240 +#: panels/power/cc-power-panel.c:2346 msgid "_Automatic suspend" msgstr "_Automatikus felfüggesztés" -#: panels/power/cc-power-panel.c:2241 +#: panels/power/cc-power-panel.c:2347 msgid "Automatic suspend" msgstr "Automatikus felfüggesztés" -#: panels/power/cc-power-panel.c:2308 +#: panels/power/cc-power-panel.c:2414 msgid "_When the Power Button is pressed" msgstr "A _bekapcsológomb megnyomásakor" -#: panels/power/cc-power-panel.c:2427 shell/cc-window.c:219 +#: panels/power/cc-power-panel.c:2533 panels/thunderbolt/cc-bolt-panel.ui:466 +#: panels/thunderbolt/cc-bolt-panel.ui:525 shell/cc-window.c:233 #: shell/panel-list.ui:45 msgid "Devices" msgstr "Eszközök" @@ -4253,18 +4308,18 @@ msgid "Authentication Required" msgstr "Hitelesítés szükséges" #. Translators: %s is the printer name -#: panels/printers/cc-printers-panel.c:791 +#: panels/printers/cc-printers-panel.c:809 #, c-format msgid "Printer “%s” has been deleted" msgstr "A(z) „%s” nyomtató törölve lett" #. Translators: Addition of the new printer failed. -#: panels/printers/cc-printers-panel.c:1036 +#: panels/printers/cc-printers-panel.c:1054 msgid "Failed to add new printer." msgstr "Az új nyomtató hozzáadása meghiúsult." #. Translators: The XML file containing user interface can not be loaded -#: panels/printers/cc-printers-panel.c:1371 +#: panels/printers/cc-printers-panel.c:1391 #, c-format msgid "Could not load ui: %s" msgstr "A felület nem tölthető be: %s" @@ -4377,21 +4432,21 @@ msgid "Test Page" msgstr "Tesztoldal" #. Translators: This is the title of the dialog. %s is the printer name. -#: panels/printers/pp-details-dialog.c:135 -#: panels/printers/pp-details-dialog.c:435 +#: panels/printers/pp-details-dialog.c:134 +#: panels/printers/pp-details-dialog.c:434 #, c-format msgid "%s Details" msgstr "%s adatai" -#: panels/printers/pp-details-dialog.c:184 +#: panels/printers/pp-details-dialog.c:183 msgid "No suitable driver found" msgstr "Nem található megfelelő illesztőprogram" -#: panels/printers/pp-details-dialog.c:328 +#: panels/printers/pp-details-dialog.c:327 msgid "Select PPD File" msgstr "Válasszon PPD fájlt" -#: panels/printers/pp-details-dialog.c:337 +#: panels/printers/pp-details-dialog.c:336 msgid "" "PostScript Printer Description files (*.ppd, *.PPD, *.ppd.gz, *.PPD.gz, *." "PPD.GZ)" @@ -4403,7 +4458,7 @@ msgid "Select Printer Driver" msgstr "Válassza ki a nyomtató-illesztőprogramot" #: panels/printers/ppd-selection-dialog.ui:40 -#: panels/user-accounts/um-photo-dialog.c:104 +#: panels/user-accounts/um-photo-dialog.c:105 msgid "Select" msgstr "Kijelölés" @@ -4460,55 +4515,55 @@ msgid "Reverse portrait" msgstr "Fordított álló" #. Translators: Job's state (job is waiting to be printed) -#: panels/printers/pp-jobs-dialog.c:243 +#: panels/printers/pp-jobs-dialog.c:234 msgctxt "print job" msgid "Pending" msgstr "Függőben" #. Translators: Job's state (job is held for printing) -#: panels/printers/pp-jobs-dialog.c:249 +#: panels/printers/pp-jobs-dialog.c:240 msgctxt "print job" msgid "Paused" msgstr "Szüneteltetve" #. Translators: Job's state (job needs authentication to proceed further) -#: panels/printers/pp-jobs-dialog.c:254 +#: panels/printers/pp-jobs-dialog.c:245 msgctxt "print job" msgid "Authentication required" msgstr "Hitelesítés szükséges" #. Translators: Job's state (job is currently printing) -#: panels/printers/pp-jobs-dialog.c:259 +#: panels/printers/pp-jobs-dialog.c:250 msgctxt "print job" msgid "Processing" msgstr "Feldolgozás" #. Translators: Job's state (job has been stopped) -#: panels/printers/pp-jobs-dialog.c:263 +#: panels/printers/pp-jobs-dialog.c:254 msgctxt "print job" msgid "Stopped" msgstr "Leállítva" #. Translators: Job's state (job has been canceled) -#: panels/printers/pp-jobs-dialog.c:267 +#: panels/printers/pp-jobs-dialog.c:258 msgctxt "print job" msgid "Canceled" msgstr "Megszakítva" #. Translators: Job's state (job has aborted due to error) -#: panels/printers/pp-jobs-dialog.c:271 +#: panels/printers/pp-jobs-dialog.c:262 msgctxt "print job" msgid "Aborted" msgstr "Félbeszakítva" #. Translators: Job's state (job has completed successfully) -#: panels/printers/pp-jobs-dialog.c:275 +#: panels/printers/pp-jobs-dialog.c:266 msgctxt "print job" msgid "Completed" msgstr "Befejezve" #. Translators: This label shows how many jobs of this printer needs to be authenticated to be printed. -#: panels/printers/pp-jobs-dialog.c:399 +#: panels/printers/pp-jobs-dialog.c:390 #, c-format msgid "%u Job Requires Authentication" msgid_plural "%u Jobs Require Authentication" @@ -4516,14 +4571,14 @@ msgstr[0] "%u feladat hitelesítést igényel" msgstr[1] "%u feladat hitelesítést igényel" #. Translators: This is the printer name for which we are showing the active jobs -#: panels/printers/pp-jobs-dialog.c:617 +#: panels/printers/pp-jobs-dialog.c:620 #, c-format msgctxt "Printer jobs dialog title" msgid "%s — Active Jobs" msgstr "%s – Aktív feladatok" #. Translators: The printer needs authentication info to print. -#: panels/printers/pp-jobs-dialog.c:622 +#: panels/printers/pp-jobs-dialog.c:625 #, c-format msgid "Enter credentials to print from %s." msgstr "Hitelesítési adatok megadása a következőről történő nyomtatáshoz: %s." @@ -4890,25 +4945,25 @@ msgstr "" "Elnézést, a rendszer nyomtatószolgáltatása\n" "nem tűnik elérhetőnek." -#: panels/privacy/cc-privacy-panel.c:387 panels/privacy/privacy.ui:280 +#: panels/privacy/cc-privacy-panel.c:388 panels/privacy/privacy.ui:280 msgid "Screen Lock" msgstr "Képernyőzár" -#: panels/privacy/cc-privacy-panel.c:438 +#: panels/privacy/cc-privacy-panel.c:439 msgid "In use" msgstr "Használatban" -#: panels/privacy/cc-privacy-panel.c:443 +#: panels/privacy/cc-privacy-panel.c:444 msgctxt "Location services status" msgid "On" msgstr "Be" -#: panels/privacy/cc-privacy-panel.c:444 +#: panels/privacy/cc-privacy-panel.c:445 msgctxt "Location services status" msgid "Off" msgstr "Ki" -#: panels/privacy/cc-privacy-panel.c:823 panels/privacy/privacy.ui:745 +#: panels/privacy/cc-privacy-panel.c:825 panels/privacy/privacy.ui:745 msgid "Location Services" msgstr "Helymeghatározó szolgáltatások" @@ -5136,9 +5191,8 @@ msgid "" "Uses Mozilla Location Service: Privacy Policy" msgstr "" -"A Mozilla helymeghatározási szolgáltatást használja: adatvédelmi irányelvek<" -"/a>" +"A Mozilla helymeghatározási szolgáltatást használja: adatvédelmi irányelvek" #: panels/privacy/privacy.ui:828 msgid "_Location Services" @@ -5171,11 +5225,11 @@ msgctxt "Input Source" msgid "Other" msgstr "Egyéb" -#: panels/region/cc-region-panel.c:881 +#: panels/region/cc-region-panel.c:882 msgid "No input source selected" msgstr "Nincs kiválasztva bemeneti forrás" -#: panels/region/cc-region-panel.c:1773 +#: panels/region/cc-region-panel.c:1774 msgid "Login _Screen" msgstr "Bejelentkezési _képernyő" @@ -5401,7 +5455,7 @@ msgid "Preferences" msgstr "Beállítások" #. Label -#: panels/sharing/cc-sharing-networks.c:305 +#: panels/sharing/cc-sharing-networks.c:307 msgid "No networks selected for sharing" msgstr "Nincs kiválasztott hálózat a megosztáshoz" @@ -5780,34 +5834,203 @@ msgstr "Mélysugárzó" msgid "Custom" msgstr "Egyéni" +#: panels/thunderbolt/cc-bolt-device-dialog.c:86 +#: panels/thunderbolt/cc-bolt-device-entry.c:119 +msgctxt "Thunderbolt Device Status" +msgid "Disconnected" +msgstr "Bontva" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:89 +#: panels/thunderbolt/cc-bolt-device-entry.c:122 +msgctxt "Thunderbolt Device Status" +msgid "Connecting" +msgstr "Kapcsolódás" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:92 +#: panels/thunderbolt/cc-bolt-device-entry.c:126 +#: panels/thunderbolt/cc-bolt-device-entry.c:138 +msgctxt "Thunderbolt Device Status" +msgid "Connected" +msgstr "Kapcsolódva" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:95 +msgctxt "Thunderbolt Device Status" +msgid "Authorization Error" +msgstr "Engedélyezési hiba" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:98 +#: panels/thunderbolt/cc-bolt-device-entry.c:132 +msgctxt "Thunderbolt Device Status" +msgid "Authorizing" +msgstr "Engedélyezés" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:105 +msgctxt "Thunderbolt Device Status" +msgid "Reduced Functionality" +msgstr "Csökkentett funkcionalitás" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:107 +msgctxt "Thunderbolt Device Status" +msgid "Connected & Authorized" +msgstr "Kapcsolódva és engedélyezve" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:113 +#: panels/thunderbolt/cc-bolt-device-entry.c:146 +msgctxt "Thunderbolt Device Status" +msgid "Unknown" +msgstr "Ismeretlen" + +#. Translators: The time point the device was authorized. +#: panels/thunderbolt/cc-bolt-device-dialog.c:169 +msgid "Authorized at:" +msgstr "Engedélyezve ekkor:" + +#. Translators: The time point the device was connected. +#: panels/thunderbolt/cc-bolt-device-dialog.c:175 +msgid "Connected at:" +msgstr "Kapcsolódva ekkor:" + +#. Translators: The time point the device was enrolled, +#. * i.e. authorized and stored in the device database. +#: panels/thunderbolt/cc-bolt-device-dialog.c:182 +msgid "Enrolled at:" +msgstr "Bejegyezve ekkor:" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:250 +msgid "Failed to authorize device: " +msgstr "Az eszköz engedélyezése meghiúsult: " + +#: panels/thunderbolt/cc-bolt-device-dialog.c:327 +msgid "Failed to forget device: " +msgstr "Az eszköz elfelejtése meghiúsult: " + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:109 +msgid "Name:" +msgstr "Név:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:141 +msgid "Status:" +msgstr "Állapot:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:174 +msgid "UUID:" +msgstr "UUID:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:280 +msgid "Authorize and Connect" +msgstr "Engedélyezés és kapcsolódás" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:303 +msgid "Forget Device" +msgstr "Eszköz elfelejtése" + +#: panels/thunderbolt/cc-bolt-device-entry.c:129 +msgctxt "Thunderbolt Device Status" +msgid "Error" +msgstr "Hiba" + +#: panels/thunderbolt/cc-bolt-device-entry.c:140 +msgctxt "Thunderbolt Device Status" +msgid "Authorized" +msgstr "Engedélyezve" + +#: panels/thunderbolt/cc-bolt-panel.c:175 +msgid "" +"The Thunderbolt subsystem (boltd) is not installed or not set up properly." +msgstr "" +"A Thunderbolt alrendszer (boltd) nincs telepítve vagy rosszul van beállítva." + +#: panels/thunderbolt/cc-bolt-panel.c:460 +msgid "" +"Thunderbolt could not be detected.\n" +"Either the system lacks Thunderbolt support, it has been disabled in the " +"BIOS or is set to an unsupported security level in the BIOS." +msgstr "" +"A Thunderbolt nem észlelhető.\n" +"Vagy hiányzik a rendszerből a Thunderbolt támogatás, vagy le lett tiltva a " +"BIOS-ban, vagy nem támogatott biztonsági szintre van állítva a BIOS-ban." + +#: panels/thunderbolt/cc-bolt-panel.c:504 +msgid "Thunderbolt support has been disabled in the BIOS." +msgstr "A Thunderbolt támogatás le lett tiltva a BIOS-ban." + +#: panels/thunderbolt/cc-bolt-panel.c:613 +#, c-format +msgid "Error switching direct mode: %s" +msgstr "Hiba a közvetlen módra váltáskor: %s" + +#: panels/thunderbolt/cc-bolt-panel.ui:143 +msgid "No Thunderbolt support" +msgstr "Nincs Thunderbolt támogatás" + +#: panels/thunderbolt/cc-bolt-panel.ui:246 +msgid "Direct Access" +msgstr "Közvetlen hozzáférés" + +#: panels/thunderbolt/cc-bolt-panel.ui:269 +msgid "Allow direct access to devices such as docks and external GPUs." +msgstr "" +"Közvetlen hozzáférés engedélyezése az olyan eszközökhöz, mint a dokkolók és " +"külső GPU-k." + +#: panels/thunderbolt/cc-bolt-panel.ui:289 +msgid "Only USB and Display Port devices can attach." +msgstr "Csak USB és Display Port eszközök csatlakoztathatóak." + +#: panels/thunderbolt/cc-bolt-panel.ui:397 +msgid "Pending Devices" +msgstr "Függőben lévő eszközök" + +#: panels/thunderbolt/cc-bolt-panel.ui:535 +msgid "No devices attached" +msgstr "Nincs eszköz csatlakoztatva" + +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:3 +msgid "Thunderbolt" +msgstr "Thunderbolt" + +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:4 +msgid "Manage Thunderbolt devices" +msgstr "Thunderbolt eszközök kezelése" + +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:7 +msgid "thunderbolt" +msgstr "thunderbolt" + +#. Translators: those are keywords for the thunderbolt control-center panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:19 +msgid "Thunderbolt;" +msgstr "Thunderbolt;" + #. translators: the labels will read: #. * Cursor Size: Default -#: panels/universal-access/cc-ua-panel.c:353 +#: panels/universal-access/cc-ua-panel.c:354 msgctxt "cursor size" msgid "Default" msgstr "Alapértelmezett" -#: panels/universal-access/cc-ua-panel.c:356 +#: panels/universal-access/cc-ua-panel.c:357 msgctxt "cursor size" msgid "Medium" msgstr "Közepes" -#: panels/universal-access/cc-ua-panel.c:359 +#: panels/universal-access/cc-ua-panel.c:360 msgctxt "cursor size" msgid "Large" msgstr "Nagy" -#: panels/universal-access/cc-ua-panel.c:362 +#: panels/universal-access/cc-ua-panel.c:363 msgctxt "cursor size" msgid "Larger" msgstr "Nagyobb" -#: panels/universal-access/cc-ua-panel.c:365 +#: panels/universal-access/cc-ua-panel.c:366 msgctxt "cursor size" msgid "Largest" msgstr "Legnagyobb" -#: panels/universal-access/cc-ua-panel.c:369 +#: panels/universal-access/cc-ua-panel.c:370 #, c-format msgid "%d pixel" msgid_plural "%d pixels" @@ -5854,7 +6077,7 @@ msgid "C_ursor Size" msgstr "K_urzorméret" #: panels/universal-access/uap.ui:316 -#: panels/universal-access/zoom-options.ui:98 +#: panels/universal-access/zoom-options.ui:99 msgid "_Zoom" msgstr "_Nagyítás" @@ -6147,27 +6370,27 @@ msgctxt "dwell click threshold" msgid "Large" msgstr "Magas" -#: panels/universal-access/zoom-options.c:333 +#: panels/universal-access/zoom-options.c:338 msgctxt "Distance" msgid "Short" msgstr "Rövid" -#: panels/universal-access/zoom-options.c:334 +#: panels/universal-access/zoom-options.c:339 msgctxt "Distance" msgid "¼ Screen" msgstr "¼ képernyő" -#: panels/universal-access/zoom-options.c:335 +#: panels/universal-access/zoom-options.c:340 msgctxt "Distance" msgid "½ Screen" msgstr "½ képernyő" -#: panels/universal-access/zoom-options.c:336 +#: panels/universal-access/zoom-options.c:341 msgctxt "Distance" msgid "¾ Screen" msgstr "¾ képernyő" -#: panels/universal-access/zoom-options.c:337 +#: panels/universal-access/zoom-options.c:342 msgctxt "Distance" msgid "Long" msgstr "Hosszú" @@ -6192,134 +6415,134 @@ msgstr "Bal fél" msgid "Right Half" msgstr "Jobb fél" -#: panels/universal-access/zoom-options.ui:77 +#: panels/universal-access/zoom-options.ui:78 msgid "Zoom Options" msgstr "Nagyító beállításai" -#: panels/universal-access/zoom-options.ui:186 +#: panels/universal-access/zoom-options.ui:188 msgid "_Magnification:" msgstr "_Nagyítás:" -#: panels/universal-access/zoom-options.ui:250 +#: panels/universal-access/zoom-options.ui:252 msgid "_Follow mouse cursor" msgstr "Egérkurzor _követése" -#: panels/universal-access/zoom-options.ui:270 +#: panels/universal-access/zoom-options.ui:272 msgid "_Screen part:" msgstr "Képernyő_részlet:" -#: panels/universal-access/zoom-options.ui:332 +#: panels/universal-access/zoom-options.ui:334 msgid "Magnifier _extends outside of screen" msgstr "A nagyító _kiterjed a képernyőn kívülre is" -#: panels/universal-access/zoom-options.ui:351 +#: panels/universal-access/zoom-options.ui:353 msgid "_Keep magnifier cursor centered" msgstr "A nagyítókurzor középen _tartása" -#: panels/universal-access/zoom-options.ui:370 +#: panels/universal-access/zoom-options.ui:372 msgid "Magnifier cursor _pushes contents around" msgstr "A nagyítókurzor _eltolja a tartalmakat" -#: panels/universal-access/zoom-options.ui:389 +#: panels/universal-access/zoom-options.ui:391 msgid "Magnifier cursor moves with _contents" msgstr "A nagyítókurzor a tartalmakkal együtt _mozog" -#: panels/universal-access/zoom-options.ui:423 +#: panels/universal-access/zoom-options.ui:425 msgid "Magnifier Position:" msgstr "Nagyító pozíciója:" -#: panels/universal-access/zoom-options.ui:444 +#: panels/universal-access/zoom-options.ui:446 msgid "Magnifier" msgstr "Nagyító" -#: panels/universal-access/zoom-options.ui:490 +#: panels/universal-access/zoom-options.ui:493 msgid "_Thickness:" msgstr "_Vastagság:" -#: panels/universal-access/zoom-options.ui:516 +#: panels/universal-access/zoom-options.ui:519 msgctxt "universal access, thickness" msgid "Thin" msgstr "Vékony" -#: panels/universal-access/zoom-options.ui:548 +#: panels/universal-access/zoom-options.ui:551 msgctxt "universal access, thickness" msgid "Thick" msgstr "Vastag" -#: panels/universal-access/zoom-options.ui:574 +#: panels/universal-access/zoom-options.ui:577 msgid "_Length:" msgstr "_Hossz:" #. The color of the accessibility crosshair -#: panels/universal-access/zoom-options.ui:626 +#: panels/universal-access/zoom-options.ui:629 msgid "Co_lor:" msgstr "_Szín:" -#: panels/universal-access/zoom-options.ui:690 +#: panels/universal-access/zoom-options.ui:693 msgid "_Crosshairs:" msgstr "Szál_keresztek:" -#: panels/universal-access/zoom-options.ui:741 +#: panels/universal-access/zoom-options.ui:744 msgid "_Overlaps mouse cursor" msgstr "Át_fedi az egérkurzort" -#: panels/universal-access/zoom-options.ui:779 +#: panels/universal-access/zoom-options.ui:782 msgid "Crosshairs" msgstr "Szálkeresztek" -#: panels/universal-access/zoom-options.ui:827 +#: panels/universal-access/zoom-options.ui:831 msgid "_White on black:" msgstr "F_ehér a feketén:" -#: panels/universal-access/zoom-options.ui:850 +#: panels/universal-access/zoom-options.ui:854 msgid "_Brightness:" msgstr "_Fényerő:" -#: panels/universal-access/zoom-options.ui:874 +#: panels/universal-access/zoom-options.ui:878 msgid "_Contrast:" msgstr "_Kontraszt:" #. The contrast scale goes from Color to None (grayscale) -#: panels/universal-access/zoom-options.ui:897 +#: panels/universal-access/zoom-options.ui:901 msgctxt "universal access, contrast" msgid "Co_lor" msgstr "_Szín" -#: panels/universal-access/zoom-options.ui:925 +#: panels/universal-access/zoom-options.ui:929 msgctxt "universal access, color" msgid "None" msgstr "Nincs" -#: panels/universal-access/zoom-options.ui:957 +#: panels/universal-access/zoom-options.ui:961 msgctxt "universal access, color" msgid "Full" msgstr "Teljes" -#: panels/universal-access/zoom-options.ui:1023 +#: panels/universal-access/zoom-options.ui:1027 msgctxt "universal access, brightness" msgid "Low" msgstr "Alacsony" -#: panels/universal-access/zoom-options.ui:1056 +#: panels/universal-access/zoom-options.ui:1060 msgctxt "universal access, brightness" msgid "High" msgstr "Magas" -#: panels/universal-access/zoom-options.ui:1087 +#: panels/universal-access/zoom-options.ui:1091 msgctxt "universal access, contrast" msgid "Low" msgstr "Alacsony" -#: panels/universal-access/zoom-options.ui:1120 +#: panels/universal-access/zoom-options.ui:1124 msgctxt "universal access, contrast" msgid "High" msgstr "Nagy" -#: panels/universal-access/zoom-options.ui:1156 +#: panels/universal-access/zoom-options.ui:1160 msgid "Color Effects:" msgstr "Színeffektusok:" -#: panels/universal-access/zoom-options.ui:1181 +#: panels/universal-access/zoom-options.ui:1185 msgid "Color Effects" msgstr "Színeffektusok" @@ -6735,29 +6958,29 @@ msgstr "Ismeretlen hiba" msgid "Should match the web address of your login provider." msgstr "Egyeznie kell a bejelentkezés szolgáltatójának webcímével." -#: panels/user-accounts/um-account-dialog.c:229 +#: panels/user-accounts/um-account-dialog.c:228 msgid "Failed to add account" msgstr "A fiók hozzáadása sikertelen" -#: panels/user-accounts/um-account-dialog.c:462 +#: panels/user-accounts/um-account-dialog.c:461 msgid "Passwords do not match." msgstr "Nem egyeznek a megadott jelszavak." -#: panels/user-accounts/um-account-dialog.c:717 -#: panels/user-accounts/um-account-dialog.c:763 -#: panels/user-accounts/um-account-dialog.c:784 +#: panels/user-accounts/um-account-dialog.c:716 +#: panels/user-accounts/um-account-dialog.c:762 +#: panels/user-accounts/um-account-dialog.c:783 msgid "Failed to register account" msgstr "A fiók regisztrálása sikertelen" -#: panels/user-accounts/um-account-dialog.c:907 +#: panels/user-accounts/um-account-dialog.c:906 msgid "No supported way to authenticate with this domain" msgstr "Nincs támogatott módszer a tartományban való hitelesítésre" -#: panels/user-accounts/um-account-dialog.c:980 +#: panels/user-accounts/um-account-dialog.c:979 msgid "Failed to join domain" msgstr "Nem sikerült a tartományhoz csatlakozni" -#: panels/user-accounts/um-account-dialog.c:1041 +#: panels/user-accounts/um-account-dialog.c:1040 msgid "" "That login name didn’t work.\n" "Please try again." @@ -6765,7 +6988,7 @@ msgstr "" "A bejelentkezési név nem működik.\n" "Próbálja újra." -#: panels/user-accounts/um-account-dialog.c:1048 +#: panels/user-accounts/um-account-dialog.c:1047 msgid "" "That login password didn’t work.\n" "Please try again." @@ -6773,11 +6996,11 @@ msgstr "" "A bejelentkezési jelszó nem működik.\n" "Próbálja újra." -#: panels/user-accounts/um-account-dialog.c:1056 +#: panels/user-accounts/um-account-dialog.c:1055 msgid "Failed to log into domain" msgstr "Nem sikerült bejelentkezni a tartományba" -#: panels/user-accounts/um-account-dialog.c:1114 +#: panels/user-accounts/um-account-dialog.c:1113 msgid "Unable to find the domain. Maybe you misspelled it?" msgstr "A tartomány nem található. Lehet, hogy elgépelte?" @@ -6911,7 +7134,7 @@ msgstr "%s – %s" #. Translators: This is a time format string in the style of "22:58". #. It indicates a login time which follows a date. #: panels/user-accounts/um-history-dialog.c:177 -#: panels/user-accounts/um-user-panel.c:767 +#: panels/user-accounts/um-user-panel.c:766 msgctxt "login date-time" msgid "%k:%M" msgstr "%k.%M" @@ -6919,7 +7142,7 @@ msgstr "%k.%M" #. Translators: This indicates a login date-time. #. The first %s is a date, and the second %s a time. #: panels/user-accounts/um-history-dialog.c:180 -#: panels/user-accounts/um-user-panel.c:771 +#: panels/user-accounts/um-user-panel.c:770 #, c-format msgctxt "login date-time" msgid "%s, %s" @@ -6956,58 +7179,57 @@ msgstr "A jelszót nem sikerült megváltoztatni" msgid "The passwords do not match." msgstr "A jelszavak nem egyeznek." -#: panels/user-accounts/um-photo-dialog.c:226 +#: panels/user-accounts/um-photo-dialog.c:227 msgid "Browse for more pictures" msgstr "További képek tallózása" -#: panels/user-accounts/um-realm-manager.c:350 +#: panels/user-accounts/um-realm-manager.c:310 msgid "Cannot automatically join this type of domain" msgstr "Ilyen típusú tartományhoz nem lehet automatikusan csatlakozni" -#: panels/user-accounts/um-realm-manager.c:413 -#, c-format +#: panels/user-accounts/um-realm-manager.c:313 msgid "No such domain or realm found" msgstr "Nem található ilyen tartomány vagy zóna" -#: panels/user-accounts/um-realm-manager.c:815 -#: panels/user-accounts/um-realm-manager.c:829 +#: panels/user-accounts/um-realm-manager.c:735 +#: panels/user-accounts/um-realm-manager.c:749 #, c-format msgid "Cannot log in as %s at the %s domain" msgstr "Nem lehet bejelentkezni %s néven a(z) %s tartományba" -#: panels/user-accounts/um-realm-manager.c:821 +#: panels/user-accounts/um-realm-manager.c:741 msgid "Invalid password, please try again" msgstr "Érvénytelen jelszó, próbálja újra" -#: panels/user-accounts/um-realm-manager.c:834 +#: panels/user-accounts/um-realm-manager.c:754 #, c-format msgid "Couldn’t connect to the %s domain: %s" msgstr "Nem lehet csatlakozni a(z) %s tartományhoz: %s" -#: panels/user-accounts/um-user-panel.c:201 +#: panels/user-accounts/um-user-panel.c:200 msgid "Your account" msgstr "Az Ön fiókja" -#: panels/user-accounts/um-user-panel.c:381 +#: panels/user-accounts/um-user-panel.c:380 msgid "Failed to delete user" msgstr "A felhasználó törlése meghiúsult" -#: panels/user-accounts/um-user-panel.c:439 -#: panels/user-accounts/um-user-panel.c:498 -#: panels/user-accounts/um-user-panel.c:550 +#: panels/user-accounts/um-user-panel.c:438 +#: panels/user-accounts/um-user-panel.c:497 +#: panels/user-accounts/um-user-panel.c:549 msgid "Failed to revoke remotely managed user" msgstr "A távmenedzselt felhasználó visszavonása meghiúsult" -#: panels/user-accounts/um-user-panel.c:604 +#: panels/user-accounts/um-user-panel.c:603 msgid "You cannot delete your own account." msgstr "Nem törölheti saját fiókját." -#: panels/user-accounts/um-user-panel.c:613 +#: panels/user-accounts/um-user-panel.c:612 #, c-format msgid "%s is still logged in" msgstr "%s még be van jelentkezve" -#: panels/user-accounts/um-user-panel.c:617 +#: panels/user-accounts/um-user-panel.c:616 msgid "" "Deleting a user while they are logged in can leave the system in an " "inconsistent state." @@ -7015,12 +7237,12 @@ msgstr "" "A bejelentkezett felhasználók törlése a rendszert inkonzisztens állapotban " "hagyhatja." -#: panels/user-accounts/um-user-panel.c:626 +#: panels/user-accounts/um-user-panel.c:625 #, c-format msgid "Do you want to keep %s’s files?" msgstr "Meg szeretné tartani %s fájljait?" -#: panels/user-accounts/um-user-panel.c:630 +#: panels/user-accounts/um-user-panel.c:629 msgid "" "It is possible to keep the home directory, mail spool and temporary files " "around when deleting a user account." @@ -7028,47 +7250,47 @@ msgstr "" "Felhasználói fiók törlésekor lehetősége van a saját könyvtár, a levelezési " "várólista és az ideiglenes fájlok megtartására." -#: panels/user-accounts/um-user-panel.c:633 +#: panels/user-accounts/um-user-panel.c:632 msgid "_Delete Files" msgstr "Fájlok _törlése" -#: panels/user-accounts/um-user-panel.c:634 +#: panels/user-accounts/um-user-panel.c:633 msgid "_Keep Files" msgstr "Fájlok _megtartása" -#: panels/user-accounts/um-user-panel.c:648 +#: panels/user-accounts/um-user-panel.c:647 #, c-format msgid "Are you sure you want to revoke remotely managed %s’s account?" msgstr "Biztosan vissza szeretné vonni a távmenedzselt %s fiókját?" -#: panels/user-accounts/um-user-panel.c:652 +#: panels/user-accounts/um-user-panel.c:651 msgid "_Delete" msgstr "_Törlés" -#: panels/user-accounts/um-user-panel.c:702 +#: panels/user-accounts/um-user-panel.c:701 msgctxt "Password mode" msgid "Account disabled" msgstr "Fiók letiltva" -#: panels/user-accounts/um-user-panel.c:710 +#: panels/user-accounts/um-user-panel.c:709 msgctxt "Password mode" msgid "To be set at next login" msgstr "Következő belépéskor állítandó be" -#: panels/user-accounts/um-user-panel.c:713 +#: panels/user-accounts/um-user-panel.c:712 msgctxt "Password mode" msgid "None" msgstr "Nincs" -#: panels/user-accounts/um-user-panel.c:760 +#: panels/user-accounts/um-user-panel.c:759 msgid "Logged in" msgstr "Bejelentkezve" -#: panels/user-accounts/um-user-panel.c:1107 +#: panels/user-accounts/um-user-panel.c:1106 msgid "Failed to contact the accounts service" msgstr "A fiókszolgáltatás nem érhető el" -#: panels/user-accounts/um-user-panel.c:1109 +#: panels/user-accounts/um-user-panel.c:1108 msgid "Please make sure that the AccountService is installed and enabled." msgstr "Győződjön meg róla, hogy az AccountService telepítve van és fut." @@ -7076,7 +7298,7 @@ msgstr "Győződjön meg róla, hogy az AccountService telepítve van és fut." #. * We split the line in 2 here to "make it look good", as there's #. * no good way to do this in GTK+ for tooltips. See: #. * https://bugzilla.gnome.org/show_bug.cgi?id=657168 -#: panels/user-accounts/um-user-panel.c:1141 +#: panels/user-accounts/um-user-panel.c:1140 msgid "" "To make changes,\n" "click the * icon first" @@ -7084,12 +7306,12 @@ msgstr "" "A módosítások végrehajtásához\n" "előbb kattintson a * ikonra" -#: panels/user-accounts/um-user-panel.c:1181 +#: panels/user-accounts/um-user-panel.c:1180 msgid "Create a user account" msgstr "Felhasználói fiók létrehozása" -#: panels/user-accounts/um-user-panel.c:1192 -#: panels/user-accounts/um-user-panel.c:1371 +#: panels/user-accounts/um-user-panel.c:1191 +#: panels/user-accounts/um-user-panel.c:1370 msgid "" "To create a user account,\n" "click the * icon first" @@ -7097,12 +7319,12 @@ msgstr "" "Felhasználói fiók létrehozásához\n" "először kattintson a * ikonra" -#: panels/user-accounts/um-user-panel.c:1202 +#: panels/user-accounts/um-user-panel.c:1201 msgid "Delete the selected user account" msgstr "Kijelölt felhasználói fiók törlése" -#: panels/user-accounts/um-user-panel.c:1214 -#: panels/user-accounts/um-user-panel.c:1376 +#: panels/user-accounts/um-user-panel.c:1213 +#: panels/user-accounts/um-user-panel.c:1375 msgid "" "To delete the selected user account,\n" "click the * icon first" @@ -7377,35 +7599,35 @@ msgstr "" "A vezérlőközpont a GNOME elsődleges felülete az asztali környezet különböző " "jellemzőinek beállításához." -#: shell/cc-application.c:47 +#: shell/cc-application.c:60 msgid "Display version number" msgstr "Verziószám kiírása" -#: shell/cc-application.c:48 +#: shell/cc-application.c:61 msgid "Enable verbose mode" msgstr "Részletes mód engedélyezése" -#: shell/cc-application.c:49 +#: shell/cc-application.c:62 msgid "Show the overview" msgstr "Áttekintés megjelenítése" -#: shell/cc-application.c:50 +#: shell/cc-application.c:63 msgid "Search for the string" msgstr "Karakterlánc keresése" -#: shell/cc-application.c:51 +#: shell/cc-application.c:64 msgid "List possible panel names and exit" msgstr "Lehetséges panelnevek felsorolása és kilépés" -#: shell/cc-application.c:52 +#: shell/cc-application.c:65 msgid "Panel to display" msgstr "Megjelenítendő panel" -#: shell/cc-application.c:52 +#: shell/cc-application.c:65 msgid "[PANEL] [ARGUMENT…]" msgstr "[PANEL] [ARGUMENTUM…]" -#: shell/cc-application.c:117 +#: shell/cc-application.c:136 msgid "Available panels:" msgstr "Elérhető panelek:" @@ -7457,12 +7679,6 @@ msgctxt "shortcut window" msgid "Cancel search" msgstr "Keresés megszakítása" -#. translators: This is the default hotspot name, need to be less than 32-bytes -#: shell/hostname-helper.c:189 -msgctxt "hotspot" -msgid "Hotspot" -msgstr "Hotspot" - #: shell/org.gnome.ControlCenter.gschema.xml:5 msgid "The identifier for the last Settings panel to be opened" msgstr "Az azonosító a megnyitandó legutolsó Beállítások panelhez" @@ -7472,8 +7688,9 @@ msgid "" "The identifier for the last Settings panel to be opened. Unrecognised values " "will be ignored and the first panel in the list selected." msgstr "" -"Az azonosító a megnyitandó legutolsó Beállítások panelhez. A felismerhetetlen " -"értékek mellőzve lesznek, és a listában lévő első panel kerül kiválasztásra." +"Az azonosító a megnyitandó legutolsó Beállítások panelhez. A " +"felismerhetetlen értékek mellőzve lesznek, és a listában lévő első panel " +"kerül kiválasztásra." #: shell/panel-list.ui:195 msgid "No results found" -- cgit v1.2.1 From 8fa0f6eecd535cec55fbaeb6384a53b66fa09003 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emin=20Tufan=20=C3=87etin?= Date: Sun, 6 May 2018 18:48:01 +0000 Subject: Update Turkish translation --- po/tr.po | 879 +++++++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 540 insertions(+), 339 deletions(-) diff --git a/po/tr.po b/po/tr.po index 7ac15732f..16cf51c14 100644 --- a/po/tr.po +++ b/po/tr.po @@ -11,22 +11,23 @@ # Muhammet Kara , 2011, 2012, 2013, 2014, 2015, 2016, 2017. # Emin Tufan Çetin , 2013, 2016, 2017, 2018. # Furkan Ahmet Kara , 2018. +# Çağatay Yiğit Şahin , 2018. # msgid "" msgstr "" "Project-Id-Version: gnome-control-center\n" "Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-control-center/" "issues\n" -"POT-Creation-Date: 2018-02-23 19:10+0000\n" -"PO-Revision-Date: 2018-02-24 17:06+0200\n" -"Last-Translator: Furkan Ahmet Kara \n" +"POT-Creation-Date: 2018-05-03 08:05+0000\n" +"PO-Revision-Date: 2018-05-06 15:04+0300\n" +"Last-Translator: Emin Tufan Çetin \n" "Language-Team: Türkçe \n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Gtranslator 2.91.7\n" +"X-Generator: Poedit 2.0.7\n" #: panels/background/background.ui:49 msgid "_Background" @@ -112,16 +113,16 @@ msgstr "" "gözükecektir" #: panels/background/cc-background-chooser-dialog.c:560 -#: panels/color/cc-color-panel.c:225 panels/color/cc-color-panel.c:963 +#: panels/color/cc-color-panel.c:224 panels/color/cc-color-panel.c:962 #: panels/color/color-calibrate.ui:25 panels/color/color.ui:657 -#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2594 +#: panels/common/language-chooser.ui:23 panels/display/cc-display-panel.c:2610 #: panels/network/connection-editor/connection-editor.ui:15 #: panels/network/connection-editor/vpn-helpers.c:181 #: panels/network/connection-editor/vpn-helpers.c:310 #: panels/network/net-device-wifi.c:1411 panels/network/net-device-wifi.c:1491 #: panels/network/net-device-wifi.c:1736 panels/network/network-wifi.ui:24 #: panels/printers/new-printer-dialog.ui:45 -#: panels/printers/pp-details-dialog.c:331 +#: panels/printers/pp-details-dialog.c:330 #: panels/privacy/cc-privacy-panel.c:1053 panels/region/format-chooser.ui:25 #: panels/region/input-chooser.ui:13 #: panels/search/cc-search-locations-dialog.c:642 @@ -130,10 +131,10 @@ msgstr "" #: panels/user-accounts/data/join-dialog.ui:20 #: panels/user-accounts/data/password-dialog.ui:21 #: panels/user-accounts/um-fingerprint-dialog.c:261 -#: panels/user-accounts/um-photo-dialog.c:102 -#: panels/user-accounts/um-photo-dialog.c:229 -#: panels/user-accounts/um-user-panel.c:635 -#: panels/user-accounts/um-user-panel.c:653 +#: panels/user-accounts/um-photo-dialog.c:103 +#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-user-panel.c:634 +#: panels/user-accounts/um-user-panel.c:652 msgid "_Cancel" msgstr "_İptal" @@ -178,39 +179,39 @@ msgstr "preferences-desktop-wallpaper" msgid "Wallpaper;Screen;Desktop;" msgstr "Duvar kağıdı;Ekran;Masaüstü;" -#: panels/bluetooth/cc-bluetooth-panel.c:265 +#: panels/bluetooth/cc-bluetooth-panel.c:266 msgid "Turn Off Airplane Mode" msgstr "Uçak Kipini Kapat" -#: panels/bluetooth/cc-bluetooth-panel.c:330 +#: panels/bluetooth/cc-bluetooth-panel.c:329 msgid "No Bluetooth Found" msgstr "Bluetooth Bulunamadı" -#: panels/bluetooth/cc-bluetooth-panel.c:330 +#: panels/bluetooth/cc-bluetooth-panel.c:329 msgid "Plug in a dongle to use Bluetooth." msgstr "Bluetooth özelliğini kullanmak için aygıt takmalısınız." -#: panels/bluetooth/cc-bluetooth-panel.c:331 +#: panels/bluetooth/cc-bluetooth-panel.c:330 msgid "Bluetooth Turned Off" msgstr "Bluetooth Kapatıldı" -#: panels/bluetooth/cc-bluetooth-panel.c:331 +#: panels/bluetooth/cc-bluetooth-panel.c:330 msgid "Turn on to connect devices and receive file transfers." msgstr "Aygıtlara bağlanmak ve dosya aktarımı yapmak için açın." -#: panels/bluetooth/cc-bluetooth-panel.c:332 +#: panels/bluetooth/cc-bluetooth-panel.c:331 msgid "Airplane Mode is on" msgstr "Uçak Kipi açık" -#: panels/bluetooth/cc-bluetooth-panel.c:332 +#: panels/bluetooth/cc-bluetooth-panel.c:331 msgid "Bluetooth is disabled when airplane mode is on." msgstr "Uçak kipi açıldığında Bluetooth devre dışı kalır." -#: panels/bluetooth/cc-bluetooth-panel.c:333 +#: panels/bluetooth/cc-bluetooth-panel.c:332 msgid "Hardware Airplane Mode is on" msgstr "Donanımsal Uçak Kipi açık" -#: panels/bluetooth/cc-bluetooth-panel.c:333 +#: panels/bluetooth/cc-bluetooth-panel.c:332 msgid "Turn off the Airplane mode switch to enable Bluetooth." msgstr "Bluetooth’u etkinleştirmek için Uçak kipini kapat." @@ -235,14 +236,14 @@ msgid "share;sharing;bluetooth;obex;" msgstr "paylaş;paylaşım;bluetooth;obex;" #. TRANSLATORS: The user has to attach the sensor to the screen -#: panels/color/cc-color-calibrate.c:361 +#: panels/color/cc-color-calibrate.c:363 msgid "Place your calibration device over the square and press “Start”" msgstr "Kalibrasyon aygıtınızı karenin üzerine yerleştirin ve “Başlat”a basın" #. TRANSLATORS: Some calibration devices need the user to move a #. * dial or switch manually. We also show a picture showing them #. * what to do... -#: panels/color/cc-color-calibrate.c:367 +#: panels/color/cc-color-calibrate.c:369 msgid "" "Move your calibration device to the calibrate position and press “Continue”" msgstr "Kalibrasyon aygıtınızı kalibrasyon konumuna getirip “Devam Et”e basın" @@ -250,7 +251,7 @@ msgstr "Kalibrasyon aygıtınızı kalibrasyon konumuna getirip “Devam Et”e #. TRANSLATORS: Some calibration devices need the user to move a #. * dial or switch manually. We also show a picture showing them #. * what to do... -#: panels/color/cc-color-calibrate.c:373 +#: panels/color/cc-color-calibrate.c:375 msgid "" "Move your calibration device to the surface position and press “Continue”" msgstr "Kalibrasyon aygıtınızı yüzey konumuna getirip “Devam Et”e basın" @@ -258,54 +259,54 @@ msgstr "Kalibrasyon aygıtınızı yüzey konumuna getirip “Devam Et”e bası #. TRANSLATORS: on some hardware e.g. Lenovo W700 the sensor #. * is built into the palmrest and we need to fullscreen the #. * sample widget and shut the lid. -#: panels/color/cc-color-calibrate.c:379 +#: panels/color/cc-color-calibrate.c:381 msgid "Shut the laptop lid" msgstr "Dizüstü bilgisayarın kapağını kapat" #. TRANSLATORS: We suck, the calibation failed and we have no #. * good idea why or any suggestions -#: panels/color/cc-color-calibrate.c:410 +#: panels/color/cc-color-calibrate.c:412 msgid "An internal error occurred that could not be recovered." msgstr "Telafi edilemeyecek bir iç hata oluştu." #. TRANSLATORS: Some required-at-runtime tools were not #. * installed, which should only affect insane distros -#: panels/color/cc-color-calibrate.c:415 +#: panels/color/cc-color-calibrate.c:417 msgid "Tools required for calibration are not installed." msgstr "Kalibrasyon için gerekli araçlar kurulu değil." #. TRANSLATORS: The profile failed for some reason -#: panels/color/cc-color-calibrate.c:421 +#: panels/color/cc-color-calibrate.c:423 msgid "The profile could not be generated." msgstr "Profil oluşturulamadı." #. TRANSLATORS: The user specified a whitepoint that was #. * unobtainable with the hardware they've got -- see #. * https://en.wikipedia.org/wiki/White_point for details -#: panels/color/cc-color-calibrate.c:427 +#: panels/color/cc-color-calibrate.c:429 msgid "The target whitepoint was not obtainable." msgstr "Hedef beyaznokta bulunabilir değildi." #. TRANSLATORS: the display calibration process is finished -#: panels/color/cc-color-calibrate.c:467 +#: panels/color/cc-color-calibrate.c:469 msgid "Complete!" msgstr "Tamamlandı!" #. TRANSLATORS: the display calibration failed, and we also show #. * the translated (or untranslated) error string after this -#: panels/color/cc-color-calibrate.c:475 +#: panels/color/cc-color-calibrate.c:477 msgid "Calibration failed!" msgstr "Kalibrasyon başarısız!" #. TRANSLATORS: The user can now remove the sensor from the screen -#: panels/color/cc-color-calibrate.c:482 +#: panels/color/cc-color-calibrate.c:484 msgid "You can remove the calibration device." msgstr "Kalibrasyon aygıtını çıkartabilirsiniz." #. TRANSLATORS: The user has to be careful not to knock the #. * display off the screen (although we do cope if this is #. * detected early enough) -#: panels/color/cc-color-calibrate.c:553 +#: panels/color/cc-color-calibrate.c:556 msgid "Do not disturb the calibration device while in progress" msgstr "Kalibrasyon esnasında kalibrasyon aygıtıyla oynamayın" @@ -367,48 +368,48 @@ msgstr "Kalibrasyon yok" #. TRANSLATORS: this is a profile prefix to signify the #. * profile has been auto-generated for this hardware -#: panels/color/cc-color-panel.c:141 +#: panels/color/cc-color-panel.c:140 msgid "Default: " -msgstr "Öntanımlı:" +msgstr "Öntanımlı: " #. TRANSLATORS: this is a profile prefix to signify the #. * profile his a standard space like AdobeRGB -#: panels/color/cc-color-panel.c:149 +#: panels/color/cc-color-panel.c:148 msgid "Colorspace: " msgstr "Colorspace: " #. TRANSLATORS: this is a profile prefix to signify the #. * profile is a test profile -#: panels/color/cc-color-panel.c:156 +#: panels/color/cc-color-panel.c:155 msgid "Test profile: " msgstr "Sınama profili: " #. TRANSLATORS: an ICC profile is a file containing colorspace data -#: panels/color/cc-color-panel.c:223 +#: panels/color/cc-color-panel.c:222 msgid "Select ICC Profile File" msgstr "ICC Profil Dosyasını Seç" -#: panels/color/cc-color-panel.c:226 +#: panels/color/cc-color-panel.c:225 msgid "_Import" msgstr "_İçe Aktar" #. TRANSLATORS: filter name on the file->open dialog -#: panels/color/cc-color-panel.c:237 +#: panels/color/cc-color-panel.c:236 msgid "Supported ICC profiles" msgstr "Desteklenen ICC profilleri" #. TRANSLATORS: filter name on the file->open dialog -#: panels/color/cc-color-panel.c:244 +#: panels/color/cc-color-panel.c:243 #: panels/network/wireless-security/eap-method-fast.c:417 msgid "All files" msgstr "Tüm dosyalar" -#: panels/color/cc-color-panel.c:583 +#: panels/color/cc-color-panel.c:582 msgid "Screen" msgstr "Ekran" #. TRANSLATORS: this is when the upload of the profile failed -#: panels/color/cc-color-panel.c:908 +#: panels/color/cc-color-panel.c:907 #, c-format msgid "Failed to upload file: %s" msgstr "Dosya yüklenmesi başarısız: %s" @@ -416,40 +417,40 @@ msgstr "Dosya yüklenmesi başarısız: %s" #. TRANSLATORS: these are instructions on how to recover #. * the ICC profile on the native operating system and are #. * only shown when the user uses a LiveCD to calibrate -#: panels/color/cc-color-panel.c:922 +#: panels/color/cc-color-panel.c:921 msgid "The profile has been uploaded to:" msgstr "Profil şuraya yüklendi:" -#: panels/color/cc-color-panel.c:924 +#: panels/color/cc-color-panel.c:923 msgid "Write down this URL." msgstr "Bu URL’yi not edin." -#: panels/color/cc-color-panel.c:925 +#: panels/color/cc-color-panel.c:924 msgid "Restart this computer and boot your normal operating system." msgstr "" "Bu bilgisayarı yeniden başlatın ve olağan işletim sisteminizi başlatın." -#: panels/color/cc-color-panel.c:926 +#: panels/color/cc-color-panel.c:925 msgid "Type the URL into your browser to download and install the profile." msgstr "Profili indirmek ve yüklemek için adresi tarayıcınıza yazın." #. TRANSLATORS: this is the dialog to save the ICC profile -#: panels/color/cc-color-panel.c:960 +#: panels/color/cc-color-panel.c:959 msgid "Save Profile" msgstr "Profili Kaydet" -#: panels/color/cc-color-panel.c:964 +#: panels/color/cc-color-panel.c:963 #: panels/network/connection-editor/vpn-helpers.c:311 msgid "_Save" msgstr "_Kaydet" #. TRANSLATORS: this is when the button is sensitive -#: panels/color/cc-color-panel.c:1325 +#: panels/color/cc-color-panel.c:1324 msgid "Create a color profile for the selected device" msgstr "Seçilen aygıt için bir renk profili oluştur" #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1340 panels/color/cc-color-panel.c:1364 +#: panels/color/cc-color-panel.c:1339 panels/color/cc-color-panel.c:1363 msgid "" "The measuring instrument is not detected. Please check it is turned on and " "correctly connected." @@ -458,12 +459,12 @@ msgstr "" "bağlandığından emin olunuz." #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1374 +#: panels/color/cc-color-panel.c:1373 msgid "The measuring instrument does not support printer profiling." msgstr "Ölçüm aygıtı yazıcı profillemeyi desteklemiyor." #. TRANSLATORS: this is when the button is insensitive -#: panels/color/cc-color-panel.c:1385 +#: panels/color/cc-color-panel.c:1384 msgid "The device type is not currently supported." msgstr "Aygıt türü şu anda desteklenmiyor." @@ -867,7 +868,7 @@ msgstr "Renk" msgid "" "Calibrate the color of your devices, such as displays, cameras or printers" msgstr "" -"Ekran, kamera veya yazıcı gibi aygıtlarınızın renk kalibrasyonunu yapın." +"Ekran, kamera veya yazıcı gibi aygıtlarınızın renk kalibrasyonunu yapın" #. Translators: Do NOT translate or transliterate this text (this is an icon file name)! #: panels/color/gnome-color-panel.desktop.in.in:7 @@ -912,6 +913,12 @@ msgstr "%e %b" msgid "%b %e, %Y" msgstr "%e %b, %Y" +#. translators: This is the default hotspot name, need to be less than 32-bytes +#: panels/common/hostname-helper.c:189 +msgctxt "hotspot" +msgid "Hotspot" +msgstr "Erişim Noktası" + #: panels/common/language-chooser.ui:5 msgid "Language" msgstr "Dil" @@ -1040,7 +1047,7 @@ msgstr "Saat" #. Translator: this is the separator between hours and minutes, like in HH∶MM #: panels/datetime/datetime.ui:121 msgid "∶" -msgstr ":" +msgstr "∶" #: panels/datetime/datetime.ui:143 msgid "Minute" @@ -1110,58 +1117,58 @@ msgstr "" "Saat ya da tarih ayarlarını değiştirmek için kimliğinizi doğrulamanız " "gerekiyor." -#: panels/display/cc-display-panel.c:729 +#: panels/display/cc-display-panel.c:739 msgctxt "Display rotation" msgid "Landscape" msgstr "Yatay" -#: panels/display/cc-display-panel.c:732 +#: panels/display/cc-display-panel.c:742 msgctxt "Display rotation" msgid "Portrait Right" msgstr "Dikey Sağ" -#: panels/display/cc-display-panel.c:735 +#: panels/display/cc-display-panel.c:745 msgctxt "Display rotation" msgid "Portrait Left" msgstr "Dikey Sol" -#: panels/display/cc-display-panel.c:738 +#: panels/display/cc-display-panel.c:748 msgctxt "Display rotation" msgid "Landscape (flipped)" msgstr "Yatay (ters yüz)" #. Translators: This option sets orientation of print (portrait, landscape...) -#: panels/display/cc-display-panel.c:805 +#: panels/display/cc-display-panel.c:816 #: panels/printers/pp-options-dialog.c:558 msgid "Orientation" msgstr "Yönelim" -#: panels/display/cc-display-panel.c:870 panels/display/cc-display-panel.c:1673 +#: panels/display/cc-display-panel.c:885 panels/display/cc-display-panel.c:1691 #: panels/printers/pp-options-dialog.c:87 msgid "Resolution" msgstr "Çözünürlük" -#: panels/display/cc-display-panel.c:958 +#: panels/display/cc-display-panel.c:974 msgid "Refresh Rate" msgstr "Tazeleme Hızı" -#: panels/display/cc-display-panel.c:1095 +#: panels/display/cc-display-panel.c:1111 msgid "Scale" msgstr "Ölçekle" -#: panels/display/cc-display-panel.c:1148 +#: panels/display/cc-display-panel.c:1164 msgid "Adjust for TV" msgstr "TV için Ayarla" -#: panels/display/cc-display-panel.c:1410 +#: panels/display/cc-display-panel.c:1427 msgid "Primary Display" msgstr "Birincil Ekran" -#: panels/display/cc-display-panel.c:1439 +#: panels/display/cc-display-panel.c:1456 msgid "Display Arrangement" msgstr "Ekran Düzeni" -#: panels/display/cc-display-panel.c:1440 +#: panels/display/cc-display-panel.c:1457 msgid "" "Drag displays to match your setup. The top bar is placed on the primary " "display." @@ -1169,59 +1176,67 @@ msgstr "" "Ekranları, düzeninizle eşleşecek şekilde sürükleyin. Üst çubuk, birincil " "ekranda gösterilir." -#: panels/display/cc-display-panel.c:1863 +#: panels/display/cc-display-panel.c:1881 msgid "Display Mode" msgstr "Ekran Kipi" -#: panels/display/cc-display-panel.c:1879 +#: panels/display/cc-display-panel.c:1897 msgid "Join Displays" msgstr "Ekranları Birleştir" -#: panels/display/cc-display-panel.c:1882 +#: panels/display/cc-display-panel.c:1900 msgid "Mirror" msgstr "Aynala" -#: panels/display/cc-display-panel.c:1885 +#: panels/display/cc-display-panel.c:1903 msgid "Single Display" msgstr "Tek Ekran" -#: panels/display/cc-display-panel.c:2590 -msgid "Apply Changes?" -msgstr "Değişiklikler Uygulansın Mı?" - -#: panels/display/cc-display-panel.c:2604 +#: panels/display/cc-display-panel.c:2620 #: panels/network/connection-editor/connection-editor.ui:24 #: panels/network/network-wifi.ui:38 msgid "_Apply" msgstr "Uygul_a" -#: panels/display/cc-display-panel.c:2979 +#: panels/display/cc-display-panel.c:2642 +msgid "Apply Changes?" +msgstr "Değişiklikler Uygulansın Mı?" + +#: panels/display/cc-display-panel.c:2647 +msgid "Changes Cannot be Applied" +msgstr "Değişiklikler Uygulanamadı" + +#: panels/display/cc-display-panel.c:2648 +msgid "This could be due to hardware limitations." +msgstr "Bu donanım kısıtlamalarından kaynaklanabilir." + +#: panels/display/cc-display-panel.c:3003 #, c-format msgid "%.2lf Hz" msgstr "%.2lf Hz" #. TRANSLATORS: the state of the night light setting -#: panels/display/cc-display-panel.c:3195 +#: panels/display/cc-display-panel.c:3219 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1991 panels/power/cc-power-panel.c:1998 -#: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 -#: panels/universal-access/cc-ua-panel.c:333 -#: panels/universal-access/cc-ua-panel.c:714 -#: panels/universal-access/cc-ua-panel.c:727 -#: panels/universal-access/cc-ua-panel.c:739 -#: panels/universal-access/cc-ua-panel.c:910 +#: panels/power/cc-power-panel.c:2097 panels/power/cc-power-panel.c:2104 +#: panels/privacy/cc-privacy-panel.c:191 panels/privacy/cc-privacy-panel.c:258 +#: panels/universal-access/cc-ua-panel.c:334 +#: panels/universal-access/cc-ua-panel.c:715 +#: panels/universal-access/cc-ua-panel.c:728 +#: panels/universal-access/cc-ua-panel.c:740 +#: panels/universal-access/cc-ua-panel.c:911 msgid "On" msgstr "Açık" -#: panels/display/cc-display-panel.c:3195 panels/network/net-proxy.c:54 +#: panels/display/cc-display-panel.c:3219 panels/network/net-proxy.c:54 #: panels/notifications/cc-notifications-panel.c:292 -#: panels/power/cc-power-panel.c:1985 panels/power/cc-power-panel.c:1996 -#: panels/privacy/cc-privacy-panel.c:190 panels/privacy/cc-privacy-panel.c:257 -#: panels/universal-access/cc-ua-panel.c:333 -#: panels/universal-access/cc-ua-panel.c:714 -#: panels/universal-access/cc-ua-panel.c:727 -#: panels/universal-access/cc-ua-panel.c:739 -#: panels/universal-access/cc-ua-panel.c:910 panels/universal-access/uap.ui:334 +#: panels/power/cc-power-panel.c:2091 panels/power/cc-power-panel.c:2102 +#: panels/privacy/cc-privacy-panel.c:191 panels/privacy/cc-privacy-panel.c:258 +#: panels/universal-access/cc-ua-panel.c:334 +#: panels/universal-access/cc-ua-panel.c:715 +#: panels/universal-access/cc-ua-panel.c:728 +#: panels/universal-access/cc-ua-panel.c:740 +#: panels/universal-access/cc-ua-panel.c:911 panels/universal-access/uap.ui:334 #: panels/universal-access/uap.ui:380 panels/universal-access/uap.ui:426 #: panels/universal-access/uap.ui:532 panels/universal-access/uap.ui:685 #: panels/universal-access/uap.ui:731 panels/universal-access/uap.ui:777 @@ -1229,11 +1244,11 @@ msgstr "Açık" msgid "Off" msgstr "Kapalı" -#: panels/display/cc-display-panel.c:3216 +#: panels/display/cc-display-panel.c:3240 msgid "_Night Light" msgstr "_Gece Işığı" -#: panels/display/cc-display-panel.c:3281 +#: panels/display/cc-display-panel.c:3305 msgid "Could not get screen information" msgstr "Ekran bilgisi alınamadı" @@ -1273,7 +1288,7 @@ msgstr "Gün Batımından Gün Doğumuna" #: panels/network/connection-editor/ip6-page.ui:83 #: panels/network/net-proxy.c:56 panels/network/network-proxy.ui:113 #: panels/network/network-wifi.ui:777 panels/network/network-wifi.ui:1054 -#: panels/privacy/cc-privacy-panel.c:217 +#: panels/privacy/cc-privacy-panel.c:218 msgid "Manual" msgstr "Elle" @@ -1318,12 +1333,12 @@ msgid "" "Panel;Projector;xrandr;Screen;Resolution;Refresh;Monitor;Night;Light;Blue;" "redshift;color;sunset;sunrise;" msgstr "" -"xrandr;Projektör;Ekran;Çözünürlük;Tazele;Yenile;Monitör;Gece;Işık;Mavi;" -"redshift;renk;gün doğumu;gün batımı;" +"Panel;Projektör;Gösterici;xrandr;Ekran;Çözünürlük;Tazele;Yenile;Monitör;Gece;" +"Işık;Mavi;redshift;renk;gün doğumu;gün batımı;" #. TRANSLATORS: AP type -#: panels/info/cc-info-overview-panel.c:374 -#: panels/info/cc-info-overview-panel.c:457 panels/network/panel-common.c:123 +#: panels/info/cc-info-overview-panel.c:373 +#: panels/info/cc-info-overview-panel.c:456 panels/network/panel-common.c:123 msgid "Unknown" msgstr "Bilinmeyen" @@ -1331,24 +1346,24 @@ msgstr "Bilinmeyen" #. * example: #. * "Fedora 25 (Workstation Edition); Build ID: xyz" or #. * "Ubuntu 16.04 LTS; Build ID: jki" -#: panels/info/cc-info-overview-panel.c:465 +#: panels/info/cc-info-overview-panel.c:464 #, c-format msgid "%s; Build ID: %s" msgstr "%s; İnşa Kimliği: %s" #. translators: This is the type of architecture for the OS -#: panels/info/cc-info-overview-panel.c:482 +#: panels/info/cc-info-overview-panel.c:481 #, c-format msgid "64-bit" msgstr "64-bit" #. translators: This is the type of architecture for the OS -#: panels/info/cc-info-overview-panel.c:485 +#: panels/info/cc-info-overview-panel.c:484 #, c-format msgid "32-bit" msgstr "32-bit" -#: panels/info/cc-info-overview-panel.c:775 +#: panels/info/cc-info-overview-panel.c:773 #, c-format msgid "Version %s" msgstr "Sürüm %s" @@ -1679,8 +1694,8 @@ msgstr "Başlatıcılar" msgid "Launch help browser" msgstr "Yardım tarayıcısını çalıştır" -#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:223 -#: shell/cc-window.c:761 shell/gnome-control-center.desktop.in.in:3 +#: panels/keyboard/01-launchers.xml.in:6 shell/cc-window.c:237 +#: shell/cc-window.c:773 shell/gnome-control-center.desktop.in.in:3 #: shell/window.ui:125 msgid "Settings" msgstr "Ayarlar" @@ -1789,7 +1804,7 @@ msgstr "Yüksek karşıtlık açık ya da kapalı" #: panels/keyboard/cc-keyboard-manager.c:506 #: panels/keyboard/cc-keyboard-manager.c:514 -#: panels/keyboard/cc-keyboard-manager.c:822 +#: panels/keyboard/cc-keyboard-manager.c:821 msgid "Custom Shortcuts" msgstr "Özel Kısayollar" @@ -1800,7 +1815,7 @@ msgstr "Özel Kısayollar" #. * The device has been disabled #: panels/keyboard/cc-keyboard-option.c:263 #: panels/keyboard/cc-keyboard-option.c:382 -#: panels/keyboard/keyboard-shortcuts.c:435 +#: panels/keyboard/keyboard-shortcuts.c:434 #: panels/keyboard/shortcut-editor.ui:96 panels/network/network-proxy.ui:123 #: panels/network/network-wifi.ui:782 panels/network/network-wifi.ui:1059 #: panels/user-accounts/um-fingerprint-dialog.c:211 @@ -2099,7 +2114,7 @@ msgid "Single click, secondary button" msgstr "Tek tıklama, ikincil düğme" #. add proxy to device list -#: panels/network/cc-network-panel.c:579 +#: panels/network/cc-network-panel.c:583 msgid "Network proxy" msgstr "Ağ Vekili" @@ -2107,23 +2122,23 @@ msgstr "Ağ Vekili" #. * window for vpn connections, it is also used to display #. * vpn connections in the device list. #. -#: panels/network/cc-network-panel.c:715 panels/network/net-vpn.c:192 -#: panels/network/net-vpn.c:321 +#: panels/network/cc-network-panel.c:719 panels/network/net-vpn.c:167 +#: panels/network/net-vpn.c:296 #, c-format msgid "%s VPN" msgstr "%s VPN" -#: panels/network/cc-network-panel.c:779 panels/network/wifi.ui:282 +#: panels/network/cc-network-panel.c:783 panels/network/wifi.ui:282 msgid "Oops, something has gone wrong. Please contact your software vendor." msgstr "Aahh, birşeyler ters gitti. Lütfen yazılım sağlayıcınıza başvurun." -#: panels/network/cc-network-panel.c:785 +#: panels/network/cc-network-panel.c:789 msgid "NetworkManager needs to be running." msgstr "NetworkManager’in çalışıyor olması gerekir." -#: panels/network/cc-wifi-panel.c:213 +#: panels/network/cc-wifi-panel.c:214 #: panels/network/gnome-wifi-panel.desktop.in.in:3 -#: panels/network/network-wifi.ui:1766 +#: panels/network/network-wifi.ui:1769 msgid "Wi-Fi" msgstr "Kablosuz" @@ -2266,7 +2281,7 @@ msgid "Remove VPN" msgstr "VPN’yi Kaldır" #: panels/network/connection-editor/ce-page-details.c:334 -#: panels/network/network-wifi.ui:1456 shell/cc-window.c:215 +#: panels/network/network-wifi.ui:1456 shell/cc-window.c:229 #: shell/panel-list.ui:103 msgid "Details" msgstr "Ayrıntılar" @@ -2401,7 +2416,7 @@ msgstr "Veri ücreti veya sınırı olan bağlantılar için uygundur." #: panels/network/connection-editor/ip6-page.ui:291 #: panels/network/net-proxy.c:58 panels/network/network-proxy.ui:103 #: panels/network/wireless-security/eap-method-peap.ui:22 -#: panels/privacy/cc-privacy-panel.c:217 +#: panels/privacy/cc-privacy-panel.c:218 msgid "Automatic" msgstr "Kendiliğinden" @@ -2598,9 +2613,9 @@ msgid "Select file to import" msgstr "İçe aktarılacak dosyayı seçin" #: panels/network/connection-editor/vpn-helpers.c:182 -#: panels/printers/pp-details-dialog.c:332 +#: panels/printers/pp-details-dialog.c:331 #: panels/sharing/cc-sharing-panel.c:385 -#: panels/user-accounts/um-photo-dialog.c:230 +#: panels/user-accounts/um-photo-dialog.c:231 msgid "_Open" msgstr "_Aç" @@ -3022,19 +3037,19 @@ msgctxt "Wi-Fi passkey" msgid "Password" msgstr "Parola" -#: panels/network/network-wifi.ui:1796 +#: panels/network/network-wifi.ui:1799 msgid "Turn Wi-Fi off" msgstr "Kablosuzu Kapat" -#: panels/network/network-wifi.ui:1828 +#: panels/network/network-wifi.ui:1831 msgid "_Connect to Hidden Network…" msgstr "Gizli Ağa _Bağlan…" -#: panels/network/network-wifi.ui:1838 +#: panels/network/network-wifi.ui:1841 msgid "_Turn On Wi-Fi Hotspot…" msgstr "Kablosuz Erişim Nok_tasını Aç…" -#: panels/network/network-wifi.ui:1848 +#: panels/network/network-wifi.ui:1851 msgid "_Known Wi-Fi Networks" msgstr "_Bilinen Wi-Fi Ağları" @@ -3343,23 +3358,23 @@ msgstr "Firmware eksik" msgid "Cable unplugged" msgstr "Kablo takılı değil" -#: panels/network/wireless-security/eap-method.c:57 +#: panels/network/wireless-security/eap-method.c:69 msgid "undefined error in 802.1X security (wpa-eap)" msgstr "802.1X güvenliğinde (wpa-eap) tanımlanmamış hata" -#: panels/network/wireless-security/eap-method.c:233 +#: panels/network/wireless-security/eap-method.c:245 msgid "no file selected" msgstr "hiçbir dosya seçilmedi" -#: panels/network/wireless-security/eap-method.c:264 +#: panels/network/wireless-security/eap-method.c:276 msgid "unspecified error validating eap-method file" msgstr "eap-method dosyası doğrulamada belirtilmemiş hata" -#: panels/network/wireless-security/eap-method.c:439 +#: panels/network/wireless-security/eap-method.c:451 msgid "DER, PEM, or PKCS#12 private keys (*.der, *.pem, *.p12, *.key)" msgstr "DER, PEM, veya PKCS#12 özel anahtarları (*.der, *.pem, *.p12, *.key)" -#: panels/network/wireless-security/eap-method.c:442 +#: panels/network/wireless-security/eap-method.c:454 msgid "DER or PEM certificates (*.der, *.pem, *.crt, *.cer)" msgstr "DER veya PEM sertifikaları (*.der, *.pem, *.crt, *.cer)" @@ -3774,19 +3789,19 @@ msgstr "Diğer" #. translators: This is the title of the "Show Account" dialog. The #. * %s is the name of the provider. e.g., 'Google'. -#: panels/online-accounts/cc-online-accounts-panel.c:551 +#: panels/online-accounts/cc-online-accounts-panel.c:612 #, c-format msgid "%s Account" msgstr "%s Hesabı" -#: panels/online-accounts/cc-online-accounts-panel.c:843 +#: panels/online-accounts/cc-online-accounts-panel.c:904 msgid "Error removing account" msgstr "Hesap silinirken hata oluştu" #. Translators: The %s is the username (eg., debarshi.ray@gmail.com #. * or rishi). #. -#: panels/online-accounts/cc-online-accounts-panel.c:908 +#: panels/online-accounts/cc-online-accounts-panel.c:969 #, c-format msgid "%s removed" msgstr "%s kaldırıldı" @@ -3839,17 +3854,17 @@ msgstr "Hesap ekle" msgid "Remove Account" msgstr "Hesabı Kaldır" -#: panels/power/cc-power-panel.c:253 +#: panels/power/cc-power-panel.c:254 msgid "Unknown time" msgstr "Bilinmeyen süre" -#: panels/power/cc-power-panel.c:259 +#: panels/power/cc-power-panel.c:260 #, c-format msgid "%i minute" msgid_plural "%i minutes" msgstr[0] "%i dakika" -#: panels/power/cc-power-panel.c:271 +#: panels/power/cc-power-panel.c:272 #, c-format msgid "%i hour" msgid_plural "%i hours" @@ -3857,254 +3872,292 @@ msgstr[0] "%i saat" #. TRANSLATOR: "%i %s %i %s" are "%i hours %i minutes" #. * Swap order with "%2$s %2$i %1$s %1$i if needed -#: panels/power/cc-power-panel.c:279 +#: panels/power/cc-power-panel.c:280 #, c-format msgid "%i %s %i %s" msgstr "%i %s %i %s" -#: panels/power/cc-power-panel.c:280 +#: panels/power/cc-power-panel.c:281 msgid "hour" msgid_plural "hours" msgstr[0] "saat" -#: panels/power/cc-power-panel.c:281 +#: panels/power/cc-power-panel.c:282 msgid "minute" msgid_plural "minutes" msgstr[0] "dakika" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:300 +#: panels/power/cc-power-panel.c:301 #, c-format msgid "%s until fully charged" msgstr "Tam dolana kadar %s" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:307 +#: panels/power/cc-power-panel.c:308 #, c-format msgid "Caution: %s remaining" msgstr "Dikkat: %s kaldı" #. TRANSLATORS: %1 is a time string, e.g. "1 hour 5 minutes" -#: panels/power/cc-power-panel.c:312 +#: panels/power/cc-power-panel.c:313 #, c-format msgid "%s remaining" msgstr "%s kaldı" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:317 panels/power/cc-power-panel.c:345 +#: panels/power/cc-power-panel.c:318 panels/power/cc-power-panel.c:346 msgid "Fully charged" msgstr "Tamamen dolu" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:321 panels/power/cc-power-panel.c:349 +#: panels/power/cc-power-panel.c:322 panels/power/cc-power-panel.c:350 msgid "Empty" msgstr "Boş" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:336 +#: panels/power/cc-power-panel.c:337 msgid "Charging" msgstr "Şarj oluyor" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:341 +#: panels/power/cc-power-panel.c:342 msgid "Discharging" msgstr "Boşalıyor" -#: panels/power/cc-power-panel.c:464 +#: panels/power/cc-power-panel.c:465 msgctxt "Battery name" msgid "Main" msgstr "Birincil" -#: panels/power/cc-power-panel.c:466 +#: panels/power/cc-power-panel.c:467 msgctxt "Battery name" msgid "Extra" msgstr "Ek" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:537 +#: panels/power/cc-power-panel.c:538 msgid "Wireless mouse" msgstr "Kablosuz fare" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:540 +#: panels/power/cc-power-panel.c:541 msgid "Wireless keyboard" msgstr "Kablosuz klavye" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:543 +#: panels/power/cc-power-panel.c:544 msgid "Uninterruptible power supply" msgstr "Kesintisiz güç kaynağı" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:546 +#: panels/power/cc-power-panel.c:547 msgid "Personal digital assistant" msgstr "Kişisel sayısal yardımcı (PDA)" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:549 +#: panels/power/cc-power-panel.c:550 msgid "Cellphone" msgstr "Cep telefonu" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:552 +#: panels/power/cc-power-panel.c:553 msgid "Media player" msgstr "Ortam oynatıcısı" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:555 panels/wacom/cc-wacom-panel.c:793 +#: panels/power/cc-power-panel.c:556 panels/wacom/cc-wacom-panel.c:793 msgid "Tablet" msgstr "Tablet" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:558 +#: panels/power/cc-power-panel.c:559 msgid "Computer" msgstr "Bilgisayar" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:561 +#: panels/power/cc-power-panel.c:562 msgid "Gaming input device" msgstr "Oyun girdi aygıtı" #. TRANSLATORS: secondary battery, misc -#: panels/power/cc-power-panel.c:564 panels/power/cc-power-panel.c:804 -#: panels/power/cc-power-panel.c:2377 +#: panels/power/cc-power-panel.c:565 panels/power/cc-power-panel.c:829 +#: panels/power/cc-power-panel.c:2483 msgid "Battery" msgstr "Pil" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:618 +#: panels/power/cc-power-panel.c:632 msgctxt "Battery power" msgid "Charging" msgstr "Doluyor" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:625 +#: panels/power/cc-power-panel.c:639 msgctxt "Battery power" msgid "Caution" msgstr "Dikkat" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:630 +#: panels/power/cc-power-panel.c:644 msgctxt "Battery power" msgid "Low" msgstr "Düşük" #. TRANSLATORS: secondary battery -#: panels/power/cc-power-panel.c:635 +#: panels/power/cc-power-panel.c:649 msgctxt "Battery power" msgid "Good" msgstr "İyi" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:640 +#: panels/power/cc-power-panel.c:654 msgctxt "Battery power" msgid "Fully charged" msgstr "Tamamen dolu" #. TRANSLATORS: primary battery -#: panels/power/cc-power-panel.c:644 +#: panels/power/cc-power-panel.c:658 msgctxt "Battery power" msgid "Empty" msgstr "Boş" -#: panels/power/cc-power-panel.c:802 +#: panels/power/cc-power-panel.c:827 msgid "Batteries" msgstr "Piller" -#: panels/power/cc-power-panel.c:1239 +#: panels/power/cc-power-panel.c:1206 +#, c-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d saat" + +#: panels/power/cc-power-panel.c:1208 +#, c-format +msgid "%d minute" +msgid_plural "%d minutes" +msgstr[0] "%d dakika" + +#: panels/power/cc-power-panel.c:1211 +#, c-format +msgid "%d second" +msgid_plural "%d seconds" +msgstr[0] "%d saniye" + +#. 5 hours 2 minutes 12 seconds +#: panels/power/cc-power-panel.c:1217 +#, c-format +msgctxt "time" +msgid "%s %s %s" +msgstr "%s %s %s" + +#. 2 minutes 12 seconds +#: panels/power/cc-power-panel.c:1220 +#, c-format +msgctxt "time" +msgid "%s %s" +msgstr "%s %s" + +#. 0 seconds +#: panels/power/cc-power-panel.c:1226 +msgid "0 seconds" +msgstr "0 saniye" + +#: panels/power/cc-power-panel.c:1328 msgid "When _idle" msgstr "Bo_şta olduğunda" -#: panels/power/cc-power-panel.c:1693 +#: panels/power/cc-power-panel.c:1793 msgid "Power Saving" msgstr "Güç Tasarrufu" -#: panels/power/cc-power-panel.c:1724 +#: panels/power/cc-power-panel.c:1824 msgid "_Screen brightness" msgstr "_Ekran parlaklığı" -#: panels/power/cc-power-panel.c:1743 +#: panels/power/cc-power-panel.c:1843 msgid "Automatic brightness" msgstr "Kendiliğinden parlaklık" -#: panels/power/cc-power-panel.c:1763 +#: panels/power/cc-power-panel.c:1863 msgid "_Keyboard brightness" msgstr "_Klavye parlaklığı" -#: panels/power/cc-power-panel.c:1773 +#: panels/power/cc-power-panel.c:1873 msgid "_Dim screen when inactive" msgstr "Etkin olunma_dığında ekranı karart" -#: panels/power/cc-power-panel.c:1798 +#: panels/power/cc-power-panel.c:1898 msgid "_Blank screen" msgstr "_Boş Ekran" -#: panels/power/cc-power-panel.c:1835 +#: panels/power/cc-power-panel.c:1935 msgid "_Wi-Fi" msgstr "_Wi-Fi" -#: panels/power/cc-power-panel.c:1840 +#: panels/power/cc-power-panel.c:1940 msgid "Turn off Wi-Fi to save power." msgstr "Enerji tasarrufu için Kablosuz Ağı kapatın." -#: panels/power/cc-power-panel.c:1865 +#: panels/power/cc-power-panel.c:1965 msgid "_Mobile broadband" msgstr "_Mobil Genişbant" -#: panels/power/cc-power-panel.c:1870 +#: panels/power/cc-power-panel.c:1970 msgid "Turn off mobile broadband (3G, 4G, LTE, etc.) to save power." msgstr "Enerji tasarrufu için mobil genişbantı (3G, 4G, LTE, vb.) kapat." -#: panels/power/cc-power-panel.c:1923 +#: panels/power/cc-power-panel.c:2029 msgid "_Bluetooth" msgstr "_Bluetooth" -#: panels/power/cc-power-panel.c:1928 +#: panels/power/cc-power-panel.c:2034 msgid "Turn off Bluetooth to save power." msgstr "Enerji tasarrufu için Bluetoothʼu kapatın." -#: panels/power/cc-power-panel.c:1987 +#: panels/power/cc-power-panel.c:2093 msgid "When on battery power" msgstr "Pille çalışırken" -#: panels/power/cc-power-panel.c:1989 +#: panels/power/cc-power-panel.c:2095 msgid "When plugged in" msgstr "Fişe takıldığında" -#: panels/power/cc-power-panel.c:2084 +#: panels/power/cc-power-panel.c:2190 msgid "Suspend" msgstr "Askıya al" -#: panels/power/cc-power-panel.c:2085 +#: panels/power/cc-power-panel.c:2191 msgid "Power Off" msgstr "Kapat" -#: panels/power/cc-power-panel.c:2086 +#: panels/power/cc-power-panel.c:2192 msgid "Hibernate" msgstr "Derin uyku" -#: panels/power/cc-power-panel.c:2087 +#: panels/power/cc-power-panel.c:2193 msgid "Nothing" msgstr "Hiçbir şey" #. Frame header -#: panels/power/cc-power-panel.c:2201 +#: panels/power/cc-power-panel.c:2307 msgid "Suspend & Power Button" msgstr "Askıya Alma ve Güç Düğmesi" -#: panels/power/cc-power-panel.c:2240 +#: panels/power/cc-power-panel.c:2346 msgid "_Automatic suspend" msgstr "Kendiliğinden _askıya al" -#: panels/power/cc-power-panel.c:2241 +#: panels/power/cc-power-panel.c:2347 msgid "Automatic suspend" msgstr "Kendiliğinden askıya al" -#: panels/power/cc-power-panel.c:2308 +#: panels/power/cc-power-panel.c:2414 msgid "_When the Power Button is pressed" msgstr "Gü_ç düğmesine basıldığında" -#: panels/power/cc-power-panel.c:2427 shell/cc-window.c:219 +#: panels/power/cc-power-panel.c:2533 panels/thunderbolt/cc-bolt-panel.ui:466 +#: panels/thunderbolt/cc-bolt-panel.ui:525 shell/cc-window.c:233 #: shell/panel-list.ui:45 msgid "Devices" msgstr "Aygıtlar" @@ -4237,18 +4290,18 @@ msgid "Authentication Required" msgstr "Kimlik doğrulaması gerekli" #. Translators: %s is the printer name -#: panels/printers/cc-printers-panel.c:791 +#: panels/printers/cc-printers-panel.c:809 #, c-format msgid "Printer “%s” has been deleted" msgstr "“%s” yazıcısı silindi" #. Translators: Addition of the new printer failed. -#: panels/printers/cc-printers-panel.c:1036 +#: panels/printers/cc-printers-panel.c:1054 msgid "Failed to add new printer." msgstr "Yeni yazıcı eklenemedi." #. Translators: The XML file containing user interface can not be loaded -#: panels/printers/cc-printers-panel.c:1371 +#: panels/printers/cc-printers-panel.c:1391 #, c-format msgid "Could not load ui: %s" msgstr "Arayüz yüklenemedi: %s" @@ -4301,7 +4354,6 @@ msgstr "Yazıcı;Kuyruk;Yazdır;Kâğıt;Mürekkep;Toner;" #. Translators: This is a windows domain used with SMB protocol. #: panels/printers/jobs-dialog.ui:44 -#| msgid "_Domain" msgid "Domain" msgstr "Etki Alanı" @@ -4317,7 +4369,6 @@ msgstr "Tümünü Temizle" #. Translators: This button pop up authentication dialog for print jobs which need credentials. #: panels/printers/jobs-dialog.ui:225 -#| msgid "Authenticate" msgid "_Authenticate" msgstr "Kimlik doğrul_ama" @@ -4363,21 +4414,21 @@ msgid "Test Page" msgstr "Deneme Sayfası" #. Translators: This is the title of the dialog. %s is the printer name. -#: panels/printers/pp-details-dialog.c:135 -#: panels/printers/pp-details-dialog.c:435 +#: panels/printers/pp-details-dialog.c:134 +#: panels/printers/pp-details-dialog.c:434 #, c-format msgid "%s Details" msgstr "%s Ayrıntıları" -#: panels/printers/pp-details-dialog.c:184 +#: panels/printers/pp-details-dialog.c:183 msgid "No suitable driver found" msgstr "Uygun sürücü bulunamadı" -#: panels/printers/pp-details-dialog.c:328 +#: panels/printers/pp-details-dialog.c:327 msgid "Select PPD File" msgstr "PPD Dosyası Seç" -#: panels/printers/pp-details-dialog.c:337 +#: panels/printers/pp-details-dialog.c:336 msgid "" "PostScript Printer Description files (*.ppd, *.PPD, *.ppd.gz, *.PPD.gz, *." "PPD.GZ)" @@ -4390,7 +4441,7 @@ msgid "Select Printer Driver" msgstr "Yazıcı Sürücüsü Seçin" #: panels/printers/ppd-selection-dialog.ui:40 -#: panels/user-accounts/um-photo-dialog.c:104 +#: panels/user-accounts/um-photo-dialog.c:105 msgid "Select" msgstr "Seç" @@ -4447,73 +4498,70 @@ msgid "Reverse portrait" msgstr "Ters dikey" #. Translators: Job's state (job is waiting to be printed) -#: panels/printers/pp-jobs-dialog.c:243 +#: panels/printers/pp-jobs-dialog.c:234 msgctxt "print job" msgid "Pending" msgstr "Beklemede" #. Translators: Job's state (job is held for printing) -#: panels/printers/pp-jobs-dialog.c:249 +#: panels/printers/pp-jobs-dialog.c:240 msgctxt "print job" msgid "Paused" msgstr "Duraklatıldı" #. Translators: Job's state (job needs authentication to proceed further) -#: panels/printers/pp-jobs-dialog.c:254 -#| msgid "Authentication required" +#: panels/printers/pp-jobs-dialog.c:245 msgctxt "print job" msgid "Authentication required" msgstr "Kimlik doğrulaması gerekli" #. Translators: Job's state (job is currently printing) -#: panels/printers/pp-jobs-dialog.c:259 +#: panels/printers/pp-jobs-dialog.c:250 msgctxt "print job" msgid "Processing" msgstr "İşleniyor" #. Translators: Job's state (job has been stopped) -#: panels/printers/pp-jobs-dialog.c:263 +#: panels/printers/pp-jobs-dialog.c:254 msgctxt "print job" msgid "Stopped" msgstr "Durduruldu" #. Translators: Job's state (job has been canceled) -#: panels/printers/pp-jobs-dialog.c:267 +#: panels/printers/pp-jobs-dialog.c:258 msgctxt "print job" msgid "Canceled" msgstr "İptal edildi" #. Translators: Job's state (job has aborted due to error) -#: panels/printers/pp-jobs-dialog.c:271 +#: panels/printers/pp-jobs-dialog.c:262 msgctxt "print job" msgid "Aborted" msgstr "Hata nedeniyle iptal edildi" #. Translators: Job's state (job has completed successfully) -#: panels/printers/pp-jobs-dialog.c:275 +#: panels/printers/pp-jobs-dialog.c:266 msgctxt "print job" msgid "Completed" msgstr "Tamamlandı" #. Translators: This label shows how many jobs of this printer needs to be authenticated to be printed. -#: panels/printers/pp-jobs-dialog.c:399 +#: panels/printers/pp-jobs-dialog.c:390 #, c-format -#| msgid "Server requires authentication" msgid "%u Job Requires Authentication" msgid_plural "%u Jobs Require Authentication" msgstr[0] "%u Görev Kimlik Doğrulaması Gerektiriyor" #. Translators: This is the printer name for which we are showing the active jobs -#: panels/printers/pp-jobs-dialog.c:617 +#: panels/printers/pp-jobs-dialog.c:620 #, c-format msgctxt "Printer jobs dialog title" msgid "%s — Active Jobs" msgstr "%s — Etkin Görevler" #. Translators: The printer needs authentication info to print. -#: panels/printers/pp-jobs-dialog.c:622 +#: panels/printers/pp-jobs-dialog.c:625 #, c-format -#| msgid "Enter username and password to view printers on %s." msgid "Enter credentials to print from %s." msgstr "%s üzerinden yazdırmak için kimlik bilgilerini girin." @@ -4877,25 +4925,25 @@ msgstr "" "Üzgünüm! Sistem yazdırma hizmeti\n" "kullanılamıyor." -#: panels/privacy/cc-privacy-panel.c:387 panels/privacy/privacy.ui:280 +#: panels/privacy/cc-privacy-panel.c:388 panels/privacy/privacy.ui:280 msgid "Screen Lock" msgstr "Ekran Kilidi" -#: panels/privacy/cc-privacy-panel.c:438 +#: panels/privacy/cc-privacy-panel.c:439 msgid "In use" msgstr "Kullanımda" -#: panels/privacy/cc-privacy-panel.c:443 +#: panels/privacy/cc-privacy-panel.c:444 msgctxt "Location services status" msgid "On" msgstr "Açık" -#: panels/privacy/cc-privacy-panel.c:444 +#: panels/privacy/cc-privacy-panel.c:445 msgctxt "Location services status" msgid "Off" msgstr "Kapalı" -#: panels/privacy/cc-privacy-panel.c:823 panels/privacy/privacy.ui:745 +#: panels/privacy/cc-privacy-panel.c:825 panels/privacy/privacy.ui:745 msgid "Location Services" msgstr "Konum Hizmetleri" @@ -5157,11 +5205,11 @@ msgctxt "Input Source" msgid "Other" msgstr "Diğer" -#: panels/region/cc-region-panel.c:881 +#: panels/region/cc-region-panel.c:882 msgid "No input source selected" msgstr "Girdi kaynağı seçilmedi" -#: panels/region/cc-region-panel.c:1773 +#: panels/region/cc-region-panel.c:1774 msgid "Login _Screen" msgstr "Oturum A_çma Ekranı" @@ -5386,7 +5434,7 @@ msgid "Preferences" msgstr "Tercihler" #. Label -#: panels/sharing/cc-sharing-networks.c:305 +#: panels/sharing/cc-sharing-networks.c:307 msgid "No networks selected for sharing" msgstr "Paylaşımı için ağ seçilmedi" @@ -5713,7 +5761,7 @@ msgstr "Ses Etkileri" #: panels/sound/gvc-mixer-dialog.c:1754 msgid "_Alert volume:" -msgstr "Uy_arı ses düzeyi: " +msgstr "Uy_arı ses düzeyi:" #: panels/sound/gvc-mixer-dialog.c:1775 msgid "No application is currently playing or recording audio." @@ -5764,34 +5812,203 @@ msgstr "Subwoofer" msgid "Custom" msgstr "Özel" +#: panels/thunderbolt/cc-bolt-device-dialog.c:86 +#: panels/thunderbolt/cc-bolt-device-entry.c:119 +msgctxt "Thunderbolt Device Status" +msgid "Disconnected" +msgstr "Bağlantısı Kesilmiş" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:89 +#: panels/thunderbolt/cc-bolt-device-entry.c:122 +msgctxt "Thunderbolt Device Status" +msgid "Connecting" +msgstr "Bağlanıyor" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:92 +#: panels/thunderbolt/cc-bolt-device-entry.c:126 +#: panels/thunderbolt/cc-bolt-device-entry.c:138 +msgctxt "Thunderbolt Device Status" +msgid "Connected" +msgstr "Bağlı" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:95 +msgctxt "Thunderbolt Device Status" +msgid "Authorization Error" +msgstr "Yetkilendirme Hatası" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:98 +#: panels/thunderbolt/cc-bolt-device-entry.c:132 +msgctxt "Thunderbolt Device Status" +msgid "Authorizing" +msgstr "Yetkilendiriliyor" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:105 +msgctxt "Thunderbolt Device Status" +msgid "Reduced Functionality" +msgstr "Azaltılmış İşlev" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:107 +msgctxt "Thunderbolt Device Status" +msgid "Connected & Authorized" +msgstr "Bağlı ve Yetkilendirilmiş" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:113 +#: panels/thunderbolt/cc-bolt-device-entry.c:146 +msgctxt "Thunderbolt Device Status" +msgid "Unknown" +msgstr "Bilinmeyen" + +#. Translators: The time point the device was authorized. +#: panels/thunderbolt/cc-bolt-device-dialog.c:169 +msgid "Authorized at:" +msgstr "Yetkilendirilmiş:" + +#. Translators: The time point the device was connected. +#: panels/thunderbolt/cc-bolt-device-dialog.c:175 +msgid "Connected at:" +msgstr "Bağlı:" + +#. Translators: The time point the device was enrolled, +#. * i.e. authorized and stored in the device database. +#: panels/thunderbolt/cc-bolt-device-dialog.c:182 +msgid "Enrolled at:" +msgstr "Kaydedilmiş:" + +#: panels/thunderbolt/cc-bolt-device-dialog.c:250 +msgid "Failed to authorize device: " +msgstr "Aygıt yetkilendirilemedi: " + +#: panels/thunderbolt/cc-bolt-device-dialog.c:327 +msgid "Failed to forget device: " +msgstr "Aygıt unutulamadı: " + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:109 +msgid "Name:" +msgstr "Ad:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:141 +msgid "Status:" +msgstr "Durum:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:174 +msgid "UUID:" +msgstr "UUID:" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:280 +msgid "Authorize and Connect" +msgstr "Yetkilendir ve Bağla" + +#: panels/thunderbolt/cc-bolt-device-dialog.ui:303 +msgid "Forget Device" +msgstr "Aygıtı Unut" + +#: panels/thunderbolt/cc-bolt-device-entry.c:129 +msgctxt "Thunderbolt Device Status" +msgid "Error" +msgstr "Hata" + +#: panels/thunderbolt/cc-bolt-device-entry.c:140 +msgctxt "Thunderbolt Device Status" +msgid "Authorized" +msgstr "Yetkilendirilmiş" + +#: panels/thunderbolt/cc-bolt-panel.c:175 +msgid "" +"The Thunderbolt subsystem (boltd) is not installed or not set up properly." +msgstr "" +"Thunderbolt altsistemi (boltd) yüklenmemiş veya doğru şekilde ayarlanmamış." + +#: panels/thunderbolt/cc-bolt-panel.c:460 +msgid "" +"Thunderbolt could not be detected.\n" +"Either the system lacks Thunderbolt support, it has been disabled in the " +"BIOS or is set to an unsupported security level in the BIOS." +msgstr "" +"Thunderbolt algılanamadı.\n" +"Sistemin Thunderbolt desteği yok, BIOS’ta devre dışı bırakılmış veya BIOS’ta " +"desteklenmeyen bir güvenlik düzeyine ayarlanmış." + +#: panels/thunderbolt/cc-bolt-panel.c:504 +msgid "Thunderbolt support has been disabled in the BIOS." +msgstr "Thunderbolt desteği BIOS’ta devre dışı bırakılmış." + +#: panels/thunderbolt/cc-bolt-panel.c:613 +#, c-format +msgid "Error switching direct mode: %s" +msgstr "Doğrudan kipe geçilirken hata: %s" + +#: panels/thunderbolt/cc-bolt-panel.ui:143 +msgid "No Thunderbolt support" +msgstr "Thunderbolt desteği yok" + +#: panels/thunderbolt/cc-bolt-panel.ui:246 +msgid "Direct Access" +msgstr "Doğrudan Erişim" + +#: panels/thunderbolt/cc-bolt-panel.ui:269 +msgid "Allow direct access to devices such as docks and external GPUs." +msgstr "" +"Bağlantı istasyonları ve haricî grafik işlemciler gibi aygıtlara doğrudan " +"erişim tanı." + +#: panels/thunderbolt/cc-bolt-panel.ui:289 +msgid "Only USB and Display Port devices can attach." +msgstr "Yalnızca USB ve Display Port aygıtları bağlanabilir." + +#: panels/thunderbolt/cc-bolt-panel.ui:397 +msgid "Pending Devices" +msgstr "Bekleyen Aygıtlar" + +#: panels/thunderbolt/cc-bolt-panel.ui:535 +msgid "No devices attached" +msgstr "Aygıt bağlanmamış" + +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:3 +msgid "Thunderbolt" +msgstr "Thunderbolt" + +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:4 +msgid "Manage Thunderbolt devices" +msgstr "Thunderbolt aygıtlarını yönet" + +#. Translators: Do NOT translate or transliterate this text (this is an icon file name)! +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:7 +msgid "thunderbolt" +msgstr "thunderbolt" + +#. Translators: those are keywords for the thunderbolt control-center panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +#: panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in:19 +msgid "Thunderbolt;" +msgstr "Thunderbolt;" + #. translators: the labels will read: #. * Cursor Size: Default -#: panels/universal-access/cc-ua-panel.c:353 +#: panels/universal-access/cc-ua-panel.c:354 msgctxt "cursor size" msgid "Default" msgstr "Öntanımlı" -#: panels/universal-access/cc-ua-panel.c:356 +#: panels/universal-access/cc-ua-panel.c:357 msgctxt "cursor size" msgid "Medium" msgstr "Orta" -#: panels/universal-access/cc-ua-panel.c:359 +#: panels/universal-access/cc-ua-panel.c:360 msgctxt "cursor size" msgid "Large" msgstr "Büyük" -#: panels/universal-access/cc-ua-panel.c:362 +#: panels/universal-access/cc-ua-panel.c:363 msgctxt "cursor size" msgid "Larger" msgstr "Çok Büyük" -#: panels/universal-access/cc-ua-panel.c:365 +#: panels/universal-access/cc-ua-panel.c:366 msgctxt "cursor size" msgid "Largest" msgstr "En Büyük" -#: panels/universal-access/cc-ua-panel.c:369 +#: panels/universal-access/cc-ua-panel.c:370 #, c-format msgid "%d pixel" msgid_plural "%d pixels" @@ -5799,7 +6016,7 @@ msgstr[0] "%d piksel" #: panels/universal-access/gnome-universal-access-panel.desktop.in.in:4 msgid "Make it easier to see, hear, type, point and click" -msgstr "Görme, duyma, yazma, işaretleme ve tıklamayı kolaylaştır." +msgstr "Görme, duyma, yazma, işaretleme ve tıklamayı kolaylaştır" #. Translators: Do NOT translate or transliterate this text (this is an icon file name)! #: panels/universal-access/gnome-universal-access-panel.desktop.in.in:7 @@ -5837,7 +6054,7 @@ msgid "C_ursor Size" msgstr "İ_mleç Boyutu" #: panels/universal-access/uap.ui:316 -#: panels/universal-access/zoom-options.ui:98 +#: panels/universal-access/zoom-options.ui:99 msgid "_Zoom" msgstr "_Yaklaştır" @@ -5902,7 +6119,7 @@ msgid "" "Cursor size can be combined with zoom to make it easier to see the cursor." msgstr "" "İmleç boyutu, imleci görmeyi kolaylaştırması için yakınlaştırma ile " -"birleştirilebilir. " +"birleştirilebilir." #: panels/universal-access/uap.ui:1105 msgid "Screen Reader" @@ -6097,7 +6314,7 @@ msgstr "_Üzerindeyken Tıklama" #: panels/universal-access/uap.ui:2668 msgid "Trigger a click when the pointer hovers" -msgstr "Belirteç nesne üstüne geldiğinde tıklama yap" +msgstr "Belirteç nesne üstüne geldiğinde tıkla" #: panels/universal-access/uap.ui:2701 msgid "D_elay:" @@ -6127,27 +6344,27 @@ msgctxt "dwell click threshold" msgid "Large" msgstr "Büyük" -#: panels/universal-access/zoom-options.c:333 +#: panels/universal-access/zoom-options.c:338 msgctxt "Distance" msgid "Short" msgstr "Kısa" -#: panels/universal-access/zoom-options.c:334 +#: panels/universal-access/zoom-options.c:339 msgctxt "Distance" msgid "¼ Screen" msgstr "¼ Ekran" -#: panels/universal-access/zoom-options.c:335 +#: panels/universal-access/zoom-options.c:340 msgctxt "Distance" msgid "½ Screen" msgstr "½ Ekran" -#: panels/universal-access/zoom-options.c:336 +#: panels/universal-access/zoom-options.c:341 msgctxt "Distance" msgid "¾ Screen" msgstr "¾ Ekran" -#: panels/universal-access/zoom-options.c:337 +#: panels/universal-access/zoom-options.c:342 msgctxt "Distance" msgid "Long" msgstr "Uzun" @@ -6172,134 +6389,134 @@ msgstr "Sol Yarı" msgid "Right Half" msgstr "Sağ Yarı" -#: panels/universal-access/zoom-options.ui:77 +#: panels/universal-access/zoom-options.ui:78 msgid "Zoom Options" msgstr "Yakınlaştırma Seçenekleri" -#: panels/universal-access/zoom-options.ui:186 +#: panels/universal-access/zoom-options.ui:188 msgid "_Magnification:" msgstr "Büyüt_me:" -#: panels/universal-access/zoom-options.ui:250 +#: panels/universal-access/zoom-options.ui:252 msgid "_Follow mouse cursor" msgstr "_Fare imlecini takip et" -#: panels/universal-access/zoom-options.ui:270 +#: panels/universal-access/zoom-options.ui:272 msgid "_Screen part:" msgstr "_Ekrandan bölüm:" -#: panels/universal-access/zoom-options.ui:332 +#: panels/universal-access/zoom-options.ui:334 msgid "Magnifier _extends outside of screen" msgstr "Büyüt_eç ekranın dışına taşar" -#: panels/universal-access/zoom-options.ui:351 +#: panels/universal-access/zoom-options.ui:353 msgid "_Keep magnifier cursor centered" msgstr "B_üyüteç imlecini ortalı tut" -#: panels/universal-access/zoom-options.ui:370 +#: panels/universal-access/zoom-options.ui:372 msgid "Magnifier cursor _pushes contents around" msgstr "Büyüteç imleci çevresindeki içeriği _iter" -#: panels/universal-access/zoom-options.ui:389 +#: panels/universal-access/zoom-options.ui:391 msgid "Magnifier cursor moves with _contents" msgstr "Büyüteç imleci i_çerik ile birlikte hareket eder" -#: panels/universal-access/zoom-options.ui:423 +#: panels/universal-access/zoom-options.ui:425 msgid "Magnifier Position:" msgstr "Büyüteç Konumu:" -#: panels/universal-access/zoom-options.ui:444 +#: panels/universal-access/zoom-options.ui:446 msgid "Magnifier" msgstr "Büyüteç" -#: panels/universal-access/zoom-options.ui:490 +#: panels/universal-access/zoom-options.ui:493 msgid "_Thickness:" msgstr "_Kalınlık:" -#: panels/universal-access/zoom-options.ui:516 +#: panels/universal-access/zoom-options.ui:519 msgctxt "universal access, thickness" msgid "Thin" msgstr "İnce" -#: panels/universal-access/zoom-options.ui:548 +#: panels/universal-access/zoom-options.ui:551 msgctxt "universal access, thickness" msgid "Thick" msgstr "Kalın" -#: panels/universal-access/zoom-options.ui:574 +#: panels/universal-access/zoom-options.ui:577 msgid "_Length:" msgstr "Uzun_luk:" #. The color of the accessibility crosshair -#: panels/universal-access/zoom-options.ui:626 +#: panels/universal-access/zoom-options.ui:629 msgid "Co_lor:" msgstr "Re_nk:" -#: panels/universal-access/zoom-options.ui:690 +#: panels/universal-access/zoom-options.ui:693 msgid "_Crosshairs:" msgstr "_Referans Noktaları:" -#: panels/universal-access/zoom-options.ui:741 +#: panels/universal-access/zoom-options.ui:744 msgid "_Overlaps mouse cursor" msgstr "Fare imleci ile _örtüşür" -#: panels/universal-access/zoom-options.ui:779 +#: panels/universal-access/zoom-options.ui:782 msgid "Crosshairs" msgstr "Çarpılar" -#: panels/universal-access/zoom-options.ui:827 +#: panels/universal-access/zoom-options.ui:831 msgid "_White on black:" msgstr "_Siyah üzerine beyaz:" -#: panels/universal-access/zoom-options.ui:850 +#: panels/universal-access/zoom-options.ui:854 msgid "_Brightness:" msgstr "_Parlaklık:" -#: panels/universal-access/zoom-options.ui:874 +#: panels/universal-access/zoom-options.ui:878 msgid "_Contrast:" msgstr "_Karşıtlık:" #. The contrast scale goes from Color to None (grayscale) -#: panels/universal-access/zoom-options.ui:897 +#: panels/universal-access/zoom-options.ui:901 msgctxt "universal access, contrast" msgid "Co_lor" msgstr "R_enk" -#: panels/universal-access/zoom-options.ui:925 +#: panels/universal-access/zoom-options.ui:929 msgctxt "universal access, color" msgid "None" msgstr "Hiçbiri" -#: panels/universal-access/zoom-options.ui:957 +#: panels/universal-access/zoom-options.ui:961 msgctxt "universal access, color" msgid "Full" msgstr "Tam" -#: panels/universal-access/zoom-options.ui:1023 +#: panels/universal-access/zoom-options.ui:1027 msgctxt "universal access, brightness" msgid "Low" msgstr "Düşük" -#: panels/universal-access/zoom-options.ui:1056 +#: panels/universal-access/zoom-options.ui:1060 msgctxt "universal access, brightness" msgid "High" msgstr "Yüksek" -#: panels/universal-access/zoom-options.ui:1087 +#: panels/universal-access/zoom-options.ui:1091 msgctxt "universal access, contrast" msgid "Low" msgstr "Düşük" -#: panels/universal-access/zoom-options.ui:1120 +#: panels/universal-access/zoom-options.ui:1124 msgctxt "universal access, contrast" msgid "High" msgstr "Yüksek" -#: panels/universal-access/zoom-options.ui:1156 +#: panels/universal-access/zoom-options.ui:1160 msgid "Color Effects:" msgstr "Renk Etkileri:" -#: panels/universal-access/zoom-options.ui:1181 +#: panels/universal-access/zoom-options.ui:1185 msgid "Color Effects" msgstr "Renk Etkileri" @@ -6715,29 +6932,29 @@ msgstr "Bilinmeyen hata" msgid "Should match the web address of your login provider." msgstr "Hesap sağlayıcınızın web adresi ile aynı olmalıdır." -#: panels/user-accounts/um-account-dialog.c:229 +#: panels/user-accounts/um-account-dialog.c:228 msgid "Failed to add account" msgstr "Hesap eklenemedi" -#: panels/user-accounts/um-account-dialog.c:462 +#: panels/user-accounts/um-account-dialog.c:461 msgid "Passwords do not match." -msgstr "Parolalar uyuşmuyor" +msgstr "Parolalar uyuşmuyor." -#: panels/user-accounts/um-account-dialog.c:717 -#: panels/user-accounts/um-account-dialog.c:763 -#: panels/user-accounts/um-account-dialog.c:784 +#: panels/user-accounts/um-account-dialog.c:716 +#: panels/user-accounts/um-account-dialog.c:762 +#: panels/user-accounts/um-account-dialog.c:783 msgid "Failed to register account" msgstr "Hesap kaydedilemedi" -#: panels/user-accounts/um-account-dialog.c:907 +#: panels/user-accounts/um-account-dialog.c:906 msgid "No supported way to authenticate with this domain" msgstr "Bu alan adıyla kimlik doğrulama yapılamaz" -#: panels/user-accounts/um-account-dialog.c:980 +#: panels/user-accounts/um-account-dialog.c:979 msgid "Failed to join domain" msgstr "Etki alanına katılma başarısız" -#: panels/user-accounts/um-account-dialog.c:1041 +#: panels/user-accounts/um-account-dialog.c:1040 msgid "" "That login name didn’t work.\n" "Please try again." @@ -6745,7 +6962,7 @@ msgstr "" "Oturum açma adı işe yaramadı.\n" "Lütfen yeniden deneyin." -#: panels/user-accounts/um-account-dialog.c:1048 +#: panels/user-accounts/um-account-dialog.c:1047 msgid "" "That login password didn’t work.\n" "Please try again." @@ -6753,11 +6970,11 @@ msgstr "" "Oturum açma parolası işe yaramadı.\n" "Lütfen yeniden deneyin." -#: panels/user-accounts/um-account-dialog.c:1056 +#: panels/user-accounts/um-account-dialog.c:1055 msgid "Failed to log into domain" msgstr "Etki alanına girilemedi" -#: panels/user-accounts/um-account-dialog.c:1114 +#: panels/user-accounts/um-account-dialog.c:1113 msgid "Unable to find the domain. Maybe you misspelled it?" msgstr "Etki alanı bulunamadı. Belki yanlış yazmışsınızdır?" @@ -6891,7 +7108,7 @@ msgstr "%s — %s" #. Translators: This is a time format string in the style of "22:58". #. It indicates a login time which follows a date. #: panels/user-accounts/um-history-dialog.c:177 -#: panels/user-accounts/um-user-panel.c:767 +#: panels/user-accounts/um-user-panel.c:766 msgctxt "login date-time" msgid "%k:%M" msgstr "%k:%M" @@ -6899,7 +7116,7 @@ msgstr "%k:%M" #. Translators: This indicates a login date-time. #. The first %s is a date, and the second %s a time. #: panels/user-accounts/um-history-dialog.c:180 -#: panels/user-accounts/um-user-panel.c:771 +#: panels/user-accounts/um-user-panel.c:770 #, c-format msgctxt "login date-time" msgid "%s, %s" @@ -6922,7 +7139,7 @@ msgstr "%s — Hesap Etkinliği" #: panels/user-accounts/um-password-dialog.c:144 msgid "Please choose another password." -msgstr "Lütfen farklı bir parola seçin" +msgstr "Lütfen başka bir parola seçin." #: panels/user-accounts/um-password-dialog.c:153 msgid "Please type your current password again." @@ -6936,70 +7153,69 @@ msgstr "Parolanız değiştirilemedi" msgid "The passwords do not match." msgstr "Parolalar eşleşmiyor." -#: panels/user-accounts/um-photo-dialog.c:226 +#: panels/user-accounts/um-photo-dialog.c:227 msgid "Browse for more pictures" msgstr "Daha çok resim için göz at" -#: panels/user-accounts/um-realm-manager.c:350 +#: panels/user-accounts/um-realm-manager.c:310 msgid "Cannot automatically join this type of domain" msgstr "Bu tür bir etki alanına kendiliğinden girilemiyor" -#: panels/user-accounts/um-realm-manager.c:413 -#, c-format +#: panels/user-accounts/um-realm-manager.c:313 msgid "No such domain or realm found" msgstr "Böyle bir etki alanı veya alan (realm) yok" -#: panels/user-accounts/um-realm-manager.c:815 -#: panels/user-accounts/um-realm-manager.c:829 +#: panels/user-accounts/um-realm-manager.c:735 +#: panels/user-accounts/um-realm-manager.c:749 #, c-format msgid "Cannot log in as %s at the %s domain" msgstr "%2$s etki alanına %1$s olarak giriş yapılamıyor" -#: panels/user-accounts/um-realm-manager.c:821 +#: panels/user-accounts/um-realm-manager.c:741 msgid "Invalid password, please try again" msgstr "Yanlış parola, lütfen yeniden deneyin" -#: panels/user-accounts/um-realm-manager.c:834 +#: panels/user-accounts/um-realm-manager.c:754 #, c-format msgid "Couldn’t connect to the %s domain: %s" msgstr "%s etki alanına bağlanılamadı: %s" -#: panels/user-accounts/um-user-panel.c:201 +#: panels/user-accounts/um-user-panel.c:200 msgid "Your account" msgstr "Hesabınız" -#: panels/user-accounts/um-user-panel.c:381 +#: panels/user-accounts/um-user-panel.c:380 msgid "Failed to delete user" msgstr "Kullanıcı silinemedi" -#: panels/user-accounts/um-user-panel.c:439 -#: panels/user-accounts/um-user-panel.c:498 -#: panels/user-accounts/um-user-panel.c:550 +#: panels/user-accounts/um-user-panel.c:438 +#: panels/user-accounts/um-user-panel.c:497 +#: panels/user-accounts/um-user-panel.c:549 msgid "Failed to revoke remotely managed user" msgstr "Uzaktan yönetilen kullanıcı iptal edilemedi" -#: panels/user-accounts/um-user-panel.c:604 +#: panels/user-accounts/um-user-panel.c:603 msgid "You cannot delete your own account." msgstr "Kendi hesabınızı silemezsiniz." -#: panels/user-accounts/um-user-panel.c:613 +#: panels/user-accounts/um-user-panel.c:612 #, c-format msgid "%s is still logged in" msgstr "%s halen sisteme giriş yapmış durumda" -#: panels/user-accounts/um-user-panel.c:617 +#: panels/user-accounts/um-user-panel.c:616 msgid "" "Deleting a user while they are logged in can leave the system in an " "inconsistent state." msgstr "" "Giriş yapmış bir kullanıcıyı silmek sistemi tutarsız bir duruma sokabilir." -#: panels/user-accounts/um-user-panel.c:626 +#: panels/user-accounts/um-user-panel.c:625 #, c-format msgid "Do you want to keep %s’s files?" msgstr "%s’in dosyalarını saklamak ister misiniz?" -#: panels/user-accounts/um-user-panel.c:630 +#: panels/user-accounts/um-user-panel.c:629 msgid "" "It is possible to keep the home directory, mail spool and temporary files " "around when deleting a user account." @@ -7007,49 +7223,49 @@ msgstr "" "Kullanıcı silerken ev klasörünü, postalarını ve geçici dosyalarını bırakmak " "mümkün." -#: panels/user-accounts/um-user-panel.c:633 +#: panels/user-accounts/um-user-panel.c:632 msgid "_Delete Files" msgstr "_Dosyaları Sil" -#: panels/user-accounts/um-user-panel.c:634 +#: panels/user-accounts/um-user-panel.c:633 msgid "_Keep Files" msgstr "Dosyaları _Tut" -#: panels/user-accounts/um-user-panel.c:648 +#: panels/user-accounts/um-user-panel.c:647 #, c-format msgid "Are you sure you want to revoke remotely managed %s’s account?" msgstr "" "Uzaktan yönetilen %s kullanıcısının hesabını iptal etmek istediğinizden emin " "misiniz?" -#: panels/user-accounts/um-user-panel.c:652 +#: panels/user-accounts/um-user-panel.c:651 msgid "_Delete" msgstr "_Sil" -#: panels/user-accounts/um-user-panel.c:702 +#: panels/user-accounts/um-user-panel.c:701 msgctxt "Password mode" msgid "Account disabled" msgstr "Hesap devre dışı" -#: panels/user-accounts/um-user-panel.c:710 +#: panels/user-accounts/um-user-panel.c:709 msgctxt "Password mode" msgid "To be set at next login" msgstr "Bir sonraki girişte ayarlanacak" -#: panels/user-accounts/um-user-panel.c:713 +#: panels/user-accounts/um-user-panel.c:712 msgctxt "Password mode" msgid "None" msgstr "Hiçbiri" -#: panels/user-accounts/um-user-panel.c:760 +#: panels/user-accounts/um-user-panel.c:759 msgid "Logged in" msgstr "Oturum açık" -#: panels/user-accounts/um-user-panel.c:1107 +#: panels/user-accounts/um-user-panel.c:1106 msgid "Failed to contact the accounts service" msgstr "Hesap hizmetiyle bağlantı kurulamadı" -#: panels/user-accounts/um-user-panel.c:1109 +#: panels/user-accounts/um-user-panel.c:1108 msgid "Please make sure that the AccountService is installed and enabled." msgstr "Lütfen AccountService’in kurulu ve etkin olduğundan emin olun." @@ -7057,7 +7273,7 @@ msgstr "Lütfen AccountService’in kurulu ve etkin olduğundan emin olun." #. * We split the line in 2 here to "make it look good", as there's #. * no good way to do this in GTK+ for tooltips. See: #. * https://bugzilla.gnome.org/show_bug.cgi?id=657168 -#: panels/user-accounts/um-user-panel.c:1141 +#: panels/user-accounts/um-user-panel.c:1140 msgid "" "To make changes,\n" "click the * icon first" @@ -7065,12 +7281,12 @@ msgstr "" "Değişiklik yapmak için,\n" "önce * simgesine tıklayın" -#: panels/user-accounts/um-user-panel.c:1181 +#: panels/user-accounts/um-user-panel.c:1180 msgid "Create a user account" msgstr "Kullanıcı hesabı oluştur" -#: panels/user-accounts/um-user-panel.c:1192 -#: panels/user-accounts/um-user-panel.c:1371 +#: panels/user-accounts/um-user-panel.c:1191 +#: panels/user-accounts/um-user-panel.c:1370 msgid "" "To create a user account,\n" "click the * icon first" @@ -7078,12 +7294,12 @@ msgstr "" "Kullanıcı hesabı oluşturmak için,\n" "önce * simgesine tıklayın" -#: panels/user-accounts/um-user-panel.c:1202 +#: panels/user-accounts/um-user-panel.c:1201 msgid "Delete the selected user account" msgstr "Seçilen kullanıcı hesabını sil" -#: panels/user-accounts/um-user-panel.c:1214 -#: panels/user-accounts/um-user-panel.c:1376 +#: panels/user-accounts/um-user-panel.c:1213 +#: panels/user-accounts/um-user-panel.c:1375 msgid "" "To delete the selected user account,\n" "click the * icon first" @@ -7361,35 +7577,35 @@ msgstr "" "Denetim merkezi, masaüstünüzün çeşitli yönlerini yapılandırmak için GNOME’un " "temel arabirimidir." -#: shell/cc-application.c:47 +#: shell/cc-application.c:60 msgid "Display version number" msgstr "Sürüm numarasını göster" -#: shell/cc-application.c:48 +#: shell/cc-application.c:61 msgid "Enable verbose mode" msgstr "Ayrıntılı kipi etkinleştir" -#: shell/cc-application.c:49 +#: shell/cc-application.c:62 msgid "Show the overview" msgstr "Genel görünümü göster" -#: shell/cc-application.c:50 +#: shell/cc-application.c:63 msgid "Search for the string" msgstr "Dizgeyi ara" -#: shell/cc-application.c:51 +#: shell/cc-application.c:64 msgid "List possible panel names and exit" msgstr "Olası panel adlarını listele ve çık" -#: shell/cc-application.c:52 +#: shell/cc-application.c:65 msgid "Panel to display" msgstr "Gösterilecek panel" -#: shell/cc-application.c:52 +#: shell/cc-application.c:65 msgid "[PANEL] [ARGUMENT…]" msgstr "[PANEL] [BAĞIMSIZ DEĞİŞKEN…]" -#: shell/cc-application.c:117 +#: shell/cc-application.c:136 msgid "Available panels:" msgstr "Kullanılabilir Paneller:" @@ -7441,12 +7657,6 @@ msgctxt "shortcut window" msgid "Cancel search" msgstr "Aramayı iptal et" -#. translators: This is the default hotspot name, need to be less than 32-bytes -#: shell/hostname-helper.c:189 -msgctxt "hotspot" -msgid "Hotspot" -msgstr "Erişim Noktası" - #: shell/org.gnome.ControlCenter.gschema.xml:5 msgid "The identifier for the last Settings panel to be opened" msgstr "En son açılan Ayarlar paneli için tanımlayıcı" @@ -7660,12 +7870,6 @@ msgstr "Sistem Sesleri" #~ msgid "_Method" #~ msgstr "Yönte_m" -#~ msgid "Add Device" -#~ msgstr "Aygıt Ekle" - -#~ msgid "Remove Device" -#~ msgstr "Aygıtı Kaldır" - #~ msgid "VPN Type" #~ msgstr "VPN Türü" @@ -7971,9 +8175,6 @@ msgstr "Sistem Sesleri" #~ "Bir kısayolu düzenlemek için, ilgili satıra tıklayın ve tuşlara ya da " #~ "temizlemek için Backspace tuşuna basın." -#~ msgid "_Name:" -#~ msgstr "_İsim:" - #~ msgid "Add Shortcut" #~ msgstr "Kısayol Ekle" -- cgit v1.2.1 From 197ed1ed55d1d55108ee44ea009089babf4f0fed Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Wed, 9 May 2018 15:30:19 -0300 Subject: datetime: Update backwards file This is just a plain copy of the most recent (2017-10) backwards file from tzinfo. --- panels/datetime/backward | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/panels/datetime/backward b/panels/datetime/backward index f1f95a894..8594be65f 100644 --- a/panels/datetime/backward +++ b/panels/datetime/backward @@ -1,13 +1,12 @@ -#
-# @(#)backward	8.9
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 
 # This file provides links between current names for time zones
 # and their old names.  Many names changed in late 1993.
 
-Link	Africa/Asmara		Africa/Asmera
-Link	Africa/Bamako		Africa/Timbuktu
+# Link	TARGET			LINK-NAME
+Link	Africa/Nairobi		Africa/Asmera
+Link	Africa/Abidjan		Africa/Timbuktu
 Link	America/Argentina/Catamarca	America/Argentina/ComodRivadavia
 Link	America/Adak		America/Atka
 Link	America/Argentina/Buenos_Aires	America/Buenos_Aires
@@ -21,17 +20,25 @@ Link	America/Argentina/Jujuy	America/Jujuy
 Link	America/Indiana/Knox	America/Knox_IN
 Link	America/Kentucky/Louisville	America/Louisville
 Link	America/Argentina/Mendoza	America/Mendoza
+Link	America/Toronto		America/Montreal
 Link	America/Rio_Branco	America/Porto_Acre
 Link	America/Argentina/Cordoba	America/Rosario
-Link	America/St_Thomas	America/Virgin
+Link	America/Tijuana		America/Santa_Isabel
+Link	America/Denver		America/Shiprock
+Link	America/Port_of_Spain	America/Virgin
+Link	Pacific/Auckland	Antarctica/South_Pole
 Link	Asia/Ashgabat		Asia/Ashkhabad
-Link	Asia/Chongqing		Asia/Chungking
+Link	Asia/Kolkata		Asia/Calcutta
+Link	Asia/Shanghai		Asia/Chongqing
+Link	Asia/Shanghai		Asia/Chungking
 Link	Asia/Dhaka		Asia/Dacca
+Link	Asia/Shanghai		Asia/Harbin
+Link	Asia/Urumqi		Asia/Kashgar
 Link	Asia/Kathmandu		Asia/Katmandu
-Link	Asia/Kolkata		Asia/Calcutta
 Link	Asia/Macau		Asia/Macao
-Link	Asia/Jerusalem		Asia/Tel_Aviv
+Link	Asia/Yangon		Asia/Rangoon
 Link	Asia/Ho_Chi_Minh	Asia/Saigon
+Link	Asia/Jerusalem		Asia/Tel_Aviv
 Link	Asia/Thimphu		Asia/Thimbu
 Link	Asia/Makassar		Asia/Ujung_Pandang
 Link	Asia/Ulaanbaatar	Asia/Ulan_Bator
@@ -54,7 +61,9 @@ Link	America/Sao_Paulo	Brazil/East
 Link	America/Manaus		Brazil/West
 Link	America/Halifax		Canada/Atlantic
 Link	America/Winnipeg	Canada/Central
-Link	America/Regina		Canada/East-Saskatchewan
+# This line is commented out, as the name exceeded the 14-character limit
+# and was an unused misnomer.
+#Link	America/Regina		Canada/East-Saskatchewan
 Link	America/Toronto		Canada/Eastern
 Link	America/Edmonton	Canada/Mountain
 Link	America/St_Johns	Canada/Newfoundland
@@ -89,10 +98,11 @@ Link	Pacific/Auckland	NZ
 Link	Pacific/Chatham		NZ-CHAT
 Link	America/Denver		Navajo
 Link	Asia/Shanghai		PRC
+Link	Pacific/Honolulu	Pacific/Johnston
+Link	Pacific/Pohnpei		Pacific/Ponape
 Link	Pacific/Pago_Pago	Pacific/Samoa
-Link	Pacific/Chuuk		Pacific/Yap
 Link	Pacific/Chuuk		Pacific/Truk
-Link	Pacific/Pohnpei		Pacific/Ponape
+Link	Pacific/Chuuk		Pacific/Yap
 Link	Europe/Warsaw		Poland
 Link	Europe/Lisbon		Portugal
 Link	Asia/Taipei		ROC
@@ -115,4 +125,4 @@ Link	Pacific/Pago_Pago	US/Samoa
 Link	Etc/UTC			UTC
 Link	Etc/UTC			Universal
 Link	Europe/Moscow		W-SU
-Link	Etc/UTC			Zulu
+Link	Etc/UTC			Zulu
\ No newline at end of file
-- 
cgit v1.2.1


From 0b854910bb806f2662d083d9c5e7bdcc07c61084 Mon Sep 17 00:00:00 2001
From: Georges Basile Stavracas Neto 
Date: Wed, 9 May 2018 15:31:01 -0300
Subject: tests: Rely only on zone.tab

First of all, this is a complete rewrite of the
timezone tests. Everything was revisited, starting
from code style, to concepts, etc.

The problem  with the previous timezone test was that
is was relying on listing the /usr/share/zoneinfo
directory, and assuming that those entries would be
always present.

Turns out, some of them are extensions, some of them
are undocumented files, etc. A huge mess. I could've
blacklisted the undesired files and folders, but that
would still be insufficient for other OSes like *BSDs
and Sun.

The final solution was pretty straightforward: only
use the information from zone.tab to run the tests.
---
 tests/datetime/test-timezone.c | 134 ++++++++++++++---------------------------
 1 file changed, 44 insertions(+), 90 deletions(-)

diff --git a/tests/datetime/test-timezone.c b/tests/datetime/test-timezone.c
index 436f536b5..5962fc45e 100644
--- a/tests/datetime/test-timezone.c
+++ b/tests/datetime/test-timezone.c
@@ -3,109 +3,63 @@
 #include "cc-datetime-resources.h"
 #include "cc-timezone-map.h"
 
-#define TZ_DIR "/usr/share/zoneinfo/"
-
-static GList *
-get_timezone_list (GList *tzs,
-		   const char *top_path,
-		   const char *subpath)
+static void
+test_timezone (void)
 {
-	GDir *dir;
-	char *fullpath;
-	const char *name;
-
-	if (subpath == NULL)
-		fullpath = g_strdup (top_path);
-	else
-		fullpath = g_build_filename (top_path, subpath, NULL);
-	dir = g_dir_open (fullpath, 0, NULL);
-	if (dir == NULL) {
-		g_warning ("Could not open %s", fullpath);
-		return NULL;
-	}
-	while ((name = g_dir_read_name (dir)) != NULL) {
-		g_autofree gchar *path = NULL;
+  g_autoptr(GHashTable) ht = NULL;
+  CcTimezoneMap *map;
+  TzDB *tz_db;
+  guint i;
 
-		if (g_str_has_suffix (name, ".tab"))
-			continue;
+  ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+  map = cc_timezone_map_new ();
+  tz_db = tz_load_db ();
 
-		if (subpath != NULL)
-			path = g_build_filename (top_path, subpath, name, NULL);
-		else
-			path = g_build_filename (top_path, name, NULL);
-		if (g_file_test (path, G_FILE_TEST_IS_DIR)) {
-			if (subpath == NULL) {
-				tzs = get_timezone_list (tzs, top_path, name);
-			} else {
-				g_autofree gchar *new_subpath = NULL;
-				new_subpath = g_strdup_printf ("%s/%s", subpath, name);
-				tzs = get_timezone_list (tzs, top_path, new_subpath);
-			}
-		} else if (g_file_test (path, G_FILE_TEST_IS_REGULAR)) {
-			if (subpath == NULL)
-				tzs = g_list_prepend (tzs, g_strdup (name));
-			else {
-				char *tz;
-				tz = g_strdup_printf ("%s/%s", subpath, name);
-				tzs = g_list_prepend (tzs, tz);
-			}
-		}
-	}
-	g_dir_close (dir);
+  g_assert_nonnull (tz_db);
+  g_assert_nonnull (tz_db->locations);
 
-	return tzs;
-}
+  for (i = 0; tz_db->locations && i < tz_db->locations->len; i++)
+    {
+      g_autofree gchar *clean_tz = NULL;
+      TzLocation *location = NULL;
 
-static void
-test_timezone (void)
-{
-	CcTimezoneMap *map;
-	TzDB *tz_db;
-	GList *tzs, *l;
-	GHashTable *ht;
+      location = g_ptr_array_index (tz_db->locations, i);
+      clean_tz = tz_info_get_clean_name (tz_db, location->zone);
 
-	ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-	map = cc_timezone_map_new ();
-	tz_db = tz_load_db ();
-	tzs = get_timezone_list (NULL, TZ_DIR, NULL);
-	for (l = tzs; l != NULL; l = l->next) {
-		const gchar *timezone = l->data;
-		g_autofree gchar *clean_tz = NULL;
+      if (!cc_timezone_map_set_timezone (map, location->zone))
+        {
+          if (!g_hash_table_contains (ht, clean_tz))
+            {
+              if (g_strcmp0 (clean_tz, location->zone) == 0)
+                g_printerr ("Failed to locate timezone '%s'\n", location->zone);
+              else
+                g_printerr ("Failed to locate timezone '%s' (original name: '%s')\n", clean_tz, location->zone);
+              g_hash_table_insert (ht, g_strdup (clean_tz), GINT_TO_POINTER (TRUE));
+            }
 
-		clean_tz = tz_info_get_clean_name (tz_db, timezone);
+          /* We don't warn for those, we'll just fallback
+           * in the panel code */
+          if (!g_str_equal (clean_tz, "posixrules") && !g_str_equal (clean_tz, "Factory"))
+            g_test_fail ();
+        }
+    }
 
-		if (cc_timezone_map_set_timezone (map, clean_tz) == FALSE) {
-			if (g_hash_table_lookup (ht, clean_tz) == NULL) {
-				if (g_strcmp0 (clean_tz, timezone) == 0)
-					g_print ("Failed to locate timezone '%s'\n", timezone);
-				else
-					g_print ("Failed to locate timezone '%s' (original name: '%s')\n", clean_tz, timezone);
-				g_hash_table_insert (ht, g_strdup (clean_tz), GINT_TO_POINTER (TRUE));
-				g_test_fail ();
-			}
-			/* We don't warn for those two, we'll just fallback
-			 * in the panel code */
-			if (!g_str_equal (clean_tz, "posixrules") &&
-			    !g_str_equal (clean_tz, "Factory"))
-				g_test_fail ();
-		}
-	}
-	g_list_free_full (tzs, g_free);
-	tz_db_free (tz_db);
-	g_hash_table_destroy (ht);
+  tz_db_free (tz_db);
 }
 
-int main (int argc, char **argv)
+gint
+main (gint    argc,
+      gchar **argv)
 {
-	setlocale (LC_ALL, "");
-	gtk_init (NULL, NULL);
-	g_test_init (&argc, &argv, NULL);
+  setlocale (LC_ALL, "");
+  gtk_init (NULL, NULL);
+  g_test_init (&argc, &argv, NULL);
 
-	g_resources_register (cc_datetime_get_resource ());
+  g_resources_register (cc_datetime_get_resource ());
 
-	g_setenv ("G_DEBUG", "fatal_warnings", FALSE);
+  g_setenv ("G_DEBUG", "fatal_warnings", FALSE);
 
-	g_test_add_func ("/datetime/timezone", test_timezone);
+  g_test_add_func ("/datetime/timezone", test_timezone);
 
-	return g_test_run ();
+  return g_test_run ();
 }
-- 
cgit v1.2.1


From c23e8f354755144b1ce48e7237855fdc68fc7549 Mon Sep 17 00:00:00 2001
From: Georges Basile Stavracas Neto 
Date: Wed, 9 May 2018 16:16:25 -0300
Subject: tests: Rework test-timezone-gfx

---
 tests/datetime/test-timezone-gfx.c | 92 +++++++++++++++++++++-----------------
 1 file changed, 51 insertions(+), 41 deletions(-)

diff --git a/tests/datetime/test-timezone-gfx.c b/tests/datetime/test-timezone-gfx.c
index a8f704627..22619c30c 100644
--- a/tests/datetime/test-timezone-gfx.c
+++ b/tests/datetime/test-timezone-gfx.c
@@ -1,5 +1,6 @@
 #include 
 #include 
+#include 
 
 #include "cc-datetime-resources.h"
 #include "tz.h"
@@ -7,58 +8,67 @@
 static void
 test_timezone_gfx (gconstpointer data)
 {
-	const char *pixmap_dir = data;
-	g_autoptr(TzDB) db = NULL;
-	GPtrArray *locs;
-	guint i;
+  g_autoptr(TzDB) db = NULL;
+  GPtrArray *locs;
+  const char *pixmap_dir;
+  guint i;
 
-	db = tz_load_db ();
-	locs = tz_get_locations (db);
-	for (i = 0; i < locs->len ; i++) {
-		TzLocation *loc = locs->pdata[i];
-		TzInfo *info;
-		g_autofree gchar *filename = NULL;
-		g_autofree gchar *path = NULL;
-		gdouble selected_offset;
-                char buf[16];
+  pixmap_dir = data;
+  db = tz_load_db ();
+  locs = tz_get_locations (db);
 
-		info = tz_info_from_location (loc);
-		selected_offset = tz_location_get_utc_offset (loc)
-			/ (60.0*60.0) + ((info->daylight) ? -1.0 : 0.0);
+  for (i = 0; i < locs->len ; i++)
+    {
+      g_autofree gchar *filename = NULL;
+      g_autofree gchar *path = NULL;
+      TzLocation *location;
+      TzInfo *info;
+      gdouble selected_offset;
+      gchar buf[16];
 
-		filename = g_strdup_printf ("timezone_%s.png",
-                                            g_ascii_formatd (buf, sizeof (buf),
-                                                             "%g", selected_offset));
-		path = g_build_filename (pixmap_dir, filename, NULL);
+      location = locs->pdata[i];
+      info = tz_info_from_location (location);
+      selected_offset = tz_location_get_utc_offset (location) / (60.0 * 60.0) + (info->daylight ? -1.0 : 0.0);
 
-		if (g_file_test (path, G_FILE_TEST_IS_REGULAR) == FALSE) {
-			g_message ("File '%s' missing for zone '%s'", filename, loc->zone);
-			g_test_fail ();
-		}
-	}
+      filename = g_strdup_printf ("timezone_%s.png", g_ascii_formatd (buf, sizeof (buf), "%g", selected_offset));
+      path = g_build_filename (pixmap_dir, filename, NULL);
+
+      if (!g_file_test (path, G_FILE_TEST_IS_REGULAR))
+        {
+          g_message ("File '%s' missing for zone '%s'", filename, location->zone);
+          g_test_fail ();
+        }
+    }
 }
 
-int main (int argc, char **argv)
+gint
+main (gint    argc,
+      gchar **argv)
 {
-	char *pixmap_dir;
+  gchar *pixmap_dir;
 
-        setlocale (LC_ALL, "");
-	g_test_init (&argc, &argv, NULL);
+  setlocale (LC_ALL, "");
+  g_test_init (&argc, &argv, NULL);
 
-	g_setenv ("G_DEBUG", "fatal_warnings", FALSE);
+  g_setenv ("G_DEBUG", "fatal_warnings", FALSE);
 
-	g_resources_register (cc_datetime_get_resource ());
+  g_resources_register (cc_datetime_get_resource ());
 
-	if (argc == 2) {
-		pixmap_dir = g_strdup (argv[1]);
-	} else if (argc == 1) {
-		pixmap_dir = g_strdup (SRCDIR "/data/");
-	} else {
-		g_message ("Usage: %s [PIXMAP DIRECTORY]", argv[0]);
-		return 1;
-	}
+  if (argc == 2)
+    {
+      pixmap_dir = g_strdup (argv[1]);
+    }
+  else if (argc == 1)
+    {
+      pixmap_dir = g_strdup (SRCDIR "/data/");
+    }
+  else
+    {
+      g_message ("Usage: %s [PIXMAP DIRECTORY]", argv[0]);
+      return 1;
+    }
 
-	g_test_add_data_func ("/datetime/timezone-gfx", pixmap_dir, test_timezone_gfx);
+  g_test_add_data_func ("/datetime/timezone-gfx", pixmap_dir, test_timezone_gfx);
 
-	return g_test_run ();
+  return g_test_run ();
 }
-- 
cgit v1.2.1


From 8404f526b6c145e93d091ff7e79b6aeddf154e9c Mon Sep 17 00:00:00 2001
From: Georges Basile Stavracas Neto 
Date: Wed, 9 May 2018 17:44:46 -0300
Subject: tests: Make logging verbose

---
 tests/datetime/meson.build | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/tests/datetime/meson.build b/tests/datetime/meson.build
index b1dd514b4..4b2b03b36 100644
--- a/tests/datetime/meson.build
+++ b/tests/datetime/meson.build
@@ -6,6 +6,9 @@ test_units = [
 ]
 
 includes = [top_inc, include_directories('../../panels/datetime')]
+env = [
+  'G_MESSAGES_DEBUG=all',
+]
 cflags = [
   '-DTEST_SRCDIR="@0@"'.format(meson.current_source_dir()),
   '-DSRCDIR="@0@"'.format(meson.source_root() + '/panels/datetime')
@@ -21,6 +24,6 @@ foreach unit: test_units
                  c_args : cflags
   )
 
-  test(unit, exe)
+  test(unit, exe, env: env)
 endforeach
 
-- 
cgit v1.2.1


From eea231dc1c2ea08a294de2a6c159bcc0869560c7 Mon Sep 17 00:00:00 2001
From: Georges Basile Stavracas Neto 
Date: Wed, 9 May 2018 18:17:27 -0300
Subject: tests: Run each datetime test under Xvfb

That way, gtk_init() cannot fail.
---
 tests/datetime/meson.build      | 10 ++++++--
 tests/datetime/test-datetime.py | 54 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 2 deletions(-)
 create mode 100644 tests/datetime/test-datetime.py

diff --git a/tests/datetime/meson.build b/tests/datetime/meson.build
index 4b2b03b36..fd0896400 100644
--- a/tests/datetime/meson.build
+++ b/tests/datetime/meson.build
@@ -8,6 +8,8 @@ test_units = [
 includes = [top_inc, include_directories('../../panels/datetime')]
 env = [
   'G_MESSAGES_DEBUG=all',
+          'BUILDDIR=' + meson.current_build_dir(),
+      'TOP_BUILDDIR=' + meson.build_root()
 ]
 cflags = [
   '-DTEST_SRCDIR="@0@"'.format(meson.current_source_dir()),
@@ -23,7 +25,11 @@ foreach unit: test_units
               link_with : [datetime_panel_lib],
                  c_args : cflags
   )
-
-  test(unit, exe, env: env)
 endforeach
 
+test(
+  'test-datetime',
+  find_program('test-datetime.py'),
+      env : env,
+  timeout : 10
+)
\ No newline at end of file
diff --git a/tests/datetime/test-datetime.py b/tests/datetime/test-datetime.py
new file mode 100644
index 000000000..c478374a8
--- /dev/null
+++ b/tests/datetime/test-datetime.py
@@ -0,0 +1,54 @@
+#!/usr/bin/python3
+# Copyright © 2018 Red Hat, Inc
+#             2018 Endless Mobile, Inc
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see .
+#
+# Authors: Benjamin Berg 
+#          Georges Basile Stavracas Neto 
+
+import os
+import sys
+import unittest
+
+try:
+    import dbusmock
+except ImportError:
+    sys.stderr.write('You need python-dbusmock (http://pypi.python.org/pypi/python-dbusmock) for this test suite.\n')
+    sys.exit(1)
+
+# Add the shared directory to the search path
+sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'shared'))
+
+from gtest import GTest
+from x11session import X11SessionTestCase
+
+BUILDDIR = os.environ.get('BUILDDIR', os.path.join(os.path.dirname(__file__)))
+
+
+class EndianessTestCase(X11SessionTestCase, GTest):
+    g_test_exe = os.path.join(BUILDDIR, 'test-endianess')
+
+
+class TimezoneTestCase(X11SessionTestCase, GTest):
+    g_test_exe = os.path.join(BUILDDIR, 'test-timezone')
+
+
+class TimezoneGfxTestCase(X11SessionTestCase, GTest):
+    g_test_exe = os.path.join(BUILDDIR, 'test-timezone-gfx')
+
+
+if __name__ == '__main__':
+    _test = unittest.TextTestRunner(stream=sys.stdout, verbosity=2)
+    unittest.main(testRunner=_test)
\ No newline at end of file
-- 
cgit v1.2.1


From 6ec0bcde1520e0cee19f6596b4b03c801a1ca571 Mon Sep 17 00:00:00 2001
From: Andrea Azzarone 
Date: Mon, 7 May 2018 16:20:13 +0200
Subject: object-storage: Avoid double free when propagating error

In cc_object_storage_create_dbus_proxy_sync and
cc_object_storage_create_dbus_proxy_finish we need to use g_steal_pointer to
make sure local_error is not double freed.

Fixes: https://gitlab.gnome.org/GNOME/gnome-control-center/issues/86
---
 shell/cc-object-storage.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/shell/cc-object-storage.c b/shell/cc-object-storage.c
index 0e708dc3b..46038cc34 100644
--- a/shell/cc-object-storage.c
+++ b/shell/cc-object-storage.c
@@ -256,7 +256,7 @@ cc_object_storage_create_dbus_proxy_sync (GBusType          bus_type,
 
   if (local_error)
     {
-      g_propagate_error (error, local_error);
+      g_propagate_error (error, g_steal_pointer (&local_error));
       return NULL;
     }
 
@@ -385,7 +385,7 @@ cc_object_storage_create_dbus_proxy_finish (GAsyncResult  *result,
   /* If the proxy is not cached, do the normal caching routine */
   if (local_error)
     {
-      g_propagate_error (error, local_error);
+      g_propagate_error (error, g_steal_pointer (&local_error));
       return NULL;
     }
 
-- 
cgit v1.2.1


From 1d26f63b18f54e2d354d64ec8b312c70b35a2808 Mon Sep 17 00:00:00 2001
From: Andrea Azzarone 
Date: Mon, 7 May 2018 21:11:27 +0200
Subject: night-ligth-dialog: Avoid dereferencing invalid pointer

dialog_got_proxy_cb and dialog_got_proxy_props_cb may be called after the
instance of CcNightLightDialog has been disposed. Make sure 'self' pointer is
not dereferenced if not valid.

Fixes: https://gitlab.gnome.org/GNOME/gnome-control-center/issues/86
---
 panels/display/cc-night-light-dialog.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/panels/display/cc-night-light-dialog.c b/panels/display/cc-night-light-dialog.c
index 1d03ba393..b26b9e3e5 100644
--- a/panels/display/cc-night-light-dialog.c
+++ b/panels/display/cc-night-light-dialog.c
@@ -386,13 +386,18 @@ static void
 dialog_got_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
 {
   CcNightLightDialog *self = (CcNightLightDialog *) user_data;
+  GDBusProxy *proxy;
   g_autoptr(GError) error = NULL;
-  self->proxy_color = cc_object_storage_create_dbus_proxy_finish (res, &error);
-  if (self->proxy_color == NULL)
+
+  proxy = cc_object_storage_create_dbus_proxy_finish (res, &error);
+  if (proxy == NULL)
     {
       g_warning ("failed to connect to g-s-d: %s", error->message);
       return;
     }
+
+  self->proxy_color = proxy;
+
   g_signal_connect_object (self->proxy_color, "g-properties-changed",
                            G_CALLBACK (dialog_color_properties_changed_cb), self, 0);
   dialog_update_state (self);
@@ -403,13 +408,17 @@ static void
 dialog_got_proxy_props_cb (GObject *source_object, GAsyncResult *res, gpointer user_data)
 {
   CcNightLightDialog *self = (CcNightLightDialog *) user_data;
+  GDBusProxy *proxy;
   g_autoptr(GError) error = NULL;
-  self->proxy_color_props = cc_object_storage_create_dbus_proxy_finish (res, &error);
-  if (self->proxy_color_props == NULL)
+
+  proxy = cc_object_storage_create_dbus_proxy_finish (res, &error);
+  if (proxy == NULL)
     {
       g_warning ("failed to connect to g-s-d: %s", error->message);
       return;
     }
+
+  self->proxy_color_props = proxy;
 }
 
 static gboolean
-- 
cgit v1.2.1


From f3257ce82a1f7db6eac649fa5d26d487ea946a85 Mon Sep 17 00:00:00 2001
From: Marek Kasik 
Date: Thu, 10 May 2018 14:13:38 +0200
Subject: printers: Focus search entry in new printer dialog

Focus search entry in the new printer dialog once user starts to type
so he does not need to click on it.

Closes #41
---
 panels/printers/new-printer-dialog.ui   |  1 +
 panels/printers/pp-new-printer-dialog.c | 16 ++++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/panels/printers/new-printer-dialog.ui b/panels/printers/new-printer-dialog.ui
index 0e9a8110a..437220542 100644
--- a/panels/printers/new-printer-dialog.ui
+++ b/panels/printers/new-printer-dialog.ui
@@ -153,6 +153,7 @@
                     True
                     True
                     none
+                    True
                     
diff --git a/panels/printers/pp-new-printer-dialog.c b/panels/printers/pp-new-printer-dialog.c
index 7a15a455f..e7857fc01 100644
--- a/panels/printers/pp-new-printer-dialog.c
+++ b/panels/printers/pp-new-printer-dialog.c
@@ -506,6 +506,20 @@ authenticate_samba_server (GtkButton *button,
     }
 }
 
+static gboolean
+stack_key_press_cb (GtkWidget *widget,
+                    GdkEvent  *event,
+                    gpointer   user_data)
+{
+  PpNewPrinterDialog        *dialog = (PpNewPrinterDialog *) user_data;
+  PpNewPrinterDialogPrivate *priv = dialog->priv;
+
+  gtk_widget_grab_focus (WID ("search-entry"));
+  gtk_main_do_event (event);
+
+  return TRUE;
+}
+
 static void
 pp_new_printer_dialog_init (PpNewPrinterDialog *dialog)
 {
@@ -556,6 +570,8 @@ pp_new_printer_dialog_init (PpNewPrinterDialog *dialog)
   widget = WID ("unlock-button");
   g_signal_connect (widget, "clicked", G_CALLBACK (authenticate_samba_server), dialog);
 
+  g_signal_connect (WID ("stack"), "key-press-event", G_CALLBACK (stack_key_press_cb), dialog);
+
   /* Authentication form widgets */
   g_signal_connect (WID ("username-entry"), "changed", G_CALLBACK (auth_entries_changed), dialog);
   g_signal_connect (WID ("password-entry"), "changed", G_CALLBACK (auth_entries_changed), dialog);
-- 
cgit v1.2.1


From f9b65046e9b6912ee7ea8db16a8fde9090879517 Mon Sep 17 00:00:00 2001
From: Andrea Azzarone 
Date: Mon, 7 May 2018 17:01:20 +0200
Subject: night-light-dialog: Ignore G_IO_ERROR_CANCELLED errors

We should ignore G_IO_ERROR_CANCELLED errors and avoid displaying useless
warnings. Also use g_clear_object instead of g_object_unref.

Fixes: https://gitlab.gnome.org/GNOME/gnome-control-center/issues/87
---
 panels/display/cc-night-light-dialog.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/panels/display/cc-night-light-dialog.c b/panels/display/cc-night-light-dialog.c
index b26b9e3e5..55fca2429 100644
--- a/panels/display/cc-night-light-dialog.c
+++ b/panels/display/cc-night-light-dialog.c
@@ -79,11 +79,11 @@ cc_night_light_dialog_finalize (GObject *object)
       self->main_window = NULL;
     }
 
-  g_object_unref (self->builder);
-  g_object_unref (self->proxy_color);
-  g_object_unref (self->proxy_color_props);
-  g_object_unref (self->settings_display);
-  g_object_unref (self->settings_clock);
+  g_clear_object (&self->builder);
+  g_clear_object (&self->proxy_color);
+  g_clear_object (&self->proxy_color_props);
+  g_clear_object (&self->settings_display);
+  g_clear_object (&self->settings_clock);
   if (self->timer_id > 0)
     g_source_remove (self->timer_id);
 
@@ -392,7 +392,8 @@ dialog_got_proxy_cb (GObject *source_object, GAsyncResult *res, gpointer user_da
   proxy = cc_object_storage_create_dbus_proxy_finish (res, &error);
   if (proxy == NULL)
     {
-      g_warning ("failed to connect to g-s-d: %s", error->message);
+      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+        g_warning ("failed to connect to g-s-d: %s", error->message);
       return;
     }
 
@@ -414,7 +415,8 @@ dialog_got_proxy_props_cb (GObject *source_object, GAsyncResult *res, gpointer u
   proxy = cc_object_storage_create_dbus_proxy_finish (res, &error);
   if (proxy == NULL)
     {
-      g_warning ("failed to connect to g-s-d: %s", error->message);
+      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+        g_warning ("failed to connect to g-s-d: %s", error->message);
       return;
     }
 
-- 
cgit v1.2.1


From ffcd5b15f2e62aae7d6bf5acb6b6610dd9ec2e43 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Claudio=20Andr=C3=A9?= 
Date: Thu, 10 May 2018 14:26:42 -0300
Subject: CI: shrink the test process

See #46
---
 .gitlab-ci.yml | 46 ++++++++++------------------------------------
 1 file changed, 10 insertions(+), 36 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9d661ea57..1039e0550 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,25 +1,7 @@
-image: fedora:rawhide
+image: claudioandre/control-center:job-445.6
 stages:
   - build
   - test
-  - deploy
-
-variables:
-  DEPENDENCIES: accountsservice-devel cheese-libs-devel chrpath clutter-gtk-devel colord-devel
-                colord-gtk-devel cups-devel desktop-file-utils docbook-style-xsl gdk-pixbuf2-devel
-                gettext git glib2-devel gnome-bluetooth-libs-devel gnome-desktop3-devel
-                gnome-online-accounts-devel gnome-settings-daemon-devel grilo-devel
-                gsettings-desktop-schemas-devel gtk3-devel ibus-devel intltool libcanberra-devel
-                libgtop2-devel libgudev-devel libnma-devel libpwquality-devel libsmbclient-devel
-                libsoup-devel libwacom-devel libX11-devel libXi-devel libxml2-devel libxslt
-                libXxf86misc-devel meson ModemManager-glib-devel NetworkManager-libnm-devel
-                polkit-devel pulseaudio-libs-devel upower-devel
-                python3-dbusmock xorg-x11-server-Xvfb mesa-dri-drivers
-
-
-before_script:
-  - dnf update -y --nogpgcheck && dnf install -y --nogpgcheck $DEPENDENCIES
-
 
 ##
 # Stage: Build
@@ -46,20 +28,12 @@ test:
   script:
     - meson . _build
     - ninja -C _build
-    - meson test -C _build --verbose --no-stdsplit
-
-
-##
-# Stage: Deploy
-#
-# Checks if the released version is in a good shape.
-##
-deploy:
-  stage: deploy
-  script:
-    - meson . _build
-    - ninja -C _build
-    - meson test -C _build
-    - ninja dist -C _build
-  only:
-    - tags
\ No newline at end of file
+    - |
+      if [[ -n "${CI_COMMIT_TAG}" ]]; then
+        echo "== Distro Test =="
+        meson test -C _build
+        ninja dist -C _build
+      else
+        echo "== Testing =="
+        meson test -C _build --verbose --no-stdsplit
+      fi
-- 
cgit v1.2.1


From 949f8cb22733dbec21a607a64d8ce3deb76d5de9 Mon Sep 17 00:00:00 2001
From: Ting-Wei Lan 
Date: Fri, 4 May 2018 23:01:43 +0800
Subject: tests/network: Disable on non-Linux systems

NetworkManager is only available on Linux, so we cannot build or run the
network test on non-Linux systems.
---
 tests/meson.build | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tests/meson.build b/tests/meson.build
index 41adee9e1..33b460148 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -1,5 +1,7 @@
 subdir('common')
 subdir('datetime')
-subdir('network')
+if host_is_linux
+  subdir('network')
+endif
 subdir('printers')
 subdir('info')
-- 
cgit v1.2.1


From f4b1fb66a4ccbe99ecd520afeb9fb9997c90a6b4 Mon Sep 17 00:00:00 2001
From: Ondrej Holy 
Date: Wed, 25 Apr 2018 18:57:19 +0200
Subject: user-accounts: Fix hint for wrong enterprise user/password

A variable of label widget, used for a hint when wrong enterprise
user/password is used, is not properly initialized and thus criticals
are shown instead of the hint when user/password is wrong. Let's bind
the variable properly.
---
 panels/user-accounts/data/account-dialog.ui | 4 ++--
 panels/user-accounts/um-account-dialog.c    | 1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/panels/user-accounts/data/account-dialog.ui b/panels/user-accounts/data/account-dialog.ui
index a508ecd30..50dad028e 100644
--- a/panels/user-accounts/data/account-dialog.ui
+++ b/panels/user-accounts/data/account-dialog.ui
@@ -538,7 +538,7 @@
                   
                 
                 
-                  
+                  
                     True
                     False
                     0
@@ -810,7 +810,7 @@
       
       
       
-      
+      
     
   
   
diff --git a/panels/user-accounts/um-account-dialog.c b/panels/user-accounts/um-account-dialog.c
index 91ac55a7a..ba4c24375 100644
--- a/panels/user-accounts/um-account-dialog.c
+++ b/panels/user-accounts/um-account-dialog.c
@@ -1580,6 +1580,7 @@ um_account_dialog_class_init (UmAccountDialogClass *klass)
         gtk_widget_class_bind_template_child (widget_class, UmAccountDialog, enterprise_login);
         gtk_widget_class_bind_template_child (widget_class, UmAccountDialog, enterprise_password);
         gtk_widget_class_bind_template_child (widget_class, UmAccountDialog, enterprise_domain_hint);
+        gtk_widget_class_bind_template_child (widget_class, UmAccountDialog, enterprise_hint);
 }
 
 UmAccountDialog *
-- 
cgit v1.2.1


From e7d79d8d1bbe0dd5d2520a00220fdc0a9d31e24e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Claudio=20Andr=C3=A9?= 
Date: Sat, 12 May 2018 10:11:31 -0300
Subject: CI: add build status badge

[skip ci]
---
 README.md | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 3de9100bc..e19f5dceb 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
+[![Build Status](https://gitlab.gnome.org/GNOME/gnome-control-center/badges/master/build.svg)](https://gitlab.gnome.org/GNOME/gnome-control-center/pipelines)
+[![License](https://img.shields.io/badge/License-GPL%20v2-blue.svg)](https://gitlab.gnome.org/GNOME/gnome-control-center/blob/master/COPYING)
+
 GNOME Settings
 ====================
 
@@ -37,4 +40,4 @@ stack trace -
 		ie. (gdb) bt full
 
 Once you have the backtrace, copy and paste this either into the 
-'Comments' field or attach a file with it included.
\ No newline at end of file
+'Comments' field or attach a file with it included.
-- 
cgit v1.2.1


From c5417d8916b9ca9ae75aef10a41fde4d5070d271 Mon Sep 17 00:00:00 2001
From: Georges Basile Stavracas Neto 
Date: Sat, 12 May 2018 20:16:52 -0300
Subject: project: Update gitignore

---
 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index bee8a64b7..0c7ddc104 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
 __pycache__
+_build/
+**/*~
\ No newline at end of file
-- 
cgit v1.2.1


From 8ae16f34f645a3f4de7a15436437a062156a49f2 Mon Sep 17 00:00:00 2001
From: Georges Basile Stavracas Neto 
Date: Sat, 12 May 2018 20:54:23 -0300
Subject: docs: Document style of comments

---
 docs/HACKING.md | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/docs/HACKING.md b/docs/HACKING.md
index aa798d44e..8415c2e3d 100644
--- a/docs/HACKING.md
+++ b/docs/HACKING.md
@@ -10,6 +10,18 @@ The most important rule is: **see the surrounding code, and copy its style**.
 Another rule that applies to function declarations is that all parameters are
 aligned by the last '*'. There are plenty of examples below.
 
+## Comments
+
+Comment blocks should be formatted as following:
+
+```c
+/* Single line comment */
+
+/* Multiline comments start at the first line of the comment block,
+ * but have the closing slash a line after. Every line starts with
+ * an asterisk that is aligned with every the rest of the block.
+ */
+
 ## Header (.h) files
 
 It is organized by the following structure:
-- 
cgit v1.2.1


From 057610e982adf07a14a9ff96c9730acc2db4bd6e Mon Sep 17 00:00:00 2001
From: Georges Basile Stavracas Neto 
Date: Sun, 13 May 2018 19:45:52 +0000
Subject: docs: Fix code block

---
 docs/HACKING.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/docs/HACKING.md b/docs/HACKING.md
index 8415c2e3d..cf9265f50 100644
--- a/docs/HACKING.md
+++ b/docs/HACKING.md
@@ -21,6 +21,7 @@ Comment blocks should be formatted as following:
  * but have the closing slash a line after. Every line starts with
  * an asterisk that is aligned with every the rest of the block.
  */
+```
 
 ## Header (.h) files
 
-- 
cgit v1.2.1


From 66668676fcb2cd95422b6da734e7b96b5e36ce3a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Claudio=20Andr=C3=A9?= 
Date: Sat, 12 May 2018 09:24:59 -0300
Subject: CI: pass build artifacts to another stage

Avoid to redo some tasks (save git untracked files e use them).

See #46.
---
 .gitlab-ci.yml | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 1039e0550..5508db235 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -12,6 +12,11 @@ stages:
 ##
 build:
   stage: build
+  artifacts:
+    name: builded
+    untracked: true
+    expire_in: 3h30min
+
   script:
     - meson . _build
     - ninja -C _build
@@ -25,9 +30,10 @@ build:
 ##
 test:
   stage: test
+  dependencies:
+    - build
+
   script:
-    - meson . _build
-    - ninja -C _build
     - |
       if [[ -n "${CI_COMMIT_TAG}" ]]; then
         echo "== Distro Test =="
-- 
cgit v1.2.1


From 9460babd1e54d1e977b62d59e0e1177c34721615 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Claudio=20Andr=C3=A9?= 
Date: Sat, 12 May 2018 13:00:29 -0300
Subject: CI: use an updated Docker image

We value repeatability and reproducibility; that said, we need to use a
fresh Fedora. So, pick an image that is updated every week.
---
 .gitlab-ci.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5508db235..a51869f64 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,4 +1,4 @@
-image: claudioandre/control-center:job-445.6
+image: claudioandre/settings:fedora.dev
 stages:
   - build
   - test
-- 
cgit v1.2.1


From e2a18bec4964ef82d8ec6bd921c9467aff2fcf15 Mon Sep 17 00:00:00 2001
From: Georges Basile Stavracas Neto 
Date: Thu, 10 May 2018 18:11:23 -0300
Subject: project: Move build files to build-aux

An attempt to make the root folder slightly less
cluttered and more organized. No functional changes
whatsoever.
---
 build-aux/meson.build                 |  5 +++++
 build-aux/meson/meson_post_install.py | 15 +++++++++++++++
 build-aux/meson/update-from-gsd.in    | 10 ++++++++++
 build-aux/meson/update-from-gsd.sh    | 26 ++++++++++++++++++++++++++
 build-aux/meson/update-from-nma.in    | 19 +++++++++++++++++++
 meson.build                           | 10 +---------
 meson_post_install.py                 | 15 ---------------
 update-from-gsd.in                    | 10 ----------
 update-from-gsd.sh                    | 26 --------------------------
 update-from-nma.in                    | 19 -------------------
 10 files changed, 76 insertions(+), 79 deletions(-)
 create mode 100644 build-aux/meson.build
 create mode 100644 build-aux/meson/meson_post_install.py
 create mode 100755 build-aux/meson/update-from-gsd.in
 create mode 100755 build-aux/meson/update-from-gsd.sh
 create mode 100755 build-aux/meson/update-from-nma.in
 delete mode 100644 meson_post_install.py
 delete mode 100755 update-from-gsd.in
 delete mode 100755 update-from-gsd.sh
 delete mode 100755 update-from-nma.in

diff --git a/build-aux/meson.build b/build-aux/meson.build
new file mode 100644
index 000000000..f3fdb40a8
--- /dev/null
+++ b/build-aux/meson.build
@@ -0,0 +1,5 @@
+update_from_gsd = find_program('meson/update-from-gsd.sh')
+update_from_gsd_in = files('meson/update-from-gsd.in')
+update_from_nma_in = files('meson/update-from-nma.in')
+
+meson.add_install_script('meson/meson_post_install.py', control_center_datadir)
diff --git a/build-aux/meson/meson_post_install.py b/build-aux/meson/meson_post_install.py
new file mode 100644
index 000000000..f9119e1a7
--- /dev/null
+++ b/build-aux/meson/meson_post_install.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+import os
+import subprocess
+import sys
+
+gsettingsschemadir = os.path.join(sys.argv[1], 'glib-2.0', 'schemas')
+icondir = os.path.join(sys.argv[1], 'icons', 'hicolor')
+
+if not os.environ.get('DESTDIR'):
+    print('Compiling gsettings schemas...')
+    subprocess.call(['glib-compile-schemas', gsettingsschemadir])
+
+    print('Update icon cache...')
+    subprocess.call(['gtk-update-icon-cache', '-f', '-t', icondir])
diff --git a/build-aux/meson/update-from-gsd.in b/build-aux/meson/update-from-gsd.in
new file mode 100755
index 000000000..29d06be8d
--- /dev/null
+++ b/build-aux/meson/update-from-gsd.in
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+cd @working_dir@
+
+export FILES="@source_files@"
+export DIR="@input_dir@"
+
+@program@ &&
+git add @source_files@ &&
+git commit -m "@source_message@"
diff --git a/build-aux/meson/update-from-gsd.sh b/build-aux/meson/update-from-gsd.sh
new file mode 100755
index 000000000..9f2d6b79c
--- /dev/null
+++ b/build-aux/meson/update-from-gsd.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+function die() {
+  echo $*
+  exit 1
+}
+
+if test -z "$DIR"; then
+   echo "Must set DIR"
+   exit 1
+fi
+
+if test -z "$FILES"; then
+   echo "Must set FILES"
+   exit 1
+fi
+
+for FILE in $FILES; do
+  if cmp -s $DIR/$FILE $FILE; then
+     echo "File $FILE is unchanged"
+  else
+     cp $DIR/$FILE $FILE || die "Could not move $DIR/$FILE to $FILE"
+     echo "Updated $FILE"
+     git add $FILE
+  fi
+done
diff --git a/build-aux/meson/update-from-nma.in b/build-aux/meson/update-from-nma.in
new file mode 100755
index 000000000..76738b10b
--- /dev/null
+++ b/build-aux/meson/update-from-nma.in
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+cd @working_dir@
+
+export FILES="@source_files@"
+export DIR="@input_dir@"
+
+@program@ &&
+patch -p4 < @source_patch@ &&
+git add @source_files@ &&
+git commit -m "@source_message@"
+
+export FILES="@resource_data@"
+export DIR="@input_dir@"
+
+@program@ &&
+patch -p4 < @resource_patch@ &&
+git add @resource_data@ &&
+git commit -m "@resource_message@"
diff --git a/meson.build b/meson.build
index 2e7a36d3c..340e2004e 100644
--- a/meson.build
+++ b/meson.build
@@ -249,10 +249,7 @@ install_subdir(
 top_inc = include_directories('.')
 shell_inc = include_directories('shell')
 
-update_from_gsd = find_program('update-from-gsd.sh')
-update_from_gsd_in = files('update-from-gsd.in')
-update_from_nma_in = files('update-from-nma.in')
-
+subdir('build-aux')
 subdir('data/icons')
 subdir('po')
 subdir('panels')
@@ -269,11 +266,6 @@ configure_file(
   configuration: config_h
 )
 
-meson.add_install_script(
-  'meson_post_install.py',
-  control_center_datadir
-)
-
 output = ''
 output += '\n        ' + meson.project_name() + ' - ' + meson.project_version() + '\n'
 output += '    ===================================\n'
diff --git a/meson_post_install.py b/meson_post_install.py
deleted file mode 100644
index f9119e1a7..000000000
--- a/meson_post_install.py
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env python3
-
-import os
-import subprocess
-import sys
-
-gsettingsschemadir = os.path.join(sys.argv[1], 'glib-2.0', 'schemas')
-icondir = os.path.join(sys.argv[1], 'icons', 'hicolor')
-
-if not os.environ.get('DESTDIR'):
-    print('Compiling gsettings schemas...')
-    subprocess.call(['glib-compile-schemas', gsettingsschemadir])
-
-    print('Update icon cache...')
-    subprocess.call(['gtk-update-icon-cache', '-f', '-t', icondir])
diff --git a/update-from-gsd.in b/update-from-gsd.in
deleted file mode 100755
index 29d06be8d..000000000
--- a/update-from-gsd.in
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-
-cd @working_dir@
-
-export FILES="@source_files@"
-export DIR="@input_dir@"
-
-@program@ &&
-git add @source_files@ &&
-git commit -m "@source_message@"
diff --git a/update-from-gsd.sh b/update-from-gsd.sh
deleted file mode 100755
index 9f2d6b79c..000000000
--- a/update-from-gsd.sh
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-
-function die() {
-  echo $*
-  exit 1
-}
-
-if test -z "$DIR"; then
-   echo "Must set DIR"
-   exit 1
-fi
-
-if test -z "$FILES"; then
-   echo "Must set FILES"
-   exit 1
-fi
-
-for FILE in $FILES; do
-  if cmp -s $DIR/$FILE $FILE; then
-     echo "File $FILE is unchanged"
-  else
-     cp $DIR/$FILE $FILE || die "Could not move $DIR/$FILE to $FILE"
-     echo "Updated $FILE"
-     git add $FILE
-  fi
-done
diff --git a/update-from-nma.in b/update-from-nma.in
deleted file mode 100755
index 76738b10b..000000000
--- a/update-from-nma.in
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/sh
-
-cd @working_dir@
-
-export FILES="@source_files@"
-export DIR="@input_dir@"
-
-@program@ &&
-patch -p4 < @source_patch@ &&
-git add @source_files@ &&
-git commit -m "@source_message@"
-
-export FILES="@resource_data@"
-export DIR="@input_dir@"
-
-@program@ &&
-patch -p4 < @resource_patch@ &&
-git add @resource_data@ &&
-git commit -m "@resource_message@"
-- 
cgit v1.2.1


From 7322cdc45bc5b23b99e1ccaced8c554554f98af3 Mon Sep 17 00:00:00 2001
From: Georges Basile Stavracas Neto 
Date: Thu, 10 May 2018 23:01:09 -0300
Subject: project: Add a development flatpak manifest

The development flatpak is meant to be used exactly
that: development. It isn't and won't ever be released
as a regular Flatpak application.

GNOME Setting is still supposed to run as a host system
tool.
---
 build-aux/flatpak/org.gnome.Settings.json | 446 ++++++++++++++++++++++++++++++
 1 file changed, 446 insertions(+)
 create mode 100644 build-aux/flatpak/org.gnome.Settings.json

diff --git a/build-aux/flatpak/org.gnome.Settings.json b/build-aux/flatpak/org.gnome.Settings.json
new file mode 100644
index 000000000..ea91887fc
--- /dev/null
+++ b/build-aux/flatpak/org.gnome.Settings.json
@@ -0,0 +1,446 @@
+{
+    "app-id" : "org.gnome.Settings",
+    "runtime" : "org.gnome.Platform",
+    "runtime-version" : "master",
+    "sdk" : "org.gnome.Sdk",
+    "command" : "gnome-control-center",
+    "tags" : [
+        "devel"
+    ],
+    "desktop-file-name-prefix" : "(Development) ",
+    "finish-args" : [
+        "--device=dri",
+        "--env=DCONF_USER_CONFIG_DIR=.config/dconf",
+        "--filesystem=host",
+        "--own-name=org.gnome.ControlCenter",
+        "--own-name=org.gnome.SessionManager",
+        "--share=ipc",
+        "--share=network",
+        "--socket=x11",
+        "--socket=pulseaudio",
+        "--socket=session-bus",
+        "--socket=system-bus",
+        "--socket=wayland"
+    ],
+    "build-options" : {
+        "cflags" : "-O2 -g",
+        "cxxflags" : "-O2 -g",
+        "env" : {
+            "V" : "1"
+        }
+    },
+    "x-run-args" : [
+        "--verbose"
+    ],
+    "cleanup" : [
+        "/include",
+        "/share/aclocal",
+        "/man",
+        "/share/man",
+        "/share/gtk-doc",
+        "/share/vala",
+        "*.la",
+        "*.a"
+    ],
+    "modules" : [
+        {
+            "name" : "pwquality",
+            "buildsystem" : "autotools",
+            "config-opts" : [
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "https://github.com/libpwquality/libpwquality.git"
+                }
+            ]
+        },
+        {
+            "name" : "polkit",
+            "buildsystem" : "autotools",
+            "config-opts" : [
+                "--disable-introspection",
+                "--disable-libelogind"
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://anongit.freedesktop.org/polkit"
+                }
+            ]
+        },
+        {
+            "name" : "accountservice",
+            "buildsystem" : "autotools",
+            "config-opts" : [
+                "--disable-systemd",
+                "--disable-elogind"
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://anongit.freedesktop.org/accountsservice"
+                }
+            ]
+        },
+        {
+            "name" : "libusb1",
+            "buildsystem" : "autotools",
+            "config-opts" : [
+                "--disable-udev"
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://github.com/libusb/libusb.git"
+                }
+            ]
+        },
+        {
+            "name" : "gusb",
+            "buildsystem" : "meson",
+            "config-opts" : [
+                "-Ddocs=false",
+                "-Dtests=false",
+                "-Dvapi=false"
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://github.com/hughsie/libgusb.git"
+                }
+            ]
+        },
+        {
+            "name" : "udev",
+            "config-opts" : [
+                "--disable-hwdb",
+                "--disable-logging",
+                "--disable-gudev",
+                "--disable-introspection",
+                "--disable-keymap",
+                "--disable-mtd_probe"
+            ],
+            "cleanup" : [
+                "/include",
+                "/etc",
+                "/libexec",
+                "/sbin",
+                "/lib/pkgconfig",
+                "/man",
+                "/share/aclocal",
+                "/share/doc",
+                "/share/gtk-doc",
+                "/share/man",
+                "/share/pkgconfig",
+                "*.la",
+                "*.a"
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://github.com/gentoo/eudev.git"
+                }
+            ]
+        },
+        {
+            "name" : "gudev",
+            "buildsystem" : "autotools",
+            "config-opts" : [
+                "--disable-umockdev"
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://git.gnome.org/libgudev"
+                }
+            ]
+        },
+        {
+            "name" : "colord",
+            "buildsystem" : "meson",
+            "config-opts" : [
+                "-Dargyllcms_sensor=false",
+                "-Dbash_completion=false",
+                "-Dman=false",
+                "-Dudev_rules=false",
+                "-Dsystemd=false"
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://github.com/hughsie/colord.git"
+                }
+            ]
+        },
+        {
+            "name" : "colord-gtk",
+            "buildsystem" : "autotools",
+            "config-opts" : [
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://github.com/hughsie/colord-gtk.git"
+                }
+            ]
+        },
+        {
+            "name" : "rest",
+            "buildsystem" : "autotools",
+            "sources" : [
+                {
+                    "type" : "git",
+                    "branch" : "librest-0-7",
+                    "url" : "https://git.gnome.org/browse/librest"
+                }
+            ]
+        },
+        {
+            "name" : "gnome-online-accounts",
+            "buildsystem" : "autotools",
+            "config-opts" : [
+                "--disable-telepathy",
+                "--disable-documentation"
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://git.gnome.org/gnome-online-accounts"
+                }
+            ]
+        },
+        {
+            "name" : "gnome-desktop",
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://git.gnome.org/gnome-desktop"
+                }
+            ]
+        },
+        {
+            "name" : "geocode-glib",
+            "buildsystem" : "meson",
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://git.gnome.org/geocode-glib"
+                }
+            ]
+        },
+        {
+            "name" : "libgweather",
+            "buildsystem" : "meson",
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "https://gitlab.gnome.org/GNOME/libgweather.git"
+                }
+            ]
+        },
+        {
+            "name" : "upower",
+            "buildsystem" : "autotools",
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://anongit.freedesktop.org/upower"
+                }
+            ]
+        },
+        {
+            "name" : "libwacom",
+            "buildsystem" : "autotools",
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "https://github.com/linuxwacom/libwacom.git"
+                }
+            ]
+        },
+        {
+            "name" : "libndp",
+            "buildsystem" : "autotools",
+            "sources" : [
+                {
+                    "type" : "archive",
+                    "url" : " http://libndp.org/files/libndp-1.6.tar.gz",
+                    "sha256" : "0c7dfa84e013bd5e569ef2c6292a6f72cfaf14f4ff77a77425e52edc33ffac0e"
+                }
+            ]
+        },
+        {
+            "name" : "NetworkManager",
+            "buildsystem" : "meson",
+            "config-opts" : [
+                "-Dlibaudit=no",
+                "-Ddbus_conf_dir=/app/etc/dbus-1/system.d",
+                "-Ddbus_ifaces_dir=/app/share/dbus-1/interfaces",
+                "-Ddbus_sys_dir=/app/share/dbus-1/system.d",
+                "-Ddnsmasq=/usr/bin/true",
+                "-Ddocs=false",
+                "-Dintrospection=false",
+                "-Diptables=/usr/bin/true",
+                "-Djson_validation=false",
+                "-Dlibnm_glib=false",
+                "-Dmodem_manager=false",
+                "-Dnmtui=false",
+                "-Dovs=false",
+                "-Dppp=false",
+                "-Dqt=false",
+                "-Dselinux=false",
+                "-Dsession_tracking=no",
+                "-Dsystemdsystemunitdir='no'",
+                "-Dsystemd_journal=false",
+                "-Dtests=no",
+                "-Dvapi=false"
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://anongit.freedesktop.org/NetworkManager/NetworkManager"
+                }
+            ]
+        },
+        {
+            "name" : "network-manager-applet",
+            "buildsystem" : "meson",
+            "config-opts" : [
+                "-Dgtk_doc=false",
+                "-Dintrospection=false",
+                "-Dlibnm_gtk=false",
+                "-Dselinux=false",
+                "-Dteam=false",
+                "-Dwwan=false"
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://git.gnome.org/network-manager-applet"
+                }
+            ]
+        },
+        {
+            "name" : "ModemManager",
+            "buildsystem" : "autotools",
+            "config-opts" : [
+                "--disable-introspection",
+                "--disable-vala",
+                "--with-udev-base-dir=/app/lib",
+                "--without-mbim",
+                "--without-qmi"
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://anongit.freedesktop.org/ModemManager/ModemManager"
+                }
+            ]
+        },
+        {
+            "name" : "gnome-settings-daemon",
+            "buildsystem" : "meson",
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "https://gitlab.gnome.org/GNOME/gnome-settings-daemon.git"
+                }
+            ]
+        },
+        {
+            "name" : "gnome-bluetooth",
+            "buildsystem" : "meson",
+            "config-opts" : [
+                "-Dintrospection=false"
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://git.gnome.org/gnome-bluetooth"
+                }
+            ]
+        },
+        {
+            "name" : "grilo",
+            "buildsystem" : "meson",
+            "config-opts" : [
+                "-Denable-grl-pls=false",
+                "-Denable-gtk-doc=false",
+                "-Denable-introspection=false",
+                "-Denable-test-ui=false",
+                "-Denable-vala=false"
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://git.gnome.org/grilo"
+                }
+            ]
+        },
+        {
+            "name" : "openldap",
+            "buildsystem" : "autotools",
+            "config-opts" : [
+                "--disable-slapd"
+            ],
+            "sources" : [
+                {
+                    "type" : "archive",
+                    "url" : "https://www.openldap.org/software/download/OpenLDAP/openldap-release/openldap-2.4.46.tgz",
+                    "sha256" : "9a90dcb86b99ae790ccab93b7585a31fbcbeec8c94bf0f7ab0ca0a87ea0c4b2d"
+                }
+            ]
+        },
+        {
+            "name" : "samba",
+            "buildsystem" : "autotools",
+            "sources" : [
+                {
+                    "type" : "archive",
+                    "url" : "https://download.samba.org/pub/samba/stable/samba-4.8.1.tar.gz",
+                    "sha256" : "8ef7367507f16b7a5e2f6aed5bcdbd1143feca79aa2a07c9b21292b17d7f789d"
+                }
+            ]
+        },
+        {
+            "name" : "libgtop2",
+            "buildsystem" : "autotools",
+            "config-opts" : [
+                "--disable-introspection"
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "https://gitlab.gnome.org/GNOME/libgtop.git"
+                }
+            ]
+        },
+        {
+            "name" : "cheese",
+            "buildsystem" : "autotools",
+            "config-opts" : [
+                "--disable-introspection"
+            ],
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "git://git.gnome.org/cheese"
+                }
+            ]
+        },
+        {
+            "name" : "gnome-control-center",
+            "buildsystem" : "meson",
+            "sources" : [
+                {
+                    "type" : "git",
+                    "url" : "https://gitlab.gnome.org/GNOME/gnome-control-center.git"
+                }
+            ],
+            "config-opts" : [
+                "-Dtracing=true"
+            ]
+        }
+    ]
+}
\ No newline at end of file
-- 
cgit v1.2.1


From 50094b45a67b4266532f34433001ca110b7a95ce Mon Sep 17 00:00:00 2001
From: Georges Basile Stavracas Neto 
Date: Fri, 11 May 2018 22:45:51 -0300
Subject: window: Warn about development builds

With this commit, a message dialog pops up whenever a
development build runs. This is meant to actually annoy,
so that we're always reminded that things may not work
as expected.

Since the dialog can be dismissed with a single button
press, it is not the end of the world. But people still
should be aware that Settings is ~not~ meant to run with
Flatpak, and that this is a development tool only.
---
 meson.build                               |  2 +-
 meson_options.txt                         |  2 +-
 shell/cc-window.c                         | 74 +++++++++++++++++++++++++++++++
 shell/org.gnome.ControlCenter.gschema.xml |  7 +++
 shell/window.ui                           | 13 ++++++
 5 files changed, 96 insertions(+), 2 deletions(-)

diff --git a/meson.build b/meson.build
index 340e2004e..a61acc9c4 100644
--- a/meson.build
+++ b/meson.build
@@ -282,4 +282,4 @@ output += '     NetworkManager (Network panel) ............. ' + host_is_linux.t
 output += '     Wacom (Wacom tablet panel) ................. ' + host_is_linux_not_s390.to_string() + '\n'
 output += '     Wayland .................................... ' + enable_wayland.to_string() + '\n'
 
-message(output)
+message(output)
\ No newline at end of file
diff --git a/meson_options.txt b/meson_options.txt
index a01c11553..a347168b7 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -3,4 +3,4 @@ option('documentation', type: 'boolean', value: false, description: 'build docum
 option('gnome_session_libexecdir', type: 'string', value: '', description: 'Directory for gnome-session\'s libexecdir')
 option('ibus', type: 'boolean', value: true, description: 'build with IBus support')
 option('tracing', type: 'boolean', value: false, description: 'add extra debugging information')
-option('wayland', type: 'boolean', value: true, description: 'build with Wayland support')
+option('wayland', type: 'boolean', value: true, description: 'build with Wayland support')
\ No newline at end of file
diff --git a/shell/cc-window.c b/shell/cc-window.c
index f8dbc0ffb..50d3995d7 100644
--- a/shell/cc-window.c
+++ b/shell/cc-window.c
@@ -65,6 +65,7 @@ struct _CcWindow
   GtkWidget  *search_entry;
   GtkWidget  *lock_button;
   GtkWidget  *current_panel_box;
+  GtkWidget  *development_warning_dialog;
   GtkWidget  *current_panel;
   char       *current_panel_id;
   GQueue     *previous_panels;
@@ -91,6 +92,47 @@ enum
 };
 
 /* Auxiliary methods */
+static gboolean
+in_flatpak_sandbox (void)
+{
+  return g_file_test ("/.flatpak-info", G_FILE_TEST_EXISTS);
+}
+
+static void
+add_development_build_css (CcWindow *self)
+{
+  g_autoptr(GtkCssProvider) provider = NULL;
+  g_autoptr(GError) error = NULL;
+
+  /* This CSS snipped is added on development builds of GNOME Settings. It is
+   * not meant to be beautiful (althout it is) and is only supposed to integrate
+   * with Adwaita light (although it integrates well with dark too).
+   */
+
+  const gchar *development_build_css =
+  "window.development-version headerbar {\n"
+   "  background: @theme_bg_color linear-gradient(to top,\n"
+   "                                              alpha(@theme_selected_bg_color, 0.34),\n"
+   "                                              alpha(@theme_selected_bg_color, 0.27) 2px,\n"
+   "                                              alpha(@theme_selected_bg_color, 0.20) 3px);\n"
+   "}";
+
+  gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (self)), "development-version");
+
+  provider = gtk_css_provider_new ();
+  gtk_css_provider_load_from_data (provider, development_build_css, -1, &error);
+
+  if (error)
+    {
+      g_error ("Failed to load CSS: %s", error->message);
+      return;
+    }
+
+  gtk_style_context_add_provider_for_screen (gtk_widget_get_screen (GTK_WIDGET (self)),
+                                             GTK_STYLE_PROVIDER (provider),
+                                             GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+}
+
 static gchar *
 get_symbolic_icon_name_from_g_icon (GIcon *gicon)
 {
@@ -580,6 +622,17 @@ split_decorations_cb (GtkSettings *settings,
   gtk_header_bar_set_decoration_layout (GTK_HEADER_BAR (self->panel_headerbar), layout_end);
 }
 
+static void
+on_development_warning_dialog_responded_cb (GtkWidget *dialog,
+                                            gint       response,
+                                            CcWindow  *self)
+{
+  g_debug ("Disabling development build warning dialog");
+  g_settings_set_boolean (self->settings, "show-development-warning", FALSE);
+
+  gtk_widget_hide (dialog);
+}
+
 /* CcShell implementation */
 static gboolean
 cc_window_set_active_panel_from_id (CcShell      *shell,
@@ -618,6 +671,19 @@ cc_shell_iface_init (CcShellInterface *iface)
   iface->get_toplevel = cc_window_get_toplevel;
 }
 
+/* GtkWidget overrides */
+static void
+cc_window_map (GtkWidget *widget)
+{
+  CcWindow *self = (CcWindow *) widget;
+
+  GTK_WIDGET_CLASS (cc_window_parent_class)->map (widget);
+
+  /* Show a warning for Flatpak builds */
+  if (in_flatpak_sandbox () && g_settings_get_boolean (self->settings, "show-development-warning"))
+    gtk_window_present (GTK_WINDOW (self->development_warning_dialog));
+}
+
 /* GObject Implementation */
 static void
 cc_window_get_property (GObject    *object,
@@ -695,10 +761,13 @@ cc_window_class_init (CcWindowClass *klass)
   object_class->dispose = cc_window_dispose;
   object_class->finalize = cc_window_finalize;
 
+  widget_class->map = cc_window_map;
+
   g_object_class_override_property (object_class, PROP_ACTIVE_PANEL, "active-panel");
 
   gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/ControlCenter/gtk/window.ui");
 
+  gtk_widget_class_bind_template_child (widget_class, CcWindow, development_warning_dialog);
   gtk_widget_class_bind_template_child (widget_class, CcWindow, header);
   gtk_widget_class_bind_template_child (widget_class, CcWindow, header_box);
   gtk_widget_class_bind_template_child (widget_class, CcWindow, header_sizegroup);
@@ -714,6 +783,7 @@ cc_window_class_init (CcWindowClass *klass)
   gtk_widget_class_bind_template_child (widget_class, CcWindow, top_right_box);
 
   gtk_widget_class_bind_template_callback (widget_class, gdk_window_set_cb);
+  gtk_widget_class_bind_template_callback (widget_class, on_development_warning_dialog_responded_cb);
   gtk_widget_class_bind_template_callback (widget_class, panel_list_view_changed_cb);
   gtk_widget_class_bind_template_callback (widget_class, previous_button_clicked_cb);
   gtk_widget_class_bind_template_callback (widget_class, search_entry_activate_cb);
@@ -760,6 +830,10 @@ cc_window_init (CcWindow *self)
     cc_panel_list_set_active_panel (CC_PANEL_LIST (self->panel_list), id);
   else
     cc_panel_list_activate (CC_PANEL_LIST (self->panel_list));
+
+  /* Add a custom CSS class on development builds */
+  if (in_flatpak_sandbox ())
+    add_development_build_css (self);
 }
 
 CcWindow *
diff --git a/shell/org.gnome.ControlCenter.gschema.xml b/shell/org.gnome.ControlCenter.gschema.xml
index a40b9b08c..40350bca4 100644
--- a/shell/org.gnome.ControlCenter.gschema.xml
+++ b/shell/org.gnome.ControlCenter.gschema.xml
@@ -8,5 +8,12 @@
         will be ignored and the first panel in the list selected.
       
     
+    
+      true
+      Show warning when running a development build of Settings
+      
+        Whether Settings should show a warning when running a development build.
+      
+    
   
 
diff --git a/shell/window.ui b/shell/window.ui
index 92ff197ce..c34ce60bc 100644
--- a/shell/window.ui
+++ b/shell/window.ui
@@ -224,4 +224,17 @@
       
     
   
+
+  
+  
+    warning
+    CcWindow
+    false
+    true
+    ok
+    Warning: Development Version
+    This version of Settings should only be used for development purposes. You may experience incorrect system behavior, data loss, and other unexpected issues. 
+    
+  
+
 
-- 
cgit v1.2.1


From 4a5a2c72802101771fb0dc86f86a71a450427487 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Claudio=20Andr=C3=A9?= 
Date: Mon, 14 May 2018 14:32:38 -0300
Subject: CI: add status information to the build

---
 .gitlab-ci.yml | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index a51869f64..516ae9577 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -18,10 +18,12 @@ build:
     expire_in: 3h30min
 
   script:
+    - echo "== Building =="
     - meson . _build
     - ninja -C _build
-    - ninja -C _build install
 
+    - echo "== Installing =="
+    - ninja -C _build install
 
 ##
 # Stage: Test
-- 
cgit v1.2.1


From f4433b3766bab48b85ae0e42e3e704bb7f380663 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Claudio=20Andr=C3=A9?= 
Date: Mon, 14 May 2018 14:53:48 -0300
Subject: CI: print some info about the build env

It is not possible to debug if the developer knows nothing about
the CI running environment.
---
 .gitlab-ci.yml     | 19 ++++++++++++++++-
 tests/ci-helper.sh | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 1 deletion(-)
 create mode 100755 tests/ci-helper.sh

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 516ae9577..6d17c8dab 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -18,13 +18,20 @@ build:
     expire_in: 3h30min
 
   script:
+    - echo "== Info =="
+    - tests/ci-helper.sh "INFO"
+    - tests/ci-helper.sh "GIT_INFO"
+
     - echo "== Building =="
     - meson . _build
-    - ninja -C _build
+    - ninja -C _build 2>&1 | tee compilation.log
 
     - echo "== Installing =="
     - ninja -C _build install
 
+    - echo "== Report =="
+    - tests/ci-helper.sh "WARNINGS"
+
 ##
 # Stage: Test
 #
@@ -32,10 +39,20 @@ build:
 ##
 test:
   stage: test
+  artifacts:
+    name: log
+    when: always
+    paths:
+    - $(pwd)/*.log
+
   dependencies:
     - build
 
   script:
+    - echo "== Info =="
+    - tests/ci-helper.sh "INFO"
+    - tests/ci-helper.sh "GIT_INFO"
+
     - |
       if [[ -n "${CI_COMMIT_TAG}" ]]; then
         echo "== Distro Test =="
diff --git a/tests/ci-helper.sh b/tests/ci-helper.sh
new file mode 100755
index 000000000..f8409dd21
--- /dev/null
+++ b/tests/ci-helper.sh
@@ -0,0 +1,61 @@
+#!/bin/bash -e
+
+function do_print_labels(){
+
+    if [[ -n "${1}" ]]; then
+        label_len=${#1}
+        span=$(((54 - $label_len) / 2))
+
+        echo
+        echo "= ======================================================== ="
+        printf "%s %${span}s %s %${span}s %s\n" "=" "" "$1" "" "="
+        echo "= ======================================================== ="
+    else
+        echo "= ========================= Done ========================= ="
+        echo
+    fi
+}
+
+function do_show_info(){
+
+    local compiler=gcc
+
+    echo -n "Processors: "; grep -c ^processor /proc/cpuinfo
+    grep ^MemTotal /proc/meminfo
+    id; uname -a
+    printenv
+    echo '-----------------------------------------'
+    cat /etc/*-release
+    echo '-----------------------------------------'
+
+    if [[ ! -z $CC ]]; then
+        compiler=$CC
+    fi
+    echo 'Compiler version'
+    $compiler --version
+    echo '-----------------------------------------'
+    $compiler -dM -E -x c /dev/null
+    echo '-----------------------------------------'
+}
+
+function do_check_warnings(){
+
+    cat compilation.log | grep "warning:" | awk '{total+=1}END{print "Total number of warnings: "total}'
+}
+
+# -----------  -----------
+if [[ $1 == "INFO" ]]; then
+    do_print_labels 'Build environment '
+    do_show_info
+    do_print_labels
+
+elif [[ $1 == "GIT_INFO" ]]; then
+    do_print_labels 'The Commit'
+    git log --pretty=format:"%h %cd %s" -1; echo
+    do_print_labels
+
+elif [[ $1 == "WARNINGS" ]]; then
+    do_print_labels 'Warnings Report '
+    do_check_warnings
+    do_print_labels
+fi
-- 
cgit v1.2.1