summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatej Urbančič <mateju@svn.gnome.org>2018-05-15 21:03:11 +0200
committerMatej Urbančič <mateju@svn.gnome.org>2018-05-15 21:03:11 +0200
commit2acb520fc9b19118107916b4c89a041d1651df4d (patch)
treede915d27698f0f0ee89862dfce8c103c157df952
parent2da5fd3b3dfb4a0f2885349dad2a8e2cc063119c (diff)
parentf4433b3766bab48b85ae0e42e3e704bb7f380663 (diff)
downloadgnome-control-center-2acb520fc9b19118107916b4c89a041d1651df4d.tar.gz
Merge branch 'master' of gitlab.gnome.org:GNOME/gnome-control-center
-rw-r--r--.gitignore3
-rw-r--r--.gitlab-ci.yml73
-rw-r--r--.gitlab/issue_templates/Bug.md8
-rw-r--r--.gitlab/issue_templates/Epic.md41
-rw-r--r--.gitlab/issue_templates/Feature.md17
-rw-r--r--README.md (renamed from README)34
-rw-r--r--build-aux/flatpak/org.gnome.Settings.json446
-rw-r--r--build-aux/meson.build5
-rw-r--r--build-aux/meson/meson_post_install.py (renamed from meson_post_install.py)0
-rwxr-xr-xbuild-aux/meson/update-from-gsd.in (renamed from update-from-gsd.in)0
-rwxr-xr-xbuild-aux/meson/update-from-gsd.sh (renamed from update-from-gsd.sh)0
-rwxr-xr-xbuild-aux/meson/update-from-nma.in (renamed from update-from-nma.in)0
-rw-r--r--data/icons/meson.build4
-rw-r--r--docs/CONTRIBUTING.md71
-rw-r--r--docs/HACKING.md213
-rw-r--r--gnome-control-center.doap25
-rw-r--r--man/meson.build12
-rw-r--r--meson.build60
-rw-r--r--meson_options.txt3
-rw-r--r--panels/bluetooth/cc-bluetooth-panel.c35
-rw-r--r--panels/color/cc-color-calibrate.c48
-rw-r--r--panels/color/cc-color-panel.c3
-rw-r--r--panels/color/meson.build2
-rw-r--r--panels/common/cc-common-language.c16
-rw-r--r--panels/common/cc-hostname-entry.c (renamed from shell/cc-hostname-entry.c)0
-rw-r--r--panels/common/cc-hostname-entry.h (renamed from shell/cc-hostname-entry.h)0
-rw-r--r--panels/common/cc-language-chooser.c2
-rw-r--r--panels/common/hostname-helper.c (renamed from shell/hostname-helper.c)0
-rw-r--r--panels/common/hostname-helper.h (renamed from shell/hostname-helper.h)0
-rw-r--r--panels/common/list-box-helper.c (renamed from shell/list-box-helper.c)0
-rw-r--r--panels/common/list-box-helper.h (renamed from shell/list-box-helper.h)0
-rw-r--r--panels/common/meson.build18
-rw-r--r--panels/datetime/backward34
-rw-r--r--panels/datetime/cc-datetime-panel.c2
-rw-r--r--panels/datetime/meson.build25
-rw-r--r--panels/datetime/test-timezone-gfx.c61
-rw-r--r--panels/datetime/test-timezone.c108
-rw-r--r--panels/display/cc-display-panel.c108
-rw-r--r--panels/display/cc-night-light-dialog.c75
-rw-r--r--panels/display/meson.build2
-rw-r--r--panels/info/cc-info-overview-panel.c44
-rw-r--r--panels/info/meson.build24
-rw-r--r--panels/keyboard/shortcut-editor.ui2
-rw-r--r--panels/meson.build1
-rw-r--r--panels/mouse/gnome-mouse-properties.c2
-rw-r--r--panels/network/cc-network-panel.c34
-rw-r--r--panels/network/cc-wifi-panel.c65
-rw-r--r--panels/network/connection-editor/ce-page-ip4.c2
-rw-r--r--panels/network/connection-editor/ce-page-ip6.c2
-rw-r--r--panels/network/connection-editor/meson.build2
-rw-r--r--panels/network/connection-editor/net-connection-editor.c2
-rw-r--r--panels/network/meson.build5
-rw-r--r--panels/network/net-device-ethernet.c6
-rw-r--r--panels/network/net-device-wifi.c4
-rw-r--r--panels/notifications/cc-edit-dialog.c2
-rw-r--r--panels/notifications/cc-notifications-panel.c22
-rw-r--r--panels/notifications/meson.build2
-rw-r--r--panels/online-accounts/cc-online-accounts-panel.c18
-rw-r--r--panels/online-accounts/meson.build2
-rw-r--r--panels/power/cc-power-panel.c231
-rw-r--r--panels/power/meson.build2
-rw-r--r--panels/printers/cc-printers-panel.c29
-rw-r--r--panels/printers/meson.build26
-rw-r--r--panels/printers/new-printer-dialog.ui1
-rw-r--r--panels/printers/pp-details-dialog.c1
-rw-r--r--panels/printers/pp-jobs-dialog.c2
-rw-r--r--panels/printers/pp-new-printer-dialog.c16
-rw-r--r--panels/privacy/cc-privacy-panel.c52
-rw-r--r--panels/region/cc-format-chooser.c2
-rw-r--r--panels/region/cc-input-chooser.c2
-rw-r--r--panels/region/cc-region-panel.c22
-rw-r--r--panels/search/cc-search-locations-dialog.c2
-rw-r--r--panels/search/cc-search-panel.c2
-rw-r--r--panels/search/meson.build2
-rw-r--r--panels/sharing/cc-sharing-networks.c4
-rw-r--r--panels/sharing/cc-sharing-panel.c4
-rw-r--r--panels/sharing/meson.build2
-rw-r--r--panels/thunderbolt/bolt-client.c697
-rw-r--r--panels/thunderbolt/bolt-client.h107
-rw-r--r--panels/thunderbolt/bolt-device.c604
-rw-r--r--panels/thunderbolt/bolt-device.h87
-rw-r--r--panels/thunderbolt/bolt-enums.c395
-rw-r--r--panels/thunderbolt/bolt-enums.h249
-rw-r--r--panels/thunderbolt/bolt-error.c99
-rw-r--r--panels/thunderbolt/bolt-error.h55
-rw-r--r--panels/thunderbolt/bolt-names.h50
-rw-r--r--panels/thunderbolt/bolt-proxy.c514
-rw-r--r--panels/thunderbolt/bolt-proxy.h97
-rw-r--r--panels/thunderbolt/bolt-str.c117
-rw-r--r--panels/thunderbolt/bolt-str.h43
-rw-r--r--panels/thunderbolt/bolt-time.c44
-rw-r--r--panels/thunderbolt/bolt-time.h32
-rw-r--r--panels/thunderbolt/cc-bolt-device-dialog.c476
-rw-r--r--panels/thunderbolt/cc-bolt-device-dialog.h45
-rw-r--r--panels/thunderbolt/cc-bolt-device-dialog.ui359
-rw-r--r--panels/thunderbolt/cc-bolt-device-entry.c218
-rw-r--r--panels/thunderbolt/cc-bolt-device-entry.h34
-rw-r--r--panels/thunderbolt/cc-bolt-device-entry.ui49
-rw-r--r--panels/thunderbolt/cc-bolt-panel.c959
-rw-r--r--panels/thunderbolt/cc-bolt-panel.h (renamed from shell/cc-shell-log.h)18
-rw-r--r--panels/thunderbolt/cc-bolt-panel.ui594
-rw-r--r--panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in18
-rw-r--r--panels/thunderbolt/meson.build74
-rw-r--r--panels/thunderbolt/thunderbolt.gresource.xml9
-rwxr-xr-xpanels/thunderbolt/update-from-bolt.sh50
-rw-r--r--panels/universal-access/cc-ua-panel.c2
-rw-r--r--panels/universal-access/meson.build2
-rw-r--r--panels/user-accounts/data/account-dialog.ui4
-rw-r--r--panels/user-accounts/um-account-dialog.c43
-rw-r--r--panels/user-accounts/um-realm-manager.c263
-rw-r--r--panels/user-accounts/um-realm-manager.h3
-rw-r--r--panels/wacom/meson.build54
-rw-r--r--po/POTFILES.in8
-rw-r--r--po/cs.po810
-rw-r--r--po/es.po1097
-rw-r--r--po/fur.po873
-rw-r--r--po/hr.po981
-rw-r--r--po/hu.po861
-rw-r--r--po/ko.po492
-rw-r--r--po/ro.po820
-rw-r--r--po/ru.po258
-rw-r--r--po/tr.po879
-rw-r--r--search-provider/meson.build30
-rw-r--r--shell/cc-application.c19
-rw-r--r--shell/cc-debug.h.in229
-rw-r--r--shell/cc-editable-entry.c644
-rw-r--r--shell/cc-editable-entry.h83
-rw-r--r--shell/cc-log.c107
-rw-r--r--shell/cc-log.h25
-rw-r--r--shell/cc-object-storage.c438
-rw-r--r--shell/cc-object-storage.h65
-rw-r--r--shell/cc-panel-list.c1
-rw-r--r--shell/cc-panel-loader.c6
-rw-r--r--shell/cc-shell-log.c62
-rw-r--r--shell/cc-shell-model.c61
-rw-r--r--shell/cc-shell-model.h67
-rw-r--r--shell/cc-window.c170
-rw-r--r--shell/meson.build128
-rw-r--r--shell/org.gnome.ControlCenter.gschema.xml7
-rw-r--r--shell/window.ui13
-rwxr-xr-xtests/ci-helper.sh61
-rw-r--r--tests/common/hostnames-test.txt (renamed from shell/hostnames-test.txt)0
-rw-r--r--tests/common/meson.build23
-rw-r--r--tests/common/ssids-test.txt (renamed from shell/ssids-test.txt)0
-rw-r--r--tests/common/test-hostname.c (renamed from shell/test-hostname.c)4
-rw-r--r--tests/datetime/meson.build35
-rw-r--r--tests/datetime/test-datetime.py54
-rw-r--r--tests/datetime/test-endianess.c (renamed from panels/datetime/test-endianess.c)0
-rw-r--r--tests/datetime/test-timezone-gfx.c74
-rw-r--r--tests/datetime/test-timezone.c65
-rw-r--r--tests/info/info-cleanup-test.txt (renamed from panels/info/info-cleanup-test.txt)0
-rw-r--r--tests/info/meson.build21
-rw-r--r--tests/info/test-info-cleanup.c (renamed from panels/info/test-info-cleanup.c)0
-rw-r--r--tests/meson.build7
-rw-r--r--tests/network/cc-test-window.c203
-rw-r--r--tests/network/cc-test-window.h35
-rw-r--r--tests/network/meson.build31
-rw-r--r--tests/network/nm-utils/README17
-rw-r--r--tests/network/nm-utils/gsystem-local-alloc.h208
-rw-r--r--tests/network/nm-utils/nm-dbus-compat.h74
-rw-r--r--tests/network/nm-utils/nm-default.h316
-rw-r--r--tests/network/nm-utils/nm-glib.h125
-rw-r--r--tests/network/nm-utils/nm-hash-utils.h0
-rw-r--r--tests/network/nm-utils/nm-macros-internal.h1384
-rw-r--r--tests/network/nm-utils/nm-shared-utils.h0
-rw-r--r--tests/network/nm-utils/nm-test-libnm-utils.h105
-rw-r--r--tests/network/nm-utils/nm-test-utils-impl.c457
-rw-r--r--tests/network/nm-utils/nm-test-utils.h0
-rwxr-xr-xtests/network/nm-utils/test-networkmanager-service.py1445
-rw-r--r--tests/network/nmtst-helpers.h297
-rw-r--r--tests/network/test-network-panel.c382
-rw-r--r--tests/network/test-network-panel.py44
-rw-r--r--tests/printers/canonicalization-test.txt (renamed from panels/printers/canonicalization-test.txt)0
-rw-r--r--tests/printers/meson.build22
-rw-r--r--tests/printers/shift-test.txt (renamed from panels/printers/shift-test.txt)0
-rw-r--r--tests/printers/test-canonicalization.c (renamed from panels/printers/test-canonicalization.c)0
-rw-r--r--tests/printers/test-shift.c (renamed from panels/printers/test-shift.c)0
-rw-r--r--tests/shared/gtest.py113
-rw-r--r--tests/shared/x11session.py101
179 files changed, 18883 insertions, 4715 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..0c7ddc104
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+__pycache__
+_build/
+**/*~ \ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 711923889..6d17c8dab 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,24 +1,7 @@
-image: fedora:rawhide
+image: claudioandre/settings:fedora.dev
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
-
-
-before_script:
- - dnf update -y --nogpgcheck && dnf install -y --nogpgcheck $DEPENDENCIES
-
##
# Stage: Build
@@ -29,11 +12,25 @@ before_script:
##
build:
stage: build
+ artifacts:
+ name: builded
+ untracked: true
+ 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
@@ -42,24 +39,26 @@ build:
##
test:
stage: test
- script:
- - meson . _build
- - ninja -C _build
- - ninja -C _build install
- - meson test -C _build --verbose --no-stdsplit
+ artifacts:
+ name: log
+ when: always
+ paths:
+ - $(pwd)/*.log
+ dependencies:
+ - build
-##
-# 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
+ - echo "== Info =="
+ - tests/ci-helper.sh "INFO"
+ - tests/ci-helper.sh "GIT_INFO"
+
+ - |
+ 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
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
+<!--
+What are the problems that the current project has?
+
+For example:
+* User cannot use the keyboard to perform most common actions
+or
+* User cannot see documents from cloud services
+-->
+
+# Goals & use cases
+<!--
+What are the use cases that this proposal will cover? What are the end goals?
+
+For example:
+* User needs to share a file with their friends.
+or
+* It should be easy to edit a picture within the app.
+-->
+
+# Requirements
+<!--
+What does the solution needs to ensure for being succesful?
+
+For example:
+* Work on small form factors and touch
+or
+* Use the Meson build system and integrate with it
+-->
+
+# Relevant art
+<!--
+Is there any product that has implemented something similar? Put links to other
+projects, pictures, links to other code, etc.
+-->
+
+# Proposal & plan
+<!-- What's the solution and how should be achieved? It can be split in smaller
+tasks of minimum change, so they can be delivered across several releases. -->
+
+/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
diff --git a/README b/README.md
index d9646c7a3..e19f5dceb 100644
--- a/README
+++ b/README.md
@@ -1,19 +1,21 @@
-GNOME Control Center
-====================
+[![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)
-About -
+GNOME Settings
+====================
-The control center is GNOME's main interface for configuration of various
-aspects of your desktop.
+GNOME Settings is GNOME's main interface for configuration of various aspects of
+your desktop.
-Installation -
+## Contributing
-See the file 'INSTALL'
+See `docs/CONTRIBUTING.md` for details on the contribution process, and `docs/HACKING.md`
+for the coding style guidelines.
-How to report bugs -
+## Reporting 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.
+gnome-control-center. It is available at https://gitlab.gnome.org.
In the report please include the following information -
@@ -23,7 +25,7 @@ In the report please include the following information -
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 -
+### 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
@@ -39,15 +41,3 @@ stack trace -
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/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
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/meson_post_install.py b/build-aux/meson/meson_post_install.py
index f9119e1a7..f9119e1a7 100644
--- a/meson_post_install.py
+++ b/build-aux/meson/meson_post_install.py
diff --git a/update-from-gsd.in b/build-aux/meson/update-from-gsd.in
index 29d06be8d..29d06be8d 100755
--- a/update-from-gsd.in
+++ b/build-aux/meson/update-from-gsd.in
diff --git a/update-from-gsd.sh b/build-aux/meson/update-from-gsd.sh
index 9f2d6b79c..9f2d6b79c 100755
--- a/update-from-gsd.sh
+++ b/build-aux/meson/update-from-gsd.sh
diff --git a/update-from-nma.in b/build-aux/meson/update-from-nma.in
index 76738b10b..76738b10b 100755
--- a/update-from-nma.in
+++ b/build-aux/meson/update-from-nma.in
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/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 <builddir>` 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: <summary>
+ ‌
+ A paragraph explaining the problem and its context.
+‌
+ Another one explaining how you solved that.
+‌
+ <link to the issue>
+ ```
+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..cf9265f50
--- /dev/null
+++ b/docs/HACKING.md
@@ -0,0 +1,213 @@
+# 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.
+
+## 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:
+
+ 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 <georges.stavracas@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+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_<object_name>` 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
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,38 +4,17 @@
xmlns:gnome="http://api.gnome.org/doap-extensions#"
xmlns="http://usefulinc.com/ns/doap#">
- <name xml:lang="en">gnome-control-center</name>
+ <name xml:lang="en">GNOME Settings</name>
<shortdesc xml:lang="en">GNOME's main interface to configure various aspects of the desktop</shortdesc>
<description xml:lang="en">GNOME's main interface to configure various aspects of the desktop</description>
<mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/gnomecc-list" />
<download-page rdf:resource="http://download.gnome.org/sources/gnome-control-center/" />
- <bug-database rdf:resource="http://bugzilla.gnome.org/browse.cgi?product=gnome-control-center" />
+ <bug-database rdf:resource="http://gitlab.gnome.org/GNOME/gnome-control-center/issues" />
<category rdf:resource="http://api.gnome.org/doap-extensions#core" />
<programming-language>C</programming-language>
<maintainer>
<foaf:Person>
- <foaf:name>Rui Matos</foaf:name>
- <foaf:mbox rdf:resource="mailto:tiagomatos@gmail.com" />
- <gnome:userid>rtcm</gnome:userid>
- </foaf:Person>
- </maintainer>
- <maintainer>
- <foaf:Person>
- <foaf:name>Richard Hughes</foaf:name>
- <foaf:mbox rdf:resource="mailto:richard@hughsie.com" />
- <gnome:userid>rhughes</gnome:userid>
- </foaf:Person>
- </maintainer>
- <maintainer>
- <foaf:Person>
- <foaf:name>Olivier Fourdan</foaf:name>
- <foaf:mbox rdf:resource="mailto:ofourdan@redhat.com" />
- <gnome:userid>ofourdan</gnome:userid>
- </foaf:Person>
- </maintainer>
- <maintainer>
- <foaf:Person>
<foaf:name>Georges Basile Stavracas Neto</foaf:name>
<foaf:mbox rdf:resource="mailto:gbsneto@gnome.org" />
<gnome:userid>gbsneto</gnome:userid>
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 20aeb9fc1..a61acc9c4 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')
@@ -25,8 +25,16 @@ 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()
+py3 = import('python3')
+python = py3.find_python()
+
+config_h.set_quoted('TEST_NM_PYTHON', python.path())
+
# defines
set_defines = [
# package
@@ -41,7 +49,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
@@ -55,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'
@@ -203,6 +212,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')
@@ -212,6 +222,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')
@@ -237,15 +249,13 @@ 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')
subdir('shell')
subdir('search-provider')
+subdir('tests')
if get_option('documentation')
subdir('man')
@@ -256,18 +266,20 @@ configure_file(
configuration: config_h
)
-meson.add_install_script(
- 'meson_post_install.py',
- 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'
-output += 'End options'
-message(output)
+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 += ' 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'
+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'
+
+message(output) \ No newline at end of file
diff --git a/meson_options.txt b/meson_options.txt
index 7498af4d6..a347168b7 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('wayland', type: 'boolean', value: true, description: 'build with Wayland support')
+option('tracing', type: 'boolean', value: false, description: 'add extra debugging information')
+option('wayland', type: 'boolean', value: true, description: 'build with Wayland support') \ No newline at end of file
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 <glib/gi18n-lib.h>
#include <shell/cc-shell.h>
+#include <shell/cc-object-storage.h>
#include <bluetooth-settings-widget.h>
#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);
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 <math.h>
#include <colord-session/cd-session.h>
+#include "shell/cc-object-storage.h"
+
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include <libgnome-desktop/gnome-rr.h>
@@ -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..e9a65cf58 100644
--- a/panels/color/cc-color-panel.c
+++ b/panels/color/cc-color-panel.c
@@ -26,7 +26,7 @@
#include <gdk/gdkx.h>
#include <libsoup/soup.h>
-#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"
@@ -49,7 +49,6 @@ struct _CcColorPanelPrivate
GPtrArray *devices;
GPtrArray *sensors;
GCancellable *cancellable;
- GDBusProxy *proxy;
GSettings *settings;
GSettings *settings_colord;
GtkBuilder *builder;
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-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 <libgnome-desktop/gnome-languages.h>
#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);
diff --git a/shell/cc-hostname-entry.c b/panels/common/cc-hostname-entry.c
index 0b0d6d10c..0b0d6d10c 100644
--- a/shell/cc-hostname-entry.c
+++ b/panels/common/cc-hostname-entry.c
diff --git a/shell/cc-hostname-entry.h b/panels/common/cc-hostname-entry.h
index a48177961..a48177961 100644
--- a/shell/cc-hostname-entry.h
+++ b/panels/common/cc-hostname-entry.h
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 <gio/gio.h>
#include <gtk/gtk.h>
-#include "shell/list-box-helper.h"
+#include "list-box-helper.h"
#include "cc-common-language.h"
#include "cc-util.h"
diff --git a/shell/hostname-helper.c b/panels/common/hostname-helper.c
index df596975e..df596975e 100644
--- a/shell/hostname-helper.c
+++ b/panels/common/hostname-helper.c
diff --git a/shell/hostname-helper.h b/panels/common/hostname-helper.h
index 9f96c12f9..9f96c12f9 100644
--- a/shell/hostname-helper.h
+++ b/panels/common/hostname-helper.h
diff --git a/shell/list-box-helper.c b/panels/common/list-box-helper.c
index 415cdde94..415cdde94 100644
--- a/shell/list-box-helper.c
+++ b/panels/common/list-box-helper.c
diff --git a/shell/list-box-helper.h b/panels/common/list-box-helper.h
index c2a0acc97..c2a0acc97 100644
--- a/shell/list-box-helper.h
+++ b/panels/common/list-box-helper.h
diff --git a/panels/common/meson.build b/panels/common/meson.build
index 561f42cf7..e9451e6d6 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,4 @@ run_target(
script_name,
command: script
)
+
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 @@
-# <pre>
-# @(#)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
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 <langinfo.h>
#include <sys/time.h>
-#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..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,
+ 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-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 <config.h>
-#include <locale.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);
-
- 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 <locale.h>
-#include <gtk/gtk.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_setenv ("G_DEBUG", "fatal_warnings", FALSE);
-
- g_test_add_func ("/datetime/timezone", test_timezone);
-
- return g_test_run ();
-}
diff --git a/panels/display/cc-display-panel.c b/panels/display/cc-display-panel.c
index 2f372fd7e..9488ca80b 100644
--- a/panels/display/cc-display-panel.c
+++ b/panels/display/cc-display-panel.c
@@ -29,7 +29,8 @@
#include <gdesktop-enums.h>
#include <math.h>
-#include "shell/list-box-helper.h"
+#include "shell/cc-object-storage.h"
+#include "list-box-helper.h"
#include <libupower-glib/upower.h>
#include "cc-display-config-manager-dbus.h"
@@ -87,6 +88,8 @@ struct _CcDisplayPanelPrivate
GtkWidget *main_titlebar;
GtkWidget *apply_titlebar;
+ GtkWidget *apply_titlebar_apply;
+ GtkWidget *apply_titlebar_warning;
};
typedef struct
@@ -283,6 +286,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 +2595,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 +2657,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 +2666,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
@@ -3107,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))
@@ -3326,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..55fca2429 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;
@@ -77,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);
@@ -384,15 +386,21 @@ 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 = g_dbus_proxy_new_for_bus_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);
+ 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;
}
- g_signal_connect (self->proxy_color, "g-properties-changed",
- G_CALLBACK (dialog_color_properties_changed_cb), self);
+
+ 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);
self->timer_id = g_timeout_add_seconds (10, dialog_tick_cb, self);
}
@@ -401,13 +409,18 @@ 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 = g_dbus_proxy_new_for_bus_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);
+ 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;
}
+
+ self->proxy_color_props = proxy;
}
static gboolean
@@ -669,25 +682,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);
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 411c1c905..19f785a36 100644
--- a/panels/info/cc-info-overview-panel.c
+++ b/panels/info/cc-info-overview-panel.c
@@ -21,7 +21,8 @@
#include <config.h>
-#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"
@@ -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)
{
diff --git a/panels/info/meson.build b/panels/info/meson.build
index 13015b96c..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,
+ 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/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 @@
<child>
<object class="GtkButton" id="change_custom_shortcut_button">
<property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="can_focus">True</property>
<property name="label" translatable="yes">Set Shortcut…</property>
<signal name="clicked" handler="change_custom_shortcut_button_clicked_cb" object="CcKeyboardShortcutEditor" swapped="yes" />
</object>
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/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 <sys/types.h>
diff --git a/panels/network/cc-network-panel.c b/panels/network/cc-network-panel.c
index 51ea823f7..a03ab56da 100644
--- a/panels/network/cc-network-panel.c
+++ b/panels/network/cc-network-panel.c
@@ -23,6 +23,8 @@
#include <glib/gi18n.h>
#include <stdlib.h>
+#include "shell/cc-object-storage.h"
+
#include "cc-network-panel.h"
#include "cc-network-resources.h"
@@ -554,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 */
@@ -876,16 +880,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 +919,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..d785bad0d 100644
--- a/panels/network/cc-wifi-panel.c
+++ b/panels/network/cc-wifi-panel.c
@@ -23,7 +23,8 @@
#include "net-device-wifi.h"
#include "network-dialogs.h"
-#include "shell/list-box-helper.h"
+#include "shell/cc-object-storage.h"
+#include "list-box-helper.h"
#include <glib/gi18n.h>
#include <NetworkManager.h>
@@ -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);
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 <glib/gi18n.h>
#include <NetworkManager.h>
-#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 <glib/gi18n.h>
#include <NetworkManager.h>
-#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 <NetworkManager.h>
-#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..2ec4fbf71 100644
--- a/panels/network/meson.build
+++ b/panels/network/meson.build
@@ -69,11 +69,12 @@ 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,
+ include_directories: [top_inc, common_inc],
dependencies: deps,
c_args: cflags,
link_with: libconnection_editor
)
+panels_libs += network_panel_lib
diff --git a/panels/network/net-device-ethernet.c b/panels/network/net-device-ethernet.c
index 603ad6c86..afb544352 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"
@@ -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);
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 <NetworkManager.h>
#include <polkit/polkit.h>
-#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 <gio/gio.h>
#include <gio/gdesktopappinfo.h>
-#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 1265b5b6f..9baa5a80e 100644
--- a/panels/notifications/cc-notifications-panel.c
+++ b/panels/notifications/cc-notifications-panel.c
@@ -25,7 +25,8 @@
#include <gio/gio.h>
#include <gio/gdesktopappinfo.h>
-#include "shell/list-box-helper.h"
+#include "shell/cc-object-storage.h"
+#include "list-box-helper.h"
#include "cc-notifications-panel.h"
#include "cc-notifications-resources.h"
#include "cc-edit-dialog.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 *
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 835810003..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
{
@@ -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);
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 f9b67a458..7b7c4a24d 100644
--- a/panels/power/cc-power-panel.c
+++ b/panels/power/cc-power-panel.c
@@ -29,7 +29,8 @@
#include <NetworkManager.h>
#endif
-#include "shell/list-box-helper.h"
+#include "shell/cc-object-storage.h"
+#include "list-box-helper.h"
#include "cc-power-panel.h"
#include "cc-power-resources.h"
@@ -567,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)
{
@@ -581,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,
@@ -593,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)
{
@@ -667,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);
@@ -1083,7 +1108,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 +1121,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 +1145,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 +1158,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);
}
@@ -1163,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)
{
@@ -1184,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));
@@ -1441,12 +1527,30 @@ nm_device_changed (NMClient *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 +1571,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 +1746,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 +1984,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 +2047,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 +2612,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);
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/cc-printers-panel.c b/panels/printers/cc-printers-panel.c
index 55a1682b4..877028863 100644
--- a/panels/printers/cc-printers-panel.c
+++ b/panels/printers/cc-printers-panel.c
@@ -18,6 +18,8 @@
#include <config.h>
+#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)
{
@@ -1229,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)
{
@@ -1244,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
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/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 @@
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="transition-type">none</property>
+ <property name="has_focus">True</property>
<style>
<class name="view"/>
</style>
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 <cups/cups.h>
#include <cups/ppd.h>
-#include "cc-editable-entry.h"
#include "pp-details-dialog.h"
#include "pp-ppd-selection-dialog.h"
#include "pp-printer.h"
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 <cups/cups.h>
-#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/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);
diff --git a/panels/privacy/cc-privacy-panel.c b/panels/privacy/cc-privacy-panel.c
index 428dafef7..8735e33d0 100644
--- a/panels/privacy/cc-privacy-panel.c
+++ b/panels/privacy/cc-privacy-panel.c
@@ -18,7 +18,8 @@
* Author: Matthias Clasen <mclasen@redhat.com>
*/
-#include "shell/list-box-helper.h"
+#include "shell/cc-object-storage.h"
+#include "list-box-helper.h"
#include "cc-privacy-panel.h"
#include "cc-privacy-resources.h"
#include "cc-util.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
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 <string.h>
#include <glib/gi18n.h>
-#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 <libgnome-desktop/gnome-languages.h>
-#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 48c0d7ac0..5fdb35a25 100644
--- a/panels/region/cc-region-panel.c
+++ b/panels/region/cc-region-panel.c
@@ -26,7 +26,8 @@
#include <gtk/gtk.h>
#include <polkit/polkit.h>
-#include "shell/list-box-helper.h"
+#include "shell/cc-object-storage.h"
+#include "list-box-helper.h"
#include "cc-region-panel.h"
#include "cc-region-resources.h"
#include "cc-language-chooser.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);
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 <glib/gi18n.h>
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 <gio/gdesktopappinfo.h>
#include <glib/gi18n.h>
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..672ac98d6 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;
@@ -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 ();
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/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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Christian J. Kellner <christian@kellner.me>
+ */
+
+#include "bolt-client.h"
+
+#include "bolt-device.h"
+#include "bolt-error.h"
+#include "bolt-names.h"
+
+#include <gio/gio.h>
+
+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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Christian J. Kellner <christian@kellner.me>
+ */
+
+#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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Christian J. Kellner <christian@kellner.me>
+ */
+
+#include "config.h"
+
+#include "bolt-device.h"
+
+#include "bolt-enums.h"
+#include "bolt-error.h"
+#include "bolt-names.h"
+
+#include <gio/gio.h>
+
+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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Christian J. Kellner <christian@kellner.me>
+ */
+
+#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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Christian J. Kellner <christian@kellner.me>
+ */
+
+#include "config.h"
+
+#include "bolt-enums.h"
+#include "bolt-error.h"
+
+#include <gio/gio.h>
+
+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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Christian J. Kellner <christian@kellner.me>
+ */
+
+#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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Christian J. Kellner <christian@kellner.me>
+ */
+
+#include "config.h"
+
+#include "bolt-error.h"
+
+#include "bolt-names.h"
+
+#include <gio/gio.h>
+
+/**
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Christian J. Kellner <christian@kellner.me>
+ */
+
+#pragma once
+
+#include <glib.h>
+
+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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Christian J. Kellner <christian@kellner.me>
+ */
+
+#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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Christian J. Kellner <christian@kellner.me>
+ */
+
+#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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Christian J. Kellner <christian@kellner.me>
+ */
+
+#pragma once
+
+#include <gio/gio.h>
+
+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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Christian J. Kellner <christian@kellner.me>
+ */
+
+#include "config.h"
+
+#include "bolt-str.h"
+
+#include <string.h>
+
+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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Christian J. Kellner <christian@kellner.me>
+ */
+
+#pragma once
+
+#include <glib.h>
+#include <string.h>
+
+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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Christian J. Kellner <christian@kellner.me>
+ */
+
+#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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Christian J. Kellner <christian@kellner.me>
+ */
+
+#pragma once
+
+#include <glib.h>
+
+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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Christian J. Kellner <ckellner@redhat.com>
+ *
+ */
+
+#include <config.h>
+
+#include <glib/gi18n.h>
+
+#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..bd91eac71
--- /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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Christian J. Kellner <ckellner@redhat.com>
+ *
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+
+#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..584915a31
--- /dev/null
+++ b/panels/thunderbolt/cc-bolt-device-dialog.ui
@@ -0,0 +1,359 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
+<interface>
+ <requires lib="gtk+" version="3.20"/>
+ <template class="CcBoltDeviceDialog" parent="GtkDialog">
+ <property name="can_focus">False</property>
+ <property name="type_hint">dialog</property>
+ <property name="use_header_bar">1</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+
+ <child internal-child="headerbar">
+ <object class="GtkHeaderBar" id="header_bar">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="show_close_button">True</property>
+ <property name="title">Device Identifier</property>
+ <property name="subtitle"></property>
+ <property name="has-subtitle">False</property>
+ </object>
+ </child>
+
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="margin-bottom">24</property>
+ <property name="border-width">0</property>
+ <child>
+ <object class="GtkOverlay">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child type="overlay">
+ <object class="GtkRevealer" id="notify_revealer">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+ <property name="transition_type">slide-down</property>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="notify_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="use_markup">True</property>
+ <property name="wrap">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">none</property>
+ <signal name="clicked"
+ handler="on_notify_button_clicked_cb"
+ object="CcBoltDeviceDialog"
+ swapped="no" />
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">window-close-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <style>
+ <class name="app-notification" />
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="expand">True</property>
+ <property name="orientation">vertical</property>
+
+ <child>
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin-left">72</property>
+ <property name="margin-right">72</property>
+ <property name="margin-top">24</property>
+ <property name="margin-bottom">0</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">24</property>
+ <child>
+ <object class="GtkLabel" id="name_title_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="hexpand">False</property>
+ <property name="vexpand">False</property>
+ <property name="label" translatable="yes">Name:</property>
+ <property name="justify">right</property>
+ <property name="xalign">1</property>
+ <property name="mnemonic_widget">name_label</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="name_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="label">Device identifier</property>
+ <property name="use_markup">True</property>
+ <property name="ellipsize">end</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="status_title_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="hexpand">False</property>
+ <property name="vexpand">False</property>
+ <property name="label" translatable="yes">Status:</property>
+ <property name="justify">right</property>
+ <property name="xalign">1</property>
+ <property name="mnemonic_widget">status_label</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="status_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="label">Status</property>
+ <property name="ellipsize">end</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+
+ <child>
+ <object class="GtkLabel" id="uuid_title_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="hexpand">False</property>
+ <property name="vexpand">False</property>
+ <property name="label" translatable="yes">UUID:</property>
+ <property name="justify">right</property>
+ <property name="xalign">1</property>
+ <property name="mnemonic_widget">uuid_label</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="uuid_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="label">Status</property>
+ <property name="ellipsize">end</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+
+ <child>
+ <object class="GtkLabel" id="time_title">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">end</property>
+ <property name="hexpand">False</property>
+ <property name="vexpand">False</property>
+ <property name="label">Timestamp:</property>
+ <property name="justify">right</property>
+ <property name="xalign">1</property>
+ <property name="mnemonic_widget">time_label</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="time_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">center</property>
+ <property name="hexpand">True</property>
+ <property name="label">Status</property>
+ <property name="ellipsize">end</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="padding">1</property>
+ <property name="position">1</property>
+ </packing>
+ <object class="GtkSizeGroup" id="device_titles_sizegroup">
+ <widgets>
+ <widget name="name_title_label"/>
+ <widget name="status_title_label"/>
+ <widget name="uuid_title_label"/>
+ <widget name="time_title"/>
+ </widgets>
+ </object>
+ <object class="GtkSizeGroup" id="device_labels_sizegroup">
+ <widgets>
+ <widget name="name_label"/>
+ <widget name="status_label"/>
+ <widget name="uuid_label"/>
+ <widget name="time_label"/>
+ </widgets>
+ </object>
+ </child>
+ <!-- end of grid -->
+ <child>
+ <object class="GtkBox" id="button_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">12</property>
+ <property name="margin-left">72</property>
+ <property name="margin-right">72</property>
+ <property name="margin-top">36</property>
+ <property name="margin-bottom">0</property>
+ <property name="halign">fill</property>
+ <child>
+ <object class="GtkSpinner" id="spinner">
+ <property name="visible">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="active">False</property>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkButton" id="connect_button">
+ <property name="label" translatable="yes">Authorize and Connect</property>
+ <property name="visible">True</property>
+ <property name="no_show_all">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="halign">fill</property>
+
+ <signal name="clicked"
+ handler="on_connect_button_clicked_cb"
+ object="CcBoltDeviceDialog"
+ swapped="yes" />
+ <style>
+ <class name="suggested-action"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <object class="GtkButton" id="forget_button">
+ <property name="label" translatable="yes">Forget Device</property>
+ <property name="visible">True</property>
+ <property name="no_show_all">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="halign">fill</property>
+ <signal name="clicked"
+ handler="on_forget_button_clicked_cb"
+ object="CcBoltDeviceDialog"
+ swapped="yes" />
+ <style>
+ <class name="destructive-action"/>
+ </style>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="spinner_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ </child>
+ </object>
+
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+
+ <object class="GtkSizeGroup" id="actions_sizegroup">
+ <widgets>
+ <widget name="forget_button"/>
+ <widget name="connect_button"/>
+ </widgets>
+ </object>
+
+ <object class="GtkSizeGroup" id="spinner_sizegroup">
+ <widgets>
+ <widget name="spinner"/>
+ <widget name="spinner_box"/>
+ </widgets>
+ </object>
+
+ </child>
+ </object>
+ </child>
+
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/panels/thunderbolt/cc-bolt-device-entry.c b/panels/thunderbolt/cc-bolt-device-entry.c
new file mode 100644
index 000000000..27beaddea
--- /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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Christian J. Kellner <ckellner@redhat.com>
+ *
+ */
+
+#include <config.h>
+
+#include "bolt-str.h"
+
+#include "cc-bolt-device-entry.h"
+
+#include "cc-thunderbolt-resources.h"
+
+#include <glib/gi18n.h>
+
+#define RESOURCE_UI "/org/gnome/control-center/thunderbolt/cc-bolt-device-entry.ui"
+
+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);
+
+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, };
+
+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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Christian J. Kellner <ckellner@redhat.com>
+ *
+ */
+
+#pragma once
+
+#include <gtk/gtk.h>
+#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..d1ada1856
--- /dev/null
+++ b/panels/thunderbolt/cc-bolt-device-entry.ui
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="3.20"/>
+
+ <template class="CcBoltDeviceEntry" parent="GtkListBoxRow">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="activatable">True</property>
+ <child>
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="border-width">12</property>
+ <property name="margin_left">6</property>
+ <property name="margin_right">6</property>
+ <property name="column-spacing">12</property>
+ <property name="row-spacing">2</property>
+ <child>
+ <object class="GtkLabel" id="name_label">
+ <property name="ellipsize">end</property>
+ <property name="use-markup">True</property>
+ <property name="visible">True</property>
+ <property name="hexpand">True</property>
+ <property name="label">Device Name</property>
+ <property name="xalign">0.0</property>
+ <property name="valign">center</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="status_label">
+ <property name="visible">True</property>
+ <property name="hexpand">False</property>
+ <property name="label">Status</property>
+ <property name="halign">end</property>
+ <property name="valign">center</property>
+ <property name="xalign">1.0</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="top-attach">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/panels/thunderbolt/cc-bolt-panel.c b/panels/thunderbolt/cc-bolt-panel.c
new file mode 100644
index 000000000..a4face5b3
--- /dev/null
+++ b/panels/thunderbolt/cc-bolt-panel.c
@@ -0,0 +1,959 @@
+/* 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 <http://www.gnu.org/licenses/>.
+ *
+ * Authors: Christian J. Kellner <ckellner@redhat.com>
+ *
+ */
+
+#include <config.h>
+
+#include <shell/cc-panel.h>
+#include <list-box-helper.h>
+
+#include <glib/gi18n.h>
+#include <polkit/polkit.h>
+
+#include "cc-bolt-device-dialog.h"
+#include "cc-bolt-device-entry.h"
+
+#include "bolt-client.h"
+#include "bolt-str.h"
+
+#include "cc-bolt-panel.h"
+#include "cc-thunderbolt-resources.h"
+
+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);
+
+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 set up 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_DEFAULT | 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);
+}
+
+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(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)
+ {
+ 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 (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)
+ {
+ 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)
+{
+ cc_bolt_panel_name_owner_changed (CC_BOLT_PANEL (user_data));
+}
+
+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)
+ {
+ 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)
+ 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)
+{
+ cc_bolt_panel_authmode_sync (CC_BOLT_PANEL (user_data));
+}
+
+/* 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(CcBoltPanel) panel = user_data;
+ g_autoptr(GError) err = NULL;
+ GPermission *permission;
+ gboolean is_allowed;
+ const char *name;
+
+ permission = polkit_permission_new_finish (res, &err);
+ panel->permission = permission;
+
+ if (!panel->permission)
+ {
+ 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_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);
+ 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_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);
+ 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);
+}
+
+/* GObject overrides */
+
+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, "/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, pending_box);
+ 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_cb,
+ panel,
+ NULL);
+
+ gtk_list_box_set_sort_func (panel->pending_list,
+ 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_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/shell/cc-shell-log.h b/panels/thunderbolt/cc-bolt-panel.h
index 132a19dcf..5901044e8 100644
--- a/shell/cc-shell-log.h
+++ b/panels/thunderbolt/cc-bolt-panel.h
@@ -1,6 +1,4 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2009 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
@@ -15,18 +13,18 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
+ * Authors: Christian J. Kellner <ckellner@redhat.com>
+ *
*/
-#ifndef __CC_SHELL_LOG_H
-#define __CC_SHELL_LOG_H
+#pragma once
-#include <glib.h>
+#include <glib-object.h>
G_BEGIN_DECLS
-void cc_shell_log_init (void);
-void cc_shell_log_set_debug (gboolean debug);
+#define CC_TYPE_BOLT_PANEL cc_bolt_panel_get_type ()
-G_END_DECLS
+G_DECLARE_FINAL_TYPE (CcBoltPanel, cc_bolt_panel, CC, BOLT_PANEL, CcPanel);
-#endif /* __CC_SHELL_LOG_H */
+G_END_DECLS
diff --git a/panels/thunderbolt/cc-bolt-panel.ui b/panels/thunderbolt/cc-bolt-panel.ui
new file mode 100644
index 000000000..226353c64
--- /dev/null
+++ b/panels/thunderbolt/cc-bolt-panel.ui
@@ -0,0 +1,594 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="3.20"/>
+
+ <template class="CcBoltPanel" parent="CcPanel">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+
+ <child>
+ <object class="GtkOverlay">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child type="overlay">
+ <object class="GtkRevealer" id="notification_revealer">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+ <property name="transition_type">slide-down</property>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="notification_label">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="use_markup">True</property>
+ <property name="wrap">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">none</property>
+ <signal name="clicked"
+ handler="on_notification_button_clicked_cb"
+ object="CcBoltPanel"
+ swapped="no" />
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon-name">window-close-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <style>
+ <class name="app-notification" />
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkStack" id="container">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="homogeneous">False</property>
+ <property name="transition_type">crossfade</property>
+
+ <!-- Spinner for when we are creating -->
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="expand">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">10</property>
+ <property name="margin">18</property>
+ <child type="center">
+ <object class="GtkSpinner" id="loading-spinner">
+ <property name="visible">True</property>
+ <property name="active">True</property>
+ <property name="expand">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="name">loading</property>
+ </packing>
+ </child>
+
+ <!-- No tunderbolt -->
+
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="expand">True</property>
+ <property name="halign">center</property>
+ <property name="valign">center</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">10</property>
+ <property name="margin">18</property>
+ <child type="center" >
+ <object class="GtkGrid">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_start">12</property>
+ <property name="margin_end">6</property>
+ <property name="margin_top">12</property>
+ <property name="margin_bottom">12</property>
+ <property name="row_spacing">12</property>
+ <property name="column_spacing">24</property>
+
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">thunderbolt-symbolic</property>
+ <property name="pixel_size">96</property>
+ <property name="yalign">0</property>
+ <style>
+ <class name="dim-label" />
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ <property name="height">2</property>
+ </packing>
+ </child>
+
+ <child>
+ <object class="GtkLabel" id="notb_caption">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="wrap">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">No Thunderbolt support</property>
+ <attributes>
+ <attribute name="scale" value="1.2" />
+ </attributes>
+ <style>
+ <class name="dim-label" />
+ </style>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+
+ <child>
+ <object class="GtkLabel" id="notb_details">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="max-width-chars">40</property>
+ <property name="use_markup">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="wrap">True</property>
+ <property name="label" translatable="no">Could not connect to the thunderbolt subsystem.</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+
+ </object>
+ </child>
+
+ </object>
+ <packing>
+ <property name="name">no-thunderbolt</property>
+ </packing>
+ </child>
+
+ <!-- Normal operation mode (show list of devices) -->
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hscrollbar-policy">never</property>
+
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="shadow-type">none</property>
+
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">horizontal</property>
+ <property name="valign">start</property>
+
+ <!-- Stub box -->
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ </object>
+ </child>
+
+ <!-- center/content box -->
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="spacing">32</property>
+ <property name="margin_top">32</property>
+ <property name="margin_bottom">32</property>
+ <property name="margin_left">18</property>
+ <property name="margin_right">18</property>
+ <property name="orientation">vertical</property>
+
+ <!-- Auth Mode -->
+ <child>
+ <object class="GtkBox" id="authmode_box">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">False</property>
+ <property name="halign">start</property>
+ <property name="xalign">0.0</property>
+ <property name="label" translatable="yes">Direct Access</property>
+ <property name="mnemonic_widget">authmode_switch</property>
+ <attributes>
+ <attribute name="weight" value="bold" />
+ </attributes>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkStack" id="authmode_mode">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="transition-type">crossfade</property>
+ <property name="homogeneous">True</property>
+
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_left">0</property>
+ <property name="hexpand">False</property>
+ <property name="vexpand">False</property>
+ <property name="label" translatable="yes" >Allow direct access to devices such as docks and external GPUs.</property>
+ <property name="use_markup">True</property>
+ <property name="wrap">True</property>
+ <property name="xalign">0.0</property>
+ <property name="yalign">0.0</property>
+ <property name="max-width-chars">45</property>
+ </object>
+ <packing>
+ <property name="name">enabled</property>
+ </packing>
+ </child>
+
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_left">0</property>
+ <property name="hexpand">False</property>
+ <property name="vexpand">False</property>
+ <property name="label" translatable="yes" >Only USB and Display Port devices can attach.</property>
+ <property name="use_markup">True</property>
+ <property name="wrap">True</property>
+ <property name="xalign">0.0</property>
+ <property name="yalign">0.0</property>
+ <property name="max-width-chars">45</property>
+ </object>
+ <packing>
+ <property name="name">disabled</property>
+ </packing>
+ </child>
+
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">horizontal</property>
+ <property name="spacing">6</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+
+ <child>
+ <object class="GtkSpinner" id="authmode_spinner">
+ <property name="visible">True</property>
+ <property name="active">False</property>
+ </object>
+ </child>
+
+ <child>
+ <object class="GtkSwitch" id="authmode_switch">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="halign">end</property>
+ <property name="valign">start</property>
+ <property name="active">True</property>
+ <signal name="state-set"
+ handler="on_authmode_state_set_cb"
+ object="CcBoltPanel"
+ swapped="yes" />
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ <property name="pack-type">end</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+
+ <!-- Stack: devices/no-devices -->
+ <child>
+ <object class="GtkStack" id="devices_stack">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="transition-type">crossfade</property>
+
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">32</property>
+
+ <!-- Pending Device List -->
+ <child>
+ <object class="GtkBox" id="pending_box">
+ <property name="visible">False</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+
+ <!-- Pending Device List: Header -->
+ <child>
+ <object class="GtkBox" id="pending_header">
+ <property name="visible">True</property>
+ <property name="hexpand">True</property>
+ <property name="halign">start</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">dialog-warning-symbolic</property>
+ <property name="icon_size">1</property>
+ <property name="margin_left">0</property>
+ <property name="xalign">0.0</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Pending Devices</property>
+ <property name="xalign">0.0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinner" id="pending_spinner">
+ <property name="hexpand">True</property>
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+
+ <!-- Pending List: Devices -->
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="valign">start</property>
+ <property name="vexpand">False</property>
+ <style>
+ <class name="view" />
+ </style>
+ <child>
+ <object class="GtkListBox" id="pending_list">
+ <property name="visible">True</property>
+ <property name="selection-mode">none</property>
+ <property name="can_focus">True</property>
+ <signal name="row-activated"
+ handler="on_device_entry_row_activated_cb"
+ object="CcBoltPanel"
+ swapped="yes" />
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <!-- Device List -->
+ <child>
+ <object class="GtkBox" id="devices_box">
+ <property name="visible">False</property>
+ <property name="can_focus">False</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+
+ <!-- Device List: Header -->
+ <child>
+ <object class="GtkBox" id="devices_header">
+ <property name="visible">True</property>
+ <property name="hexpand">True</property>
+ <property name="halign">start</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Devices</property>
+ <property name="xalign">0.0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSpinner" id="probing_spinner">
+ <property name="hexpand">True</property>
+ <property name="visible">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+
+ <!-- Device List: Devices -->
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="valign">start</property>
+ <property name="vexpand">False</property>
+ <style>
+ <class name="view" />
+ </style>
+ <child>
+ <object class="GtkListBox" id="devices_list">
+ <property name="visible">True</property>
+ <property name="selection-mode">none</property>
+ <property name="can_focus">True</property>
+ <signal name="row-activated"
+ handler="on_device_entry_row_activated_cb"
+ object="CcBoltPanel"
+ swapped="yes" />
+ </object>
+ </child>
+ </object>
+ </child>
+
+ </object>
+ </child>
+
+ </object>
+ <packing>
+ <property name="name">have-devices</property>
+ </packing>
+ </child>
+
+ <!-- No Devices -->
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="hexpand">True</property>
+ <property name="halign">start</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Devices</property>
+ <property name="xalign">0.0</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">No devices attached</property>
+ <property name="xalign">0.0</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="name">no-devices</property>
+ </packing>
+ </child> <!-- End of: No Devices -->
+
+ </object>
+ </child> <!-- End of Stack: devices/no-devices -->
+
+ </object>
+ </child> <!-- End of enter/content box -->
+
+
+ <!-- Stub box -->
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ </object>
+ </child>
+
+ <!-- End of content -->
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="name">devices-listing</property>
+ </packing>
+ </child>
+
+ <!-- End of 'container' -->
+ </object>
+ </child>
+
+ <!-- End of overlay -->
+ </object>
+ </child>
+ </template>
+
+ <!-- Headerbar entries -->
+ <object class="GtkBox" id="headerbar_box">
+ <property name="visible">False</property>
+ <property name="can_focus">False</property>
+ <property name="spacing">6</property>
+ <property name="halign">end</property>
+ <child>
+ <object class="GtkLockButton" id="lock_button">
+ <property name="visible">True</property>
+ </object>
+ </child>
+ </object>
+
+</interface>
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..12ba0330c
--- /dev/null
+++ b/panels/thunderbolt/gnome-thunderbolt-panel.desktop.in.in
@@ -0,0 +1,18 @@
+[Desktop Entry]
+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
+NoDisplay=true
+StartupNotify=true
+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
+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..17e125b5f
--- /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, common_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 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+ <gresource prefix="/org/gnome/control-center/thunderbolt">
+ <file preprocess="xml-stripblanks">cc-bolt-device-dialog.ui</file>
+ <file preprocess="xml-stripblanks">cc-bolt-device-entry.ui</file>
+ <file preprocess="xml-stripblanks">cc-bolt-panel.ui</file>
+ </gresource>
+</gresources>
+
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: <BOLT-SOURCE>"
+ 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/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 <glib/gi18n-lib.h>
#include <gdesktop-enums.h>
-#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/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 @@
</packing>
</child>
<child>
- <object class="GtkLabel" id="enterprise-hint">
+ <object class="GtkLabel" id="enterprise_hint">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="yalign">0</property>
@@ -810,7 +810,7 @@
<widget name="enterprise_domain_hint"/>
<widget name="enterprise_login"/>
<widget name="enterprise_password"/>
- <widget name="enterprise-hint"/>
+ <widget name="enterprise_hint"/>
</widgets>
</object>
<object class="GtkSizeGroup">
diff --git a/panels/user-accounts/um-account-dialog.c b/panels/user-accounts/um-account-dialog.c
index 9ca2c6d9d..ba4c24375 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
@@ -895,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) {
@@ -1001,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
@@ -1581,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 *
@@ -1599,15 +1599,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 +1626,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);
}
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,
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/po/POTFILES.in b/po/POTFILES.in
index dfd8ccff0..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
@@ -183,6 +184,12 @@ 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/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
@@ -226,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
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ý <marek@manet.cz>\n"
"Language-Team: čeština <gnome-cs-list@gnome.org>\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 "<b>%s</b> removed"
msgstr "<b>%s</b> 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í"
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 <daniel.mustieles@gmail.com>\n"
"Language-Team: es <gnome-es-list@gnome.org>\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 <b>%s</b>."
msgstr "Cambiar al «hotspot» inalámbrico le desconectará de <b>%s</b>."
-#: 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 "<b>%s</b> removed"
msgstr "<b>%s</b> 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"
diff --git a/po/fur.po b/po/fur.po
index 7cc4bb2dc..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-02-23 19:10+0000\n"
-"PO-Revision-Date: 2018-02-24 06:09+0100\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 <f.t.public@gmail.com>\n"
"Language-Team: Friulian <f.t.public@gmail.com>\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"
@@ -1487,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"
@@ -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:583
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: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: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 ""
"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:789
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 "<b>%s</b> removed"
msgstr "<b>%s</b> 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,297 @@ 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 "%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 "%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 +4299,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 +4417,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 +4447,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 +4504,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 +4705,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 +4933,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 +5213,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"
@@ -5391,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"
@@ -5665,7 +5717,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 +5730,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 +5790,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 +5811,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 +5821,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 +6064,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 +6355,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 +6400,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"
@@ -6721,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."
@@ -6751,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."
@@ -6759,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?"
@@ -6898,7 +7119,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 +7127,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,58 +7164,57 @@ 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"
-#: 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"
-#: 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 +7222,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 +7235,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 +7283,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 +7291,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 +7304,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 +7587,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 +7667,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 +7879,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 +8209,6 @@ msgstr "Suns di sisteme"
#~ msgid "_Sign In"
#~ msgstr "_Jentre"
-#~ msgid "_Name:"
-#~ msgstr "_Non:"
-
#~ msgid "Add Shortcut"
#~ msgstr "Zonte scurte"
diff --git a/po/hr.po b/po/hr.po
index 480fe5037..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-02-20 09:14+0000\n"
-"PO-Revision-Date: 2018-02-20 12:18+0100\n"
+"POT-Creation-Date: 2018-04-16 12:25+0000\n"
+"PO-Revision-Date: 2018-04-16 14:27+0200\n"
"Last-Translator: gogo <trebelnik2@gmail.com>\n"
"Language-Team: Croatian <lokalizacija@linux.hr>\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 "Promjene se ne mogu primijeniti"
+
+#: panels/display/cc-display-panel.c:2648
+msgid "This could be due to hardware limitations."
+msgstr "To može biti uzrokovano ograničenjem hardvera."
+
+#: 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 <b>%s</b>."
msgstr "Prebacivanje na bežičnu pristupnu točku odspojiti će vas s <b>%s</b>."
-#: 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 "<b>%s</b> removed"
msgstr "<b>%s</b> 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: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: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 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: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:613
+#, 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"
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 <timar at gnome dot hu>, 2001, 2002, 2003.
# Gabor Sari <saga at gnome dot hu>, 2003.
# Laszlo Dvornik <dvornik at gnome dot hu>, 2004.
-# Gabor Kelemen <kelemeng at gnome dot hu>, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2015, 2016, 2017.
+# Gabor Kelemen <kelemeng at gnome dot hu>, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2015, 2016, 2017, 2018.
# Mate ORY <orymate at gmail d0t com>, 2006.
# Richard Somloi <ricsipontaz at gmail dot com>, 2011, 2012.
# Peter Trombitas <trombipeti at gmail dot com>, 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 <urbalazs@gmail.com>\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 <kelemeng at ubuntu dot com>\n"
"Language-Team: Hungarian <openscope at googlegroups dot com>\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 "<b>%s</b> removed"
msgstr "<b>%s</b> 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: <a href='https://location.services.mozilla."
"com/privacy'>Privacy Policy</a>"
msgstr ""
-"A Mozilla helymeghatározási szolgáltatást használja: <a "
-"href='https://location.services.mozilla.com/privacy'>adatvédelmi irányelvek<"
-"/a>"
+"A Mozilla helymeghatározási szolgáltatást használja: <a href='https://"
+"location.services.mozilla.com/privacy'>adatvédelmi irányelvek</a>"
#: 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"
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 <cwryu@debian.org>\n"
"Language-Team: GNOME Korea <gnome-kr@googlegroups.com>\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 <b>%s</b>."
msgstr "무선 핫스팟을 전환하면 <b>%s</b>의 연결이 끊어집니다."
-#: 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 "<b>%s</b> removed"
msgstr "<b>%s</b> 제거함"
@@ -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;설정;"
diff --git a/po/ro.po b/po/ro.po
index d79e9a235..2acd53354 100644
--- a/po/ro.po
+++ b/po/ro.po
@@ -17,17 +17,18 @@ 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 <daniel [at] serbanescu [dot] dk>\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 <florentina.musat.28 [at] gmail [dot] "
+"com>\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.7\n"
"X-Launchpad-Export-Date: 2014-07-13 17:08+0000\n"
"X-Project-Style: gnome\n"
@@ -113,16 +114,16 @@ 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
#: 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,8 +132,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 +180,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 +237,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 +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 ""
@@ -254,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 ""
@@ -264,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 "Î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 +374,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 +423,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 +464,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."
@@ -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"
@@ -1120,58 +1127,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 +1186,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: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 "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: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
@@ -1239,11 +1254,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 +1298,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 +1348,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 +1357,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 +1442,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 +1450,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 +1709,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 +1819,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 +1830,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 +1935,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 +2128,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 +2136,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 +2299,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 +2434,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"
@@ -2617,9 +2632,9 @@ 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:230
+#: panels/user-accounts/um-photo-dialog.c:231
msgid "_Open"
msgstr "_Deschide"
@@ -3358,23 +3373,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 +3807,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 "<b>%s</b> removed"
msgstr "<b>%s</b> eliminat"
@@ -3858,41 +3873,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 +3915,283 @@ 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: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 "Se încarcă"
#. TRANSLATORS: secondary battery
-#: panels/power/cc-power-panel.c:625
+#: panels/power/cc-power-panel.c:639
msgctxt "Battery power"
msgid "Caution"
msgstr "Atenție"
#. TRANSLATORS: secondary battery
-#: panels/power/cc-power-panel.c:630
+#: panels/power/cc-power-panel.c:644
msgctxt "Battery power"
msgid "Low"
msgstr "Scăzută"
#. TRANSLATORS: secondary battery
-#: panels/power/cc-power-panel.c:635
+#: panels/power/cc-power-panel.c:649
msgctxt "Battery power"
msgid "Good"
msgstr "Bună"
#. TRANSLATORS: primary battery
-#: panels/power/cc-power-panel.c:640
+#: 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:644
+#: panels/power/cc-power-panel.c:658
msgctxt "Battery power"
msgid "Empty"
msgstr "Descărcată complet"
-#: panels/power/cc-power-panel.c:802
+#: panels/power/cc-power-panel.c:827
msgid "Batteries"
msgstr "Baterii"
-#: panels/power/cc-power-panel.c:1242
+#: 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:1696
+#: panels/power/cc-power-panel.c:1793
msgid "Power Saving"
msgstr "Economisire de energie"
-#: panels/power/cc-power-panel.c:1727
+#: panels/power/cc-power-panel.c:1824
msgid "_Screen brightness"
msgstr "Luminozitate ec_ran"
-#: panels/power/cc-power-panel.c:1746
+#: panels/power/cc-power-panel.c:1843
msgid "Automatic brightness"
msgstr "Luminozitate automată"
-#: panels/power/cc-power-panel.c:1766
+#: panels/power/cc-power-panel.c:1863
msgid "_Keyboard brightness"
msgstr "Luminozitate _tastatură"
-#: panels/power/cc-power-panel.c:1776
+#: panels/power/cc-power-panel.c:1873
msgid "_Dim screen when inactive"
msgstr "_Diminuează luminozitatea la inactivitate"
-#: panels/power/cc-power-panel.c:1801
+#: panels/power/cc-power-panel.c:1898
msgid "_Blank screen"
msgstr "Ecran _gol"
-#: panels/power/cc-power-panel.c:1838
+#: panels/power/cc-power-panel.c:1935
msgid "_Wi-Fi"
msgstr "_Wi-Fi"
-#: panels/power/cc-power-panel.c:1843
+#: 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:1868
+#: panels/power/cc-power-panel.c:1965
msgid "_Mobile broadband"
msgstr "Internet _mobil de bandă largă"
-#: panels/power/cc-power-panel.c:1873
+#: 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:1926
+#: panels/power/cc-power-panel.c:2029
msgid "_Bluetooth"
msgstr "_Bluetooth"
-#: panels/power/cc-power-panel.c:1931
+#: 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:1990
+#: 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:1992
+#: panels/power/cc-power-panel.c:2095
msgid "When plugged in"
msgstr "Alimentat de la rețea"
-#: panels/power/cc-power-panel.c:2087
+#: panels/power/cc-power-panel.c:2190
msgid "Suspend"
msgstr "Suspendă"
-#: panels/power/cc-power-panel.c:2088
+#: panels/power/cc-power-panel.c:2191
msgid "Power Off"
msgstr "Oprește"
-#: panels/power/cc-power-panel.c:2089
+#: panels/power/cc-power-panel.c:2192
msgid "Hibernate"
msgstr "Hibernează"
-#: panels/power/cc-power-panel.c:2090
+#: panels/power/cc-power-panel.c:2193
msgid "Nothing"
msgstr "Nimic"
#. Frame header
-#: panels/power/cc-power-panel.c:2204
+#: panels/power/cc-power-panel.c:2307
msgid "Suspend & Power Button"
msgstr "Buton de suspendare și oprire"
-#: panels/power/cc-power-panel.c:2243
+#: panels/power/cc-power-panel.c:2346
msgid "_Automatic suspend"
msgstr "Suspendare _automată"
-#: panels/power/cc-power-panel.c:2244
+#: panels/power/cc-power-panel.c:2347
msgid "Automatic suspend"
msgstr "Suspendare automată"
-#: panels/power/cc-power-panel.c:2311
+#: 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:2430 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 "Dispozitive"
@@ -4163,11 +4222,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 +4325,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"
@@ -4390,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)"
@@ -4417,7 +4476,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 +4966,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 +5014,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 +5177,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 +5188,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 +5245,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 +5596,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"
@@ -5798,34 +5856,202 @@ 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: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 +6062,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 +6082,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 +6101,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 +6165,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 +6174,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 +6270,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 +6397,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 +6442,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 +6830,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"
@@ -6759,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."
@@ -6789,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."
@@ -6797,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?"
@@ -6982,30 +7209,29 @@ 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"
-#: 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"
@@ -7156,7 +7382,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 +7632,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"
@@ -7486,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"
@@ -7714,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"
@@ -7741,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ă"
@@ -8393,8 +8604,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"
@@ -8742,9 +8953,6 @@ msgstr "Sunete de sistem"
#~ msgid "Mesh"
#~ msgstr "Mesh"
-#~ msgid "Disconnected"
-#~ msgstr "Deconectat"
-
#~ msgid "Power management settings"
#~ msgstr "Configurări administrare consum"
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 <whats_up@tut.by>\n"
"Language-Team: Русский <gnome-cyr@gnome.org>\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 "<b>%s</b> removed"
msgstr "<b>%s</b> удалён"
@@ -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"
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 <muhammetk@gmail.com>, 2011, 2012, 2013, 2014, 2015, 2016, 2017.
# Emin Tufan Çetin <etcetin@gmail.com>, 2013, 2016, 2017, 2018.
# Furkan Ahmet Kara <furkanahmetkara.fk@gmail.com>, 2018.
+# Çağatay Yiğit Şahin <cyigitsahin@outlook.com>, 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 <furkanahmetkara.fk@gmail.com>\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 <etcetin@gmail.com>\n"
"Language-Team: Türkçe <gnome-turk@gnome.org>\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 "<b>%s</b> removed"
msgstr "<b>%s</b> 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"
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/cc-application.c b/shell/cc-application.c
index 8beb61714..3f828f3a6 100644
--- a/shell/cc-application.c
+++ b/shell/cc-application.c
@@ -26,8 +26,9 @@
#include <gio/gio.h>
#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)
@@ -157,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));
@@ -264,6 +267,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 +301,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 +312,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-debug.h.in b/shell/cc-debug.h.in
new file mode 100644
index 000000000..226f82e03
--- /dev/null
+++ b/shell/cc-debug.h.in
@@ -0,0 +1,229 @@
+/* cc-debug.h.in
+ *
+ * Copyright © 2018 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib.h>
+
+/**
+ * SECTION:cc-debug
+ * @short_description: Debugging macros
+ * @title:Debugging
+ * @stability:stable
+ *
+ * Macros used for tracing and debugging code. These
+ * are only valid when Settings 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 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); \
+ 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-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 <http://www.gnu.org/licenses/>.
- *
- * Written by: Matthias Clasen <mclasen@redhat.com>
- */
-
-#include <gdk/gdkkeysyms.h>
-#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 <http://www.gnu.org/licenses/>.
- *
- * Written by: Matthias Clasen <mclasen@redhat.com>
- */
-
-#ifndef _CC_EDITABLE_ENTRY_H_
-#define _CC_EDITABLE_ENTRY_H_
-
-#include <gtk/gtk.h>
-
-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/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 <georges.stavracas@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "cc-debug.h"
+#include "cc-log.h"
+
+#include <unistd.h>
+#include <glib.h>
+
+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 <georges.stavracas@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+G_BEGIN_DECLS
+
+void cc_log_init (void);
+
+G_END_DECLS
diff --git a/shell/cc-object-storage.c b/shell/cc-object-storage.c
new file mode 100644
index 000000000..46038cc34
--- /dev/null
+++ b/shell/cc-object-storage.c
@@ -0,0 +1,438 @@
+/* cc-object-storage.h
+ *
+ * Copyright 2018 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#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, g_steal_pointer (&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, g_steal_pointer (&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 <georges.stavracas@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+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/cc-panel-list.c b/shell/cc-panel-list.c
index 0fd093cf9..f5b83509d 100644
--- a/shell/cc-panel-list.c
+++ b/shell/cc-panel-list.c
@@ -294,6 +294,7 @@ static const gchar * const panel_order[] = {
"mouse",
"printers",
"removable-media",
+ "thunderbolt",
"wacom",
"color",
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
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 <http://www.gnu.org/licenses/>.
- *
- */
-
-
-#include "config.h"
-
-#include <glib.h>
-#include <glib/gstdio.h>
-
-#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-model.c b/shell/cc-shell-model.c
index 55f3e3c82..4dcddba45 100644
--- a/shell/cc-shell-model.c
+++ b/shell/cc-shell-model.c
@@ -19,23 +19,25 @@
* Author: Thomas Wood <thos@gnome.org>
*/
+#include "cc-shell-model.h"
+#include "cc-util.h"
+
#include <string.h>
#include <gio/gdesktopappinfo.h>
-#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);
@@ -328,6 +326,30 @@ cc_shell_model_add_item (CcShellModel *model,
}
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 (GTK_TREE_MODEL (model), &iter);
+ while (valid)
+ {
+ g_autofree gchar *panel_id = NULL;
+
+ 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 (GTK_TREE_MODEL (model), &iter);
+ }
+
+ return FALSE;
+}
+
+gboolean
cc_shell_model_iter_matches_search (CcShellModel *model,
GtkTreeIter *iter,
const char *term)
@@ -366,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 259407109..b0fe50ff6 100644
--- a/shell/cc-shell-model.h
+++ b/shell/cc-shell-model.h
@@ -18,9 +18,7 @@
* Author: Thomas Wood <thos@gnome.org>
*/
-
-#ifndef _CC_SHELL_MODEL_H
-#define _CC_SHELL_MODEL_H
+#pragma once
#include <gtk/gtk.h>
@@ -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,34 +54,22 @@ enum
N_COLS
};
-struct _CcShellModel
-{
- GtkListStore parent;
- CcShellModelPrivate *priv;
-};
+CcShellModel* cc_shell_model_new (void);
-struct _CcShellModelClass
-{
- GtkListStoreClass parent_class;
-};
+void cc_shell_model_add_item (CcShellModel *model,
+ CcPanelCategory category,
+ GAppInfo *appinfo,
+ const char *id);
-GType cc_shell_model_get_type (void) G_GNUC_CONST;
+gboolean cc_shell_model_has_panel (CcShellModel *model,
+ const char *id);
-CcShellModel *cc_shell_model_new (void);
+gboolean cc_shell_model_iter_matches_search (CcShellModel *model,
+ GtkTreeIter *iter,
+ const char *term);
-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);
-
-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 */
diff --git a/shell/cc-window.c b/shell/cc-window.c
index f7593dc55..50d3995d7 100644
--- a/shell/cc-window.c
+++ b/shell/cc-window.c
@@ -20,6 +20,8 @@
* Author: Thomas Wood <thos@gnome.org>
*/
+#define G_LOG_DOMAIN "cc-window"
+
#include <config.h>
#include "cc-window.h"
@@ -31,6 +33,7 @@
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkx.h>
#include <string.h>
+#include <time.h>
#include "cc-panel.h"
#include "cc-shell.h"
@@ -62,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;
@@ -88,8 +92,49 @@ enum
};
/* Auxiliary methods */
-static const gchar *
-get_icon_name_from_g_icon (GIcon *gicon)
+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)
{
const gchar * const *names;
GtkIconTheme *icon_theme;
@@ -103,8 +148,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;
@@ -117,14 +165,20 @@ 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);
@@ -144,18 +198,21 @@ 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);
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;
}
@@ -253,9 +310,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,
@@ -266,8 +322,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,
@@ -275,7 +330,7 @@ setup_model (CcWindow *shell)
name,
description,
keywords,
- symbolic_icon);
+ icon_name);
valid = gtk_tree_model_iter_next (model, &iter);
}
@@ -288,12 +343,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)
@@ -332,26 +390,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;
- g_clear_pointer (&name, g_free);
- g_clear_object (&gicon);
+ /* 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);
+
+ cc_panel_list_set_active_panel (CC_PANEL_LIST (self->panel_list), start_id);
return TRUE;
}
@@ -370,13 +427,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");
}
}
@@ -568,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,
@@ -606,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,
@@ -683,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);
@@ -702,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);
@@ -744,10 +826,14 @@ 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 (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));
+
+ /* Add a custom CSS class on development builds */
+ if (in_flatpak_sandbox ())
+ add_development_build_css (self);
}
CcWindow *
@@ -779,4 +865,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
+}
diff --git a/shell/meson.build b/shell/meson.build
index d9364521b..73b18f84e 100644
--- a/shell/meson.build
+++ b/shell/meson.build
@@ -7,53 +7,50 @@ 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
)
-common_sources = files(
+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',
'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
]
@@ -90,48 +87,61 @@ 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,
- 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']
)
-test_unit = 'test-hostname'
-
+# libshell_test
sources = files(
- 'hostname-helper.c',
- test_unit + '.c'
+ 'cc-panel.c',
+ 'cc-shell.c',
+ 'cc-log.c',
+ 'cc-object-storage.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
+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 ]
-test(test_unit, exe)
-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/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.
</description>
</key>
+ <key name="show-development-warning" type="b">
+ <default>true</default>
+ <summary>Show warning when running a development build of Settings</summary>
+ <description>
+ Whether Settings should show a warning when running a development build.
+ </description>
+ </key>
</schema>
</schemalist>
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 @@
<widget name="sidebar_box"/>
</widgets>
</object>
+
+ <!-- Warning dialog for development builds -->
+ <object class="GtkMessageDialog" id="development_warning_dialog">
+ <property name="message-type">warning</property>
+ <property name="transient-for">CcWindow</property>
+ <property name="resizable">false</property>
+ <property name="modal">true</property>
+ <property name="buttons">ok</property>
+ <property name="text" translatable="yes">Warning: Development Version</property>
+ <property name="secondary-text" translatable="yes">This version of Settings should only be used for development purposes. You may experience incorrect system behavior, data loss, and other unexpected issues. </property>
+ <signal name="response" handler="on_development_warning_dialog_responded_cb" object="CcWindow" swapped="no" />
+ </object>
+
</interface>
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
diff --git a/shell/hostnames-test.txt b/tests/common/hostnames-test.txt
index 5a31ce28b..5a31ce28b 100644
--- a/shell/hostnames-test.txt
+++ b/tests/common/hostnames-test.txt
diff --git a/tests/common/meson.build b/tests/common/meson.build
new file mode 100644
index 000000000..4d982f029
--- /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/shell/ssids-test.txt b/tests/common/ssids-test.txt
index 0545437cf..0545437cf 100644
--- a/shell/ssids-test.txt
+++ b/tests/common/ssids-test.txt
diff --git a/shell/test-hostname.c b/tests/common/test-hostname.c
index 3df293051..4e14f715a 100644
--- a/shell/test-hostname.c
+++ b/tests/common/test-hostname.c
@@ -129,8 +129,8 @@ int main (int argc, char **argv)
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);
+ g_test_add_func ("/common/hostname", test_hostname);
+ g_test_add_func ("/common/ssid", test_ssid);
return g_test_run ();
}
diff --git a/tests/datetime/meson.build b/tests/datetime/meson.build
new file mode 100644
index 000000000..fd0896400
--- /dev/null
+++ b/tests/datetime/meson.build
@@ -0,0 +1,35 @@
+
+test_units = [
+ 'test-timezone',
+ 'test-timezone-gfx',
+ 'test-endianess',
+]
+
+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()),
+ '-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
+ )
+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 <http://www.gnu.org/licenses/>.
+#
+# Authors: Benjamin Berg <bberg@redhat.com>
+# Georges Basile Stavracas Neto <georges@endlessm.com>
+
+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
diff --git a/panels/datetime/test-endianess.c b/tests/datetime/test-endianess.c
index 06b26131b..06b26131b 100644
--- a/panels/datetime/test-endianess.c
+++ b/tests/datetime/test-endianess.c
diff --git a/tests/datetime/test-timezone-gfx.c b/tests/datetime/test-timezone-gfx.c
new file mode 100644
index 000000000..22619c30c
--- /dev/null
+++ b/tests/datetime/test-timezone-gfx.c
@@ -0,0 +1,74 @@
+#include <config.h>
+#include <locale.h>
+#include <gtk/gtk.h>
+
+#include "cc-datetime-resources.h"
+#include "tz.h"
+
+static void
+test_timezone_gfx (gconstpointer data)
+{
+ g_autoptr(TzDB) db = NULL;
+ GPtrArray *locs;
+ const char *pixmap_dir;
+ guint i;
+
+ pixmap_dir = data;
+ db = tz_load_db ();
+ locs = tz_get_locations (db);
+
+ 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];
+
+ 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);
+
+ 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 ();
+ }
+ }
+}
+
+gint
+main (gint argc,
+ gchar **argv)
+{
+ gchar *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..5962fc45e
--- /dev/null
+++ b/tests/datetime/test-timezone.c
@@ -0,0 +1,65 @@
+#include <locale.h>
+#include <gtk/gtk.h>
+#include "cc-datetime-resources.h"
+#include "cc-timezone-map.h"
+
+static void
+test_timezone (void)
+{
+ g_autoptr(GHashTable) ht = NULL;
+ CcTimezoneMap *map;
+ TzDB *tz_db;
+ guint i;
+
+ 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 ();
+
+ g_assert_nonnull (tz_db);
+ g_assert_nonnull (tz_db->locations);
+
+ for (i = 0; tz_db->locations && i < tz_db->locations->len; i++)
+ {
+ g_autofree gchar *clean_tz = NULL;
+ TzLocation *location = NULL;
+
+ location = g_ptr_array_index (tz_db->locations, i);
+ clean_tz = tz_info_get_clean_name (tz_db, location->zone);
+
+ 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));
+ }
+
+ /* 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 ();
+ }
+ }
+
+ tz_db_free (tz_db);
+}
+
+gint
+main (gint argc,
+ gchar **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/panels/info/info-cleanup-test.txt b/tests/info/info-cleanup-test.txt
index 29f4e79fc..29f4e79fc 100644
--- a/panels/info/info-cleanup-test.txt
+++ b/tests/info/info-cleanup-test.txt
diff --git a/tests/info/meson.build b/tests/info/meson.build
new file mode 100644
index 000000000..202e9e34e
--- /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/panels/info/test-info-cleanup.c b/tests/info/test-info-cleanup.c
index 3e6bebd2e..3e6bebd2e 100644
--- a/panels/info/test-info-cleanup.c
+++ b/tests/info/test-info-cleanup.c
diff --git a/tests/meson.build b/tests/meson.build
new file mode 100644
index 000000000..33b460148
--- /dev/null
+++ b/tests/meson.build
@@ -0,0 +1,7 @@
+subdir('common')
+subdir('datetime')
+if host_is_linux
+ subdir('network')
+endif
+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 <bberg@redhat.com>
+ */
+
+#define G_LOG_DOMAIN "cc-test-window"
+
+#include <config.h>
+
+#include "cc-test-window.h"
+
+#include <gio/gio.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <gdk/gdkx.h>
+#include <string.h>
+
+#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 <bberg@redhat.com>
+ */
+
+#pragma once
+
+#include <glib-object.h>
+#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..5c929232b
--- /dev/null
+++ b/tests/network/meson.build
@@ -0,0 +1,31 @@
+
+
+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/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 <walters@verbum.org>.
+ *
+ * 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 <gio/gio.h>
+
+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 <dbus/dbus-shared.h> */
+
+/* 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 <config.h>
+#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 <stdlib.h>
+
+/*****************************************************************************/
+
+#if (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_GLIB
+
+#include <glib.h>
+
+#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 <glib/gi18n.h>
+#elif (NETWORKMANAGER_COMPILATION) & NM_NETWORKMANAGER_COMPILATION_WITH_GLIB_I18N_LIB
+#include <glib/gi18n-lib.h>
+#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, "<dropped>");
+}
+
+#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, "<unknown-fcn>", (expr) ? "<dropped>" : 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__, \
+ "<dropped>"); \
+ 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__, \
+ "<dropped>"); \
+ return; \
+ } G_STMT_END
+
+#define NM_ASSERT_G_RETURN_EXPR(expr) "<dropped>"
+#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 <gio/gio.h>
+#include <string.h>
+
+#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
--- /dev/null
+++ b/tests/network/nm-utils/nm-hash-utils.h
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 <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#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
--- /dev/null
+++ b/tests/network/nm-utils/nm-shared-utils.h
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 <string.h>
+
+#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
--- /dev/null
+++ b/tests/network/nm-utils/nm-test-utils.h
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..9dd95bb77
--- /dev/null
+++ b/tests/network/nm-utils/test-networkmanager-service.py
@@ -0,0 +1,1445 @@
+#!/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 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
+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_STATE_REASON = "StateReason"
+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.reason = NM_DEVICE_STATE_REASON_NONE
+ 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_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)
+ 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 set_state_reason(self, state, reason):
+ self.state = state
+ self.reason = reason
+ self.__notify(PD_STATE)
+ self.__notify(PD_STATE_REASON)
+
+
+###################################################################
+
+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.speed = 100
+ 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(self.speed)
+ 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
+
+ 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'
+
+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='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")
+ 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)
+ 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)
+
+ try:
+ mainloop.run()
+ except Exception as e:
+ pass
+
+ sys.exit(0)
+
+if __name__ == '__main__':
+ main()
+
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 <bberg@redhat.com>
+ */
+
+#define G_LOG_DOMAIN "test-network-panel"
+
+#include "nm-macros-internal.h"
+
+#include <NetworkManager.h>
+#include <nm-client.h>
+#include <nm-utils.h>
+
+#include "nm-test-libnm-utils.h"
+
+#include <string.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <gtk/gtk.h>
+
+#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 <http://www.gnu.org/licenses/>.
+#
+# Authors: Benjamin Berg <bberg@redhat.com>
+
+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))
diff --git a/panels/printers/canonicalization-test.txt b/tests/printers/canonicalization-test.txt
index 10ceee17d..10ceee17d 100644
--- a/panels/printers/canonicalization-test.txt
+++ b/tests/printers/canonicalization-test.txt
diff --git a/tests/printers/meson.build b/tests/printers/meson.build
new file mode 100644
index 000000000..bbf43ab0c
--- /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/panels/printers/shift-test.txt b/tests/printers/shift-test.txt
index b9eced439..b9eced439 100644
--- a/panels/printers/shift-test.txt
+++ b/tests/printers/shift-test.txt
diff --git a/panels/printers/test-canonicalization.c b/tests/printers/test-canonicalization.c
index d5556600f..d5556600f 100644
--- a/panels/printers/test-canonicalization.c
+++ b/tests/printers/test-canonicalization.c
diff --git a/panels/printers/test-shift.c b/tests/printers/test-shift.c
index e85fe9af3..e85fe9af3 100644
--- a/panels/printers/test-shift.c
+++ b/tests/printers/test-shift.c
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 <http://www.gnu.org/licenses/>.
+#
+# Authors: Benjamin Berg <bberg@redhat.com>
+
+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)
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 <http://www.gnu.org/licenses/>.
+#
+# Authors: Benjamin Berg <bberg@redhat.com>
+
+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()