diff --git a/po/POTFILES.in b/po/POTFILES.in index bdb26a90e9b..951bb90e62d 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -76,12 +76,14 @@ src/plugins/sftp/valent-sftp-plugin.c src/plugins/sftp/valent-sftp-preferences.c src/plugins/sftp/valent-sftp-preferences.ui src/plugins/share/share.plugin.desktop.in +src/plugins/share/valent-share-dialog.c +src/plugins/share/valent-share-dialog.ui +src/plugins/share/valent-share-dialog-row.c +src/plugins/share/valent-share-dialog-row.ui src/plugins/share/valent-share-plugin.c src/plugins/share/valent-share-plugin.c src/plugins/share/valent-share-preferences.c src/plugins/share/valent-share-preferences.ui -src/plugins/share/valent-share-target-chooser.c -src/plugins/share/valent-share-target-chooser.ui src/plugins/share/valent-share-text-dialog.c src/plugins/share/valent-share-text-dialog.ui src/plugins/sms/sms.plugin.desktop.in diff --git a/po/en.po b/po/en.po index be9cab58455..c3de7dc2719 100644 --- a/po/en.po +++ b/po/en.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: valent\n" "Report-Msgid-Bugs-To: https://github.com/andyholmes/valent/issues\n" -"POT-Creation-Date: 2023-09-29 20:31-0700\n" +"POT-Creation-Date: 2023-09-30 20:16-0700\n" "PO-Revision-Date: 2022-03-28 11:21-0700\n" "Last-Translator: Andy Holmes \n" "Language-Team: English \n" @@ -464,7 +464,8 @@ msgid "Main Menu" msgstr "" #: src/libvalent/ui/valent-window.ui:85 src/libvalent/ui/valent-window.ui:100 -#: src/plugins/share/valent-share-target-chooser.ui:68 +#: src/plugins/share/valent-share-dialog.ui:161 +#: src/plugins/share/valent-share-dialog.ui:178 msgid "Devices" msgstr "" @@ -736,7 +737,6 @@ msgstr "" #: src/plugins/notification/valent-notification-dialog.ui:19 #: src/plugins/runcommand/valent-runcommand-editor.ui:17 -#: src/plugins/share/valent-share-target-chooser.ui:22 msgid "_Cancel" msgstr "" @@ -1034,11 +1034,14 @@ msgstr[0] "" msgstr[1] "" #: src/plugins/share/valent-share-plugin.c:671 -#: src/plugins/share/valent-share-target-chooser.ui:8 msgid "Share Files" msgstr "" #: src/plugins/share/valent-share-plugin.c:672 +#: src/plugins/share/valent-share-dialog.ui:8 +#: src/plugins/share/valent-share-dialog.ui:29 +#: src/plugins/share/valent-share-dialog.ui:40 +#: src/plugins/share/valent-share-dialog.ui:112 msgid "Share" msgstr "" @@ -1058,20 +1061,48 @@ msgstr "" msgid "Where received files are stored" msgstr "" -#: src/plugins/share/valent-share-target-chooser.ui:29 -msgid "_Share" +#: src/plugins/share/valent-share-dialog.c:261 +#, c-format +msgid "Size: %s" +msgstr "" + +#: src/plugins/share/valent-share-dialog.c:294 +#, c-format +msgid "%u files and links" +msgstr "" + +#: src/plugins/share/valent-share-dialog.c:305 +#, c-format +msgid "%u files" +msgstr "" + +#: src/plugins/share/valent-share-dialog.c:315 +#, c-format +msgid "%u links" msgstr "" -#: src/plugins/share/valent-share-target-chooser.ui:58 -msgid "Choose a device to share the selected files with." +#: src/plugins/share/valent-share-dialog.ui:41 +msgid "Select files, enter a link or paste text" msgstr "" -#: src/plugins/share/valent-share-target-chooser.ui:86 +#: src/plugins/share/valent-share-dialog.ui:50 +msgid "Pick Files" +msgstr "" + +#: src/plugins/share/valent-share-dialog.ui:75 +msgid "Enter URL" +msgstr "" + +#: src/plugins/share/valent-share-dialog.ui:165 +msgid "Share with multiple devices" +msgstr "" + +#: src/plugins/share/valent-share-dialog.ui:192 msgid "Searching…" msgstr "" -#: src/plugins/share/valent-share-target-chooser.ui:128 -msgid "Always use this device" +#: src/plugins/share/valent-share-dialog.ui:215 +msgid "_Share" msgstr "" #: src/plugins/share/valent-share-text-dialog.c:98 diff --git a/po/fr.po b/po/fr.po index 17c1bcbd511..3b2f8f8f5ab 100644 --- a/po/fr.po +++ b/po/fr.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: valent\n" "Report-Msgid-Bugs-To: https://github.com/andyholmes/valent/issues\n" -"POT-Creation-Date: 2023-09-29 20:31-0700\n" +"POT-Creation-Date: 2023-09-30 20:16-0700\n" "PO-Revision-Date: 2023-03-04 17:28+0100\n" "Last-Translator: Valérie Roux \n" "Language-Team: French \n" @@ -483,7 +483,8 @@ msgid "Main Menu" msgstr "Nom de l'appareil" #: src/libvalent/ui/valent-window.ui:85 src/libvalent/ui/valent-window.ui:100 -#: src/plugins/share/valent-share-target-chooser.ui:68 +#: src/plugins/share/valent-share-dialog.ui:161 +#: src/plugins/share/valent-share-dialog.ui:178 msgid "Devices" msgstr "Appareils" @@ -770,7 +771,6 @@ msgstr "Notification" #: src/plugins/notification/valent-notification-dialog.ui:19 #: src/plugins/runcommand/valent-runcommand-editor.ui:17 -#: src/plugins/share/valent-share-target-chooser.ui:22 msgid "_Cancel" msgstr "Annuler" @@ -1090,11 +1090,14 @@ msgstr[0] "Un fichier envoyé vers %1$s" msgstr[1] "%2$d fichiers envoyés vers %1$s" #: src/plugins/share/valent-share-plugin.c:671 -#: src/plugins/share/valent-share-target-chooser.ui:8 msgid "Share Files" msgstr "Partager des fichiers" #: src/plugins/share/valent-share-plugin.c:672 +#: src/plugins/share/valent-share-dialog.ui:8 +#: src/plugins/share/valent-share-dialog.ui:29 +#: src/plugins/share/valent-share-dialog.ui:40 +#: src/plugins/share/valent-share-dialog.ui:112 msgid "Share" msgstr "Partager" @@ -1114,21 +1117,52 @@ msgstr "Dossier de téléchargement" msgid "Where received files are stored" msgstr "Où les fichiers entrants sont stockés" -#: src/plugins/share/valent-share-target-chooser.ui:29 -msgid "_Share" -msgstr "Partager" +#: src/plugins/share/valent-share-dialog.c:261 +#, c-format +msgid "Size: %s" +msgstr "" + +#: src/plugins/share/valent-share-dialog.c:294 +#, c-format +msgid "%u files and links" +msgstr "" + +#: src/plugins/share/valent-share-dialog.c:305 +#, fuzzy, c-format +msgid "%u files" +msgstr "Tous les fichiers" + +#: src/plugins/share/valent-share-dialog.c:315 +#, c-format +msgid "%u links" +msgstr "" + +#: src/plugins/share/valent-share-dialog.ui:41 +#, fuzzy +msgid "Select files, enter a link or paste text" +msgstr "Partagez des fichiers, des liens et du texte" -#: src/plugins/share/valent-share-target-chooser.ui:58 -msgid "Choose a device to share the selected files with." -msgstr "Choisissez un appareil auquel partager les fichiers seléctionnés." +#: src/plugins/share/valent-share-dialog.ui:50 +#, fuzzy +msgid "Pick Files" +msgstr "Système de fichiers local" -#: src/plugins/share/valent-share-target-chooser.ui:86 +#: src/plugins/share/valent-share-dialog.ui:75 +msgid "Enter URL" +msgstr "" + +#: src/plugins/share/valent-share-dialog.ui:165 +#, fuzzy +msgid "Share with multiple devices" +msgstr "Prendre une photo avec l'appareil distant" + +#: src/plugins/share/valent-share-dialog.ui:192 msgid "Searching…" msgstr "Recherche..." -#: src/plugins/share/valent-share-target-chooser.ui:128 -msgid "Always use this device" -msgstr "Toujours utiliser cet appareil" +#: src/plugins/share/valent-share-dialog.ui:215 +msgid "_Share" +msgstr "Partager" #: src/plugins/share/valent-share-text-dialog.c:98 #: src/plugins/share/valent-share-text-dialog.ui:54 @@ -1363,5 +1397,11 @@ msgstr "Portails" msgid "Integration with desktop portals" msgstr "Intégration avec les portails de bureau" +#~ msgid "Always use this device" +#~ msgstr "Toujours utiliser cet appareil" + +#~ msgid "Choose a device to share the selected files with." +#~ msgstr "Choisissez un appareil auquel partager les fichiers seléctionnés." + #~ msgid "Applications" #~ msgstr "Applications" diff --git a/po/nl.po b/po/nl.po index b9ac661a045..4c6590d6486 100644 --- a/po/nl.po +++ b/po/nl.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: valent\n" "Report-Msgid-Bugs-To: https://github.com/andyholmes/valent/issues\n" -"POT-Creation-Date: 2023-09-29 20:31-0700\n" +"POT-Creation-Date: 2023-09-30 20:16-0700\n" "PO-Revision-Date: 2022-09-12 19:59+0200\n" "Last-Translator: Heimen Stoffels \n" "Language-Team: Dutch\n" @@ -477,7 +477,8 @@ msgid "Main Menu" msgstr "Apparaatnaam" #: src/libvalent/ui/valent-window.ui:85 src/libvalent/ui/valent-window.ui:100 -#: src/plugins/share/valent-share-target-chooser.ui:68 +#: src/plugins/share/valent-share-dialog.ui:161 +#: src/plugins/share/valent-share-dialog.ui:178 msgid "Devices" msgstr "Apparaten" @@ -764,7 +765,6 @@ msgstr "Melding" #: src/plugins/notification/valent-notification-dialog.ui:19 #: src/plugins/runcommand/valent-runcommand-editor.ui:17 -#: src/plugins/share/valent-share-target-chooser.ui:22 msgid "_Cancel" msgstr "_Annuleren" @@ -1085,11 +1085,14 @@ msgstr[0] "Eén bestand verstuurd naar %1$s" msgstr[1] "%2$d bestanden verstuurd naar %1$s" #: src/plugins/share/valent-share-plugin.c:671 -#: src/plugins/share/valent-share-target-chooser.ui:8 msgid "Share Files" msgstr "Bestanden delen" #: src/plugins/share/valent-share-plugin.c:672 +#: src/plugins/share/valent-share-dialog.ui:8 +#: src/plugins/share/valent-share-dialog.ui:29 +#: src/plugins/share/valent-share-dialog.ui:40 +#: src/plugins/share/valent-share-dialog.ui:112 msgid "Share" msgstr "Delen" @@ -1109,23 +1112,54 @@ msgstr "Downloadmap" msgid "Where received files are stored" msgstr "Waar ontvangen bestanden dienen te worden opgeslagen" -#: src/plugins/share/valent-share-target-chooser.ui:29 +#: src/plugins/share/valent-share-dialog.c:261 +#, c-format +msgid "Size: %s" +msgstr "" + +#: src/plugins/share/valent-share-dialog.c:294 +#, c-format +msgid "%u files and links" +msgstr "" + +#: src/plugins/share/valent-share-dialog.c:305 +#, fuzzy, c-format +msgid "%u files" +msgstr "Alle bestanden" + +#: src/plugins/share/valent-share-dialog.c:315 +#, c-format +msgid "%u links" +msgstr "" + +#: src/plugins/share/valent-share-dialog.ui:41 #, fuzzy -msgid "_Share" -msgstr "Delen" +msgid "Select files, enter a link or paste text" +msgstr "Deel bestanden, links en tekst" + +#: src/plugins/share/valent-share-dialog.ui:50 +#, fuzzy +msgid "Pick Files" +msgstr "Lokaal bestandssysteem" -#: src/plugins/share/valent-share-target-chooser.ui:58 -msgid "Choose a device to share the selected files with." +#: src/plugins/share/valent-share-dialog.ui:75 +msgid "Enter URL" msgstr "" -#: src/plugins/share/valent-share-target-chooser.ui:86 +#: src/plugins/share/valent-share-dialog.ui:165 +#, fuzzy +msgid "Share with multiple devices" +msgstr "Maak een foto met het externe apparaat" + +#: src/plugins/share/valent-share-dialog.ui:192 #, fuzzy msgid "Searching…" msgstr "Bezig met zoeken naar apparaten…" -#: src/plugins/share/valent-share-target-chooser.ui:128 -msgid "Always use this device" -msgstr "" +#: src/plugins/share/valent-share-dialog.ui:215 +#, fuzzy +msgid "_Share" +msgstr "Delen" #: src/plugins/share/valent-share-text-dialog.c:98 #: src/plugins/share/valent-share-text-dialog.ui:54 diff --git a/po/valent.pot b/po/valent.pot index 2d38ee4f331..e7825537680 100644 --- a/po/valent.pot +++ b/po/valent.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: valent\n" "Report-Msgid-Bugs-To: https://github.com/andyholmes/valent/issues\n" -"POT-Creation-Date: 2023-09-29 20:31-0700\n" +"POT-Creation-Date: 2023-09-30 20:16-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -464,7 +464,8 @@ msgid "Main Menu" msgstr "" #: src/libvalent/ui/valent-window.ui:85 src/libvalent/ui/valent-window.ui:100 -#: src/plugins/share/valent-share-target-chooser.ui:68 +#: src/plugins/share/valent-share-dialog.ui:161 +#: src/plugins/share/valent-share-dialog.ui:178 msgid "Devices" msgstr "" @@ -736,7 +737,6 @@ msgstr "" #: src/plugins/notification/valent-notification-dialog.ui:19 #: src/plugins/runcommand/valent-runcommand-editor.ui:17 -#: src/plugins/share/valent-share-target-chooser.ui:22 msgid "_Cancel" msgstr "" @@ -1034,11 +1034,14 @@ msgstr[0] "" msgstr[1] "" #: src/plugins/share/valent-share-plugin.c:671 -#: src/plugins/share/valent-share-target-chooser.ui:8 msgid "Share Files" msgstr "" #: src/plugins/share/valent-share-plugin.c:672 +#: src/plugins/share/valent-share-dialog.ui:8 +#: src/plugins/share/valent-share-dialog.ui:29 +#: src/plugins/share/valent-share-dialog.ui:40 +#: src/plugins/share/valent-share-dialog.ui:112 msgid "Share" msgstr "" @@ -1058,20 +1061,48 @@ msgstr "" msgid "Where received files are stored" msgstr "" -#: src/plugins/share/valent-share-target-chooser.ui:29 -msgid "_Share" +#: src/plugins/share/valent-share-dialog.c:261 +#, c-format +msgid "Size: %s" +msgstr "" + +#: src/plugins/share/valent-share-dialog.c:294 +#, c-format +msgid "%u files and links" +msgstr "" + +#: src/plugins/share/valent-share-dialog.c:305 +#, c-format +msgid "%u files" +msgstr "" + +#: src/plugins/share/valent-share-dialog.c:315 +#, c-format +msgid "%u links" msgstr "" -#: src/plugins/share/valent-share-target-chooser.ui:58 -msgid "Choose a device to share the selected files with." +#: src/plugins/share/valent-share-dialog.ui:41 +msgid "Select files, enter a link or paste text" msgstr "" -#: src/plugins/share/valent-share-target-chooser.ui:86 +#: src/plugins/share/valent-share-dialog.ui:50 +msgid "Pick Files" +msgstr "" + +#: src/plugins/share/valent-share-dialog.ui:75 +msgid "Enter URL" +msgstr "" + +#: src/plugins/share/valent-share-dialog.ui:165 +msgid "Share with multiple devices" +msgstr "" + +#: src/plugins/share/valent-share-dialog.ui:192 msgid "Searching…" msgstr "" -#: src/plugins/share/valent-share-target-chooser.ui:128 -msgid "Always use this device" +#: src/plugins/share/valent-share-dialog.ui:215 +msgid "_Share" msgstr "" #: src/plugins/share/valent-share-text-dialog.c:98 diff --git a/po/zh_CN.po b/po/zh_CN.po index 8c6357c2d0c..8ced0eccfb9 100755 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: valent\n" "Report-Msgid-Bugs-To: https://github.com/andyholmes/valent/issues\n" -"POT-Creation-Date: 2023-09-29 20:31-0700\n" +"POT-Creation-Date: 2023-09-30 20:16-0700\n" "PO-Revision-Date: 2023-07-03 19:05+0800\n" "Last-Translator: sky96111 \n" "Language-Team: Chinese Simplified\n" @@ -470,7 +470,8 @@ msgid "Main Menu" msgstr "主菜单" #: src/libvalent/ui/valent-window.ui:85 src/libvalent/ui/valent-window.ui:100 -#: src/plugins/share/valent-share-target-chooser.ui:68 +#: src/plugins/share/valent-share-dialog.ui:161 +#: src/plugins/share/valent-share-dialog.ui:178 msgid "Devices" msgstr "设备" @@ -742,7 +743,6 @@ msgstr "通知" #: src/plugins/notification/valent-notification-dialog.ui:19 #: src/plugins/runcommand/valent-runcommand-editor.ui:17 -#: src/plugins/share/valent-share-target-chooser.ui:22 msgid "_Cancel" msgstr "" @@ -1037,11 +1037,14 @@ msgid_plural "Sent %2$d files to %1$s" msgstr[0] "已发送 %2$d 文件到 %1$s" #: src/plugins/share/valent-share-plugin.c:671 -#: src/plugins/share/valent-share-target-chooser.ui:8 msgid "Share Files" msgstr "共享文件" #: src/plugins/share/valent-share-plugin.c:672 +#: src/plugins/share/valent-share-dialog.ui:8 +#: src/plugins/share/valent-share-dialog.ui:29 +#: src/plugins/share/valent-share-dialog.ui:40 +#: src/plugins/share/valent-share-dialog.ui:112 msgid "Share" msgstr "发送" @@ -1061,21 +1064,52 @@ msgstr "下载目录" msgid "Where received files are stored" msgstr "收到的文件储存位置" -#: src/plugins/share/valent-share-target-chooser.ui:29 -msgid "_Share" +#: src/plugins/share/valent-share-dialog.c:261 +#, c-format +msgid "Size: %s" +msgstr "" + +#: src/plugins/share/valent-share-dialog.c:294 +#, c-format +msgid "%u files and links" +msgstr "" + +#: src/plugins/share/valent-share-dialog.c:305 +#, fuzzy, c-format +msgid "%u files" +msgstr "文件" + +#: src/plugins/share/valent-share-dialog.c:315 +#, c-format +msgid "%u links" +msgstr "" + +#: src/plugins/share/valent-share-dialog.ui:41 +#, fuzzy +msgid "Select files, enter a link or paste text" +msgstr "分享文件、链接和文本" + +#: src/plugins/share/valent-share-dialog.ui:50 +#, fuzzy +msgid "Pick Files" +msgstr "本地文件" + +#: src/plugins/share/valent-share-dialog.ui:75 +msgid "Enter URL" msgstr "" -#: src/plugins/share/valent-share-target-chooser.ui:58 -msgid "Choose a device to share the selected files with." -msgstr "选择一个设备来分享所选文件。" +#: src/plugins/share/valent-share-dialog.ui:165 +#, fuzzy +msgid "Share with multiple devices" +msgstr "与远程设备共享联系人" -#: src/plugins/share/valent-share-target-chooser.ui:86 +#: src/plugins/share/valent-share-dialog.ui:192 msgid "Searching…" msgstr "搜索中..." -#: src/plugins/share/valent-share-target-chooser.ui:128 -msgid "Always use this device" -msgstr "始终使用这个装置" +#: src/plugins/share/valent-share-dialog.ui:215 +msgid "_Share" +msgstr "" #: src/plugins/share/valent-share-text-dialog.c:98 #: src/plugins/share/valent-share-text-dialog.ui:54 @@ -1305,5 +1339,11 @@ msgstr "桌面环境" msgid "Integration with desktop portals" msgstr "与桌面环境集成" +#~ msgid "Always use this device" +#~ msgstr "始终使用这个装置" + +#~ msgid "Choose a device to share the selected files with." +#~ msgstr "选择一个设备来分享所选文件。" + #~ msgid "Applications" #~ msgstr "应用" diff --git a/src/plugins/share/data/share-file-symbolic.svg b/src/plugins/share/data/share-file-symbolic.svg new file mode 100644 index 00000000000..201457c428e --- /dev/null +++ b/src/plugins/share/data/share-file-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/src/plugins/share/data/share-link-symbolic.svg b/src/plugins/share/data/share-link-symbolic.svg new file mode 100644 index 00000000000..1d5fefea3c0 --- /dev/null +++ b/src/plugins/share/data/share-link-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/src/plugins/share/data/share-symbolic.svg b/src/plugins/share/data/share-symbolic.svg new file mode 100644 index 00000000000..08551f53c83 --- /dev/null +++ b/src/plugins/share/data/share-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/src/plugins/share/meson.build b/src/plugins/share/meson.build index 569a3a5523c..482a01fcd56 100644 --- a/src/plugins/share/meson.build +++ b/src/plugins/share/meson.build @@ -9,11 +9,12 @@ plugin_share_deps = [ # Sources plugin_share_sources = files([ 'share-plugin.c', + 'valent-share-dialog.c', + 'valent-share-dialog-row.c', 'valent-share-download.c', 'valent-share-plugin.c', 'valent-share-preferences.c', 'valent-share-target.c', - 'valent-share-target-chooser.c', 'valent-share-text-dialog.c', 'valent-share-upload.c', ]) diff --git a/src/plugins/share/share.gresource.xml b/src/plugins/share/share.gresource.xml index 72856749c11..8c7ccf3f5e6 100644 --- a/src/plugins/share/share.gresource.xml +++ b/src/plugins/share/share.gresource.xml @@ -6,12 +6,16 @@ share.plugin + valent-share-dialog.ui + valent-share-dialog-row.ui valent-share-preferences.ui - valent-share-target-chooser.ui valent-share-text-dialog.ui data/document-send-symbolic.svg + data/share-file-symbolic.svg + data/share-link-symbolic.svg + data/share-symbolic.svg data/valent-share-plugin-symbolic.svg diff --git a/src/plugins/share/valent-share-dialog-row.c b/src/plugins/share/valent-share-dialog-row.c new file mode 100644 index 00000000000..d2bf183ee37 --- /dev/null +++ b/src/plugins/share/valent-share-dialog-row.c @@ -0,0 +1,348 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: Andy Holmes + +#define G_LOG_DOMAIN "valent-share-dialog-row" + +#include "config.h" + +#include +#include +#include + +#include "valent-share-dialog-row.h" + + +struct _ValentShareDialogRow +{ + GtkListBoxRow parent_instance; + + ValentDevice *device; + AdwAnimation *animation; + unsigned int selected : 1; + unsigned int selection_mode : 1; + + /* template */ + GtkRevealer *revealer; + GtkCheckButton *selected_button; + GtkImage *icon_image; + GtkLabel *name_label; + GtkImage *next_image; +}; + +G_DEFINE_FINAL_TYPE (ValentShareDialogRow, valent_share_dialog_row, GTK_TYPE_LIST_BOX_ROW) + + +enum { + PROP_0, + PROP_DEVICE, + PROP_SELECTED, + PROP_SELECTION_MODE, + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + + +static void +on_selection_enable (ValentShareDialogRow *self) +{ + GtkRoot *root = NULL; + + if (self->selection_mode) + return; + + if ((root = gtk_widget_get_root (GTK_WIDGET (self))) == NULL) + return; + + g_object_set (root, "selection-mode", TRUE, NULL); + valent_share_dialog_row_set_selected (self, TRUE); +} + +static void +on_selection_disable (ValentShareDialogRow *self) +{ + if (!gtk_revealer_get_child_revealed (self->revealer)) + valent_share_dialog_row_set_selected (self, FALSE); +} + +/* + * ValentShareDialogRow + */ +static void +valent_share_dialog_row_set_device (ValentShareDialogRow *self, + ValentDevice *device) +{ + g_assert (VALENT_IS_SHARE_DIALOG_ROW (self)); + g_assert (device == NULL || VALENT_IS_DEVICE (device)); + + if (!g_set_object (&self->device, device)) + return; + + g_object_bind_property (device, "icon-name", + self->icon_image, "icon-name", + G_BINDING_SYNC_CREATE); + g_object_bind_property (device, "name", + self->name_label, "label", + G_BINDING_SYNC_CREATE); + + g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_DEVICE]); +} + +/* + * GObject + */ +static void +valent_share_dialog_row_dispose (GObject *object) +{ + ValentShareDialogRow *self = VALENT_SHARE_DIALOG_ROW (object); + + if (self->animation != NULL) + { + adw_animation_skip (self->animation); + g_clear_object (&self->animation); + } + + g_clear_object (&self->device); + gtk_widget_dispose_template (GTK_WIDGET (self), VALENT_TYPE_SHARE_DIALOG_ROW); + + G_OBJECT_CLASS (valent_share_dialog_row_parent_class)->dispose (object); +} + +static void +valent_share_dialog_row_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ValentShareDialogRow *self = VALENT_SHARE_DIALOG_ROW (object); + + switch (prop_id) + { + case PROP_DEVICE: + g_value_set_object (value, self->device); + break; + + case PROP_SELECTED: + g_value_set_boolean (value, self->selected); + break; + + case PROP_SELECTION_MODE: + g_value_set_boolean (value, self->selection_mode); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +valent_share_dialog_row_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ValentShareDialogRow *self = VALENT_SHARE_DIALOG_ROW (object); + + switch (prop_id) + { + case PROP_DEVICE: + valent_share_dialog_row_set_device (self, g_value_get_object (value)); + break; + + case PROP_SELECTED: + valent_share_dialog_row_set_selected (self, g_value_get_boolean (value)); + break; + + case PROP_SELECTION_MODE: + valent_share_dialog_row_set_selection_mode (self, g_value_get_boolean (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +valent_share_dialog_row_class_init (ValentShareDialogRowClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->dispose = valent_share_dialog_row_dispose; + object_class->get_property = valent_share_dialog_row_get_property; + object_class->set_property = valent_share_dialog_row_set_property; + + /** + * ValentShareDialogRow:device: (getter get_device) + * + * The [class@Valent.Device] this row displays. + */ + properties [PROP_DEVICE] = + g_param_spec_object ("device", NULL, NULL, + VALENT_TYPE_DEVICE, + (G_PARAM_READWRITE | + G_PARAM_EXPLICIT_NOTIFY | + G_PARAM_STATIC_STRINGS)); + + /** + * ValentShareDialogRow:selected: (getter get_selected) (setter set_selected) + * + * Whether the row is selected. + */ + properties [PROP_SELECTED] = + g_param_spec_boolean ("selected", NULL, NULL, + FALSE, + (G_PARAM_READWRITE | + G_PARAM_EXPLICIT_NOTIFY | + G_PARAM_STATIC_STRINGS)); + + /** + * ValentShareDialogRow:selection-mode: (getter get_selection_mode) (setter set_selection_mode) + * + * Whether the row is in selection mode. + */ + properties [PROP_SELECTION_MODE] = + g_param_spec_boolean ("selection-mode", NULL, NULL, + FALSE, + (G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_EXPLICIT_NOTIFY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); + + gtk_widget_class_set_template_from_resource (widget_class, "/plugins/share/valent-share-dialog-row.ui"); + gtk_widget_class_bind_template_child (widget_class, ValentShareDialogRow, revealer); + gtk_widget_class_bind_template_child (widget_class, ValentShareDialogRow, selected_button); + gtk_widget_class_bind_template_child (widget_class, ValentShareDialogRow, icon_image); + gtk_widget_class_bind_template_child (widget_class, ValentShareDialogRow, name_label); + gtk_widget_class_bind_template_child (widget_class, ValentShareDialogRow, next_image); + gtk_widget_class_bind_template_callback (widget_class, on_selection_enable); + gtk_widget_class_bind_template_callback (widget_class, on_selection_disable); +} + +static void +valent_share_dialog_row_init (ValentShareDialogRow *self) +{ + AdwAnimationTarget *target = NULL; + + gtk_widget_init_template (GTK_WIDGET (self)); + + target = adw_property_animation_target_new (G_OBJECT (self->next_image), + "opacity"); + self->animation = adw_timed_animation_new (GTK_WIDGET (self), + 0.0, 1.0, 250, + target); +} + +/** + * valent_share_dialog_row_get_device: (set-property device) + * @row: a `ValentShareDialogRow` + * + * Get the device. + * + * Returns: (transfer none) (nullable): a `ValentDevice` + */ +ValentDevice * +valent_share_dialog_row_get_device (ValentShareDialogRow *row) +{ + g_return_val_if_fail (VALENT_IS_SHARE_DIALOG_ROW (row), NULL); + + return row->device; +} + +/** + * valent_share_dialog_row_get_selected: (get-property selected) + * @row: a `ValentShareDialogRow` + * + * Get whether the row is selected. + * + * Returns: %TRUE if the row is selected, or %FALSE if not + */ +gboolean +valent_share_dialog_row_get_selected (ValentShareDialogRow *row) +{ + g_return_val_if_fail (VALENT_IS_SHARE_DIALOG_ROW (row), FALSE); + + return row->selected; +} + +/** + * valent_share_dialog_row_set_selected: (set-property selected) + * @row: a `ValentShareDialogRow` + * @selected: whether to select the row + * + * Set whether the row is selected. + */ +void +valent_share_dialog_row_set_selected (ValentShareDialogRow *row, + gboolean selected) +{ + g_return_if_fail (VALENT_IS_SHARE_DIALOG_ROW (row)); + + selected = !!selected; + if (row->selected == selected) + return; + + gtk_accessible_update_state (GTK_ACCESSIBLE (row), + GTK_ACCESSIBLE_STATE_SELECTED, selected, + -1); + + row->selected = selected; + g_object_notify_by_pspec (G_OBJECT (row), properties [PROP_SELECTED]); +} + +/** + * valent_share_dialog_row_get_selection_mode: + * @row: a `ValentShareDialogRow` + * + * Get whether selection mode is enabled. + * + * Returns: %TRUE if selection mode is enabled, or %FALSE if not + */ +gboolean +valent_share_dialog_row_get_selection_mode (ValentShareDialogRow *row) +{ + g_return_val_if_fail (VALENT_IS_SHARE_DIALOG_ROW (row), FALSE); + + return row->selection_mode; +} + +/** + * valent_share_dialog_row_set_selection_mode: (set-property selection-mode) + * @row: a `ValentShareDialogRow` + * @selection_mode: whether to select the row + * + * Set whether selection mode is enabled. + */ +void +valent_share_dialog_row_set_selection_mode (ValentShareDialogRow *row, + gboolean selection_mode) +{ + g_return_if_fail (VALENT_IS_SHARE_DIALOG_ROW (row)); + + selection_mode = !!selection_mode; + if (row->selection_mode == selection_mode) + return; + + if (selection_mode) + { + gtk_accessible_update_state (GTK_ACCESSIBLE (row), + GTK_ACCESSIBLE_STATE_SELECTED, FALSE, + -1); + } + else + { + gtk_accessible_reset_state (GTK_ACCESSIBLE (row), + GTK_ACCESSIBLE_STATE_SELECTED); + } + + adw_animation_skip (row->animation); + adw_timed_animation_set_reverse (ADW_TIMED_ANIMATION (row->animation), + selection_mode); + adw_animation_play (row->animation); + + row->selection_mode = selection_mode; + g_object_notify_by_pspec (G_OBJECT (row), properties [PROP_SELECTION_MODE]); +} + diff --git a/src/plugins/share/valent-share-dialog-row.h b/src/plugins/share/valent-share-dialog-row.h new file mode 100644 index 00000000000..43d8f73c4cb --- /dev/null +++ b/src/plugins/share/valent-share-dialog-row.h @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: Andy Holmes + +#pragma once + +#include + +G_BEGIN_DECLS + +#define VALENT_TYPE_SHARE_DIALOG_ROW (valent_share_dialog_row_get_type()) + +G_DECLARE_FINAL_TYPE (ValentShareDialogRow, valent_share_dialog_row, VALENT, SHARE_DIALOG_ROW, GtkListBoxRow) + +ValentDevice * valent_share_dialog_row_get_device (ValentShareDialogRow *row); +gboolean valent_share_dialog_row_get_selected (ValentShareDialogRow *row); +void valent_share_dialog_row_set_selected (ValentShareDialogRow *row, + gboolean selected); +gboolean valent_share_dialog_row_get_selection_mode (ValentShareDialogRow *row); +void valent_share_dialog_row_set_selection_mode (ValentShareDialogRow *row, + gboolean selection_mode); + +G_END_DECLS diff --git a/src/plugins/share/valent-share-dialog-row.ui b/src/plugins/share/valent-share-dialog-row.ui new file mode 100644 index 00000000000..68c27c09b54 --- /dev/null +++ b/src/plugins/share/valent-share-dialog-row.ui @@ -0,0 +1,100 @@ + + + + + + + + diff --git a/src/plugins/share/valent-share-dialog.c b/src/plugins/share/valent-share-dialog.c new file mode 100644 index 00000000000..6d567ef0081 --- /dev/null +++ b/src/plugins/share/valent-share-dialog.c @@ -0,0 +1,850 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: Andy Holmes + +#define G_LOG_DOMAIN "valent-share-target-chooser" + +#include "config.h" + +#include +#include +#include +#include + +#include "valent-share-dialog.h" +#include "valent-share-dialog-row.h" + + +struct _ValentShareDialog +{ + AdwWindow parent_instance; + + ValentDeviceManager *manager; + GListModel *files; + unsigned int refresh_id; + unsigned int selection_mode : 1; + + GPtrArray *rows; + GCancellable *cancellable; + guint64 total_size; + unsigned int n_files; + unsigned int n_links; + + /* template */ + AdwNavigationView *view; + AdwActionRow *single_row; + GtkImage *single_icon; + AdwExpanderRow *multiple_row; + GtkImage *multiple_icon; + GtkListBox *device_list; + AdwEntryRow *uri_entry; +}; + +G_DEFINE_FINAL_TYPE (ValentShareDialog, valent_share_dialog, ADW_TYPE_WINDOW) + +enum { + PROP_0, + PROP_FILES, + PROP_SELECTION_MODE, + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + +static void valent_share_dialog_set_files (ValentShareDialog *self, + GListModel *files); +static void valent_share_dialog_share (ValentShareDialog *self, + ValentShareDialogRow *row); + + +/* + * Summary + */ +typedef struct +{ + ValentShareDialog *self; + GtkWidget *row; + GtkImage *icon; +} EntryData; + +static void +g_file_query_info_cb (GFile *file, + GAsyncResult *result, + gpointer user_data) +{ + g_autofree EntryData *data = (EntryData *)user_data; + GIcon *icon = NULL; + g_autoptr (GFileInfo) info = NULL; + g_autoptr (GError) error = NULL; + g_autofree char *size_str = NULL; + g_autofree char *size_label = NULL; + gsize size = 0; + + if ((info = g_file_query_info_finish (file, result, &error)) == NULL) + { + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; + + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) + { + gtk_widget_add_css_class (GTK_WIDGET (data->row), "error"); + } + + return; + } + + if ((icon = g_file_info_get_icon (info)) != NULL) + { + gtk_image_set_from_gicon (data->icon, icon); + gtk_widget_add_css_class (GTK_WIDGET (data->icon), "lowres-icon"); + } + else + { + gtk_image_set_from_icon_name (data->icon, "share-file-symbolic"); + gtk_widget_remove_css_class (GTK_WIDGET (data->icon), "lowres-icon"); + } + + size = g_file_info_get_size (info); + if ((G_MAXUINT64 - data->self->total_size) < size) + data->self->total_size = G_MAXUINT64; + else + data->self->total_size += size; + + size_str = g_format_size (data->self->total_size); + size_label = g_strdup_printf (_("Size: %s"), size_str); + g_object_set (data->row, "subtitle", size_label, NULL); +} + +static void +valent_share_dialog_add_entry (ValentShareDialog *self, + GFile *file, + GCancellable *cancellable) +{ + g_autofree char *title = NULL; + const char *icon_name = NULL; + gboolean is_file = FALSE; + GtkWidget *row; + GtkWidget *icon; + + is_file = g_file_has_uri_scheme (file, "file"); + + if (is_file) + { + self->n_files += 1; + title = g_file_get_basename (file); + icon_name = "share-file-symbolic"; + } + else + { + g_autofree char *uri = NULL; + + uri = g_file_get_uri (file); + + self->n_links += 1; + title = g_strdup_printf ("%s", uri, uri); + icon_name = "share-link-symbolic"; + } + + row = g_object_new (ADW_TYPE_ACTION_ROW, + "title", title, + "title-lines", 1, + NULL); + icon = g_object_new (GTK_TYPE_IMAGE, + "accessible-role", GTK_ACCESSIBLE_ROLE_PRESENTATION, + "icon-name", icon_name, + NULL); + adw_action_row_add_prefix (ADW_ACTION_ROW (row), icon); + adw_expander_row_add_row (self->multiple_row, row); + g_ptr_array_add (self->rows, row); + + if (is_file) + { + EntryData *data = NULL; + + data = g_new0 (EntryData, 1); + data->self = self; + data->row = (GtkWidget *)row; + data->icon = (GtkImage *)icon; + + g_file_query_info_async (file, + G_FILE_ATTRIBUTE_STANDARD_SIZE"," + G_FILE_ATTRIBUTE_STANDARD_ICON, + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT_IDLE, + cancellable, + (GAsyncReadyCallback)g_file_query_info_cb, + g_steal_pointer (&data)); + } +} + +static void +valent_share_dialog_reset (ValentShareDialog *self) +{ + g_assert (VALENT_IS_SHARE_DIALOG (self)); + + g_cancellable_cancel (self->cancellable); + g_clear_object (&self->cancellable); + self->cancellable = g_cancellable_new (); + self->n_files = 0; + self->n_links = 0; + self->total_size = 0; + + g_object_set (self->single_row, + "title", NULL, + "subtitle", NULL, + NULL); + g_object_set (self->multiple_row, + "title", NULL, + "subtitle", NULL, + NULL); + gtk_editable_set_text (GTK_EDITABLE (self->uri_entry), ""); + + if (self->rows != NULL) + { + for (unsigned int i = 0; i < self->rows->len; i++) + { + adw_expander_row_remove (self->multiple_row, + g_ptr_array_index (self->rows, i)); + } + g_clear_pointer (&self->rows, g_ptr_array_unref); + } + +} + +static void +on_files_changed (GListModel *list, + unsigned int position, + unsigned int removed, + unsigned int added, + ValentShareDialog *self) +{ + unsigned int n_items = 0; + + g_assert (VALENT_IS_SHARE_DIALOG (self); + + valent_share_dialog_reset (self); + + if (self->files != NULL) + n_items = g_list_model_get_n_items (self->files); + + if (n_items > 1) + { + g_autofree char *title = NULL; + + self->rows = g_ptr_array_sized_new (n_items); + + for (unsigned int i = 0; i < n_items; i++) + { + g_autoptr (GFile) file = NULL; + + file = g_list_model_get_item (self->files, i); + valent_share_dialog_add_entry (self, file, self->cancellable); + } + + if (self->n_files > 0 && self->n_links > 0) + title = g_strdup_printf (_("%u files and links"), n_items); + else if (self->n_files > 0) + title = g_strdup_printf (_("%u files"), n_items); + else if (self->n_links > 0) + title = g_strdup_printf (_("%u links"), n_items); + + g_object_set (self->multiple_row, + "title", title, + "visible", TRUE, + NULL); + } + else if (n_items > 0) + { + g_autofree char *title = NULL; + g_autoptr (GFile) entry = NULL; + const char *icon_name = NULL; + + entry = g_list_model_get_item (self->files, 0); + + if (g_file_has_uri_scheme (entry, "file")) + { + EntryData *data; + + data = g_new0 (EntryData, 1); + data->self = self; + data->row = (GtkWidget *)self->single_row; + data->icon = self->single_icon; + + g_file_query_info_async (entry, + G_FILE_ATTRIBUTE_STANDARD_SIZE"," + G_FILE_ATTRIBUTE_STANDARD_ICON, + G_FILE_QUERY_INFO_NONE, + G_PRIORITY_DEFAULT_IDLE, + self->cancellable, + (GAsyncReadyCallback)g_file_query_info_cb, + g_steal_pointer (&data)); + + title = g_file_get_basename (entry); + icon_name = "share-symbolic"; + } + else + { + g_autofree char *uri = NULL; + + uri = g_file_get_uri (entry); + + title = g_strdup_printf ("%s", uri, uri); + icon_name = "share-link-symbolic"; + } + + g_object_set (self->single_row, + "title", title, + "visible", TRUE, + NULL); + gtk_image_set_from_icon_name (self->single_icon, icon_name); + gtk_widget_remove_css_class (GTK_WIDGET (self->single_icon), "lowres-icon"); + } +} + +/* + * Devices + */ +static void +on_action_added (GActionGroup *action_group, + const char *action_name, + GtkWidget *widget) +{ + gboolean visible = FALSE; + + if (g_action_group_get_action_enabled (action_group, action_name)) + visible = TRUE; + + gtk_widget_set_visible (widget, visible); +} + +static void +on_action_removed (GActionGroup *action_group, + const char *action_name, + GtkWidget *widget) +{ + gtk_widget_set_visible (widget, FALSE); +} + +static void +on_action_enabled_changed (GActionGroup *action_group, + const char *action_name, + gboolean enabled, + GtkWidget *widget) +{ + gtk_widget_set_visible (widget, enabled); +} + +static void +on_device_activated (GtkListBox *box, + ValentShareDialogRow *row, + ValentShareDialog *self) +{ + g_assert (GTK_IS_LIST_BOX (box)); + g_assert (VALENT_IS_SHARE_DIALOG_ROW (row)); + g_assert (VALENT_IS_SHARE_DIALOG (self)); + + if (self->selection_mode) + { + gboolean selected; + + selected = valent_share_dialog_row_get_selected (row); + valent_share_dialog_row_set_selected (row, !selected); + } + else + { + valent_share_dialog_share (self, row); + } +} + +static void +on_selected_changed (ValentShareDialog *self) +{ + GtkWidget *child; + gboolean enabled = FALSE; + + if (!self->selection_mode) + { + gtk_widget_action_set_enabled (GTK_WIDGET (self), + "chooser.share", + enabled); + return; + } + + for (child = gtk_widget_get_first_child (GTK_WIDGET (self->device_list)); + child != NULL; + child = gtk_widget_get_next_sibling (child)) + { + if (!VALENT_IS_SHARE_DIALOG_ROW (child)) + continue; + + if (valent_share_dialog_row_get_selected (VALENT_SHARE_DIALOG_ROW (child))) + { + enabled = TRUE; + break; + } + } + + gtk_widget_action_set_enabled (GTK_WIDGET (self), "chooser.share", enabled); +} + +static GtkWidget * +valent_share_dialog_create_row (gpointer item, + gpointer user_data) +{ + ValentShareDialog *self = VALENT_SHARE_DIALOG (user_data); + ValentDevice *device = VALENT_DEVICE (item); + GtkWidget *row; + + g_assert (VALENT_IS_DEVICE (device)); + + row = g_object_new (VALENT_TYPE_SHARE_DIALOG_ROW, + "device", device, + "selection-mode", self->selection_mode, + NULL); + g_object_bind_property (self, "selection-mode", + row, "selection-mode", + G_BINDING_SYNC_CREATE); + g_signal_connect_object (row, + "notify::selected", + G_CALLBACK (on_selected_changed), + self, G_CONNECT_SWAPPED); + g_signal_connect_object (device, + "action-added::share.uris", + G_CALLBACK (on_action_added), + row, 0); + g_signal_connect_object (device, + "action-removed::share.uris", + G_CALLBACK (on_action_removed), + row, 0); + g_signal_connect_object (device, + "action-enabled-changed::share.uris", + G_CALLBACK (on_action_enabled_changed), + row, 0); + on_action_added (G_ACTION_GROUP (device), "share.uris", row); + + return row; +} + +static void +on_items_changed (GListModel *list, + unsigned int position, + unsigned int removed, + unsigned int added, + ValentShareDialog *self) +{ + g_assert (VALENT_IS_SHARE_DIALOG (self)); + + while (removed--) + { + GtkListBoxRow *row; + + row = gtk_list_box_get_row_at_index (self->device_list, position); + gtk_list_box_remove (self->device_list, GTK_WIDGET (row)); + } + + for (unsigned int i = 0; i < added; i++) + { + g_autoptr (GObject) item = NULL; + g_autoptr (GtkWidget) widget = NULL; + + item = g_list_model_get_item (list, position + i); + widget = valent_share_dialog_create_row (item, self); + + if (g_object_is_floating (widget)) + g_object_ref_sink (widget); + + gtk_list_box_insert (self->device_list, widget, position + i); + } + + on_selected_changed (self); +} + +static gboolean +valent_share_dialog_refresh (gpointer data) +{ + ValentDeviceManager *manager = VALENT_DEVICE_MANAGER (data); + + g_assert (VALENT_IS_DEVICE_MANAGER (manager)); + + valent_device_manager_refresh (manager); + + return G_SOURCE_CONTINUE; +} + +/* + * URI Selector + */ +static void +on_uri_activated (GtkEditable *editable, + ValentShareDialog *self) +{ + const char *text = NULL; + + g_assert (VALENT_IS_SHARE_DIALOG (self)); + + text = gtk_editable_get_text (editable); + if (text == NULL || *text == '\0') + return; + + if (!gtk_widget_has_css_class (GTK_WIDGET (self->uri_entry), "error")) + { + g_autoptr (GListStore) files = NULL; + g_autoptr (GFile) file = NULL; + + file = g_file_new_for_uri (text); + files = g_list_store_new (G_TYPE_FILE); + g_list_store_append (files, file); + + valent_share_dialog_set_files (self, G_LIST_MODEL (files)); + } +} + +static void +on_uri_changed (GtkEditable *editable, + ValentShareDialog *self) +{ + const char *text = NULL; + const char *scheme = NULL; + + g_assert (VALENT_IS_SHARE_DIALOG (self)); + + text = gtk_editable_get_text (editable); + if (text == NULL || *text == '\0') + { + gtk_widget_remove_css_class (GTK_WIDGET (self->uri_entry), "error"); + gtk_accessible_reset_state (GTK_ACCESSIBLE (self->uri_entry), + GTK_ACCESSIBLE_STATE_INVALID); + return; + } + + scheme = g_uri_peek_scheme (text); + if (scheme != NULL && !g_str_equal (scheme, "file")) + { + gtk_widget_remove_css_class (GTK_WIDGET (self->uri_entry), "error"); + gtk_accessible_reset_state (GTK_ACCESSIBLE (self->uri_entry), + GTK_ACCESSIBLE_STATE_INVALID); + } + else + { + gtk_widget_add_css_class (GTK_WIDGET (self->uri_entry), "error"); + gtk_accessible_update_state (GTK_ACCESSIBLE (self->uri_entry), + GTK_ACCESSIBLE_STATE_INVALID, TRUE, + -1); + } +} + +/* + * GAction + */ +static void +gtk_file_dialog_open_multiple_cb (GtkFileDialog *dialog, + GAsyncResult *result, + ValentShareDialog *self) +{ + g_autoptr (GListModel) files = NULL; + g_autoptr (GError) error = NULL; + + files = gtk_file_dialog_open_multiple_finish (dialog, result, &error); + + if (files == NULL) + { + if (!g_error_matches (error, GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_CANCELLED) && + !g_error_matches (error, GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_DISMISSED)) + g_warning ("%s(): %s", G_STRFUNC, error->message); + + return; + } + + valent_share_dialog_set_files (self, files); +} + +static void +chooser_select_files_action (GtkWidget *widget, + const char *action_name, + GVariant *parameter) +{ + ValentShareDialog *self = VALENT_SHARE_DIALOG (widget); + g_autoptr (GtkFileDialog) dialog = NULL; + + g_assert (VALENT_IS_SHARE_DIALOG (self)); + + dialog = gtk_file_dialog_new (); + gtk_file_dialog_open_multiple (dialog, + GTK_WINDOW (self), + NULL, + (GAsyncReadyCallback)gtk_file_dialog_open_multiple_cb, + self); +} + +static void +chooser_share_action (GtkWidget *widget, + const char *action_name, + GVariant *parameter) +{ + ValentShareDialog *self = VALENT_SHARE_DIALOG (widget); + GtkWidget *child; + + for (child = gtk_widget_get_first_child (GTK_WIDGET (self->device_list)); + child != NULL; + child = gtk_widget_get_next_sibling (child)) + { + if (!VALENT_IS_SHARE_DIALOG_ROW (child)) + continue; + + if (!valent_share_dialog_row_get_selected (VALENT_SHARE_DIALOG_ROW (child))) + continue; + + valent_share_dialog_share (self, VALENT_SHARE_DIALOG_ROW (child)); + } +} + +/* + * ValentShareDialog + */ +static void +valent_share_dialog_set_files (ValentShareDialog *self, + GListModel *files) +{ + unsigned int n_items = 0; + + g_assert (VALENT_IS_SHARE_DIALOG (self)); + g_assert (files == NULL || G_IS_LIST_MODEL (files)); + + if (!g_set_object (&self->files, files)) + return; + + valent_share_dialog_reset (self); + + if (self->files != NULL) + { + n_items = g_list_model_get_n_items (files); + g_signal_connect_object (self->files, + "items-changed", + G_CALLBACK (on_files_changed), + self, + G_CONNECT_DEFAULT); + on_files_changed (self->files, + 0, + self->n_links + self->n_files, + n_items, + self); + } + + if (n_items > 0) + adw_navigation_view_push_by_tag (self->view, "device"); + else + adw_navigation_view_pop (self->view); + + g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_FILES]); +} + +static void +valent_share_dialog_set_selection_mode (ValentShareDialog *self, + gboolean selection_mode) +{ + g_assert (VALENT_IS_SHARE_DIALOG (self)); + + selection_mode = !!selection_mode; + if (self->selection_mode == selection_mode) + return; + + gtk_list_box_set_selection_mode (self->device_list, + selection_mode + ? GTK_SELECTION_MULTIPLE + : GTK_SELECTION_NONE); + + self->selection_mode = selection_mode; + g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_SELECTION_MODE]); +} + +static void +valent_share_dialog_share (ValentShareDialog *self, + ValentShareDialogRow *row) +{ + ValentDevice *device = NULL; + GVariantBuilder builder; + unsigned int n_files = 0; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY); + n_files = g_list_model_get_n_items (self->files); + + for (unsigned int i = 0; i < n_files; i++) + { + g_autoptr (GFile) file = g_list_model_get_item (self->files, i); + GVariant *uri = g_variant_new_take_string (g_file_get_uri (file)); + + g_variant_builder_add_value (&builder, uri); + } + + device = valent_share_dialog_row_get_device (row); + g_action_group_activate_action (G_ACTION_GROUP (device), + "share.uris", + g_variant_builder_end (&builder)); + + gtk_window_close (GTK_WINDOW (self)); +} + +/* + * GObject + */ +static void +valent_share_dialog_constructed (GObject *object) +{ + ValentShareDialog *self = VALENT_SHARE_DIALOG (object); + + self->manager = valent_device_manager_get_default (); + g_signal_connect_object (self->manager, + "items-changed", + G_CALLBACK (on_items_changed), + self, 0); + on_items_changed (G_LIST_MODEL (self->manager), + 0, + 0, + g_list_model_get_n_items (G_LIST_MODEL (self->manager)), + self); + + /* Broadcast every 5 seconds to re-connect devices that may have gone idle */ + valent_device_manager_refresh (self->manager); + self->refresh_id = g_timeout_add_seconds_full (G_PRIORITY_LOW, + 5, + valent_share_dialog_refresh, + g_object_ref (self->manager), + g_object_unref); + + G_OBJECT_CLASS (valent_share_dialog_parent_class)->constructed (object); +} + +static void +valent_share_dialog_dispose (GObject *object) +{ + ValentShareDialog *self = VALENT_SHARE_DIALOG (object); + + g_clear_handle_id (&self->refresh_id, g_source_remove); + + if (self->manager != NULL) + { + g_signal_handlers_disconnect_by_data (self->manager, self); + self->manager = NULL; + } + + if (self->cancellable != NULL) + { + g_cancellable_cancel (self->cancellable); + g_clear_object (&self->cancellable); + } + + g_clear_object (&self->files); + g_clear_pointer (&self->rows, g_ptr_array_unref); + + gtk_widget_dispose_template (GTK_WIDGET (object), + VALENT_TYPE_SHARE_DIALOG); + + G_OBJECT_CLASS (valent_share_dialog_parent_class)->dispose (object); +} + +static void +valent_share_dialog_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + ValentShareDialog *self = VALENT_SHARE_DIALOG (object); + + switch (prop_id) + { + case PROP_FILES: + g_value_set_object (value, self->files); + break; + + case PROP_SELECTION_MODE: + g_value_set_boolean (value, self->selection_mode); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +valent_share_dialog_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ValentShareDialog *self = VALENT_SHARE_DIALOG (object); + + switch (prop_id) + { + case PROP_FILES: + valent_share_dialog_set_files (self, g_value_get_object (value)); + break; + + case PROP_SELECTION_MODE: + valent_share_dialog_set_selection_mode (self, g_value_get_boolean (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +valent_share_dialog_class_init (ValentShareDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->constructed = valent_share_dialog_constructed; + object_class->dispose = valent_share_dialog_dispose; + object_class->get_property = valent_share_dialog_get_property; + object_class->set_property = valent_share_dialog_set_property; + + gtk_widget_class_set_template_from_resource (widget_class, "/plugins/share/valent-share-dialog.ui"); + gtk_widget_class_bind_template_child (widget_class, ValentShareDialog, view); + gtk_widget_class_bind_template_child (widget_class, ValentShareDialog, device_list); + gtk_widget_class_bind_template_child (widget_class, ValentShareDialog, single_row); + gtk_widget_class_bind_template_child (widget_class, ValentShareDialog, single_icon); + gtk_widget_class_bind_template_child (widget_class, ValentShareDialog, multiple_row); + gtk_widget_class_bind_template_child (widget_class, ValentShareDialog, multiple_icon); + gtk_widget_class_bind_template_child (widget_class, ValentShareDialog, uri_entry); + gtk_widget_class_bind_template_callback (widget_class, on_device_activated); + gtk_widget_class_bind_template_callback (widget_class, on_uri_activated); + gtk_widget_class_bind_template_callback (widget_class, on_uri_changed); + + gtk_widget_class_install_action (widget_class, "chooser.share", NULL, chooser_share_action); + gtk_widget_class_install_action (widget_class, "chooser.select-files", NULL, chooser_select_files_action); + + /** + * ValentShareDialog:files: + * + * The URIs to share. + */ + properties [PROP_FILES] = + g_param_spec_object ("files", NULL, NULL, + G_TYPE_LIST_MODEL, + (G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_EXPLICIT_NOTIFY | + G_PARAM_STATIC_STRINGS)); + + /** + * ValentShareDialog:selection-mode: + * + * Whether multiple devices can be selected. + */ + properties [PROP_SELECTION_MODE] = + g_param_spec_boolean ("selection-mode", NULL, NULL, + FALSE, + (G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_EXPLICIT_NOTIFY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_properties (object_class, N_PROPERTIES, properties); +} + +static void +valent_share_dialog_init (ValentShareDialog *self) +{ + gtk_widget_init_template (GTK_WIDGET (self)); +} + diff --git a/src/plugins/share/valent-share-dialog.h b/src/plugins/share/valent-share-dialog.h new file mode 100644 index 00000000000..f0922529855 --- /dev/null +++ b/src/plugins/share/valent-share-dialog.h @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-FileCopyrightText: Andy Holmes + +#pragma once + +#include + +G_BEGIN_DECLS + +#define VALENT_TYPE_SHARE_DIALOG (valent_share_dialog_get_type()) + +G_DECLARE_FINAL_TYPE (ValentShareDialog, valent_share_dialog, VALENT, SHARE_DIALOG, AdwWindow) + +G_END_DECLS + diff --git a/src/plugins/share/valent-share-dialog.ui b/src/plugins/share/valent-share-dialog.ui new file mode 100644 index 00000000000..36b6ed3cbef --- /dev/null +++ b/src/plugins/share/valent-share-dialog.ui @@ -0,0 +1,231 @@ + + + + + + + + diff --git a/src/plugins/share/valent-share-target-chooser.c b/src/plugins/share/valent-share-target-chooser.c deleted file mode 100644 index 148da48ed80..00000000000 --- a/src/plugins/share/valent-share-target-chooser.c +++ /dev/null @@ -1,409 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileCopyrightText: Andy Holmes - -#define G_LOG_DOMAIN "valent-share-target-chooser" - -#include "config.h" - -#include -#include -#include -#include - -#include "valent-share-target-chooser.h" - - -struct _ValentShareTargetChooser -{ - GtkWindow parent_instance; - - ValentDeviceManager *manager; - GListModel *files; - unsigned int refresh_id; - - /* template */ - GtkListBox *device_list; -}; - -G_DEFINE_FINAL_TYPE (ValentShareTargetChooser, valent_share_target_chooser, GTK_TYPE_WINDOW) - -enum { - PROP_0, - PROP_FILES, - N_PROPERTIES -}; - -static GParamSpec *properties[N_PROPERTIES] = { NULL, }; - - -static void -on_action_added (GActionGroup *action_group, - const char *action_name, - GtkWidget *widget) -{ - gboolean visible = FALSE; - - if (g_action_group_get_action_enabled (action_group, action_name)) - visible = TRUE; - - gtk_widget_set_visible (widget, visible); -} - -static void -on_action_removed (GActionGroup *action_group, - const char *action_name, - GtkWidget *widget) -{ - gtk_widget_set_visible (widget, FALSE); -} - -static void -on_action_enabled_changed (GActionGroup *action_group, - const char *action_name, - gboolean enabled, - GtkWidget *widget) -{ - gtk_widget_set_visible (widget, enabled); -} - -static GtkWidget * -valent_share_target_chooser_create_row (gpointer item, - gpointer user_data) -{ - ValentShareTargetChooser *self = VALENT_SHARE_TARGET_CHOOSER (user_data); - ValentDevice *device = VALENT_DEVICE (item); - GtkWidget *row; - - g_assert (VALENT_IS_DEVICE (device)); - - row = g_object_new (ADW_TYPE_ACTION_ROW, - "activatable", TRUE, - "selectable", FALSE, - NULL); - - g_object_bind_property (self->device_list, "activate-on-single-click", - row, "selectable", - G_BINDING_INVERT_BOOLEAN | G_BINDING_SYNC_CREATE); - g_object_bind_property (device, "icon-name", - row, "icon-name", - G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); - g_object_bind_property (device, "name", - row, "title", - G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE); - g_object_set_data_full (G_OBJECT (row), - "device", - g_object_ref (device), - g_object_unref); - - g_signal_connect_object (device, - "action-added::share.uris", - G_CALLBACK (on_action_added), - row, 0); - g_signal_connect_object (device, - "action-removed::share.uris", - G_CALLBACK (on_action_removed), - row, 0); - g_signal_connect_object (device, - "action-enabled-changed::share.uris", - G_CALLBACK (on_action_enabled_changed), - row, 0); - on_action_added (G_ACTION_GROUP (device), "share.uris", row); - - return row; -} - -static void -on_items_changed (GListModel *list, - unsigned int position, - unsigned int removed, - unsigned int added, - ValentShareTargetChooser *self) -{ - g_assert (VALENT_IS_SHARE_TARGET_CHOOSER (self)); - - while (removed--) - { - GtkListBoxRow *row; - - row = gtk_list_box_get_row_at_index (self->device_list, position); - gtk_list_box_remove (self->device_list, GTK_WIDGET (row)); - } - - for (unsigned int i = 0; i < added; i++) - { - g_autoptr (GObject) item = NULL; - g_autoptr (GtkWidget) widget = NULL; - - item = g_list_model_get_item (list, position + i); - widget = valent_share_target_chooser_create_row (item, self); - - if (g_object_is_floating (widget)) - g_object_ref_sink (widget); - - gtk_list_box_insert (self->device_list, widget, position + i); - } -} - -static void -on_row_activated (GtkListBox *box, - GtkListBoxRow *row, - ValentShareTargetChooser *self) -{ - ValentDevice *device = NULL; - GVariantBuilder builder; - unsigned int n_files = 0; - - g_assert (GTK_IS_LIST_BOX (box)); - g_assert (GTK_IS_LIST_BOX_ROW (row)); - g_assert (VALENT_IS_SHARE_TARGET_CHOOSER (self)); - - g_variant_builder_init (&builder, G_VARIANT_TYPE_STRING_ARRAY); - n_files = g_list_model_get_n_items (self->files); - - for (unsigned int i = 0; i < n_files; i++) - { - g_autoptr (GFile) file = g_list_model_get_item (self->files, i); - GVariant *uri = g_variant_new_take_string (g_file_get_uri (file)); - - g_variant_builder_add_value (&builder, uri); - } - - device = g_object_get_data (G_OBJECT (row), "device"); - g_action_group_activate_action (G_ACTION_GROUP (device), - "share.uris", - g_variant_builder_end (&builder)); - - gtk_window_close (GTK_WINDOW (self)); -} - -static void -on_selected_rows_changed (GtkListBox *box, - ValentShareTargetChooser *self) -{ - g_autoptr (GList) rows = NULL; - unsigned int n_rows = 0; - unsigned int n_files = 0; - - g_assert (GTK_IS_LIST_BOX (box)); - g_assert (VALENT_IS_SHARE_TARGET_CHOOSER (self)); - - if ((rows = gtk_list_box_get_selected_rows (box)) != NULL) - n_rows = g_list_length (rows); - - if (self->files != NULL) - n_files = g_list_model_get_n_items (self->files); - - gtk_widget_action_set_enabled (GTK_WIDGET (self), "chooser.open", - (n_rows > 0 && n_files == 1)); - gtk_widget_action_set_enabled (GTK_WIDGET (self), "chooser.share", - (n_rows > 0 && n_files >= 1)); -} - -static gboolean -valent_share_target_chooser_refresh (gpointer data) -{ - ValentDeviceManager *manager = VALENT_DEVICE_MANAGER (data); - - g_assert (VALENT_IS_DEVICE_MANAGER (manager)); - - valent_device_manager_refresh (manager); - - return G_SOURCE_CONTINUE; -} - -/* - * GAction - */ -static void -chooser_cancel_action (GtkWidget *widget, - const char *action_name, - GVariant *parameter) -{ - ValentShareTargetChooser *self = VALENT_SHARE_TARGET_CHOOSER (widget); - - g_assert (VALENT_IS_SHARE_TARGET_CHOOSER (self)); - - gtk_window_destroy (GTK_WINDOW (self)); -} - -static void -chooser_open_action (GtkWidget *widget, - const char *action_name, - GVariant *parameter) -{ - ValentShareTargetChooser *self = VALENT_SHARE_TARGET_CHOOSER (widget); - GtkListBoxRow *row; - ValentDevice *device = NULL; - g_autoptr (GFile) file = NULL; - GVariant *target = NULL; - - g_assert (VALENT_IS_SHARE_TARGET_CHOOSER (self)); - - if ((row = gtk_list_box_get_selected_row (self->device_list)) == NULL || - g_list_model_get_n_items (self->files) == 0) - return; - - device = g_object_get_data (G_OBJECT (row), "device"); - file = g_list_model_get_item (self->files, 0); - target = g_variant_new_take_string (g_file_get_uri (file)); - - g_action_group_activate_action (G_ACTION_GROUP (device), "share.open", target); - - gtk_window_close (GTK_WINDOW (self)); -} - -static void -chooser_share_action (GtkWidget *widget, - const char *action_name, - GVariant *parameter) -{ - ValentShareTargetChooser *self = VALENT_SHARE_TARGET_CHOOSER (widget); - GtkListBoxRow *row; - - row = gtk_list_box_get_selected_row (self->device_list); - on_row_activated (self->device_list, row, self); -} - -/* - * GObject - */ -static void -valent_share_target_chooser_constructed (GObject *object) -{ - ValentShareTargetChooser *self = VALENT_SHARE_TARGET_CHOOSER (object); - - g_assert (G_IS_LIST_MODEL (self->files)); - - self->manager = valent_device_manager_get_default (); - g_signal_connect_object (self->manager, - "items-changed", - G_CALLBACK (on_items_changed), - self, 0); - on_items_changed (G_LIST_MODEL (self->manager), - 0, - 0, - g_list_model_get_n_items (G_LIST_MODEL (self->manager)), - self); - on_selected_rows_changed (self->device_list, self); - - /* Broadcast every 5 seconds to re-connect devices that may have gone idle */ - valent_device_manager_refresh (self->manager); - self->refresh_id = g_timeout_add_seconds_full (G_PRIORITY_LOW, - 5, - valent_share_target_chooser_refresh, - g_object_ref (self->manager), - g_object_unref); - - G_OBJECT_CLASS (valent_share_target_chooser_parent_class)->constructed (object); -} - -static void -valent_share_target_chooser_dispose (GObject *object) -{ - ValentShareTargetChooser *self = VALENT_SHARE_TARGET_CHOOSER (object); - - g_clear_handle_id (&self->refresh_id, g_source_remove); - - if (self->manager != NULL) - { - g_signal_handlers_disconnect_by_data (self->manager, self); - self->manager = NULL; - } - - gtk_widget_dispose_template (GTK_WIDGET (object), - VALENT_TYPE_SHARE_TARGET_CHOOSER); - - G_OBJECT_CLASS (valent_share_target_chooser_parent_class)->dispose (object); -} - -static void -valent_share_target_chooser_finalize (GObject *object) -{ - ValentShareTargetChooser *self = VALENT_SHARE_TARGET_CHOOSER (object); - - g_clear_object (&self->files); - - G_OBJECT_CLASS (valent_share_target_chooser_parent_class)->finalize (object); -} - -static void -valent_share_target_chooser_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ValentShareTargetChooser *self = VALENT_SHARE_TARGET_CHOOSER (object); - - switch (prop_id) - { - case PROP_FILES: - g_value_set_object (value, self->files); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -valent_share_target_chooser_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ValentShareTargetChooser *self = VALENT_SHARE_TARGET_CHOOSER (object); - - switch (prop_id) - { - case PROP_FILES: - self->files = g_value_dup_object (value); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - } -} - -static void -valent_share_target_chooser_class_init (ValentShareTargetChooserClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); - - object_class->constructed = valent_share_target_chooser_constructed; - object_class->dispose = valent_share_target_chooser_dispose; - object_class->finalize = valent_share_target_chooser_finalize; - object_class->get_property = valent_share_target_chooser_get_property; - object_class->set_property = valent_share_target_chooser_set_property; - - gtk_widget_class_set_template_from_resource (widget_class, "/plugins/share/valent-share-target-chooser.ui"); - gtk_widget_class_bind_template_child (widget_class, ValentShareTargetChooser, device_list); - gtk_widget_class_bind_template_callback (widget_class, on_row_activated); - gtk_widget_class_bind_template_callback (widget_class, on_selected_rows_changed); - - gtk_widget_class_install_action (widget_class, "chooser.cancel", NULL, chooser_cancel_action); - gtk_widget_class_install_action (widget_class, "chooser.open", NULL, chooser_open_action); - gtk_widget_class_install_action (widget_class, "chooser.share", NULL, chooser_share_action); - - /** - * ValentShareTargetChooser:files: - * - * The URIs to pass to the selected [class@Valent.Device]. - */ - properties [PROP_FILES] = - g_param_spec_object ("files", NULL, NULL, - G_TYPE_LIST_MODEL, - (G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_EXPLICIT_NOTIFY | - G_PARAM_STATIC_STRINGS)); - - g_object_class_install_properties (object_class, N_PROPERTIES, properties); -} - -static void -valent_share_target_chooser_init (ValentShareTargetChooser *self) -{ - gtk_widget_init_template (GTK_WIDGET (self)); -} - diff --git a/src/plugins/share/valent-share-target-chooser.h b/src/plugins/share/valent-share-target-chooser.h deleted file mode 100644 index 566510f2087..00000000000 --- a/src/plugins/share/valent-share-target-chooser.h +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0-or-later -// SPDX-FileCopyrightText: Andy Holmes - -#pragma once - -#include - -G_BEGIN_DECLS - -#define VALENT_TYPE_SHARE_TARGET_CHOOSER (valent_share_target_chooser_get_type()) - -G_DECLARE_FINAL_TYPE (ValentShareTargetChooser, valent_share_target_chooser, VALENT, SHARE_TARGET_CHOOSER, GtkWindow) - -G_END_DECLS - diff --git a/src/plugins/share/valent-share-target-chooser.ui b/src/plugins/share/valent-share-target-chooser.ui deleted file mode 100644 index c4ab7bbdbe9..00000000000 --- a/src/plugins/share/valent-share-target-chooser.ui +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - diff --git a/src/plugins/share/valent-share-target.c b/src/plugins/share/valent-share-target.c index c15c479ceab..2d4302397db 100644 --- a/src/plugins/share/valent-share-target.c +++ b/src/plugins/share/valent-share-target.c @@ -7,8 +7,8 @@ #include #include +#include "valent-share-dialog.h" #include "valent-share-target.h" -#include "valent-share-target-chooser.h" struct _ValentShareTarget @@ -48,7 +48,7 @@ valent_share_target_open (ValentApplicationPlugin *plugin, const char *hint) { ValentShareTarget *self = VALENT_SHARE_TARGET (plugin); - g_autoptr (GListStore) list = NULL; + g_autoptr (GListStore) files_list = NULL; GtkWindow *window = NULL; g_assert (VALENT_IS_SHARE_TARGET (plugin)); @@ -56,13 +56,11 @@ valent_share_target_open (ValentApplicationPlugin *plugin, g_assert (n_files > 0); g_assert (hint != NULL); - list = g_list_store_new (G_TYPE_FILE); + files_list = g_list_store_new (G_TYPE_FILE); + g_list_store_splice (files_list, 0, 0, (gpointer *)files, n_files); - for (int i = 0; i < n_files; i++) - g_list_store_append (list, files[i]); - - window = g_object_new (VALENT_TYPE_SHARE_TARGET_CHOOSER, - "files", list, + window = g_object_new (VALENT_TYPE_SHARE_DIALOG, + "files", files_list, NULL); g_signal_connect_object (G_OBJECT (window), diff --git a/tests/extra/cppcheck.cfg b/tests/extra/cppcheck.cfg index b3f778a580a..e8ffbe342ec 100644 --- a/tests/extra/cppcheck.cfg +++ b/tests/extra/cppcheck.cfg @@ -3,9 +3,7 @@ - - @@ -13,4 +11,19 @@ + + + + + + false + + + + false + + + + false + diff --git a/tests/plugins/share/meson.build b/tests/plugins/share/meson.build index 9e7d3754d4b..d465d69c60c 100644 --- a/tests/plugins/share/meson.build +++ b/tests/plugins/share/meson.build @@ -8,11 +8,11 @@ plugin_share_test_deps = [ ] plugin_runcommand_tests = [ + 'test-share-dialog', 'test-share-download', 'test-share-plugin', 'test-share-preferences', 'test-share-target', - 'test-share-target-chooser', 'test-share-text-dialog', 'test-share-upload', ] diff --git a/tests/plugins/share/test-share-target-chooser.c b/tests/plugins/share/test-share-dialog.c similarity index 84% rename from tests/plugins/share/test-share-target-chooser.c rename to tests/plugins/share/test-share-dialog.c index 72532042bbc..78e17ab216a 100644 --- a/tests/plugins/share/test-share-target-chooser.c +++ b/tests/plugins/share/test-share-dialog.c @@ -6,11 +6,11 @@ #include "valent-mock-channel.h" #include "valent-mock-channel-service.h" -#include "valent-share-target-chooser.h" +#include "valent-share-dialog.h" static void -test_share_target_chooser (void) +test_share_dialog (void) { GtkWindow *window = NULL; ValentChannelService *service = NULL; @@ -26,13 +26,13 @@ test_share_target_chooser (void) VALENT_TEST_CHECK ("Window can be constructed"); manager = valent_device_manager_get_default (); - window = g_object_new (VALENT_TYPE_SHARE_TARGET_CHOOSER, - "files", files, + window = g_object_new (VALENT_TYPE_SHARE_DIALOG, + "files", files, NULL); g_object_add_weak_pointer (G_OBJECT (window), (gpointer)&window); g_object_get (window, - "files", &files_out, + "files", &files_out, NULL); g_assert_true (files == files_out); @@ -64,8 +64,8 @@ main (int argc, { valent_test_ui_init (&argc, &argv, NULL); - g_test_add_func ("/plugins/share/target-chooser", - test_share_target_chooser); + g_test_add_func ("/plugins/share/dialog", + test_share_dialog); return g_test_run (); }