diff -Nru gnome-shell-extension-zorin-connect-24.1/crowdin.yml gnome-shell-extension-zorin-connect-28.0.2/crowdin.yml --- gnome-shell-extension-zorin-connect-24.1/crowdin.yml 2019-05-01 13:29:29.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/crowdin.yml 2019-11-30 11:25:37.000000000 +0000 @@ -4,6 +4,7 @@ translation: /po/%locale%.po languages_mapping: locale: + ar-SA: ar ca-ES: ca ca: ca fr: fr @@ -28,3 +29,4 @@ tr: tr uk: uk zh-CN: zh_CN + zh-TW: zh_TW diff -Nru gnome-shell-extension-zorin-connect-24.1/data/application.css gnome-shell-extension-zorin-connect-28.0.2/data/application.css --- gnome-shell-extension-zorin-connect-24.1/data/application.css 2019-03-04 02:15:42.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/application.css 2019-11-30 12:41:43.000000000 +0000 @@ -50,7 +50,7 @@ /** * ZorinConnectConversationWidget */ -.message-window { +.message-scrolled { border-bottom: 1px solid @borders; } @@ -62,56 +62,25 @@ margin-bottom: 1em; } -.conversation-list { +.thread-list { background: @content_view_bg_color; } - /** * Incoming Message Bubbles (GtkLabel subclass) */ .message-in { - background: @theme_selected_bg_color; - color: @theme_selected_fg_color; - padding: 6px; - padding-right: 9px; - padding-left: 9px; + color: @theme_fg_color; + background: alpha(@theme_selected_bg_color, 0.2); + border: 1px solid alpha(@theme_selected_bg_color, 0.2); + border-radius: 5px; + box-shadow: 2px 2px 3px -2px rgba(0, 0, 0, 0.75); + padding: 6px 9px 6px 9px; } .message-in selection { - background-color: @theme_selected_fg_color; color: @theme_selected_bg_color; -} - -.message-in:dir(ltr) { - border-radius: 0.25em 1em 1em 0.25em; -} - -.message-in:first-child:dir(ltr) { - border-top-left-radius: 1em; -} - -.message-in:last-child:dir(ltr) { - border-bottom-left-radius: 1em; -} - -.message-in:dir(rtl) { - border-radius: 1em 0.25em 0.25em 1em; -} - -.message-in:first-child:dir(rtl) { - border-top-right-radius: 1em; -} - -.message-in:last-child:dir(rtl) { - border-bottom-right-radius: 1em; -} - -/** - * Must contrast with .message-in background - */ -.message-in *:link { - color: @theme_selected_fg_color; + background-color: @theme_selected_fg_color; } @@ -119,12 +88,14 @@ * Outgoing Message Bubbles (GtkLabel subclass) */ .message-out { - background: alpha(@theme_selected_bg_color, 0.2); + color: @theme_fg_color; + background-color: @theme_bg_color; + border: 1px solid alpha(@theme_fg_color, 0.1); + border-radius: 5px; + box-shadow: 2px 2px 3px -2px rgba(0, 0, 0, 0.75); caret-color: currentColor; -gtk-secondary-caret-color: currentColor; - padding: 6px; - padding-right: 6px; - padding-left: 9px; + padding: 6px 9px 6px 9px; } .message-out selection { @@ -132,35 +103,10 @@ color: @theme_selected_fg_color; } -.message-out:dir(ltr) { - border-right: 3px solid @theme_selected_bg_color; - border-radius: 1em 0.25em 0.25em 1em; -} - -.message-out:first-child:dir(ltr) { - border-top-right-radius: 1em; -} - -.message-out:last-child:dir(ltr) { - border-bottom-right-radius: 1em; -} - -.message-out:dir(rtl) { - border-left: 3px solid @theme_selected_bg_color; - border-radius: 0.25em 1em 1em 0.25em; -} - -.message-out:first-child:dir(rtl) { - border-top-left-radius: 1em; -} - -.message-out:last-child:dir(rtl) { - border-bottom-left-radius: 1em; -} - /** - * Must contrast with .message-out background + * Must contrast with message background */ +.message-in *:link, .message-out *:link { color: @theme_fg_color; } Binary files /tmp/tmp3rLlVa/q9MxMBweRe/gnome-shell-extension-zorin-connect-24.1/data/chrome-badge.png and /tmp/tmp3rLlVa/feI3AdV5Xv/gnome-shell-extension-zorin-connect-28.0.2/data/chrome-badge.png differ diff -Nru gnome-shell-extension-zorin-connect-24.1/data/computer.svg gnome-shell-extension-zorin-connect-28.0.2/data/computer.svg --- gnome-shell-extension-zorin-connect-24.1/data/computer.svg 2019-02-27 14:48:10.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/computer.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ - - - - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/computer-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/computer-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/computer-symbolic.svg 2019-03-11 16:31:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/computer-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,179 +0,0 @@ - - - - - - - - - - - image/svg+xml - - Paper Symbolic Icon Theme - - - - Paper Symbolic Icon Theme - - - - - - - - - - - - - - - - - - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/connect.ui gnome-shell-extension-zorin-connect-28.0.2/data/connect.ui --- gnome-shell-extension-zorin-connect-24.1/data/connect.ui 2019-03-04 02:20:56.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/connect.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,196 +0,0 @@ - - - - - - - - - - - - - - - - 1716 - 1764 - 1 - 1 - - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/contacts.ui gnome-shell-extension-zorin-connect-28.0.2/data/contacts.ui --- gnome-shell-extension-zorin-connect-24.1/data/contacts.ui 2019-03-04 02:26:18.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/contacts.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,96 +0,0 @@ - - - - - - - True - False - center - center - - - True - False - 144 - avatar-default-symbolic - - - - 0 - 0 - - - - - True - False - No contacts - - - - 0 - 1 - - - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/conversation.ui gnome-shell-extension-zorin-connect-28.0.2/data/conversation.ui --- gnome-shell-extension-zorin-connect-24.1/data/conversation.ui 2019-03-04 02:20:26.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/conversation.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ - - - - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/devel.ui gnome-shell-extension-zorin-connect-28.0.2/data/devel.ui --- gnome-shell-extension-zorin-connect-24.1/data/devel.ui 2019-03-04 02:20:10.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/devel.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,1589 +0,0 @@ - - - - - - 1 - 2147483647 - 1 - 1 - 1 - - - 1 - 2147483647 - 2147483647 - 1 - 1 - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/device.ui gnome-shell-extension-zorin-connect-28.0.2/data/device.ui --- gnome-shell-extension-zorin-connect-24.1/data/device.ui 2019-03-17 11:36:50.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/device.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,2244 +0,0 @@ - - - - - - - True - False - center - center - 16 - 32 - system-run-symbolic - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/enter-keyboard-shortcut.svg gnome-shell-extension-zorin-connect-28.0.2/data/enter-keyboard-shortcut.svg --- gnome-shell-extension-zorin-connect-24.1/data/enter-keyboard-shortcut.svg 2019-02-27 14:48:10.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/enter-keyboard-shortcut.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,245 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Binary files /tmp/tmp3rLlVa/q9MxMBweRe/gnome-shell-extension-zorin-connect-24.1/data/fdroid-badge.png and /tmp/tmp3rLlVa/feI3AdV5Xv/gnome-shell-extension-zorin-connect-28.0.2/data/fdroid-badge.png differ Binary files /tmp/tmp3rLlVa/q9MxMBweRe/gnome-shell-extension-zorin-connect-24.1/data/firefox-badge.png and /tmp/tmp3rLlVa/feI3AdV5Xv/gnome-shell-extension-zorin-connect-28.0.2/data/firefox-badge.png differ diff -Nru gnome-shell-extension-zorin-connect-24.1/data/gtk/menus.ui gnome-shell-extension-zorin-connect-28.0.2/data/gtk/menus.ui --- gnome-shell-extension-zorin-connect-24.1/data/gtk/menus.ui 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/gtk/menus.ui 2019-11-30 12:58:32.000000000 +0000 @@ -0,0 +1,25 @@ + + + +
+ + + Encryption Info + settings.encryption-info + + + + Pair + settings.pair + action-disabled + + + + Unpair + settings.unpair + action-disabled + +
+
+
+ diff -Nru gnome-shell-extension-zorin-connect-24.1/data/icons/computer-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/icons/computer-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/icons/computer-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/icons/computer-symbolic.svg 2019-11-30 13:09:43.000000000 +0000 @@ -0,0 +1,179 @@ + + + + + + + + + + + image/svg+xml + + Paper Symbolic Icon Theme + + + + Paper Symbolic Icon Theme + + + + + + + + + + + + + + + + + + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/icons/group-avatar-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/icons/group-avatar-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/icons/group-avatar-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/icons/group-avatar-symbolic.svg 2019-11-30 21:40:49.000000000 +0000 @@ -0,0 +1,39 @@ + + + + + + + + + + + image/svg+xml + + Paper Symbolic Icon Theme + + + + Paper Symbolic Icon Theme + + + + + + + + + + + + + + + + + + + + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/icons/laptop-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/icons/laptop-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/icons/laptop-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/icons/laptop-symbolic.svg 2019-03-11 16:31:33.000000000 +0000 @@ -0,0 +1,39 @@ + + + + + + + + + + + image/svg+xml + + Paper Symbolic Icon Theme + + + + Paper Symbolic Icon Theme + + + + + + + + + + + + + + + + + + + + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/icons/org.gnome.Shell.Extensions.ZorinConnect.svg gnome-shell-extension-zorin-connect-28.0.2/data/icons/org.gnome.Shell.Extensions.ZorinConnect.svg --- gnome-shell-extension-zorin-connect-24.1/data/icons/org.gnome.Shell.Extensions.ZorinConnect.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/icons/org.gnome.Shell.Extensions.ZorinConnect.svg 2019-03-12 13:07:56.000000000 +0000 @@ -0,0 +1,67 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/icons/org.gnome.Shell.Extensions.ZorinConnect-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/icons/org.gnome.Shell.Extensions.ZorinConnect-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/icons/org.gnome.Shell.Extensions.ZorinConnect-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/icons/org.gnome.Shell.Extensions.ZorinConnect-symbolic.svg 2019-11-30 13:09:15.000000000 +0000 @@ -0,0 +1,3 @@ + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/icons/phonelink-delete-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/icons/phonelink-delete-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/icons/phonelink-delete-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/icons/phonelink-delete-symbolic.svg 2019-11-30 21:23:28.000000000 +0000 @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/icons/phonelink-lock-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/icons/phonelink-lock-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/icons/phonelink-lock-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/icons/phonelink-lock-symbolic.svg 2019-11-30 21:25:30.000000000 +0000 @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/icons/phonelink-off-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/icons/phonelink-off-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/icons/phonelink-off-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/icons/phonelink-off-symbolic.svg 2019-11-30 21:36:55.000000000 +0000 @@ -0,0 +1,65 @@ + + + + + + image/svg+xml + + + + + + + + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/icons/phonelink-ring-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/icons/phonelink-ring-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/icons/phonelink-ring-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/icons/phonelink-ring-symbolic.svg 2019-11-30 21:29:48.000000000 +0000 @@ -0,0 +1,64 @@ + + + + + + image/svg+xml + + + + + + + + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/icons/phonelink-setup-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/icons/phonelink-setup-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/icons/phonelink-setup-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/icons/phonelink-setup-symbolic.svg 2019-11-30 21:31:37.000000000 +0000 @@ -0,0 +1,57 @@ + + + + + + image/svg+xml + + + + + + + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/icons/phonelink-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/icons/phonelink-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/icons/phonelink-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/icons/phonelink-symbolic.svg 2019-11-30 13:09:15.000000000 +0000 @@ -0,0 +1,3 @@ + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/icons/smartphone-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/icons/smartphone-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/icons/smartphone-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/icons/smartphone-symbolic.svg 2019-11-30 13:12:16.000000000 +0000 @@ -0,0 +1,3 @@ + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/icons/sms-send.svg gnome-shell-extension-zorin-connect-28.0.2/data/icons/sms-send.svg --- gnome-shell-extension-zorin-connect-24.1/data/icons/sms-send.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/icons/sms-send.svg 2019-11-01 23:59:50.000000000 +0000 @@ -0,0 +1,3 @@ + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/icons/sms-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/icons/sms-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/icons/sms-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/icons/sms-symbolic.svg 2019-11-01 23:59:50.000000000 +0000 @@ -0,0 +1,3 @@ + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/icons/tablet-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/icons/tablet-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/icons/tablet-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/icons/tablet-symbolic.svg 2019-11-01 23:59:50.000000000 +0000 @@ -0,0 +1,4 @@ + + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/icons/tv-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/icons/tv-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/icons/tv-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/icons/tv-symbolic.svg 2019-11-30 21:39:39.000000000 +0000 @@ -0,0 +1,39 @@ + + + + + + + + + + + image/svg+xml + + Paper Symbolic Icon Theme + + + + Paper Symbolic Icon Theme + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/tmp3rLlVa/q9MxMBweRe/gnome-shell-extension-zorin-connect-24.1/data/images/chrome-badge.png and /tmp/tmp3rLlVa/feI3AdV5Xv/gnome-shell-extension-zorin-connect-28.0.2/data/images/chrome-badge.png differ diff -Nru gnome-shell-extension-zorin-connect-24.1/data/images/enter-keyboard-shortcut.svg gnome-shell-extension-zorin-connect-28.0.2/data/images/enter-keyboard-shortcut.svg --- gnome-shell-extension-zorin-connect-24.1/data/images/enter-keyboard-shortcut.svg 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/images/enter-keyboard-shortcut.svg 2019-11-01 23:59:50.000000000 +0000 @@ -0,0 +1,245 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Binary files /tmp/tmp3rLlVa/q9MxMBweRe/gnome-shell-extension-zorin-connect-24.1/data/images/fdroid-badge.png and /tmp/tmp3rLlVa/feI3AdV5Xv/gnome-shell-extension-zorin-connect-28.0.2/data/images/fdroid-badge.png differ Binary files /tmp/tmp3rLlVa/q9MxMBweRe/gnome-shell-extension-zorin-connect-24.1/data/images/firefox-badge.png and /tmp/tmp3rLlVa/feI3AdV5Xv/gnome-shell-extension-zorin-connect-28.0.2/data/images/firefox-badge.png differ Binary files /tmp/tmp3rLlVa/q9MxMBweRe/gnome-shell-extension-zorin-connect-24.1/data/images/play-store-badge.png and /tmp/tmp3rLlVa/feI3AdV5Xv/gnome-shell-extension-zorin-connect-28.0.2/data/images/play-store-badge.png differ diff -Nru gnome-shell-extension-zorin-connect-24.1/data/laptop.svg gnome-shell-extension-zorin-connect-28.0.2/data/laptop.svg --- gnome-shell-extension-zorin-connect-24.1/data/laptop.svg 2019-02-27 14:48:10.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/laptop.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,11 +0,0 @@ - - - - - - - - - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/laptop-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/laptop-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/laptop-symbolic.svg 2019-03-11 16:31:33.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/laptop-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ - - - - - - - - - - - image/svg+xml - - Paper Symbolic Icon Theme - - - - Paper Symbolic Icon Theme - - - - - - - - - - - - - - - - - - - - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/menus.ui gnome-shell-extension-zorin-connect-28.0.2/data/menus.ui --- gnome-shell-extension-zorin-connect-24.1/data/menus.ui 2019-03-05 23:46:36.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/menus.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ - - - -
- - - Connect to… - win.connect - -
-
- Display Mode - - - Panel - win.display-mode - panel - - - - User Menu - win.display-mode - user-menu - -
-
- - - Generate Support Log - win.support-log - - - About Zorin Connect - win.about - -
-
- - - -
- - - Switch to Bluetooth - settings.connect-bluetooth - bluetooth-symbolic - action-disabled - - - - Switch to LAN - settings.connect-tcp - network-wireless-symbolic - action-disabled - - - - Encryption Info - settings.encryption-info - - - - Pair - settings.pair - action-disabled - - - - Unpair - settings.unpair - action-disabled - -
-
- - - -
- - - To Device - edit-paste-symbolic - settings.send-content - - - - From Device - edit-copy-symbolic - settings.receive-content - -
-
- - - -
- - - Nothing - audio-volume-medium-symbolic - settings.ringing-volume - nothing - - - - Lower - audio-volume-low-symbolic - settings.ringing-volume - lower - - - - Mute - audio-volume-muted-symbolic - settings.ringing-volume - mute - -
-
- - -
- - - Nothing - audio-volume-medium-symbolic - settings.talking-volume - nothing - - - - Lower - audio-volume-low-symbolic - settings.talking-volume - lower - - - - Mute - audio-volume-muted-symbolic - settings.talking-volume - mute - -
-
-
- diff -Nru gnome-shell-extension-zorin-connect-24.1/data/meson.build gnome-shell-extension-zorin-connect-28.0.2/data/meson.build --- gnome-shell-extension-zorin-connect-24.1/data/meson.build 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/meson.build 2019-11-30 12:45:34.000000000 +0000 @@ -0,0 +1,124 @@ +# metadata.json +configure_file( + input: 'metadata.json.in', + output: 'metadata.json', + configuration: extconfig, + install_dir: extdatadir +) + + +# Desktop Entry +desktop_file = configure_file( + input: 'org.gnome.Shell.Extensions.ZorinConnect.desktop', + output: 'org.gnome.Shell.Extensions.ZorinConnect.desktop', + configuration: extconfig, + install_dir: join_paths(datadir, 'applications') +) + +desktop_utils = find_program('desktop-file-validate', required: false) + +if desktop_utils.found() + test('Validate desktop file', desktop_utils, + args: [desktop_file] + ) +endif + + +# Application Icon +install_data([ + 'icons/org.gnome.Shell.Extensions.ZorinConnect.svg', + 'icons/org.gnome.Shell.Extensions.ZorinConnect-symbolic.svg'], + install_dir: join_paths(datadir, 'icons', 'hicolor', 'scalable', 'apps') +) + + +# DBus Service +dbus = dependency('dbus-1', required: false) + +if get_option('session_bus_services_dir') != '' + dbus_dir = get_option('session_bus_services_dir') +elif dbus.found() + dbus_dir = dbus.get_pkgconfig_variable('session_bus_services_dir') +else + dbus_dir = join_paths(datadir, 'dbus-1', 'services') +endif + +configure_file( + input: 'org.gnome.Shell.Extensions.ZorinConnect.service', + output: 'org.gnome.Shell.Extensions.ZorinConnect.service', + configuration: extconfig, + install_dir: dbus_dir +) + + +# WebExtension Manifests +if get_option('webextension') + nmh_manifest = 'org.gnome.shell.extensions.zorin_connect.json' + + # Chrome + if get_option('chrome_nmhdir') != '' + chrome_nmhdir = get_option('chrome_nmhdir') + else + chrome_nmhdir = join_paths(sysconfdir, 'opt', 'chrome', 'native-messaging-hosts') + endif + + chrome_nmh = configure_file( + input: 'org.gnome.shell.extensions.zorin_connect.json-chrome', + output: 'org.gnome.shell.extensions.zorin_connect.json-chrome', + configuration: extconfig + ) + + install_data( + chrome_nmh, + rename: join_paths(chrome_nmhdir, nmh_manifest) + ) + + # Chromium + if get_option('chromium_nmhdir') != '' + chromium_nmhdir = get_option('chromium_nmhdir') + else + chromium_nmhdir = join_paths(sysconfdir, 'chromium', 'native-messaging-hosts') + endif + + chromium_nmh = configure_file( + input: 'org.gnome.shell.extensions.zorin_connect.json-chrome', + output: 'org.gnome.shell.extensions.zorin_connect.json-chromium', + configuration: extconfig + ) + + install_data( + chromium_nmh, + rename: join_paths(chromium_nmhdir, nmh_manifest) + ) + + # Mozilla + if get_option('mozilla_nmhdir') != '' + mozilla_nmhdir = get_option('mozilla_nmhdir') + else + mozilla_nmhdir = join_paths(libdir, 'mozilla', 'native-messaging-hosts') + endif + + configure_file( + input: 'org.gnome.shell.extensions.zorin_connect.json-mozilla', + output: nmh_manifest, + configuration: extconfig, + install_dir: mozilla_nmhdir + ) +endif + + +# GSettings +install_data( + 'org.gnome.Shell.Extensions.ZorinConnect.gschema.xml', + install_dir: gschemadir +) + + +# GResource +gnome.compile_resources( + 'org.gnome.Shell.Extensions.ZorinConnect', + 'org.gnome.Shell.Extensions.ZorinConnect.gresource.xml', + gresource_bundle: true, + install: true, + install_dir: extdatadir +) diff -Nru gnome-shell-extension-zorin-connect-24.1/data/messaging.ui gnome-shell-extension-zorin-connect-28.0.2/data/messaging.ui --- gnome-shell-extension-zorin-connect-24.1/data/messaging.ui 2019-03-04 02:19:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/messaging.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,265 +0,0 @@ - - - - - - - True - False - center - center - - - True - False - 96 - view-list-symbolic - - - - 0 - 0 - - - - - True - False - 12 - No Conversations - - - - 0 - 1 - - - - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/metadata.json.in gnome-shell-extension-zorin-connect-28.0.2/data/metadata.json.in --- gnome-shell-extension-zorin-connect-24.1/data/metadata.json.in 2019-03-18 10:52:27.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/metadata.json.in 2019-11-30 12:44:03.000000000 +0000 @@ -4,16 +4,14 @@ "name": "Zorin Connect", "description": "Zorin Connect allows devices to securely share content like notifications or files and other features like SMS messaging and remote control.", "version": @VERSION@, - "shell-version": [ "3.28", "3.30", "3.32" ], + "shell-version": [ "3.28", "3.30", "3.32", "3.34"], "libdir": "@GNOME_SHELL_LIBDIR@", "localedir": "@LOCALEDIR@", "gschemadir": "@GSCHEMADIR@", "bin": { "ffmpeg": "@FFMPEG_PATH@", - "fusermount": "@FUSERMOUNT_PATH@", "openssl": "@OPENSSL_PATH@", "ssh_add": "@SSHADD_PATH@", - "ssh_keygen": "@SSHKEYGEN_PATH@", - "sshfs": "@SSHFS_PATH@" + "ssh_keygen": "@SSHKEYGEN_PATH@" } } diff -Nru gnome-shell-extension-zorin-connect-24.1/data/notification.ui gnome-shell-extension-zorin-connect-28.0.2/data/notification.ui --- gnome-shell-extension-zorin-connect-24.1/data/notification.ui 2019-03-04 02:16:50.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/notification.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,187 +0,0 @@ - - - - - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/org.gnome.Shell.Extensions.ZorinConnect.gresource.xml gnome-shell-extension-zorin-connect-28.0.2/data/org.gnome.Shell.Extensions.ZorinConnect.gresource.xml --- gnome-shell-extension-zorin-connect-24.1/data/org.gnome.Shell.Extensions.ZorinConnect.gresource.xml 2019-05-01 22:11:17.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/org.gnome.Shell.Extensions.ZorinConnect.gresource.xml 2019-11-30 22:47:51.000000000 +0000 @@ -3,57 +3,59 @@ application.css - connect.ui - contacts.ui - conversation.ui - devel.ui - device.ui - messaging.ui - notification.ui - settings.ui - telephony.ui - enter-keyboard-shortcut.svg + gtk/menus.ui + ui/connect.ui + ui/contact-chooser.ui + ui/conversation.ui + ui/device-preferences.ui + ui/messaging-window.ui + ui/notification-reply-dialog.ui + ui/preferences-window.ui + ui/telephony.ui - + org.gnome.Shell.Extensions.ZorinConnect.desktop org.gnome.Shell.Extensions.ZorinConnect.service org.gnome.Shell.Extensions.ZorinConnect.xml - - org.gnome.Shell.Extensions.ZorinConnect.sdp.xml - - org.gnome.shell.extensions.zorin_connect.json-chrome - org.gnome.shell.extensions.zorin_connect.json-mozilla - - - org.gnome.Shell.Extensions.ZorinConnect.svg - org.gnome.Shell.Extensions.ZorinConnect-symbolic.svg + icons/org.gnome.Shell.Extensions.ZorinConnect.svg + icons/org.gnome.Shell.Extensions.ZorinConnect-symbolic.svg - - sms-send.svg - sms-symbolic.svg - - - computer.svg - computer-symbolic.svg - laptop.svg - laptop-symbolic.svg - smartphone.svg - smartphone-symbolic.svg - tablet.svg - tablet-symbolic.svg - - - firefox-badge.png - chrome-badge.png - - - fdroid-badge.png - play-store-badge.png - - - menus.ui + + icons/computer-symbolic.svg + icons/smartphone-symbolic.svg + icons/tv-symbolic.svg + + + icons/laptop-symbolic.svg + icons/tablet-symbolic.svg + + + icons/phonelink-symbolic.svg + icons/phonelink-delete-symbolic.svg + icons/phonelink-lock-symbolic.svg + icons/phonelink-off-symbolic.svg + icons/phonelink-ring-symbolic.svg + icons/phonelink-setup-symbolic.svg + + + icons/group-avatar-symbolic.svg + icons/sms-send.svg + icons/sms-symbolic.svg + images/enter-keyboard-shortcut.svg + + + org.gnome.shell.extensions.zorin_connect.json-chrome + org.gnome.shell.extensions.zorin_connect.json-mozilla + images/chrome-badge.png + images/firefox-badge.png + images/play-store-badge.png + images/fdroid-badge.png diff -Nru gnome-shell-extension-zorin-connect-24.1/data/org.gnome.Shell.Extensions.ZorinConnect.gschema.xml gnome-shell-extension-zorin-connect-28.0.2/data/org.gnome.Shell.Extensions.ZorinConnect.gschema.xml --- gnome-shell-extension-zorin-connect-24.1/data/org.gnome.Shell.Extensions.ZorinConnect.gschema.xml 2019-05-29 12:38:56.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/org.gnome.Shell.Extensions.ZorinConnect.gschema.xml 2019-11-30 12:52:16.000000000 +0000 @@ -2,6 +2,9 @@ + + true + false @@ -10,6 +13,12 @@ "" + + "" + + + "" + [] @@ -24,25 +33,11 @@ - - - (0, 0) - + + - (300, 300) - - - false - - - - - (0, 0) - - (640, 440) - false @@ -53,9 +48,6 @@ "" - - "" - {} @@ -69,7 +61,7 @@ false - "unknown" + "smartphone" [] @@ -80,24 +72,9 @@ [] - - [] - [] - - "" - - - 1716 - - - "" - - - "" - "" @@ -107,6 +84,12 @@ false + + true + + + false + @@ -136,6 +119,9 @@ true + + true + '{}' @@ -144,15 +130,26 @@ true + + "" + + {} - + + + true + + + "" + + false diff -Nru gnome-shell-extension-zorin-connect-24.1/data/org.gnome.Shell.Extensions.ZorinConnect.svg gnome-shell-extension-zorin-connect-28.0.2/data/org.gnome.Shell.Extensions.ZorinConnect.svg --- gnome-shell-extension-zorin-connect-24.1/data/org.gnome.Shell.Extensions.ZorinConnect.svg 2019-03-12 13:07:56.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/org.gnome.Shell.Extensions.ZorinConnect.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/org.gnome.Shell.Extensions.ZorinConnect-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/org.gnome.Shell.Extensions.ZorinConnect-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/org.gnome.Shell.Extensions.ZorinConnect-symbolic.svg 2019-03-08 17:41:16.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/org.gnome.Shell.Extensions.ZorinConnect-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ - - - Binary files /tmp/tmp3rLlVa/q9MxMBweRe/gnome-shell-extension-zorin-connect-24.1/data/play-store-badge.png and /tmp/tmp3rLlVa/feI3AdV5Xv/gnome-shell-extension-zorin-connect-28.0.2/data/play-store-badge.png differ diff -Nru gnome-shell-extension-zorin-connect-24.1/data/settings.ui gnome-shell-extension-zorin-connect-28.0.2/data/settings.ui --- gnome-shell-extension-zorin-connect-24.1/data/settings.ui 2019-05-01 22:17:59.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/settings.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,635 +0,0 @@ - - - - - - 52 - True - False - True - Searching for devices… - - - - False - - - True - True - True - center - center - 6 - 6 - 6 - 6 - True - name - - - - - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/smartphone.svg gnome-shell-extension-zorin-connect-28.0.2/data/smartphone.svg --- gnome-shell-extension-zorin-connect-24.1/data/smartphone.svg 2019-02-27 14:48:10.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/smartphone.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,10 +0,0 @@ - - - - - - - - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/smartphone-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/smartphone-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/smartphone-symbolic.svg 2019-02-27 14:48:11.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/smartphone-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/sms-send.svg gnome-shell-extension-zorin-connect-28.0.2/data/sms-send.svg --- gnome-shell-extension-zorin-connect-24.1/data/sms-send.svg 2019-02-27 14:48:10.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/sms-send.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/sms-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/sms-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/sms-symbolic.svg 2019-02-27 14:48:10.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/sms-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/tablet.svg gnome-shell-extension-zorin-connect-28.0.2/data/tablet.svg --- gnome-shell-extension-zorin-connect-24.1/data/tablet.svg 2019-02-27 14:48:10.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/tablet.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/tablet-symbolic.svg gnome-shell-extension-zorin-connect-28.0.2/data/tablet-symbolic.svg --- gnome-shell-extension-zorin-connect-24.1/data/tablet-symbolic.svg 2019-02-27 14:48:10.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/tablet-symbolic.svg 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ - - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/telephony.ui gnome-shell-extension-zorin-connect-28.0.2/data/telephony.ui --- gnome-shell-extension-zorin-connect-24.1/data/telephony.ui 2019-03-04 02:15:54.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/telephony.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,158 +0,0 @@ - - - - - - - diff -Nru gnome-shell-extension-zorin-connect-24.1/data/ui/connect.ui gnome-shell-extension-zorin-connect-28.0.2/data/ui/connect.ui --- gnome-shell-extension-zorin-connect-24.1/data/ui/connect.ui 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/ui/connect.ui 2019-11-30 13:14:47.000000000 +0000 @@ -0,0 +1,118 @@ + + + + + + 1716 + 1764 + 1 + 1 + + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/ui/contact-chooser.ui gnome-shell-extension-zorin-connect-28.0.2/data/ui/contact-chooser.ui --- gnome-shell-extension-zorin-connect-24.1/data/ui/contact-chooser.ui 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/ui/contact-chooser.ui 2019-11-30 13:16:04.000000000 +0000 @@ -0,0 +1,99 @@ + + + + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/ui/conversation.ui gnome-shell-extension-zorin-connect-28.0.2/data/ui/conversation.ui --- gnome-shell-extension-zorin-connect-24.1/data/ui/conversation.ui 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/ui/conversation.ui 2019-11-30 13:16:20.000000000 +0000 @@ -0,0 +1,97 @@ + + + + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/ui/device-preferences.ui gnome-shell-extension-zorin-connect-28.0.2/data/ui/device-preferences.ui --- gnome-shell-extension-zorin-connect-24.1/data/ui/device-preferences.ui 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/ui/device-preferences.ui 2019-11-30 13:16:38.000000000 +0000 @@ -0,0 +1,2650 @@ + + + + + + + + + +
+ + + To Device + edit-paste-symbolic + settings.send-content + + + + From Device + edit-copy-symbolic + settings.receive-content + +
+
+ + + +
+ + + Nothing + audio-volume-medium-symbolic + settings.ringing-volume + nothing + + + + Lower + audio-volume-low-symbolic + settings.ringing-volume + lower + + + + Mute + audio-volume-muted-symbolic + settings.ringing-volume + mute + +
+
+ + +
+ + + Nothing + audio-volume-medium-symbolic + settings.talking-volume + nothing + + + + Lower + audio-volume-low-symbolic + settings.talking-volume + lower + + + + Mute + audio-volume-muted-symbolic + settings.talking-volume + mute + +
+
+
diff -Nru gnome-shell-extension-zorin-connect-24.1/data/ui/messaging-window.ui gnome-shell-extension-zorin-connect-28.0.2/data/ui/messaging-window.ui --- gnome-shell-extension-zorin-connect-24.1/data/ui/messaging-window.ui 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/ui/messaging-window.ui 2019-11-30 13:17:15.000000000 +0000 @@ -0,0 +1,270 @@ + + + + + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/ui/notification-reply-dialog.ui gnome-shell-extension-zorin-connect-28.0.2/data/ui/notification-reply-dialog.ui --- gnome-shell-extension-zorin-connect-24.1/data/ui/notification-reply-dialog.ui 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/ui/notification-reply-dialog.ui 2019-11-30 13:17:26.000000000 +0000 @@ -0,0 +1,186 @@ + + + + + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/data/ui/preferences-window.ui gnome-shell-extension-zorin-connect-28.0.2/data/ui/preferences-window.ui --- gnome-shell-extension-zorin-connect-24.1/data/ui/preferences-window.ui 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/ui/preferences-window.ui 2019-12-02 17:25:18.000000000 +0000 @@ -0,0 +1,704 @@ + + + + + + False + + + True + 10 + 6 + 6 + + + True + False + start + Device Name + rename-entry + + + + + + 0 + 0 + 2 + + + + + True + True + True + center + center + True + name + 20 + + + + 0 + 1 + + + + + _Rename + True + True + False + False + False + True + + + + + 1 + 1 + + + + + + + + +
+ + + Connect to… + win.connect + +
+
+ Display Mode + + + Panel + win.display-mode + panel + + + + User Menu + win.display-mode + user-menu + +
+
+ + + Generate Support Log + win.support-log + + + About Zorin Connect + win.about + +
+
+
diff -Nru gnome-shell-extension-zorin-connect-24.1/data/ui/telephony.ui gnome-shell-extension-zorin-connect-28.0.2/data/ui/telephony.ui --- gnome-shell-extension-zorin-connect-24.1/data/ui/telephony.ui 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/data/ui/telephony.ui 2019-11-30 13:18:53.000000000 +0000 @@ -0,0 +1,158 @@ + + + + + + + diff -Nru gnome-shell-extension-zorin-connect-24.1/debian/changelog gnome-shell-extension-zorin-connect-28.0.2/debian/changelog --- gnome-shell-extension-zorin-connect-24.1/debian/changelog 2019-05-29 12:59:05.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/debian/changelog 2019-12-02 17:27:35.000000000 +0000 @@ -1,3 +1,22 @@ +gnome-shell-extension-zorin-connect (28.0.2) bionic; urgency=medium + + * Updated full colour icon + + -- Artyom Zorin Mon, 02 Dec 2019 17:27:35 +0000 + +gnome-shell-extension-zorin-connect (28.0.1) bionic; urgency=medium + + * Added Play Store and F-Droid badges + + -- Artyom Zorin Sat, 30 Nov 2019 22:50:11 +0000 + +gnome-shell-extension-zorin-connect (28) bionic; urgency=medium + + * Based on upstream version 28 as at commit + 3050a7878a1cf35a6cf9b648b9253b74c7cc1967 + + -- Artyom Zorin Sat, 30 Nov 2019 21:44:43 +0000 + gnome-shell-extension-zorin-connect (24.1) bionic; urgency=medium * Based on upstream commit 0abf2b0dcb00aa363518122ab4cd3efbe5cb2cc9 diff -Nru gnome-shell-extension-zorin-connect-24.1/.eslintrc.json gnome-shell-extension-zorin-connect-28.0.2/.eslintrc.json --- gnome-shell-extension-zorin-connect-24.1/.eslintrc.json 2019-03-17 11:36:06.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/.eslintrc.json 2019-11-30 14:45:20.000000000 +0000 @@ -58,6 +58,9 @@ "allow": ["!!"] } ], + "no-prototype-builtins": [ + "off" + ], "no-unused-vars": [ "error", { @@ -65,6 +68,9 @@ "vars": "local" } ], + "nonblock-statement-body-position": [ + "off" + ], "object-curly-newline": [ "error", { @@ -114,16 +120,12 @@ "global": false, "zorin_connect": false, "debug": false, - "warning": false, - "get_download_file": false, "open_uri": false, "_": false, "_C": false, "_N": false, "ngettext": false, - "_GSOUND_CONTEXT": false, - "_SFX_BACKEND": false, "_WAYLAND": false }, "parserOptions": { diff -Nru gnome-shell-extension-zorin-connect-24.1/meson/nmh.sh gnome-shell-extension-zorin-connect-28.0.2/meson/nmh.sh --- gnome-shell-extension-zorin-connect-24.1/meson/nmh.sh 2019-03-06 16:36:16.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/meson/nmh.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +0,0 @@ -#!/bin/sh - -# Use DESTDIR if defined -if [ -n "${DESTDIR}" ]; then - CHROME_NMHDIR=${DESTDIR}/${1} -else - CHROME_NMHDIR=${1} -fi - -mkdir -p ${CHROME_NMHDIR} -cp ${MESON_BUILD_ROOT}/org.gnome.shell.extensions.zorin_connect.json-chrome \ - ${CHROME_NMHDIR}/org.gnome.shell.extensions.zorin_connect.json - - -# Use DESTDIR if defined -if [ -n "${DESTDIR}" ]; then - CHROMIUM_NMHDIR=${DESTDIR}/${2} -else - CHROMIUM_NMHDIR=${2} -fi - -mkdir -p ${CHROMIUM_NMHDIR} -cp ${MESON_BUILD_ROOT}/org.gnome.shell.extensions.zorin_connect.json-chrome \ - ${CHROMIUM_NMHDIR}/org.gnome.shell.extensions.zorin_connect.json - diff -Nru gnome-shell-extension-zorin-connect-24.1/meson.build gnome-shell-extension-zorin-connect-28.0.2/meson.build --- gnome-shell-extension-zorin-connect-24.1/meson.build 2019-05-16 22:20:04.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/meson.build 2019-11-30 11:26:31.000000000 +0000 @@ -1,6 +1,7 @@ -project('zorin-connect', 'c', version: '24', meson_version: '>= 0.45.0') +project('zorin-connect', 'c', version: '28', meson_version: '>= 0.49.0') gnome = import('gnome') +i18n = import('i18n') prefix = get_option('prefix') datadir = join_paths(prefix, get_option('datadir')) @@ -33,11 +34,9 @@ extconfig.set('EXTDATADIR', extdatadir) extconfig.set('GSCHEMADIR', gschemadir) extconfig.set('FFMPEG_PATH', get_option('ffmpeg_path')) -extconfig.set('FUSERMOUNT_PATH', get_option('fusermount_path')) extconfig.set('OPENSSL_PATH', get_option('openssl_path')) extconfig.set('SSHADD_PATH', get_option('sshadd_path')) extconfig.set('SSHKEYGEN_PATH', get_option('sshkeygen_path')) -extconfig.set('SSHFS_PATH', get_option('sshfs_path')) # ZIP targets for user extension builds run_target( @@ -64,46 +63,8 @@ ] ) -# Extension Source -install_subdir( - 'src', - install_dir: extdatadir, - strip_directory: true -) - -# metadata.json -configure_file( - input: 'data/metadata.json.in', - output: 'metadata.json', - configuration: extconfig, - install_dir: extdatadir -) -# Desktop Entry -install_data( - 'data/org.gnome.Shell.Extensions.ZorinConnect.desktop', - install_dir: join_paths(datadir, 'applications') -) - -# DBus Service -dbus = dependency('dbus-1', required: false) - -if get_option('session_bus_services_dir') != '' - dbus_dir = get_option('session_bus_services_dir') -elif dbus.found() - dbus_dir = dbus.get_pkgconfig_variable('session_bus_services_dir') -else - dbus_dir = join_paths(datadir, 'dbus-1', 'services') -endif - -configure_file( - input: 'data/org.gnome.Shell.Extensions.ZorinConnect.service', - output: 'org.gnome.Shell.Extensions.ZorinConnect.service', - configuration: extconfig, - install_dir: dbus_dir -) - -# Nautilus Extension +# Nautilus/Nemo Extension if get_option('nautilus') install_data( 'src/nautilus-zorin-connect.py', @@ -111,68 +72,31 @@ ) endif -# WebExtension Manifests -if get_option('webextension') - - # Chrome - if get_option('chrome_nmhdir') != '' - chrome_nmhdir = get_option('chrome_nmhdir') - else - chrome_nmhdir = join_paths(sysconfdir, 'opt', 'chrome', 'native-messaging-hosts') - endif - - # Chromium - if get_option('chromium_nmhdir') != '' - chromium_nmhdir = get_option('chromium_nmhdir') - else - chromium_nmhdir = join_paths(sysconfdir, 'chromium', 'native-messaging-hosts') - endif - - configure_file( - input: 'data/org.gnome.shell.extensions.zorin_connect.json-chrome', - output: 'org.gnome.shell.extensions.zorin_connect.json-chrome', - configuration: extconfig - ) - - # HACK: use 'rename' in meson >=0.46.0 - meson.add_install_script( - 'meson/nmh.sh', - join_paths(chrome_nmhdir), - join_paths(chromium_nmhdir) - ) - - # Mozilla - if get_option('mozilla_nmhdir') != '' - mozilla_nmhdir = get_option('mozilla_nmhdir') - else - mozilla_nmhdir = join_paths(libdir, 'mozilla', 'native-messaging-hosts') - endif - - configure_file( - input: 'data/org.gnome.shell.extensions.zorin_connect.json-mozilla', - output: 'org.gnome.shell.extensions.zorin_connect.json', - configuration: extconfig, - install_dir: mozilla_nmhdir +if get_option('nemo') + install_data( + 'src/nautilus-zorin-connect.py', + install_dir: join_paths(datadir, 'nemo-python', 'extensions') ) endif -# GSettings -install_data( - 'data/org.gnome.Shell.Extensions.ZorinConnect.gschema.xml', - install_dir: gschemadir -) -# GResource -gnome.compile_resources( - 'org.gnome.Shell.Extensions.ZorinConnect', - 'data/org.gnome.Shell.Extensions.ZorinConnect.gresource.xml', - source_dir: 'data', - gresource_bundle: true, - install: true, - install_dir: extdatadir +# Extension Source +install_subdir( + 'src', + install_dir: extdatadir, + strip_directory: true ) +eslint = find_program('eslint', required: false) + +if eslint.found() + test('ESLint', eslint, + args: join_paths(meson.build_root(), extuuid) + ) +endif + # Gettext Translations +subdir('data') subdir('po') # Post-Install Script for distributions without the hooks diff -Nru gnome-shell-extension-zorin-connect-24.1/meson_options.txt gnome-shell-extension-zorin-connect-28.0.2/meson_options.txt --- gnome-shell-extension-zorin-connect-24.1/meson_options.txt 2019-03-17 11:39:28.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/meson_options.txt 2019-11-30 11:26:43.000000000 +0000 @@ -1,5 +1,3 @@ -# See https://github.com/andyholmes/gnome-shell-extension-gsconnect/wiki/Packaging - # Run meson/post-install.sh (glib-compile-schemas) option( 'post_install', @@ -41,13 +39,6 @@ ) option( - 'fusermount_path', - type: 'string', - value: 'fusermount', - description: 'Path to fusermount binary' -) - -option( 'openssl_path', type: 'string', value: 'openssl', @@ -68,19 +59,20 @@ description: 'Path to ssh-keygen binary' ) +# Enable/Disable Nautilus Python extension installation option( - 'sshfs_path', - type: 'string', - value: 'sshfs', - description: 'Path to sshfs binary' + 'nautilus', + type: 'boolean', + value: true, + description: 'Install file browser extension for Nautilus' ) -# Enable/Disable Nautilus extension installation +# Enable/Disable Nemo Python extension installation option( - 'nautilus', + 'nemo', type: 'boolean', value: true, - description: 'Install nautilus-python extension' + description: 'Install file browser extension for Nemo' ) # Enable/Disable WebExtension manifest installation @@ -112,4 +104,3 @@ value: '', description: 'Native Messaging Host directory for Mozilla' ) - diff -Nru gnome-shell-extension-zorin-connect-24.1/po/ar.po gnome-shell-extension-zorin-connect-28.0.2/po/ar.po --- gnome-shell-extension-zorin-connect-24.1/po/ar.po 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/ar.po 2019-11-30 17:27:48.000000000 +0000 @@ -0,0 +1,1064 @@ +msgid "" +msgstr "" +"Project-Id-Version: zorin-connect\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-10 11:13\n" +"Last-Translator: Andy Holmes (andyholmes)\n" +"Language-Team: Arabic\n" +"Language: ar_SA\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5);\n" +"X-Generator: crowdin.com\n" +"X-Crowdin-Project: zorin-connect\n" +"X-Crowdin-Language: ar\n" +"X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" + +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "معلومات التشفير" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "اقتران" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "إلغاء الاقتران" + +#. TRANSLATORS: Open a dialog to connect to an IP or Bluez device +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 +msgid "Connect to…" +msgstr "الاتصال بـ…" + +#. Action Buttons +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 +msgid "Cancel" +msgstr "إلغاء" + +#: data/ui/connect.ui:27 +msgid "Connect" +msgstr "اتصال" + +#: data/ui/connect.ui:74 +msgid "IP Address" +msgstr "عنوان الـ IP" + +#: data/ui/contact-chooser.ui:50 +msgid "No contacts" +msgstr "لا توجد جهات اتصال" + +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 +msgid "Help" +msgstr "المساعدة" + +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "اكتب رقم هاتف أو اسم" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 +msgid "Type a message" +msgstr "اكتب رسالة" + +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 +msgid "Send Message" +msgstr "إرسال رسالة" + +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "سطح المكتب" + +#: data/ui/device-preferences.ui:88 +msgid "Camera" +msgstr "الكاميرا" + +#: data/ui/device-preferences.ui:144 +msgid "Clipboard Sync" +msgstr "مزامنة الحافظة" + +#: data/ui/device-preferences.ui:208 +msgid "Media Players" +msgstr "مشغلات الوسائط" + +#: data/ui/device-preferences.ui:263 +msgid "Mouse & Keyboard" +msgstr "الفأرة ولوحة المفاتيح" + +#: data/ui/device-preferences.ui:318 +msgid "Volume Control" +msgstr "التحكم بمستوى الصوت" + +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "الملفات" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "استلام ملفات" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 +msgid "Sharing" +msgstr "المشاركة" + +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 +msgid "Commands" +msgstr "اﻷوامر" + +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 +msgid "Name" +msgstr "الاسم" + +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 +msgid "Command Line" +msgstr "سطر الأوامر" + +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 +msgid "Choose an executable" +msgstr "اختر ملف تنفيذي" + +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 +msgid "Add" +msgstr "إضافة" + +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 +msgid "Remove" +msgstr "إزالة" + +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 +msgid "Edit" +msgstr "تعديل" + +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 +msgid "Save" +msgstr "حفظ" + +#: data/ui/device-preferences.ui:887 +msgid "Share Notifications" +msgstr "مشاركة الإشعارات" + +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "" + +#: data/ui/device-preferences.ui:998 +msgid "Applications" +msgstr "التطبيقات" + +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 +#: src/service/plugins/notification.js:13 +msgid "Notifications" +msgstr "الإشعارات" + +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 +msgid "Contacts" +msgstr "جهات الاتصال" + +#: data/ui/device-preferences.ui:1155 +msgid "Incoming Calls" +msgstr "المكالمات الواردة" + +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 +msgid "Volume" +msgstr "مستوى الصوت" + +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 +msgid "Pause Media" +msgstr "إيقاف الوسائط" + +#: data/ui/device-preferences.ui:1323 +msgid "Ongoing Calls" +msgstr "المكالمة الحالية" + +#: data/ui/device-preferences.ui:1493 +msgid "Mute Microphone" +msgstr "كتم المايكروفون" + +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 +msgid "Telephony" +msgstr "المهاتفة" + +#: data/ui/device-preferences.ui:1582 +msgid "Action Shortcuts" +msgstr "اختصارات اﻹجراءات" + +#: data/ui/device-preferences.ui:1597 +msgid "Reset All…" +msgstr "إعادة تعيين الكل…" + +#: data/ui/device-preferences.ui:1646 +msgid "Shortcuts" +msgstr "الاختصارات" + +#: data/ui/device-preferences.ui:1677 +msgid "Plugins" +msgstr "الإضافات" + +#: data/ui/device-preferences.ui:1723 +msgid "Experimental" +msgstr "تجريبي" + +#: data/ui/device-preferences.ui:1771 +msgid "Legacy SMS Support" +msgstr "دعم الرسائل النصية القديم" + +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 +msgid "Advanced" +msgstr "خيارات متقدمة" + +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "بطارية الجهاز" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "إشعار انخفاض البطارية" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "إشعار امتلاء البطارية" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "بطارية الجهاز" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "مشاركة الاحصائيات" + +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "البطارية" + +#: data/ui/device-preferences.ui:2394 +msgid "Keyboard Shortcuts" +msgstr "اختصارات لوحة المفاتيح" + +#: data/ui/device-preferences.ui:2529 +msgid "Device is unpaired" +msgstr "الجهاز غير مقترن" + +#: data/ui/device-preferences.ui:2544 +msgid "You may configure this device before pairing" +msgstr "قد تحتاج إلى إعداد هذا الجهاز أولا قبل اﻹقتران" + +#. TRANSLATORS: Send clipboard content to device +#: data/ui/device-preferences.ui:2585 +msgid "To Device" +msgstr "إلى الجهاز" + +#. TRANSLATORS: Receive clipboard content from the device +#: data/ui/device-preferences.ui:2591 +msgid "From Device" +msgstr "من الجهاز" + +#. TRANSLATORS: Don't change the system volume +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 +msgid "Nothing" +msgstr "لا شيء" + +#. TRANSLATORS: Lower the system volume +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 +msgid "Lower" +msgstr "منخفض" + +#. TRANSLATORS: Mute the system volume +#. TRANSLATORS: Silence the phone ringer +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 +msgid "Mute" +msgstr "كتم" + +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 +msgid "Messaging" +msgstr "المراسة" + +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 +msgid "New Conversation" +msgstr "محادثة جديدة" + +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "لا توجد محادثات" + +#: data/ui/messaging-window.ui:168 +msgid "No conversation selected" +msgstr "لم يتم تحديد أي محادثة" + +#: data/ui/messaging-window.ui:184 +msgid "Select or start a conversation" +msgstr "" + +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 +msgid "Device is disconnected" +msgstr "" + +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 +msgid "Send" +msgstr "" + +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "" + +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 +msgid "Refresh" +msgstr "" + +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 +msgid "Mobile Settings" +msgstr "" + +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 +msgid "Edit Device Name" +msgstr "" + +#: data/ui/preferences-window.ui:257 +msgid "Devices" +msgstr "" + +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "" + +#: data/ui/preferences-window.ui:332 +msgid "Browser Add-Ons" +msgstr "" + +#: data/ui/preferences-window.ui:612 +msgid "Enable" +msgstr "" + +#: data/ui/preferences-window.ui:644 +msgid "This device is invisible to unpaired devices" +msgstr "" + +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 +msgid "Discovery Disabled" +msgstr "" + +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "" + +#. TRANSLATORS: Share URL by SMS +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 +msgid "Send SMS" +msgstr "" + +#. Service Menu +#: src/extension.js:118 src/extension.js:249 +msgid "Mobile Devices" +msgstr "" + +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "" + +#: src/extension.js:244 +#, javascript-format +msgid "%d Connected" +msgid_plural "%d Connected" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "" + +#. TRANSLATORS: Top-level context menu item for Zorin Connect +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 +msgid "Send To Mobile Device" +msgstr "" + +#: src/preferences/device.js:658 +msgid "Open" +msgstr "" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "" + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "" + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "" + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "" + +#: src/service/daemon.js:337 +msgid "Report" +msgstr "" + +#: src/service/daemon.js:580 +msgid "Authentication Failure" +msgstr "" + +#: src/service/daemon.js:589 +msgid "Network Error" +msgstr "" + +#: src/service/daemon.js:590 +msgid "Click for help troubleshooting" +msgstr "" + +#: src/service/daemon.js:599 +msgid "Discovery has been disabled due to the number of devices on this network." +msgstr "" + +#: src/service/daemon.js:608 +msgid "Click for more information" +msgstr "" + +#: src/service/daemon.js:705 +msgid "Dial Number" +msgstr "" + +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 +msgid "Share File" +msgstr "" + +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "" + +#: src/service/device.js:174 +msgid "Not available" +msgstr "" + +#. TRANSLATORS: Bluetooth address for remote device +#: src/service/device.js:179 +#, javascript-format +msgid "Bluetooth device at %s" +msgstr "" + +#. TRANSLATORS: Label for TLS Certificate fingerprint +#. +#. Example: +#. +#. Google Pixel Fingerprint: +#. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 +#: src/service/device.js:199 src/service/device.js:201 +#, javascript-format +msgid "%s Fingerprint:" +msgstr "" + +#. TRANSLATORS: eg. Pair Request from Google Pixel +#: src/service/device.js:748 +#, javascript-format +msgid "Pair Request from %s" +msgstr "" + +#: src/service/device.js:755 +msgid "Reject" +msgstr "" + +#: src/service/device.js:760 +msgid "Accept" +msgstr "" + +#. TRANSLATORS: eg. Google Pixel: Battery is low +#: src/service/plugins/battery.js:181 +#, javascript-format +msgid "%s: Battery is low" +msgstr "" + +#. TRANSLATORS: eg. 15% remaining +#: src/service/plugins/battery.js:183 +#, javascript-format +msgid "%d%% remaining" +msgstr "" + +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "" + +#: src/service/plugins/clipboard.js:11 +msgid "Clipboard" +msgstr "" + +#: src/service/plugins/clipboard.js:23 +msgid "Clipboard Push" +msgstr "" + +#: src/service/plugins/clipboard.js:31 +msgid "Clipboard Pull" +msgstr "" + +#. Ensure we have a sender +#. TRANSLATORS: No name or phone number +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 +msgid "Unknown Contact" +msgstr "" + +#: src/service/plugins/findmyphone.js:13 +msgid "Find My Phone" +msgstr "" + +#: src/service/plugins/mousepad.js:14 +msgid "Mousepad" +msgstr "" + +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 +msgid "Keyboard" +msgstr "" + +#: src/service/plugins/mousepad.js:413 +msgid "Keyboard not ready" +msgstr "" + +#: src/service/plugins/mpris.js:12 +msgid "MPRIS" +msgstr "" + +#: src/service/plugins/notification.js:27 +msgid "Cancel Notification" +msgstr "" + +#: src/service/plugins/notification.js:35 +msgid "Close Notification" +msgstr "" + +#: src/service/plugins/notification.js:43 +msgid "Reply Notification" +msgstr "" + +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "" + +#. TRANSLATORS: An optional message accompanying a ping, rarely if ever used +#. eg. Ping: A message sent with ping +#: src/service/plugins/ping.js:51 +#, javascript-format +msgid "Ping: %s" +msgstr "" + +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "" + +#: src/service/plugins/runcommand.js:12 +msgid "Run Commands" +msgstr "" + +#: src/service/plugins/sftp.js:12 +msgid "SFTP" +msgstr "" + +#: src/service/plugins/sftp.js:18 +msgid "Mount" +msgstr "" + +#: src/service/plugins/sftp.js:26 +msgid "Unmount" +msgstr "" + +#: src/service/plugins/sftp.js:134 +msgid "All files" +msgstr "" + +#: src/service/plugins/sftp.js:135 +msgid "Camera pictures" +msgstr "" + +#: src/service/plugins/share.js:13 src/service/plugins/share.js:19 +msgid "Share" +msgstr "" + +#: src/service/plugins/share.js:35 +msgid "Share Text" +msgstr "" + +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "" + +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "" + +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "" + +#. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel +#: src/service/plugins/share.js:156 +#, javascript-format +msgid "Receiving “%s” from %s" +msgstr "" + +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 +msgid "Transfer Successful" +msgstr "" + +#. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel +#: src/service/plugins/share.js:183 +#, javascript-format +msgid "Received “%s” from %s" +msgstr "" + +#: src/service/plugins/share.js:189 +msgid "Open Folder" +msgstr "" + +#: src/service/plugins/share.js:194 +msgid "Open File" +msgstr "" + +#. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel +#: src/service/plugins/share.js:203 +#, javascript-format +msgid "Failed to receive “%s” from %s" +msgstr "" + +#: src/service/plugins/share.js:232 +#, javascript-format +msgid "Text Shared By %s" +msgstr "" + +#. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel +#: src/service/plugins/share.js:304 +#, javascript-format +msgid "Sending “%s” to %s" +msgstr "" + +#. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel +#: src/service/plugins/share.js:327 +#, javascript-format +msgid "Sent “%s” to %s" +msgstr "" + +#. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel +#: src/service/plugins/share.js:335 +#, javascript-format +msgid "Failed to send “%s” to %s" +msgstr "" + +#. TRANSLATORS: eg. Send files to Google Pixel +#: src/service/plugins/share.js:404 +#, javascript-format +msgid "Send files to %s" +msgstr "" + +#. TRANSLATORS: Mark the file to be opened once completed +#: src/service/plugins/share.js:408 +msgid "Open when done" +msgstr "" + +#. TRANSLATORS: eg. Send a link to Google Pixel +#: src/service/plugins/share.js:447 +#, javascript-format +msgid "Send a link to %s" +msgstr "" + +#: src/service/plugins/sms.js:13 +msgid "SMS" +msgstr "" + +#: src/service/plugins/sms.js:34 +msgid "New SMS (URI)" +msgstr "" + +#: src/service/plugins/sms.js:42 src/service/plugins/telephony.js:22 +msgid "Reply SMS" +msgstr "" + +#: src/service/plugins/sms.js:66 +msgid "Share SMS" +msgstr "" + +#: src/service/plugins/systemvolume.js:11 +msgid "System Volume" +msgstr "" + +#: src/service/plugins/telephony.js:30 +msgid "Mute Call" +msgstr "" + +#. TRANSLATORS: The phone is ringing +#: src/service/plugins/telephony.js:187 +msgid "Incoming call" +msgstr "" + +#. TRANSLATORS: A phone call is active +#: src/service/plugins/telephony.js:202 +msgid "Ongoing call" +msgstr "" + +#. TRANSLATORS: All other phone number types +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 +#, javascript-format +msgid "%s・Other" +msgstr "" + +#. TRANSLATORS: A fax number +#: src/service/ui/contacts.js:131 +#, javascript-format +msgid "%s・Fax" +msgstr "" + +#. TRANSLATORS: A work phone number +#: src/service/ui/contacts.js:135 +#, javascript-format +msgid "%s・Work" +msgstr "" + +#. TRANSLATORS: A mobile or cellular phone number +#: src/service/ui/contacts.js:139 +#, javascript-format +msgid "%s・Mobile" +msgstr "" + +#. TRANSLATORS: A home phone number +#: src/service/ui/contacts.js:143 +#, javascript-format +msgid "%s・Home" +msgstr "" + +#. TRANSLATORS: A phone number (eg. "Send to 555-5555") +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 +#, javascript-format +msgid "Send to %s" +msgstr "" + +#. TRANSLATORS: Less than a minute ago +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 +msgid "Just now" +msgstr "" + +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 +#, javascript-format +msgid "%d minute" +msgid_plural "%d minutes" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) +#: src/service/ui/messaging.js:43 +#, javascript-format +msgid "Yesterday・%s" +msgstr "" + +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "" + +#. TRANSLATORS: An outgoing message body in a conversation summary +#: src/service/ui/messaging.js:265 +#, javascript-format +msgid "You: %s" +msgstr "" + +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#: src/service/ui/service.js:31 +msgid "Select a Device" +msgstr "" + +#: src/service/ui/service.js:35 +msgid "Select" +msgstr "" + +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "لم يتم العثور على أي جهاز" + +#. TRANSLATORS: When no time estimate for the battery is available +#. EXAMPLE: 42% (Estimating…) +#: src/shell/device.js:119 +#, javascript-format +msgid "%d%% (Estimating…)" +msgstr "" + +#. TRANSLATORS: Estimated time until battery is charged +#. EXAMPLE: 42% (1:15 Until Full) +#: src/shell/device.js:129 +#, javascript-format +msgid "%d%% (%d∶%02d Until Full)" +msgstr "" + +#. TRANSLATORS: Estimated time until battery is empty +#. EXAMPLE: 42% (12:15 Remaining) +#: src/shell/device.js:137 +#, javascript-format +msgid "%d%% (%d∶%02d Remaining)" +msgstr "" + +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" +msgstr[4] "" +msgstr[5] "" + +#. TRANSLATORS: Time until change with time duration +#. EXAMPLE: Until 10:00 (2 hours) +#: src/shell/donotdisturb.js:150 +#, javascript-format +msgid "Until %s (%s)" +msgstr "" + +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 +msgid "Do Not Disturb" +msgstr "" + +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" +msgstr "" + +#: src/shell/donotdisturb.js:261 +msgid "Until you turn off Do Not Disturb" +msgstr "" + +#: src/shell/donotdisturb.js:302 +msgid "Done" +msgstr "" + +#: src/shell/notification.js:43 +msgid "Reply" +msgstr "" + +#. TRANSLATORS: Extension name +#: webextension/gettext.js:27 +msgid "Zorin Connect" +msgstr "" + +#. TRANSLATORS: Chrome/Firefox WebExtension description +#: webextension/gettext.js:29 +msgid "Share links with Zorin Connect, direct to the browser or by SMS." +msgstr "" + +#. TRANSLATORS: WebExtension can't connect to Zorin Connect +#: webextension/gettext.js:33 +msgid "Service Unavailable" +msgstr "الخدمة غير متاحة" + +#. TRANSLATORS: Open URL with the device's browser +#: webextension/gettext.js:37 +msgid "Open in Browser" +msgstr "فتح في المتصفح" + +msgid "Mobile Application" +msgstr "تطبيق المحمول" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/be.po gnome-shell-extension-zorin-connect-28.0.2/po/be.po --- gnome-shell-extension-zorin-connect-24.1/po/be.po 2019-05-29 12:46:26.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/be.po 2019-11-30 17:24:03.000000000 +0000 @@ -2,11 +2,11 @@ msgstr "" "Project-Id-Version: zorin-connect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" -"PO-Revision-Date: 2019-05-18 10:54\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-13 23:34\n" "Last-Translator: Andy Holmes (andyholmes)\n" "Language-Team: Belarusian\n" -"Language: be\n" +"Language: be_BY\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -16,413 +16,596 @@ "X-Crowdin-Language: be\n" "X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Інфармацыя пра шыфраванне" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Спалучыць" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Разлучыць" + #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "Падлучыцца да…" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "Скасаваць" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Злучэнне" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "IP-адрас" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Bluetooth прылада" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Увесці нумар тэлефона або імя" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "Няма кантактаў" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Даведка" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Увесці нумар тэлефона або імя" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "Напісаць паведамлене" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "Адправіць паведамленне" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Акумулятар" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Камп'ютар" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" msgstr "Камера" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Сінхранізацыя буферу абмену" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Медыяплэеры" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Мыш і клавіятура" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Кіраванне гучнасцю" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Файлы" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "Атрымліваць файлы" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Абагульванне" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Каманды" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Імя" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "Камандны радок" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Выбраць выконвальны файл" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Дадаць" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Выдаліць" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Рэдагаваць" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Захаваць" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Абагульваць апавяшчэнні" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "Абагульваць, калі актыўны" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Праграмы" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Апавяшчэнні" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Кантакты" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Уваходныя выклікі" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Гук" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Прыпыніць плэер" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Выходныя выклікі" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Адключыць мікрафон" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Тэлефанія" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Спалучэнні клавіш для дзеянняў" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Скінуць усе…" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Камандныя спалучэнні клавіш" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Спалучэнні клавіш" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Убудовы" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Эксперыментальныя" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "Падтрымка SMS (ранейшая версія)" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Выдаліць" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Выдаліць гэту прыладу" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Разлучыць і выдаліць усе налады і файлы" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Пашыраныя" -#: data/device.ui:2048 +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "Акумулятар прылады" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "Апавяшчэнне пра нізкі ўзровень зараду акумулятара" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "Апавяшчэнне пра поўнасцю зараджаны акумулятар" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "Сістэмны акумулятар" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "Абагульваць статыстыку" + +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Акумулятар" + +#: data/ui/device-preferences.ui:2394 msgid "Keyboard Shortcuts" msgstr "Спалучэнні клавіш" -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Спалучыць" - -#: data/device.ui:2183 +#: data/ui/device-preferences.ui:2529 msgid "Device is unpaired" msgstr "Прылада разлучана" -#: data/device.ui:2198 +#: data/ui/device-preferences.ui:2544 msgid "You may configure this device before pairing" msgstr "Вы можаце наладзіць гэту прыладу перад спалучэннем" -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "Рэжым паказу" - -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Панэль" - -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Меню карыстальніка" - -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" -msgstr "Стварыць журнал для падтрымкі" - -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "Пра Zorin Connect" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Пераключыць на Bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "Пераключыць на LAN" - -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Інфармацыя пра шыфраванне" - -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Разлучыць" - #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "На прыладу" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "З прылады" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Нічога" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Ніжэйшы" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Выключыць гук" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Паведамленні" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Новая размова" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Няма размоў" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "Не выбрана размова" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "Выберыце або пачніце размову" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Прылада адлучана" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "Няма размоў" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Адправіць" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "Пошук прылад…" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "Назва прылады" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "_Перайменаваць" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "Абнавіць" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" msgstr "Налады прылад" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Рэдагаваць назву прылады" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Прылады" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Пошук прылад…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Пашырэнні для браўзера" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Уключана" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" msgstr "Гэта прылада нябачная для разлучаных прылад" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" msgstr "Знаходжанне адключана" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Рэжым паказу" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Панэль" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Меню карыстальніка" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Стварыць журнал для падтрымкі" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "Пра Zorin Connect" + #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "Адправіць SMS" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Мабільныя прылады" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "Уключыць" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" msgstr[0] "%d падлучана" msgstr[1] "%d падлучаны" msgstr[2] "%d падлучана" -msgstr[3] "" +msgstr[3] "%d падлучана" + +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "Выключыць" #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Адправіць на мабільную прыладу" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Адкрыць" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Укл." + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Выкл." + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Адключана" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Задаць спалучэнні клавіш" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Задаць" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Увядзіце новыя спалучэнні, каб змяніць %s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "Націсніце Esc, каб скасаваць або Прабел, каб скінуць спалучэнне клавіш." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s ужо выкарыстоўваецца" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "Паўнавартасная рэалізацыя KDE Connect для GNOME" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "Maksim Krapiŭka " + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "Паведамленні адладкі былі запісаны ў журнал. Зрабіце любыя крокі неабходныя для ўзнаўлення праблемы і затым праглядзіце журнал." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Праверыць журнал" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Ноўтбук" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Смартфон" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Планшэт" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "Тэлебачанне" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Разлучана" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Адлучана" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Падлучана" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "Чаканне сэрвісу…" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Справаздача" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Няўдача праверкі сапраўднасці" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Памылка сеткі" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Націсніце для дапамогі ў выпраўленні непаладак" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "Discovery has been disabled due to the number of devices on this network." msgstr "Знаходжанне было адключана праз колькасць прылад у гэтай сетцы." -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "%s убудова не загрузілася" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" msgstr "Націсніце для большай інфармацыі" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "Набраць нумар" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" msgstr "Абагуліць файл" +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "Спіс даступных прылад" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "Спіс усіх прылад" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "Мэтавая прылада" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "Змест паведамлення" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Адправіць апавяшчэнне" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "Назва праграмы ў апавяшчэнні" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "Змест апавяшчэння" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "Значок апавяшчэння" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "Ідэнтыфікатар апавяшчэння" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Фота" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Пінг" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Званок" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Абагуліць спасылку" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "Паказаць версію праграмы" + #: src/service/device.js:174 msgid "Not available" msgstr "Недаступны" @@ -439,83 +622,69 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "%s адбітак пальца:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Ноўтбук" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Смартфон" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Планшэт" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Камп'ютар" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Перападлучыцца" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Налады" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Запыт спалучэння ад %s" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Адхіліць" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Прыняць" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Званок" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: нізкі зарад акумулятара" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d%% засталося" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "%s: акумулятар зараджаны" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Зараджана цалкам" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Буфер абмену" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Адправіць буфер абмену" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Запрасіць буфер абмену" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Невядомы кантакт" @@ -527,54 +696,45 @@ msgid "Mousepad" msgstr "Тачпад" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Клавіятура" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "Патрабуецца дадатковае ПЗ" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "Клавіятура не гатова" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Скасаваць апавяшчэнне" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Закрыць апавяшчэнне" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Адказаць на апавяшчэнне" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "Адправіць апавяшчэнне" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" -msgstr "Фота" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Пінг" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "Актываваць апавяшчэнне" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Пінг: %s" +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "Прэзентацыя" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Запусціць каманды" @@ -591,18 +751,14 @@ msgid "Unmount" msgstr "Адлучыць" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Усе файлы" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Фатаграфіі камеры" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "Файлы" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Абагуліць" @@ -611,85 +767,87 @@ msgid "Share Text" msgstr "Абагуліць тэкст" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Абагуліць спасылку" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Збой перадачы" + +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "%s не дазваляе запампоўваць файлы" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" -msgstr "Пачынаецца перадача" +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "Перадача файла" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "Атрыманне “%s” з %s" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Паспяхова перададзена" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "Атрымана “%s” з %s" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Адкрыць папку" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Адкрыць файл" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "Збой перадачы" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Не ўдалося атрымаць “%s” з %s" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "Тэкст абагулены %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Адпраўка “%s” у %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "Адпраўлена “%s” у %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Збой адпраўкі “%s” у %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Адправіць файлы ў %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Адкрыць па сканчэнні" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Адправіць спасылку ў %s" @@ -706,7 +864,7 @@ msgid "Reply SMS" msgstr "Адказаць на SMS" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Абагуліць SMS" @@ -719,125 +877,91 @@ msgstr "Адкл. гук выкліку" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Уваходны выклік" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Выходны выклік" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Іншы" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Факс" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Работа" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Мабільны" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Дом" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Адправіць у %s" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Адкрыць" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "Укл." - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "Выкл." - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Адключана" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Задаць спалучэнні клавіш" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Задаць" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Увядзіце новыя спалучэнні, каб змяніць %s" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Націсніце Esc, каб скасаваць або Прабел, каб скінуць спалучэнне клавіш." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s ужо выкарыстоўваецца" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Толькі што" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" msgstr[0] "%d хвіліна" msgstr[1] "%d хвіліны" msgstr[2] "%d хвілін" -msgstr[3] "" +msgstr[3] "%d хвіліны" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Учора・%s" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "Групавое паведамленне" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "Вы: %s" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "І яшчэ %d кантакт" +msgstr[1] "І %d іншыя кантакты" +msgstr[2] "І %d іншых кантактаў" +msgstr[3] "І %d іншых" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "Выбраць прыладу" @@ -846,101 +970,65 @@ msgid "Select" msgstr "Выбраць" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "Разлучана" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Адлучана" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Падлучана" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "Transferred files are placed in the Downloads folder." -msgstr "Перанесеныя файлы размяшчаюцца ў папцы Спампоўкі." - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "Паўнавартасная рэалізацыя KDE Connect для GNOME" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "Maksim Krapiŭka " - -#: src/service/ui/settings.js:529 -msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." -msgstr "Паведамленні адладкі былі запісаны ў журнал. Зрабіце любыя крокі неабходныя для ўзнаўлення праблемы і затым праглядзіце журнал." - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "Праверыць журнал" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "Зараджана цалкам" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Не знойдзена прылад" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (Ацэнка…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (%d∶%02d Да поўнага зараду)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (%d∶%02d застаецца)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 -msgid "Do Not Disturb" -msgstr "Не турбаваць" - -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" -msgstr "Адключыць апавяшчэнні прылады" - -#: src/shell/donotdisturb.js:171 -msgid "Until you turn off Do Not Disturb" -msgstr "Пакуль вы не адключыце «Не турбаваць»" +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d гадзіна" +msgstr[1] "%d гадзіны" +msgstr[2] "%d гадзін" +msgstr[3] "%d гадзіны" #. TRANSLATORS: Time until change with time duration #. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 +#: src/shell/donotdisturb.js:150 #, javascript-format msgid "Until %s (%s)" msgstr "Да %s (%s)" -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 +msgid "Do Not Disturb" +msgstr "Не турбаваць" + +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" +msgstr "Без апавяшчэнняў з мабільных прылад" + +#: src/shell/donotdisturb.js:261 +msgid "Until you turn off Do Not Disturb" +msgstr "Пакуль вы не адключыце «Не турбаваць»" + +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Гатова" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d гадзіна" -msgstr[1] "%d гадзіны" -msgstr[2] "%d гадзін" -msgstr[3] "" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Адказаць" @@ -959,11 +1047,6 @@ msgid "Service Unavailable" msgstr "Сэрвіс недаступны" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Не знойдзена прылад" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/ca-ES.po gnome-shell-extension-zorin-connect-28.0.2/po/ca-ES.po --- gnome-shell-extension-zorin-connect-24.1/po/ca-ES.po 2019-03-17 12:29:26.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/ca-ES.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,963 +0,0 @@ -msgid "" -msgstr "" -"Project-Id-Version: zorin-connect\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-29 16:44-0800\n" -"PO-Revision-Date: 2018-12-31 05:33\n" -"Last-Translator: andyholmes \n" -"Language-Team: Catalan\n" -"Language: ca\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: crowdin.com\n" -"X-Crowdin-Project: zorin-connect\n" -"X-Crowdin-Language: ca\n" -"X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" - -#. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 -msgid "Connect to…" -msgstr "" - -#. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:139 src/service/plugins/share.js:310 -#: src/service/plugins/share.js:456 src/service/ui/device.js:607 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:539 src/shell/donotdisturb.js:215 -msgid "Cancel" -msgstr "" - -#: data/connect.ui:37 -msgid "Connect" -msgstr "" - -#: data/connect.ui:98 -msgid "IP Address" -msgstr "" - -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "" - -#: data/contacts.ui:49 -msgid "Type a phone number or name" -msgstr "" - -#: data/contacts.ui:83 -msgid "No contacts" -msgstr "" - -#: data/contacts.ui:95 data/menus.ui:33 data/messaging.ui:247 -msgid "Help" -msgstr "" - -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 -msgid "Type a message" -msgstr "" - -#: data/conversation.ui:84 -msgid "Send Message" -msgstr "" - -#: data/device.ui:67 src/service/plugins/battery.js:12 -msgid "Battery" -msgstr "" - -#: data/device.ui:122 -msgid "Clipboard Sync" -msgstr "" - -#: data/device.ui:185 -msgid "Media Players" -msgstr "" - -#: data/device.ui:240 -msgid "Mouse & Keyboard" -msgstr "" - -#: data/device.ui:295 -msgid "Volume Control" -msgstr "" - -#: data/device.ui:345 data/device.ui:1728 -msgid "Sharing" -msgstr "" - -#: data/device.ui:374 data/device.ui:651 data/device.ui:1774 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:169 -msgid "Commands" -msgstr "" - -#: data/device.ui:424 data/device.ui:427 -msgid "Name" -msgstr "" - -#: data/device.ui:440 data/device.ui:446 -msgid "Command Line" -msgstr "" - -#: data/device.ui:444 data/device.ui:445 -msgid "Choose an executable" -msgstr "" - -#: data/device.ui:496 data/device.ui:511 -msgid "Add" -msgstr "" - -#: data/device.ui:527 data/device.ui:542 -msgid "Remove" -msgstr "" - -#: data/device.ui:576 data/device.ui:588 -msgid "Edit" -msgstr "" - -#: data/device.ui:604 data/device.ui:616 -msgid "Save" -msgstr "" - -#: data/device.ui:712 -msgid "Share Notifications" -msgstr "" - -#: data/device.ui:763 -msgid "Applications" -msgstr "" - -#: data/device.ui:809 data/device.ui:1820 -#: src/service/plugins/notification.js:13 -msgid "Notifications" -msgstr "" - -#: data/device.ui:839 -msgid "Incoming Calls" -msgstr "" - -#: data/device.ui:888 data/device.ui:1055 -msgid "Volume" -msgstr "" - -#: data/device.ui:954 data/device.ui:1120 -msgid "Pause Media" -msgstr "" - -#: data/device.ui:1007 -msgid "Ongoing Calls" -msgstr "" - -#: data/device.ui:1176 -msgid "Mute Microphone" -msgstr "" - -#: data/device.ui:1230 data/device.ui:1866 src/service/plugins/telephony.js:13 -msgid "Telephony" -msgstr "" - -#: data/device.ui:1265 -msgid "Action Shortcuts" -msgstr "" - -#: data/device.ui:1280 data/device.ui:1349 -msgid "Reset All…" -msgstr "" - -#: data/device.ui:1334 -msgid "Command Shortcuts" -msgstr "" - -#: data/device.ui:1398 -msgid "Shortcuts" -msgstr "" - -#: data/device.ui:1429 -msgid "Plugins" -msgstr "" - -#: data/device.ui:1475 -msgid "Experimental" -msgstr "" - -#: data/device.ui:1524 -msgid "Legacy SMS Support" -msgstr "" - -#: data/device.ui:1598 -msgid "Delete" -msgstr "" - -#: data/device.ui:1627 -msgid "Delete this device" -msgstr "" - -#: data/device.ui:1645 -msgid "Unpair and remove all settings and files" -msgstr "" - -#: data/device.ui:1678 data/device.ui:1958 -msgid "Advanced" -msgstr "" - -#: data/device.ui:1912 -msgid "Keyboard Shortcuts" -msgstr "" - -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2015 data/menus.ui:68 src/service/device.js:424 -msgid "Pair" -msgstr "" - -#: data/device.ui:2047 -msgid "Device is unpaired" -msgstr "" - -#: data/device.ui:2062 -msgid "You may configure this device before pairing" -msgstr "" - -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "" - -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "" - -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "" - -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:536 -msgid "Generate Support Log" -msgstr "" - -#: data/menus.ui:38 -msgid "About" -msgstr "" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "" - -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:317 -msgid "Encryption Info" -msgstr "" - -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 src/service/device.js:432 -msgid "Unpair" -msgstr "" - -#. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 -msgid "To Device" -msgstr "" - -#. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 -msgid "From Device" -msgstr "" - -#. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 -msgid "Nothing" -msgstr "" - -#. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 -msgid "Lower" -msgstr "" - -#. TRANSLATORS: Mute the system volume -#. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:194 -msgid "Mute" -msgstr "" - -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:911 -msgid "Messaging" -msgstr "" - -#: data/messaging.ui:21 src/service/ui/messaging.js:992 -msgid "New Conversation" -msgstr "" - -#: data/messaging.ui:110 -msgid "No conversation selected" -msgstr "" - -#: data/messaging.ui:126 -msgid "Select or start a conversation" -msgstr "" - -#: data/messaging.ui:193 data/notification.ui:52 data/telephony.ui:52 -msgid "Device is disconnected" -msgstr "" - -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:457 -msgid "Send" -msgstr "" - -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "" - -#: data/settings.ui:49 data/settings.ui:63 -msgid "Refresh" -msgstr "" - -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:105 -msgid "Mobile Settings" -msgstr "" - -#: data/settings.ui:144 data/settings.ui:158 -msgid "Edit Device Name" -msgstr "" - -#: data/settings.ui:236 -msgid "Devices" -msgstr "" - -#: data/settings.ui:299 -msgid "Browser Add-Ons" -msgstr "" - -#: data/settings.ui:579 -msgid "Enable" -msgstr "" - -#: data/settings.ui:611 -msgid "This device is invisible to unpaired devices" -msgstr "" - -#: data/settings.ui:623 src/service/daemon.js:532 -msgid "Discovery Disabled" -msgstr "" - -#. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:718 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 -msgid "Send SMS" -msgstr "" - -#. Service Menu -#: src/extension.js:79 src/extension.js:255 -msgid "Mobile Devices" -msgstr "" - -#. TRANSLATORS: %d is the number of devices connected -#: src/extension.js:253 -#, javascript-format -msgid "%d Connected" -msgid_plural "%d Connected" -msgstr[0] "" -msgstr[1] "" - -#. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:112 webextension/gettext.js:31 -msgid "Send To Mobile Device" -msgstr "" - -#: src/service/daemon.js:372 -msgid "Report" -msgstr "" - -#: src/service/daemon.js:507 -msgid "Authentication Failure" -msgstr "" - -#: src/service/daemon.js:516 -msgid "Network Error" -msgstr "" - -#: src/service/daemon.js:517 src/service/daemon.js:525 -msgid "Click for help troubleshooting" -msgstr "" - -#: src/service/daemon.js:524 -msgid "PulseAudio Error" -msgstr "" - -#: src/service/daemon.js:533 -msgid "Discovery has been disabled due to the number of devices on this network." -msgstr "" - -#: src/service/daemon.js:541 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "" - -#: src/service/daemon.js:542 -msgid "Click for more information" -msgstr "" - -#: src/service/daemon.js:724 -msgid "Dial Number" -msgstr "" - -#: src/service/daemon.js:730 src/service/plugins/share.js:27 -msgid "Share File" -msgstr "" - -#: src/service/device.js:161 -msgid "Not available" -msgstr "" - -#. TRANSLATORS: Bluetooth address for remote device -#: src/service/device.js:165 -#, javascript-format -msgid "Bluetooth device at %s" -msgstr "" - -#. TRANSLATORS: Label for TLS Certificate fingerprint -#. -#. Example: -#. -#. Google Pixel Fingerprint: -#. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:183 src/service/device.js:185 -#, javascript-format -msgid "%s Fingerprint:" -msgstr "" - -#: src/service/device.js:242 -msgid "Laptop" -msgstr "" - -#: src/service/device.js:244 -msgid "Smartphone" -msgstr "" - -#: src/service/device.js:246 -msgid "Tablet" -msgstr "" - -#: src/service/device.js:248 -msgid "Desktop" -msgstr "" - -#: src/service/device.js:408 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "" - -#: src/service/device.js:416 src/service/ui/device.js:16 -#: src/service/ui/settings.js:371 -msgid "Settings" -msgstr "" - -#. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:607 -#, javascript-format -msgid "Pair Request from %s" -msgstr "" - -#: src/service/device.js:614 -msgid "Reject" -msgstr "" - -#: src/service/device.js:619 -msgid "Accept" -msgstr "" - -#: src/service/plugins/battery.js:188 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "" - -#. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:197 -#, javascript-format -msgid "%s: Battery is low" -msgstr "" - -#. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:199 -#, javascript-format -msgid "%d%% remaining" -msgstr "" - -#: src/service/plugins/clipboard.js:11 -msgid "Clipboard" -msgstr "" - -#: src/service/plugins/clipboard.js:17 -msgid "Clipboard Push" -msgstr "" - -#: src/service/plugins/clipboard.js:25 -msgid "Clipboard Pull" -msgstr "" - -#: src/service/plugins/contacts.js:12 -msgid "Contacts" -msgstr "" - -#. Ensure we have a sender -#. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:263 src/service/plugins/telephony.js:173 -#: src/service/plugins/telephony.js:224 src/service/plugins/telephony.js:264 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:397 -msgid "Unknown Contact" -msgstr "" - -#: src/service/plugins/findmyphone.js:13 -msgid "Find My Phone" -msgstr "" - -#: src/service/plugins/mousepad.js:14 -msgid "Mousepad" -msgstr "" - -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:569 -msgid "Keyboard" -msgstr "" - -#: src/service/plugins/mousepad.js:223 -msgid "Additional Software Required" -msgstr "" - -#: src/service/plugins/mousepad.js:586 -msgid "Keyboard not ready" -msgstr "" - -#: src/service/plugins/mpris.js:10 -msgid "MPRIS" -msgstr "" - -#: src/service/plugins/notification.js:26 -msgid "Cancel Notification" -msgstr "" - -#: src/service/plugins/notification.js:34 -msgid "Close Notification" -msgstr "" - -#: src/service/plugins/notification.js:42 -msgid "Reply Notification" -msgstr "" - -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "" - -#. TRANSLATORS: An optional message accompanying a ping, rarely if ever used -#. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 -#, javascript-format -msgid "Ping: %s" -msgstr "" - -#: src/service/plugins/runcommand.js:12 -msgid "Run Commands" -msgstr "" - -#: src/service/plugins/sftp.js:12 -msgid "SFTP" -msgstr "" - -#: src/service/plugins/sftp.js:18 -msgid "Mount" -msgstr "" - -#: src/service/plugins/sftp.js:26 -msgid "Unmount" -msgstr "" - -#: src/service/plugins/sftp.js:159 -msgid "All files" -msgstr "" - -#: src/service/plugins/sftp.js:160 -msgid "Camera pictures" -msgstr "" - -#: src/service/plugins/sftp.js:417 -msgid "Files" -msgstr "" - -#: src/service/plugins/share.js:13 src/service/plugins/share.js:19 -msgid "Share" -msgstr "" - -#: src/service/plugins/share.js:35 -msgid "Share Text" -msgstr "" - -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:975 -#: src/service/ui/messaging.js:983 -msgid "Share Link" -msgstr "" - -#: src/service/plugins/share.js:132 src/service/plugins/share.js:303 -msgid "Starting Transfer" -msgstr "" - -#. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:134 -#, javascript-format -msgid "Receiving “%s” from %s" -msgstr "" - -#: src/service/plugins/share.js:172 src/service/plugins/share.js:327 -msgid "Transfer Successful" -msgstr "" - -#. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:174 -#, javascript-format -msgid "Received “%s” from %s" -msgstr "" - -#: src/service/plugins/share.js:180 -msgid "Open Folder" -msgstr "" - -#: src/service/plugins/share.js:185 -msgid "Open File" -msgstr "" - -#: src/service/plugins/share.js:192 src/service/plugins/share.js:335 -msgid "Transfer Failed" -msgstr "" - -#. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:194 -#, javascript-format -msgid "Failed to receive “%s” from %s" -msgstr "" - -#: src/service/plugins/share.js:233 -#, javascript-format -msgid "Text Shared By %s" -msgstr "" - -#. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:305 -#, javascript-format -msgid "Sending “%s” to %s" -msgstr "" - -#. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:329 -#, javascript-format -msgid "Sent “%s” to %s" -msgstr "" - -#. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:337 -#, javascript-format -msgid "Failed to send “%s” to %s" -msgstr "" - -#. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:408 -#, javascript-format -msgid "Send files to %s" -msgstr "" - -#. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:412 -msgid "Open when done" -msgstr "" - -#. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:451 -#, javascript-format -msgid "Send a link to %s" -msgstr "" - -#: src/service/plugins/sms.js:13 -msgid "SMS" -msgstr "" - -#: src/service/plugins/sms.js:34 -msgid "New SMS (URI)" -msgstr "" - -#: src/service/plugins/sms.js:42 src/service/plugins/telephony.js:22 -msgid "Reply SMS" -msgstr "" - -#: src/service/plugins/sms.js:58 -msgid "Share SMS" -msgstr "" - -#: src/service/plugins/systemvolume.js:11 -msgid "System Volume" -msgstr "" - -#: src/service/plugins/telephony.js:30 -msgid "Mute Call" -msgstr "" - -#. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:190 -msgid "Incoming call" -msgstr "" - -#. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:205 -msgid "Ongoing call" -msgstr "" - -#. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 -#, javascript-format -msgid "%s・Other" -msgstr "" - -#. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 -#, javascript-format -msgid "%s・Fax" -msgstr "" - -#. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 -#, javascript-format -msgid "%s・Work" -msgstr "" - -#. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 -#, javascript-format -msgid "%s・Mobile" -msgstr "" - -#. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 -#, javascript-format -msgid "%s・Home" -msgstr "" - -#. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:278 src/service/ui/contacts.js:292 -#, javascript-format -msgid "Send to %s" -msgstr "" - -#: src/service/ui/device.js:608 -msgid "Open" -msgstr "" - -#: src/service/ui/device.js:660 src/service/ui/device.js:673 -msgid "On" -msgstr "" - -#: src/service/ui/device.js:660 src/service/ui/device.js:673 -msgid "Off" -msgstr "" - -#: src/service/ui/device.js:798 src/service/ui/device.js:826 -#: src/service/ui/device.js:850 -msgid "Disabled" -msgstr "" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "" - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "" - -#. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:65 src/service/ui/messaging.js:98 -msgid "Just now" -msgstr "" - -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:70 src/service/ui/messaging.js:102 -#: src/shell/donotdisturb.js:266 -#, javascript-format -msgid "%d minute" -msgid_plural "%d minutes" -msgstr[0] "" -msgstr[1] "" - -#. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:75 -#, javascript-format -msgid "Yesterday・%s" -msgstr "" - -#. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:243 -#, javascript-format -msgid "You: %s" -msgstr "" - -#: src/service/ui/service.js:31 -msgid "Select a Device" -msgstr "" - -#: src/service/ui/service.js:35 -msgid "Select" -msgstr "" - -#: src/service/ui/settings.js:331 -msgid "Unpaired" -msgstr "" - -#: src/service/ui/settings.js:333 -msgid "Disconnected" -msgstr "" - -#: src/service/ui/settings.js:336 -msgid "Connected" -msgstr "" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:406 -#, javascript-format -msgid "Transferred files are placed in the Downloads folder." -msgstr "" - -#: src/service/ui/settings.js:499 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:508 -msgid "translator-credits" -msgstr "" - -#: src/service/ui/settings.js:537 -msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." -msgstr "" - -#: src/service/ui/settings.js:540 -msgid "Review Log" -msgstr "" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:82 -msgid "Fully Charged" -msgstr "" - -#. TRANSLATORS: When no time estimate for the battery is available -#. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:86 -#, javascript-format -msgid "%d%% (Estimating…)" -msgstr "" - -#. TRANSLATORS: Estimated time until battery is charged -#. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:96 -#, javascript-format -msgid "%d%% (%d∶%02d Until Full)" -msgstr "" - -#. TRANSLATORS: Estimated time until battery is empty -#. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:104 -#, javascript-format -msgid "%d%% (%d∶%02d Remaining)" -msgstr "" - -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 -msgid "Do Not Disturb" -msgstr "" - -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" -msgstr "" - -#: src/shell/donotdisturb.js:171 -msgid "Until you turn off Do Not Disturb" -msgstr "" - -#. TRANSLATORS: Time until change with time duration -#. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 -#, javascript-format -msgid "Until %s (%s)" -msgstr "" - -#: src/shell/donotdisturb.js:216 -msgid "Done" -msgstr "" - -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "" -msgstr[1] "" - -#: src/shell/notification.js:42 -msgid "Reply" -msgstr "" - -#. TRANSLATORS: Extension name -#: webextension/gettext.js:27 -msgid "Zorin Connect" -msgstr "" - -#. TRANSLATORS: Chrome/Firefox WebExtension description -#: webextension/gettext.js:29 -msgid "Share links with Zorin Connect, direct to the browser or by SMS." -msgstr "" - -#. TRANSLATORS: WebExtension can't connect to Zorin Connect -#: webextension/gettext.js:33 -msgid "Service Unavailable" -msgstr "" - -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "" - -#. TRANSLATORS: Open URL with the device's browser -#: webextension/gettext.js:37 -msgid "Open in Browser" -msgstr "" - -msgid "Mobile Application" -msgstr "Aplicació mòbil" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/ca.po gnome-shell-extension-zorin-connect-28.0.2/po/ca.po --- gnome-shell-extension-zorin-connect-24.1/po/ca.po 2019-05-29 12:46:32.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/ca.po 2019-11-30 17:24:13.000000000 +0000 @@ -2,11 +2,11 @@ msgstr "" "Project-Id-Version: zorin-connect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" -"PO-Revision-Date: 2019-05-18 10:54\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-11 11:25\n" "Last-Translator: Andy Holmes (andyholmes)\n" "Language-Team: Catalan\n" -"Language: ca\n" +"Language: ca_ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -16,411 +16,595 @@ "X-Crowdin-Language: ca\n" "X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Informació de xifratge" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Aparella" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Desaparella" + #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "Connecta amb…" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "Cancel·la" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Connecta" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "Adreça IP" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Dispositiu Bluetooth" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Introduïu un número telefònic o un nom" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "No hi ha cap contacte" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Ajuda" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Introduïu un número telefònic o un nom" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "Escriviu un missatge" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "Envia el missatge" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Bateria" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Ordinador d’escriptori" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" msgstr "Càmera" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Sincronització del porta-retalls" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Reproductors multimèdia" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Ratolí i teclat" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Control de volum" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Fitxers" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Compartició" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Ordres" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Nom" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "Línia d’ordres" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Trieu un executable" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Afegeix" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Elimina" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Edita" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Desa" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Notificacions de compartició" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Aplicacions" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Notificacions" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Contactes" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Trucades entrants" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Volum" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Posa en pausa la multimèdia" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Trucades en curs" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Silencia el micròfon" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Telefonia" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Dreceres d’accions" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Reinicialitza-ho tot…" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Dreceres d’ordres" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Dreceres" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Connectors" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Experiments" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Suprimeix" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Suprimeix aquest dispositiu" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Desaparella’l i suprimeix-ne tots els paràmetres i fitxers" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Avançat" -#: data/device.ui:2048 -msgid "Keyboard Shortcuts" -msgstr "Dreceres de teclat" - -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Aparella" - -#: data/device.ui:2183 -msgid "Device is unpaired" -msgstr "No s’ha aparellat el dispositiu" - -#: data/device.ui:2198 -msgid "You may configure this device before pairing" -msgstr "Podeu configurar el dispositiu abans d’aparellar-lo" +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "Bateria del dispositiu" -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "Mode de visualització" +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "Notificació de bateria baixa" -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Plafó" +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "Notificació de bateria carregada" -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Menú d’usuari" +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "Bateria del sistema" -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" msgstr "" -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "Quant al Zorin Connect" +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Bateria" -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Canvia a Bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "Canvia a LAN" +#: data/ui/device-preferences.ui:2394 +msgid "Keyboard Shortcuts" +msgstr "Dreceres de teclat" -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Informació de xifratge" +#: data/ui/device-preferences.ui:2529 +msgid "Device is unpaired" +msgstr "No s’ha aparellat el dispositiu" -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Desaparella" +#: data/ui/device-preferences.ui:2544 +msgid "You may configure this device before pairing" +msgstr "Podeu configurar el dispositiu abans d’aparellar-lo" #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Al dispositiu" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Des del dispositiu" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Res" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Abaixa" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Silencia" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Missatgeria" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Conversa nova" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "No hi ha cap conversa" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "No s’ha seleccionat cap conversa" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "Seleccioneu una conversa o inicieu-ne una de nova" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "El dispositiu està desconnectat" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "No hi ha cap conversa" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Envia" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "S’estan cercant dispositius…" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "Nom del dispositiu" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "_Canvia el nom" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "Actualitza" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" -msgstr "" +msgstr "Paràmetres del mòbil" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Edita el nom del dispositiu" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Dispositius" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "S’estan cercant dispositius…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Connectors per als navegadors" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Activa" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" msgstr "Aquest dispositiu és invisible als dispositius no aparellats" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" msgstr "" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Mode de visualització" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Plafó" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Menú d’usuari" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Genera un registre d'assistència" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "Quant al Zorin Connect" + #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "Envia un SMS" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Dispositius mòbils" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "Activa" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%d connectat" +msgstr[1] "%d connectats" + +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "Desactiva" #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Envia al dispositiu mòbil" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Obre" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Desactivat" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Definició d’una drecera" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Defineix" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "Premeu Esc per a cancel·lar o Retrocés per a reinicialitzar la drecera de teclat." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s ja s’està fent servir" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "Una implementació completa de KDE Connect per al GNOME" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "Adolfo Jayme Barrientos , 2019\n" +"Marc Riera Irigoyen , 2019" + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "S’estan registrant els missatges de depuració. Efectueu els passos necessaris per a reproduir un problema i, tot seguit, reviseu el registre." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Mostra el registre" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Ordinador portàtil" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Telèfon intel·ligent" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Tauleta" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "Televisió" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Desaparellat" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Desconnectat" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Connectat" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "S’està esperant el servei…" + +#: src/service/daemon.js:337 msgid "Report" msgstr "" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Error de xarxa" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Ajuda per a resoldre el problema" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "Discovery has been disabled due to the number of devices on this network." msgstr "" -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "No s’ha pogut carregar el connector %s" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" msgstr "Més informació" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" msgstr "Comparteix un fitxer" +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "Enumera els dispositius disponibles" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "Enumera tots els dispositius" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "Dispositiu de destinació" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "Cos del missatge" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Envia una notificació" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "Icona de notificació" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Comprovació de connectivitat" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Truca" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Comparteix un enllaç" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "" + #: src/service/device.js:174 msgid "Not available" msgstr "No disponible" @@ -437,83 +621,69 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "Empremta de l’aparell %s:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Ordinador portàtil" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Telèfon intel·ligent" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Tauleta" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Ordinador d’escriptori" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Torna a connectar" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Paràmetres" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Sol·licitud d’aparellament d’un %s" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Rebutja-la" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Accepta-la" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Truca" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d%% restant" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Càrrega completa" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Porta-retalls" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Contacte desconegut" @@ -525,54 +695,45 @@ msgid "Mousepad" msgstr "" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Teclat" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "Cal programari addicional" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "El teclat no està preparat" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "Envia una notificació" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" msgstr "" -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Comprovació de connectivitat" - #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Comprovació de connectivitat: %s" +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "Presentació" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Execució d’ordres" @@ -589,18 +750,14 @@ msgid "Unmount" msgstr "Desmunta" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Tots els fitxers" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Fotografies de la càmera" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "Fitxers" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Compartició" @@ -609,85 +766,87 @@ msgid "Share Text" msgstr "Comparteix text" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Comparteix un enllaç" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Ha fallat la transferència" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" -msgstr "S'està iniciant la transferència" +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "" + +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "S’està rebent «%s» del %s" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" -msgstr "" +msgstr "La transferència ha estat exitosa" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "S’ha rebut «%s» del %s" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Obre la carpeta" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Obre el fitxer" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "Ha fallat la transferència" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "No s’ha pogut rebre «%s» del %s" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" -msgstr "" +msgstr "Text compartit per %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "S’està enviant «%s» al %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "S’ha enviat «%s» al %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "No s’ha pogut enviar «%s» al %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Envia fitxers al %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Obre’l en finalitzar" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Envia un enllaç al %s" @@ -704,7 +863,7 @@ msgid "Reply SMS" msgstr "" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "" @@ -717,105 +876,58 @@ msgstr "Silencia la trucada" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Trucada entrant" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Trucada en curs" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Altre" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Fax" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Feina" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Mòbil" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Particular" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Envia al %s" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Obre" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "" - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Desactivat" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "" - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s ja s’està fent servir" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Ara mateix" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -823,17 +935,28 @@ msgstr[1] "%d minuts" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Ahir・%s" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "Vós: %s" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "" +msgstr[1] "" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "Seleccioneu un dispositiu" @@ -842,100 +965,63 @@ msgid "Select" msgstr "Selecciona" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "Desaparellat" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Desconnectat" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Connectat" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "Transferred files are placed in the Downloads folder." -msgstr "Els fitxers transferits es col·loquen a la carpeta Baixades." - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "Una implementació completa de KDE Connect per al GNOME" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "Adolfo Jayme Barrientos , 2019\n" -"Marc Riera Irigoyen , 2019" - -#: src/service/ui/settings.js:529 -msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." -msgstr "S’estan registrant els missatges de depuració. Efectueu els passos necessaris per a reproduir un problema i, tot seguit, reviseu el registre." - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "Mostra el registre" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "Càrrega completa" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "No s'ha trobat cap dispositiu" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (en estimació…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (%d∶%02d restants)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d hora" +msgstr[1] "%d hores" + +#. TRANSLATORS: Time until change with time duration +#. EXAMPLE: Until 10:00 (2 hours) +#: src/shell/donotdisturb.js:150 +#, javascript-format +msgid "Until %s (%s)" +msgstr "" + +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 msgid "Do Not Disturb" msgstr "No molesteu" -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" msgstr "Silencia les notificacions del dispositiu mòbil" -#: src/shell/donotdisturb.js:171 +#: src/shell/donotdisturb.js:261 msgid "Until you turn off Do Not Disturb" msgstr "Fins que desactiveu el mode No molesteu" -#. TRANSLATORS: Time until change with time duration -#. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 -#, javascript-format -msgid "Until %s (%s)" -msgstr "" - -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Fet" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d hora" -msgstr[1] "%d hores" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Respon" @@ -954,11 +1040,6 @@ msgid "Service Unavailable" msgstr "El servei no està disponible" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "No s'ha trobat cap dispositiu" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/cs.po gnome-shell-extension-zorin-connect-28.0.2/po/cs.po --- gnome-shell-extension-zorin-connect-24.1/po/cs.po 2019-05-29 12:46:41.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/cs.po 2019-11-30 17:28:03.000000000 +0000 @@ -2,11 +2,11 @@ msgstr "" "Project-Id-Version: zorin-connect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" -"PO-Revision-Date: 2019-05-18 10:54\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-10 11:57\n" "Last-Translator: Andy Holmes (andyholmes)\n" "Language-Team: Czech\n" -"Language: cs\n" +"Language: cs_CZ\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -16,363 +16,391 @@ "X-Crowdin-Language: cs\n" "X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Informace o šifrování" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Spárování" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Zrušit spárování" + #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "Připojit k…" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "Storno" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Připojit" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "IP adresa" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Zařízení Bluetooth" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Napište telefonní číslo nebo jméno" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "Žádné kontakty" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Nápověda" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Napište telefonní číslo nebo jméno" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "Napsat zprávu" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "Odeslat zprávu" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Akumulátor" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Počítač" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" msgstr "Fotoaparát" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Synchronizace schránky" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Přehrávače médií" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Myš a klávesnice" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Ovládání hlasitosti" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Soubory" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "Přijmout soubory" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Sdílení" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Příkazy" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Jméno" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "Příkazový řádek" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Vyberte spustitelný soubor" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Přidat" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Odebrat" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Upravit" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Uložit" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Sdílet oznámení" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "Sdílet když je aktivní" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Aplikace" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Oznámení" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Kontakty" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Příchozí hovory" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Hlasitost" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Pozastavit multimédia" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Probíhající hovory" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Ztlumit mikrofon" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Telefonie" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Klávesové zkratky akcí" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Vrátit vše na výchozí hodnoty…" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Zkratky příkazů" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Klávesové zkratky" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Zásuvné moduly" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Experimentální" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "Podpora původních SMS zpráv" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Smazat" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Odstranit toto zařízení" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Zrušit spárování a odebrat všechna nastavení a soubory" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Pokročilé" -#: data/device.ui:2048 +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "Akumulátor zařízení" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "Upozornění na téměř vybitý akumulátor" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "Oznámení o úplném dobití" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "Systémový akumulátor" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "Sdílet statistiky" + +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Akumulátor" + +#: data/ui/device-preferences.ui:2394 msgid "Keyboard Shortcuts" msgstr "Klávesové zkratky" -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Spárování" - -#: data/device.ui:2183 +#: data/ui/device-preferences.ui:2529 msgid "Device is unpaired" msgstr "Zařízení není spárováno" -#: data/device.ui:2198 +#: data/ui/device-preferences.ui:2544 msgid "You may configure this device before pairing" msgstr "Před spárováním může být třeba toto zařízení nastavit" -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "Režim zobrazení" - -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Panel" - -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Uživatelská nabídka" - -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" -msgstr "Vytvořit záznam událostí pro podporu" - -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "O Zorin Connect" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Přejít na Bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "Přejít na LAN" - -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Informace o šifrování" - -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Zrušit spárování" - #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Do zařízení" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Ze zařízení" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Nic" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Snížit" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Ztlumit" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Zasílání zpráv" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Nová konverzace" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Žádné konverzace" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "Nevybrána žádná konverzace" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "Vybrat nebo zahájit konverzaci" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Zařízení je odpojeno" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "Žádné konverzace" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Poslat" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "Vyhledávání zařízení…" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "Název zařízení" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "_Přejmenovat" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "Obnovit" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" msgstr "Nastavení telefonu" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Upravit název zařízení" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Zařízení" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Vyhledávání zařízení…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Doplňky pro prohlížeče" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Zapnout" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" msgstr "Toto zařízení je pro nespárovaná zařízení neviditelné" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" msgstr "Objevování vypnuto" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Režim zobrazení" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Panel" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Uživatelská nabídka" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Vytvořit záznam událostí pro podporu" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "O Zorin Connect" + #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "Poslat SMS" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Mobilní zařízení" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "Zapnout" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" @@ -381,48 +409,203 @@ msgstr[2] "%d připojených" msgstr[3] "%d připojených" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "Vypnout" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Odeslat do mobilního zařízení" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Otevřít" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Zap." + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Vyp." + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Vypnuto" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Nastavení klávesové zkratky" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Nastavit" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Zadejte novou zkratku pro %s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "Zrušíte stiskem Esc nebo pomocí Backspace vrátíte do původního stavu." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s už je používáno" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "Úplná (re)implementace KDE Connect pro GNOME" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "Pavel Borecki " + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "Ladící zprávy jsou zaznamenávány. Podnikněte kroky, potřebné pro vyvolání problému a pak si záznam prohlédněte." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Prohlédnout si záznam událostí" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Notebook" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Chytrý telefon" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Tablet" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "Televize" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Nespárováno" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Odpojeno" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Připojeno" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "Čeká se na službu…" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Hlášení" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Ověření se nezdařilo" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Chyba sítě" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Kliknutím otevřete nápovědu pro odstraňování potíží" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "Discovery has been disabled due to the number of devices on this network." msgstr "Kvůli velkému množství zařízení na této síti bylo objevování vypnuto." -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "Zásuvný modul %s se nepodařilo načíst" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" msgstr "Další informace získáte kliknutím" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "Vytočit číslo" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" msgstr "Sdílet soubor" +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "Vypsat zařízení k dispozici" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "Vypsat všechna zařízení" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "Cílové zařízení" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "Tělo zprávy" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Poslat oznámení" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "Název oznamovací aplikace" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "Tělo oznámení" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "Ikona oznámení" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "Identif. oznámení" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Fotka" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ping" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Vyzvánění" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Sdílet odkaz" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "Zobrazit verzi vydání" + #: src/service/device.js:174 msgid "Not available" msgstr "Není k dispozici" @@ -439,83 +622,69 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "Otisk %s:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Notebook" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Chytrý telefon" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Tablet" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Počítač" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Znovu připojit" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Nastavení" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Žádost o spárování od %s" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Odmítnout" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Přijmout" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Vyzvánění" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: Akumulátor je téměř vybitý" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d%% zbývá" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "%s: Akumulátor je nabitý" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Plně nabito" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Schránka" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Odesílání schránky" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Stahování schránky" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Neznámý kontakt" @@ -527,54 +696,45 @@ msgid "Mousepad" msgstr "Myš" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Klávesnice" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "Je zapotřebí další software" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "Klávesnice není připravena" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Zrušit oznámení" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Zavřít oznámení" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Odpovědět na oznámení" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "Poslat oznámení" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" -msgstr "Fotka" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Ping" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "Zapnout oznamování" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Ping: %s" +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "Prezentace" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Spustit příkazy" @@ -591,18 +751,14 @@ msgid "Unmount" msgstr "Odpojit" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Všechny soubory" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Snímky z fotoaparátu" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "Soubory" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Sdílet" @@ -611,85 +767,87 @@ msgid "Share Text" msgstr "Sdílet text" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Sdílet odkaz" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Přenos se nezdařil" + +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "%s není umožněno nahrávat soubory" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" -msgstr "Přenos začíná" +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "Přenášení souboru" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "Získávání „%s“ z %s" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Přenos úspěšný" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "Obdrženo „%s“ z %s" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Otevřít složku" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Otevřít soubor" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "Přenos se nezdařil" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Nepodařilo se přijmout „%s“ od %s" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "Text sdílený %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Posílání „%s“ do %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "„%s“ odesláno do %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Nepodařilo se odeslat „%s“ do %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Odeslat soubory do %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Po dokončení otevřít" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Poslat odkaz do %s" @@ -706,7 +864,7 @@ msgid "Reply SMS" msgstr "Odpovědět na SMS" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Sdílet SMS" @@ -719,105 +877,58 @@ msgstr "Umlčet hovor" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Příchozí hovor" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Probíhající hovor" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Ostatní" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Fax" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Pracovní" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Mobilní" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Domů" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Poslat na %s" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Otevřít" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "Zap." - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "Vyp." - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Vypnuto" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Nastavení klávesové zkratky" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Nastavit" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Zadejte novou zkratku pro %s" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Zrušíte stiskem Esc nebo pomocí Backspace vrátíte do původního stavu." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s už je používáno" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Právě teď" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -827,17 +938,30 @@ msgstr[3] "%d minut" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Včera・%s" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "Skupinová zpráva" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "Vy: %s" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "A %d další kontakt" +msgstr[1] "A %d další kontakty" +msgstr[2] "A %d dalších kontaktů" +msgstr[3] "A %d další" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "Vybrat zařízení" @@ -846,101 +970,65 @@ msgid "Select" msgstr "Vybrat" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "Nespárováno" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Odpojeno" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Připojeno" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "Transferred files are placed in the Downloads folder." -msgstr "Přenesené soubory jsou umístěny do složky Stažené." - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "Úplná (re)implementace KDE Connect pro GNOME" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "Pavel Borecki " - -#: src/service/ui/settings.js:529 -msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." -msgstr "Ladící zprávy jsou zaznamenávány. Podnikněte kroky, potřebné pro vyvolání problému a pak si záznam prohlédněte." - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "Prohlédnout si záznam událostí" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "Plně nabito" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Nenalezeno žádné zařízení" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (odhaduje se…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (%d∶%02d do úplného nabití)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (%d∶%02d zbývá)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 -msgid "Do Not Disturb" -msgstr "Nerušit" - -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" -msgstr "Umlčet oznámení z mobilního zařízení" - -#: src/shell/donotdisturb.js:171 -msgid "Until you turn off Do Not Disturb" -msgstr "Dokud nevypnete režim Nerušit" +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d hodina" +msgstr[1] "%d hodiny" +msgstr[2] "%d hodin" +msgstr[3] "%d hodin" #. TRANSLATORS: Time until change with time duration #. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 +#: src/shell/donotdisturb.js:150 #, javascript-format msgid "Until %s (%s)" msgstr "Do %s (%s)" -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 +msgid "Do Not Disturb" +msgstr "Nerušit" + +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" +msgstr "Umlčet oznámení z mobilních zařízení" + +#: src/shell/donotdisturb.js:261 +msgid "Until you turn off Do Not Disturb" +msgstr "Dokud nevypnete režim Nerušit" + +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Hotovo" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d hodina" -msgstr[1] "%d hodiny" -msgstr[2] "%d hodin" -msgstr[3] "%d hodin" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Odpovědět" @@ -959,11 +1047,6 @@ msgid "Service Unavailable" msgstr "Služba nedostupná" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Nenalezeno žádné zařízení" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/da.po gnome-shell-extension-zorin-connect-28.0.2/po/da.po --- gnome-shell-extension-zorin-connect-24.1/po/da.po 2019-05-16 22:17:20.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/da.po 2019-11-30 17:29:27.000000000 +0000 @@ -2,11 +2,11 @@ msgstr "" "Project-Id-Version: zorin-connect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" -"PO-Revision-Date: 2019-05-04 15:44\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-10 11:13\n" "Last-Translator: Andy Holmes (andyholmes)\n" "Language-Team: Danish\n" -"Language: da\n" +"Language: da_DK\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -16,410 +16,593 @@ "X-Crowdin-Language: da\n" "X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Kryptering Info" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Par" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Unpair" + #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "Forbind til…" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "Anuller" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Forbind" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "IP adresse" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Bluetooth Enhed" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Indtast et telefonnummer eller navn" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "Ingen kontakter" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Hjælp" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Indtast et telefonnummer eller navn" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "Skriv en meddelelse" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "Send Meddelelse" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Batteri" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Stationær Computer" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" msgstr "Kamera" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Udklipsholder synkroniseres" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Medieafspillere" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Mus & Tastatur" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Volumen Kontrol" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Filer" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Deling" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Kommandoer" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Navn" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "Kommandolinje" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Vælg en eksekverbar" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Tilføje" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Fjerne" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Rediger" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Gem" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Del Notifikationer" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Applikationer" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Notifikationer" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Kontakter" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Indgående Opkald" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Lydstryke" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Pause Media" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Igangværende Opkald" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Stum Mikrofon" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Telefoni" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Handlings Genveje" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Nulstil Alle…" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Kommando Genveje" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Genveje" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Plugins" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Eksperimentel" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" -msgstr "" +msgstr "Arv SMS" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Slet" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Slet dette enheden" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Uparret og fjerne alle indstillinger og filer" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Avanceret" -#: data/device.ui:2048 -msgid "Keyboard Shortcuts" -msgstr "Tastaturgenveje" - -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Par" - -#: data/device.ui:2183 -msgid "Device is unpaired" -msgstr "Enheden er uparret" - -#: data/device.ui:2198 -msgid "You may configure this device before pairing" -msgstr "Du kan konfigurere denne enhed før parring" +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "" -#: data/menus.ui:12 -msgid "Display Mode" +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" msgstr "" -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Panel" +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "" -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Bruger Menu" +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "" -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" msgstr "" -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "Om Zorin Connect" +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Batteri" -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Skift til Bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "Skift til LAN" +#: data/ui/device-preferences.ui:2394 +msgid "Keyboard Shortcuts" +msgstr "Tastaturgenveje" -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Kryptering Info" +#: data/ui/device-preferences.ui:2529 +msgid "Device is unpaired" +msgstr "Enheden er uparret" -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Unpair" +#: data/ui/device-preferences.ui:2544 +msgid "You may configure this device before pairing" +msgstr "Du kan konfigurere denne enhed før parring" #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Til Apparat" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" -msgstr "" +msgstr "Fra Enhed" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Intet" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Reducere" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Lydløs" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Messaging" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Ny Samtale" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Ingen Samtaler" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "Ingen samtaler valgt" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "Vælg eller start en samtale" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Enheden er afbrudt" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "Ingen Samtaler" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Send" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "Søger efter enheder…" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "Opdater" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" msgstr "Mobile Indstillinger" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Rediger Enheds Navn" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Enheder" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Søger efter enheder…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" -msgstr "" +msgstr "Webbrowser Tilføj-Ons" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Aktiver" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" -msgstr "" +msgstr "Denne enhed er usynlig til ikke parret enheder" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" -msgstr "" +msgstr "Discovery Deaktiveret" + +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Visningstilstand" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Panel" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Bruger Menu" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Generere Underbygge Log" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "Om Zorin Connect" #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" -msgstr "" +msgstr "Send SMS" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" +msgstr "Mobil Enheder" + +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" msgstr "" -#: src/extension.js:193 +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%d Tilsuttet" +msgstr[1] "%d Tilsuttet" + +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "" #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" +msgstr "Send til Mobil Enhed" + +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Åbn" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Tænde" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Slukke" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Deaktiveret" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Indstil Genvej" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Indstil" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Indtast en ny genvej for at ændre %s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "Tryk på Esc at annullere eller backspace-nøgle for at nulstille tastaturgenvejen." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s er allerede bliver brugt" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "En komplet KDE Connect implementering for GNOME" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "oversætter-kreditter" + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "Fejlmeddelelser er logges. Tage de nødvendige skridt til at reproducere et problem, og gennemgå loggen." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Gennemgå Loggen" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Bærbar" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Smartphone" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Tablet" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Ikke parret" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Frakoblet" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Tilsluttet" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" msgstr "" -#: src/service/daemon.js:373 +#: src/service/daemon.js:337 msgid "Report" msgstr "Anmeld" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" -msgstr "" +msgstr "Godkendelsesfejl" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Netværks Fejl" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" -msgstr "" +msgstr "Klik for hjælp fejlfinding" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "Discovery has been disabled due to the number of devices on this network." +msgstr "Discovery er deaktiveret på grund af antallet af enheder på dette netværk." + +#: src/service/daemon.js:608 +msgid "Click for more information" +msgstr "Klik for mere information" + +#: src/service/daemon.js:705 +msgid "Dial Number" +msgstr "Opkaldsnummer" + +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 +msgid "Share File" +msgstr "Del Fil" + +#: src/service/daemon.js:774 +msgid "List available devices" msgstr "" -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" +#: src/service/daemon.js:783 +msgid "List all devices" msgstr "" -#: src/service/daemon.js:528 src/service/daemon.js:542 -msgid "Click for more information" +#: src/service/daemon.js:792 +msgid "Target Device" msgstr "" -#: src/service/daemon.js:681 -msgid "Dial Number" +#: src/service/daemon.js:834 +msgid "Message Body" msgstr "" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 -msgid "Share File" -msgstr "Del Fil" +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Send Notifikation" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Foto" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ping" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Ring" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Del Link" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "" #: src/service/device.js:174 msgid "Not available" @@ -437,85 +620,71 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "%s Fingeraftryk:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Bærbar" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Smartphone" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Tablet" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Stationær Computer" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Tilslut Igen" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Indstillinger" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Paranmodning fra %s" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Afvise" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Acceptere" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Ring" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: Batteriet er lavt" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d%% tilbage" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Fuldt Opladet" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Udklipsholder" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Udklipsholder Tryk" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Udklipsholder Trække" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" -msgstr "" +msgstr "Ukendt Kontakt" #: src/service/plugins/findmyphone.js:13 msgid "Find My Phone" @@ -525,81 +694,68 @@ msgid "Mousepad" msgstr "Musemåtte" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Tastatur" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" -msgstr "" +msgstr "Tastaturet ikke klar" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Annullere Besked" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Luk Besked" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" -msgstr "" +msgstr "Svar Notifikation" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" msgstr "" -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" -msgstr "Foto" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Ping" - #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Ping: %s" +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Udføre Kommando" #: src/service/plugins/sftp.js:12 msgid "SFTP" -msgstr "" +msgstr "SFTP" #: src/service/plugins/sftp.js:18 msgid "Mount" -msgstr "" +msgstr "Monter" #: src/service/plugins/sftp.js:26 msgid "Unmount" -msgstr "" +msgstr "Afmonter" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Alle filer" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" -msgstr "" - -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "Filer" +msgstr "Kamera Billeder" #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" @@ -609,88 +765,90 @@ msgid "Share Text" msgstr "Del tekst" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Del Link" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Overførsel mislykkedes" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "" + +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" msgstr "" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" -msgstr "" +msgstr "Modtager \"%s\" fra %s" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" -msgstr "" +msgstr "Overførsel Succesfuld" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" -msgstr "" +msgstr "Modtaget \"%s\" fra %s" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Åbn mappe" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Åben fil" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" -msgstr "" +msgstr "Kunne ikke modtage \"%s\" fra %s" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" -msgstr "" +msgstr "Tekst Deles Af %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" -msgstr "" +msgstr "Sende \"%s\" til %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" -msgstr "" +msgstr "Sendt \"%s\" til %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" -msgstr "" +msgstr "Kunne ikke send \"%s\" til %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" -msgstr "" +msgstr "Send filer til %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" -msgstr "" +msgstr "Åbne, når færdig" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" -msgstr "" +msgstr "Send et link til %s" #: src/service/plugins/sms.js:13 msgid "SMS" @@ -704,7 +862,7 @@ msgid "Reply SMS" msgstr "Besvar SMS" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Del SMS" @@ -714,227 +872,155 @@ #: src/service/plugins/telephony.js:30 msgid "Mute Call" -msgstr "" +msgstr "Stum Opkald" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" -msgstr "" +msgstr "Indgående Opkald" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" -msgstr "" +msgstr "Igangværende Opkald" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" -msgstr "" +msgstr "%s・Anden" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" -msgstr "" +msgstr "%s・Fax" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" -msgstr "" +msgstr "%s・Arbejde" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" -msgstr "" +msgstr "%s・Mobil" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" -msgstr "" +msgstr "%s・Hjem" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" -msgstr "" - -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Åbn" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "Tænde" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "Slukke" - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Deaktiveret" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Indstil Genvej" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Indstil" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Tryk på Esc at annullere eller backspace-nøgle for at nulstille tastaturgenvejen." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s er allerede bliver brugt" +msgstr "Send til %s" #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Lige Nu" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%d minut" +msgstr[1] "%d minutter" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" +msgstr "I går・%s" + +#: src/service/ui/messaging.js:255 +msgid "Group Message" msgstr "" #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" -msgstr "" +msgstr "Du: %s" + +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "" +msgstr[1] "" #: src/service/ui/service.js:31 msgid "Select a Device" -msgstr "" +msgstr "Vælg en mobil enhed" #: src/service/ui/service.js:35 msgid "Select" -msgstr "" - -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Frakoblet" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Tilsluttet" +msgstr "Vælg" -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "Transferred files are placed in the Downloads folder." -msgstr "" - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "oversætter-kreditter" - -#: src/service/ui/settings.js:529 -msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." -msgstr "" - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "Fuldt Opladet" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Ingen Enhed Fundet" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (Estimering…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (%d:%02d Indtil Fuld)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (%d:%02d Resterende)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d time" +msgstr[1] "%d timer" + +#. TRANSLATORS: Time until change with time duration +#. EXAMPLE: Until 10:00 (2 hours) +#: src/shell/donotdisturb.js:150 +#, javascript-format +msgid "Until %s (%s)" +msgstr "Indtil %s (%s)" + +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 msgid "Do Not Disturb" msgstr "Forstyr ikke" -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" msgstr "Stilhed mobilmeddelelser" -#: src/shell/donotdisturb.js:171 +#: src/shell/donotdisturb.js:261 msgid "Until you turn off Do Not Disturb" msgstr "Indtil du deaktiverer \"Forstyr ikke\"" -#. TRANSLATORS: Time until change with time duration -#. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 -#, javascript-format -msgid "Until %s (%s)" -msgstr "Indtil %s (%s)" - -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Færdig" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d time" -msgstr[1] "%d timer" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Svar" @@ -953,11 +1039,6 @@ msgid "Service Unavailable" msgstr "Tjenesten er ikke tilgængelig" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Ingen Enhed Fundet" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/de.po gnome-shell-extension-zorin-connect-28.0.2/po/de.po --- gnome-shell-extension-zorin-connect-24.1/po/de.po 2019-05-29 12:46:51.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/de.po 2019-11-30 17:29:37.000000000 +0000 @@ -2,11 +2,11 @@ msgstr "" "Project-Id-Version: zorin-connect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" -"PO-Revision-Date: 2019-05-18 10:54\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-10 11:34\n" "Last-Translator: Andy Holmes (andyholmes)\n" "Language-Team: German\n" -"Language: de\n" +"Language: de_DE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -16,410 +16,594 @@ "X-Crowdin-Language: de\n" "X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Verschlüsselunginfo" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Koppeln" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Entkoppeln" + #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" -msgstr "Verbinde mit…" +msgstr "Verbinden mit …" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "Abbruch" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Verbinden" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "IP-Adresse" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Bluetooth-Gerät" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Telefonnummer oder Name eingeben" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "Keine Kontakte" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Hilfe" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Telefonnummer oder Name eingeben" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" -msgstr "Verfasse eine Nachricht" +msgstr "Eine Nachricht verfassen" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" -msgstr "Nachricht schicken" +msgstr "Nachricht senden" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Akku" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Desktop" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" -msgstr "" +msgstr "Kamera" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" -msgstr "Synchronisiere die Zwischenablage" +msgstr "Zwischenablagesynchronisierung" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" -msgstr "Medien Steuerung" +msgstr "Medienwiedergaben" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Maus & Tastatur" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" -msgstr "Lautstärken Kontrolle" +msgstr "Lautstärkenregler" + +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Dateien" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "Dateien empfangen" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Teilen" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Befehle" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Name" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" -msgstr "Kommandozeile" +msgstr "Befehlszeile" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" -msgstr "Wähle ein ausführbares Programm" +msgstr "Ein ausführbares Programm auswählen" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Hinzufügen" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Entfernen" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Bearbeiten" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Speichern" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" -msgstr "Teile Benachrichtigungen" +msgstr "Benachrichtigungen freigeben" + +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "Teilen wenn aktiv" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Anwendungen" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Benachrichtigungen" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Kontakte" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Eingehende Anrufe" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Lautstärke" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" -msgstr "Wiedergabe pausieren" +msgstr "Medienwiedergabe pausieren" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Laufende Anrufe" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Mikrofon stummschalten" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Telefonie" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" -msgstr "Aktions Tastenkürzel" +msgstr "Aktionstastenkürzel" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" -msgstr "Setze alles zurück…" - -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Befehlstastenkürzel" +msgstr "Alles zurücksetzen …" -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Tastenkürzel" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" -msgstr "Plugins" +msgstr "Module" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Experimentell" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "Alte SMS-Unterstützung" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Löschen" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Lösche dieses Gerät" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Trenne und entferne alle Einstellungen und Dateien" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Erweitert" -#: data/device.ui:2048 +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "Geräte Akku" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "Benachrichtigung bei geringen Akkustand" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "Vollständig geladen Benachrichtigung" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "Systembatterie" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "Statistik teilen" + +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Akku" + +#: data/ui/device-preferences.ui:2394 msgid "Keyboard Shortcuts" msgstr "Tastenkürzel" -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Verbinde" - -#: data/device.ui:2183 +#: data/ui/device-preferences.ui:2529 msgid "Device is unpaired" -msgstr "Gerät ist nicht gepaart" +msgstr "Gerät ist nicht gekoppelt" -#: data/device.ui:2198 +#: data/ui/device-preferences.ui:2544 msgid "You may configure this device before pairing" msgstr "Sie können dieses Gerät vor der Paarung konfigurieren" -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "Anzeigemodus" - -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Panel" - -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Benutzermenü" - -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" -msgstr "Support-Protokoll generieren" - -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Wechseln Sie zu Bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "Wechseln Sie zu LAN" - -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Verschlüsselung Info" - -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Trenne" - #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Zum Gerät" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Vom Gerät" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Nichts" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Leiser" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Stumm schalten" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Nachrichten" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Neues Gespräch" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Keine Konversationen" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "Keine Unterhaltung ausgewählt" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" -msgstr "Wähle oder Starte eine Unterhaltung" +msgstr "Eine Unterhaltung auswähle oder starten" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Gerät ist getrennt" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "Keine Konversationen" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Senden" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "Geräte werden gesucht…" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "Gerätename" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "_Umbenennen" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" -msgstr "Aktualisieren" +msgstr "Auffrischen" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" -msgstr "Mobile Einstellungen" +msgstr "Handy-Einstellungen" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Gerätename bearbeiten" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Geräte" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Geräte werden gesucht…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" -msgstr "Browser Erweiterungen" +msgstr "Browser-Erweiterungen" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Aktivieren" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" -msgstr "Dieses Gerät ist für ungepaarte Geräte unsichtbar" +msgstr "Dieses Gerät ist für nicht gekoppelte Geräte unsichtbar" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" -msgstr "Suchen deaktiviert" +msgstr "Erkennen deaktiviert" + +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Anzeigemodus" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Leiste" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Benutzermenü" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Hilfeprotokoll generieren" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "Über Zorin Connect" #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "SMS senden" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Mobile Geräte" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "Aktivieren" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" msgstr[0] "%d verbunden" msgstr[1] "%d verbunden" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "Deaktivieren" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "An Mobilgerät senden" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Öffnen" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "An" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Aus" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Deaktiviert" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Tastenkürzel festlegen" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Festlegen" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Ein neues Tastenkürzel eingeben, um %s zu Ändern" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "ESC zum Abbrechen oder die Rücktaste drücken, um das Tastenkürzel zurückzusetzen." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s ist schon vergeben" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "Eine vollständige KDE-Connect-Implementierung für GNOME" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "taaem \n" +"Tobias Bannert " + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "Fehlersuchmeldungen werden protokolliert. Führen Sie alle erforderlichen Schritte aus, um ein Problem zu reproduzieren, und überprüfen Sie das Protokoll." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Protokoll überprüfen" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Laptop" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Smartphone" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Tablet" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "Fernseher" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Ungekoppelt" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Getrennt" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Verbunden" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "Warte auf Dienst…" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Bericht" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" -msgstr "Authentifikationsfehler" +msgstr "Legitimerungsfehler" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Netzwerkfehler" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" -msgstr "Klicke um Hilfe zu bekommen" +msgstr "Für Hilfe bei der Fehlerbehebung hier klicken" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "Discovery has been disabled due to the number of devices on this network." -msgstr "Suchen wurde deaktiviert aufgrund der Anzahl an Geräten in diesem Netzwerk." +msgstr "Erkennen wurde deaktiviert, aufgrund der Anzahl an Geräten in diesem Netzwerk." -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "%s Plugin konnte nicht geladen werden" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" -msgstr "Klicke für mehr Informationen" +msgstr "Für mehr Informationen klicken" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "Nummer wählen" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" -msgstr "Datei teilen" +msgstr "Datei freigeben" + +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "Alle verfügbaren Geräte anzeigen" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "Alle Geräte anzeigen" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "Zielgerät" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "Nachrichtentext" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Benachrichtigung senden" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "Benachrichtigungs-Symbol" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "Mitteilungs-ID" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Foto" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ping" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Ring" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Verweis freigeben" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "Neuste Version zeigen" #: src/service/device.js:174 msgid "Not available" @@ -437,142 +621,119 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "%s Fingerabdruck:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Laptop" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Smartphone" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Tablet" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Desktop" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Neuverbinden" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Einstellungen" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Kopplung von %s angefordert" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Ablehnen" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Annehmen" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Ring" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: Akku ist leer" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d%% verbleibend" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "%s: Akku ist voll" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Vollständig geladen" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Zwischenablage" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" -msgstr "Pushen der Zwischenablage" +msgstr "Zwischenablage senden" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" -msgstr "Ziehen der Zwischenablage" +msgstr "Zwischenablage laden" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Unbekannter Kontakt" #: src/service/plugins/findmyphone.js:13 msgid "Find My Phone" -msgstr "Finde mein Handy" +msgstr "Mein Handy finden" #: src/service/plugins/mousepad.js:14 msgid "Mousepad" msgstr "Mauspad" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Tastatur" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "Zusätzliche benötigte Software" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "Tastatur nicht bereit" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Benachrichtigung abbrechen" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Benachrichtigung schließen" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Auf Benachrichtigung antworten" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "Benachrichtigung senden" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" -msgstr "" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Ping" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "Benachrichtigungen aktivieren" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Ping: %s" +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "Präsentation" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Befehl ausführen" @@ -589,18 +750,14 @@ msgid "Unmount" msgstr "Aushängen" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Alle Dateien" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Kamerabilder" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "Dateien" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Teilen" @@ -609,88 +766,90 @@ msgid "Share Text" msgstr "Text teilen" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Link teilen" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Übertragung gescheitert" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" -msgstr "Übertragung starten" +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "%s besitzt keine Berechtigung Dateien hochzuladen" + +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "Übertrage Datei" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" -msgstr "Empfange „%s“ von %s" +msgstr "»%s« wird von %s empfangen" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Übertragung erfolgreich" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" -msgstr "„%s“ von %s empfangen" +msgstr "»%s« von %s empfangen" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Ordner öffnen" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Datei öffnen" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "Übertragung gescheitert" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" -msgstr "Empfang von „%s“ von %s gescheitert" +msgstr "Empfang von »%s« von %s gescheitert" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" -msgstr "Text geteilt von %s" +msgstr "Text von %s freigegeben" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" -msgstr "„%s“ an %s senden" +msgstr "»%s« an %s senden" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" -msgstr "„%s“ an %s gesendet" +msgstr "»%s« an %s gesendet" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" -msgstr "Senden von „%s“ an %s gescheitert" +msgstr "Senden von »%s« an %s gescheitert" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" -msgstr "Sende Dateien an %s" +msgstr "Dateien an %s senden" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Öffnen nach Erledigung" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" -msgstr "Sende Link an %s" +msgstr "Verweis an %s senden" #: src/service/plugins/sms.js:13 msgid "SMS" @@ -704,118 +863,71 @@ msgid "Reply SMS" msgstr "Auf SMS antworten" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" -msgstr "SMS teilen" +msgstr "SMS freigeben" #: src/service/plugins/systemvolume.js:11 msgid "System Volume" -msgstr "System Lautstärke" +msgstr "Systemlautstärke" #: src/service/plugins/telephony.js:30 msgid "Mute Call" -msgstr "Stelle Anruf stumm" +msgstr "Anruf stumm stellen" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Eingehender Anruf" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Laufender Anruf" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Andere" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Fax" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Arbeit" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Handy" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Haus" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "An %s senden" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Öffnen" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "An" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "Aus" - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Deaktiviert" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Setze Tastenkürzel" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Setze" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Gebe ein neues Tastenkürzel ein um %s zu Ändern" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Drücke ESC zum Abbrechen oder die Rücktaste um das Tastenkürzel Zurückzusetzen." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s ist schon vergeben" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Gerade jetzt" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -823,17 +935,28 @@ msgstr[1] "%d Minuten" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Gestern・%s" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "Gruppennachricht" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "Sie: %s" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "" +msgstr[1] "" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "Gerät auswählen" @@ -842,99 +965,63 @@ msgid "Select" msgstr "Auswählen" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "Ungepaarte" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Getrennt" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Verbunden" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "Transferred files are placed in the Downloads folder." -msgstr "Übertragene Dateien befinden sich im Ordner \" Downloads\"." - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "Eine vollständige KDE Connect Implementierung für GNOME" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "taaem " - -#: src/service/ui/settings.js:529 -msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." -msgstr "Debugmeldungen werden protokolliert. Führen Sie alle erforderlichen Schritte aus, um ein Problem zu reproduzieren, und überprüfen Sie das Protokoll." - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "Protokoll überprüfen" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "Vollständig geladen" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Kein Gerät gefunden" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" -msgstr "%d%% (Schätze..)" +msgstr "%d%% (wird geschätzt …)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (%d:%02d bis vollständig geladen)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (%d∶%02d verbleibend)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 -msgid "Do Not Disturb" -msgstr "Nicht stören" - -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" -msgstr "Stelle Mobile Benachrichtigungen stumm" - -#: src/shell/donotdisturb.js:171 -msgid "Until you turn off Do Not Disturb" -msgstr "Bis zum Ausschalten von \"Nicht stören\"" +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d Stunde" +msgstr[1] "%d Stunden" #. TRANSLATORS: Time until change with time duration #. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 +#: src/shell/donotdisturb.js:150 #, javascript-format msgid "Until %s (%s)" msgstr "Bis %s (%s)" -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 +msgid "Do Not Disturb" +msgstr "Nicht stören" + +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" +msgstr "Schalte Benachrichtigungen von Mobilgeräten stumm" + +#: src/shell/donotdisturb.js:261 +msgid "Until you turn off Do Not Disturb" +msgstr "Bis zum Ausschalten von »Nicht stören«" + +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Erledigt" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d stunde" -msgstr[1] "%d stunden" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Antworten" @@ -946,17 +1033,12 @@ #. TRANSLATORS: Chrome/Firefox WebExtension description #: webextension/gettext.js:29 msgid "Share links with Zorin Connect, direct to the browser or by SMS." -msgstr "Teile Links über Zorin Connect, direkt an den Browser oder per SMS." +msgstr "Verweise mit Zorin Connect direkt an den Browser oder per SMS freigeben." #. TRANSLATORS: WebExtension can't connect to Zorin Connect #: webextension/gettext.js:33 msgid "Service Unavailable" -msgstr "Service nicht verfügbar" - -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Kein Gerät gefunden" +msgstr "Dienst nicht verfügbar" #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 diff -Nru gnome-shell-extension-zorin-connect-24.1/po/es.po gnome-shell-extension-zorin-connect-28.0.2/po/es.po --- gnome-shell-extension-zorin-connect-24.1/po/es.po 2019-05-29 12:46:58.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/es.po 2019-11-30 17:29:47.000000000 +0000 @@ -2,11 +2,11 @@ msgstr "" "Project-Id-Version: zorin-connect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" -"PO-Revision-Date: 2019-05-18 10:54\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-11 11:44\n" "Last-Translator: Andy Holmes (andyholmes)\n" "Language-Team: Spanish\n" -"Language: es\n" +"Language: es_ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -16,411 +16,594 @@ "X-Crowdin-Language: es-ES\n" "X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Información de cifrado" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Emparejamiento" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Desemparejar" + #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "Conectar con…" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "Cancelar" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Conectar" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "Dirección IP" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Dispositivo Bluetooth" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Escriba un número telefónico o un nombre" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "No hay ningún contacto" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Ayuda" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Escriba un número telefónico o un nombre" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "Escriba un mensaje" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "Enviar mensaje" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Batería" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Equipo de escritorio" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" msgstr "Cámara" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Sincronización de portapapeles" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Reproductores multimedia" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Ratón y teclado" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Control de volumen" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Archivos" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "Recibir archivos" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Compartición" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Órdenes" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Nombre" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "Línea de órdenes" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Elija un ejecutable" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Añadir" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Quitar" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Editar" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Guardar" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Notificaciones de compartición" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Aplicaciones" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Notificaciones" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Contactos" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Llamadas entrantes" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Volumen" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Pausar multimedia" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Llamadas en curso" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Silenciar micrófono" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Telefonía" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Atajos de acciones" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Restablecer todo…" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Atajos de órdenes" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Atajos" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Complementos" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Experimentos" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "Compatibilidad SMS heredada" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Eliminar" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Eliminar este dispositivo" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Desemparejar y eliminar todos los archivos y las configuraciones" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Avanzado" -#: data/device.ui:2048 +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "Batería del dispositivo" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "Notificación de batería baja" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "Notificación de carga completa" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "Batería del sistema" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "Compartir estadísticas" + +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Batería" + +#: data/ui/device-preferences.ui:2394 msgid "Keyboard Shortcuts" msgstr "Atajos de teclado" -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Emparejamiento" - -#: data/device.ui:2183 +#: data/ui/device-preferences.ui:2529 msgid "Device is unpaired" msgstr "El dispositivo no está emparejado" -#: data/device.ui:2198 +#: data/ui/device-preferences.ui:2544 msgid "You may configure this device before pairing" msgstr "Puede configurar este dispositivo antes de emparejarlo" -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "Modo de visualización" - -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Panel" - -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Menú de usuario" - -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" -msgstr "Generar registro para asistencia" - -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "Acerca de Zorin Connect" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Cambiar a Bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "Cambiar a LAN" - -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Información de cifrado" - -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Desemparejar" - #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Al dispositivo" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Del dispositivo" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Nada" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Disminuir" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Silenciar" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Mensajería" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Conversación nueva" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "No hay ninguna conversación" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "No se seleccionó ninguna conversación" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "Seleccione una conversación o inicie una" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "El dispositivo está desconectado" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "No hay ninguna conversación" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Enviar" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "Buscando dispositivos…" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "Nombre del dispositivo" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "_Cambiar nombre" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "Actualizar" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" msgstr "Configuración de móvil" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Editar nombre de dispositivo" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Dispositivos" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Buscando dispositivos…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Complementos para navegadores" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Activar" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" msgstr "Este dispositivo es invisible a dispositivos no emparejados" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" msgstr "Descubrimiento desactivado" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Modo de visualización" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Panel" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Menú de usuario" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Generar registro para asistencia" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "Acerca de Zorin Connect" + #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "Enviar SMS" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Dispositivos móviles" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "Encender" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" msgstr[0] "%d conectado" msgstr[1] "%d conectados" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "Apagar" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Enviar a dispositivo móvil" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Abrir" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Activado" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Desactivado" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Desactivado" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Establecer atajo" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Establecer" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Digite un atajo nuevo para cambiar %s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "Oprima Esc para cancelar o Retroceso para restablecer el atajo de teclado." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "Ya está utilizándose %s" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "Una completa implementación de KDE Connect para GNOME" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "Adolfo Jayme Barrientos , 2018-2019" + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "Los mensajes de depuración están registrándose. Realice las acciones necesarias para reproducir un problema y, a continuación, revise el registro." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Revisar registro" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Equipo portátil" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Teléfono inteligente" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Tableta" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "Televisión" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Desemparejado" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Desconectado" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Conectado" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "Esperando el servicio…" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Informe" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Fallo de autenticación" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Error de red" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Pulse para obtener información de solución de problemas" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "Discovery has been disabled due to the number of devices on this network." msgstr "Se desactivó el descubrimiento debido al número de dispositivos presentes en esta red." -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "Falló la carga del complemento %s" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" msgstr "Pulse para más información" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "Marcar número" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" msgstr "Compartir archivo" +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "Enumerar dispositivos disponibles" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "Enumerar todos los dispositivos" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "Dispositivo de destino" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "Cuerpo del mensaje" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Enviar notificación" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "Cuerpo de la notificación" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "Icono de la notificación" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "Identificador de la notificación" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Fotografía" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Prueba de conectividad" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Timbrar" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Compartir enlace" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "Mostrar versión" + #: src/service/device.js:174 msgid "Not available" msgstr "No disponible" @@ -437,83 +620,69 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "Huella digital de %s:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Equipo portátil" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Teléfono inteligente" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Tableta" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Equipo de escritorio" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Volver a conectar" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Configuración" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Solicitud de emparejamiento de %s" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Rechazar" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Aceptar" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Timbrar" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: batería baja" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d %% restante" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "%s: batería cargada" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Carga completa" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Portapapeles" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Envío a portapapeles" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Recepción desde portapapeles" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Contacto desconocido" @@ -525,54 +694,45 @@ msgid "Mousepad" msgstr "Mousepad" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Teclado" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "Se necesita software adicional" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "El teclado no está preparado" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Cancelar notificación" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Cerrar notificación" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Notificación de respuesta" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "Enviar notificación" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" -msgstr "Fotografía" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Prueba de conectividad" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "Activar notificación" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Prueba de conectividad: %s" +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "Presentación" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Ejecutar órdenes" @@ -589,18 +749,14 @@ msgid "Unmount" msgstr "Desmontar" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Todos los archivos" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Fotografías de la cámara" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "Archivos" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Compartición" @@ -609,85 +765,87 @@ msgid "Share Text" msgstr "Compartir texto" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Compartir enlace" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Transferencia fallida" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" -msgstr "Comenzando la transferencia" +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "%s no tiene permitido cargar archivos" + +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "Recibiendo «%s» de %s" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Transferencia exitosa" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "Se recibió «%s» de %s" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Abrir carpeta" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Abrir archivo" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "Transferencia fallida" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Falló la recepción de «%s» desde %s" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "Texto compartido por %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Enviando «%s» a %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "Se envió «%s» a %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Falló el envío de «%s» a %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Enviar archivos a %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Abrir al terminar" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Enviar un enlace a %s" @@ -704,7 +862,7 @@ msgid "Reply SMS" msgstr "Responder a SMS" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Compartir SMS" @@ -717,105 +875,58 @@ msgstr "Silenciar llamada" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Llamada entrante" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Llamada en curso" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Otro" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Fax" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Trabajo" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Móvil" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Residencial" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Enviar a %s" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Abrir" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "Activado" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "Desactivado" - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Desactivado" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Establecer atajo" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Establecer" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Digite un atajo nuevo para cambiar %s" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Oprima Esc para cancelar o Retroceso para restablecer el atajo de teclado." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "Ya está utilizándose %s" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Ahora mismo" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -823,17 +934,28 @@ msgstr[1] "%d minutos" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Ayer・%s" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "Mensaje grupal" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "Usted: %s" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "Y %d contacto más" +msgstr[1] "Y %d más" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "Seleccione un dispositivo" @@ -842,99 +964,63 @@ msgid "Select" msgstr "Seleccionar" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "Desemparejado" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Desconectado" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Conectado" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "Transferred files are placed in the Downloads folder." -msgstr "Los archivos transferidos se almacenan en la carpeta Descargas." - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "Una completa implementación de KDE Connect para GNOME" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "Adolfo Jayme Barrientos , 2018-2019" - -#: src/service/ui/settings.js:529 -msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." -msgstr "Los mensajes de depuración están registrándose. Realice las acciones necesarias para reproducir un problema y, a continuación, revise el registro." - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "Revisar registro" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "Carga completa" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "No se encontró ningún dispositivo" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d %% (estimando…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d %% (%d∶%02d hasta completarse)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d %% (quedan %d∶%02d)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 -msgid "Do Not Disturb" -msgstr "No molestar" - -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" -msgstr "Silenciar notificaciones de dispositivo móvil" - -#: src/shell/donotdisturb.js:171 -msgid "Until you turn off Do Not Disturb" -msgstr "Hasta que desactive No molestar" +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d hora" +msgstr[1] "%d horas" #. TRANSLATORS: Time until change with time duration #. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 +#: src/shell/donotdisturb.js:150 #, javascript-format msgid "Until %s (%s)" msgstr "Hasta las %s (en %s)" -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 +msgid "Do Not Disturb" +msgstr "No molestar" + +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" +msgstr "Silenciar notificaciones de dispositivos móviles" + +#: src/shell/donotdisturb.js:261 +msgid "Until you turn off Do Not Disturb" +msgstr "Hasta que desactive No molestar" + +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Hecho" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d hora" -msgstr[1] "%d horas" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Responder" @@ -953,11 +1039,6 @@ msgid "Service Unavailable" msgstr "Servicio no disponible" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "No se encontró ningún dispositivo" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/et.po gnome-shell-extension-zorin-connect-28.0.2/po/et.po --- gnome-shell-extension-zorin-connect-24.1/po/et.po 2019-05-29 12:47:07.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/et.po 2019-11-30 17:29:54.000000000 +0000 @@ -2,11 +2,11 @@ msgstr "" "Project-Id-Version: zorin-connect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" -"PO-Revision-Date: 2019-05-18 10:54\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-10 11:34\n" "Last-Translator: Andy Holmes (andyholmes)\n" "Language-Team: Estonian\n" -"Language: et\n" +"Language: et_EE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -16,411 +16,594 @@ "X-Crowdin-Language: et\n" "X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Krüpteeringu teave" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Paarita" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Eemalda paardumine" + #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "Ühendu…" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "Loobu" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Ühenda" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "IP-aadress" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Bluetooth-seade" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Kirjuta telefoninumber või nimi" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "Kontakte pole" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Abi" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Kirjuta telefoninumber või nimi" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "Kirjuta sõnum" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "Saada sõnum" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Aku" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Lauaarvuti" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" msgstr "Kaamera" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Lõikelaua sünkroonimine" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Meediamängijad" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Hiir ja klaviatuur" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Helitugevuse juhtimine" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Failid" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "Võta faile vastu" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Jagamine" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Käsklused" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Nimi" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "Käsurida" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Vali käivitatav" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Lisa" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Eemalda" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Muuda" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Salvesta" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Jaga teateid" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "Jaga, kui on aktiivne" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Rakendused" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Teated" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Kontaktid" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Sissetulevad kõned" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Helitugevus" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Peata meedia" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Käimasolevad kõned" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Vaigista mikrofon" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Telefonifunktsioon" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Tegevuste otseteed" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Lähtesta kõik…" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Käskluste otseteed" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Otseteed" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Pluginad" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Katseline" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "Pärand SMS-tugi" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Kustuta" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Kustuta see seade" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Eemalda paardumine ja kustuta kõik seadistused ning failid" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Täpsemad" -#: data/device.ui:2048 +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "Seadme aku" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "Tühjeneva aku teade" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "Täislaetud aku teade" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "Süsteemi aku" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "Jaga statistikat" + +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Aku" + +#: data/ui/device-preferences.ui:2394 msgid "Keyboard Shortcuts" msgstr "Klaviatuuriotseteed" -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Paarita" - -#: data/device.ui:2183 +#: data/ui/device-preferences.ui:2529 msgid "Device is unpaired" msgstr "Seade on paaritamata" -#: data/device.ui:2198 +#: data/ui/device-preferences.ui:2544 msgid "You may configure this device before pairing" msgstr "Sa võid seda seadet enne paaritamist seadistada" -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "Ekraanirežiim" - -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Paneel" - -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Kasutajamenüü" - -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" -msgstr "Genereeri tugiteenusele logi" - -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "Zorin Connecti teave" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Lülitu Bluetoothile" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "Lülitu LANile" - -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Krüpteeringu teave" - -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Eemalda paardumine" - #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Seadmesse" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Seadmest" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Puudub" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Vaiksem" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Vaigista" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Sõnumside" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Uus vestlus" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Vestlused puuduvad" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "Ühtegi vestlust pole valitud" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "Vali või alusta vestlus" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Seade on lahti ühendatud" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "Vestlused puuduvad" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Saada" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "Seadmete otsimine…" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "Seadme nimi" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "Nimeta ümber" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "Värskenda" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" msgstr "Mobiiliseaded" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Muuda seadme nime" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Seadmed" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Seadmete otsimine…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Brauserilaiendused" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Luba" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" msgstr "See seade on paardumata seadmetele nähtamatu" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" msgstr "Avastamine keelatud" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Ekraanirežiim" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Paneel" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Kasutajamenüü" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Genereeri tugiteenusele logi" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "Zorin Connecti teave" + #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "Saada SMS" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Mobiilseadmed" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "Lülita sisse" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" msgstr[0] "%d ühendatud" msgstr[1] "%d ühendatud" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "Lülita välja" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Saada mobiilseadmesse" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Ava" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Sees" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Väljas" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Keelatud" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Määra otsetee" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Määra" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Sisesta %s muutmiseks uus otsetee" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "Vajuta tühistamiseks Esc või klaviatuuriotsetee lähtestamiseks Tagasilüke." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s on juba kasutusel" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "Täielik KDE Connect'i teostus GNOMEle" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "Madis O, 2018." + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "Silumissõnumid logitakse. Teosta mistahes vajalikud sammud probleemi taasloomiseks, seejärel vaata logi üle." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Vaata logi üle" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Sülearvuti" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Nutitelefon" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Tahvelarvuti" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "Televisioon" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Paaritamata" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Ühendus katkestatud" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Ühendatud" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "Teenuse ootamine…" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Teata" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Autentimise viga" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Võrguviga" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Klõpsa, et saada veaotsingul abi" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "Discovery has been disabled due to the number of devices on this network." msgstr "Avastamine on keelatud selles võrgus olevate seadmete arvu tõttu." -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "%s plugina laadimine ebaõnnestus" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" msgstr "Klõpsa rohkema teabe saamiseks" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "Helista telefoninumbrile" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" msgstr "Jaga faili" +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "Kuva saadaolevad seadmed" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "Kuva kõik seadmed" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "Sihtseade" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "Sõnumi sisu" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Saada teade" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "Teavitava rakenduse nimi" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "Teate sisu" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "Teate ikoon" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "Teate ID" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Foto" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ping" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Helise" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Jaga linki" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "Kuva väljalaskeversiooni" + #: src/service/device.js:174 msgid "Not available" msgstr "Pole saadaval" @@ -437,83 +620,69 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "%s sõrmejälg:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Sülearvuti" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Nutitelefon" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Tahvelarvuti" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Lauaarvuti" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Taasühenda" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Seaded" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Paaritamistaotlus seadmelt %s" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Keeldu" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Nõustu" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Helise" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: aku on tühi" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d%% jäänud" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "%s: aku on täis" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Täielikult laetud" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Lõikelaud" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Lõikelaua saatmine" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Lõikelaua vastuvõtmine" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Tundmatu kontakt" @@ -525,54 +694,45 @@ msgid "Mousepad" msgstr "Hiirepadi" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Klaviatuur" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "Lisatarkvara on nõutud" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "Klaviatuur pole valmis" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Tühista teade" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Sulge teade" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Vasta teatele" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "Saada teade" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" -msgstr "Foto" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Ping" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "Aktiveeri teade" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Ping: %s" +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "Esitlus" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Käivita käsklusi" @@ -589,18 +749,14 @@ msgid "Unmount" msgstr "Haagi lahti" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Kõik failid" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Kaamera pildid" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "Failid" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Jaga" @@ -609,85 +765,87 @@ msgid "Share Text" msgstr "Jaga teksti" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Jaga linki" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Ülekanne ebaõnnestus" + +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "%s ei tohi faile üles laadida" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" -msgstr "Alustan ülekannet" +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "Faili edastamine" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "„%s“vastuvõtmine seadmelt %s" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Ülekanne edukas" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "„%s“vastu võetud seadmelt %s" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Ava kataloog" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Ava fail" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "Ülekanne ebaõnnestus" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "„%s“vastuvõtmine seadmest %s ebaõnnestus" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "%s poolt jagatud tekst" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Saadan „%s“seadmesse %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "„%s“saadetud seadmesse %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "„%s“saatmine seadmesse %s ebaõnnestus" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Saada faile seadmesse %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Ava, kui valmis" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Saada link seadmesse %s" @@ -704,7 +862,7 @@ msgid "Reply SMS" msgstr "Vasta SMSile" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Jaga SMSi" @@ -717,105 +875,58 @@ msgstr "Vaigista kõne" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Sissetulev kõne" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Väljuv kõne" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Muu" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Faks" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Töö" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Mobiil" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Kodu" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Saada seadmesse %s" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Ava" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "Sees" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "Väljas" - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Keelatud" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Määra otsetee" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Määra" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Sisesta %s muutmiseks uus otsetee" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Vajuta tühistamiseks Esc või klaviatuuriotsetee lähtestamiseks Tagasilüke." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s on juba kasutusel" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Praegu" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -823,17 +934,28 @@ msgstr[1] "%d minutit" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Eile・%s" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "Grupisõnum" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "Sina: %s" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "Ja %d teine kontakt" +msgstr[1] "Ja %d teist" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "Vali seade" @@ -842,99 +964,63 @@ msgid "Select" msgstr "Vali" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "Paaritamata" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Ühendus katkestatud" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Ühendatud" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "Transferred files are placed in the Downloads folder." -msgstr "Edastatud failid asetatakse Allalaadimiste kausta." - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "Täielik KDE Connect'i teostus GNOMEle" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "Madis O, 2018." - -#: src/service/ui/settings.js:529 -msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." -msgstr "Silumissõnumid logitakse. Teosta mistahes vajalikud sammud probleemi taasloomiseks, seejärel vaata logi üle." - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "Vaata logi üle" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "Täielikult laetud" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Seadet ei leitud" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (hindamine…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (täitumiseni %d∶%02d)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (jäänud %d∶%02d)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 -msgid "Do Not Disturb" -msgstr "Mitte segada" - -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" -msgstr "Vaigista mobiilseadme teated" - -#: src/shell/donotdisturb.js:171 -msgid "Until you turn off Do Not Disturb" -msgstr "Kuni lülitad välja režiimi Mitte segada" +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d tund" +msgstr[1] "%d tundi" #. TRANSLATORS: Time until change with time duration #. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 +#: src/shell/donotdisturb.js:150 #, javascript-format msgid "Until %s (%s)" msgstr "Kuni %s (%s)" -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 +msgid "Do Not Disturb" +msgstr "Mitte segada" + +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" +msgstr "Vaigista mobiilseadmete teated" + +#: src/shell/donotdisturb.js:261 +msgid "Until you turn off Do Not Disturb" +msgstr "Kuni lülitad välja režiimi Mitte segada" + +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Valmis" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d tund" -msgstr[1] "%d tundi" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Vasta" @@ -953,11 +1039,6 @@ msgid "Service Unavailable" msgstr "Teenus pole saadaval" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Seadet ei leitud" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/fr.po gnome-shell-extension-zorin-connect-28.0.2/po/fr.po --- gnome-shell-extension-zorin-connect-24.1/po/fr.po 2019-05-29 12:47:13.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/fr.po 2019-11-30 17:30:14.000000000 +0000 @@ -2,11 +2,11 @@ msgstr "" "Project-Id-Version: zorin-connect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" -"PO-Revision-Date: 2019-05-18 10:54\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-12 14:03\n" "Last-Translator: Andy Holmes (andyholmes)\n" "Language-Team: French\n" -"Language: fr\n" +"Language: fr_FR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -16,411 +16,594 @@ "X-Crowdin-Language: fr\n" "X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Informations de chiffrement" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Associer" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Dissocier" + #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "Se connecter à…" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "Annuler" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Connecter" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "Adresse IP" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Périphérique bluetooth" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Taper un numéro de téléphone ou un nom" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "\"Aucun contact\"" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Aide" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Taper un numéro de téléphone ou un nom" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "Taper un message" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "Envoyer le message" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Batterie" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Ordinateur de bureau" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" -msgstr "" +msgstr "Appareil photo" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Synchroniser le presse-papiers" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Lecteurs multimédia" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Souris et clavier" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Gestion du volume" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Fichiers" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Partage" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Commandes" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Nom" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "Commande" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Choisir un exécutable" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Ajouter" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Supprimer" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Modifier" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Enregistrer" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Synchroniser les notifications" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "Partager quand actif" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Applications" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Notifications" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Contacts" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Appels entrants" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Volume" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Mettre les médias en pause" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Appels en cours" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Mettre le microphone en sourdine" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Téléphonie" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Raccourcis d'actions" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Tout réinitialiser…" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Raccourcis de commandes" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Raccourcis" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Greffons" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Expérimental" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "Ancienne gestion des SMS" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Effacer" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Supprimer cet appareil" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Dissocier et supprimer tous les paramètres et fichiers" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Avancé" -#: data/device.ui:2048 +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "Batterie de l'appareil" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "Notification de batterie faible" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "Notification entièrement chargée" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "Partager les statistiques" + +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Batterie" + +#: data/ui/device-preferences.ui:2394 msgid "Keyboard Shortcuts" msgstr "Raccourcis clavier" -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Associer" - -#: data/device.ui:2183 +#: data/ui/device-preferences.ui:2529 msgid "Device is unpaired" msgstr "L'appareil n'est pas pairé" -#: data/device.ui:2198 +#: data/ui/device-preferences.ui:2544 msgid "You may configure this device before pairing" msgstr "Vous pouvez configurer cet appareil avant le pairage" -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "Mode d'affichage" - -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Barre des tâches" - -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Menu utilisateur" - -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" -msgstr "Générer des logs pour le support" - -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Se connecter en Bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "Se connecter au réseau local" - -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Informations de chiffrement" - -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Dissocier" - #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Vers l'Appareil" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Depuis l'Appareil" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Ne rien faire" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Réduire" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Mettre en sourdine" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Messagerie" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Nouvelle conversation" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Aucune discussion" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "Aucune conversation sélectionnée" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "Choisir ou commencer une discussion" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "L'appareil est déconnecté" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "Aucune discussion" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Envoyer" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "Recherche d'appareils…" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "Nom de l'appareil" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "_Renommer" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "Rafraîchir" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" msgstr "Paramètres" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Modifier le nom de l'appareil" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Appareils" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Recherche d'appareils…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Extensions du navigateur" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Activer" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" msgstr "Cet appareil est invisible par les appareils non pairés" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" msgstr "Découverte désactivée" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Mode d'affichage" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Barre des tâches" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Menu utilisateur" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Générer des logs pour le support" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "À propos de Zorin Connect" + #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "Envoyer un SMS" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Appareils mobiles" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" msgstr[0] "%d Connecté" msgstr[1] "%d Connectés" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Envoyer vers l'appareil mobile" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Ouvrir" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Activé" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Désactivé" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Désactivé" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Définir un raccourci" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Définir" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Entrer un nouveau raccourci pour modifier %s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "Appuyez sur Echap pour annuler ou sur Retour Arrière pour réinitialiser le raccourci clavier." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s est déjà utilisé" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "Une implémentation complète de KDE Connect pour GNOME" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "Mickaël Coiraton " + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "Les messages de dépannage sont enregistrés. Faites le nécessaire pour reproduire le problème puis vérifiez le fichier de log." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Vérifier les logs" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Ordinateur portable" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Smartphone" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Tablette" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "Télévision" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Dissocié" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Déconnecté" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Connecté" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Signaler" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Échec d'authentification" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Erreur réseau" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Cliquer pour l'aide de dépannage" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "Discovery has been disabled due to the number of devices on this network." msgstr "La découverte a été désactivée en raison du nombre de périphériques sur ce réseau." -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "Échec du chargement du greffon %s" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" msgstr "Cliquer pour plus d'informations" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "Composer le numéro" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" msgstr "Partager un fichier" +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Envoyer la notification" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ping" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Faire sonner" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Partager un lien" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "" + #: src/service/device.js:174 msgid "Not available" msgstr "Indisponible" @@ -437,83 +620,69 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "Empreinte %s:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Ordinateur portable" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Smartphone" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Tablette" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Ordinateur de bureau" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Reconnecter" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Paramètres" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Demande d'association depuis %s" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Rejeter" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Accepter" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Faire sonner" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: la batterie est faible" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d %% restant" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Complètement chargé" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Presse-papiers" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Envoyer le presse-papiers" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Récupérer le presse-papiers" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Contact inconnu" @@ -525,54 +694,45 @@ msgid "Mousepad" msgstr "Pavé tactile" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Clavier" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "Logiciels supplémentaires requis" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "Le clavier n'est pas prêt" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Annuler la notification" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Fermer la notification" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Répondre à la notification" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "Envoyer la notification" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" msgstr "" -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Ping" - #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Ping : %s" +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Exécuter des commandes" @@ -589,18 +749,14 @@ msgid "Unmount" msgstr "Démonter" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Tous les fichiers" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Images de la caméra" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "Fichiers" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Partage" @@ -609,85 +765,87 @@ msgid "Share Text" msgstr "Partager du texte" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Partager un lien" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Échec du transfert" + +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" -msgstr "Début du transfert" +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "Réception de « %s » depuis %s" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Transfert réussi" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "Reçu « %s » depuis %s" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Ouvrir le dossier" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Ouvrir le fichier" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "Échec du transfert" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Échec de réception de « %s » depuis %s" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "Texte partagé par %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Envoi de « %s » vers %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "« %s » envoyé vers %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Échec d'envoi de « %s » vers %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Envoyer des fichiers vers %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Ouvrir une fois fini" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Envoyer un lien vers %s" @@ -704,7 +862,7 @@ msgid "Reply SMS" msgstr "Répondre au SMS" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Partager le SMS" @@ -717,105 +875,58 @@ msgstr "Mettre l'appel en sourdine" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Appel entrant" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Appel sortant" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Autre" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Fax" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Travail" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Mobile" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Maison" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Envoyer vers %s" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Ouvrir" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "Activé" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "Désactivé" - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Désactivé" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Définir un raccourci" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Définir" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Entrer un nouveau raccourci pour modifier %s" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Appuyez sur Echap pour annuler ou sur Retour Arrière pour réinitialiser le raccourci clavier." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s est déjà utilisé" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "À l'instant" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -823,17 +934,28 @@ msgstr[1] "%d minutes" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Hier・%s" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "Vous: %s" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "" +msgstr[1] "" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "Sélectionner un appareil" @@ -842,99 +964,63 @@ msgid "Select" msgstr "Sélectionner" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "Dissocié" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Déconnecté" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Connecté" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "Transferred files are placed in the Downloads folder." -msgstr "Les fichiers téléchargés sont enregistrés dans le dossier Downloads ." - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "Une implémentation complète de KDE Connect pour GNOME" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "Mickaël Coiraton " - -#: src/service/ui/settings.js:529 -msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." -msgstr "Les messages de dépannage sont enregistrés. Faites le nécessaire pour reproduire le problème puis vérifiez le fichier de log." - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "Vérifier les logs" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "Complètement chargé" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Aucun appareil trouvé" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d %% (estimation en cours…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d %% (%d∶%02d jusqu'à charge complète)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d %% (%d∶%02d restant)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d heure" +msgstr[1] "%d heures" + +#. TRANSLATORS: Time until change with time duration +#. EXAMPLE: Until 10:00 (2 hours) +#: src/shell/donotdisturb.js:150 +#, javascript-format +msgid "Until %s (%s)" +msgstr "Jusqu'à %s (%s)" + +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 msgid "Do Not Disturb" msgstr "Ne pas déranger" -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" msgstr "Désactiver les notifications de l'appareil mobile" -#: src/shell/donotdisturb.js:171 +#: src/shell/donotdisturb.js:261 msgid "Until you turn off Do Not Disturb" msgstr "Jusqu'à ce que vous désactiviez Ne pas déranger" -#. TRANSLATORS: Time until change with time duration -#. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 -#, javascript-format -msgid "Until %s (%s)" -msgstr "Jusqu'à %s (%s)" - -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Terminé" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d heure" -msgstr[1] "%d heures" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Répondre" @@ -953,11 +1039,6 @@ msgid "Service Unavailable" msgstr "Service indisponible" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Aucun appareil trouvé" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/gl.po gnome-shell-extension-zorin-connect-28.0.2/po/gl.po --- gnome-shell-extension-zorin-connect-24.1/po/gl.po 2019-05-29 12:50:26.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/gl.po 2019-11-30 17:30:20.000000000 +0000 @@ -2,11 +2,11 @@ msgstr "" "Project-Id-Version: zorin-connect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" -"PO-Revision-Date: 2019-05-18 16:34\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-10 11:12\n" "Last-Translator: Andy Holmes (andyholmes)\n" "Language-Team: Galician\n" -"Language: gl\n" +"Language: gl_ES\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -16,411 +16,594 @@ "X-Crowdin-Language: gl\n" "X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Info de cifrado" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Enparellar" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Desemparellar" + #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "Conectar con…" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "Anular" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Conectar" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "Enderezo IP" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Dispositivo bluetooth" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Escriba o número de teléfono ou nome" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "Sen contactos" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Axuda" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Escriba o número de teléfono ou nome" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "Escriba unha mensaxe" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "Enviar mensaxe" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Batería" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Escritorio" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" msgstr "Cámara" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Sincronizar portapapeis" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Reprodutores multimedia" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Rato e teclado" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Control de volume" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Ficheiros" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Compartindo" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Ordes" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Nome" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "Liña de ordes" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Escoller un executábel" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Engadir" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Retirar" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Editar" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Gardar" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Compartir notificacións" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Aplicativos" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Notificacións" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Contactos" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Chamadas entrantes" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Volume" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Deter reprodución" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Chamadas saíntes" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Silenciar micrófono" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Telefonía" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Atallos de acción" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Reiniciar todo…" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Atallos de ordes" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Atallos" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Engadidos" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Experimental" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "Compatibilidade con SMS herdados" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Eliminar" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Eliminar este dispositivo" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Desemparellar e retirar todos os axustes e ficheiros" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Avanzado" -#: data/device.ui:2048 -msgid "Keyboard Shortcuts" -msgstr "Atallos de teclado" - -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Enparellar" - -#: data/device.ui:2183 -msgid "Device is unpaired" -msgstr "O dispositivo non está emparellado" - -#: data/device.ui:2198 -msgid "You may configure this device before pairing" -msgstr "Pode configurar este dispositivo antes do emparellado" +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "" -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "Modo de visualización" +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "" -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Panel" +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "" -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Menú do usuario" +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "" -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" -msgstr "Xerar o rexistro para asistencia" +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "" -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "Verbo de Zorin Connect" +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Batería" -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Trocar para bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "Trocar para LAN" +#: data/ui/device-preferences.ui:2394 +msgid "Keyboard Shortcuts" +msgstr "Atallos de teclado" -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Info de cifrado" +#: data/ui/device-preferences.ui:2529 +msgid "Device is unpaired" +msgstr "O dispositivo non está emparellado" -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Desemparellar" +#: data/ui/device-preferences.ui:2544 +msgid "You may configure this device before pairing" +msgstr "Pode configurar este dispositivo antes do emparellado" #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "A dispositivo" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Do dispositivo" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Ningún" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Baixar" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Silencio" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Mensaxes" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Nova conversa" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Sen conversas" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "Non se seleccionou conversa" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "Seleccionar ou comezar conversa" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "O dispositivo está desconectado" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "Sen conversas" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Enviar" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "Buscando dispositivos…" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "" + +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "Actualizar" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" msgstr "Configuración móbil" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Editar o nome do dispositivo" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Dispositivos" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Buscando dispositivos…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Engadidos de navegador" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Activar" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" msgstr "Este dispositivo é invisíbel para dispositivos non emparellados" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" msgstr "Descuberta desactivada" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Modo de visualización" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Panel" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Menú do usuario" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Xerar o rexistro para asistencia" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "Verbo de Zorin Connect" + #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "Enviar SMS" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Dispositivos móbiles" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" msgstr[0] "%d Conectado" msgstr[1] "%d Conectados" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Enviar a dispositivo móbil" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Abrir" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Aceso" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Apagado" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Desactivado" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Definir atallo" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Definir" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Escribir un novo atallo para cambiar%s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "Premer Esc para anular ou Retroceso para redefinir o atallo de teclado." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s xa está en uso" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "Unha implementación completa de KDE Connect para GNOME" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "tradutor" + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "Estanse a rexistrar as mensaxes de depuración. Faga o necesario para reproducir o problema e logo revise o rexistro." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Revisar o rexistro" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Portátil" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Móbil" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Tableta" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Desemparellado" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Desconectado" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Conectado" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Informar" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Fallo de autenticación" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Erro de rede" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Prema para obter axuda de solucións" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "Discovery has been disabled due to the number of devices on this network." msgstr "A descuberta desactivouse debido ao número de dispositivos nesta rede." -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "O engadido %s fallou ao cargar" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" msgstr "Premer para ter máis información" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "Número en dial" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" msgstr "Compartir ficheiro" +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Enviar a notificación" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Foto" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ping" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Timbre" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Compartir ligazón" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "" + #: src/service/device.js:174 msgid "Not available" msgstr "Non dispoñíbel" @@ -437,83 +620,69 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "Dactilograma %s:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Portátil" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Móbil" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Tableta" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Escritorio" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Reconectar" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Configuración" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Petición de emparellado desde %s" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Rexeitar" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Aceptar" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Timbre" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: A batería está baixa" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "Queda o %d%%" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Carga completa" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Portapapeis" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Entregar do portapapeis" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Recoller no portapapeis" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Contacto descoñecido" @@ -525,54 +694,45 @@ msgid "Mousepad" msgstr "Área de rato" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Teclado" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "Requírese software adicional" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "O teclado non está listo" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Anular a notificación" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Pechar a notificación" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Responder a notificación" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "Enviar a notificación" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" -msgstr "Foto" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Ping" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Ping: %s" +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Executar ordes" @@ -589,18 +749,14 @@ msgid "Unmount" msgstr "Desmontar" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Todos os ficheiros" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Imaxes da cámara" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "Ficheiros" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Compartir" @@ -609,85 +765,87 @@ msgid "Share Text" msgstr "Compartir texto" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Compartir ligazón" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Fallou a transferencia" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" -msgstr "Comezar a transferencia" +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "" + +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "Recibindo \"%s\" de %s" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Transferencia correcta" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "Recibíronse \"%s\" desde %s" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Abrir cartafol" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Abrir ficheiro" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "Fallou a transferencia" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Fallou a recepción de \"%s\" desde %s" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "Texto compartido por %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Enviando \"%s\" a %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "Enviar \"%s\" a %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Fallou o envío de \"%s\" a %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Enviar ficheiros a %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Abrir cando estea feito" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Enviar unha ligazón a %s" @@ -704,7 +862,7 @@ msgid "Reply SMS" msgstr "Responder a SMS" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Compartir SMS" @@ -717,105 +875,58 @@ msgstr "Silenciar chamada" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Chamada entrante" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Chamada en curso" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Outra" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Fax" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Traballo" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Móbil" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Casa" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Enviar a %s" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Abrir" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "Aceso" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "Apagado" - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Desactivado" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Definir atallo" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Definir" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Escribir un novo atallo para cambiar%s" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Premer Esc para anular ou Retroceso para redefinir o atallo de teclado." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s xa está en uso" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Agora mesmo" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -823,17 +934,28 @@ msgstr[1] "%d minutos" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Onte・%s" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "Vostede: %s" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "" +msgstr[1] "" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "Seleccionar un dispositivo" @@ -842,99 +964,63 @@ msgid "Select" msgstr "Seleccionar" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "Desemparellado" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Desconectado" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Conectado" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "Transferred files are placed in the Downloads folder." -msgstr "Os ficheiros transferidos están situados no cartafol Descargas." - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "Unha implementación completa de KDE Connect para GNOME" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "tradutor" - -#: src/service/ui/settings.js:529 -msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." -msgstr "Estanse a rexistrar as mensaxes de depuración. Faga o necesario para reproducir o problema e logo revise o rexistro." - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "Revisar o rexistro" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "Carga completa" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Non se atopou o dispositivo" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (Estímase…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (%d:%02d Ata completar)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (%d:%02d Restante)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d hora" +msgstr[1] "%d horas" + +#. TRANSLATORS: Time until change with time duration +#. EXAMPLE: Until 10:00 (2 hours) +#: src/shell/donotdisturb.js:150 +#, javascript-format +msgid "Until %s (%s)" +msgstr "Ata %s (%s)" + +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 msgid "Do Not Disturb" msgstr "Non molestar" -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" msgstr "Silenciar notificacións no dispositivo móbiil" -#: src/shell/donotdisturb.js:171 +#: src/shell/donotdisturb.js:261 msgid "Until you turn off Do Not Disturb" msgstr "Ata desactivares o modo Non molestar" -#. TRANSLATORS: Time until change with time duration -#. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 -#, javascript-format -msgid "Until %s (%s)" -msgstr "Ata %s (%s)" - -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Feito" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d hora" -msgstr[1] "%d horas" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Responder" @@ -953,11 +1039,6 @@ msgid "Service Unavailable" msgstr "Servizo non dispoñíbel" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Non se atopou o dispositivo" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/hu.po gnome-shell-extension-zorin-connect-28.0.2/po/hu.po --- gnome-shell-extension-zorin-connect-24.1/po/hu.po 2019-03-17 12:30:34.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/hu.po 2019-11-30 17:30:56.000000000 +0000 @@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: org.gnome.Shell.Extensions.ZorinConnect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-08 21:51+0100\n" -"PO-Revision-Date: 2019-03-08 21:53+0100\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-09-22 23:57+0200\n" "Last-Translator: Báthory Péter \n" "Language-Team: \n" "Language: hu\n" @@ -16,414 +16,603 @@ "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.1.1\n" +"X-Generator: Poedit 2.2.1\n" + +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Titkosítási információ" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Párosítás" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Párosítás megszűntetése" #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "Kapcsolódás egy eszközhöz…" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "Mégse" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Csatlakozás" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "IP-cím" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Bluetooth Eszköz" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Adjon meg egy számot vagy nevet" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "Nincsenek névjegyek" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Súgó" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Adjon meg egy számot vagy nevet" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "Írja be az üzenetet" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "Üzenet küldése" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Akkumulátor" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Asztali gép" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" msgstr "Fényképező" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Vágólap szinkronizálás" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Médialejátszók" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Egér és billentyűzet" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Hangerőszabályzó" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Fájlok" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "Fájlok fogadása" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Megosztás" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Parancsok" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Név" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "Parancssor" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Válassz egy programot" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Hozzáadás" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Eltávolítás" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Szerkesztés" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Mentés" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Értesítések megosztása" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Alkalmazások" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Értesítések" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Névjegyek" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Bejövő hívások" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Hangerő" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Média szüneteltetése" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Kimenő hívások" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Mikrofon némítása" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Telefonálás" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Művelet gyorsbillentyűk" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Összes visszaállítása…" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Parancs gyorsbillentyűk" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Gyorsbillentyűk" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Bővítmények" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Kísérleti" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "Régi fajta SMS támogatás" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Törlés" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Eszköz törlése" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Párosítás megszüntetése és az összes beállítás és fájl törlése" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Haladó" -#: data/device.ui:2048 +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "Eszköz akkumulátor" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "Alacsony töltöttség értesítés" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "Teljes töltöttség értesítés" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "Rendszer akkumulátor" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "Statisztikák megosztása" + +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Akkumulátor" + +#: data/ui/device-preferences.ui:2394 msgid "Keyboard Shortcuts" msgstr "Gyorsbillentyűk" -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Párosítás" - -#: data/device.ui:2183 +#: data/ui/device-preferences.ui:2529 msgid "Device is unpaired" msgstr "Az eszköz nincs párosítva" -#: data/device.ui:2198 +#: data/ui/device-preferences.ui:2544 msgid "You may configure this device before pairing" msgstr "Párosítás előtt testreszabhatod az eszközt" -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "Megjelenítési mód" - -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Panel" - -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Felhasználói menü" - -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" -msgstr "Naplófájl készítése terméktámogatáshoz" - -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "A Zorin Connect névjegye" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Váltás Bluetoothra" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "Váltás LAN-ra" - -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Titkosítási információ" - -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Párosítás megszűntetése" - #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Eszközre" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Eszközről" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Semmi" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Halkítás" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Némítás" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Üzenetküldés" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Új beszélgetés" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Nincsenek beszélgetések" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "Nincs kiválasztva beszélgetés" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "Indíts, vagy válassz ki egy beszélgetést" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Az eszköz nincs csatlakoztatva" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "Nincsenek beszélgetések" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Küldés" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "Eszközök keresése…" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "Eszköz neve" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "_Átnevezés" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "Frissítés" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" msgstr "Mobil beállítások" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Eszköz nevének szerkesztése" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Eszközök" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Eszközök keresése…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Böngésző bővítmények" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Engedélyez" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" msgstr "Ez az eszköz nem látható a párosítatlan eszközök számára" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" msgstr "Felderítés letiltva" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Megjelenítési mód" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Panel" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Felhasználói menü" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Naplófájl készítése terméktámogatáshoz" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "A Zorin Connect névjegye" + #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "SMS küldése" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Mobil eszközök" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "Bekapcsolás" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" msgstr[0] "Egy eszköz csatlakoztatva" msgstr[1] "%d eszköz csatlakoztatva" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "Kikapcsolás" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Küldés mobil eszközre" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Megnyitás" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Be" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Ki" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Letiltva" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Gyorsbillentyű beállítása" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Kiválasztás" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "%s megváltoztatásához adj meg egy új gyorsbillentyűt" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "" +"A megszakításhoz nyomj Esc gombot, vagy Backspace-t a gyorsbillentyű " +"visszaállításához." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s már használatban van" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "Teljes KDE Connect implementáció GNOME-hoz" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "Báthory Péter " + +#: src/preferences/service.js:430 +msgid "" +"Debug messages are being logged. Take any steps necessary to reproduce a " +"problem then review the log." +msgstr "" +"A hibakeresési üzenetek naplózásra kerülnek. Csinálj a hiba reprodukálásához " +"szükséges lépést, majd nézd át a naplót." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Napló átnézése" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Laptop" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Okostelefon" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Táblagép" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "TV" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Nincs párosítva" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Nincs csatlakoztatva" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Csatlakoztatva" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "Várakozás a szolgáltatásra…" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Jelentés" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Hitelesítési hiba" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Hálózati hiba" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Kattintson ide, hogy segítséget kapj a hibaelhárításhoz" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "" "Discovery has been disabled due to the number of devices on this network." msgstr "A felderítés le lett tiltva a hálózaton lévő eszközök száma miatt." -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "%s bővítményt nem sikerült betölteni" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" msgstr "További információért kattintson ide" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "Telefonszám hívása" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" msgstr "Fájl megosztása" +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "Elérhető eszközök listázása" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "Összes eszköz listázása" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "Cél eszköz" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "Üzenet szövege" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Értesítés küldése" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "Értesítés alkalmazásnév" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "Értesítés törzs" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "Értesítés ikon" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "Értesítés ID" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Fotó" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ping" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Csörgetés" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Hivatkozás megosztása" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "Kiadás verziószám megjelenítése" + #: src/service/device.js:174 msgid "Not available" msgstr "Nem érhető el" @@ -440,84 +629,69 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "%s ujjlenyomat:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Laptop" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Okostelefon" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Táblagép" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Asztali gép" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Újracsatlakozás" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Beállítások" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Párosítási kérelem innen: %s" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Elutasítás" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Elfogadás" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Csörgés" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: alacsony töltöttség" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d%% van hátra" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "%s: Akkumulátor feltöltve" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Teljesen feltöltve" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Vágólap" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Vágólap küldés" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Vágólap fogadás" #. Ensure we have a sender #. TRANSLATORS: No name or phone number #. HACK: fix missing contact names -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Ismeretlen névjegy" @@ -529,54 +703,46 @@ msgid "Mousepad" msgstr "Egérpad" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Billentyűzet" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "További szoftverre van szükség" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "A billentyűzet nem áll készen" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Értesítés megszakítása" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Értesítés bezárása" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Értesítések küldése" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "Értesítés küldése" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" -msgstr "Fotó" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Ping" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "Értesítés aktiválása" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Ping: %s" +#: src/service/plugins/presenter.js:9 +#, fuzzy +msgid "Presentation" +msgstr "Fájlkezelő integráció" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Parancsok futtatása" @@ -593,18 +759,14 @@ msgid "Unmount" msgstr "Leválasztás" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Összes fájl" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Kamera fényképek" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "Fájlok" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Megosztás" @@ -613,85 +775,87 @@ msgid "Share Text" msgstr "Szöveg megosztása" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Hivatkozás megosztása" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Sikertelen átvitel" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" -msgstr "Átvitel megkezdése" +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "% számára nem engedélyezett a fájlok feltöltése" + +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "Fájl átvitele" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "„%s” fogadása innen: %s" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Sikeres átvitel" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "„%s” fogadva innen: %s" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Könyvtár megnyitása" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Fájl megnyitása" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "Sikertelen átvitel" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "„%s” fogadása %s eszközről nem sikerült" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "%s által megosztott szöveg" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "„%s” küldése ide: %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "„%s” elküldve ide: %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "„%s” küldése %s eszközre nem sikerült" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Fájlok küldése ide: %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Megnyitás ha kész" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Hivatkozás küldése ide: %s" @@ -708,7 +872,7 @@ msgid "Reply SMS" msgstr "SMS válasz" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "SMS megosztása" @@ -721,107 +885,58 @@ msgstr "Hívás némítása" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Bejövő hívás" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Kimenő hívás" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Egyéb" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Fax" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Munkahelyi" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Mobil" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Otthoni" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Küldés neki: %s" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Megnyitás" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "Be" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "Ki" - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Letiltva" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Gyorsbillentyű beállítása" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Kiválasztás" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "%s megváltoztatásához adj meg egy új gyorsbillentyűt" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "" -"A megszakításhoz nyomj Esc gombot, vagy Backspace-t a gyorsbillentyű " -"visszaállításához." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s már használatban van" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Épp most" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -829,17 +944,28 @@ msgstr[1] "%d perc" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Tegnap・%s" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "Csoportos üzenet" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "Te: %s" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "És %d másik névjegy" +msgstr[1] "És további %d" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "Eszköz kiválasztása" @@ -848,105 +974,63 @@ msgid "Select" msgstr "Kiválasztás" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "Nincs párosítva" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Nincs csatlakoztatva" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Csatlakoztatva" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "" -"Transferred files are placed in the Downloads folder." -msgstr "" -"Az átküldött fájlok a Letöltések könyvtárban találhatók." - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "Teljes KDE Connect implementáció GNOME-hoz" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "Báthory Péter " - -#: src/service/ui/settings.js:529 -msgid "" -"Debug messages are being logged. Take any steps necessary to reproduce a " -"problem then review the log." -msgstr "" -"A hibakeresési üzenetek naplózásra kerülnek. Csinálj a hiba reprodukálásához " -"szükséges lépést, majd nézd át a naplót." - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "Napló átnézése" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "Teljesen feltöltve" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Nem található eszköz" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (becslés…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (%d∶%02d a feltöltésig)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (%d∶%02d van hátra)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d óra" +msgstr[1] "%d óra" + +#. TRANSLATORS: Time until change with time duration +#. EXAMPLE: Until 10:00 (2 hours) +#: src/shell/donotdisturb.js:150 +#, javascript-format +msgid "Until %s (%s)" +msgstr "%s-ig (%s)" + +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 msgid "Do Not Disturb" msgstr "Ne zavarjanak" -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" msgstr "Mobileszköz értesítéseinek némítása" -#: src/shell/donotdisturb.js:171 +#: src/shell/donotdisturb.js:261 msgid "Until you turn off Do Not Disturb" msgstr "Amíg ön ki nem kapcsolja a Ne zavarjanak funkciót" -#. TRANSLATORS: Time until change with time duration -#. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 -#, javascript-format -msgid "Until %s (%s)" -msgstr "%s-ig (%s)" - -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Kész" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d óra" -msgstr[1] "%d óra" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Válasz" @@ -966,11 +1050,6 @@ msgid "Service Unavailable" msgstr "A szolgáltatás nem érhető el" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Nem található eszköz" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" @@ -979,6 +1058,48 @@ msgid "Mobile Application" msgstr "Mobilos alkalmazás" +#~ msgid "Bluetooth Device" +#~ msgstr "Bluetooth Eszköz" + +#~ msgid "Command Shortcuts" +#~ msgstr "Parancs gyorsbillentyűk" + +#~ msgid "Delete" +#~ msgstr "Törlés" + +#~ msgid "Delete this device" +#~ msgstr "Eszköz törlése" + +#~ msgid "Unpair and remove all settings and files" +#~ msgstr "Párosítás megszüntetése és az összes beállítás és fájl törlése" + +#~ msgid "Switch to Bluetooth" +#~ msgstr "Váltás Bluetoothra" + +#~ msgid "Switch to LAN" +#~ msgstr "Váltás LAN-ra" + +#~ msgid "%s Plugin Failed To Load" +#~ msgstr "%s bővítményt nem sikerült betölteni" + +#~ msgid "Reconnect" +#~ msgstr "Újracsatlakozás" + +#~ msgid "Settings" +#~ msgstr "Beállítások" + +#~ msgid "Additional Software Required" +#~ msgstr "További szoftverre van szükség" + +#~ msgid "Starting Transfer" +#~ msgstr "Átvitel megkezdése" + +#~ msgid "" +#~ "Transferred files are placed in the Downloads folder." +#~ msgstr "" +#~ "Az átküldött fájlok a Letöltések könyvtárban " +#~ "találhatók." + #~ msgid "About" #~ msgstr "Névjegy" @@ -1012,9 +1133,6 @@ #~ msgid "Desktop Contacts" #~ msgstr "Asztali névjegyek" -#~ msgid "Files Integration" -#~ msgstr "Fájlkezelő integráció" - #~ msgid "Additional Features" #~ msgstr "További funkciók" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/it.po gnome-shell-extension-zorin-connect-28.0.2/po/it.po --- gnome-shell-extension-zorin-connect-24.1/po/it.po 2019-05-29 12:51:06.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/it.po 2019-11-30 17:31:09.000000000 +0000 @@ -2,11 +2,11 @@ msgstr "" "Project-Id-Version: zorin-connect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" -"PO-Revision-Date: 2019-05-18 10:54\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-11 06:25\n" "Last-Translator: Andy Holmes (andyholmes)\n" "Language-Team: Italian\n" -"Language: it\n" +"Language: it_IT\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -16,411 +16,594 @@ "X-Crowdin-Language: it\n" "X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Informazioni di criptazione" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Accoppia" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Disaccoppia" + #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "Connetti a…" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "Annulla" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Connetti" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "Indirizzo IP" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Dispositivo Bluetooth" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Digita un numero di telefono o un nome" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "Nessun contatto" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Aiuto" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Digita un numero di telefono o un nome" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "Digita un messaggio" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "Invia un messaggio" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Batteria" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Desktop" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" msgstr "Fotocamera" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Sincronizzazione appunti" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Riproduzione multimediale" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Mouse e tastiera" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Controllo volume" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "File" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "Ricezione file" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Condivisione" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Comandi" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Nome" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "Linea di comando" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Seleziona un eseguibile" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Aggiungi" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Rimuovi" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Modifica" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Salva" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Condividi notifiche" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "Condividi quando attivo" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Applicazioni" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Notifiche" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Contatti" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Chiamate in entrata" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Volume" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Metti in pausa il media" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Chiamate in uscita" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Silenzia il microfono" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Telefonia" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Scorciatoie azioni" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Ripristina tutte…" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Scorciatoie comandi" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Scorciatoie" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Plugin" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Sperimentale" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "Supporto SMS legacy" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Elimina" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Elimina questo dispositivo" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Disaccoppia e rimuovi impostazioni e file" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Avanzate" -#: data/device.ui:2048 +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "Batteria del dispositivo" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "Notifica di batteria scarica" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "Notifica di ricarica completa" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "Batteria di sistema" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "Condivisione statistiche" + +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Batteria" + +#: data/ui/device-preferences.ui:2394 msgid "Keyboard Shortcuts" msgstr "Scorciatoie da tastiera" -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Accoppia" - -#: data/device.ui:2183 +#: data/ui/device-preferences.ui:2529 msgid "Device is unpaired" msgstr "Il dispositivo è disaccoppiato" -#: data/device.ui:2198 +#: data/ui/device-preferences.ui:2544 msgid "You may configure this device before pairing" msgstr "È possibile configurare questo dispositivo prima dell'accoppiamento" -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "Modalità di visualizzazione" - -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Pannello" - -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Menu utente" - -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" -msgstr "Genera log di supporto" - -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "Info su Zorin Connect" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Passa a Bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "Passa a LAN" - -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Informazioni di criptazione" - -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Disaccoppia" - #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Al dispositivo" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Dal dispositivo" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Niente" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Riduci" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Silenzia" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Messaggi" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Nuova conversazione" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Nessuna conversazione" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "Nessuna conversazione selezionata" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "Seleziona o inizia una conversazione" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Il dispositivo è disconnesso" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "Nessuna conversazione" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Invia" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "Ricerca dei dispositivi…" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "Nome del dispositivo" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "_Rinomina" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "Aggiorna" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" msgstr "Impostazioni mobile" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Modifica il nome del dispositivo" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Dispositivi" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Ricerca dei dispositivi…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Estensioni browser" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Abilita" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" msgstr "Questo dispositivo è invisibile ai dispositivi disaccoppiati" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" msgstr "Ricerca disattiva" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Modalità di visualizzazione" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Pannello" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Menu utente" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Genera log di supporto" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "Informazioni su Zorin Connect" + #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "Invia SMS" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Dispositivi mobili" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "Attiva" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" msgstr[0] "%d connesso" msgstr[1] "%d connessi" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "Disattiva" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Invia al dispositivo mobile" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Apri" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "On" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Off" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Disabilitato" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Imposta scorciatoia" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Imposta" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Inserisci una nuova scorciatoia per %s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "Premi ESC per annullare o Backspace per ripristinare la scorciatoia." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s già in uso" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "Un'implementazione completa di KDE Connect per GNOME" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "Jimmy Scionti " + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "I messaggi di debug vengono registrati. Adotta tutte le misure necessarie per riprodurre un problema, quindi rivedi il registro." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Log delle Revisioni" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Laptop" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Smartphone" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Tablet" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "Televisione" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Disaccoppiato" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Disconnesso" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Connesso" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "In attesa del servizio…" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Segnalazione" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Autenticazione fallita" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Errore di rete" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Click per la risoluzione del problema" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "Discovery has been disabled due to the number of devices on this network." msgstr "La ricerca è stata disattivata a causa dell'elevato numero di dispositivi nella rete." -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "Fallito caricamento del plugin %s" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" msgstr "Click per altre informazioni" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "Componi numero" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" msgstr "Invia file" +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "Elenco dei dispositivi disponibili" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "Elenco di tutti i dispositivi" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "Dispositivo di destinazione" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "Corpo del messaggio" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Invia notifica" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "Nome app di notifica" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "Corpo della notifica" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "Icona di notifica" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "ID della notifica" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Foto" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ping" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Squilla" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Condividi collegamento" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "Mostrare versione di rilascio" + #: src/service/device.js:174 msgid "Not available" msgstr "Non disponibile" @@ -437,83 +620,69 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "%s fingerprint:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Laptop" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Smartphone" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Tablet" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Desktop" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Riconnetti" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Impostazioni" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Richiesta di accoppiamento da %s" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Rifiuta" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Accetta" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Squilla" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: batteria quasi scarica" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d%% rimanenti" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "%s: la batteria è carica" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Completamente carica" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Appunti" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Invia appunti" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Ricevi appunti" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Contatto sconosciuto" @@ -525,54 +694,45 @@ msgid "Mousepad" msgstr "Mousepad" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Tastiera" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "Software addizionale richiesto" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "Tastiera non pronta" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Cancella notifica" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Chiudi notifica" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Rispondi alla notifica" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "Invia notifica" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" -msgstr "Foto" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Ping" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "Attivare le notifiche" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Ping: %s" +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "Presentazione" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Esegui comandi" @@ -589,18 +749,14 @@ msgid "Unmount" msgstr "Smonta" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Tutti i file" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Immagini fotocamera" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "File" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Invia file" @@ -609,85 +765,87 @@ msgid "Share Text" msgstr "Invia testo" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Condividi collegamento" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Trasferimento fallito" + +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "%s non può caricare file" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" -msgstr "Avvia trasferimento" +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "Trasferimento file" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "Ricezione in corso di \"%s\" da %s" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Trasferimento riuscito" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "Ricevuto \"%s\" da %s" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Apri cartella" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Apri file" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "Trasferimento fallito" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Ricezione fallita di \"%s\" da %s" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "Testo condiviso da %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Invio in corso di \"%s\" a %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "\"%s\" inviato a %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Invio fallito di \"%s\" a %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Invia file a %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Apri al termine" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Invia collegamento a %s" @@ -704,7 +862,7 @@ msgid "Reply SMS" msgstr "Rispondi all'SMS" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Condividi SMS" @@ -717,105 +875,58 @@ msgstr "Silenzia chiamata" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Chiamata in arrivo" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Chiamata in corso" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Altro" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Fax" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Lavoro" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Mobile" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Casa" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Invia a %s" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Apri" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "On" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "Off" - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Disabilitato" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Imposta scorciatoia" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Imposta" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Inserisci una nuova scorciatoia per %s" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Premi ESC per annullare o Backspace per ripristinare la scorciatoia." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s già in uso" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Proprio ora" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -823,17 +934,28 @@ msgstr[1] "%d minuti" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Ieri・%s" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "Messaggio di gruppo" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "Tu: %s" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "E %d altro contatto" +msgstr[1] "E altri %d" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "Seleziona un dispositivo" @@ -842,99 +964,63 @@ msgid "Select" msgstr "Seleziona" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "Disaccoppiato" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Disconnesso" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Connesso" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "Transferred files are placed in the Downloads folder." -msgstr "I file trasferiti sono collocati nella cartella Scaricati." - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "Un'implementazione completa di KDE Connect per GNOME" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "Jimmy Scionti " - -#: src/service/ui/settings.js:529 -msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." -msgstr "I messaggi di debug vengono registrati. Adotta tutte le misure necessarie per riprodurre un problema, quindi rivedi il registro." - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "Log delle Revisioni" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "Completamente carica" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Dispositivo non trovato" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (Stima…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (%d∶%02d Al completamento)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (%d∶%02d Rimanenti)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 -msgid "Do Not Disturb" -msgstr "Non disturbare" - -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" -msgstr "Silenzia le notifiche del dispositivo mobile" - -#: src/shell/donotdisturb.js:171 -msgid "Until you turn off Do Not Disturb" -msgstr "Fino a quando non disattivi Non disturbare" +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d ora" +msgstr[1] "%d ore" #. TRANSLATORS: Time until change with time duration #. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 +#: src/shell/donotdisturb.js:150 #, javascript-format msgid "Until %s (%s)" msgstr "Fino alle %s (%s)" -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 +msgid "Do Not Disturb" +msgstr "Non disturbare" + +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" +msgstr "Silenziare le notifiche dai dispositivi mobili" + +#: src/shell/donotdisturb.js:261 +msgid "Until you turn off Do Not Disturb" +msgstr "Fino a quando non disattivi Non disturbare" + +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Fatto" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d ora" -msgstr[1] "%d ore" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Rispondi" @@ -953,11 +1039,6 @@ msgid "Service Unavailable" msgstr "Servizio non disponibile" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Dispositivo non trovato" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/ja.po gnome-shell-extension-zorin-connect-28.0.2/po/ja.po --- gnome-shell-extension-zorin-connect-24.1/po/ja.po 2019-03-17 12:32:02.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/ja.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,982 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the org.gnome.Shell.Extensions.ZorinConnect package. -# FIRST AUTHOR , YEAR. -# -msgid "" -msgstr "" -"Project-Id-Version: org.gnome.Shell.Extensions.ZorinConnect\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-19 11:14-0800\n" -"PO-Revision-Date: 2018-05-24 00:30+0900\n" -"Last-Translator: \n" -"Language-Team: \n" -"Language: ja\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: Poedit 2.0.6\n" - -#: data/conversation.ui:71 data/conversation.ui:79 -#, fuzzy -msgid "Type a message" -msgstr "SMSメッセージを入力" - -#: data/contacts.ui:51 data/contacts.ui:52 -msgid "Type a phone number or name" -msgstr "電話番号または名前を入力" - -#: data/device.ui:68 src/service/plugins/battery.js:12 -msgid "Battery" -msgstr "電池" - -#: data/device.ui:116 -#, fuzzy -msgid "Clipboard Sync" -msgstr "クリップボード" - -#: data/device.ui:172 -#, fuzzy -msgid "Media Players" -msgstr "メディアプレーヤーコントロール" - -#: data/device.ui:220 -msgid "Mouse & Keyboard" -msgstr "" - -#: data/device.ui:268 -msgid "Volume Control" -msgstr "" - -#: data/device.ui:308 data/device.ui:1406 -#, fuzzy -msgid "Sharing" -msgstr "リンクを共有" - -#: data/device.ui:337 data/device.ui:534 data/device.ui:1449 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:169 -#, fuzzy -msgid "Commands" -msgstr "コマンド" - -#: data/device.ui:385 -msgid "Name" -msgstr "名前" - -#: data/device.ui:401 data/device.ui:402 -msgid "Choose an executable" -msgstr "" - -#: data/device.ui:403 -#, fuzzy -msgid "Command Line" -msgstr "コマンド" - -#: data/device.ui:597 -#, fuzzy -msgid "Share Notifications" -msgstr "通知を送信" - -#: data/device.ui:636 -msgid "Applications" -msgstr "アプリケーション" - -#: data/device.ui:675 data/device.ui:1492 -#: src/service/plugins/notification.js:12 -msgid "Notifications" -msgstr "通知" - -#: data/device.ui:705 -msgid "Incoming Calls" -msgstr "着信中" - -#: data/device.ui:755 data/device.ui:900 -#, fuzzy -msgid "Volume" -msgstr "システムの音量" - -#: data/device.ui:813 data/device.ui:958 -msgid "Pause Media" -msgstr "メディアを一時停止" - -#: data/device.ui:852 -#, fuzzy -msgid "Ongoing Calls" -msgstr "着信中" - -#: data/device.ui:1007 -msgid "Mute Microphone" -msgstr "マイクをミュート" - -#: data/device.ui:1047 data/device.ui:1535 src/service/plugins/telephony.js:12 -msgid "Telephony" -msgstr "電話" - -#: data/device.ui:1082 -#, fuzzy -msgid "Action Shortcuts" -msgstr "キーボードショートカット" - -#: data/device.ui:1094 data/device.ui:1157 -msgid "Reset All…" -msgstr "" - -#: data/device.ui:1145 -#, fuzzy -msgid "Command Shortcuts" -msgstr "キーボードショートカット" - -#: data/device.ui:1203 -#, fuzzy -msgid "Shortcuts" -msgstr "キーボードショートカット" - -#: data/device.ui:1234 -msgid "Plugins" -msgstr "プラグイン" - -#: data/device.ui:1295 -msgid "Delete" -msgstr "" - -#: data/device.ui:1320 -#, fuzzy -msgid "Delete this device" -msgstr "%sがこの端末を探すよう要求しました" - -#: data/device.ui:1335 -msgid "Unpair and remove all settings and files" -msgstr "" - -#: data/device.ui:1365 data/device.ui:1621 -msgid "Advanced" -msgstr "" - -#: data/device.ui:1578 -#, fuzzy -msgid "Keyboard Shortcuts" -msgstr "キーボードショートカット" - -#. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/menus.ui:7 src/service/ui/service.js:115 -#, fuzzy -msgid "Connect to…" -msgstr "Zorin Connect" - -#: data/menus.ui:13 data/settings.ui:881 -msgid "Help" -msgstr "" - -#. TRANSLATORS: Open the developer's dialog -#: data/menus.ui:19 -#, fuzzy -msgid "Debugger" -msgstr "デバッグモード" - -#: data/menus.ui:23 -msgid "About" -msgstr "概要" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:34 -msgid "Switch to Bluetooth" -msgstr "" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:41 -msgid "Switch to LAN" -msgstr "" - -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:48 src/service/ui/settings.js:612 -msgid "Encryption Info" -msgstr "" - -#. TRANSLATORS: Send a pair request to the device -#: data/menus.ui:53 src/service/device.js:425 -msgid "Pair" -msgstr "" - -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:59 src/service/device.js:433 -#, fuzzy -msgid "Unpair" -msgstr "ペア解除した端末を表示" - -#. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:71 -#, fuzzy -msgid "To Device" -msgstr "端末" - -#. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:77 -#, fuzzy -msgid "From Device" -msgstr "端末を探す" - -#. TRANSLATORS: Don't change the system volume -#: data/menus.ui:89 data/menus.ui:115 -msgid "Nothing" -msgstr "何もしない" - -#. TRANSLATORS: Lower the system volume -#: data/menus.ui:96 data/menus.ui:122 -msgid "Lower" -msgstr "下げる" - -#. TRANSLATORS: Mute the system volume -#. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:103 data/menus.ui:129 src/service/plugins/telephony.js:176 -msgid "Mute" -msgstr "ミュート" - -#: data/messaging.ui:12 src/service/plugins/sms.js:25 -#: src/service/ui/messaging.js:871 -#, fuzzy -msgid "Messaging" -msgstr "メッセージ" - -#: data/messaging.ui:110 -#, fuzzy -msgid "Select a conversation" -msgstr "他の人を招待して会議を始める" - -#: data/messaging.ui:188 -msgid "Device is disconnected" -msgstr "端末は切断" - -#: data/settings.ui:333 -msgid "Appearance" -msgstr "外観" - -#: data/settings.ui:383 -msgid "Display Mode" -msgstr "" - -#: data/settings.ui:425 -#, fuzzy -msgid "Service" -msgstr "端末" - -#: data/settings.ui:475 -msgid "Discoverable" -msgstr "" - -#: data/settings.ui:528 -#, fuzzy -msgid "Restart Service" -msgstr "端末" - -#: data/settings.ui:581 data/settings.ui:1015 src/service/device.js:417 -#, fuzzy -msgid "Settings" -msgstr "モバイル設定" - -#: data/settings.ui:639 -msgid "Remote Filesystems" -msgstr "" - -#: data/settings.ui:675 -msgid "Sound Effects" -msgstr "" - -#: data/settings.ui:712 -#, fuzzy -msgid "Extended Keyboard Support" -msgstr "キーボードショートカット" - -#: data/settings.ui:749 -#, fuzzy -msgid "Desktop Contacts" -msgstr "不明な連絡先" - -#: data/settings.ui:786 -#, fuzzy -msgid "Files Integration" -msgstr "Nautilus統合" - -#: data/settings.ui:813 -msgid "Additional Features" -msgstr "" - -#: data/settings.ui:903 -msgid "Browser Add-Ons" -msgstr "" - -#: data/settings.ui:921 -#, fuzzy -msgid "KDE Connect" -msgstr "Zorin Connect" - -#: data/settings.ui:956 data/settings.ui:1058 -msgid "Other" -msgstr "その他" - -#. TRANSLATORS: No devices are known or available -#: data/settings.ui:1106 webextension/gettext.js:35 -#, fuzzy -msgid "No Device Found" -msgstr "端末はペア解除" - -#: data/settings.ui:1142 -msgid "Refresh" -msgstr "更新" - -#. Service Menu -#: src/extension.js:79 src/extension.js:259 -msgid "Mobile Devices" -msgstr "モバイル端末" - -#: src/extension.js:105 -msgid "Mobile Settings" -msgstr "モバイル設定" - -#. TRANSLATORS: Extension name -#: src/extension.js:196 src/extension.js:311 src/service/daemon.js:95 -#: src/service/daemon.js:413 webextension/gettext.js:27 -msgid "Zorin Connect" -msgstr "Zorin Connect" - -#. TRANSLATORS: %d is the number of devices connected -#: src/extension.js:257 -#, fuzzy, javascript-format -msgid "%d Connected" -msgid_plural "%d Connected" -msgstr[0] "Zorin Connect" - -#. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:112 webextension/gettext.js:31 -msgid "Send To Mobile Device" -msgstr "モバイル端末に送信" - -#: src/service/daemon.js:406 -#, fuzzy -msgid "A complete KDE Connect implementation for GNOME" -msgstr "GNOME Shellと統合されたKDE Connectの実装" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/daemon.js:415 -msgid "translator-credits" -msgstr "" - -#: src/service/daemon.js:437 -msgid "Report" -msgstr "" - -#: src/service/daemon.js:567 -msgid "Authentication Failure" -msgstr "" - -#: src/service/daemon.js:576 -msgid "Network Error" -msgstr "" - -#: src/service/daemon.js:577 src/service/daemon.js:587 -msgid "Click for help troubleshooting" -msgstr "" - -#: src/service/daemon.js:586 -msgid "PulseAudio Error" -msgstr "" - -#: src/service/daemon.js:596 -msgid "Discovery Disabled" -msgstr "" - -#: src/service/daemon.js:597 -msgid "" -"Discovery has been disabled due to the number of devices on this network." -msgstr "" - -#: src/service/daemon.js:599 src/service/daemon.js:609 -msgid "Click to open preferences" -msgstr "" - -#: src/service/daemon.js:608 -msgid "Additional Software Required" -msgstr "" - -#: src/service/daemon.js:617 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "" - -#: src/service/daemon.js:618 src/service/daemon.js:635 -msgid "Click for more information" -msgstr "" - -#: src/service/daemon.js:633 -msgid "Wayland Not Supported" -msgstr "" - -#: src/service/daemon.js:634 -msgid "Remote input not supported on Wayland" -msgstr "" - -#. Create an urgent notification -#: src/service/daemon.js:658 -#, fuzzy, javascript-format -msgid "Zorin Connect: %s" -msgstr "Zorin Connect" - -#. TRANSLATORS: Share URL by SMS -#: src/service/daemon.js:808 src/service/plugins/sms.js:49 -#: webextension/gettext.js:39 -msgid "Send SMS" -msgstr "SMSを送信" - -#: src/service/daemon.js:812 -#, fuzzy -msgid "Dial Number" -msgstr "電話番号をダイヤル" - -#: src/service/device.js:166 -#, fuzzy -msgid "Not available" -msgstr "Gvcが利用できません" - -#. TRANSLATORS: Bluetooth address for remote device -#: src/service/device.js:170 -#, javascript-format -msgid "Bluetooth device at %s" -msgstr "" - -#. TRANSLATORS: Label for TLS Certificate fingerprint -#. -#. Example: -#. -#. Google Pixel Fingerprint: -#. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:188 src/service/device.js:190 -#, javascript-format -msgid "%s Fingerprint:" -msgstr "" - -#: src/service/device.js:240 -msgid "Laptop" -msgstr "ラップトップ" - -#: src/service/device.js:242 -msgid "Smartphone" -msgstr "スマートフォン" - -#: src/service/device.js:244 -msgid "Tablet" -msgstr "タブレット" - -#: src/service/device.js:246 -msgid "Desktop" -msgstr "デスクトップ" - -#: src/service/device.js:409 -#, fuzzy -msgid "Reconnect" -msgstr "Zorin Connect" - -#. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:606 -#, javascript-format -msgid "Pair Request from %s" -msgstr "%sからのペアリクエスト" - -#: src/service/device.js:613 -msgid "Reject" -msgstr "拒否" - -#: src/service/device.js:618 -msgid "Accept" -msgstr "承認" - -#: src/service/plugins/battery.js:194 src/service/plugins/findmyphone.js:18 -#, fuzzy -msgid "Ring" -msgstr "探す" - -#. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:203 -#, javascript-format -msgid "%s: Battery is low" -msgstr "" - -#. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:205 -#, fuzzy, javascript-format -msgid "%d%% remaining" -msgstr "%d%% (残り %d∶%02d)" - -#: src/service/plugins/clipboard.js:11 -msgid "Clipboard" -msgstr "クリップボード" - -#: src/service/plugins/clipboard.js:17 -#, fuzzy -msgid "Clipboard Push" -msgstr "クリップボード" - -#: src/service/plugins/clipboard.js:25 -#, fuzzy -msgid "Clipboard Pull" -msgstr "クリップボード" - -#: src/service/plugins/contacts.js:12 -#, fuzzy -msgid "Contacts" -msgstr "不明な連絡先" - -#: src/service/plugins/findmyphone.js:12 -msgid "Find My Phone" -msgstr "" - -#: src/service/plugins/findmyphone.js:65 -msgid "Locate Device" -msgstr "端末を探す" - -#: src/service/plugins/findmyphone.js:66 -#, javascript-format -msgid "%s asked to locate this device" -msgstr "%sがこの端末を探すよう要求しました" - -#: src/service/plugins/findmyphone.js:74 -msgid "Found" -msgstr "発見" - -#: src/service/plugins/mousepad.js:14 -msgid "Mousepad" -msgstr "" - -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:578 -#, fuzzy -msgid "Keyboard" -msgstr "キーボードショートカット" - -#: src/service/plugins/mousepad.js:595 -#, fuzzy -msgid "Keyboard not ready" -msgstr "キーボードショートカット" - -#: src/service/plugins/mpris.js:10 -msgid "MPRIS" -msgstr "" - -#: src/service/plugins/notification.js:25 -#, fuzzy -msgid "Cancel Notification" -msgstr "通知を送信" - -#: src/service/plugins/notification.js:33 -#, fuzzy -msgid "Close Notification" -msgstr "通知を送信" - -#: src/service/plugins/notification.js:41 -#, fuzzy -msgid "Reply Notification" -msgstr "通知を送信" - -#: src/service/plugins/notification.js:49 -#, fuzzy -msgid "Send Notification" -msgstr "通知を送信" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Ping" - -#. TRANSLATORS: An optional message accompanying a ping, rarely if ever used -#. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 -#, javascript-format -msgid "Ping: %s" -msgstr "Ping: %s" - -#: src/service/plugins/runcommand.js:12 -msgid "Run Commands" -msgstr "コマンドを実行" - -#: src/service/plugins/sftp.js:12 -msgid "SFTP" -msgstr "" - -#: src/service/plugins/sftp.js:18 -#, fuzzy -msgid "Mount" -msgstr "アンマウント" - -#: src/service/plugins/sftp.js:26 -msgid "Unmount" -msgstr "アンマウント" - -#: src/service/plugins/sftp.js:170 -msgid "All files" -msgstr "" - -#: src/service/plugins/sftp.js:171 -msgid "Camera pictures" -msgstr "" - -#: src/service/plugins/sftp.js:333 -msgid "Files" -msgstr "" - -#: src/service/plugins/share.js:12 src/service/plugins/share.js:18 -msgid "Share" -msgstr "共有" - -#: src/service/plugins/share.js:26 -#, fuzzy -msgid "Share File" -msgstr "ファイル/URLを共有" - -#: src/service/plugins/share.js:34 -#, fuzzy -msgid "Share Text" -msgstr "共有" - -#: src/service/plugins/share.js:42 src/service/ui/messaging.js:903 -#: src/service/ui/messaging.js:911 -msgid "Share Link" -msgstr "リンクを共有" - -#: src/service/plugins/share.js:131 src/service/plugins/share.js:282 -msgid "Starting Transfer" -msgstr "転送開始" - -#. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:133 -#, javascript-format -msgid "Receiving “%s” from %s" -msgstr "「%s」を%sから受信しています" - -#. Action Buttons -#: src/service/plugins/share.js:138 src/service/plugins/share.js:289 -#: src/service/plugins/share.js:407 src/service/ui/keybindings.js:44 -#: src/service/ui/service.js:121 src/service/ui/service.js:300 -#: src/service/ui/settings.js:873 src/shell/donotdisturb.js:215 -msgid "Cancel" -msgstr "キャンセル" - -#: src/service/plugins/share.js:149 src/service/plugins/share.js:303 -msgid "Transfer Successful" -msgstr "転送成功" - -#. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:151 -#, javascript-format -msgid "Received “%s” from %s" -msgstr "「%s」を%sから受信しました" - -#: src/service/plugins/share.js:157 -msgid "Open Folder" -msgstr "フォルダーを開く" - -#: src/service/plugins/share.js:162 -msgid "Open File" -msgstr "ファイルを開く" - -#: src/service/plugins/share.js:169 src/service/plugins/share.js:311 -msgid "Transfer Failed" -msgstr "転送失敗" - -#. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:171 -#, fuzzy, javascript-format -msgid "Failed to receive “%s” from %s" -msgstr "「%s」を%sから受信失敗: %s" - -#: src/service/plugins/share.js:211 -#, javascript-format -msgid "Text Shared By %s" -msgstr "" - -#. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:284 -#, javascript-format -msgid "Sending “%s” to %s" -msgstr "「%s」を%sに送信しています" - -#. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:305 -#, javascript-format -msgid "Sent “%s” to %s" -msgstr "「%s」を%sに送信しました" - -#. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:313 -#, fuzzy, javascript-format -msgid "Failed to send “%s” to %s" -msgstr "「%s」を%sに送信失敗: %s" - -#. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:384 -#, javascript-format -msgid "Send files to %s" -msgstr "%sにファイルを送信" - -#. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:402 -#, javascript-format -msgid "Send a link to %s" -msgstr "%sにリンクを送信" - -#: src/service/plugins/share.js:408 -msgid "Send" -msgstr "送信" - -#: src/service/plugins/sms.js:12 -msgid "SMS" -msgstr "" - -#: src/service/plugins/sms.js:33 -msgid "New SMS (URI)" -msgstr "" - -#: src/service/plugins/sms.js:41 -msgid "Reply SMS" -msgstr "" - -#: src/service/plugins/sms.js:57 -#, fuzzy -msgid "Share SMS" -msgstr "共有" - -#: src/service/plugins/systemvolume.js:11 -msgid "System Volume" -msgstr "システムの音量" - -#: src/service/plugins/telephony.js:21 -#, fuzzy -msgid "Mute Call" -msgstr "不在着信" - -#. Ensure we have a sender -#. TRANSLATORS: No name or phone number -#: src/service/plugins/telephony.js:155 src/service/ui/contacts.js:96 -#: src/service/ui/contacts.js:350 -msgid "Unknown Contact" -msgstr "不明な連絡先" - -#. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:172 -#, fuzzy -msgid "Incoming call" -msgstr "着信" - -#. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:187 -#, fuzzy -msgid "Ongoing call" -msgstr "着信" - -#. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:58 src/service/ui/contacts.js:79 -#, fuzzy, javascript-format -msgid "%s・Other" -msgstr "%s・その他" - -#. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:63 -#, javascript-format -msgid "%s・Fax" -msgstr "" - -#. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:67 -#, fuzzy, javascript-format -msgid "%s・Work" -msgstr "%s・仕事" - -#. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:71 -#, fuzzy, javascript-format -msgid "%s・Mobile" -msgstr "%s・モバイル" - -#. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:75 -#, fuzzy, javascript-format -msgid "%s・Home" -msgstr "%s・家" - -#: src/service/ui/contacts.js:203 -msgid "Select a contact or number" -msgstr "" - -#. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:239 src/service/ui/contacts.js:253 -#, javascript-format -msgid "Send to %s" -msgstr "%sに送信" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -#, fuzzy -msgid "Set Shortcut" -msgstr "キーボードショートカット" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -#, fuzzy -msgid "Set" -msgstr "選択" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "" - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "" - -#: src/service/ui/service.js:122 -#, fuzzy -msgid "Connect" -msgstr "Zorin Connect" - -#: src/service/ui/service.js:294 -msgid "Select a Device" -msgstr "端末を選択" - -#: src/service/ui/service.js:298 -msgid "Select" -msgstr "選択" - -#: src/service/ui/settings.js:298 -msgid "Panel" -msgstr "" - -#: src/service/ui/settings.js:298 -#, fuzzy -msgid "User Menu" -msgstr "メニューを開く" - -#: src/service/ui/settings.js:874 -#, fuzzy -msgid "Open" -msgstr "ファイルを開く" - -#: src/service/ui/settings.js:931 src/service/ui/settings.js:944 -msgid "On" -msgstr "" - -#: src/service/ui/settings.js:931 src/service/ui/settings.js:944 -msgid "Off" -msgstr "" - -#: src/service/ui/settings.js:1065 src/service/ui/settings.js:1131 -msgid "Disabled" -msgstr "" - -#. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:93 src/service/ui/messaging.js:126 -msgid "Just now" -msgstr "" - -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:98 src/service/ui/messaging.js:130 -#: src/shell/donotdisturb.js:266 -#, javascript-format -msgid "%d minute" -msgid_plural "%d minutes" -msgstr[0] "" - -#. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:103 -#, javascript-format -msgid "Yesterday・%s" -msgstr "" - -#: src/service/ui/messaging.js:920 -msgid "New Message" -msgstr "新しいメッセージ" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:86 -msgid "Fully Charged" -msgstr "充電完了" - -#. TRANSLATORS: When no time estimate for the battery is available -#. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:90 -#, javascript-format -msgid "%d%% (Estimating…)" -msgstr "%d%% (計測中…)" - -#. TRANSLATORS: Estimated time until battery is charged -#. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:100 -#, javascript-format -msgid "%d%% (%d∶%02d Until Full)" -msgstr "%d%% (フルまで %d∶%02d)" - -#. TRANSLATORS: Estimated time until battery is empty -#. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:108 -#, javascript-format -msgid "%d%% (%d∶%02d Remaining)" -msgstr "%d%% (残り %d∶%02d)" - -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 -msgid "Do Not Disturb" -msgstr "" - -#: src/shell/donotdisturb.js:156 -#, fuzzy -msgid "Silence Mobile Device Notifications" -msgstr "通知を受信" - -#: src/shell/donotdisturb.js:171 -msgid "Until you turn off Do Not Disturb" -msgstr "" - -#. TRANSLATORS: Time until change with time duration -#. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 -#, javascript-format -msgid "Until %s (%s)" -msgstr "" - -#: src/shell/donotdisturb.js:216 -msgid "Done" -msgstr "" - -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "One hour" -msgid_plural "%d hours" -msgstr[0] "" - -#. TRANSLATORS: Chrome/Firefox WebExtension description -#: webextension/gettext.js:29 -#, fuzzy -msgid "Share links with Zorin Connect, direct to the browser or by SMS." -msgstr "ウェブブラウザから端末や連絡先とリンクを共有" - -#. TRANSLATORS: WebExtension can't connect to Zorin Connect -#: webextension/gettext.js:33 -#, fuzzy -msgid "Service Unavailable" -msgstr "Gvcが利用できません" - -#. TRANSLATORS: Open URL with the device's browser -#: webextension/gettext.js:37 -#, fuzzy -msgid "Open in Browser" -msgstr "フォルダーを開く" - -msgid "Mobile Application" -msgstr "モバイルアプリ" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/LINGUAS gnome-shell-extension-zorin-connect-28.0.2/po/LINGUAS --- gnome-shell-extension-zorin-connect-24.1/po/LINGUAS 2019-03-17 12:26:48.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/LINGUAS 2019-11-30 14:52:32.000000000 +0000 @@ -1,12 +1,15 @@ +ar be +ca cs +da de es et fr +gl hu it -ja lt nl_BE nl_NL @@ -19,3 +22,4 @@ tr uk zh_CN +zh_TW diff -Nru gnome-shell-extension-zorin-connect-24.1/po/lt.po gnome-shell-extension-zorin-connect-28.0.2/po/lt.po --- gnome-shell-extension-zorin-connect-24.1/po/lt.po 2019-05-29 12:51:13.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/lt.po 2019-11-30 17:31:26.000000000 +0000 @@ -2,11 +2,11 @@ msgstr "" "Project-Id-Version: zorin-connect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" -"PO-Revision-Date: 2019-05-18 10:54\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-25 19:04\n" "Last-Translator: Andy Holmes (andyholmes)\n" "Language-Team: Lithuanian\n" -"Language: lt\n" +"Language: lt_LT\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -16,363 +16,391 @@ "X-Crowdin-Language: lt\n" "X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Šifravimo informacija" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Suporuoti" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Panaikinti suporavimą" + #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "Prisijungti prie…" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "Atsisakyti" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Prisijungti" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "IP adresas" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Bluetooth įrenginys" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Įrašykite telefono numerį ar vardą" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "Adresatų nėra" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Žinynas" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Įrašykite telefono numerį ar vardą" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "Rašyti žinutę" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "Siųsti žinutę" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Baterija" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Stalinis kompiuteris" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" msgstr "Kamera" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Iškarpinės sinchronizavimas" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Medijos leistuvės" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Pelė ir klaviatūra" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Garsumo reguliavimas" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Failai" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "Gauti failus" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Bendrinimas" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Komandos" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Pavadinimas" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "Komandų eilutė" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Pasirinkti vykdomąjį failą" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Pridėti" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Šalinti" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Taisyti" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Įrašyti" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Bendrinimo pranešimai" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "Bendrinti, kai aktyvus" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Programos" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Pranešimai" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Adresatai" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Gaunami skambučiai" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Garsumas" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Pristabdyti mediją" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Vykstantys skambučiai" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Nutildyti mikrofoną" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Telefonija" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Veiksmų trumpiniai" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Atstatyti visus…" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Komandų trumpiniai" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Trumpiniai" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Įskiepiai" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Eksperimentinis" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "Pasenusių SMS palaikymas" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Ištrinti" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Ištrinti šį įrenginį" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Nebeporuoti ir pašalinti visus nustatymus ir failus" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Išplėstiniai" -#: data/device.ui:2048 +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "Įrenginio baterija" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "Pranešimas apie žemą baterijos įkrovos lygį" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "Pranešimas apie pilnai įkrauta bateriją" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "Sistemos baterija" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "Bendrinti statistiką" + +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Baterija" + +#: data/ui/device-preferences.ui:2394 msgid "Keyboard Shortcuts" msgstr "Klaviatūros trumpiniai" -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Suporuoti" - -#: data/device.ui:2183 +#: data/ui/device-preferences.ui:2529 msgid "Device is unpaired" msgstr "Įrenginys yra nesuporuotas" -#: data/device.ui:2198 +#: data/ui/device-preferences.ui:2544 msgid "You may configure this device before pairing" msgstr "Prieš suporuodami, galite konfigūruoti šį įrenginį" -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "Rodinio veiksena" - -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Skydelis" - -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Naudotojo meniu" - -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" -msgstr "Generuoti palaikymo žurnalą" - -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "Apie Zorin Connect" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Perjungti į Bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "Perjungti į LAN" - -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Šifravimo informacija" - -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Panaikinti suporavimą" - #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Į įrenginį" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Iš įrenginio" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Nieko" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Sumažinti" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Nutildyti" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Susirašinėjimai" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Naujas pokalbis" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Pokalbių nėra" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "Nepasirinktas joks pokalbis" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "Pasirinkite arba pradėkite pokalbį" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Įrenginys yra atsijungęs" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "Pokalbių nėra" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Siųsti" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "Ieškoma įrenginių…" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "Įrenginio pavadinimas" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "Pe_rvadinti" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "Įkelti iš naujo" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" msgstr "Mobiliųjų nustatymai" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Taisyti įrenginio pavadinimą" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Įrenginiai" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Ieškoma įrenginių…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Naršyklių priedai" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Įjungti" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" msgstr "Šis įrenginys yra nematomas nesuporuotiems įrenginiams" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" msgstr "Aptikimas išjungtas" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Rodinio veiksena" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Skydelis" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Naudotojo meniu" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Generuoti palaikymo žurnalą" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "Apie Zorin Connect" + #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "Siųsti SMS" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Mobilieji įrenginiai" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "Įjungti" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" @@ -381,48 +409,203 @@ msgstr[2] "%d prijungtų" msgstr[3] "%d prijungtas" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "Išjungti" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Siųsti į mobilųjį įrenginį" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Atverti" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Įjungta" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Išjungta" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Išjungta" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Nustatykite trumpinį" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Nustatyti" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Norėdami pakeisti%s, įveskite naują trumpinį" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "Norėdami atsisakyti, paspauskite Grįžimo (Esc) klavišą arba Naikinimo (Backspace) klavišą, norėdami atstatyti trumpinį." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s jau yra naudojamas" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "Pilnas KDE Connect įgyvendinimas, skirtas GNOME" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "Moo" + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "Derinimo pranešimai yra registruojami. Atlikite reikiamus veiksmus, kad pakartotumėte problemą, o tuomet peržiūrėkite žurnalą." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Peržiūrėti žurnalą" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Nešiojamas kompiuteris" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Išmanusis telefonas" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Planšetė" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "Televizija" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Nebesuporuotas" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Atjungtas" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Prijungtas" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "Laukiama paslaugos…" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Ataskaita" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Tapatybės nustatymo nesėkmė" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Tinklo klaida" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Spustelėkite, norėdami šalinti nesklandumus" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "Discovery has been disabled due to the number of devices on this network." msgstr "Aptikimas buvo išjungtas dėl šiame tinkle esančių įrenginių skaičiaus." -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "Nepavyko įkelti %s įskiepio" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" msgstr "Spustelėkite išsamesnei informacijai" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "Rinkti numerį" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" msgstr "Bendrinti failą" +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "Išvardyti prieinamus įrenginius" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "Išvardyti visus įrenginius" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "Paskirties įrenginys" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "Pagrindinė žinutės dalis" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Siųsti pranešimą" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "Pranešimo programėlės pavadinimas" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "Pagrindinė pranešimo dalis" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "Pranešimo piktograma" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "Pranešimo ID" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Nuotrauka" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ryšio patikrinimas" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Rasti telefoną" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Bendrinti nuorodą" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "Rodyti laidos versiją" + #: src/service/device.js:174 msgid "Not available" msgstr "Neprieinamas" @@ -439,83 +622,69 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "%s kontrolinis kodas:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Nešiojamas kompiuteris" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Išmanusis telefonas" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Planšetė" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Stalinis kompiuteris" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Prisijungti iš naujo" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Nustatymai" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Suporavimo užklausa nuo %s" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Atmesti" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Priimti" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Rasti telefoną" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: Baterija baigia išsikrauti" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "Liko %d%%" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "%s: Baterija pilna" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Pilnai įkrauta" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Iškarpinė" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Išsiųsti iškarpinės turinį" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Gauti iškaprinės turinį" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Nežinomas adresatas" @@ -527,54 +696,45 @@ msgid "Mousepad" msgstr "Jutiklinis kilimėlis" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Klaviatūra" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "Reikalinga papildoma programinė įranga" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "Klaviatūra nepasiruošusi" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Atsisakyti pranešimo" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Užverti pranešimą" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Atsakyti į pranešimą" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "Siųsti pranešimą" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" -msgstr "Nuotrauka" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Ryšio patikrinimas" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "Aktyvuoti pranešimą" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Ryšio patikrinimas: %s" +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "Pristatymas" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Vykdyti komandas" @@ -591,18 +751,14 @@ msgid "Unmount" msgstr "Atjungti" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Visi failai" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Kameros nuotraukos" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "Failai" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Bendrinti" @@ -611,85 +767,87 @@ msgid "Share Text" msgstr "Bendrinti tekstą" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Bendrinti nuorodą" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Persiuntimas nepavyko" + +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "%s neleidžiama įkelti failų" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" -msgstr "Pradedamas persiuntimas" +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "Persiunčiamas failas" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "Gaunama „%s“ iš %s" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Persiuntimas sėkmingas" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "Gautas „%s“ iš %s" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Atverti aplanką" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Atverti failą" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "Persiuntimas nepavyko" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Nepavyko gauti “%s” iš %s" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "%s bendrino tekstą" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Siunčiama „%s“ į %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "Išsiųsta „%s“ į %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Nepavyko išsiųsti “%s” į %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Siųsti failus į %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Užbaigus, atverti failą" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Siųsti nuorodą į %s" @@ -706,7 +864,7 @@ msgid "Reply SMS" msgstr "Atsakyti į SMS žinutę" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Bendrinti SMS žinutę" @@ -719,105 +877,58 @@ msgstr "Nutildyti skambutį" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Gaunamas skambutis" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Vykstantis skambutis" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Kiti" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Faksas" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Darbo" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Mobilusis" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Namų" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Siųsti %s" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Atverti" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "Įjungta" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "Išjungta" - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Išjungta" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Nustatykite trumpinį" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Nustatyti" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Norėdami pakeisti%s, įveskite naują trumpinį" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Norėdami atsisakyti, paspauskite Grįžimo (Esc) klavišą arba Naikinimo (Backspace) klavišą, norėdami atstatyti trumpinį." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s jau yra naudojamas" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Ką tik" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -827,17 +938,30 @@ msgstr[3] "%d minutė" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Vakar・%s" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "Grupės žinutė" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "Jūs: %s" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "Ir dar %d adresatas" +msgstr[1] "Ir dar %d adresatai" +msgstr[2] "Ir dar %d adresatų" +msgstr[3] "Ir dar %d adresatas" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "Pasirinkti įrenginį" @@ -846,101 +970,65 @@ msgid "Select" msgstr "Pasirinkti" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "Nebesuporuotas" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Atjungtas" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Prijungtas" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "Transferred files are placed in the Downloads folder." -msgstr "Persiųsti failai yra patalpinami į Atsiuntimų aplanką." - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "Pilnas KDE Connect įgyvendinimas, skirtas GNOME" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "Moo" - -#: src/service/ui/settings.js:529 -msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." -msgstr "Derinimo pranešimai yra registruojami. Atlikite reikiamus veiksmus, kad pakartotumėte problemą, o tuomet peržiūrėkite žurnalą." - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "Peržiūrėti žurnalą" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "Pilnai įkrauta" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Nerasta jokių įrenginių" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (Apskaičiuojama…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (%d∶%02d iki pilnos)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (Liko %d∶%02d)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 -msgid "Do Not Disturb" -msgstr "Netrukdyti" - -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" -msgstr "Nutildyti mobiliojo įrenginio pranešimus" - -#: src/shell/donotdisturb.js:171 -msgid "Until you turn off Do Not Disturb" -msgstr "Kol išjungsite veikseną \"Netrukdyti\"" +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d valanda" +msgstr[1] "%d valandos" +msgstr[2] "%d valandų" +msgstr[3] "%d valanda" #. TRANSLATORS: Time until change with time duration #. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 +#: src/shell/donotdisturb.js:150 #, javascript-format msgid "Until %s (%s)" msgstr "Iki %s (%s)" -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 +msgid "Do Not Disturb" +msgstr "Netrukdyti" + +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" +msgstr "Nutildyti pranešimus iš mobiliųjų įrenginių" + +#: src/shell/donotdisturb.js:261 +msgid "Until you turn off Do Not Disturb" +msgstr "Kol išjungsite veikseną \"Netrukdyti\"" + +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Atlikta" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d valanda" -msgstr[1] "%d valandos" -msgstr[2] "%d valandų" -msgstr[3] "%d valanda" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Atsakyti" @@ -959,11 +1047,6 @@ msgid "Service Unavailable" msgstr "Paslauga neprieinama" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Nerasta jokių įrenginių" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/meson.build gnome-shell-extension-zorin-connect-28.0.2/po/meson.build --- gnome-shell-extension-zorin-connect-24.1/po/meson.build 2019-03-17 12:26:48.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/meson.build 2019-11-30 14:52:32.000000000 +0000 @@ -1,7 +1,4 @@ # build translations in LINGUAS - -i18n = import('i18n') - i18n.gettext( 'org.gnome.Shell.Extensions.ZorinConnect', preset: 'glib' diff -Nru gnome-shell-extension-zorin-connect-24.1/po/nl_BE.po gnome-shell-extension-zorin-connect-28.0.2/po/nl_BE.po --- gnome-shell-extension-zorin-connect-24.1/po/nl_BE.po 2019-03-17 12:32:17.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/nl_BE.po 2019-11-30 17:34:34.000000000 +0000 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: org.gnome.Shell.Extensions.ZorinConnect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-19 11:14-0800\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" "PO-Revision-Date: 2018-11-21 19:57+0100\n" "Last-Translator: Heimen Stoffels \n" "Language-Team: Dutch \n" @@ -18,395 +18,634 @@ "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.1.1\n" -#: data/conversation.ui:71 data/conversation.ui:79 -msgid "Type a message" -msgstr "Typ een bericht" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Encryptie-info" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Koppel aan" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Koppel af" + +#. TRANSLATORS: Open a dialog to connect to an IP or Bluez device +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 +msgid "Connect to…" +msgstr "Verbind met…" + +#. Action Buttons +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 +msgid "Cancel" +msgstr "Annuleer" + +#: data/ui/connect.ui:27 +msgid "Connect" +msgstr "Verbind" + +#: data/ui/connect.ui:74 +msgid "IP Address" +msgstr "" + +#: data/ui/contact-chooser.ui:50 +#, fuzzy +msgid "No contacts" +msgstr "Contacten" + +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 +msgid "Help" +msgstr "Hulp" -#: data/contacts.ui:51 data/contacts.ui:52 +#: data/ui/contact-chooser.ui:103 msgid "Type a phone number or name" msgstr "Typ een telefoonnummer of naam" -#: data/device.ui:68 src/service/plugins/battery.js:12 -msgid "Battery" -msgstr "Accu" +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 +msgid "Type a message" +msgstr "Typ een bericht" + +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 +#, fuzzy +msgid "Send Message" +msgstr "Nieuw bericht" -#: data/device.ui:116 +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Desktop" + +#: data/ui/device-preferences.ui:88 +msgid "Camera" +msgstr "" + +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Klembordsynchronisatie" -#: data/device.ui:172 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Mediaspelers" -#: data/device.ui:220 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Muis en klavier" -#: data/device.ui:268 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Volumebeheer" -#: data/device.ui:308 data/device.ui:1406 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Bestanden" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Deling" -#: data/device.ui:337 data/device.ui:534 data/device.ui:1449 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:169 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Commando's" -#: data/device.ui:385 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Naam" -#: data/device.ui:401 data/device.ui:402 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 +msgid "Command Line" +msgstr "Commandoregel" + +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Kies een uitvoerbaar bestand" -#: data/device.ui:403 -msgid "Command Line" -msgstr "Commandoregel" +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 +msgid "Add" +msgstr "" -#: data/device.ui:597 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 +msgid "Remove" +msgstr "" + +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 +msgid "Edit" +msgstr "" + +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 +msgid "Save" +msgstr "" + +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Deelnotificaties" -#: data/device.ui:636 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Apps" -#: data/device.ui:675 data/device.ui:1492 -#: src/service/plugins/notification.js:12 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 +#: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Notificaties" -#: data/device.ui:705 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 +msgid "Contacts" +msgstr "Contacten" + +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Inkomende oproepen" -#: data/device.ui:755 data/device.ui:900 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Volume" -#: data/device.ui:813 data/device.ui:958 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Pauzeer media" -#: data/device.ui:852 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "In gesprek" -#: data/device.ui:1007 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Microfoon toedoen" -#: data/device.ui:1047 data/device.ui:1535 src/service/plugins/telephony.js:12 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Telefonie" -#: data/device.ui:1082 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Actie-sneltoetsen" -#: data/device.ui:1094 data/device.ui:1157 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Herstel alles…" -#: data/device.ui:1145 -msgid "Command Shortcuts" -msgstr "Commando-sneltoetsen" - -#: data/device.ui:1203 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Sneltoetsen" -#: data/device.ui:1234 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Invoegtoepassingen" -#: data/device.ui:1295 -msgid "Delete" -msgstr "Verwijder" - -#: data/device.ui:1320 -msgid "Delete this device" -msgstr "Verwijder deze GSM" - -#: data/device.ui:1335 -msgid "Unpair and remove all settings and files" -msgstr "Koppel af en wis alle instellingen en bestanden" +#: data/ui/device-preferences.ui:1723 +msgid "Experimental" +msgstr "" + +#: data/ui/device-preferences.ui:1771 +msgid "Legacy SMS Support" +msgstr "" -#: data/device.ui:1365 data/device.ui:1621 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Geavanceerd" -#: data/device.ui:1578 -msgid "Keyboard Shortcuts" -msgstr "Sneltoetsen" +#: data/ui/device-preferences.ui:1855 +#, fuzzy +msgid "Device Battery" +msgstr "Accu" -#. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/menus.ui:7 src/service/ui/service.js:115 -msgid "Connect to…" -msgstr "Verbind met…" +#: data/ui/device-preferences.ui:1906 +#, fuzzy +msgid "Low Battery Notification" +msgstr "Antwoordnotificatie" -#: data/menus.ui:13 data/settings.ui:881 -msgid "Help" -msgstr "Hulp" +#: data/ui/device-preferences.ui:1967 +#, fuzzy +msgid "Fully Charged Notification" +msgstr "Deelnotificaties" -#. TRANSLATORS: Open the developer's dialog -#: data/menus.ui:19 -msgid "Debugger" -msgstr "Foutopsporing" - -#: data/menus.ui:23 -msgid "About" -msgstr "Over" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:34 -msgid "Switch to Bluetooth" -msgstr "Schakel naar Bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:41 -msgid "Switch to LAN" -msgstr "Schakel naar LAN" +#: data/ui/device-preferences.ui:2014 +#, fuzzy +msgid "System Battery" +msgstr "Accu" -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:48 src/service/ui/settings.js:612 -msgid "Encryption Info" -msgstr "Encryptie-info" +#: data/ui/device-preferences.ui:2065 +#, fuzzy +msgid "Share Statistics" +msgstr "Deelnotificaties" -#. TRANSLATORS: Send a pair request to the device -#: data/menus.ui:53 src/service/device.js:425 -msgid "Pair" -msgstr "Koppel aan" +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Accu" -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:59 src/service/device.js:433 -msgid "Unpair" -msgstr "Koppel af" +#: data/ui/device-preferences.ui:2394 +msgid "Keyboard Shortcuts" +msgstr "Sneltoetsen" + +#: data/ui/device-preferences.ui:2529 +#, fuzzy +msgid "Device is unpaired" +msgstr "Toestel is niet geconnecteerd" + +#: data/ui/device-preferences.ui:2544 +msgid "You may configure this device before pairing" +msgstr "" #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:71 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Naar GSM" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:77 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Van GSM" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:89 data/menus.ui:115 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Niets" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:96 data/menus.ui:122 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Verlagen" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:103 data/menus.ui:129 src/service/plugins/telephony.js:176 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Toedoen" -#: data/messaging.ui:12 src/service/plugins/sms.js:25 -#: src/service/ui/messaging.js:871 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Berichten" -#: data/messaging.ui:110 -msgid "Select a conversation" +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 +#, fuzzy +msgid "New Conversation" +msgstr "Kies een conversatie" + +#: data/ui/messaging-window.ui:108 +#, fuzzy +msgid "No Conversations" msgstr "Kies een conversatie" -#: data/messaging.ui:188 +#: data/ui/messaging-window.ui:168 +msgid "No conversation selected" +msgstr "" + +#: data/ui/messaging-window.ui:184 +#, fuzzy +msgid "Select or start a conversation" +msgstr "Kies een conversatie" + +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Toestel is niet geconnecteerd" -#: data/settings.ui:333 -msgid "Appearance" -msgstr "Uiterlijk" +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 +msgid "Send" +msgstr "Verzend" -#: data/settings.ui:383 -msgid "Display Mode" -msgstr "Weergavemodus" +#: data/ui/preferences-window.ui:18 +#, fuzzy +msgid "Device Name" +msgstr "Naar GSM" -#: data/settings.ui:425 -msgid "Service" -msgstr "Dienst" - -#: data/settings.ui:475 -msgid "Discoverable" -msgstr "Zichtbaar" - -#: data/settings.ui:528 -msgid "Restart Service" -msgstr "Herstart dienst" - -#: data/settings.ui:581 data/settings.ui:1015 src/service/device.js:417 -msgid "Settings" -msgstr "Instellingen" - -#: data/settings.ui:639 -msgid "Remote Filesystems" -msgstr "Externe bestandssystemen" - -#: data/settings.ui:675 -msgid "Sound Effects" -msgstr "Geluidseffecten" - -#: data/settings.ui:712 -msgid "Extended Keyboard Support" -msgstr "Uitgebreide klavierondersteuning" - -#: data/settings.ui:749 -msgid "Desktop Contacts" -msgstr "Bureaubladcontacten" +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "" -#: data/settings.ui:786 -msgid "Files Integration" -msgstr "Bestanden-integratie" +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 +msgid "Refresh" +msgstr "Herlaad" -#: data/settings.ui:813 -msgid "Additional Features" -msgstr "Additionele functionaliteiten" +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 +msgid "Mobile Settings" +msgstr "GSM-instellingen" + +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 +msgid "Edit Device Name" +msgstr "" + +#: data/ui/preferences-window.ui:257 +#, fuzzy +msgid "Devices" +msgstr "Naar GSM" + +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "" -#: data/settings.ui:903 +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Browser-add-ons" -#: data/settings.ui:921 -msgid "KDE Connect" -msgstr "KDE Connect" - -#: data/settings.ui:956 data/settings.ui:1058 -msgid "Other" -msgstr "Ander" +#: data/ui/preferences-window.ui:612 +#, fuzzy +msgid "Enable" +msgstr "Tablet" -#. TRANSLATORS: No devices are known or available -#: data/settings.ui:1106 webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Geen toestel gevonden" +#: data/ui/preferences-window.ui:644 +msgid "This device is invisible to unpaired devices" +msgstr "" -#: data/settings.ui:1142 -msgid "Refresh" -msgstr "Herlaad" +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 +msgid "Discovery Disabled" +msgstr "Herkenning uitgeschakeld" + +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Weergavemodus" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Paneel" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Gebruikersmenu" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "" + +#: data/ui/preferences-window.ui:740 +#, fuzzy +msgid "About Zorin Connect" +msgstr "Zorin Connect" + +#. TRANSLATORS: Share URL by SMS +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 +msgid "Send SMS" +msgstr "Verzend SMS" #. Service Menu -#: src/extension.js:79 src/extension.js:259 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "GSM's" -#: src/extension.js:105 -msgid "Mobile Settings" -msgstr "GSM-instellingen" - -#. TRANSLATORS: Extension name -#: src/extension.js:196 src/extension.js:311 src/service/daemon.js:95 -#: src/service/daemon.js:413 webextension/gettext.js:27 -msgid "Zorin Connect" -msgstr "Zorin Connect" +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "" -#. TRANSLATORS: %d is the number of devices connected -#: src/extension.js:257 +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" msgstr[0] "%d verbonden" msgstr[1] "%d verbonden" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:112 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Verzend naar GSM" -#: src/service/daemon.js:406 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Open" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Aan" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Uit" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Uitgeschakeld" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Stel sneltoets in" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Stel in" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Voer een nieuwe sneltoets in voor het wijzigen van %s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "" +"Druk op Esc om te annuleren of op Backspace om de sneltoets terug te zetten." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s is al in gebruik" + +#: src/preferences/service.js:388 msgid "A complete KDE Connect implementation for GNOME" msgstr "Volledige KDE Connect-implementatie voor GNOME" #. TRANSLATORS: eg. 'Translator Name ' -#: src/service/daemon.js:415 +#: src/preferences/service.js:397 msgid "translator-credits" msgstr "Heimen Stoffels" -#: src/service/daemon.js:437 +#: src/preferences/service.js:430 +msgid "" +"Debug messages are being logged. Take any steps necessary to reproduce a " +"problem then review the log." +msgstr "" + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Laptop" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Smartphone" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Tablet" + +#: src/preferences/service.js:508 +#, fuzzy +msgid "Television" +msgstr "Telefonie" + +#: src/preferences/service.js:529 +#, fuzzy +msgid "Unpaired" +msgstr "Koppel af" + +#: src/preferences/service.js:533 +#, fuzzy +msgid "Disconnected" +msgstr "Toestel is niet geconnecteerd" + +#: src/preferences/service.js:537 +#, fuzzy +msgid "Connected" +msgstr "Verbind" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Rapporteer" -#: src/service/daemon.js:567 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Authenticatieprobleem" -#: src/service/daemon.js:576 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Netwerkfout" -#: src/service/daemon.js:577 src/service/daemon.js:587 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Klik voor probleemoplossing" -#: src/service/daemon.js:586 -msgid "PulseAudio Error" -msgstr "PulseAudio-fout" +#: src/service/daemon.js:599 +msgid "" +"Discovery has been disabled due to the number of devices on this network." +msgstr "" +"Herkenning is uitgeschakeld vanwege het aantal toestellen op dit netwerk." -#: src/service/daemon.js:596 -msgid "Discovery Disabled" -msgstr "Herkenning uitgeschakeld" +#: src/service/daemon.js:608 +msgid "Click for more information" +msgstr "Klik voor meer informatie" -#: src/service/daemon.js:597 -msgid "Discovery has been disabled due to the number of devices on this network." -msgstr "Herkenning is uitgeschakeld vanwege het aantal toestellen op dit netwerk." - -#: src/service/daemon.js:599 src/service/daemon.js:609 -msgid "Click to open preferences" -msgstr "Klik om voorkeuren te openen" +#: src/service/daemon.js:705 +msgid "Dial Number" +msgstr "Telefoonoproep" -#: src/service/daemon.js:608 -msgid "Additional Software Required" -msgstr "Additionele software vereist" +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 +msgid "Share File" +msgstr "Deel bestand" -#: src/service/daemon.js:617 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "Kon plug-in %s niet laden" +#: src/service/daemon.js:774 +#, fuzzy +msgid "List available devices" +msgstr "Onbeschikbaar" -#: src/service/daemon.js:618 src/service/daemon.js:635 -msgid "Click for more information" -msgstr "Klik voor meer informatie" +#: src/service/daemon.js:783 +#, fuzzy +msgid "List all devices" +msgstr "GSM's" -#: src/service/daemon.js:633 -msgid "Wayland Not Supported" -msgstr "Wayland niet ondersteund" - -#: src/service/daemon.js:634 -msgid "Remote input not supported on Wayland" -msgstr "Externe input wordt niet ondersteund op Wayland" +#: src/service/daemon.js:792 +#, fuzzy +msgid "Target Device" +msgstr "Naar GSM" -#. Create an urgent notification -#: src/service/daemon.js:658 -#, javascript-format -msgid "Zorin Connect: %s" -msgstr "Zorin Connect: %s" +#: src/service/daemon.js:834 +#, fuzzy +msgid "Message Body" +msgstr "Nieuw bericht" -#. TRANSLATORS: Share URL by SMS -#: src/service/daemon.js:808 src/service/plugins/sms.js:49 -#: webextension/gettext.js:39 -msgid "Send SMS" -msgstr "Verzend SMS" +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Verzendnotificatie" -#: src/service/daemon.js:812 -msgid "Dial Number" -msgstr "Telefoonoproep" +#: src/service/daemon.js:855 +#, fuzzy +msgid "Notification App Name" +msgstr "Notificaties" + +#: src/service/daemon.js:864 +#, fuzzy +msgid "Notification Body" +msgstr "Notificaties" + +#: src/service/daemon.js:873 +#, fuzzy +msgid "Notification Icon" +msgstr "Notificaties" + +#: src/service/daemon.js:882 +#, fuzzy +msgid "Notification ID" +msgstr "Notificaties" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ping" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +#, fuzzy +msgid "Ring" +msgstr "Lokaliseer" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Deel link" -#: src/service/device.js:166 +#: src/service/daemon.js:942 +#, fuzzy +msgid "Show release version" +msgstr "Kies een conversatie" + +#: src/service/device.js:174 msgid "Not available" msgstr "Onbeschikbaar" #. TRANSLATORS: Bluetooth address for remote device -#: src/service/device.js:170 +#: src/service/device.js:179 #, javascript-format msgid "Bluetooth device at %s" msgstr "Bluetooth-toestel op %s" @@ -417,139 +656,121 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:188 src/service/device.js:190 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "%s-vingerafdruk:" -#: src/service/device.js:240 -msgid "Laptop" -msgstr "Laptop" - -#: src/service/device.js:242 -msgid "Smartphone" -msgstr "Smartphone" - -#: src/service/device.js:244 -msgid "Tablet" -msgstr "Tablet" - -#: src/service/device.js:246 -msgid "Desktop" -msgstr "Desktop" - -#: src/service/device.js:409 -msgid "Reconnect" -msgstr "Herverbinden" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:606 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Koppelaanvraag van %s" -#: src/service/device.js:613 +#: src/service/device.js:755 msgid "Reject" msgstr "Verwerp" -#: src/service/device.js:618 +#: src/service/device.js:760 msgid "Accept" msgstr "Accepteer" -#: src/service/plugins/battery.js:194 src/service/plugins/findmyphone.js:18 -#, fuzzy -msgid "Ring" -msgstr "Lokaliseer" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:203 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: batterij is laag" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:205 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d%% resterend" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, fuzzy, javascript-format +msgid "%s: Battery is full" +msgstr "%s: batterij is laag" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Volledig opgeladen" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Klembord" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Verstuur klembord" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Haal klembord op" -#: src/service/plugins/contacts.js:12 -msgid "Contacts" -msgstr "Contacten" +#. Ensure we have a sender +#. TRANSLATORS: No name or phone number +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 +msgid "Unknown Contact" +msgstr "Onbekend contact" -#: src/service/plugins/findmyphone.js:12 +#: src/service/plugins/findmyphone.js:13 msgid "Find My Phone" msgstr "Vind mijn telefoon" -#: src/service/plugins/findmyphone.js:65 -msgid "Locate Device" -msgstr "Lokaliseer GSM" - -#: src/service/plugins/findmyphone.js:66 -#, javascript-format -msgid "%s asked to locate this device" -msgstr "%s wil deze GSM lokaliseren" - -#: src/service/plugins/findmyphone.js:74 -msgid "Found" -msgstr "Gevonden" - #: src/service/plugins/mousepad.js:14 msgid "Mousepad" msgstr "Touchpad" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:578 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Klavier" -#: src/service/plugins/mousepad.js:595 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "Klavier niet gereed" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:25 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Annuleer notificatie" -#: src/service/plugins/notification.js:33 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Sluit notificatie" -#: src/service/plugins/notification.js:41 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Antwoordnotificatie" -#: src/service/plugins/notification.js:49 -msgid "Send Notification" -msgstr "Verzendnotificatie" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Ping" +#: src/service/plugins/notification.js:59 +#, fuzzy +msgid "Activate Notification" +msgstr "Deelnotificaties" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Ping: %s" +#: src/service/plugins/presenter.js:9 +#, fuzzy +msgid "Presentation" +msgstr "Bestanden-integratie" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Voer commando's uit" @@ -566,133 +787,122 @@ msgid "Unmount" msgstr "Koppel af" -#: src/service/plugins/sftp.js:170 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Alle bestanden" -#: src/service/plugins/sftp.js:171 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Camera-afbeeldingen" -#: src/service/plugins/sftp.js:333 -msgid "Files" -msgstr "Bestanden" - -#: src/service/plugins/share.js:12 src/service/plugins/share.js:18 +#: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Deel" -#: src/service/plugins/share.js:26 -msgid "Share File" -msgstr "Deel bestand" - -#: src/service/plugins/share.js:34 +#: src/service/plugins/share.js:35 msgid "Share Text" msgstr "Deel tekst" -#: src/service/plugins/share.js:42 src/service/ui/messaging.js:903 -#: src/service/ui/messaging.js:911 -msgid "Share Link" -msgstr "Deel link" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Overzetten niet gelukt" + +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "" -#: src/service/plugins/share.js:131 src/service/plugins/share.js:282 -msgid "Starting Transfer" -msgstr "Overzetten starten" +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +#, fuzzy +msgid "Transferring File" +msgstr "Overzetten niet gelukt" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:133 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "“%s” ontvangen van %s" -#. Action Buttons -#: src/service/plugins/share.js:138 src/service/plugins/share.js:289 -#: src/service/plugins/share.js:407 src/service/ui/keybindings.js:44 -#: src/service/ui/service.js:121 src/service/ui/service.js:300 -#: src/service/ui/settings.js:873 src/shell/donotdisturb.js:215 -msgid "Cancel" -msgstr "Annuleer" - -#: src/service/plugins/share.js:149 src/service/plugins/share.js:303 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Met succes overgezet" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:151 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "“%s” ontvangen van %s" -#: src/service/plugins/share.js:157 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Open folder" -#: src/service/plugins/share.js:162 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Open bestand" -#: src/service/plugins/share.js:169 src/service/plugins/share.js:311 -msgid "Transfer Failed" -msgstr "Overzetten niet gelukt" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Kon “%s” niet ontvangen van %s" -#: src/service/plugins/share.js:211 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "Tekst, gedeeld door %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:284 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "“%s” verzenden naar %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:305 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "“%s” verzonden naar %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:313 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Kon “%s” niet verzenden naar %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:384 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Verzend bestanden naar %s" +#. TRANSLATORS: Mark the file to be opened once completed +#: src/service/plugins/share.js:408 +#, fuzzy +msgid "Open when done" +msgstr "Open in browser" + #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:402 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Verzend een link naar %s" -#: src/service/plugins/share.js:408 -msgid "Send" -msgstr "Verzend" - -#: src/service/plugins/sms.js:12 +#: src/service/plugins/sms.js:13 msgid "SMS" msgstr "SMS" -#: src/service/plugins/sms.js:33 +#: src/service/plugins/sms.js:34 msgid "New SMS (URI)" msgstr "Nieuwe SMS (URI)" -#: src/service/plugins/sms.js:41 +#: src/service/plugins/sms.js:42 src/service/plugins/telephony.js:22 msgid "Reply SMS" msgstr "Beantwoord SMS" -#: src/service/plugins/sms.js:57 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Deel SMS" @@ -700,140 +910,63 @@ msgid "System Volume" msgstr "Systeemvolume" -#: src/service/plugins/telephony.js:21 +#: src/service/plugins/telephony.js:30 msgid "Mute Call" msgstr "Demp oproep" -#. Ensure we have a sender -#. TRANSLATORS: No name or phone number -#: src/service/plugins/telephony.js:155 src/service/ui/contacts.js:96 -#: src/service/ui/contacts.js:350 -msgid "Unknown Contact" -msgstr "Onbekend contact" - #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:172 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Inkomende oproep" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:187 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "In gesprek" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:58 src/service/ui/contacts.js:79 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Ander" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:63 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Fax" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:67 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Job" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:71 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・GSM" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:75 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Thuis" -#: src/service/ui/contacts.js:203 -msgid "Select a contact or number" -msgstr "Kies een contact of nummer" - #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:239 src/service/ui/contacts.js:253 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Verzend naar %s" -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Stel sneltoets in" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Stel in" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Voer een nieuwe sneltoets in voor het wijzigen van %s" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Druk op Esc om te annuleren of op Backspace om de sneltoets terug te zetten." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s is al in gebruik" - -#: src/service/ui/service.js:122 -msgid "Connect" -msgstr "Verbind" - -#: src/service/ui/service.js:294 -msgid "Select a Device" -msgstr "Kies een GSM" - -#: src/service/ui/service.js:298 -msgid "Select" -msgstr "Kies" - -#: src/service/ui/settings.js:298 -msgid "Panel" -msgstr "Paneel" - -#: src/service/ui/settings.js:298 -msgid "User Menu" -msgstr "Gebruikersmenu" - -#: src/service/ui/settings.js:874 -msgid "Open" -msgstr "Open" - -#: src/service/ui/settings.js:931 src/service/ui/settings.js:944 -msgid "On" -msgstr "Aan" - -#: src/service/ui/settings.js:931 src/service/ui/settings.js:944 -msgid "Off" -msgstr "Uit" - -#: src/service/ui/settings.js:1065 src/service/ui/settings.js:1131 -msgid "Disabled" -msgstr "Uitgeschakeld" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:93 src/service/ui/messaging.js:126 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Zopas" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:98 src/service/ui/messaging.js:130 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -841,71 +974,102 @@ msgstr[1] "%d minuten" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:103 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Gisteren - %s" -#: src/service/ui/messaging.js:920 -msgid "New Message" +#: src/service/ui/messaging.js:255 +#, fuzzy +msgid "Group Message" msgstr "Nieuw bericht" -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:86 -msgid "Fully Charged" -msgstr "Volledig opgeladen" +#. TRANSLATORS: An outgoing message body in a conversation summary +#: src/service/ui/messaging.js:265 +#, javascript-format +msgid "You: %s" +msgstr "" + +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "" +msgstr[1] "" + +#: src/service/ui/service.js:31 +msgid "Select a Device" +msgstr "Kies een GSM" + +#: src/service/ui/service.js:35 +msgid "Select" +msgstr "Kies" + +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Geen toestel gevonden" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:90 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (berekenen...)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:100 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (%d%02d tot volledig opgeladen)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:108 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (%d%02d resterend)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 +#: src/shell/donotdisturb.js:135 +#, fuzzy, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "Eén uur" +msgstr[1] "%d uur" + +#. TRANSLATORS: Time until change with time duration +#. EXAMPLE: Until 10:00 (2 hours) +#: src/shell/donotdisturb.js:150 +#, javascript-format +msgid "Until %s (%s)" +msgstr "Tot %s (%s)" + +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 msgid "Do Not Disturb" msgstr "Stoor mij niet" -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" msgstr "Geen GSM-notificaties" -#: src/shell/donotdisturb.js:171 +#: src/shell/donotdisturb.js:261 msgid "Until you turn off Do Not Disturb" msgstr "Totdat je Stoor mij niet uitschakelt" -#. TRANSLATORS: Time until change with time duration -#. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 -#, javascript-format -msgid "Until %s (%s)" -msgstr "Tot %s (%s)" - -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Klaar" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "One hour" -msgid_plural "%d hours" -msgstr[0] "Eén uur" -msgstr[1] "%d uur" +#: src/shell/notification.js:43 +#, fuzzy +msgid "Reply" +msgstr "Beantwoord SMS" + +#. TRANSLATORS: Extension name +#: webextension/gettext.js:27 +msgid "Zorin Connect" +msgstr "Zorin Connect" #. TRANSLATORS: Chrome/Firefox WebExtension description #: webextension/gettext.js:29 @@ -924,3 +1088,102 @@ msgid "Mobile Application" msgstr "Mobiele applicatie" + +#~ msgid "Command Shortcuts" +#~ msgstr "Commando-sneltoetsen" + +#~ msgid "Delete" +#~ msgstr "Verwijder" + +#~ msgid "Delete this device" +#~ msgstr "Verwijder deze GSM" + +#~ msgid "Unpair and remove all settings and files" +#~ msgstr "Koppel af en wis alle instellingen en bestanden" + +#~ msgid "Debugger" +#~ msgstr "Foutopsporing" + +#~ msgid "About" +#~ msgstr "Over" + +#~ msgid "Switch to Bluetooth" +#~ msgstr "Schakel naar Bluetooth" + +#~ msgid "Switch to LAN" +#~ msgstr "Schakel naar LAN" + +#~ msgid "Appearance" +#~ msgstr "Uiterlijk" + +#~ msgid "Service" +#~ msgstr "Dienst" + +#~ msgid "Discoverable" +#~ msgstr "Zichtbaar" + +#~ msgid "Restart Service" +#~ msgstr "Herstart dienst" + +#~ msgid "Settings" +#~ msgstr "Instellingen" + +#~ msgid "Remote Filesystems" +#~ msgstr "Externe bestandssystemen" + +#~ msgid "Sound Effects" +#~ msgstr "Geluidseffecten" + +#~ msgid "Extended Keyboard Support" +#~ msgstr "Uitgebreide klavierondersteuning" + +#~ msgid "Desktop Contacts" +#~ msgstr "Bureaubladcontacten" + +#~ msgid "Additional Features" +#~ msgstr "Additionele functionaliteiten" + +#~ msgid "KDE Connect" +#~ msgstr "KDE Connect" + +#~ msgid "Other" +#~ msgstr "Ander" + +#~ msgid "PulseAudio Error" +#~ msgstr "PulseAudio-fout" + +#~ msgid "Click to open preferences" +#~ msgstr "Klik om voorkeuren te openen" + +#~ msgid "Additional Software Required" +#~ msgstr "Additionele software vereist" + +#~ msgid "%s Plugin Failed To Load" +#~ msgstr "Kon plug-in %s niet laden" + +#~ msgid "Wayland Not Supported" +#~ msgstr "Wayland niet ondersteund" + +#~ msgid "Remote input not supported on Wayland" +#~ msgstr "Externe input wordt niet ondersteund op Wayland" + +#~ msgid "Zorin Connect: %s" +#~ msgstr "Zorin Connect: %s" + +#~ msgid "Reconnect" +#~ msgstr "Herverbinden" + +#~ msgid "Locate Device" +#~ msgstr "Lokaliseer GSM" + +#~ msgid "%s asked to locate this device" +#~ msgstr "%s wil deze GSM lokaliseren" + +#~ msgid "Found" +#~ msgstr "Gevonden" + +#~ msgid "Starting Transfer" +#~ msgstr "Overzetten starten" + +#~ msgid "Select a contact or number" +#~ msgstr "Kies een contact of nummer" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/nl_NL.po gnome-shell-extension-zorin-connect-28.0.2/po/nl_NL.po --- gnome-shell-extension-zorin-connect-24.1/po/nl_NL.po 2019-05-29 12:57:23.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/nl_NL.po 2019-11-30 17:34:49.000000000 +0000 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: org.gnome.Shell.Extensions.ZorinConnect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" "PO-Revision-Date: 2019-05-26 12:20+0200\n" "Last-Translator: Heimen Stoffels \n" "Language-Team: Dutch \n" @@ -18,413 +18,618 @@ "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.1.1\n" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Versleutelingsinformatie" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Aankoppelen" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Ontkoppelen" + #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "Verbinden met…" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "Annuleren" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Verbinden" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "IP-adres" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Bluetooth-apparaat" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Typ een telefoonnummer of naam" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "Contactpersonen" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Hulp" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Typ een telefoonnummer of naam" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "Typ een bericht" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "Bericht versturen" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Batterij" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Bureaubladcomputer" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" msgstr "Camera" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Klembordsynchronisatie" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Mediaspelers" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Muis en toetsenbord" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Volumebeheer" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Bestanden" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Delen" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Opdrachten" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Naam" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "Opdrachtregel" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Kies een uitvoerbaar bestand" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Toevoegen" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Verwijderen" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Bewerken" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Opslaan" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Deelmeldingen" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Applicaties" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Meldingen" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Contactpersonen" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Inkomende oproepen" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Volume" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Media pauzeren" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Lopende gesprekken" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Microfoon dempen" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Telefoon" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Actie-sneltoetsen" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Standaardwaarden…" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Opdracht-sneltoetsen" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Sneltoetsen" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Plug-ins" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Experimenteel" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "Verouderde SMS-ondersteuning" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Verwijderen" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Dit apparaat verwijderen" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Ontkoppelen en alle instellingen en bestanden verwijderen" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Geavanceerd" -#: data/device.ui:2048 -msgid "Keyboard Shortcuts" -msgstr "Sneltoetsen" - -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Aankoppelen" - -#: data/device.ui:2183 -msgid "Device is unpaired" -msgstr "Apparaat is niet gekoppeld" - -#: data/device.ui:2198 -msgid "You may configure this device before pairing" -msgstr "Je kunt dit apparaat instellen alvorens het te koppelen" +#: data/ui/device-preferences.ui:1855 +#, fuzzy +msgid "Device Battery" +msgstr "Batterij" -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "Weergavemodus" +#: data/ui/device-preferences.ui:1906 +#, fuzzy +msgid "Low Battery Notification" +msgstr "Antwoordmelding" -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Paneel" +#: data/ui/device-preferences.ui:1967 +#, fuzzy +msgid "Fully Charged Notification" +msgstr "Deelmeldingen" -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Gebruikersmenu" +#: data/ui/device-preferences.ui:2014 +#, fuzzy +msgid "System Battery" +msgstr "Batterij" -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" -msgstr "Ondersteuningslogboek genereren" +#: data/ui/device-preferences.ui:2065 +#, fuzzy +msgid "Share Statistics" +msgstr "Deelmeldingen" -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "Over Zorin Connect" +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Batterij" -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Overschakelen naar Bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "Overschakelen naar LAN" +#: data/ui/device-preferences.ui:2394 +msgid "Keyboard Shortcuts" +msgstr "Sneltoetsen" -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Versleutelingsinformatie" +#: data/ui/device-preferences.ui:2529 +msgid "Device is unpaired" +msgstr "Apparaat is niet gekoppeld" -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Ontkoppelen" +#: data/ui/device-preferences.ui:2544 +msgid "You may configure this device before pairing" +msgstr "Je kunt dit apparaat instellen alvorens het te koppelen" #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Naar apparaat" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Van apparaat" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Niets" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Verlagen" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Dempen" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Berichten" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Nieuw gesprek" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Geen gesprekken" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "Geen gesprek gekozen" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "Kies of begin een gesprek" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Apparaat is niet verbonden" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "Geen gesprekken" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Versturen" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "Bezig met zoeken naar apparaten…" +#: data/ui/preferences-window.ui:18 +#, fuzzy +msgid "Device Name" +msgstr "Apparaatnaam bewerken" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "" + +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "Verversen" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" msgstr "Mobiele instellingen" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Apparaatnaam bewerken" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Apparaten" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Bezig met zoeken naar apparaten…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Browser-add-ons" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Inschakelen" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" msgstr "Dit apparaat is onzichtbaar voor niet-gekoppelde apparaten" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" msgstr "Herkenning uitgeschakeld" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Weergavemodus" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Paneel" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Gebruikersmenu" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Ondersteuningslogboek genereren" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "Over Zorin Connect" + #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "SMS versturen" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Mobiele apparaten" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" msgstr[0] "%d verbonden" msgstr[1] "%d verbonden" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Versturen naar mobiel apparaat" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Openen" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Aan" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Uit" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Uitgeschakeld" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Sneltoets instellen" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Instellen" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Voer een nieuwe sneltoets in om %s te wijzigen" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "" +"Druk op Esc om te annuleren of Backspace om de standaard sneltoets te " +"herstellen." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s wordt al gebruikt" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "Een volledige KDE Connect-implementatie voor GNOME" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "Heimen Stoffels" + +#: src/preferences/service.js:430 +msgid "" +"Debug messages are being logged. Take any steps necessary to reproduce a " +"problem then review the log." +msgstr "" +"Foutopsporingsberichten worden gelogd. Doe alles wat nodig is om het " +"probleem aan te tonen en kijk dan het logbestand na." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Logbestand nakijken" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Laptop" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Smartphone" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Tablet" + +#: src/preferences/service.js:508 +#, fuzzy +msgid "Television" +msgstr "Telefoon" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Ontkoppeld" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Niet verbonden" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Verbonden" + +#: src/preferences/service.js:675 +#, fuzzy +msgid "Waiting for service…" +msgstr "Bezig met zoeken naar apparaten…" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Rapporteren" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Authenticatiefout" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Netwerkfout" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Klik voor probleemoplossing" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "" "Discovery has been disabled due to the number of devices on this network." msgstr "" "Herkenning is uitgeschakeld vanwege het aantal apparaten op dit netwerk." -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "Kan plug-in %s niet laden" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" msgstr "Klik voor meer informatie" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "Nummer bellen" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" msgstr "Bestand delen" +#: src/service/daemon.js:774 +#, fuzzy +msgid "List available devices" +msgstr "Niet beschikbaar" + +#: src/service/daemon.js:783 +#, fuzzy +msgid "List all devices" +msgstr "Mobiele apparaten" + +#: src/service/daemon.js:792 +#, fuzzy +msgid "Target Device" +msgstr "Naar apparaat" + +#: src/service/daemon.js:834 +#, fuzzy +msgid "Message Body" +msgstr "Nieuw bericht" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Melding versturen" + +#: src/service/daemon.js:855 +#, fuzzy +msgid "Notification App Name" +msgstr "Meldingen" + +#: src/service/daemon.js:864 +#, fuzzy +msgid "Notification Body" +msgstr "Meldingen" + +#: src/service/daemon.js:873 +#, fuzzy +msgid "Notification Icon" +msgstr "Meldingen" + +#: src/service/daemon.js:882 +#, fuzzy +msgid "Notification ID" +msgstr "Meldingen" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Foto" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ping" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Over laten gaan" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Link delen" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "" + #: src/service/device.js:174 msgid "Not available" msgstr "Niet beschikbaar" @@ -441,83 +646,69 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "%s-vingerafdruk:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Laptop" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Smartphone" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Tablet" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Bureaubladcomputer" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Opnieuw verbinden" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Instellingen" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Koppelverzoek van %s" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Weigeren" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Accepteren" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Over laten gaan" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: accuniveau is laag" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d%% resterend" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, fuzzy, javascript-format +msgid "%s: Battery is full" +msgstr "%s: accuniveau is laag" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Volledig opgeladen" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Klembord" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Klembord versturen" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Klembord ophalen" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Onbekende contactpersoon" @@ -529,54 +720,47 @@ msgid "Mousepad" msgstr "Touchpad" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Toetsenbord" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "Extra software vereist" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "Toetsenbord niet gereed" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Melding annuleren" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Melding sluiten" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Antwoordmelding" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "Melding versturen" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" -msgstr "Foto" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Ping" +#: src/service/plugins/notification.js:59 +#, fuzzy +msgid "Activate Notification" +msgstr "Deelmeldingen" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Ping: %s" +#: src/service/plugins/presenter.js:9 +#, fuzzy +msgid "Presentation" +msgstr "Bestanden-integratie" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Opdrachten uitvoeren" @@ -593,18 +777,14 @@ msgid "Unmount" msgstr "Ontkoppelen" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Alle bestanden" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Camera-afbeeldingen" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "Bestanden" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Delen" @@ -613,85 +793,88 @@ msgid "Share Text" msgstr "Tekst delen" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Link delen" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Overdracht mislukt" + +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" -msgstr "Bezig met starten van overdracht" +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +#, fuzzy +msgid "Transferring File" +msgstr "Overdracht mislukt" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "Bezig met ontvangen van “%s” van %s" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Overdracht voltooid" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "“%s” ontvangen van %s" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Map openen" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Bestand openen" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "Overdracht mislukt" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Ontvangen van “%s” van %s mislukt" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "Tekst, gedeeld door %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Bezig met versturen van “%s” naar %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "“%s” verstuurd naar %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Versturen van “%s” naar %s mislukt" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Bestanden versturen naar %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Openen na afronden" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Link versturen naar %s" @@ -708,7 +891,7 @@ msgid "Reply SMS" msgstr "SMS beantwoorden" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "SMS delen" @@ -721,107 +904,58 @@ msgstr "Oproep dempen" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Inkomende oproep" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Lopende oproep" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Overig" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Fax" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Werk" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Mobiel" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Thuis" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Versturen naar %s" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Openen" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "Aan" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "Uit" - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Uitgeschakeld" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Sneltoets instellen" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Instellen" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Voer een nieuwe sneltoets in om %s te wijzigen" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "" -"Druk op Esc om te annuleren of Backspace om de standaard sneltoets te " -"herstellen." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s wordt al gebruikt" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Zojuist" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -829,17 +963,29 @@ msgstr[1] "%d minuten" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Gisteren - %s" +#: src/service/ui/messaging.js:255 +#, fuzzy +msgid "Group Message" +msgstr "Nieuw bericht" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "Jij: %s" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "" +msgstr[1] "" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "Kies een apparaat" @@ -848,106 +994,63 @@ msgid "Select" msgstr "Kiezen" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "Ontkoppeld" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Niet verbonden" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Verbonden" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "" -"Transferred files are placed in the Downloads folder." -msgstr "" -"Overgedragen bestanden worden geplaatst in de map Downloads." - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "Een volledige KDE Connect-implementatie voor GNOME" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "Heimen Stoffels" - -#: src/service/ui/settings.js:529 -msgid "" -"Debug messages are being logged. Take any steps necessary to reproduce a " -"problem then review the log." -msgstr "" -"Foutopsporingsberichten worden gelogd. Doe alles wat nodig is om het " -"probleem aan te tonen en kijk dan het logbestand na." - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "Logbestand nakijken" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "Volledig opgeladen" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Geen apparaat gevonden" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (bezig met berekenen...)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (%d:%02d tot volledig opgeladen)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (%d:%02d resterend)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d uur" +msgstr[1] "%d uur" + +#. TRANSLATORS: Time until change with time duration +#. EXAMPLE: Until 10:00 (2 hours) +#: src/shell/donotdisturb.js:150 +#, javascript-format +msgid "Until %s (%s)" +msgstr "Tot %s (%s)" + +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 msgid "Do Not Disturb" msgstr "Niet storen" -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" msgstr "Geen geluid bij mobiele meldingen" -#: src/shell/donotdisturb.js:171 +#: src/shell/donotdisturb.js:261 msgid "Until you turn off Do Not Disturb" msgstr "Totdat je Niet storen uitschakelt" -#. TRANSLATORS: Time until change with time duration -#. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 -#, javascript-format -msgid "Until %s (%s)" -msgstr "Tot %s (%s)" - -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Klaar" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d uur" -msgstr[1] "%d uur" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Beantwoorden" @@ -966,11 +1069,6 @@ msgid "Service Unavailable" msgstr "Dienst niet beschikbaar" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Geen apparaat gevonden" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" @@ -979,6 +1077,48 @@ msgid "Mobile Application" msgstr "Mobiele applicatie" +#~ msgid "Bluetooth Device" +#~ msgstr "Bluetooth-apparaat" + +#~ msgid "Command Shortcuts" +#~ msgstr "Opdracht-sneltoetsen" + +#~ msgid "Delete" +#~ msgstr "Verwijderen" + +#~ msgid "Delete this device" +#~ msgstr "Dit apparaat verwijderen" + +#~ msgid "Unpair and remove all settings and files" +#~ msgstr "Ontkoppelen en alle instellingen en bestanden verwijderen" + +#~ msgid "Switch to Bluetooth" +#~ msgstr "Overschakelen naar Bluetooth" + +#~ msgid "Switch to LAN" +#~ msgstr "Overschakelen naar LAN" + +#~ msgid "%s Plugin Failed To Load" +#~ msgstr "Kan plug-in %s niet laden" + +#~ msgid "Reconnect" +#~ msgstr "Opnieuw verbinden" + +#~ msgid "Settings" +#~ msgstr "Instellingen" + +#~ msgid "Additional Software Required" +#~ msgstr "Extra software vereist" + +#~ msgid "Starting Transfer" +#~ msgstr "Bezig met starten van overdracht" + +#~ msgid "" +#~ "Transferred files are placed in the Downloads folder." +#~ msgstr "" +#~ "Overgedragen bestanden worden geplaatst in de map Downloads." + #~ msgid "About" #~ msgstr "Over" @@ -988,9 +1128,6 @@ #~ msgid "KDE Connect" #~ msgstr "KDE Connect" -#~ msgid "New Message" -#~ msgstr "Nieuw bericht" - #~ msgid "Debugger" #~ msgstr "Foutopsporing" @@ -1018,9 +1155,6 @@ #~ msgid "Desktop Contacts" #~ msgstr "Bureaubladcontactpersonen" -#~ msgid "Files Integration" -#~ msgstr "Bestanden-integratie" - #~ msgid "Additional Features" #~ msgstr "Extra functies" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/org.gnome.Shell.Extensions.ZorinConnect.pot gnome-shell-extension-zorin-connect-28.0.2/po/org.gnome.Shell.Extensions.ZorinConnect.pot --- gnome-shell-extension-zorin-connect-24.1/po/org.gnome.Shell.Extensions.ZorinConnect.pot 2019-03-17 12:29:07.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/org.gnome.Shell.Extensions.ZorinConnect.pot 2019-11-30 17:35:00.000000000 +0000 @@ -8,422 +8,607 @@ msgstr "" "Project-Id-Version: org.gnome.Shell.Extensions.ZorinConnect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" -"Language: en\n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "" + #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" msgstr "" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" msgstr "" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "" -#: data/device.ui:1734 -msgid "Delete" -msgstr "" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "" -#: data/device.ui:2048 -msgid "Keyboard Shortcuts" +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" msgstr "" -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" msgstr "" -#: data/device.ui:2183 -msgid "Device is unpaired" +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" msgstr "" -#: data/device.ui:2198 -msgid "You may configure this device before pairing" +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" msgstr "" -#: data/menus.ui:12 -msgid "Display Mode" +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" msgstr "" -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "" - -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "" - -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" -msgstr "" - -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" msgstr "" -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" +#: data/ui/device-preferences.ui:2394 +msgid "Keyboard Shortcuts" msgstr "" -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" +#: data/ui/device-preferences.ui:2529 +msgid "Device is unpaired" msgstr "" -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" +#: data/ui/device-preferences.ui:2544 +msgid "You may configure this device before pairing" msgstr "" #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "" -#: data/messaging.ui:264 -msgid "No Conversations" +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 +msgid "Send" msgstr "" -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 -msgid "Send" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" msgstr "" -#: data/settings.ui:10 -msgid "Searching for devices…" +#: data/ui/preferences-window.ui:49 +msgid "_Rename" msgstr "" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" msgstr "" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" msgstr "" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" msgstr "" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "" + #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" msgstr[0] "" msgstr[1] "" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "" + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "" + +#: src/preferences/service.js:430 +msgid "" +"Debug messages are being logged. Take any steps necessary to reproduce a " +"problem then review the log." +msgstr "" + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "" + +#: src/service/daemon.js:337 msgid "Report" msgstr "" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "" "Discovery has been disabled due to the number of devices on this network." msgstr "" -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" msgstr "" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" msgstr "" +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "" + #: src/service/device.js:174 msgid "Not available" msgstr "" @@ -440,83 +625,69 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "" @@ -528,54 +699,45 @@ msgid "Mousepad" msgstr "" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" -msgstr "" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" msgstr "" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "" +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "" @@ -592,18 +754,14 @@ msgid "Unmount" msgstr "" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "" @@ -612,85 +770,87 @@ msgid "Share Text" msgstr "" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" msgstr "" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "" + +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" msgstr "" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "" @@ -707,7 +867,7 @@ msgid "Reply SMS" msgstr "" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "" @@ -720,105 +880,58 @@ msgstr "" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "" - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "" - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -826,17 +939,28 @@ msgstr[1] "" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "" +msgstr[1] "" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "" @@ -845,102 +969,63 @@ msgid "Select" msgstr "" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "" -"Transferred files are placed in the Downloads folder." -msgstr "" - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "" - -#: src/service/ui/settings.js:529 -msgid "" -"Debug messages are being logged. Take any steps necessary to reproduce a " -"problem then review the log." -msgstr "" - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" msgstr "" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 -msgid "Do Not Disturb" +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "" +msgstr[1] "" + +#. TRANSLATORS: Time until change with time duration +#. EXAMPLE: Until 10:00 (2 hours) +#: src/shell/donotdisturb.js:150 +#, javascript-format +msgid "Until %s (%s)" msgstr "" -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 +msgid "Do Not Disturb" msgstr "" -#: src/shell/donotdisturb.js:171 -msgid "Until you turn off Do Not Disturb" +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" msgstr "" -#. TRANSLATORS: Time until change with time duration -#. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 -#, javascript-format -msgid "Until %s (%s)" +#: src/shell/donotdisturb.js:261 +msgid "Until you turn off Do Not Disturb" msgstr "" -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "" -msgstr[1] "" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "" @@ -959,11 +1044,6 @@ msgid "Service Unavailable" msgstr "" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/pl.po gnome-shell-extension-zorin-connect-28.0.2/po/pl.po --- gnome-shell-extension-zorin-connect-24.1/po/pl.po 2019-05-29 12:51:21.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/pl.po 2019-11-30 17:35:09.000000000 +0000 @@ -2,11 +2,11 @@ msgstr "" "Project-Id-Version: zorin-connect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" -"PO-Revision-Date: 2019-05-18 10:54\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-10 11:34\n" "Last-Translator: Andy Holmes (andyholmes)\n" "Language-Team: Polish\n" -"Language: pl\n" +"Language: pl_PL\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -16,363 +16,391 @@ "X-Crowdin-Language: pl\n" "X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Informacje o szyfrowaniu" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Powiąż" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Odwiąż" + #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "Połącz z…" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "Anuluj" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Połącz" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "Adres IP" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Urządzenie Bluetooth" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Numer telefonu lub nazwa kontaktu" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "Brak kontaktów" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Pomoc" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Numer telefonu lub nazwa kontaktu" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "Napisz wiadomość" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "Wysyła wiadomość" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Akumulator" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Komputer stacjonarny" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" msgstr "Aparat" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Synchronizacja schowka" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Odtwarzacze multimediów" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Mysz i klawiatura" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Sterowanie głośnością" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Pliki" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "Odbieranie plików" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Udostępnianie" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Polecenia" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Nazwa" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "Wiersz poleceń" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Wybiera plik wykonywalny" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Dodaje" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Usuwa" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Modyfikuje" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Zapisuje" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Udostępnianie powiadomień" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "Udostępnianie podczas aktywności" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Programy" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Powiadomienia" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Kontakty" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Połączenia przychodzące" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Głośność" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Wstrzymywanie multimediów" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Trwające połączenia" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Wyciszanie mikrofonu" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Komunikacja" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Skróty działań" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Przywróć wszystko…" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Skróty poleceń" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Skróty" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Wtyczki" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Eksperymentalne" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "Obsługa SMS (poprzednia wersja)" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Usuń" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Usuń to urządzenie" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Odwiąż i usuń wszystkie ustawienia i pliki" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Zaawansowane" -#: data/device.ui:2048 +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "Akumulator urządzenia" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "Powiadomienie o niskim poziomie naładowania akumulatora" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "Powiadomienie o pełnym naładowaniu" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "Akumulator komputera" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "Udostępnianie statystyk" + +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Akumulator" + +#: data/ui/device-preferences.ui:2394 msgid "Keyboard Shortcuts" msgstr "Skróty klawiszowe" -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Powiąż" - -#: data/device.ui:2183 +#: data/ui/device-preferences.ui:2529 msgid "Device is unpaired" msgstr "Urządzenie jest niepowiązane" -#: data/device.ui:2198 +#: data/ui/device-preferences.ui:2544 msgid "You may configure this device before pairing" msgstr "Można skonfigurować to urządzenie przed powiązaniem" -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "Tryb wyświetlania" - -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Panel" - -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Menu użytkownika" - -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" -msgstr "Utwórz dziennik wsparcia" - -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "O programie" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Przełącz na sieć Bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "Przełącz na sieć LAN" - -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Informacje o szyfrowaniu" - -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Odwiąż" - #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Do urządzenia" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Z urządzenia" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Nic" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Ciszej" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Wycisz" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Wiadomości" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Nowa rozmowa" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Brak rozmów" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "Nie wybrano rozmowy" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "Wybierz lub rozpocznij rozmowę" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Urządzenie jest rozłączone" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "Brak rozmów" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Wyślij" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "Wyszukiwanie urządzeń…" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "Nazwa urządzenia" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "_Zmień nazwę" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "Odśwież" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" msgstr "Ustawienia urządzeń mobilnych" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Modyfikuje nazwę urządzenia" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Urządzenia" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Wyszukiwanie urządzeń…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Dodatki do przeglądarek" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Włącz" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" msgstr "To urządzenie jest niewidoczne dla niepowiązanych urządzeń" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" msgstr "Wykrywanie jest wyłączone" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Tryb wyświetlania" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Panel" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Menu użytkownika" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Utwórz dziennik wsparcia" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "O programie" + #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "Wyślij SMS" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Urządzenia mobilne" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "Włącz" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" @@ -381,48 +409,205 @@ msgstr[2] "%d połączonych urządzeń" msgstr[3] "%d połączonych urządzeń" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "Wyłącz" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Wyślij na urządzenie mobilne" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Otwórz" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Włączone" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Wyłączone" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Wyłączone" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Ustawienie skrótu" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Ustaw" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Proszę wprowadzić nowy skrót, aby zmienić „%s”" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "Klawisz Esc anuluje, a Backspace przywróci skrót klawiszowy." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s jest już używane" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "Pełna implementacja KDE Connect dla środowiska GNOME" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "Adrian Kryński , 2017\n" +"Piotr Drąg , 2018-2019\n" +"Aviary.pl , 2018-2019" + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "Komunikaty debugowania są zapisywane w dzienniku. Proszę podjąć działania niezbędne do powtórzenia problemu, a następnie przejrzeć dziennik." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Przejrzyj dziennik" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Laptop" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Smartfon" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Tablet" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "Telewizor" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Niepowiązane" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Rozłączone" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Połączone" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "Oczekiwanie na usługę…" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Zgłoś" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Niepowodzenie uwierzytelnienia" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Błąd sieci" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Uzyskaj pomoc w rozwiązaniu problemu" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "Discovery has been disabled due to the number of devices on this network." msgstr "Wykrywanie zostało wyłączone z powodu liczby urządzeń w tej sieci." -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "Wczytanie wtyczki %s się nie powiodło" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" msgstr "Więcej informacji" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "Zadzwoń" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" msgstr "Udostępnij plik" +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "Wyświetla listę dostępnych urządzeń" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "Wyświetla listę wszystkich urządzeń" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "Urządzenie docelowe" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "Treść wiadomości" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Wyślij powiadomienie" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "Nazwa aplikacji powiadomienia" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "Treść powiadomienia" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "Ikona powiadomienia" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "Identyfikator powiadomienia" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Zdjęcie" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ping" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Zadzwoń" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Udostępnij odnośnik" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "Wyświetla wersję wydania" + #: src/service/device.js:174 msgid "Not available" msgstr "Niedostępne" @@ -439,83 +624,69 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "Odcisk urządzenia %s:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Laptop" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Smartfon" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Tablet" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Komputer stacjonarny" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Połącz ponownie" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Ustawienia" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Prośba o powiązanie z urządzenia %s" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Odrzuć" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Przyjmij" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Zadzwoń" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: poziom naładowania akumulatora jest niski" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "Pozostało %d%%" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "%s: akumulator jest w pełni naładowany" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "W pełni naładowane" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Schowek" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Wysyłanie do schowka" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Odbieranie ze schowka" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Nieznany kontakt" @@ -527,54 +698,45 @@ msgid "Mousepad" msgstr "Podkładka pod mysz" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Klawiatura" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "Wymagane jest dodatkowe oprogramowanie" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "Klawiatura nie jest gotowa" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Anuluj powiadomienie" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Zamknij powiadomienie" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Odpowiedz na powiadomienie" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "Wyślij powiadomienie" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" -msgstr "Zdjęcie" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Ping" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "Aktywuj powiadomienie" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Ping: %s" +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "Prezentacja" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Wykonywanie poleceń" @@ -591,18 +753,14 @@ msgid "Unmount" msgstr "Odmontuj" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Wszystkie pliki" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Zdjęcia z aparatu" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "Pliki" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Udostępnij" @@ -611,85 +769,87 @@ msgid "Share Text" msgstr "Udostępnij tekst" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Udostępnij odnośnik" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Przesłanie się nie powiodło" + +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "Urządzenie %s nie może wysyłać plików" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" -msgstr "Rozpoczynanie przesyłania" +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "Przesyłanie pliku" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "Odbieranie „%s” z urządzenia %s" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Pomyślnie przesłano" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "Odebrano „%s” z urządzenia %s" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Otwórz katalog" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Otwórz plik" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "Przesłanie się nie powiodło" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Odebranie „%s” z urządzenia %s się nie powiodło" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "Tekst udostępniony przez: %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Wysyłanie „%s” do urządzenia %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "Wysłano „%s” do urządzenia %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Wysłanie „%s” do urządzenia %s się nie powiodło" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Wysłanie plików do urządzenia %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Otwarcie po ukończeniu" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Wysyła odnośnik do urządzenia %s" @@ -706,7 +866,7 @@ msgid "Reply SMS" msgstr "Odpowiedz na SMS" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Udostępnij SMS" @@ -719,105 +879,58 @@ msgstr "Wycisz połączenie" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Połączenie przychodzące" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Trwające połączenie" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Inne" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Faks" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Praca" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Komórkowy" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Domowy" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Wyślij do „%s”" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Otwórz" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "Włączone" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "Wyłączone" - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Wyłączone" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Ustawienie skrótu" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Ustaw" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Proszę wprowadzić nowy skrót, aby zmienić „%s”" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Klawisz Esc anuluje, a Backspace przywróci skrót klawiszowy." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s jest już używane" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Przed chwilą" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -827,17 +940,30 @@ msgstr[3] "%d minut" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Wczoraj・%s" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "Wiadomość grupowa" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "Ja: %s" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "I %d inny kontakt" +msgstr[1] "I %d inne kontakty" +msgstr[2] "I %d innych kontaktów" +msgstr[3] "I %d innych kontaktów" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "Wybór urządzenia" @@ -846,103 +972,65 @@ msgid "Select" msgstr "Wybierz" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "Niepowiązane" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Rozłączone" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Połączone" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "Transferred files are placed in the Downloads folder." -msgstr "Przesłane pliki są umieszczane w katalogu Pobrane." - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "Pełna implementacja KDE Connect dla środowiska GNOME" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "Adrian Kryński , 2017\n" -"Piotr Drąg , 2018\n" -"Aviary.pl , 2018" - -#: src/service/ui/settings.js:529 -msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." -msgstr "Komunikaty debugowania są zapisywane w dzienniku. Proszę podjąć działania niezbędne do powtórzenia problemu, a następnie przejrzeć dziennik." - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "Przejrzyj dziennik" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "W pełni naładowane" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Nie odnaleziono żadnego urządzenia" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (obliczanie…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (do naładowania: %d∶%02d)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (pozostało: %d∶%02d)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d godzina" +msgstr[1] "%d godziny" +msgstr[2] "%d godzin" +msgstr[3] "%d godzin" + +#. TRANSLATORS: Time until change with time duration +#. EXAMPLE: Until 10:00 (2 hours) +#: src/shell/donotdisturb.js:150 +#, javascript-format +msgid "Until %s (%s)" +msgstr "Do %s (%s)" + +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 msgid "Do Not Disturb" msgstr "Nie przeszkadzać" -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" msgstr "Wycisz powiadomienia z urządzenia mobilnego" -#: src/shell/donotdisturb.js:171 +#: src/shell/donotdisturb.js:261 msgid "Until you turn off Do Not Disturb" msgstr "Do wyłączenia trybu „Nie przeszkadzać”" -#. TRANSLATORS: Time until change with time duration -#. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 -#, javascript-format -msgid "Until %s (%s)" -msgstr "Do %s (%s)" - -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Gotowe" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d godzina" -msgstr[1] "%d godziny" -msgstr[2] "%d godzin" -msgstr[3] "%d godzin" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Odpowiedz" @@ -961,11 +1049,6 @@ msgid "Service Unavailable" msgstr "Usługa jest niedostępna" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Nie odnaleziono żadnego urządzenia" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/POTFILES gnome-shell-extension-zorin-connect-28.0.2/po/POTFILES --- gnome-shell-extension-zorin-connect-24.1/po/POTFILES 2019-03-17 12:26:48.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/POTFILES 2019-11-30 14:52:32.000000000 +0000 @@ -1,14 +1,17 @@ -data/connect.ui -data/contacts.ui -data/conversation.ui -data/device.ui -data/menus.ui -data/messaging.ui -data/notification.ui -data/settings.ui -data/telephony.ui +data/gtk/menus.ui +data/ui/connect.ui +data/ui/contact-chooser.ui +data/ui/conversation.ui +data/ui/device-preferences.ui +data/ui/messaging-window.ui +data/ui/notification-reply-dialog.ui +data/ui/preferences-window.ui +data/ui/telephony.ui src/extension.js src/nautilus-zorin-connect.py +src/preferences/device.js +src/preferences/keybindings.js +src/preferences/service.js src/service/daemon.js src/service/device.js src/service/plugins/battery.js @@ -20,6 +23,7 @@ src/service/plugins/notification.js src/service/plugins/photo.js src/service/plugins/ping.js +src/service/plugins/presenter.js src/service/plugins/runcommand.js src/service/plugins/sftp.js src/service/plugins/share.js @@ -27,11 +31,8 @@ src/service/plugins/systemvolume.js src/service/plugins/telephony.js src/service/ui/contacts.js -src/service/ui/device.js -src/service/ui/keybindings.js src/service/ui/messaging.js src/service/ui/service.js -src/service/ui/settings.js src/service/ui/telephony.js src/shell/device.js src/shell/donotdisturb.js diff -Nru gnome-shell-extension-zorin-connect-24.1/po/pt_BR.po gnome-shell-extension-zorin-connect-28.0.2/po/pt_BR.po --- gnome-shell-extension-zorin-connect-24.1/po/pt_BR.po 2019-03-17 12:33:01.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/pt_BR.po 2019-11-30 17:35:20.000000000 +0000 @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: org.gnome.Shell.Extensions.ZorinConnect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-19 11:14-0800\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" "PO-Revision-Date: 2018-11-24 21:11-0200\n" "Last-Translator: Ricardo Silva Veloso \n" "Language-Team: \n" @@ -18,395 +18,634 @@ "Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Generator: Poedit 2.2\n" -#: data/conversation.ui:71 data/conversation.ui:79 -msgid "Type a message" -msgstr "Escrever uma mensagem" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Informação de criptografia" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Parear" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Esquecer" + +#. TRANSLATORS: Open a dialog to connect to an IP or Bluez device +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 +msgid "Connect to…" +msgstr "Conectar a…" + +#. Action Buttons +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 +msgid "Cancel" +msgstr "Cancelar" + +#: data/ui/connect.ui:27 +msgid "Connect" +msgstr "Conectar" + +#: data/ui/connect.ui:74 +msgid "IP Address" +msgstr "" + +#: data/ui/contact-chooser.ui:50 +#, fuzzy +msgid "No contacts" +msgstr "Contatos" + +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 +msgid "Help" +msgstr "Ajuda" -#: data/contacts.ui:51 data/contacts.ui:52 +#: data/ui/contact-chooser.ui:103 msgid "Type a phone number or name" msgstr "Digite um número de telefone ou nome" -#: data/device.ui:68 src/service/plugins/battery.js:12 -msgid "Battery" -msgstr "Bateria" +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 +msgid "Type a message" +msgstr "Escrever uma mensagem" + +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 +#, fuzzy +msgid "Send Message" +msgstr "Nova mensagem" -#: data/device.ui:116 +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Computador" + +#: data/ui/device-preferences.ui:88 +msgid "Camera" +msgstr "" + +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Sincronização da área de transferência" -#: data/device.ui:172 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Reprodutores de mídia" -#: data/device.ui:220 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Mouse & teclado" -#: data/device.ui:268 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Controle de volume" -#: data/device.ui:308 data/device.ui:1406 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Arquivos" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Compartilhar" -#: data/device.ui:337 data/device.ui:534 data/device.ui:1449 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:169 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Comandos" -#: data/device.ui:385 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Nome" -#: data/device.ui:401 data/device.ui:402 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 +msgid "Command Line" +msgstr "Linha de comando" + +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Escolher um executável" -#: data/device.ui:403 -msgid "Command Line" -msgstr "Linha de comando" +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 +msgid "Add" +msgstr "" -#: data/device.ui:597 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 +msgid "Remove" +msgstr "" + +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 +msgid "Edit" +msgstr "" + +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 +msgid "Save" +msgstr "" + +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Compartilhar notificações" -#: data/device.ui:636 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Aplicativos" -#: data/device.ui:675 data/device.ui:1492 -#: src/service/plugins/notification.js:12 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 +#: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Notificações" -#: data/device.ui:705 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 +msgid "Contacts" +msgstr "Contatos" + +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Chamadas recebidas" -#: data/device.ui:755 data/device.ui:900 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Volume" -#: data/device.ui:813 data/device.ui:958 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Pausar mídia" -#: data/device.ui:852 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Chamadas em andamento" -#: data/device.ui:1007 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Silenciar microfone" -#: data/device.ui:1047 data/device.ui:1535 src/service/plugins/telephony.js:12 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Telefonia" -#: data/device.ui:1082 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Atalhos de ações" -#: data/device.ui:1094 data/device.ui:1157 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Redefinir tudo…" -#: data/device.ui:1145 -msgid "Command Shortcuts" -msgstr "Atalhos de comandos" - -#: data/device.ui:1203 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Atalhos" -#: data/device.ui:1234 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Plugins" -#: data/device.ui:1295 -msgid "Delete" -msgstr "Excluir" - -#: data/device.ui:1320 -msgid "Delete this device" -msgstr "Excluir este dispositivo" - -#: data/device.ui:1335 -msgid "Unpair and remove all settings and files" -msgstr "Esquecer e remover todas as configurações e arquivos" +#: data/ui/device-preferences.ui:1723 +msgid "Experimental" +msgstr "" + +#: data/ui/device-preferences.ui:1771 +msgid "Legacy SMS Support" +msgstr "" -#: data/device.ui:1365 data/device.ui:1621 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Avançado" -#: data/device.ui:1578 -msgid "Keyboard Shortcuts" -msgstr "Atalhos de teclado" +#: data/ui/device-preferences.ui:1855 +#, fuzzy +msgid "Device Battery" +msgstr "Bateria" -#. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/menus.ui:7 src/service/ui/service.js:115 -msgid "Connect to…" -msgstr "Conectar a…" +#: data/ui/device-preferences.ui:1906 +#, fuzzy +msgid "Low Battery Notification" +msgstr "Responder notificação" -#: data/menus.ui:13 data/settings.ui:881 -msgid "Help" -msgstr "Ajuda" +#: data/ui/device-preferences.ui:1967 +#, fuzzy +msgid "Fully Charged Notification" +msgstr "Compartilhar notificações" -#. TRANSLATORS: Open the developer's dialog -#: data/menus.ui:19 -msgid "Debugger" -msgstr "Depurador" - -#: data/menus.ui:23 -msgid "About" -msgstr "Sobre" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:34 -msgid "Switch to Bluetooth" -msgstr "Mudar para Bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:41 -msgid "Switch to LAN" -msgstr "Mudar para LAN" +#: data/ui/device-preferences.ui:2014 +#, fuzzy +msgid "System Battery" +msgstr "Bateria" -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:48 src/service/ui/settings.js:612 -msgid "Encryption Info" -msgstr "Informação de criptografia" +#: data/ui/device-preferences.ui:2065 +#, fuzzy +msgid "Share Statistics" +msgstr "Compartilhar notificações" -#. TRANSLATORS: Send a pair request to the device -#: data/menus.ui:53 src/service/device.js:425 -msgid "Pair" -msgstr "Parear" +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Bateria" -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:59 src/service/device.js:433 -msgid "Unpair" -msgstr "Esquecer" +#: data/ui/device-preferences.ui:2394 +msgid "Keyboard Shortcuts" +msgstr "Atalhos de teclado" + +#: data/ui/device-preferences.ui:2529 +#, fuzzy +msgid "Device is unpaired" +msgstr "Dispositivo está desconectado" + +#: data/ui/device-preferences.ui:2544 +msgid "You may configure this device before pairing" +msgstr "" #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:71 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Para o dispositivo" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:77 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Do dispositivo" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:89 data/menus.ui:115 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Nada" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:96 data/menus.ui:122 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Baixo" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:103 data/menus.ui:129 src/service/plugins/telephony.js:176 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Silenciar" -#: data/messaging.ui:12 src/service/plugins/sms.js:25 -#: src/service/ui/messaging.js:871 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Mensagens" -#: data/messaging.ui:110 -msgid "Select a conversation" +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 +#, fuzzy +msgid "New Conversation" +msgstr "Selecione uma conversa" + +#: data/ui/messaging-window.ui:108 +#, fuzzy +msgid "No Conversations" msgstr "Selecione uma conversa" -#: data/messaging.ui:188 +#: data/ui/messaging-window.ui:168 +msgid "No conversation selected" +msgstr "" + +#: data/ui/messaging-window.ui:184 +#, fuzzy +msgid "Select or start a conversation" +msgstr "Selecione uma conversa" + +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Dispositivo está desconectado" -#: data/settings.ui:333 -msgid "Appearance" -msgstr "Aparência" +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 +msgid "Send" +msgstr "Enviar" -#: data/settings.ui:383 -msgid "Display Mode" -msgstr "Modo de exibição" +#: data/ui/preferences-window.ui:18 +#, fuzzy +msgid "Device Name" +msgstr "Para o dispositivo" -#: data/settings.ui:425 -msgid "Service" -msgstr "Serviço" - -#: data/settings.ui:475 -msgid "Discoverable" -msgstr "Visível" - -#: data/settings.ui:528 -msgid "Restart Service" -msgstr "Reiniciar serviço" - -#: data/settings.ui:581 data/settings.ui:1015 src/service/device.js:417 -msgid "Settings" -msgstr "Configurações" - -#: data/settings.ui:639 -msgid "Remote Filesystems" -msgstr "Sistemas de arquivos remotos" - -#: data/settings.ui:675 -msgid "Sound Effects" -msgstr "Efeitos sonoros" - -#: data/settings.ui:712 -msgid "Extended Keyboard Support" -msgstr "Suporte a teclado estendido" - -#: data/settings.ui:749 -msgid "Desktop Contacts" -msgstr "Integração com contatos" +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "" -#: data/settings.ui:786 -msgid "Files Integration" -msgstr "Integração com arquivos" +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 +msgid "Refresh" +msgstr "Recarregar" -#: data/settings.ui:813 -msgid "Additional Features" -msgstr "Funcionalidades adicionais" +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 +msgid "Mobile Settings" +msgstr "Configurações de dispositivos" + +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 +msgid "Edit Device Name" +msgstr "" + +#: data/ui/preferences-window.ui:257 +#, fuzzy +msgid "Devices" +msgstr "Para o dispositivo" + +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "" -#: data/settings.ui:903 +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Complementos para navegadores" -#: data/settings.ui:921 -msgid "KDE Connect" -msgstr "KDE Connect" - -#: data/settings.ui:956 data/settings.ui:1058 -msgid "Other" -msgstr "Outro" +#: data/ui/preferences-window.ui:612 +#, fuzzy +msgid "Enable" +msgstr "Tablet" -#. TRANSLATORS: No devices are known or available -#: data/settings.ui:1106 webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Nenhum dispositivo encontrado" +#: data/ui/preferences-window.ui:644 +msgid "This device is invisible to unpaired devices" +msgstr "" -#: data/settings.ui:1142 -msgid "Refresh" -msgstr "Recarregar" +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 +msgid "Discovery Disabled" +msgstr "Descoberta desativada" + +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Modo de exibição" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Painel" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Menu do usuário" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "" + +#: data/ui/preferences-window.ui:740 +#, fuzzy +msgid "About Zorin Connect" +msgstr "Zorin Connect" + +#. TRANSLATORS: Share URL by SMS +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 +msgid "Send SMS" +msgstr "Enviar SMS" #. Service Menu -#: src/extension.js:79 src/extension.js:259 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Dispositivos móveis" -#: src/extension.js:105 -msgid "Mobile Settings" -msgstr "Configurações de dispositivos" - -#. TRANSLATORS: Extension name -#: src/extension.js:196 src/extension.js:311 src/service/daemon.js:95 -#: src/service/daemon.js:413 webextension/gettext.js:27 -msgid "Zorin Connect" -msgstr "Zorin Connect" +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "" -#. TRANSLATORS: %d is the number of devices connected -#: src/extension.js:257 +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" msgstr[0] "%d conectado" msgstr[1] "%d conectados" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:112 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Enviar para dispositivo móvel" -#: src/service/daemon.js:406 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Abrir" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Ativada" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Desativada" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Desativado" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Definir atalho" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Definir" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Digite um novo atalho para mudar %s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "" +"Pressione Esc para cancelar ou Backspace para redefinir o atalho de teclado." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s já está em uso" + +#: src/preferences/service.js:388 msgid "A complete KDE Connect implementation for GNOME" msgstr "Uma implementação completa do KDE Connect para o GNOME" #. TRANSLATORS: eg. 'Translator Name ' -#: src/service/daemon.js:415 +#: src/preferences/service.js:397 msgid "translator-credits" msgstr "Ricardo Silva Veloso " -#: src/service/daemon.js:437 +#: src/preferences/service.js:430 +msgid "" +"Debug messages are being logged. Take any steps necessary to reproduce a " +"problem then review the log." +msgstr "" + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Laptop" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Smartphone" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Tablet" + +#: src/preferences/service.js:508 +#, fuzzy +msgid "Television" +msgstr "Telefonia" + +#: src/preferences/service.js:529 +#, fuzzy +msgid "Unpaired" +msgstr "Esquecer" + +#: src/preferences/service.js:533 +#, fuzzy +msgid "Disconnected" +msgstr "Dispositivo está desconectado" + +#: src/preferences/service.js:537 +#, fuzzy +msgid "Connected" +msgstr "Conectar" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Reportar" -#: src/service/daemon.js:567 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Falha de autenticação" -#: src/service/daemon.js:576 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Erro de rede" -#: src/service/daemon.js:577 src/service/daemon.js:587 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Clique para ajuda na solução de problemas" -#: src/service/daemon.js:586 -msgid "PulseAudio Error" -msgstr "Erro do PulseAudio" +#: src/service/daemon.js:599 +msgid "" +"Discovery has been disabled due to the number of devices on this network." +msgstr "" +"A descoberta foi desativada devido ao número de dispositivos nesta rede." -#: src/service/daemon.js:596 -msgid "Discovery Disabled" -msgstr "Descoberta desativada" +#: src/service/daemon.js:608 +msgid "Click for more information" +msgstr "Clique para mais informação" -#: src/service/daemon.js:597 -msgid "Discovery has been disabled due to the number of devices on this network." -msgstr "A descoberta foi desativada devido ao número de dispositivos nesta rede." - -#: src/service/daemon.js:599 src/service/daemon.js:609 -msgid "Click to open preferences" -msgstr "Clique para abrir preferências" +#: src/service/daemon.js:705 +msgid "Dial Number" +msgstr "Ligar para número" -#: src/service/daemon.js:608 -msgid "Additional Software Required" -msgstr "Necessário software adicional" +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 +msgid "Share File" +msgstr "Compartilhar arquivo" -#: src/service/daemon.js:617 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "Falha ao carregar o plugin %s" +#: src/service/daemon.js:774 +#, fuzzy +msgid "List available devices" +msgstr "Indisponível" -#: src/service/daemon.js:618 src/service/daemon.js:635 -msgid "Click for more information" -msgstr "Clique para mais informação" +#: src/service/daemon.js:783 +#, fuzzy +msgid "List all devices" +msgstr "Dispositivos móveis" -#: src/service/daemon.js:633 -msgid "Wayland Not Supported" -msgstr "Sem suporte a Wayland" - -#: src/service/daemon.js:634 -msgid "Remote input not supported on Wayland" -msgstr "Não há suporte para entrada remota no Wayland" +#: src/service/daemon.js:792 +#, fuzzy +msgid "Target Device" +msgstr "Para o dispositivo" -#. Create an urgent notification -#: src/service/daemon.js:658 -#, javascript-format -msgid "Zorin Connect: %s" -msgstr "Zorin Connect: %s" +#: src/service/daemon.js:834 +#, fuzzy +msgid "Message Body" +msgstr "Nova mensagem" -#. TRANSLATORS: Share URL by SMS -#: src/service/daemon.js:808 src/service/plugins/sms.js:49 -#: webextension/gettext.js:39 -msgid "Send SMS" -msgstr "Enviar SMS" +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Enviar notificação" -#: src/service/daemon.js:812 -msgid "Dial Number" -msgstr "Ligar para número" +#: src/service/daemon.js:855 +#, fuzzy +msgid "Notification App Name" +msgstr "Notificações" + +#: src/service/daemon.js:864 +#, fuzzy +msgid "Notification Body" +msgstr "Notificações" + +#: src/service/daemon.js:873 +#, fuzzy +msgid "Notification Icon" +msgstr "Notificações" + +#: src/service/daemon.js:882 +#, fuzzy +msgid "Notification ID" +msgstr "Notificações" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ping" -#: src/service/device.js:166 +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +#, fuzzy +msgid "Ring" +msgstr "Localizar" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Compartilhar link" + +#: src/service/daemon.js:942 +#, fuzzy +msgid "Show release version" +msgstr "Selecione uma conversa" + +#: src/service/device.js:174 msgid "Not available" msgstr "Indisponível" #. TRANSLATORS: Bluetooth address for remote device -#: src/service/device.js:170 +#: src/service/device.js:179 #, javascript-format msgid "Bluetooth device at %s" msgstr "Dispositivo Bluetooth em %s" @@ -417,139 +656,121 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:188 src/service/device.js:190 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "Impressão digital de %s:" -#: src/service/device.js:240 -msgid "Laptop" -msgstr "Laptop" - -#: src/service/device.js:242 -msgid "Smartphone" -msgstr "Smartphone" - -#: src/service/device.js:244 -msgid "Tablet" -msgstr "Tablet" - -#: src/service/device.js:246 -msgid "Desktop" -msgstr "Computador" - -#: src/service/device.js:409 -msgid "Reconnect" -msgstr "Reconectar" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:606 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Convite de pareamento de %s" -#: src/service/device.js:613 +#: src/service/device.js:755 msgid "Reject" msgstr "Rejeitar" -#: src/service/device.js:618 +#: src/service/device.js:760 msgid "Accept" msgstr "Aceitar" -#: src/service/plugins/battery.js:194 src/service/plugins/findmyphone.js:18 -#, fuzzy -msgid "Ring" -msgstr "Localizar" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:203 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: bateria fraca" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:205 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d%% restante" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, fuzzy, javascript-format +msgid "%s: Battery is full" +msgstr "%s: bateria fraca" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Carregado" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Área de transferência" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Enviar para área de transferência" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Pegar da área de transferência" -#: src/service/plugins/contacts.js:12 -msgid "Contacts" -msgstr "Contatos" +#. Ensure we have a sender +#. TRANSLATORS: No name or phone number +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 +msgid "Unknown Contact" +msgstr "Contato desconhecido" -#: src/service/plugins/findmyphone.js:12 +#: src/service/plugins/findmyphone.js:13 msgid "Find My Phone" msgstr "Encontrar meu smartphone" -#: src/service/plugins/findmyphone.js:65 -msgid "Locate Device" -msgstr "Localizar dispositivo" - -#: src/service/plugins/findmyphone.js:66 -#, javascript-format -msgid "%s asked to locate this device" -msgstr "%s pediu para localizar este dispositivo" - -#: src/service/plugins/findmyphone.js:74 -msgid "Found" -msgstr "Encontrado" - #: src/service/plugins/mousepad.js:14 msgid "Mousepad" msgstr "Mousepad" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:578 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Teclado" -#: src/service/plugins/mousepad.js:595 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "O teclado não está pronto" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:25 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Cancelar notificação" -#: src/service/plugins/notification.js:33 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Fechar notificação" -#: src/service/plugins/notification.js:41 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Responder notificação" -#: src/service/plugins/notification.js:49 -msgid "Send Notification" -msgstr "Enviar notificação" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Ping" +#: src/service/plugins/notification.js:59 +#, fuzzy +msgid "Activate Notification" +msgstr "Compartilhar notificações" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Ping: %s" +#: src/service/plugins/presenter.js:9 +#, fuzzy +msgid "Presentation" +msgstr "Integração com arquivos" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Executar comandos" @@ -566,133 +787,122 @@ msgid "Unmount" msgstr "Desmontar" -#: src/service/plugins/sftp.js:170 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Todos os arquivos" -#: src/service/plugins/sftp.js:171 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Fotos da câmera" -#: src/service/plugins/sftp.js:333 -msgid "Files" -msgstr "Arquivos" - -#: src/service/plugins/share.js:12 src/service/plugins/share.js:18 +#: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Compartilhar" -#: src/service/plugins/share.js:26 -msgid "Share File" -msgstr "Compartilhar arquivo" - -#: src/service/plugins/share.js:34 +#: src/service/plugins/share.js:35 msgid "Share Text" msgstr "Compartilhar texto" -#: src/service/plugins/share.js:42 src/service/ui/messaging.js:903 -#: src/service/ui/messaging.js:911 -msgid "Share Link" -msgstr "Compartilhar link" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Transferência falhou" + +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "" -#: src/service/plugins/share.js:131 src/service/plugins/share.js:282 -msgid "Starting Transfer" -msgstr "Iniciando transferência" +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +#, fuzzy +msgid "Transferring File" +msgstr "Transferência falhou" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:133 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "Recebendo “%s” de %s" -#. Action Buttons -#: src/service/plugins/share.js:138 src/service/plugins/share.js:289 -#: src/service/plugins/share.js:407 src/service/ui/keybindings.js:44 -#: src/service/ui/service.js:121 src/service/ui/service.js:300 -#: src/service/ui/settings.js:873 src/shell/donotdisturb.js:215 -msgid "Cancel" -msgstr "Cancelar" - -#: src/service/plugins/share.js:149 src/service/plugins/share.js:303 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Transferência completa" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:151 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "Recebido “%s” de %s" -#: src/service/plugins/share.js:157 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Abrir pasta" -#: src/service/plugins/share.js:162 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Abrir arquivo" -#: src/service/plugins/share.js:169 src/service/plugins/share.js:311 -msgid "Transfer Failed" -msgstr "Transferência falhou" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Falha ao receber “%s” de %s" -#: src/service/plugins/share.js:211 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "Texto compartilhado por %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:284 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Enviando “%s” para %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:305 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "Enviado “%s” para %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:313 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Falha ao enviar “%s” para %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:384 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Enviar arquivos para %s" +#. TRANSLATORS: Mark the file to be opened once completed +#: src/service/plugins/share.js:408 +#, fuzzy +msgid "Open when done" +msgstr "Abrir no navegador" + #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:402 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Enviar um link para %s" -#: src/service/plugins/share.js:408 -msgid "Send" -msgstr "Enviar" - -#: src/service/plugins/sms.js:12 +#: src/service/plugins/sms.js:13 msgid "SMS" msgstr "SMS" -#: src/service/plugins/sms.js:33 +#: src/service/plugins/sms.js:34 msgid "New SMS (URI)" msgstr "Novo SMS (URI)" -#: src/service/plugins/sms.js:41 +#: src/service/plugins/sms.js:42 src/service/plugins/telephony.js:22 msgid "Reply SMS" msgstr "Responder SMS" -#: src/service/plugins/sms.js:57 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Compartilhar SMS" @@ -700,140 +910,63 @@ msgid "System Volume" msgstr "Volume do sistema" -#: src/service/plugins/telephony.js:21 +#: src/service/plugins/telephony.js:30 msgid "Mute Call" msgstr "Silenciar chamada" -#. Ensure we have a sender -#. TRANSLATORS: No name or phone number -#: src/service/plugins/telephony.js:155 src/service/ui/contacts.js:96 -#: src/service/ui/contacts.js:350 -msgid "Unknown Contact" -msgstr "Contato desconhecido" - #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:172 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Recebendo chamada" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:187 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Chamada em andamento" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:58 src/service/ui/contacts.js:79 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Outro" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:63 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Fax" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:67 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Trabalho" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:71 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Celular" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:75 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Casa" -#: src/service/ui/contacts.js:203 -msgid "Select a contact or number" -msgstr "Selecione um contato ou número" - #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:239 src/service/ui/contacts.js:253 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Enviar para %s" -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Definir atalho" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Definir" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Digite um novo atalho para mudar %s" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Pressione Esc para cancelar ou Backspace para redefinir o atalho de teclado." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s já está em uso" - -#: src/service/ui/service.js:122 -msgid "Connect" -msgstr "Conectar" - -#: src/service/ui/service.js:294 -msgid "Select a Device" -msgstr "Selecione um dispositivo" - -#: src/service/ui/service.js:298 -msgid "Select" -msgstr "Selecionar" - -#: src/service/ui/settings.js:298 -msgid "Panel" -msgstr "Painel" - -#: src/service/ui/settings.js:298 -msgid "User Menu" -msgstr "Menu do usuário" - -#: src/service/ui/settings.js:874 -msgid "Open" -msgstr "Abrir" - -#: src/service/ui/settings.js:931 src/service/ui/settings.js:944 -msgid "On" -msgstr "Ativada" - -#: src/service/ui/settings.js:931 src/service/ui/settings.js:944 -msgid "Off" -msgstr "Desativada" - -#: src/service/ui/settings.js:1065 src/service/ui/settings.js:1131 -msgid "Disabled" -msgstr "Desativado" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:93 src/service/ui/messaging.js:126 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Agora" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:98 src/service/ui/messaging.js:130 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -841,76 +974,108 @@ msgstr[1] "%d minutos" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:103 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Ontem・%s" -#: src/service/ui/messaging.js:920 -msgid "New Message" +#: src/service/ui/messaging.js:255 +#, fuzzy +msgid "Group Message" msgstr "Nova mensagem" -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:86 -msgid "Fully Charged" -msgstr "Carregado" +#. TRANSLATORS: An outgoing message body in a conversation summary +#: src/service/ui/messaging.js:265 +#, javascript-format +msgid "You: %s" +msgstr "" + +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "" +msgstr[1] "" + +#: src/service/ui/service.js:31 +msgid "Select a Device" +msgstr "Selecione um dispositivo" + +#: src/service/ui/service.js:35 +msgid "Select" +msgstr "Selecionar" + +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Nenhum dispositivo encontrado" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:90 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (Estimando…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:100 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (%d∶%02d até a carga completa)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:108 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (%d∶%02d restante)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 +#: src/shell/donotdisturb.js:135 +#, fuzzy, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "Uma hora" +msgstr[1] "%d horas" + +#. TRANSLATORS: Time until change with time duration +#. EXAMPLE: Until 10:00 (2 hours) +#: src/shell/donotdisturb.js:150 +#, javascript-format +msgid "Until %s (%s)" +msgstr "Até %s (%s)" + +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 msgid "Do Not Disturb" msgstr "Não perturbe" -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" msgstr "Silenciar notificações de dispositivos móveis" -#: src/shell/donotdisturb.js:171 +#: src/shell/donotdisturb.js:261 msgid "Until you turn off Do Not Disturb" msgstr "Até que você desative o \"Não perturbe\"" -#. TRANSLATORS: Time until change with time duration -#. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 -#, javascript-format -msgid "Until %s (%s)" -msgstr "Até %s (%s)" - -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Pronto" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "One hour" -msgid_plural "%d hours" -msgstr[0] "Uma hora" -msgstr[1] "%d horas" +#: src/shell/notification.js:43 +#, fuzzy +msgid "Reply" +msgstr "Responder SMS" + +#. TRANSLATORS: Extension name +#: webextension/gettext.js:27 +msgid "Zorin Connect" +msgstr "Zorin Connect" #. TRANSLATORS: Chrome/Firefox WebExtension description #: webextension/gettext.js:29 msgid "Share links with Zorin Connect, direct to the browser or by SMS." -msgstr "Compartilhe links com o Zorin Connect, diretamente no navegador ou por SMS." +msgstr "" +"Compartilhe links com o Zorin Connect, diretamente no navegador ou por SMS." #. TRANSLATORS: WebExtension can't connect to Zorin Connect #: webextension/gettext.js:33 @@ -924,3 +1089,102 @@ msgid "Mobile Application" msgstr "Aplicação Móvel" + +#~ msgid "Command Shortcuts" +#~ msgstr "Atalhos de comandos" + +#~ msgid "Delete" +#~ msgstr "Excluir" + +#~ msgid "Delete this device" +#~ msgstr "Excluir este dispositivo" + +#~ msgid "Unpair and remove all settings and files" +#~ msgstr "Esquecer e remover todas as configurações e arquivos" + +#~ msgid "Debugger" +#~ msgstr "Depurador" + +#~ msgid "About" +#~ msgstr "Sobre" + +#~ msgid "Switch to Bluetooth" +#~ msgstr "Mudar para Bluetooth" + +#~ msgid "Switch to LAN" +#~ msgstr "Mudar para LAN" + +#~ msgid "Appearance" +#~ msgstr "Aparência" + +#~ msgid "Service" +#~ msgstr "Serviço" + +#~ msgid "Discoverable" +#~ msgstr "Visível" + +#~ msgid "Restart Service" +#~ msgstr "Reiniciar serviço" + +#~ msgid "Settings" +#~ msgstr "Configurações" + +#~ msgid "Remote Filesystems" +#~ msgstr "Sistemas de arquivos remotos" + +#~ msgid "Sound Effects" +#~ msgstr "Efeitos sonoros" + +#~ msgid "Extended Keyboard Support" +#~ msgstr "Suporte a teclado estendido" + +#~ msgid "Desktop Contacts" +#~ msgstr "Integração com contatos" + +#~ msgid "Additional Features" +#~ msgstr "Funcionalidades adicionais" + +#~ msgid "KDE Connect" +#~ msgstr "KDE Connect" + +#~ msgid "Other" +#~ msgstr "Outro" + +#~ msgid "PulseAudio Error" +#~ msgstr "Erro do PulseAudio" + +#~ msgid "Click to open preferences" +#~ msgstr "Clique para abrir preferências" + +#~ msgid "Additional Software Required" +#~ msgstr "Necessário software adicional" + +#~ msgid "%s Plugin Failed To Load" +#~ msgstr "Falha ao carregar o plugin %s" + +#~ msgid "Wayland Not Supported" +#~ msgstr "Sem suporte a Wayland" + +#~ msgid "Remote input not supported on Wayland" +#~ msgstr "Não há suporte para entrada remota no Wayland" + +#~ msgid "Zorin Connect: %s" +#~ msgstr "Zorin Connect: %s" + +#~ msgid "Reconnect" +#~ msgstr "Reconectar" + +#~ msgid "Locate Device" +#~ msgstr "Localizar dispositivo" + +#~ msgid "%s asked to locate this device" +#~ msgstr "%s pediu para localizar este dispositivo" + +#~ msgid "Found" +#~ msgstr "Encontrado" + +#~ msgid "Starting Transfer" +#~ msgstr "Iniciando transferência" + +#~ msgid "Select a contact or number" +#~ msgstr "Selecione um contato ou número" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/ru.po gnome-shell-extension-zorin-connect-28.0.2/po/ru.po --- gnome-shell-extension-zorin-connect-24.1/po/ru.po 2019-05-29 12:51:28.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/ru.po 2019-11-30 17:35:27.000000000 +0000 @@ -2,11 +2,11 @@ msgstr "" "Project-Id-Version: zorin-connect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" -"PO-Revision-Date: 2019-05-18 10:54\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-10 11:34\n" "Last-Translator: Andy Holmes (andyholmes)\n" "Language-Team: Russian\n" -"Language: ru\n" +"Language: ru_RU\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -16,363 +16,391 @@ "X-Crowdin-Language: ru\n" "X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Информация о шифровании" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Сопряжение" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Забыть" + #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "Подключиться к…" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "Отмена" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Подключиться" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "IP адрес" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Bluetooth устройство" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Наберите номер или имя" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "Нет контактов" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Помощь" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Наберите номер или имя" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "Набрать сообщение" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "Отправить сообщение" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Батарея" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Компьютер" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" msgstr "Камера" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Синхронизация буфера обмена" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Проигрыватели" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Мышь и клавиатура" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Управление громкостью" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Файлы" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "Принять файлы" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Общий доступ и обмен" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Команды" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Имя" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "Командная строка" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Выберите исполняемый файл" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Добавить" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Удалить" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Изменить" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Сохранить" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Отправлять уведомления" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Приложения" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Уведомления" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Контакты" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "При входящем вызове" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Громкость" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Приостановить плеер" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "При исходящем вызове" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Выключить микрофон" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Телефония" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Комбинации клавиш" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Сбросить все…" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Комбинации клавиш" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Комбинации клавиш" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Плагины" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Экспериментальное" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "Устаревшая поддержка SMS" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Удалить" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Удалить устройство" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Забыть и удалить все настройки и файлы" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Дополнительные" -#: data/device.ui:2048 +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "Батарея устройства" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "Уведомление о низком уровне заряда" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "Индикация полной зарядки" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "Системная батарея" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "Поделиться статистикой" + +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Батарея" + +#: data/ui/device-preferences.ui:2394 msgid "Keyboard Shortcuts" msgstr "Комбинации клавиш" -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Сопряжение" - -#: data/device.ui:2183 +#: data/ui/device-preferences.ui:2529 msgid "Device is unpaired" msgstr "Устройство не сопряжено" -#: data/device.ui:2198 +#: data/ui/device-preferences.ui:2544 msgid "You may configure this device before pairing" msgstr "Вы можете настроить это устройство перед сопряжением" -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "Режим отображения" - -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Панель" - -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Меню пользователя" - -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" -msgstr "Сгенерировать журнал" - -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "О Zorin Connect" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Переключиться на Bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "Переключиться на LAN" - -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Информация о шифровании" - -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Забыть" - #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "На устройство" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "С устройства" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Ничего" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Тише" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Выключить" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Сообщение" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Новый диалог" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Нет диалогов" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "Не выбран диалог" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "Выберите или начните диалог" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Устройство отключено" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "Нет диалогов" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Отправить" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "Поиск устройств…" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "Название устройства" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "_Переименовать" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "Обновить" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" msgstr "Настройки" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Редактировать название устройства" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Устройства" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Поиск устройств…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Расширения браузера" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Включить" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" msgstr "Это устройство является невидимым для неспаренных устройств" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" msgstr "Обнаружение выключено" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Режим отображения" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Панель" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Меню пользователя" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Сгенерировать журнал" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "О Zorin Connect" + #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "Отправить СМС" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Устройства" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "Включить" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" @@ -381,48 +409,203 @@ msgstr[2] "%d подключено" msgstr[3] "%d подключено" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "Выключить" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Отправить на устройство" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Открыть" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Вкл" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Выкл" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Отключено" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Установить комбинацию клавиш" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Выбор" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Введите новую комбинацию клавиш для %s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "Нажмите Esc для отмены или Backspace чтобы сбросить комбинацию." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s уже используется" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "Полная реализация KDE Connect для GNOME" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "'Losted' " + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "Отладочные сообщения будут записаны. Произведите действия при которых произошла проблема, затем посмотрите журнал." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Посмотреть журнал" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Ноутбук" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Смартфон" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Планшет" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "Телевидение" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Не сопряжен" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Отключено" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Подключено" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "Ожидание службы…" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Отзыв" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Ошибка аутентификации" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Ошибка сети" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Нажмите для решения проблем" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "Discovery has been disabled due to the number of devices on this network." msgstr "Обнаружение было выключено из-за количества устройств в этой сети." -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "Ошибка загрузки плагина %s" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" msgstr "Нажмите для получения информации" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "Вызвать номер" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" msgstr "Поделиться файлом" +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "Список доступных устройств" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "Список всех устройств" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "Целевое устройство" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "Текст сообщения" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Отправить" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "Имя приложения" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "Текст уведомления" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "Иконка уведомления" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "ID уведомления" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Фото" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Пинг" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Найти" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Поделиться ссылкой" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "Показать версию программы" + #: src/service/device.js:174 msgid "Not available" msgstr "Недоступно" @@ -439,83 +622,69 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "Отпечаток %s:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Ноутбук" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Смартфон" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Планшет" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Компьютер" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Переподключиться" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Настройки" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Запрос сопряжения от %s" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Отклонить" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Принять" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Найти" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: Аккумулятор разряжен" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d%% осталось" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "%s: Аккумулятор заряжен" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Полностью заряжено" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Буфер обмена" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Отправить Буфер обмена" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Запросить Буфер обмена" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Неизвестный контакт" @@ -527,54 +696,45 @@ msgid "Mousepad" msgstr "Тачпад" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Клавиатура" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "Необходимо дополнительное ПО" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "Клавиатура не готова" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Отменить уведомление" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Закрыть уведомление" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Ответить" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "Отправить" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" -msgstr "Фото" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Пинг" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "Активировать уведомление" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Пинг: %s" +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "Презентация" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Отправить Команду" @@ -591,18 +751,14 @@ msgid "Unmount" msgstr "Размонтировать" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Все файлы" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Фотографии" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "Файлы" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Поделиться" @@ -611,85 +767,87 @@ msgid "Share Text" msgstr "Поделиться текстом" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Поделиться ссылкой" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Передача не удалась" + +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "%s не разрешено загружать файлы" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" -msgstr "Начало передачи" +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "Передача файла" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "Получение «%s» от %s" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Передача завершена" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "Получен «%s» от %s" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Открыть папку" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Открыть файл" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "Передача не удалась" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Не удалось получить«%s» от %s" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "Текст получен с %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Отправка «%s» на %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "Отправлено «%s» на %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Не удалось отправить «%s» на %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Отправить файлы на %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Открыть при завершении" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Отправить ссылку на %s" @@ -706,7 +864,7 @@ msgid "Reply SMS" msgstr "Ответить на SMS" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Отправить SMS" @@ -719,105 +877,58 @@ msgstr "Отключить звонок" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Входящий звонок" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Исходящий звонок" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Другой" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Факс" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Рабочий" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Мобильный" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Домашний" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Отправить на %s" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Открыть" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "Вкл" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "Выкл" - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Отключено" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Установить комбинацию клавиш" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Выбор" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Введите новую комбинацию клавиш для %s" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Нажмите Esc для отмены или Backspace чтобы сбросить комбинацию." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s уже используется" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Только что" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -827,17 +938,30 @@ msgstr[3] "%d минуты" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Вчера・%s" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "Групповое сообщение" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "Вы: %s" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "И %d другой контакт" +msgstr[1] "И %d других" +msgstr[2] "И %d других" +msgstr[3] "И %d других" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "Выберите устройство" @@ -846,101 +970,65 @@ msgid "Select" msgstr "Выбор" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "Не сопряжен" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Отключено" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Подключено" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "Transferred files are placed in the Downloads folder." -msgstr "Переданные файлы помещаются в папку Загрузки." - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "Полная реализация KDE Connect для GNOME" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "'Losted' " - -#: src/service/ui/settings.js:529 -msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." -msgstr "Отладочные сообщения будут записаны. Произведите действия при которых произошла проблема, затем посмотрите журнал." - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "Посмотреть журнал" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "Полностью заряжено" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Устройства не найдены" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (Осталось…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (%d∶%02d До полного заряда)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (%d∶%02d Осталось)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d час" +msgstr[1] "%d часа" +msgstr[2] "%d часов" +msgstr[3] "%d часа" + +#. TRANSLATORS: Time until change with time duration +#. EXAMPLE: Until 10:00 (2 hours) +#: src/shell/donotdisturb.js:150 +#, javascript-format +msgid "Until %s (%s)" +msgstr "До %s (%s)" + +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 msgid "Do Not Disturb" msgstr "Не беспокоить" -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" msgstr "Отключить уведомления с устройства" -#: src/shell/donotdisturb.js:171 +#: src/shell/donotdisturb.js:261 msgid "Until you turn off Do Not Disturb" msgstr "Пока вы не отключите режим Не беспокоить" -#. TRANSLATORS: Time until change with time duration -#. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 -#, javascript-format -msgid "Until %s (%s)" -msgstr "До %s (%s)" - -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Готово" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d час" -msgstr[1] "%d часа" -msgstr[2] "%d часов" -msgstr[3] "%d часа" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Ответить" @@ -959,11 +1047,6 @@ msgid "Service Unavailable" msgstr "Сервис недоступен" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Устройства не найдены" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/sk.po gnome-shell-extension-zorin-connect-28.0.2/po/sk.po --- gnome-shell-extension-zorin-connect-24.1/po/sk.po 2019-03-17 12:33:15.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/sk.po 2019-11-30 17:35:41.000000000 +0000 @@ -7,298 +7,402 @@ msgstr "" "Project-Id-Version: org.gnome.Shell.Extensions.ZorinConnect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-30 14:46+0100\n" -"PO-Revision-Date: 2018-11-30 15:56+0100\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-09-29 16:23+0200\n" +"Last-Translator: Jose Riha \n" "Language-Team: \n" +"Language: sk\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>=2 && n<=4 ? 1 : 2);\n" -"X-Generator: Poedit 2.2\n" -"Last-Translator: Dušan Kazik \n" -"Language: sk\n" +"X-Generator: Poedit 2.2.1\n" -#: data/conversation.ui:73 data/conversation.ui:81 -msgid "Type a message" -msgstr "Zadajte správu" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Informácie o šifrovaní" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Spárovať" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Zrušiť párovanie" + +#. TRANSLATORS: Open a dialog to connect to an IP or Bluez device +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 +msgid "Connect to…" +msgstr "Pripojiť k…" + +#. Action Buttons +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 +msgid "Cancel" +msgstr "Zrušiť" + +#: data/ui/connect.ui:27 +msgid "Connect" +msgstr "Pripojiť" + +#: data/ui/connect.ui:74 +msgid "IP Address" +msgstr "IP adresa" + +#: data/ui/contact-chooser.ui:50 +msgid "No contacts" +msgstr "Žiadne kontakty" + +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 +msgid "Help" +msgstr "Pomocník" -#: data/contacts.ui:51 data/contacts.ui:52 +#: data/ui/contact-chooser.ui:103 msgid "Type a phone number or name" msgstr "Zadajte telefónne číslo alebo meno" -#: data/device.ui:68 src/service/plugins/battery.js:12 -msgid "Battery" -msgstr "Batéria" +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 +msgid "Type a message" +msgstr "Zadajte správu" + +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 +msgid "Send Message" +msgstr "Odoslať správu" + +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Stolný počítač" + +#: data/ui/device-preferences.ui:88 +msgid "Camera" +msgstr "Fotoaparát" -#: data/device.ui:116 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Synchronizácia schránky" -#: data/device.ui:172 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Multimediálne prehrávače" -#: data/device.ui:220 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Myš a klávesnica" -#: data/device.ui:268 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Ovládanie hlasitosti" -#: data/device.ui:308 data/device.ui:1406 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Súbory" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "Prijať súbory" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Zdieľanie" -#: data/device.ui:337 data/device.ui:534 data/device.ui:1449 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:169 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Príkazy" -#: data/device.ui:385 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Názov" -#: data/device.ui:401 data/device.ui:402 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 +msgid "Command Line" +msgstr "Príkazový riadok" + +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Zvolí spustiteľný súbor" -#: data/device.ui:403 -msgid "Command Line" -msgstr "Príkazový riadok" +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 +msgid "Add" +msgstr "Pridať" -#: data/device.ui:597 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 +msgid "Remove" +msgstr "Odstrániť" + +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 +msgid "Edit" +msgstr "Upraviť" + +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 +msgid "Save" +msgstr "Uložiť" + +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Zdieľať oznámenia" -#: data/device.ui:636 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Aplikácie" -#: data/device.ui:675 data/device.ui:1492 -#: src/service/plugins/notification.js:12 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 +#: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Oznámenia" -#: data/device.ui:705 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 +msgid "Contacts" +msgstr "Kontakty" + +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Prichádzajúce hovory" -#: data/device.ui:755 data/device.ui:900 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Hlasitosť" -#: data/device.ui:813 data/device.ui:958 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Pozastaviť médiá" -#: data/device.ui:852 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Odchádzajúce hovory" -#: data/device.ui:1007 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Stíšiť mikrofón" -#: data/device.ui:1047 data/device.ui:1535 src/service/plugins/telephony.js:12 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Telefonovanie" -#: data/device.ui:1082 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Skratky akcií" -#: data/device.ui:1094 data/device.ui:1157 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Obnoviť všetko…" -#: data/device.ui:1145 -msgid "Command Shortcuts" -msgstr "Skratky príkazov" - -#: data/device.ui:1203 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Skratky" -#: data/device.ui:1234 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Zásuvné moduly" -#: data/device.ui:1295 -msgid "Delete" -msgstr "Odstrániť" - -#: data/device.ui:1320 -msgid "Delete this device" -msgstr "Odstránenie tohoto zariadenia" - -#: data/device.ui:1335 -msgid "Unpair and remove all settings and files" -msgstr "Zruší párovanie a odstráni všetky nastavenia a súbory" +#: data/ui/device-preferences.ui:1723 +msgid "Experimental" +msgstr "Experimentálne" + +#: data/ui/device-preferences.ui:1771 +msgid "Legacy SMS Support" +msgstr "Podpora SMS (zastarané)" -#: data/device.ui:1365 data/device.ui:1621 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Pokročilé" -#: data/device.ui:1578 -msgid "Keyboard Shortcuts" -msgstr "Klávesové skratky" - -#. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/menus.ui:7 src/service/ui/service.js:115 -msgid "Connect to…" -msgstr "Pripojiť k…" - -#: data/menus.ui:13 data/messaging.ui:244 data/settings.ui:669 -#: data/settings.ui:735 data/settings.ui:801 src/service/ui/settings.js:337 -msgid "Help" -msgstr "Pomocník" - -#. TRANSLATORS: Open the developer's dialog -#: data/menus.ui:19 -msgid "Debugger" -msgstr "Ladiaci nástroj" - -#: data/menus.ui:23 -msgid "About" -msgstr "O aplikácii" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:34 -msgid "Switch to Bluetooth" -msgstr "Prepnúť na Bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:41 -msgid "Switch to LAN" -msgstr "Prepnúť na LAN" +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "Stav batérie" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "Upozornenie na slabú batériu" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "Oznámenie o plnom nabití" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "Systémová batéria" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "Zdieľať štatistiky" -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:48 src/service/ui/settings.js:687 -msgid "Encryption Info" -msgstr "Informácie o šifrovaní" +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Batéria" -#. TRANSLATORS: Send a pair request to the device -#: data/menus.ui:53 src/service/device.js:432 -msgid "Pair" -msgstr "Spárovať" +#: data/ui/device-preferences.ui:2394 +msgid "Keyboard Shortcuts" +msgstr "Klávesové skratky" -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:59 src/service/device.js:440 -msgid "Unpair" -msgstr "Zrušiť párovanie" +#: data/ui/device-preferences.ui:2529 +msgid "Device is unpaired" +msgstr "Spárovanie so zariadením bolo zrušené" + +#: data/ui/device-preferences.ui:2544 +msgid "You may configure this device before pairing" +msgstr "Pred spárovaním môžete toto zariadenie nastaviť" #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:71 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Do zariadenia" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:77 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Zo zariadenia" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:89 data/menus.ui:115 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Bez zmeny" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:96 data/menus.ui:122 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Tichšie" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:103 data/menus.ui:129 src/service/plugins/telephony.js:175 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Stíšiť" -#: data/messaging.ui:12 src/service/plugins/sms.js:25 -#: src/service/ui/messaging.js:873 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Písanie správ" -#: data/messaging.ui:111 -msgid "Select a conversation" -msgstr "Vyberte rozhovor" +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 +msgid "New Conversation" +msgstr "Nová konverzácia" + +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Žiadna konverzácia" + +#: data/ui/messaging-window.ui:168 +msgid "No conversation selected" +msgstr "Nie je vybraná konverzácia" + +#: data/ui/messaging-window.ui:184 +msgid "Select or start a conversation" +msgstr "Vyberte alebo začnite novú konverzáciu" -#: data/messaging.ui:189 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Zariadenie je odpojené" -#: data/settings.ui:334 -msgid "Appearance" -msgstr "Vzhľad" +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 +msgid "Send" +msgstr "Odoslať" -#: data/settings.ui:384 -msgid "Display Mode" -msgstr "Režim zobrazenia" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "Meno zariadenia" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "_Premenovať" -#: data/settings.ui:426 -msgid "Service" -msgstr "Služba" - -#: data/settings.ui:476 -msgid "Discoverable" -msgstr "Objaviteľná" - -#: data/settings.ui:529 -msgid "Restart Service" -msgstr "Reštartovať službu" - -#: data/settings.ui:582 data/settings.ui:1016 src/service/device.js:424 -msgid "Settings" -msgstr "Nastavenia" - -#: data/settings.ui:640 -msgid "Remote Filesystems" -msgstr "Vzdialené súborové systémy" - -#: data/settings.ui:707 -msgid "Extended Keyboard Support" -msgstr "Rozšírená podpora klávesnice" +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 +msgid "Refresh" +msgstr "Obnoviť" -#: data/settings.ui:773 -msgid "Files Integration" -msgstr "Integrácia v aplikácii Súbory" +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 +msgid "Mobile Settings" +msgstr "Mobilné nastavenia" -#: data/settings.ui:830 -msgid "Additional Features" -msgstr "Dodatočné funkcie" +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 +msgid "Edit Device Name" +msgstr "Upraviť meno zariadenia" + +#: data/ui/preferences-window.ui:257 +msgid "Devices" +msgstr "Zariadenia" + +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Hľadajú sa zariadenia…" -#: data/settings.ui:905 +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Doplnky prehliadačov" -#: data/settings.ui:923 -msgid "KDE Connect" -msgstr "KDE Connect" - -#: data/settings.ui:957 data/settings.ui:1059 -msgid "Other" -msgstr "Ostatné" +#: data/ui/preferences-window.ui:612 +msgid "Enable" +msgstr "Povoliť" + +#: data/ui/preferences-window.ui:644 +msgid "This device is invisible to unpaired devices" +msgstr "Toto zariadenie nie je viditeľné pre nespárované zariadenia" -#. TRANSLATORS: No devices are known or available -#: data/settings.ui:1107 webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Nenašlo sa žiadne zariadenie" +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 +msgid "Discovery Disabled" +msgstr "Objavenie zakázané" -#: data/settings.ui:1143 -msgid "Refresh" -msgstr "Obnoviť" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Režim zobrazenia" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Panel" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Užívateľská ponuka" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Vytvoriť záznam pre technickú podporu" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "O programe Zorin Connect" + +#. TRANSLATORS: Share URL by SMS +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 +msgid "Send SMS" +msgstr "Odoslať SMS" #. Service Menu -#: src/extension.js:79 src/extension.js:255 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Mobilné zariadenia" -#: src/extension.js:105 -msgid "Mobile Settings" -msgstr "Mobilné nastavenia" +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "Zapnúť" -#. TRANSLATORS: %d is the number of devices connected -#: src/extension.js:253 +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" @@ -306,89 +410,216 @@ msgstr[1] "%d pripojené" msgstr[2] "%d pripojených" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "Vypnúť" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:112 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Odoslať do mobilného zariadenia" -#. TRANSLATORS: Extension name -#: src/service/daemon.js:95 src/service/daemon.js:415 -#: webextension/gettext.js:27 -msgid "Zorin Connect" -msgstr "Zorin Connect" +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Otvoriť" -#: src/service/daemon.js:408 +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Zapnuté" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Vypnuté" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Zakázané" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Nastavenie skratky" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Nastaviť" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Zadajte novú skratku pre zmenu akcie %s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "" +"Stlačte klávesu Esc na zrušenie alebo klávesu Backspace na obnovenie " +"klávesovej skratky." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "Klávesová skratka %s sa už používa" + +#: src/preferences/service.js:388 msgid "A complete KDE Connect implementation for GNOME" msgstr "Kompletná implementácia aplikácie KDE Connect pre prostredie GNOME" #. TRANSLATORS: eg. 'Translator Name ' -#: src/service/daemon.js:417 +#: src/preferences/service.js:397 msgid "translator-credits" -msgstr "Dušan Kazik " +msgstr "Dušan Kazik , Jose Riha " + +#: src/preferences/service.js:430 +msgid "" +"Debug messages are being logged. Take any steps necessary to reproduce a " +"problem then review the log." +msgstr "" +"Správy ladenia sú zaznamenávané. Pokúste sa opätovne vyvolať problém a " +"pozrite sa na súbor so záznamom." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Prezrieť súbor so záznamom" -#: src/service/daemon.js:439 +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Notebook" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Smartphone" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Tablet" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "Televízia" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Spárovanie zrušené" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Odpojené" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Pripojené" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "Čaká sa na službu…" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Ohlásiť" -#: src/service/daemon.js:557 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Zlyhalo overenie totožnosti" -#: src/service/daemon.js:566 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Sieťová chyba" -#: src/service/daemon.js:567 src/service/daemon.js:577 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Kliknutím získate pomoc pri riešení problému" -#: src/service/daemon.js:576 -msgid "PulseAudio Error" -msgstr "Chyba systému PulseAudio" +#: src/service/daemon.js:599 +msgid "" +"Discovery has been disabled due to the number of devices on this network." +msgstr "Objavenie bolo zakázané kvôli počtu zariadení na tejto sieti." -#: src/service/daemon.js:586 -msgid "Discovery Disabled" -msgstr "Objavenie zakázané" +#: src/service/daemon.js:608 +msgid "Click for more information" +msgstr "Kliknutím získate viac informácií" -#: src/service/daemon.js:587 -msgid "Discovery has been disabled due to the number of devices on this network." -msgstr "Objavenie bolo zakázané kvôli počtu zariadení na tejto sieti." +#: src/service/daemon.js:705 +msgid "Dial Number" +msgstr "Vytočiť číslo" -#: src/service/daemon.js:589 -msgid "Click to open preferences" -msgstr "Kliknutím otvoríte nastavenia" +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 +msgid "Share File" +msgstr "Zdieľať súbor" -#: src/service/daemon.js:597 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "Zlyhalo načítanie zásuvného modulu %s" +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "Zobraziť dostupné zariadenia" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "Zobraziť všetky zariadenia" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "Cieľové zariadenie" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "Telo správy" -#: src/service/daemon.js:598 -msgid "Click for more information" -msgstr "Kliknutím získate viac informácií" +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Odoslať oznámenie" -#. Create an urgent notification -#: src/service/daemon.js:626 -#, javascript-format -msgid "Zorin Connect: %s" -msgstr "Zorin Connect: %s" +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "Meno aplikácie v oznámení" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "Telo oznámenia" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "Ikona oznámenia" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "ID oznámenia" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Fotografia" -#. TRANSLATORS: Share URL by SMS -#: src/service/daemon.js:776 src/service/plugins/sms.js:49 -#: webextension/gettext.js:39 -msgid "Send SMS" -msgstr "Odoslať SMS" +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ping" -#: src/service/daemon.js:780 -msgid "Dial Number" -msgstr "Vytočiť číslo" +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Prezvoniť" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Zdieľať odkaz" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "Zobraziť verziu vydania" -#: src/service/device.js:166 +#: src/service/device.js:174 msgid "Not available" msgstr "Nedostupný" #. TRANSLATORS: Bluetooth address for remote device -#: src/service/device.js:170 +#: src/service/device.js:179 #, javascript-format msgid "Bluetooth device at %s" msgstr "Zariadenie Bluetooth na adrese %s" @@ -399,136 +630,120 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:188 src/service/device.js:190 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" -msgstr "Odtlačok zariadenia %s" - -#: src/service/device.js:247 -msgid "Laptop" -msgstr "Notebook" - -#: src/service/device.js:249 -msgid "Smartphone" -msgstr "Smartphone" - -#: src/service/device.js:251 -msgid "Tablet" -msgstr "Tablet" - -#: src/service/device.js:253 -msgid "Desktop" -msgstr "Stolný počítač" - -#: src/service/device.js:416 -msgid "Reconnect" -msgstr "Znovu pripojiť" +msgstr "Odtlačok zariadenia %s:" #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:613 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" -msgstr "Požiadavka na spárovanie zo zariadenia %s" +msgstr "Požiadavka na spárovanie od zariadenia %s" -#: src/service/device.js:620 +#: src/service/device.js:755 msgid "Reject" msgstr "Odmietnuť" -#: src/service/device.js:625 +#: src/service/device.js:760 msgid "Accept" msgstr "Prijať" -#: src/service/plugins/battery.js:194 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Zvoniť" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:203 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: Batéria je vybitá" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:205 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "Zostáva %d%%" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "%s: Batéria je plne nabitá" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Plne nabitá" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Schránka" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Odoslať obsah schránky" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Prijať obsah schránky" -#: src/service/plugins/contacts.js:12 -msgid "Contacts" -msgstr "Kontakty" - #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:191 src/service/plugins/telephony.js:154 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:415 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Neznámy kontakt" #: src/service/plugins/findmyphone.js:13 msgid "Find My Phone" -msgstr "Nájdenie môjho telefónu" +msgstr "Nájsť môj telefón" #: src/service/plugins/mousepad.js:14 msgid "Mousepad" msgstr "Ovládanie myši" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:568 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Klávesnica" -#: src/service/plugins/mousepad.js:223 src/service/plugins/sftp.js:69 -msgid "Additional Software Required" -msgstr "Vyžaduje sa dodatočný softvér" - -#: src/service/plugins/mousepad.js:585 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "Klávesnica nie je pripravená" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:25 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Zrušiť oznámenie" -#: src/service/plugins/notification.js:33 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Zavrieť oznámenie" -#: src/service/plugins/notification.js:41 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Odpovedať na oznámenie" -#: src/service/plugins/notification.js:49 -msgid "Send Notification" -msgstr "Odoslať oznámenie" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Ping" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "Aktivovať oznámenia" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Ping: %s" +#: src/service/plugins/presenter.js:9 +#, fuzzy +msgid "Presentation" +msgstr "Integrácia v aplikácii Súbory" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Spustiť príkazy" @@ -545,138 +760,120 @@ msgid "Unmount" msgstr "Odpojiť" -#: src/service/plugins/sftp.js:168 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Všetky súbory" -#: src/service/plugins/sftp.js:169 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Snímky fotoaparátu" -#: src/service/plugins/sftp.js:331 -msgid "Files" -msgstr "Súbory" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Zdieľať" -#: src/service/plugins/share.js:27 -msgid "Share File" -msgstr "Zdieľať súbor" - #: src/service/plugins/share.js:35 msgid "Share Text" msgstr "Zdieľať text" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:905 -#: src/service/ui/messaging.js:913 -msgid "Share Link" -msgstr "Zdieľať odkaz" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Prenos zlyhal" + +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "%s nemá povolené nahrávanie súborov" -#: src/service/plugins/share.js:132 src/service/plugins/share.js:303 -msgid "Starting Transfer" -msgstr "Spúšťa sa prenos" +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "Prebieha prenos súboru" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "Prijíma sa „%s“ zo zariadenia %s" -#. Action Buttons -#: src/service/plugins/share.js:139 src/service/plugins/share.js:310 -#: src/service/plugins/share.js:455 src/service/ui/keybindings.js:44 -#: src/service/ui/service.js:121 src/service/ui/service.js:300 -#: src/service/ui/settings.js:948 src/shell/donotdisturb.js:215 -msgid "Cancel" -msgstr "Zrušiť" - -#: src/service/plugins/share.js:172 src/service/plugins/share.js:327 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Prenos úspešný" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:174 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "Prijatý súbor „%s“ zo zariadenia %s" -#: src/service/plugins/share.js:180 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Otvoriť priečinok" -#: src/service/plugins/share.js:185 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Otvoriť súbor" -#: src/service/plugins/share.js:192 src/service/plugins/share.js:335 -msgid "Transfer Failed" -msgstr "Prenos zlyhal" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:194 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Zlyhalo prijatie súboru „%s“ zo zariadenia %s" -#: src/service/plugins/share.js:233 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "Text zdieľaný zariadením %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:305 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Odosiela sa súbor „%s“ do zariadenia %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:329 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "Odoslaný súbor „%s“ do zariadenia %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:337 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Zlyhalo odoslanie súboru „%s“ do zariadenia %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:408 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Odoslanie súborov do zariadenia %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:412 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Otvoriť po dokončení" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:450 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Odošle odkaz do zariadenia %s" -#: src/service/plugins/share.js:456 -msgid "Send" -msgstr "Odoslať" - -#: src/service/plugins/sms.js:12 +#: src/service/plugins/sms.js:13 msgid "SMS" msgstr "SMS" -#: src/service/plugins/sms.js:33 +#: src/service/plugins/sms.js:34 msgid "New SMS (URI)" msgstr "Nová SMS (URI)" -#: src/service/plugins/sms.js:41 +#: src/service/plugins/sms.js:42 src/service/plugins/telephony.js:22 msgid "Reply SMS" msgstr "Odpovedať na SMS" -#: src/service/plugins/sms.js:57 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Zdieľať SMS" @@ -684,133 +881,63 @@ msgid "System Volume" msgstr "Systémová hlasitosť" -#: src/service/plugins/telephony.js:21 +#: src/service/plugins/telephony.js:30 msgid "Mute Call" msgstr "Stíšiť hovor" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:171 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Prichádzajúci hovor" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:186 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Odchádzajúci hovor" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Iné" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Fax" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Práca" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Mobil" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Domov" -#: src/service/ui/contacts.js:267 -msgid "Select a contact or number" -msgstr "Vyberte kontakt alebo číslo" - #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:304 src/service/ui/contacts.js:318 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Odoslať na číslo %s" -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Nastavenie skratky" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Nastaviť" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Zadajte novú skratku pre zmenu akcie %s" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Stlačte klávesu Esc na zrušenie alebo klávesu Backspace na obnovenie klávesovej skratky." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "Klávesová skratka %s sa už používa" - -#: src/service/ui/service.js:122 -msgid "Connect" -msgstr "Pripojiť" - -#: src/service/ui/service.js:294 -msgid "Select a Device" -msgstr "Výber zariadenia" - -#: src/service/ui/service.js:298 -msgid "Select" -msgstr "Vybrať" - -#: src/service/ui/settings.js:315 -msgid "Panel" -msgstr "Panel" - -#: src/service/ui/settings.js:315 -msgid "User Menu" -msgstr "Užívateľská ponuka" - -#: src/service/ui/settings.js:949 -msgid "Open" -msgstr "Otvoriť" - -#: src/service/ui/settings.js:1006 src/service/ui/settings.js:1019 -msgid "On" -msgstr "Zapnuté" - -#: src/service/ui/settings.js:1006 src/service/ui/settings.js:1019 -msgid "Off" -msgstr "Vypnuté" - -#: src/service/ui/settings.js:1135 src/service/ui/settings.js:1201 -msgid "Disabled" -msgstr "Zakázané" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:93 src/service/ui/messaging.js:126 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Práve teraz" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:98 src/service/ui/messaging.js:130 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -819,77 +946,109 @@ msgstr[2] "%d minút" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:103 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Včera・%s" -#: src/service/ui/messaging.js:922 -msgid "New Message" -msgstr "Nová správa" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "Skupinová správa" -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:82 -msgid "Fully Charged" -msgstr "Plne nabitá" +#. TRANSLATORS: An outgoing message body in a conversation summary +#: src/service/ui/messaging.js:265 +#, javascript-format +msgid "You: %s" +msgstr "Vy: %s" + +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "A jeden ďalší kontakt" +msgstr[1] "A %d ďalšie kontakty" +msgstr[2] "A %d ďalších kontaktov" + +#: src/service/ui/service.js:31 +msgid "Select a Device" +msgstr "Výber zariadenia" + +#: src/service/ui/service.js:35 +msgid "Select" +msgstr "Vybrať" + +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Nenašlo sa žiadne zariadenie" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:86 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (Odhaduje sa…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:96 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (%d∶%02d do plného nabitia)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:104 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (Zostáva %d∶%02d)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d hodina" +msgstr[1] "%d hodiny" +msgstr[2] "%d hodín" + +#. TRANSLATORS: Time until change with time duration +#. EXAMPLE: Until 10:00 (2 hours) +#: src/shell/donotdisturb.js:150 +#, javascript-format +msgid "Until %s (%s)" +msgstr "Do %s (%s)" + +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 msgid "Do Not Disturb" msgstr "Nevyrušovať" -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" msgstr "Stíšenie oznámení z mobilného zariadenia" -#: src/shell/donotdisturb.js:171 +#: src/shell/donotdisturb.js:261 msgid "Until you turn off Do Not Disturb" msgstr "Pokiaľ nevypnete funkciu Nerušiť" -#. TRANSLATORS: Time until change with time duration -#. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 -#, javascript-format -msgid "Until %s (%s)" -msgstr "Do %s (%s)" - -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Hotovo" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "One hour" -msgid_plural "%d hours" -msgstr[0] "%d hodina" -msgstr[1] "%d hodiny" -msgstr[2] "%d hodín" +#: src/shell/notification.js:43 +msgid "Reply" +msgstr "Odpovedať" + +#. TRANSLATORS: Extension name +#: webextension/gettext.js:27 +msgid "Zorin Connect" +msgstr "Zorin Connect" #. TRANSLATORS: Chrome/Firefox WebExtension description #: webextension/gettext.js:29 msgid "Share links with Zorin Connect, direct to the browser or by SMS." -msgstr "Zdieľanie odkazov s aplikáciou Zorin Connect, priamo cez prehliadač alebo formou SMS." +msgstr "" +"Zdieľanie odkazov s aplikáciou Zorin Connect, priamo cez prehliadač alebo formou " +"SMS." #. TRANSLATORS: WebExtension can't connect to Zorin Connect #: webextension/gettext.js:33 @@ -903,3 +1062,81 @@ msgid "Mobile Application" msgstr "Mobilná aplikácia" + +#~ msgid "Command Shortcuts" +#~ msgstr "Skratky príkazov" + +#~ msgid "Delete" +#~ msgstr "Odstrániť" + +#~ msgid "Delete this device" +#~ msgstr "Odstránenie tohoto zariadenia" + +#~ msgid "Unpair and remove all settings and files" +#~ msgstr "Zruší párovanie a odstráni všetky nastavenia a súbory" + +#~ msgid "Debugger" +#~ msgstr "Ladiaci nástroj" + +#~ msgid "About" +#~ msgstr "O aplikácii" + +#~ msgid "Switch to Bluetooth" +#~ msgstr "Prepnúť na Bluetooth" + +#~ msgid "Switch to LAN" +#~ msgstr "Prepnúť na LAN" + +#~ msgid "Appearance" +#~ msgstr "Vzhľad" + +#~ msgid "Service" +#~ msgstr "Služba" + +#~ msgid "Discoverable" +#~ msgstr "Objaviteľná" + +#~ msgid "Restart Service" +#~ msgstr "Reštartovať službu" + +#~ msgid "Settings" +#~ msgstr "Nastavenia" + +#~ msgid "Remote Filesystems" +#~ msgstr "Vzdialené súborové systémy" + +#~ msgid "Extended Keyboard Support" +#~ msgstr "Rozšírená podpora klávesnice" + +#~ msgid "Additional Features" +#~ msgstr "Dodatočné funkcie" + +#~ msgid "KDE Connect" +#~ msgstr "KDE Connect" + +#~ msgid "Other" +#~ msgstr "Ostatné" + +#~ msgid "PulseAudio Error" +#~ msgstr "Chyba systému PulseAudio" + +#~ msgid "Click to open preferences" +#~ msgstr "Kliknutím otvoríte nastavenia" + +#~ msgid "%s Plugin Failed To Load" +#~ msgstr "Zlyhalo načítanie zásuvného modulu %s" + +#~ msgid "Zorin Connect: %s" +#~ msgstr "Zorin Connect: %s" + +#~ msgid "Reconnect" +#~ msgstr "Znovu pripojiť" + +#~ msgid "Additional Software Required" +#~ msgstr "Vyžaduje sa dodatočný softvér" + +#~ msgid "Starting Transfer" +#~ msgstr "Spúšťa sa prenos" + +#~ msgid "Select a contact or number" +#~ msgstr "Vyberte kontakt alebo číslo" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/sr@latin.po gnome-shell-extension-zorin-connect-28.0.2/po/sr@latin.po --- gnome-shell-extension-zorin-connect-24.1/po/sr@latin.po 2019-03-17 12:33:27.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/sr@latin.po 2019-11-30 17:36:03.000000000 +0000 @@ -2,316 +2,404 @@ msgstr "" "Project-Id-Version: org.gnome.Shell.Extensions.ZorinConnect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-19 11:14-0800\n" -"PO-Revision-Date: 2018-11-05 11:00+0100\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-09-25 15:46+0200\n" "Last-Translator: Slobodan Terzić \n" "Language-Team: \n" "Language: sr@latin\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.2\n" +"X-Generator: Poedit 2.2.1\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: data/conversation.ui:71 data/conversation.ui:79 -msgid "Type a message" -msgstr "Unesite poruku" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Informacije o šifrovanju" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Upari" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Raspari" + +#. TRANSLATORS: Open a dialog to connect to an IP or Bluez device +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 +msgid "Connect to…" +msgstr "Poveži se sa…" + +#. Action Buttons +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 +msgid "Cancel" +msgstr "Otkaži" + +#: data/ui/connect.ui:27 +msgid "Connect" +msgstr "Poveži" -#: data/contacts.ui:51 data/contacts.ui:52 +#: data/ui/connect.ui:74 +msgid "IP Address" +msgstr "IP adresa" + +#: data/ui/contact-chooser.ui:50 +msgid "No contacts" +msgstr "Nema kontakata" + +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 +msgid "Help" +msgstr "Pomoć" + +#: data/ui/contact-chooser.ui:103 msgid "Type a phone number or name" msgstr "Uneite broj telefona ili ime" -#: data/device.ui:68 src/service/plugins/battery.js:12 -msgid "Battery" -msgstr "Baterija" +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 +msgid "Type a message" +msgstr "Unesite poruku" + +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 +msgid "Send Message" +msgstr "Pošalji poruku" + +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Radna površ" -#: data/device.ui:116 +#: data/ui/device-preferences.ui:88 +msgid "Camera" +msgstr "Kamera" + +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Sinhronizacija ostave" -#: data/device.ui:172 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Medijski plejeri" -#: data/device.ui:220 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Miš i tastatura" -#: data/device.ui:268 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Jačina zvuka" -#: data/device.ui:308 data/device.ui:1406 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Fajlovi" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "Primi fajlove" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Deljenje" -#: data/device.ui:337 data/device.ui:534 data/device.ui:1449 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:169 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Naredbe" -#: data/device.ui:385 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Ime" -#: data/device.ui:401 data/device.ui:402 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 +msgid "Command Line" +msgstr "Komandna linija" + +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Izaberite izvršni fajl" -#: data/device.ui:403 -msgid "Command Line" -msgstr "Komandna linija" +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 +msgid "Add" +msgstr "Dodaj" + +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 +msgid "Remove" +msgstr "Ukloni" + +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 +msgid "Edit" +msgstr "Uredi" + +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 +msgid "Save" +msgstr "Snimi" -#: data/device.ui:597 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Deli obaveštenja" -#: data/device.ui:636 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Programi" -#: data/device.ui:675 data/device.ui:1492 -#: src/service/plugins/notification.js:12 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 +#: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Obaveštenja" -#: data/device.ui:705 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 +msgid "Contacts" +msgstr "Kontakti" + +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Dolazni pozivi" -#: data/device.ui:755 data/device.ui:900 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Jačina" -#: data/device.ui:813 data/device.ui:958 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Pauziraj medije" -#: data/device.ui:852 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Tekućii pozivi" -#: data/device.ui:1007 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Utišaj mikrofon" -#: data/device.ui:1047 data/device.ui:1535 src/service/plugins/telephony.js:12 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Telefonija" -#: data/device.ui:1082 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Prečice radnji" -#: data/device.ui:1094 data/device.ui:1157 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Resetuj sve…" -#: data/device.ui:1145 -msgid "Command Shortcuts" -msgstr "Prečice naredbi" - -#: data/device.ui:1203 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Prečice" -#: data/device.ui:1234 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Priključci" -#: data/device.ui:1295 -msgid "Delete" -msgstr "Obriši" - -#: data/device.ui:1320 -msgid "Delete this device" -msgstr "Obriši ovaj uređaj" - -#: data/device.ui:1335 -msgid "Unpair and remove all settings and files" -msgstr "Raspari i ukloni sve postavke i fajlove" +#: data/ui/device-preferences.ui:1723 +msgid "Experimental" +msgstr "Probno" + +#: data/ui/device-preferences.ui:1771 +msgid "Legacy SMS Support" +msgstr "Nasledna podrška za SMS" -#: data/device.ui:1365 data/device.ui:1621 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Napredno" -#: data/device.ui:1578 -msgid "Keyboard Shortcuts" -msgstr "Prečice tastature" - -#. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/menus.ui:7 src/service/ui/service.js:115 -msgid "Connect to…" -msgstr "Poveži se sa…" - -#: data/menus.ui:13 data/settings.ui:881 -msgid "Help" -msgstr "Pomoć" - -#. TRANSLATORS: Open the developer's dialog -#: data/menus.ui:19 -msgid "Debugger" -msgstr "Ispravljač grešaka" - -#: data/menus.ui:23 -msgid "About" -msgstr "O programu" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:34 -#, fuzzy -msgid "Switch to Bluetooth" -msgstr "Poveži Blututom" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:41 -msgid "Switch to LAN" -msgstr "" +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "Baterija uređaja" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "Obaveštenje o skoro praznoj bateriji" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "Obaveštenje o potpunoj napunjenosti" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "Baterija sistema" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "Deli ststistiku" -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:48 src/service/ui/settings.js:612 -msgid "Encryption Info" -msgstr "" +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Baterija" -#. TRANSLATORS: Send a pair request to the device -#: data/menus.ui:53 src/service/device.js:425 -msgid "Pair" -msgstr "Upari" +#: data/ui/device-preferences.ui:2394 +msgid "Keyboard Shortcuts" +msgstr "Prečice tastature" -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:59 src/service/device.js:433 -msgid "Unpair" -msgstr "Raspari" +#: data/ui/device-preferences.ui:2529 +msgid "Device is unpaired" +msgstr "Uređaj je rasparen" + +#: data/ui/device-preferences.ui:2544 +msgid "You may configure this device before pairing" +msgstr "Možete podesiti ovaj uređaj pre uparivanja" #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:71 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Na uređaj" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:77 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Sa uređaja" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:89 data/menus.ui:115 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Ništa" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:96 data/menus.ui:122 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Utišaj" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:103 data/menus.ui:129 src/service/plugins/telephony.js:176 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Utišaj" -#: data/messaging.ui:12 src/service/plugins/sms.js:25 -#: src/service/ui/messaging.js:871 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Poruke" -#: data/messaging.ui:110 -#, fuzzy -msgid "Select a conversation" -msgstr "Dodajte osobe da započnete razgovor" +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 +msgid "New Conversation" +msgstr "Novi razgovor" + +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Nema razgovora" + +#: data/ui/messaging-window.ui:168 +msgid "No conversation selected" +msgstr "Nije izabran razgovor" + +#: data/ui/messaging-window.ui:184 +msgid "Select or start a conversation" +msgstr "Izaberite ili započnite razgovor" -#: data/messaging.ui:188 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Uređaj nije povezan" -#: data/settings.ui:333 -msgid "Appearance" -msgstr "Izgled" +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 +msgid "Send" +msgstr "Pošalji" -#: data/settings.ui:383 -msgid "Display Mode" -msgstr "Režim prikaza" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "Naziv uređaja" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "_Preimenuj" -#: data/settings.ui:425 -msgid "Service" -msgstr "Servis" - -#: data/settings.ui:475 -msgid "Discoverable" -msgstr "Otkrivanje je omogućeno" - -#: data/settings.ui:528 -msgid "Restart Service" -msgstr "Ponovo pokreni servis" +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 +msgid "Refresh" +msgstr "Osveži" -#: data/settings.ui:581 data/settings.ui:1015 src/service/device.js:417 -msgid "Settings" +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 +msgid "Mobile Settings" msgstr "Podešavanje" -#: data/settings.ui:639 -msgid "Remote Filesystems" -msgstr "Udaljeni sistemi fajlova" - -#: data/settings.ui:675 -msgid "Sound Effects" -msgstr "Zvučni efekti" - -#: data/settings.ui:712 -msgid "Extended Keyboard Support" -msgstr "Proširena podrška za tastaturu" - -#: data/settings.ui:749 -msgid "Desktop Contacts" -msgstr "Kontakti sa desktopa" - -#: data/settings.ui:786 -msgid "Files Integration" -msgstr "Ugrađivanje u Fajlove" - -#: data/settings.ui:813 -msgid "Additional Features" -msgstr "Dodatne mogućnosti" +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 +msgid "Edit Device Name" +msgstr "Uredi naziv uređaja" + +#: data/ui/preferences-window.ui:257 +msgid "Devices" +msgstr "Uređaji" + +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Tražim uređaje…" -#: data/settings.ui:903 +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Dodaci za pregledače" -# Leaving the name in original form for About dialog. -#: data/settings.ui:921 -msgid "KDE Connect" -msgstr "KDE Connect" - -#: data/settings.ui:956 data/settings.ui:1058 -msgid "Other" -msgstr "Drugo" +#: data/ui/preferences-window.ui:612 +msgid "Enable" +msgstr "Omogući" + +#: data/ui/preferences-window.ui:644 +msgid "This device is invisible to unpaired devices" +msgstr "Ovaj uređaj je nevidljiv neuparenim uređajima" -#. TRANSLATORS: No devices are known or available -#: data/settings.ui:1106 webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Nema nađenih uređaja" +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 +msgid "Discovery Disabled" +msgstr "Otkrivanje je onemogućeno" -#: data/settings.ui:1142 -msgid "Refresh" -msgstr "Osveži" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Režim prikaza" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Panel" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Korisnički meni" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Napravi dnevnik za podršku" + +# Leaving the name in original form for About dialog. +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "O programu" + +#. TRANSLATORS: Share URL by SMS +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 +msgid "Send SMS" +msgstr "Pošalji SMS" #. Service Menu -#: src/extension.js:79 src/extension.js:259 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Mobilni uređaji" -#: src/extension.js:105 -msgid "Mobile Settings" -msgstr "Podešavanje" - -# Leaving the name in original form for About dialog. -#. TRANSLATORS: Extension name -#: src/extension.js:196 src/extension.js:311 src/service/daemon.js:95 -#: src/service/daemon.js:413 webextension/gettext.js:27 -msgid "Zorin Connect" -msgstr "Zorin Connect" +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "" -#. TRANSLATORS: %d is the number of devices connected -#: src/extension.js:257 +#: src/extension.js:244 #, fuzzy, javascript-format msgid "%d Connected" msgid_plural "%d Connected" @@ -319,97 +407,224 @@ msgstr[1] "%d je povezan" msgstr[2] "%d je povezan" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:112 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Pošalji na mobilni uređaj" -#: src/service/daemon.js:406 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Otvori" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Uključen" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Isključen" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Onemogućen" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Postavi prečicu" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Postavi" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Unesite novu prečicu da zamenite %s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "" +"Pritisnite Esc da otkažete ili Povratnik da resetujete prečicu tastature." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s je spreman za upotrebu" + +#: src/preferences/service.js:388 msgid "A complete KDE Connect implementation for GNOME" msgstr "Potpuna implementacija KDE Konekta za Gnom" #. TRANSLATORS: eg. 'Translator Name ' -#: src/service/daemon.js:415 +#: src/preferences/service.js:397 msgid "translator-credits" msgstr "Slobodan Terzić (githzerai06@gmail.com)" -#: src/service/daemon.js:437 +#: src/preferences/service.js:430 +msgid "" +"Debug messages are being logged. Take any steps necessary to reproduce a " +"problem then review the log." +msgstr "" +"Poruke za ispravljanje grešaka se beleže. Preduzmite neophodne korake da " +"ponovo prizvedete problem i pregeledajte dnevnik." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Pregled dnevnika" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Laptop" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Pametni telefon" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Tablet" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "Televizija" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Rasparen" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Nepovezan" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Povezan" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "Čekam na servis…" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Prijavi" -#: src/service/daemon.js:567 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Greška autentifikacje" -#: src/service/daemon.js:576 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Greška mreže" -#: src/service/daemon.js:577 src/service/daemon.js:587 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Kliknite za pomoć u otklanjanju" -#: src/service/daemon.js:586 -msgid "PulseAudio Error" -msgstr "Greška Pulsaudija" - -#: src/service/daemon.js:596 -msgid "Discovery Disabled" -msgstr "Otkrivanje je onemogućeno" - -#: src/service/daemon.js:597 +#: src/service/daemon.js:599 msgid "" "Discovery has been disabled due to the number of devices on this network." msgstr "Otkrivanje je onemogućeno usled broja uređaja u ovoj mreži." -#: src/service/daemon.js:599 src/service/daemon.js:609 -msgid "Click to open preferences" -msgstr "Kliknite da otvorite postavke" - #: src/service/daemon.js:608 -msgid "Additional Software Required" -msgstr "Neophodan je dodatan softver" - -#: src/service/daemon.js:617 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "Neuspelo učitavanje prključka %s" - -#: src/service/daemon.js:618 src/service/daemon.js:635 msgid "Click for more information" msgstr "Kliknite za više detalja" -#: src/service/daemon.js:633 -msgid "Wayland Not Supported" -msgstr "Vejland nije podržan" - -#: src/service/daemon.js:634 -msgid "Remote input not supported on Wayland" -msgstr "Unos na daljinu nije podržan pod Vejlandom" +#: src/service/daemon.js:705 +msgid "Dial Number" +msgstr "Biraj broj" -# Leaving the name in original form for About dialog. -#. Create an urgent notification -#: src/service/daemon.js:658 -#, javascript-format -msgid "Zorin Connect: %s" -msgstr "Zorin Connect: %s" +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 +msgid "Share File" +msgstr "Deli fajl" -#. TRANSLATORS: Share URL by SMS -#: src/service/daemon.js:808 src/service/plugins/sms.js:49 -#: webextension/gettext.js:39 -msgid "Send SMS" -msgstr "Pošalji SMS" +#: src/service/daemon.js:774 +#, fuzzy +msgid "List available devices" +msgstr "Nije dostupno" -#: src/service/daemon.js:812 -msgid "Dial Number" -msgstr "Biraj broj" +#: src/service/daemon.js:783 +#, fuzzy +msgid "List all devices" +msgstr "Mobilni uređaji" + +#: src/service/daemon.js:792 +#, fuzzy +msgid "Target Device" +msgstr "Na uređaj" + +#: src/service/daemon.js:834 +#, fuzzy +msgid "Message Body" +msgstr "Nova poruka" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Pošalji obaveštenje" + +#: src/service/daemon.js:855 +#, fuzzy +msgid "Notification App Name" +msgstr "Obaveštenja" + +#: src/service/daemon.js:864 +#, fuzzy +msgid "Notification Body" +msgstr "Obaveštenja" + +#: src/service/daemon.js:873 +#, fuzzy +msgid "Notification Icon" +msgstr "Obaveštenja" + +#: src/service/daemon.js:882 +#, fuzzy +msgid "Notification ID" +msgstr "Obaveštenja" -#: src/service/device.js:166 +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Fotografije" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ping" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Pozvoni" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Podeli vezu" + +#: src/service/daemon.js:942 +#, fuzzy +msgid "Show release version" +msgstr "Dodajte osobe da započnete razgovor" + +#: src/service/device.js:174 msgid "Not available" msgstr "Nije dostupno" #. TRANSLATORS: Bluetooth address for remote device -#: src/service/device.js:170 +#: src/service/device.js:179 #, javascript-format msgid "Bluetooth device at %s" msgstr "Blutut uređaj na %s" @@ -420,139 +635,120 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:188 src/service/device.js:190 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "Otisak %s:" -#: src/service/device.js:240 -msgid "Laptop" -msgstr "Laptop" - -#: src/service/device.js:242 -msgid "Smartphone" -msgstr "Pametni telefon" - -#: src/service/device.js:244 -msgid "Tablet" -msgstr "Tablet" - -#: src/service/device.js:246 -msgid "Desktop" -msgstr "Radna površ" - -#: src/service/device.js:409 -msgid "Reconnect" -msgstr "Ponovo poveži" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:606 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Zahtev za uparivanje od %s" -#: src/service/device.js:613 +#: src/service/device.js:755 msgid "Reject" msgstr "Odbij" -#: src/service/device.js:618 +#: src/service/device.js:760 msgid "Accept" msgstr "Prihvati" -#: src/service/plugins/battery.js:194 src/service/plugins/findmyphone.js:18 -#, fuzzy -msgid "Ring" -msgstr "Lociraj" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:203 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: baterija je pri kraju" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:205 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d%% preostaje" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, fuzzy, javascript-format +msgid "%s: Battery is full" +msgstr "%s: baterija je pri kraju" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Potpuno puna" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Ostava" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Slanje u ostavu" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Dovlačenje iz ostave" -#: src/service/plugins/contacts.js:12 -msgid "Contacts" -msgstr "Kontakti" +#. Ensure we have a sender +#. TRANSLATORS: No name or phone number +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 +msgid "Unknown Contact" +msgstr "Nepoznat kontakt" -#: src/service/plugins/findmyphone.js:12 +#: src/service/plugins/findmyphone.js:13 msgid "Find My Phone" msgstr "Nađi mi telefon" -#: src/service/plugins/findmyphone.js:65 -msgid "Locate Device" -msgstr "Lociranje uređaja" - -#: src/service/plugins/findmyphone.js:66 -#, javascript-format -msgid "%s asked to locate this device" -msgstr "%s traži ovaj uređaj" - -#: src/service/plugins/findmyphone.js:74 -msgid "Found" -msgstr "Nađen" - #: src/service/plugins/mousepad.js:14 msgid "Mousepad" msgstr "Podloga za miša" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:578 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Tastatura" -#: src/service/plugins/mousepad.js:595 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "Tastatura nije spremna" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:25 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Otkaži obaveštenje" -#: src/service/plugins/notification.js:33 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Zatvori obaveštenje" -#: src/service/plugins/notification.js:41 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Obaveštenje o oddgovoru" -#: src/service/plugins/notification.js:49 -msgid "Send Notification" -msgstr "Pošalji obaveštenje" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Ping" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "Aktiviraj obaveštenje" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Ping: %s" +#: src/service/plugins/presenter.js:9 +#, fuzzy +msgid "Presentation" +msgstr "Ugrađivanje u Fajlove" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Izvršavanje narebi" @@ -569,133 +765,122 @@ msgid "Unmount" msgstr "Demontiraj" -#: src/service/plugins/sftp.js:170 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Svi fajlovi" -#: src/service/plugins/sftp.js:171 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Slike sa kamere" -#: src/service/plugins/sftp.js:333 -msgid "Files" -msgstr "Fajlovi" - -#: src/service/plugins/share.js:12 src/service/plugins/share.js:18 +#: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Deljenje" -#: src/service/plugins/share.js:26 -msgid "Share File" -msgstr "Deli fajl" - -#: src/service/plugins/share.js:34 +#: src/service/plugins/share.js:35 msgid "Share Text" msgstr "Deli tekst" -#: src/service/plugins/share.js:42 src/service/ui/messaging.js:903 -#: src/service/ui/messaging.js:911 -msgid "Share Link" -msgstr "Podeli vezu" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Prenos nije uspeo" -#: src/service/plugins/share.js:131 src/service/plugins/share.js:282 -msgid "Starting Transfer" -msgstr "Započinjem prenos" +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "" + +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +#, fuzzy +msgid "Transferring File" +msgstr "Prenos nije uspeo" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:133 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "Primam „%s“ od %s" -#. Action Buttons -#: src/service/plugins/share.js:138 src/service/plugins/share.js:289 -#: src/service/plugins/share.js:407 src/service/ui/keybindings.js:44 -#: src/service/ui/service.js:121 src/service/ui/service.js:300 -#: src/service/ui/settings.js:873 src/shell/donotdisturb.js:215 -msgid "Cancel" -msgstr "Otkaži" - -#: src/service/plugins/share.js:149 src/service/plugins/share.js:303 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Uspešan prenos" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:151 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "Primih „%s“ od %s" -#: src/service/plugins/share.js:157 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Otvori fasciklu" -#: src/service/plugins/share.js:162 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Otvori fajl" -#: src/service/plugins/share.js:169 src/service/plugins/share.js:311 -msgid "Transfer Failed" -msgstr "Prenos nije uspeo" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Neuspešan prijem „%s“ od %s" -#: src/service/plugins/share.js:211 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "Deljeni tekst od %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:284 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Slanje „%s“ za %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:305 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "Poslah „%s“ za %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:313 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Neuspelo slanje „%s“ na %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:384 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Pošalji fajlove na %s" +#. TRANSLATORS: Mark the file to be opened once completed +#: src/service/plugins/share.js:408 +#, fuzzy +msgid "Open when done" +msgstr "Otvori u pregledaču" + #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:402 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Pošalji veze na %s" -#: src/service/plugins/share.js:408 -msgid "Send" -msgstr "Pošalji" - -#: src/service/plugins/sms.js:12 +#: src/service/plugins/sms.js:13 msgid "SMS" msgstr "SMS" -#: src/service/plugins/sms.js:33 +#: src/service/plugins/sms.js:34 msgid "New SMS (URI)" msgstr "Novi SMS (URI)" -#: src/service/plugins/sms.js:41 +#: src/service/plugins/sms.js:42 src/service/plugins/telephony.js:22 msgid "Reply SMS" msgstr "Odgovori na SMS" -#: src/service/plugins/sms.js:57 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Deli SMS" @@ -703,215 +888,170 @@ msgid "System Volume" msgstr "Sistemska jačina" -#: src/service/plugins/telephony.js:21 +#: src/service/plugins/telephony.js:30 msgid "Mute Call" msgstr "Utišaj poziv" -#. Ensure we have a sender -#. TRANSLATORS: No name or phone number -#: src/service/plugins/telephony.js:155 src/service/ui/contacts.js:96 -#: src/service/ui/contacts.js:350 -msgid "Unknown Contact" -msgstr "Nepoznat kontakt" - #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:172 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Dolazni poziv" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:187 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Tekući poziv" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:58 src/service/ui/contacts.js:79 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, fuzzy, javascript-format msgid "%s・Other" msgstr "%s・Drugo" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:63 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Faks" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:67 +#: src/service/ui/contacts.js:135 #, fuzzy, javascript-format msgid "%s・Work" msgstr "%s・Posao" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:71 +#: src/service/ui/contacts.js:139 #, fuzzy, javascript-format msgid "%s・Mobile" msgstr "%s・Mobilni" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:75 +#: src/service/ui/contacts.js:143 #, fuzzy, javascript-format msgid "%s・Home" msgstr "%s・Kućni" -#: src/service/ui/contacts.js:203 -msgid "Select a contact or number" -msgstr "" - #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:239 src/service/ui/contacts.js:253 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Pošalji na %s" -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Postavi prečicu" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Postavi" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Unesite novu prečicu da zamenite %s" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "" -"Pritisnite Esc da otkažete ili Povratnik da resetujete prečicu tastature." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s je spreman za upotrebu" - -#: src/service/ui/service.js:122 -msgid "Connect" -msgstr "Poveži" - -#: src/service/ui/service.js:294 -msgid "Select a Device" -msgstr "Izaberite uređaj" - -#: src/service/ui/service.js:298 -msgid "Select" -msgstr "Izaberite" - -#: src/service/ui/settings.js:298 -msgid "Panel" -msgstr "Panel" - -#: src/service/ui/settings.js:298 -msgid "User Menu" -msgstr "Korisnički meni" - -#: src/service/ui/settings.js:874 -msgid "Open" -msgstr "Otvori" - -#: src/service/ui/settings.js:931 src/service/ui/settings.js:944 -msgid "On" -msgstr "Uključen" - -#: src/service/ui/settings.js:931 src/service/ui/settings.js:944 -msgid "Off" -msgstr "Isključen" - -#: src/service/ui/settings.js:1065 src/service/ui/settings.js:1131 -msgid "Disabled" -msgstr "Onemogućen" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:93 src/service/ui/messaging.js:126 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Upravo sada" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:98 src/service/ui/messaging.js:130 -#: src/shell/donotdisturb.js:266 -#, fuzzy, javascript-format +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 +#, javascript-format msgid "%d minute" msgid_plural "%d minutes" -msgstr[0] "%d minuta" +msgstr[0] "%d minut" msgstr[1] "%d minuta" msgstr[2] "%d minuta" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:103 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Juče・%s" -#: src/service/ui/messaging.js:920 -msgid "New Message" +#: src/service/ui/messaging.js:255 +#, fuzzy +msgid "Group Message" msgstr "Nova poruka" -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:86 -msgid "Fully Charged" -msgstr "Potpuno puna" +#. TRANSLATORS: An outgoing message body in a conversation summary +#: src/service/ui/messaging.js:265 +#, javascript-format +msgid "You: %s" +msgstr "" + +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: src/service/ui/service.js:31 +msgid "Select a Device" +msgstr "Izaberite uređaj" + +#: src/service/ui/service.js:35 +msgid "Select" +msgstr "Izaberite" + +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Nema nađenih uređaja" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:90 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (Procenjujem…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:100 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (%d∶%02d do pune)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:108 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (%d∶%02d preostaje)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 -msgid "Do Not Disturb" -msgstr "Ne uznemiravaj" - -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" -msgstr "Utišaj obaveštenja mobilinih uređaja" - -#: src/shell/donotdisturb.js:171 -msgid "Until you turn off Do Not Disturb" -msgstr "Dok ne isključim Ne uznemiravaj" +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d čas" +msgstr[1] "%d časa" +msgstr[2] "%d časova" #. TRANSLATORS: Time until change with time duration #. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 +#: src/shell/donotdisturb.js:150 #, javascript-format msgid "Until %s (%s)" msgstr "Do %s (%s)" -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 +msgid "Do Not Disturb" +msgstr "Ne uznemiravaj" + +#: src/shell/donotdisturb.js:249 +#, fuzzy +msgid "Silence Notifications from Mobile Devices" +msgstr "Pošalji na mobilni uređaj" + +#: src/shell/donotdisturb.js:261 +msgid "Until you turn off Do Not Disturb" +msgstr "Dok ne isključim Ne uznemiravaj" + +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Gotovo" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "One hour" -msgid_plural "%d hours" -msgstr[0] "%d čas" -msgstr[1] "%d časa" -msgstr[2] "%d časova" +#: src/shell/notification.js:43 +msgid "Reply" +msgstr "Odgovori" + +# Leaving the name in original form for About dialog. +#. TRANSLATORS: Extension name +#: webextension/gettext.js:27 +msgid "Zorin Connect" +msgstr "Zorin Connect" #. TRANSLATORS: Chrome/Firefox WebExtension description #: webextension/gettext.js:29 @@ -930,3 +1070,102 @@ msgid "Mobile Application" msgstr "Mobilna aplikacija" + +#~ msgid "Silence Mobile Device Notifications" +#~ msgstr "Utišaj obaveštenja mobilinih uređaja" + +#~ msgid "Command Shortcuts" +#~ msgstr "Prečice naredbi" + +#~ msgid "Delete" +#~ msgstr "Obriši" + +#~ msgid "Delete this device" +#~ msgstr "Obriši ovaj uređaj" + +#~ msgid "Unpair and remove all settings and files" +#~ msgstr "Raspari i ukloni sve postavke i fajlove" + +#~ msgid "Debugger" +#~ msgstr "Ispravljač grešaka" + +#~ msgid "About" +#~ msgstr "O programu" + +#, fuzzy +#~ msgid "Switch to Bluetooth" +#~ msgstr "Poveži Blututom" + +#~ msgid "Appearance" +#~ msgstr "Izgled" + +#~ msgid "Service" +#~ msgstr "Servis" + +#~ msgid "Discoverable" +#~ msgstr "Otkrivanje je omogućeno" + +#~ msgid "Restart Service" +#~ msgstr "Ponovo pokreni servis" + +#~ msgid "Settings" +#~ msgstr "Podešavanje" + +#~ msgid "Remote Filesystems" +#~ msgstr "Udaljeni sistemi fajlova" + +#~ msgid "Sound Effects" +#~ msgstr "Zvučni efekti" + +#~ msgid "Extended Keyboard Support" +#~ msgstr "Proširena podrška za tastaturu" + +#~ msgid "Desktop Contacts" +#~ msgstr "Kontakti sa desktopa" + +#~ msgid "Additional Features" +#~ msgstr "Dodatne mogućnosti" + +# Leaving the name in original form for About dialog. +#~ msgid "KDE Connect" +#~ msgstr "KDE Connect" + +#~ msgid "Other" +#~ msgstr "Drugo" + +#~ msgid "PulseAudio Error" +#~ msgstr "Greška Pulsaudija" + +#~ msgid "Click to open preferences" +#~ msgstr "Kliknite da otvorite postavke" + +#~ msgid "Additional Software Required" +#~ msgstr "Neophodan je dodatan softver" + +#~ msgid "%s Plugin Failed To Load" +#~ msgstr "Neuspelo učitavanje prključka %s" + +#~ msgid "Wayland Not Supported" +#~ msgstr "Vejland nije podržan" + +#~ msgid "Remote input not supported on Wayland" +#~ msgstr "Unos na daljinu nije podržan pod Vejlandom" + +# Leaving the name in original form for About dialog. +#~ msgid "Zorin Connect: %s" +#~ msgstr "Zorin Connect: %s" + +#~ msgid "Reconnect" +#~ msgstr "Ponovo poveži" + +#~ msgid "Locate Device" +#~ msgstr "Lociranje uređaja" + +#~ msgid "%s asked to locate this device" +#~ msgstr "%s traži ovaj uređaj" + +#~ msgid "Found" +#~ msgstr "Nađen" + +#~ msgid "Starting Transfer" +#~ msgstr "Započinjem prenos" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/sr.po gnome-shell-extension-zorin-connect-28.0.2/po/sr.po --- gnome-shell-extension-zorin-connect-24.1/po/sr.po 2019-03-17 12:33:21.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/sr.po 2019-11-30 17:35:53.000000000 +0000 @@ -2,316 +2,404 @@ msgstr "" "Project-Id-Version: org.gnome.Shell.Extensions.ZorinConnect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-11-19 11:14-0800\n" -"PO-Revision-Date: 2018-11-04 12:25+0100\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-09-25 15:46+0200\n" "Last-Translator: Слободан Терзић \n" "Language-Team: \n" "Language: sr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 2.2\n" +"X-Generator: Poedit 2.2.1\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: data/conversation.ui:71 data/conversation.ui:79 -msgid "Type a message" -msgstr "Унесите поруку" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Информације о шифровању" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Упари" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Распари" + +#. TRANSLATORS: Open a dialog to connect to an IP or Bluez device +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 +msgid "Connect to…" +msgstr "Повежи се са…" + +#. Action Buttons +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 +msgid "Cancel" +msgstr "Откажи" + +#: data/ui/connect.ui:27 +msgid "Connect" +msgstr "Повежи" -#: data/contacts.ui:51 data/contacts.ui:52 +#: data/ui/connect.ui:74 +msgid "IP Address" +msgstr "ИП адреса" + +#: data/ui/contact-chooser.ui:50 +msgid "No contacts" +msgstr "Нема контаката" + +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 +msgid "Help" +msgstr "Помоћ" + +#: data/ui/contact-chooser.ui:103 msgid "Type a phone number or name" msgstr "Унеите број телефона или име" -#: data/device.ui:68 src/service/plugins/battery.js:12 -msgid "Battery" -msgstr "Батерија" +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 +msgid "Type a message" +msgstr "Унесите поруку" + +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 +msgid "Send Message" +msgstr "Пошаљи поруку" + +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Радна површ" -#: data/device.ui:116 +#: data/ui/device-preferences.ui:88 +msgid "Camera" +msgstr "Камера" + +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Синхронизација оставе" -#: data/device.ui:172 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Медијски плејери" -#: data/device.ui:220 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Миш и тастатура" -#: data/device.ui:268 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Јачина звука" -#: data/device.ui:308 data/device.ui:1406 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Фајлови" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "Прими фајлове" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Дељење" -#: data/device.ui:337 data/device.ui:534 data/device.ui:1449 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:169 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Наредбе" -#: data/device.ui:385 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Име" -#: data/device.ui:401 data/device.ui:402 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 +msgid "Command Line" +msgstr "Командна линија" + +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Изаберите извршни фајл" -#: data/device.ui:403 -msgid "Command Line" -msgstr "Командна линија" +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 +msgid "Add" +msgstr "Додај" + +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 +msgid "Remove" +msgstr "Уклони" + +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 +msgid "Edit" +msgstr "Уреди" + +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 +msgid "Save" +msgstr "Сними" -#: data/device.ui:597 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Дели обавештења" -#: data/device.ui:636 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Програми" -#: data/device.ui:675 data/device.ui:1492 -#: src/service/plugins/notification.js:12 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 +#: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Обавештења" -#: data/device.ui:705 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 +msgid "Contacts" +msgstr "Контакти" + +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Долазни позиви" -#: data/device.ui:755 data/device.ui:900 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Јачина" -#: data/device.ui:813 data/device.ui:958 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Паузирај медије" -#: data/device.ui:852 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Текућии позиви" -#: data/device.ui:1007 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Утишај микрофон" -#: data/device.ui:1047 data/device.ui:1535 src/service/plugins/telephony.js:12 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Телефонија" -#: data/device.ui:1082 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Пречице радњи" -#: data/device.ui:1094 data/device.ui:1157 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Ресетуј све…" -#: data/device.ui:1145 -msgid "Command Shortcuts" -msgstr "Пречице наредби" - -#: data/device.ui:1203 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Пречице" -#: data/device.ui:1234 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Прикључци" -#: data/device.ui:1295 -msgid "Delete" -msgstr "Обриши" - -#: data/device.ui:1320 -msgid "Delete this device" -msgstr "Обриши овај уређај" - -#: data/device.ui:1335 -msgid "Unpair and remove all settings and files" -msgstr "Распари и уклони све поставке и фајлове" +#: data/ui/device-preferences.ui:1723 +msgid "Experimental" +msgstr "Пробно" + +#: data/ui/device-preferences.ui:1771 +msgid "Legacy SMS Support" +msgstr "Наследна подршка за СМС" -#: data/device.ui:1365 data/device.ui:1621 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Напредно" -#: data/device.ui:1578 -msgid "Keyboard Shortcuts" -msgstr "Пречице тастатуре" +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "Батерија уређаја" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "Обавештење о скоро празној батерији" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "Обавештење о потпуној напуњености" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "Батерија система" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "Дели стстистику" -#. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/menus.ui:7 src/service/ui/service.js:115 -msgid "Connect to…" -msgstr "Повежи се са…" - -#: data/menus.ui:13 data/settings.ui:881 -msgid "Help" -msgstr "Помоћ" - -#. TRANSLATORS: Open the developer's dialog -#: data/menus.ui:19 -msgid "Debugger" -msgstr "Исправљач грешака" - -#: data/menus.ui:23 -msgid "About" -msgstr "О програму" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:34 -#, fuzzy -msgid "Switch to Bluetooth" -msgstr "Повежи Блутутом" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:41 -msgid "Switch to LAN" -msgstr "" - -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:48 src/service/ui/settings.js:612 -msgid "Encryption Info" -msgstr "" +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Батерија" -#. TRANSLATORS: Send a pair request to the device -#: data/menus.ui:53 src/service/device.js:425 -msgid "Pair" -msgstr "Упари" +#: data/ui/device-preferences.ui:2394 +msgid "Keyboard Shortcuts" +msgstr "Пречице тастатуре" -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:59 src/service/device.js:433 -msgid "Unpair" -msgstr "Распари" +#: data/ui/device-preferences.ui:2529 +msgid "Device is unpaired" +msgstr "Уређај је распарен" + +#: data/ui/device-preferences.ui:2544 +msgid "You may configure this device before pairing" +msgstr "Можете подесити овај уређај пре упаривања" #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:71 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "На уређај" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:77 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Са уређаја" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:89 data/menus.ui:115 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Ништа" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:96 data/menus.ui:122 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Утишај" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:103 data/menus.ui:129 src/service/plugins/telephony.js:176 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Утишај" -#: data/messaging.ui:12 src/service/plugins/sms.js:25 -#: src/service/ui/messaging.js:871 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Поруке" -#: data/messaging.ui:110 -#, fuzzy -msgid "Select a conversation" -msgstr "Додајте особе да започнете разговор" +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 +msgid "New Conversation" +msgstr "Нови разговор" + +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Нема разговора" + +#: data/ui/messaging-window.ui:168 +msgid "No conversation selected" +msgstr "Није изабран разговор" + +#: data/ui/messaging-window.ui:184 +msgid "Select or start a conversation" +msgstr "Изаберите или започните разговор" -#: data/messaging.ui:188 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Уређај није повезан" -#: data/settings.ui:333 -msgid "Appearance" -msgstr "Изглед" +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 +msgid "Send" +msgstr "Пошаљи" -#: data/settings.ui:383 -msgid "Display Mode" -msgstr "Режим приказа" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "Назив уређаја" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "_Преименуј" -#: data/settings.ui:425 -msgid "Service" -msgstr "Сервис" - -#: data/settings.ui:475 -msgid "Discoverable" -msgstr "Откривање је омогућено" - -#: data/settings.ui:528 -msgid "Restart Service" -msgstr "Поново покрени сервис" +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 +msgid "Refresh" +msgstr "Освежи" -#: data/settings.ui:581 data/settings.ui:1015 src/service/device.js:417 -msgid "Settings" +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 +msgid "Mobile Settings" msgstr "Подешавање" -#: data/settings.ui:639 -msgid "Remote Filesystems" -msgstr "Удаљени системи фајлова" - -#: data/settings.ui:675 -msgid "Sound Effects" -msgstr "Звучни ефекти" - -#: data/settings.ui:712 -msgid "Extended Keyboard Support" -msgstr "Проширена подршка за тастатуру" - -#: data/settings.ui:749 -msgid "Desktop Contacts" -msgstr "Контакти са десктопа" - -#: data/settings.ui:786 -msgid "Files Integration" -msgstr "Уграђивање у Фајлове" - -#: data/settings.ui:813 -msgid "Additional Features" -msgstr "Додатне могућности" +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 +msgid "Edit Device Name" +msgstr "Уреди назив уређаја" + +#: data/ui/preferences-window.ui:257 +msgid "Devices" +msgstr "Уређаји" + +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Тражим уређаје…" -#: data/settings.ui:903 +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Додаци за прегледаче" -# Leaving the name in original form for About dialog. -#: data/settings.ui:921 -msgid "KDE Connect" -msgstr "KDE Connect" - -#: data/settings.ui:956 data/settings.ui:1058 -msgid "Other" -msgstr "Друго" +#: data/ui/preferences-window.ui:612 +msgid "Enable" +msgstr "Омогући" + +#: data/ui/preferences-window.ui:644 +msgid "This device is invisible to unpaired devices" +msgstr "Овај уређај је невидљив неупареним уређајима" -#. TRANSLATORS: No devices are known or available -#: data/settings.ui:1106 webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Нема нађених уређаја" +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 +msgid "Discovery Disabled" +msgstr "Откривање је онемогућено" -#: data/settings.ui:1142 -msgid "Refresh" -msgstr "Освежи" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Режим приказа" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Панел" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Кориснички мени" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Направи дневник за подршку" + +# Leaving the name in original form for About dialog. +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "О програму" + +#. TRANSLATORS: Share URL by SMS +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 +msgid "Send SMS" +msgstr "Пошаљи СМС" #. Service Menu -#: src/extension.js:79 src/extension.js:259 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Мобилни уређаји" -#: src/extension.js:105 -msgid "Mobile Settings" -msgstr "Подешавање" - -# Leaving the name in original form for About dialog. -#. TRANSLATORS: Extension name -#: src/extension.js:196 src/extension.js:311 src/service/daemon.js:95 -#: src/service/daemon.js:413 webextension/gettext.js:27 -msgid "Zorin Connect" -msgstr "Zorin Connect" +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "" -#. TRANSLATORS: %d is the number of devices connected -#: src/extension.js:257 +#: src/extension.js:244 #, fuzzy, javascript-format msgid "%d Connected" msgid_plural "%d Connected" @@ -319,97 +407,224 @@ msgstr[1] "%d је повезан" msgstr[2] "%d је повезан" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:112 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Пошаљи на мобилни уређај" -#: src/service/daemon.js:406 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Отвори" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Укључен" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Искључен" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Онемогућен" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Постави пречицу" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Постави" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Унесите нову пречицу да замените %s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "" +"Притисните Есц да откажете или Повратник да ресетујете пречицу тастатуре." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s је спреман за употребу" + +#: src/preferences/service.js:388 msgid "A complete KDE Connect implementation for GNOME" msgstr "Потпуна имплементација КДЕ Конекта за Гном" #. TRANSLATORS: eg. 'Translator Name ' -#: src/service/daemon.js:415 +#: src/preferences/service.js:397 msgid "translator-credits" msgstr "Слободан Терзић (githzerai06@gmail.com)" -#: src/service/daemon.js:437 +#: src/preferences/service.js:430 +msgid "" +"Debug messages are being logged. Take any steps necessary to reproduce a " +"problem then review the log." +msgstr "" +"Поруке за исправљање грешака се бележе. Предузмите неопходне кораке да " +"поново призведете проблем и прегеледајте дневник." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Преглед дневника" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Лаптоп" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Паметни телефон" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Таблет" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "Телевизија" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Распарен" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Неповезан" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Повезан" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "Чекам на сервис…" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Пријави" -#: src/service/daemon.js:567 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Грешка аутентификацје" -#: src/service/daemon.js:576 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Грешка мреже" -#: src/service/daemon.js:577 src/service/daemon.js:587 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Кликните за помоћ у отклањању" -#: src/service/daemon.js:586 -msgid "PulseAudio Error" -msgstr "Грешка Пулсаудија" - -#: src/service/daemon.js:596 -msgid "Discovery Disabled" -msgstr "Откривање је онемогућено" - -#: src/service/daemon.js:597 +#: src/service/daemon.js:599 msgid "" "Discovery has been disabled due to the number of devices on this network." msgstr "Откривање је онемогућено услед броја уређаја у овој мрежи." -#: src/service/daemon.js:599 src/service/daemon.js:609 -msgid "Click to open preferences" -msgstr "Кликните да отворите поставке" - #: src/service/daemon.js:608 -msgid "Additional Software Required" -msgstr "Неопходан је додатан софтвер" - -#: src/service/daemon.js:617 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "Неуспело учитавање пркључка %s" - -#: src/service/daemon.js:618 src/service/daemon.js:635 msgid "Click for more information" msgstr "Кликните за више детаља" -#: src/service/daemon.js:633 -msgid "Wayland Not Supported" -msgstr "Вејланд није подржан" - -#: src/service/daemon.js:634 -msgid "Remote input not supported on Wayland" -msgstr "Унос на даљину није подржан под Вејландом" +#: src/service/daemon.js:705 +msgid "Dial Number" +msgstr "Бирај број" -# Leaving the name in original form for About dialog. -#. Create an urgent notification -#: src/service/daemon.js:658 -#, javascript-format -msgid "Zorin Connect: %s" -msgstr "Zorin Connect: %s" +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 +msgid "Share File" +msgstr "Дели фајл" -#. TRANSLATORS: Share URL by SMS -#: src/service/daemon.js:808 src/service/plugins/sms.js:49 -#: webextension/gettext.js:39 -msgid "Send SMS" -msgstr "Пошаљи СМС" +#: src/service/daemon.js:774 +#, fuzzy +msgid "List available devices" +msgstr "Није доступно" -#: src/service/daemon.js:812 -msgid "Dial Number" -msgstr "Бирај број" +#: src/service/daemon.js:783 +#, fuzzy +msgid "List all devices" +msgstr "Мобилни уређаји" + +#: src/service/daemon.js:792 +#, fuzzy +msgid "Target Device" +msgstr "На уређај" + +#: src/service/daemon.js:834 +#, fuzzy +msgid "Message Body" +msgstr "Нова порука" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Пошаљи обавештење" + +#: src/service/daemon.js:855 +#, fuzzy +msgid "Notification App Name" +msgstr "Обавештења" + +#: src/service/daemon.js:864 +#, fuzzy +msgid "Notification Body" +msgstr "Обавештења" + +#: src/service/daemon.js:873 +#, fuzzy +msgid "Notification Icon" +msgstr "Обавештења" + +#: src/service/daemon.js:882 +#, fuzzy +msgid "Notification ID" +msgstr "Обавештења" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Фотографије" -#: src/service/device.js:166 +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Пинг" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Позвони" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Подели везу" + +#: src/service/daemon.js:942 +#, fuzzy +msgid "Show release version" +msgstr "Додајте особе да започнете разговор" + +#: src/service/device.js:174 msgid "Not available" msgstr "Није доступно" #. TRANSLATORS: Bluetooth address for remote device -#: src/service/device.js:170 +#: src/service/device.js:179 #, javascript-format msgid "Bluetooth device at %s" msgstr "Блутут уређај на %s" @@ -420,139 +635,120 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:188 src/service/device.js:190 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "Отисак %s:" -#: src/service/device.js:240 -msgid "Laptop" -msgstr "Лаптоп" - -#: src/service/device.js:242 -msgid "Smartphone" -msgstr "Паметни телефон" - -#: src/service/device.js:244 -msgid "Tablet" -msgstr "Таблет" - -#: src/service/device.js:246 -msgid "Desktop" -msgstr "Радна површ" - -#: src/service/device.js:409 -msgid "Reconnect" -msgstr "Поново повежи" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:606 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Захтев за упаривање од %s" -#: src/service/device.js:613 +#: src/service/device.js:755 msgid "Reject" msgstr "Одбиј" -#: src/service/device.js:618 +#: src/service/device.js:760 msgid "Accept" msgstr "Прихвати" -#: src/service/plugins/battery.js:194 src/service/plugins/findmyphone.js:18 -#, fuzzy -msgid "Ring" -msgstr "Лоцирај" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:203 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: батерија је при крају" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:205 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d%% преостаје" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, fuzzy, javascript-format +msgid "%s: Battery is full" +msgstr "%s: батерија је при крају" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Потпуно пуна" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Остава" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Слање у оставу" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Довлачење из оставе" -#: src/service/plugins/contacts.js:12 -msgid "Contacts" -msgstr "Контакти" +#. Ensure we have a sender +#. TRANSLATORS: No name or phone number +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 +msgid "Unknown Contact" +msgstr "Непознат контакт" -#: src/service/plugins/findmyphone.js:12 +#: src/service/plugins/findmyphone.js:13 msgid "Find My Phone" msgstr "Нађи ми телефон" -#: src/service/plugins/findmyphone.js:65 -msgid "Locate Device" -msgstr "Лоцирање уређаја" - -#: src/service/plugins/findmyphone.js:66 -#, javascript-format -msgid "%s asked to locate this device" -msgstr "%s тражи овај уређај" - -#: src/service/plugins/findmyphone.js:74 -msgid "Found" -msgstr "Нађен" - #: src/service/plugins/mousepad.js:14 msgid "Mousepad" msgstr "Подлога за миша" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:578 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Тастатура" -#: src/service/plugins/mousepad.js:595 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "Тастатура није спремна" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "МПРИС" -#: src/service/plugins/notification.js:25 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Откажи обавештење" -#: src/service/plugins/notification.js:33 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Затвори обавештење" -#: src/service/plugins/notification.js:41 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Обавештење о оддговору" -#: src/service/plugins/notification.js:49 -msgid "Send Notification" -msgstr "Пошаљи обавештење" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Пинг" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "Активирај обавештење" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Пинг: %s" +#: src/service/plugins/presenter.js:9 +#, fuzzy +msgid "Presentation" +msgstr "Уграђивање у Фајлове" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Извршавање нареби" @@ -569,133 +765,122 @@ msgid "Unmount" msgstr "Демонтирај" -#: src/service/plugins/sftp.js:170 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Сви фајлови" -#: src/service/plugins/sftp.js:171 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Слике са камере" -#: src/service/plugins/sftp.js:333 -msgid "Files" -msgstr "Фајлови" - -#: src/service/plugins/share.js:12 src/service/plugins/share.js:18 +#: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Дељење" -#: src/service/plugins/share.js:26 -msgid "Share File" -msgstr "Дели фајл" - -#: src/service/plugins/share.js:34 +#: src/service/plugins/share.js:35 msgid "Share Text" msgstr "Дели текст" -#: src/service/plugins/share.js:42 src/service/ui/messaging.js:903 -#: src/service/ui/messaging.js:911 -msgid "Share Link" -msgstr "Подели везу" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Пренос није успео" -#: src/service/plugins/share.js:131 src/service/plugins/share.js:282 -msgid "Starting Transfer" -msgstr "Започињем пренос" +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "" + +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +#, fuzzy +msgid "Transferring File" +msgstr "Пренос није успео" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:133 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "Примам „%s“ од %s" -#. Action Buttons -#: src/service/plugins/share.js:138 src/service/plugins/share.js:289 -#: src/service/plugins/share.js:407 src/service/ui/keybindings.js:44 -#: src/service/ui/service.js:121 src/service/ui/service.js:300 -#: src/service/ui/settings.js:873 src/shell/donotdisturb.js:215 -msgid "Cancel" -msgstr "Откажи" - -#: src/service/plugins/share.js:149 src/service/plugins/share.js:303 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Успешан пренос" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:151 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "Примих „%s“ од %s" -#: src/service/plugins/share.js:157 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Отвори фасциклу" -#: src/service/plugins/share.js:162 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Отвори фајл" -#: src/service/plugins/share.js:169 src/service/plugins/share.js:311 -msgid "Transfer Failed" -msgstr "Пренос није успео" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Неуспешан пријем „%s“ од %s" -#: src/service/plugins/share.js:211 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "Дељени текст од %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:284 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Слање „%s“ за %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:305 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "Послах „%s“ за %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:313 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Неуспело слање „%s“ на %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:384 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Пошаљи фајлове на %s" +#. TRANSLATORS: Mark the file to be opened once completed +#: src/service/plugins/share.js:408 +#, fuzzy +msgid "Open when done" +msgstr "Отвори у прегледачу" + #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:402 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Пошаљи везе на %s" -#: src/service/plugins/share.js:408 -msgid "Send" -msgstr "Пошаљи" - -#: src/service/plugins/sms.js:12 +#: src/service/plugins/sms.js:13 msgid "SMS" msgstr "СМС" -#: src/service/plugins/sms.js:33 +#: src/service/plugins/sms.js:34 msgid "New SMS (URI)" msgstr "Нови СМС (УРИ)" -#: src/service/plugins/sms.js:41 +#: src/service/plugins/sms.js:42 src/service/plugins/telephony.js:22 msgid "Reply SMS" msgstr "Одговори на СМС" -#: src/service/plugins/sms.js:57 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Дели СМС" @@ -703,215 +888,169 @@ msgid "System Volume" msgstr "Системска јачина" -#: src/service/plugins/telephony.js:21 +#: src/service/plugins/telephony.js:30 msgid "Mute Call" msgstr "Утишај позив" -#. Ensure we have a sender -#. TRANSLATORS: No name or phone number -#: src/service/plugins/telephony.js:155 src/service/ui/contacts.js:96 -#: src/service/ui/contacts.js:350 -msgid "Unknown Contact" -msgstr "Непознат контакт" - #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:172 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Долазни позив" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:187 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Текући позив" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:58 src/service/ui/contacts.js:79 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, fuzzy, javascript-format msgid "%s・Other" msgstr "%s・Друго" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:63 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Факс" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:67 +#: src/service/ui/contacts.js:135 #, fuzzy, javascript-format msgid "%s・Work" msgstr "%s・Посао" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:71 +#: src/service/ui/contacts.js:139 #, fuzzy, javascript-format msgid "%s・Mobile" msgstr "%s・Мобилни" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:75 +#: src/service/ui/contacts.js:143 #, fuzzy, javascript-format msgid "%s・Home" msgstr "%s・Кућни" -#: src/service/ui/contacts.js:203 -msgid "Select a contact or number" -msgstr "" - #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:239 src/service/ui/contacts.js:253 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Пошаљи на %s" -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Постави пречицу" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Постави" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Унесите нову пречицу да замените %s" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "" -"Притисните Есц да откажете или Повратник да ресетујете пречицу тастатуре." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s је спреман за употребу" - -#: src/service/ui/service.js:122 -msgid "Connect" -msgstr "Повежи" - -#: src/service/ui/service.js:294 -msgid "Select a Device" -msgstr "Изаберите уређај" - -#: src/service/ui/service.js:298 -msgid "Select" -msgstr "Изаберите" - -#: src/service/ui/settings.js:298 -msgid "Panel" -msgstr "Панел" - -#: src/service/ui/settings.js:298 -msgid "User Menu" -msgstr "Кориснички мени" - -#: src/service/ui/settings.js:874 -msgid "Open" -msgstr "Отвори" - -#: src/service/ui/settings.js:931 src/service/ui/settings.js:944 -msgid "On" -msgstr "Укључен" - -#: src/service/ui/settings.js:931 src/service/ui/settings.js:944 -msgid "Off" -msgstr "Искључен" - -#: src/service/ui/settings.js:1065 src/service/ui/settings.js:1131 -msgid "Disabled" -msgstr "Онемогућен" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:93 src/service/ui/messaging.js:126 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Управо сада" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:98 src/service/ui/messaging.js:130 -#: src/shell/donotdisturb.js:266 -#, fuzzy, javascript-format +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 +#, javascript-format msgid "%d minute" msgid_plural "%d minutes" -msgstr[0] "%d минута" +msgstr[0] "%d минут" msgstr[1] "%d минута" msgstr[2] "%d минута" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:103 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Јуче・%s" -#: src/service/ui/messaging.js:920 -msgid "New Message" +#: src/service/ui/messaging.js:255 +#, fuzzy +msgid "Group Message" msgstr "Нова порука" -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:86 -msgid "Fully Charged" -msgstr "Потпуно пуна" +#. TRANSLATORS: An outgoing message body in a conversation summary +#: src/service/ui/messaging.js:265 +#, javascript-format +msgid "You: %s" +msgstr "" + +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: src/service/ui/service.js:31 +msgid "Select a Device" +msgstr "Изаберите уређај" + +#: src/service/ui/service.js:35 +msgid "Select" +msgstr "Изаберите" + +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Нема нађених уређаја" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:90 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (Процењујем…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:100 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (%d∶%02d до пуне)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:108 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (%d∶%02d преостаје)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d час" +msgstr[1] "%d часа" +msgstr[2] "%d часова" + +#. TRANSLATORS: Time until change with time duration +#. EXAMPLE: Until 10:00 (2 hours) +#: src/shell/donotdisturb.js:150 +#, javascript-format +msgid "Until %s (%s)" +msgstr "До %s (%s)" + +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 msgid "Do Not Disturb" msgstr "Не узнемиравај" -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" msgstr "Утишај обавештења мобилиних уређаја" -#: src/shell/donotdisturb.js:171 +#: src/shell/donotdisturb.js:261 msgid "Until you turn off Do Not Disturb" msgstr "Док не искључим Не узнемиравај" -#. TRANSLATORS: Time until change with time duration -#. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 -#, javascript-format -msgid "Until %s (%s)" -msgstr "До %s (%s)" - -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Готово" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "One hour" -msgid_plural "%d hours" -msgstr[0] "%d час" -msgstr[1] "%d часа" -msgstr[2] "%d часова" +#: src/shell/notification.js:43 +msgid "Reply" +msgstr "Одговори" + +# Leaving the name in original form for About dialog. +#. TRANSLATORS: Extension name +#: webextension/gettext.js:27 +msgid "Zorin Connect" +msgstr "Zorin Connect" #. TRANSLATORS: Chrome/Firefox WebExtension description #: webextension/gettext.js:29 @@ -930,3 +1069,99 @@ msgid "Mobile Application" msgstr "Мобилна апликација" + +#~ msgid "Command Shortcuts" +#~ msgstr "Пречице наредби" + +#~ msgid "Delete" +#~ msgstr "Обриши" + +#~ msgid "Delete this device" +#~ msgstr "Обриши овај уређај" + +#~ msgid "Unpair and remove all settings and files" +#~ msgstr "Распари и уклони све поставке и фајлове" + +#~ msgid "Debugger" +#~ msgstr "Исправљач грешака" + +#~ msgid "About" +#~ msgstr "О програму" + +#, fuzzy +#~ msgid "Switch to Bluetooth" +#~ msgstr "Повежи Блутутом" + +#~ msgid "Appearance" +#~ msgstr "Изглед" + +#~ msgid "Service" +#~ msgstr "Сервис" + +#~ msgid "Discoverable" +#~ msgstr "Откривање је омогућено" + +#~ msgid "Restart Service" +#~ msgstr "Поново покрени сервис" + +#~ msgid "Settings" +#~ msgstr "Подешавање" + +#~ msgid "Remote Filesystems" +#~ msgstr "Удаљени системи фајлова" + +#~ msgid "Sound Effects" +#~ msgstr "Звучни ефекти" + +#~ msgid "Extended Keyboard Support" +#~ msgstr "Проширена подршка за тастатуру" + +#~ msgid "Desktop Contacts" +#~ msgstr "Контакти са десктопа" + +#~ msgid "Additional Features" +#~ msgstr "Додатне могућности" + +# Leaving the name in original form for About dialog. +#~ msgid "KDE Connect" +#~ msgstr "KDE Connect" + +#~ msgid "Other" +#~ msgstr "Друго" + +#~ msgid "PulseAudio Error" +#~ msgstr "Грешка Пулсаудија" + +#~ msgid "Click to open preferences" +#~ msgstr "Кликните да отворите поставке" + +#~ msgid "Additional Software Required" +#~ msgstr "Неопходан је додатан софтвер" + +#~ msgid "%s Plugin Failed To Load" +#~ msgstr "Неуспело учитавање пркључка %s" + +#~ msgid "Wayland Not Supported" +#~ msgstr "Вејланд није подржан" + +#~ msgid "Remote input not supported on Wayland" +#~ msgstr "Унос на даљину није подржан под Вејландом" + +# Leaving the name in original form for About dialog. +#~ msgid "Zorin Connect: %s" +#~ msgstr "Zorin Connect: %s" + +#~ msgid "Reconnect" +#~ msgstr "Поново повежи" + +#~ msgid "Locate Device" +#~ msgstr "Лоцирање уређаја" + +#~ msgid "%s asked to locate this device" +#~ msgstr "%s тражи овај уређај" + +#~ msgid "Found" +#~ msgstr "Нађен" + +#~ msgid "Starting Transfer" +#~ msgstr "Започињем пренос" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/tr.po gnome-shell-extension-zorin-connect-28.0.2/po/tr.po --- gnome-shell-extension-zorin-connect-24.1/po/tr.po 2019-05-29 12:53:57.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/tr.po 2019-11-30 17:36:10.000000000 +0000 @@ -1,423 +1,611 @@ msgid "" msgstr "" -"Project-Id-Version: org.gnome.Shell.Extensions.ZorinConnect\n" +"Project-Id-Version: zorin-connect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" -"PO-Revision-Date: 2019-05-18 10:54\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-11 03:35\n" "Last-Translator: Andy Holmes (andyholmes)\n" "Language-Team: Turkish\n" -"Language: tr\n" +"Language: tr_TR\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: Poedit 2.2.1\n" +"X-Generator: crowdin.com\n" +"X-Crowdin-Project: zorin-connect\n" +"X-Crowdin-Language: tr\n" +"X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" + +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Şifreleme Bilgisi" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Eşleştir" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Eşleştirmeyi Bitir" #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "Bağlan…" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "İptal" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Bağlan" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "IP Adresi" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Bluetooth Cihazı" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Telefon numarası veya isim yaz" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "Kişi yok" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Yardım" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Telefon numarası veya isim yaz" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "Bir Mesaj Yaz" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "Mesaj Gönder" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Batarya" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Masaüstü" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" msgstr "Kamera" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Pano Eşleşmesi" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Medya Oynatıcılar" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Fare & Klavye" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Ses Kontrolü" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Dosyalar" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "Alınan Dosyalar" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Paylaşım" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Komutlar" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "İsim" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "Komut Satırı" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Yürütülebilir dosya seç" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Ekle" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Kaldır" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Düzenle" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Kaydet" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Bildirimleri Paylaş" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "Aktif Olduğunda Paylaş" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Uygulamalar" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Bildirimler" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Kişiler" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Gelen Çağrılar" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Ses" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Medyayı Duraklat" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Devam Eden Çağrılar" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Mikrofonu Sustur" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Telefon" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Kısayol Eylemleri" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Tümünü Sıfırla…" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Komut Kısayolları" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Kısayollar" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Eklentiler" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Deneysel" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "Eski SMS Desteği" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Sil" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Bu Cihazı Sil" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Tüm ayarları sıfırla ve dosyaları kaldır" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Gelişmiş" -#: data/device.ui:2048 +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "Cihaz Bataryası" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "Düşük Batarya Bildirimi" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "Tam Şarj Bildirimi" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "Sistem Bataryası" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "İstatistikleri Paylaş" + +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Batarya" + +#: data/ui/device-preferences.ui:2394 msgid "Keyboard Shortcuts" msgstr "Klavye Kısayolları" -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Eşleştir" - -#: data/device.ui:2183 +#: data/ui/device-preferences.ui:2529 msgid "Device is unpaired" msgstr "Cihaz eşleşmemiş" -#: data/device.ui:2198 +#: data/ui/device-preferences.ui:2544 msgid "You may configure this device before pairing" msgstr "Eşleşmeden önce cihazı yapılandır" -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "Görünüm Kipi" - -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Sistem Paneli" - -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Kullanıcı Menüsü" - -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" -msgstr "Destek Günlüğü Oluştur" - -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "Zorin Connect Hakkında" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Bluetooth'a Geç" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "LAN'a Geç" - -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Şifreleme Bilgisi" - -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Eşleştirmeyi Bitir" - #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "Cihaza" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Cihazdan" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Hiç Biri" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Düşük" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Sessiz" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Mesajlaşma" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Yeni Sohbet" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Sohbet yok" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "Hiçbir sohbet seçilmedi" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "Sohbet seç ya da başlat" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Cihaz çevrim dışı" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "Sohbet yok" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Gönder" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "Cihazlar aranıyor…" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "Cihaz Adı" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "_Adlandır" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "Yenile" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" msgstr "Mobil Ayarları" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Cihaz Adını Düzenle" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Cihazlar" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Cihazlar aranıyor…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Tarayıcı Eklentileri" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Etkin" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" msgstr "Bu cihaz eşleştirme yapılmayan cihazlara görünmez" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" msgstr "Keşif Devre Dışı" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Görünüm Kipi" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Sistem Paneli" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Kullanıcı Menüsü" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Destek Günlüğü Oluştur" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "Zorin Connect Hakkında" + #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "SMS Gönder" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Mobil Cihazlar" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "Aç" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" msgstr[0] "%d Bağlı" msgstr[1] "%d Bağlı" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "Kapat" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Mobil Cihaza Gönder" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Aç" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Açık" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Kapalı" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Devre dışı" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Kısayol Ayarla" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Ayarla" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Değiştirmek için yeni bir kısayol gir %s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "Klavye kısayolunu sıfırlamak için iptal, geri almak için ESC tuşuna bas." + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s zaten kullanılıyor" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "GNOME için eksiksiz bir KDE Connect uygulaması" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "Serdar Sağlam \n" +"Orhan Engin Okay \n" +"A. Burak Tektaş " + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "Hata ayıklama mesajları kaydediliyor. Sorunu yeniden oluşturmak için gerekli adımları izleyin ve günlüğü inceleyin." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Günlüğü Gözden Geçir" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Dizüstü" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Telefon" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Tablet" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "Televizyon" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Eşleşmemiş" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Bağlantı kesildi" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Bağlı" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "Hizmet bekleniyor…" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Rapor" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Kimlik Doğrulama Hatası" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Ağ Hatası" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Sorun giderme konusunda yardım için tıkla" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "Discovery has been disabled due to the number of devices on this network." msgstr "Bu ağdaki cihazların sayısı nedeniyle keşif devre dışı bırakıldı." -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "%s Eklentisi Yüklenemedi" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" msgstr "Daha fazla bilgi için tıkla" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "Numarayı Çevir" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" msgstr "Dosya Paylaşımı" +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "Kullanılabilir cihazları listele" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "Tüm cihazları listele" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "Hedef Cihaz" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "Mesaj Metni" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Bildirim Gönder" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "Bildirim Uygulama Adı" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "Bildirim Metni" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "Bildirim Simgesi" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "Bildirim Kimliği" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Fotoğraf" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Yokla" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Çaldır" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Bağlantıyı Paylaş" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "Sürüm versiyonunu göster" + #: src/service/device.js:174 msgid "Not available" msgstr "Müsait Değil" @@ -434,83 +622,69 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "%s Parmak İzi:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Dizüstü" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Telefon" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Tablet" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Masaüstü" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Yeniden Bağlan" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Ayarlar" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "%s tarafından Gelen Eşleşme İsteği" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Reddet" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Kabul et" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Çaldır" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: Düşük batarya" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "%d%% kaldı" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "%s: Batarya dolu" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Şarj Oldu" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Pano" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Panoya Gönder" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Panodan Al" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Bilinmeyen Kişi" @@ -522,54 +696,45 @@ msgid "Mousepad" msgstr "Fare Desteği" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Klavye" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "Gerekli Ek Yazılım" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "Klavye hazır değil" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Bildirimi İptal Et" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Bildirimi Kapat" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Bildirimi Yanıtla" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "Bildirim Gönder" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" -msgstr "Fotoğraf" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Yokla" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "Bildirimi Etkinleştir" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Yokla: %s" +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "Sunum" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Komutları Çalıştır" @@ -586,18 +751,14 @@ msgid "Unmount" msgstr "Ayır" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Tüm Dosyalar" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Kamera resimleri" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "Dosyalar" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Paylaş" @@ -606,85 +767,87 @@ msgid "Share Text" msgstr "Metni Paylaş" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Bağlantıyı Paylaş" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Aktarım Başarısız" + +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "%s dosya yükleme iznine sahip değil" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" -msgstr "Aktarım Başlatılıyor" +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "Dosya Aktarımı" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "Alınıyor “%s” kaynak %s" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Aktarım Başarılı" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "Alınan “%s” kaynak %s" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Klasörü Aç" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Dosyayı Aç" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "Aktarım Başarısız" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Alım başarısız “%s” kaynak %s" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "Paylaşılan Metin %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Gönderiliyor “%s” hedef %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "Gönderildi “%s” hedef %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Gönderilemedi “%s” hedef %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Dosyaları gönder %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Tamamlandığında aç" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Bağlantı gönder %s" @@ -701,7 +864,7 @@ msgid "Reply SMS" msgstr "SMS Yanıtla" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "SMS Paylaş" @@ -714,105 +877,58 @@ msgstr "Sesi Kapat" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Gelen çağrı" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Devam eden çağrı" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Diğer" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Faks" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・İş" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Mobil" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Ev" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Gönder %s" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Aç" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "Açık" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "Kapalı" - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Devre dışı" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Kısayol Ayarla" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Ayarla" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Değiştirmek için yeni bir kısayol gir %s" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Klavye kısayolunu sıfırlamak için iptal, geri almak için ESC tuşuna bas." - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s zaten kullanılıyor" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Hemen şimdi" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -820,17 +936,28 @@ msgstr[1] "%d dakika" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Dün %s" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "Grup Mesajı" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "Sen: %s" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "Ve %d başka kişi" +msgstr[1] "Ve %d başkaları" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "Cihaz Seç" @@ -839,101 +966,63 @@ msgid "Select" msgstr "Seç" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "Eşleşmemiş" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Bağlantı kesildi" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Bağlı" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "Transferred files are placed in the Downloads folder." -msgstr "Aktarılan dosyalar İndirilenler klasörüne eklenir." - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "GNOME için eksiksiz bir KDE Connect uygulaması" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "Serdar Sağlam \n" -"Orhan Engin Okay \n" -"A. Burak Tektaş " - -#: src/service/ui/settings.js:529 -msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." -msgstr "Hata ayıklama mesajları kaydediliyor. Sorunu yeniden oluşturmak için gerekli adımları izleyin ve günlüğü inceleyin." - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "Günlüğü Gözden Geçir" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "Şarj Oldu" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Cihaz Bulunamadı" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (Tahmini…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (Dolma Süresi %d∶%02d)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (Kalan Süre %d∶%02d)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 -msgid "Do Not Disturb" -msgstr "Rahatsız Etme" - -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" -msgstr "Sessiz Mobil Cihaz Bildirimleri" - -#: src/shell/donotdisturb.js:171 -msgid "Until you turn off Do Not Disturb" -msgstr "Kapatana kadar Rahatsız Etme" +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d saat" +msgstr[1] "%d saat" #. TRANSLATORS: Time until change with time duration #. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 +#: src/shell/donotdisturb.js:150 #, javascript-format msgid "Until %s (%s)" msgstr "Kadar %s (%s)" -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 +msgid "Do Not Disturb" +msgstr "Rahatsız Etme" + +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" +msgstr "Mobil Cihazlardan Gelen Bildirimleri Sustur" + +#: src/shell/donotdisturb.js:261 +msgid "Until you turn off Do Not Disturb" +msgstr "Kapatana kadar Rahatsız Etme" + +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Tamam" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d saat" -msgstr[1] "%d saat" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Yanıtla" @@ -952,11 +1041,6 @@ msgid "Service Unavailable" msgstr "Servis Mevcut Değil" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Cihaz Bulunamadı" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/uk.po gnome-shell-extension-zorin-connect-28.0.2/po/uk.po --- gnome-shell-extension-zorin-connect-24.1/po/uk.po 2019-05-29 12:54:15.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/uk.po 2019-11-30 17:36:18.000000000 +0000 @@ -2,11 +2,11 @@ msgstr "" "Project-Id-Version: zorin-connect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-03-07 12:39-0800\n" -"PO-Revision-Date: 2019-05-18 10:54\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-10 11:13\n" "Last-Translator: Andy Holmes (andyholmes)\n" "Language-Team: Ukrainian\n" -"Language: uk\n" +"Language: uk_UA\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -16,363 +16,391 @@ "X-Crowdin-Language: uk\n" "X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "Дані щодо шифрування" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "Пов'язати" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "Відв'язати" + #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" msgstr "Під'єднатися до…" #. Action Buttons -#: data/connect.ui:30 data/notification.ui:14 data/telephony.ui:14 -#: src/service/plugins/share.js:102 src/service/plugins/share.js:244 -#: src/service/plugins/share.js:387 src/service/ui/device.js:604 -#: src/service/ui/keybindings.js:44 src/service/ui/service.js:37 -#: src/service/ui/settings.js:531 src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" msgstr "Скасувати" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" msgstr "Під'єднатись" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" msgstr "IP-адреса" -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "Bluetooth-пристрій" - -#: data/contacts.ui:48 -msgid "Type a phone number or name" -msgstr "Введіть номер телефону або ім'я" - -#: data/contacts.ui:82 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" msgstr "Немає контактів" -#: data/contacts.ui:94 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" msgstr "Допомога" -#: data/conversation.ui:76 data/conversation.ui:85 src/shell/notification.js:51 +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "Введіть номер телефону або ім'я" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" msgstr "Введіть повідомлення" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" msgstr "Відправити повідомлення" -#: data/device.ui:67 src/service/plugins/battery.js:11 -msgid "Battery" -msgstr "Акумулятор" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "Настільний комп'ютер" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:88 msgid "Camera" msgstr "Камера" -#: data/device.ui:178 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" msgstr "Синхронізація буферу обміну" -#: data/device.ui:241 +#: data/ui/device-preferences.ui:208 msgid "Media Players" msgstr "Медіапрогравачі" -#: data/device.ui:296 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" msgstr "Миша та клавіатура" -#: data/device.ui:351 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" msgstr "Керування гучністю" -#: data/device.ui:401 data/device.ui:1864 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "Файли" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" msgstr "Надання доступу" -#: data/device.ui:430 data/device.ui:707 data/device.ui:1910 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:175 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" msgstr "Команди" -#: data/device.ui:480 data/device.ui:483 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" msgstr "Назва" -#: data/device.ui:496 data/device.ui:502 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" msgstr "Командний рядок" -#: data/device.ui:500 data/device.ui:501 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" msgstr "Обрати виконуваний файл" -#: data/device.ui:552 data/device.ui:567 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" msgstr "Додати" -#: data/device.ui:583 data/device.ui:598 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" msgstr "Видалити" -#: data/device.ui:632 data/device.ui:644 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" msgstr "Редагувати" -#: data/device.ui:660 data/device.ui:672 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" msgstr "Зберегти" -#: data/device.ui:768 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" msgstr "Ділитися сповіщеннями" -#: data/device.ui:819 +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "" + +#: data/ui/device-preferences.ui:998 msgid "Applications" msgstr "Додатки" -#: data/device.ui:865 data/device.ui:1956 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 #: src/service/plugins/notification.js:13 msgid "Notifications" msgstr "Сповіщення" -#: data/device.ui:923 src/service/plugins/contacts.js:12 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 msgid "Contacts" msgstr "Контакти" -#: data/device.ui:976 +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" msgstr "Вхідні дзвінки" -#: data/device.ui:1025 data/device.ui:1191 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" msgstr "Гучність" -#: data/device.ui:1090 data/device.ui:1256 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" msgstr "Призупинити відтворення" -#: data/device.ui:1143 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" msgstr "Під час дзвінків" -#: data/device.ui:1312 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" msgstr "Вимкнути мікрофон" -#: data/device.ui:1366 data/device.ui:2002 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" msgstr "Телефонія" -#: data/device.ui:1401 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" msgstr "Скорочення для дій" -#: data/device.ui:1416 data/device.ui:1485 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" msgstr "Скинути всі…" -#: data/device.ui:1470 -msgid "Command Shortcuts" -msgstr "Скорочення для команд" - -#: data/device.ui:1534 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" msgstr "Скорочення" -#: data/device.ui:1565 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" msgstr "Плагіни" -#: data/device.ui:1611 +#: data/ui/device-preferences.ui:1723 msgid "Experimental" msgstr "Експериментальне" -#: data/device.ui:1660 +#: data/ui/device-preferences.ui:1771 msgid "Legacy SMS Support" msgstr "Застаріла підтримка SMS" -#: data/device.ui:1734 -msgid "Delete" -msgstr "Видалити" - -#: data/device.ui:1763 -msgid "Delete this device" -msgstr "Видалити цей пристрій" - -#: data/device.ui:1781 -msgid "Unpair and remove all settings and files" -msgstr "Відв'язати та видалити всі налаштування та файли" - -#: data/device.ui:1814 data/device.ui:2094 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" msgstr "Додатково" -#: data/device.ui:2048 -msgid "Keyboard Shortcuts" -msgstr "Клавіатурні скорочення" - -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:2151 data/menus.ui:68 -msgid "Pair" -msgstr "Пов'язати" - -#: data/device.ui:2183 -msgid "Device is unpaired" -msgstr "Пристрій непов'язаний" - -#: data/device.ui:2198 -msgid "You may configure this device before pairing" -msgstr "Ви можете налаштувати цей пристрій перед пов'язуванням" +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "" -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "Режим відображення" +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "" -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "Панель" +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "" -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "Меню користувача" +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "" -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:528 -msgid "Generate Support Log" -msgstr "Згенерувати журнал для підтримки" +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "" -#: data/menus.ui:38 -msgid "About Zorin Connect" -msgstr "Про Zorin Connect" +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "Акумулятор" -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "Перемкнутися до Bluetooth" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "Перемкнутися до мережі" +#: data/ui/device-preferences.ui:2394 +msgid "Keyboard Shortcuts" +msgstr "Клавіатурні скорочення" -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:308 -msgid "Encryption Info" -msgstr "Дані щодо шифрування" +#: data/ui/device-preferences.ui:2529 +msgid "Device is unpaired" +msgstr "Пристрій непов'язаний" -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 -msgid "Unpair" -msgstr "Відв'язати" +#: data/ui/device-preferences.ui:2544 +msgid "You may configure this device before pairing" +msgstr "Ви можете налаштувати цей пристрій перед пов'язуванням" #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" msgstr "До пристрою" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" msgstr "Від пристрою" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" msgstr "Нічого" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" msgstr "Зменшити" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:177 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" msgstr "Вимкнути" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:881 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" msgstr "Повідомлення" -#: data/messaging.ui:21 src/service/ui/messaging.js:1005 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" msgstr "Нова бесіда" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "Немає бесід" + +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" msgstr "Жодну бесіду не обрано" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" msgstr "Оберіть або розпочніть бесіду" -#: data/messaging.ui:193 data/notification.ui:53 data/telephony.ui:53 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" msgstr "Пристрій від'єднаний" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "Немає бесід" - -#: data/notification.ui:21 data/telephony.ui:21 -#: src/service/plugins/share.js:388 +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 msgid "Send" msgstr "Відправити" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "Пошук пристроїв…" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" msgstr "Оновити" -#. Service Menu -> "Mobile Settings" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:104 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" msgstr "Параметри мобільних пристроїв" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" msgstr "Редагувати ім'я пристрою" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" msgstr "Пристрої" -#: data/settings.ui:299 +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "Пошук пристроїв…" + +#: data/ui/preferences-window.ui:332 msgid "Browser Add-Ons" msgstr "Браузерні розширення" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" msgstr "Увімкнути" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" msgstr "Цей пристрій є невидимим для непов'язаних пристроїв" -#: data/settings.ui:623 src/service/daemon.js:518 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" msgstr "Видимість вимкнено" +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "Режим відображення" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "Панель" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "Меню користувача" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "Згенерувати журнал для підтримки" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "Про Zorin Connect" + #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:675 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" msgstr "Відправити SMS" #. Service Menu -#: src/extension.js:79 src/extension.js:198 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" msgstr "Мобільні пристрої" -#: src/extension.js:193 +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "" + +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" @@ -381,48 +409,203 @@ msgstr[2] "%d під'єднано" msgstr[3] "" +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "" + #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:149 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" msgstr "Відправити до мобільного пристрою" -#: src/service/daemon.js:373 +#: src/preferences/device.js:658 +msgid "Open" +msgstr "Відкрити" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "Вимкнено" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "Увімкнено" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "Вимкнено" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "Встановити скорочення" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "Встановити" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "Введіть нове скорочення, щоб замінити %s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "Натисніть Esc щоб скасувати або Backspace щоб скинути комбінацію клавіш" + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s вже використовується" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "Повна реалізація KDE Connect для GNOME" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "kotyhoroshko" + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "Повідомлення налагодження записуються. Виконайте всі необхідні дії для відтворення проблеми, а потім перегляньте журнал." + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "Переглянути журнал" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "Ноутбук" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "Смартфон" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "Планшет" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "Не пов'язаний" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "Від'єднаний" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "Під'єднаний" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "" + +#: src/service/daemon.js:337 msgid "Report" msgstr "Повідомити" -#: src/service/daemon.js:500 +#: src/service/daemon.js:580 msgid "Authentication Failure" msgstr "Помилка аутентифікації" -#: src/service/daemon.js:509 +#: src/service/daemon.js:589 msgid "Network Error" msgstr "Помилка мережі" -#: src/service/daemon.js:510 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" msgstr "Натисніть, щоб допомогти усунути проблему" -#: src/service/daemon.js:519 +#: src/service/daemon.js:599 msgid "Discovery has been disabled due to the number of devices on this network." msgstr "Видимість було вимкнено через велику кількість пристроїв у цій мережі." -#: src/service/daemon.js:527 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "Не вдалося завантажити плагін %s" - -#: src/service/daemon.js:528 src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" msgstr "Натисніть для отримання додаткової інформації" -#: src/service/daemon.js:681 +#: src/service/daemon.js:705 msgid "Dial Number" msgstr "Набрати номер" -#: src/service/daemon.js:687 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" msgstr "Поділитися файлом" +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "Відправити сповіщення" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "Фото" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Пінг" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "Дзвеніти" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "Поділитися посиланням" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "" + #: src/service/device.js:174 msgid "Not available" msgstr "недоступний" @@ -439,83 +622,69 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:201 src/service/device.js:203 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" msgstr "Відбиток %s:" -#: src/service/device.js:261 -msgid "Laptop" -msgstr "Ноутбук" - -#: src/service/device.js:263 -msgid "Smartphone" -msgstr "Смартфон" - -#: src/service/device.js:265 -msgid "Tablet" -msgstr "Планшет" - -#: src/service/device.js:267 -msgid "Desktop" -msgstr "Настільний комп'ютер" - -#: src/service/device.js:426 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "Перепід'єднатись" - -#: src/service/device.js:433 src/service/ui/device.js:16 -#: src/service/ui/settings.js:363 -msgid "Settings" -msgstr "Налаштування" - #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:615 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" msgstr "Запит на пов'язування від %s" -#: src/service/device.js:622 +#: src/service/device.js:755 msgid "Reject" msgstr "Відхилити" -#: src/service/device.js:627 +#: src/service/device.js:760 msgid "Accept" msgstr "Прийняти" -#: src/service/plugins/battery.js:155 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "Дзвеніти" - #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:164 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" msgstr "%s: Низький заряд акумулятора" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:166 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" msgstr "залишилось %d%%" +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "Повністю заряджений" + #: src/service/plugins/clipboard.js:11 msgid "Clipboard" msgstr "Буфер обміну" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" msgstr "Поміщати у буфер обміну" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" msgstr "Отримувати з буферу обміну" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:213 src/service/plugins/telephony.js:156 -#: src/service/plugins/telephony.js:207 src/service/plugins/telephony.js:247 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:455 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" msgstr "Невідомий контакт" @@ -527,54 +696,45 @@ msgid "Mousepad" msgstr "Тачпад" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:720 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" msgstr "Клавіатура" -#: src/service/plugins/mousepad.js:266 -msgid "Additional Software Required" -msgstr "Потребується додаткове програмне забезпечення" - -#: src/service/plugins/mousepad.js:737 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" msgstr "Клавіатура не готова" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" msgstr "MPRIS" -#: src/service/plugins/notification.js:26 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" msgstr "Скасувати сповіщення" -#: src/service/plugins/notification.js:34 +#: src/service/plugins/notification.js:35 msgid "Close Notification" msgstr "Закрити сповіщення" -#: src/service/plugins/notification.js:42 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" msgstr "Відповісти на сповіщення" -#: src/service/plugins/notification.js:50 -msgid "Send Notification" -msgstr "Відправити сповіщення" - -#: src/service/plugins/photo.js:11 src/service/plugins/photo.js:17 -msgid "Photo" -msgstr "Фото" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "Пінг" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" msgstr "Пінг: %s" +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "" + #: src/service/plugins/runcommand.js:12 msgid "Run Commands" msgstr "Виконати команди" @@ -591,18 +751,14 @@ msgid "Unmount" msgstr "Демонтувати" -#: src/service/plugins/sftp.js:119 +#: src/service/plugins/sftp.js:134 msgid "All files" msgstr "Усі файли" -#: src/service/plugins/sftp.js:120 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" msgstr "Фотографії з камери" -#: src/service/plugins/sftp.js:316 -msgid "Files" -msgstr "Файли" - #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" msgstr "Поділитись" @@ -611,85 +767,87 @@ msgid "Share Text" msgstr "Поділитися текстом" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:988 -#: src/service/ui/messaging.js:996 -msgid "Share Link" -msgstr "Поділитися посиланням" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "Помилка передачі" + +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "" -#: src/service/plugins/share.js:95 src/service/plugins/share.js:237 -msgid "Starting Transfer" -msgstr "Початок передачі" +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:97 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" msgstr "Отримання «%s» від %s" -#: src/service/plugins/share.js:121 src/service/plugins/share.js:260 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" msgstr "Передача успішна" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:123 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" msgstr "Отримано «%s» від %s" -#: src/service/plugins/share.js:129 +#: src/service/plugins/share.js:189 msgid "Open Folder" msgstr "Відкрити каталог" -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:194 msgid "Open File" msgstr "Відкрити файл" -#: src/service/plugins/share.js:141 src/service/plugins/share.js:268 -msgid "Transfer Failed" -msgstr "Помилка передачі" - #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:143 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" msgstr "Не вдалося отримати «%s» від %s" -#: src/service/plugins/share.js:171 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" msgstr "Текст " #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:239 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" msgstr "Відправлення «%s» до %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:262 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" msgstr "«%s» надіслано до %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:270 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" msgstr "Не вдалося відправити «%s» до %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:339 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" msgstr "Відправити файли до %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:343 +#: src/service/plugins/share.js:408 msgid "Open when done" msgstr "Відкрити після завершення" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:382 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" msgstr "Відправити посилання до %s" @@ -706,7 +864,7 @@ msgid "Reply SMS" msgstr "Відповісти на SMS" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" msgstr "Поділитись SMS" @@ -719,105 +877,58 @@ msgstr "Приглушити дзвінок" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:173 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" msgstr "Вхідний дзвінок" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:188 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" msgstr "Поточний виклик" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" msgstr "%s・Інший" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" msgstr "%s・Факс" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" msgstr "%s・Робочий" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" msgstr "%s・Мобільний" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" msgstr "%s・Домашній" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:367 src/service/ui/contacts.js:381 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" msgstr "Відправити до %s" -#: src/service/ui/device.js:605 -msgid "Open" -msgstr "Відкрити" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "On" -msgstr "Вимкнено" - -#: src/service/ui/device.js:657 src/service/ui/device.js:670 -msgid "Off" -msgstr "Увімкнено" - -#: src/service/ui/device.js:795 src/service/ui/device.js:823 -#: src/service/ui/device.js:847 -msgid "Disabled" -msgstr "Вимкнено" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "Встановити скорочення" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "Встановити" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "Введіть нове скорочення, щоб замінити %s" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "Натисніть Esc щоб скасувати або Backspace щоб скинути комбінацію клавіш" - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "%s вже використовується" - #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:28 src/service/ui/messaging.js:61 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" msgstr "Тільки що" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:33 src/service/ui/messaging.js:65 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" @@ -827,17 +938,30 @@ msgstr[3] "" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:38 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" msgstr "Учора・%s" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "" + #. TRANSLATORS: An outgoing message body in a conversation summary -#: src/service/ui/messaging.js:207 +#: src/service/ui/messaging.js:265 #, javascript-format msgid "You: %s" msgstr "Ви: %s" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + #: src/service/ui/service.js:31 msgid "Select a Device" msgstr "Оберіть пристрій" @@ -846,101 +970,65 @@ msgid "Select" msgstr "Обрати" -#: src/service/ui/settings.js:323 -msgid "Unpaired" -msgstr "Не пов'язаний" - -#: src/service/ui/settings.js:325 -msgid "Disconnected" -msgstr "Від'єднаний" - -#: src/service/ui/settings.js:328 -msgid "Connected" -msgstr "Під'єднаний" - -#. TRANSLATORS: Description of where directly shared files are stored. -#: src/service/ui/settings.js:398 -#, javascript-format -msgid "Transferred files are placed in the Downloads folder." -msgstr "Отримані файли розміщуються у теці Завантаження." - -#: src/service/ui/settings.js:491 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "Повна реалізація KDE Connect для GNOME" - -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:500 -msgid "translator-credits" -msgstr "kotyhoroshko" - -#: src/service/ui/settings.js:529 -msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." -msgstr "Повідомлення налагодження записуються. Виконайте всі необхідні дії для відтворення проблеми, а потім перегляньте журнал." - -#: src/service/ui/settings.js:532 -msgid "Review Log" -msgstr "Переглянути журнал" - -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:113 -msgid "Fully Charged" -msgstr "Повністю заряджений" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "Пристроїв не знайдено" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:117 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" msgstr "%d%% (Розраховується…)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:127 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" msgstr "%d%% (%d∶%02d до зарядження)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:135 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" msgstr "%d%% (%d∶%02d залишилося)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d година" +msgstr[1] "%d години" +msgstr[2] "%d годин" +msgstr[3] "" + +#. TRANSLATORS: Time until change with time duration +#. EXAMPLE: Until 10:00 (2 hours) +#: src/shell/donotdisturb.js:150 +#, javascript-format +msgid "Until %s (%s)" +msgstr "До %s (%s)" + +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 msgid "Do Not Disturb" msgstr "Не турбувати" -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" msgstr "Заглушити сповіщення мобільних пристроїв" -#: src/shell/donotdisturb.js:171 +#: src/shell/donotdisturb.js:261 msgid "Until you turn off Do Not Disturb" msgstr "Допоки ви не вимкнете режим «Не турбувати»" -#. TRANSLATORS: Time until change with time duration -#. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 -#, javascript-format -msgid "Until %s (%s)" -msgstr "До %s (%s)" - -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:302 msgid "Done" msgstr "Готово" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "%d година" -msgstr[1] "%d години" -msgstr[2] "%d годин" -msgstr[3] "" - -#: src/shell/notification.js:42 +#: src/shell/notification.js:43 msgid "Reply" msgstr "Відповісти" @@ -959,11 +1047,6 @@ msgid "Service Unavailable" msgstr "Сервіс недоступний" -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "Пристроїв не знайдено" - #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/zh_CN.po gnome-shell-extension-zorin-connect-28.0.2/po/zh_CN.po --- gnome-shell-extension-zorin-connect-24.1/po/zh_CN.po 2019-03-17 12:33:45.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/zh_CN.po 2019-11-30 17:36:50.000000000 +0000 @@ -1,428 +1,617 @@ -# Chinese translations for org.gnome.Shell.Extensions.ZorinConnect package. -# Copyright (C) 2018 THE org.gnome.Shell.Extensions.ZorinConnect'S COPYRIGHT HOLDER -# This file is distributed under the same license as the org.gnome.Shell.Extensions.ZorinConnect package. -# Automatically generated, 2018. -# msgid "" msgstr "" -"Project-Id-Version: org.gnome.Shell.Extensions.ZorinConnect\n" +"Project-Id-Version: zorin-connect\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-12-24 09:24-0800\n" -"PO-Revision-Date: 2018-12-24 09:24-0800\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-10 11:13\n" +"Last-Translator: Andy Holmes (andyholmes)\n" +"Language-Team: Chinese Simplified\n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: crowdin.com\n" +"X-Crowdin-Project: zorin-connect\n" +"X-Crowdin-Language: zh-CN\n" +"X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" + +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "加密信息" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "配对" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "取消配对" #. TRANSLATORS: Open a dialog to connect to an IP or Bluez device -#: data/connect.ui:24 data/menus.ui:7 +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 msgid "Connect to…" -msgstr "" +msgstr "连接到..." #. Action Buttons -#: data/connect.ui:30 data/telephony.ui:14 src/service/plugins/share.js:139 -#: src/service/plugins/share.js:310 src/service/plugins/share.js:456 -#: src/service/ui/device.js:609 src/service/ui/keybindings.js:44 -#: src/service/ui/service.js:37 src/service/ui/settings.js:539 -#: src/shell/donotdisturb.js:215 +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 msgid "Cancel" -msgstr "" +msgstr "取消" -#: data/connect.ui:37 +#: data/ui/connect.ui:27 msgid "Connect" -msgstr "" +msgstr "连接" -#: data/connect.ui:98 +#: data/ui/connect.ui:74 msgid "IP Address" -msgstr "" - -#: data/connect.ui:142 -msgid "Bluetooth Device" -msgstr "" +msgstr "IP 地址" -#: data/contacts.ui:49 -msgid "Type a phone number or name" -msgstr "" - -#: data/contacts.ui:83 +#: data/ui/contact-chooser.ui:50 msgid "No contacts" -msgstr "" +msgstr "没有联系人" -#: data/contacts.ui:95 data/menus.ui:33 data/messaging.ui:247 +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 msgid "Help" -msgstr "" +msgstr "帮助" + +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "输入电话号码或姓名" -#: data/conversation.ui:76 data/conversation.ui:85 +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 msgid "Type a message" -msgstr "" +msgstr "键入消息" -#: data/conversation.ui:84 +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 msgid "Send Message" -msgstr "" +msgstr "发送消息" -#: data/device.ui:67 src/service/plugins/battery.js:12 -msgid "Battery" -msgstr "" +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "桌面" + +#: data/ui/device-preferences.ui:88 +msgid "Camera" +msgstr "相机" -#: data/device.ui:122 +#: data/ui/device-preferences.ui:144 msgid "Clipboard Sync" -msgstr "" +msgstr "剪贴板同步" -#: data/device.ui:185 +#: data/ui/device-preferences.ui:208 msgid "Media Players" -msgstr "" +msgstr "媒体播放" -#: data/device.ui:240 +#: data/ui/device-preferences.ui:263 msgid "Mouse & Keyboard" -msgstr "" +msgstr "鼠标和键盘" -#: data/device.ui:295 +#: data/ui/device-preferences.ui:318 msgid "Volume Control" -msgstr "" +msgstr "音量控制" -#: data/device.ui:345 data/device.ui:1625 +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "文件" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "文件接收" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 msgid "Sharing" -msgstr "" +msgstr "共享" -#: data/device.ui:374 data/device.ui:651 data/device.ui:1671 -#: src/service/plugins/runcommand.js:18 src/service/plugins/runcommand.js:169 +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 msgid "Commands" -msgstr "" +msgstr "命令" -#: data/device.ui:424 data/device.ui:427 +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 msgid "Name" -msgstr "" +msgstr "名称" -#: data/device.ui:440 data/device.ui:446 +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 msgid "Command Line" -msgstr "" +msgstr "命令行" -#: data/device.ui:444 data/device.ui:445 +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 msgid "Choose an executable" -msgstr "" +msgstr "选择可执行文件" -#: data/device.ui:496 data/device.ui:511 +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 msgid "Add" -msgstr "" +msgstr "添加" -#: data/device.ui:527 data/device.ui:542 +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 msgid "Remove" -msgstr "" +msgstr "删除" -#: data/device.ui:576 data/device.ui:588 +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 msgid "Edit" -msgstr "" +msgstr "编辑" -#: data/device.ui:604 data/device.ui:616 +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 msgid "Save" -msgstr "" +msgstr "保存" -#: data/device.ui:712 +#: data/ui/device-preferences.ui:887 msgid "Share Notifications" +msgstr "共享通知" + +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" msgstr "" -#: data/device.ui:763 +#: data/ui/device-preferences.ui:998 msgid "Applications" -msgstr "" +msgstr "应用" -#: data/device.ui:809 data/device.ui:1717 -#: src/service/plugins/notification.js:12 +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 +#: src/service/plugins/notification.js:13 msgid "Notifications" -msgstr "" +msgstr "通知" -#: data/device.ui:839 +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 +msgid "Contacts" +msgstr "联络" + +#: data/ui/device-preferences.ui:1155 msgid "Incoming Calls" -msgstr "" +msgstr "来电" -#: data/device.ui:888 data/device.ui:1055 +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 msgid "Volume" -msgstr "" +msgstr "音量" -#: data/device.ui:954 data/device.ui:1120 +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 msgid "Pause Media" -msgstr "" +msgstr "暂停媒体" -#: data/device.ui:1007 +#: data/ui/device-preferences.ui:1323 msgid "Ongoing Calls" -msgstr "" +msgstr "正在进行的呼叫" -#: data/device.ui:1176 +#: data/ui/device-preferences.ui:1493 msgid "Mute Microphone" -msgstr "" +msgstr "麦克风静音" -#: data/device.ui:1230 data/device.ui:1763 src/service/plugins/telephony.js:13 +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 msgid "Telephony" -msgstr "" +msgstr "电话" -#: data/device.ui:1265 +#: data/ui/device-preferences.ui:1582 msgid "Action Shortcuts" -msgstr "" +msgstr "操作快捷方式" -#: data/device.ui:1280 data/device.ui:1349 +#: data/ui/device-preferences.ui:1597 msgid "Reset All…" -msgstr "" +msgstr "全部重置..." -#: data/device.ui:1334 -msgid "Command Shortcuts" -msgstr "" - -#: data/device.ui:1398 +#: data/ui/device-preferences.ui:1646 msgid "Shortcuts" -msgstr "" +msgstr "快捷方式" -#: data/device.ui:1429 +#: data/ui/device-preferences.ui:1677 msgid "Plugins" -msgstr "" +msgstr "插件" -#: data/device.ui:1495 -msgid "Delete" -msgstr "" - -#: data/device.ui:1524 -msgid "Delete this device" -msgstr "" +#: data/ui/device-preferences.ui:1723 +msgid "Experimental" +msgstr "实验功能" -#: data/device.ui:1542 -msgid "Unpair and remove all settings and files" -msgstr "" +#: data/ui/device-preferences.ui:1771 +msgid "Legacy SMS Support" +msgstr "旧版短信支持" -#: data/device.ui:1575 data/device.ui:1855 +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 msgid "Advanced" -msgstr "" +msgstr "高级" -#: data/device.ui:1809 -msgid "Keyboard Shortcuts" -msgstr "" +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "设备电量" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "低电量通知" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "充满电通知" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "系统电池" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "分享统计信息" -#. TRANSLATORS: Send a pair request to the device -#: data/device.ui:1912 data/menus.ui:68 src/service/device.js:429 -msgid "Pair" -msgstr "" +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "电池" + +#: data/ui/device-preferences.ui:2394 +msgid "Keyboard Shortcuts" +msgstr "键盘快捷键" -#: data/device.ui:1944 +#: data/ui/device-preferences.ui:2529 msgid "Device is unpaired" -msgstr "" +msgstr "设备未配对" -#: data/device.ui:1959 +#: data/ui/device-preferences.ui:2544 msgid "You may configure this device before pairing" -msgstr "" - -#: data/menus.ui:12 -msgid "Display Mode" -msgstr "" - -#. TRANSLATORS: Show device indicators in the top bar -#: data/menus.ui:15 -msgid "Panel" -msgstr "" - -#. TRANSLATORS: Show devices in the user menu like Bluetooth -#: data/menus.ui:21 -msgid "User Menu" -msgstr "" - -#. TRANSLATORS: Generate a support log -#: data/menus.ui:29 src/service/ui/settings.js:536 -msgid "Generate Support Log" -msgstr "" - -#: data/menus.ui:38 -msgid "About" -msgstr "" - -#. TRANSLATORS: Change the connection type to Bluetooth -#: data/menus.ui:49 -msgid "Switch to Bluetooth" -msgstr "" - -#. TRANSLATORS: Change the connection type to TCP/IP -#: data/menus.ui:56 -msgid "Switch to LAN" -msgstr "" - -#. TRANSLATORS: View the TLS Certificate fingerprint -#: data/menus.ui:63 src/service/ui/device.js:322 -msgid "Encryption Info" -msgstr "" - -#. TRANSLATORS: Unpair the device and notify it -#: data/menus.ui:74 src/service/device.js:437 -msgid "Unpair" -msgstr "" +msgstr "您可以在配对前配置此设备" #. TRANSLATORS: Send clipboard content to device -#: data/menus.ui:86 +#: data/ui/device-preferences.ui:2585 msgid "To Device" -msgstr "" +msgstr "到设备" #. TRANSLATORS: Receive clipboard content from the device -#: data/menus.ui:92 +#: data/ui/device-preferences.ui:2591 msgid "From Device" -msgstr "" +msgstr "从设备" #. TRANSLATORS: Don't change the system volume -#: data/menus.ui:104 data/menus.ui:130 +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 msgid "Nothing" -msgstr "" +msgstr "无" #. TRANSLATORS: Lower the system volume -#: data/menus.ui:111 data/menus.ui:137 +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 msgid "Lower" -msgstr "" +msgstr "降低" #. TRANSLATORS: Mute the system volume #. TRANSLATORS: Silence the phone ringer -#: data/menus.ui:118 data/menus.ui:144 src/service/plugins/telephony.js:194 +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 msgid "Mute" -msgstr "" +msgstr "静音" -#: data/messaging.ui:12 src/service/plugins/sms.js:26 -#: src/service/ui/messaging.js:902 +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 msgid "Messaging" -msgstr "" +msgstr "消息" -#: data/messaging.ui:21 src/service/ui/messaging.js:971 +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 msgid "New Conversation" -msgstr "" +msgstr "新建对话" + +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "没有对话" -#: data/messaging.ui:110 +#: data/ui/messaging-window.ui:168 msgid "No conversation selected" -msgstr "" +msgstr "未选择对话" -#: data/messaging.ui:126 +#: data/ui/messaging-window.ui:184 msgid "Select or start a conversation" -msgstr "" +msgstr "选择或开始对话" -#: data/messaging.ui:193 data/telephony.ui:52 +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 msgid "Device is disconnected" -msgstr "" +msgstr "设备已断开连接" -#: data/messaging.ui:264 -msgid "No Conversations" -msgstr "" +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 +msgid "Send" +msgstr "发送" -#: data/settings.ui:10 -msgid "Searching for devices…" -msgstr "" +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "设备名称" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "修改名称" -#: data/settings.ui:49 data/settings.ui:63 +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 msgid "Refresh" -msgstr "" +msgstr "刷新" -#: data/settings.ui:74 data/settings.ui:91 src/extension.js:105 +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 msgid "Mobile Settings" -msgstr "" +msgstr "移动设置" -#: data/settings.ui:144 data/settings.ui:158 +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 msgid "Edit Device Name" -msgstr "" +msgstr "编辑设备名称" -#: data/settings.ui:236 +#: data/ui/preferences-window.ui:257 msgid "Devices" -msgstr "" +msgstr "设备" -#: data/settings.ui:299 -msgid "Browser Add-Ons" -msgstr "" +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "正在搜索设备…" -#: data/settings.ui:409 -msgid "KDE Connect" -msgstr "" +#: data/ui/preferences-window.ui:332 +msgid "Browser Add-Ons" +msgstr "浏览器附加组件" -#: data/settings.ui:579 +#: data/ui/preferences-window.ui:612 msgid "Enable" -msgstr "" +msgstr "启用" -#: data/settings.ui:611 +#: data/ui/preferences-window.ui:644 msgid "This device is invisible to unpaired devices" -msgstr "" +msgstr "此设备对未配对的设备不可见" -#: data/settings.ui:623 src/service/daemon.js:532 +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 msgid "Discovery Disabled" -msgstr "" +msgstr "发现已禁用" + +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "显示模式" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "面板" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "用户菜单" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "生成支持日志" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "关于 Zorin Connect" #. TRANSLATORS: Share URL by SMS -#: data/telephony.ui:9 src/service/daemon.js:714 src/service/plugins/sms.js:50 -#: webextension/gettext.js:39 +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 msgid "Send SMS" -msgstr "" - -#: data/telephony.ui:21 src/service/plugins/share.js:457 -msgid "Send" -msgstr "" +msgstr "发送短信" #. Service Menu -#: src/extension.js:79 src/extension.js:255 +#: src/extension.js:118 src/extension.js:249 msgid "Mobile Devices" -msgstr "" +msgstr "移动设备" + +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "开启" -#. TRANSLATORS: %d is the number of devices connected -#: src/extension.js:253 +#: src/extension.js:244 #, javascript-format msgid "%d Connected" msgid_plural "%d Connected" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%d 连接" + +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "关闭" #. TRANSLATORS: Top-level context menu item for Zorin Connect -#: src/nautilus-zorin-connect.py:112 webextension/gettext.js:31 +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 msgid "Send To Mobile Device" -msgstr "" +msgstr "发送到移动设备" + +#: src/preferences/device.js:658 +msgid "Open" +msgstr "打开" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "开" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "关" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "禁用" -#: src/service/daemon.js:372 +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "设置快捷方式" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "设置" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "输入新的快捷方式 %s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "按 Esc 键取消,或按 Backsace 键重置键盘快捷方式。" + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "%s 已在使用中" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "KDE Connect 在 GNOME 的完整实现" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "翻译贡献" + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "正在记录调试日志。请采取任何必要的步骤来重现问题,然后即可查看日志。" + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "查看日志" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "笔记本电脑" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "智能手机" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "平板电脑" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "电视" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "未配对" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "已断开" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "已连接" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "等待服务响应..." + +#: src/service/daemon.js:337 msgid "Report" -msgstr "" +msgstr "报告" -#: src/service/daemon.js:507 +#: src/service/daemon.js:580 msgid "Authentication Failure" -msgstr "" +msgstr "身份验证失败" -#: src/service/daemon.js:516 +#: src/service/daemon.js:589 msgid "Network Error" -msgstr "" +msgstr "网络错误" -#: src/service/daemon.js:517 src/service/daemon.js:525 +#: src/service/daemon.js:590 msgid "Click for help troubleshooting" -msgstr "" - -#: src/service/daemon.js:524 -msgid "PulseAudio Error" -msgstr "" - -#: src/service/daemon.js:533 -msgid "" -"Discovery has been disabled due to the number of devices on this network." -msgstr "" +msgstr "单击以获取疑难解答帮助" -#: src/service/daemon.js:541 -#, javascript-format -msgid "%s Plugin Failed To Load" -msgstr "" +#: src/service/daemon.js:599 +msgid "Discovery has been disabled due to the number of devices on this network." +msgstr "由于此网络上的设备数量,已禁用发现。" -#: src/service/daemon.js:542 +#: src/service/daemon.js:608 msgid "Click for more information" -msgstr "" +msgstr "单击以获取详细信息" -#: src/service/daemon.js:720 +#: src/service/daemon.js:705 msgid "Dial Number" -msgstr "" +msgstr "拨打号码" -#: src/service/daemon.js:726 src/service/plugins/share.js:27 +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 msgid "Share File" -msgstr "" +msgstr "共享文件" + +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "可用设备列表" -#: src/service/device.js:166 +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "所有可用设备" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "目标设备" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "消息正文" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "发送通知" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "通知的应用名称" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "通知的信息正文" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "通知的图标" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "通知的ID" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "照片" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ping" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "响铃" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "共享链接" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "显示版本信息" + +#: src/service/device.js:174 msgid "Not available" -msgstr "" +msgstr "无法使用的" #. TRANSLATORS: Bluetooth address for remote device -#: src/service/device.js:170 +#: src/service/device.js:179 #, javascript-format msgid "Bluetooth device at %s" -msgstr "" +msgstr "蓝牙设备位于 %s" #. TRANSLATORS: Label for TLS Certificate fingerprint #. @@ -430,524 +619,426 @@ #. #. Google Pixel Fingerprint: #. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 -#: src/service/device.js:188 src/service/device.js:190 +#: src/service/device.js:199 src/service/device.js:201 #, javascript-format msgid "%s Fingerprint:" -msgstr "" - -#: src/service/device.js:247 -msgid "Laptop" -msgstr "" - -#: src/service/device.js:249 -msgid "Smartphone" -msgstr "" - -#: src/service/device.js:251 -msgid "Tablet" -msgstr "" - -#: src/service/device.js:253 -msgid "Desktop" -msgstr "" - -#: src/service/device.js:413 src/service/ui/device.js:15 -msgid "Reconnect" -msgstr "" - -#: src/service/device.js:421 src/service/ui/device.js:16 -#: src/service/ui/settings.js:371 -msgid "Settings" -msgstr "" +msgstr "%s 指纹:" #. TRANSLATORS: eg. Pair Request from Google Pixel -#: src/service/device.js:612 +#: src/service/device.js:748 #, javascript-format msgid "Pair Request from %s" -msgstr "" +msgstr "%s 请求配对" -#: src/service/device.js:619 +#: src/service/device.js:755 msgid "Reject" -msgstr "" +msgstr "拒绝" -#: src/service/device.js:624 +#: src/service/device.js:760 msgid "Accept" -msgstr "" - -#: src/service/plugins/battery.js:188 src/service/plugins/findmyphone.js:19 -msgid "Ring" -msgstr "" +msgstr "接受" #. TRANSLATORS: eg. Google Pixel: Battery is low -#: src/service/plugins/battery.js:197 +#: src/service/plugins/battery.js:181 #, javascript-format msgid "%s: Battery is low" -msgstr "" +msgstr "%s: 电池电量低" #. TRANSLATORS: eg. 15% remaining -#: src/service/plugins/battery.js:199 +#: src/service/plugins/battery.js:183 #, javascript-format msgid "%d%% remaining" -msgstr "" +msgstr "剩余 %d%%" + +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "%s: 电池已充满" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "充满电" #: src/service/plugins/clipboard.js:11 msgid "Clipboard" -msgstr "" +msgstr "剪贴板" -#: src/service/plugins/clipboard.js:17 +#: src/service/plugins/clipboard.js:23 msgid "Clipboard Push" -msgstr "" +msgstr "推送剪贴板" -#: src/service/plugins/clipboard.js:25 +#: src/service/plugins/clipboard.js:31 msgid "Clipboard Pull" -msgstr "" - -#: src/service/plugins/contacts.js:12 -msgid "Contacts" -msgstr "" +msgstr "获取剪贴板" #. Ensure we have a sender #. TRANSLATORS: No name or phone number -#: src/service/plugins/contacts.js:263 src/service/plugins/telephony.js:173 -#: src/service/plugins/telephony.js:224 src/service/plugins/telephony.js:264 -#: src/service/ui/contacts.js:156 src/service/ui/contacts.js:397 +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 msgid "Unknown Contact" -msgstr "" +msgstr "未知联系人" #: src/service/plugins/findmyphone.js:13 msgid "Find My Phone" -msgstr "" +msgstr "查找我的手机" #: src/service/plugins/mousepad.js:14 msgid "Mousepad" -msgstr "" +msgstr "鼠标" -#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:568 +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 msgid "Keyboard" -msgstr "" +msgstr "键盘" -#: src/service/plugins/mousepad.js:223 -msgid "Additional Software Required" -msgstr "" - -#: src/service/plugins/mousepad.js:585 +#: src/service/plugins/mousepad.js:413 msgid "Keyboard not ready" -msgstr "" +msgstr "键盘未就绪" -#: src/service/plugins/mpris.js:10 +#: src/service/plugins/mpris.js:12 msgid "MPRIS" -msgstr "" +msgstr "MPRIS" -#: src/service/plugins/notification.js:25 +#: src/service/plugins/notification.js:27 msgid "Cancel Notification" -msgstr "" +msgstr "取消通知" -#: src/service/plugins/notification.js:33 +#: src/service/plugins/notification.js:35 msgid "Close Notification" -msgstr "" +msgstr "关闭通知" -#: src/service/plugins/notification.js:41 +#: src/service/plugins/notification.js:43 msgid "Reply Notification" -msgstr "" +msgstr "回复通知" -#: src/service/plugins/notification.js:49 -msgid "Send Notification" -msgstr "" - -#: src/service/plugins/ping.js:11 src/service/plugins/ping.js:17 -#: src/service/plugins/ping.js:46 -msgid "Ping" -msgstr "" +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "激活通知" #. TRANSLATORS: An optional message accompanying a ping, rarely if ever used #. eg. Ping: A message sent with ping -#: src/service/plugins/ping.js:53 +#: src/service/plugins/ping.js:51 #, javascript-format msgid "Ping: %s" +msgstr "Ping: %s" + +#: src/service/plugins/presenter.js:9 +msgid "Presentation" msgstr "" #: src/service/plugins/runcommand.js:12 msgid "Run Commands" -msgstr "" +msgstr "运行命令" #: src/service/plugins/sftp.js:12 msgid "SFTP" -msgstr "" +msgstr "SFTP" #: src/service/plugins/sftp.js:18 msgid "Mount" -msgstr "" +msgstr "挂载" #: src/service/plugins/sftp.js:26 msgid "Unmount" -msgstr "" +msgstr "卸载" -#: src/service/plugins/sftp.js:159 +#: src/service/plugins/sftp.js:134 msgid "All files" -msgstr "" +msgstr "全部文件" -#: src/service/plugins/sftp.js:160 +#: src/service/plugins/sftp.js:135 msgid "Camera pictures" -msgstr "" - -#: src/service/plugins/sftp.js:416 -msgid "Files" -msgstr "" +msgstr "相机图片" #: src/service/plugins/share.js:13 src/service/plugins/share.js:19 msgid "Share" -msgstr "" +msgstr "共享" #: src/service/plugins/share.js:35 msgid "Share Text" -msgstr "" +msgstr "共享文本" -#: src/service/plugins/share.js:43 src/service/ui/messaging.js:954 -#: src/service/ui/messaging.js:962 -msgid "Share Link" -msgstr "" +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "传输失败" -#: src/service/plugins/share.js:132 src/service/plugins/share.js:303 -msgid "Starting Transfer" -msgstr "" +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "%s 不允许上传文件" + +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "文件传输中" #. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:134 +#: src/service/plugins/share.js:156 #, javascript-format msgid "Receiving “%s” from %s" -msgstr "" +msgstr "从 %s 接收 “%s”" -#: src/service/plugins/share.js:172 src/service/plugins/share.js:327 +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 msgid "Transfer Successful" -msgstr "" +msgstr "传输成功" #. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:174 +#: src/service/plugins/share.js:183 #, javascript-format msgid "Received “%s” from %s" -msgstr "" +msgstr "从 %s 接收 “%s”" -#: src/service/plugins/share.js:180 +#: src/service/plugins/share.js:189 msgid "Open Folder" -msgstr "" +msgstr "打开目录" -#: src/service/plugins/share.js:185 +#: src/service/plugins/share.js:194 msgid "Open File" -msgstr "" - -#: src/service/plugins/share.js:192 src/service/plugins/share.js:335 -msgid "Transfer Failed" -msgstr "" +msgstr "打开文件" #. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel -#: src/service/plugins/share.js:194 +#: src/service/plugins/share.js:203 #, javascript-format msgid "Failed to receive “%s” from %s" -msgstr "" +msgstr "无法从 %s 接收 “%s”" -#: src/service/plugins/share.js:233 +#: src/service/plugins/share.js:232 #, javascript-format msgid "Text Shared By %s" -msgstr "" +msgstr "共享的文本 %s" #. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel -#: src/service/plugins/share.js:305 +#: src/service/plugins/share.js:304 #, javascript-format msgid "Sending “%s” to %s" -msgstr "" +msgstr "正在将 “%s” 发送到 %s" #. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel -#: src/service/plugins/share.js:329 +#: src/service/plugins/share.js:327 #, javascript-format msgid "Sent “%s” to %s" -msgstr "" +msgstr "发送 “%s” 到 %s" #. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel -#: src/service/plugins/share.js:337 +#: src/service/plugins/share.js:335 #, javascript-format msgid "Failed to send “%s” to %s" -msgstr "" +msgstr "无法将 “%s” 发送到 %s" #. TRANSLATORS: eg. Send files to Google Pixel -#: src/service/plugins/share.js:408 +#: src/service/plugins/share.js:404 #, javascript-format msgid "Send files to %s" -msgstr "" +msgstr "发送文件到 %s" #. TRANSLATORS: Mark the file to be opened once completed -#: src/service/plugins/share.js:412 +#: src/service/plugins/share.js:408 msgid "Open when done" -msgstr "" +msgstr "完成后打开" #. TRANSLATORS: eg. Send a link to Google Pixel -#: src/service/plugins/share.js:451 +#: src/service/plugins/share.js:447 #, javascript-format msgid "Send a link to %s" -msgstr "" +msgstr "发送链接到 %s" #: src/service/plugins/sms.js:13 msgid "SMS" -msgstr "" +msgstr "短信" #: src/service/plugins/sms.js:34 msgid "New SMS (URI)" -msgstr "" +msgstr "新短信(URI)" #: src/service/plugins/sms.js:42 src/service/plugins/telephony.js:22 msgid "Reply SMS" -msgstr "" +msgstr "回复短信" -#: src/service/plugins/sms.js:58 +#: src/service/plugins/sms.js:66 msgid "Share SMS" -msgstr "" +msgstr "共享短信" #: src/service/plugins/systemvolume.js:11 msgid "System Volume" -msgstr "" +msgstr "系统音量" #: src/service/plugins/telephony.js:30 msgid "Mute Call" -msgstr "" +msgstr "静音通话" #. TRANSLATORS: The phone is ringing -#: src/service/plugins/telephony.js:190 +#: src/service/plugins/telephony.js:187 msgid "Incoming call" -msgstr "" +msgstr "来电" #. TRANSLATORS: A phone call is active -#: src/service/plugins/telephony.js:205 +#: src/service/plugins/telephony.js:202 msgid "Ongoing call" -msgstr "" +msgstr "呼叫中" #. TRANSLATORS: All other phone number types -#: src/service/ui/contacts.js:118 src/service/ui/contacts.js:139 +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 #, javascript-format msgid "%s・Other" -msgstr "" +msgstr "%s・其它" #. TRANSLATORS: A fax number -#: src/service/ui/contacts.js:123 +#: src/service/ui/contacts.js:131 #, javascript-format msgid "%s・Fax" -msgstr "" +msgstr "%s・传真" #. TRANSLATORS: A work phone number -#: src/service/ui/contacts.js:127 +#: src/service/ui/contacts.js:135 #, javascript-format msgid "%s・Work" -msgstr "" +msgstr "%s・工作" #. TRANSLATORS: A mobile or cellular phone number -#: src/service/ui/contacts.js:131 +#: src/service/ui/contacts.js:139 #, javascript-format msgid "%s・Mobile" -msgstr "" +msgstr "%s・手机" #. TRANSLATORS: A home phone number -#: src/service/ui/contacts.js:135 +#: src/service/ui/contacts.js:143 #, javascript-format msgid "%s・Home" -msgstr "" +msgstr "%s・住宅" #. TRANSLATORS: A phone number (eg. "Send to 555-5555") -#: src/service/ui/contacts.js:278 src/service/ui/contacts.js:292 +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 #, javascript-format msgid "Send to %s" -msgstr "" - -#: src/service/ui/device.js:610 -msgid "Open" -msgstr "" - -#: src/service/ui/device.js:662 src/service/ui/device.js:675 -msgid "On" -msgstr "" - -#: src/service/ui/device.js:662 src/service/ui/device.js:675 -msgid "Off" -msgstr "" - -#: src/service/ui/device.js:800 src/service/ui/device.js:838 -#: src/service/ui/device.js:862 -msgid "Disabled" -msgstr "" - -#. TRANSLATORS: Title of keyboard shortcut dialog -#: src/service/ui/keybindings.js:33 -msgid "Set Shortcut" -msgstr "" - -#. TRANSLATORS: Button to confirm the new shortcut -#: src/service/ui/keybindings.js:47 -msgid "Set" -msgstr "" - -#. TRANSLATORS: Summary of a keyboard shortcut function -#. Example: Enter a new shortcut to change Messaging -#: src/service/ui/keybindings.js:54 -#, javascript-format -msgid "Enter a new shortcut to change %s" -msgstr "" - -#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut -#: src/service/ui/keybindings.js:83 -msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." -msgstr "" - -#. TRANSLATORS: When a keyboard shortcut is unavailable -#. Example: [Ctrl]+[S] is already being used -#: src/service/ui/keybindings.js:182 -#, javascript-format -msgid "%s is already being used" -msgstr "" +msgstr "发送到 %s" #. TRANSLATORS: Less than a minute ago -#: src/service/ui/messaging.js:93 src/service/ui/messaging.js:126 +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 msgid "Just now" -msgstr "" +msgstr "刚才" -#. TRANSLATORS: Time duration in minutes (eg. 15 minutes) -#: src/service/ui/messaging.js:98 src/service/ui/messaging.js:130 -#: src/shell/donotdisturb.js:266 +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 #, javascript-format msgid "%d minute" msgid_plural "%d minutes" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%d 分钟" #. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) -#: src/service/ui/messaging.js:103 +#: src/service/ui/messaging.js:43 #, javascript-format msgid "Yesterday・%s" -msgstr "" - -#: src/service/ui/service.js:31 -msgid "Select a Device" -msgstr "" - -#: src/service/ui/service.js:35 -msgid "Select" -msgstr "" - -#: src/service/ui/settings.js:331 -msgid "Unpaired" -msgstr "" - -#: src/service/ui/settings.js:333 -msgid "Disconnected" -msgstr "" +msgstr "昨天・%s" -#: src/service/ui/settings.js:336 -msgid "Connected" -msgstr "" +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "群组消息" -#. TODO: Copied from GNOME Control Center; may change -#: src/service/ui/settings.js:406 +#. TRANSLATORS: An outgoing message body in a conversation summary +#: src/service/ui/messaging.js:265 #, javascript-format -msgid "" -"Transferred files are placed in the Downloads folder." -msgstr "" - -#: src/service/ui/settings.js:499 -msgid "A complete KDE Connect implementation for GNOME" -msgstr "" +msgid "You: %s" +msgstr "你: %s" -#. TRANSLATORS: eg. 'Translator Name ' -#: src/service/ui/settings.js:508 -msgid "translator-credits" -msgstr "" +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "添加 %d 位联系人" -#: src/service/ui/settings.js:537 -msgid "" -"Debug messages are being logged. Take any steps necessary to reproduce a " -"problem then review the log." -msgstr "" +#: src/service/ui/service.js:31 +msgid "Select a Device" +msgstr "选择设备" -#: src/service/ui/settings.js:540 -msgid "Review Log" -msgstr "" +#: src/service/ui/service.js:35 +msgid "Select" +msgstr "选择" -#. TRANSLATORS: When the battery level is 100% -#: src/shell/device.js:82 -msgid "Fully Charged" -msgstr "" +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "没有找到设备" #. TRANSLATORS: When no time estimate for the battery is available #. EXAMPLE: 42% (Estimating…) -#: src/shell/device.js:86 +#: src/shell/device.js:119 #, javascript-format msgid "%d%% (Estimating…)" -msgstr "" +msgstr "%d%% (估计...)" #. TRANSLATORS: Estimated time until battery is charged #. EXAMPLE: 42% (1:15 Until Full) -#: src/shell/device.js:96 +#: src/shell/device.js:129 #, javascript-format msgid "%d%% (%d∶%02d Until Full)" -msgstr "" +msgstr "%d%% (%d∶%02d 为止)" #. TRANSLATORS: Estimated time until battery is empty #. EXAMPLE: 42% (12:15 Remaining) -#: src/shell/device.js:104 +#: src/shell/device.js:137 #, javascript-format msgid "%d%% (%d∶%02d Remaining)" -msgstr "" +msgstr "%d%% (剩余 %d∶%02d)" -#: src/shell/donotdisturb.js:150 src/shell/donotdisturb.js:289 -msgid "Do Not Disturb" -msgstr "" - -#: src/shell/donotdisturb.js:156 -msgid "Silence Mobile Device Notifications" -msgstr "" - -#: src/shell/donotdisturb.js:171 -msgid "Until you turn off Do Not Disturb" -msgstr "" +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d 小时" #. TRANSLATORS: Time until change with time duration #. EXAMPLE: Until 10:00 (2 hours) -#: src/shell/donotdisturb.js:184 src/shell/donotdisturb.js:278 +#: src/shell/donotdisturb.js:150 #, javascript-format msgid "Until %s (%s)" -msgstr "" +msgstr "到 %s (%s)" + +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 +msgid "Do Not Disturb" +msgstr "请勿打扰" + +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" +msgstr "移动设备通知静音" -#: src/shell/donotdisturb.js:216 +#: src/shell/donotdisturb.js:261 +msgid "Until you turn off Do Not Disturb" +msgstr "在关机之前不要打扰" + +#: src/shell/donotdisturb.js:302 msgid "Done" -msgstr "" +msgstr "完成" -#. TRANSLATORS: Time duration in hours (eg. 2 hours) -#: src/shell/donotdisturb.js:263 -#, javascript-format -msgid "%d hour" -msgid_plural "%d hours" -msgstr[0] "" -msgstr[1] "" +#: src/shell/notification.js:43 +msgid "Reply" +msgstr "回复" #. TRANSLATORS: Extension name #: webextension/gettext.js:27 msgid "Zorin Connect" -msgstr "" +msgstr "Zorin Connect" #. TRANSLATORS: Chrome/Firefox WebExtension description #: webextension/gettext.js:29 msgid "Share links with Zorin Connect, direct to the browser or by SMS." -msgstr "" +msgstr "与 Zorin Connect 共享链接,直接发送到浏览器或短信。" #. TRANSLATORS: WebExtension can't connect to Zorin Connect #: webextension/gettext.js:33 msgid "Service Unavailable" -msgstr "" - -#. TRANSLATORS: No devices are known or available -#: webextension/gettext.js:35 -msgid "No Device Found" -msgstr "" +msgstr "服务不可用" #. TRANSLATORS: Open URL with the device's browser #: webextension/gettext.js:37 msgid "Open in Browser" -msgstr "" +msgstr "在浏览器中打开" msgid "Mobile Application" msgstr "移动应用" diff -Nru gnome-shell-extension-zorin-connect-24.1/po/zh_TW.po gnome-shell-extension-zorin-connect-28.0.2/po/zh_TW.po --- gnome-shell-extension-zorin-connect-24.1/po/zh_TW.po 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/po/zh_TW.po 2019-11-30 17:36:44.000000000 +0000 @@ -0,0 +1,1044 @@ +msgid "" +msgstr "" +"Project-Id-Version: zorin-connect\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2019-10-10 07:07-0400\n" +"PO-Revision-Date: 2019-10-10 11:13\n" +"Last-Translator: Andy Holmes (andyholmes)\n" +"Language-Team: Chinese Traditional\n" +"Language: zh_TW\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: crowdin.com\n" +"X-Crowdin-Project: zorin-connect\n" +"X-Crowdin-Language: zh-TW\n" +"X-Crowdin-File: /master/po/org.gnome.Shell.Extensions.ZorinConnect.pot\n" + +#. TRANSLATORS: View the TLS Certificate fingerprint +#: data/gtk/menus.ui:7 src/preferences/device.js:293 +msgid "Encryption Info" +msgstr "加密資訊" + +#. TRANSLATORS: Send a pair request to the device +#: data/gtk/menus.ui:12 data/ui/device-preferences.ui:2497 +#: src/service/daemon.js:804 +msgid "Pair" +msgstr "配對" + +#. TRANSLATORS: Unpair the device and notify it +#: data/gtk/menus.ui:18 src/service/daemon.js:813 +msgid "Unpair" +msgstr "取消配對" + +#. TRANSLATORS: Open a dialog to connect to an IP or Bluez device +#: data/ui/connect.ui:14 data/ui/preferences-window.ui:710 +msgid "Connect to…" +msgstr "連線到…" + +#. Action Buttons +#: data/ui/connect.ui:20 data/ui/notification-reply-dialog.ui:13 +#: data/ui/telephony.ui:14 src/preferences/device.js:657 +#: src/preferences/keybindings.js:86 src/preferences/service.js:432 +#: src/service/plugins/share.js:161 src/service/plugins/share.js:309 +#: src/service/plugins/share.js:452 src/service/ui/service.js:37 +#: src/shell/donotdisturb.js:301 +msgid "Cancel" +msgstr "取消" + +#: data/ui/connect.ui:27 +msgid "Connect" +msgstr "連線" + +#: data/ui/connect.ui:74 +msgid "IP Address" +msgstr "IP 位址" + +#: data/ui/contact-chooser.ui:50 +msgid "No contacts" +msgstr "沒有聯絡人" + +#: data/ui/contact-chooser.ui:62 data/ui/messaging-window.ui:91 +#: data/ui/preferences-window.ui:736 +msgid "Help" +msgstr "幫助" + +#: data/ui/contact-chooser.ui:103 +msgid "Type a phone number or name" +msgstr "輸入電話號碼或姓名" + +#: data/ui/conversation.ui:76 data/ui/conversation.ui:85 +#: src/shell/notification.js:52 +msgid "Type a message" +msgstr "輸入訊息" + +#: data/ui/conversation.ui:84 src/service/plugins/sms.js:50 +msgid "Send Message" +msgstr "傳送訊息" + +#: data/ui/device-preferences.ui:40 src/preferences/service.js:510 +msgid "Desktop" +msgstr "桌面" + +#: data/ui/device-preferences.ui:88 +msgid "Camera" +msgstr "攝影機" + +#: data/ui/device-preferences.ui:144 +msgid "Clipboard Sync" +msgstr "同步剪貼簿" + +#: data/ui/device-preferences.ui:208 +msgid "Media Players" +msgstr "媒體播放器" + +#: data/ui/device-preferences.ui:263 +msgid "Mouse & Keyboard" +msgstr "滑鼠 & 鍵盤" + +#: data/ui/device-preferences.ui:318 +msgid "Volume Control" +msgstr "音量控制" + +#: data/ui/device-preferences.ui:367 src/service/plugins/sftp.js:359 +msgid "Files" +msgstr "檔案" + +#: data/ui/device-preferences.ui:418 +msgid "Receive Files" +msgstr "接收檔案" + +#: data/ui/device-preferences.ui:503 data/ui/device-preferences.ui:2164 +msgid "Sharing" +msgstr "分享" + +#: data/ui/device-preferences.ui:532 data/ui/device-preferences.ui:826 +#: data/ui/device-preferences.ui:2256 src/service/plugins/runcommand.js:18 +#: src/service/plugins/runcommand.js:26 src/service/plugins/runcommand.js:199 +msgid "Commands" +msgstr "指令" + +#: data/ui/device-preferences.ui:596 data/ui/device-preferences.ui:599 +msgid "Name" +msgstr "名稱" + +#: data/ui/device-preferences.ui:612 data/ui/device-preferences.ui:618 +msgid "Command Line" +msgstr "命令列" + +#: data/ui/device-preferences.ui:616 data/ui/device-preferences.ui:617 +msgid "Choose an executable" +msgstr "選擇可執行程式" + +#: data/ui/device-preferences.ui:668 data/ui/device-preferences.ui:684 +msgid "Add" +msgstr "新增" + +#: data/ui/device-preferences.ui:700 data/ui/device-preferences.ui:715 +msgid "Remove" +msgstr "移除" + +#: data/ui/device-preferences.ui:749 data/ui/device-preferences.ui:762 +msgid "Edit" +msgstr "編輯" + +#: data/ui/device-preferences.ui:778 data/ui/device-preferences.ui:791 +msgid "Save" +msgstr "儲存" + +#: data/ui/device-preferences.ui:887 +msgid "Share Notifications" +msgstr "分享通知" + +#: data/ui/device-preferences.ui:947 +msgid "Share When Active" +msgstr "" + +#: data/ui/device-preferences.ui:998 +msgid "Applications" +msgstr "應用程式" + +#: data/ui/device-preferences.ui:1044 data/ui/device-preferences.ui:2302 +#: src/service/plugins/notification.js:13 +msgid "Notifications" +msgstr "通知" + +#: data/ui/device-preferences.ui:1102 src/service/plugins/contacts.js:23 +msgid "Contacts" +msgstr "聯繫人" + +#: data/ui/device-preferences.ui:1155 +msgid "Incoming Calls" +msgstr "來電" + +#: data/ui/device-preferences.ui:1204 data/ui/device-preferences.ui:1371 +msgid "Volume" +msgstr "音量" + +#: data/ui/device-preferences.ui:1270 data/ui/device-preferences.ui:1437 +msgid "Pause Media" +msgstr "暫停媒體" + +#: data/ui/device-preferences.ui:1323 +msgid "Ongoing Calls" +msgstr "通話中" + +#: data/ui/device-preferences.ui:1493 +msgid "Mute Microphone" +msgstr "靜音麥克風" + +#: data/ui/device-preferences.ui:1547 data/ui/device-preferences.ui:2348 +#: src/service/plugins/telephony.js:13 +msgid "Telephony" +msgstr "電話" + +#: data/ui/device-preferences.ui:1582 +msgid "Action Shortcuts" +msgstr "應用快捷鍵" + +#: data/ui/device-preferences.ui:1597 +msgid "Reset All…" +msgstr "全部重設" + +#: data/ui/device-preferences.ui:1646 +msgid "Shortcuts" +msgstr "快捷鍵" + +#: data/ui/device-preferences.ui:1677 +msgid "Plugins" +msgstr "外掛" + +#: data/ui/device-preferences.ui:1723 +msgid "Experimental" +msgstr "實驗性質" + +#: data/ui/device-preferences.ui:1771 +msgid "Legacy SMS Support" +msgstr "舊版簡訊支援" + +#: data/ui/device-preferences.ui:1824 data/ui/device-preferences.ui:2440 +msgid "Advanced" +msgstr "進階" + +#: data/ui/device-preferences.ui:1855 +msgid "Device Battery" +msgstr "裝置電池" + +#: data/ui/device-preferences.ui:1906 +msgid "Low Battery Notification" +msgstr "低電量通知" + +#: data/ui/device-preferences.ui:1967 +msgid "Fully Charged Notification" +msgstr "電池充飽通知" + +#: data/ui/device-preferences.ui:2014 +msgid "System Battery" +msgstr "系統電池" + +#: data/ui/device-preferences.ui:2065 +msgid "Share Statistics" +msgstr "分享狀態" + +#: data/ui/device-preferences.ui:2114 data/ui/device-preferences.ui:2210 +#: src/service/plugins/battery.js:11 +msgid "Battery" +msgstr "電池" + +#: data/ui/device-preferences.ui:2394 +msgid "Keyboard Shortcuts" +msgstr "鍵盤快捷鍵" + +#: data/ui/device-preferences.ui:2529 +msgid "Device is unpaired" +msgstr "裝置已取消配對" + +#: data/ui/device-preferences.ui:2544 +msgid "You may configure this device before pairing" +msgstr "您可以在配對此裝置前進行設置" + +#. TRANSLATORS: Send clipboard content to device +#: data/ui/device-preferences.ui:2585 +msgid "To Device" +msgstr "到裝置" + +#. TRANSLATORS: Receive clipboard content from the device +#: data/ui/device-preferences.ui:2591 +msgid "From Device" +msgstr "從裝置" + +#. TRANSLATORS: Don't change the system volume +#: data/ui/device-preferences.ui:2603 data/ui/device-preferences.ui:2629 +msgid "Nothing" +msgstr "無動作" + +#. TRANSLATORS: Lower the system volume +#: data/ui/device-preferences.ui:2610 data/ui/device-preferences.ui:2636 +msgid "Lower" +msgstr "降低音量" + +#. TRANSLATORS: Mute the system volume +#. TRANSLATORS: Silence the phone ringer +#: data/ui/device-preferences.ui:2617 data/ui/device-preferences.ui:2643 +#: src/service/plugins/telephony.js:191 +msgid "Mute" +msgstr "靜音" + +#: data/ui/messaging-window.ui:14 src/service/plugins/sms.js:26 +#: src/service/ui/messaging.js:976 +msgid "Messaging" +msgstr "發送簡訊" + +#: data/ui/messaging-window.ui:23 src/service/ui/messaging.js:1193 +msgid "New Conversation" +msgstr "新的對話" + +#: data/ui/messaging-window.ui:108 +msgid "No Conversations" +msgstr "沒有對話" + +#: data/ui/messaging-window.ui:168 +msgid "No conversation selected" +msgstr "尚無對話" + +#: data/ui/messaging-window.ui:184 +msgid "Select or start a conversation" +msgstr "選擇或開始聊天" + +#: data/ui/messaging-window.ui:251 data/ui/notification-reply-dialog.ui:52 +#: data/ui/telephony.ui:53 +msgid "Device is disconnected" +msgstr "設備已斷開" + +#: data/ui/notification-reply-dialog.ui:20 data/ui/telephony.ui:21 +#: src/service/plugins/share.js:453 +msgid "Send" +msgstr "傳送" + +#: data/ui/preferences-window.ui:18 +msgid "Device Name" +msgstr "裝置名稱" + +#: data/ui/preferences-window.ui:49 +msgid "_Rename" +msgstr "重新命名(_R)" + +#: data/ui/preferences-window.ui:86 data/ui/preferences-window.ui:100 +msgid "Refresh" +msgstr "重新整理" + +#: data/ui/preferences-window.ui:111 data/ui/preferences-window.ui:128 +#: src/extension.js:151 +msgid "Mobile Settings" +msgstr "手機設置" + +#: data/ui/preferences-window.ui:182 data/ui/preferences-window.ui:197 +msgid "Edit Device Name" +msgstr "修改裝置名稱" + +#: data/ui/preferences-window.ui:257 +msgid "Devices" +msgstr "裝置" + +#: data/ui/preferences-window.ui:307 src/preferences/service.js:673 +msgid "Searching for devices…" +msgstr "正在搜尋裝置…" + +#: data/ui/preferences-window.ui:332 +msgid "Browser Add-Ons" +msgstr "瀏覽器外掛" + +#: data/ui/preferences-window.ui:612 +msgid "Enable" +msgstr "啟用" + +#: data/ui/preferences-window.ui:644 +msgid "This device is invisible to unpaired devices" +msgstr "未配對裝置看不到此裝置" + +#: data/ui/preferences-window.ui:656 src/service/daemon.js:598 +msgid "Discovery Disabled" +msgstr "禁止被探索" + +#: data/ui/preferences-window.ui:715 +msgid "Display Mode" +msgstr "顯示模式" + +#. TRANSLATORS: Show device indicators in the top bar +#: data/ui/preferences-window.ui:718 +msgid "Panel" +msgstr "頂端列" + +#. TRANSLATORS: Show devices in the user menu like Bluetooth +#: data/ui/preferences-window.ui:724 +msgid "User Menu" +msgstr "使用者選單" + +#. TRANSLATORS: Generate a support log +#: data/ui/preferences-window.ui:732 src/preferences/service.js:429 +msgid "Generate Support Log" +msgstr "產生支援 Log" + +#: data/ui/preferences-window.ui:740 +msgid "About Zorin Connect" +msgstr "關於 Zorin Connect" + +#. TRANSLATORS: Share URL by SMS +#: data/ui/telephony.ui:9 src/service/daemon.js:699 src/service/daemon.js:825 +#: src/service/plugins/sms.js:58 webextension/gettext.js:39 +msgid "Send SMS" +msgstr "發送簡訊" + +#. Service Menu +#: src/extension.js:118 src/extension.js:249 +msgid "Mobile Devices" +msgstr "行動裝置" + +#. TRANSLATORS: A menu option to activate the extension +#: src/extension.js:145 src/extension.js:383 +msgid "Turn On" +msgstr "開啟" + +#: src/extension.js:244 +#, javascript-format +msgid "%d Connected" +msgid_plural "%d Connected" +msgstr[0] "%d 已連線" + +#. TRANSLATORS: A menu option to deactivate the extension +#: src/extension.js:380 +msgid "Turn Off" +msgstr "關閉" + +#. TRANSLATORS: Top-level context menu item for Zorin Connect +#: src/nautilus-zorin-connect.py:164 webextension/gettext.js:31 +msgid "Send To Mobile Device" +msgstr "傳送到手機" + +#: src/preferences/device.js:658 +msgid "Open" +msgstr "打開" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "On" +msgstr "開啟" + +#: src/preferences/device.js:713 src/preferences/device.js:726 +msgid "Off" +msgstr "關閉" + +#: src/preferences/device.js:831 src/preferences/device.js:859 +msgid "Disabled" +msgstr "停用" + +#. TRANSLATORS: Title of keyboard shortcut dialog +#: src/preferences/keybindings.js:75 +msgid "Set Shortcut" +msgstr "設置快捷鍵" + +#. TRANSLATORS: Button to confirm the new shortcut +#: src/preferences/keybindings.js:89 +msgid "Set" +msgstr "設定" + +#. TRANSLATORS: Summary of a keyboard shortcut function +#. Example: Enter a new shortcut to change Messaging +#: src/preferences/keybindings.js:96 +#, javascript-format +msgid "Enter a new shortcut to change %s" +msgstr "輸入新的快捷鍵取代 %s" + +#. TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut +#: src/preferences/keybindings.js:125 +msgid "Press Esc to cancel or Backspace to reset the keyboard shortcut." +msgstr "按下 Esc 取消快捷鍵,或按下倒退鍵(Backspace)重設快捷鍵。" + +#. TRANSLATORS: When a keyboard shortcut is unavailable +#. Example: [Ctrl]+[S] is already being used +#: src/preferences/keybindings.js:224 +#, javascript-format +msgid "%s is already being used" +msgstr "「%s」已經被使用" + +#: src/preferences/service.js:388 +msgid "A complete KDE Connect implementation for GNOME" +msgstr "一個為 GNOME 完整實做的 KDE Connect" + +#. TRANSLATORS: eg. 'Translator Name ' +#: src/preferences/service.js:397 +msgid "translator-credits" +msgstr "翻譯組員" + +#: src/preferences/service.js:430 +msgid "Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log." +msgstr "除錯訊息已被紀錄。請執行任何可能造成問題的動作,然後查看日誌。" + +#: src/preferences/service.js:433 +msgid "Review Log" +msgstr "查看日誌" + +#: src/preferences/service.js:502 +msgid "Laptop" +msgstr "筆電" + +#: src/preferences/service.js:504 +msgid "Smartphone" +msgstr "智慧型手機" + +#: src/preferences/service.js:506 +msgid "Tablet" +msgstr "平板" + +#: src/preferences/service.js:508 +msgid "Television" +msgstr "電視" + +#: src/preferences/service.js:529 +msgid "Unpaired" +msgstr "未配對" + +#: src/preferences/service.js:533 +msgid "Disconnected" +msgstr "已中斷連線" + +#: src/preferences/service.js:537 +msgid "Connected" +msgstr "已連接" + +#: src/preferences/service.js:675 +msgid "Waiting for service…" +msgstr "等待伺服器…" + +#: src/service/daemon.js:337 +msgid "Report" +msgstr "回報" + +#: src/service/daemon.js:580 +msgid "Authentication Failure" +msgstr "認證失敗" + +#: src/service/daemon.js:589 +msgid "Network Error" +msgstr "網路錯誤" + +#: src/service/daemon.js:590 +msgid "Click for help troubleshooting" +msgstr "點擊以幫助除錯" + +#: src/service/daemon.js:599 +msgid "Discovery has been disabled due to the number of devices on this network." +msgstr "因為此網域內的裝置數量,探索已停用" + +#: src/service/daemon.js:608 +msgid "Click for more information" +msgstr "按一下以瞭解詳情" + +#: src/service/daemon.js:705 +msgid "Dial Number" +msgstr "撥打電話" + +#: src/service/daemon.js:711 src/service/daemon.js:921 +#: src/service/plugins/share.js:27 +msgid "Share File" +msgstr "分享檔案" + +#: src/service/daemon.js:774 +msgid "List available devices" +msgstr "列出可用裝置" + +#: src/service/daemon.js:783 +msgid "List all devices" +msgstr "列出所有裝置" + +#: src/service/daemon.js:792 +msgid "Target Device" +msgstr "目標裝置" + +#: src/service/daemon.js:834 +msgid "Message Body" +msgstr "訊息內文" + +#: src/service/daemon.js:846 src/service/plugins/notification.js:51 +msgid "Send Notification" +msgstr "發送通知" + +#: src/service/daemon.js:855 +msgid "Notification App Name" +msgstr "程式名稱通知" + +#: src/service/daemon.js:864 +msgid "Notification Body" +msgstr "通知欄本身" + +#: src/service/daemon.js:873 +msgid "Notification Icon" +msgstr "通知圖示" + +#: src/service/daemon.js:882 +msgid "Notification ID" +msgstr "ID 通知" + +#: src/service/daemon.js:891 src/service/plugins/photo.js:11 +#: src/service/plugins/photo.js:17 +msgid "Photo" +msgstr "拍攝" + +#: src/service/daemon.js:900 src/service/plugins/ping.js:11 +#: src/service/plugins/ping.js:17 src/service/plugins/ping.js:44 +msgid "Ping" +msgstr "Ping" + +#: src/service/daemon.js:909 src/service/plugins/battery.js:155 +#: src/service/plugins/findmyphone.js:19 +msgid "Ring" +msgstr "響音" + +#: src/service/daemon.js:930 src/service/plugins/share.js:43 +#: src/service/ui/messaging.js:1176 src/service/ui/messaging.js:1184 +msgid "Share Link" +msgstr "共享鏈結" + +#: src/service/daemon.js:942 +msgid "Show release version" +msgstr "顯示版本" + +#: src/service/device.js:174 +msgid "Not available" +msgstr "無法使用" + +#. TRANSLATORS: Bluetooth address for remote device +#: src/service/device.js:179 +#, javascript-format +msgid "Bluetooth device at %s" +msgstr "在「%s」的藍牙裝置" + +#. TRANSLATORS: Label for TLS Certificate fingerprint +#. +#. Example: +#. +#. Google Pixel Fingerprint: +#. 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 +#: src/service/device.js:199 src/service/device.js:201 +#, javascript-format +msgid "%s Fingerprint:" +msgstr "「%s」數位指紋:" + +#. TRANSLATORS: eg. Pair Request from Google Pixel +#: src/service/device.js:748 +#, javascript-format +msgid "Pair Request from %s" +msgstr "「%s」的配對請求" + +#: src/service/device.js:755 +msgid "Reject" +msgstr "拒絕" + +#: src/service/device.js:760 +msgid "Accept" +msgstr "接受" + +#. TRANSLATORS: eg. Google Pixel: Battery is low +#: src/service/plugins/battery.js:181 +#, javascript-format +msgid "%s: Battery is low" +msgstr "%s:電量過低" + +#. TRANSLATORS: eg. 15% remaining +#: src/service/plugins/battery.js:183 +#, javascript-format +msgid "%d%% remaining" +msgstr "剩下 %d%%" + +#. TRANSLATORS: eg. Google Pixel: Battery is full +#: src/service/plugins/battery.js:199 +#, javascript-format +msgid "%s: Battery is full" +msgstr "%s:電池已充飽" + +#. TRANSLATORS: when the battery is fully charged +#. TRANSLATORS: When the battery level is 100% +#: src/service/plugins/battery.js:201 src/shell/device.js:115 +msgid "Fully Charged" +msgstr "充電完成" + +#: src/service/plugins/clipboard.js:11 +msgid "Clipboard" +msgstr "剪貼簿" + +#: src/service/plugins/clipboard.js:23 +msgid "Clipboard Push" +msgstr "推送剪貼簿" + +#: src/service/plugins/clipboard.js:31 +msgid "Clipboard Pull" +msgstr "接收剪貼簿" + +#. Ensure we have a sender +#. TRANSLATORS: No name or phone number +#. HACK: fix missing contact names +#. Contact Name +#: src/service/plugins/contacts.js:230 src/service/plugins/contacts.js:338 +#: src/service/plugins/telephony.js:170 src/service/plugins/telephony.js:221 +#: src/service/plugins/telephony.js:267 src/service/ui/contacts.js:571 +#: src/service/ui/messaging.js:247 +msgid "Unknown Contact" +msgstr "未知的聯絡人" + +#: src/service/plugins/findmyphone.js:13 +msgid "Find My Phone" +msgstr "找尋我的手機" + +#: src/service/plugins/mousepad.js:14 +msgid "Mousepad" +msgstr "觸控板" + +#: src/service/plugins/mousepad.js:28 src/service/plugins/mousepad.js:396 +msgid "Keyboard" +msgstr "鍵盤" + +#: src/service/plugins/mousepad.js:413 +msgid "Keyboard not ready" +msgstr "鍵盤尚未準備好" + +#: src/service/plugins/mpris.js:12 +msgid "MPRIS" +msgstr "MPRIS" + +#: src/service/plugins/notification.js:27 +msgid "Cancel Notification" +msgstr "取消通知" + +#: src/service/plugins/notification.js:35 +msgid "Close Notification" +msgstr "關閉通知" + +#: src/service/plugins/notification.js:43 +msgid "Reply Notification" +msgstr "回覆通知" + +#: src/service/plugins/notification.js:59 +msgid "Activate Notification" +msgstr "啟用通知" + +#. TRANSLATORS: An optional message accompanying a ping, rarely if ever used +#. eg. Ping: A message sent with ping +#: src/service/plugins/ping.js:51 +#, javascript-format +msgid "Ping: %s" +msgstr "Ping: %s" + +#: src/service/plugins/presenter.js:9 +msgid "Presentation" +msgstr "" + +#: src/service/plugins/runcommand.js:12 +msgid "Run Commands" +msgstr "執行指令" + +#: src/service/plugins/sftp.js:12 +msgid "SFTP" +msgstr "SFTP" + +#: src/service/plugins/sftp.js:18 +msgid "Mount" +msgstr "掛載" + +#: src/service/plugins/sftp.js:26 +msgid "Unmount" +msgstr "卸載" + +#: src/service/plugins/sftp.js:134 +msgid "All files" +msgstr "所有檔案" + +#: src/service/plugins/sftp.js:135 +msgid "Camera pictures" +msgstr "相機照片" + +#: src/service/plugins/share.js:13 src/service/plugins/share.js:19 +msgid "Share" +msgstr "共享" + +#: src/service/plugins/share.js:35 +msgid "Share Text" +msgstr "分享文字" + +#: src/service/plugins/share.js:116 src/service/plugins/share.js:201 +#: src/service/plugins/share.js:333 +msgid "Transfer Failed" +msgstr "傳輸失敗" + +#. TRANSLATORS: eg. Google Pixel is not allowed to upload files +#: src/service/plugins/share.js:118 +#, javascript-format +msgid "%s is not allowed to upload files" +msgstr "不允許「%s」上傳檔案" + +#: src/service/plugins/share.js:154 src/service/plugins/share.js:302 +msgid "Transferring File" +msgstr "檔案傳送中" + +#. TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel +#: src/service/plugins/share.js:156 +#, javascript-format +msgid "Receiving “%s” from %s" +msgstr "正在接收「%s」,來自於「%s」" + +#: src/service/plugins/share.js:181 src/service/plugins/share.js:325 +msgid "Transfer Successful" +msgstr "傳輸成功" + +#. TRANSLATORS: eg. Received 'book.pdf' from Google Pixel +#: src/service/plugins/share.js:183 +#, javascript-format +msgid "Received “%s” from %s" +msgstr "已接收「%s」,來自於「%s」" + +#: src/service/plugins/share.js:189 +msgid "Open Folder" +msgstr "打開資料夾" + +#: src/service/plugins/share.js:194 +msgid "Open File" +msgstr "打開檔案" + +#. TRANSLATORS: eg. Failed to receive 'book.pdf' from Google Pixel +#: src/service/plugins/share.js:203 +#, javascript-format +msgid "Failed to receive “%s” from %s" +msgstr "接收「%s」失敗,來自於「%s」" + +#: src/service/plugins/share.js:232 +#, javascript-format +msgid "Text Shared By %s" +msgstr "「%s」分享的文字" + +#. TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel +#: src/service/plugins/share.js:304 +#, javascript-format +msgid "Sending “%s” to %s" +msgstr "正在將「%s」傳送到「%s」" + +#. TRANSLATORS: eg. Sent "book.pdf" to Google Pixel +#: src/service/plugins/share.js:327 +#, javascript-format +msgid "Sent “%s” to %s" +msgstr "「%s」已傳送到「%s」" + +#. TRANSLATORS: eg. Failed to send "book.pdf" to Google Pixel +#: src/service/plugins/share.js:335 +#, javascript-format +msgid "Failed to send “%s” to %s" +msgstr "傳送「%s」到「%s」失敗" + +#. TRANSLATORS: eg. Send files to Google Pixel +#: src/service/plugins/share.js:404 +#, javascript-format +msgid "Send files to %s" +msgstr "將檔案傳送到「%s」" + +#. TRANSLATORS: Mark the file to be opened once completed +#: src/service/plugins/share.js:408 +msgid "Open when done" +msgstr "當完成時開啟" + +#. TRANSLATORS: eg. Send a link to Google Pixel +#: src/service/plugins/share.js:447 +#, javascript-format +msgid "Send a link to %s" +msgstr "發送一個鏈結到「%s」" + +#: src/service/plugins/sms.js:13 +msgid "SMS" +msgstr "簡訊" + +#: src/service/plugins/sms.js:34 +msgid "New SMS (URI)" +msgstr "新增簡訊(URI)" + +#: src/service/plugins/sms.js:42 src/service/plugins/telephony.js:22 +msgid "Reply SMS" +msgstr "回覆簡訊" + +#: src/service/plugins/sms.js:66 +msgid "Share SMS" +msgstr "分享簡訊" + +#: src/service/plugins/systemvolume.js:11 +msgid "System Volume" +msgstr "系統音量" + +#: src/service/plugins/telephony.js:30 +msgid "Mute Call" +msgstr "通話靜音" + +#. TRANSLATORS: The phone is ringing +#: src/service/plugins/telephony.js:187 +msgid "Incoming call" +msgstr "來電" + +#. TRANSLATORS: A phone call is active +#: src/service/plugins/telephony.js:202 +msgid "Ongoing call" +msgstr "通話中" + +#. TRANSLATORS: All other phone number types +#: src/service/ui/contacts.js:126 src/service/ui/contacts.js:147 +#, javascript-format +msgid "%s・Other" +msgstr "%s・其他" + +#. TRANSLATORS: A fax number +#: src/service/ui/contacts.js:131 +#, javascript-format +msgid "%s・Fax" +msgstr "%s・傳真" + +#. TRANSLATORS: A work phone number +#: src/service/ui/contacts.js:135 +#, javascript-format +msgid "%s・Work" +msgstr "%s・工作" + +#. TRANSLATORS: A mobile or cellular phone number +#: src/service/ui/contacts.js:139 +#, javascript-format +msgid "%s・Mobile" +msgstr "%s・手機" + +#. TRANSLATORS: A home phone number +#: src/service/ui/contacts.js:143 +#, javascript-format +msgid "%s・Home" +msgstr "%s・家裡" + +#. TRANSLATORS: A phone number (eg. "Send to 555-5555") +#: src/service/ui/contacts.js:433 src/service/ui/contacts.js:447 +#, javascript-format +msgid "Send to %s" +msgstr "傳送到「%s」" + +#. TRANSLATORS: Less than a minute ago +#: src/service/ui/messaging.js:29 src/service/ui/messaging.js:66 +msgid "Just now" +msgstr "就在剛才" + +#: src/service/ui/messaging.js:35 src/service/ui/messaging.js:71 +#: src/shell/donotdisturb.js:142 +#, javascript-format +msgid "%d minute" +msgid_plural "%d minutes" +msgstr[0] "%d 分鐘" + +#. TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) +#: src/service/ui/messaging.js:43 +#, javascript-format +msgid "Yesterday・%s" +msgstr "昨天・%s" + +#: src/service/ui/messaging.js:255 +msgid "Group Message" +msgstr "群組簡訊" + +#. TRANSLATORS: An outgoing message body in a conversation summary +#: src/service/ui/messaging.js:265 +#, javascript-format +msgid "You: %s" +msgstr "你:%s" + +#: src/service/ui/messaging.js:869 +#, javascript-format +msgid "And %d other contact" +msgid_plural "And %d others" +msgstr[0] "和 %d 位其他聯絡人" + +#: src/service/ui/service.js:31 +msgid "Select a Device" +msgstr "選擇裝置" + +#: src/service/ui/service.js:35 +msgid "Select" +msgstr "選擇" + +#. TRANSLATORS: No devices are known or available +#: src/service/ui/service.js:77 webextension/gettext.js:35 +msgid "No Device Found" +msgstr "找不到裝置" + +#. TRANSLATORS: When no time estimate for the battery is available +#. EXAMPLE: 42% (Estimating…) +#: src/shell/device.js:119 +#, javascript-format +msgid "%d%% (Estimating…)" +msgstr "%d%% (計算中…)" + +#. TRANSLATORS: Estimated time until battery is charged +#. EXAMPLE: 42% (1:15 Until Full) +#: src/shell/device.js:129 +#, javascript-format +msgid "%d%% (%d∶%02d Until Full)" +msgstr "%d%%(距離充滿還需 %d∶%02d )" + +#. TRANSLATORS: Estimated time until battery is empty +#. EXAMPLE: 42% (12:15 Remaining) +#: src/shell/device.js:137 +#, javascript-format +msgid "%d%% (%d∶%02d Remaining)" +msgstr "%d%% (%d∶%02d 剩餘)" + +#: src/shell/donotdisturb.js:135 +#, javascript-format +msgid "%d hour" +msgid_plural "%d hours" +msgstr[0] "%d 小時" + +#. TRANSLATORS: Time until change with time duration +#. EXAMPLE: Until 10:00 (2 hours) +#: src/shell/donotdisturb.js:150 +#, javascript-format +msgid "Until %s (%s)" +msgstr "直到 %s(%s)" + +#: src/shell/donotdisturb.js:243 src/shell/donotdisturb.js:342 +msgid "Do Not Disturb" +msgstr "勿擾模式" + +#: src/shell/donotdisturb.js:249 +msgid "Silence Notifications from Mobile Devices" +msgstr "靜音行動裝置通知" + +#: src/shell/donotdisturb.js:261 +msgid "Until you turn off Do Not Disturb" +msgstr "直到您關閉勿擾模式" + +#: src/shell/donotdisturb.js:302 +msgid "Done" +msgstr "完成" + +#: src/shell/notification.js:43 +msgid "Reply" +msgstr "回覆" + +#. TRANSLATORS: Extension name +#: webextension/gettext.js:27 +msgid "Zorin Connect" +msgstr "Zorin Connect" + +#. TRANSLATORS: Chrome/Firefox WebExtension description +#: webextension/gettext.js:29 +msgid "Share links with Zorin Connect, direct to the browser or by SMS." +msgstr "直接用瀏覽器或經由簡訊和 Zorin Connect 共享鏈結" + +#. TRANSLATORS: WebExtension can't connect to Zorin Connect +#: webextension/gettext.js:33 +msgid "Service Unavailable" +msgstr "服務無法使用" + +#. TRANSLATORS: Open URL with the device's browser +#: webextension/gettext.js:37 +msgid "Open in Browser" +msgstr "以瀏覽器開啟" + +msgid "Mobile Application" +msgstr "移动应用" diff -Nru gnome-shell-extension-zorin-connect-24.1/src/extension.js gnome-shell-extension-zorin-connect-28.0.2/src/extension.js --- gnome-shell-extension-zorin-connect-24.1/src/extension.js 2019-03-17 12:03:04.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/extension.js 2019-11-30 00:41:12.000000000 +0000 @@ -18,7 +18,7 @@ imports.searchPath.unshift(zorin_connect.extdatadir); imports._zorin_connect; -// Local Imports +// eslint-disable-next-line no-redeclare const _ = zorin_connect._; const Device = imports.shell.device; const DoNotDisturb = imports.shell.donotdisturb; @@ -67,6 +67,43 @@ this.keybindingManager = new Keybindings.Manager(); + // GSettings + this.settings = new Gio.Settings({ + settings_schema: zorin_connect.gschema.lookup( + 'org.gnome.Shell.Extensions.ZorinConnect', + null + ), + path: '/org/gnome/shell/extensions/zorin-connect/' + }); + + this._enabledId = this.settings.connect( + 'changed::enabled', + this._onEnabledChanged.bind(this) + ); + + this._panelModeId = this.settings.connect( + 'changed::show-indicators', + this._sync.bind(this) + ); + + // Service Proxy + this.service = new Remote.Service(); + + this._deviceAddedId = this.service.connect( + 'device-added', + this._onDeviceAdded.bind(this) + ); + + this._deviceRemovedId = this.service.connect( + 'device-removed', + this._onDeviceRemoved.bind(this) + ); + + this._serviceChangedId = this.service.connect( + 'notify::active', + this._onServiceChanged.bind(this) + ); + // Service Indicator this._indicator = this._addIndicator(); this._indicator.gicon = zorin_connect.get_gicon( @@ -88,7 +125,7 @@ // Service Menu -> Devices Section this.deviceSection = new PopupMenu.PopupMenuSection(); this.deviceSection.actor.add_style_class_name('zorin-connect-device-section'); - zorin_connect.settings.bind( + this.settings.bind( 'show-indicators', this.deviceSection.actor, 'visible', @@ -100,67 +137,88 @@ this._item.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); // Service Menu -> "Do Not Disturb" - this._item.menu.addMenuItem(new DoNotDisturb.MenuItem()); - - // Service Menu -> "Mobile Settings" - this._item.menu.addAction(_('Mobile Settings'), this._settings); + let dndItem = new DoNotDisturb.createMenuItem(this.settings); + this._item.menu.addMenuItem(dndItem); - // Watch for UI prefs - this._gsettingsId = zorin_connect.settings.connect( - 'changed::show-indicators', - this._sync.bind(this) + // Service Menu -> "Turn On/Off" + this._enableItem = this._item.menu.addAction( + _('Turn On'), + this._enable.bind(this) ); - // Async setup - this._init_async(); + // Service Menu -> "Mobile Settings" + this._item.menu.addAction(_('Mobile Settings'), this._preferences); + + // Prime the service + this._initService(); } - async _init_async() { + async _initService() { try { - // Device Manager - this.manager = new Remote.Service(); - - // Watch for new and removed - this._deviceAddedId = this.manager.connect( - 'device-added', - this._onDeviceAdded.bind(this) - ); - - this._deviceRemovedId = this.manager.connect( - 'device-removed', - this._onDeviceRemoved.bind(this) - ); - - this._availableChangedId = this.manager.connect( - 'available-changed', - this._sync.bind(this) - ); - - await this.manager._init_async(); + if (this.settings.get_boolean('enabled')) { + await this.service.start(); + } else { + await this.service.reload(); + } } catch (e) { - Gio.DBusError.strip_remote_error(e); + logError(e, 'Zorin Connect'); + } + } - if (!e.code || e.code !== Gio.IOErrorEnum.CANCELLED) { - logError(e, 'Zorin Connect'); + _enable() { + try { + // If the service state matches the enabled setting, we should + // toggle the service by toggling the setting + let enabled = this.settings.get_boolean('enabled'); + + if (this.service.active === enabled) { + this.settings.set_boolean('enabled', !enabled); + + // Otherwise, we should change the service to match the setting + } else if (this.service.active) { + this.service.stop(); + } else { + this.service.start(); } + } catch (e) { + logError(e, 'Zorin Connect'); } } + _preferences() { + let proc = new Gio.Subprocess({ + argv: [zorin_connect.extdatadir + '/zorin-connect-preferences'] + }); + proc.init(null); + proc.wait_async(null, null); + } + _sync() { - let available = this.manager.available; - let panelMode = zorin_connect.settings.get_boolean('show-indicators'); + let available = this.service.devices.filter(device => { + return (device.connected && device.paired); + }); + let panelMode = this.settings.get_boolean('show-indicators'); // Hide status indicator if in Panel mode or no devices are available this._indicator.visible = (!panelMode && available.length); // Show device indicators in Panel mode if available - for (let device of this.manager.devices) { - let indicator = Main.panel.statusArea[device.g_object_path].actor; - indicator.visible = panelMode && available.includes(device); + for (let device of this.service.devices) { + let isAvailable = available.includes(device); + let indicator = Main.panel.statusArea[device.g_object_path]; + + // TODO: remove after 3.34+ + if (zorin_connect.shell_version >= 34) { + indicator.visible = panelMode && isAvailable; + } else { + indicator.actor.visible = panelMode && isAvailable; + } + + indicator.update_icon(device.icon_name); let menu = this._menus[device.g_object_path]; - menu.actor.visible = !panelMode && available.includes(device); - menu._title.actor.visible = menu.actor.visible; + menu.actor.visible = !panelMode && isAvailable; + menu._title.actor.visible = !panelMode && isAvailable; } // One connected device in User Menu mode @@ -169,7 +227,7 @@ // Hide the menu title and move it to the submenu item this._menus[device.g_object_path]._title.actor.visible = false; - this._item.label.text = device.Name; + this._item.label.text = device.name; // Destroy any other device's battery if (this._item._battery && this._item._battery.device !== device) { @@ -208,28 +266,20 @@ } } - _settings() { - Gio.DBus.session.call( - 'org.gnome.Shell.Extensions.ZorinConnect', - '/org/gnome/Shell/Extensions/ZorinConnect', - 'org.freedesktop.Application', - 'ActivateAction', - new GLib.Variant('(sava{sv})', ['settings', [], {}]), - null, - Gio.DBusCallFlags.NONE, - -1, - null, - (connection, res) => { - try { - connection.call_finish(res); - } catch (e) { - logError(e, 'Zorin Connect'); - } + _onDeviceChanged(device, changed, invalidated) { + try { + changed = changed.deep_unpack(); + + if (changed.hasOwnProperty('Connected') || + changed.hasOwnProperty('Paired')) { + this._sync(); } - ); + } catch (e) { + logError(e, 'Zorin Connect' ); + } } - _onDeviceAdded(manager, device) { + _onDeviceAdded(service, device) { try { // Device Indicator let indicator = new Device.Indicator({device: device}); @@ -244,26 +294,36 @@ this.deviceSection.addMenuItem(menu); // Keyboard Shortcuts - device._keybindingsChangedId = device.settings.connect( + device.__keybindingsChangedId = device.settings.connect( 'changed::keybindings', - this._onKeybindingsChanged.bind(this, device) + this._onDeviceKeybindingsChanged.bind(this, device) ); - this._onKeybindingsChanged(device); + this._onDeviceKeybindingsChanged(device); - // Try activating the device - device.action_group.activate_action('activate', null); + // Watch the for status changes + device.__deviceChangedId = device.connect( + 'g-properties-changed', + this._onDeviceChanged.bind(this) + ); this._sync(); } catch (e) { - logError(e, device.g_object_path); + logError(e, 'Zorin Connect'); } } - _onDeviceRemoved(manager, device) { + _onDeviceRemoved(service, device, sync = true) { try { + // Stop watching for status changes + if (device.__deviceChangedId) { + device.disconnect(device.__deviceChangedId); + } + // Release keybindings - device.settings.disconnect(device._keybindingsChangedId); - device._keybindings.map(id => this.keybindingManager.remove(id)); + if (device.__keybindingsChangedId) { + device.settings.disconnect(device.__keybindingsChangedId); + device._keybindings.map(id => this.keybindingManager.remove(id)); + } // Destroy the indicator Main.panel.statusArea[device.g_object_path].destroy(); @@ -272,13 +332,15 @@ this._menus[device.g_object_path].destroy(); delete this._menus[device.g_object_path]; - this._sync(); + if (sync) { + this._sync(); + } } catch (e) { - logError(e, device.g_object_path); + logError(e, 'Zorin Connect'); } } - async _onKeybindingsChanged(device) { + _onDeviceKeybindingsChanged(device) { try { // Reset any existing keybindings if (device.hasOwnProperty('_keybindings')) { @@ -304,37 +366,63 @@ } } } catch (e) { - logError(e, device.g_object_path); + logError(e, 'Zorin Connect'); } } - // TODO: need hardcoded keybinding for this - _openDeviceMenu(indicator) { - if (zorin_connect.settings.get_boolean('show-indicators')) { - indicator.menu.toggle(); - } else { - Main.panel._toggleMenu(AggregateMenu); - this._item.menu.toggle(); - this._item.actor.grab_key_focus(); + async _onEnabledChanged(settings, key) { + try { + if (this.settings.get_boolean('enabled')) { + await this.service.start(); + } else { + await this.service.stop(); + } + } catch (e) { + logError(e, 'Zorin Connect'); + } + } + + async _onServiceChanged(service, pspec) { + try { + if (this.service.active) { + // TRANSLATORS: A menu option to deactivate the extension + this._enableItem.label.text = _('Turn Off'); + } else { + // TRANSLATORS: A menu option to activate the extension + this._enableItem.label.text = _('Turn On'); + + // If it's enabled, we should try to restart now + if (this.settings.get_boolean('enabled')) { + await this.service.start(); + } + } + } catch (e) { + logError(e, 'Zorin Connect'); } } destroy() { - // Unhook from any ObjectManager events - if (this.manager) { - this.manager.destroy(); - this.manager.disconnect(this._deviceAddedId); - this.manager.disconnect(this._deviceRemovedId); - this.manager.disconnect(this._availableChangedId); + // Unhook from Remote.Service + if (this.service) { + this.service.disconnect(this._serviceChangedId); + this.service.disconnect(this._deviceAddedId); + this.service.disconnect(this._deviceRemovedId); + + for (let device of this.service.devices) { + this._onDeviceRemoved(this.service, device, false); + } + + this.service.destroy(); } // Disconnect any keybindings this.keybindingManager.destroy(); // Disconnect from any GSettings changes - zorin_connect.settings.disconnect(this._gsettingsId); + this.settings.disconnect(this._panelModeId); + this.settings.run_dispose(); - // Destroy the UI + // Destroy the PanelMenu.SystemIndicator actors delete AggregateMenu._zorin_connect; this.indicators.destroy(); this._item.destroy(); @@ -348,7 +436,7 @@ function init() { // This is only relevant on gnome-shell <= 3.30 - if (imports.system.version < 15500) { + if (zorin_connect.shell_version <= 30) { Gtk.IconTheme.get_default().add_resource_path('/org/gnome/Shell/Extensions/ZorinConnect/icons'); } diff -Nru gnome-shell-extension-zorin-connect-24.1/src/nautilus-zorin-connect.py gnome-shell-extension-zorin-connect-28.0.2/src/nautilus-zorin-connect.py --- gnome-shell-extension-zorin-connect-24.1/src/nautilus-zorin-connect.py 2019-03-04 01:45:06.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/nautilus-zorin-connect.py 2019-11-30 00:58:18.000000000 +0000 @@ -12,11 +12,26 @@ import os.path import gi -gi.require_version('Nautilus', '3.0') gi.require_version('Gio', '2.0') gi.require_version('GLib', '2.0') gi.require_version('GObject', '2.0') -from gi.repository import Nautilus, Gio, GLib, GObject +from gi.repository import Gio, GLib, GObject + +import sys + +# Host application detection +# +# Nemo seems to reliably identify itself as 'nemo' in argv[0], so we +# can test for that. Nautilus detection is less reliable, so don't try. +# See https://github.com/linuxmint/nemo-extensions/issues/330 +if "nemo" in sys.argv[0].lower(): + # Host runtime is nemo-python + gi.require_version('Nemo', '3.0') + from gi.repository import Nemo as FileManager +else: + # Otherwise, just assume it's nautilus-python + gi.require_version('Nautilus', '3.0') + from gi.repository import Nautilus as FileManager _ = gettext.gettext @@ -34,7 +49,7 @@ -class ZorinConnectShareExtension(GObject.Object, Nautilus.MenuProvider): +class ZorinConnectShareExtension(GObject.Object, FileManager.MenuProvider): """A context menu for sending files via Zorin Connect.""" def __init__(self): @@ -144,18 +159,18 @@ return () # Context Menu Item - menu = Nautilus.MenuItem( + menu = FileManager.MenuItem( name='ZorinConnectShareExtension::Devices', label=_('Send To Mobile Device') ) # Context Submenu - submenu = Nautilus.Menu() + submenu = FileManager.Menu() menu.set_submenu(submenu) # Context Submenu Items for name, action_group in devices: - item = Nautilus.MenuItem( + item = FileManager.MenuItem( name='ZorinConnectShareExtension::Device' + name, label=name ) diff -Nru gnome-shell-extension-zorin-connect-24.1/src/preferences/device.js gnome-shell-extension-zorin-connect-28.0.2/src/preferences/device.js --- gnome-shell-extension-zorin-connect-24.1/src/preferences/device.js 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/preferences/device.js 2019-11-30 01:01:40.000000000 +0000 @@ -0,0 +1,1033 @@ +'use strict'; + +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; +const GObject = imports.gi.GObject; +const Gtk = imports.gi.Gtk; +const Pango = imports.gi.Pango; + +const Keybindings = imports.preferences.keybindings; + + +// Build a list of plugins and shortcuts for devices +const DEVICE_PLUGINS = []; +const DEVICE_SHORTCUTS = {}; + +for (let name in imports.service.plugins) { + let module = imports.service.plugins[name]; + + if (module.Metadata !== undefined) { + // Plugins + DEVICE_PLUGINS.push(name); + + // Shortcuts (GActions without parameters + for (let [name, action] of Object.entries(module.Metadata.actions)) { + if (action.parameter_type === null) { + DEVICE_SHORTCUTS[name] = [action.icon_name, action.label]; + } + } + } +} + + +// A GtkListBoxUpdateHeaderFunc for sections +function rowSeparators(row, before) { + let header = row.get_header(); + + if (before === null) { + if (header !== null) { + header.destroy(); + } + + return; + } + + if (header === null) { + header = new Gtk.Separator({visible: true}); + row.set_header(header); + } +} + + +// A GtkListBoxSortFunc for SectionRow rows +function title_sort(row1, row2) { + if (!row1.title || !row2.title) return 0; + + return row1.title.localeCompare(row2.title); +} + + +/** + * A row for a section of settings + */ +const SectionRow = GObject.registerClass({ + GTypeName: 'ZorinConnectSectionRow' +}, class SectionRow extends Gtk.ListBoxRow { + + _init(params) { + super._init({ + height_request: 56, + selectable: false, + visible: true + }); + + let grid = new Gtk.Grid({ + column_spacing: 12, + margin_top: 8, + margin_right: 12, + margin_bottom: 8, + margin_left: 12, + visible: true + }); + this.add(grid); + + // Row Icon + this._icon = new Gtk.Image({ + pixel_size: 32 + }); + grid.attach(this._icon, 0, 0, 1, 2); + + // Row Title + this._title = new Gtk.Label({ + halign: Gtk.Align.START, + hexpand: true, + valign: Gtk.Align.CENTER, + vexpand: true + }); + grid.attach(this._title, 1, 0, 1, 1); + + // Row Subtitle + this._subtitle = new Gtk.Label({ + halign: Gtk.Align.START, + hexpand: true, + valign: Gtk.Align.CENTER, + vexpand: true + }); + this._subtitle.get_style_context().add_class('dim-label'); + grid.attach(this._subtitle, 1, 1, 1, 1); + + Object.assign(this, params); + } + + get icon_name() { + return this._icon.gicon.names[0]; + } + + set icon_name(icon_name) { + this._icon.visible = (icon_name); + this._icon.gicon = new Gio.ThemedIcon({name: icon_name}); + } + + get title() { + return this._title.label; + } + + set title(text) { + this._title.visible = (text); + this._title.label = text; + } + + get subtitle() { + return this._subtitle.label; + } + + set subtitle(text) { + this._subtitle.visible = (text); + this._subtitle.label = text; + } + + get widget() { + return this._widget; + } + + set widget(widget) { + if (this._widget && this._widget instanceof Gtk.Widget) { + this._widget.destroy(); + this._widget = null; + } + + this._widget = widget; + this.get_child().attach(this.widget, 2, 0, 1, 2); + } +}); + + +var DevicePreferences = GObject.registerClass({ + GTypeName: 'ZorinConnectDevicePreferences', + Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/ui/device-preferences.ui', + Children: [ + 'sidebar', 'stack', 'infobar', + + // Sharing + 'sharing', 'sharing-page', + 'desktop-list', 'clipboard', 'clipboard-sync', 'mousepad', 'mpris', 'systemvolume', + 'share', 'receive-files', 'receive-directory', + + // Battery + 'battery', + 'battery-device-label', 'battery-device', 'battery-device-list', + 'battery-system-label', 'battery-system', 'battery-system-list', + + // RunCommand + 'runcommand', 'runcommand-page', + 'command-list', + 'command-toolbar', 'command-add', 'command-remove', 'command-edit', 'command-save', + 'command-editor', 'command-name', 'command-line', + + // Notifications + 'notification', 'notification-page', + 'notification-list', 'notification-apps', + + // Telephony + 'telephony', 'telephony-page', + 'ringing-list', 'ringing-volume', 'talking-list', 'talking-volume', + + // Shortcuts + 'shortcuts-page', + 'shortcuts-actions', 'shortcuts-actions-title', 'shortcuts-actions-list', + + // Advanced + 'advanced-page', + 'plugin-list', 'experimental-list' + ] +}, class DevicePreferences extends Gtk.Grid { + + _init(device) { + this.connectTemplate(); + super._init(); + + this.device = device; + + // GSettings + this.settings = new Gio.Settings({ + settings_schema: zorin_connect.gschema.lookup( + 'org.gnome.Shell.Extensions.ZorinConnect.Device', + true + ), + path: '/org/gnome/shell/extensions/zorin-connect/device/' + device.id + '/' + }); + + // Infobar + this.device.bind_property( + 'paired', + this.infobar, + 'reveal-child', + (GObject.BindingFlags.SYNC_CREATE | + GObject.BindingFlags.INVERT_BOOLEAN) + ); + + this._setupActions(); + + // Settings Pages + this._sharingSettings(); + this._batterySettings(); + this._runcommandSettings(); + this._notificationSettings(); + this._telephonySettings(); + // -------------------------- + this._keybindingSettings(); + this._advancedSettings(); + + // Separate plugins and other settings + this.sidebar.set_header_func((row, before) => { + if (row.get_name() === 'shortcuts') { + row.set_header(new Gtk.Separator({visible: true})); + } + }); + + // Hide elements for any disabled plugins + for (let name of DEVICE_PLUGINS) { + if (this.hasOwnProperty(name)) { + this[name].visible = this.get_plugin_allowed(name); + } + } + } + + get menu() { + if (this._menu === undefined) { + let menus = Gtk.Builder.new_from_resource( + '/org/gnome/Shell/Extensions/ZorinConnect/gtk/menus.ui' + ); + menus.translation_domain = 'org.gnome.Shell.Extensions.ZorinConnect'; + + this._menu = menus.get_object('device-menu'); + this._menu.prepend_section(null, this.device.menu); + this.insert_action_group('device', this.device.action_group); + } + + return this._menu; + } + + get_incoming_supported(type) { + let incoming = this.settings.get_strv('incoming-capabilities'); + return incoming.includes(`kdeconnect.${type}`); + } + + get_outgoing_supported(type) { + let outgoing = this.settings.get_strv('outgoing-capabilities'); + return outgoing.includes(`kdeconnect.${type}`); + } + + _onKeynavFailed(widget, direction) { + if (direction === Gtk.DirectionType.UP && widget.prev) { + widget.prev.child_focus(direction); + } else if (direction === Gtk.DirectionType.DOWN && widget.next) { + widget.next.child_focus(direction); + } + + return true; + } + + _onSwitcherRowSelected(box, row) { + this.stack.set_visible_child_name(row.get_name()); + } + + _onToggleRowActivated(box, row) { + let widget = row.get_child().get_child_at(1, 0); + widget.active = !widget.active; + } + + _onEncryptionInfo() { + let dialog = new Gtk.MessageDialog({ + buttons: Gtk.ButtonsType.OK, + text: _('Encryption Info'), + secondary_text: this.device.encryption_info, + modal: true, + transient_for: this.get_toplevel() + }); + dialog.connect('response', (dialog) => dialog.destroy()); + dialog.present(); + } + + _deviceAction(action, parameter) { + this.action_group.activate_action(action.name, parameter); + } + + dispose() { + if (this.__disposed === undefined) { + this.__disposed = true; + + // Template + this.disconnectTemplate(); + + // Device signals + this.device.action_group.disconnect(this._actionAddedId); + this.device.action_group.disconnect(this._actionRemovedId); + + // GActions/GMenu + this.menu.run_dispose(); + this.actions.run_dispose(); + + // GSettings + for (let settings of Object.values(this._pluginSettings)) { + settings.run_dispose(); + } + + this.settings.disconnect(this._keybindingsId); + this.settings.disconnect(this._pluginsId); + this.settings.run_dispose(); + } + } + + pluginSettings(name) { + if (this._pluginSettings === undefined) { + this._pluginSettings = {}; + } + + if (!this._pluginSettings.hasOwnProperty(name)) { + let meta = imports.service.plugins[name].Metadata; + + this._pluginSettings[name] = new Gio.Settings({ + settings_schema: zorin_connect.gschema.lookup(meta.id, -1), + path: this.settings.path + 'plugin/' + name + '/' + }); + } + + return this._pluginSettings[name]; + } + + _setupActions() { + this.actions = new Gio.SimpleActionGroup(); + this.insert_action_group('settings', this.actions); + + let settings = this.pluginSettings('battery'); + this.actions.add_action(settings.create_action('send-statistics')); + this.actions.add_action(settings.create_action('low-battery-notification')); + this.actions.add_action(settings.create_action('full-battery-notification')); + + settings = this.pluginSettings('clipboard'); + this.actions.add_action(settings.create_action('send-content')); + this.actions.add_action(settings.create_action('receive-content')); + + settings = this.pluginSettings('contacts'); + this.actions.add_action(settings.create_action('contacts-source')); + + settings = this.pluginSettings('mousepad'); + this.actions.add_action(settings.create_action('share-control')); + + settings = this.pluginSettings('mpris'); + this.actions.add_action(settings.create_action('share-players')); + + settings = this.pluginSettings('notification'); + this.actions.add_action(settings.create_action('send-notifications')); + this.actions.add_action(settings.create_action('send-active')); + + settings = this.pluginSettings('photo'); + this.actions.add_action(settings.create_action('share-camera')); + + settings = this.pluginSettings('share'); + this.actions.add_action(settings.create_action('receive-files')); + + settings = this.pluginSettings('sms'); + this.actions.add_action(settings.create_action('legacy-sms')); + + settings = this.pluginSettings('systemvolume'); + this.actions.add_action(settings.create_action('share-sinks')); + + settings = this.pluginSettings('telephony'); + this.actions.add_action(settings.create_action('ringing-volume')); + this.actions.add_action(settings.create_action('ringing-pause')); + + this.actions.add_action(settings.create_action('talking-volume')); + this.actions.add_action(settings.create_action('talking-pause')); + this.actions.add_action(settings.create_action('talking-microphone')); + + // Pair Actions + let encryption_info = new Gio.SimpleAction({name: 'encryption-info'}); + encryption_info.connect('activate', this._onEncryptionInfo.bind(this)); + this.actions.add_action(encryption_info); + + let status_pair = new Gio.SimpleAction({name: 'pair'}); + status_pair.connect('activate', this._deviceAction.bind(this.device)); + this.settings.bind('paired', status_pair, 'enabled', 16); + this.actions.add_action(status_pair); + + let status_unpair = new Gio.SimpleAction({name: 'unpair'}); + status_unpair.connect('activate', this._deviceAction.bind(this.device)); + this.settings.bind('paired', status_unpair, 'enabled', 0); + this.actions.add_action(status_unpair); + } + + /** + * Sharing Settings + */ + _sharingSettings() { + // Share Plugin + let settings = this.pluginSettings('share'); + + settings.connect( + 'changed::receive-directory', + this._onReceiveDirectoryChanged.bind(this) + ); + this._onReceiveDirectoryChanged(settings, 'receive-directory'); + + // Visibility + this.desktop_list.foreach(row => { + let name = row.get_name(); + row.visible = this.get_outgoing_supported(`${name}.request`); + }); + + // Separators & Sorting + this.desktop_list.set_header_func(rowSeparators); + + this.desktop_list.set_sort_func((row1, row2) => { + row1 = row1.get_child().get_child_at(0, 0); + row2 = row2.get_child().get_child_at(0, 0); + return row1.label.localeCompare(row2.label); + }); + } + + _onReceiveDirectoryChanged(settings, key) { + let receiveDir = settings.get_string(key); + + if (receiveDir.length === 0) { + receiveDir = GLib.get_user_special_dir( + GLib.UserDirectory.DIRECTORY_DOWNLOAD + ); + + // Account for some corner cases with a fallback + if (!receiveDir || receiveDir === GLib.get_home_dir()) { + receiveDir = GLib.build_filenamev([ + GLib.get_home_dir(), + 'Downloads' + ]); + } + + settings.set_string(key, receiveDir); + } + + if (this.receive_directory.get_filename() !== receiveDir) { + this.receive_directory.set_filename(receiveDir); + } + } + + _onReceiveDirectorySet(button) { + let settings = this.pluginSettings('share'); + let receiveDir = settings.get_string('receive-directory'); + let filename = button.get_filename(); + + if (filename !== receiveDir) { + settings.set_string('receive-directory', filename); + } + } + + /** + * Battery Settings + */ + async _batterySettings() { + try { + this.battery_device_list.set_header_func(rowSeparators); + this.battery_system_list.set_header_func(rowSeparators); + + // If the device can't handle statistics we're done + if (!this.get_incoming_supported('battery')) { + this.battery_system_label.visible = false; + this.battery_system.visible = false; + return; + } + + // Check UPower for a battery + let hasBattery = await new Promise((resolve, reject) => { + Gio.DBus.system.call( + 'org.freedesktop.UPower', + '/org/freedesktop/UPower/devices/DisplayDevice', + 'org.freedesktop.DBus.Properties', + 'Get', + new GLib.Variant('(ss)', [ + 'org.freedesktop.UPower.Device', + 'IsPresent' + ]), + null, + Gio.DBusCallFlags.NONE, + -1, + null, + (connection, res) => { + try { + let variant = connection.call_finish(res); + let value = variant.deep_unpack()[0]; + let isPresent = value.get_boolean(); + + resolve(isPresent); + } catch (e) { + resolve(false); + } + } + ); + }); + + this.battery_system_label.visible = hasBattery; + this.battery_system.visible = hasBattery; + } catch (e) { + this.battery_system_label.visible = false; + this.battery_system.visible = false; + } + } + + /** + * RunCommand Page + */ + _runcommandSettings() { + // Scroll with keyboard focus + let runcommand_box = this.runcommand_page.get_child().get_child(); + runcommand_box.set_focus_vadjustment(this.runcommand_page.vadjustment); + + // Local Command List + let settings = this.pluginSettings('runcommand'); + this._commands = settings.get_value('command-list').full_unpack(); + this._commands = (typeof this._commands === 'string') ? {} : this._commands; + + this.command_list.set_sort_func(title_sort); + this.command_list.set_header_func(rowSeparators); + + Object.keys(this._commands).map(uuid => this._insertCommand(uuid)); + } + + _resetCommandEditor() { + // Reset the command editor + delete this.command_editor.uuid; + this.command_name.text = ''; + this.command_line.text = ''; + this.command_editor.visible = false; + + this.command_list.foreach(child => { + if (child !== this.command_editor) { + child.visible = true; + child.sensitive = true; + } + }); + + this.command_list.invalidate_sort(); + this.command_list.invalidate_headers(); + } + + _insertCommand(uuid) { + let row = new SectionRow({ + title: this._commands[uuid].name, + subtitle: this._commands[uuid].command, + selectable: true + }); + row.set_name(uuid); + row._subtitle.ellipsize = Pango.EllipsizeMode.MIDDLE; + + this.command_list.add(row); + + return row; + } + + _onCommandSelected(box) { + let selected = (box.get_selected_row() !== null); + this.command_edit.sensitive = selected; + this.command_remove.sensitive = selected; + } + + // The [+] button in the toolbar + _onAddCommand(button) { + let uuid = GLib.uuid_string_random(); + this._commands[uuid] = {name: '', command: ''}; + + let row = this._insertCommand(uuid); + this.command_list.select_row(row); + this._onEditCommand(); + } + + // The [-] button in the toolbar + _onRemoveCommand(button) { + let row = this.command_list.get_selected_row(); + delete this._commands[row.get_name()]; + + this.pluginSettings('runcommand').set_value( + 'command-list', + GLib.Variant.full_pack(this._commands) + ); + + row.destroy(); + this._resetCommandEditor(); + } + + // 'Edit' icon in the toolbar + _onEditCommand(button) { + let row = this.command_list.get_selected_row(); + let uuid = row.get_name(); + + this.command_editor.uuid = uuid; + this.command_name.text = this._commands[uuid].name; + this.command_line.text = this._commands[uuid].command; + + row.visible = false; + this.command_editor.visible = true; + this.command_name.has_focus = true; + + this.command_list.foreach(child => { + child.sensitive = (child === this.command_editor); + }); + } + + // 'Save' icon in the toolbar + _onSaveCommand(button) { + let row = this.command_list.get_selected_row(); + let uuid = row.get_name(); + + if (this.command_name.text && this.command_line.text) { + this._commands[uuid] = { + name: this.command_name.text, + command: this.command_line.text + }; + + row.title = this.command_name.text; + row.subtitle = this.command_line.text; + + this.pluginSettings('runcommand').set_value( + 'command-list', + GLib.Variant.full_pack(this._commands) + ); + } else { + delete this._commands[uuid]; + row.destroy(); + } + + this._resetCommandEditor(); + } + + // The 'folder' icon in the command editor GtkEntry + _onBrowseCommand(entry, icon_pos, event) { + let filter = new Gtk.FileFilter(); + filter.add_mime_type('application/x-executable'); + + let dialog = new Gtk.FileChooserDialog({filter: filter}); + dialog.add_button(_('Cancel'), Gtk.ResponseType.CANCEL); + dialog.add_button(_('Open'), Gtk.ResponseType.OK); + dialog.set_default_response(Gtk.ResponseType.OK); + + dialog.connect('response', (dialog, response_id) => { + if (response_id === Gtk.ResponseType.OK) { + this.command_line.text = dialog.get_filename(); + } + + dialog.destroy(); + }); + + dialog.show_all(); + } + + /** + * Notification Settings + */ + _notificationSettings() { + let settings = this.pluginSettings('notification'); + + settings.bind( + 'send-notifications', + this.notification_apps, + 'sensitive', + Gio.SettingsBindFlags.DEFAULT + ); + + // Separators & Sorting + this.notification_list.set_header_func(rowSeparators); + + // Scroll with keyboard focus + let notification_box = this.notification_page.get_child().get_child(); + notification_box.set_focus_vadjustment(this.notification_page.vadjustment); + + // Continue focus chain between lists + this.notification_list.next = this.notification_apps; + this.notification_apps.prev = this.notification_list; + + this.notification_apps.set_sort_func(title_sort); + this.notification_apps.set_header_func(rowSeparators); + + this._populateApplications(settings); + } + + _onNotificationRowActivated(box, row) { + let settings = this.pluginSettings('notification'); + let applications = {}; + + try { + applications = JSON.parse(settings.get_string('applications')); + } catch (e) { + applications = {}; + } + + applications[row.title].enabled = !applications[row.title].enabled; + row.widget.label = applications[row.title].enabled ? _('On') : _('Off'); + settings.set_string('applications', JSON.stringify(applications)); + } + + _populateApplications(settings) { + let applications = this._queryApplications(settings); + + for (let name in applications) { + let row = new SectionRow({ + icon_name: applications[name].iconName, + title: name, + height_request: 48, + widget: new Gtk.Label({ + label: applications[name].enabled ? _('On') : _('Off'), + margin_start: 12, + margin_end: 12, + halign: Gtk.Align.END, + valign: Gtk.Align.CENTER, + vexpand: true, + visible: true + }) + }); + + this.notification_apps.add(row); + } + } + + _queryApplications(settings) { + let applications = {}; + + try { + applications = JSON.parse(settings.get_string('applications')); + } catch (e) { + applications = {}; + } + + // Scan applications that statically declare to show notifications + let appInfos = []; + let ignoreId = 'org.gnome.Shell.Extensions.ZorinConnect.desktop'; + + for (let appInfo of Gio.AppInfo.get_all()) { + if (appInfo.get_id() !== ignoreId && + appInfo.get_boolean('X-GNOME-UsesNotifications')) { + appInfos.push(appInfo); + } + } + + // Update GSettings + for (let appInfo of appInfos) { + let appName = appInfo.get_name(); + + if (appName && !applications[appName]) { + let icon = appInfo.get_icon(); + icon = (icon) ? icon.to_string() : 'application-x-executable'; + + applications[appName] = { + iconName: icon, + enabled: true + }; + } + } + + settings.set_string('applications', JSON.stringify(applications)); + + return applications; + } + + /** + * Telephony Settings + */ + _telephonySettings() { + // Continue focus chain between lists + this.ringing_list.next = this.talking_list; + this.talking_list.prev = this.ringing_list; + + this.ringing_list.set_header_func(rowSeparators); + this.talking_list.set_header_func(rowSeparators); + } + + /** + * Keyboard Shortcuts + */ + _keybindingSettings() { + // Scroll with keyboard focus + let shortcuts_box = this.shortcuts_page.get_child().get_child(); + shortcuts_box.set_focus_vadjustment(this.shortcuts_page.vadjustment); + + // Filter & Sort + this.shortcuts_actions_list.set_filter_func(this._filterPluginKeybindings.bind(this)); + this.shortcuts_actions_list.set_header_func(rowSeparators); + this.shortcuts_actions_list.set_sort_func(title_sort); + + // Init + for (let name in DEVICE_SHORTCUTS) { + this._addPluginKeybinding(name); + } + + this._setPluginKeybindings(); + + // Watch for GAction and Keybinding changes + this._actionAddedId = this.device.action_group.connect( + 'action-added', + () => this.shortcuts_actions_list.invalidate_filter() + ); + this._actionRemovedId = this.device.action_group.connect( + 'action-removed', + () => this.shortcuts_actions_list.invalidate_filter() + ); + this._keybindingsId = this.settings.connect( + 'changed::keybindings', + this._setPluginKeybindings.bind(this) + ); + } + + _addPluginKeybinding(name) { + let [icon_name, label] = DEVICE_SHORTCUTS[name]; + + let widget = new Gtk.Label({ + label: _('Disabled'), + visible: true + }); + widget.get_style_context().add_class('dim-label'); + + let row = new SectionRow({ + icon_name: icon_name, + title: label, + widget: widget + }); + row.height_request = 48; + row._icon.pixel_size = 16; + row.action = name; + this.shortcuts_actions_list.add(row); + } + + _filterPluginKeybindings(row) { + return this.device.action_group.has_action(row.action); + } + + _setPluginKeybindings() { + let keybindings = this.settings.get_value('keybindings').deep_unpack(); + + this.shortcuts_actions_list.foreach(row => { + if (keybindings[row.action]) { + let accel = Gtk.accelerator_parse(keybindings[row.action]); + row.widget.label = Gtk.accelerator_get_label(...accel); + } else { + row.widget.label = _('Disabled'); + } + }); + } + + _onResetActionShortcuts(button) { + let keybindings = this.settings.get_value('keybindings').deep_unpack(); + + for (let action in keybindings) { + if (!action.includes('::')) { + delete keybindings[action]; + } + } + + this.settings.set_value( + 'keybindings', + new GLib.Variant('a{ss}', keybindings) + ); + } + + async _onShortcutRowActivated(box, row) { + try { + let keybindings = this.settings.get_value('keybindings').deep_unpack(); + let accelerator = await Keybindings.get_accelerator( + row.title, + keybindings[row.action] + ); + + if (accelerator) { + keybindings[row.action] = accelerator; + } else { + delete keybindings[row.action]; + } + + this.settings.set_value( + 'keybindings', + new GLib.Variant('a{ss}', keybindings) + ); + } catch (e) { + logError(e); + } + } + + /** + * Advanced Page + */ + _advancedSettings() { + // Scroll with keyboard focus + let advanced_box = this.advanced_page.get_child().get_child(); + advanced_box.set_focus_vadjustment(this.advanced_page.vadjustment); + + // + this.plugin_list.set_header_func(rowSeparators); + + // Continue focus chain between lists + this.plugin_list.next = this.experimental_list; + this.experimental_list.prev = this.plugin_list; + + this._pluginsId = this.settings.connect( + 'changed::supported-plugins', + this._populatePlugins.bind(this) + ); + this._populatePlugins(); + } + + get_plugin_allowed(name) { + let disabled = this.settings.get_strv('disabled-plugins'); + let supported = this.settings.get_strv('supported-plugins'); + + return supported.filter(name => !disabled.includes(name)).includes(name); + } + + _addPlugin(name) { + let plugin = imports.service.plugins[name]; + + let row = new Gtk.ListBoxRow({ + border_width: 0, + visible: true + }); + + let grid = new Gtk.Grid({ + height_request: 32, + visible: true + }); + row.add(grid); + + let widget = new Gtk.CheckButton({ + label: plugin.Metadata.label, + active: this.get_plugin_allowed(name), + hexpand: true, + tooltip_text: name, + valign: Gtk.Align.CENTER, + vexpand: true, + visible: true + }); + grid.add(widget); + + if (plugin.Plugin.prototype.cacheClear) { + let button = new Gtk.Button({ + action_name: 'device.clearCache', + action_target: GLib.Variant.new_string(name), + image: new Gtk.Image({ + icon_name: 'edit-clear-all-symbolic', + pixel_size: 16, + visible: true + }), + valign: Gtk.Align.CENTER, + vexpand: true, + visible: true + }); + button.get_style_context().add_class('flat'); + widget.bind_property('active', button, 'sensitive', 2); + grid.add(button); + } + + this.plugin_list.add(row); + + widget._togglePluginId = widget.connect( + 'notify::active', + this._togglePlugin.bind(this) + ); + + if (this.hasOwnProperty(name)) { + this[name].visible = widget.active; + } + } + + _populatePlugins() { + let supported = this.settings.get_strv('supported-plugins'); + + for (let row of this.plugin_list.get_children()) { + let checkbutton = row.get_child().get_child_at(0, 0); + let name = checkbutton.tooltip_text; + + if (supported.includes(name)) { + row.visible = true; + checkbutton.active = this.get_plugin_allowed(name); + } else { + row.visible = false; + + if (this.hasOwnProperty(name)) { + this[name].visible = false; + } + } + + supported.splice(supported.indexOf(name), 1); + } + + for (let name of supported) { + this._addPlugin(name); + } + } + + _togglePlugin(widget) { + try { + let name = widget.tooltip_text; + let disabled = this.settings.get_strv('disabled-plugins'); + + if (disabled.includes(name)) { + disabled.splice(disabled.indexOf(name), 1); + } else { + disabled.push(name); + } + + this.settings.set_strv('disabled-plugins', disabled); + + if (this.hasOwnProperty(name)) { + this[name].visible = !disabled.includes(name); + } + } catch (e) { + logError(e); + } + } +}); + diff -Nru gnome-shell-extension-zorin-connect-24.1/src/preferences/__init__.js gnome-shell-extension-zorin-connect-28.0.2/src/preferences/__init__.js --- gnome-shell-extension-zorin-connect-24.1/src/preferences/__init__.js 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/preferences/__init__.js 2019-11-01 23:59:50.000000000 +0000 @@ -0,0 +1,22 @@ +'use strict'; + +const Gtk = imports.gi.Gtk; + + +// TODO: required for GJS 1.52 (GNOME 3.28) +Gtk.Widget.prototype.connectTemplate = function() { + this.$templateHandlers = []; + + Gtk.Widget.set_connect_func.call(this, (builder, obj, signalName, handlerName, connectObj, flags) => { + this.$templateHandlers.push([ + obj, + obj.connect(signalName, this[handlerName].bind(this)) + ]); + }); +}; + +Gtk.Widget.prototype.disconnectTemplate = function() { + Gtk.Widget.set_connect_func.call(this, function() {}); + this.$templateHandlers.map(([obj, id]) => obj.disconnect(id)); +}; + diff -Nru gnome-shell-extension-zorin-connect-24.1/src/preferences/keybindings.js gnome-shell-extension-zorin-connect-28.0.2/src/preferences/keybindings.js --- gnome-shell-extension-zorin-connect-24.1/src/preferences/keybindings.js 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/preferences/keybindings.js 2019-11-30 01:01:58.000000000 +0000 @@ -0,0 +1,424 @@ +'use strict'; + +const Gdk = imports.gi.Gdk; +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; +const GObject = imports.gi.GObject; +const Gtk = imports.gi.Gtk; + + +/** + * Response enum for ShortcutChooserDialog + */ +var ResponseType = { + CANCEL: Gtk.ResponseType.CANCEL, + SET: Gtk.ResponseType.APPLY, + UNSET: 2 +}; + + +/** + * Check the minor version of gnome-shell. + * + * @param {number} - the minor version of gnome-shell + */ +async function getShellVersionMinor() { + try { + if (getShellVersionMinor.__value) + return getShellVersionMinor.__value; + + getShellVersionMinor.__value = await new Promise((resolve, reject) => { + Gio.DBus.session.call( + 'org.gnome.Shell', + '/org/gnome/Shell', + 'org.freedesktop.DBus.Properties', + 'Get', + new GLib.Variant('(ss)', ['org.gnome.Shell', 'ShellVersion']), + null, + Gio.DBusCallFlags.NONE, + -1, + null, + (connection, res) => { + try { + res = connection.call_finish(res); + let version = res.deep_unpack()[0].get_string()[0]; + let minor = parseInt(version.split('.')[1], 10); + resolve(minor); + } catch (e) { + reject(e); + } + } + ); + }); + + return getShellVersionMinor.__value; + } catch (e) { + logError(e); + return 32; + } +} + + +/** + * A simplified version of the shortcut editor from GNOME Control Center + */ +var ShortcutChooserDialog = GObject.registerClass({ + GTypeName: 'ShortcutChooserDialog' +}, class ShortcutChooserDialog extends Gtk.Dialog { + + _init(params) { + super._init({ + transient_for: Gio.Application.get_default().get_active_window(), + use_header_bar: true, + modal: true, + // TRANSLATORS: Title of keyboard shortcut dialog + title: _('Set Shortcut') + }); + + this.seat = Gdk.Display.get_default().get_default_seat(); + + // Content + let content = this.get_content_area(); + content.spacing = 18; + content.margin = 12; + + // Action Buttons + this.cancel_button = this.add_button(_('Cancel'), ResponseType.CANCEL); + this.cancel_button.visible = false; + // TRANSLATORS: Button to confirm the new shortcut + this.set_button = this.add_button(_('Set'), ResponseType.SET); + this.set_button.visible = false; + this.set_default_response(ResponseType.SET); + + let summaryLabel = new Gtk.Label({ + // TRANSLATORS: Summary of a keyboard shortcut function + // Example: Enter a new shortcut to change Messaging + label: _('Enter a new shortcut to change %s').format( + params.summary + ), + use_markup: true, + visible: true + }); + content.add(summaryLabel); + + this.stack = new Gtk.Stack({ + transition_type: Gtk.StackTransitionType.CROSSFADE, + visible: true + }); + content.add(this.stack); + + // Edit page + let editPage = new Gtk.Grid({ + row_spacing: 18, + visible: true + }); + this.stack.add_named(editPage, 'edit'); + + let editImage = new Gtk.Image({ + resource: '/org/gnome/Shell/Extensions/ZorinConnect/images/enter-keyboard-shortcut.svg', + visible: true + }); + editPage.attach(editImage, 0, 0, 1, 1); + + let editLabel = new Gtk.Label({ + // TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut + label: _('Press Esc to cancel or Backspace to reset the keyboard shortcut.'), + visible: true + }); + editLabel.get_style_context().add_class('dim-label'); + editPage.attach(editLabel, 0, 1, 1, 1); + + // Confirm page + let confirmPage = new Gtk.Grid({ + row_spacing: 18, + visible: true + }); + this.stack.add_named(confirmPage, 'confirm'); + + this.shortcut_label = new Gtk.ShortcutLabel({ + accelerator: params.accelerator, + hexpand: true, + halign: Gtk.Align.CENTER, + visible: true + }); + confirmPage.attach(this.shortcut_label, 0, 0, 1, 1); + + this.conflict_label = new Gtk.Label({ + hexpand: true, + halign: Gtk.Align.CENTER + }); + confirmPage.attach(this.conflict_label, 0, 1, 1, 1); + } + + get accelerator() { + return this.shortcut_label.accelerator; + } + + set accelerator(value) { + this.shortcut_label.accelerator = value; + } + + vfunc_key_press_event(event) { + let keyvalLower = Gdk.keyval_to_lower(event.keyval); + let realMask = event.state & Gtk.accelerator_get_default_mod_mask(); + + // TODO: Remove modifier keys + let mods = [ + Gdk.KEY_Alt_L, + Gdk.KEY_Alt_R, + Gdk.KEY_Caps_Lock, + Gdk.KEY_Control_L, + Gdk.KEY_Control_R, + Gdk.KEY_Meta_L, + Gdk.KEY_Meta_R, + Gdk.KEY_Num_Lock, + Gdk.KEY_Shift_L, + Gdk.KEY_Shift_R, + Gdk.KEY_Super_L, + Gdk.KEY_Super_R + ]; + if (mods.includes(keyvalLower)) { + return true; + } + + // Normalize Tab + if (keyvalLower === Gdk.KEY_ISO_Left_Tab) { + keyvalLower = Gdk.KEY_Tab; + } + + // Put shift back if it changed the case of the key, not otherwise. + if (keyvalLower !== event.keyval) { + realMask |= Gdk.ModifierType.SHIFT_MASK; + } + + // HACK: we don't want to use SysRq as a keybinding (but we do want + // Alt+Print), so we avoid translation from Alt+Print to SysRq + if (keyvalLower === Gdk.KEY_Sys_Req && (realMask & Gdk.ModifierType.MOD1_MASK) !== 0) { + keyvalLower = Gdk.KEY_Print; + } + + // A single Escape press cancels the editing + if (realMask === 0 && keyvalLower === Gdk.KEY_Escape) { + this.response(ResponseType.CANCEL); + return false; + } + + // Backspace disables the current shortcut + if (realMask === 0 && keyvalLower === Gdk.KEY_BackSpace) { + this.response(ResponseType.UNSET); + return false; + } + + // CapsLock isn't supported as a keybinding modifier, so keep it from + // confusing us + realMask &= ~Gdk.ModifierType.LOCK_MASK; + + if (keyvalLower !== 0 && realMask !== 0) { + this._ungrab(); + + // Set the accelerator property/label + this.accelerator = Gtk.accelerator_name(keyvalLower, realMask); + + // TRANSLATORS: When a keyboard shortcut is unavailable + // Example: [Ctrl]+[S] is already being used + this.conflict_label.label = _('%s is already being used').format( + Gtk.accelerator_get_label(keyvalLower, realMask) + ); + + // Show Cancel button and switch to confirm/conflict page + this.cancel_button.visible = true; + this.stack.visible_child_name = 'confirm'; + + this._check(); + } + + return true; + } + + async _check() { + try { + let available = await check_accelerator(this.accelerator); + this.set_button.visible = available; + this.conflict_label.visible = !available; + } catch (e) { + logError(e); + this.response(ResponseType.CANCEL); + } + } + + _grab() { + let seat = Gdk.Display.get_default().get_default_seat(); + let success = seat.grab( + this.get_window(), + Gdk.SeatCapabilities.KEYBOARD, + true, // owner_events + null, // cursor + null, // event + null + ); + + if (success !== Gdk.GrabStatus.SUCCESS) { + return this.response(ResponseType.CANCEL); + } + + let device = seat.get_keyboard() || seat.get_pointer(); + + if (!device) { + return this.response(ResponseType.CANCEL); + } + + this.grab_add(); + } + + _ungrab() { + this.seat.ungrab(); + this.grab_remove(); + } + + // Override to use our own ungrab process + response(response_id) { + this.hide(); + this._ungrab(); + + return super.response(response_id); + } + + // Override with a non-blocking version of Gtk.Dialog.run() + run() { + this.show(); + + // Wait a bit before attempting grab + GLib.timeout_add(GLib.PRIORITY_DEFAULT, 100, () => { + this._grab(); + return GLib.SOURCE_REMOVE; + }); + } +}); + + +/** + * Check the availability of an accelerator using GNOME Shell's DBus interface. + * + * @param {string} - An accelerator + * @param {number} - Mode Flags + * @param {number} - Grab Flags + * @param {boolean} - %true if available, %false on error or unavailable + */ +async function check_accelerator(accelerator, modeFlags = 0, grabFlags = 0) { + let action; + let result = false; + + try { + // Check whether we're >= gnome-shell 3.32 + let minor = await getShellVersionMinor(); + let params; + + if (minor >= 32) { + params = new GLib.Variant('(suu)', [accelerator, modeFlags, grabFlags]); + } else { + params = new GLib.Variant('(su)', [accelerator, modeFlags]); + } + + // Use gnome-shell's DBus interface to try and grab the accelerator + action = await new Promise((resolve, reject) => { + Gio.DBus.session.call( + 'org.gnome.Shell', + '/org/gnome/Shell', + 'org.gnome.Shell', + 'GrabAccelerator', + params, + null, + Gio.DBusCallFlags.NONE, + -1, + null, + (connection, res) => { + try { + res = connection.call_finish(res); + resolve(res.deep_unpack()[0]); + } catch (e) { + reject(e); + } + } + ); + }); + + // If successful, use the result of ungrabbing as our return + if (action !== 0) { + result = await new Promise((resolve, reject) => { + Gio.DBus.session.call( + 'org.gnome.Shell', + '/org/gnome/Shell', + 'org.gnome.Shell', + 'UngrabAccelerator', + new GLib.Variant('(u)', [action]), + null, + Gio.DBusCallFlags.NONE, + -1, + null, + (connection, res) => { + try { + res = connection.call_finish(res); + resolve(res.deep_unpack()[0]); + } catch (e) { + reject(e); + } + } + ); + }); + } + + return result; + } catch (e) { + debug (e); + return false; + } +} + + +/** + * Show a dialog to get a keyboard shortcut from a user. + * + * @param {string} summary - A description of the keybinding's function + * @param {string} accelerator - An accelerator as taken by Gtk.ShortcutLabel + * @return {string} - An accelerator or %null if it should be unset. + */ +async function get_accelerator(summary, accelerator = null) { + let dialog; + + try { + dialog = new ShortcutChooserDialog({ + summary: summary, + accelerator: accelerator + }); + + accelerator = await new Promise((resolve, reject) => { + dialog.connect('response', (dialog, response) => { + switch (response) { + case ResponseType.SET: + accelerator = dialog.accelerator; + break; + + case ResponseType.UNSET: + accelerator = null; + break; + + case ResponseType.CANCEL: + // leave the accelerator as passed in + break; + } + + dialog.destroy(); + + resolve(accelerator); + }); + + dialog.run(); + }); + + return accelerator; + } catch (e) { + logError(e); + return accelerator; + } +} + diff -Nru gnome-shell-extension-zorin-connect-24.1/src/preferences/service.js gnome-shell-extension-zorin-connect-28.0.2/src/preferences/service.js --- gnome-shell-extension-zorin-connect-24.1/src/preferences/service.js 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/preferences/service.js 2019-11-30 17:57:27.000000000 +0000 @@ -0,0 +1,663 @@ +'use strict'; + +const Gdk = imports.gi.Gdk; +const GdkPixbuf = imports.gi.GdkPixbuf; +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; +const GObject = imports.gi.GObject; +const Gtk = imports.gi.Gtk; + +const Device = imports.preferences.device; +const Remote = imports.shell.remote; + +/* + * Header for support logs + */ +const LOG_HEADER = new GLib.Bytes(` +Zorin Connect Version: ${zorin_connect.metadata.version} +Zorin Connect Install: ${(zorin_connect.is_local) ? 'user' : 'system'} +GJS: ${imports.system.version} +XDG_SESSION_TYPE: ${GLib.getenv('XDG_SESSION_TYPE')} +GDMSESSION: ${GLib.getenv('GDMSESSION')} +-------------------------------------------------------------------------------- +`); + + +/** + * Generate a support log + */ +async function generateSupportLog(time) { + try { + let file = Gio.File.new_tmp('zorin-connect.XXXXXX')[0]; + + let logFile = await new Promise((resolve, reject) => { + file.replace_async(null, false, 2, 0, null, (file, res) => { + try { + resolve(file.replace_finish(res)); + } catch (e) { + reject(e); + } + }); + }); + + await new Promise((resolve, reject) => { + logFile.write_bytes_async(LOG_HEADER, 0, null, (file, res) => { + try { + resolve(file.write_bytes_finish(res)); + } catch (e) { + reject(e); + } + }); + }); + + // FIXME: BSD??? + let proc = new Gio.Subprocess({ + flags: Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_MERGE, + argv: ['journalctl', '--no-host', '--since', time] + }); + proc.init(null); + + logFile.splice_async( + proc.get_stdout_pipe(), + Gio.OutputStreamSpliceFlags.CLOSE_TARGET, + GLib.PRIORITY_DEFAULT, + null, + (source, res) => { + try { + source.splice_finish(res); + } catch (e) { + logError(e); + } + } + ); + + await new Promise((resolve, reject) => { + proc.wait_check_async(null, (proc, res) => { + try { + resolve(proc.wait_finish(res)); + } catch (e) { + reject(e); + } + }); + }); + + let uri = file.get_uri(); + Gio.AppInfo.launch_default_for_uri_async(uri, null, null, null); + } catch (e) { + logError(e); + } +} + + +/** + * "Connect to..." Dialog + */ +var ConnectDialog = GObject.registerClass({ + GTypeName: 'ZorinConnectConnectDialog', + Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/ui/connect.ui', + Children: [ + 'cancel-button', 'connect-button', + 'lan-radio', 'lan-grid', 'lan-ip', 'lan-port' + ] +}, class ConnectDialog extends Gtk.Dialog { + + _init(params = {}) { + this.connectTemplate(); + super._init(Object.assign({ + use_header_bar: true + }, params)); + } + + vfunc_response(response_id) { + if (response_id === Gtk.ResponseType.OK) { + try { + let address; + + // Lan host/port entered + if (this.lan_ip.text) { + let host = this.lan_ip.text; + let port = this.lan_port.value; + address = GLib.Variant.new_string('lan://' + host + ':' + port); + } else { + return false; + } + + this.application.activate_action('connect', address); + } catch (e) { + logError(e); + } + } + + if (this._devicesId) { + this.application.bluetooth.disconnect(this._devicesId); + } + + this.disconnectTemplate(); + this.destroy(); + return false; + } +}); + + +function rowSeparators(row, before) { + let header = row.get_header(); + + if (before === null) { + if (header !== null) { + header.destroy(); + } + + return; + } + + if (header === null) { + header = new Gtk.Separator({visible: true}); + row.set_header(header); + } +} + + +var Window = GObject.registerClass({ + GTypeName: 'ZorinConnectPreferencesWindow', + Properties: { + 'display-mode': GObject.ParamSpec.string( + 'display-mode', + 'Display Mode', + 'Display devices in either the Panel or User Menu', + GObject.ParamFlags.READWRITE, + null + ) + }, + Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/ui/preferences-window.ui', + Children: [ + // HeaderBar + 'headerbar', 'infobar', 'stack', + 'service-menu', 'service-edit', 'service-refresh', + 'device-menu', 'prev-button', + + // Popover + 'rename-popover', 'rename', 'rename-label', 'rename-entry', 'rename-submit', + + // Focus Box + 'service-window', 'service-box', + + // Device List + 'device-list', 'device-list-spinner', 'device-list-placeholder' + ] +}, class PreferencesWindow extends Gtk.ApplicationWindow { + + _init(params) { + this.connectTemplate(); + super._init(params); + + // Service Settings + this.settings = new Gio.Settings({ + settings_schema: zorin_connect.gschema.lookup( + 'org.gnome.Shell.Extensions.ZorinConnect', + true + ) + }); + + // Service Proxy + this.service = new Remote.Service(); + + this._deviceAddedId = this.service.connect( + 'device-added', + this._onDeviceAdded.bind(this) + ); + + this._deviceRemovedId = this.service.connect( + 'device-removed', + this._onDeviceRemoved.bind(this) + ); + + this._serviceChangedId = this.service.connect( + 'notify::active', + this._onServiceChanged.bind(this) + ); + + // HeaderBar (Service Name) + this.headerbar.title = this.settings.get_string('name'); + this.rename_entry.text = this.headerbar.title; + + // Scroll with keyboard focus + this.service_box.set_focus_vadjustment(this.service_window.vadjustment); + + // Device List + this.device_list.set_header_func(rowSeparators); + + // Discoverable InfoBar + this.settings.bind( + 'discoverable', + this.infobar, + 'reveal-child', + Gio.SettingsBindFlags.INVERT_BOOLEAN + ); + this.add_action(this.settings.create_action('discoverable')); + + // Application Menu + this._initMenu(); + + // Broadcast automatically every 5 seconds if there are no devices yet + this._refreshSource = GLib.timeout_add_seconds( + GLib.PRIORITY_DEFAULT, + 5, + this._refresh.bind(this) + ); + + // Restore window size/maximized/position + this._restoreGeometry(); + + // Prime the service + this._initService(); + } + + get display_mode() { + if (this.settings.get_boolean('show-indicators')) { + return 'panel'; + } else { + return 'user-menu'; + } + } + + set display_mode(mode) { + this.settings.set_boolean('show-indicators', (mode === 'panel')); + } + + vfunc_delete_event(event) { + if (this.service) { + this.service.disconnect(this._deviceAddedId); + this.service.disconnect(this._deviceRemovedId); + this.service.disconnect(this._serviceChangedId); + this.service.destroy(); + this.service = null; + } + + this._saveGeometry(); + this.disconnectTemplate(); + GLib.source_remove(this._refreshSource); + + // FIXME: this wouldn't be necessary if we were disposing devices right + this.application.quit(); + return false; + } + + async _initService() { + try { + this._onServiceChanged(this.service, null); + await this.service.reload(); + } catch (e) { + logError(e, 'Zorin Connect'); + } + } + + _initMenu() { + // Panel/User Menu mode + let displayMode = new Gio.PropertyAction({ + name: 'display-mode', + property_name: 'display-mode', + object: this + }); + this.add_action(displayMode); + + // About Dialog + let aboutDialog = new Gio.SimpleAction({name: 'about'}); + aboutDialog.connect('activate', this._aboutDialog.bind(this)); + this.add_action(aboutDialog); + + // "Connect to..." Dialog + let connectDialog = new Gio.SimpleAction({name: 'connect'}); + connectDialog.connect('activate', this._connectDialog.bind(this)); + this.add_action(connectDialog); + + // "Generate Support Log" GAction + let generateSupportLog = new Gio.SimpleAction({name: 'support-log'}); + generateSupportLog.connect('activate', this._generateSupportLog.bind(this)); + this.add_action(generateSupportLog); + } + + _refresh() { + if (this.service.active && this.device_list.get_children().length < 1) { + this.device_list_spinner.active = true; + this.service.activate_action('refresh', null); + } else { + this.device_list_spinner.active = false; + } + + return GLib.SOURCE_CONTINUE; + } + + /** + * Window State + */ + _restoreGeometry() { + this._windowState = new Gio.Settings({ + settings_schema: zorin_connect.gschema.lookup( + 'org.gnome.Shell.Extensions.ZorinConnect.WindowState', + true + ), + path: '/org/gnome/shell/extensions/zorin-connect/preferences/' + }); + + // Size + let [width, height] = this._windowState.get_value('window-size').deep_unpack(); + + if (width && height) { + this.set_default_size(width, height); + } + + // Maximized State + if (this._windowState.get_boolean('window-maximized')) { + this.maximize(); + } + } + + _saveGeometry() { + let state = this.get_window().get_state(); + + // Maximized State + let maximized = (state & Gdk.WindowState.MAXIMIZED); + this._windowState.set_boolean('window-maximized', maximized); + + // Leave the size at the value before maximizing + if (maximized || (state & Gdk.WindowState.FULLSCREEN)) + return; + + // Size + let size = this.get_size(); + this._windowState.set_value('window-size', new GLib.Variant('(ii)', size)); + } + + /** + * About Dialog + */ + _aboutDialog() { + if (this._about === undefined) { + this._about = new Gtk.AboutDialog({ + application: Gio.Application.get_default(), + authors: [ + 'Andy Holmes ', + 'Bertrand Lacoste ', + 'Frank Dana ' + ], + logo: GdkPixbuf.Pixbuf.new_from_resource_at_scale( + '/org/gnome/Shell/Extensions/ZorinConnect/icons/org.gnome.Shell.Extensions.ZorinConnect.svg', + 128, + 128, + true + ), + program_name: 'Zorin Connect', + // TRANSLATORS: eg. 'Translator Name ' + translator_credits: _('translator-credits'), + version: zorin_connect.metadata.version.toString(), + license_type: Gtk.License.GPL_2_0, + modal: true, + transient_for: this + }); + + // Persist + this._about.connect('response', (dialog) => dialog.hide_on_delete()); + this._about.connect('delete-event', (dialog) => dialog.hide_on_delete()); + } + + this._about.present(); + } + + /** + * Connect to..." Dialog + */ + _connectDialog() { + new ConnectDialog({ + application: Gio.Application.get_default(), + modal: true, + transient_for: this + }); + } + + /** + * "Generate Support Log" GAction + */ + _generateSupportLog() { + let dialog = new Gtk.MessageDialog({ + text: _('Generate Support Log'), + secondary_text: _('Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log.') + }); + dialog.add_button(_('Cancel'), Gtk.ResponseType.CANCEL); + dialog.add_button(_('Review Log'), Gtk.ResponseType.OK); + + // Enable debug logging and mark the current time + this.settings.set_boolean('debug', true); + let now = GLib.DateTime.new_now_local().format('%R'); + + dialog.connect('response', (dialog, response_id) => { + // Disable debug logging and destroy the dialog + this.settings.set_boolean('debug', false); + dialog.destroy(); + + // Only generate a log if instructed + if (response_id === Gtk.ResponseType.OK) { + generateSupportLog(now); + } + }); + + dialog.show_all(); + } + + /** + * HeaderBar Callbacks + */ + _onPrevious(button, event) { + // HeaderBar (Service) + this.prev_button.visible = false; + this.device_menu.visible = false; + + this.service_refresh.visible = true; + this.service_edit.visible = true; + this.service_menu.visible = true; + + this.headerbar.title = this.settings.get_string('name'); + this.headerbar.subtitle = null; + + // Panel + this.stack.visible_child_name = 'service'; + this._setDeviceMenu(); + } + + _onEditServiceName(button, event) { + this.rename_entry.text = this.headerbar.title; + this.rename_entry.has_focus = true; + } + + _onSetServiceName(widget) { + if (this.rename_entry.text.length) { + this.headerbar.title = this.rename_entry.text; + this.settings.set_string('name', this.rename_entry.text); + } + + this.service_edit.active = false; + } + + /** + * Context Switcher + */ + _getTypeLabel(device) { + switch (device.type) { + case 'laptop': + return _('Laptop'); + case 'phone': + return _('Smartphone'); + case 'tablet': + return _('Tablet'); + case 'tv': + return _('Television'); + default: + return _('Desktop'); + } + } + + _setDeviceMenu(panel = null) { + this.device_menu.insert_action_group('device', null); + this.device_menu.insert_action_group('settings', null); + this.device_menu.set_menu_model(null); + + if (panel) { + this.device_menu.insert_action_group('device', panel.device.action_group); + this.device_menu.insert_action_group('settings', panel.actions); + this.device_menu.set_menu_model(panel.menu); + } + } + + _onDeviceChanged(statusLabel, device, pspec) { + switch (false) { + case device.paired: + statusLabel.label = _('Unpaired'); + break; + + case device.connected: + statusLabel.label = _('Disconnected'); + break; + + default: + statusLabel.label = _('Connected'); + } + } + + _createDeviceRow(device) { + let row = new Gtk.ListBoxRow({ + height_request: 52, + selectable: false, + visible: true + }); + row.set_name(device.id); + + let grid = new Gtk.Grid({ + column_spacing: 12, + margin_left: 20, + margin_right: 20, + margin_bottom: 8, + margin_top: 8, + visible: true + }); + row.add(grid); + + let icon = new Gtk.Image({ + gicon: new Gio.ThemedIcon({name: device.icon_name}), + icon_size: Gtk.IconSize.BUTTON, + visible: true + }); + grid.attach(icon, 0, 0, 1, 1); + + let title = new Gtk.Label({ + halign: Gtk.Align.START, + hexpand: true, + valign: Gtk.Align.CENTER, + vexpand: true, + visible: true + }); + grid.attach(title, 1, 0, 1, 1); + + let status = new Gtk.Label({ + halign: Gtk.Align.END, + hexpand: true, + valign: Gtk.Align.CENTER, + vexpand: true, + visible: true + }); + grid.attach(status, 2, 0, 1, 1); + + // Keep name up to date + device.bind_property( + 'name', + title, + 'label', + GObject.BindingFlags.SYNC_CREATE + ); + + // Keep status up to date + device.connect( + 'notify::connected', + this._onDeviceChanged.bind(null, status) + ); + device.connect( + 'notify::paired', + this._onDeviceChanged.bind(null, status) + ); + this._onDeviceChanged(status, device, null); + + return row; + } + + _onDeviceAdded(service, device) { + try { + if (!this.stack.get_child_by_name(device.id)) { + // Add the device preferences + let prefs = new Device.DevicePreferences(device); + this.stack.add_titled(prefs, device.id, device.name); + + // Add a row to the device list + prefs.row = this._createDeviceRow(device); + this.device_list.add(prefs.row); + } + } catch (e) { + logError (e); + } + } + + _onDeviceRemoved(service, device) { + try { + let prefs = this.stack.get_child_by_name(device.id); + + if (prefs !== null) { + if (prefs === this.stack.get_visible_child()) { + this._onPrevious(); + } + + prefs.row.destroy(); + prefs.row = null; + + prefs.dispose(); + prefs.destroy(); + } + } catch (e) { + logError (e); + } + } + + _onDeviceSelected(box, row) { + try { + if (row === null) { + this._onPrevious(); + return; + } + + // Transition the panel + let name = row.get_name(); + let prefs = this.stack.get_child_by_name(name); + + this.stack.visible_child = prefs; + this._setDeviceMenu(prefs); + + // HeaderBar (Device) + this.service_refresh.visible = false; + this.service_edit.visible = false; + this.service_menu.visible = false; + + this.prev_button.visible = true; + this.device_menu.visible = true; + + this.headerbar.title = prefs.device.name; + this.headerbar.subtitle = this._getTypeLabel(prefs.device); + } catch (e) { + logError(e); + } + } + + _onServiceChanged(service, pspec) { + if (this.service.active) { + this.device_list_placeholder.label = _('Searching for devices…'); + } else { + this.device_list_placeholder.label = _('Waiting for service…'); + } + } +}); + diff -Nru gnome-shell-extension-zorin-connect-24.1/src/prefs.js gnome-shell-extension-zorin-connect-28.0.2/src/prefs.js --- gnome-shell-extension-zorin-connect-24.1/src/prefs.js 2019-03-05 21:26:36.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/prefs.js 2019-11-30 00:56:56.000000000 +0000 @@ -18,23 +18,23 @@ function init() { zorin_connect.installService(); - Gtk.IconTheme.get_default().add_resource_path(zorin_connect.app_path); } function buildPrefsWidget() { + // Destroy the window once the mainloop starts let label = new Gtk.Label(); + GLib.timeout_add(GLib.PRIORITY_DEFAULT, 0, () => { label.get_toplevel().destroy(); return false; }); - let service = Gio.DBusActionGroup.get( - Gio.DBus.session, - 'org.gnome.Shell.Extensions.ZorinConnect', - '/org/gnome/Shell/Extensions/ZorinConnect' - ); - service.list_actions(); - service.activate_action('settings', null); + // Exec `zorin-connect-preferences + let proc = new Gio.Subprocess({ + argv: [zorin_connect.extdatadir + '/zorin-connect-preferences'] + }); + proc.init(null); + proc.wait_async(null, null); return label; } diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/components/atspi.js gnome-shell-extension-zorin-connect-28.0.2/src/service/components/atspi.js --- gnome-shell-extension-zorin-connect-24.1/src/service/components/atspi.js 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/components/atspi.js 2019-11-30 12:14:10.000000000 +0000 @@ -0,0 +1,299 @@ +'use strict'; + +imports.gi.versions.Atspi = '2.0'; + +const Atspi = imports.gi.Atspi; +const Gdk = imports.gi.Gdk; +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; +const GObject = imports.gi.GObject; +const Gtk = imports.gi.Gtk; + + +/** + * Printable ASCII range + */ +const _ASCII = /[\x20-\x7E]/; + + +/** + * Modifier Keycode Defaults + */ +const XKeycode = { + Alt_L: 0x40, + Control_L: 0x25, + Shift_L: 0x32, + Super_L: 0x85 +}; + + +var Controller = class { + constructor() { + // Atspi.init() return 2 on fail, but still marks itself as inited. We + // uninit before throwing an error otherwise any future call to init() + // will appear successful and other calls will cause Zorin Connect to exit. + // See: https://gitlab.gnome.org/GNOME/at-spi2-core/blob/master/atspi/atspi-misc.c + if (Atspi.init() === 2) { + this.destroy(); + throw new Error('Failed to start AT-SPI'); + } + + try { + this._display = Gdk.Display.get_default(); + this._seat = this._display.get_default_seat(); + this._pointer = this._seat.get_pointer(); + } catch (e) { + this.destroy(); + throw e; + } + + // Try to read modifier keycodes from Gdk + try { + let keymap = Gdk.Keymap.get_for_display(this._display); + let modifier; + + modifier = keymap.get_entries_for_keyval(Gdk.KEY_Alt_L)[1][0]; + XKeycode.Alt_L = modifier.keycode; + + modifier = keymap.get_entries_for_keyval(Gdk.KEY_Control_L)[1][0]; + XKeycode.Control_L = modifier.keycode; + + modifier = keymap.get_entries_for_keyval(Gdk.KEY_Shift_L)[1][0]; + XKeycode.Shift_L = modifier.keycode; + + modifier = keymap.get_entries_for_keyval(Gdk.KEY_Super_L)[1][0]; + XKeycode.Super_L = modifier.keycode; + } catch (e) { + debug('using default modifier keycodes'); + } + } + + /** + * Pointer events + */ + clickPointer(button) { + try { + let [, x, y] = this._pointer.get_position(); + let monitor = this._display.get_monitor_at_point(x, y); + let scale = monitor.get_scale_factor(); + Atspi.generate_mouse_event(scale * x, scale * y, `b${button}c`); + } catch (e) { + logError(e); + } + } + + doubleclickPointer(button) { + try { + let [, x, y] = this._pointer.get_position(); + let monitor = this._display.get_monitor_at_point(x, y); + let scale = monitor.get_scale_factor(); + Atspi.generate_mouse_event(scale * x, scale * y, `b${button}d`); + } catch (e) { + logError(e); + } + } + + movePointer(dx, dy) { + try { + let [, x, y] = this._pointer.get_position(); + let monitor = this._display.get_monitor_at_point(x, y); + let scale = monitor.get_scale_factor(); + Atspi.generate_mouse_event(scale * dx, scale * dy, 'rel'); + } catch (e) { + logError(e); + } + } + + pressPointer(button) { + try { + let [, x, y] = this._pointer.get_position(); + let monitor = this._display.get_monitor_at_point(x, y); + let scale = monitor.get_scale_factor(); + Atspi.generate_mouse_event(scale * x, scale * y, `b${button}p`); + } catch (e) { + logError(e); + } + } + + releasePointer(button) { + try { + let [, x, y] = this._pointer.get_position(); + let monitor = this._display.get_monitor_at_point(x, y); + let scale = monitor.get_scale_factor(); + Atspi.generate_mouse_event(scale * x, scale * y, `b${button}r`); + } catch (e) { + logError(e); + } + } + + scrollPointer(dx, dy) { + if (dy > 0) { + this.clickPointer(4); + } else if (dy > 0) { + this.clickPointer(5); + } + } + + /** + * Phony virtual keyboard helpers + */ + _modeLock(keycode) { + Atspi.generate_keyboard_event( + keycode, + null, + Atspi.KeySynthType.PRESS + ); + } + + _modeUnlock(keycode) { + Atspi.generate_keyboard_event( + keycode, + null, + Atspi.KeySynthType.RELEASE + ); + } + + /** + * Simulate a printable-ASCII character. + * + */ + _pressASCII(key, modifiers) { + try { + // Press Modifiers + if (modifiers & Gdk.ModifierType.MOD1_MASK) this._modeLock(XKeycode.Alt_L); + if (modifiers & Gdk.ModifierType.CONTROL_MASK) this._modeLock(XKeycode.Control_L); + if (modifiers & Gdk.ModifierType.SHIFT_MASK) this._modeLock(XKeycode.Shift_L); + if (modifiers & Gdk.ModifierType.SUPER_MASK) this._modeLock(XKeycode.Super_L); + + Atspi.generate_keyboard_event( + 0, + key, + Atspi.KeySynthType.STRING + ); + + // Release Modifiers + if (modifiers & Gdk.ModifierType.MOD1_MASK) this._modeUnlock(XKeycode.Alt_L); + if (modifiers & Gdk.ModifierType.CONTROL_MASK) this._modeUnlock(XKeycode.Control_L); + if (modifiers & Gdk.ModifierType.SHIFT_MASK) this._modeUnlock(XKeycode.Shift_L); + if (modifiers & Gdk.ModifierType.SUPER_MASK) this._modeUnlock(XKeycode.Super_L); + } catch (e) { + logError(e); + } + } + + _pressKeysym(keysym, modifiers) { + try { + // Press Modifiers + if (modifiers & Gdk.ModifierType.MOD1_MASK) this._modeLock(XKeycode.Alt_L); + if (modifiers & Gdk.ModifierType.CONTROL_MASK) this._modeLock(XKeycode.Control_L); + if (modifiers & Gdk.ModifierType.SHIFT_MASK) this._modeLock(XKeycode.Shift_L); + if (modifiers & Gdk.ModifierType.SUPER_MASK) this._modeLock(XKeycode.Super_L); + + Atspi.generate_keyboard_event( + keysym, + null, + Atspi.KeySynthType.PRESSRELEASE | Atspi.KeySynthType.SYM + ); + + // Release Modifiers + if (modifiers & Gdk.ModifierType.MOD1_MASK) this._modeUnlock(XKeycode.Alt_L); + if (modifiers & Gdk.ModifierType.CONTROL_MASK) this._modeUnlock(XKeycode.Control_L); + if (modifiers & Gdk.ModifierType.SHIFT_MASK) this._modeUnlock(XKeycode.Shift_L); + if (modifiers & Gdk.ModifierType.SUPER_MASK) this._modeUnlock(XKeycode.Super_L); + } catch (e) { + logError(e); + } + } + + /** + * Simulate the composition of a unicode character with: + * Control+Shift+u, [hex], Return + * + * @param {object} input - 'body' of a 'kdeconnect.mousepad.request' packet + */ + _pressUnicode(key, modifiers) { + try { + if (modifiers > 0) { + log('Zorin Connect: ignoring modifiers for unicode keyboard event'); + } + + // TODO: Using Control and Shift keysym is not working (it triggers + // key release). Probably using LOCKMODIFIERS will not work either + // as unlocking the modifier will not trigger a release + + // Activate compose sequence + this._modeLock(XKeycode.Control_L); + this._modeLock(XKeycode.Shift_L); + + this.pressreleaseKeysym(Gdk.KEY_U); + + this._modeUnlock(XKeycode.Control_L); + this._modeUnlock(XKeycode.Shift_L); + + // Enter the unicode sequence + let ucode = key.charCodeAt(0).toString(16); + let keysym; + + for (let h = 0, len = ucode.length; h < len; h++) { + keysym = Gdk.unicode_to_keyval(ucode.charAt(h).codePointAt(0)); + this.pressreleaseKeysym(keysym); + } + + // Finish the compose sequence + this.pressreleaseKeysym(Gdk.KEY_Return); + } catch (e) { + logError(e); + } + } + + /** + * Keyboard Events + */ + pressKeysym(keysym) { + Atspi.generate_keyboard_event( + keysym, + null, + Atspi.KeySynthType.PRESS | Atspi.KeySynthType.SYM + ); + } + + releaseKeysym(keysym) { + Atspi.generate_keyboard_event( + keysym, + null, + Atspi.KeySynthType.RELEASE | Atspi.KeySynthType.SYM + ); + } + + pressreleaseKeysym(keysym) { + Atspi.generate_keyboard_event( + keysym, + null, + Atspi.KeySynthType.PRESSRELEASE | Atspi.KeySynthType.SYM + ); + } + + pressKey(input, modifiers) { + // We were passed a keysym + if (typeof input === 'number') { + this._pressKeysym(input, modifiers); + + // Regular ASCII + } else if (_ASCII.test(input)) { + this._pressASCII(input, modifiers); + + // Unicode + } else { + this._pressUnicode(input, modifiers); + } + } + + destroy() { + try { + Atspi.exit(); + } catch (e) { + // Silence errors + } + } +}; + diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/components/clipboard.js gnome-shell-extension-zorin-connect-28.0.2/src/service/components/clipboard.js --- gnome-shell-extension-zorin-connect-24.1/src/service/components/clipboard.js 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/components/clipboard.js 2019-11-30 12:14:24.000000000 +0000 @@ -0,0 +1,255 @@ +'use strict'; + +const Gdk = imports.gi.Gdk; +const GLib = imports.gi.GLib; +const Gtk = imports.gi.Gtk; +const Gio = imports.gi.Gio; +const GObject = imports.gi.GObject; + + +var Clipboard = GObject.registerClass({ + GTypeName: 'ZorinConnectClipboard', + Properties: { + 'text': GObject.ParamSpec.string( + 'text', + 'Text Content', + 'The current text content of the clipboard', + GObject.ParamFlags.READWRITE, + null + ) + } +}, class Clipboard extends GObject.Object { + + _init() { + super._init(); + + this._proc = null; + + try { + // On Wayland we use a small subprocess running in XWayland where + // GtkClipboard still functions properly. + if (_WAYLAND) { + this._proc = new Gio.Subprocess({ + argv: [zorin_connect.extdatadir + '/service/components/xclipboard'], + flags: Gio.SubprocessFlags.STDIN_PIPE | + Gio.SubprocessFlags.STDOUT_PIPE | + Gio.SubprocessFlags.STDERR_PIPE + }); + this._proc.init(null); + + // IO Channels + this._stdin = new Gio.DataOutputStream({ + base_stream: this._proc.get_stdin_pipe(), + byte_order: Gio.DataStreamByteOrder.HOST_ENDIAN + }); + + this._stdout = new Gio.DataInputStream({ + base_stream: this._proc.get_stdout_pipe(), + byte_order: Gio.DataStreamByteOrder.HOST_ENDIAN + }); + + this._stderr = new Gio.DataInputStream({ + base_stream: this._proc.get_stderr_pipe(), + byte_order: Gio.DataStreamByteOrder.HOST_ENDIAN + }); + + // Watch for premature exits + this._proc.wait_check_async(null, this._procExit.bind(this)); + + // Watch for clipboard content + let source = this._stdout.base_stream.create_source(null); + source.set_callback(this._readContent.bind(this)); + source.attach(null); + + // Watch for errors + this._readError(this._stderr); + + // If we're in X11/Xorg we're just a wrapper around GtkClipboard + } else { + let display = Gdk.Display.get_default(); + this._clipboard = Gtk.Clipboard.get_default(display); + + this._ownerChangeId = this._clipboard.connect( + 'owner-change', + this._onOwnerChange.bind(this) + ); + } + } catch (e) { + this.destroy(); + throw e; + } + } + + get text() { + if (this._text === undefined) { + this._text = null; + } + + return this._text; + } + + set text(content) { + if (this.text !== content) { + this._text = content; + this.notify('text'); + + this._setText(content); + } + } + + _onTextReceived(clipboard, text) { + this.text = text; + } + + _onTargetsReceived(clipboard, atoms) { + // Empty clipboard + if (atoms === null) { + return this.text = ''; + } + + let hasText = false; + + for (let type of Array.from(atoms)) { + if (type === 'UTF8_STRING') { + hasText = true; + continue; + } + + // Serialized text formats + if (type === 'text/html') + return this.text = null; + + if (type === 'text/rdf' || type === 'text/richtext') + return this.text = null; + + // URI list + if (type === 'text/uri-list') + return this.text = null; + + // Image + if (type.startsWith('image/')) + return this.text = null; + } + + if (hasText) { + clipboard.request_text(this._onTextReceived.bind(this)); + } else { + this.text = ''; + } + } + + _onOwnerChange(clipboard, event) { + clipboard.request_targets(this._onTargetsReceived.bind(this)); + } + + _readContent() { + try { + // Read the message + let length = this._stdout.read_int32(null); + + // We're being sent text content + if (length > 0) { + let text = this._stdout.read_bytes(length, null).toArray(); + + if (text instanceof Uint8Array) { + text = imports.byteArray.toString(text); + } + + this.text = `${text}`; + + // The clipboard was cleared + } else if (length === 0) { + this.text = ''; + + // The clipboard contains non-text content + } else { + this.text = null; + } + + return true; + } catch (e) { + debug(e); + return false; + } + } + + _readError(stderr) { + stderr.read_line_async(GLib.PRIORITY_DEFAULT, null, (stream, res) => { + try { + let line = stream.read_line_finish_utf8(res)[0]; + + if (line !== null) { + logError(new Error(line), 'XClipboard Proxy'); + this._readError(stream); + } + } catch (e) { + debug(e); + } + }); + } + + _writeContent(text) { + // Bail if xclipboard failed + if (!this._proc) { + logError(new Error('XClipboard not running')); + return; + } + + try { + if (text === null) { + this._stdin.put_int32(-1, null); + } else { + this._stdin.put_int32(text.length, null); + this._stdin.put_string(text, null); + } + } catch (e) { + debug(e, 'XClipboard Proxy'); + } + } + + _procExit(proc, res) { + try { + this._proc = null; + this._stdin = this._stdin.close(null); + this._stdout = this._stdout.close(null); + this._stderr = this._stderr.close(null); + + proc.wait_check_finish(res); + } catch (e) { + logError(e, 'XClipboard Proxy'); + } + } + + _setText(text) { + try { + // If we're using the XWayland subprocess, we'll ostensibly write + // anything, so even if it's %null the value can be buffered + if (_WAYLAND) { + this._writeContent(text); + + // If we're wrapping GtkClipboard, we only set actual text content + } else if (text !== null) { + this._clipboard.set_text(text, -1); + } + } catch (e) { + logError(e); + } + } + + destroy() { + if (this._proc) { + this._proc.force_exit(); + } + + if (this._ownerChangeId) { + this._clipboard.disconnect(this._ownerChangeId); + } + } +}); + + +/** + * The service class for this component + */ +var Component = Clipboard; + diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/components/contacts.js gnome-shell-extension-zorin-connect-28.0.2/src/service/components/contacts.js --- gnome-shell-extension-zorin-connect-24.1/src/service/components/contacts.js 2019-03-17 11:53:04.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/components/contacts.js 2019-11-30 12:15:25.000000000 +0000 @@ -59,7 +59,7 @@ this.__cache_lock = true; await JSON.dump(this.__cache_data, this.__cache_file); } catch (e) { - warning(e); + debug(e); } finally { this.__cache_lock = false; @@ -132,7 +132,7 @@ file.replace_contents_finish(res); resolve(file.get_path()); } catch (e) { - warning(e, 'Storing avatar'); + debug(e, 'Storing avatar'); resolve(undefined); } } @@ -267,6 +267,30 @@ } } + /** + * Lookup a contact for each address object in @addresses and return a + * dictionary of address (eg. phone number) to contact object. + * + * { "555-5555": { "name": "...", "numbers": [], ... } } + * + * @param {Array of object} addresses - A list of address objects + * @return {object} - A dictionary of phone numbers and contacts + */ + lookupAddresses(addresses) { + let contacts = {}; + + // Lookup contacts for each address + for (let i = 0, len = addresses.length; i < len; i++) { + let address = addresses[i].address; + + contacts[address] = this.query({ + number: address + }); + } + + return contacts; + } + async clear() { try { let contacts = this.contacts; @@ -277,7 +301,7 @@ await this.__cache_write(); } catch (e) { - warning(e, 'Clearing contacts'); + debug(e, 'Clearing contacts'); } } @@ -307,11 +331,11 @@ await this.__cache_write(); } catch (e) { - warning(e, 'Updating contacts'); + debug(e, 'Updating contacts'); } } - async _loadFolks() { + async fetch() { try { let folks = await new Promise((resolve, reject) => { let proc = this._launcher.spawnv([ @@ -342,11 +366,14 @@ debug(e, 'Loading folks'); } } + + destroy() { + } }); /** * The service class for this component */ -var Service = Store; +var Component = Store; diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/components/dbus.js gnome-shell-extension-zorin-connect-28.0.2/src/service/components/dbus.js --- gnome-shell-extension-zorin-connect-24.1/src/service/components/dbus.js 2019-03-04 02:12:44.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/components/dbus.js 2019-11-30 12:15:40.000000000 +0000 @@ -280,9 +280,7 @@ } _exportMethods(info) { - if (info.methods.length === 0) { - return; - } + if (info.methods.length === 0) return; this.connect('handle-method-call', (impl, name, parameters, invocation) => { return this._call.call( @@ -296,38 +294,47 @@ } _get(info, propertyName) { - // Look up the property info let propertyInfo = info.lookup_property(propertyName); - // Convert to lower_underscore case before getting - let value = this[propertyName.toUnderscoreCase()]; + let value; - // TODO: better pack - if (value != undefined) { - return new GLib.Variant(propertyInfo.signature, value); + // Check before assuming native DBus case + if (this[propertyName] !== undefined) { + value = this[propertyName]; + } else { + value = this[propertyName.toUnderscoreCase()]; } - return null; + if (value !== undefined) { + return new GLib.Variant(propertyInfo.signature, value); + } else { + return null; + } } _set(info, name, value) { + // Unpack the value value = full_unpack(value); + if (this[name] !== undefined) { + this[name] = value; + return; + } + if (!this._propertyCase) { - if (this[name.toUnderscoreCase()]) { + if (this[name.toUnderscoreCase()] !== undefined) { this._propertyCase = 'toUnderScoreCase'; - } else if (this[name.toCamelCase()]) { + } else if (this[name.toCamelCase()] !== undefined) { this._propertyCase = 'toCamelCase'; } } // Convert to lower_underscore case before setting - this[name[this._propertyCase]()] = value; + let nativeName = name[this._propertyCase](); + this[nativeName] = value; } _exportProperties(info) { - if (info.properties.length === 0) { - return; - } + if (info.properties.length === 0) return; this.connect('handle-property-get', (impl, name) => { return this._get.call(this._exportee, info, name); @@ -356,7 +363,7 @@ _exportSignals(info) { for (let signal of info.signals) { - this._exportee.connect(signal.name.toHyphenCase(), (obj, ...args) => { + this._exportee.connect(signal.name, (obj, ...args) => { this.emit_signal( signal.name, new GLib.Variant( diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/components/input.js gnome-shell-extension-zorin-connect-28.0.2/src/service/components/input.js --- gnome-shell-extension-zorin-connect-24.1/src/service/components/input.js 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/components/input.js 2019-11-30 12:16:16.000000000 +0000 @@ -0,0 +1,584 @@ +'use strict'; + +const Gdk = imports.gi.Gdk; +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; +const GObject = imports.gi.GObject; + + +const SESSION_TIMEOUT = 15; + + +const RemoteSession = GObject.registerClass({ + GTypeName: 'ZorinConnectRemoteSession', + Implements: [Gio.DBusInterface], + Properties: { + 'session-id': GObject.ParamSpec.string( + 'session-id', + 'SessionId', + 'The unique session ID', + GObject.ParamFlags.READABLE, + null + ) + }, + Signals: { + 'closed': { + flags: GObject.SignalFlags.RUN_FIRST + } + } +}, class RemoteSession extends Gio.DBusProxy { + + _init(objectPath) { + super._init({ + g_bus_type: Gio.BusType.SESSION, + g_name: 'org.gnome.Mutter.RemoteDesktop', + g_object_path: objectPath, + g_interface_name: 'org.gnome.Mutter.RemoteDesktop.Session' + }); + + this._started = false; + } + + vfunc_g_signal(sender_name, signal_name, parameters) { + if (signal_name === 'Closed') { + this.emit('closed'); + } + } + + get session_id() { + if (this._id === undefined) { + this._id = this.get_cached_property('SessionId').unpack(); + } + + return this._id; + } + + _call(name, parameters = null) { + if (!this._started) return; + + this.call( + name, + parameters, + Gio.DBusCallFlags.NONE, + -1, + null, + (proxy, res) => { + try { + proxy.call_finish(res); + } catch (e) { + Gio.DBusError.strip_remote_error(e); + logError(e); + } + } + ); + } + + async start() { + try { + if (this._started) return; + + // Initialize the proxy + await new Promise((resolve, reject) => { + this.init_async( + GLib.PRIORITY_DEFAULT, + null, + (proxy, res) => { + try { + proxy.init_finish(res); + resolve(); + } catch (e) { + reject(e); + } + } + ); + }); + + // Start the session + await new Promise((resolve, reject) => { + this.call( + 'Start', + null, + Gio.DBusCallFlags.NONE, + -1, + null, + (proxy, res) => { + try { + resolve(proxy.call_finish(res)); + } catch (e) { + reject(e); + } + } + ); + }); + + this._started = true; + } catch (e) { + this.destroy(); + + Gio.DBusError.strip_remote_error(e); + throw e; + } + } + + stop() { + if (this._started) { + this._started = false; + this.call('Stop', null, Gio.DBusCallFlags.NONE, -1, null, null); + } + } + + _translateButton(button) { + switch (button) { + case Gdk.BUTTON_PRIMARY: + return 0x110; + + case Gdk.BUTTON_MIDDLE: + return 0x112; + + case Gdk.BUTTON_SECONDARY: + return 0x111; + + case 4: + return 0; // FIXME + + case 5: + return 0x10F; // up + } + } + + movePointer(dx, dy) { + this._call( + 'NotifyPointerMotionRelative', + GLib.Variant.new('(dd)', [dx, dy]) + ); + } + + pressPointer(button) { + button = this._translateButton(button); + + this._call( + 'NotifyPointerButton', + GLib.Variant.new('(ib)', [button, true]) + ); + } + + releasePointer(button) { + button = this._translateButton(button); + + this._call( + 'NotifyPointerButton', + GLib.Variant.new('(ib)', [button, false]) + ); + } + + clickPointer(button) { + button = this._translateButton(button); + + this._call( + 'NotifyPointerButton', + GLib.Variant.new('(ib)', [button, true]) + ); + + this._call( + 'NotifyPointerButton', + GLib.Variant.new('(ib)', [button, false]) + ); + } + + doubleclickPointer(button) { + this.clickPointer(button); + this.clickPointer(button); + } + + scrollPointer(dx, dy) { + // TODO: NotifyPointerAxis only seems to work on Wayland, but maybe + // NotifyPointerAxisDiscrete is the better choice anyways + if (_WAYLAND) { + this._call( + 'NotifyPointerAxis', + GLib.Variant.new('(ddu)', [dx, dy, 0]) + ); + this._call( + 'NotifyPointerAxis', + GLib.Variant.new('(ddu)', [0, 0, 1]) + ); + } else { + if (dy > 0) { + this._call( + 'NotifyPointerAxisDiscrete', + GLib.Variant.new('(ui)', [Gdk.ScrollDirection.UP, 1]) + ); + } else if (dy < 0) { + this._call( + 'NotifyPointerAxisDiscrete', + GLib.Variant.new('(ui)', [Gdk.ScrollDirection.UP, -1]) + ); + } + } + } + + /** + * Keyboard Events + */ + pressKeysym(keysym) { + this._call( + 'NotifyKeyboardKeysym', + GLib.Variant.new('(ub)', [keysym, true]) + ); + } + + releaseKeysym(keysym) { + this._call( + 'NotifyKeyboardKeysym', + GLib.Variant.new('(ub)', [keysym, false]) + ); + } + + pressreleaseKeysym(keysym) { + this._call( + 'NotifyKeyboardKeysym', + GLib.Variant.new('(ub)', [keysym, true]) + ); + this._call( + 'NotifyKeyboardKeysym', + GLib.Variant.new('(ub)', [keysym, false]) + ); + } + + /** + * High-level keyboard input + */ + pressKey(input, modifiers) { + // Press Modifiers + if (modifiers & Gdk.ModifierType.MOD1_MASK) this.pressKeysym(Gdk.KEY_Alt_L); + if (modifiers & Gdk.ModifierType.CONTROL_MASK) this.pressKeysym(Gdk.KEY_Control_L); + if (modifiers & Gdk.ModifierType.SHIFT_MASK) this.pressKeysym(Gdk.KEY_Shift_L); + if (modifiers & Gdk.ModifierType.SUPER_MASK) this.pressKeysym(Gdk.KEY_Super_L); + + if (typeof input === 'string') { + let keysym = Gdk.unicode_to_keyval(input.codePointAt(0)); + this.pressreleaseKeysym(keysym); + } else { + this.pressreleaseKeysym(input); + } + + // Release Modifiers + if (modifiers & Gdk.ModifierType.MOD1_MASK) this.releaseKeysym(Gdk.KEY_Alt_L); + if (modifiers & Gdk.ModifierType.CONTROL_MASK) this.releaseKeysym(Gdk.KEY_Control_L); + if (modifiers & Gdk.ModifierType.SHIFT_MASK) this.releaseKeysym(Gdk.KEY_Shift_L); + if (modifiers & Gdk.ModifierType.SUPER_MASK) this.releaseKeysym(Gdk.KEY_Super_L); + } + + destroy() { + if (this.__disposed === undefined) { + this.__disposed = true; + this.run_dispose(); + } + } +}); + + +const Controller = class Controller { + constructor() { + this._adapter = null; + this._nameAppearedId = 0; + this._sessionCloseId = 0; + this._sessionExpiry = 0; + this._sessionExpiryId = 0; + this._sessionStarting = false; + + // Watch for the RemoteDesktop portal + this._nameWatcherId = Gio.bus_watch_name( + Gio.BusType.SESSION, + 'org.gnome.Mutter.RemoteDesktop', + Gio.BusNameWatcherFlags.NONE, + this._onNameAppeared.bind(this), + this._onNameVanished.bind(this) + ); + } + + get connection() { + if (this._connection === undefined) { + this._connection = null; + } + + return this._connection; + } + + _onNameAppeared(connection, name, name_owner) { + try { + // Destroy any old Atspi adapter + if (!this.connection && this._adapter) { + this._adapter.destroy(); + this._adapter = null; + } + + this._connection = connection; + } catch (e) { + logError(e); + } + } + + _onNameVanished(connection, name) { + try { + // Destroy any old RemoteDesktop session + if (this._adapter instanceof RemoteSession) { + // Disconnect from the session + if (this._sessionClosedId > 0) { + this._adapter.disconnect(this._sessionClosedId); + this._sessionClosedId = 0; + } + + // Destroy the session + this._adapter.destroy(); + this._adapter = null; + } + + this._connection = null; + } catch (e) { + logError(e); + } + } + + _onSessionClosed(session) { + // Disconnect from the session + if (this._sessionClosedId > 0) { + session.disconnect(this._sessionClosedId); + this._sessionClosedId = 0; + } + + // Destroy the session + session.destroy(); + this._adapter = null; + } + + _onSessionExpired() { + // If the session has been used recently, schedule a new expiry + let remainder = Math.floor(this._sessionExpiry - (Date.now() / 1000)); + + if (remainder > 0) { + this._sessionExpiryId = GLib.timeout_add_seconds( + GLib.PRIORITY_DEFAULT, + remainder, + this._onSessionExpired.bind(this) + ); + + return GLib.SOURCE_REMOVE; + } + + // If there's a current session, close it + if (this._adapter instanceof RemoteSession) { + this._adapter.stop(); + } + + // Reset the GSource Id + this._sessionExpiryId = 0; + + return GLib.SOURCE_REMOVE; + } + + _createSession() { + return new Promise((resolve, reject) => { + if (this.connection === null) { + reject(new Error('No DBus connection')); + return; + } + + this.connection.call( + 'org.gnome.Mutter.RemoteDesktop', + '/org/gnome/Mutter/RemoteDesktop', + 'org.gnome.Mutter.RemoteDesktop', + 'CreateSession', + null, + null, + Gio.DBusCallFlags.NONE, + -1, + null, + (connection, res) => { + try { + res = connection.call_finish(res); + resolve(res.deep_unpack()[0]); + } catch (e) { + reject(e); + } + } + ); + }); + } + + async _ensureAdapter() { + try { + // Update the timestamp of the last event + this._sessionExpiry = Math.floor((Date.now() / 1000) + SESSION_TIMEOUT); + + // Adapter is ensured + if (this._adapter) return; + + // Mutter's RemoteDesktop portal is not available + if (!this.connection) { + debug('Falling back to Atspi'); + + let fallback = imports.service.components.atspi; + this._adapter = new fallback.Controller(); + + // Mutter is available and there isn't another session starting + } else if (this._sessionStarting === false) { + debug('Creating Mutter RemoteDesktop session'); + + this._sessionStarting = true; + + let objectPath = await this._createSession(); + this._adapter = new RemoteSession(objectPath); + this._adapter.start(); + + this._sessionClosedId = this._adapter.connect( + 'closed', + this._onSessionClosed.bind(this) + ); + + if (this._sessionExpiryId === 0) { + this._sessionExpiryId = GLib.timeout_add_seconds( + GLib.PRIORITY_DEFAULT, + SESSION_TIMEOUT, + this._onSessionExpired.bind(this) + ); + } + } + } catch (e) { + logError(e); + + this._adapter.destroy(); + this._adapter = null; + } finally { + this._sessionStarting = false; + } + } + + /** + * Pointer Events + */ + movePointer(dx, dy) { + try { + if (dx === 0 && dy === 0) return; + + this._ensureAdapter(); + this._adapter.movePointer(dx, dy); + } catch (e) { + debug(e); + } + } + + pressPointer(button) { + try { + this._ensureAdapter(); + this._adapter.pressPointer(button); + } catch (e) { + debug(e); + } + } + + releasePointer(button) { + try { + this._ensureAdapter(); + this._adapter.releasePointer(button); + } catch (e) { + debug(e); + } + } + + clickPointer(button) { + try { + this._ensureAdapter(); + this._adapter.clickPointer(button); + } catch (e) { + debug(e); + } + } + + doubleclickPointer(button) { + try { + this._ensureAdapter(); + this._adapter.doubleclickPointer(button); + } catch (e) { + debug(e); + } + } + + scrollPointer(dx, dy) { + if (dx === 0 && dy === 0) return; + + try { + this._ensureAdapter(); + this._adapter.scrollPointer(dx, dy); + } catch (e) { + debug(e); + } + } + + /** + * Keyboard Events + */ + pressKeysym(keysym) { + try { + this._ensureAdapter(); + this._adapter.pressKeysym(keysym); + } catch (e) { + debug(e); + } + } + + releaseKeysym(keysym) { + try { + this._ensureAdapter(); + this._adapter.releaseKeysym(keysym); + } catch (e) { + debug(e); + } + } + + pressreleaseKeysym(keysym) { + try { + this._ensureAdapter(); + this._adapter.pressreleaseKeysym(keysym); + } catch (e) { + debug(e); + } + } + + /** + * High-level keyboard input + */ + pressKey(input, modifiers) { + try { + this._ensureAdapter(); + this._adapter.pressKey(input, modifiers); + } catch (e) { + debug(e); + } + } + + destroy() { + if (this._adapter !== null) { + // Disconnect from the session + if (this._sessionClosedId > 0) { + this._adapter.disconnect(this._sessionClosedId); + this._sessionClosedId = 0; + } + + this._adapter.destroy(); + this._adapter = null; + } + + if (this._nameWatcherId > 0) { + Gio.bus_unwatch_name(this._nameWatcherId); + this._nameWatcherId = 0; + } + } +}; + + +/** + * The service class for this component + */ +var Component = Controller; + diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/components/mpris.js gnome-shell-extension-zorin-connect-28.0.2/src/service/components/mpris.js --- gnome-shell-extension-zorin-connect-24.1/src/service/components/mpris.js 2019-03-05 21:20:38.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/components/mpris.js 2019-11-30 12:17:24.000000000 +0000 @@ -81,7 +81,8 @@ for (let i = 0, len = names.length; i < len; i++) { let name = names[i]; - if (name.startsWith('org.mpris.MediaPlayer2')) { + if (name.startsWith('org.mpris.MediaPlayer2') && + !name.includes('ZorinConnect')) { this._addPlayer(name); } } @@ -121,7 +122,8 @@ if (signal_name === 'NameOwnerChanged') { let [name, old_owner, new_owner] = parameters.deep_unpack(); - if (name.startsWith('org.mpris.MediaPlayer2')) { + if (name.startsWith('org.mpris.MediaPlayer2') && + !name.includes('ZorinConnect')) { if (new_owner.length) { this._addPlayer(name); } else if (old_owner.length) { @@ -252,5 +254,5 @@ /** * The service class for this component */ -var Service = Manager; +var Component = Manager; diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/components/notification.js gnome-shell-extension-zorin-connect-28.0.2/src/service/components/notification.js --- gnome-shell-extension-zorin-connect-24.1/src/service/components/notification.js 2019-03-17 11:54:53.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/components/notification.js 2019-11-30 12:18:25.000000000 +0000 @@ -420,15 +420,22 @@ destroy() { try { - this._fdoNotifications.disconnect(this._fdoMethodCallId); - this._fdoNotifications.flush(); - this._fdoNotifications.unexport(); - - this._gtkNotifications.disconnect(this._gtkMethodCallId); - this._gtkNotifications.flush(); - this._gtkNotifications.unexport(); - - this._settings.disconnect(this._settingsId); + if (this._fdoNotifications) { + this._fdoNotifications.disconnect(this._fdoMethodCallId); + this._fdoNotifications.flush(); + this._fdoNotifications.unexport(); + } + + if (this._gtkNotifications) { + this._gtkNotifications.disconnect(this._gtkMethodCallId); + this._gtkNotifications.flush(); + this._gtkNotifications.unexport(); + } + + if (this._settings) { + this._settings.disconnect(this._settingsId); + this._settings.run_dispose(); + } // TODO: Gio.IOErrorEnum: The connection is closed //this._monitor.close_sync(null); @@ -442,5 +449,5 @@ /** * The service class for this component */ -var Service = Listener; +var Component = Listener; diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/components/pulseaudio.js gnome-shell-extension-zorin-connect-28.0.2/src/service/components/pulseaudio.js --- gnome-shell-extension-zorin-connect-24.1/src/service/components/pulseaudio.js 2019-03-05 21:20:46.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/components/pulseaudio.js 2019-11-30 12:21:17.000000000 +0000 @@ -36,8 +36,10 @@ */ class Stream { constructor(mixer, stream) { - this._max = mixer.get_vol_max_norm(); + this._mixer = mixer; this._stream = stream; + + this._max = mixer.get_vol_max_norm(); } get muted() { @@ -61,22 +63,26 @@ /** * Gradually raise or lower the stream volume to @value * - * @param {Number} value - A number in the range 0-1 + * @param {number} value - A number in the range 0-1 + * @param {number} [duration] - Duration to fade in seconds */ - fade(value) { + fade(value, duration = 1) { Tweener.removeTweens(this); + this._mixer.fading = true; if (this._stream.volume > value) { Tweener.addTween(this, { volume: value, - time: 1, - transition: 'easeOutCubic' + time: duration, + transition: 'easeOutCubic', + onComplete: () => this._mixer.fading = false }); } else if (this._stream.volume < value) { Tweener.addTween(this, { volume: value, - time: 1, - transition: 'easeInCubic' + time: duration, + transition: 'easeInCubic', + onComplete: () => this._mixer.fading = false }); } } @@ -103,6 +109,24 @@ this._microphoneMuted = false; } + get fading() { + if (this._fading === undefined) { + this._fading = false; + } + + return this._fading; + } + + set fading(bool) { + if (this.fading !== bool) { + this._fading = bool; + + if (!this.fading) { + this.emit('stream-changed', this._output._stream.id); + } + } + } + get input() { if (this._input === undefined) { this.vfunc_default_source_changed(); @@ -151,11 +175,11 @@ /** * Store the current output volume then lower it to %15 */ - lowerVolume() { + lowerVolume(duration = 1) { try { if (this.output.volume > 0.15) { this._previousVolume = Number(this.output.volume); - this.output.fade(0.15); + this.output.fade(0.15, duration); } } catch (e) { logError(e); @@ -216,11 +240,14 @@ logError(e); } } + + destroy() { + } }); /** * The service class for this component */ -var Service = Mixer; +var Component = Mixer; diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/components/session.js gnome-shell-extension-zorin-connect-28.0.2/src/service/components/session.js --- gnome-shell-extension-zorin-connect-24.1/src/service/components/session.js 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/components/session.js 2019-11-01 23:59:50.000000000 +0000 @@ -0,0 +1,120 @@ +'use strict'; + +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; + + +const Session = class { + constructor() { + this._connection = Gio.DBus.system; + this._session = null; + + this._initAsync(); + } + + async _initAsync() { + try { + let userName = GLib.get_user_name(); + let sessions = await this._listSessions(); + let sessionPath = '/org/freedesktop/login1/session/auto'; + + // eslint-disable-next-line no-unused-vars + for (let [num, uid, name, seat, objectPath] of sessions) { + if (name === userName) { + sessionPath = objectPath; + break; + } + } + + this._session = await this._getSession(sessionPath); + } catch (e) { + this._session = null; + logError(e); + } + } + + get idle() { + if (this._session === null) { + return false; + } + + return this._session.get_cached_property('IdleHint').unpack(); + } + + get locked() { + if (this._session === null) { + return false; + } + + return this._session.get_cached_property('LockedHint').unpack(); + } + + get active() { + // Active if not idle and not locked + return !(this.idle || this.locked); + } + + _listSessions() { + return new Promise((resolve, reject) => { + this._connection.call( + 'org.freedesktop.login1', + '/org/freedesktop/login1', + 'org.freedesktop.login1.Manager', + 'ListSessions', + null, + null, + Gio.DBusCallFlags.NONE, + -1, + null, + (connection, res) => { + try { + res = connection.call_finish(res); + resolve(res.deep_unpack()[0]); + } catch (e) { + reject(e); + } + } + ); + }); + } + + async _getSession(objectPath) { + let session = new Gio.DBusProxy({ + g_connection: this._connection, + g_name: 'org.freedesktop.login1', + g_object_path: objectPath, + g_interface_name: 'org.freedesktop.login1.Session' + }); + + // Initialize the proxy + await new Promise((resolve, reject) => { + session.init_async( + GLib.PRIORITY_DEFAULT, + null, + (proxy, res) => { + try { + resolve(proxy.init_finish(res)); + } catch (e) { + Gio.DBusError.strip_remote_error(e); + reject(e); + } + } + ); + }); + + return session; + } + + destroy() { + if (this._session !== null) { + this._session.run_dispose(); + } + } +}; + + +/** + * The service class for this component + */ +var Component = Session; + diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/components/sound.js gnome-shell-extension-zorin-connect-28.0.2/src/service/components/sound.js --- gnome-shell-extension-zorin-connect-24.1/src/service/components/sound.js 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/components/sound.js 2019-11-01 23:59:50.000000000 +0000 @@ -0,0 +1,201 @@ +'use strict'; + +const Gdk = imports.gi.Gdk; +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; +const GObject = imports.gi.GObject; + + +/** + * Used to ensure 'audible-bell' is enabled for fallback + */ +const WM_SETTINGS = new Gio.Settings({ + schema_id: 'org.gnome.desktop.wm.preferences', + path: '/org/gnome/desktop/wm/preferences/' +}); + + +var Sound = class Sound { + + constructor() { + } + + get backend() { + if (this._backend === undefined) { + // Prefer GSound + try { + this._gsound = new imports.gi.GSound.Context(); + this._gsound.init(null); + this._backend = 'gsound'; + + // Try falling back to libcanberra, otherwise just re-run the test + // in case one or the other is installed later + } catch (e) { + if (GLib.find_program_in_path('canberra-gtk-play') !== null) { + this._canberra = new Gio.SubprocessLauncher({ + flags: Gio.SubprocessFlags.NONE + }); + this._backend = 'libcanberra'; + } else { + return null; + } + } + } + + return this._backend; + } + + get playing() { + if (this._playing === undefined) { + this._playing = new Set(); + } + + return this._playing; + } + + _canberraPlaySound(name, cancellable) { + return new Promise((resolve, reject) => { + let proc = this._canberra.spawnv(['canberra-gtk-play', '-i', name]); + + proc.wait_check_async(cancellable, (proc, res) => { + try { + resolve(proc.wait_check_finish(res)); + } catch (e) { + reject(e); + } + }); + }); + } + + async _canberraLoopSound(name, cancellable) { + while (!cancellable.is_cancelled()) { + await this._canberraPlaySound(name, cancellable); + } + } + + _gsoundPlaySound(name, cancellable) { + return new Promise((resolve, reject) => { + this._gsound.play_full( + {'event.id': name}, + cancellable, + (source, res) => { + try { + resolve(source.play_full_finish(res)); + } catch (e) { + reject(e); + } + } + ); + }); + } + + async _gsoundLoopSound(name, cancellable) { + while (!cancellable.is_cancelled()) { + await this._gsoundPlaySound(name, cancellable); + } + } + + _gdkPlaySound(name, cancellable) { + if (this._display === undefined) { + this._display = Gdk.Display.get_default(); + } + + let count = 0; + + GLib.timeout_add(GLib.PRIORITY_DEFAULT, 200, () => { + try { + if (count++ < 4 && !cancellable.is_cancelled()) { + this._display.beep(); + return GLib.SOURCE_CONTINUE; + } + + return GLib.SOURCE_REMOVE; + } catch (e) { + logError(e); + return GLib.SOURCE_REMOVE; + } + }); + + return !cancellable.is_cancelled(); + } + + _gdkLoopSound(name, cancellable) { + this._gdkPlaySound(name, cancellable); + GLib.timeout_add( + GLib.PRIORITY_DEFAULT, + 1500, + this._gdkPlaySound.bind(this, name, cancellable) + ); + } + + async playSound(name, cancellable) { + try { + if (!(cancellable instanceof Gio.Cancellable)) { + cancellable = new Gio.Cancellable(); + } + + this.playing.add(cancellable); + + switch (this.backend) { + case 'gsound': + await this._gsoundPlaySound(name, cancellable); + break; + + case 'canberra': + await this._canberraPlaySound(name, cancellable); + break; + + default: + await this._gdkPlaySound(name, cancellable); + } + } catch (e) { + if (!e.code || e.code !== Gio.IOErrorEnum.CANCELLED) { + logError(e); + } + } finally { + this.playing.delete(cancellable); + } + } + + async loopSound(name, cancellable) { + try { + if (!(cancellable instanceof Gio.Cancellable)) { + cancellable = new Gio.Cancellable(); + } + + this.playing.add(cancellable); + + switch (this.backend) { + case 'gsound': + await this._gsoundLoopSound(name, cancellable); + break; + + case 'canberra': + await this._canberraLoopSound(name, cancellable); + break; + + default: + await this._gdkLoopSound(name, cancellable); + } + } catch (e) { + if (!e.code || e.code !== Gio.IOErrorEnum.CANCELLED) { + logError(e); + } + } finally { + this.playing.delete(cancellable); + } + } + + destroy() { + for (let cancellable of this.playing) { + cancellable.cancel(); + } + } +}; + + +/** + * The service class for this component + */ +var Component = Sound; + diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/components/upower.js gnome-shell-extension-zorin-connect-28.0.2/src/service/components/upower.js --- gnome-shell-extension-zorin-connect-24.1/src/service/components/upower.js 2019-03-04 02:11:56.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/components/upower.js 2019-11-30 12:21:50.000000000 +0000 @@ -14,7 +14,7 @@ _init() { super._init(); - // This will throw an exception + // This may throw an exception? this.set_object_path_sync( '/org/freedesktop/UPower/devices/DisplayDevice', null @@ -49,11 +49,14 @@ return 0; } } + + destroy() { + } }); /** * The service class for this component */ -var Service = Battery; +var Component = Battery; diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/components/xclipboard gnome-shell-extension-zorin-connect-28.0.2/src/service/components/xclipboard --- gnome-shell-extension-zorin-connect-24.1/src/service/components/xclipboard 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/components/xclipboard 2019-11-01 23:59:50.000000000 +0000 @@ -0,0 +1,148 @@ +#!/usr/bin/env gjs + +'use strict'; + +imports.gi.versions.Gdk = '3.0'; +imports.gi.versions.Gio = '2.0'; +imports.gi.versions.Gtk = '3.0'; + +const Gdk = imports.gi.Gdk; +const Gio = imports.gi.Gio; +const Gtk = imports.gi.Gtk; + +/* + * We set the X11 backend as default to force XWayland + */ +Gdk.set_allowed_backends('x11,*'); +Gtk.init(null); + +const clipboard = Gtk.Clipboard.get_default(Gdk.Display.get_default()); +var buffer = null; + + +/* + * We use stdin and stdout to pipe changes to the parent process, using a + * protocol very similar to native messaging hosts. A 32-bit integer is written + * indicating the length in bytes of the content that will follow. + */ +const stdin = new Gio.DataInputStream({ + base_stream: new Gio.UnixInputStream({fd: 0}), + byte_order: Gio.DataStreamByteOrder.HOST_ENDIAN +}); + +const stdout = new Gio.DataOutputStream({ + base_stream: new Gio.UnixOutputStream({fd: 1}), + byte_order: Gio.DataStreamByteOrder.HOST_ENDIAN +}); + + +/* + * Watch GtkClipboard for changes and write them to stdout + */ +function writeContent(clipboard, text) { + // Avoid duplicate copies + if (text === buffer) return; + + try { + buffer = text; + + // Non-textual content + if (text === null) { + stdout.put_int32(-1, null); + + // Text content (including empty string) + } else { + stdout.put_int32(text.length, null); + stdout.put_string(text, null); + } + } catch (e) { + printerr(e.message); + } +} + +function onOwnerChange(clipboard, event) { + let atoms = clipboard.wait_for_targets()[1]; + + // TODO: This often means the selection owner has disappeared, which happens + // frequently in Wayland because Mutter seems to use a temporary selection. + // However, it's difficult or impossible to tell if we should clear it. + if (atoms.length === 0) return; + + let hasText = false; + + for (let type of Array.from(atoms)) { + if (type === 'UTF8_STRING') { + hasText = true; + continue; + } + + // Serialized text formats + if (type === 'text/html') + return writeContent(clipboard, null); + + if (type === 'text/rdf' || type === 'text/richtext') + return writeContent(clipboard, null); + + // URI list + if (type === 'text/uri-list') + return writeContent(clipboard, null); + + // Image + if (type.startsWith('image/')) + return writeContent(clipboard, null); + } + + if (hasText) { + clipboard.request_text(writeContent); + } else { + writeContent(clipboard, ''); + } +} + +clipboard.connect('owner-change', onOwnerChange); + + +/* + * Watch stdin for changes and apply them to GtkClipboard + */ +function readContent(text) { + try { + // Read the message + let length = stdin.read_int32(null); + + // Text content + if (length > 0) { + let text = stdin.read_bytes(length, null).toArray(); + + if (text instanceof Uint8Array) { + text = imports.byteArray.toString(text); + } + + // Set the buffer and GtkClipboard + buffer = `${text}`; + clipboard.set_text(buffer, -1); + + // We're being asked to clear the clipboard + } else if (length === 0) { + buffer = ''; + clipboard.clear(); + + // We currently don't support non-text content, so this is a no-op + } else if (length === -1) { + buffer = null; + } + } catch (e) { + // If there's an error reading we exit so we don't end up in a bad loop + printerr(e.message); + Gtk.main_quit(); + } + + return true; +} + +let source = stdin.base_stream.create_source(null); +source.set_callback(readContent); +source.attach(null); + +Gtk.main(); + diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/daemon.js gnome-shell-extension-zorin-connect-28.0.2/src/service/daemon.js --- gnome-shell-extension-zorin-connect-24.1/src/service/daemon.js 2019-03-18 11:05:07.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/daemon.js 2019-11-30 18:52:50.000000000 +0000 @@ -2,11 +2,6 @@ 'use strict'; -const Gettext = imports.gettext.domain('org.gnome.Shell.Extensions.ZorinConnect'); -const _ = Gettext.gettext; -const System = imports.system; - -imports.gi.versions.Atspi = '2.0'; imports.gi.versions.Gdk = '3.0'; imports.gi.versions.GdkPixbuf = '2.0'; imports.gi.versions.Gio = '2.0'; @@ -34,26 +29,15 @@ imports._zorin_connect; // Local Imports -const Bluetooth = imports.service.protocol.bluetooth; const Core = imports.service.protocol.core; const Device = imports.service.device; -const Lan = imports.service.protocol.lan; const ServiceUI = imports.service.ui.service; -const Settings = imports.service.ui.settings; const Service = GObject.registerClass({ GTypeName: 'ZorinConnectService', Properties: { - 'devices': GObject.param_spec_variant( - 'devices', - 'Devices', - 'A list of known devices', - new GLib.VariantType('as'), - null, - GObject.ParamFlags.READABLE - ), 'discoverable': GObject.ParamSpec.boolean( 'discoverable', 'Discoverable', @@ -61,19 +45,19 @@ GObject.ParamFlags.READWRITE, false ), + 'id': GObject.ParamSpec.string( + 'id', + 'Id', + 'The service id', + GObject.ParamFlags.READWRITE, + null + ), 'name': GObject.ParamSpec.string( 'name', 'deviceName', 'The name announced to the network', GObject.ParamFlags.READWRITE, 'ZorinConnect' - ), - 'type': GObject.ParamSpec.string( - 'type', - 'deviceType', - 'The service device type', - GObject.ParamFlags.READABLE, - 'desktop' ) } }, class Service extends Gtk.Application { @@ -84,34 +68,34 @@ flags: Gio.ApplicationFlags.HANDLES_OPEN }); - GLib.set_prgname(zorin_connect.app_id); - GLib.set_application_name('ZorinConnect'); + GLib.set_prgname('Zorin Connect'); + GLib.set_application_name('Zorin Connect'); // Track devices with id as key this._devices = new Map(); - - // Properties - zorin_connect.settings.bind('discoverable', this, 'discoverable', 0); - zorin_connect.settings.bind('public-name', this, 'name', 0); + + // Command-line + this._initOptions(); } - get certificate() { - if (this._certificate === undefined) { - this._certificate = Gio.TlsCertificate.new_for_paths( - GLib.build_filenamev([zorin_connect.configdir, 'certificate.pem']), - GLib.build_filenamev([zorin_connect.configdir, 'private.pem']) - ); + get backends() { + if (this._backends === undefined) { + this._backends = new Map(); } - return this._certificate; + return this._backends; } - get devices() { - return Array.from(this._devices.keys()); + get components() { + if (this._components === undefined) { + this._components = new Map(); + } + + return this._components; } - get fingerprint() { - return this.certificate.fingerprint(); + get devices() { + return Array.from(this._devices.values()); } get identity() { @@ -120,10 +104,9 @@ id: 0, type: 'kdeconnect.identity', body: { - deviceId: this.certificate.common_name, + deviceId: this.id, deviceName: this.name, - deviceType: this.type, - tcpPort: 1716, + deviceType: this._getDeviceType(), protocolVersion: 7, incomingCapabilities: [], outgoingCapabilities: [] @@ -131,9 +114,6 @@ }); for (let name in imports.service.plugins) { - // Don't report clipbaord/mousepad support in Wayland sessions - if (_WAYLAND && ['clipboard', 'mousepad'].includes(name)) continue; - let meta = imports.service.plugins[name].Metadata; if (!meta) continue; @@ -151,75 +131,27 @@ return this._identity; } - get type() { - if (this._type === undefined) { - try { - let type = GLib.file_get_contents('/sys/class/dmi/id/chassis_type')[1]; - - if (type instanceof Uint8Array) { - type = imports.byteArray.toString(type); - } - - type = Number(type); - this._type = [8, 9, 10, 14].includes(type) ? 'laptop' : 'desktop'; - } catch (e) { - this._type = 'desktop'; - } - } - - return this._type; - } - /** - * Send identity to @address or broadcast if %null - * - * @param {string|Gio.InetSocketAddress} - TCP address, bluez path or %null + * Helpers */ - broadcast(address = null) { + _getDeviceType() { try { - switch (true) { - case (address instanceof Gio.InetSocketAddress): - this.lan.broadcast(address); - break; - - case (typeof address === 'string'): - this.bluetooth.broadcast(address); - break; - - // If not discoverable we'll only broadcast to paired devices - case !this.discoverable: - this.reconnect(); - break; + let type = GLib.file_get_contents('/sys/class/dmi/id/chassis_type')[1]; - // We only do true "broadcasts" for LAN - default: - this.lan.broadcast(); + if (type instanceof Uint8Array) { + type = imports.byteArray.toString(type); } - } catch (e) { - logError(e); - } - } - /** - * Try to reconnect to each paired device that has disconnected - */ - reconnect() { - for (let [id, device] of this._devices.entries()) { - if (!device.connected) { - if (device.paired) { - device.activate(); + type = Number(type); - // Prune the device if the settings window is not open - } else if (!this._window || !this._window.visible) { - device.destroy(); - this._devices.delete(id); - zorin_connect.settings.set_strv('devices', this.devices); - this.notify('devices'); - } + if ([8, 9, 10, 14].includes(type)) { + return 'laptop'; } - } - return GLib.SOURCE_CONTINUE; + return 'desktop'; + } catch (e) { + return 'desktop'; + } } /** @@ -244,7 +176,7 @@ }); if (unpaired.length === 3 && this.discoverable) { - this.activate_action('discoverable', null); + this.discoverable = false; let error = new Error(); error.name = 'DiscoveryWarning'; @@ -253,58 +185,91 @@ device = new Device.Device(packet); this._devices.set(device.id, device); - device.loadPlugins(); - zorin_connect.settings.set_strv('devices', this.devices); - this.notify('devices'); + // Notify + this.settings.set_strv( + 'devices', + Array.from(this._devices.keys()) + ); } return device; } /** - * Delete a known device. + * Permanently remove a device. * - * Removes the device from the list of known devices, unpairs it, destroys - * it and deletes all GSettings and cached files. + * Removes the device from the list of known devices, deletes all GSettings + * and files. * * @param {String} id - The id of the device to delete */ - deleteDevice(id) { - let device = this._devices.get(id); + _removeDevice(id) { + // Delete all GSettings + let settings_path = '/org/gnome/shell/extensions/zorin-connect/' + id + '/'; + GLib.spawn_command_line_async(`dconf reset -f ${settings_path}`); + + // Delete the cache + let cache = GLib.build_filenamev([zorin_connect.cachedir, id]); + Gio.File.rm_rf(cache); + + // Forget the device + this._devices.delete(id); + this.settings.set_strv( + 'devices', + Array.from(this._devices.keys()) + ); + } - if (device) { - // Stash the settings path before unpairing and removing - let settings_path = device.settings.path; - device.sendPacket({type: 'kdeconnect.pair', pair: 'false'}); + /** + * GSettings + */ + _initSettings() { + this.settings = new Gio.Settings({ + settings_schema: zorin_connect.gschema.lookup(zorin_connect.app_id, true) + }); - // - device.destroy(); - this._devices.delete(id); + // TODO: added v25, remove after a few releases + let publicName = this.settings.get_string('public-name'); - // Delete all GSettings - GLib.spawn_command_line_async(`dconf reset -f ${settings_path}`); + if (publicName.length > 0) { + this.settings.set_string('name', publicName); + this.settings.reset('public-name'); + } - // Delete the cache - let cache = GLib.build_filenamev([zorin_connect.cachedir, id]); - Gio.File.rm_rf(cache); + // Bound Properties + this.settings.bind('discoverable', this, 'discoverable', 0); + this.settings.bind('id', this, 'id', 0); + this.settings.bind('name', this, 'name', 0); - // Notify - zorin_connect.settings.set_strv('devices', this.devices); - this.notify('devices'); + // Set the default name to the computer's hostname + if (this.name.length === 0) { + this.settings.set_string('name', GLib.get_host_name()); } + + // Keep identity updated and broadcast any name changes + this._nameChangedId = this.settings.connect( + 'changed::name', + this._onNameChanged.bind(this) + ); + } + + _onNameChanged(settings, key) { + this.identity.body.deviceName = this.name; + this._identify(); } /** - * Service GActions + * GActions */ _initActions() { let actions = [ - ['broadcast', this.broadcast.bind(this)], - ['devel', this._devel.bind(this)], + ['connect', this._identify.bind(this), 's'], ['device', this._device.bind(this), '(ssbv)'], ['error', this._error.bind(this), 'a{ss}'], - ['settings', this._settings.bind(this)] + ['preferences', this._preferences], + ['quit', () => this.quit()], + ['refresh', this._identify.bind(this)] ]; for (let [name, callback, type] of actions) { @@ -315,8 +280,6 @@ action.connect('activate', callback); this.add_action(action); } - - this.add_action(zorin_connect.settings.create_action('discoverable')); } /** @@ -331,26 +294,34 @@ * @param {GLib.Variant(v)} parameter[3] - GAction parameter */ _device(action, parameter) { - parameter = parameter.unpack(); + try { + parameter = parameter.unpack(); - let id = parameter[0].unpack(); - let devices = (id === '*') ? this._devices.values() : [this._devices.get(id)]; + // Select the appropriate device(s) + let devices; + let id = parameter[0].unpack(); + + if (id === '*') { + devices = this._devices.values(); + } else { + devices = [this._devices.get(id)]; + } - for (let device of devices) { - // If the device is available - if (device) { - device.activate_action( - parameter[1].unpack(), - parameter[2].unpack() ? parameter[3].unpack() : null - ); + // Unpack the action data + let name = parameter[1].unpack(); + let target = parameter[2].unpack() ? parameter[3].unpack() : null; + + // Activate the action on each available device + for (let device of devices) { + if (device) { + device.activate_action(name, target); + } } + } catch (e) { + logError(e); } } - _devel() { - (new imports.service.ui.devel.Window()).present(); - } - _error(action, parameter) { try { let error = parameter.deep_unpack(); @@ -377,25 +348,142 @@ } } - _settings(page = null, parameter = null) { - if (parameter instanceof GLib.Variant) { - page = parameter.unpack(); + _identify(action, parameter) { + try { + // If we're passed a parameter, try and find a backend for it + if (parameter instanceof GLib.Variant) { + let uri = parameter.unpack(); + let [scheme, address] = uri.split('://'); + + let backend = this.backends.get(scheme); + + if (backend) { + backend.broadcast(address); + } + + // If we're not discoverable, only try to reconnect known devices + } else if (!this.discoverable) { + this._reconnect(); + + // Otherwise have each backend broadcast to it's network + } else { + for (let backend of this.backends.values()) { + backend.broadcast(); + } + } + } catch (e) { + logError(e); + } + } + + _preferences() { + let proc = new Gio.Subprocess({ + argv: [zorin_connect.extdatadir + '/zorin-connect-preferences'] + }); + proc.init(null); + proc.wait_async(null, null); + } + + /** + * A GSourceFunc that tries to reconnect to each paired device, while + * pruning unpaired devices that have disconnected. + */ + _reconnect() { + for (let [id, device] of this._devices.entries()) { + switch (true) { + case device.connected: + break; + + case device.paired: + device.activate(); + break; + + default: + this._removeDevice(id); + device.destroy(); + } } - if (!this._window) { - this._window = new Settings.Window(); + return GLib.SOURCE_CONTINUE; + } + + /** + * Components + */ + _initComponents() { + for (let name in imports.service.components) { + try { + let module = imports.service.components[name]; + + if (module.hasOwnProperty('Component')) { + let component = new module.Component(); + this.components.set(name, component); + } + } catch (e) { + logError(e, `'${name}' Component`); + } } + } - // Open to a specific page - if (typeof page === 'string' && this._window.stack.get_child_by_name(page)) { - this._window._onDeviceSelected(page); + /** + * Backends + * + * These are the implementations of Core.ChannelService that emit + * Core.ChannelService::channel with objects implementing Core.Channel. + */ + _onChannel(backend, channel) { + try { + let device = this._devices.get(channel.identity.body.deviceId); - // Open the main page - } else { - this._window._onPrevious(); + switch (true) { + // Proceed if this is an existing device... + case (device !== undefined): + break; + + // Or the service is discoverable... + case this.discoverable: + device = this._ensureDevice(channel.identity); + break; + + // ...otherwise bail + default: + debug(`${channel.identity.body.deviceName}: not allowed`); + return false; + } + + channel.attach(device); + return true; + } catch (e) { + logError(e, backend.name); + return false; } + } - this._window.present(); + _initBackends() { + let backends = [ + //'bluetooth', + 'lan' + ]; + + for (let name of backends) { + try { + // Try to create the backend and track it if successful + let module = imports.service.protocol[name]; + let backend = new module.ChannelService(); + this.backends.set(name, backend); + + // Connect to the backend + backend.__channelId = backend.connect( + 'channel', + this._onChannel.bind(this) + ); + + // Now try to start the backend, allowing us to retry if we fail + backend.start(); + } catch (e) { + this.notify_error(e); + } + } } /** @@ -410,7 +498,7 @@ } let now = GLib.DateTime.new_now_local().to_unix(); - let dnd = (zorin_connect.settings.get_int('donotdisturb') <= now); + let dnd = (this.settings.get_int('donotdisturb') <= now); // TODO: Maybe the 'enable-sound-alerts' should be left alone/queried this._notificationSettings.set_boolean('enable-sound-alerts', dnd); @@ -457,7 +545,6 @@ * Report a service-level error * * @param {object} error - An Error or object with name, message and stack - * @param {string} context - The scope of the error */ notify_error(error) { try { @@ -495,20 +582,6 @@ notif.set_default_action('app.settings'); break; - case 'PluginError': - id = `${error.plugin}-error`; - title = _('%s Plugin Failed To Load').format(error.plugin); - body = _('Click for more information'); - icon = new Gio.ThemedIcon({name: 'dialog-error'}); - priority = Gio.NotificationPriority.HIGH; - error = new GLib.Variant('a{ss}', { - name: error.name.trim(), - message: error.message.trim(), - stack: error.stack.trim() - }); - notif.set_default_action_and_target('app.error', error); - break; - default: id = `${Date.now()}`; title = error.name.trim(); @@ -536,23 +609,6 @@ } } - /** - * Load each script in components/ and instantiate a Service if it has one - */ - _loadComponents() { - for (let name in imports.service.components) { - try { - let module = imports.service.components[name]; - - if (module.hasOwnProperty('Service')) { - this[name] = new module.Service(); - } - } catch (e) { - logError(e); - } - } - } - vfunc_activate() { super.vfunc_activate(); } @@ -565,17 +621,9 @@ // Watch *this* file and stop the service if it's updated/uninstalled this._serviceMonitor = Gio.File.new_for_path( zorin_connect.extdatadir + '/service/daemon.js' - ).monitor( - Gio.FileMonitorFlags.WATCH_MOVES, - null - ); + ).monitor(Gio.FileMonitorFlags.WATCH_MOVES, null); this._serviceMonitor.connect('changed', () => this.quit()); - // Changing the default public name to the computer's hostname - if (this.name.length === 0) { - zorin_connect.settings.set_string('public-name', GLib.get_host_name()); - } - // Init some resources let provider = new Gtk.CssProvider(); provider.load_from_resource(zorin_connect.app_path + '/application.css'); @@ -591,38 +639,23 @@ appInfo.add_supports_type('x-scheme-handler/sms'); appInfo.add_supports_type('x-scheme-handler/tel'); } catch (e) { - warning(e); + logError(e); } - // Keep identity updated and broadcast any name changes - zorin_connect.settings.connect('changed::public-name', (settings) => { - this.identity.body.deviceName = this.name; - }); - - // GActions + // GActions & GSettings + this._initSettings(); this._initActions(); + this._initComponents(); + this._initBackends(); - // Components (PulseAudio, UPower, etc) - this._loadComponents(); - - // Lan.ChannelService - try { - this.lan = new Lan.ChannelService(); - } catch (e) { - e.name = 'LanError'; - this.notify_error(e); - } - - // Bluetooth.ChannelService - try { - //this.bluetooth = new Bluetooth.ChannelService(); - } catch (e) { - if (this.bluetooth) { - this.bluetooth.destroy(); - } + // Load cached devices + for (let id of this.settings.get_strv('devices')) { + let device = new Device.Device({body: {deviceId: id}}); + this._devices.set(id, device); } - GLib.timeout_add_seconds(300, 5, this.reconnect.bind(this)); + // Reconnect to paired devices every 5 seconds + GLib.timeout_add_seconds(300, 5, this._reconnect.bind(this)); } vfunc_dbus_register(connection, object_path) { @@ -630,14 +663,7 @@ connection: connection, object_path: object_path }); - - // Load cached devices - for (let id of zorin_connect.settings.get_strv('devices')) { - let device = new Device.Device({body: {deviceId: id}}); - this._devices.set(id, device); - device.loadPlugins(); - } - + return true; } @@ -668,8 +694,7 @@ break; default: - warning(`Unsupported URI: ${file.get_uri()}`); - return; + throw new Error(`Unsupported URI: ${file.get_uri()}`); } // Show chooser dialog @@ -679,45 +704,427 @@ parameter: parameter }); } catch (e) { - logError(e, `Zorin Connect: Opening ${file.get_uri()}:`); + logError(e, `Zorin Connect: Opening ${file.get_uri()}`); } } } vfunc_shutdown() { - // Destroy the channel providers first to avoid any further connections - try { - if (this.lan) this.lan.destroy(); - } catch (e) { - debug(e); - } + // Dispose GSettings + this.settings.disconnect(this._nameChangedId); + this.settings.run_dispose(); - try { - if (this.bluetooth) this.bluetooth.destroy(); - } catch (e) { - debug(e); + // Destroy the backends first to avoid any further connections + for (let [name, backend] of this.backends) { + try { + backend.destroy(); + } catch (e) { + logError(e, `'${name}' Backend`); + } } - // This must be done before ::dbus-unregister is emitted + // We must unexport the devices before ::dbus-unregister is emitted this._devices.forEach(device => device.destroy()); - // Destroy the remaining components last - try { - if (this.mpris) this.mpris.destroy(); - } catch (e) { - debug(e); + // Destroy the components last + for (let [name, component] of this.components) { + try { + component.destroy(); + } catch (e) { + logError(e, `'${name}' Component`); + } } + // Chain up last (application->priv->did_shutdown) + super.vfunc_shutdown(); + } + + /* + * CLI + */ + _initOptions() { + /* + * Device Listings + */ + this.add_main_option( + 'list-devices', + 'l'.charCodeAt(0), + GLib.OptionFlags.NONE, + GLib.OptionArg.NONE, + _('List available devices'), + null + ); + + this.add_main_option( + 'list-all', + 'a'.charCodeAt(0), + GLib.OptionFlags.NONE, + GLib.OptionArg.NONE, + _('List all devices'), + null + ); + + this.add_main_option( + 'device', + 'd'.charCodeAt(0), + GLib.OptionFlags.NONE, + GLib.OptionArg.STRING, + _('Target Device'), + '' + ); + + /** + * Pairing + */ + this.add_main_option( + 'pair', + null, + GLib.OptionFlags.NONE, + GLib.OptionArg.NONE, + _('Pair'), + null + ); + + this.add_main_option( + 'unpair', + null, + GLib.OptionFlags.NONE, + GLib.OptionArg.NONE, + _('Unpair'), + null + ); + + /* + * Messaging + */ + this.add_main_option( + 'message', + null, + GLib.OptionFlags.NONE, + GLib.OptionArg.STRING_ARRAY, + _('Send SMS'), + '' + ); + + this.add_main_option( + 'message-body', + null, + GLib.OptionFlags.NONE, + GLib.OptionArg.STRING, + _('Message Body'), + '' + ); + + /* + * Notifications + */ + this.add_main_option( + 'notification', + null, + GLib.OptionFlags.NONE, + GLib.OptionArg.STRING, + _('Send Notification'), + '' + ); + + this.add_main_option( + 'notification-appname', + null, + GLib.OptionFlags.NONE, + GLib.OptionArg.STRING, + _('Notification App Name'), + '<name>' + ); + + this.add_main_option( + 'notification-body', + null, + GLib.OptionFlags.NONE, + GLib.OptionArg.STRING, + _('Notification Body'), + '<text>' + ); + + this.add_main_option( + 'notification-icon', + null, + GLib.OptionFlags.NONE, + GLib.OptionArg.STRING, + _('Notification Icon'), + '<icon-name>' + ); + + this.add_main_option( + 'notification-id', + null, + GLib.OptionFlags.NONE, + GLib.OptionArg.STRING, + _('Notification ID'), + '<id>' + ); + + this.add_main_option( + 'photo', + null, + GLib.OptionFlags.NONE, + GLib.OptionArg.NONE, + _('Photo'), + null + ); + + this.add_main_option( + 'ping', + null, + GLib.OptionFlags.NONE, + GLib.OptionArg.NONE, + _('Ping'), + null + ); + + this.add_main_option( + 'ring', + null, + GLib.OptionFlags.NONE, + GLib.OptionArg.NONE, + _('Ring'), + null + ); + + /* + * Sharing + */ + this.add_main_option( + 'share-file', + null, + GLib.OptionFlags.NONE, + GLib.OptionArg.FILENAME_ARRAY, + _('Share File'), + '<filepath|URI>' + ); + + this.add_main_option( + 'share-link', + null, + GLib.OptionFlags.NONE, + GLib.OptionArg.STRING_ARRAY, + _('Share Link'), + '<URL>' + ); + + /* + * Misc + */ + this.add_main_option( + 'version', + 'v'.charCodeAt(0), + GLib.OptionFlags.NONE, + GLib.OptionArg.NONE, + _('Show release version'), + null + ); + } + + _cliAction(id, name, parameter = null) { + let parameters = []; + + if (parameter instanceof GLib.Variant) { + parameters[0] = parameter; + } + + id = id.replace(/\W+/g, '_'); + + Gio.DBus.session.call_sync( + 'org.gnome.Shell.Extensions.ZorinConnect', + `/org/gnome/Shell/Extensions/ZorinConnect/Device/${id}`, + 'org.gtk.Actions', + 'Activate', + GLib.Variant.new('(sava{sv})', [name, parameters, {}]), + null, + Gio.DBusCallFlags.NONE, + -1, + null + ); + } + + _cliListDevices(full = true) { + let result = Gio.DBus.session.call_sync( + 'org.gnome.Shell.Extensions.ZorinConnect', + '/org/gnome/Shell/Extensions/ZorinConnect', + 'org.freedesktop.DBus.ObjectManager', + 'GetManagedObjects', + null, + null, + Gio.DBusCallFlags.NONE, + -1, + null + ); + + let variant = result.unpack()[0].unpack(); + let device; + + for (let object of Object.values(variant)) { + object = object.full_unpack(); + device = object['org.gnome.Shell.Extensions.ZorinConnect.Device']; + + if (full) { + print(`${device.Id}\t${device.Name}\t${device.Connected}\t${device.Paired}`); + } else if (device.Connected && device.Paired) { + print(device.Id); + } + } + } + + _cliMessage(id, options) { + if (!options.contains('message-body')) { + throw new TypeError('missing --message-body option'); + } + + let address = options.lookup_value('message', null).deep_unpack(); + let body = options.lookup_value('message-body', null).deep_unpack(); + + this._cliAction(id, 'sendSms', GLib.Variant.new('(ss)', [address, body])); + } + + _cliNotify(id, options) { + let title = options.lookup_value('notification', null).unpack(); + let body = ''; + let icon = null; + let nid = `${Date.now()}`; + let appName = zorin_connect.settings.get_string('name'); + + if (options.contains('notification-id')) { + nid = options.lookup_value('notification-id', null).unpack(); + } + + if (options.contains('notification-body')) { + body = options.lookup_value('notification-body', null).unpack(); + } + + if (options.contains('notification-app')) { + appName = options.lookup_value('notification-appname', null).unpack(); + } + + if (options.contains('notification-icon')) { + icon = options.lookup_value('notification-icon', null).unpack(); + icon = Gio.Icon.new_for_string(icon); + } + + let notif = { + appName: appName, + id: nid, + title: title, + text: body, + ticker: `${title}: ${body}`, + time: `${Date.now()}`, + isClearable: true, + icon: icon + }; + + let parameter = GLib.Variant.full_pack(notif); + this._cliAction(id, 'sendNotification', parameter); + } + + _cliShareFile(device, options) { + let files = options.lookup_value('share-file', null); + + debug(files.print(true)); + + files = files.deep_unpack(); + + files.map(file => { + if (file instanceof Uint8Array) { + file = imports.byteArray.toString(file); + } + + this._cliAction(device, 'shareFile', GLib.Variant.new('(sb)', [file, false])); + }); + } + + _cliShareLink(device, options) { + let uris = options.lookup_value('share-link', null).deep_unpack(); + + uris.map(uri => { + if (uri instanceof Uint8Array) { + uri = imports.byteArray.toString(uri); + } + + this._cliAction(device, 'shareUri', GLib.Variant.new_string(uri)); + }); + } + + vfunc_handle_local_options(options) { try { - if (this.notification) this.notification.destroy(); + if (options.contains('version')) { + print(`Zorin Connect ${zorin_connect.metadata.version}`); + return 0; + } + + this.register(null); + + if (options.contains('list-devices')) { + this._cliListDevices(false); + return 0; + } + + if (options.contains('list-all')) { + this._cliListDevices(true); + return 0; + } + + // We need a device for anything else; exit since this is probably + // the daemon being started. + if (!options.contains('device')) { + return -1; + } + + let id = options.lookup_value('device', null).unpack(); + + // Pairing + if (options.contains('pair')) { + this._cliAction(id, 'pair'); + } + + if (options.contains('unpair')) { + this._cliAction(id, 'unpair'); + return 0; + } + + // Plugins + if (options.contains('message')) { + this._cliMessage(id, options); + } + + if (options.contains('notification')) { + this._cliNotify(id, options); + } + + if (options.contains('photo')) { + this._cliAction(id, 'photo'); + } + + if (options.contains('ping')) { + this._cliAction(id, 'ping', GLib.Variant.new_string('')); + } + + if (options.contains('ring')) { + this._cliAction(id, 'ring'); + } + + if (options.contains('share-file')) { + this._cliShareFile(id, options); + } + + if (options.contains('share-link')) { + this._cliShareFile(id, options); + } + + return 0; } catch (e) { - debug(e); + logError(e); + return 1; } - - // Chain up last (application->priv->did_shutdown) - super.vfunc_shutdown(); } }); -(new Service()).run([System.programInvocationName].concat(ARGV)); +(new Service()).run([imports.system.programInvocationName].concat(ARGV)); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/device.js gnome-shell-extension-zorin-connect-28.0.2/src/service/device.js --- gnome-shell-extension-zorin-connect-24.1/src/service/device.js 2019-03-18 11:05:33.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/device.js 2019-11-30 12:12:16.000000000 +0000 @@ -5,8 +5,7 @@ const GObject = imports.gi.GObject; const Gtk = imports.gi.Gtk; -const Bluetooth = imports.service.protocol.bluetooth; -const Lan = imports.service.protocol.lan; +const Core = imports.service.protocol.core; const DBus = imports.service.components.dbus; const UUID = 'org.gnome.Shell.Extensions.ZorinConnect.Device'; @@ -87,7 +86,7 @@ super._init(); this._channel = null; - this._connected = false; + this._id = identity.body.deviceId; // GLib.Source timeout id's for pairing requests this._incomingPairRequest = 0; @@ -98,13 +97,10 @@ this._handlers = new Map(); this._transfers = new Map(); - // We at least need the device Id for GSettings and the DBus interface - let deviceId = identity.body.deviceId; - // GSettings this.settings = new Gio.Settings({ settings_schema: zorin_connect.gschema.lookup(UUID, true), - path: '/org/gnome/shell/extensions/zorin-connect/device/' + deviceId + '/' + path: '/org/gnome/shell/extensions/zorin-connect/device/' + this.id + '/' }); // Watch for plugins changes @@ -120,13 +116,13 @@ // Export an object path for the device this._dbus_object = new Gio.DBusObjectSkeleton({ - g_object_path: this.object_path + g_object_path: this.g_object_path }); this.service.objectManager.export(this._dbus_object); // Export GActions this._actionsId = Gio.DBus.session.export_action_group( - this.object_path, + this.g_object_path, this ); this._registerActions(); @@ -134,7 +130,7 @@ // Export GMenu this.menu = new Gio.Menu(); this._menuId = Gio.DBus.session.export_menu_model( - this.object_path, + this.g_object_path, this.menu ); @@ -144,45 +140,47 @@ g_interface_info: INTERFACE_INFO }); this._dbus_object.add_interface(this._dbus); + + // Load plugins + this._loadPlugins(); } - /** Device Properties */ get connected () { + if (this._connected === undefined) { + this._connected = false; + } + return this._connected; } get connection_type() { - if (this._channel !== null) { - return this._channel.type; - } + let lastConnection = this.settings.get_string('last-connection'); - return this.settings.get_string('last-connection'); + return lastConnection.split('://')[0]; } get contacts() { - let contacts = this.lookup_plugin('contacts'); + let contacts = this._plugins.get('contacts'); if (contacts && contacts.settings.get_boolean('contacts-source')) { return contacts._store; } else { - return this.service.contacts; + return this.service.components.get('contacts'); } } - // TODO: should we just store the fingerprint instead of the pem? + // FIXME: backend should do this stuff get encryption_info() { let fingerprint = _('Not available'); // Bluetooth connections have no certificate so we use the host address if (this.connection_type === 'bluetooth') { // TRANSLATORS: Bluetooth address for remote device - return _('Bluetooth device at %s').format( - this.settings.get_string('bluetooth-host') - ); + return _('Bluetooth device at %s').format('???'); // If the device is connected use the certificate from the connection } else if (this.connected) { - fingerprint = this._channel.certificate.fingerprint(); + fingerprint = this._channel.peer_certificate.fingerprint(); // Otherwise pull it out of the settings } else if (this.paired) { @@ -201,11 +199,11 @@ return _('%s Fingerprint:').format(this.name) + '\n' + fingerprint + '\n\n' + _('%s Fingerprint:').format(this.service.name) + '\n' + - this.service.fingerprint; + this.service.backends.get('lan').certificate.fingerprint(); } get id() { - return this.settings.get_string('id'); + return this._id; } get name() { @@ -216,34 +214,18 @@ return this.settings.get_boolean('paired'); } - get supported_plugins() { - let supported = this.settings.get_strv('supported-plugins'); - - // Preempt clipboard and mousepad plugins on Wayland - if (_WAYLAND) { - supported = supported.filter(name => { - return (name !== 'clipboard' && name !== 'mousepad'); - }); - } - - return supported; - } - - get allowed_plugins() { - let disabled = this.settings.get_strv('disabled-plugins'); - return this.supported_plugins.filter(name => !disabled.includes(name)); - } - get icon_name() { switch (this.type) { case 'laptop': - return 'laptop'; + return 'laptop-symbolic'; case 'phone': - return 'smartphone'; + return 'smartphone-symbolic'; case 'tablet': - return 'tablet'; + return 'tablet-symbolic'; + case 'tv': + return 'tv-symbolic'; default: - return 'computer'; + return 'computer-symbolic'; } } @@ -255,48 +237,42 @@ return this.settings.get_string('type'); } - get display_type() { - switch (this.type) { - case 'laptop': - return _('Laptop'); - case 'phone': - return _('Smartphone'); - case 'tablet': - return _('Tablet'); - default: - return _('Desktop'); - } - } - - get object_path() { + get g_object_path() { return `${zorin_connect.app_path}/Device/${this.id.replace(/\W+/g, '_')}`; } _handleIdentity(packet) { - this.settings.set_string('id', packet.body.deviceId); - this.settings.set_string('name', packet.body.deviceName); - this.settings.set_string('type', packet.body.deviceType); - - if (packet.body.hasOwnProperty('bluetoothHost')) { - this.settings.set_string('bluetooth-host', packet.body.bluetoothHost); - this.settings.set_string('bluetooth-path', packet.body.bluetoothPath); - this.settings.set_string('last-connection', 'bluetooth'); - } else if (packet.body.hasOwnProperty('tcpHost')) { - this.settings.set_string('tcp-host', packet.body.tcpHost); - this.settings.set_uint('tcp-port', packet.body.tcpPort); - this.settings.set_string('last-connection', 'tcp'); - } - - this.settings.set_strv( - 'incoming-capabilities', - packet.body.incomingCapabilities.sort() - ); + // The type won't change, but it might not be properly set yet + if (this.type !== packet.body.deviceType) { + this.settings.set_string('type', packet.body.deviceType); + this.notify('type'); + this.notify('icon-name'); + } - this.settings.set_strv( - 'outgoing-capabilities', - packet.body.outgoingCapabilities.sort() - ); + // The name may change so we check and notify if so + if (this.name !== packet.body.deviceName) { + this.settings.set_string('name', packet.body.deviceName); + this.notify('name'); + } + // Connection + if (this._channel) { + this.settings.set_string('last-connection', this._channel.address); + } + + // Packets + let incoming = packet.body.incomingCapabilities.sort(); + let outgoing = packet.body.outgoingCapabilities.sort(); + let inc = this.settings.get_strv('incoming-capabilities'); + let out = this.settings.get_strv('outgoing-capabilities'); + + // Only write GSettings if something has changed + if (incoming.join('') != inc.join('') || outgoing.join('') != out.join('')) { + this.settings.set_strv('incoming-capabilities', incoming); + this.settings.set_strv('outgoing-capabilities', outgoing); + } + + // Determine supported plugins by matching incoming to outgoing types let supported = []; for (let name in imports.service.plugins) { @@ -305,15 +281,21 @@ if (!meta) continue; // If we can handle packets it sends... - if (meta.incomingCapabilities.some(t => packet.body.outgoingCapabilities.includes(t))) { + if (meta.incomingCapabilities.some(t => outgoing.includes(t))) { supported.push(name); // ...or we send packets it can handle - } else if (meta.outgoingCapabilities.some(t => packet.body.incomingCapabilities.includes(t))) { + } else if (meta.outgoingCapabilities.some(t => incoming.includes(t))) { supported.push(name); } } - this.settings.set_strv('supported-plugins', supported.sort()); + // Only write GSettings if something has changed + let currentSupported = this.settings.get_strv('supported-plugins'); + supported.sort(); + + if (currentSupported.join('') !== supported.join('')) { + this.settings.set_strv('supported-plugins', supported); + } } /** @@ -322,12 +304,19 @@ _setConnected() { debug(`Connected to ${this.name} (${this.id})`); - this.settings.set_string('last-connection', this._channel.type); - - this._connected = true; - this.notify('connected'); - - this._plugins.forEach(async (plugin) => plugin.connected()); + if (!this.connected) { + this._connected = true; + this.notify('connected'); + + // Run the connected hook for each plugin + this._plugins.forEach(async (plugin) => { + try { + plugin.connected(); + } catch (e) { + logError(e, `${this.name}: ${plugin.name}`); + } + }); + } } /** @@ -336,34 +325,31 @@ _setDisconnected() { debug(`Disconnected from ${this.name} (${this.id})`); - this._channel = null; - this._connected = false; - this.notify('connected'); - - this._plugins.forEach(async (plugin) => plugin.disconnected()); + if (this.connected) { + this._channel = null; + this._connected = false; + this.notify('connected'); + + // Run the disconnected hook for each plugin + this._plugins.forEach(async (plugin) => { + try { + plugin.disconnected(); + } catch (e) { + logError(e, `${this.name}: ${plugin.name}`); + } + }); + } } /** * Request a connection from the device */ activate() { - let lastConnection = this.settings.get_string('last-connection'); - - // If the same channel type is currently open bail... - if (this._channel !== null && this.connection_type === lastConnection) { - debug(`${this.name}: ${lastConnection} connection already active`); - return; - - } else if (lastConnection === 'bluetooth') { - this.service.broadcast(this.settings.get_string('bluetooth-path')); - - } else { - let tcpAddress = Gio.InetSocketAddress.new_from_string( - this.settings.get_string('tcp-host'), - this.settings.get_uint('tcp-port') - ); - - this.service.broadcast(tcpAddress); + try { + let lastConnection = this.settings.get_value('last-connection'); + this.service.activate_action('connect', lastConnection); + } catch (e) { + logError(e, this.name); } } @@ -397,7 +383,7 @@ throw new Error(`Unsupported packet type (${packet.type})`); } } catch (e) { - warning(e, this.name); + debug(e, this.name); } } @@ -420,21 +406,6 @@ * Actions */ _registerActions() { - // Stock device actions - let activate = new Gio.SimpleAction({ - name: 'activate', - state: new GLib.Variant('(ss)', [_('Reconnect'), 'view-refresh-symbolic']), - }); - activate.connect('activate', this.activate.bind(this)); - this.add_action(activate); - - let openSettings = new Gio.SimpleAction({ - name: 'openSettings', - state: new GLib.Variant('(ss)', [_('Settings'), 'preferences-system-symbolic']) - }); - openSettings.connect('activate', this.openSettings.bind(this)); - this.add_action(openSettings); - // Pairing notification actions let acceptPair = new Gio.SimpleAction({name: 'pair'}); acceptPair.connect('activate', this.pair.bind(this)); @@ -458,6 +429,134 @@ }); openPath.connect('activate', this.openPath); this.add_action(openPath); + + // Preference helpers + let clearCache = new Gio.SimpleAction({ + name: 'clearCache', + parameter_type: new GLib.VariantType('s') + }); + clearCache.connect('activate', this._clearCache.bind(this)); + this.add_action(clearCache); + } + + /** + * Get the position of a GMenuItem with @actionName in the top level of the + * device menu. + * + * @param {string} actionName - An action name with scope (eg. device.foo) + * @return {number} - An 0-based index or -1 if not found + */ + getMenuAction(actionName) { + for (let i = 0, len = this.menu.get_n_items(); i < len; i++) { + try { + let val = this.menu.get_item_attribute_value(i, 'action', null); + + if (val.unpack() === actionName) { + return i; + } + } catch (e) { + continue; + } + } + + return -1; + } + + /** + * Add a GMenuItem to the top level of the device menu + * + * @param {Gio.MenuItem} menuItem - A GMenuItem + * @param {number} [index] - The position to place the item + * @return {number} - The position the item was placed + */ + addMenuItem(menuItem, index = -1) { + try { + if (index > -1) { + this.menu.insert_item(index, menuItem); + return index; + } + + this.menu.append_item(menuItem); + return this.menu.get_n_items(); + } catch (e) { + logError(e, this.name); + return -1; + } + } + + /** + * Add a Device GAction to the top level of the device menu + * + * @param {Gio.Action} action - A GAction + * @param {number} [index] - The position to place the item + * @param {string} label - A label for the item + * @param {string} icon_name - A themed icon name for the item + * @return {number} - The position the item was placed + */ + addMenuAction(action, index = -1, label, icon_name) { + try { + // Create a GMenuItem for @action + let item = new Gio.MenuItem(); + + if (label) + item.set_label(label); + + if (icon_name) + item.set_icon(new Gio.ThemedIcon({name: icon_name})); + + item.set_attribute_value( + 'hidden-when', + new GLib.Variant('s', 'action-disabled') + ); + + item.set_detailed_action(`device.${action.name}`); + + return this.addMenuItem(item, index); + } catch (e) { + logError(e, this.name); + return -1; + } + } + + /** + * Remove a GAction from the top level of the device menu by action name + * + * @param {string} actionName - A GAction name, including scope + * @return {number} - The position the item was removed from or -1 + */ + removeMenuAction(actionName) { + try { + let index = this.getMenuAction(actionName); + + if (index > -1) { + this.menu.remove(index); + } + + return index; + } catch (e) { + logError(e, this.name); + return -1; + } + } + + /** + * Replace a GAction in the top level of the device menu with the name + * @actionName and insert @item in its place. If @actionName is not found + * @item will appended to the device menu. + * + * @param {string} actionName - A GAction name, including scope + * @param (Gio.MenuItem} menuItem - A GMenuItem + * @return {number} - The position the item was placed + */ + replaceMenuAction(actionName, menuItem) { + try { + let index = this.removeMenuAction(actionName); + + return this.addMenuItem(menuItem, index); + } catch (e) { + logError(e, this.name); + return -1; + } } /** @@ -535,32 +634,53 @@ * File Transfers */ cancelTransfer(action, parameter) { - let uuid = parameter.unpack(); - let transfer = this._transfers.get(uuid); + try { + let uuid = parameter.unpack(); + let transfer = this._transfers.get(uuid); - if (transfer !== undefined) { - this._transfers.delete(uuid); - transfer.close(); + if (transfer !== undefined) { + transfer.close(); + this._transfers.delete(uuid); + } + } catch (e) { + logError(e, this.name); } } createTransfer(params) { - params.device = this; + try { + params.device = this; + + return this._channel.createTransfer(params); + } catch (e) { + logError(e, this.name); - switch (this.connection_type) { - case 'tcp': - return new Lan.Transfer(params); + // Return a mock transfer that always appears to fail + return { + uuid: 'mock-transfer', + download: () => false, + upload: () => false + }; + } + } - case 'bluetooth': - return new Bluetooth.Transfer(params); + /** + * Reject the transfer payload described by @packet by passing an invalid + * stream to Core.Transfer. + * + * @param {Core.Packet} packet - A packet + */ + async rejectTransfer(packet) { + if (!packet || !packet.payloadTransferInfo) return; - // Fallback to returning a mock transfer that always appears to fail - default: - return { - uuid: 'mock-transfer', - download: () => false, - upload: () => false - }; + try { + let transfer = this.createTransfer(Object.assign({ + output_stream: null, + size: packet.payloadSize + }, packet.payloadTransferInfo)); + + await transfer.download(); + } catch (e) { } } @@ -568,8 +688,24 @@ let path = parameter.unpack(); // Normalize paths to URIs, assuming local file - path = path.includes('://') ? path : `file://${path}`; - open_uri(path); + let uri = path.includes('://') ? path : `file://${path}`; + Gio.AppInfo.launch_default_for_uri_async(uri, null, null, null); + } + + _clearCache(action, parameter) { + try { + let context = parameter.unpack(); + + if (context && this._plugins.has(context)) { + let plugin = this._plugins.get(context); + + if (typeof plugin.cacheClear === 'function') { + plugin.cacheClear(); + } + } + } catch (e) { + logError(e, this.name); + } } /** @@ -582,26 +718,23 @@ if (packet.body.pair) { // The device is accepting our request if (this._outgoingPairRequest) { - debug(`Pair accepted by ${this.name}`); - this._setPaired(true); - this.loadPlugins(); + this._loadPlugins(); + // The device thinks we're unpaired } else if (this.paired) { this._setPaired(true); this.pair(); - this.loadPlugins(); + this._loadPlugins(); + // The device is requesting pairing } else { - debug(`Pair request from ${this.name}`); this._notifyPairRequest(); } // Device is requesting unpairing/rejecting our request } else { - debug(`Pair rejected by ${this.name}`); - this._setPaired(false); - this.unloadPlugins(); + this._unloadPlugins(); } } @@ -665,11 +798,11 @@ this._resetPairRequest(); // For TCP connections we store or reset the TLS Certificate - if (this.connection_type === 'tcp') { + if (this.connection_type === 'lan') { if (bool) { this.settings.set_string( 'certificate-pem', - this._channel.certificate.certificate_pem + this._channel.peer_certificate.certificate_pem ); } else { this.settings.reset('certificate-pem'); @@ -684,35 +817,36 @@ * Send or accept an incoming pair request; also exported as a GAction */ pair() { - // We're accepting an incoming pair request... - if (this._incomingPairRequest) { - // so set the paired state to true... - this._setPaired(true); - // then loop back around to send confirmation... - this.pair(); - // ...before loading plugins - this.loadPlugins(); - return; - } - - // Send a pair packet - this.sendPacket({ - id: 0, - type: 'kdeconnect.pair', - body: {pair: true} - }); + try { + // We're accepting an incoming pair request... + if (this._incomingPairRequest) { + // so set the paired state to true... + this._setPaired(true); + // then loop back around to send confirmation... + this.pair(); + // ...before loading plugins + this._loadPlugins(); + return; + } - // We're initiating an outgoing pair request - if (!this.paired) { - this._resetPairRequest(); - - this._outgoingPairRequest = GLib.timeout_add_seconds( - GLib.PRIORITY_DEFAULT, - 30, - this._setPaired.bind(this, false) - ); + // Send a pair packet + this.sendPacket({ + type: 'kdeconnect.pair', + body: {pair: true} + }); - debug(`Pair request sent to ${this.name}`); + // We're initiating an outgoing pair request + if (!this.paired) { + this._resetPairRequest(); + + this._outgoingPairRequest = GLib.timeout_add_seconds( + GLib.PRIORITY_DEFAULT, + 30, + this._setPaired.bind(this, false) + ); + } + } catch (e) { + logError(e, this.name); } } @@ -720,64 +854,50 @@ * Unpair or reject an incoming pair request; also exported as a GAction */ unpair() { - debug(`${this.name} (${this.id})`); + try { + if (this.connected) { + this.sendPacket({ + type: 'kdeconnect.pair', + body: {pair: false} + }); + } - // Send the unpair packet only if we're connected - if (this.connected) { - this.sendPacket({ - id: 0, - type: 'kdeconnect.pair', - body: {pair: false} - }); + this._setPaired(false); + this._unloadPlugins(); + } catch (e) { + logError(e, this.name); } - - this._setPaired(false); - this.unloadPlugins(); } /** * Plugin Functions */ - get_incoming_supported(type) { - let incoming = this.settings.get_strv('incoming-capabilities'); - return incoming.includes(`kdeconnect.${type}`); - } - - get_outgoing_supported(type) { - let outgoing = this.settings.get_strv('outgoing-capabilities'); - return outgoing.includes(`kdeconnect.${type}`); - } - - get_plugin_supported(name) { - return this.supported_plugins.includes(name); - } - - get_plugin_allowed(name) { - return this.allowed_plugins.includes(name); - } - - lookup_plugin(name) { - return this._plugins.get(name) || null; - } - - _onDisabledPlugins(settings) { + async _onDisabledPlugins(settings) { let disabled = this.settings.get_strv('disabled-plugins'); - disabled.map(name => this.unloadPlugin(name)); - this.allowed_plugins.map(name => this.loadPlugin(name)); - // Make sure we're change the contacts store if the plugin was disabled - if (!this.get_plugin_allowed('contacts')) { + // Unload disabled plugins + for (let name of disabled) { + await this._unloadPlugin(name); + } + + // Make sure we change the contacts store if the plugin was disabled + if (disabled.includes('contacts')) { this.notify('contacts'); } + + // Load allowed plugins + for (let name of this.settings.get_strv('supported-plugins')) { + if (!disabled.includes(name)) { + await this._loadPlugin(name); + } + } } - loadPlugin(name) { + _loadPlugin(name) { let handler, plugin; try { if (this.paired && !this._plugins.has(name)) { - debug(`loading '${name}' plugin`, this.name); - // Instantiate the handler handler = imports.service.plugins[name]; plugin = new handler.Plugin(this); @@ -794,25 +914,25 @@ this.connected ? plugin.connected() : plugin.disconnected(); } } catch (e) { - e.name = (e.name === 'Error') ? 'PluginError' : e.name; - e.plugin = handler.Metadata.label; this.service.notify_error(e); } } - async loadPlugins() { - for (let name of this.allowed_plugins) { - await this.loadPlugin(name); + async _loadPlugins() { + let disabled = this.settings.get_strv('disabled-plugins'); + + for (let name of this.settings.get_strv('supported-plugins')) { + if (!disabled.includes(name)) { + await this._loadPlugin(name); + } } } - unloadPlugin(name) { + _unloadPlugin(name) { let handler, plugin; try { if (this._plugins.has(name)) { - debug(`unloading '${name}' plugin`, this.name); - // Unregister packet handlers handler = imports.service.plugins[name]; plugin = this._plugins.get(name); @@ -830,20 +950,13 @@ } } - async unloadPlugins() { + async _unloadPlugins() { for (let name of this._plugins.keys()) { - await this.unloadPlugin(name); + await this._unloadPlugin(name); } } - openSettings() { - this.service._settings(this.id); - } - destroy() { - // - this.settings.disconnect(this._disabledPluginsId); - // Close the channel if still connected if (this._channel !== null) { this._channel.close(); @@ -861,6 +974,12 @@ this._dbus_object.remove_interface(this._dbus); this._dbus_object.flush(); this.service.objectManager.unexport(this._dbus_object.g_object_path); + + // Dispose GSettings + this.settings.disconnect(this._disabledPluginsId); + this.settings.run_dispose(); + + this.run_dispose(); } }); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/__init__.js gnome-shell-extension-zorin-connect-28.0.2/src/service/__init__.js --- gnome-shell-extension-zorin-connect-24.1/src/service/__init__.js 2019-05-16 22:18:58.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/__init__.js 2019-11-30 12:13:26.000000000 +0000 @@ -40,7 +40,7 @@ let [, func, file, line] = caller.match(/([^@]*)@([^:]*):([^:]*)/); let script = file.replace(zorin_connect.extdatadir, ''); - GLib.log_structured('ZorinConnect', GLib.LogLevelFlags.LEVEL_MESSAGE, { + GLib.log_structured('Zorin Connect', GLib.LogLevelFlags.LEVEL_MESSAGE, { 'MESSAGE': `[${script}:${func}:${line}]: ${message}`, 'SYSLOG_IDENTIFIER': 'org.gnome.Shell.Extensions.ZorinConnect', 'CODE_FILE': file, @@ -58,67 +58,6 @@ /** - * A simple warning function along the lines of logError() - * - * @param {Error|string} message - A string or Error to log - * @param {string} [prefix] - An optional prefix for the warning - */ -window.warning = function(message, prefix = null) { - message = (message.message) ? message.message : message; - message = (prefix) ? `${prefix}: ${message}` : message; - - GLib.log_structured( - 'ZorinConnect', - GLib.LogLevelFlags.LEVEL_WARNING, - {MESSAGE: `WARNING: ${message}`} - ); -}; - - -/** - * Convenience Functions - */ -window.open_uri = function(uri) { - Gio.AppInfo.launch_default_for_uri_async(uri, null, null, (src, res) => { - try { - Gio.AppInfo.launch_default_for_uri_finish(res); - } catch (e) { - logError(e, uri); - } - }); -}; - -/** - * Get a GFile for @filename in ~/Downloads, with a numbered suffix if it - * already exists (eg. `picture.jpg (1)`) - * - * @param {String} filename - The basename of the file - * @return {Gio.File} - A new GFile for the given @filename in ~/Downloads - */ -window.get_download_file = function(filename) { - let download_dir = GLib.get_user_special_dir( - GLib.UserDirectory.DIRECTORY_DOWNLOAD - ); - - // Account for some corner cases with a fallback - if (!download_dir || download_dir === GLib.get_home_dir()) { - download_dir = GLib.build_filenamev([GLib.get_home_dir(), 'Downloads']); - } - - let path = GLib.build_filenamev([download_dir, filename]); - let filepath = path; - let copyNum = 0; - - while (GLib.file_test(filepath, GLib.FileTest.EXISTS)) { - copyNum += 1; - filepath = `${path} (${copyNum})`; - } - - return Gio.File.new_for_path(filepath); -}; - - -/** * Convenience function for loading JSON from a file * * @param {Gio.File|string} file - A Gio.File or path to a JSON file @@ -291,6 +230,19 @@ return this; }; +/** + * A simple equality check for phone numbers based on `toPhoneNumber()` + * + * @param {string} number - A phone number string to compare + * @return {boolean} - If `this` and @number are equivalent phone numbers + */ +String.prototype.equalsPhoneNumber = function(number) { + let a = this.toPhoneNumber(); + let b = number.toPhoneNumber(); + + return (a.endsWith(b) || b.endsWith(a)); +}; + /** * An implementation of `rm -rf` in Gio @@ -327,245 +279,6 @@ /** - * Extend Gio.Menu with some convenience methods for Device menus and working - * with menu items. - */ -Object.defineProperties(Gio.Menu.prototype, { - /** - * Return the position of an item in the menu by attribute and value - * - * @param {String} name - The attribute name (eg. 'label', 'action') - * @param {*} - The value of the attribute - * @return {Number} - The index of the item or %-1 if not found - */ - '_get': { - value: function(name, value) { - let len = this.get_n_items(); - - for (let i = 0; i < len; i++) { - try { - let item = this.get_item_attribute_value(i, name, null).unpack(); - - if (item === value) { - return i; - } - } catch (e) { - continue; - } - } - - return -1; - }, - enumerable: false - }, - - - /** - * Remove an item from the menu by attribute and value - * - * @param {String} name - The attribute name (eg. 'label', 'action') - * @param {*} - The value of the attribute - * @return {Number} - The index of the removed item or %-1 if not found - */ - '_remove': { - value: function(name, value) { - let index = this._get(name, value); - - if (index > -1) { - this.remove(index); - } - - return index; - }, - enumerable: false - }, - - /** - * Add a GMenuItem for a plugin action - * - * @param {Device.Action} action - The device action to add - * @return {Number} - The index of the added item - */ - 'add_action': { - value: function(action, index = -1) { - let [label, icon_name] = action.get_state().deep_unpack(); - - let item = new Gio.MenuItem(); - item.set_label(label); - item.set_icon(new Gio.ThemedIcon({name: icon_name})); - item.set_attribute_value( - 'hidden-when', - new GLib.Variant('s', 'action-disabled') - ); - - item.set_detailed_action(`device.${action.name}`); - - if (index === -1) { - this.append_item(item); - return this.get_n_items(); - } else { - this.insert_item(index, item); - return index; - } - }, - enumerable: false - }, - - /** - * Remove a GMenuItem by action name, falling back to device.@name if - * necessary. - * - * @param {String} name - Action name of the item to remove - * @return {Number} - The index of the removed item or -1 if not found - */ - 'remove_action': { - value: function(name) { - let index = this._remove('action', name); - - if (index === -1) { - index = this._remove('action', `device.${name}`); - } - - return index; - }, - enumerable: false - }, - - /** - * Replace the item with the action name @name with @item - * - * @param {String} name - Action name of the item to remove - * @param {Gio.MenuItem} item - The replacement menu item - * @return {Number} - The index of the replaced item or -1 if not found - */ - 'replace_action': { - value: function(name, item) { - let index = this.remove_action(name); - - if (index > -1) { - this.insert_item(index, item); - } - - return index; - }, - enumerable: false - } -}); - - -/** - * Creates a GTlsCertificate from the PEM-encoded data in @cert_path and - * @key_path. If either are missing a new pair will be generated. - * - * Additionally, the private key will be added using ssh-add to allow sftp - * connections using Gio. - * - * @param {string} cert_path - Absolute path to a x509 certificate in PEM format - * @param {string} key_path - Absolute path to a private key in PEM format - * - * See: https://github.com/KDE/kdeconnect-kde/blob/master/core/kdeconnectconfig.cpp#L119 - */ -Gio.TlsCertificate.new_for_paths = function (cert_path, key_path) { - let cert_exists = GLib.file_test(cert_path, GLib.FileTest.EXISTS); - let key_exists = GLib.file_test(key_path, GLib.FileTest.EXISTS); - - // Create a new certificate and private key if necessary - if (!cert_exists || !key_exists) { - let proc = new Gio.Subprocess({ - argv: [ - zorin_connect.metadata.bin.openssl, 'req', - '-new', '-x509', '-sha256', - '-out', cert_path, - '-newkey', 'rsa:4096', '-nodes', - '-keyout', key_path, - '-days', '3650', - '-subj', '/O=Zorin OS/OU=Zorin Connect/CN=' + GLib.uuid_string_random() - ], - flags: Gio.SubprocessFlags.STDOUT_SILENCE | Gio.SubprocessFlags.STDERR_SILENCE - }); - proc.init(null); - proc.wait_check(null); - } - - return Gio.TlsCertificate.new_from_files(cert_path, key_path); -}; - -Object.defineProperties(Gio.TlsCertificate.prototype, { - /** - * Compute a SHA1 fingerprint of the certificate. - * See: https://gitlab.gnome.org/GNOME/glib/issues/1290 - * - * @return {string} - A SHA1 fingerprint of the certificate. - */ - 'fingerprint': { - value: function() { - if (!this.__fingerprint) { - let proc = new Gio.Subprocess({ - argv: [zorin_connect.metadata.bin.openssl, 'x509', '-noout', '-fingerprint', '-sha1', '-inform', 'pem'], - flags: Gio.SubprocessFlags.STDIN_PIPE | Gio.SubprocessFlags.STDOUT_PIPE - }); - proc.init(null); - - let stdout = proc.communicate_utf8(this.certificate_pem, null)[1]; - this.__fingerprint = /[a-zA-Z0-9:]{59}/.exec(stdout)[0]; - - proc.wait_check(null); - } - - return this.__fingerprint; - }, - enumerable: false - }, - - /** - * The common name of the certificate. - */ - 'common_name': { - get: function() { - if (!this.__common_name) { - let proc = new Gio.Subprocess({ - argv: [zorin_connect.metadata.bin.openssl, 'x509', '-noout', '-subject', '-inform', 'pem'], - flags: Gio.SubprocessFlags.STDIN_PIPE | Gio.SubprocessFlags.STDOUT_PIPE - }); - proc.init(null); - - let stdout = proc.communicate_utf8(this.certificate_pem, null)[1]; - this.__common_name = /[a-zA-Z0-9-]{36}/.exec(stdout)[0]; - - proc.wait_check(null); - } - - return this.__common_name; - }, - enumerable: true - }, - - /** - * The common name of the certificate. - */ - 'certificate_der': { - get: function() { - if (!this.__certificate_der) { - let proc = new Gio.Subprocess({ - argv: [zorin_connect.metadata.bin.openssl, 'x509', '-outform', 'der', '-inform', 'pem'], - flags: Gio.SubprocessFlags.STDIN_PIPE | Gio.SubprocessFlags.STDOUT_PIPE - }); - proc.init(null); - - let stdout = proc.communicate(new GLib.Bytes(this.certificate_pem), null)[1]; - this.__certificate_der = stdout.toArray(); - - proc.wait_check(null); - } - - return this.__certificate_der; - }, - enumerable: true - } -}); - - -/** * Polyfill for GLib.uuid_string_random() (GLib v2.52+) * * Source: https://gist.github.com/jed/982883 @@ -685,59 +398,3 @@ GLib.Variant.prototype.full_unpack = _full_unpack; - -/** - * A convenience functions for connecting/disconnecting Gtk template callbacks - */ -Gtk.Widget.prototype.connect_template = function() { - this.$templateHandlers = []; - - Gtk.Widget.set_connect_func.call(this, (builder, obj, signalName, handlerName, connectObj, flags) => { - this.$templateHandlers.push([ - obj, - obj.connect(signalName, this[handlerName].bind(this)) - ]); - }); -}; - -Gtk.Widget.prototype.disconnect_template = function() { - Gtk.Widget.set_connect_func.call(this, function() {}); - this.$templateHandlers.map(([obj, id]) => obj.disconnect(id)); -}; - - -/** - * Convenience functions for saving/restoring window geometry - */ -const _mutter = new Gio.Settings({schema_id: 'org.gnome.mutter'}); - -Gtk.Window.prototype.restore_geometry = function() { - let [width, height] = this.settings.get_value('window-size').deep_unpack(); - this.set_default_size(width, height); - - if (!_mutter.get_boolean('center-new-windows')) { - let [x, y] = this.settings.get_value('window-position').deep_unpack(); - this.move(x, y); - } - - if (this.settings.get_boolean('window-maximized')) - this.maximize(); -}; - -Gtk.Window.prototype.save_geometry = function() { - let state = this.get_window().get_state(); - - let maximized = (state & Gdk.WindowState.MAXIMIZED); - this.settings.set_boolean('window-maximized', maximized); - - if (maximized || (state & Gdk.WindowState.FULLSCREEN)) - return; - - // GLib.Variant.new() can handle arrays just fine - let size = this.get_size(); - this.settings.set_value('window-size', new GLib.Variant('(ii)', size)); - - let position = this.get_position(); - this.settings.set_value('window-position', new GLib.Variant('(ii)', position)); -}; - diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/nativeMessagingHost.js gnome-shell-extension-zorin-connect-28.0.2/src/service/nativeMessagingHost.js --- gnome-shell-extension-zorin-connect-24.1/src/service/nativeMessagingHost.js 2019-03-04 01:55:22.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/nativeMessagingHost.js 2019-11-30 12:13:52.000000000 +0000 @@ -28,7 +28,7 @@ this._devices = {}; } - return Object.values(this._devices); + return this._devices; } vfunc_activate() { @@ -131,7 +131,7 @@ // A request to invoke an action } else if (message.type === 'share') { let actionName; - let device = this._devices[message.data.device]; + let device = this.devices[message.data.device]; if (device) { if (message.data.action === 'share') { @@ -172,7 +172,7 @@ let available = []; - for (let device of this.devices) { + for (let device of Object.values(this.devices)) { let share = device.actions.get_action_enabled('shareUri'); let telephony = device.actions.get_action_enabled('shareSms'); @@ -217,12 +217,12 @@ iface.g_object_path ); - this._devices[iface.g_object_path] = iface; + this.devices[iface.g_object_path] = iface; this.sendDeviceList(); } _onObjectRemoved(manager, object) { - delete this._devices[object.g_object_path]; + delete this.devices[object.g_object_path]; this.sendDeviceList(); } }); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/base.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/base.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/base.js 2019-05-29 12:39:36.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/base.js 2019-11-30 12:22:30.000000000 +0000 @@ -20,29 +20,21 @@ this._name = name; this._meta = imports.service.plugins[name].Metadata; - // Init GSettings + // GSettings this.settings = new Gio.Settings({ settings_schema: zorin_connect.gschema.lookup(this._meta.id, false), - path: `${zorin_connect.settings.path}device/${device.id}/plugin/${name}/` + path: `${device.settings.path}plugin/${name}/` }); // GActions this._gactions = []; if (this._meta.actions) { - // Register based on device capabilities, which shouldn't change - let deviceHandles = this.device.settings.get_strv('incoming-capabilities'); - let deviceProvides = this.device.settings.get_strv('outgoing-capabilities'); - let disabled = this.device.settings.get_strv('disabled-actions'); let menu = this.device.settings.get_strv('menu-actions'); for (let name in this._meta.actions) { let meta = this._meta.actions[name]; - - if (meta.incoming.every(p => deviceProvides.includes(p)) && - meta.outgoing.every(p => deviceHandles.includes(p))) { - this._registerAction(name, meta, menu, disabled); - } + this._registerAction(name, menu.indexOf(name), meta); } } } @@ -59,63 +51,75 @@ return Gio.Application.get_default(); } - _activateAction(action, parameter) { + _activateAction(action, parameter = null) { try { - parameter = parameter ? parameter.full_unpack() : null; + if (parameter instanceof GLib.Variant) { + parameter = parameter.full_unpack(); + } if (Array.isArray(parameter)) { this[action.name].apply(this, parameter); - } else if (parameter) { - this[action.name].call(this, parameter); } else { - this[action.name].call(this); + this[action.name].call(this, parameter); } } catch (e) { - debug(e, action.name); + logError(e, action.name); } } - _registerAction(name, meta, menu, disabled) { - let action = new Gio.SimpleAction({ - name: name, - parameter_type: meta.parameter_type, - state: new GLib.Variant('(ss)', [meta.label, meta.icon_name]) - }); - - // Set the enabled state - action.set_enabled(this.device.connected && !disabled.includes(action.name)); - - // Bind the activation - action.connect('activate', this._activateAction.bind(this)); - - this.device.add_action(action); - - // Menu - let index = menu.indexOf(action.name); + _registerAction(name, menuIndex, meta) { + try { + // Device Action + let action = new Gio.SimpleAction({ + name: name, + parameter_type: meta.parameter_type, + enabled: false + }); + action.connect('activate', this._activateAction.bind(this)); + + this.device.add_action(action); + + // Menu + if (menuIndex > -1) { + this.device.addMenuAction( + action, + menuIndex, + meta.label, + meta.icon_name + ); + } - if (index > -1) { - this.device.menu.add_action(action, index); + this._gactions.push(action); + } catch (e) { + logError(e, `${this.device.name}: ${this.name}`); } - - this._gactions.push(action); } /** * This is called when a packet is received the plugin is a handler for + * + * @param {object} packet - A KDE Connect packet */ handlePacket(packet) { throw new GObject.NotImplementedError(); } /** - * These two methods are optional and called by the device in response to - * the connection state changing. + * These two methods are called by the device in response to the connection + * state changing. */ connected() { - let disabled = this.device.settings.get_strv('disabled-actions'); + // Enabled based on device capabilities, which might change + let incoming = this.device.settings.get_strv('incoming-capabilities'); + let outgoing = this.device.settings.get_strv('outgoing-capabilities'); for (let action of this._gactions) { - action.set_enabled(!disabled.includes(action.name)); + let meta = this._meta.actions[action.name]; + + if (meta.incoming.every(type => outgoing.includes(type)) && + meta.outgoing.every(type => incoming.includes(type))) { + action.set_enabled(true); + } } } @@ -203,10 +207,11 @@ * any dangling signal handlers. */ destroy() { - this._gactions.map(action => { - this.device.menu.remove_action(`device.${action.name}`); + for (let action of this._gactions) { + this.device.removeMenuAction(`device.${action.name}`); this.device.remove_action(action.name); - }); + action.run_dispose(); + } // Write the cache to disk synchronously if (this.__cache_file && !this.__cache_lock) { @@ -225,8 +230,8 @@ } // Try to avoid any cyclic references from signal handlers - GObject.signal_handlers_destroy(this); - GObject.signal_handlers_destroy(this.settings); + this.settings.run_dispose(); + this.run_dispose(); } }); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/battery.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/battery.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/battery.js 2019-03-04 02:08:44.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/battery.js 2019-11-30 12:22:46.000000000 +0000 @@ -146,10 +146,10 @@ /** * Notify that the remote device considers the battery level low */ - _notifyState() { + _batteryNotification(event, title, body, iconName) { let buttons = []; - // Offer the option to locate the device, if available + // Offer the option to ring the device, if available if (this.device.get_action_enabled('ring')) { buttons = [{ label: _('Ring'), @@ -159,12 +159,10 @@ } this.device.showNotification({ - id: 'battery|threshold', - // TRANSLATORS: eg. Google Pixel: Battery is low - title: _('%s: Battery is low').format(this.device.name), - // TRANSLATORS: eg. 15% remaining - body: _('%d%% remaining').format(this.level), - icon: new Gio.ThemedIcon({name: 'battery-caution-symbolic'}), + id: `battery|${event}`, + title: title, + body: body, + icon: new Gio.ThemedIcon({name: iconName}), buttons: buttons }); @@ -172,6 +170,39 @@ this._thresholdLevel = this.level; } + _lowBatteryNotification() { + if (!this.settings.get_boolean('low-battery-notification')) { + return; + } + + this._batteryNotification( + 'battery|low', + // TRANSLATORS: eg. Google Pixel: Battery is low + _('%s: Battery is low').format(this.device.name), + // TRANSLATORS: eg. 15% remaining + _('%d%% remaining').format(this.level), + 'battery-caution-symbolic' + ); + + // Save the threshold level + this._thresholdLevel = this.level; + } + + _fullBatteryNotification() { + if (!this.settings.get_boolean('full-battery-notification')) { + return; + } + + this._batteryNotification( + 'battery|full', + // TRANSLATORS: eg. Google Pixel: Battery is full + _('%s: Battery is full').format(this.device.name), + // TRANSLATORS: when the battery is fully charged + _('Fully Charged'), + 'battery-full-charged-symbolic' + ); + } + /** * Handle a remote battery update. * @@ -185,14 +216,24 @@ if (this._level !== packet.body.currentCharge) { this._level = packet.body.currentCharge; + // If the level is above the threshold hide the notification if (this._level > this._thresholdLevel) { - this.device.hideNotification('battery|threshold'); + this.device.hideNotification('battery|low'); + } + + // If the level just changed to full show a notification + if (this._level === 100) { + this._fullBatteryNotification(); + + // Otherwise hide it + } else { + this.device.hideNotification('battery|full'); } } // Device considers the level low if (packet.body.thresholdEvent > 0) { - this._notifyState(); + this._lowBatteryNotification(); } this._updateEstimate(); @@ -205,7 +246,6 @@ */ _requestState() { this.device.sendPacket({ - id: 0, type: 'kdeconnect.battery.request', body: {request: true} }); @@ -219,14 +259,18 @@ return; } - this.device.sendPacket({ - type: 'kdeconnect.battery', - body: { - currentCharge: this.service.upower.level, - isCharging: this.service.upower.charging, - thresholdEvent: this.service.upower.threshold - } - }); + let upower = this.service.get('upower'); + + if (upower) { + this.device.sendPacket({ + type: 'kdeconnect.battery', + body: { + currentCharge: upower.level, + isCharging: upower.charging, + thresholdEvent: upower.threshold + } + }); + } } /** @@ -234,16 +278,18 @@ */ _monitorState() { try { + let upower = this.service.components.get('upower'); + let incoming = this.device.settings.get_strv('incoming-capabilities'); + switch (true) { - // upower failed, already monitoring, no battery or no support - case (!this.service.upower): + case (!incoming.includes('kdeconnect.battery')): case (this._upowerId > 0): - case (this.service.type !== 'laptop'): - case (!this.device.get_incoming_supported('battery')): + case (!upower): + case (!upower.is_present): return; } - this._upowerId = this.service.upower.connect( + this._upowerId = upower.connect( 'changed', this._sendState.bind(this) ); @@ -256,9 +302,18 @@ } _unmonitorState() { - if (this._upowerId > 0) { - this.service.upower.disconnect(this._upowerId); - this._upowerId = 0; + try { + if (this._upowerId > 0) { + let upower = this.service.components.get('upower'); + + if (upower) { + upower.disconnect(this._upowerId); + } + + this._upowerId = 0; + } + } catch (e) { + logError(e, this.device.name); } } diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/clipboard.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/clipboard.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/clipboard.js 2019-05-01 11:35:11.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/clipboard.js 2019-11-30 12:23:01.000000000 +0000 @@ -10,8 +10,14 @@ var Metadata = { label: _('Clipboard'), id: 'org.gnome.Shell.Extensions.ZorinConnect.Plugin.Clipboard', - incomingCapabilities: ['kdeconnect.clipboard'], - outgoingCapabilities: ['kdeconnect.clipboard'], + incomingCapabilities: [ + 'kdeconnect.clipboard', + 'kdeconnect.clipboard.connect' + ], + outgoingCapabilities: [ + 'kdeconnect.clipboard', + 'kdeconnect.clipboard.connect' + ], actions: { clipboardPush: { label: _('Clipboard Push'), @@ -45,26 +51,60 @@ super._init(device, 'clipboard'); try { - let display = Gdk.Display.get_default(); - this._clipboard = Gtk.Clipboard.get_default(display); + this._clipboard = this.service.components.get('clipboard'); + + // Watch local clipboard for changes + this._textChangedId = this._clipboard.connect( + 'notify::text', + this._onLocalClipboardChanged.bind(this) + ); } catch (e) { this.destroy(); throw e; } // Buffer content to allow selective sync - this._localBuffer = ''; - this._remoteBuffer = ''; + this._localBuffer = null; + this._localTimestamp = 0; + this._remoteBuffer = null; + } + + connected() { + super.connected(); - // Watch local clipboard for changes - this._ownerChangeId = this._clipboard.connect( - 'owner-change', - this._onLocalClipboardChanged.bind(this) - ); + // TODO: if we're not auto-syncing local->remote, but we are doing the + // reverse, it's possible older remote content will end up + // overwriting newer local content. + if (!this.settings.get_boolean('send-content')) return; + + if (this._localBuffer !== null && this._localTimestamp) { + this.device.sendPacket({ + type: 'kdeconnect.clipboard.connect', + body: { + content: this._localBuffer, + timestamp: this._localTimestamp + } + }); + } } handlePacket(packet) { - if (packet.body.hasOwnProperty('content')) { + if (!packet.body.hasOwnProperty('content')) return; + + if (packet.type === 'kdeconnect.clipboard') { + this._handleContent(packet); + } else if (packet.type === 'kdeconnect.clipboard.connect') { + this._handleConnectContent(packet); + } + } + + _handleContent(packet) { + this._onRemoteClipboardChanged(packet.body.content); + } + + _handleConnectContent(packet) { + if (packet.body.hasOwnProperty('timestamp') && + packet.body.timestamp > this._localTimestamp) { this._onRemoteClipboardChanged(packet.body.content); } } @@ -72,14 +112,13 @@ /** * Store the updated clipboard content and forward it if enabled */ - _onLocalClipboardChanged(clipboard, event) { - clipboard.request_text((clipboard, text) => { - this._localBuffer = text; + _onLocalClipboardChanged(clipboard, pspec) { + this._localBuffer = clipboard.text; + this._localTimestamp = Date.now(); - if (this.settings.get_boolean('send-content')) { - this.clipboardPush(); - } - }); + if (this.settings.get_boolean('send-content')) { + this.clipboardPush(); + } } /** @@ -98,16 +137,21 @@ */ clipboardPush() { // Don't sync if the clipboard is empty or not text - if (this._localBuffer === null) - return; + if (!this._localTimestamp) return; if (this._remoteBuffer !== this._localBuffer) { this._remoteBuffer = this._localBuffer; - this.device.sendPacket({ - type: 'kdeconnect.clipboard', - body: {content: this._localBuffer} - }); + // If the buffer is %null, the clipboard contains non-text content, + // so we neither clear the remote clipboard nor pass the content + if (this._localBuffer !== null) { + this.device.sendPacket({ + type: 'kdeconnect.clipboard', + body: { + content: this._localBuffer + } + }); + } } } @@ -117,13 +161,16 @@ clipboardPull() { if (this._localBuffer !== this._remoteBuffer) { this._localBuffer = this._remoteBuffer; + this._localTimestamp = Date.now(); - this._clipboard.set_text(this._remoteBuffer, -1); + this._clipboard.text = this._remoteBuffer; } } destroy() { - this._clipboard.disconnect(this._ownerChangeId); + if (this._clipboard && this._textChangedId) { + this._clipboard.disconnect(this._textChangedId); + } super.destroy(); } diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/contacts.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/contacts.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/contacts.js 2019-03-04 02:08:16.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/contacts.js 2019-11-30 12:23:15.000000000 +0000 @@ -7,6 +7,17 @@ const PluginsBase = imports.service.plugins.base; const Contacts = imports.service.components.contacts; +/* + * We prefer libebook's vCard parser if it's available + */ +var EBookContacts; + +try { + EBookContacts = imports.gi.EBookContacts; +} catch (e) { + EBookContacts = null; +} + var Metadata = { label: _('Contacts'), @@ -26,10 +37,12 @@ /** * vCard 2.1 Patterns */ -const FIELD_BASIC = /^([^:;]+):(.+)$/; -const FIELD_TYPED = /^([^:;]+);([^:]+):(.+)$/; -const FIELD_TYPED_KEY = /item\d{1,2}\./; -const FIELD_TYPED_META = /([a-z]+)=(.*)/i; +const VCARD_FOLDING = /\r\n |\r |\n |=\n/g; +const VCARD_SUPPORTED = /^fn|tel|photo|x-kdeconnect/i; +const VCARD_BASIC = /^([^:;]+):(.+)$/; +const VCARD_TYPED = /^([^:;]+);([^:]+):(.+)$/; +const VCARD_TYPED_KEY = /item\d{1,2}\./; +const VCARD_TYPED_META = /([a-z]+)=(.*)/i; /** @@ -43,6 +56,7 @@ _init(device) { super._init(device, 'contacts'); this._store = new Contacts.Store(device.id); + this._store.fetch = this.requestUids.bind(this); // Notify when the store is ready this._contactsStoreReadyId = this._store.connect( @@ -79,12 +93,15 @@ _handleUids(packet) { try { - // Delete any contacts that were removed on the device let contacts = this._store.contacts; let remote_uids = packet.body.uids; let removed = false; delete packet.body.uids; + // Usually a failed request, so avoid wiping the cache + if (remote_uids.length === 0) return; + + // Delete any contacts that were removed on the device for (let i = 0, len = contacts.length; i < len; i++) { let contact = contacts[i]; @@ -194,7 +211,7 @@ // Say "chowdah" frenchie! } catch (e) { - warning(`Failed to decode UTF-8 VCard field "${input}"`); + debug(e, `Failed to decode UTF-8 VCard field ${input}`); return input; } } @@ -215,26 +232,26 @@ }; // Remove line folding and split - let lines = vcard_data.replace(/\n /g, '').split('\n'); + let lines = vcard_data.replace(VCARD_FOLDING, '').split(/\r\n|\r|\n/); for (let i = 0, len = lines.length; i < len; i++) { let line = lines[i]; let results, key, type, value; - // Empty line - if (!line) continue; + // Empty line or a property we aren't interested in + if (!line || !line.match(VCARD_SUPPORTED)) continue; // Basic Fields (fn, x-kdeconnect-timestamp, etc) - if ((results = line.match(FIELD_BASIC))) { + if ((results = line.match(VCARD_BASIC))) { [results, key, value] = results; vcard[key.toLowerCase()] = value; continue; } // Typed Fields (tel, adr, etc) - if ((results = line.match(FIELD_TYPED))) { + if ((results = line.match(VCARD_TYPED))) { [results, key, type, value] = results; - key = key.replace(FIELD_TYPED_KEY, '').toLowerCase(); + key = key.replace(VCARD_TYPED_KEY, '').toLowerCase(); value = value.split(';'); type = type.split(';'); @@ -242,7 +259,7 @@ let meta = {}; for (let i = 0, len = type.length; i < len; i++) { - let res = type[i].match(FIELD_TYPED_META); + let res = type[i].match(VCARD_TYPED_META); if (res) { meta[res[1]] = res[2]; @@ -252,7 +269,7 @@ } // Value(s) - if (!vcard[key]) vcard[key] = []; + if (vcard[key] === undefined) vcard[key] = []; // Decode QUOTABLE-PRINTABLE if (meta.ENCODING && meta.ENCODING === 'QUOTED-PRINTABLE') { @@ -278,7 +295,7 @@ return vcard; } - async parseContact(uid, vcard_data) { + async parseVCardNative(uid, vcard_data) { try { let vcard = this.parseVCard21(vcard_data); @@ -309,7 +326,60 @@ return contact; } catch (e) { - warning(e, `Failed to parse VCard contact "${uid}"`); + debug(e, `Failed to parse VCard contact ${uid}`); + return undefined; + } + } + + async parseVCard(uid, vcard_data) { + try { + let contact = { + id: uid, + name: _('Unknown Contact'), + numbers: [], + origin: 'device', + timestamp: 0 + }; + + let evcard = EBookContacts.VCard.new_from_string(vcard_data); + let evattrs = evcard.get_attributes(); + + for (let i = 0, len = evattrs.length; i < len; i++) { + let attr = evattrs[i]; + let data, number; + + switch (attr.get_name().toLowerCase()) { + case 'fn': + contact.name = attr.get_value(); + break; + + case 'tel': + number = {value: attr.get_value(), type: 'unknown'}; + + if (attr.has_type('CELL')) + number.type = 'cell'; + else if (attr.has_type('HOME')) + number.type = 'home'; + else if (attr.has_type('WORK')) + number.type = 'work'; + + contact.numbers.push (number); + break; + + case 'x-kdeconnect-timestamp': + contact.timestamp = parseInt(attr.get_value()); + break; + + case 'photo': + data = GLib.base64_decode(attr.get_value()); + contact.avatar = await this._store.storeAvatar(data); + break; + } + } + + return contact; + } catch (e) { + debug(e, `Failed to parse VCard contact ${uid}`); return undefined; } } @@ -321,7 +391,13 @@ // Parse each vCard and add the contact for (let [uid, vcard] of Object.entries(packet.body)) { - let contact = await this.parseContact(uid, vcard); + let contact; + + if (EBookContacts) { + contact = await this.parseVCard(uid, vcard); + } else { + contact = await this.parseVCardNative(uid, vcard); + } if (contact) { this._store.add(contact); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/findmyphone.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/findmyphone.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/findmyphone.js 2019-03-04 02:08:02.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/findmyphone.js 2019-11-30 12:23:38.000000000 +0000 @@ -17,7 +17,7 @@ actions: { ring: { label: _('Ring'), - icon_name: 'find-location-symbolic', + icon_name: 'phonelink-ring-symbolic', parameter_type: null, incoming: [], @@ -90,33 +90,6 @@ /** - * Return the backend to be used for playing sound effects - * - * @return {string|boolean} - 'gsound', 'libcanberra' or %false - */ -function get_backend() { - if (window._SFX_BACKEND) { - return _SFX_BACKEND; - } - - // Service-wide GSound.Context singleton - try { - window._GSOUND_CONTEXT = new imports.gi.GSound.Context(); - window._GSOUND_CONTEXT.init(null); - window._SFX_BACKEND = 'gsound'; - - // Try falling back to libcanberra - } catch (e) { - if (GLib.find_program_in_path('canberra-gtk-play') !== null) { - window._SFX_BACKEND = 'libcanberra'; - } - } - - return _SFX_BACKEND; -} - - -/** * Used to ensure 'audible-bell' is enabled for fallback */ const WM_SETTINGS = new Gio.Settings({ @@ -135,119 +108,86 @@ super._init({ buttons: Gtk.ButtonsType.CLOSE, image: new Gtk.Image({ - icon_name: 'find-location-symbolic', - pixel_size: 128 + icon_name: 'phonelink-ring-symbolic', + pixel_size: 512, + halign: Gtk.Align.CENTER, + hexpand: true, + valign: Gtk.Align.CENTER, + vexpand: true, + visible: true }), - urgency_hint: true, - window_position: Gtk.WindowPosition.CENTER_ALWAYS + urgency_hint: true }); this.set_keep_above(true); + this.maximize(); this.message_area.destroy(); - // Ensure the volume is sufficient - let mixer = Gio.Application.get_default().pulseaudio; + // If the mixer is available start fading the volume up + let service = Gio.Application.get_default(); + let mixer = service.components.get('pulseaudio'); if (mixer) { this._stream = mixer.output; - this._previousVolume = this._stream.volume; + this._previousMuted = this._stream.muted; - this._stream.volume = 0.85; + this._previousVolume = this._stream.volume; + this._stream.muted = false; + this._stream.fade(0.85, 15); + + // Otherwise ensure audible-bell is enabled + } else { + this._previousBell = WM_SETTINGS.get_boolean('audible-bell'); + WM_SETTINGS.set_boolean('audible-bell', true); } - // Ensure audible-bell is enabled for fallback - this._previousBell = WM_SETTINGS.get_boolean('audible-bell'); - WM_SETTINGS.set_boolean('audible-bell', true); + // Start the alarm + let sound = service.components.get('sound'); + + if (sound !== undefined) { + sound.loopSound('phone-incoming-call', this.cancellable); + } - // Show the dialog and start the alarm + // Show the dialog this.show_all(); - this._cancellable = new Gio.Cancellable(); - this.bell(); + } + + vfunc_key_press_event(event) { + this.response(Gtk.ResponseType.DELETE_EVENT); + + return Gdk.EVENT_STOP; + } + + vfunc_motion_notify_event(event) { + this.response(Gtk.ResponseType.DELETE_EVENT); + + return Gdk.EVENT_STOP; } vfunc_response(response_id) { // Stop the alarm - this._cancellable.cancel(); + this.cancellable.cancel(); // Restore the mixer level if (this._stream) { - this._stream.volume = this._previousVolume; this._stream.muted = this._previousMuted; - } + this._stream.fade(this._previousVolume); // Restore the audible-bell - WM_SETTINGS.set_boolean('audible-bell', this._previousBell); + } else { + WM_SETTINGS.set_boolean('audible-bell', this._previousBell); + } this.destroy(); } - bell() { - let proc; - - switch (get_backend()) { - case 'gsound': - _GSOUND_CONTEXT.play_full( - {'event.id': 'phone-incoming-call'}, - this._cancellable, - (source, res) => { - try { - source.play_full_finish(res); - this.bell(); - } catch (e) { - } - } - ); - break; - - case 'libcanberra': - proc = new Gio.Subprocess({ - argv: ['canberra-gtk-play', '-i', 'phone-incoming-call'], - flags: Gio.SubprocessFlags.NONE - }); - proc.init(null); - - proc.wait_check_async(this._cancellable, (proc, res) => { - try { - proc.wait_check_finish(res); - this.bell(); - } catch (e) { - } - }); - break; - - default: - this._display = Gdk.Display.get_default(); - this._fallback(); - GLib.timeout_add( - GLib.PRIORITY_DEFAULT, - 1500, - () => this._fallback() - ); + get cancellable() { + if (this._cancellable === undefined) { + this._cancellable = new Gio.Cancellable(); } - } - - /** - * A fallback for playing an alert using gdk_display_bell() when neither - * GSound nor canberra-gtk-play are available. - */ - _fallback() { - let count = 0; - - GLib.timeout_add(GLib.PRIORITY_DEFAULT, 200, () => { - try { - if (count++ < 4 && !this._cancellable.is_cancelled()) { - this._display.beep(); - return GLib.SOURCE_CONTINUE; - } - - return GLib.SOURCE_REMOVE; - } catch (e) { - return GLib.SOURCE_REMOVE; - } - }); - return !this._cancellable.is_cancelled(); + return this._cancellable; } }); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/mousepad.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/mousepad.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/mousepad.js 2019-03-04 02:07:42.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/mousepad.js 2019-11-30 12:41:11.000000000 +0000 @@ -37,23 +37,6 @@ /** - * Printable ASCII range - */ -const _ASCII = /[\x20-\x7E]/; - - -/** - * Modifier Keycode Defaults - */ -const XKeycode = { - Alt_L: 0x40, - Control_L: 0x25, - Shift_L: 0x32, - Super_L: 0x85 -}; - - -/** * A map of "KDE Connect" keyvals to Gdk */ const KeyMap = new Map([ @@ -121,43 +104,7 @@ _init(device) { super._init(device, 'mousepad'); - // Atspi.init() return 2 on fail, but still marks itself as inited. We - // uninit before throwing an error otherwise any future call to init() - // will appear successful and other calls will cause Zorin Connect to exit. - // See: https://gitlab.gnome.org/GNOME/at-spi2-core/blob/master/atspi/atspi-misc.c - if (Atspi.init() === 2) { - Atspi.exit(); - this.destroy(); - throw new Error('Failed to start AT-SPI'); - } - - try { - this._display = Gdk.Display.get_default(); - this._seat = this._display.get_default_seat(); - this._pointer = this._seat.get_pointer(); - } catch (e) { - this.destroy(); - throw e; - } - - // Try to read modifier keycodes from Gdk - try { - let keymap = Gdk.Keymap.get_default(); - - let modifier = keymap.get_entries_for_keyval(Gdk.KEY_Alt_L)[1][0]; - XKeycode.Alt_L = modifier.keycode; - - modifier = keymap.get_entries_for_keyval(Gdk.KEY_Control_L)[1][0]; - XKeycode.Control_L = modifier.keycode; - - modifier = keymap.get_entries_for_keyval(Gdk.KEY_Shift_L)[1][0]; - XKeycode.Shift_L = modifier.keycode; - - modifier = keymap.get_entries_for_keyval(Gdk.KEY_Super_L)[1][0]; - XKeycode.Super_L = modifier.keycode; - } catch (e) { - warning('using default modifier keycodes', this.name); - } + this._input = this.service.components.get('input'); this.settings.bind( 'share-control', @@ -166,36 +113,30 @@ Gio.SettingsBindFlags.GET ); - this._state = false; this._stateId = 0; } connected() { super.connected(); - // Recheck for Caribou - if (!this._virtual_keyboard) { - try { - let Caribou = imports.gi.Caribou; - this._virtual_keyboard = Caribou.DisplayAdapter.get_default(); - } catch (e) { - this._virtual_keyboard = false; - } - } - this.sendState(); } disconnected() { super.disconnected(); + // Set the keyboard state to inactive this._state = false; this._stateId = 0; this.notify('state'); } get state() { - return (this._state); + if (this._state === undefined) { + this._state = false; + } + + return this._state; } get virtual_keyboard() { @@ -221,336 +162,71 @@ } _handleInput(input) { - let mods = false; + let keysym; + let modifiers = 0; // These are ordered, as much as possible, to create the shortest code // path for high-frequency, low-latency events (eg. mouse movement) switch (true) { case input.hasOwnProperty('scroll'): - if (input.dy < 0) { - this.clickPointer(5); - } else if (input.dy > 0) { - this.clickPointer(4); - } + this._input.scrollPointer(input.dx, input.dy); break; case (input.hasOwnProperty('dx') && input.hasOwnProperty('dy')): - this.movePointer(input.dx, input.dy); + this._input.movePointer(input.dx, input.dy); break; case (input.hasOwnProperty('key') || input.hasOwnProperty('specialKey')): // NOTE: \u0000 sometimes sent in advance of a specialKey packet if (input.key && input.key === '\u0000') return; - // We need to decide if we have modifiers to deal with - mods = (input.alt || input.ctrl || input.shift || input.super); + // Modifiers + if (input.alt || input.ctrl || input.shift || input.super) { + if (input.alt) modifiers |= Gdk.ModifierType.MOD1_MASK; + if (input.ctrl) modifiers |= Gdk.ModifierType.CONTROL_MASK; + if (input.shift) modifiers |= Gdk.ModifierType.SHIFT_MASK; + if (input.super) modifiers |= Gdk.ModifierType.SUPER_MASK; + } - // Special key (eg. non-printable ASCII) - if (input.specialKey && KeyMap.has(input.specialKey)) { - this.pressSpecialKey(input); + // Regular key (printable ASCII or Unicode) + if (input.key) { + this._input.pressKey(input.key, modifiers); + this.sendEcho(input); - // Regular key (printable ASCII) - } else if (input.key && _ASCII.test(input.key)) { - this.pressKey(input); - - // Unicode character without modifiers - } else if (input.key && !_ASCII.test(input.key) && !mods) { - this.pressUnicodeKey(input); - - // Unicode character with modifiers; Caribou/XTest is required - } else if (this.virtual_keyboard) { - this.pressKeySym(input); - - // Caribou not available or key out of range - } else { - warning(_('Additional Software Required') + ': libcaribou'); + // Special key (eg. non-printable ASCII) + } else if (input.specialKey && KeyMap.has(input.specialKey)) { + keysym = KeyMap.get(input.specialKey); + this._input.pressKey(keysym, modifiers); + this.sendEcho(input); } break; case input.hasOwnProperty('singleclick'): - this.clickPointer(1); + this._input.clickPointer(Gdk.BUTTON_PRIMARY); break; case input.hasOwnProperty('doubleclick'): - this.doubleclickPointer(1); + this._input.doubleclickPointer(Gdk.BUTTON_PRIMARY); break; case input.hasOwnProperty('middleclick'): - this.clickPointer(2); + this._input.clickPointer(Gdk.BUTTON_MIDDLE); break; case input.hasOwnProperty('rightclick'): - this.clickPointer(3); + this._input.clickPointer(Gdk.BUTTON_SECONDARY); break; case input.hasOwnProperty('singlehold'): - this.pressPointer(1); + this._input.pressPointer(Gdk.BUTTON_PRIMARY); break; - // This is not used, hold is released with a regular click instead case input.hasOwnProperty('singlerelease'): - this.releasePointer(1); + this._input.releasePointer(Gdk.BUTTON_PRIMARY); break; - } - } - - /** - * Pointer events - */ - clickPointer(button) { - try { - let [, x, y] = this._pointer.get_position(); - let monitor = this._display.get_monitor_at_point(x, y); - let scale = monitor.get_scale_factor(); - Atspi.generate_mouse_event(scale * x, scale * y, `b${button}c`); - } catch (e) { - logError(e, this.device.name); - } - } - - doubleclickPointer(button) { - try { - let [, x, y] = this._pointer.get_position(); - let monitor = this._display.get_monitor_at_point(x, y); - let scale = monitor.get_scale_factor(); - Atspi.generate_mouse_event(scale * x, scale * y, `b${button}d`); - } catch (e) { - logError(e, this.device.name); - } - } - - movePointer(dx, dy) { - try { - let [, x, y] = this._pointer.get_position(); - let monitor = this._display.get_monitor_at_point(x, y); - let scale = monitor.get_scale_factor(); - Atspi.generate_mouse_event(scale * dx, scale * dy, 'rel'); - } catch (e) { - logError(e, this.device.name); - } - } - - pressPointer(button) { - try { - let [, x, y] = this._pointer.get_position(); - let monitor = this._display.get_monitor_at_point(x, y); - let scale = monitor.get_scale_factor(); - Atspi.generate_mouse_event(scale * x, scale * y, `b${button}p`); - } catch (e) { - logError(e, this.device.name); - } - } - - releasePointer(button) { - try { - let [, x, y] = this._pointer.get_position(); - let monitor = this._display.get_monitor_at_point(x, y); - let scale = monitor.get_scale_factor(); - Atspi.generate_mouse_event(scale * x, scale * y, `b${button}r`); - } catch (e) { - logError(e, this.device.name); - } - } - - /** - * Phony virtual keyboard helpers - */ - keyval_press(keyval) { - Atspi.generate_keyboard_event( - keyval, - null, - Atspi.KeySynthType.PRESS | Atspi.KeySynthType.SYM - ); - } - - keyval_release(keyval) { - Atspi.generate_keyboard_event( - keyval, - null, - Atspi.KeySynthType.RELEASE | Atspi.KeySynthType.SYM - ); - } - - keyval_pressrelease(keyval) { - Atspi.generate_keyboard_event( - keyval, - null, - Atspi.KeySynthType.PRESSRELEASE | Atspi.KeySynthType.SYM - ); - } - - mode_lock(keycode) { - Atspi.generate_keyboard_event( - keycode, - null, - Atspi.KeySynthType.PRESS - ); - } - mode_unlock(keycode) { - Atspi.generate_keyboard_event( - keycode, - null, - Atspi.KeySynthType.RELEASE - ); - } - - /** - * Simulate a keypress in the printable ASCII range (x20-x7E) - * - * @param {object} input - 'body' of a 'kdeconnect.mousepad.request' packet - */ - pressKey(input) { - try { - debug(`key: ${input.key}`); - - // Press Modifiers - if (input.alt) this.mode_lock(XKeycode.Alt_L); - if (input.ctrl) this.mode_lock(XKeycode.Control_L); - if (input.shift) this.mode_lock(XKeycode.Shift_L); - if (input.super) this.mode_lock(XKeycode.Super_L); - - Atspi.generate_keyboard_event( - 0, - input.key, - Atspi.KeySynthType.STRING - ); - - // Release Modifiers - if (input.alt) this.mode_unlock(XKeycode.Alt_L); - if (input.ctrl) this.mode_unlock(XKeycode.Control_L); - if (input.shift) this.mode_unlock(XKeycode.Shift_L); - if (input.super) this.mode_unlock(XKeycode.Super_L); - - this.sendEcho(input); - } catch (e) { - logError(e, this.device.name); - } - } - - /** - * Simulate a special key from KeyMap (F1, Home, Esc, etc) - * - * @param {object} input - 'body' of a 'kdeconnect.mousepad.request' packet - */ - pressSpecialKey(input) { - try { - debug(`specialKey: ${KeyMap.get(input.specialKey)}`); - - // Press Modifiers - if (input.alt) this.mode_lock(XKeycode.Alt_L); - if (input.ctrl) this.mode_lock(XKeycode.Control_L); - if (input.shift) this.mode_lock(XKeycode.Shift_L); - if (input.super) this.mode_lock(XKeycode.Super_L); - - Atspi.generate_keyboard_event( - KeyMap.get(input.specialKey), - null, - Atspi.KeySynthType.PRESSRELEASE | Atspi.KeySynthType.SYM - ); - - // Release Modifiers - if (input.alt) this.mode_unlock(XKeycode.Alt_L); - if (input.ctrl) this.mode_unlock(XKeycode.Control_L); - if (input.shift) this.mode_unlock(XKeycode.Shift_L); - if (input.super) this.mode_unlock(XKeycode.Super_L); - - this.sendEcho(input); - } catch (e) { - logError(e, this.device.name); - } - } - - /** - * Simulate the composition of a unicode character with Control+Shift+u, [hex], Return - * - * @param {object} input - 'body' of a 'kdeconnect.mousepad.request' packet - */ - pressUnicodeKey(input) { - try { - debug(`unicodeKey: ${input.key}`); - - // TODO: Hardcoded Control_L and Shift_L keycodes. - // Using Control and Shift keysym is not working (it triggers key release) - // Probably using LOCKMODIFIERS will not work either as unlocking the modifier - // will not trigger a release - - let ucode = input.key.charCodeAt(0).toString(16); - let ukeyval; - - // Press Control_L & Shift_L - this.mode_lock(XKeycode.Control_L); - this.mode_lock(XKeycode.Shift_L); - - // Press and release 'u' - this.keyval_pressrelease(Gdk.KEY_U); - - // Release Control_L & Shift_L - this.mode_unlock(XKeycode.Control_L); - this.mode_unlock(XKeycode.Shift_L); - - // Press and release hex code - for (let h = 0; h < ucode.length; h++) { - ukeyval = Gdk.unicode_to_keyval(ucode.charAt(h).codePointAt(0)); - this.keyval_pressrelease(ukeyval); - } - - // Press and release Return - this.keyval_pressrelease(Gdk.KEY_Return); - - this.sendEcho(input); - } catch (e) { - logError(e, this.device.name); - } - } - - /** - * Simulate a unicode key press with modifiers using libcaribou - * - * @param {object} input - 'body' of a 'kdeconnect.mousepad.request' packet - * @param {number} mask - Modifier mask for keypress - */ - pressKeySym(input) { - try { - debug('simulating keypress with libcaribou'); - - // Transform unicode to hex code - let ucode = input.key.charCodeAt(0).toString(16); - let ukeyvar; - - // Prepare modifier mask - let mask = 0; - if (input.alt) mask |= Gdk.ModifierType.MOD1_MASK; - if (input.ctrl) mask |= Gdk.ModifierType.CONTROL_MASK; - if (input.shift) mask |= Gdk.ModifierType.SHIFT_MASK; - if (input.super) mask |= Gdk.ModifierType.MOD4_MASK; - - debug(`unicode hex: /u${ucode}, mask: ${mask}`); - - // Press Control + Shift - // NOTE: .mod_un/lock does not work as mod_unlock is not equivalent - // to a key release - this.virtual_keyboard.keyval_press(Gdk.KEY_Control_L); - this.virtual_keyboard.keyval_press(Gdk.KEY_Shift_L); - - // Press and release 'u' - this.virtual_keyboard.keyval_press(Gdk.KEY_U); - this.virtual_keyboard.keyval_release(Gdk.KEY_U); - - // Press and release hex code - for (let h = 0; h < ucode.length; h++) { - ukeyvar = Gdk.unicode_to_keyval(ucode.charAt(h).codePointAt(0)); - this.virtual_keyboard.keyval_press(ukeyvar); - this.virtual_keyboard.keyval_release(ukeyvar); - } - - // Release Control + Shift - this.virtual_keyboard.keyval_release(Gdk.KEY_Shift_L); - this.virtual_keyboard.keyval_release(Gdk.KEY_Control_L); - - this.sendEcho(input); - } catch (e) { - logError(e, this.device.name); + default: + logError(new Error('Unknown input')); } } @@ -913,8 +589,6 @@ _grab() { if (!this.visible || this._device) return; - debug('acquiring grab'); - let seat = Gdk.Display.get_default().get_default_seat(); let status = seat.grab( this.get_window(), @@ -926,7 +600,7 @@ ); if (status !== Gdk.GrabStatus.SUCCESS) { - warning('Grabbing keyboard failed'); + logError(new Error('Grabbing keyboard failed')); return; } @@ -937,8 +611,6 @@ _ungrab() { if (this._device) { - debug('releasing grab'); - this._device.get_seat().ungrab(); this._device = null; this.grab_remove(); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/mpris.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/mpris.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/mpris.js 2019-03-04 02:07:20.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/mpris.js 2019-11-30 12:24:29.000000000 +0000 @@ -1,16 +1,18 @@ 'use strict'; const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; const GObject = imports.gi.GObject; const PluginsBase = imports.service.plugins.base; +const DBus = imports.service.components.dbus; var Metadata = { label: _('MPRIS'), id: 'org.gnome.Shell.Extensions.ZorinConnect.Plugin.MPRIS', - incomingCapabilities: ['kdeconnect.mpris.request'], - outgoingCapabilities: ['kdeconnect.mpris'], + incomingCapabilities: ['kdeconnect.mpris', 'kdeconnect.mpris.request'], + outgoingCapabilities: ['kdeconnect.mpris', 'kdeconnect.mpris.request'], actions: {} }; @@ -23,9 +25,6 @@ * https://specifications.freedesktop.org/mpris-spec/latest/ * https://github.com/GNOME/gnome-shell/blob/master/js/ui/mpris.js * https://github.com/JasonLG1979/gnome-shell-extensions-mediaplayer/wiki/Known-Player-Bugs - * - * TODO: It's probably possible to mirror a remote MPRIS2 player on local DBus - * https://github.com/KDE/kdeconnect-kde/commit/9e0d4874c072646f1018ad413d59d1f43e590777 */ var Plugin = GObject.registerClass({ GTypeName: 'ZorinConnectMPRISPlugin', @@ -35,33 +34,123 @@ super._init(device, 'mpris'); try { - this._notifyPlayersId = this.service.mpris.connect( + this._mpris = this.service.components.get('mpris'); + + this._notifyPlayersId = this._mpris.connect( 'notify::players', this._sendPlayerList.bind(this) ); - this._playerChangedId = this.service.mpris.connect( + this._playerChangedId = this._mpris.connect( 'player-changed', this._onPlayerChanged.bind(this) ); - this._playerSeekedId = this.service.mpris.connect( + this._playerSeekedId = this._mpris.connect( 'player-seeked', this._onPlayerSeeked.bind(this) ); } catch (e) { this.destroy(); - throw new Error('mpris-error'); + throw e; } } + get players() { + if (this._players === undefined) { + this._players = new Map(); + } + + return this._players; + } + handlePacket(packet) { + if (packet.type === 'kdeconnect.mpris.request') { + this._handleRequest(packet); + } else if (packet.type === 'kdeconnect.mpris') { + this._handleStatus(packet); + } + } + + connected() { + super.connected(); + + this._requestPlayerList(); + this._sendPlayerList(); + } + + _handleStatus(packet) { + try { + if (packet.body.hasOwnProperty('playerList')) { + this._handlePlayerList(packet.body.playerList); + } else if (packet.body.hasOwnProperty('player')) { + this._handlePlayerState(packet.body); + } + } catch (e) { + debug(e, `${this.device.name}: MPRIS`); + } + } + + /** + * Handle a player list update + * + * @param {array} playerList - A list of remote player names + */ + _handlePlayerList(playerList) { + for (let player of this.players.values()) { + if (!playerList.includes(player.Identity)) { + this.players.delete(player.Identity); + player.destroy(); + } + } + + for (let identity of playerList) { + this._device.sendPacket({ + type: 'kdeconnect.mpris.request', + body: { + player: identity, + requestNowPlaying: true, + requestVolume: true + } + }); + } + } + + /** + * Handle a player state update + * + * @param {object} state - The body of a kdeconnect.mpris packet + */ + _handlePlayerState(state) { + let player = this.players.get(state.player); + + if (player === undefined) { + player = new RemotePlayer(this.device, state); + this.players.set(state.player, player); + } else { + player.parseState(state); + } + } + + /** + * Request the list of player identities + */ + _requestPlayerList() { + this.device.sendPacket({ + type: 'kdeconnect.mpris.request', + body: { + requestPlayerList: true + } + }); + } + + _handleRequest(packet) { // A request for the list of players if (packet.body.requestPlayerList) { this._sendPlayerList(); // A request for an unknown player; send the list of players - } else if (!this.service.mpris.players.has(packet.body.player)) { + } else if (!this._mpris.players.has(packet.body.player)) { this._sendPlayerList(); // An album art request @@ -74,12 +163,6 @@ } } - connected() { - super.connected(); - - this._sendPlayerList(); - } - /** * Handle an incoming player command or information request * @@ -93,7 +176,7 @@ try { this._updating = true; - let player = this.service.mpris.players.get(packet.body.player); + let player = this._mpris.players.get(packet.body.player); // Player Actions if (packet.body.hasOwnProperty('action')) { @@ -231,7 +314,7 @@ return; } - let player = this.service.mpris.players.get(packet.body.player); + let player = this._mpris.players.get(packet.body.player); if (player.Metadata === null) { return; @@ -253,7 +336,6 @@ }); await transfer.upload({ - id: 0, type: 'kdeconnect.mpris', body: { transferringAlbumArt: true, @@ -262,7 +344,7 @@ } }); } catch (e) { - warning(e, `${this.device.name}: transferring album art`); + debug(e, 'transferring album art'); } finally { this._transferring = false; } @@ -276,29 +358,576 @@ let playerList = []; if (this.settings.get_boolean('share-players')) { - playerList = this.service.mpris.identities; + playerList = this._mpris.identities; } this.device.sendPacket({ - id: 0, type: 'kdeconnect.mpris', body: { playerList: playerList, - supportAlbumArtPayload: (this.device.connection_type === 'tcp') + supportAlbumArtPayload: true } }); } destroy() { try { - this.service.mpris.disconnect(this._notifyPlayersId); - this.service.mpris.disconnect(this._playerChangedId); - this.service.mpris.disconnect(this._playerSeekedId); + this._mpris.disconnect(this._notifyPlayersId); + this._mpris.disconnect(this._playerChangedId); + this._mpris.disconnect(this._playerSeekedId); } catch (e) { // Silence errors } + for (let [identity, player] of this.players.entries()) { + player.destroy(); + this.players.delete(identity); + } + super.destroy(); } }); + +/* + * A class for mirroring a remote Media Player on DBus + */ +const MPRISIface = zorin_connect.dbusinfo.lookup_interface('org.mpris.MediaPlayer2'); +const MPRISPlayerIface = zorin_connect.dbusinfo.lookup_interface('org.mpris.MediaPlayer2.Player'); + + +var RemotePlayer = GObject.registerClass({ + GTypeName: 'ZorinConnectMPRISRemotePlayer', + Properties: { + 'PlaybackStatus': GObject.ParamSpec.string( + 'PlaybackStatus', + 'Playback Status', + 'The current playback status.', + GObject.ParamFlags.READABLE, + null + ), + 'LoopStatus': GObject.ParamSpec.string( + 'LoopStatus', + 'Loop Status', + 'The current loop status.', + GObject.ParamFlags.READWRITE, + null + ), + 'Rate': GObject.ParamSpec.double( + 'Rate', + 'Rate', + 'The current playback rate.', + GObject.ParamFlags.READWRITE, + 0.0, 1.0, + 1.0 + ), + 'Shuffle': GObject.ParamSpec.boolean( + 'Shuffle', + 'Shuffle', + 'Whether track changes are linear.', + GObject.ParamFlags.READWRITE, + null + ), + 'Metadata': GObject.param_spec_variant( + 'Metadata', + 'Metadata', + 'The metadata of the current element.', + new GLib.VariantType('a{sv}'), + null, + GObject.ParamFlags.READABLE + ), + 'Volume': GObject.ParamSpec.double( + 'Volume', + 'Volume', + 'The volume level.', + GObject.ParamFlags.READWRITE, + 0.0, 1.0, + 1.0 + ), + 'Position': GObject.ParamSpec.int64( + 'Position', + 'Position', + 'The current track position in microseconds.', + GObject.ParamFlags.READABLE, + 0, Number.MAX_SAFE_INTEGER, + 0 + ), + 'CanGoNext': GObject.ParamSpec.boolean( + 'CanGoNext', + 'Can Go Next', + 'Whether the client can call the Next method.', + GObject.ParamFlags.READABLE, + null + ), + 'CanGoPrevious': GObject.ParamSpec.boolean( + 'CanGoPrevious', + 'Can Go Previous', + 'Whether the client can call the Previous method.', + GObject.ParamFlags.READABLE, + null + ), + 'CanPlay': GObject.ParamSpec.boolean( + 'CanPlay', + 'Can Play', + 'Whether playback can be started using Play or PlayPause.', + GObject.ParamFlags.READABLE, + null + ), + 'CanPause': GObject.ParamSpec.boolean( + 'CanPause', + 'Can Pause', + 'Whether playback can be paused using Play or PlayPause.', + GObject.ParamFlags.READABLE, + null + ), + 'CanSeek': GObject.ParamSpec.boolean( + 'CanSeek', + 'Can Seek', + 'Whether the client can control the playback position using Seek and SetPosition.', + GObject.ParamFlags.READABLE, + null + ), + 'CanControl': GObject.ParamSpec.boolean( + 'CanControl', + 'Can Control', + 'Whether the media player may be controlled over this interface.', + GObject.ParamFlags.READABLE, + null + ) + }, + Signals: { + 'Seeked': { + flags: GObject.SignalFlags.RUN_FIRST, + param_types: [GObject.TYPE_INT64] + } + } +}, class RemotePlayer extends GObject.Object { + + _init(device, initialState) { + super._init(); + + this._isPlaying = false; + this._device = device; + this.parseState(initialState); + + // Own name + let name = [device.name, this.Identity].join('').replace(/[\W]*/g, ''); + + this._ownerId = Gio.bus_own_name( + Gio.BusType.SESSION, + `org.mpris.MediaPlayer2.ZorinConnect.${name}`, + Gio.BusNameOwnerFlags.NONE, + this._onBusAcquired.bind(this), + this._onNameAcquired.bind(this), + this._onNameLost.bind(this) + ); + } + + _onBusAcquired(connection, name) { + debug(arguments); + + this._applicationIface = new DBus.Interface({ + g_instance: this, + g_connection: Gio.DBus.session, + g_object_path: '/org/mpris/MediaPlayer2', + g_interface_info: MPRISIface + }); + + this._playerIface = new DBus.Interface({ + g_instance: this, + g_connection: Gio.DBus.session, + g_object_path: '/org/mpris/MediaPlayer2', + g_interface_info: MPRISPlayerIface + }); + } + + _onNameAcquired(connection, name) { + } + + _onNameLost(connection, name) { + debug(arguments); + } + + parseState(state) { + this._Identity = state.player; + + // Metadata + let metadataChanged = false; + + if (state.hasOwnProperty('title')) { + metadataChanged = true; + this._title = state.title; + } + + if (state.hasOwnProperty('artist')) { + metadataChanged = true; + this._artist = state.artist; + } + + if (state.hasOwnProperty('album')) { + metadataChanged = true; + this._album = state.album; + } + + if (state.hasOwnProperty('length')) { + metadataChanged = true; + this._length = state.length * 1000; + } + + // Probably a good idea to update this before emitting the length change + if (state.hasOwnProperty('pos')) { + this._Position = state.pos * 1000; + } + + if (metadataChanged) this.notify('Metadata'); + + // Playback Status + if (state.hasOwnProperty('isPlaying')) { + if (this._isPlaying !== state.isPlaying) { + this._isPlaying = state.isPlaying; + this.notify('PlaybackStatus'); + } + } + + if (state.hasOwnProperty('canPlay')) { + if (this.CanPlay !== state.canPlay) { + this._CanPlay = state.canPlay; + this.notify('CanPlay'); + } + } + + if (state.hasOwnProperty('canPause')) { + if (this.CanPause !== state.canPause) { + this._CanPause = state.canPause; + this.notify('CanPause'); + } + } + + if (state.hasOwnProperty('canGoNext')) { + if (this.CanGoNext !== state.canGoNext) { + this._CanGoNext = state.canGoNext; + this.notify('CanGoNext'); + } + } + + if (state.hasOwnProperty('canGoPrevious')) { + if (this.CanGoPrevious !== state.canGoPrevious) { + this._CanGoPrevious = state.canGoPrevious; + this.notify('CanGoPrevious'); + } + } + + if (state.hasOwnProperty('volume')) { + this.volume = state.volume / 100; + } + } + + /* + * Native properties + */ + get device() { + return this._device; + } + + /* + * The org.mpris.MediaPlayer2 Interface + */ + get CanQuit() { + return false; + } + + get Fullscreen() { + return false; + } + + get CanSetFullscreen() { + return false; + } + + get CanRaise() { + return false; + } + + get HasTrackList() { + return false; + } + + get Identity() { + return this._Identity; + } + + get DesktopEntry() { + return 'org.gnome.Shell.Extensions.ZorinConnect'; + } + + get SupportedUriSchemes() { + return []; + } + + get SupportedMimeTypes() { + return []; + } + + Raise() { + } + + Quit() { + } + + /* + * The org.mpris.MediaPlayer2.Player Interface + */ + + // 'Playing', 'Paused', 'Stopped' + get PlaybackStatus() { + if (this._isPlaying) { + return 'Playing'; + } else { + return 'Stopped'; + } + } + + // 'None', 'Track', 'Playlist' + get LoopStatus() { + return 'None'; + } + + set LoopStatus(status) { + this.notify('LoopStatus'); + } + + get Rate() { + return 1.0; + } + + set Rate(rate) { + this.notify('Rate'); + } + + get Shuffle() { + return false; + } + + set Shuffle(mode) { + this.notify('Shuffle'); + } + + get Metadata() { + if (this._metadata === undefined) { + this._metadata = {}; + } + + Object.assign(this._metadata, { + 'xesam:artist': new GLib.Variant('as', [this._artist || '']), + 'xesam:album': new GLib.Variant('s', this._album || ''), + 'xesam:title': new GLib.Variant('s', this._title || ''), + 'mpris:length': new GLib.Variant('x', this._length || 0) + }); + + return this._metadata; + } + + get Volume() { + if (this._Volume === undefined) { + this._Volume = 1.0; + } + + return this._Volume; + } + + set Volume(level) { + if (this._Volume !== level) { + this._Volume = level; + this.notify('Volume'); + + this.device.sendPacket({ + type: 'kdeconnect.mpris.request', + body: { + player: this.Identity, + setVolume: this.Volume * 100 + } + }); + } + } + + get Position() { + if (this._Position === undefined) { + this._Position = 0; + } + + return this._Position; + } + + get MinimumRate() { + return 1.0; + } + + get MaximumRate() { + return 1.0; + } + + get CanGoNext() { + if (this._CanGoNext === undefined) { + this._CanGoNext = false; + } + + return this._CanGoNext; + } + + get CanGoPrevious() { + if (this._CanGoPrevious === undefined) { + this._CanGoPrevious = false; + } + + return this._CanGoPrevious; + } + + get CanPlay() { + if (this._CanPlay === undefined) { + this._CanPlay = false; + } + + return this._CanPlay; + } + + get CanPause() { + if (this._CanPause === undefined) { + this._CanPause = false; + } + + return this._CanPause; + } + + get CanSeek() { + if (this._CanSeek === undefined) { + this._CanSeek = false; + } + + return this._CanSeek; + } + + get CanControl() { + if (this._CanControl === undefined) { + this._CanControl = false; + } + + return true; + } + + Next() { + if (!this.CanControl || !this.CanGoNext) return; + + this.device.sendPacket({ + type: 'kdeconnect.mpris.request', + body: { + player: this.Identity, + action: 'Next' + } + }); + } + + Previous() { + if (!this.CanControl || !this.CanGoPrevious) return; + + this.device.sendPacket({ + type: 'kdeconnect.mpris.request', + body: { + player: this.Identity, + action: 'Previous' + } + }); + } + + Pause() { + if (!this.CanControl || !this.CanGoPause) return; + + this.device.sendPacket({ + type: 'kdeconnect.mpris.request', + body: { + player: this.Identity, + action: 'Pause' + } + }); + } + + PlayPause() { + if (!this.CanControl || !this.CanPause) return; + + this.device.sendPacket({ + type: 'kdeconnect.mpris.request', + body: { + player: this.Identity, + action: 'PlayPause' + } + }); + } + + Stop() { + if (!this.CanControl) return; + + this.device.sendPacket({ + type: 'kdeconnect.mpris.request', + body: { + player: this.Identity, + action: 'Stop' + } + }); + } + + Play() { + if (!this.CanControl || !this.CanPlay) return; + + this.device.sendPacket({ + type: 'kdeconnect.mpris.request', + body: { + player: this.Identity, + action: 'Next' + } + }); + } + + Seek(offset) { + if (!this.CanControl || !this.CanSeek) return; + + this.device.sendPacket({ + type: 'kdeconnect.mpris.request', + body: { + player: this.Identity, + Seek: offset + } + }); + } + + SetPosition(trackId, position) { + debug(`${this._Identity}: SetPosition(${trackId}, ${position})`); + + if (!this.CanControl || !this.CanSeek) return; + + this.device.sendPacket({ + type: 'kdeconnect.mpris.request', + body: { + player: this.Identity, + SetPosition: position / 1000 + } + }); + } + + OpenUri(uri) { + debug(`OpenUri(${uri}): Not Supported`); + } + + destroy() { + if (this._ownerId != 0) { + Gio.bus_unown_name(this._ownerId); + } + + if (this._applicationIface) { + this._applicationIface.destroy(); + } + + if (this._playerIface) { + this._playerIface.destroy(); + } + } +}); + diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/notification.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/notification.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/notification.js 2019-05-16 22:18:18.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/notification.js 2019-11-30 12:41:02.000000000 +0000 @@ -106,7 +106,7 @@ _init(device) { super._init(device, 'notification'); - this._sms = {}; + this._session = this.service.components.get('session'); } handlePacket(packet) { @@ -119,11 +119,11 @@ // We don't support *incoming* replies (yet) case 'kdeconnect.notification.reply': - warning('Not implemented', packet.type); + debug(`Not implemented: ${packet.type}`); return; default: - warning('Unknown notification packet', this.device.name); + debug(`Unknown notification packet: ${packet.type}`); } } @@ -141,9 +141,9 @@ if (packet.body.hasOwnProperty('isCancel')) { this.device.hideNotification(packet.body.id); - // A silent notification; process it so we can abort the transfer - } else if (packet.body.hasOwnProperty('silent')) { - this.silenceNotification(packet); + // A silent notification; silence it by aborting the icon transfer + } else if (packet.body.hasOwnProperty('silent') && packet.body.silent) { + this.device.rejectTransfer(packet); // A normal, remote notification } else { @@ -181,7 +181,7 @@ break; default: - warning('Unknown notification type', this.device.name); + debug(`Unknown notification type ${this.device.name}`); } } } @@ -207,16 +207,12 @@ */ async _uploadIcon(packet, icon) { try { - // Normalize icon-name strings into GIcons + // Normalize strings into GIcons if (typeof icon === 'string') { - icon = new Gio.ThemedIcon({name: icon}); + icon = Gio.Icon.new_for_string(icon); } switch (true) { - // TODO: Currently we skip icons for bluetooth connections - case (this.device.connection_type === 'bluetooth'): - return this.device.sendPacket(packet); - // GBytesIcon case (icon instanceof Gio.BytesIcon): return this._uploadBytesIcon(packet, icon.get_bytes()); @@ -349,7 +345,10 @@ return; } - debug(`(${notif.appName}) ${notif.title}: ${notif.text}`); + // Sending when the session is active is forbidden + if (this._session.active && !this.settings.get_boolean('send-active')) { + return; + } // TODO: revisit application notification settings let applications = JSON.parse(this.settings.get_string('applications')); @@ -380,7 +379,6 @@ delete notif.icon; let packet = { - id: 0, type: 'kdeconnect.notification', body: notif }; @@ -519,8 +517,6 @@ parameter: new GLib.Variant('s', packet.body.title) }; icon = icon || new Gio.ThemedIcon({name: 'sms-symbolic'}); - - this._sms[packet.body.ticker] = packet.body.id; break; // Ignore 'appName' if it's the same as 'title' @@ -547,39 +543,12 @@ } /** - * Handle a "silent" notification - * - * @param {kdeconnect.notification} packet - The notification packet - */ - async silenceNotification(packet) { - try { - if (!packet.payloadTransferInfo) { - return null; - } - - let transfer = this.device.createTransfer({ - output_stream: null, - size: packet.payloadSize - }); - - // Since we've passed a bogus stream, this will abort the transfer - await transfer.download( - packet.payloadTransferInfo.port || packet.payloadTransferInfo.uuid - ); - } catch (e) { - debug(e); - } - } - - /** * Report that a local notification has been closed/dismissed. * TODO: kdeconnect-android doesn't handle incoming isCancel packets. * * @param {string} id - The local notification id */ withdrawNotification(id) { - debug(id); - this.device.sendPacket({ type: 'kdeconnect.notification', body: { @@ -596,15 +565,6 @@ * @param {string} id - The remote notification id */ closeNotification(id) { - debug(id); - - let tickerId = this._sms[id]; - - if (tickerId) { - delete this._sms[id]; - id = tickerId; - } - this.device.sendPacket({ type: 'kdeconnect.notification.request', body: {cancel: id} @@ -616,18 +576,20 @@ * * @param {string} uuid - The requestReplyId for the repliable notification * @param {string} message - The message to reply with - * @param {object} notification - The original notification + * @param {object} notification - The original notification packet */ replyNotification(uuid, message, notification) { - debug([uuid, message]); - - // If the message has no content, we're being asked to open the dialog - if (message.length === 0) { - new NotificationUI.Dialog({ + // If the message has no content, open a dialog for the user to add one + if (!message) { + let dialog = new NotificationUI.ReplyDialog({ device: this.device, uuid: uuid, - notification: notification + notification: notification, + plugin: this }); + dialog.present(); + + // Otherwise just send the reply } else { this.device.sendPacket({ type: 'kdeconnect.notification.reply', diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/photo.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/photo.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/photo.js 2019-03-17 11:42:34.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/photo.js 2019-11-30 12:25:07.000000000 +0000 @@ -41,7 +41,8 @@ // A reusable launcher for silence procs this._launcher = new Gio.SubprocessLauncher({ - flags: Gio.SubprocessFlags.STDOUT_SILENCE | Gio.SubprocessFlags.STDERR_SILENCE + flags: (Gio.SubprocessFlags.STDOUT_SILENCE | + Gio.SubprocessFlags.STDERR_SILENCE) }); } @@ -57,11 +58,55 @@ } } + _ensureReceiveDirectory() { + let receiveDir = this.settings.get_string('receive-directory'); + + // Ensure a directory is set + if (!receiveDir) { + receiveDir = GLib.get_user_special_dir( + GLib.UserDirectory.DIRECTORY_PICTURES + ); + + // Fallback to ~/Pictures + let homeDir = GLib.get_home_dir(); + + if (!receiveDir || receiveDir === homeDir) { + receiveDir = GLib.build_filenamev([homeDir, 'Pictures']); + } + + this.settings.set_string('receive-directory', receiveDir); + } + + // Ensure the directory exists + if (!GLib.file_test(receiveDir, GLib.FileTest.IS_DIR)) { + GLib.mkdir_with_parents(receiveDir, 448); + } + + return receiveDir; + } + + _getFile(filename) { + let dirpath = this._ensureReceiveDirectory(); + let basepath = GLib.build_filenamev([dirpath, filename]); + let filepath = basepath; + let copyNum = 0; + + while (GLib.file_test(filepath, GLib.FileTest.EXISTS)) { + copyNum += 1; + filepath = `${basepath} (${copyNum})`; + } + + return Gio.File.new_for_path(filepath); + } + async _receivePhoto(packet) { let file, stream, success, transfer; try { - file = get_download_file(packet.body.filename); + // Remote device cancelled the photo operation + if (packet.body.cancel) return; + + file = this._getFile(packet.body.filename); stream = await new Promise((resolve, reject) => { file.replace_async(null, false, 0, 0, null, (file, res) => { @@ -83,7 +128,8 @@ // Open the photo on success if (success) { - open_uri (file.get_uri()); + let uri = file.get_uri(); + Gio.AppInfo.launch_default_for_uri_async(uri, null, null, null); // Clean up the downloaded file on failure } else { diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/ping.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/ping.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/ping.js 2019-03-04 02:06:40.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/ping.js 2019-11-30 12:25:25.000000000 +0000 @@ -38,8 +38,6 @@ } handlePacket(packet) { - debug(packet); - // Notification let notif = { title: this.device.name, @@ -60,7 +58,6 @@ debug(message); let packet = { - id: 0, type: 'kdeconnect.ping', body: {} }; diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/presenter.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/presenter.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/presenter.js 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/presenter.js 2019-11-30 12:25:38.000000000 +0000 @@ -0,0 +1,44 @@ +'use strict'; + +const GObject = imports.gi.GObject; + +const PluginsBase = imports.service.plugins.base; + + +var Metadata = { + label: _('Presentation'), + id: 'org.gnome.Shell.Extensions.ZorinConnect.Plugin.Presenter', + incomingCapabilities: ['kdeconnect.presenter'], + outgoingCapabilities: [], + actions: {} +}; + + +/** + * Presenter Plugin + * https://github.com/KDE/kdeconnect-kde/tree/master/plugins/presenter + * https://github.com/KDE/kdeconnect-android/tree/master/src/org/kde/kdeconnect/Plugins/PresenterPlugin/ + */ +var Plugin = GObject.registerClass({ + GTypeName: 'ZorinConnectPresenterPlugin' +}, class Plugin extends PluginsBase.Plugin { + + _init(device) { + super._init(device, 'presenter'); + + this._input = this.service.components.get('input'); + } + + handlePacket(packet) { + if (packet.body.hasOwnProperty('dx')) { + this._input.movePointer( + packet.body.dx * 1000, + packet.body.dy * 1000 + ); + } else if (packet.body.stop) { + // Currently unsupported and unnecessary as we just re-use the mouse + // pointer instead of showing an arbitrary window. + } + } +}); + diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/runcommand.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/runcommand.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/runcommand.js 2019-03-04 02:06:26.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/runcommand.js 2019-11-30 12:26:58.000000000 +0000 @@ -21,6 +21,14 @@ parameter_type: new GLib.VariantType('s'), incoming: ['kdeconnect.runcommand'], outgoing: ['kdeconnect.runcommand.request'] + }, + executeCommand: { + label: _('Commands'), + icon_name: 'system-run-symbolic', + + parameter_type: new GLib.VariantType('s'), + incoming: ['kdeconnect.runcommand'], + outgoing: ['kdeconnect.runcommand.request'] } } }; @@ -47,9 +55,22 @@ _init(device) { super._init(device, 'runcommand'); + + // Setup a launcher with env variables for commands + let application = GLib.build_filenamev([ + zorin_connect.extdatadir, + 'service', + 'daemon.js' + ]); + this._launcher = new Gio.SubprocessLauncher(); + this._launcher.setenv('ZORIN_CONNECT', application, false); + this._launcher.setenv('ZORIN_CONNECT_DEVICE_ID', this.device.id, false); + this._launcher.setenv('ZORIN_CONNECT_DEVICE_NAME', this.device.name, false); + this._launcher.setenv('ZORIN_CONNECT_DEVICE_ICON', this.device.icon_name, false); + this._launcher.setenv('ZORIN_CONNECT_DEVICE_DBUS', this.device.g_object_path, false); // Local Commands - this.settings.connect( + this._commandListChangedId = this.settings.connect( 'changed::command-list', this.sendCommandList.bind(this) ); @@ -58,15 +79,6 @@ // when the device is offline. this._remote_commands = {}; this.cacheProperties(['_remote_commands']); - - // Define executeCommand here so since plugin actions are all stateful - let executeCommand = new Gio.SimpleAction({ - name: 'executeCommand', - parameter_type: new GLib.VariantType('s') - }); - executeCommand.connect('activate', this._activateAction.bind(this)); - this.device.add_action(executeCommand); - this._gactions.push(executeCommand); } get remote_commands() { @@ -92,8 +104,11 @@ connected() { super.connected(); + // Disable the commands action until we know better this.sendCommandList(); this.requestCommandList(); + + this._handleCommandList(this.remote_commands); } cacheClear() { @@ -106,10 +121,6 @@ if (this.device.connected) { this.connected(); } - - if (this.device.get_incoming_supported('runcommand.request')) { - this._handleCommandList(this.remote_commands); - } } /** @@ -123,18 +134,25 @@ if (!commandList.hasOwnProperty(key)) { throw new Error(`Unknown command: ${key}`); } - - GLib.spawn_async( - null, - ['/bin/sh', '-c', commandList[key].command], - null, - GLib.SpawnFlags.DEFAULT, - null - ); + + let proc = this._launcher.spawnv([ + '/bin/sh', + '-c', + commandList[key].command + ]); + proc.wait_check_async(null, this._commandExit); } catch (e) { logError(e, this.device.name); } } + + _commandExit(proc, res) { + try { + proc.wait_check_finish(res); + } catch (e) { + debug(e); + } + } /** * Parse the response to a request for the remote command list. Remove the @@ -176,7 +194,12 @@ item.set_submenu(submenu); // If the submenu item is already present it will be replaced - this.device.menu.replace_action('commands', item); + let index = this.device.settings.get_strv('menu-actions').indexOf('commands'); + + if (index > -1) { + this.device.removeMenuAction('commands'); + this.device.addMenuItem(item, index); + } } /** @@ -190,7 +213,6 @@ */ executeCommand(key) { this.device.sendPacket({ - id: 0, type: 'kdeconnect.runcommand.request', body: {key: key} }); @@ -201,7 +223,6 @@ */ requestCommandList() { this.device.sendPacket({ - id: 0, type: 'kdeconnect.runcommand.request', body: {requestCommandList: true} }); @@ -214,10 +235,17 @@ let commands = this.settings.get_value('command-list').full_unpack(); this.device.sendPacket({ - id: 0, type: 'kdeconnect.runcommand', body: {commandList: commands} }); } + + destroy() { + if (this._commandListChangedId) { + this.settings.disconnect(this._commandListChangedId); + } + + super.destroy(); + } }); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/sftp.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/sftp.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/sftp.js 2019-05-29 12:41:12.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/sftp.js 2019-11-30 12:27:42.000000000 +0000 @@ -51,14 +51,20 @@ flags: Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_MERGE }); - this._directories = {}; - this._gmount = null; this._mounting = false; } - get ip() { - // Always use the IP from the current connection - return this.device.settings.get_string('tcp-host'); + get info() { + if (this._info === undefined) { + this._info = { + directories: {}, + mount: null, + regex: null, + uri: null + }; + } + + return this._info; } handlePacket(packet) { @@ -74,7 +80,7 @@ }); // Ensure we don't mount on top of an existing mount - } else if (this._gmount === null) { + } else if (this.info.mount === null) { this._mount(packet.body); } } @@ -84,11 +90,11 @@ super.connected(); // Disable for all bluetooth connections - if (this.device.connection_type === 'bluetooth') { + if (this.device.connection_type !== 'lan') { this.device.lookup_action('mount').enabled = false; this.device.lookup_action('unmount').enabled = false; - // Request a mount; if using sshfs we will "delay-connect" + // Request a mount } else { this.mount(); } @@ -100,86 +106,86 @@ } /** - * Setup the directories for export with GMenu and store the mountpoint. + * Parse the connection info * * @param {object} info - The body of a kdeconnect.sftp packet */ - async _setup(info) { - try { - this._port = info.port; - this._uri = `sftp://${this.ip}:${this._port}/`; + _parseInfo(info) { + this._info = info; - // HACK: Test an SFTP mount for this IP in the 1716-1764 range - this._uriRegex = new RegExp(`sftp://(${this.ip}):(171[6-9]|17[2-5][0-9]|176[0-4])`); - - // Ensure the private key is in the keyring - await this._add_identity(); - - // If 'multiPaths' is present setup a local URI for each - if (info.hasOwnProperty('multiPaths')) { - for (let i = 0; i < info.multiPaths.length; i++) { - let name = info.pathNames[i]; - let path = info.multiPaths[i]; - this._directories[name] = this._uri + path; - } + this.info.directories = {}; + this.info.mount = null; + this.info.regex = new RegExp( + 'sftp://(' + this.info.ip + '):(1739|17[4-5][0-9]|176[0-4])' + ); + this.info.uri = 'sftp://' + this.info.ip + ':' + this.info.port + '/'; - // If 'multiPaths' is missing use 'path' and assume a Camera folder - } else { - let uri = this._uri + info.path; - this._directories[_('All files')] = uri; - this._directories[_('Camera pictures')] = uri + 'DCIM/Camera'; + // If 'multiPaths' is present setup a local URI for each + if (info.hasOwnProperty('multiPaths')) { + for (let i = 0; i < info.multiPaths.length; i++) { + let name = info.pathNames[i]; + let path = info.multiPaths[i]; + this.info.directories[name] = this.info.uri + path; } - return Promise.resolve(); - } catch (e) { - return Promise.reject(e); + // If 'multiPaths' is missing use 'path' and assume a Camera folder + } else { + let uri = this.info.uri + this.info.path; + this.info.directories[_('All files')] = uri; + this.info.directories[_('Camera pictures')] = uri + 'DCIM/Camera'; } } + _onAskQuestion(op, message, choices) { + op.reply(Gio.MountOperationResult.HANDLED); + } + + _onAskPassword(op, message, user, domain, flags) { + op.reply(Gio.MountOperationResult.HANDLED); + } + async _mount(info) { try { // If mounting is already in progress, let that fail before retrying if (this._mounting) return; this._mounting = true; - await this._setup(info); + // Parse the connection info + await this._parseInfo(info); + // Ensure the private key is in the keyring + await this._addPrivateKey(); + + // Create a new mount operation let op = new Gio.MountOperation({ username: info.user, password: info.password, password_save: Gio.PasswordSave.NEVER }); - // Auto-accept new host keys - let question_id = op.connect('ask-question', (op, message, choices) => { - op.reply(Gio.MountOperationResult.HANDLED); - }); - - // Automatically answer password requests - let password_id = op.connect('ask-password', (op, message, user, domain, flags) => { - op.reply(Gio.MountOperationResult.HANDLED); - }); + // Auto-accept new host keys and password requests + let questionId = op.connect('ask-question', this._onAskQuestion); + let passwordId = op.connect('ask-password', this._onAskPassword); // This is the actual call to mount the device await new Promise((resolve, reject) => { - let file = Gio.File.new_for_uri(this._uri); + let file = Gio.File.new_for_uri(this.info.uri); file.mount_enclosing_volume(0, op, null, (file, res) => { try { - op.disconnect(question_id); - op.disconnect(password_id); + op.disconnect(questionId); + op.disconnect(passwordId); resolve(file.mount_enclosing_volume_finish(res)); } catch (e) { // Special case when the GMount didn't unmount properly // but is still on the same port and can be reused. if (e.code && e.code === Gio.IOErrorEnum.ALREADY_MOUNTED) { - debug(e, `${this.device.name} (${this.name})`); resolve(true); // There's a good chance this is a host key verification // error; regardless we'll remove the key for security. } else { - this._remove_host(this._port); + this._removeHostKey(); reject(e); } } @@ -192,15 +198,19 @@ for (let mount of monitor.get_mounts()) { let uri = mount.get_root().get_uri(); - // Check if this is our mount - if (this._uri === uri) { - this._gmount = mount; - this._gmount.connect('unmounted', this.unmount.bind(this)); + // This is our GMount + if (this.info.uri === uri) { + this.info.mount = mount; + this.info.mount.connect( + 'unmounted', + this.unmount.bind(this) + ); + this._addSymlink(mount); - // Or if it's a stale mount we need to cleanup - } else if (this._uriRegex.test(uri)) { - warning('Removing stale GMount', `${this.device.name} (${this.name})`); + // This is one of our old mounts + } else if (this.info.regex.test(uri)) { + debug(`Remove stale mount at ${uri}`); await this._unmount(mount); } } @@ -209,21 +219,24 @@ this._addSubmenu(); this._mounting = false; } catch (e) { - logError(e, `${this.device.name} (${this.name})`); - this._mounting = false; + logError(e, this.device.name); this.unmount(); } } - _unmount(mount) { + _unmount(mount = null) { + if (!mount) return Promise.resolve(); + return new Promise((resolve, reject) => { let op = new Gio.MountOperation(); mount.unmount_with_operation(1, op, null, (mount, res) => { try { - resolve(mount.unmount_with_operation_finish(res)); + mount.unmount_with_operation_finish(res); + resolve(); } catch (e) { - reject(e); + debug(e); + resolve(); } }); }); @@ -233,7 +246,7 @@ * Add Zorin Connect's private key identity to the authentication agent so our * identity can be verified by Android during private key authentication. */ - _add_identity() { + _addPrivateKey() { let ssh_add = this._launcher.spawnv([ zorin_connect.metadata.bin.ssh_add, GLib.build_filenamev([zorin_connect.configdir, 'private.pem']) @@ -245,7 +258,7 @@ let result = proc.communicate_utf8_finish(res)[1].trim(); if (proc.get_exit_status() !== 0) { - warning(result, `${this.device.name} (${this.name})`); + debug(result, this.device.name); } resolve(); @@ -257,87 +270,116 @@ } /** - * Remove old host keys from ~/.ssh/known_hosts for this host from the range + * Remove all host keys from ~/.ssh/known_hosts for @host in the port range * used by KDE Connect (1739-1764). * - * @param {number} port - The port to remove the host key for + * @param {string} host - A hostname or IP address */ - async _remove_host(port = 1739) { - try { - let ssh_keygen = this._launcher.spawnv([ - zorin_connect.metadata.bin.ssh_keygen, - '-R', - `[${this.ip}]:${port}` - ]); + async _removeHostKey(host) { + for (let port = 1739; port <= 1764; port++) { + try { + let ssh_keygen = this._launcher.spawnv([ + zorin_connect.metadata.bin.ssh_keygen, + '-R', + `[${host}]:${port}` + ]); - await new Promise((resolve, reject) => { - ssh_keygen.wait_check_async(null, (proc, res) => { - try { - resolve(proc.wait_check_finish(res)); - } catch (e) { - reject(e); - } + await new Promise((resolve, reject) => { + ssh_keygen.wait_check_async(null, (proc, res) => { + try { + resolve(proc.wait_check_finish(res)); + } catch (e) { + reject(e); + } + }); }); - }); - - debug(`removed host key for [${this.ip}]:${port}`); - } catch (e) { - warning(e, `${this.device.name} (${this.name})`); + } catch (e) { + debug(e); + } } } /** - * Replace the 'Mount' item with a submenu of directories + * Mount menu helpers */ - _addSubmenu() { - // Sftp Submenu - let submenu = new Gio.Menu(); + _getUnmountSection() { + if (this._unmountSection === undefined) { + this._unmountSection = new Gio.Menu(); + + let unmountItem = new Gio.MenuItem(); + unmountItem.set_label(Metadata.actions.unmount.label); + unmountItem.set_icon(new Gio.ThemedIcon({ + name: Metadata.actions.unmount.icon_name + })); + unmountItem.set_detailed_action('device.unmount'); + this._unmountSection.append_item(unmountItem); + } + + return this._unmountSection; + } - // Directories Section - let directories = new Gio.Menu(); + _getMountedIcon() { + if (this._mountedIcon === undefined) { + this._mountedIcon = new Gio.EmblemedIcon({ + gicon: new Gio.ThemedIcon({name: 'folder-remote-symbolic'}) + }); + + // TODO: this emblem often isn't very visible + let emblem = new Gio.Emblem({ + icon: new Gio.ThemedIcon({name: 'emblem-default'}) + }); - for (let [name, uri] of Object.entries(this._directories)) { - directories.append(name, `device.openPath::${uri}`); + this._mountedIcon.add_emblem(emblem); } - submenu.append_section(null, directories); + return this._mountedIcon; + } - // Unmount Section/Item - let unmount = new Gio.Menu(); - unmount.add_action(this.device.lookup_action('unmount')); - submenu.append_section(null, unmount); + _addSubmenu() { + try { + // Directories Section + let dirSection = new Gio.Menu(); - // Files Item - let item = new Gio.MenuItem(); - item.set_detailed_action('device.mount'); + for (let [name, uri] of Object.entries(this.info.directories)) { + dirSection.append(name, `device.openPath::${uri}`); + } - // Icon with check emblem - // TODO: this emblem often isn't very visible - let icon = new Gio.EmblemedIcon({ - gicon: new Gio.ThemedIcon({name: 'folder-remote-symbolic'}) - }); - let emblem = new Gio.Emblem({ - icon: new Gio.ThemedIcon({name: 'emblem-default'}) - }); - icon.add_emblem(emblem); - item.set_icon(icon); + // Unmount Section + let unmountSection = this._getUnmountSection(); - item.set_attribute_value( - 'hidden-when', - new GLib.Variant('s', 'action-disabled') - ); - item.set_label(_('Files')); - item.set_submenu(submenu); + // Files Submenu + let filesSubmenu = new Gio.Menu(); + filesSubmenu.append_section(null, dirSection); + filesSubmenu.append_section(null, unmountSection); + + // Files Item + let filesItem = new Gio.MenuItem(); + filesItem.set_detailed_action('device.mount'); + filesItem.set_icon(this._getMountedIcon()); + filesItem.set_label(_('Files')); + filesItem.set_submenu(filesSubmenu); - this.device.menu.replace_action('device.mount', item); + this.device.replaceMenuAction('device.mount', filesItem); + } catch (e) { + logError(e); + } } _removeSubmenu() { - let index = this.device.menu.remove_action('device.mount'); - let action = this.device.lookup_action('mount'); + try { + let index = this.device.removeMenuAction('device.mount'); + let action = this.device.lookup_action('mount'); - if (action !== null) { - this.device.menu.add_action(action, index); + if (action !== null) { + this.device.addMenuAction( + action, + index, + Metadata.actions.mount.label, + Metadata.actions.mount.icon_name + ); + } + } catch (e) { + logError(e); } } @@ -349,19 +391,21 @@ let by_name_dir = Gio.File.new_for_path( zorin_connect.runtimedir + '/by-name/' ); + try { by_name_dir.make_directory_with_parents(null); } catch (e) { - if ( ! e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.EXISTS) ) { + if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.EXISTS)) { throw e; } } // Replace path separator with a Unicode lookalike: let safe_device_name = this.device.name.replace('/', '∕'); - if ( safe_device_name == '.' ) { + + if (safe_device_name === '.') { safe_device_name = '·'; - } else if ( safe_device_name == '..' ) { + } else if (safe_device_name === '..') { safe_device_name = '··'; } @@ -370,10 +414,9 @@ by_name_dir.get_path() + '/' + safe_device_name ); - // Check for and remove any existing stale link: - let link_stat; + // Check for and remove any existing stale link try { - link_stat = await new Promise((resolve, reject) => { + let link_stat = await new Promise((resolve, reject) => { link.query_info_async( 'standard::symlink-target', Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, @@ -389,7 +432,7 @@ ); }); - if ( link_stat.get_symlink_target() == link_target ) { + if (link_stat.get_symlink_target() === link_target) { return; } @@ -407,14 +450,14 @@ ); }); } catch (e) { - if ( ! e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND) ) { + if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND)) { throw e; } } link.make_symbolic_link(link_target, null); } catch (e) { - warning(e, `${this.device.name}: ${this.name}`); + debug(e, this.device.name); } } @@ -424,7 +467,9 @@ mount() { this.device.sendPacket({ type: 'kdeconnect.sftp.request', - body: {startBrowsing: true} + body: { + startBrowsing: true + } }); } @@ -433,19 +478,19 @@ */ async unmount() { try { - // Skip since this will always fail - if (this._gmount) { - await this._unmount(this._gmount); + if (this.info.mount === null) { + return; } - } catch (e) { - debug(e, this.device.name); - // Always reset the state and menu - } finally { - this._directories = {}; - this._gmount = null; - this._mounting = false; + let mount = this.info.mount; + this._removeSubmenu(); + this._info = undefined; + this._mounting = false; + + await this._unmount(mount); + } catch (e) { + debug(e); } } diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/share.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/share.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/share.js 2019-03-17 11:45:08.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/share.js 2019-11-30 12:28:03.000000000 +0000 @@ -66,13 +66,72 @@ super._init(device, 'share'); } + _ensureReceiveDirectory() { + let receiveDir = this.settings.get_string('receive-directory'); + + // Ensure a directory is set + if (!receiveDir) { + receiveDir = GLib.get_user_special_dir( + GLib.UserDirectory.DIRECTORY_DOWNLOAD + ); + + // Fallback to ~/Downloads + let homeDir = GLib.get_home_dir(); + + if (!receiveDir || receiveDir === homeDir) { + receiveDir = GLib.build_filenamev([homeDir, 'Downloads']); + } + + this.settings.set_string('receive-directory', receiveDir); + } + + // Ensure the directory exists + if (!GLib.file_test(receiveDir, GLib.FileTest.IS_DIR)) { + GLib.mkdir_with_parents(receiveDir, 448); + } + + return receiveDir; + } + + _getFile(filename) { + let dirpath = this._ensureReceiveDirectory(); + let basepath = GLib.build_filenamev([dirpath, filename]); + let filepath = basepath; + let copyNum = 0; + + while (GLib.file_test(filepath, GLib.FileTest.EXISTS)) { + copyNum += 1; + filepath = `${basepath} (${copyNum})`; + } + + return Gio.File.new_for_path(filepath); + } + + async _refuseFile(packet) { + try { + await this.device.rejectTransfer(packet); + + this.device.showNotification({ + id: `${Date.now()}`, + title: _('Transfer Failed'), + // TRANSLATORS: eg. Google Pixel is not allowed to upload files + body: _('%s is not allowed to upload files').format( + this.device.name + ), + icon: new Gio.ThemedIcon({name: 'dialog-error-symbolic'}) + }); + } catch (e) { + logError(e, this.device.name); + } + } + async _handleFile(packet) { let file, stream, success, transfer; let title, body, iconName; let buttons = []; try { - file = get_download_file(packet.body.filename); + file = this._getFile(packet.body.filename); stream = await new Promise((resolve, reject) => { file.replace_async(null, false, 0, 0, null, (file, res) => { @@ -92,7 +151,7 @@ // Notify that we're about to start the transfer this.device.showNotification({ id: transfer.uuid, - title: _('Starting Transfer'), + title: _('Transferring File'), // TRANSLATORS: eg. Receiving 'book.pdf' from Google Pixel body: _('Receiving “%s” from %s').format( packet.body.filename, @@ -112,7 +171,8 @@ // We've been asked to open this directly if (success && packet.body.open) { - open_uri(file.get_uri()); + let uri = file.get_uri(); + Gio.AppInfo.launch_default_for_uri_async(uri, null, null, null); return; } @@ -163,7 +223,8 @@ } _handleUri(packet) { - open_uri(packet.body.url); + let uri = packet.body.url; + Gio.AppInfo.launch_default_for_uri_async(uri, null, null, null); } _handleText(packet) { @@ -183,7 +244,11 @@ */ handlePacket(packet) { if (packet.body.hasOwnProperty('filename')) { - this._handleFile(packet); + if (this.settings.get_boolean('receive-files')) { + this._handleFile(packet); + } else { + this._refuseFile(packet); + } } else if (packet.body.hasOwnProperty('text')) { this._handleText(packet); } else if (packet.body.hasOwnProperty('url')) { @@ -202,7 +267,7 @@ /** * Share local file path or URI * - * @param {string} path - Local file path or file URI + * @param {string} path - Local file path or URI * @param {boolean} open - Whether the file should be opened after transfer */ async shareFile(path, open = false) { @@ -210,7 +275,7 @@ let title, body, iconName; try { - if (path.startsWith('file://')) { + if (path.includes('://')) { file = Gio.File.new_for_uri(path); } else { file = Gio.File.new_for_path(path); @@ -234,7 +299,7 @@ // Notify that we're about to start the transfer this.device.showNotification({ id: transfer.uuid, - title: _('Starting Transfer'), + title: _('Transferring File'), // TRANSLATORS: eg. Sending 'book.pdf' to Google Pixel body: _('Sending “%s” to %s').format( file.get_basename(), @@ -282,7 +347,7 @@ icon: new Gio.ThemedIcon({name: iconName}) }); } catch (e) { - warning(e, this.device.name); + debug(e, this.device.name); } } diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/sms.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/sms.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/sms.js 2019-03-04 02:05:28.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/sms.js 2019-11-30 12:28:24.000000000 +0000 @@ -46,6 +46,14 @@ incoming: [], outgoing: ['kdeconnect.sms.request'] }, + sendMessage: { + label: _('Send Message'), + icon_name: 'sms-send', + + parameter_type: new GLib.VariantType('(aa{sv})'), + incoming: [], + outgoing: ['kdeconnect.sms.request'] + }, sendSms: { label: _('Send SMS'), icon_name: 'sms-send', @@ -183,7 +191,7 @@ * IN: An incoming message * OUT: An outgoing message */ -var MessageType = { +var MessageBox = { ALL: 0, INBOX: 1, SENT: 2, @@ -201,10 +209,10 @@ var Plugin = GObject.registerClass({ GTypeName: 'ZorinConnectSMSPlugin', Properties: { - 'conversations': GObject.param_spec_variant( - 'conversations', + 'threads': GObject.param_spec_variant( + 'threads', 'Conversation List', - 'A list of conversations', + 'A list of threads', new GLib.VariantType('aa{sv}'), null, GObject.ParamFlags.READABLE @@ -215,19 +223,24 @@ _init(device) { super._init(device, 'sms'); - this.conversations = {}; - this.cacheProperties(['conversations']); + this.threads = {}; + this.cacheProperties(['threads']); + this._version = 1; } get window() { if (this.settings.get_boolean('legacy-sms')) { - return new TelephonyUI.Dialog({device: this.device}); + return new TelephonyUI.LegacyMessagingDialog({ + device: this.device, + plugin: this + }); } if (this._window === undefined) { this._window = new Messaging.Window({ application: this.service, - device: this.device + device: this.device, + plugin: this }); } @@ -242,13 +255,30 @@ } cacheClear() { - this.conversations = {}; + this.threads = {}; this.__cache_write(); - this.notify('conversations'); + this.notify('threads'); } cacheLoaded() { - this.notify('conversations'); + // Backwards compatibility with single-address format + let threads = Object.values(this.threads); + + if (threads.length > 0 && threads[0][0].address) { + for (let t = 0, n_threads = threads.length; t < n_threads; t++) { + let thread = n_threads[t]; + + for (let m = 0, n_msgs = thread.length; m < n_msgs; m++) { + let message = thread[m]; + + message.addresses = [{address: message.address}]; + message.thread_id = parseInt(message.thread_id, 10); + delete message.address; + } + } + } + + this.notify('threads'); } connected() { @@ -257,67 +287,98 @@ } /** + * Handle a digest of threads. + * + * @param {Object[]} messages - A list of message objects + * @param {string[]} thread_ids - A list of thread IDs as strings + */ + _handleDigest(messages, thread_ids) { + // Prune threads + for (let thread_id of Object.keys(this.threads)) { + if (!thread_ids.includes(thread_id)) { + delete this.threads[thread_id]; + } + } + + // Request each new or newer thread + for (let i = 0, len = messages.length; i < len; i++) { + let message = messages[i]; + let cache = this.threads[message.thread_id]; + + // If this message is marked read and it's for an existing + // thread, we should mark the rest in this thread as read + if (cache && message.read === MessageStatus.READ) { + cache.forEach(msg => msg.read = MessageStatus.READ); + } + + // If we don't have a thread for this message or it's newer + // than the last message in the cache, request the thread + if (!cache || cache[cache.length - 1].date < message.date) { + this.requestConversation(message.thread_id); + } + } + + this.__cache_write(); + this.notify('threads'); + } + + /** * Handle a new single message + * + * @param {Object} message - A message object */ - _handleMessage(contact, message) { + _handleMessage(message) { let conversation = null; + // If the window is open, try and find an active conversation if (this._window) { - conversation = this._window.getConversation(message.address); + conversation = this._window.getConversationForMessage(message); } + // If there's an active conversation, we should log the message now if (conversation) { - // Track expected ticker of outgoing messages so they can be closed - // FIXME: this is not working well - if (message.type === MessageType.SENT) { - conversation._notifications.push( - `${contact.name}: ${message.body}` - ); - } - - conversation.logMessage(message); + conversation.logNext(message); } } /** * Parse a conversation (thread of messages) and sort them * - * @param {object[]} messages - A list of sms message objects from a thread + * @param {Object[]} thread - A list of sms message objects from a thread */ - async _handleConversation(messages) { + _handleThread(thread) { try { - // If the address is missing this will cause problems... - if (!messages[0].address) return; + // If there are no addresses this will cause major problems... + if (!thread[0].addresses || !thread[0].addresses[0]) return; - let thread_id = messages[0].thread_id; - let conversation = this.conversations[thread_id] || []; - let contact = this.device.contacts.query({ - number: messages[0].address - }); + let thread_id = thread[0].thread_id; + let cache = this.threads[thread_id] || []; - for (let i = 0, len = messages.length; i < len; i++) { - let message = messages[i]; + // Handle each message + for (let i = 0, len = thread.length; i < len; i++) { + let message = thread[i]; - // TODO: invalid MessageType + // TODO: invalid MessageBox if (message.type < 0 || message.type > 5) continue; - let extant = conversation.find(msg => msg._id === message._id); + // If the message exists, just update it + let cacheMessage = cache.find(m => m.date === message.date); - if (extant) { - Object.assign(extant, message); + if (cacheMessage) { + Object.assign(cacheMessage, message); } else { - conversation.push(message); - await this._handleMessage(contact, message); + cache.push(message); + this._handleMessage(message); } } - // Sort and store the conversation - this.conversations[thread_id] = conversation.sort((a, b) => { - return (a._id < b._id) ? -1 : 1; + // Sort the thread by ascending date and write to cache + this.threads[thread_id] = cache.sort((a, b) => { + return (a.date < b.date) ? -1 : 1; }); - await this.__cache_write(); - this.notify('conversations'); + this.__cache_write(); + this.notify('threads'); } catch (e) { logError(e); } @@ -328,44 +389,36 @@ * * @param {object[]} messages - A list of sms message objects */ - async _handleMessages(messages) { + _handleMessages(messages) { try { // If messages is empty there's nothing to do... if (messages.length === 0) return; - let thread_ids = messages.map(msg => msg.thread_id); - - // If there's multiple thread_id's it's a summary of threads - if (thread_ids.some(id => id !== thread_ids[0])) { + // TODO: Backwards compatibility kdeconnect-android <= ??? + if (messages[0].address) { + this._version = 1; - // Prune conversations - Object.keys(this.conversations).map(id => { - if (!thread_ids.includes(parseInt(id))) { - delete this.conversations[id]; - } - }); - - // Request each new or newer thread for (let i = 0, len = messages.length; i < len; i++) { let message = messages[i]; - let cache = this.conversations[message.thread_id]; - - // If this is for an existing thread, mark the rest as read - if (cache && message.read === MessageStatus.READ) { - cache.forEach(message => message.read = MessageStatus.READ); - } - if (!cache || cache[cache.length - 1]._id < message._id) { - this.requestConversation(message.thread_id); - } + message.addresses = [{address: message.address}]; + message.thread_id = parseInt(message.thread_id, 10); + delete message.address; } + } else { + this._version = 2; + } + + // If there's multiple thread_id's it's a summary of threads + // COERCION: thread_id's to strings + let thread_ids = messages.map(msg => `${msg.thread_id}`); - await this.__cache_write(); - this.notify('conversations'); + if (thread_ids.some(id => id !== thread_ids[0])) { + this._handleDigest(messages, thread_ids); // Otherwise this is single thread or new message } else { - await this._handleConversation(messages); + this._handleThread(messages); } } catch (e) { logError(e); @@ -375,7 +428,7 @@ /** * Request a list of messages from a single thread. * - * @param {Number} thread_id - The thread_id of the conversation to request + * @param {Number} thread_id - The id of the thread to request */ requestConversation(thread_id) { this.device.sendPacket({ @@ -413,14 +466,41 @@ * @param {string} messageBody - The message to send */ sendSms(phoneNumber, messageBody) { + this.sendMessage([{address: phoneNumber}], messageBody, 1, true); + } + + /** + * Send a message + * + * @param {Array of Address} addresses - A list of address objects + * @param {string} messageBody - The message text + * @param {number} [event] - An event bitmask + * @param {boolean} [forceSms] - Whether to force SMS + * @param {number} [subId] - The SIM card to use + */ + sendMessage(addresses, messageBody, event = 1, forceSms = false, subId = undefined) { + // TODO: waiting on support in kdeconnect-android + // if (this._version === 1) { this.device.sendPacket({ type: 'kdeconnect.sms.request', body: { sendSms: true, - phoneNumber: phoneNumber, + phoneNumber: addresses[0].address, messageBody: messageBody } }); + // } else if (this._version == 2) { + // this.device.sendPacket({ + // type: 'kdeconnect.sms.request', + // body: { + // version: 2, + // addresses: addresses, + // messageBody: messageBody, + // forceSms: forceSms, + // sub_id: subId + // } + // }); + // } } /** @@ -437,12 +517,13 @@ window.present(); window.setMessage(url); - // If there are active conversations, show the chooser dialog - } else if (Object.values(this.conversations).length > 0) { + // If there are active threads, show the chooser dialog + } else if (Object.values(this.threads).length > 0) { let window = new Messaging.ConversationChooser({ application: this.service, device: this.device, - message: url + message: url, + plugin: this }); window.present(); @@ -463,7 +544,6 @@ /** * This is the sms: URI scheme handler - * TODO: we should now reject multi-recipient URIs * * @param {string} uri - The URI the handle (sms:|sms://|sms:///) */ @@ -471,9 +551,16 @@ try { uri = new URI(uri); + // Lookup contacts + let addresses = uri.recipients.map(number => { + return {address: number.toPhoneNumber()}; + }); + let contacts = this.device.contacts.lookupAddresses(addresses); + + // Present the window and show the conversation let window = this.window; window.present(); - window.address = uri.recipients[0]; + window.setContacts(contacts); // Set the outgoing message if the uri has a body variable if (uri.body) { @@ -484,6 +571,53 @@ } } + addressesIncludesAddress(addresses, addressObj) { + let number = addressObj.address.toPhoneNumber(); + + for (let taddressObj of addresses) { + let tnumber = taddressObj.address.toPhoneNumber(); + + if (number.endsWith(tnumber) || tnumber.endsWith(number)) { + return true; + } + } + + return false; + } + + _threadHasAddress(thread, addressObj) { + let number = addressObj.address.toPhoneNumber(); + + for (let taddressObj of thread[0].addresses) { + let tnumber = taddressObj.address.toPhoneNumber(); + + if (number.endsWith(tnumber) || tnumber.endsWith(number)) { + return true; + } + } + + return false; + } + + /** + * Try to find a thread_id in @smsPlugin for @addresses. + * + * @param {Array of Object} - a list of address objects + */ + getThreadIdForAddresses(addresses) { + let threads = Object.values(this.threads); + + for (let thread of threads) { + if (addresses.length !== thread[0].addresses.length) continue; + + if (addresses.every(addressObj => this._threadHasAddress(thread, addressObj))) { + return thread[0].thread_id; + } + } + + return null; + } + destroy() { if (this._window) { this._window.destroy(); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/systemvolume.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/systemvolume.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/systemvolume.js 2019-03-04 02:05:12.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/systemvolume.js 2019-11-30 12:28:45.000000000 +0000 @@ -29,24 +29,26 @@ super._init(device, 'systemvolume'); try { - // Cache stream properties - this._cache = new WeakMap(); - // Connect to the mixer - this._streamChangedId = this.service.pulseaudio.connect( + this._pulseaudio = this.service.components.get('pulseaudio'); + + this._streamChangedId = this._pulseaudio.connect( 'stream-changed', this._sendSink.bind(this) ); - this._outputAddedId = this.service.pulseaudio.connect( + this._outputAddedId = this._pulseaudio.connect( 'output-added', this._sendSinkList.bind(this) ); - this._outputRemovedId = this.service.pulseaudio.connect( + this._outputRemovedId = this._pulseaudio.connect( 'output-removed', this._sendSinkList.bind(this) ); + + // Cache stream properties + this._cache = new WeakMap(); } catch (e) { this.destroy(); e.name = 'GvcError'; @@ -78,7 +80,7 @@ _changeSink(packet) { let stream; - for (let sink of this.service.pulseaudio.get_sinks()) { + for (let sink of this._pulseaudio.get_sinks()) { if (sink.name === packet.body.name) { stream = sink; break; @@ -92,16 +94,16 @@ } // Get a cache and store volume and mute states if changed - let cache = this._cache.get(stream) || [null, null, null]; + let cache = this._cache.get(stream) || {}; if (packet.body.hasOwnProperty('muted')) { - cache[1] = packet.body.muted; + cache.muted = packet.body.muted; this._cache.set(stream, cache); stream.change_is_muted(packet.body.muted); } if (packet.body.hasOwnProperty('volume')) { - cache[0] = packet.body.volume; + cache.volume = packet.body.volume; this._cache.set(stream, cache); stream.volume = packet.body.volume; stream.push_volume(); @@ -109,75 +111,71 @@ } /** + * Update the cache for @stream + * + * @param {Gvc.MixerStream} stream - The stream to cache + * @return {object} - The updated cache object + */ + _updateCache(stream) { + let state = { + name: stream.name, + description: stream.display_name, + muted: stream.is_muted, + volume: stream.volume, + maxVolume: this._pulseaudio.get_vol_max_norm() + }; + + this._cache.set(stream, state); + + return state; + } + + /** * Send the state of a local sink * * @param {Gvc.MixerControl} mixer - The mixer that owns the stream * @param {Number} id - The Id of the stream that changed */ _sendSink(mixer, id) { - let stream = this.service.pulseaudio.lookup_stream_id(id); - - // Get a cache to check for changes - let cache = this._cache.get(stream) || [null, null, null]; - - switch (true) { - // If the port (we show in the description) has changed we have to - // send the whole list to show the change - case (cache[2] !== stream.display_name): - this._sendSinkList(); - return; - - // If only volume and/or mute are set, send a single update - case (cache[0] !== stream.volume): - case (cache[1] !== stream.is_muted): - this._cache.set(stream, [ - stream.volume, - stream.is_muted, - stream.display_name - ]); - break; + // Avoid starving the packet channel when fading + if (this._pulseaudio.fading) { + return; + } - // Bail if nothing relevant has changed - default: - return; + // Check the cache + let stream = this._pulseaudio.lookup_stream_id(id); + let cache = this._cache.get(stream) || {}; + + // If the port has changed we have to send the whole list to update the + // display name + if (!cache.display_name || cache.display_name !== stream.display_name) { + this._sendSinkList(); + return; } - // Send the stream update - this.device.sendPacket({ - type: 'kdeconnect.systemvolume', - body: { - name: stream.name, - volume: stream.volume, - muted: stream.is_muted - } - }); + // If only volume and/or mute are set, send a single update + if (cache.volume !== stream.volume || cache.muted !== stream.is_muted) { + // Update the cache + let state = this._updateCache(stream); + + // Send the stream update + this.device.sendPacket({ + type: 'kdeconnect.systemvolume', + body: state + }); + } } /** * Send a list of local sinks */ _sendSinkList() { - let sinkList = this.service.pulseaudio.get_sinks().map(sink => { - // Cache the sink state - this._cache.set(sink, [ - sink.volume, - sink.is_muted, - sink.display_name - ]); - - // return a sinkList entry - return { - name: sink.name, - description: sink.display_name, - muted: sink.is_muted, - volume: sink.volume, - maxVolume: this.service.pulseaudio.get_vol_max_norm() - }; + let sinkList = this._pulseaudio.get_sinks().map(sink => { + return this._updateCache(sink); }); // Send the sinkList this.device.sendPacket({ - id: 0, type: 'kdeconnect.systemvolume', body: { sinkList: sinkList @@ -187,10 +185,11 @@ destroy() { try { - this.service.pulseaudio.disconnect(this._streamChangedId); - this.service.pulseaudio.disconnect(this._outputAddedId); - this.service.pulseaudio.disconnect(this._outputRemovedId); + this._pulseaudio.disconnect(this._streamChangedId); + this._pulseaudio.disconnect(this._outputAddedId); + this._pulseaudio.disconnect(this._outputRemovedId); } catch (e) { + debug(e, this.device.name); } super.destroy(); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/plugins/telephony.js gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/telephony.js --- gnome-shell-extension-zorin-connect-24.1/src/service/plugins/telephony.js 2019-03-04 02:04:58.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/plugins/telephony.js 2019-11-30 12:29:03.000000000 +0000 @@ -52,7 +52,9 @@ } get legacy_sms() { - let sms = this.device.lookup_plugin('sms'); + // We have to do this lookup each time, because if we hold a reference + // to the plugin we don't know if it's disabled + let sms = this.device._plugins.get('sms'); return (sms && sms.settings.get_boolean('legacy-sms')); } @@ -85,24 +87,30 @@ * @param {String} eventType - 'ringing' or 'talking' */ _setMediaState(eventType) { - if (this.service.pulseaudio) { + // Mixer Volume + let pulseaudio = this.service.components.get('pulseaudio'); + + if (pulseaudio) { switch (this.settings.get_string(`${eventType}-volume`)) { case 'lower': - this.service.pulseaudio.lowerVolume(); + pulseaudio.lowerVolume(); break; case 'mute': - this.service.pulseaudio.muteVolume(); + pulseaudio.muteVolume(); break; } if (eventType === 'talking' && this.settings.get_boolean('talking-microphone')) { - this.service.pulseaudio.muteMicrophone(); + pulseaudio.muteMicrophone(); } } - if (this.service.mpris && this.settings.get_boolean(`${eventType}-pause`)) { - this.service.mpris.pauseAll(); + // Media Playback + let mpris = this.service.components.get('mpris'); + + if (mpris && this.settings.get_boolean(`${eventType}-pause`)) { + mpris.pauseAll(); } } @@ -111,12 +119,18 @@ * sure to unpause before raising volume. */ _restoreMediaState() { - if (this.service.mpris) { - this.service.mpris.unpauseAll(); + // Media Playback + let mpris = this.service.components.get('mpris'); + + if (mpris) { + mpris.unpauseAll(); } - if (this.service.pulseaudio) { - this.service.pulseaudio.restore(); + // Mixer Volume + let pulseaudio = this.service.components.get('pulseaudio'); + + if (pulseaudio) { + pulseaudio.restore(); } } @@ -134,7 +148,7 @@ loader.write(data); loader.close(); } catch (e) { - warning(e); + debug(e); } return loader.get_pixbuf(); @@ -237,18 +251,28 @@ } legacyReply(packet) { - let window = new TelephonyUI.Dialog({ - address: packet.body.phoneNumber, - device: this.device, - message: { - date: packet.id, - address: packet.body.phoneNumber, - body: packet.body.messageBody, - sender: packet.body.contactName || _('Unknown Contact'), - type: 1 + try { + let plugin = this.device._plugins.get('sms'); + + if (plugin === undefined) { + throw new Error('SMS Plugin is disabled'); } - }); - window.present(); + + let dialog = new TelephonyUI.LegacyMessagingDialog({ + device: this.device, + message: { + date: packet.id, + addresses: [{address: packet.body.phoneNumber}], + body: packet.body.messageBody, + sender: packet.body.contactName || _('Unknown Contact'), + type: 1 // MessageBox.INBOX + }, + plugin: plugin + }); + dialog.present(); + } catch (e) { + logError(e); + } } /** diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/protocol/bluetooth.js gnome-shell-extension-zorin-connect-28.0.2/src/service/protocol/bluetooth.js --- gnome-shell-extension-zorin-connect-24.1/src/service/protocol/bluetooth.js 2019-03-05 21:21:32.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/protocol/bluetooth.js 2019-11-30 12:30:43.000000000 +0000 @@ -190,7 +190,7 @@ Gio.DBusError.strip_remote_error(e); } - warning(`Zorin Connect: Bluetooth Error: ${e.message}`); + debug(`Zorin Connect: Bluetooth Error: ${e.message}`); this.destroy(); } } @@ -249,7 +249,7 @@ return proxy; } catch (e) { - warning(e); + debug(e); return undefined; } } @@ -491,7 +491,7 @@ bdevice._channel = null; } - warning(e, bdevice.Alias); + debug(e, bdevice.Alias); } } diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/protocol/core.js gnome-shell-extension-zorin-connect-28.0.2/src/service/protocol/core.js --- gnome-shell-extension-zorin-connect-24.1/src/service/protocol/core.js 2019-02-27 14:48:10.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/protocol/core.js 2019-11-30 12:31:00.000000000 +0000 @@ -27,14 +27,28 @@ } } + [Symbol.toPrimitive](hint) { + this.id = Date.now(); + + switch (hint) { + case 'string': + return `${JSON.stringify(this)}\n`; + case 'number': + return `${JSON.stringify(this)}\n`.length; + default: + return true; + } + } + /** - * Update the packet from a string of JSON + * Update the packet from an Object, using and intermediate call to + * JSON.stringify() to deep-copy the object, avoiding reference entanglement * - * @param {string} data - A string of text + * @param {string} data - An object */ - fromString(data) { + fromObject(data) { try { - let json = JSON.parse(data); + let json = JSON.parse(JSON.stringify(data)); Object.assign(this, json); } catch (e) { throw Error(`Malformed packet: ${e.message}`); @@ -42,33 +56,40 @@ } /** - * Update the packet from an Object, using and intermediate call to - * JSON.stringify() to deep-copy the object, avoiding reference entanglement + * Update the packet from a string of JSON * - * @param {string} data - An object + * @param {string} data - A string of text */ - fromObject(data) { + fromString(data) { try { - let json = JSON.parse(JSON.stringify(data)); + let json = JSON.parse(data); Object.assign(this, json); } catch (e) { throw Error(`Malformed packet: ${e.message}`); } } - [Symbol.toPrimitive](hint) { - this.id = Date.now(); - - switch (hint) { - case 'string': - return `${JSON.stringify(this)}\n`; - case 'number': - return `${JSON.stringify(this)}\n`.length; - default: - return true; + /** + * Make a deep copy of the packet, using and intermediate call to + * JSON.stringify() to avoid reference entanglement. + * + * @return {Core.Packet} - A new packet + */ + toObject() { + try { + let data = JSON.stringify(this); + return new Packet(data); + } catch (e) { + throw Error(`Malformed packet: ${e.message}`); } } + /** + * Serialize the packet as a single line with a terminating new-line (\n) + * character, ready to be written to a channel. + * + * @return {string} - A serialized packet + */ toString() { return `${this}`; } @@ -76,12 +97,54 @@ /** - * Data Channel + * Channel + * + * Channels are essentially wrappers around an I/O stream pair that handle KDE + * Connect identity exchange and either packet or data exchange. + * + * There are effectively two types of channels: packet exchange channels and + * data transfer channels. Both channel types begin by exchanging identity + * packets and then performing whatever encryption or authentication is + * appropriate for the transport protocol. + * + * + * Packet Channels + * + * Packet exchange channels are used to send or receive packets, which are JSON + * objects serialized as single line with a terminating new-line character + * marking the end of the packet. The only packet type allowed to be exchanged + * before authentication is `kdeconnect.identity`. The only packets allowed + * before pairing are `kdeconnect.identity` and `kdeconnect.pair`. + * + * + * Transfer Channels + * + * Data transfer channels are used to send or receive streams of binary data and + * are only possible for paired and authenticated devices. Once the + * identification and authentication has completed, the binary payload is read + * or written and then the channel is closed (unless cancelled first). + * + * These channels are opened when the uploading party sends a packet with two + * extra fields in the top-level of the packet: `payloadSize` (size in bytes) + * and `payloadTransferInfo` which contains protocol specific information such + * as a TCP port. The uploading party then waits for an incoming connection that + * corresponds with the `payloadTransferInfo` field. */ -var Channel = class Channel { +var Channel = GObject.registerClass({ + GTypeName: 'ZorinConnectChannel', + Requires: [GObject.Object] +}, class Channel extends GObject.Interface { + + get address() { + throw new GObject.NotImplementedError(); + } + + get backend() { + return this._backend || null; + } - constructor(params) { - Object.assign(this, params); + set backend(backend) { + this._backend = backend; } get cancellable() { @@ -92,12 +155,44 @@ return this._cancellable; } - get service() { - return Gio.Application.get_default(); + get input_stream() { + if (this._input_stream === undefined) { + if (this._connection instanceof Gio.IOStream) { + return this._connection.get_input_stream(); + } + + return null; + } + + return this._input_stream; + } + + set input_stream(stream) { + this._input_stream = stream; + } + + get output_stream() { + if (this._output_stream === undefined) { + if (this._connection instanceof Gio.IOStream) { + return this._connection.get_output_stream(); + } + + return null; + } + + return this._output_stream; + } + + set output_stream(stream) { + this._output_stream = stream; } - get type() { - return null; + get service() { + if (this._service === undefined) { + this._service = Gio.Application.get_default(); + } + + return this._service; } get uuid() { @@ -165,7 +260,10 @@ let data = stream.read_line_finish_utf8(res)[0]; if (data === null) { - throw new Error('End of stream'); + throw new Gio.IOErrorEnum({ + message: 'End of stream', + code: Gio.IOErrorEnum.CONNECTION_CLOSED + }); } // Queue another receive() before handling the packet @@ -177,10 +275,13 @@ debug(packet, device.name); device.receivePacket(packet); } catch (e) { - warning(e); + debug(e, device.name); } } catch (e) { - debug(e, device.name); + if (!e.code || e.code !== Gio.IOErrorEnum.CANCELLED) { + debug(e, device.name); + } + this.close(); } } @@ -229,13 +330,18 @@ } /** - * Override these in subclasses to negotiate payload transfers. Both methods - * should cleanup after themselves and return a success boolean. + * Override these in subclasses to negotiate payload transfers. `download()` + * and `upload()` should cleanup after themselves and return a success + * boolean. * * The default implementation will always report failure, for protocols that * won't or don't yet support payload transfers. */ - async download(packet) { + createTransfer(params) { + throw new GObject.NotImplementedError(); + } + + async download() { let result = false; try { @@ -249,7 +355,7 @@ return result; } - async upload(port) { + async upload() { let result = false; try { @@ -262,5 +368,126 @@ return result; } -}; + + /** + * Transfer using g_output_stream_splice() + * + * @return {Boolean} - %true on success, %false on failure. + */ + async transfer() { + let result = false; + + try { + result = await new Promise((resolve, reject) => { + this.output_stream.splice_async( + this.input_stream, + Gio.OutputStreamSpliceFlags.NONE, + GLib.PRIORITY_DEFAULT, + this.cancellable, + (source, res) => { + try { + if (source.splice_finish(res) < this.size) { + throw new Error('incomplete data'); + } + + resolve(true); + } catch (e) { + reject(e); + } + } + ); + }); + } catch (e) { + debug(e, this.device.name); + } finally { + this.close(); + } + + return result; + } +}); + + +/** + * ChannelService + */ +var ChannelService = GObject.registerClass({ + GTypeName: 'ZorinConnectChannelService', + Requires: [GObject.Object], + Properties: { + 'name': GObject.ParamSpec.string( + 'name', + 'Name', + 'The name of the backend', + GObject.ParamFlags.READABLE, + null + ) + }, + Signals: { + 'channel': { + flags: GObject.SignalFlags.RUN_LAST, + param_types: [Channel.$gtype], + return_type: GObject.TYPE_BOOLEAN + }, + } +}, class ChannelService extends GObject.Interface { + + get name() { + throw new GObject.NotImplementedError(); + } + + get service() { + if (this._service === undefined) { + this._service = Gio.Application.get_default(); + } + + return this._service; + } + + /** + * Broadcast directly to @address or the whole network if %null + * + * @param {string} [address] - A string address + */ + broadcast(address = null) { + throw new GObject.NotImplementedError(); + } + + /** + * Emit Core.ChannelService::channel + * + * @param {Core.Channel} channel - The new channel + */ + channel(channel) { + try { + if (!this.emit('channel', channel)) { + channel.close(); + } + } catch (e) { + logError(e); + } + } + + /** + * Start the channel service. Implementations should throw an error if the + * service fails to meet any of its requirements for opening or accepting + * connections. + */ + start() { + throw new GObject.NotImplementedError(); + } + + /** + * Stop the channel service. + */ + stop() { + throw new GObject.NotImplementedError(); + } + + /** + * Destroy the channel service. + */ + destroy() { + } +}); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/protocol/__init__.js gnome-shell-extension-zorin-connect-28.0.2/src/service/protocol/__init__.js --- gnome-shell-extension-zorin-connect-24.1/src/service/protocol/__init__.js 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/protocol/__init__.js 2019-11-30 12:32:39.000000000 +0000 @@ -0,0 +1,125 @@ +'use strict'; + +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; + + +/** + * Creates a GTlsCertificate from the PEM-encoded data in @cert_path and + * @key_path. If either are missing a new pair will be generated. + * + * Additionally, the private key will be added using ssh-add to allow sftp + * connections using Gio. + * + * @param {string} certPath - Absolute path to a x509 certificate in PEM format + * @param {string} keyPath - Absolute path to a private key in PEM format + * @param {string} commonName - A unique common name for the certificate + * + * See: https://github.com/KDE/kdeconnect-kde/blob/master/core/kdeconnectconfig.cpp#L119 + */ +Gio.TlsCertificate.new_for_paths = function (certPath, keyPath, commonName = null) { + // Check if the certificate/key pair already exists + let certExists = GLib.file_test(certPath, GLib.FileTest.EXISTS); + let keyExists = GLib.file_test(keyPath, GLib.FileTest.EXISTS); + + // Create a new certificate and private key if necessary + if (!certExists || !keyExists) { + // If we weren't passed a common name, generate a random one + if (!commonName) { + commonName = GLib.uuid_string_random(); + } + + let proc = new Gio.Subprocess({ + argv: [ + zorin_connect.metadata.bin.openssl, 'req', + '-new', '-x509', '-sha256', + '-out', certPath, + '-newkey', 'rsa:4096', '-nodes', + '-keyout', keyPath, + '-days', '3650', + '-subj', `/O=Zorin OS/OU=Zorin Connect/CN=${commonName}` + ], + flags: (Gio.SubprocessFlags.STDOUT_SILENCE | + Gio.SubprocessFlags.STDERR_SILENCE) + }); + proc.init(null); + proc.wait_check(null); + } + + return Gio.TlsCertificate.new_from_files(certPath, keyPath); +}; + +Object.defineProperties(Gio.TlsCertificate.prototype, { + /** + * Compute a SHA1 fingerprint of the certificate. + * See: https://gitlab.gnome.org/GNOME/glib/issues/1290 + * + * @return {string} - A SHA1 fingerprint of the certificate. + */ + 'fingerprint': { + value: function() { + if (!this.__fingerprint) { + let proc = new Gio.Subprocess({ + argv: [zorin_connect.metadata.bin.openssl, 'x509', '-noout', '-fingerprint', '-sha1', '-inform', 'pem'], + flags: Gio.SubprocessFlags.STDIN_PIPE | Gio.SubprocessFlags.STDOUT_PIPE + }); + proc.init(null); + + let stdout = proc.communicate_utf8(this.certificate_pem, null)[1]; + this.__fingerprint = /[a-zA-Z0-9:]{59}/.exec(stdout)[0]; + + proc.wait_check(null); + } + + return this.__fingerprint; + }, + enumerable: false + }, + + /** + * The common name of the certificate. + */ + 'common_name': { + get: function() { + if (!this.__common_name) { + let proc = new Gio.Subprocess({ + argv: [zorin_connect.metadata.bin.openssl, 'x509', '-noout', '-subject', '-inform', 'pem'], + flags: Gio.SubprocessFlags.STDIN_PIPE | Gio.SubprocessFlags.STDOUT_PIPE + }); + proc.init(null); + + let stdout = proc.communicate_utf8(this.certificate_pem, null)[1]; + this.__common_name = /(?:cn|CN) ?= ?([^,\n]*)/.exec(stdout)[1]; + + proc.wait_check(null); + } + + return this.__common_name; + }, + enumerable: true + }, + + /** + * The common name of the certificate. + */ + 'certificate_der': { + get: function() { + if (!this.__certificate_der) { + let proc = new Gio.Subprocess({ + argv: [zorin_connect.metadata.bin.openssl, 'x509', '-outform', 'der', '-inform', 'pem'], + flags: Gio.SubprocessFlags.STDIN_PIPE | Gio.SubprocessFlags.STDOUT_PIPE + }); + proc.init(null); + + let stdout = proc.communicate(new GLib.Bytes(this.certificate_pem), null)[1]; + this.__certificate_der = stdout.toArray(); + + proc.wait_check(null); + } + + return this.__certificate_der; + }, + enumerable: true + } +}); + diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/protocol/lan.js gnome-shell-extension-zorin-connect-28.0.2/src/service/protocol/lan.js --- gnome-shell-extension-zorin-connect-24.1/src/service/protocol/lan.js 2019-03-17 12:00:42.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/protocol/lan.js 2019-11-30 12:33:31.000000000 +0000 @@ -10,9 +10,9 @@ /** * TCP Port Constants */ -const TCP_MIN_PORT = 1716; -const TCP_MAX_PORT = 1764; -const UDP_PORT = 1716; +const DEFAULT_PORT = 1716; +const TRANSFER_MIN = 1739; +const TRANSFER_MAX = 1764; /** @@ -30,10 +30,8 @@ }).get_option(6, 5); // Otherwise we can use Linux socket options - debug('Using Linux socket options'); _LINUX_SOCKETS = true; } catch (e) { - debug('Using FreeBSD socket options'); _LINUX_SOCKETS = false; } @@ -41,35 +39,80 @@ /** * Lan.ChannelService consists of two parts. * - * The TCP Listener listens on a port (usually 1716) and constructs a Channel - * object from the incoming Gio.TcpConnection. + * The TCP Listener listens on a port and constructs a Channel object from the + * incoming Gio.TcpConnection. * - * The UDP Listener listens on a port 1716 for incoming JSON identity packets - * which include the TCP port for connections, while the IP address is taken - * from the UDP packet itself. We respond to incoming packets by opening a TCP - * connection and broadcast outgoing packets to 255.255.255.255. + * The UDP Listener listens on a port for incoming JSON identity packets which + * include the TCP port for connections, while the IP address is taken from the + * UDP packet itself. We respond to incoming packets by opening a TCP connection + * and broadcast outgoing packets to 255.255.255.255. */ -var ChannelService = class ChannelService { +var ChannelService = GObject.registerClass({ + GTypeName: 'ZorinConnectLanChannelService', + Implements: [Core.ChannelService], + Properties: { + 'name': GObject.ParamSpec.override('name', Core.ChannelService), + 'port': GObject.ParamSpec.uint( + 'port', + 'Port', + 'The port used by the service', + GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, + 0, GLib.MAXUINT16, + DEFAULT_PORT + ) + } +}, class LanChannelService extends GObject.Object { + + _init(params) { + super._init(params); + + // Track hosts we identify to directly, allowing them to ignore the + // discoverable state of the service. + this._allowed = new Set(); + + // + this._tcp = null; + this._udp4 = null; + this._udp6 = null; - constructor() { - this.allowed = new Set(); - this.connecting = new Map(); + // Monitor network status + this._networkMonitor = Gio.NetworkMonitor.get_default(); + this._networkAvailable = false; + this._networkChangedId = 0; - // Start TCP/UDP listeners - this._initUdpListener(); - this._initTcpListener(); + // Ensure a certificate exists + this._initCertificate(); + } - // Monitor network changes - this._networkMonitor = Gio.NetworkMonitor.get_default(); - this._networkAvailable = this._networkMonitor.network_available; - this._networkChangedId = this._networkMonitor.connect( - 'network-changed', - this._onNetworkChanged.bind(this) - ); + get certificate() { + return this._certificate; + } + + get channels() { + if (this._channels === undefined) { + this._channels = new Map(); + } + + return this._channels; + } + + get name() { + return 'lan'; + } + + get port() { + if (this._port === undefined) { + this._port = DEFAULT_PORT; + } + + return this._port; } - get service() { - return Gio.Application.get_default(); + set port(port) { + if (this.port !== port) { + this._port = port; + this.notify('port'); + } } _onNetworkChanged(monitor, network_available) { @@ -79,125 +122,152 @@ } } - _initTcpListener() { - this._tcp = new Gio.SocketService(); - - try { - this._tcp.add_inet_port(TCP_MIN_PORT, null); - } catch (e) { - this._tcp.stop(); - this._tcp.close(); - - // The UDP listener must have succeeded so shut it down, too - this._udp_source.destroy(); - this._udp_stream.close(null); - this._udp.close(); + _initCertificate() { + let certPath = GLib.build_filenamev([ + zorin_connect.configdir, + 'certificate.pem' + ]); + let keyPath = GLib.build_filenamev([ + zorin_connect.configdir, + 'private.pem' + ]); + + // Ensure a certificate exists with our id as the common name + this._certificate = Gio.TlsCertificate.new_for_paths( + certPath, + keyPath, + this.service.id + ); - throw e; + // If the service id doesn't match the common name, this is probably a + // certificate from an earlier version and we need to set it now + if (this.service.settings.get_string('id') !== this._certificate.common_name) { + this.service.settings.set_string('id', this._certificate.common_name); } + } + + _initTcpListener() { + this._tcp = new Gio.SocketService(); + this._tcp.add_inet_port(this.port, null); this._tcp.connect('incoming', this._onIncomingChannel.bind(this)); } async _onIncomingChannel(listener, connection) { - let channel, host, device; - try { - channel = new Channel(); - host = connection.get_remote_address().address.to_string(); + let host = connection.get_remote_address().address.to_string(); - // Cancel any connection still resolving with this host - if (this.connecting.has(host)) { - debug(`Cancelling current connection with ${host}`); - this.connecting.get(host).close(); - this.connecting.delete(host); + // Decide whether we should try to accept this connection + if (!this._allowed.has(host) && !this.service.discoverable) { + connection.close_async(0, null, null); + return; } - // Track this connection to avoid a race condition - debug(`Accepting connection from ${host}`); - this.connecting.set(host, channel); + // Create a channel + let channel = new Channel({ + backend: this, + certificate: this.certificate, + host: host, + port: DEFAULT_PORT + }); // Accept the connection await channel.accept(connection); - channel.identity.body.tcpHost = host; - channel.identity.body.tcpPort = '1716'; - - device = this.service._devices.get(channel.identity.body.deviceId); + channel.identity.body.tcpHost = channel.host; + channel.identity.body.tcpPort = DEFAULT_PORT; - switch (true) { - // An existing device - case (device !== undefined): - break; - - // A response to a "direct" broadcast, or we're discoverable - case this.allowed.has(host): - case this.service.discoverable: - device = await this.service._ensureDevice(channel.identity); - break; - - // ...otherwise bail - default: - channel.close(); - throw Error('device not allowed'); - } - - // Attach a device to the channel - channel.attach(device); + this.channel(channel); } catch (e) { debug(e); - } finally { - this.connecting.delete(host); } } _initUdpListener() { - this._udp = new Gio.Socket({ - family: Gio.SocketFamily.IPV4, - type: Gio.SocketType.DATAGRAM, - protocol: Gio.SocketProtocol.UDP, - broadcast: true - }); - this._udp.init(null); + // Default broadcast address + this._udp_address = Gio.InetSocketAddress.new_from_string( + '255.255.255.255', + this.port + ); try { - let addr = Gio.InetSocketAddress.new_from_string( - '0.0.0.0', - UDP_PORT - ); + this._udp6 = new Gio.Socket({ + family: Gio.SocketFamily.IPV6, + type: Gio.SocketType.DATAGRAM, + protocol: Gio.SocketProtocol.UDP, + broadcast: true + }); + this._udp6.init(null); + + // Bind the socket + let inetAddr = Gio.InetAddress.new_any(Gio.SocketFamily.IPV6); + let sockAddr = Gio.InetSocketAddress.new(inetAddr, this.port); + this._udp6.bind(sockAddr, false); + + // Input stream + this._udp6_stream = new Gio.DataInputStream({ + base_stream: new Gio.UnixInputStream({ + fd: this._udp6.fd, + close_fd: false + }) + }); - this._udp.bind(addr, false); + // Watch socket for incoming packets + this._udp6_source = this._udp6.create_source(GLib.IOCondition.IN, null); + this._udp6_source.set_callback(this._onIncomingIdentity.bind(this, this._udp6)); + this._udp6_source.attach(null); } catch (e) { - this._udp.close(); + this._udp6 = null; + } - throw e; + // Our IPv6 socket also supports IPv4; we're all done + if (this._udp6 && this._udp6.speaks_ipv4()) { + this._udp4 = null; + return; } - // Default broadcast address - this._udp_address = Gio.InetSocketAddress.new_from_string( - '255.255.255.255', - UDP_PORT - ); + try { + this._udp4 = new Gio.Socket({ + family: Gio.SocketFamily.IPV4, + type: Gio.SocketType.DATAGRAM, + protocol: Gio.SocketProtocol.UDP, + broadcast: true + }); + this._udp4.init(null); - // Input stream - this._udp_stream = new Gio.DataInputStream({ - base_stream: new Gio.UnixInputStream({ - fd: this._udp.fd, - close_fd: false - }) - }); + // Bind the socket + let inetAddr = Gio.InetAddress.new_any(Gio.SocketFamily.IPV4); + let sockAddr = Gio.InetSocketAddress.new(inetAddr, this.port); + this._udp4.bind(sockAddr, false); + + // Input stream + this._udp4_stream = new Gio.DataInputStream({ + base_stream: new Gio.UnixInputStream({ + fd: this._udp4.fd, + close_fd: false + }) + }); + + // Watch input socket for incoming packets + this._udp4_source = this._udp4.create_source(GLib.IOCondition.IN, null); + this._udp4_source.set_callback(this._onIncomingIdentity.bind(this, this._udp4)); + this._udp4_source.attach(null); + } catch (e) { + this._udp4 = null; - // Watch input socket for incoming packets - this._udp_source = this._udp.create_source(GLib.IOCondition.IN, null); - this._udp_source.set_callback(this._onIncomingIdentity.bind(this)); - this._udp_source.attach(null); + // We failed to get either an IPv4 or IPv6 socket to bind + if (this._udp6 === null) { + e.name = 'LanError'; + throw e; + } + } } - _onIncomingIdentity() { + _onIncomingIdentity(socket) { let host, data, packet; - // Try to peek the remote address, but don't prevent reading the data + // Try to peek the remote address try { - host = this._udp.receive_message( + host = socket.receive_message( [], Gio.SocketMsgFlags.PEEK, null @@ -206,8 +276,13 @@ logError(e); } + // Whether or not we peeked the address, we need to read the packet try { - data = this._udp_stream.read_line_utf8(null)[0]; + if (socket === this._udp6) { + data = this._udp6_stream.read_line_utf8(null)[0]; + } else { + data = this._udp4_stream.read_line_utf8(null)[0]; + } // Only process the packet if we succeeded in peeking the address if (host !== undefined) { @@ -226,7 +301,7 @@ try { // Bail if the deviceId is missing if (!packet.body.hasOwnProperty('deviceId')) { - warning('missing deviceId', packet.body.deviceName); + debug(`${packet.body.deviceName}: missing deviceId`); return; } @@ -237,36 +312,23 @@ debug(packet); - let device = this.service._devices.get(packet.body.deviceId); - - switch (true) { - // Proceed if this is an existing device... - case (device !== undefined): - break; - - // Or the service is discoverable or host is allowed... - case this.service.discoverable: - case this.allowed.has(packet.body.tcpHost): - device = this.service._ensureDevice(packet); - break; - - // ...otherwise bail - default: - warning('device not allowed', packet.body.deviceName); - return; - } + // Create a new channel + let channel = new Channel({ + backend: this, + certificate: this.certificate, + host: packet.body.tcpHost, + port: packet.body.tcpPort, + identity: packet + }); - // Silently ignore broadcasts from connected devices, but update - // from the identity packet - if (device._channel !== null) { - debug('already connected'); - device._handleIdentity(packet); + // Check if channel is already open with this address + if (this.channels.has(channel.address)) { return; + } else { + this.channels.set(channel.address, channel); } - // Create a new channel - let channel = new Channel({identity: packet}); - + // Open a TCP connection let connection = await new Promise((resolve, reject) => { let address = Gio.InetSocketAddress.new_from_string( packet.body.tcpHost, @@ -285,7 +347,8 @@ // Connect the channel and attach it to the device on success await channel.open(connection); - channel.attach(device); + + this.channel(channel); } catch (e) { logError(e); } @@ -303,52 +366,163 @@ broadcast(address = null) { try { if (!this._networkAvailable) { - debug('Network unavailable; aborting'); return; + } - // Remember manual addresses so we know to accept connections - } else if (address instanceof Gio.InetSocketAddress) { - this.allowed.add(address.address.to_string()); + // Try to parse strings as <host>:<port> + if (typeof address === 'string') { + let [host, port] = address.split(':'); + port = parseInt(port) || DEFAULT_PORT; + address = Gio.InetSocketAddress.new_from_string(host, port); + } + + // If we succeed, remember this host + if (address instanceof Gio.InetSocketAddress) { + this._allowed.add(address.address.to_string()); - // Only broadcast to the network if no address is specified + // Broadcast to the network if no address is specified } else { debug('Broadcasting to LAN'); address = this._udp_address; } - this._udp.send_to(address, `${this.service.identity}`, null); + // Set the tcpPort before broadcasting + this.service.identity.body.tcpPort = this.port; + + if (this._udp6 !== null) { + this._udp6.send_to(address, `${this.service.identity}`, null); + } + + if (this._udp4 !== null) { + this._udp4.send_to(address, `${this.service.identity}`, null); + } } catch (e) { - warning(e); + debug(e, address); + } finally { + this.service.identity.body.tcpPort = undefined; } } - destroy() { - this._networkMonitor.disconnect(this._networkChangedId); + start() { + // Start TCP/UDP listeners + if (this._udp4 === null && this._udp6 === null) { + this._initUdpListener(); + } - this._tcp.stop(); - this._tcp.close(); + if (this._tcp === null) { + this._initTcpListener(); + } - this._udp_source.destroy(); - this._udp_stream.close(null); - this._udp.close(); + // Monitor network changes + if (this._networkChangedId === 0) { + this._networkAvailable = this._networkMonitor.network_available; + this._networkChangedId = this._networkMonitor.connect( + 'network-changed', + this._onNetworkChanged.bind(this) + ); + } } -}; + + stop() { + if (this._networkChangedId) { + this._networkMonitor.disconnect(this._networkChangedId); + this._networkChangedId = 0; + this._networkAvailable = false; + } + + if (this._tcp !== null) { + this._tcp.stop(); + this._tcp.close(); + this._tcp = null; + } + + if (this._udp6 !== null) { + this._udp6_source.destroy(); + this._udp6_stream.close(null); + this._udp6.close(); + this._udp6 = null; + } + + if (this._udp4 !== null) { + this._udp4_source.destroy(); + this._udp4_stream.close(null); + this._udp4.close(); + this._udp4 = null; + } + } + + destroy() { + try { + this.stop(); + } catch (e) { + debug(e); + } + } +}); /** - * Lan Base Channel + * Lan Channel * * This class essentially just extends Core.Channel to set TCP socket options * and negotiate TLS encrypted connections. */ -var Channel = class Channel extends Core.Channel { +var Channel = GObject.registerClass({ + GTypeName: 'ZorinConnectLanChannel', + Implements: [Core.Channel] +}, class LanChannel extends GObject.Object { + + _init(params) { + super._init(); + Object.assign(this, params); + } + + get address() { + return `lan://${this.host}:${this.port}`; + } get certificate() { - return this._connection.get_peer_certificate(); + return this._certificate || null; + } + + set certificate(certificate) { + this._certificate = certificate; } - get type() { - return 'tcp'; + get peer_certificate() { + if (this._connection instanceof Gio.TlsConnection) { + return this._connection.get_peer_certificate(); + } + + return null; + } + + get host() { + if (this._host === undefined) { + this._host = null; + } + + return this._host; + } + + set host(host) { + this._host = host; + } + + get port() { + if (this._port === undefined) { + if (this.identity && this.identity.body.tcpPort) { + this._port = this.identity.body.tcpPort; + } else { + return DEFAULT_PORT; + } + } + + return this._port; + } + + set port(port) { + this._port = port; } _initSocket(connection) { @@ -390,12 +564,16 @@ } async _authenticate(connection) { - try { - // Standard TLS Handshake - await this._handshake(connection); + // Standard TLS Handshake + await this._handshake(connection); + + // Try to find a certificate for this deviceId + let cert_pem; - // Get a GSettings object for this deviceId - let id = (this.device) ? this.device.id : this.identity.body.deviceId; + if (this.device) { + cert_pem = this.device.settings.get_string('certificate-pem'); + } else { + let id = this.identity.body.deviceId; let settings = new Gio.Settings({ settings_schema: zorin_connect.gschema.lookup( 'org.gnome.Shell.Extensions.ZorinConnect.Device', @@ -403,29 +581,27 @@ ), path: `/org/gnome/shell/extensions/zorin-connect/device/${id}/` }); - let cert_pem = settings.get_string('certificate-pem'); + cert_pem = settings.get_string('certificate-pem'); + } - // If we have a certificate for this deviceId, we can verify it - if (cert_pem !== '') { - let certificate = Gio.TlsCertificate.new_from_pem(cert_pem, -1); - let valid = certificate.is_same(connection.peer_certificate); - - // This is a fraudulent certificate; notify the user - if (!valid) { - let error = new Error(); - error.name = 'AuthenticationError'; - error.deviceName = this.identity.body.deviceName; - error.deviceHost = connection.base_io_stream.get_remote_address().address.to_string(); - this.service.notify_error(error); + // If we have a certificate for this deviceId, we can verify it + if (cert_pem !== '') { + let certificate = Gio.TlsCertificate.new_from_pem(cert_pem, -1); + let valid = certificate.is_same(connection.peer_certificate); + + // This is a fraudulent certificate; notify the user + if (!valid) { + let error = new Error(); + error.name = 'AuthenticationError'; + error.deviceName = this.identity.body.deviceName; + error.deviceHost = connection.base_io_stream.get_remote_address().address.to_string(); + this.service.notify_error(error); - throw error; - } + throw error; } - - return connection; - } catch (e) { - return Promise.reject(e); } + + return connection; } /** @@ -439,7 +615,7 @@ connection, connection.socket.remote_address ); - connection.set_certificate(this.service.certificate); + connection.set_certificate(this.certificate); return this._authenticate(connection); } @@ -451,10 +627,7 @@ * @return {Gio.TlsServerConnection} - The authenticated connection */ _serverEncryption(connection) { - connection = Gio.TlsServerConnection.new( - connection, - this.service.certificate - ); + connection = Gio.TlsServerConnection.new(connection, this.certificate); // We're the server so we trust-on-first-use and verify after let _id = connection.connect('accept-certificate', (connection) => { @@ -473,8 +646,6 @@ */ _receiveIdent(connection) { return new Promise((resolve, reject) => { - debug('receiving identity'); - let stream = new Gio.DataInputStream({ base_stream: connection.input_stream, close_base_stream: false @@ -513,7 +684,7 @@ */ _sendIdent(connection) { return new Promise((resolve, reject) => { - debug('sending identity'); + this.service.identity.body.tcpPort = this.backend.port; connection.output_stream.write_all_async( `${this.service.identity}`, @@ -521,6 +692,8 @@ this.cancellable, (stream, res) => { try { + this.service.identity.body.tcpPort = undefined; + stream.write_all_finish(res); resolve(connection); } catch (e) { @@ -538,7 +711,10 @@ */ async accept(connection) { try { - this._connection = await this._initSocket(connection); + debug(`${this.address} (${this.uuid})`); + this.backend.channels.set(this.address, this); + + this._connection = this._initSocket(connection); this._connection = await this._receiveIdent(this._connection); this._connection = await this._clientEncryption(this._connection); } catch (e) { @@ -554,7 +730,10 @@ */ async open(connection) { try { - this._connection = await this._initSocket(connection); + debug(`${this.address} (${this.uuid})`); + this.backend.channels.set(this.address, this); + + this._connection = this._initSocket(connection); this._connection = await this._sendIdent(this._connection); this._connection = await this._serverEncryption(this._connection); } catch (e) { @@ -567,19 +746,30 @@ * Close all streams associated with this channel, silencing any errors */ close() { - debug(`${this.constructor.name} (${this.type})`); + if (this._closed === undefined) { + debug(`${this.address} (${this.uuid})`); - // Cancel any queued operations - this.cancellable.cancel(); + this._closed = true; + this.backend.channels.delete(this.address); - // Close any streams - [this._connection, this.input_stream, this.output_stream].map(stream => { - try { - stream.close(null); - } catch (e) { - // Silence errors + // Cancel any queued operations + this.cancellable.cancel(); + + // Close any streams + let streams = [ + this.input_stream, + this.output_stream, + this._connection + ]; + + for (let stream of streams) { + try { + stream.close_async(0, null, null); + } catch (e) { + // Silence errors + } } - }); + } } /** @@ -589,10 +779,13 @@ */ attach(device) { try { - // Detach any existing channel + // Detach any existing channel and avoid an unnecessary disconnect if (device._channel && device._channel !== this) { - device._channel.cancellable.disconnect(device._channel._id); - device._channel.close(); + debug(`${device._channel.address} (${device._channel.uuid}) => ${this.address} (${this.uuid})`); + + let channel = device._channel; + channel.cancellable.disconnect(channel._id); + channel.close(); } // Attach the new channel and parse it's identity @@ -610,23 +803,31 @@ // Start listening for packets this.receive(device); - - // Emit connected:: if necessary - if (!device.connected) { - device._setConnected(); - } + device._setConnected(); } catch (e) { logError(e); this.close(); } } -}; + + createTransfer(params) { + params = Object.assign(params, { + backend: this.backend, + certificate: this.certificate, + host: this.host + }); + + return new Transfer(params); + } +}); /** - * Lan Transfer Channel + * Lan Transfer */ -var Transfer = class Transfer extends Channel { +var Transfer = GObject.registerClass({ + GTypeName: 'ZorinConnectLanTransfer' +}, class Transfer extends Channel { /** * @param {object} params - Transfer parameters @@ -635,8 +836,8 @@ * @param {Gio.OutputStream} params.output_stream - The output stream (write) * @param {number} params.size - The size of the transfer in bytes */ - constructor(params) { - super(params); + _init(params) { + super._init(params); // The device tracks transfers it owns so they can be closed from the // notification action. @@ -658,7 +859,6 @@ * When finished the channel and local input stream will be closed whether * or not the transfer succeeds. * - * @param {number} port - The port the transfer is listening for connection * @return {boolean} - %true on success or %false on fail */ async download() { @@ -671,7 +871,7 @@ // Use the address from GSettings with @port let address = Gio.InetSocketAddress.new_from_string( - this.device.settings.get_string('tcp-host'), + this.host, this.port ); @@ -688,7 +888,7 @@ this.input_stream = this._connection.get_input_stream(); // Start the transfer - result = await this._transfer(); + result = await this.transfer(); } catch (e) { logError(e, this.device.name); } finally { @@ -710,19 +910,20 @@ * @return {boolean} - %true on success or %false on fail */ async upload(packet) { - let port = 1739; + let port = TRANSFER_MIN; let result = false; try { // Start listening on the first available port between 1739-1764 let listener = new Gio.SocketListener(); - while (port <= TCP_MAX_PORT) { + while (port <= TRANSFER_MAX) { try { listener.add_inet_port(port, null); + this._port = port; break; } catch (e) { - if (port < TCP_MAX_PORT) { + if (port < TRANSFER_MAX) { port++; continue; } else { @@ -758,7 +959,7 @@ this.output_stream = this._connection.get_output_stream(); // Start the transfer - result = await this._transfer(); + result = await this.transfer(); } catch (e) { logError(e, this.device.name); } finally { @@ -767,42 +968,5 @@ return result; } - - /** - * Transfer using g_output_stream_splice() - * - * @return {Boolean} - %true on success, %false on failure. - */ - async _transfer() { - let result = false; - - try { - result = await new Promise((resolve, reject) => { - this.output_stream.splice_async( - this.input_stream, - Gio.OutputStreamSpliceFlags.NONE, - GLib.PRIORITY_DEFAULT, - this.cancellable, - (source, res) => { - try { - if (source.splice_finish(res) < this.size) { - throw new Error('incomplete data'); - } - - resolve(true); - } catch (e) { - reject(e); - } - } - ); - }); - } catch (e) { - debug(e, this.device.name); - } finally { - this.close(); - } - - return result; - } -}; +}); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/ui/contacts.js gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/contacts.js --- gnome-shell-extension-zorin-connect-24.1/src/service/ui/contacts.js 2019-03-04 01:58:18.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/contacts.js 2019-11-30 12:33:52.000000000 +0000 @@ -72,18 +72,18 @@ /** * Get Gdk.Pixbuf for @path, allowing the corrupt JPEG's KDE Connect sometimes - * sends. This function is synchronous + * sends. This function is synchronous. * * @param {string} path - A local file path */ -function getPixbuf(path, size = null) { - let data, loader; +function getPixbufForPath(path, size = null) { + let data, loader, pixbuf; // Catch missing avatar files try { data = GLib.file_get_contents(path)[1]; } catch (e) { - warning(e.message, path); + debug(e, path); return undefined; } @@ -93,10 +93,10 @@ loader.write(data); loader.close(); } catch (e) { - warning(e, path); + debug(e, path); } - let pixbuf = loader.get_pixbuf(); + pixbuf = loader.get_pixbuf(); // Scale if requested if (size !== null) { @@ -106,6 +106,14 @@ } } +function getPixbufForIcon(name, size, bgColor) { + let color = getFgRGBA(bgColor); + let theme = Gtk.IconTheme.get_default(); + let info = theme.lookup_icon(name, size, Gtk.IconLookupFlags.FORCE_SYMBOLIC); + + return info.load_symbolic(color, null, null, null)[0]; +} + /** * Return a localized string for a phone number and type @@ -140,69 +148,134 @@ } } +/** + * Get a display number from @contact for @address. + * + * @param {object} contact - A contact object + * @param {string} address - A phone number + */ +function getDisplayNumber(contact, address) { + let number = address.toPhoneNumber(); + + for (let contactNumber of contact.numbers) { + let cnumber = contactNumber.value.toPhoneNumber(); + + if (number.endsWith(cnumber) || cnumber.endsWith(number)) { + return contactNumber.value; + } + } + + return address; +} + /** * Contact Avatar */ +const AvatarCache = new WeakMap(); + var Avatar = GObject.registerClass({ GTypeName: 'ZorinConnectContactAvatar' }, class Avatar extends Gtk.DrawingArea { - _init(contact) { + _init(contact = null) { super._init({ height_request: 32, width_request: 32, - visible: true, - tooltip_text: contact.name || _('Unknown Contact') + visible: true }); - this._path = contact.avatar; + this.contact = contact; } - _loadPixbuf() { - if (this._path) { - this._pixbuf = getPixbuf(this._path, 32); + get contact() { + if (this._contact === undefined) { + this._contact = null; } - if (this._pixbuf === undefined) { - this._fallback = true; + return this._contact; + } - this.bg_color = randomRGBA(this.tooltip_text); + set contact(contact) { + if (this.contact !== contact) { + this._contact = contact; - let info = Gtk.IconTheme.get_default().lookup_icon( - 'avatar-default', - 24, - Gtk.IconLookupFlags.FORCE_SYMBOLIC - ); + this._surface = undefined; + this._bgRGBA = null; + this._offset = 0; + } + } + + _loadSurface() { + // If there's a contact with an avatar, try to load it + if (this.contact && this.contact.avatar) { + // Check the cache + this._surface = AvatarCache.get(this.contact); + + // Try loading the pixbuf + if (!this._surface) { + let pixbuf = getPixbufForPath( + this.contact.avatar, + this.width_request + ); - this._pixbuf = info.load_symbolic( - getFgRGBA(this.bg_color), - null, - null, - null - )[0]; + if (pixbuf) { + this._surface = Gdk.cairo_surface_create_from_pixbuf( + pixbuf, + 0, + this.get_window() + ); + AvatarCache.set(this.contact, this._surface); + } + } } - this._offset = (this.width_request - this._pixbuf.width) / 2; + // If we still don't have a surface, load a fallback + if (!this._surface) { + let colorSalt, iconName; + + // If we were given a contact, it's direct message + if (this.contact) { + colorSalt = this.contact.name; + iconName = 'avatar-default-symbolic'; + // Otherwise it's a group message + } else { + colorSalt = GLib.uuid_string_random(); + iconName = 'group-avatar-symbolic'; + } + + this._bgRGBA = randomRGBA(colorSalt); + this._offset = (this.width_request - 24) / 2; + + // Load the fallback + let pixbuf = getPixbufForIcon(iconName, 24, this._bgRGBA); + + this._surface = Gdk.cairo_surface_create_from_pixbuf( + pixbuf, + 0, + this.get_window() + ); + } } vfunc_draw(cr) { - if (this._pixbuf === undefined) { - this._loadPixbuf(); + if (!this._surface) { + this._loadSurface(); } // Clip to a circle - cr.arc(16, 16, 16, 0, 2 * Math.PI); + let rad = this.width_request / 2; + cr.arc(rad, rad, rad, 0, 2 * Math.PI); cr.clipPreserve(); - // Fill the background if we don't have an avatar - if (this._fallback) { - Gdk.cairo_set_source_rgba(cr, this.bg_color); + // Fill the background if the the surface is offset + if (this._offset > 0) { + Gdk.cairo_set_source_rgba(cr, this._bgRGBA); cr.fill(); } // Draw the avatar/icon - Gdk.cairo_set_source_pixbuf(cr, this._pixbuf, this._offset, this._offset); + cr.setSourceSurface(this._surface, this._offset, this._offset); cr.paint(); cr.$dispose(); @@ -225,7 +298,7 @@ 'store', 'Store', 'The contacts store', - GObject.ParamFlags.READWRITE, + GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT, GObject.Object ) }, @@ -235,107 +308,103 @@ param_types: [GObject.TYPE_STRING] } }, - Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/contacts.ui', - Children: [ - 'contact-entry', - 'contact-list', - 'contact-placeholder', - 'contact-window' - ] + Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/ui/contact-chooser.ui', + Children: ['entry', 'list', 'scrolled'] }, class ContactChooser extends Gtk.Grid { _init(params) { - this.connect_template(); + this.connectTemplate(); super._init(params); + // Setup the contact list + this.list._entry = this.entry.text; + this.list.set_filter_func(this._filter); + this.list.set_sort_func(this._sort); + // Make sure we're using the correct contacts store this.device.bind_property( 'contacts', this, 'store', - GObject.BindingFlags.DEFAULT + GObject.BindingFlags.SYNC_CREATE ); - // Setup the contact list - this.contact_list._entry = this.contact_entry.text; - this.contact_list.set_filter_func(this._filter); - this.contact_list.set_sort_func(this._sort); - this.contact_list.set_placeholder(this.contact_placeholder); - // Cleanup on ::destroy this.connect('destroy', this._onDestroy); - - // Initial populate - this._populate(); } get store() { - return this._store || null; + if (this._store === undefined) { + this._store = null; + } + + return this._store; } set store(store) { // Do nothing if the store hasn't changed - if (this._store && this._store === store) return; + if (this.store === store) return; + // Unbind the old store if (this._store) { - // Disconnect the current store + // Disconnect from the store this._store.disconnect(this._contactAddedId); this._store.disconnect(this._contactRemovedId); this._store.disconnect(this._contactChangedId); - // Clear the current list - let rows = this.contact_list.get_children(); + // Clear the contact list + let rows = this.list.get_children(); for (let i = 0, len = rows.length; i < len; i++) { + rows[i].destroy(); // HACK: temporary mitigator for mysterious GtkListBox leak - //row.destroy(); - rows[i].run_dispose(); imports.system.gc(); } } - // Connect to the new store - this._contactAddedId = store.connect( - 'contact-added', - this._onContactAdded.bind(this) - ); + // Set the store + this._store = store; - this._contactRemovedId = store.connect( - 'contact-removed', - this._onContactRemoved.bind(this) - ); + // Bind the new store + if (this._store) { + // Connect to the new store + this._contactAddedId = store.connect( + 'contact-added', + this._onContactAdded.bind(this) + ); - this._contactChangedId = store.connect( - 'contact-changed', - this._onContactChanged.bind(this) - ); + this._contactRemovedId = store.connect( + 'contact-removed', + this._onContactRemoved.bind(this) + ); - // If we're replacing the store we need to repopulate now - if (this._store) { - this._store = store; - this._populate(); + this._contactChangedId = store.connect( + 'contact-changed', + this._onContactChanged.bind(this) + ); - // Otherwise we're waiting for _init() to complete - } else { - this._store = store; + // Populate the list + this._populate(); } } + /** + * ContactStore Callbacks + */ _onContactAdded(store, id) { let contact = this.store.get_contact(id); - this.add_contact(contact); + this._addContact(contact); } _onContactRemoved(store, id) { - let rows = this.contact_list.get_children(); + let rows = this.list.get_children(); for (let i = 0, len = rows.length; i < len; i++) { let row = rows[i]; if (row.contact.id === id) { + row.destroy(); // HACK: temporary mitigator for mysterious GtkListBox leak - //row.destroy(); - row.run_dispose(); imports.system.gc(); } } @@ -347,22 +416,19 @@ } _onDestroy(chooser) { - chooser.store.disconnect(chooser._contactAddedId); - chooser.store.disconnect(chooser._contactRemovedId); - chooser.store.disconnect(chooser._contactChangedId); - - chooser.disconnect_template(); + chooser.store = null; + chooser.disconnectTemplate(); } _onSearchChanged(entry) { - this.contact_list._entry = entry.text; - let dynamic = this.contact_list.get_row_at_index(0); + this.list._entry = entry.text; + let dynamic = this.list.get_row_at_index(0); // If the entry contains string with 2 or more digits... if (entry.text.replace(/\D/g, '').length >= 2) { // ...ensure we have a dynamic contact for it if (!dynamic || !dynamic.__tmp) { - dynamic = this.add_contact({ + dynamic = this._addContact({ // TRANSLATORS: A phone number (eg. "Send to 555-5555") name: _('Send to %s').format(entry.text), numbers: [{type: 'unknown', value: entry.text}] @@ -388,19 +454,22 @@ dynamic.destroy(); } - this.contact_list.invalidate_filter(); - this.contact_list.invalidate_sort(); + this.list.invalidate_filter(); + this.list.invalidate_sort(); } + // GtkListBox::row-selected _onNumberSelected(box, row) { - // Reset the contact list - this.contact_entry.text = ''; - this.contact_list.select_row(null); - this.contact_window.vadjustment.value = 0; + if (row === null) return; // Emit the number let address = row.number.value; this.emit('number-selected', address); + + // Reset the contact list + this.entry.text = ''; + this.list.select_row(null); + this.scrolled.vadjustment.value = 0; } _filter(row) { @@ -446,24 +515,11 @@ let contacts = this.store.contacts; for (let i = 0, len = contacts.length; i < len; i++) { - this.add_contact(contacts[i]); + this._addContact(contacts[i]); } } - add_contact(contact) { - // HACK: fix missing contact names - contact.name = contact.name || _('Unknown Contact'); - - if (contact.numbers.length === 1) { - return this.add_contact_number(contact, 0); - } - - for (let i = 0, len = contact.numbers.length; i < len; i++) { - this.add_contact_number(contact, i); - } - } - - add_contact_number(contact, index) { + _addContactNumber(contact, index) { let row = new Gtk.ListBoxRow({ activatable: true, selectable: true, @@ -471,7 +527,7 @@ }); row.contact = contact; row.number = contact.numbers[index]; - this.contact_list.add(row); + this.list.add(row); let grid = new Gtk.Grid({ margin: 6, @@ -508,5 +564,40 @@ return row; } + + _addContact(contact) { + try { + // HACK: fix missing contact names + contact.name = contact.name || _('Unknown Contact'); + + if (contact.numbers.length === 1) { + return this._addContactNumber(contact, 0); + } + + for (let i = 0, len = contact.numbers.length; i < len; i++) { + this._addContactNumber(contact, i); + } + } catch (e) { + logError(e); + } + } + + /** + * Get a dictionary of number-contact pairs for each selected phone number. + */ + getSelected() { + try { + let selected = {}; + + for (let row of this.list.get_selected_rows()) { + selected[row.number.value] = row.contact; + } + + return selected; + } catch (e) { + logError(e); + return {}; + } + } }); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/ui/devel.js gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/devel.js --- gnome-shell-extension-zorin-connect-24.1/src/service/ui/devel.js 2019-03-05 21:21:46.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/devel.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,491 +0,0 @@ -'use strict'; - -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; -const Gdk = imports.gi.Gdk; -const System = imports.system; - - -function getPID() { - return Gio.DBus.session.call_sync( - 'org.freedesktop.DBus', - '/org/freedesktop/DBus', - 'org.freedesktop.DBus', - 'GetConnectionUnixProcessID', - new GLib.Variant('(s)', ['org.gnome.Shell.Extensions.ZorinConnect']), - null, - Gio.DBusCallFlags.NONE, - -1, - null - ).deep_unpack()[0]; -} - - -var Window = GObject.registerClass({ - GTypeName: 'ZorinConnectDevelWindow', - Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/devel.ui', - Children: [ - 'headerbar', 'stack', 'switcher', - 'packet-device', 'packet-direction', 'packet-type', 'packet-body', 'packet-button', - 'notification-device', 'notification-id', 'notification-time', - 'notification-appname', 'notification-title', 'notification-text', - 'notification-ticker', 'notification-requestreplyid', 'notification-isclearable', - 'sms-device', 'sms-address', 'sms-body', 'sms-type', 'sms-read', 'sms-id', 'sms-thread-id', 'sms-event-text', - 'sms-phonenumber', 'sms-messagebody', 'sms-uri', - 'telephony-device', 'telephony-event', 'telephony-name', 'telephony-number', - 'telephony-body', 'telephony-duplicate', 'telephony-iscancel', 'telephony-receive', - 'heap-path', 'heap-save' - ] -}, class Window extends Gtk.ApplicationWindow { - - _init() { - this.connect_template(); - - super._init({ - application: Gio.Application.get_default(), - visible: true - }); - - // Log & Debug Mode actions - this.add_action(zorin_connect.settings.create_action('debug')); - - let openLog = new Gio.SimpleAction({name: 'open-log'}); - openLog.connect('activate', this._openLog); - this.add_action(openLog); - - // Watch for device changes - this._devicesChangedId = this.application.connect( - 'notify::devices', - this._onDevicesChanged.bind(this) - ); - this._onDevicesChanged(); - - // Validate packet entry - this.packet_body.buffer.connect( - 'changed', - this._onPacketBodyChanged.bind(this) - ); - - // Bind notification id to tooltip - this.notification_id.bind_property( - 'active-id', - this.notification_id, - 'tooltip-text', - GObject.BindingFlags.SYNC_CREATE - ); - - // Set default heap path - this.heap_path.set_current_folder(GLib.get_home_dir()); - - this.show_all(); - } - - vfunc_delete_event(event) { - this.disconnect_template(); - this.application.disconnect(this._devicesChangedId); - } - - _onDevicesChanged() { - this.packet_device.remove_all(); - this.notification_device.remove_all(); - this.sms_device.remove_all(); - this.telephony_device.remove_all(); - - for (let device of this.application._devices.values()) { - this.packet_device.append(device.id, device.name); - this.notification_device.append(device.id, device.name); - this.sms_device.append(device.id, device.name); - this.telephony_device.append(device.id, device.name); - } - - if (this.application.devices.length > 0) { - this.packet_device.active = 0; - this.notification_device.active = 0; - this.sms_device.active = 0; - this.telephony_device.active = 0; - } - } - - /** - * Toggling Bluetooth for testing purposes - */ - _onBluetoothEnabled(widget) { - if (widget.active) { - this.application.bluetooth = new imports.service.bluetooth.ChannelService(); - widget.sensitive = false; - } - } - - /** - * Raw Packet - */ - _onPacketDestinationChanged(combobox) { - this.packet_type.remove_all(); - - let device = this.application._devices.get(this.packet_device.active_id); - - if (device === undefined) { - return; - } - - if (this.packet_direction.active_id === 'incoming') { - let incoming = device.settings.get_strv('incoming-capabilities'); - incoming.map(c => this.packet_type.append(c, c)); - } else if (this.packet_direction.active_id === 'outgoing') { - let outgoing = device.settings.get_strv('outgoing-capabilities'); - outgoing.map(c => this.packet_type.append(c, c)); - } - - this.packet_type.active = 0; - } - - _onPacketBodyChanged(buffer) { - let style, button; - - if (buffer === this.packet_body.buffer) { - button = this.packet_button; - style = button.get_style_context(); - } else { - button = this.receive_packet_button; - style = button.get_style_context(); - } - - if (buffer.text.length < 1) { - button.tooltip_text = null; - style.remove_class('destructive-action'); - } else { - try { - JSON.parse(buffer.text); - button.tooltip_text = null; - style.remove_class('destructive-action'); - } catch (e) { - button.tooltip_text = e.message; - style.add_class('destructive-action'); - } - } - } - - _onPacketExecute(button) { - try { - let body = {}; - - if (this.packet_body.buffer.text.length > 0) { - body = JSON.parse(this.packet_body.buffer.text); - } - - let device = this.application._devices.get( - this.packet_device.active_id - ); - - if (this.packet_direction.active_id === 'outgoing') { - device.receivePacket({ - id: Date.now(), - type: this.packet_type.active_id, - body: body - }); - } else if (this.packet_direction.active_id === 'incoming') { - device.sendPacket({ - id: Date.now(), - type: this.packet_type.active_id, - body: body - }); - } - } catch (e) { - logError(e); - } - } - - /** - * Notification - */ - _onNotificationIdChanged(combobox) { - if (this.notification_id.active_id === '0|com.google.android.apps.messaging|0|com.google.android.apps.messaging:sms:22|10109') { - this.notification_appname.text = 'Messages'; - this.notification_title.text = 'Contact Name'; - this.notification_text.text = 'SMS Message Body'; - } else if (this.notification_id.active_id === '0|com.google.android.dialer|1|MissedCall_content://call_log/calls/163?allow_voicemails=true|10073') { - this.notification_appname.text = 'Phone'; - this.notification_title.text = 'Missed call'; - this.notification_text.text = 'Contact Name'; - } else { - this.notification_appname.text = ''; - this.notification_title.text = ''; - this.notification_text.text = ''; - } - } - - _onNotificationTickerChanged(entry) { - this.notification_ticker.text = [ - this.notification_title.text, - this.notification_text.text - ].join(': '); - } - - _onNotificationReceive(button) { - try { - let device = this.application._devices.get( - this.notification_device.active_id - ); - - device.receivePacket({ - id: Date.now(), - type: 'kdeconnect.notification', - body: { - id: this.notification_id.active_id, - time: this.notification_time.text, - appName: this.notification_appname.text, - title: this.notification_title.text, - text: this.notification_text.text, - ticker: this.notification_ticker.text, - requestReplyId: this.notification_requestreplyid.text, - isClearable: this.notification_isclearable.active - } - }); - } catch (e) { - logError(e); - } - } - - _onNotificationIsCancel(button) { - try { - let device = this.application._devices.get( - this.notification_device.active_id - ); - - device.receivePacket({ - id: Date.now(), - type: 'kdeconnect.notification', - body: { - id: this.notification_id.active_id, - isCancel: true - } - }); - } catch (e) { - logError(e); - } - } - - /** - * SMS - */ - _onSmsReceive(button) { - let device = this.application._devices.get(this.sms_device.active_id); - - device.receivePacket({ - id: Date.now(), - type: 'kdeconnect.sms.messages', - body: { - messages: [ - { - address: this.sms_address.text, - body: this.sms_body.text, - date: Date.now(), - type: parseInt(this.sms_type.active_id), - read: parseInt(this.sms_read.active_id), - _id: this.sms_id.value, - thread_id: this.sms_thread_id.value, - // FIXME - event: (this.sms_event_text.active) ? 0x1 : 0 - } - ] - } - }); - - this.sms_id.value++; - } - - _onSmsSend(button) { - let device = this.application._devices.get(this.sms_device.active_id); - - device.sendPacket({ - id: Date.now(), - type: 'kdeconnect.sms.request', - body: { - sendSms: true, - phoneNumber: this.sms_phonenumber.text, - messageBody: this.sms_messagebody.text - } - }); - } - - _onSyncContacts(button) { - let device = this.application._devices.get(this.sms_device.active_id); - device.lookup_plugin('contacts').connected(); - } - - _onDeleteContacts(button) { - let device = this.application._devices.get(this.sms_device.active_id); - device.lookup_plugin('contacts')._store.clear(); - } - - _onSyncSMS(button) { - let device = this.application._devices.get(this.sms_device.active_id); - device.lookup_plugin('sms').connected(); - } - - _onDeleteSMS(button) { - let device = this.application._devices.get(this.sms_device.active_id); - device.lookup_plugin('sms').conversations = {}; - device.lookup_plugin('sms').__cache_write(); - } - - _onOpenURI(entry) { - if (this.sms_uri.text) { - log(this.sms_uri.text); - open_uri(this.sms_uri.text); - } - } - - /** - * Telephony - */ - _onTelephonyEventChanged(combobox) { - this.telephony_duplicate.sensitive = ['missedCall', 'sms'].includes(combobox.active_id); - } - - _onTelephonyReceive(button) { - try { - let device = this.application._devices.get( - this.telephony_device.active_id - ); - - let nid, nappname, ntime, ntitle, ntext; - - if (this.telephony_duplicate.active_id !== 0) { - if (this.telephony_event.active_id === 'missedCall') { - nid = '0|com.google.android.dialer|1|MissedCall_content://call_log/calls/163?allow_voicemails=true|10073'; - nappname = 'Phone'; - ntitle = 'Missed call'; - ntext = (this.telephony_name.text) ? this.telephony_name.text : this.telephony_number.text; - } else if (this.telephony_event.active_id === 'sms') { - nid = '0|com.google.android.apps.messaging|0|com.google.android.apps.messaging:sms:22|10109'; - nappname = 'Messages'; - ntitle = (this.telephony_name.text) ? this.telephony_name.text : this.telephony_number.text; - ntext = this.telephony_body.text; - } - - ntime = `${Date.now() - 1000}`; - } - - if (this.telephony_duplicate.active_id === 2) { - device.receivePacket({ - id: Date.now(), - type: 'kdeconnect.notification', - body: { - id: nid, - time: ntime, - appName: nappname, - title: ntitle, - text: ntext, - ticker: `${ntitle}: ${ntext}`, - requestReplyId: '23b1b660-8eb8-4c13-a232-79104300c114', - isClearable: true - } - }); - } - - device.receivePacket({ - id: Date.now(), - type: 'kdeconnect.telephony', - body: { - event: this.telephony_event.active_id, - phoneNumber: this.telephony_number.text || undefined, - contactName: this.telephony_name.text || undefined, - messageBody: this.telephony_body.text || undefined - } - }); - - if (this.telephony_duplicate.active_id === 1) { - device.receivePacket({ - id: Date.now(), - type: 'kdeconnect.notification', - body: { - id: nid, - time: ntime, - appName: nappname, - title: ntitle, - text: ntext, - ticker: `${ntitle}: ${ntext}`, - requestReplyId: '23b1b660-8eb8-4c13-a232-79104300c114', - isClearable: true - } - }); - } - } catch (e) { - logError(e); - } - } - - _onTelephonyIsCancel(button) { - try { - let device = this.application._devices.get( - this.telephony_device.active_id - ); - - device.receivePacket({ - id: Date.now(), - type: 'kdeconnect.telephony', - body: { - event: this.telephony_event.active_id, - phoneNumber: this.telephony_number.text, - contactName: this.telephony_name.text, - messageBody: this.telephony_body.text, - isCancel: true - } - }); - } catch (e) { - logError(e); - } - } - - /** - * Logging - */ - _openLog() { - try { - let display = Gdk.Display.get_default(); - let ctx = display.get_app_launch_context(); - - Gio.AppInfo.create_from_commandline( - 'journalctl -f -o cat GLIB_DOMAIN=ZorinConnect', - 'ZorinConnect', - Gio.AppInfoCreateFlags.NEEDS_TERMINAL - ).launch([], ctx); - } catch (e) { - logError(e); - } - } - - /** - * System methods - */ - breakpoint() { - log('Debug: System.breakpoint()'); - System.breakpoint(); - } - - dumpHeap() { - let path = GLib.build_filenamev([ - GLib.filename_from_uri(this.heap_path.get_uri())[0], - 'zorin-connect.heap' - ]); - - let i = 1; - - while (GLib.file_test(`${path}.${i}`, GLib.FileTest.EXISTS)) { - i++; - } - - path = `${path}.${i}`; - - log(`Debug: System.dumpHeap('${path}')`); - System.dumpHeap(path); - } - - gc() { - log('Debug: System.gc()'); - System.gc(); - } -}); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/ui/device.js gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/device.js --- gnome-shell-extension-zorin-connect-24.1/src/service/ui/device.js 2019-03-17 11:42:59.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/device.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,1085 +0,0 @@ -'use strict'; - -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; -const Pango = imports.gi.Pango; - -const Keybindings = imports.service.ui.keybindings; - - -// Build a list of plugins and shortcuts for devices -const DEVICE_PLUGINS = []; -const DEVICE_SHORTCUTS = { - activate: ['view-refresh-symbolic', _('Reconnect')], - openSettings: ['preferences-system-symbolic', _('Settings')] -}; - -for (let name in imports.service.plugins) { - if (name === 'base') continue; - - // Plugins - DEVICE_PLUGINS.push(name); - - // Shortcuts - let meta = imports.service.plugins[name].Metadata; - - for (let [name, action] of Object.entries(meta.actions)) { - if (action.parameter_type === null) { - DEVICE_SHORTCUTS[name] = [action.icon_name, action.label]; - } - } -} - - -// A GtkListBoxUpdateHeaderFunc for sections -function section_separators(row, before) { - if (before) { - row.set_header(new Gtk.Separator({visible: true})); - } -} - - -// A GtkListBoxSortFunc for SectionRow rows -function title_sort(row1, row2) { - if (!row1.title || !row2.title) return 0; - - return row1.title.localeCompare(row2.title); -} - - -/** - * A row for a section of settings - */ -const SectionRow = GObject.registerClass({ - GTypeName: 'ZorinConnectSectionRow' -}, class SectionRow extends Gtk.ListBoxRow { - - _init(params) { - super._init({ - height_request: 56, - selectable: false, - visible: true - }); - - let grid = new Gtk.Grid({ - column_spacing: 12, - margin_top: 8, - margin_right: 12, - margin_bottom: 8, - margin_left: 12, - visible: true - }); - this.add(grid); - - // Row Icon - this._icon = new Gtk.Image({ - pixel_size: 32 - }); - grid.attach(this._icon, 0, 0, 1, 2); - - // Row Title - this._title = new Gtk.Label({ - halign: Gtk.Align.START, - hexpand: true, - valign: Gtk.Align.CENTER, - vexpand: true - }); - grid.attach(this._title, 1, 0, 1, 1); - - // Row Subtitle - this._subtitle = new Gtk.Label({ - halign: Gtk.Align.START, - hexpand: true, - valign: Gtk.Align.CENTER, - vexpand: true - }); - this._subtitle.get_style_context().add_class('dim-label'); - grid.attach(this._subtitle, 1, 1, 1, 1); - - Object.assign(this, params); - } - - get icon_name() { - return this._icon.gicon.names[0]; - } - - set icon_name(icon_name) { - this._icon.visible = (icon_name); - this._icon.gicon = new Gio.ThemedIcon({name: icon_name}); - } - - get title() { - return this._title.label; - } - - set title(text) { - this._title.visible = (text); - this._title.label = text; - } - - get subtitle() { - return this._subtitle.label; - } - - set subtitle(text) { - this._subtitle.visible = (text); - this._subtitle.label = text; - } - - get widget() { - return this._widget; - } - - set widget(widget) { - if (this._widget && this._widget instanceof Gtk.Widget) { - this._widget.destroy(); - this._widget = null; - } - - this._widget = widget; - this.get_child().attach(this.widget, 2, 0, 1, 2); - } -}); - - -var DevicePreferences = GObject.registerClass({ - GTypeName: 'ZorinConnectDevicePreferences', - Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/device.ui', - Children: [ - 'sidebar', 'stack', 'infobar', - // Sharing - 'sharing-list', 'sharing-page', - 'clipboard', 'clipboard-sync', 'mousepad', 'mpris', 'systemvolume', - // RunCommand - 'runcommand', 'runcommand-page', - 'command-list', 'command-list-placeholder', - 'command-toolbar', 'command-add', 'command-remove', 'command-edit', 'command-save', - 'command-editor', 'command-name', 'command-line', - // Notifications - 'notification', 'notification-page', - 'notification-list', 'notification-apps', - // Telephony - 'telephony', 'telephony-page', - 'ringing-list', 'ringing-volume', 'talking-list', 'talking-volume', - // Shortcuts - 'shortcuts-page', - 'shortcuts-actions', 'shortcuts-actions-title', 'shortcuts-actions-list', - 'shortcuts-commands', 'shortcuts-commands-title', 'shortcuts-commands-list', - // Advanced - 'advanced-page', - 'plugin-list', 'experimental-list', 'danger-list' - ] -}, class DevicePreferences extends Gtk.Grid { - - _init(device) { - this.connect_template(); - - super._init(); - - this.device = device; - this.set_name(device.id); - - // Menus - this._menus = Gtk.Builder.new_from_resource(zorin_connect.app_path + '/gtk/menus.ui'); - this._menus.translation_domain = 'org.gnome.Shell.Extensions.ZorinConnect'; - - // GSettings - this.settings = new Gio.Settings({ - settings_schema: zorin_connect.gschema.lookup('org.gnome.Shell.Extensions.ZorinConnect.Device', true), - path: '/org/gnome/shell/extensions/zorin-connect/device/' + this.device.id + '/' - }); - - // Infobar - this.settings.bind( - 'paired', - this.infobar, - 'reveal-child', - Gio.SettingsBindFlags.GET | Gio.SettingsBindFlags.INVERT_BOOLEAN - ); - - this._setupActions(); - - // Device Menu - this.menu = this._menus.get_object('device-menu'); - this.menu.prepend_section(null, this.device.menu); - - this.insert_action_group('device', this.device); - - // Settings Pages - this._sharingSettings(); - this._runcommandSettings(); - this._notificationSettings(); - this._telephonySettings(); - // -------------------------- - this._keybindingSettings(); - this._advancedSettings(); - - // Separate plugins and other settings - this.sidebar.set_header_func((row, before) => { - if (row.get_name() === 'shortcuts') { - row.set_header(new Gtk.Separator({visible: true})); - } - }); - - // Connected/Paired - this._bluetoothHostChangedId = this.settings.connect( - 'changed::bluetooth-host', - this._onBluetoothHostChanged.bind(this) - ); - - this._tcpHostChangedId = this.settings.connect( - 'changed::tcp-host', - this._onTcpHostChanged.bind(this) - ); - - this._connectedId = this.device.connect( - 'notify::connected', - this._onConnected.bind(this) - ); - this._onConnected(this.device); - - // Hide elements for any disabled plugins - for (let name of DEVICE_PLUGINS) { - if (this.hasOwnProperty(name)) { - this[name].visible = this.get_plugin_allowed(name); - } - } - } - - get service() { - return Gio.Application.get_default(); - } - - _onKeynavFailed(widget, direction) { - if (direction === Gtk.DirectionType.UP && widget.prev) { - widget.prev.child_focus(direction); - } else if (direction === Gtk.DirectionType.DOWN && widget.next) { - widget.next.child_focus(direction); - } - - return true; - } - - _onSwitcherRowSelected(box, row) { - this.stack.set_visible_child_name(row.get_name()); - } - - _onToggleRowActivated(box, row) { - let widget = row.get_child().get_child_at(1, 0); - widget.active = !widget.active; - } - - _onConnected(device) { - this._onTcpHostChanged(); - this._onBluetoothHostChanged(); - } - - _onBluetoothHostChanged() { - let action = this.actions.lookup_action('connect-bluetooth'); - let hasBluetooth = (this.settings.get_string('bluetooth-host').length); - let isLan = (this.settings.get_string('last-connection') === 'tcp'); - - action.enabled = (isLan && hasBluetooth); - } - - _onActivateBluetooth() { - this.settings.set_string('last-connection', 'bluetooth'); - this.device.activate(); - } - - _onTcpHostChanged() { - let action = this.actions.lookup_action('connect-tcp'); - let hasLan = (this.settings.get_string('tcp-host').length); - let isBluetooth = (this.settings.get_string('last-connection') === 'bluetooth'); - - action.enabled = (isBluetooth && hasLan); - } - - _onActivateLan() { - this.settings.set_string('last-connection', 'tcp'); - this.device.activate(); - } - - _onEncryptionInfo() { - let dialog = new Gtk.MessageDialog({ - buttons: Gtk.ButtonsType.OK, - text: _('Encryption Info'), - secondary_text: this.device.encryption_info, - modal: true, - transient_for: this.get_toplevel() - }); - dialog.connect('response', (dialog) => dialog.destroy()); - dialog.present(); - } - - _onDeleteDevice(button) { - let application = Gio.Application.get_default(); - application.deleteDevice(this.device.id); - } - - _destroy() { - this.disconnect_template(); - - // Keybindings signals - this.device.disconnect(this._actionAddedId); - this.device.disconnect(this._actionRemovedId); - this.settings.disconnect(this._keybindingsId); - - // Device state signals - this.device.disconnect(this._connectedId); - this.settings.disconnect(this._bluetoothHostChangedId); - this.settings.disconnect(this._tcpHostChangedId); - - this.settings.disconnect(this._pluginsId); - } - - _getSettings(name) { - if (this._gsettings === undefined) { - this._gsettings = {}; - } - - if (this._gsettings.hasOwnProperty(name)) { - return this._gsettings[name]; - } - - let meta = imports.service.plugins[name].Metadata; - - this._gsettings[name] = new Gio.Settings({ - settings_schema: zorin_connect.gschema.lookup(meta.id, -1), - path: this.settings.path + 'plugin/' + name + '/' - }); - - return this._gsettings[name]; - } - - _setupActions() { - this.actions = new Gio.SimpleActionGroup(); - this.insert_action_group('settings', this.actions); - - let settings = this._getSettings('battery'); - this.actions.add_action(settings.create_action('send-statistics')); - - settings = this._getSettings('clipboard'); - this.actions.add_action(settings.create_action('send-content')); - this.actions.add_action(settings.create_action('receive-content')); - this.clipboard_sync.set_menu_model(this._menus.get_object('clipboard-sync')); - - settings = this._getSettings('contacts'); - this.actions.add_action(settings.create_action('contacts-source')); - - settings = this._getSettings('mousepad'); - this.actions.add_action(settings.create_action('share-control')); - - settings = this._getSettings('mpris'); - this.actions.add_action(settings.create_action('share-players')); - - settings = this._getSettings('notification'); - this.actions.add_action(settings.create_action('send-notifications')); - - settings = this._getSettings('photo'); - this.actions.add_action(settings.create_action('share-camera')); - - settings = this._getSettings('sms'); - this.actions.add_action(settings.create_action('legacy-sms')); - - settings = this._getSettings('systemvolume'); - this.actions.add_action(settings.create_action('share-sinks')); - - settings = this._getSettings('telephony'); - this.actions.add_action(settings.create_action('ringing-volume')); - this.actions.add_action(settings.create_action('ringing-pause')); - this.ringing_volume.set_menu_model(this._menus.get_object('ringing-volume')); - - this.actions.add_action(settings.create_action('talking-volume')); - this.actions.add_action(settings.create_action('talking-pause')); - this.actions.add_action(settings.create_action('talking-microphone')); - this.talking_volume.set_menu_model(this._menus.get_object('talking-volume')); - - // Connect Actions - let status_bluetooth = new Gio.SimpleAction({name: 'connect-bluetooth'}); - status_bluetooth.connect('activate', this._onActivateBluetooth.bind(this)); - this.actions.add_action(status_bluetooth); - - let status_lan = new Gio.SimpleAction({name: 'connect-tcp'}); - status_lan.connect('activate', this._onActivateLan.bind(this)); - this.actions.add_action(status_lan); - - // Pair Actions - let encryption_info = new Gio.SimpleAction({name: 'encryption-info'}); - encryption_info.connect('activate', this._onEncryptionInfo.bind(this)); - this.actions.add_action(encryption_info); - - let status_pair = new Gio.SimpleAction({name: 'pair'}); - status_pair.connect('activate', this.device.pair.bind(this.device)); - this.settings.bind('paired', status_pair, 'enabled', 16); - this.actions.add_action(status_pair); - - let status_unpair = new Gio.SimpleAction({name: 'unpair'}); - status_unpair.connect('activate', this.device.unpair.bind(this.device)); - this.settings.bind('paired', status_unpair, 'enabled', 0); - this.actions.add_action(status_unpair); - } - - /** - * Sharing Settings - */ - _sharingSettings() { - this.sharing_list.foreach(row => { - let name = row.get_name(); - row.visible = this.device.get_outgoing_supported(`${name}.request`); - - // Extra check for battery reporting - if (name === 'battery') { - row.visible = row.visible && this.service.type === 'laptop'; - } - }); - - // Separators & Sorting - this.sharing_list.set_header_func(section_separators); - - this.sharing_list.set_sort_func((row1, row2) => { - row1 = row1.get_child().get_child_at(0, 0); - row2 = row2.get_child().get_child_at(0, 0); - return row1.label.localeCompare(row2.label); - }); - } - - /** - * RunCommand Page - */ - _runcommandSettings() { - // Exclusively enable the editor or add button - this.command_editor.bind_property( - 'visible', - this.command_add, - 'sensitive', - GObject.BindingFlags.INVERT_BOOLEAN - ); - - // Bind the edit/save button sensitivity to the editor visibility - this.command_editor.bind_property( - 'visible', - this.command_edit, - 'sensitive', - GObject.BindingFlags.INVERT_BOOLEAN - ); - - this.command_editor.bind_property( - 'visible', - this.command_save, - 'sensitive', - GObject.BindingFlags.DEFAULT - ); - - // Scroll with keyboard focus - let runcommand_box = this.runcommand_page.get_child().get_child(); - runcommand_box.set_focus_vadjustment(this.runcommand_page.vadjustment); - - // Local Command List - let settings = this._getSettings('runcommand'); - this._commands = settings.get_value('command-list').full_unpack(); - this._commands = (typeof this._commands === 'string') ? {} : this._commands; - - this.command_list.set_placeholder(this.command_list_placeholder); - this.command_list.set_sort_func(title_sort); - this.command_list.set_header_func(section_separators); - - Object.keys(this._commands).map(uuid => this._insertCommand(uuid)); - } - - _resetCommandEditor() { - // Reset the command editor - delete this.command_editor.uuid; - this.command_name.text = ''; - this.command_line.text = ''; - this.command_editor.visible = false; - - this.command_list.foreach(child => { - if (child === this.command_editor) return; - - child.visible = true; - child.sensitive = true; - }); - - this.command_list.invalidate_sort(); - this.command_list.invalidate_headers(); - } - - _insertCommand(uuid) { - let row = new SectionRow({ - title: this._commands[uuid].name, - subtitle: this._commands[uuid].command, - selectable: true - }); - row.set_name(uuid); - row._subtitle.ellipsize = Pango.EllipsizeMode.MIDDLE; - - this.command_list.add(row); - - return row; - } - - _onCommandSelected(box) { - let selected = (box.get_selected_row() !== null); - this.command_edit.sensitive = selected; - this.command_remove.sensitive = selected; - } - - // The [+] button in the toolbar - _onAddCommand(button) { - let uuid = GLib.uuid_string_random(); - this._commands[uuid] = {name: '', command: ''}; - - let row = this._insertCommand(uuid); - this.command_list.select_row(row); - this._onEditCommand(); - } - - // The [-] button in the toolbar - _onRemoveCommand(button) { - let row = this.command_list.get_selected_row(); - delete this._commands[row.get_name()]; - - this._getSettings('runcommand').set_value( - 'command-list', - GLib.Variant.full_pack(this._commands) - ); - - row.destroy(); - this._resetCommandEditor(); - } - - // 'Edit' icon in the toolbar - _onEditCommand(button) { - let row = this.command_list.get_selected_row(); - let uuid = row.get_name(); - - this.command_editor.uuid = uuid; - this.command_name.text = this._commands[uuid].name; - this.command_line.text = this._commands[uuid].command; - - row.visible = false; - this.command_editor.visible = true; - this.command_name.has_focus = true; - - this.command_list.foreach(child => { - child.sensitive = (child === this.command_editor); - }); - } - - // 'Save' icon in the toolbar - _onSaveCommand(button) { - let row = this.command_list.get_selected_row(); - let uuid = row.get_name(); - - if (this.command_name.text && this.command_line.text) { - this._commands[uuid] = { - name: this.command_name.text, - command: this.command_line.text - }; - - row.title = this.command_name.text; - row.subtitle = this.command_line.text; - - this._getSettings('runcommand').set_value( - 'command-list', - GLib.Variant.full_pack(this._commands) - ); - } else { - delete this._commands[uuid]; - row.destroy(); - } - - this._resetCommandEditor(); - } - - // The 'folder' icon in the command editor GtkEntry - _onBrowseCommand(entry, icon_pos, event) { - let filter = new Gtk.FileFilter(); - filter.add_mime_type('application/x-executable'); - - let dialog = new Gtk.FileChooserDialog({filter: filter}); - dialog.add_button(_('Cancel'), Gtk.ResponseType.CANCEL); - dialog.add_button(_('Open'), Gtk.ResponseType.OK); - dialog.set_default_response(Gtk.ResponseType.OK); - - dialog.connect('response', (dialog, response_id) => { - if (response_id === Gtk.ResponseType.OK) { - this.command_line.text = dialog.get_filename(); - } - - dialog.destroy(); - }); - - dialog.show_all(); - } - - /** - * Notification Settings - */ - _notificationSettings() { - let settings = this._getSettings('notification'); - - settings.bind( - 'send-notifications', - this.notification_apps, - 'sensitive', - Gio.SettingsBindFlags.DEFAULT - ); - - // Scroll with keyboard focus - let notification_box = this.notification_page.get_child().get_child(); - notification_box.set_focus_vadjustment(this.notification_page.vadjustment); - - // Continue focus chain between lists - this.notification_list.next = this.notification_apps; - this.notification_apps.prev = this.notification_list; - - this.notification_apps.set_sort_func(title_sort); - this.notification_apps.set_header_func(section_separators); - - this._populateApplications(settings); - } - - _onNotificationRowActivated(box, row) { - let settings = this._getSettings('notification'); - let applications = {}; - - try { - applications = JSON.parse(settings.get_string('applications')); - } catch (e) { - applications = {}; - } - - applications[row.title].enabled = !applications[row.title].enabled; - row.widget.label = applications[row.title].enabled ? _('On') : _('Off'); - settings.set_string('applications', JSON.stringify(applications)); - } - - _populateApplications(settings) { - let applications = this._queryApplications(settings); - - for (let name in applications) { - let row = new SectionRow({ - icon_name: applications[name].iconName, - title: name, - height_request: 48, - widget: new Gtk.Label({ - label: applications[name].enabled ? _('On') : _('Off'), - margin_start: 12, - margin_end: 12, - halign: Gtk.Align.END, - valign: Gtk.Align.CENTER, - vexpand: true, - visible: true - }) - }); - - this.notification_apps.add(row); - } - } - - // TODO: move to components/notification.js - _queryApplications(settings) { - let applications = {}; - - try { - applications = JSON.parse(settings.get_string('applications')); - } catch (e) { - applications = {}; - } - - let appInfos = []; - let ignoreId = 'org.gnome.Shell.Extensions.ZorinConnect.desktop'; - - // Query GNOME's notification settings - for (let appSettings of Object.values(this.service.notification.applications)) { - let appId = appSettings.get_string('application-id'); - - if (appId !== ignoreId) { - let appInfo = Gio.DesktopAppInfo.new(appId); - - if (appInfo) { - appInfos.push(appInfo); - } - } - } - - // Scan applications that statically declare to show notifications - // TODO: if g-s-d does this already, maybe we don't have to - for (let appInfo of Gio.AppInfo.get_all()) { - if (appInfo.get_id() !== ignoreId && - appInfo.get_boolean('X-GNOME-UsesNotifications')) { - appInfos.push(appInfo); - } - } - - // Update GSettings - for (let appInfo of appInfos) { - let appName = appInfo.get_name(); - - if (appName && !applications[appName]) { - let icon = appInfo.get_icon(); - icon = (icon) ? icon.to_string() : 'application-x-executable'; - - applications[appName] = { - iconName: icon, - enabled: true - }; - } - } - - settings.set_string('applications', JSON.stringify(applications)); - - return applications; - } - - /** - * Telephony Settings - */ - _telephonySettings() { - // Continue focus chain between lists - this.ringing_list.next = this.talking_list; - this.talking_list.prev = this.ringing_list; - - this.ringing_list.set_header_func(section_separators); - this.talking_list.set_header_func(section_separators); - } - - /** - * Keyboard Shortcuts - */ - _keybindingSettings() { - // Scroll with keyboard focus - let shortcuts_box = this.shortcuts_page.get_child().get_child(); - shortcuts_box.set_focus_vadjustment(this.shortcuts_page.vadjustment); - - // Filter & Sort - this.shortcuts_actions_list.set_filter_func(this._filterPluginKeybindings.bind(this)); - this.shortcuts_actions_list.set_header_func(section_separators); - this.shortcuts_actions_list.set_sort_func(title_sort); - - // Init - for (let name in DEVICE_SHORTCUTS) { - this._addPluginKeybinding(name); - } - - this._setPluginKeybindings(); - - // Watch for GAction and Keybinding changes - this._actionAddedId = this.device.connect( - 'action-added', - () => this.shortcuts_actions_list.invalidate_filter() - ); - this._actionRemovedId = this.device.connect( - 'action-removed', - () => this.shortcuts_actions_list.invalidate_filter() - ); - this._keybindingsId = this.settings.connect( - 'changed::keybindings', - this._setPluginKeybindings.bind(this) - ); - - // TODO: probably not used very often, but needs work - this.shortcuts_commands_list.set_header_func(section_separators); - this.shortcuts_commands_list.set_sort_func(title_sort); - this._populateCommandKeybindings(); - } - - _addPluginKeybinding(name) { - let [icon_name, label] = DEVICE_SHORTCUTS[name]; - - let widget = new Gtk.Label({ - label: _('Disabled'), - visible: true - }); - widget.get_style_context().add_class('dim-label'); - - let row = new SectionRow({ - icon_name: icon_name, - title: label, - widget: widget - }); - row.height_request = 48; - row._icon.pixel_size = 16; - row.action = name; - this.shortcuts_actions_list.add(row); - } - - _filterPluginKeybindings(row) { - return (this.device.lookup_action(row.action)); - } - - _setPluginKeybindings() { - let keybindings = this.settings.get_value('keybindings').deep_unpack(); - - this.shortcuts_actions_list.foreach(row => { - if (keybindings[row.action]) { - let accel = Gtk.accelerator_parse(keybindings[row.action]); - row.widget.label = Gtk.accelerator_get_label(...accel); - } else { - row.widget.label = _('Disabled'); - } - }); - } - - _onResetActionShortcuts(button) { - let keybindings = this.settings.get_value('keybindings').deep_unpack(); - - for (let action in keybindings) { - if (!action.includes('::')) { - delete keybindings[action]; - } - } - - this.settings.set_value( - 'keybindings', - new GLib.Variant('a{ss}', keybindings) - ); - } - - _addCommandKeybinding(uuid, command, keybindings) { - let action = `executeCommand::${uuid}`; - - let widget = new Gtk.Label({ - label: _('Disabled'), - visible: true - }); - widget.get_style_context().add_class('dim-label'); - - if (keybindings[action]) { - let accel = Gtk.accelerator_parse(keybindings[action]); - widget.label = Gtk.accelerator_get_label(...accel); - } - - let row = new SectionRow({ - title: command.name, - subtitle: command.command, - widget: widget - }); - row.action = action; - this.shortcuts_commands_list.add(row); - } - - _populateCommandKeybindings() { - this.shortcuts_commands_list.foreach(row => { - // HACK: temporary mitigator for mysterious GtkListBox leak - //row.destroy(); - row.run_dispose(); - imports.system.gc(); - }); - - let keybindings = this.settings.get_value('keybindings').deep_unpack(); - - // Exclude defunct commands - for (let action in keybindings) { - if (action.includes('::')) { - let uuid = action.split('::')[1]; - - if (!remoteCommands.hasOwnProperty(uuid)) { - delete keybindings[action]; - } - } - } - - // Commands - let runcommand = this.device.lookup_plugin('runcommand'); - let remoteCommands = (runcommand) ? runcommand.remote_commands : {}; - let hasCommands = (Object.keys(remoteCommands).length > 0); - this.shortcuts_commands_title.visible = hasCommands; - this.shortcuts_commands.visible = hasCommands; - - for (let [uuid, command] of Object.entries(remoteCommands)) { - this._addCommandKeybinding(uuid, command, keybindings); - } - - for (let action in keybindings) { - if (action.includes('::')) { - let uuid = action.split('::')[1]; - - if (!remoteCommands.hasOwnProperty(uuid)) { - delete keybindings[action]; - } - } - } - } - - _onResetCommandShortcuts(button) { - let keybindings = this.settings.get_value('keybindings').deep_unpack(); - - for (let action in keybindings) { - if (action.includes('::')) { - delete keybindings[action]; - } - } - - this.settings.set_value( - 'keybindings', - new GLib.Variant('a{ss}', keybindings) - ); - } - - async _onShortcutRowActivated(box, row) { - try { - let keybindings = this.settings.get_value('keybindings').deep_unpack(); - let accelerator = await Keybindings.get_accelerator( - row.title, - keybindings[row.action] - ); - - if (accelerator) { - keybindings[row.action] = accelerator; - } else { - delete keybindings[row.action]; - } - - this.settings.set_value( - 'keybindings', - new GLib.Variant('a{ss}', keybindings) - ); - } catch (e) { - logError(e); - } - } - - /** - * Advanced Page - */ - _advancedSettings() { - // Scroll with keyboard focus - let advanced_box = this.advanced_page.get_child().get_child(); - advanced_box.set_focus_vadjustment(this.advanced_page.vadjustment); - - // - this.plugin_list.set_header_func(section_separators); - - // Continue focus chain between lists - this.plugin_list.next = this.experimental_list; - this.experimental_list.prev = this.plugin_list; - - this._pluginsId = this.settings.connect( - 'changed::supported-plugins', - this._populatePlugins.bind(this) - ); - this._populatePlugins(); - } - - get_plugin_allowed(name) { - let disabled = this.settings.get_strv('disabled-plugins'); - let supported = this.device.supported_plugins; - - return supported.filter(name => !disabled.includes(name)).includes(name); - } - - _addPlugin(name) { - let plugin = imports.service.plugins[name]; - - let row = new Gtk.ListBoxRow({ - border_width: 0, - visible: true - }); - - let grid = new Gtk.Grid({ - height_request: 32, - visible: true - }); - row.add(grid); - - let widget = new Gtk.CheckButton({ - label: plugin.Metadata.label, - active: this.get_plugin_allowed(name), - hexpand: true, - tooltip_text: name, - valign: Gtk.Align.CENTER, - vexpand: true, - visible: true - }); - grid.add(widget); - - if (plugin.Plugin.prototype.cacheClear) { - let button = new Gtk.Button({ - image: new Gtk.Image({ - icon_name: 'edit-clear-all-symbolic', - pixel_size: 16, - visible: true - }), - valign: Gtk.Align.CENTER, - vexpand: true, - visible: true - }); - button.connect('clicked', this._clearPluginCache.bind(this, name)); - button.get_style_context().add_class('flat'); - widget.bind_property('active', button, 'sensitive', 2); - grid.add(button); - } - - this.plugin_list.add(row); - - widget._togglePluginId = widget.connect( - 'notify::active', - this._togglePlugin.bind(this) - ); - - if (this.hasOwnProperty(name)) { - this[name].visible = widget.active; - } - } - - _clearPluginCache(name) { - try { - this.device.lookup_plugin(name).cacheClear(); - } catch (e) { - warning(e, `${this.device.name}: ${this.name}`); - } - } - - _populatePlugins() { - let supported = this.device.supported_plugins; - - for (let row of this.plugin_list.get_children()) { - let checkbutton = row.get_child().get_child_at(0, 0); - let name = checkbutton.tooltip_text; - - if (supported.includes(name)) { - row.visible = true; - checkbutton.active = this.get_plugin_allowed(name); - } else { - row.visible = false; - - if (this.hasOwnProperty(name)) { - this[name].visible = false; - } - } - - supported.splice(supported.indexOf(name), 1); - } - - for (let name of supported) { - this._addPlugin(name); - } - } - - _togglePlugin(widget) { - try { - let name = widget.tooltip_text; - let disabled = this.settings.get_strv('disabled-plugins'); - - if (disabled.includes(name)) { - disabled.splice(disabled.indexOf(name), 1); - } else { - disabled.push(name); - } - - this.settings.set_strv('disabled-plugins', disabled); - - if (this.hasOwnProperty(name)) { - this[name].visible = !disabled.includes(name); - } - } catch (e) { - logError(e); - } - } -}); - diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/ui/__init__.js gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/__init__.js --- gnome-shell-extension-zorin-connect-24.1/src/service/ui/__init__.js 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/__init__.js 2019-11-30 12:34:10.000000000 +0000 @@ -0,0 +1,69 @@ +'use strict'; + +const Gdk = imports.gi.Gdk; +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; +const Gtk = imports.gi.Gtk; + + +/** + * TODO: required for GJS 1.52 (GNOME 3.28) + */ +Gtk.Widget.prototype.connectTemplate = function() { + this.$templateHandlers = []; + + Gtk.Widget.set_connect_func.call(this, (builder, obj, signalName, handlerName, connectObj, flags) => { + this.$templateHandlers.push([ + obj, + obj.connect(signalName, this[handlerName].bind(this)) + ]); + }); +}; + +Gtk.Widget.prototype.disconnectTemplate = function() { + Gtk.Widget.set_connect_func.call(this, function() {}); + this.$templateHandlers.map(([obj, id]) => obj.disconnect(id)); +}; + + +/** + * Window State + */ +Gtk.Window.prototype.restoreGeometry = function(context = 'default') { + this._windowState = new Gio.Settings({ + settings_schema: zorin_connect.gschema.lookup( + 'org.gnome.Shell.Extensions.ZorinConnect.WindowState', + true + ), + path: `/org/gnome/shell/extensions/zorin-connect/${context}/` + }); + + // Size + let [width, height] = this._windowState.get_value('window-size').deep_unpack(); + + if (width && height) { + this.set_default_size(width, height); + } + + // Maximized State + if (this._windowState.get_boolean('window-maximized')) { + this.maximize(); + } +}; + +Gtk.Window.prototype.saveGeometry = function() { + let state = this.get_window().get_state(); + + // Maximized State + let maximized = (state & Gdk.WindowState.MAXIMIZED); + this._windowState.set_boolean('window-maximized', maximized); + + // Leave the size at the value before maximizing + if (maximized || (state & Gdk.WindowState.FULLSCREEN)) + return; + + // Size + let size = this.get_size(); + this._windowState.set_value('window-size', new GLib.Variant('(ii)', size)); +}; + diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/ui/keybindings.js gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/keybindings.js --- gnome-shell-extension-zorin-connect-24.1/src/service/ui/keybindings.js 2019-05-01 11:42:21.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/keybindings.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,424 +0,0 @@ -'use strict'; - -const Gdk = imports.gi.Gdk; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; - - -/** - * Response enum for ShortcutChooserDialog - */ -var ResponseType = { - CANCEL: Gtk.ResponseType.CANCEL, - SET: Gtk.ResponseType.APPLY, - UNSET: 2 -}; - - -/** - * Check the minor version of gnome-shell. - * - * @param {number} - the minor version of gnome-shell - */ -async function getShellVersionMinor() { - try { - if (getShellVersionMinor.__value) - return getShellVersionMinor.__value; - - getShellVersionMinor.__value = await new Promise((resolve, reject) => { - Gio.DBus.session.call( - 'org.gnome.Shell', - '/org/gnome/Shell', - 'org.freedesktop.DBus.Properties', - 'Get', - new GLib.Variant('(ss)', ['org.gnome.Shell', 'ShellVersion']), - null, - Gio.DBusCallFlags.NONE, - -1, - null, - (connection, res) => { - try { - res = connection.call_finish(res); - let version = res.deep_unpack()[0].get_string()[0]; - let minor = parseInt(version.split('.')[1], 10); - resolve(minor); - } catch (e) { - reject(e); - } - } - ); - }); - - return getShellVersionMinor.__value; - } catch (e) { - logError(e); - return 32; - } -} - - -/** - * A simplified version of the shortcut editor from GNOME Control Center - */ -var ShortcutChooserDialog = GObject.registerClass({ - GTypeName: 'ShortcutChooserDialog' -}, class ShortcutChooserDialog extends Gtk.Dialog { - - _init(params) { - super._init({ - transient_for: Gio.Application.get_default().get_active_window(), - use_header_bar: true, - modal: true, - // TRANSLATORS: Title of keyboard shortcut dialog - title: _('Set Shortcut') - }); - - this.seat = Gdk.Display.get_default().get_default_seat(); - - // Content - let content = this.get_content_area(); - content.spacing = 18; - content.margin = 12; - - // Action Buttons - this.cancel_button = this.add_button(_('Cancel'), ResponseType.CANCEL); - this.cancel_button.visible = false; - // TRANSLATORS: Button to confirm the new shortcut - this.set_button = this.add_button(_('Set'), ResponseType.SET); - this.set_button.visible = false; - this.set_default_response(ResponseType.SET); - - let summaryLabel = new Gtk.Label({ - // TRANSLATORS: Summary of a keyboard shortcut function - // Example: Enter a new shortcut to change Messaging - label: _('Enter a new shortcut to change <b>%s</b>').format( - params.summary - ), - use_markup: true, - visible: true - }); - content.add(summaryLabel); - - this.stack = new Gtk.Stack({ - transition_type: Gtk.StackTransitionType.CROSSFADE, - visible: true - }); - content.add(this.stack); - - // Edit page - let editPage = new Gtk.Grid({ - row_spacing: 18, - visible: true - }); - this.stack.add_named(editPage, 'edit'); - - let editImage = new Gtk.Image({ - resource: '/org/gnome/Shell/Extensions/ZorinConnect/enter-keyboard-shortcut.svg', - visible: true - }); - editPage.attach(editImage, 0, 0, 1, 1); - - let editLabel = new Gtk.Label({ - // TRANSLATORS: Keys for cancelling (␛) or resetting (␈) a shortcut - label: _('Press Esc to cancel or Backspace to reset the keyboard shortcut.'), - visible: true - }); - editLabel.get_style_context().add_class('dim-label'); - editPage.attach(editLabel, 0, 1, 1, 1); - - // Confirm page - let confirmPage = new Gtk.Grid({ - row_spacing: 18, - visible: true - }); - this.stack.add_named(confirmPage, 'confirm'); - - this.shortcut_label = new Gtk.ShortcutLabel({ - accelerator: params.accelerator, - hexpand: true, - halign: Gtk.Align.CENTER, - visible: true - }); - confirmPage.attach(this.shortcut_label, 0, 0, 1, 1); - - this.conflict_label = new Gtk.Label({ - hexpand: true, - halign: Gtk.Align.CENTER - }); - confirmPage.attach(this.conflict_label, 0, 1, 1, 1); - } - - get accelerator() { - return this.shortcut_label.accelerator; - } - - set accelerator(value) { - this.shortcut_label.accelerator = value; - } - - vfunc_key_press_event(event) { - let keyvalLower = Gdk.keyval_to_lower(event.keyval); - let realMask = event.state & Gtk.accelerator_get_default_mod_mask(); - - // TODO: Remove modifier keys - let mods = [ - Gdk.KEY_Alt_L, - Gdk.KEY_Alt_R, - Gdk.KEY_Caps_Lock, - Gdk.KEY_Control_L, - Gdk.KEY_Control_R, - Gdk.KEY_Meta_L, - Gdk.KEY_Meta_R, - Gdk.KEY_Num_Lock, - Gdk.KEY_Shift_L, - Gdk.KEY_Shift_R, - Gdk.KEY_Super_L, - Gdk.KEY_Super_R - ]; - if (mods.includes(keyvalLower)) { - return true; - } - - // Normalize Tab - if (keyvalLower === Gdk.KEY_ISO_Left_Tab) { - keyvalLower = Gdk.KEY_Tab; - } - - // Put shift back if it changed the case of the key, not otherwise. - if (keyvalLower !== event.keyval) { - realMask |= Gdk.ModifierType.SHIFT_MASK; - } - - // HACK: we don't want to use SysRq as a keybinding (but we do want - // Alt+Print), so we avoid translation from Alt+Print to SysRq - if (keyvalLower === Gdk.KEY_Sys_Req && (realMask & Gdk.ModifierType.MOD1_MASK) !== 0) { - keyvalLower = Gdk.KEY_Print; - } - - // A single Escape press cancels the editing - if (realMask === 0 && keyvalLower === Gdk.KEY_Escape) { - this.response(ResponseType.CANCEL); - return false; - } - - // Backspace disables the current shortcut - if (realMask === 0 && keyvalLower === Gdk.KEY_BackSpace) { - this.response(ResponseType.UNSET); - return false; - } - - // CapsLock isn't supported as a keybinding modifier, so keep it from - // confusing us - realMask &= ~Gdk.ModifierType.LOCK_MASK; - - if (keyvalLower !== 0 && realMask !== 0) { - this._ungrab(); - - // Set the accelerator property/label - this.accelerator = Gtk.accelerator_name(keyvalLower, realMask); - - // TRANSLATORS: When a keyboard shortcut is unavailable - // Example: [Ctrl]+[S] is already being used - this.conflict_label.label = _('%s is already being used').format( - Gtk.accelerator_get_label(keyvalLower, realMask) - ); - - // Show Cancel button and switch to confirm/conflict page - this.cancel_button.visible = true; - this.stack.visible_child_name = 'confirm'; - - this._check(); - } - - return true; - } - - async _check() { - try { - let available = await check_accelerator(this.accelerator); - this.set_button.visible = available; - this.conflict_label.visible = !available; - } catch (e) { - logError(e); - this.response(ResponseType.CANCEL); - } - } - - _grab() { - let seat = Gdk.Display.get_default().get_default_seat(); - let success = seat.grab( - this.get_window(), - Gdk.SeatCapabilities.KEYBOARD, - true, // owner_events - null, // cursor - null, // event - null - ); - - if (success !== Gdk.GrabStatus.SUCCESS) { - return this.response(ResponseType.CANCEL); - } - - let device = seat.get_keyboard() || seat.get_pointer(); - - if (!device) { - return this.response(ResponseType.CANCEL); - } - - this.grab_add(); - } - - _ungrab() { - this.seat.ungrab(); - this.grab_remove(); - } - - // Override to use our own ungrab process - response(response_id) { - this.hide(); - this._ungrab(); - - return super.response(response_id); - } - - // Override with a non-blocking version of Gtk.Dialog.run() - run() { - this.show(); - - // Wait a bit before attempting grab - GLib.timeout_add(GLib.PRIORITY_DEFAULT, 100, () => { - this._grab(); - return GLib.SOURCE_REMOVE; - }); - } -}); - - -/** - * Check the availability of an accelerator using GNOME Shell's DBus interface. - * - * @param {string} - An accelerator - * @param {number} - Mode Flags - * @param {number} - Grab Flags - * @param {boolean} - %true if available, %false on error or unavailable - */ -async function check_accelerator(accelerator, modeFlags = 0, grabFlags = 0) { - let action; - let result = false; - - try { - // Check whether we're >= gnome-shell 3.32 - let minor = await getShellVersionMinor(); - let params; - - if (minor >= 32) { - params = new GLib.Variant('(suu)', [accelerator, modeFlags, grabFlags]); - } else { - params = new GLib.Variant('(su)', [accelerator, modeFlags]); - } - - // Use gnome-shell's DBus interface to try and grab the accelerator - action = await new Promise((resolve, reject) => { - Gio.DBus.session.call( - 'org.gnome.Shell', - '/org/gnome/Shell', - 'org.gnome.Shell', - 'GrabAccelerator', - params, - null, - Gio.DBusCallFlags.NONE, - -1, - null, - (connection, res) => { - try { - res = connection.call_finish(res); - resolve(res.deep_unpack()[0]); - } catch (e) { - reject(e); - } - } - ); - }); - - // If successful, use the result of ungrabbing as our return - if (action !== 0) { - result = await new Promise((resolve, reject) => { - Gio.DBus.session.call( - 'org.gnome.Shell', - '/org/gnome/Shell', - 'org.gnome.Shell', - 'UngrabAccelerator', - new GLib.Variant('(u)', [action]), - null, - Gio.DBusCallFlags.NONE, - -1, - null, - (connection, res) => { - try { - res = connection.call_finish(res); - resolve(res.deep_unpack()[0]); - } catch (e) { - reject(e); - } - } - ); - }); - } - - return result; - } catch (e) { - debug (e); - return false; - } -} - - -/** - * Show a dialog to get a keyboard shortcut from a user. - * - * @param {string} summary - A description of the keybinding's function - * @param {string} accelerator - An accelerator as taken by Gtk.ShortcutLabel - * @return {string} - An accelerator or %null if it should be unset. - */ -async function get_accelerator(summary, accelerator = null) { - let dialog; - - try { - dialog = new ShortcutChooserDialog({ - summary: summary, - accelerator: accelerator - }); - - accelerator = await new Promise((resolve, reject) => { - dialog.connect('response', (dialog, response) => { - switch (response) { - case ResponseType.SET: - accelerator = dialog.accelerator; - break; - - case ResponseType.UNSET: - accelerator = null; - break; - - case ResponseType.CANCEL: - // leave the accelerator as passed in - break; - } - - dialog.destroy(); - - resolve(accelerator); - }); - - dialog.run(); - }); - - return accelerator; - } catch (e) { - logError(e); - return accelerator; - } -} - diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/ui/messaging.js gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/messaging.js --- gnome-shell-extension-zorin-connect-24.1/src/service/ui/messaging.js 2019-03-05 21:22:16.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/messaging.js 2019-11-30 12:34:48.000000000 +0000 @@ -1,5 +1,6 @@ 'use strict'; +const Gdk = imports.gi.Gdk; const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; const GObject = imports.gi.GObject; @@ -17,9 +18,9 @@ * @return {String} - A timestamp similar to what Android Messages uses */ function getTime(time) { - time = GLib.DateTime.new_from_unix_local(time / 1000); + let date = GLib.DateTime.new_from_unix_local(time / 1000); let now = GLib.DateTime.new_now_local(); - let diff = now.difference(time); + let diff = now.difference(date); switch (true) { // Super recent @@ -30,30 +31,34 @@ // Under an hour case (diff < GLib.TIME_SPAN_HOUR): // TRANSLATORS: Time duration in minutes (eg. 15 minutes) - return ngettext('%d minute', '%d minutes', (diff / GLib.TIME_SPAN_MINUTE)).format(diff / GLib.TIME_SPAN_MINUTE); + return ngettext( + '%d minute', + '%d minutes', + (diff / GLib.TIME_SPAN_MINUTE) + ).format(diff / GLib.TIME_SPAN_MINUTE); // Yesterday, but less than 24 hours ago - case (diff < GLib.TIME_SPAN_DAY && (now.get_day_of_month() !== time.get_day_of_month())): + case (diff < GLib.TIME_SPAN_DAY && (now.get_day_of_month() !== date.get_day_of_month())): // TRANSLATORS: Yesterday, but less than 24 hours (eg. Yesterday · 11:29 PM) - return _('Yesterday・%s').format(time.format('%l:%M %p')); + return _('Yesterday・%s').format(date.format('%l:%M %p')); // Less than a day ago case (diff < GLib.TIME_SPAN_DAY): - return time.format('%l:%M %p'); + return date.format('%l:%M %p'); // Less than a week ago case (diff < (GLib.TIME_SPAN_DAY * 7)): - return time.format('%A・%l:%M %p'); + return date.format('%A・%l:%M %p'); default: - return time.format('%b %e'); + return date.format('%b %e'); } } function getShortTime(time) { - time = GLib.DateTime.new_from_unix_local(time / 1000); - let diff = GLib.DateTime.new_now_local().difference(time); + let date = GLib.DateTime.new_from_unix_local(time / 1000); + let diff = GLib.DateTime.new_now_local().difference(date); switch (true) { case (diff < GLib.TIME_SPAN_MINUTE): @@ -62,31 +67,65 @@ case (diff < GLib.TIME_SPAN_HOUR): // TRANSLATORS: Time duration in minutes (eg. 15 minutes) - return ngettext('%d minute', '%d minutes', (diff / GLib.TIME_SPAN_MINUTE)).format(diff / GLib.TIME_SPAN_MINUTE); + return ngettext( + '%d minute', + '%d minutes', + (diff / GLib.TIME_SPAN_MINUTE) + ).format(diff / GLib.TIME_SPAN_MINUTE); // Less than a day ago case (diff < GLib.TIME_SPAN_DAY): - return time.format('%l:%M %p'); + return date.format('%l:%M %p'); case (diff < (GLib.TIME_SPAN_DAY * 7)): - return time.format('%a'); + return date.format('%a'); default: - return time.format('%b %e'); + return date.format('%b %e'); } } +function getContactsForAddresses(device, addresses) { + let contacts = {}; + + for (let i = 0, len = addresses.length; i < len; i++) { + let address = addresses[i].address; + + contacts[address] = device.contacts.query({ + number: address + }); + } +} + +const setAvatarVisible = function(row, visible) { + let incoming = (row.type === Sms.MessageBox.INBOX); + + // Adjust the margins + if (visible) { + row.grid.margin_start = incoming ? 6 : 56; + row.grid.margin_bottom = 6; + } else { + row.grid.margin_start = incoming ? 44 : 56; + row.grid.margin_bottom = 0; + } + + // Show hide the avatar + if (incoming) { + row.avatar.visible = visible; + } +}; + /** * A simple GtkLabel subclass with a chat bubble appearance */ -var ConversationMessage = GObject.registerClass({ - GTypeName: 'ZorinConnectConversationMessage' -}, class ConversationMessage extends Gtk.Label { +var MessageLabel = GObject.registerClass({ + GTypeName: 'ZorinConnectMessageLabel' +}, class MessageLabel extends Gtk.Label { _init(message) { this.message = message; - let incoming = (message.type === Sms.MessageType.INBOX); + let incoming = (message.type === Sms.MessageBox.INBOX); super._init({ label: message.body.linkify(message.date), @@ -131,22 +170,25 @@ /** * A ListBoxRow for a preview of a conversation */ -const ConversationSummary = GObject.registerClass({ - GTypeName: 'ZorinConnectConversationSummary' -}, class ConversationSummary extends Gtk.ListBoxRow { - _init(contact, message) { +const ThreadRow = GObject.registerClass({ + GTypeName: 'ZorinConnectThreadRow' +}, class ThreadRow extends Gtk.ListBoxRow { + _init(contacts, message) { super._init({visible: true}); // Row layout let grid = new Gtk.Grid({ - margin: 6, - column_spacing: 6, + margin_top: 6, + margin_bottom: 6, + margin_start: 8, + margin_end: 8, + column_spacing: 8, visible: true }); this.add(grid); // Contact Avatar - this._avatar = new Contacts.Avatar(contact); + this._avatar = new Contacts.Avatar(null); grid.attach(this._avatar, 0, 0, 1, 3); // Contact Name @@ -181,11 +223,15 @@ }); grid.attach(this._body, 1, 1, 2, 1); - this.contact = contact; + this.contacts = contacts; this.message = message; } - get id() { + get date() { + return this._message.date; + } + + get thread_id() { return this._message.thread_id; } @@ -195,14 +241,26 @@ set message(message) { this._message = message; + this._sender = message.addresses[0].address; + + // Contact Name + let nameLabel = _('Unknown Contact'); + + // Update avatar for single-recipient messages + if (message.addresses.length === 1) { + this._avatar.contact = this.contacts[this._sender]; + nameLabel = this._avatar.contact.name; + } else { + this._avatar.contact = null; + nameLabel = _('Group Message'); + } // Contact Name & Message body - let nameLabel = this.contact.name; let bodyLabel = message.body.split(/\r|\n/)[0]; bodyLabel = GLib.markup_escape_text(bodyLabel, -1); // Ignore the 'read' flag if it's an outgoing message - if (message.type === Sms.MessageType.SENT) { + if (message.type === Sms.MessageBox.SENT) { // TRANSLATORS: An outgoing message body in a conversation summary bodyLabel = _('You: %s').format(bodyLabel); @@ -238,12 +296,12 @@ GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, GObject.Object ), - 'address': GObject.ParamSpec.string( - 'address', - 'Address', - 'The target phone number or other address', + 'plugin': GObject.ParamSpec.object( + 'plugin', + 'Plugin', + 'The plugin providing this conversation', GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, - '' + GObject.Object ), 'has-pending': GObject.ParamSpec.boolean( 'has-pending', @@ -251,22 +309,33 @@ 'Whether there are sent messages pending confirmation', GObject.ParamFlags.READABLE, false + ), + 'thread-id': GObject.ParamSpec.string( + 'thread-id', + 'Thread ID', + 'The current thread', + GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, + '' ) }, - Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/conversation.ui', + Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/ui/conversation.ui', Children: [ - 'message-entry', 'message-list', 'message-window', + 'entry', 'list', 'scrolled', 'pending', 'pending-box' ] }, class ConversationWidget extends Gtk.Grid { _init(params) { - this.connect_template(); - super._init(params); + this.connectTemplate(); + super._init({ + device: params.device, + plugin: params.plugin + }); + Object.assign(this, params); this.device.bind_property( 'connected', - this.message_entry, + this.entry, 'sensitive', GObject.BindingFlags.SYNC_CREATE ); @@ -278,61 +347,91 @@ this._onConnected.bind(this) ); - // Cleanup on ::destroy - this.connect('destroy', this._onDestroy); - // Pending messages - this.pending.id = GLib.MAXUINT32; + this.pending.date = Number.MAX_SAFE_INTEGER; this.bind_property( 'has-pending', this.pending, 'visible', - GObject.BindingFlags.DEFAULT + GObject.BindingFlags.DEFAULT | GObject.BindingFlags.SYNC_CREATE ); - this._notifications = []; - // Message List - this.message_list.set_header_func(this._headerMessages); - this.message_list.set_sort_func(this._sortMessages); + this.list.set_header_func(this._headerMessages); + this.list.set_sort_func(this._sortMessages); this._populateMessages(); // HACK: This property was added in gtk-3.24; if it's not present this // will just become a useless JS variable instead of choking - this.message_entry.enable_emoji_completion = true; + this.entry.enable_emoji_completion = true; + + // Cleanup on ::destroy + this.connect('destroy', this._onDestroy); } - get address() { - if (this._address === undefined) { - this._address = null; + get addresses() { + if (this._addresses === undefined) { + this._addresses = []; } - return this._address; + return this._addresses; } - set address(value) { - this._address = value; + set addresses(addresses) { + if (!addresses || addresses.length === 0) { + this._addresses = []; + this._contacts = {}; + return; + } + + this._addresses = addresses; + + // Lookup a contact for each address object + for (let i = 0, len = this.addresses.length; i < len; i++) { + let address = this.addresses[i].address; + + this.contacts[address] = this.device.contacts.query({ + number: address + }); + } } - get contact() { - // Ensure we have a contact and hold a reference to it - if (!this._contact) { - this._contact = this.device.contacts.query({number: this.address}); + get contacts() { + if (this._contacts === undefined) { + this._contacts = {}; } - return this._contact; + return this._contacts; } get has_pending() { return (this.pending_box.get_children().length); } - get sms() { - if (this._sms === undefined) { - this._sms = this.device.lookup_plugin('sms'); + get plugin() { + return this._plugin || null; + } + + set plugin(plugin) { + this._plugin = plugin; + } + + get thread_id() { + if (this._thread_id === undefined) { + this._thread_id = null; } - return this._sms; + return this._thread_id; + } + + set thread_id(thread_id) { + let thread = this.plugin.threads[thread_id]; + let message = (thread) ? thread[0] : null; + + if (message && this.addresses.length === 0) { + this.addresses = message.addresses; + this._thread_id = thread_id; + } } _onConnected(device) { @@ -342,90 +441,100 @@ } _onDestroy(conversation) { + conversation.disconnectTemplate(); + conversation.device.disconnect(conversation._connectedId); - conversation.disconnect_template(); - conversation.message_list.foreach(message => { + conversation.list.foreach(message => { // HACK: temporary mitigator for mysterious GtkListBox leak message.run_dispose(); imports.system.gc(); }); } + _onKeyPressEvent(entry, event) { + let keyval = event.get_keyval()[1]; + let state = event.get_state()[1]; + let mask = state & Gtk.accelerator_get_default_mod_mask(); + + if (keyval === Gdk.KEY_Return && (mask & Gdk.ModifierType.SHIFT_MASK)) { + entry.emit('insert-at-cursor', '\n'); + return true; + } + + return false; + } + /** * Messages */ - _populateMessages() { - this.__first = null; - this.__last = null; - this.__pos = 0; - this.__messages = []; + _createMessageRow(message) { + let incoming = (message.type === Sms.MessageBox.INBOX); + + let row = new Gtk.ListBoxRow({ + activatable: false, + selectable: false, + hexpand: true, + visible: true + }); + + // Sort properties + row.date = message.date; + row.type = message.type; + row.sender = message.addresses[0].address; - // Try and find a conversation for this number - let number = this.address.toPhoneNumber(); - let thread_id = null; + row.grid = new Gtk.Grid({ + can_focus: false, + hexpand: true, + margin_top: 6, + margin_bottom: 6, + margin_start: 6, + margin_end: incoming ? 18 : 6, + //margin: 6, + column_spacing: 6, + halign: incoming ? Gtk.Align.START : Gtk.Align.END + }); + row.add(row.grid); - for (let thread of Object.values(this.sms.conversations)) { - let tnumber = thread[0].address.toPhoneNumber(); + // Add avatar for incoming messages + if (incoming) { + let address = message.addresses[0].address; - if (number.endsWith(tnumber) || tnumber.endsWith(number)) { - thread_id = thread[0].thread_id; - break; + // Ensure we have a contact + if (!this.contacts[address]) { + this.contacts[address] = this.device.contacts.query({ + number: address + }); } - } - if (this.sms.conversations[thread_id]) { - this.__messages = this.sms.conversations[thread_id].slice(0); - this._populateBack(); + row.avatar = new Contacts.Avatar(this.contacts[address]); + row.avatar.valign = Gtk.Align.END; + row.grid.attach(row.avatar, 0, 0, 1, 1); } - } - /** - * Populate messages in reverse, in chunks of series - */ - _populateBack() { - // Keep track of direction and date - let date, direction; - - while (this.__messages.length > 0) { - let message = this.__messages[this.__messages.length - 1]; - - // TODO: Unsupported MessageType - if (message.type !== 1 && message.type !== 2) { - this.__messages.pop(); - continue; - } + let widget = new MessageLabel(message); + row.grid.attach(widget, 1, 0, 1, 1); - date = date || message.date; - direction = direction || message.type; + row.show_all(); - // Break if we're definitely at the end of series - if (message.type !== direction) break; + return row; + } - // Start a new series if this is the first - if (!this.__first) { - this.__first = this._createSeries(message); - this.__last = this.__first; - this.message_list.prepend(this.__first); - - // ...or there's more than an hour difference - } else if (date - message.date > GLib.TIME_SPAN_HOUR / 1000) { - this.__first = this._createSeries(message); - this.message_list.prepend(this.__first); - - // ...or it's in a different direction - } else if (message.type !== this.__first.type) { - this.__first = this._createSeries(message); - this.message_list.prepend(this.__first); - } + _populateMessages() { + this.__first = null; + this.__last = null; + this.__pos = 0; + this.__messages = []; - // Create a message, set the message id and prepend it - let widget = new ConversationMessage(this.__messages.pop()); - this.__first.id = message._id; - this.__first.messages.pack_end(widget, false, false, 0); + // Try and find a thread_id for this number + if (this.thread_id === null && this.addresses.length) { + this._thread_id = this.plugin.getThreadIdForAddresses(this.addresses); + } - // update the date tracker - date = message.date; + // Make a copy of the thread and fill the window with messages + if (this.plugin.threads[this.thread_id]) { + this.__messages = this.plugin.threads[this.thread_id].slice(0); + this.logPrevious(); } } @@ -433,47 +542,50 @@ // Skip pending if (row.get_name() === 'pending') return; - // Check if the last series was more than an hour ago - if (before && (row.date - before.date) > GLib.TIME_SPAN_HOUR / 1000) { - let header = new Gtk.Label({ - label: getTime(row.date), - visible: true - }); - header.get_style_context().add_class('dim-label'); - row.set_header(header); + if (before === null) { + setAvatarVisible(row, true); + return; } - } - _sortMessages(row1, row2) { - if (row1.id > row2.id) { - return 1; - } + // Add date header if the last message was more than an hour ago + let header = row.get_header(); - return -1; - } + if ((row.date - before.date) > GLib.TIME_SPAN_HOUR / 1000) { + if (!header) { + header = new Gtk.Label({visible: true}); + header.get_style_context().add_class('dim-label'); + row.set_header(header); + } - // message-entry::focus-in-event - // FIXME: this is not working well - _onMessageAcknowledged() { - if (this.message_entry.has_focus) { - let notification = this.device.lookup_plugin('notification'); + header.label = getTime(row.date); - if (notification) { - while (this._notifications.length > 0) { - notification.closeNotification(this._notifications.pop()); - } - } + // Also show the avatar + setAvatarVisible(row, true); + + // Or if the previous sender was the same, hide its avatar + } else if (row.type === before.type && + row.sender.equalsPhoneNumber(before.sender)) { + setAvatarVisible(before, false); + setAvatarVisible(row, true); + + // otherwise show the avatar + } else { + setAvatarVisible(row, true); } } - // message-list::size-allocate + _sortMessages(row1, row2) { + return (row1.date > row2.date) ? 1 : -1; + } + + // GtkListBox::size-allocate _onMessageLogged(listbox, allocation) { - let vadj = this.message_window.vadjustment; + let vadj = this.scrolled.vadjustment; // Try loading more messages if there's room if (vadj.get_upper() <= vadj.get_page_size()) { - this._populateBack(); - this.message_window.get_child().check_resize(); + this.logPrevious(); + this.scrolled.get_child().check_resize(); // We've been asked to hold the position } else if (this.__pos) { @@ -484,111 +596,64 @@ } else { vadj.set_value(vadj.get_upper() - vadj.get_page_size()); } - - this._onMessageAcknowledged(); } - // message-window::edge-reached + // GtkScrolledWindow::edge-reached _onMessageRequested(scrolled_window, pos) { if (pos === Gtk.PositionType.TOP) { - this.__pos = this.message_window.vadjustment.get_upper(); - this._populateBack(); + this.__pos = this.scrolled.vadjustment.get_upper(); + this.logPrevious(); } } /** - * Add a new row representing a series of sequential messages from one - * contact with a single instance of their avatar. + * Log the next message in the conversation. * - * @param {object} message - The message object to create a series for + * @param {Object} message - A sms message object */ - _createSeries(message) { - let incoming = (message.type === Sms.MessageType.INBOX); - - let row = new Gtk.ListBoxRow({ - activatable: false, - selectable: false, - hexpand: true - }); - row.date = message.date; - row.id = message._id; - row.type = message.type; - - let layout = new Gtk.Box({ - can_focus: false, - hexpand: true, - margin: 6, - spacing: 6, - halign: incoming ? Gtk.Align.START : Gtk.Align.END - }); - row.add(layout); - - // Add avatar for incoming messages - if (incoming) { - let avatar = new Contacts.Avatar(this.contact); - avatar.valign = Gtk.Align.END; - layout.add(avatar); + logNext(message) { + try { + // TODO: Unsupported MessageBox + if (message.type !== Sms.MessageBox.INBOX && + message.type !== Sms.MessageBox.SENT) + return; + + // Append the message + let row = this._createMessageRow(message); + this.list.add(row); + this.list.invalidate_headers(); + + // Remove the first pending message + if (this.has_pending && message.type === Sms.MessageBox.SENT) { + this.pending_box.get_children()[0].destroy(); + this.notify('has-pending'); + } + } catch (e) { + debug(e); } - - // Messages - row.messages = new Gtk.Box({ - orientation: Gtk.Orientation.VERTICAL, - spacing: 3, - halign: layout.halign, - // Avatar width (32px) + layout spacing (6px) + 6px - margin_end: incoming ? 44 : 0, - margin_start: incoming ? 0 : 44 - }); - layout.add(row.messages); - - row.show_all(); - - return row; } /** - * Log a new message in the conversation - * - * @param {Object} message - A sms message object + * Log the previous message in the thread */ - logMessage(message) { - // TODO: Unsupported MessageType - if (message.type !== 1 && message.type !== 2) return; - - // Ensure it's older than the last message (or the first) - // TODO: with a lot of work we could probably handle this... - if (this.__last && this.__last.id > message._id) { - warning('SMS message out of order', this.device.name); - return; - } + logPrevious() { + try { + let message = this.__messages.pop(); - // Start a new series if this is the first - if (!this.__first) { - this.__first = this._createSeries(message); - this.__last = this.__first; - this.message_list.add(this.__first); - - // ...or there's more than an hour difference - } else if (message.date - this.__last.date > GLib.TIME_SPAN_HOUR / 1000) { - this.__last = this._createSeries(message); - this.message_list.add(this.__last); - - // ...or it's in a different direction - } else if (message.type !== this.__last.type) { - this.__last = this._createSeries(message); - this.message_list.add(this.__last); - } - - // Create a message, set the message id/date and append it - let widget = new ConversationMessage(message); - this.__last.id = message._id; - this.__last.date = message.date; - this.__last.messages.pack_start(widget, false, false, 0); - - // Remove the first pending message - if (this.has_pending && message.type === Sms.MessageType.SENT) { - this.pending_box.get_children()[0].destroy(); - this.notify('has-pending'); + if (!message) return; + + // TODO: Unsupported MessageBox + if (message.type !== Sms.MessageBox.INBOX && + message.type !== Sms.MessageBox.SENT) { + return; + } + + // Prepend the message + let row = this._createMessageRow(message); + this.list.prepend(row); + this.list.invalidate_headers(); + } catch (e) { + debug(e); } } @@ -604,26 +669,29 @@ * Send the contents of the message entry to the address */ sendMessage(entry, signal_id, event) { + // TODO: removed when multi-target messages are supported + if (this.addresses.length > 1) { + this.entry.get_style_context().add_class('error'); + return; + } + // Don't send empty texts - if (!this.message_entry.text.trim()) return; + if (!this.entry.text.trim()) return; // Send the message - this.device.activate_action( - 'sendSms', - new GLib.Variant('(ss)', [this.address, entry.text]) - ); + this.plugin.sendMessage(this.addresses, entry.text); // Log the message as pending - let message = new ConversationMessage({ + let message = new MessageLabel({ body: entry.text, date: Date.now(), - type: Sms.MessageType.SENT + type: Sms.MessageBox.SENT }); this.pending_box.add(message); this.notify('has-pending'); // Clear the entry - this.message_entry.text = ''; + this.entry.text = ''; } /** @@ -632,8 +700,8 @@ * @param {String} text - The message to place in the entry */ setMessage(text) { - this.message_entry.text = text; - this.message_entry.emit('move-cursor', 0, text.length, false); + this.entry.text = text; + this.entry.emit('move-cursor', 0, text.length, false); } }); @@ -644,38 +712,40 @@ var Window = GObject.registerClass({ GTypeName: 'ZorinConnectMessagingWindow', Properties: { - 'address': GObject.ParamSpec.string( - 'address', - 'Address', - 'The phone number of the active conversation', - GObject.ParamFlags.READWRITE, - '' - ), 'device': GObject.ParamSpec.object( 'device', 'Device', 'The device associated with this window', GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, GObject.Object + ), + 'plugin': GObject.ParamSpec.object( + 'plugin', + 'Plugin', + 'The plugin providing messages', + GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, + GObject.Object + ), + 'thread-id': GObject.ParamSpec.string( + 'thread-id', + 'Thread ID', + 'The current thread', + GObject.ParamFlags.READWRITE, + '' ) }, - Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/messaging.ui', + Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/ui/messaging-window.ui', Children: [ 'headerbar', 'infobar', - 'conversation-list', 'conversation-list-placeholder', 'conversation-stack' + 'thread-list', 'stack' ] }, class Window extends Gtk.ApplicationWindow { _init(params) { - this.connect_template(); + this.connectTemplate(); super._init(params); this.headerbar.subtitle = this.device.name; - this.settings = new Gio.Settings({ - settings_schema: zorin_connect.gschema.lookup('org.gnome.Shell.Extensions.ZorinConnect.Messaging', true), - path: '/org/gnome/shell/extensions/zorin-connect/messaging/' - }); - this.insert_action_group('device', this.device); // Device Status @@ -686,195 +756,220 @@ GObject.BindingFlags.INVERT_BOOLEAN ); - this.restore_geometry(); - // Contacts - this.contact_list = new Contacts.ContactChooser({ - device: this.device, - store: this.device.contacts + this.contact_chooser = new Contacts.ContactChooser({ + device: this.device }); - this.conversation_stack.add_named(this.contact_list, 'contact-list'); + this.stack.add_named(this.contact_chooser, 'contact-chooser'); - this._numberSelectedId = this.contact_list.connect( + this._numberSelectedId = this.contact_chooser.connect( 'number-selected', this._onNumberSelected.bind(this) ); - // Conversations - this.conversation_list.set_sort_func(this._sortConversations); + // Threads + this.thread_list.set_sort_func(this._sortThreads); - this._conversationsChangedId = this.sms.connect( - 'notify::conversations', - this._onConversationsChanged.bind(this) + this._threadsChangedId = this.plugin.connect( + 'notify::threads', + this._onThreadsChanged.bind(this) ); - this._timestampConversationsId = GLib.timeout_add_seconds( + this._timestampThreadsId = GLib.timeout_add_seconds( GLib.PRIORITY_DEFAULT_IDLE, 60, - this._timestampConversations.bind(this) + this._timestampThreads.bind(this) ); - // Conversations Placeholder - this.conversation_list.set_placeholder(this.conversation_list_placeholder); - // Cleanup on ::destroy this.connect('destroy', this._onDestroy); this._sync(); - this._onConversationsChanged(); + this._onThreadsChanged(); + this.restoreGeometry('messaging'); } vfunc_delete_event(event) { - this.save_geometry(); + this.saveGeometry(); return this.hide_on_delete(); } - get address() { - return this.conversation_stack.visible_child_name; + get plugin() { + return this._plugin || null; } - set address(address) { - if (!address) { - this.conversation_list.select_row(null); - this.conversation_stack.set_visible_child_name('placeholder'); - return; - } + set plugin(plugin) { + this._plugin = plugin; + } - // Get a contact object for this address - let contact = this.device.contacts.query({number: address}); + get thread_id() { + return this.stack.visible_child_name; + } - // Set the header bar title/subtitle - this.headerbar.title = contact.name; - this.headerbar.subtitle = address; - - // See if we have a nicer display number - let number = address.toPhoneNumber(); - - for (let contactNumber of contact.numbers) { - let cnumber = contactNumber.value.toPhoneNumber(); - - if (number.endsWith(cnumber) || cnumber.endsWith(number)) { - this.headerbar.subtitle = contactNumber.value; - break; - } + set thread_id(thread_id) { + thread_id = `${thread_id}`; // FIXME + + // Reset to the empty placeholder + if (!thread_id) { + this.thread_list.select_row(null); + this.stack.set_visible_child_name('placeholder'); + return; } // Create a conversation widget if there isn't one - let conversation = this.getConversation(address); + let conversation = this.stack.get_child_by_name(thread_id); + let thread = this.plugin.threads[thread_id]; if (conversation === null) { + if (!thread) { + debug(`Thread ID ${thread_id} not found`); + return; + } + conversation = new ConversationWidget({ device: this.device, - address: address + plugin: this.plugin, + thread_id: thread_id }); - this.conversation_stack.add_named(conversation, address); + this.stack.add_named(conversation, thread_id); } + // Figure out whether this is a multi-recipient thread + this._setHeaderBar(thread[0].addresses); + // Select the conversation and entry active - this.conversation_stack.visible_child = conversation; - this.conversation_stack.visible_child.message_entry.has_focus = true; + this.stack.visible_child = conversation; + this.stack.visible_child.entry.has_focus = true; - // There was a pending message waiting for a contact to be chosen + // There was a pending message waiting for a conversation to be chosen if (this._pendingShare) { conversation.setMessage(this._pendingShare); this._pendingShare = null; } - } - - get sms() { - if (!this._sms) { - this._sms = this.device.lookup_plugin('sms'); - } - return this._sms; + this._thread_id = thread_id; + this.notify('thread_id'); } - _sync() { - // Contacts - let contacts = this.device.lookup_plugin('contacts'); + _setHeaderBar(addresses = []) { + let address = addresses[0].address; + let contact = this.device.contacts.query({number: address}); + + if (addresses.length === 1) { + // Set the header bar title/subtitle + this.headerbar.title = contact.name; + this.headerbar.subtitle = Contacts.getDisplayNumber(contact, address); - if (contacts) { - contacts.connected(); } else { - this.device.contacts._loadFolks(); + let otherLength = addresses.length - 1; + + this.headerbar.title = contact.name; + this.headerbar.subtitle = ngettext( + 'And %d other contact', + 'And %d others', + otherLength + ).format(otherLength); } + } - // SMS history - this.sms.connected(); + _sync() { + this.device.contacts.fetch(); + this.plugin.connected(); } _onDestroy(window) { - GLib.source_remove(window._timestampConversationsId); - window.contact_list.disconnect(window._numberSelectedId); - window.sms.disconnect(window._conversationsChangedId); - window.disconnect_template(); + window.disconnectTemplate(); + GLib.source_remove(window._timestampThreadsId); + window.contact_chooser.disconnect(window._numberSelectedId); + window.plugin.disconnect(window._threadsChangedId); } _onNewConversation() { this._sync(); - this.conversation_stack.set_visible_child_name('contact-list'); - this.conversation_list.select_row(null); - this.contact_list.contact_entry.has_focus = true; + this.stack.set_visible_child_name('contact-chooser'); + this.thread_list.select_row(null); + this.contact_chooser.entry.has_focus = true; } - _onNumberSelected(list, number) { - let summary = this.getSummary(number); - this.conversation_list.select_row(summary); - this.address = number; + _onNumberSelected(chooser, number) { + let contacts = chooser.getSelected(); + let row = this._getRowForContacts(contacts); + + if (row) { + this.thread_list.select_row(row); + } else { + this.setContacts(contacts); + } } /** - * Conversations + * Threads */ - _onConversationsChanged() { - let messages = new Map(); + _onThreadsChanged() { + // Get the last message in each thread + let messages = {}; - for (let thread of Object.values(this.sms.conversations)) { + for (let [thread_id, thread] of Object.entries(this.plugin.threads)) { let message = thread[thread.length - 1]; - messages.set(message.thread_id, message); + + // Skip messages without a body (eg. MMS messages without text) + if (message.body) { + messages[thread_id] = thread[thread.length - 1]; + } } // Update existing summaries and destroy old ones - for (let summary of this.conversation_list.get_children()) { - let message = messages.get(summary.id); + for (let row of this.thread_list.get_children()) { + let message = messages[row.thread_id]; // If it's an existing conversation, update it if (message) { - summary.message = message; - messages.delete(summary.id); + // Ensure there's a contact mapping + let sender = message.addresses[0].address; + + if (!row.contacts[sender]) { + row.contacts[sender] = this.device.contacts.query({ + number: sender + }); + } + + row.message = message; + delete messages[row.thread_id]; // Otherwise destroy it } else { - // HACK: temporary mitigator for mysterious GtkListBox leak - summary.run_dispose(); - imports.system.gc(); - - // Also delete the conversation - let conversation = this.getConversation(summary.message.address); + // Destroy the conversation widget + let conversation = this.stack.get_child_by_name(`${row.thread_id}`); if (conversation) { - conversation.run_dispose(); + conversation.destroy(); imports.system.gc(); } + + // Then the summary widget + row.destroy(); + // HACK: temporary mitigator for mysterious GtkListBox leak + imports.system.gc(); } } - // Add new summaries - for (let message of messages.values()) { - let contact = this.device.contacts.query({number: message.address}); - let conversation = new ConversationSummary(contact, message); - this.conversation_list.add(conversation); + // What's left in the dictionary is new summaries + for (let message of Object.values(messages)) { + let contacts = this.device.contacts.lookupAddresses(message.addresses); + let conversation = new ThreadRow(contacts, message); + this.thread_list.add(conversation); } // Re-sort the summaries - this.conversation_list.invalidate_sort(); + this.thread_list.invalidate_sort(); } - _onConversationSelected(box, row) { + // GtkListBox::row-selected + _onThreadSelected(box, row) { // Show the conversation for this number (if applicable) if (row) { - this.address = row.message.address; + this.thread_id = row.thread_id; // Show the placeholder } else { @@ -883,55 +978,141 @@ } } - _sortConversations(row1, row2) { - return (row1.message.date > row2.message.date) ? -1 : 1; + _sortThreads(row1, row2) { + return (row1.date > row2.date) ? -1 : 1; } - _timestampConversations() { + _timestampThreads() { if (this.visible) { - this.conversation_list.foreach(summary => summary.update()); + this.thread_list.foreach(row => row.update()); } return GLib.SOURCE_CONTINUE; } /** - * Find the conversation widget for an address + * Find the thread row for @contacts * - * @param {string} address - A contact address - * @return {ConversationWidget|null} - The conversation widget or %null + * @param {Array of Object} contacts - A contact group + * @return {ThreadRow|null} - The thread row or %null */ - getConversation(address) { - let number = address.toPhoneNumber(); + _getRowForContacts(contacts) { + let addresses = Object.keys(contacts).map(address => { + return {address: address}; + }); - for (let conversation of this.conversation_stack.get_children()) { - // Skip contact list - if (!conversation.address) continue; + // Try to find a thread_id + let thread_id = this.plugin.getThreadIdForAddresses(addresses); - let cnumber = conversation.address.toPhoneNumber(); + for (let row of this.thread_list.get_children()) { + if (row.message.thread_id === thread_id) + return row; + } - if (cnumber.endsWith(number) || number.endsWith(cnumber)) { - return conversation; + return null; + } + + setContacts(contacts) { + // Group the addresses + let addresses = []; + + for (let address of Object.keys(contacts)) { + addresses.push({address: address}); + } + + // Try to find a thread ID for this address group + let thread_id = this.plugin.getThreadIdForAddresses(addresses); + + if (thread_id === null) { + thread_id = GLib.uuid_string_random(); + } else { + thread_id = thread_id.toString(); + } + + // Try to find a thread row for the ID + let row = this._getRowForContacts(contacts); + + if (row !== null) { + this.thread_list.select_row(row); + return; + } + + // We're creating a new conversation + let conversation = new ConversationWidget({ + device: this.device, + plugin: this.plugin, + addresses: addresses + }); + + // Set the headerbar + this._setHeaderBar(addresses); + + // Select the conversation and entry active + this.stack.add_named(conversation, thread_id); + this.stack.visible_child = conversation; + this.stack.visible_child.entry.has_focus = true; + + // There was a pending message waiting for a conversation to be chosen + if (this._pendingShare) { + conversation.setMessage(this._pendingShare); + this._pendingShare = null; + } + + this._thread_id = thread_id; + this.notify('thread-id'); + } + + _includesAddress(addresses, addressObj) { + let number = addressObj.address.toPhoneNumber(); + + for (let haystackObj of addresses) { + let tnumber = haystackObj.address.toPhoneNumber(); + + if (number.endsWith(tnumber) || tnumber.endsWith(number)) { + return true; } } - return null; + return false; } /** - * Find the conversation summary row for an address + * Try and find an existing conversation widget for @message. * - * @param {string} address - A contact address - * @return {ConversationSummary|null} - The conversation summary or %null + * @param {object} message - A message object + * @return {ConversationWidget|null} - A conversation widget or %null */ - getSummary(address) { - let number = address.toPhoneNumber(); + getConversationForMessage(message) { + // This shouldn't happen + if (message === null) return null; - for (let summary of this.conversation_list.get_children()) { - let cnumber = summary.message.address.toPhoneNumber(); + // First try to find a conversation by thread_id + let thread_id = `${message.thread_id}`; + let conversation = this.stack.get_child_by_name(thread_id); - if (cnumber.endsWith(number) || number.endsWith(cnumber)) { - return summary; + if (conversation !== null) { + return conversation; + } + + // Try and find one by matching addresses, which is necessary if we've + // started a thread locally and haven't set the thread_id + let addresses = message.addresses; + + for (let conversation of this.stack.get_children()) { + if (conversation.addresses === undefined || + conversation.addresses.length !== addresses.length) { + continue; + } + + let caddrs = conversation.addresses; + + // If we find a match, set `thread-id` on the conversation and the + // child property `name`. + if (addresses.every(addr => this._includesAddress(caddrs, addr))) { + conversation._thread_id = thread_id; + this.stack.child_set_property(conversation, 'name', thread_id); + + return conversation; } } @@ -943,7 +1124,7 @@ * message of the currently selected conversation, otherwise mark the * message to be set for the next selected conversation. * - * @param {String} text - The message to place in the entry + * @param {string} text - The message to place in the entry * @param {boolean} pending - Wait for a conversation to be selected */ setMessage(message, pending = false) { @@ -951,10 +1132,10 @@ if (pending) { this._pendingShare = message; } else { - this.conversation_stack.visible_child.setMessage(message); + this.stack.visible_child.setMessage(message); } } catch (e) { - warning(e); + debug(e); } } }); @@ -979,6 +1160,13 @@ 'The message to share', GObject.ParamFlags.READWRITE, '' + ), + 'plugin': GObject.ParamSpec.object( + 'plugin', + 'Plugin', + 'The plugin providing messages', + GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, + GObject.Object ) } }, class ConversationChooser extends Gtk.ApplicationWindow { @@ -992,13 +1180,13 @@ this.set_keep_above(true); // HeaderBar - let headerbar = new Gtk.HeaderBar({ + this.headerbar = new Gtk.HeaderBar({ title: _('Share Link'), subtitle: this.message, show_close_button: true, tooltip_text: this.message }); - this.set_titlebar(headerbar); + this.set_titlebar(this.headerbar); let newButton = new Gtk.Button({ image: new Gtk.Image({icon_name: 'list-add-symbolic'}), @@ -1006,9 +1194,9 @@ always_show_image: true }); newButton.connect('clicked', this._new.bind(this)); - headerbar.pack_start(newButton); + this.headerbar.pack_start(newButton); - // Conversations + // Threads let scrolledWindow = new Gtk.ScrolledWindow({ can_focus: false, hexpand: true, @@ -1017,39 +1205,39 @@ }); this.add(scrolledWindow); - this.conversation_list = new Gtk.ListBox({ + this.thread_list = new Gtk.ListBox({ activate_on_single_click: false }); - this.conversation_list.set_sort_func(Window.prototype._sortConversations); - this.conversation_list.connect('row-activated', this._select.bind(this)); - scrolledWindow.add(this.conversation_list); + this.thread_list.set_sort_func(Window.prototype._sortThreads); + this.thread_list.connect('row-activated', this._select.bind(this)); + scrolledWindow.add(this.thread_list); // Filter Setup - Window.prototype._populateConversations.call(this); + Window.prototype._onThreadsChanged.call(this); this.show_all(); } - get sms() { - if (this._sms === undefined) { - this._sms = this.device.lookup_plugin('sms'); - } + get plugin() { + return this._plugin || null; + } - return this._sms; + set plugin(plugin) { + this._plugin = plugin; } _new(button) { let message = this.message; this.destroy(); - this.sms.sms(); - this.sms.window.address = null; - this.sms.window._pendingShare = message; + this.plugin.sms(); + this.plugin.window._onNewConversation(); + this.plugin.window._pendingShare = message; } _select(box, row) { - this.sms.sms(); - this.sms.window.address = row.message.address; - this.sms.window.setMessage(this.message); + this.plugin.sms(); + this.plugin.window.thread_id = row.message.thread_id.toString(); + this.plugin.window.setMessage(this.message); this.destroy(); } diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/ui/notification.js gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/notification.js --- gnome-shell-extension-zorin-connect-24.1/src/service/ui/notification.js 2019-03-04 02:01:36.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/notification.js 2019-11-30 12:35:02.000000000 +0000 @@ -5,7 +5,7 @@ const Gtk = imports.gi.Gtk; -var Dialog = GObject.registerClass({ +var ReplyDialog = GObject.registerClass({ GTypeName: 'ZorinConnectNotificationReplyDialog', Properties: { 'device': GObject.ParamSpec.object( @@ -14,21 +14,25 @@ 'The device associated with this window', GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, GObject.Object + ), + 'plugin': GObject.ParamSpec.object( + 'plugin', + 'Plugin', + 'The plugin that owns this notification', + GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, + GObject.Object ) }, - Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/notification.ui', - Children: [ - 'infobar', - 'notification-title', 'notification-body', - 'message-entry' - ] + Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/ui/notification-reply-dialog.ui', + Children: ['infobar', 'notification-title', 'notification-body', 'entry'] }, class Dialog extends Gtk.Dialog { _init(params) { - this.connect_template(); + this.connectTemplate(); super._init({ application: Gio.Application.get_default(), device: params.device, + plugin: params.plugin, use_header_bar: true }); @@ -55,7 +59,7 @@ // Message Entry/Send Button this.device.bind_property( 'connected', - this.message_entry, + this.entry, 'sensitive', GObject.BindingFlags.DEFAULT ); @@ -65,23 +69,36 @@ this._onStateChanged.bind(this) ); - this._entryChangedId = this.message_entry.buffer.connect( + this._entryChangedId = this.entry.buffer.connect( 'changed', this._onStateChanged.bind(this) ); - // Cleanup on ::destroy + this.restoreGeometry('notification-reply-dialog'); + this.connect('destroy', this._onDestroy); } + _onDestroy(dialog) { + dialog.entry.buffer.disconnect(dialog._entryChangedId); + dialog.device.disconnect(dialog._connectedId); + } + + vfunc_delete_event() { + this.disconnectTemplate(); + this.saveGeometry(); + + return false; + } + vfunc_response(response_id) { if (response_id === Gtk.ResponseType.OK) { // Refuse to send empty or whitespace only messages - if (!this.message_entry.buffer.text.trim()) return; + if (!this.entry.buffer.text.trim()) return; this.plugin.replyNotification( this.uuid, - this.message_entry.buffer.text + this.entry.buffer.text ); } @@ -98,28 +115,22 @@ this._uuid = uuid; } else { this.destroy(); - warning('no uuid for repliable notification'); + debug('no uuid for repliable notification'); } } get plugin() { - if (!this._plugin) { - this._plugin = this.device.lookup_plugin('notification'); - } - - return this._plugin; + return this._plugin || null; } - _onDestroy(window) { - window.device.disconnect(window._connectedId); - window.message_entry.buffer.disconnect(window._entryChangedId); - window.disconnect_template(); + set plugin(plugin) { + this._plugin = plugin; } _onStateChanged() { switch (false) { case this.device.connected: - case (this.message_entry.buffer.text.trim() !== ''): + case (this.entry.buffer.text.trim().length): break; default: diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/ui/service.js gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/service.js --- gnome-shell-extension-zorin-connect-24.1/src/service/ui/service.js 2019-03-04 02:01:42.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/service.js 2019-11-30 12:35:15.000000000 +0000 @@ -56,6 +56,31 @@ }); scrolledWindow.add(this.list); + // Placeholder + let placeholder = new Gtk.Grid({ + halign: Gtk.Align.CENTER, + valign: Gtk.Align.CENTER, + visible: true + }); + placeholder.get_style_context().add_class('placeholder'); + this.list.set_placeholder(placeholder); + + let placeholderImage = new Gtk.Image({ + icon_name: 'org.gnome.Shell.Extensions.ZorinConnect-symbolic', + pixel_size: 64, + visible: true + }); + placeholderImage.get_style_context().add_class('placeholder-image'); + placeholder.attach(placeholderImage, 0, 0, 1, 1); + + let placeholderLabel = new Gtk.Label({ + label: _('No Device Found'), + margin_top: 12, + visible: true + }); + placeholderLabel.get_style_context().add_class('placeholder-title'); + placeholder.attach(placeholderLabel, 0, 1, 1, 1); + this.list.connect( 'row-activated', this._onDeviceActivated.bind(this) @@ -94,21 +119,18 @@ } _populate() { - let devices = []; - for (let device of this.application._devices.values()) { - if (device.get_action_enabled(this._action)) { - devices.push(device); - } - } + let action = device.lookup_action(this._action); - for (let device of devices) { - let row = new Gtk.ListBoxRow({visible: true}); - this.list.add(row); + let row = new Gtk.ListBoxRow({ + visible: action.enabled + }); + + action.bind_property('enabled', row, 'visible', 0); row.device = device; let grid = new Gtk.Grid({ - column_spacing: 6, + column_spacing: 12, margin: 6, visible: true }); @@ -128,7 +150,10 @@ visible: true }); grid.attach(name, 1, 0, 1, 1); + this.list.add(row); } + + this.list.select_row(this.list.get_row_at_index(0)); } }); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/ui/settings.js gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/settings.js --- gnome-shell-extension-zorin-connect-24.1/src/service/ui/settings.js 2019-03-05 21:23:06.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/settings.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,665 +0,0 @@ -'use strict'; - -const GdkPixbuf = imports.gi.GdkPixbuf; -const Gio = imports.gi.Gio; -const GLib = imports.gi.GLib; -const GObject = imports.gi.GObject; -const Gtk = imports.gi.Gtk; - -const Device = imports.service.ui.device; - - -// Header for support logs -const LOG_HEADER = new GLib.Bytes(` -Zorin Connect Version: ${zorin_connect.metadata.version} -Zorin Connect Install: ${(zorin_connect.is_local) ? 'user' : 'system'} -GJS: ${imports.system.version} -XDG_SESSION_TYPE: ${GLib.getenv('XDG_SESSION_TYPE')} -GDMSESSION: ${GLib.getenv('GDMSESSION')} --------------------------------------------------------------------------------- -`); - - -/** - * Generate a support log - */ -async function generateSupportLog(time) { - try { - let file = Gio.File.new_tmp('zorin-connect.XXXXXX')[0]; - - let logFile = await new Promise((resolve, reject) => { - file.replace_async(null, false, 2, 0, null, (file, res) => { - try { - resolve(file.replace_finish(res)); - } catch (e) { - reject(e); - } - }); - }); - - await new Promise((resolve, reject) => { - logFile.write_bytes_async(LOG_HEADER, 0, null, (file, res) => { - try { - resolve(file.write_bytes_finish(res)); - } catch (e) { - reject(e); - } - }); - }); - - // FIXME: BSD??? - let proc = new Gio.Subprocess({ - flags: Gio.SubprocessFlags.STDOUT_PIPE | Gio.SubprocessFlags.STDERR_MERGE, - argv: ['journalctl', '--no-host', '--since', time] - }); - proc.init(null); - - logFile.splice_async( - proc.get_stdout_pipe(), - Gio.OutputStreamSpliceFlags.CLOSE_TARGET, - GLib.PRIORITY_DEFAULT, - null, - (source, res) => { - try { - source.splice_finish(res); - } catch (e) { - logError(e); - } - } - ); - - await new Promise((resolve, reject) => { - proc.wait_check_async(null, (proc, res) => { - try { - resolve(proc.wait_finish(res)); - } catch (e) { - reject(e); - } - }); - }); - - open_uri(file.get_uri()); - } catch (e) { - logError(e); - } -} - - -/** - * "Connect to..." Dialog - */ -var ConnectDialog = GObject.registerClass({ - GTypeName: 'ZorinConnectConnectDialog', - Properties: { - 'has-devices': GObject.ParamSpec.boolean( - 'has-devices', - 'Has Devices', - 'Whether any KDE Connect enabled bluetooth devices are present', - GObject.ParamFlags.READABLE, - false - ) - }, - Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/connect.ui', - Children: [ - 'cancel-button', 'connect-button', - 'lan-radio', 'lan-grid', 'lan-ip', 'lan-port', - 'bluez-radio', 'bluez-grid', 'bluez-device', 'bluez-devices' - ] -}, class ConnectDialog extends Gtk.Dialog { - - _init(parent = null) { - super._init({ - application: Gio.Application.get_default(), - modal: (parent), - transient_for: parent, - use_header_bar: true - }); - - // Bluez Device ComboBox - let iconCell = new Gtk.CellRendererPixbuf({xpad: 6}); - this.bluez_device.pack_start(iconCell, false); - this.bluez_device.add_attribute(iconCell, 'pixbuf', 0); - - let nameCell = new Gtk.CellRendererText(); - this.bluez_device.pack_start(nameCell, true); - this.bluez_device.add_attribute(nameCell, 'text', 1); - - if (this.application.bluetooth) { - this._devicesId = this.application.bluetooth.connect( - 'notify::devices', - this.populate.bind(this) - ); - this.populate(); - } - - // Connection type selection - this.lan_radio.bind_property( - 'active', - this.lan_grid, - 'sensitive', - GObject.BindingFlags.SYNC_CREATE - ); - - this.bluez_radio.bind_property( - 'active', - this.bluez_grid, - 'sensitive', - GObject.BindingFlags.SYNC_CREATE - ); - - // Hide Bluez and selection if there are no supported bluetooth devices - this.bind_property( - 'has-devices', - this.bluez_radio, - 'visible', - GObject.BindingFlags.SYNC_CREATE - ); - - this.bind_property( - 'has-devices', - this.bluez_grid, - 'visible', - GObject.BindingFlags.SYNC_CREATE - ); - - this.bind_property( - 'has-devices', - this.lan_radio, - 'visible', - GObject.BindingFlags.SYNC_CREATE - ); - } - - vfunc_response(response_id) { - if (response_id === Gtk.ResponseType.OK) { - try { - let address; - - // Bluetooth device selected - if (this.bluez_device.visible && this.bluez_radio.active) { - address = this.bluez_device.active_id; - - // Lan host/port entered - } else if (this.lan_ip.text) { - address = Gio.InetSocketAddress.new_from_string( - this.lan_ip.text, - this.lan_port.value - ); - } else { - return false; - } - - this.application.broadcast(address); - } catch (e) { - logError(e); - } - } - - if (this._devicesId) { - this.application.bluetooth.disconnect(this._devicesId); - } - - this.destroy(); - return false; - } - - get has_devices() { - if (!this.application.bluetooth) { - return false; - } - - return this.application.bluetooth.devices.length > 0; - } - - populate() { - this.bluez_devices.clear(); - let theme = Gtk.IconTheme.get_default(); - - if (this.has_devices) { - for (let device of this.application.bluetooth.devices) { - let pixbuf = theme.load_icon( - device.Icon, - 16, - Gtk.IconLookupFlags.FORCE_SIZE - ); - - this.bluez_devices.set( - this.bluez_devices.append(), - [0, 1, 2], - [pixbuf, `${device.Alias} (${device.Adapter})`, device.g_object_path] - ); - } - - this.bluez_device.active_id = this.application.bluetooth.devices[0].g_object_path; - } - - this.notify('has-devices'); - } -}); - - -/** - * A Device Row - */ -const DeviceRow = GObject.registerClass({ - GTypeName: 'ZorinConnectDeviceRow', - Properties: { - 'connected': GObject.ParamSpec.boolean( - 'connected', - 'deviceConnected', - 'Whether the device is connected', - GObject.ParamFlags.READWRITE, - false - ), - 'paired': GObject.ParamSpec.boolean( - 'paired', - 'devicePaired', - 'Whether the device is paired', - GObject.ParamFlags.READWRITE, - false - ), - 'status': GObject.ParamSpec.string( - 'status', - 'Device Status', - 'The status of the device', - GObject.ParamFlags.READWRITE, - null - ) - } -}, class ZorinConnectDeviceRow extends Gtk.ListBoxRow { - - _init(device) { - super._init({ - height_request: 52, - selectable: false - }); - - this.set_name(device.id); - this.device = device; - - let grid = new Gtk.Grid({ - column_spacing: 12, - margin_left: 20, // 20 - margin_right: 20, - margin_bottom: 8, // 16 - margin_top: 8 - }); - this.add(grid); - - let icon = new Gtk.Image({ - gicon: new Gio.ThemedIcon({name: `${this.device.icon_name}-symbolic`}), - icon_size: Gtk.IconSize.BUTTON - }); - grid.attach(icon, 0, 0, 1, 1); - - let title = new Gtk.Label({ - halign: Gtk.Align.START, - hexpand: true, - valign: Gtk.Align.CENTER, - vexpand: true - }); - device.settings.bind('name', title, 'label', 0); - grid.attach(title, 1, 0, 1, 1); - - let status = new Gtk.Label({ - halign: Gtk.Align.END, - hexpand: true, - valign: Gtk.Align.CENTER, - vexpand: true - }); - this.bind_property('status', status, 'label', 2); - grid.attach(status, 2, 0, 1, 1); - - this.connect('notify::connected', () => this.notify('status')); - device.bind_property('connected', this, 'connected', 2); - this.connect('notify::paired', () => this.notify('status')); - device.bind_property('paired', this, 'paired', 2); - - this.show_all(); - } - - get status() { - if (!this.paired) { - return _('Unpaired'); - } else if (!this.connected) { - return _('Disconnected'); - } - - return _('Connected'); - } -}); - - -var Window = GObject.registerClass({ - GTypeName: 'ZorinConnectSettingsWindow', - Properties: { - 'display-mode': GObject.ParamSpec.string( - 'display-mode', - 'Display Mode', - 'Display devices in either the Panel or User Menu', - GObject.ParamFlags.READWRITE, - null - ) - }, - Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/settings.ui', - Children: [ - // HeaderBar - 'headerbar', 'infobar', 'stack', - 'service-menu', 'service-refresh', 'service-edit', 'service-entry', - 'device-menu', 'prev-button', - - 'service-window', 'service-box', 'info-label', - - // Device List - 'device-list', 'device-list-spinner', 'device-list-placeholder' - ] -}, class SettingsWindow extends Gtk.ApplicationWindow { - - _init(params) { - this.connect_template(); - - super._init({ - application: Gio.Application.get_default(), - title: _('Settings') - }); - - this.settings = new Gio.Settings({ - settings_schema: zorin_connect.gschema.lookup( - 'org.gnome.Shell.Extensions.ZorinConnect.Preferences', - true - ), - path: '/org/gnome/shell/extensions/zorin-connect/preferences/' - }); - - zorin_connect.settings.bind( - 'discoverable', - this.infobar, - 'reveal-child', - Gio.SettingsBindFlags.INVERT_BOOLEAN - ); - - // HeaderBar (Service Name) - this.headerbar.title = zorin_connect.settings.get_string('public-name'); - this.service_entry.text = this.headerbar.title; - - // Scroll with keyboard focus - this.service_box.set_focus_vadjustment(this.service_window.vadjustment); - - // Downloads link; Account for some corner cases with a fallback - let download_dir = GLib.get_user_special_dir( - GLib.UserDirectory.DIRECTORY_DOWNLOAD - ); - - if (!download_dir || download_dir === GLib.get_home_dir()) { - download_dir = GLib.build_filenamev([GLib.get_home_dir(), 'Downloads']); - } - - // TRANSLATORS: Description of where directly shared files are stored. - this.info_label.label = _('Transferred files are placed in the <a href="%s">Downloads</a> folder.').format( - 'file://' + download_dir - ); - - // - let displayMode = new Gio.PropertyAction({ - name: 'display-mode', - property_name: 'display-mode', - object: this - }); - this.add_action(displayMode); - - // About Dialog - let aboutDialog = new Gio.SimpleAction({name: 'about'}); - aboutDialog.connect('activate', this._aboutDialog.bind(this)); - this.add_action(aboutDialog); - - // "Connect to..." Dialog - let connectDialog = new Gio.SimpleAction({name: 'connect'}); - connectDialog.connect('activate', this._connectDialog); - this.add_action(connectDialog); - - // "Generate Support Log" GAction - let generateSupportLog = new Gio.SimpleAction({name: 'support-log'}); - generateSupportLog.connect('activate', this._generateSupportLog); - this.add_action(generateSupportLog); - - // App Menu (in-window only) - this.service_menu.set_menu_model( - this.application.get_menu_by_id('service-menu') - ); - - // Device List - this.device_list.set_header_func((row, before) => { - if (before) row.set_header(new Gtk.Separator({visible: true})); - }); - this.device_list.set_placeholder(this.device_list_placeholder); - - // Setup devices - this._devicesChangedId = zorin_connect.settings.connect( - 'changed::devices', - this._onDevicesChanged.bind(this) - ); - this._onDevicesChanged(); - - // If there are no devices, it's safe to auto-broadcast - this._refresh(); - GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 5, this._refresh.bind(this)); - - // Restore window size/maximized/position - this.restore_geometry(); - } - - get display_mode() { - if (zorin_connect.settings.get_boolean('show-indicators')) { - return 'panel'; - } else { - return 'user-menu'; - } - } - - set display_mode(mode) { - zorin_connect.settings.set_boolean('show-indicators', (mode === 'panel')); - } - - vfunc_delete_event(event) { - this.save_geometry(); - return this.hide_on_delete(); - } - - _refresh() { - if (this.application.devices.length < 1 && this.stack.visible_child_name === 'service') { - this.application.broadcast(); - this.device_list_spinner.active = true; - } else { - this.device_list_spinner.active = false; - } - - return GLib.SOURCE_CONTINUE; - } - - /** - * About Dialog - */ - _aboutDialog() { - if (this._about === undefined) { - this._about = new Gtk.AboutDialog({ - application: Gio.Application.get_default(), - authors: [ - 'Andy Holmes <andrew.g.r.holmes@gmail.com>', - 'Bertrand Lacoste <getzze@gmail.com>', - 'Frank Dana <ferdnyc@gmail.com>' - ], - logo: GdkPixbuf.Pixbuf.new_from_resource_at_scale( - zorin_connect.app_path + '/icons/' + zorin_connect.app_id + '.svg', - 128, - 128, - true - ), - program_name: 'Zorin Connect', - // TRANSLATORS: eg. 'Translator Name <your.email@domain.com>' - translator_credits: _('translator-credits'), - version: `${zorin_connect.metadata.version}`, - license_type: Gtk.License.GPL_2_0, - modal: true, - transient_for: this - }); - - // Persist - this._about.connect('response', (dialog) => dialog.hide_on_delete()); - this._about.connect('delete-event', (dialog) => dialog.hide_on_delete()); - } - - this._about.present(); - } - - /** - * Connect to..." Dialog - */ - _connectDialog() { - new ConnectDialog(Gio.Application.get_default()._window); - } - - /** - * "Generate Support Log" GAction - */ - _generateSupportLog() { - let dialog = new Gtk.MessageDialog({ - text: _('Generate Support Log'), - secondary_text: _('Debug messages are being logged. Take any steps necessary to reproduce a problem then review the log.') - }); - dialog.add_button(_('Cancel'), Gtk.ResponseType.CANCEL); - dialog.add_button(_('Review Log'), Gtk.ResponseType.OK); - - // Enable debug logging and mark the current time - zorin_connect.settings.set_boolean('debug', true); - let now = GLib.DateTime.new_now_local().format('%R'); - - dialog.connect('response', (dialog, response_id) => { - // Disable debug logging and destroy the dialog - zorin_connect.settings.set_boolean('debug', false); - dialog.destroy(); - - // Only generate a log if instructed - if (response_id === Gtk.ResponseType.OK) { - generateSupportLog(now); - } - }); - - dialog.show_all(); - } - - /** - * HeaderBar Callbacks - */ - _onPrevious(button, event) { - // HeaderBar (Service) - this.prev_button.visible = false; - this.device_menu.visible = false; - - this.service_refresh.visible = true; - this.service_edit.visible = true; - this.service_menu.visible = true; - - this.headerbar.title = zorin_connect.settings.get_string('public-name'); - this.headerbar.subtitle = null; - - // Panel - this.stack.visible_child_name = 'service'; - this._setDeviceMenu(); - } - - _onEditServiceName(button, event) { - this.service_entry.text = this.headerbar.title; - } - - _onUnfocusServiceName(entry, event) { - this.service_edit.active = false; - return false; - } - - _onSetServiceName(button, event) { - if (this.service_entry.text.length) { - this.headerbar.title = this.service_entry.text; - zorin_connect.settings.set_string('public-name', this.service_entry.text); - } - - this.service_edit.active = false; - } - - /** - * Context Switcher - */ - _setDeviceMenu(panel = null) { - this.device_menu.insert_action_group('device', null); - this.device_menu.insert_action_group('settings', null); - this.device_menu.set_menu_model(null); - - if (panel) { - this.device_menu.insert_action_group('device', panel.device); - this.device_menu.insert_action_group('settings', panel.actions); - this.device_menu.set_menu_model(panel.menu); - } - } - - _onDeviceSelected(box, row) { - let name = (typeof box === 'string') ? box : row.get_name(); - - // Transition the panel - let panel = this.stack.get_child_by_name(name); - this.stack.visible_child_name = name; - this._setDeviceMenu(this.stack.visible_child); - - // HeaderBar (Device) - this.service_refresh.visible = false; - this.service_edit.visible = false; - this.service_menu.visible = false; - - this.prev_button.visible = true; - this.device_menu.visible = true; - - this.headerbar.title = panel.device.name; - this.headerbar.subtitle = panel.device.display_type; - } - - _onDevicesChanged() { - try { - for (let id of this.application.devices) { - if (!this.stack.get_child_by_name(id)) { - this.addDevice(id); - } - } - - this.stack.foreach(panel => { - let id = panel.get_name(); - - if (id !== 'service' && !this.application.devices.includes(id)) { - if (this.stack.visible_child === panel) { - this._onPrevious(); - } - - panel._destroy(); - panel.destroy(); - } - }); - - this.device_list.foreach(row => { - if (!this.application.devices.includes(row.get_name())) { - // HACK: temporary mitigator for mysterious GtkListBox leak - //row.destroy(); - row.run_dispose(); - imports.system.gc(); - } - }); - } catch (e) { - logError(e); - } - } - - addDevice(id) { - let device = this.application._devices.get(id); - - // Add the device settings to the content stack - this.stack.add_titled(new Device.DevicePreferences(device), id, device.name); - this.device_list.add(new DeviceRow(device)); - } -}); - diff -Nru gnome-shell-extension-zorin-connect-24.1/src/service/ui/telephony.js gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/telephony.js --- gnome-shell-extension-zorin-connect-24.1/src/service/ui/telephony.js 2019-03-04 01:57:54.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/service/ui/telephony.js 2019-11-30 12:35:31.000000000 +0000 @@ -8,7 +8,7 @@ const Messaging = imports.service.ui.messaging; -var Dialog = GObject.registerClass({ +var LegacyMessagingDialog = GObject.registerClass({ GTypeName: 'ZorinConnectLegacyMessagingDialog', Properties: { 'device': GObject.ParamSpec.object( @@ -17,26 +17,37 @@ 'The device associated with this window', GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, GObject.Object + ), + 'plugin': GObject.ParamSpec.object( + 'plugin', + 'Plugin', + 'The plugin providing messages', + GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY, + GObject.Object ) }, - Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/telephony.ui', + Template: 'resource:///org/gnome/Shell/Extensions/ZorinConnect/ui/telephony.ui', Children: [ 'infobar', 'stack', - 'message', 'message-box', 'message-entry' + 'message-box', 'entry' ] }, class Dialog extends Gtk.Dialog { _init(params) { - this.connect_template(); + this.connectTemplate(); super._init({ application: Gio.Application.get_default(), device: params.device, - use_header_bar: true, - visible: true + plugin: params.plugin, + use_header_bar: true }); this.set_response_sensitive(Gtk.ResponseType.OK, false); + // Dup some functions + this.headerbar = this.get_titlebar(); + this._setHeaderBar = Messaging.Window.prototype._setHeaderBar; + // Info bar this.device.bind_property( 'connected', @@ -48,7 +59,7 @@ // Message Entry/Send Button this.device.bind_property( 'connected', - this.message_entry, + this.entry, 'sensitive', GObject.BindingFlags.DEFAULT ); @@ -58,7 +69,7 @@ this._onStateChanged.bind(this) ); - this._entryChangedId = this.message_entry.buffer.connect( + this._entryChangedId = this.entry.buffer.connect( 'changed', this._onStateChanged.bind(this) ); @@ -66,112 +77,111 @@ // Set the message if given if (params.message) { this.message = params.message; - let message = new Messaging.ConversationMessage(this.message); - message.margin_bottom = 12; - this.message_box.add(message); + this.addresses = params.message.addresses; + + let label = new Messaging.MessageLabel(this.message); + label.margin_bottom = 12; + this.message_box.add(label); + + // Otherwise set the address(es) if we were passed those + } else if (params.addresses) { + this.addresses = params.addresses; } - // Set the address if given - if (params.address) { - this.address = params.address; - - // Otherwise load the contact list - } else { - this.contact_list = new Contacts.ContactChooser({ - device: this.device, - store: this.device.contacts + // Load the contact list if we weren't supplied with an address + if (this.addresses.length === 0) { + this.contact_chooser = new Contacts.ContactChooser({ + device: this.device }); - this.stack.add_named(this.contact_list, 'contact-list'); - this.stack.child_set_property(this.contact_list, 'position', 0); + this.stack.add_named(this.contact_chooser, 'contact-chooser'); + this.stack.child_set_property(this.contact_chooser, 'position', 0); - this._numberSelectedId = this.contact_list.connect( + this._numberSelectedId = this.contact_chooser.connect( 'number-selected', this._onNumberSelected.bind(this) ); - this.stack.visible_child_name = 'contact-list'; + this.stack.visible_child_name = 'contact-chooser'; } - // Cleanup on ::destroy + this.restoreGeometry('legacy-messaging-dialog'); + this.connect('destroy', this._onDestroy); } - vfunc_response(response_id) { - if (response_id === Gtk.ResponseType.OK) { - // Refuse to send empty or whitespace only texts - if (!this.message_entry.buffer.text.trim()) return; - - this.sms.sendSms(this.address, this.message_entry.buffer.text); + _onDestroy(dialog) { + if (dialog._numberSelectedId !== undefined) { + dialog.contact_chooser.disconnect(dialog._numberSelectedId); + dialog.contact_chooser.destroy(); } - this.destroy(); + dialog.entry.buffer.disconnect(dialog._entryChangedId); + dialog.device.disconnect(dialog._connectedId); } - get address() { - return this._address || null; - } - - set address(value) { - if (!value) return; - - this._address = value; - - let headerbar = this.get_titlebar(); - headerbar.title = this.contact.name; - headerbar.subtitle = value; + vfunc_delete_event() { + this.disconnectTemplate(); + this.saveGeometry(); - // See if we have a nicer display number - let number = value.toPhoneNumber(); + return false; + } - for (let contactNumber of this.contact.numbers) { - let cnumber = contactNumber.value.toPhoneNumber(); + vfunc_response(response_id) { + if (response_id === Gtk.ResponseType.OK) { + // Refuse to send empty or whitespace only texts + if (!this.entry.buffer.text.trim()) return; - if (number.endsWith(cnumber) || cnumber.endsWith(number)) { - headerbar.subtitle = contactNumber.value; - break; - } + this.plugin.sendMessage( + this.addresses, + this.entry.buffer.text, + 1, + true + ); } - this.stack.visible_child_name = 'message'; - this._onStateChanged(); + this.destroy(); } - get contact() { - // Ensure we have a contact and hold a reference to it - if (!this._contact) { - this._contact = this.device.contacts.query({number: this.address}); + get addresses() { + if (this._addresses === undefined) { + this._addresses = []; } - return this._contact; + return this._addresses; } - get sms() { - if (!this._sms) { - this._sms = this.device.lookup_plugin('sms'); - } + set addresses(addresses = []) { + this._addresses = addresses; + + // Set the headerbar + this._setHeaderBar(this._addresses); - return this._sms; + // Show the message editor + this.stack.visible_child_name = 'message-editor'; + this._onStateChanged(); } - _onDestroy(window) { - if (window._numberSelectedId) { - window.contact_list.disconnect(window._numberSelectedId); - } + get plugin() { + return this._plugin || null; + } - window.device.disconnect(window._connectedId); - window.message_entry.buffer.disconnect(window._entryChangedId); - window.disconnect_template(); + set plugin(plugin) { + this._plugin = plugin; } - _onNumberSelected(list, number) { - this.address = number; + _onNumberSelected(chooser, number) { + let contacts = chooser.getSelected(); + + this.addresses = Object.keys(contacts).map(address => { + return {address: address}; + }); } _onStateChanged() { switch (false) { case this.device.connected: - case (this.message_entry.buffer.text.trim() !== ''): - case (this.stack.visible_child_name === 'message'): + case (this.entry.buffer.text.trim().length): + case (this.stack.visible_child_name === 'message-editor'): this.set_response_sensitive(Gtk.ResponseType.OK, false); break; @@ -186,7 +196,7 @@ * @param {String} text - The message to place in the entry */ setMessage(text) { - this.message_entry.buffer.text = text; + this.entry.buffer.text = text; } }); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/shell/device.js gnome-shell-extension-zorin-connect-28.0.2/src/shell/device.js --- gnome-shell-extension-zorin-connect-24.1/src/shell/device.js 2019-03-17 12:03:36.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/shell/device.js 2019-11-30 12:36:23.000000000 +0000 @@ -8,6 +8,7 @@ const PanelMenu = imports.ui.panelMenu; const PopupMenu = imports.ui.popupMenu; +// eslint-disable-next-line no-redeclare const _ = zorin_connect._; const GMenu = imports.shell.gmenu; const Tooltip = imports.shell.tooltip; @@ -37,7 +38,8 @@ // Battery Icon this.icon = new St.Icon({ - fallback_icon_name: 'battery-missing-symbolic' + fallback_icon_name: 'battery-missing-symbolic', + icon_size: 16 }); this.add_child(this.icon); @@ -171,44 +173,39 @@ this.actor.add_style_class_name('zorin-connect-device-menu'); // Title - this._title = new PopupMenu.PopupSeparatorMenuItem(this.device.Name); + this._title = new PopupMenu.PopupSeparatorMenuItem(this.device.name); this.addMenuItem(this._title); // Title -> Name this._title.label.style_class = 'zorin-connect-device-name'; this._title.label.clutter_text.ellipsize = 0; - this._nameId = this.device.settings.connect( - 'changed::name', - this._onNameChanged.bind(this) + this.device.bind_property( + 'name', + this._title.label, + 'text', + GObject.BindingFlags.SYNC_CREATE ); - this.actor.connect('destroy', this._onDestroy); // Title -> Battery this._battery = new Battery({device: this.device}); this._title.actor.add_child(this._battery); // Actions + let actions; + if (this.menu_type === 'icon') { - this._actions = new GMenu.IconBox({ + actions = new GMenu.IconBox({ action_group: this.device.action_group, - menu_model: this.device.menu_model + model: this.device.menu }); } else if (this.menu_type === 'list') { - this._actions = new GMenu.ListBox({ + actions = new GMenu.ListBox({ action_group: this.device.action_group, - menu_model: this.device.menu_model + model: this.device.menu }); } - this.addMenuItem(this._actions); - } - - _onDestroy(actor) { - actor._delegate.device.settings.disconnect(actor._delegate._nameId); - } - - _onNameChanged(settings) { - this._title.label.text = settings.get_string('name'); + this.addMenuItem(actions); } isEmpty() { @@ -223,15 +220,22 @@ var Indicator = class Indicator extends PanelMenu.Button { _init(params) { - super._init(0.0, `${params.device.Name} Indicator`, false); + super._init(0.0, `${params.device.name} Indicator`, false); Object.assign(this, params); // Device Icon let icon = new St.Icon({ - gicon: zorin_connect.get_gicon(`${this.device.IconName}-symbolic`), + gicon: zorin_connect.get_gicon(this.device.icon_name), style_class: 'system-status-icon zorin-connect-device-indicator' }); - this.actor.add_child(icon); + this._icon = icon; + + // TODO: remove after 3.34+ + if (zorin_connect.shell_version >= 34) { + this.add_child(icon); + } else { + this.actor.add_child(icon); + } // Menu let menu = new Menu({ @@ -240,6 +244,10 @@ }); this.menu.addMenuItem(menu); } + + update_icon(icon_name) { + this._icon.gicon = zorin_connect.get_gicon(icon_name); + } }; /** diff -Nru gnome-shell-extension-zorin-connect-24.1/src/shell/donotdisturb.js gnome-shell-extension-zorin-connect-28.0.2/src/shell/donotdisturb.js --- gnome-shell-extension-zorin-connect-24.1/src/shell/donotdisturb.js 2019-03-05 21:25:08.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/shell/donotdisturb.js 2019-11-30 12:37:13.000000000 +0000 @@ -10,6 +10,7 @@ const PopupMenu = imports.ui.popupMenu; const Util = imports.misc.util; +// eslint-disable-next-line no-redeclare const _ = zorin_connect._; const Tooltip = imports.shell.tooltip; @@ -121,18 +122,110 @@ }); -var Dialog = class Dialog extends ModalDialog.ModalDialog { +/** + * Dialog helpers + */ +function _getTimeLabel(time) { + let now = GLib.DateTime.new_now_local(); + let duration; + + if (time >= 60 * 60) { + // TRANSLATORS: Time duration in hours (eg. 2 hours) + duration = zorin_connect.ngettext( + '%d hour', + '%d hours', + (time / 3600) + ).format(time / 3600); + } else { + // TRANSLATORS: Time duration in minutes (eg. 15 minutes) + duration = zorin_connect.ngettext( + '%d minute', + '%d minutes', + (time / 60) + ).format(time / 60); + } + + // TRANSLATORS: Time until change with time duration + // EXAMPLE: Until 10:00 (2 hours) + return _('Until %s (%s)').format( + Util.formatTime(now.add_seconds(time)), + duration + ); +} + +function _addTime(button) { + if (this._time < 60 * 60) { + this._time += 15 * 60; + } else { + this._time += 60 * 60; + } + + // Set the button reactivity + this._timerRemove.reactive = (this._time > 15 * 60); + this._timerAdd.reactive = (this._time < 12 * 60 * 60); + + // Update the label + this.timerLabel.text = _getTimeLabel(this._time); +} + +function _removeTime(button) { + if (this._time <= 60 * 60) { + this._time -= 15 * 60; + } else { + this._time -= 60 * 60; + } + + // Set the button reactivity + this._timerRemove.reactive = (this._time > 15 * 60); + this._timerAdd.reactive = (this._time < 12 * 60 * 60); + + // Update the label + this.timerLabel.text = _getTimeLabel(this._time); +} + +function _resetTime() { + this.settings.reset('donotdisturb'); + this.close(); +} + +function _setTime() { + let time; + + if (this._radioDuration.active) { + let now = GLib.DateTime.new_now_local(); + time = now.add_seconds(this._time).to_unix(); + } else { + time = GLib.MAXINT32; + } + + this.settings.set_int('donotdisturb', time); + this.close(); +} + + +/** + * Show a dialog for configuring "Do Not Disturb" timeout. + * + * @param {Gio.Settings} settings - The extension settings object + */ +function showDialog(settings) { + try { + // Create the dialog + let dialog = new ModalDialog.ModalDialog({ + styleClass: 'zorin-connect-dnd-dialog' + }); - constructor() { - super({styleClass: 'zorin-connect-dnd-dialog'}); + dialog.contentLayout.style_class = 'nm-dialog-content'; + dialog.settings = settings; - this.contentLayout.style_class = 'nm-dialog-content'; + // 1 hour in seconds + dialog._time = 1 * 60 * 60; // Header let headerBox = new St.BoxLayout({ style_class: 'nm-dialog-header-hbox' }); - this.contentLayout.add(headerBox); + dialog.contentLayout.add(headerBox); let icon = new St.Icon({ style_class: 'nm-dialog-header-icon', @@ -145,32 +238,29 @@ let titleBox = new St.BoxLayout({vertical: true}); headerBox.add(titleBox); - let header = new St.Label({ + let title = new St.Label({ style_class: 'nm-dialog-header', text: _('Do Not Disturb') }); - titleBox.add(header); + titleBox.add(title); - let subheader = new St.Label({ + let subtitle = new St.Label({ style_class: 'nm-dialog-subheader', - text: _('Silence Mobile Device Notifications') + text: _('Silence Notifications from Mobile Devices') }); - titleBox.add(subheader); + titleBox.add(subtitle); // Content let radioList = new St.BoxLayout({ style_class: 'zorin-connect-radio-list', vertical: true }); - this.contentLayout.add(radioList); + dialog.contentLayout.add(radioList); - // 1 hour in seconds - this._time = 1 * 60 * 60; - - this._radioIndefinite = new RadioButton({ + let radioIndefinite = new RadioButton({ text: _('Until you turn off Do Not Disturb') }); - radioList.add(this._radioIndefinite); + radioList.add(radioIndefinite); // Duration Timer let timer = new St.BoxLayout({ @@ -179,131 +269,82 @@ style_class: 'zorin-connect-dnd-timer' }); - let now = GLib.DateTime.new_now_local(); - this.timerLabel = new St.Label({ - text: _('Until %s (%s)').format( - Util.formatTime(now.add_seconds(this._time)), - this._getDurationLabel() - ), + dialog.timerLabel = new St.Label({ + text: _getTimeLabel(dialog._time), y_align: Clutter.ActorAlign.CENTER }); - timer.add_child(this.timerLabel); + timer.add_child(dialog.timerLabel); - this._timerRemove = new St.Button({ + dialog._timerRemove = new St.Button({ style_class: 'pager-button', child: new St.Icon({icon_name: 'list-remove-symbolic'}) }); - this._timerRemove.connect('clicked', this._removeTime.bind(this)); - timer.add_child(this._timerRemove); + dialog._timerRemove.connect('clicked', _removeTime.bind(dialog)); + timer.add_child(dialog._timerRemove); - this._timerAdd = new St.Button({ + dialog._timerAdd = new St.Button({ style_class: 'pager-button', child: new St.Icon({icon_name: 'list-add-symbolic'}) }); - this._timerAdd.connect('clicked', this._addTime.bind(this)); - timer.add_child(this._timerAdd); + dialog._timerAdd.connect('clicked', _addTime.bind(dialog)); + timer.add_child(dialog._timerAdd); - this._radioDuration = new RadioButton({ + dialog._radioDuration = new RadioButton({ widget: timer, - group: this._radioIndefinite.group, + group: radioIndefinite.group, active: true }); - radioList.add(this._radioDuration); + radioList.add_child(dialog._radioDuration); // Dialog Buttons - this.setButtons([ - {label: _('Cancel'), action: this._cancel.bind(this), default: true}, - {label: _('Done'), action: this._done.bind(this)} + dialog.setButtons([ + {label: _('Cancel'), action: _resetTime.bind(dialog), default: true}, + {label: _('Done'), action: _setTime.bind(dialog)} ]); - } - - _cancel() { - zorin_connect.settings.reset('donotdisturb'); - this.close(); - } - - _done() { - let time; - - if (this._radioDuration.active) { - let now = GLib.DateTime.new_now_local(); - time = now.add_seconds(this._time).to_unix(); - } else { - time = GLib.MAXINT32; - } - zorin_connect.settings.set_int('donotdisturb', time); - this.close(); + dialog.open(); + } catch (e) { + logError(e); } +} - _addTime() { - if (this._time < 60 * 60) { - this._time += 15 * 60; - } else { - this._time += 60 * 60; - } - - this._setTimeLabel(); - } - _removeTime() { - if (this._time <= 60 * 60) { - this._time -= 15 * 60; +/** + * Item Helper Functions + */ +function _onItemMapped(actor) { + try { + let item = actor._delegate; + let now = GLib.DateTime.new_now_local().to_unix(); + item.setToggleState(item.settings.get_int('donotdisturb') > now); + } catch (e) { + logError(e); + } +} + +function _onItemToggled(item, active) { + try { + // The state has already been changed when this is emitted + if (item.state) { + showDialog(item.settings); } else { - this._time -= 60 * 60; + item.settings.reset('donotdisturb'); } - this._setTimeLabel(); + item._getTopMenu().close(true); + } catch (e) { + logError(e); } +} - _getDurationLabel() { - if (this._time >= 60 * 60) { - let hours = this._time / 3600; - // TRANSLATORS: Time duration in hours (eg. 2 hours) - return zorin_connect.ngettext('%d hour', '%d hours', hours).format(hours); - } else { - // TRANSLATORS: Time duration in minutes (eg. 15 minutes) - return zorin_connect.ngettext('%d minute', '%d minutes', (this._time / 60)).format(this._time / 60); - } - } - _setTimeLabel() { - this._timerRemove.reactive = (this._time > 15 * 60); - this._timerAdd.reactive = (this._time < 12 * 60 * 60); +function createMenuItem(settings) { + let item = new PopupMenu.PopupSwitchMenuItem(_('Do Not Disturb'), false, {}); + item.settings = settings; - let now = GLib.DateTime.new_now_local(); + item.actor.connect('notify::mapped', _onItemMapped); + item.connect('toggled', _onItemToggled); - // TRANSLATORS: Time until change with time duration - // EXAMPLE: Until 10:00 (2 hours) - this.timerLabel.text = _('Until %s (%s)').format( - Util.formatTime(now.add_seconds(this._time)), - this._getDurationLabel() - ); - } -}; - - -var MenuItem = class MenuItem extends PopupMenu.PopupSwitchMenuItem { - - constructor() { - super(_('Do Not Disturb'), false); - - // Update the toggle state when 'paintable' - this.actor.connect('notify::mapped', () => { - let now = GLib.DateTime.new_now_local().to_unix(); - this.setToggleState(zorin_connect.settings.get_int('donotdisturb') > now); - }); - - this.connect('toggled', (item) => { - // The state has already been changed when this is emitted - if (item.state) { - let dialog = new Dialog(); - dialog.open(); - } else { - zorin_connect.settings.reset('donotdisturb'); - } + return item; +} - item._getTopMenu().close(true); - }); - } -}; diff -Nru gnome-shell-extension-zorin-connect-24.1/src/shell/gmenu.js gnome-shell-extension-zorin-connect-28.0.2/src/shell/gmenu.js --- gnome-shell-extension-zorin-connect-24.1/src/shell/gmenu.js 2019-05-29 12:45:22.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/shell/gmenu.js 2019-11-30 12:37:47.000000000 +0000 @@ -75,7 +75,8 @@ // Main Actor this.actor = new St.BoxLayout({ - x_expand: true + x_expand: true, + clip_to_allocation: true }); this.actor._delegate = this; @@ -84,7 +85,6 @@ this.box.x_expand = true; this.box.add_style_class_name('zorin-connect-list-box'); this.box.set_pivot_point(1, 1); - this.box.connect('transitions-completed', this._onTransitionsCompleted); this.actor.add_child(this.box); // Submenu Container @@ -96,25 +96,37 @@ x_expand: true }); this.sub.set_pivot_point(1, 1); - this.sub.connect('key-press-event', this._onSubmenuCloseKey); - this.sub.connect('transitions-completed', this._onTransitionsCompleted); this.sub._delegate = this; this.actor.add_child(this.sub); + // Handle transitions + this._boxTransitionsCompletedId = this.box.connect( + 'transitions-completed', + this._onTransitionsCompleted.bind(this) + ); + + this._subTransitionsCompletedId = this.sub.connect( + 'transitions-completed', + this._onTransitionsCompleted.bind(this) + ); + + // Handle keyboard navigation + this._submenuCloseKeyId = this.sub.connect( + 'key-press-event', + this._onSubmenuCloseKey.bind(this) + ); + // Refresh the menu when mapped - let _mappedId = this.actor.connect( + this._mappedId = this.actor.connect( 'notify::mapped', this._onMapped.bind(this) ); - this.actor.connect('destroy', (actor) => actor.disconnect(_mappedId)); // Watch the model for changes - let _menuId = this.menu_model.connect( + this._itemsChangedId = this.model.connect( 'items-changed', this._onItemsChanged.bind(this) ); - this.connect('destroy', (menu) => menu.menu_model.disconnect(_menuId)); - this._onItemsChanged(); } @@ -124,24 +136,24 @@ // We use this instead of close() to avoid touching finalized objects } else { - this.box.opacity = 255; - this.box.width = -1; + this.box.set_opacity(255); + this.box.set_width(-1); + this.box.set_height(-1); this.box.visible = true; this._submenu = null; - this.sub.opacity = 0; - this.sub.width = 0; + this.sub.set_opacity(0); + this.sub.set_width(0); + this.sub.set_height(0); this.sub.visible = false; this.sub.get_children().map(menu => menu.hide()); } } _onSubmenuCloseKey(actor, event) { - let menu = actor.get_parent()._delegate; - - if (menu.submenu && event.get_key_symbol() == Clutter.KEY_Left) { - menu.submenu.submenu_for.setActive(true); - menu.submenu = null; + if (this.submenu && event.get_key_symbol() == Clutter.KEY_Left) { + this.submenu.submenu_for.setActive(true); + this.submenu = null; return Clutter.EVENT_STOP; } @@ -159,35 +171,47 @@ return Clutter.EVENT_PROPAGATE; } - _addGMenuItem(info) { - let action_name = info.action.split('.')[1]; - let action_target = info.target; + _onGMenuItemActivate(item, event) { + this.emit('activate', item); + if (item.submenu) { + this.submenu = item.submenu; + } else if (item.action_name) { + this.action_group.activate_action( + item.action_name, + item.action_target + ); + this.itemActivated(); + } + } + + _addGMenuItem(info) { // TODO: Use an image menu item if there's an icon? let item = new PopupMenu.PopupMenuItem(info.label); - item.actor.visible = this.action_group.get_action_enabled(action_name); this.addMenuItem(item); - // Modify the ::activate callback to invoke the GAction or submenu - item.disconnect(item._activateId); + if (info.action !== undefined) { + item.action_name = info.action.split('.')[1]; + item.action_target = info.target; - item._activateId = item.connect('activate', (item, event) => { - this.emit('activate', item); + item.actor.visible = this.action_group.get_action_enabled( + item.action_name + ); + } - if (item.submenu) { - this.submenu = item.submenu; - } else { - this.action_group.activate_action(action_name, action_target); - this.itemActivated(); - } - }); + // Modify the ::activate callback to invoke the GAction or submenu + item.disconnect(item._activateId); + item._activateId = item.connect( + 'activate', + this._onGMenuItemActivate.bind(this) + ); return item; } _addGMenuSection(model) { let section = new ListBox({ - menu_model: model, + model: model, action_group: this.action_group }); this.addMenuItem(section); @@ -210,7 +234,7 @@ // Create the submenu item.submenu = new ListBox({ - menu_model: model, + model: model, action_group: this.action_group, submenu_for: item, _parent: this @@ -226,9 +250,8 @@ this.removeAll(); this.sub.get_children().map(child => child.destroy()); - - for (let i = 0, len = this.menu_model.get_n_items(); i < len; i++) { - let info = getItemInfo(this.menu_model, i); + for (let i = 0, len = this.model.get_n_items(); i < len; i++) { + let info = getItemInfo(this.model, i); let item; // A regular item @@ -253,14 +276,13 @@ } } - // If this is a submenu of another item, prepend a "go back" item + // If this is a submenu of another item... if (this.submenu_for) { + // Prepend an "<= Go Back" item, bold with a unicode arrow let prev = new PopupMenu.PopupMenuItem(this.submenu_for.label.text); - this.addMenuItem(prev, 0); - - // Make the title bold and replace the ornament with an arrow prev.label.style = 'font-weight: bold;'; prev._ornamentLabel.text = '\u25C2'; + this.addMenuItem(prev, 0); // Modify the ::activate callback to close the submenu prev.disconnect(prev._activateId); @@ -273,16 +295,12 @@ } _onTransitionsCompleted(actor) { - let menu = actor.get_parent()._delegate; - - if (menu.submenu) { - menu.box.visible = false; + if (this.submenu) { + this.box.visible = false; } else { - menu.sub.visible = false; - menu.sub.get_children().map(menu => menu.hide()); + this.sub.visible = false; + this.sub.get_children().map(menu => menu.hide()); } - - menu.actor.remove_clip(); } get submenu() { @@ -290,20 +308,20 @@ } set submenu(submenu) { - // Get the current allocation and set the actor's clip + // Get the current allocation to hold the menu width let allocation = this.actor.allocation; - let width = allocation.x2 - allocation.x1; - let height = allocation.y2 - allocation.y1; - this.actor.set_clip (0, 0, width, height); + let width = Math.max(0, allocation.x2 - allocation.x1); // Prepare the appropriate child for tweening if (submenu) { - this.sub.opacity = 0; - this.sub.width = 0; + this.sub.set_opacity(0); + this.sub.set_width(0); + this.sub.set_height(0); this.sub.visible = true; } else { - this.box.opacity = 0; - this.box.width = 0; + this.box.set_opacity(0); + this.box.set_width(0); + this.sub.set_height(0); this.box.visible = true; } @@ -319,17 +337,21 @@ if (submenu) { submenu.actor.show(); - this.sub.opacity = 255; - this.sub.width = width; - - this.box.opacity = 0; - this.box.width = 0; + this.sub.set_opacity(255); + this.sub.set_width(width); + this.sub.set_height(-1); + + this.box.set_opacity(0); + this.box.set_width(0); + this.box.set_height(0); } else { - this.box.opacity = 255; - this.box.width = width; + this.box.set_opacity(255); + this.box.set_width(width); + this.box.set_height(-1); - this.sub.opacity = 0; - this.sub.width = 0; + this.sub.set_opacity(0); + this.sub.set_width(0); + this.sub.set_height(0); } // Reset the animation @@ -339,6 +361,16 @@ // this._submenu = submenu; } + + destroy() { + this.actor.disconnect(this._mappedId); + this.box.disconnect(this._boxTransitionsCompletedId); + this.sub.disconnect(this._subTransitionsCompletedId); + this.sub.disconnect(this._submenuCloseKeyId); + this.model.disconnect(this._itemsChangedId); + + super.destroy(); + } }; @@ -384,7 +416,7 @@ this.connect('notify::checked', this._onChecked); this.submenu = new ListBox({ - menu_model: link.value, + model: link.value, action_group: this.action_group }); @@ -441,7 +473,6 @@ vertical: true, x_expand: true }); - this.actor.connect('notify::mapped', this._onMapped); this.actor._delegate = this; // Button Box @@ -464,32 +495,41 @@ // Track menu items so we can use ::items-changed this._menu_items = new Map(); + // PopupMenu + this._mappedId = this.actor.connect( + 'notify::mapped', + this._onMapped.bind(this) + ); + // GMenu - let _itemsChangedId = this.menu_model.connect( + this._itemsChangedId = this.model.connect( 'items-changed', this._onItemsChanged.bind(this) ); // GActions - let _actionAddedId = this.action_group.connect( + this._actionAddedId = this.action_group.connect( 'action-added', this._onActionChanged.bind(this) ); - let _actionEnabledChangedId = this.action_group.connect( + this._actionEnabledChangedId = this.action_group.connect( 'action-enabled-changed', this._onActionChanged.bind(this) ); - let _actionRemovedId = this.action_group.connect( + this._actionRemovedId = this.action_group.connect( 'action-removed', this._onActionChanged.bind(this) ); + } - this.connect('destroy', (actor) => { - actor.menu_model.disconnect(_itemsChangedId); - actor.action_group.disconnect(_actionAddedId); - actor.action_group.disconnect(_actionEnabledChangedId); - actor.action_group.disconnect(_actionRemovedId); - }); + destroy() { + this.actor.disconnect(this._mappedId); + this.model.disconnect(this._itemsChangedId); + this.action_group.disconnect(this._actionAddedId); + this.action_group.disconnect(this._actionEnabledChangedId); + this.action_group.disconnect(this._actionRemovedId); + + super.destroy(); } get submenu() { @@ -498,12 +538,12 @@ set submenu(submenu) { if (submenu) { - this.box.get_children().map(button => { + for (let button of this.box.get_children()) { if (button.submenu && this._submenu && button.submenu !== submenu) { button.checked = false; button.submenu.actor.hide(); } - }); + } this.sub.set_height(0); submenu.actor.show(); @@ -519,6 +559,14 @@ this._submenu = submenu; } + _onMapped(actor) { + if (!actor.mapped) { + this._submenu = null; + this.box.get_children().map(button => button.checked = false); + this.sub.get_children().map(submenu => submenu.hide()); + } + } + _onActionChanged(group, name, enabled) { let menuItem = this._menu_items.get(name); @@ -555,33 +603,27 @@ }); // Set the visibility based on the enabled state - button.visible = this.action_group.get_action_enabled( - button.action_name - ); + if (button.action_name !== undefined) { + button.visible = this.action_group.get_action_enabled( + button.action_name + ); + } // If it has a submenu, add it as a sibling if (button.submenu) { this.sub.add_child(button.submenu.actor); } - // Track the item - this._menu_items.set(button.action_name, button); + // Track the item if it has an action + if (button.action_name !== undefined) { + this._menu_items.set(button.action_name, button); + } // Insert it in the box at the defined position this.box.insert_child_at_index(button, index); } } - _onMapped(actor) { - // Close everything down manually when unmapped - if (!actor.mapped) { - let menu = actor._delegate; - menu._submenu = null; - menu.box.get_children().map(button => button.checked = false); - menu.sub.get_children().map(submenu => submenu.hide()); - } - } - _onTransitionsCompleted(actor) { let menu = actor._delegate; @@ -600,7 +642,7 @@ _setParent(parent) { super._setParent(parent); - this._onItemsChanged(this.menu_model, 0, 0, this.menu_model.get_n_items()); + this._onItemsChanged(this.model, 0, 0, this.model.get_n_items()); } }; diff -Nru gnome-shell-extension-zorin-connect-24.1/src/shell/keybindings.js gnome-shell-extension-zorin-connect-28.0.2/src/shell/keybindings.js --- gnome-shell-extension-zorin-connect-24.1/src/shell/keybindings.js 2019-03-17 12:04:51.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/shell/keybindings.js 2019-11-01 23:59:50.000000000 +0000 @@ -34,7 +34,7 @@ ); } - _onAcceleratorActivated(display, action, deviceId, timestamp) { + _onAcceleratorActivated(display, action, inputDevice, timestamp) { try { let binding = this._keybindings.get(action); @@ -54,24 +54,28 @@ * @return {Number} - A non-zero action id on success, or 0 on failure */ add(accelerator, callback) { - let action = Meta.KeyBindingAction.NONE; + try { + let action = Meta.KeyBindingAction.NONE; - // A flags argument was added somewhere between 3.30-3.32 - if (SHELL_VERSION_MINOR > 30) { - action = global.display.grab_accelerator(accelerator, 0); - } else { - action = global.display.grab_accelerator(accelerator); - } + // A flags argument was added somewhere between 3.30-3.32 + if (SHELL_VERSION_MINOR > 30) { + action = global.display.grab_accelerator(accelerator, 0); + } else { + action = global.display.grab_accelerator(accelerator); + } - if (action !== Meta.KeyBindingAction.NONE) { - let name = Meta.external_binding_name_for_action(action); - Main.wm.allowKeybinding(name, Shell.ActionMode.ALL); - this._keybindings.set(action, {name: name, callback: callback}); - } else { - logError(new Error(`Failed to add keybinding: '${accelerator}'`)); - } + if (action !== Meta.KeyBindingAction.NONE) { + let name = Meta.external_binding_name_for_action(action); + Main.wm.allowKeybinding(name, Shell.ActionMode.ALL); + this._keybindings.set(action, {name: name, callback: callback}); + } else { + throw new Error(`Failed to add keybinding: '${accelerator}'`); + } - return action; + return action; + } catch (e) { + logError(e); + } } /** diff -Nru gnome-shell-extension-zorin-connect-24.1/src/shell/notification.js gnome-shell-extension-zorin-connect-28.0.2/src/shell/notification.js --- gnome-shell-extension-zorin-connect-24.1/src/shell/notification.js 2019-03-06 14:56:45.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/shell/notification.js 2019-11-30 12:41:22.000000000 +0000 @@ -8,6 +8,7 @@ const MessageTray = imports.ui.messageTray; const NotificationDaemon = imports.ui.notificationDaemon; +// eslint-disable-next-line no-redeclare const _ = zorin_connect._; diff -Nru gnome-shell-extension-zorin-connect-24.1/src/shell/remote.js gnome-shell-extension-zorin-connect-28.0.2/src/shell/remote.js --- gnome-shell-extension-zorin-connect-24.1/src/shell/remote.js 2019-03-05 21:25:38.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/shell/remote.js 2019-11-30 12:40:18.000000000 +0000 @@ -4,18 +4,256 @@ const GLib = imports.gi.GLib; const GObject = imports.gi.GObject; +const DBUS_NAME = 'org.gnome.Shell.Extensions.ZorinConnect'; +const DBUS_PATH = '/org/gnome/Shell/Extensions/ZorinConnect'; -const DEVICE_NAME = 'org.gnome.Shell.Extensions.ZorinConnect.Device'; -const DEVICE_INFO = zorin_connect.dbusinfo.lookup_interface(DEVICE_NAME); + +function toHyphenCase(string) { + if (toHyphenCase.__cache === undefined) { + toHyphenCase.__cache = {}; + } + + if (!toHyphenCase.__cache[string]) { + toHyphenCase.__cache[string] = string.replace(/(?:[A-Z])/g, (c, i) => { + return (i > 0) ? '-' + c.toLowerCase() : c.toLowerCase(); + }).replace(/[\s_]+/g, ''); + } + + return toHyphenCase.__cache[string]; +} + + +function _proxyInit(proxy, cancellable = null) { + if (proxy.__initialized !== undefined) { + return Promise.resolve(); + } + + return new Promise((resolve, reject) => { + proxy.init_async( + GLib.PRIORITY_DEFAULT, + cancellable, + (proxy, res) => { + try { + proxy.init_finish(res); + proxy.__initialized = true; + resolve(); + } catch (e) { + Gio.DBusError.strip_remote_error(e); + reject(e); + } + } + ); + }); +} + + +var Device = GObject.registerClass({ + GTypeName: 'ZorinConnectRemoteDevice', + Implements: [Gio.DBusInterface], + Properties: { + 'connected': GObject.ParamSpec.boolean( + 'connected', + 'Connected', + 'Whether the device is connected', + GObject.ParamFlags.READABLE, + null + ), + 'encryption-info': GObject.ParamSpec.string( + 'encryption-info', + 'Encryption Info', + 'A formatted string with the local and remote fingerprints', + GObject.ParamFlags.READABLE, + null + ), + 'icon-name': GObject.ParamSpec.string( + 'icon-name', + 'Icon Name', + 'Icon name representing the device', + GObject.ParamFlags.READABLE, + null + ), + 'id': GObject.ParamSpec.string( + 'id', + 'deviceId', + 'The device hostname or other unique id', + GObject.ParamFlags.READABLE, + '' + ), + 'name': GObject.ParamSpec.string( + 'name', + 'deviceName', + 'The device name', + GObject.ParamFlags.READABLE, + null + ), + 'paired': GObject.ParamSpec.boolean( + 'paired', + 'Paired', + 'Whether the device is paired', + GObject.ParamFlags.READABLE, + null + ), + 'type': GObject.ParamSpec.string( + 'type', + 'deviceType', + 'The device type', + GObject.ParamFlags.READABLE, + null + ) + } +}, class Device extends Gio.DBusProxy { + + _init(service, object_path) { + this._service = service; + + super._init({ + g_connection: service.g_connection, + g_name: DBUS_NAME, + g_object_path: object_path, + g_interface_name: 'org.gnome.Shell.Extensions.ZorinConnect.Device' + }); + } + + // Proxy GObject::notify signals + vfunc_g_properties_changed(changed, invalidated) { + try { + for (let name in changed.deep_unpack()) { + this.notify(toHyphenCase(name)); + } + } catch (e) { + logError(e); + } + } + + _get(name, fallback = null) { + try { + return this.get_cached_property(name).unpack(); + } catch (e) { + return fallback; + } + } + + get connected() { + return this._get('Connected', false); + } + + get encryption_info() { + return this._get('EncryptionInfo', ''); + } + + get icon_name() { + return this._get('IconName', 'computer'); + } + + get id() { + return this._get('Id', '0'); + } + + get name() { + return this._get('Name', 'Unknown'); + } + + get paired() { + return this._get('Paired', false); + } + + get settings() { + if (this._settings === undefined) { + this._settings = new Gio.Settings({ + settings_schema: zorin_connect.gschema.lookup( + this.g_interface_name, + true + ), + path: `${this.g_object_path.toLowerCase()}/` + }); + } + + return this._settings; + } + + get service() { + return this._service; + } + + get type() { + return this._get('Type', 'desktop'); + } + + async start() { + try { + // Initialize the proxy + await _proxyInit(this); + + // GActions + this.action_group = Gio.DBusActionGroup.get( + this.g_connection, + this.service.g_name_owner, + this.g_object_path + ); + + // GMenu + this.menu = Gio.DBusMenuModel.get( + this.g_connection, + this.service.g_name_owner, + this.g_object_path + ); + + // Subscribe to the GMenu + await new Promise((resolve, reject) => { + this.g_connection.call( + DBUS_NAME, + this.g_object_path, + 'org.gtk.Menus', + 'Start', + new GLib.Variant('(au)', [[0]]), + null, + Gio.DBusCallFlags.NONE, + -1, + null, + (proxy, res) => { + try { + resolve(proxy.call_finish(res)); + } catch (e) { + Gio.DBusError.strip_remote_error(e); + reject(e); + } + } + ); + }); + } catch (e) { + this.destroy(); + throw e; + } + } + + destroy() { + if (this.__disposed === undefined) { + this.__disposed = true; + + if (this._settings) { + this._settings.run_dispose(); + this._settings = null; + } + + this.run_dispose(); + } + } +}); var Service = GObject.registerClass({ GTypeName: 'ZorinConnectRemoteService', Implements: [Gio.DBusInterface], + Properties: { + 'active': GObject.ParamSpec.boolean( + 'active', + 'Active', + 'Whether the service is active', + GObject.ParamFlags.READABLE, + false + ) + }, Signals: { - 'available-changed': { - flags: GObject.SignalFlags.RUN_FIRST - }, 'device-added': { flags: GObject.SignalFlags.RUN_FIRST, param_types: [GObject.TYPE_OBJECT] @@ -30,13 +268,15 @@ _init() { super._init({ g_bus_type: Gio.BusType.SESSION, - g_name: 'org.gnome.Shell.Extensions.ZorinConnect', - g_object_path: '/org/gnome/Shell/Extensions/ZorinConnect', + g_name: DBUS_NAME, + g_object_path: DBUS_PATH, g_interface_name: 'org.freedesktop.DBus.ObjectManager', g_flags: Gio.DBusProxyFlags.DO_NOT_AUTO_START_AT_CONSTRUCTION }); + this._active = false; this._devices = new Map(); + this._starting = false; // Watch the service this._nameOwnerChangedId = this.connect( @@ -45,30 +285,8 @@ ); } - async _init_async() { - try { - await new Promise((resolve, reject) => { - this.init_async( - GLib.PRIORITY_DEFAULT, - null, - (proxy, res) => { - try { - resolve(proxy.init_finish(res)); - } catch (e) { - reject(e); - } - } - ); - }); - - this._onNameOwnerChanged(); - } catch (e) { - return Promise.reject(e); - } - } - - get available() { - return this.devices.filter(device => (device.Connected && device.Paired)); + get active() { + return this._active; } get devices() { @@ -77,8 +295,8 @@ vfunc_g_signal(sender_name, signal_name, parameters) { try { - // Don't emit signals until the name is properly owned - if (!this.g_name_owner === null) return; + // Don't emit signals until the ObjectManager has started + if (!this.active) return; parameters = parameters.deep_unpack(); @@ -96,87 +314,11 @@ } } - _onDeviceChanged(proxy, changed, invalidated) { - changed = changed.deep_unpack(); - - if (changed.hasOwnProperty('Connected') || changed.hasOwnProperty('Paired')) { - this.emit('available-changed'); - } - } - - _proxyGetter(name) { - let variant = this.get_cached_property(name); - return variant ? variant.deep_unpack() : null; - } - - async _getProxy(object_path) { - try { - let proxy = new Gio.DBusProxy({ - g_connection: this.g_connection, - g_name: this.g_name_owner, - g_object_path: object_path, - g_interface_name: DEVICE_NAME - }); - - // Initialize the device proxy - await new Promise((resolve, reject) => { - proxy.init_async( - GLib.PRIORITY_DEFAULT, - null, - (proxy, res) => { - try { - resolve(proxy.init_finish(res)); - } catch (e) { - reject(e); - } - } - ); - }); - - // Setup properties - for (let i = 0, len = DEVICE_INFO.properties.length; i < len; i++) { - let property = DEVICE_INFO.properties[i]; - - Object.defineProperty(proxy, property.name, { - get: this._proxyGetter.bind(proxy, property.name), - enumerable: true - }); - } - - // GActions - proxy.action_group = Gio.DBusActionGroup.get( - proxy.g_connection, - proxy.g_name, - proxy.g_object_path - ); - - // GMenu - proxy.menu_model = Gio.DBusMenuModel.get( - proxy.g_connection, - proxy.g_name, - proxy.g_object_path - ); - - await this._Start(object_path); - - // GSettings - proxy.settings = new Gio.Settings({ - settings_schema: zorin_connect.gschema.lookup(DEVICE_NAME, true), - path: '/org/gnome/shell/extensions/zorin-connect/device/' + proxy.Id + '/' - }); - - return proxy; - } catch (e) { - logError(e, object_path); - return undefined; - } - } - /** * org.freedesktop.DBus.ObjectManager.InterfacesAdded * - * @param {string} object_path - Path interfaces have been removed from - * @param {object[]} - ?? + * @param {string} object_path - Path interfaces have been added to + * @param {object[]} - list of interface objects */ async _onInterfacesAdded(object_path, interfaces) { try { @@ -187,18 +329,12 @@ if (this._devices.has(object_path)) return; // Create a proxy - let proxy = await this._getProxy(object_path); - if (proxy === undefined) return; - - // Watch for connected/paired changes - proxy.__deviceChangedId = proxy.connect( - 'g-properties-changed', - this._onDeviceChanged.bind(this) - ); + let device = new Device(this, object_path); + await device.start(); // Hold the proxy and emit ::device-added - this._devices.set(object_path, proxy); - this.emit('device-added', proxy); + this._devices.set(object_path, device); + this.emit('device-added', device); } catch (e) { logError(e, object_path); } @@ -210,53 +346,28 @@ * @param {string} object_path - Path interfaces have been removed from * @param {string[]} - List of interface names removed */ - async _onInterfacesRemoved(object_path, interfaces) { + _onInterfacesRemoved(object_path, interfaces) { try { // An empty interface list means the object is being removed if (interfaces.length === 0) return; // Get the proxy - let proxy = this._devices.get(object_path); - if (proxy === undefined) return; - - // Stop watching for connected/paired changes - proxy.disconnect(proxy.__deviceChangedId); + let device = this._devices.get(object_path); + if (device === undefined) return; // Release the proxy and emit ::device-removed this._devices.delete(object_path); - this.emit('device-removed', proxy); - } catch (e) { - logError(e, object_path); - } - } - - async _onNameOwnerChanged() { - try { - // If the service stopped, clear all devices before restarting - if (this.g_name_owner === null) { - this.clear(); - await this._GetManagedObjects(); - - // Now that service is started, add each device manually - } else { - let objects = await this._GetManagedObjects(); + this.emit('device-removed', device); - for (let [object_path, object] of Object.entries(objects)) { - await this._onInterfacesAdded(object_path, object); - } - } + // Destroy the device and force disposal + device.destroy(); } catch (e) { - logError(e); + logError(e, object_path); } } - /** - * org.freedesktop.DBus.ObjectManager.GetManagedObjects - * - * @return {object} - Dictionary of managed object paths and interface names - */ - _GetManagedObjects() { - return new Promise((resolve, reject) => { + async _addDevices() { + let objects = await new Promise((resolve, reject) => { this.call( 'GetManagedObjects', null, @@ -268,55 +379,158 @@ let variant = proxy.call_finish(res); resolve(variant.deep_unpack()[0]); } catch (e) { + Gio.DBusError.strip_remote_error(e); reject(e); } } ); }); + + for (let [object_path, object] of Object.entries(objects)) { + await this._onInterfacesAdded(object_path, object); + } + } + + _clearDevices() { + for (let [object_path, device] of this._devices) { + this._devices.delete(object_path); + this.emit('device-removed', device); + device.destroy(); + } + } + + async _onNameOwnerChanged() { + try { + // If the service stopped, remove each device and mark it inactive + if (this.g_name_owner === null) { + this._clearDevices(); + + this._active = false; + this.notify('active'); + + // If the service started, mark it active and add each device + } else { + this._active = true; + this.notify('active'); + + await this._addDevices(); + } + } catch (e) { + logError(e); + } } /** - * org.gtk.Menus.Start - * - * We use this call to ensure that our connection is subscribed to GMenu - * changes if the device is added after the service has started. - * - * @param {string} object_path + * Reload all devices without affecting the remote service. This amounts to + * removing and adding each device while emitting the appropriate signals. + */ + async reload() { + try { + if (this._starting === false) { + this._starting = true; + + this._clearDevices(); + await _proxyInit(this); + await this._onNameOwnerChanged(); + + this._starting = false; + } + } catch (e) { + this._starting = false; + throw e; + } + } + + /** + * Start the service + */ + async start() { + try { + if (this._starting === false && this.active === false) { + this._starting = true; + + await _proxyInit(this); + await this._onNameOwnerChanged(); + + // Activate the service if it's not already running + if (!this.active) { + await new Promise((resolve, reject) => { + this.g_connection.call( + DBUS_NAME, + DBUS_PATH, + 'org.freedesktop.Application', + 'Activate', + GLib.Variant.new('(a{sv})', [{}]), + null, + Gio.DBusCallFlags.NONE, + -1, + null, + (proxy, res) => { + try { + resolve(proxy.call_finish(res)); + } catch (e) { + Gio.DBusError.strip_remote_error(e); + reject(e); + } + } + ); + }); + } + + this._starting = false; + } + } catch (e) { + this._starting = false; + throw e; + } + } + + /** + * Stop the service */ - _Start(object_path) { - return new Promise((resolve, reject) => { - this.g_connection.call( - this.g_name, - object_path, - 'org.gtk.Menus', - 'Start', - new GLib.Variant('(au)', [[0]]), + stop() { + if (this.active) { + this.activate_action('quit'); + } + } + + activate_action(name, parameter = null) { + try { + let paramArray = []; + + if (parameter instanceof GLib.Variant) { + paramArray[0] = parameter; + } + + let connection = this.g_connection || Gio.DBus.session; + + connection.call( + DBUS_NAME, + DBUS_PATH, + 'org.freedesktop.Application', + 'ActivateAction', + GLib.Variant.new('(sava{sv})', [name, paramArray, {}]), null, Gio.DBusCallFlags.NONE, -1, null, - (proxy, res) => { - try { - resolve(proxy.call_finish(res)); - } catch (e) { - reject(e); - } - } + null ); - }); - } - - clear() { - for (let device of this.devices) { - device.disconnect(device.__deviceChangedId); - this._devices.delete(device.g_object_path); - this.emit('device-removed', device); + } catch (e) { + logError(e); } } destroy() { - this.disconnect(this._nameOwnerChangedId); - this.clear(); + if (this._nameOwnerChangedId > 0) { + this.disconnect(this._nameOwnerChangedId); + this._nameOwnerChangedId = 0; + + this._clearDevices(); + this._active = false; + + this.run_dispose(); + } } }); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/shell/tooltip.js gnome-shell-extension-zorin-connect-28.0.2/src/shell/tooltip.js --- gnome-shell-extension-zorin-connect-24.1/src/shell/tooltip.js 2019-03-06 14:59:30.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/shell/tooltip.js 2019-11-30 12:40:31.000000000 +0000 @@ -22,93 +22,111 @@ var Tooltip = class Tooltip { constructor(params) { - // Properties - Object.defineProperties(this, { - 'custom': { - get: () => this._custom || false, - set: (actor) => { - this._custom = actor; - this._markup = null; - this._text = null; - this._update(); - } - }, - 'markup': { - get: () => this._markup || false, - set: (value) => { - this._markup = value; - this._text = null; - this._update(); - } - }, - 'text': { - get: () => this._text || false, - set: (value) => { - this._markup = null; - this._text = value; - this._update(); - } - }, - 'icon_name': { - get: () => this._gicon.name, - set: (icon_name) => { - if (!icon_name) { - this.gicon = null; - } else { - this.gicon = new Gio.ThemedIcon({ - name: icon_name - }); - } - } - }, - 'gicon': { - get: () => this._gicon || false, - set: (gicon) => { - this._gicon = gicon; - this._update(); - } - }, - 'x_offset': { - get: () => (this._x_offset === undefined) ? 0 : this._x_offset, - set: (offset) => { - this._x_offset = (Number.isInteger(offset)) ? offset : 0; - } - }, - 'y_offset': { - get: () => (this._y_offset === undefined) ? 0 : this._y_offset, - set: (offset) => { - this._y_offset = (Number.isInteger(offset)) ? offset : 0; - } - } - }); - - this._parent = params.parent; - - for (let param in params) { - if (param !== 'parent') { - this[param] = params[param]; - } - } + Object.assign(this, params); this._hoverTimeoutId = 0; this._showing = false; - // TODO: oddly fuzzy on menu items, sometimes - if (this._parent.actor) { - this._parent = this._parent.actor; - } + this._destroyId = this.parent.connect( + 'destroy', + this.destroy.bind(this) + ); - this._hoverId = this._parent.connect( + this._hoverId = this.parent.connect( 'notify::hover', this._onHover.bind(this) ); - this._pressId = this._parent.connect( + this._buttonPressEventId = this.parent.connect( 'button-press-event', this._hide.bind(this) ); + } + + get custom() { + if (this._custom === undefined) { + this._custom = null; + } + + return this._custom; + } + + set custom(actor) { + this._custom = actor; + this._markup = null; + this._text = null; + this._update(); + } + + get gicon() { + if (this._gicon === undefined) { + this._gicon = null; + } + + return this._gicon; + } + + set gicon(gicon) { + this._gicon = gicon; + this._update(); + } + + get icon() { + return (this.gicon) ? this.gicon.name : null; + } + + set icon(icon_name) { + if (!icon_name) { + this.gicon = null; + } else { + this.gicon = new Gio.ThemedIcon({ + name: icon_name + }); + } + } + + get markup() { + if (this._markup === undefined) { + this._markup = null; + } + + return this._markup; + } + + set markup(text) { + this._markup = text; + this._text = null; + this._update(); + } + + get text() { + if (this._text === undefined) { + this._text = null; + } + + return this._text; + } + + set text(text) { + this._markup = null; + this._text = text; + this._update(); + } + + get x_offset() { + return (this._x_offset === undefined) ? 0 : this._x_offset; + } + + set x_offset(offset) { + this._x_offset = (Number.isInteger(offset)) ? offset : 0; + } + + get y_offset() { + return (this._y_offset === undefined) ? 0 : this._y_offset; + } - this._parent.connect('destroy', this.destroy.bind(this)); + set y_offset(offset) { + this._y_offset = (Number.isInteger(offset)) ? offset : 0; } _update() { @@ -170,8 +188,8 @@ } // Position tooltip - let [x, y] = this._parent.get_transformed_position(); - x = (x + (this._parent.width / 2)) - Math.round(this.bin.width / 2); + let [x, y] = this.parent.get_transformed_position(); + x = (x + (this.parent.width / 2)) - Math.round(this.bin.width / 2); x += this.x_offset; y += this.y_offset; @@ -244,7 +262,7 @@ } _onHover() { - if (this._parent.hover) { + if (this.parent.hover) { if (!this._hoverTimeoutId) { if (this._showing) { this._show(); @@ -266,8 +284,9 @@ } destroy() { - this._parent.disconnect(this._hoverId); - this._parent.disconnect(this._pressId); + this.parent.disconnect(this._destroyId); + this.parent.disconnect(this._hoverId); + this.parent.disconnect(this._buttonPressEventId); if (this.custom) { this.custom.destroy(); diff -Nru gnome-shell-extension-zorin-connect-24.1/src/_zorin_connect.js gnome-shell-extension-zorin-connect-28.0.2/src/_zorin_connect.js --- gnome-shell-extension-zorin-connect-24.1/src/_zorin_connect.js 2019-03-06 16:36:25.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/_zorin_connect.js 2019-11-30 00:55:03.000000000 +0000 @@ -1,10 +1,8 @@ 'use strict'; -const Gdk = imports.gi.Gdk; const Gio = imports.gi.Gio; const GIRepository = imports.gi.GIRepository; const GLib = imports.gi.GLib; -const Gtk = imports.gi.Gtk; /** @@ -95,7 +93,7 @@ * Init Gettext * * If we aren't inside the GNOME Shell process we'll set gettext functions on - * the global object, otherwise we'll set them on the global 'zorin_connect' object + * the global object, otherwise we'll set them on the global 'zorin-connect' object */ imports.gettext.bindtextdomain(zorin_connect.app_id, zorin_connect.localedir); const Gettext = imports.gettext.domain(zorin_connect.app_id); @@ -169,9 +167,16 @@ let desktopDir = GLib.build_filenamev([dataDir, 'applications']); let desktopFile = `${zorin_connect.app_id}.desktop`; - // Nautilus Extension - let nautDir = GLib.build_filenamev([dataDir, 'nautilus-python/extensions']); - let nautScript = GLib.build_filenamev([nautDir, 'nautilus-zorin-connect.py']); + // Application Icon + let iconDir = GLib.build_filenamev([dataDir, 'icons', 'hicolor', 'scalable', 'apps']); + let iconFull = `${zorin_connect.app_id}.svg`; + let iconSym = `${zorin_connect.app_id}-symbolic.svg`; + + // File Manager Extensions + let fileManagers = [ + [dataDir + '/nautilus-python/extensions', 'nautilus-zorin-connect.py'], + [dataDir + '/nemo-python/extensions', 'nemo-zorin-connect.py'] + ]; // WebExtension Manifests let manifestFile = 'org.gnome.shell.extensions.zorin_connect.json'; @@ -182,14 +187,15 @@ [confDir + '/google-chrome/NativeMessagingHosts/', chrome], [confDir + '/google-chrome-beta/NativeMessagingHosts/', chrome], [confDir + '/google-chrome-unstable/NativeMessagingHosts/', chrome], + [confDir + '/BraveSoftware/Brave-Browser/NativeMessagingHosts/', chrome], [homeDir + '/.mozilla/native-messaging-hosts/', mozilla] ]; // If running as a user extension, ensure the DBus service, desktop entry, - // Nautilus script and WebExtension manifests are installed. + // file manager scripts, and WebExtension manifests are installed. if (zorin_connect.is_local) { // DBus Service - GLib.mkdir_with_parents(dbusDir, 493); + GLib.mkdir_with_parents(dbusDir, 493); // 0755 in octal GLib.file_set_contents( GLib.build_filenamev([dbusDir, dbusFile]), zorin_connect.get_resource(dbusFile) @@ -202,16 +208,27 @@ zorin_connect.get_resource(desktopFile) ); - // Nautilus Extension - let script = Gio.File.new_for_path(nautScript); - - if (!script.query_exists(null)) { - GLib.mkdir_with_parents(nautDir, 493); // 0755 in octal + // Application Icon + GLib.mkdir_with_parents(iconDir, 493); + GLib.file_set_contents( + GLib.build_filenamev([iconDir, iconFull]), + zorin_connect.get_resource(`icons/${iconFull}`) + ); + GLib.file_set_contents( + GLib.build_filenamev([iconDir, iconSym]), + zorin_connect.get_resource(`icons/${iconSym}`) + ); - script.make_symbolic_link( - zorin_connect.extdatadir + '/nautilus-zorin-connect.py', - null - ); + // File Manager Extensions + for (let [dir, name] of fileManagers) { + let script = Gio.File.new_for_path(GLib.build_filenamev([dir, name])); + if (!script.query_exists(null)) { + GLib.mkdir_with_parents(dir, 493); + script.make_symbolic_link( + zorin_connect.extdatadir + '/nautilus-zorin-connect.py', + null + ); + } } // WebExtension Manifests @@ -228,11 +245,15 @@ } else { GLib.unlink(GLib.build_filenamev([dbusDir, dbusFile])); GLib.unlink(GLib.build_filenamev([desktopDir, desktopFile])); - GLib.unlink(nautScript); + GLib.unlink(GLib.build_filenamev([iconDir, iconFull])); + GLib.unlink(GLib.build_filenamev([iconDir, iconSym])); + + for (let [dir, name] of fileManagers) { + GLib.unlink(GLib.build_filenamev([dir, name])); + } for (let dir of Object.keys(manifests)) { GLib.unlink(GLib.build_filenamev([dir, manifestFile])); } } }; - diff -Nru gnome-shell-extension-zorin-connect-24.1/src/zorin-connect-preferences gnome-shell-extension-zorin-connect-28.0.2/src/zorin-connect-preferences --- gnome-shell-extension-zorin-connect-24.1/src/zorin-connect-preferences 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/src/zorin-connect-preferences 2019-11-30 00:56:17.000000000 +0000 @@ -0,0 +1,112 @@ +#!/usr/bin/env gjs + +'use strict'; + +const Gettext = imports.gettext.domain('org.gnome.Shell.Extensions.ZorinConnect'); +const _ = Gettext.gettext; +const System = imports.system; + +imports.gi.versions.Gdk = '3.0'; +imports.gi.versions.GdkPixbuf = '2.0'; +imports.gi.versions.Gio = '2.0'; +imports.gi.versions.GLib = '2.0'; +imports.gi.versions.GObject = '2.0'; +imports.gi.versions.Gtk = '3.0'; + +const Gdk = imports.gi.Gdk; +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; +const GObject = imports.gi.GObject; +const Gtk = imports.gi.Gtk; + +// Find the root datadir of the extension +function get_datadir() { + let m = /@(.+):\d+/.exec((new Error()).stack.split('\n')[1]); + return Gio.File.new_for_path(m[1]).get_parent().get_path(); +} + +window.zorin_connect = {extdatadir: get_datadir()}; +imports.searchPath.unshift(zorin_connect.extdatadir); +imports._zorin_connect; + +const Remote = imports.shell.remote; +const Settings = imports.preferences.service; + + +const Preferences = GObject.registerClass({ + GTypeName: 'ZorinConnectPreferences' +}, class Preferences extends Gtk.Application { + + _init() { + super._init({ + application_id: `${zorin_connect.app_id}.Preferences` + }); + + GLib.set_prgname(_('Zorin Connect Preferences')); + GLib.set_application_name(_('Zorin Connect Preferences')); + this.set_resource_base_path(zorin_connect.app_path); + } + + vfunc_activate() { + if (this._window === undefined) { + this._window = new Settings.Window({ + application: this + }); + } + + this._window.present(); + } + + vfunc_startup() { + super.vfunc_startup(); + + // Init some resources + let provider = new Gtk.CssProvider(); + provider.load_from_resource(zorin_connect.app_path + '/application.css'); + Gtk.StyleContext.add_provider_for_screen( + Gdk.Screen.get_default(), + provider, + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION + ); + + let actions = [ + ['refresh', null], + ['connect', GLib.VariantType.new('s')] + ]; + + for (let [name, type] of actions) { + let action = new Gio.SimpleAction({ + name: name, + parameter_type: type + }); + this.add_action(action); + } + } + + vfunc_activate_action(action_name, parameter) { + try { + let paramArray = []; + + if (parameter instanceof GLib.Variant) { + paramArray[0] = parameter; + } + + this.get_dbus_connection().call( + 'org.gnome.Shell.Extensions.ZorinConnect', + '/org/gnome/Shell/Extensions/ZorinConnect', + 'org.freedesktop.Application', + 'ActivateAction', + GLib.Variant.new('(sava{sv})', [action_name, paramArray, {}]), + null, + Gio.DBusCallFlags.NONE, + -1, + null, + null + ); + } catch (e) { + logError(e); + } + } +}); + +(new Preferences()).run([System.programInvocationName].concat(ARGV)); diff -Nru gnome-shell-extension-zorin-connect-24.1/webextension/gettext.js gnome-shell-extension-zorin-connect-28.0.2/webextension/gettext.js --- gnome-shell-extension-zorin-connect-24.1/webextension/gettext.js 2019-03-04 01:18:44.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/webextension/gettext.js 2019-11-30 14:32:40.000000000 +0000 @@ -82,7 +82,7 @@ let langCode = lang.replace('_', '-'); langCode = langCode.replace('@latin', '-Latn'); - print(`Processing "${lang}" as "${langCode}"`); + print(`Processing ${lang} as ${langCode}`); // Make a new dir and file let jsondir = localedir.get_child(langCode); diff -Nru gnome-shell-extension-zorin-connect-24.1/webextension/_locales/ar/messages.json gnome-shell-extension-zorin-connect-28.0.2/webextension/_locales/ar/messages.json --- gnome-shell-extension-zorin-connect-24.1/webextension/_locales/ar/messages.json 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/webextension/_locales/ar/messages.json 2019-11-30 14:38:45.000000000 +0000 @@ -0,0 +1,45 @@ +{ + "extensionName": { + "message": "Zorin Connect", + "description": "The extension name" + }, + "extensionDescription": { + "message": "Share links with Zorin Connect, direct to the browser or by SMS.", + "description": "The extension description" + }, + "contextMenuMultipleDevices": { + "message": "Send To Mobile Device", + "description": "Top-level Context Menu label when multiple devices are available" + }, + "contextMenuSinglePlugin": { + "message": "$NAME$ ($PLUGIN$)", + "description": "Context Menu label for devices that only support a single plugin", + "placeholders": { + "name": { + "content": "$1", + "example": "Nexus 4" + }, + "plugin": { + "content": "$2", + "example": "Open in Browser" + } + } + }, + "popupMenuDisconnected": { + "message": "الخدمة غير متاحة", + "description": "Popup Menu label when disconnected from the GNOME Shell extension" + }, + "popupMenuNoDevices": { + "message": "لم يتم العثور على أي جهاز", + "description": "Popup Menu label when no devices are connected or have supported plugins enabled" + }, + "shareMessage": { + "message": "فتح في المتصفح", + "description": "Context Menu label for opening a link in the device's web browser" + }, + "smsMessage": { + "message": "Send SMS", + "description": "Context Menu label for sharing a link in an SMS message" + } +} + diff -Nru gnome-shell-extension-zorin-connect-24.1/webextension/_locales/da/messages.json gnome-shell-extension-zorin-connect-28.0.2/webextension/_locales/da/messages.json --- gnome-shell-extension-zorin-connect-24.1/webextension/_locales/da/messages.json 2019-05-01 14:23:39.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/webextension/_locales/da/messages.json 2019-11-30 14:39:38.000000000 +0000 @@ -8,7 +8,7 @@ "description": "The extension description" }, "contextMenuMultipleDevices": { - "message": "Send To Mobile Device", + "message": "Send til Mobil Enhed", "description": "Top-level Context Menu label when multiple devices are available" }, "contextMenuSinglePlugin": { diff -Nru gnome-shell-extension-zorin-connect-24.1/webextension/_locales/de/messages.json gnome-shell-extension-zorin-connect-28.0.2/webextension/_locales/de/messages.json --- gnome-shell-extension-zorin-connect-24.1/webextension/_locales/de/messages.json 2019-03-04 01:23:58.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/webextension/_locales/de/messages.json 2019-11-30 14:39:54.000000000 +0000 @@ -4,7 +4,7 @@ "description": "The extension name" }, "extensionDescription": { - "message": "Teile Links über Zorin Connect, direkt an den Browser oder per SMS.", + "message": "Verweise mit Zorin Connect direkt an den Browser oder per SMS freigeben.", "description": "The extension description" }, "contextMenuMultipleDevices": { @@ -26,7 +26,7 @@ } }, "popupMenuDisconnected": { - "message": "Service nicht verfügbar", + "message": "Dienst nicht verfügbar", "description": "Popup Menu label when disconnected from the GNOME Shell extension" }, "popupMenuNoDevices": { diff -Nru gnome-shell-extension-zorin-connect-24.1/webextension/_locales/gl/messages.json gnome-shell-extension-zorin-connect-28.0.2/webextension/_locales/gl/messages.json --- gnome-shell-extension-zorin-connect-24.1/webextension/_locales/gl/messages.json 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/webextension/_locales/gl/messages.json 2019-11-30 14:41:13.000000000 +0000 @@ -0,0 +1,45 @@ +{ + "extensionName": { + "message": "Zorin Connect", + "description": "The extension name" + }, + "extensionDescription": { + "message": "Compartir ligazóns con Zorin Connect, directamente co navegador ou por SMS.", + "description": "The extension description" + }, + "contextMenuMultipleDevices": { + "message": "Enviar a dispositivo móbil", + "description": "Top-level Context Menu label when multiple devices are available" + }, + "contextMenuSinglePlugin": { + "message": "$NAME$ ($PLUGIN$)", + "description": "Context Menu label for devices that only support a single plugin", + "placeholders": { + "name": { + "content": "$1", + "example": "Nexus 4" + }, + "plugin": { + "content": "$2", + "example": "Open in Browser" + } + } + }, + "popupMenuDisconnected": { + "message": "Servizo non dispoñíbel", + "description": "Popup Menu label when disconnected from the GNOME Shell extension" + }, + "popupMenuNoDevices": { + "message": "Non se atopou o dispositivo", + "description": "Popup Menu label when no devices are connected or have supported plugins enabled" + }, + "shareMessage": { + "message": "Abrir no navegador", + "description": "Context Menu label for opening a link in the device's web browser" + }, + "smsMessage": { + "message": "Enviar SMS", + "description": "Context Menu label for sharing a link in an SMS message" + } +} + diff -Nru gnome-shell-extension-zorin-connect-24.1/webextension/_locales/sr/messages.json gnome-shell-extension-zorin-connect-28.0.2/webextension/_locales/sr/messages.json --- gnome-shell-extension-zorin-connect-24.1/webextension/_locales/sr/messages.json 2019-03-04 01:23:58.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/webextension/_locales/sr/messages.json 2019-11-30 14:42:58.000000000 +0000 @@ -4,7 +4,7 @@ "description": "The extension name" }, "extensionDescription": { - "message": "Дели везе ГСКонектом, директно у преглдач или путем СМС-а.", + "message": "Дели везе Zorin Connect, директно у преглдач или путем СМС-а.", "description": "The extension description" }, "contextMenuMultipleDevices": { diff -Nru gnome-shell-extension-zorin-connect-24.1/webextension/_locales/sr-Latn/messages.json gnome-shell-extension-zorin-connect-28.0.2/webextension/_locales/sr-Latn/messages.json --- gnome-shell-extension-zorin-connect-24.1/webextension/_locales/sr-Latn/messages.json 2019-03-04 01:23:58.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/webextension/_locales/sr-Latn/messages.json 2019-11-30 14:43:13.000000000 +0000 @@ -4,7 +4,7 @@ "description": "The extension name" }, "extensionDescription": { - "message": "Deli veze GSKonektom, direktno u pregldač ili putem SMS-a.", + "message": "Deli veze Zorin Connect, direktno u pregldač ili putem SMS-a.", "description": "The extension description" }, "contextMenuMultipleDevices": { diff -Nru gnome-shell-extension-zorin-connect-24.1/webextension/_locales/zh-CN/messages.json gnome-shell-extension-zorin-connect-28.0.2/webextension/_locales/zh-CN/messages.json --- gnome-shell-extension-zorin-connect-24.1/webextension/_locales/zh-CN/messages.json 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/webextension/_locales/zh-CN/messages.json 2019-11-30 14:43:35.000000000 +0000 @@ -0,0 +1,45 @@ +{ + "extensionName": { + "message": "Zorin Connect", + "description": "The extension name" + }, + "extensionDescription": { + "message": "与 Zorin Connect 共享链接,直接发送到浏览器或短信。", + "description": "The extension description" + }, + "contextMenuMultipleDevices": { + "message": "发送到移动设备", + "description": "Top-level Context Menu label when multiple devices are available" + }, + "contextMenuSinglePlugin": { + "message": "$NAME$ ($PLUGIN$)", + "description": "Context Menu label for devices that only support a single plugin", + "placeholders": { + "name": { + "content": "$1", + "example": "Nexus 4" + }, + "plugin": { + "content": "$2", + "example": "Open in Browser" + } + } + }, + "popupMenuDisconnected": { + "message": "服务不可用", + "description": "Popup Menu label when disconnected from the GNOME Shell extension" + }, + "popupMenuNoDevices": { + "message": "没有找到设备", + "description": "Popup Menu label when no devices are connected or have supported plugins enabled" + }, + "shareMessage": { + "message": "在浏览器中打开", + "description": "Context Menu label for opening a link in the device's web browser" + }, + "smsMessage": { + "message": "发送短信", + "description": "Context Menu label for sharing a link in an SMS message" + } +} + diff -Nru gnome-shell-extension-zorin-connect-24.1/webextension/_locales/zh-TW/messages.json gnome-shell-extension-zorin-connect-28.0.2/webextension/_locales/zh-TW/messages.json --- gnome-shell-extension-zorin-connect-24.1/webextension/_locales/zh-TW/messages.json 1970-01-01 00:00:00.000000000 +0000 +++ gnome-shell-extension-zorin-connect-28.0.2/webextension/_locales/zh-TW/messages.json 2019-11-30 14:43:41.000000000 +0000 @@ -0,0 +1,45 @@ +{ + "extensionName": { + "message": "Zorin Connect", + "description": "The extension name" + }, + "extensionDescription": { + "message": "直接用瀏覽器或經由簡訊和 Zorin Connect 共享鏈結", + "description": "The extension description" + }, + "contextMenuMultipleDevices": { + "message": "傳送到手機", + "description": "Top-level Context Menu label when multiple devices are available" + }, + "contextMenuSinglePlugin": { + "message": "$NAME$ ($PLUGIN$)", + "description": "Context Menu label for devices that only support a single plugin", + "placeholders": { + "name": { + "content": "$1", + "example": "Nexus 4" + }, + "plugin": { + "content": "$2", + "example": "Open in Browser" + } + } + }, + "popupMenuDisconnected": { + "message": "服務無法使用", + "description": "Popup Menu label when disconnected from the GNOME Shell extension" + }, + "popupMenuNoDevices": { + "message": "找不到裝置", + "description": "Popup Menu label when no devices are connected or have supported plugins enabled" + }, + "shareMessage": { + "message": "以瀏覽器開啟", + "description": "Context Menu label for opening a link in the device's web browser" + }, + "smsMessage": { + "message": "發送簡訊", + "description": "Context Menu label for sharing a link in an SMS message" + } +} +