Merge branch 'import-folder'

This commit is contained in:
Elias Projahn 2021-01-30 13:39:23 +01:00
commit 3c61fd4568
59 changed files with 572 additions and 365 deletions

View file

@ -5,6 +5,7 @@ edition = "2018"
[dependencies] [dependencies]
anyhow = "1.0.33" anyhow = "1.0.33"
async-trait = "0.1.42"
diesel = { version = "1.4.5", features = ["sqlite"] } diesel = { version = "1.4.5", features = ["sqlite"] }
diesel_migrations = "1.4.0" diesel_migrations = "1.4.0"
discid = "0.4.4" discid = "0.4.4"
@ -39,9 +40,9 @@ features = ["v2_64"]
git = "https://github.com/gtk-rs/gtk4-rs" git = "https://github.com/gtk-rs/gtk4-rs"
package = "gtk4" package = "gtk4"
[dependencies.libhandy] [dependencies.libadwaita]
git = "https://gitlab.gnome.org/bilelmoussaoui/libhandy4-rs" git = "https://gitlab.gnome.org/bilelmoussaoui/libadwaita-rs"
package = "libhandy4" package = "libadwaita"
[dependencies.pango] [dependencies.pango]
git = "https://github.com/gtk-rs/gtk-rs/" git = "https://github.com/gtk-rs/gtk-rs/"

View file

@ -93,7 +93,7 @@
] ]
}, },
{ {
"name" : "libhandy", "name" : "libadwaita",
"buildsystem" : "meson", "buildsystem" : "meson",
"config-opts" : [ "config-opts" : [
"-Dintrospection=enabled", "-Dintrospection=enabled",
@ -109,8 +109,8 @@
"sources" : [ "sources" : [
{ {
"type" : "git", "type" : "git",
"url" : "https://gitlab.gnome.org/exalm/libhandy", "url" : "https://gitlab.gnome.org/exalm/libadwaita.git",
"branch" : "gtk4" "branch" : "main"
} }
] ]
}, },

View file

@ -11,7 +11,7 @@ dependency('gstreamer-1.0', version: '>= 1.12')
dependency('gtk+-3.0', version: '>= 3.24.7') dependency('gtk+-3.0', version: '>= 3.24.7')
dependency('libcurl', version: '>= 7.24.0') dependency('libcurl', version: '>= 7.24.0')
dependency('libdiscid', version: '>= 0.6.2') dependency('libdiscid', version: '>= 0.6.2')
dependency('libhandy-1', version: '>= 1.0.0') dependency('libadwaita-1', version: '>= 1.0')
dependency('pango', version: '>= 1.0') dependency('pango', version: '>= 1.0')
dependency('sqlite3', version: '>= 3.20') dependency('sqlite3', version: '>= 3.20')

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkStack" id="widget"> <object class="GtkStack" id="widget">
<property name="transition-type">crossfade</property> <property name="transition-type">crossfade</property>
<child> <child>
@ -11,8 +11,9 @@
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Ensemble</property> <property name="label" translatable="yes">Ensemble</property>
@ -45,7 +46,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">true</property> <property name="vexpand">true</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="margin-start">12</property> <property name="margin-start">12</property>
<property name="margin-end">12</property> <property name="margin-end">12</property>
<property name="margin-top">18</property> <property name="margin-top">18</property>
@ -59,7 +60,7 @@
<object class="GtkListBox"> <object class="GtkListBox">
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Name</property> <property name="title" translatable="yes">Name</property>
<property name="activatable-widget">name_entry</property> <property name="activatable-widget">name_entry</property>
@ -72,7 +73,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Publish to the server</property> <property name="title" translatable="yes">Publish to the server</property>
<property name="activatable-widget">upload_switch</property> <property name="activatable-widget">upload_switch</property>
@ -103,8 +104,9 @@
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Ensemble</property> <property name="label" translatable="yes">Ensemble</property>

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkBox" id="widget"> <object class="GtkBox" id="widget">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar" id="header"> <object class="AdwHeaderBar" id="header">
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel" id="title_label"> <object class="GtkLabel" id="title_label">
<property name="label" translatable="yes">Ensemble</property> <property name="label" translatable="yes">Ensemble</property>
@ -36,7 +36,7 @@
<object class="GtkSearchBar"> <object class="GtkSearchBar">
<property name="search-mode-enabled" bind-source="search_button" bind-property="active" bind-flags="bidirectional|sync-create">False</property> <property name="search-mode-enabled" bind-source="search_button" bind-property="active" bind-flags="bidirectional|sync-create">False</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="maximum-size">400</property> <property name="maximum-size">400</property>
<property name="hexpand">true</property> <property name="hexpand">true</property>
<child> <child>
@ -67,7 +67,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">true</property> <property name="vexpand">true</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="margin-start">12</property> <property name="margin-start">12</property>
<property name="margin-end">12</property> <property name="margin-end">12</property>
<property name="margin-top">18</property> <property name="margin-top">18</property>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkStack" id="widget"> <object class="GtkStack" id="widget">
<property name="transition-type">crossfade</property> <property name="transition-type">crossfade</property>
<child> <child>
@ -11,8 +11,9 @@
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Instrument</property> <property name="label" translatable="yes">Instrument</property>
@ -45,7 +46,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">true</property> <property name="vexpand">true</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="margin-start">12</property> <property name="margin-start">12</property>
<property name="margin-end">12</property> <property name="margin-end">12</property>
<property name="margin-top">18</property> <property name="margin-top">18</property>
@ -59,7 +60,7 @@
<object class="GtkListBox"> <object class="GtkListBox">
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Name</property> <property name="title" translatable="yes">Name</property>
<property name="activatable-widget">name_entry</property> <property name="activatable-widget">name_entry</property>
@ -72,7 +73,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Publish to the server</property> <property name="title" translatable="yes">Publish to the server</property>
<property name="activatable-widget">upload_switch</property> <property name="activatable-widget">upload_switch</property>
@ -103,8 +104,9 @@
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Instrument</property> <property name="label" translatable="yes">Instrument</property>

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="HdyWindow" id="window"> <object class="AdwWindow" id="window">
<property name="modal">True</property> <property name="modal">True</property>
<property name="default-width">350</property> <property name="default-width">350</property>
<child> <child>
@ -15,8 +15,9 @@
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Login</property> <property name="label" translatable="yes">Login</property>
@ -56,7 +57,7 @@
<object class="GtkListBox"> <object class="GtkListBox">
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Username</property> <property name="title" translatable="yes">Username</property>
<property name="activatable-widget">username_entry</property> <property name="activatable-widget">username_entry</property>
@ -69,7 +70,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Password</property> <property name="title" translatable="yes">Password</property>
<property name="activatable-widget">password_entry</property> <property name="activatable-widget">password_entry</property>
@ -97,8 +98,9 @@
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Login</property> <property name="label" translatable="yes">Login</property>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkStack" id="widget"> <object class="GtkStack" id="widget">
<property name="transition-type">crossfade</property> <property name="transition-type">crossfade</property>
<child> <child>
@ -11,8 +11,9 @@
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Import music</property> <property name="label" translatable="yes">Import music</property>
@ -60,7 +61,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">True</property> <property name="vexpand">True</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="margin-start">6</property> <property name="margin-start">6</property>
@ -84,7 +85,7 @@
<object class="GtkListBox"> <object class="GtkListBox">
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
<child> <child>
<object class="HdyActionRow" id="name_row"> <object class="AdwActionRow" id="name_row">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Name of the medium</property> <property name="title" translatable="yes">Name of the medium</property>
<property name="activatable-widget">name_entry</property> <property name="activatable-widget">name_entry</property>
@ -97,7 +98,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Publish to the server</property> <property name="title" translatable="yes">Publish to the server</property>
<property name="activatable-widget">publish_switch</property> <property name="activatable-widget">publish_switch</property>

View file

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkBox" id="widget"> <object class="GtkBox" id="widget">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Performance</property> <property name="label" translatable="yes">Performance</property>
@ -35,7 +36,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">true</property> <property name="vexpand">true</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="margin-start">12</property> <property name="margin-start">12</property>
<property name="margin-end">12</property> <property name="margin-end">12</property>
<property name="margin-top">18</property> <property name="margin-top">18</property>
@ -49,7 +50,7 @@
<object class="GtkListBox"> <object class="GtkListBox">
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
<child> <child>
<object class="HdyActionRow" id="person_row"> <object class="AdwActionRow" id="person_row">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Select a person</property> <property name="title" translatable="yes">Select a person</property>
<property name="activatable-widget">person_button</property> <property name="activatable-widget">person_button</property>
@ -62,7 +63,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="HdyActionRow" id="ensemble_row"> <object class="AdwActionRow" id="ensemble_row">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Select an ensemble</property> <property name="title" translatable="yes">Select an ensemble</property>
<property name="activatable-widget">ensemble_button</property> <property name="activatable-widget">ensemble_button</property>
@ -75,7 +76,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="HdyActionRow" id="role_row"> <object class="AdwActionRow" id="role_row">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Select a role</property> <property name="title" translatable="yes">Select a role</property>
<property name="activatable-widget">role_button</property> <property name="activatable-widget">role_button</property>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkStack" id="widget"> <object class="GtkStack" id="widget">
<property name="transition-type">crossfade</property> <property name="transition-type">crossfade</property>
<child> <child>
@ -11,8 +11,9 @@
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Person</property> <property name="label" translatable="yes">Person</property>
@ -45,7 +46,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">true</property> <property name="vexpand">true</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="margin-start">12</property> <property name="margin-start">12</property>
<property name="margin-end">12</property> <property name="margin-end">12</property>
<property name="margin-top">18</property> <property name="margin-top">18</property>
@ -59,7 +60,7 @@
<object class="GtkListBox"> <object class="GtkListBox">
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">First name</property> <property name="title" translatable="yes">First name</property>
<property name="activatable-widget">first_name_entry</property> <property name="activatable-widget">first_name_entry</property>
@ -72,7 +73,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Last name</property> <property name="title" translatable="yes">Last name</property>
<property name="activatable-widget">last_name_entry</property> <property name="activatable-widget">last_name_entry</property>
@ -85,7 +86,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Publish to the server</property> <property name="title" translatable="yes">Publish to the server</property>
<property name="activatable-widget">upload_switch</property> <property name="activatable-widget">upload_switch</property>
@ -116,8 +117,9 @@
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Person</property> <property name="label" translatable="yes">Person</property>

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkBox" id="widget"> <object class="GtkBox" id="widget">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar" id="header"> <object class="AdwHeaderBar" id="header">
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel" id="title_label"> <object class="GtkLabel" id="title_label">
<property name="label" translatable="yes">Person</property> <property name="label" translatable="yes">Person</property>
@ -36,7 +36,7 @@
<object class="GtkSearchBar"> <object class="GtkSearchBar">
<property name="search-mode-enabled" bind-source="search_button" bind-property="active" bind-flags="bidirectional|sync-create">False</property> <property name="search-mode-enabled" bind-source="search_button" bind-property="active" bind-flags="bidirectional|sync-create">False</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="maximum-size">400</property> <property name="maximum-size">400</property>
<property name="hexpand">true</property> <property name="hexpand">true</property>
<child> <child>
@ -71,7 +71,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">true</property> <property name="vexpand">true</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="margin-start">12</property> <property name="margin-start">12</property>
<property name="margin-end">12</property> <property name="margin-end">12</property>
<property name="margin-top">18</property> <property name="margin-top">18</property>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkImage" id="play_image"> <object class="GtkImage" id="play_image">
<property name="icon-name">media-playback-start-symbolic</property> <property name="icon-name">media-playback-start-symbolic</property>
</object> </object>
@ -13,7 +13,7 @@
<object class="GtkBox" id="widget"> <object class="GtkBox" id="widget">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Player</property> <property name="label" translatable="yes">Player</property>
@ -22,7 +22,6 @@
</style> </style>
</object> </object>
</property> </property>
<property name="show-title-buttons">True</property>
<child> <child>
<object class="GtkButton" id="back_button"> <object class="GtkButton" id="back_button">
<child> <child>
@ -38,7 +37,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">true</property> <property name="vexpand">true</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="margin-start">12</property> <property name="margin-start">12</property>
<property name="margin-end">12</property> <property name="margin-end">12</property>
<property name="margin-top">18</property> <property name="margin-top">18</property>
@ -58,7 +57,6 @@
<child> <child>
<object class="GtkButton" id="previous_button"> <object class="GtkButton" id="previous_button">
<property name="sensitive">False</property> <property name="sensitive">False</property>
<property name="can-focus">True</property>
<child> <child>
<object class="GtkImage"> <object class="GtkImage">
<property name="icon-name">media-skip-backward-symbolic</property> <property name="icon-name">media-skip-backward-symbolic</property>

View file

@ -1,14 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkBox" id="widget"> <object class="GtkBox" id="widget">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="GtkSearchBar"> <object class="GtkSearchBar">
<property name="search-mode-enabled">True</property> <property name="search-mode-enabled">True</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="maximum-size">400</property> <property name="maximum-size">400</property>
<property name="tightening-threshold">300</property> <property name="tightening-threshold">300</property>
<property name="hexpand">true</property> <property name="hexpand">true</property>
@ -44,8 +44,6 @@
<property name="name">content</property> <property name="name">content</property>
<property name="child"> <property name="child">
<object class="GtkScrolledWindow" id="scrolled_window"> <object class="GtkScrolledWindow" id="scrolled_window">
<property name="visible">True</property>
<property name="can-focus">True</property>
<child> <child>
<placeholder/> <placeholder/>
</child> </child>

View file

@ -1,19 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="HdyPreferencesWindow" id="window"> <object class="AdwPreferencesWindow" id="window">
<property name="modal">True</property> <property name="modal">True</property>
<property name="default-width">400</property> <property name="default-width">400</property>
<property name="default-height">400</property> <property name="default-height">400</property>
<child> <child>
<object class="HdyPreferencesPage"> <object class="AdwPreferencesPage">
<property name="title" translatable="yes">General</property> <property name="title" translatable="yes">General</property>
<child> <child>
<object class="HdyPreferencesGroup"> <object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Music library</property> <property name="title" translatable="yes">Music library</property>
<child> <child>
<object class="HdyActionRow" id="music_library_path_row"> <object class="AdwActionRow" id="music_library_path_row">
<property name="title" translatable="yes">Music library folder</property> <property name="title" translatable="yes">Music library folder</property>
<property name="activatable-widget">select_music_library_path_button</property> <property name="activatable-widget">select_music_library_path_button</property>
<property name="subtitle" translatable="yes">None selected</property> <property name="subtitle" translatable="yes">None selected</property>
@ -29,10 +29,10 @@
</object> </object>
</child> </child>
<child> <child>
<object class="HdyPreferencesGroup"> <object class="AdwPreferencesGroup">
<property name="title" translatable="yes">Server connection</property> <property name="title" translatable="yes">Server connection</property>
<child> <child>
<object class="HdyActionRow" id="url_row"> <object class="AdwActionRow" id="url_row">
<property name="title" translatable="yes">Server URL</property> <property name="title" translatable="yes">Server URL</property>
<property name="activatable-widget">url_button</property> <property name="activatable-widget">url_button</property>
<property name="subtitle" translatable="yes">Not set</property> <property name="subtitle" translatable="yes">Not set</property>
@ -46,7 +46,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="HdyActionRow" id="login_row"> <object class="AdwActionRow" id="login_row">
<property name="title" translatable="yes">Login credentials</property> <property name="title" translatable="yes">Login credentials</property>
<property name="activatable-widget">login_button</property> <property name="activatable-widget">login_button</property>
<property name="subtitle" translatable="yes">Not logged in</property> <property name="subtitle" translatable="yes">Not logged in</property>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkStack" id="widget"> <object class="GtkStack" id="widget">
<child> <child>
<object class="GtkStackPage"> <object class="GtkStackPage">
@ -10,8 +10,9 @@
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Recording</property> <property name="label" translatable="yes">Recording</property>
@ -45,7 +46,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">true</property> <property name="vexpand">true</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="margin-start">12</property> <property name="margin-start">12</property>
<property name="margin-end">12</property> <property name="margin-end">12</property>
<property name="margin-top">18</property> <property name="margin-top">18</property>
@ -73,7 +74,7 @@
<object class="GtkListBox"> <object class="GtkListBox">
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
<child> <child>
<object class="HdyActionRow" id="work_row"> <object class="AdwActionRow" id="work_row">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Select a work</property> <property name="title" translatable="yes">Select a work</property>
<property name="activatable-widget">work_button</property> <property name="activatable-widget">work_button</property>
@ -86,7 +87,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Comment</property> <property name="title" translatable="yes">Comment</property>
<property name="activatable-widget">comment_entry</property> <property name="activatable-widget">comment_entry</property>
@ -99,7 +100,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Publish to the server</property> <property name="title" translatable="yes">Publish to the server</property>
<property name="activatable-widget">upload_switch</property> <property name="activatable-widget">upload_switch</property>
@ -159,8 +160,9 @@
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Recording</property> <property name="label" translatable="yes">Recording</property>

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkBox" id="widget"> <object class="GtkBox" id="widget">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar" id="header"> <object class="AdwHeaderBar" id="header">
<property name="title-widget"> <property name="title-widget">
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
@ -59,7 +59,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">true</property> <property name="vexpand">true</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="margin-start">12</property> <property name="margin-start">12</property>
<property name="margin-end">12</property> <property name="margin-end">12</property>
<property name="margin-top">18</property> <property name="margin-top">18</property>

View file

@ -1,14 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkBox" id="widget"> <object class="GtkBox" id="widget">
<property name="width-request">250</property> <property name="width-request">250</property>
<property name="hexpand">False</property> <property name="hexpand">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar" id="header"> <object class="AdwHeaderBar" id="header">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
@ -46,7 +47,7 @@
<object class="GtkSearchBar"> <object class="GtkSearchBar">
<property name="search-mode-enabled">True</property> <property name="search-mode-enabled">True</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="maximum-size">500</property> <property name="maximum-size">500</property>
<property name="tightening-threshold">300</property> <property name="tightening-threshold">300</property>
<property name="hexpand">true</property> <property name="hexpand">true</property>
@ -99,7 +100,7 @@
<property name="height-request">200</property> <property name="height-request">200</property>
<property name="vexpand">true</property> <property name="vexpand">true</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="maximum-size">500</property> <property name="maximum-size">500</property>
<property name="tightening-threshold">300</property> <property name="tightening-threshold">300</property>
<child> <child>

View file

@ -1,15 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="HdyWindow" id="window"> <object class="AdwWindow" id="window">
<property name="modal">True</property> <property name="modal">True</property>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Server</property> <property name="label" translatable="yes">Server</property>
@ -38,7 +39,7 @@
<object class="GtkListBox"> <object class="GtkListBox">
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">URL</property> <property name="title" translatable="yes">URL</property>
<property name="activatable-widget">url_entry</property> <property name="activatable-widget">url_entry</property>

View file

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkBox" id="widget"> <object class="GtkBox" id="widget">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Import music</property> <property name="label" translatable="yes">Import music</property>
@ -48,49 +49,27 @@
</object> </object>
</child> </child>
<child> <child>
<object class="GtkBox"> <object class="AdwStatusPage">
<property name="vexpand">True</property> <property name="vexpand">true</property>
<property name="halign">center</property> <property name="icon-name">folder-music-symbolic</property>
<property name="valign">center</property> <property name="title" translatable="yes">Import music</property>
<property name="margin-top">18</property> <property name="description" translatable="yes">Select the source which contains the new audio files below.</property>
<property name="margin-bottom">18</property>
<property name="margin-start">18</property>
<property name="margin-end">18</property>
<property name="orientation">vertical</property>
<property name="spacing">18</property>
<child> <child>
<object class="GtkImage"> <object class="GtkBox">
<property name="opacity">0.5019607843137255</property> <property name="orientation">horizontal</property>
<property name="pixel-size">80</property> <property name="homogeneous">true</property>
<property name="icon-name">media-optical-cd-audio-symbolic</property> <property name="spacing">6</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="opacity">0.5019607843137255</property>
<property name="label" translatable="yes">Import from audio CD</property>
<attributes>
<attribute name="size" value="16384"/>
</attributes>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="opacity">0.5019607843137255</property>
<property name="label" translatable="yes">Insert an audio compact disc into your drive and click the button below. The disc will be copied in the background while you set up the metadata.</property>
<property name="justify">center</property>
<property name="wrap">True</property>
<property name="max-width-chars">40</property>
</object>
</child>
<child>
<object class="GtkButton" id="import_button">
<property name="label" translatable="yes">Import</property>
<property name="receives-default">True</property>
<property name="halign">center</property> <property name="halign">center</property>
<style> <child>
<class name="suggested-action"/> <object class="GtkButton" id="folder_button">
</style> <property name="label" translatable="true">Select folder</property>
</object>
</child>
<child>
<object class="GtkButton" id="disc_button">
<property name="label" translatable="true">Copy audio CD</property>
</object>
</child>
</object> </object>
</child> </child>
</object> </object>

View file

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkBox" id="widget"> <object class="GtkBox" id="widget">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Track</property> <property name="label" translatable="yes">Track</property>
@ -34,7 +35,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">True</property> <property name="vexpand">True</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<child> <child>
<object class="GtkFrame" id="parts_frame"> <object class="GtkFrame" id="parts_frame">
<property name="valign">start</property> <property name="valign">start</property>

View file

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkBox" id="widget"> <object class="GtkBox" id="widget">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Select tracks</property> <property name="label" translatable="yes">Select tracks</property>
@ -35,7 +36,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">True</property> <property name="vexpand">True</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<child> <child>
<object class="GtkFrame" id="tracks_frame"> <object class="GtkFrame" id="tracks_frame">
<property name="valign">start</property> <property name="valign">start</property>

View file

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkBox" id="widget"> <object class="GtkBox" id="widget">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Import music</property> <property name="label" translatable="yes">Import music</property>
@ -35,7 +36,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">True</property> <property name="vexpand">True</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
<property name="margin-start">6</property> <property name="margin-start">6</property>
@ -59,7 +60,7 @@
<object class="GtkListBox"> <object class="GtkListBox">
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
<child> <child>
<object class="HdyActionRow" id="recording_row"> <object class="AdwActionRow" id="recording_row">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Select a recording</property> <property name="title" translatable="yes">Select a recording</property>
<property name="activatable-widget">select_recording_button</property> <property name="activatable-widget">select_recording_button</property>

View file

@ -1,13 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0" /> <requires lib="gtk" version="4.0" />
<requires lib="libhandy" version="1.0" /> <requires lib="libadwaita" version="1.0" />
<object class="GtkBox" id="empty_screen"> <object class="GtkBox" id="empty_screen">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="hexpand">True</property>
<property name="show-title-buttons">True</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"/> <object class="GtkLabel"/>
</property> </property>
@ -52,7 +50,7 @@
</object> </object>
</child> </child>
</object> </object>
<object class="HdyApplicationWindow" id="window"> <object class="AdwApplicationWindow" id="window">
<property name="default-width">800</property> <property name="default-width">800</property>
<property name="default-height">566</property> <property name="default-height">566</property>
<child> <child>
@ -65,7 +63,7 @@
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label">Musicus</property> <property name="label">Musicus</property>
@ -135,7 +133,7 @@
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
</object> </object>
</child> </child>
<child> <child>
@ -158,18 +156,19 @@
<object class="GtkBox" id="content_box"> <object class="GtkBox" id="content_box">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyLeaflet" id="leaflet"> <object class="AdwLeaflet" id="leaflet">
<property name="vexpand">true</property> <property name="vexpand">true</property>
<child> <child>
<object class="HdyLeafletPage"> <object class="AdwLeafletPage">
<property name="child"> <property name="child">
<object class="GtkBox" id="sidebar_box"> <object class="GtkBox" id="sidebar_box">
<property name="width-request">250</property> <property name="width-request">250</property>
<property name="hexpand">False</property> <property name="hexpand">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">False</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label">Musicus</property> <property name="label">Musicus</property>
@ -202,7 +201,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="HdyLeafletPage"> <object class="AdwLeafletPage">
<property name="navigatable">False</property> <property name="navigatable">False</property>
<property name="child"> <property name="child">
<object class="GtkSeparator"> <object class="GtkSeparator">

View file

@ -1,19 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkStack" id="widget"> <object class="GtkStack" id="widget">
<child> <child>
<object class="GtkStackPage"> <object class="GtkStackPage">
<property name="name">content</property> <property name="name">content</property>
<property name="child"> <property name="child">
<object class="GtkBox"> <object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Work</property> <property name="label" translatable="yes">Work</property>
@ -47,7 +46,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">true</property> <property name="vexpand">true</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="margin-start">12</property> <property name="margin-start">12</property>
<property name="margin-end">12</property> <property name="margin-end">12</property>
<property name="margin-top">18</property> <property name="margin-top">18</property>
@ -75,7 +74,7 @@
<object class="GtkListBox"> <object class="GtkListBox">
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
<child> <child>
<object class="HdyActionRow" id="composer_row"> <object class="AdwActionRow" id="composer_row">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Select a composer</property> <property name="title" translatable="yes">Select a composer</property>
<property name="activatable-widget">composer_button</property> <property name="activatable-widget">composer_button</property>
@ -88,7 +87,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Title</property> <property name="title" translatable="yes">Title</property>
<property name="activatable-widget">title_entry</property> <property name="activatable-widget">title_entry</property>
@ -101,7 +100,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Publish to the server</property> <property name="title" translatable="yes">Publish to the server</property>
<property name="activatable-widget">upload_switch</property> <property name="activatable-widget">upload_switch</property>
@ -194,8 +193,9 @@
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Work</property> <property name="label" translatable="yes">Work</property>

View file

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkBox" id="widget"> <object class="GtkBox" id="widget">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Work part</property> <property name="label" translatable="yes">Work part</property>
@ -39,7 +40,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">true</property> <property name="vexpand">true</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="margin-start">12</property> <property name="margin-start">12</property>
<property name="margin-end">12</property> <property name="margin-end">12</property>
<property name="margin-top">18</property> <property name="margin-top">18</property>
@ -53,7 +54,7 @@
<object class="GtkListBox"> <object class="GtkListBox">
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Title</property> <property name="title" translatable="yes">Title</property>
<property name="activatable-widget">title_entry</property> <property name="activatable-widget">title_entry</property>
@ -66,7 +67,7 @@
</object> </object>
</child> </child>
<child> <child>
<object class="HdyActionRow" id="composer_row"> <object class="AdwActionRow" id="composer_row">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Select a composer</property> <property name="title" translatable="yes">Select a composer</property>
<property name="activatable-widget">composer_button</property> <property name="activatable-widget">composer_button</property>

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkBox" id="widget"> <object class="GtkBox" id="widget">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar" id="header"> <object class="AdwHeaderBar" id="header">
<property name="title-widget"> <property name="title-widget">
<object class="GtkBox"> <object class="GtkBox">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
@ -49,7 +49,7 @@
<object class="GtkSearchBar"> <object class="GtkSearchBar">
<property name="search-mode-enabled" bind-source="search_button" bind-property="active" bind-flags="bidirectional|sync-create">False</property> <property name="search-mode-enabled" bind-source="search_button" bind-property="active" bind-flags="bidirectional|sync-create">False</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="maximum-size">400</property> <property name="maximum-size">400</property>
<property name="hexpand">true</property> <property name="hexpand">true</property>
<child> <child>
@ -80,7 +80,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">true</property> <property name="vexpand">true</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="margin-start">12</property> <property name="margin-start">12</property>
<property name="margin-end">12</property> <property name="margin-end">12</property>
<property name="margin-top">18</property> <property name="margin-top">18</property>

View file

@ -1,12 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<interface> <interface>
<requires lib="gtk" version="4.0"/> <requires lib="gtk" version="4.0"/>
<requires lib="libhandy" version="1.0"/> <requires lib="libadwaita" version="1.0"/>
<object class="GtkBox" id="widget"> <object class="GtkBox" id="widget">
<property name="orientation">vertical</property> <property name="orientation">vertical</property>
<child> <child>
<object class="HdyHeaderBar"> <object class="AdwHeaderBar">
<property name="show-title-buttons">false</property> <property name="show-start-title-buttons">false</property>
<property name="show-end-title-buttons">false</property>
<property name="title-widget"> <property name="title-widget">
<object class="GtkLabel"> <object class="GtkLabel">
<property name="label" translatable="yes">Work section</property> <property name="label" translatable="yes">Work section</property>
@ -39,7 +40,7 @@
<object class="GtkScrolledWindow"> <object class="GtkScrolledWindow">
<property name="vexpand">true</property> <property name="vexpand">true</property>
<child> <child>
<object class="HdyClamp"> <object class="AdwClamp">
<property name="margin-start">12</property> <property name="margin-start">12</property>
<property name="margin-end">12</property> <property name="margin-end">12</property>
<property name="margin-top">18</property> <property name="margin-top">18</property>
@ -53,7 +54,7 @@
<object class="GtkListBox"> <object class="GtkListBox">
<property name="selection-mode">none</property> <property name="selection-mode">none</property>
<child> <child>
<object class="HdyActionRow"> <object class="AdwActionRow">
<property name="activatable">True</property> <property name="activatable">True</property>
<property name="title" translatable="yes">Title</property> <property name="title" translatable="yes">Title</property>
<property name="activatable-widget">title_entry</property> <property name="activatable-widget">title_entry</property>

View file

@ -8,7 +8,7 @@ use std::rc::Rc;
/// A dialog for entering login credentials. /// A dialog for entering login credentials.
pub struct LoginDialog { pub struct LoginDialog {
backend: Rc<Backend>, backend: Rc<Backend>,
window: libhandy::Window, window: libadwaita::Window,
stack: gtk::Stack, stack: gtk::Stack,
info_bar: gtk::InfoBar, info_bar: gtk::InfoBar,
username_entry: gtk::Entry, username_entry: gtk::Entry,
@ -22,7 +22,7 @@ impl LoginDialog {
// Create UI // Create UI
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/login_dialog.ui"); let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/login_dialog.ui");
get_widget!(builder, libhandy::Window, window); get_widget!(builder, libadwaita::Window, window);
get_widget!(builder, gtk::Stack, stack); get_widget!(builder, gtk::Stack, stack);
get_widget!(builder, gtk::InfoBar, info_bar); get_widget!(builder, gtk::InfoBar, info_bar);
get_widget!(builder, gtk::Button, cancel_button); get_widget!(builder, gtk::Button, cancel_button);

View file

@ -4,16 +4,16 @@ use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::rc::Rc; use std::rc::Rc;
/// A dialog for configuring the app. /// A dialog for configuring the app.
pub struct Preferences { pub struct Preferences {
backend: Rc<Backend>, backend: Rc<Backend>,
window: libhandy::Window, window: libadwaita::Window,
music_library_path_row: libhandy::ActionRow, music_library_path_row: libadwaita::ActionRow,
url_row: libhandy::ActionRow, url_row: libadwaita::ActionRow,
login_row: libhandy::ActionRow, login_row: libadwaita::ActionRow,
} }
impl Preferences { impl Preferences {
@ -22,12 +22,12 @@ impl Preferences {
// Create UI // Create UI
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/preferences.ui"); let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/preferences.ui");
get_widget!(builder, libhandy::Window, window); get_widget!(builder, libadwaita::Window, window);
get_widget!(builder, libhandy::ActionRow, music_library_path_row); get_widget!(builder, libadwaita::ActionRow, music_library_path_row);
get_widget!(builder, gtk::Button, select_music_library_path_button); get_widget!(builder, gtk::Button, select_music_library_path_button);
get_widget!(builder, libhandy::ActionRow, url_row); get_widget!(builder, libadwaita::ActionRow, url_row);
get_widget!(builder, gtk::Button, url_button); get_widget!(builder, gtk::Button, url_button);
get_widget!(builder, libhandy::ActionRow, login_row); get_widget!(builder, libadwaita::ActionRow, login_row);
get_widget!(builder, gtk::Button, login_button); get_widget!(builder, gtk::Button, login_button);
window.set_transient_for(Some(parent)); window.set_transient_for(Some(parent));
@ -66,6 +66,8 @@ impl Preferences {
} }
} }
} }
dialog.hide();
})); }));
dialog.show(); dialog.show();

View file

@ -8,7 +8,7 @@ use std::rc::Rc;
/// A dialog for setting up the server. /// A dialog for setting up the server.
pub struct ServerDialog { pub struct ServerDialog {
backend: Rc<Backend>, backend: Rc<Backend>,
window: libhandy::Window, window: libadwaita::Window,
url_entry: gtk::Entry, url_entry: gtk::Entry,
selected_cb: RefCell<Option<Box<dyn Fn(String) -> ()>>>, selected_cb: RefCell<Option<Box<dyn Fn(String) -> ()>>>,
} }
@ -19,7 +19,7 @@ impl ServerDialog {
// Create UI // Create UI
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/server_dialog.ui"); let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/server_dialog.ui");
get_widget!(builder, libhandy::Window, window); get_widget!(builder, libadwaita::Window, window);
get_widget!(builder, gtk::Button, cancel_button); get_widget!(builder, gtk::Button, cancel_button);
get_widget!(builder, gtk::Button, set_button); get_widget!(builder, gtk::Button, set_button);
get_widget!(builder, gtk::Entry, url_entry); get_widget!(builder, gtk::Entry, url_entry);

View file

@ -6,7 +6,7 @@ use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -15,9 +15,9 @@ pub struct PerformanceEditor {
backend: Rc<Backend>, backend: Rc<Backend>,
widget: gtk::Box, widget: gtk::Box,
save_button: gtk::Button, save_button: gtk::Button,
person_row: libhandy::ActionRow, person_row: libadwaita::ActionRow,
ensemble_row: libhandy::ActionRow, ensemble_row: libadwaita::ActionRow,
role_row: libhandy::ActionRow, role_row: libadwaita::ActionRow,
reset_role_button: gtk::Button, reset_role_button: gtk::Button,
person: RefCell<Option<Person>>, person: RefCell<Option<Person>>,
ensemble: RefCell<Option<Ensemble>>, ensemble: RefCell<Option<Ensemble>>,
@ -40,9 +40,9 @@ impl PerformanceEditor {
get_widget!(builder, gtk::Button, ensemble_button); get_widget!(builder, gtk::Button, ensemble_button);
get_widget!(builder, gtk::Button, role_button); get_widget!(builder, gtk::Button, role_button);
get_widget!(builder, gtk::Button, reset_role_button); get_widget!(builder, gtk::Button, reset_role_button);
get_widget!(builder, libhandy::ActionRow, person_row); get_widget!(builder, libadwaita::ActionRow, person_row);
get_widget!(builder, libhandy::ActionRow, ensemble_row); get_widget!(builder, libadwaita::ActionRow, ensemble_row);
get_widget!(builder, libhandy::ActionRow, role_row); get_widget!(builder, libadwaita::ActionRow, role_row);
let this = Rc::new(PerformanceEditor { let this = Rc::new(PerformanceEditor {
backend, backend,

View file

@ -8,7 +8,7 @@ use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -18,7 +18,7 @@ pub struct RecordingEditor {
backend: Rc<Backend>, backend: Rc<Backend>,
save_button: gtk::Button, save_button: gtk::Button,
info_bar: gtk::InfoBar, info_bar: gtk::InfoBar,
work_row: libhandy::ActionRow, work_row: libadwaita::ActionRow,
comment_entry: gtk::Entry, comment_entry: gtk::Entry,
upload_switch: gtk::Switch, upload_switch: gtk::Switch,
performance_list: Rc<List>, performance_list: Rc<List>,
@ -40,7 +40,7 @@ impl RecordingEditor {
get_widget!(builder, gtk::Button, back_button); get_widget!(builder, gtk::Button, back_button);
get_widget!(builder, gtk::Button, save_button); get_widget!(builder, gtk::Button, save_button);
get_widget!(builder, gtk::InfoBar, info_bar); get_widget!(builder, gtk::InfoBar, info_bar);
get_widget!(builder, libhandy::ActionRow, work_row); get_widget!(builder, libadwaita::ActionRow, work_row);
get_widget!(builder, gtk::Button, work_button); get_widget!(builder, gtk::Button, work_button);
get_widget!(builder, gtk::Entry, comment_entry); get_widget!(builder, gtk::Entry, comment_entry);
get_widget!(builder, gtk::Switch, upload_switch); get_widget!(builder, gtk::Switch, upload_switch);
@ -173,7 +173,7 @@ impl RecordingEditor {
} }
})); }));
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&performance.get_title())); row.set_title(Some(&performance.get_title()));
row.add_suffix(&delete_button); row.add_suffix(&delete_button);

View file

@ -9,7 +9,7 @@ use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::convert::TryInto; use std::convert::TryInto;
use std::rc::Rc; use std::rc::Rc;
@ -37,7 +37,7 @@ pub struct WorkEditor {
save_button: gtk::Button, save_button: gtk::Button,
title_entry: gtk::Entry, title_entry: gtk::Entry,
info_bar: gtk::InfoBar, info_bar: gtk::InfoBar,
composer_row: libhandy::ActionRow, composer_row: libadwaita::ActionRow,
upload_switch: gtk::Switch, upload_switch: gtk::Switch,
instrument_list: Rc<List>, instrument_list: Rc<List>,
part_list: Rc<List>, part_list: Rc<List>,
@ -62,7 +62,7 @@ impl WorkEditor {
get_widget!(builder, gtk::InfoBar, info_bar); get_widget!(builder, gtk::InfoBar, info_bar);
get_widget!(builder, gtk::Entry, title_entry); get_widget!(builder, gtk::Entry, title_entry);
get_widget!(builder, gtk::Button, composer_button); get_widget!(builder, gtk::Button, composer_button);
get_widget!(builder, libhandy::ActionRow, composer_row); get_widget!(builder, libadwaita::ActionRow, composer_row);
get_widget!(builder, gtk::Switch, upload_switch); get_widget!(builder, gtk::Switch, upload_switch);
get_widget!(builder, gtk::Frame, instrument_frame); get_widget!(builder, gtk::Frame, instrument_frame);
get_widget!(builder, gtk::Button, add_instrument_button); get_widget!(builder, gtk::Button, add_instrument_button);
@ -179,7 +179,7 @@ impl WorkEditor {
this.instrument_list.update(length); this.instrument_list.update(length);
})); }));
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_title(Some(&instrument.name)); row.set_title(Some(&instrument.name));
row.add_suffix(&delete_button); row.add_suffix(&delete_button);
@ -265,7 +265,7 @@ impl WorkEditor {
} }
})); }));
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&pos.get_title())); row.set_title(Some(&pos.get_title()));
row.add_suffix(&delete_button); row.add_suffix(&delete_button);

View file

@ -6,7 +6,7 @@ use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -15,7 +15,7 @@ pub struct WorkPartEditor {
backend: Rc<Backend>, backend: Rc<Backend>,
widget: gtk::Box, widget: gtk::Box,
title_entry: gtk::Entry, title_entry: gtk::Entry,
composer_row: libhandy::ActionRow, composer_row: libadwaita::ActionRow,
reset_composer_button: gtk::Button, reset_composer_button: gtk::Button,
composer: RefCell<Option<Person>>, composer: RefCell<Option<Person>>,
ready_cb: RefCell<Option<Box<dyn Fn(WorkPart) -> ()>>>, ready_cb: RefCell<Option<Box<dyn Fn(WorkPart) -> ()>>>,
@ -34,7 +34,7 @@ impl WorkPartEditor {
get_widget!(builder, gtk::Button, save_button); get_widget!(builder, gtk::Button, save_button);
get_widget!(builder, gtk::Entry, title_entry); get_widget!(builder, gtk::Entry, title_entry);
get_widget!(builder, gtk::Button, composer_button); get_widget!(builder, gtk::Button, composer_button);
get_widget!(builder, libhandy::ActionRow, composer_row); get_widget!(builder, libadwaita::ActionRow, composer_row);
get_widget!(builder, gtk::Button, reset_composer_button); get_widget!(builder, gtk::Button, reset_composer_button);
let composer = match part { let composer = match part {

View file

@ -1,8 +1,12 @@
use super::source::{Source, SourceTrack};
use anyhow::{anyhow, bail, Result}; use anyhow::{anyhow, bail, Result};
use async_trait::async_trait;
use discid::DiscId; use discid::DiscId;
use futures_channel::oneshot; use futures_channel::oneshot;
use gettextrs::gettext;
use gstreamer::prelude::*; use gstreamer::prelude::*;
use gstreamer::{Element, ElementFactory, Pipeline}; use gstreamer::{Element, ElementFactory, Pipeline};
use once_cell::sync::OnceCell;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::thread; use std::thread;
@ -10,67 +14,27 @@ use std::thread;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct DiscSource { pub struct DiscSource {
/// The MusicBrainz DiscID of the CD. /// The MusicBrainz DiscID of the CD.
pub discid: String, pub discid: OnceCell<String>,
/// The path to the temporary directory where the audio files will be.
pub path: PathBuf,
/// The tracks on this disc. /// The tracks on this disc.
pub tracks: Vec<TrackSource>, tracks: OnceCell<Vec<SourceTrack>>,
}
/// Representation of a single track on an audio CD.
#[derive(Clone, Debug)]
pub struct TrackSource {
/// The track number. This is different from the index in the disc
/// source's tracks list, because it is not defined from which number the
/// the track numbers start.
pub number: u32,
/// The path to the temporary file to which the track will be ripped. The
/// file will not exist until the track is actually ripped.
pub path: PathBuf,
} }
impl DiscSource { impl DiscSource {
/// Try to create a new disc source by asynchronously reading the /// Create a new disc source. The source has to be initialized by calling
/// information from the default disc drive. /// load() afterwards.
pub async fn load() -> Result<Self> { pub fn new() -> Result<Self> {
let (sender, receiver) = oneshot::channel(); let result = Self {
discid: OnceCell::new(),
tracks: OnceCell::new(),
};
thread::spawn(|| { Ok(result)
let disc = Self::load_priv();
sender.send(disc).unwrap();
});
let disc = receiver.await??;
Ok(disc)
} }
/// Rip the whole disc asynchronously. After this method has finished /// Load the disc from the default disc drive and return the MusicBrainz
/// successfully, the audio files will be available in the specified /// DiscID as well as descriptions of the contained tracks.
/// location for each track source. fn load_priv() -> Result<(String, Vec<SourceTrack>)> {
pub async fn rip(&self) -> Result<()> {
for track in &self.tracks {
let (sender, receiver) = oneshot::channel();
let number = track.number;
let path = track.path.clone();
thread::spawn(move || {
let result = Self::rip_track(&path, number);
sender.send(result).unwrap();
});
receiver.await??;
}
Ok(())
}
/// Load the disc from the default disc drive.
fn load_priv() -> Result<Self> {
let discid = DiscId::read(None)?; let discid = DiscId::read(None)?;
let id = discid.id(); let id = discid.id();
@ -82,26 +46,23 @@ impl DiscSource {
let tmp_dir = Self::create_tmp_dir()?; let tmp_dir = Self::create_tmp_dir()?;
for number in first_track..=last_track { for number in first_track..=last_track {
let name = gettext!("Track {}", number);
let file_name = format!("track_{:02}.flac", number); let file_name = format!("track_{:02}.flac", number);
let mut path = tmp_dir.clone(); let mut path = tmp_dir.clone();
path.push(file_name); path.push(file_name);
let track = TrackSource { let track = SourceTrack {
number, number,
name,
path, path,
}; };
tracks.push(track); tracks.push(track);
} }
let disc = DiscSource { Ok((id, tracks))
discid: id,
tracks,
path: tmp_dir,
};
Ok(disc)
} }
/// Create a new temporary directory and return its path. /// Create a new temporary directory and return its path.
@ -172,3 +133,57 @@ impl DiscSource {
Ok(pipeline) Ok(pipeline)
} }
} }
#[async_trait]
impl Source for DiscSource {
async fn load(&self) -> Result<()> {
let (sender, receiver) = oneshot::channel();
thread::spawn(|| {
let result = Self::load_priv();
sender.send(result).unwrap();
});
let (discid, tracks) = receiver.await??;
self.discid.set(discid);
self.tracks.set(tracks);
Ok(())
}
fn tracks(&self) -> Option<&[SourceTrack]> {
match self.tracks.get() {
Some(tracks) => Some(tracks.as_slice()),
None => None,
}
}
fn discid(&self) -> Option<String> {
match self.discid.get() {
Some(discid) => Some(discid.to_owned()),
None => None,
}
}
async fn copy(&self) -> Result<()> {
let tracks = self.tracks.get()
.ok_or_else(|| anyhow!("Tried to copy disc before loading has finished!"))?;
for track in tracks {
let (sender, receiver) = oneshot::channel();
let number = track.number;
let path = track.path.clone();
thread::spawn(move || {
let result = Self::rip_track(&path, number);
sender.send(result).unwrap();
});
receiver.await??;
}
Ok(())
}
}

View file

@ -0,0 +1,90 @@
use super::source::{Source, SourceTrack};
use anyhow::{anyhow, Result};
use async_trait::async_trait;
use futures_channel::oneshot;
use once_cell::sync::OnceCell;
use std::path::{Path, PathBuf};
use std::thread;
/// A folder outside of the music library that contains tracks to import.
#[derive(Clone, Debug)]
pub struct FolderSource {
/// The path to the folder.
path: PathBuf,
/// The tracks within the folder.
tracks: OnceCell<Vec<SourceTrack>>,
}
impl FolderSource {
/// Create a new folder source.
pub fn new(path: PathBuf) -> Self {
Self {
path,
tracks: OnceCell::new(),
}
}
/// Load the contents of the folder as tracks.
fn load_priv(path: &Path) -> Result<Vec<SourceTrack>> {
let mut tracks = Vec::new();
let mut number = 1;
for entry in std::fs::read_dir(path)? {
let entry = entry?;
if entry.file_type()?.is_file() {
let name = entry
.file_name()
.into_string()
.or_else(|_| Err(anyhow!("Failed to convert OsString to String!")))?;
let path = entry.path();
let track = SourceTrack {
number,
name,
path,
};
tracks.push(track);
number += 1;
}
}
Ok(tracks)
}
}
#[async_trait]
impl Source for FolderSource {
async fn load(&self) -> Result<()> {
let (sender, receiver) = oneshot::channel();
let path = self.path.clone();
thread::spawn(move || {
let result = Self::load_priv(&path);
sender.send(result).unwrap();
});
let tracks = receiver.await??;
self.tracks.set(tracks);
Ok(())
}
fn tracks(&self) -> Option<&[SourceTrack]> {
match self.tracks.get() {
Some(tracks) => Some(tracks.as_slice()),
None => None,
}
}
fn discid(&self) -> Option<String> {
None
}
async fn copy(&self) -> Result<()> {
Ok(())
}
}

View file

@ -1,21 +1,21 @@
use super::disc_source::DiscSource; use super::source::Source;
use super::track_set_editor::{TrackSetData, TrackSetEditor}; use super::track_set_editor::{TrackSetData, TrackSetEditor};
use crate::database::{generate_id, Medium, Track, TrackSet}; use crate::database::{generate_id, Medium, Track, TrackSet};
use crate::backend::Backend; use crate::backend::Backend;
use crate::widgets::{List, Navigator, NavigatorScreen}; use crate::widgets::{List, Navigator, NavigatorScreen};
use anyhow::Result; use anyhow::{anyhow, Result};
use glib::clone; use glib::clone;
use glib::prelude::*; use glib::prelude::*;
use gtk::prelude::*; use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
/// A dialog for editing metadata while importing music into the music library. /// A dialog for editing metadata while importing music into the music library.
pub struct MediumEditor { pub struct MediumEditor {
backend: Rc<Backend>, backend: Rc<Backend>,
source: Rc<DiscSource>, source: Rc<Box<dyn Source>>,
widget: gtk::Stack, widget: gtk::Stack,
done_button: gtk::Button, done_button: gtk::Button,
done_stack: gtk::Stack, done_stack: gtk::Stack,
@ -29,7 +29,7 @@ pub struct MediumEditor {
impl MediumEditor { impl MediumEditor {
/// Create a new medium editor. /// Create a new medium editor.
pub fn new(backend: Rc<Backend>, source: DiscSource) -> Rc<Self> { pub fn new(backend: Rc<Backend>, source: Rc<Box<dyn Source>>) -> Rc<Self> {
// Create UI // Create UI
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/medium_editor.ui"); let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/medium_editor.ui");
@ -49,7 +49,7 @@ impl MediumEditor {
let this = Rc::new(Self { let this = Rc::new(Self {
backend, backend,
source: Rc::new(source), source,
widget, widget,
done_button, done_button,
done_stack, done_stack,
@ -117,7 +117,7 @@ impl MediumEditor {
edit_button.set_valign(gtk::Align::Center); edit_button.set_valign(gtk::Align::Center);
edit_button.set_child(Some(&edit_image)); edit_button.set_child(Some(&edit_image));
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&title)); row.set_title(Some(&title));
row.set_subtitle(Some(&subtitle)); row.set_subtitle(Some(&subtitle));
@ -131,14 +131,14 @@ impl MediumEditor {
row.upcast() row.upcast()
})); }));
// Start ripping the CD in the background. // Copy the source in the background.
let context = glib::MainContext::default(); let context = glib::MainContext::default();
let clone = this.clone(); let clone = this.clone();
context.spawn_local(async move { context.spawn_local(async move {
match clone.source.rip().await { match clone.source.copy().await {
Err(error) => { Err(error) => {
// TODO: Present error. // TODO: Present error.
println!("Failed to rip: {}", error); println!("Failed to copy source: {}", error);
}, },
Ok(_) => { Ok(_) => {
clone.done_stack.set_visible_child(&clone.done); clone.done_stack.set_visible_child(&clone.done);
@ -163,6 +163,7 @@ impl MediumEditor {
// Convert the track set data to real track sets. // Convert the track set data to real track sets.
let mut track_sets = Vec::new(); let mut track_sets = Vec::new();
let source_tracks = self.source.tracks().ok_or_else(|| anyhow!("Tracks not loaded!"))?;
for track_set_data in &*self.track_sets.borrow() { for track_set_data in &*self.track_sets.borrow() {
let mut tracks = Vec::new(); let mut tracks = Vec::new();
@ -170,11 +171,10 @@ impl MediumEditor {
for track_data in &track_set_data.tracks { for track_data in &track_set_data.tracks {
// Copy the corresponding audio file to the music library. // Copy the corresponding audio file to the music library.
let track_source = &self.source.tracks[track_data.track_source]; let track_source = &source_tracks[track_data.track_source];
let file_name = format!("track_{:02}.flac", track_source.number);
let mut track_path = path.clone(); let mut track_path = path.clone();
track_path.push(&file_name); track_path.push(track_source.path.file_name().unwrap());
std::fs::copy(&track_source.path, &track_path)?; std::fs::copy(&track_source.path, &track_path)?;
@ -199,7 +199,7 @@ impl MediumEditor {
let medium = Medium { let medium = Medium {
id: generate_id(), id: generate_id(),
name: self.name_entry.get_text().unwrap().to_string(), name: self.name_entry.get_text().unwrap().to_string(),
discid: Some(self.source.discid.clone()), discid: self.source.discid(),
tracks: track_sets, tracks: track_sets,
}; };

View file

@ -1,5 +1,7 @@
mod disc_source; mod disc_source;
mod folder_source;
mod medium_editor; mod medium_editor;
mod source;
mod source_selector; mod source_selector;
mod track_editor; mod track_editor;
mod track_selector; mod track_selector;

39
src/import/source.rs Normal file
View file

@ -0,0 +1,39 @@
use anyhow::Result;
use async_trait::async_trait;
use std::path::PathBuf;
/// A source for tracks that can be imported into the music library.
#[async_trait]
pub trait Source {
/// Load the source and discover the contained tracks.
async fn load(&self) -> Result<()>;
/// Get a reference to the tracks within this source, if they are ready.
fn tracks(&self) -> Option<&[SourceTrack]>;
/// Get the DiscID of the corresponging medium, if possible.
fn discid(&self) -> Option<String>;
/// Asynchronously copy the tracks to the files that are advertised within
/// their corresponding objects.
async fn copy(&self) -> Result<()>;
}
/// Representation of a single track on a source.
#[derive(Clone, Debug)]
pub struct SourceTrack {
/// The track number. This is different from the index in the disc
/// source's tracks list, because it is not defined from which number the
/// the track numbers start.
pub number: u32,
/// A human readable identifier for the track. This will be used to
/// present the track for selection.
pub name: String,
/// The path to the file where the corresponding audio file is. This file
/// is only required to exist, once the source's copy method has finished.
/// This will not be the actual file within the user's music library, but
/// the location from which it can be copied to the music library.
pub path: PathBuf,
}

View file

@ -1,11 +1,15 @@
use super::medium_editor::MediumEditor; use super::medium_editor::MediumEditor;
use super::disc_source::DiscSource; use super::disc_source::DiscSource;
use super::folder_source::FolderSource;
use super::source::Source;
use crate::backend::Backend; use crate::backend::Backend;
use crate::widgets::{Navigator, NavigatorScreen}; use crate::widgets::{Navigator, NavigatorScreen};
use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use std::cell::RefCell; use std::cell::RefCell;
use std::path::PathBuf;
use std::rc::Rc; use std::rc::Rc;
/// A dialog for starting to import music. /// A dialog for starting to import music.
@ -28,7 +32,8 @@ impl SourceSelector {
get_widget!(builder, gtk::Button, back_button); get_widget!(builder, gtk::Button, back_button);
get_widget!(builder, gtk::Stack, stack); get_widget!(builder, gtk::Stack, stack);
get_widget!(builder, gtk::InfoBar, info_bar); get_widget!(builder, gtk::InfoBar, info_bar);
get_widget!(builder, gtk::Button, import_button); get_widget!(builder, gtk::Button, folder_button);
get_widget!(builder, gtk::Button, disc_button);
let this = Rc::new(Self { let this = Rc::new(Self {
backend, backend,
@ -47,17 +52,68 @@ impl SourceSelector {
} }
})); }));
import_button.connect_clicked(clone!(@strong this => move |_| { folder_button.connect_clicked(clone!(@strong this => move |_| {
let window = this.navigator.borrow().clone().unwrap().window.clone();
let dialog = gtk::FileChooserDialog::new(
Some(&gettext("Select folder")),
Some(&window),
gtk::FileChooserAction::SelectFolder,
&[
(&gettext("Cancel"), gtk::ResponseType::Cancel),
(&gettext("Select"), gtk::ResponseType::Accept),
]);
dialog.connect_response(clone!(@strong this => move |dialog, response| {
this.stack.set_visible_child_name("loading");
dialog.hide();
if let gtk::ResponseType::Accept = response {
if let Some(file) = dialog.get_file() {
if let Some(path) = file.get_path() {
let context = glib::MainContext::default();
let clone = this.clone();
context.spawn_local(async move {
let folder = FolderSource::new(PathBuf::from(path));
match folder.load().await {
Ok(_) => {
let navigator = clone.navigator.borrow().clone();
if let Some(navigator) = navigator {
let source = Rc::new(Box::new(folder) as Box<dyn Source>);
let editor = MediumEditor::new(clone.backend.clone(), source);
navigator.push(editor);
}
clone.info_bar.set_revealed(false);
clone.stack.set_visible_child_name("start");
}
Err(_) => {
// TODO: Present error.
clone.info_bar.set_revealed(true);
clone.stack.set_visible_child_name("start");
}
}
});
}
}
}
}));
dialog.show();
}));
disc_button.connect_clicked(clone!(@strong this => move |_| {
this.stack.set_visible_child_name("loading"); this.stack.set_visible_child_name("loading");
let context = glib::MainContext::default(); let context = glib::MainContext::default();
let clone = this.clone(); let clone = this.clone();
context.spawn_local(async move { context.spawn_local(async move {
match DiscSource::load().await { let disc = DiscSource::new().unwrap();
Ok(disc) => { match disc.load().await {
Ok(_) => {
let navigator = clone.navigator.borrow().clone(); let navigator = clone.navigator.borrow().clone();
if let Some(navigator) = navigator { if let Some(navigator) = navigator {
let editor = MediumEditor::new(clone.backend.clone(), disc); let source = Rc::new(Box::new(disc) as Box<dyn Source>);
let editor = MediumEditor::new(clone.backend.clone(), source);
navigator.push(editor); navigator.push(editor);
} }
@ -65,6 +121,7 @@ impl SourceSelector {
clone.stack.set_visible_child_name("start"); clone.stack.set_visible_child_name("start");
} }
Err(_) => { Err(_) => {
// TODO: Present error.
clone.info_bar.set_revealed(true); clone.info_bar.set_revealed(true);
clone.stack.set_visible_child_name("start"); clone.stack.set_visible_child_name("start");
} }

View file

@ -3,7 +3,7 @@ use crate::widgets::{Navigator, NavigatorScreen};
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -76,7 +76,7 @@ impl TrackEditor {
} }
})); }));
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.add_prefix(&check); row.add_prefix(&check);
row.set_activatable_widget(Some(&check)); row.set_activatable_widget(Some(&check));
row.set_title(Some(&part.title)); row.set_title(Some(&part.title));

View file

@ -1,15 +1,15 @@
use super::disc_source::DiscSource; use super::source::Source;
use crate::widgets::{Navigator, NavigatorScreen}; use crate::widgets::{Navigator, NavigatorScreen};
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
/// A screen for selecting tracks from a medium. /// A screen for selecting tracks from a source.
pub struct TrackSelector { pub struct TrackSelector {
source: Rc<DiscSource>, source: Rc<Box<dyn Source>>,
widget: gtk::Box, widget: gtk::Box,
select_button: gtk::Button, select_button: gtk::Button,
selection: RefCell<Vec<usize>>, selection: RefCell<Vec<usize>>,
@ -19,7 +19,7 @@ pub struct TrackSelector {
impl TrackSelector { impl TrackSelector {
/// Create a new track selector. /// Create a new track selector.
pub fn new(source: Rc<DiscSource>) -> Rc<Self> { pub fn new(source: Rc<Box<dyn Source>>) -> Rc<Self> {
// Create UI // Create UI
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/track_selector.ui"); let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/track_selector.ui");
@ -65,7 +65,9 @@ impl TrackSelector {
} }
})); }));
for (index, track) in this.source.tracks.iter().enumerate() { let tracks = this.source.tracks().unwrap();
for (index, track) in tracks.iter().enumerate() {
let check = gtk::CheckButton::new(); let check = gtk::CheckButton::new();
check.connect_toggled(clone!(@strong this => move |check| { check.connect_toggled(clone!(@strong this => move |check| {
@ -85,13 +87,11 @@ impl TrackSelector {
} }
})); }));
let title = format!("Track {}", track.number); let row = libadwaita::ActionRow::new();
let row = libhandy::ActionRow::new();
row.add_prefix(&check); row.add_prefix(&check);
row.set_activatable_widget(Some(&check)); row.set_activatable_widget(Some(&check));
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&title)); row.set_title(Some(&track.name));
track_list.append(&row); track_list.append(&row);
} }

View file

@ -1,4 +1,4 @@
use super::disc_source::DiscSource; use super::source::Source;
use super::track_editor::TrackEditor; use super::track_editor::TrackEditor;
use super::track_selector::TrackSelector; use super::track_selector::TrackSelector;
use crate::backend::Backend; use crate::backend::Backend;
@ -9,7 +9,7 @@ use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -33,10 +33,10 @@ pub struct TrackData {
/// A screen for editing a set of tracks for one recording. /// A screen for editing a set of tracks for one recording.
pub struct TrackSetEditor { pub struct TrackSetEditor {
backend: Rc<Backend>, backend: Rc<Backend>,
source: Rc<DiscSource>, source: Rc<Box<dyn Source>>,
widget: gtk::Box, widget: gtk::Box,
save_button: gtk::Button, save_button: gtk::Button,
recording_row: libhandy::ActionRow, recording_row: libadwaita::ActionRow,
track_list: Rc<List>, track_list: Rc<List>,
recording: RefCell<Option<Recording>>, recording: RefCell<Option<Recording>>,
tracks: RefCell<Vec<TrackData>>, tracks: RefCell<Vec<TrackData>>,
@ -46,7 +46,7 @@ pub struct TrackSetEditor {
impl TrackSetEditor { impl TrackSetEditor {
/// Create a new track set editor. /// Create a new track set editor.
pub fn new(backend: Rc<Backend>, source: Rc<DiscSource>) -> Rc<Self> { pub fn new(backend: Rc<Backend>, source: Rc<Box<dyn Source>>) -> Rc<Self> {
// Create UI // Create UI
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/track_set_editor.ui"); let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/track_set_editor.ui");
@ -54,7 +54,7 @@ impl TrackSetEditor {
get_widget!(builder, gtk::Box, widget); get_widget!(builder, gtk::Box, widget);
get_widget!(builder, gtk::Button, back_button); get_widget!(builder, gtk::Button, back_button);
get_widget!(builder, gtk::Button, save_button); get_widget!(builder, gtk::Button, save_button);
get_widget!(builder, libhandy::ActionRow, recording_row); get_widget!(builder, libadwaita::ActionRow, recording_row);
get_widget!(builder, gtk::Button, select_recording_button); get_widget!(builder, gtk::Button, select_recording_button);
get_widget!(builder, gtk::Button, edit_tracks_button); get_widget!(builder, gtk::Button, edit_tracks_button);
get_widget!(builder, gtk::Frame, tracks_frame); get_widget!(builder, gtk::Frame, tracks_frame);
@ -174,8 +174,8 @@ impl TrackSetEditor {
title_parts.join(", ") title_parts.join(", ")
}; };
let number = this.source.tracks[track.track_source].number; let tracks = this.source.tracks().unwrap();
let subtitle = format!("Track {}", number); let track_name = &tracks[track.track_source].name;
let edit_image = gtk::Image::from_icon_name(Some("document-edit-symbolic")); let edit_image = gtk::Image::from_icon_name(Some("document-edit-symbolic"));
let edit_button = gtk::Button::new(); let edit_button = gtk::Button::new();
@ -183,10 +183,10 @@ impl TrackSetEditor {
edit_button.set_valign(gtk::Align::Center); edit_button.set_valign(gtk::Align::Center);
edit_button.set_child(Some(&edit_image)); edit_button.set_child(Some(&edit_image));
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&title)); row.set_title(Some(&title));
row.set_subtitle(Some(&subtitle)); row.set_subtitle(Some(track_name));
row.add_suffix(&edit_button); row.add_suffix(&edit_button);
row.set_activatable_widget(Some(&edit_button)); row.set_activatable_widget(Some(&edit_button));

View file

@ -34,7 +34,7 @@ fn main() {
gstreamer::init().expect("Failed to initialize GStreamer!"); gstreamer::init().expect("Failed to initialize GStreamer!");
gtk::init().expect("Failed to initialize GTK!"); gtk::init().expect("Failed to initialize GTK!");
libhandy::init(); libadwaita::init();
resources::init().expect("Failed to initialize resources!"); resources::init().expect("Failed to initialize resources!");
let app = gtk::Application::new(Some("de.johrpan.musicus"), gio::ApplicationFlags::empty()) let app = gtk::Application::new(Some("de.johrpan.musicus"), gio::ApplicationFlags::empty())

View file

@ -66,8 +66,10 @@ sources = files(
'editors/work_part.rs', 'editors/work_part.rs',
'editors/work_section.rs', 'editors/work_section.rs',
'import/disc_source.rs', 'import/disc_source.rs',
'import/folder_source.rs',
'import/medium_editor.rs', 'import/medium_editor.rs',
'import/mod.rs', 'import/mod.rs',
'import/source.rs',
'import/source_selector.rs', 'import/source_selector.rs',
'import/track_editor.rs', 'import/track_editor.rs',
'import/track_selector.rs', 'import/track_selector.rs',

View file

@ -7,7 +7,7 @@ use gio::prelude::*;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -72,7 +72,7 @@ impl EnsembleScreen {
this.recording_list.set_make_widget_cb(clone!(@strong this => move |index| { this.recording_list.set_make_widget_cb(clone!(@strong this => move |index| {
let recording = &this.recordings.borrow()[index]; let recording = &this.recordings.borrow()[index];
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&recording.work.get_title())); row.set_title(Some(&recording.work.get_title()));
row.set_subtitle(Some(&recording.get_performers())); row.set_subtitle(Some(&recording.get_performers()));

View file

@ -7,7 +7,7 @@ use gio::prelude::*;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -86,7 +86,7 @@ impl PersonScreen {
this.work_list.set_make_widget_cb(clone!(@strong this => move |index| { this.work_list.set_make_widget_cb(clone!(@strong this => move |index| {
let work = &this.works.borrow()[index]; let work = &this.works.borrow()[index];
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&work.title)); row.set_title(Some(&work.title));
@ -111,7 +111,7 @@ impl PersonScreen {
this.recording_list.set_make_widget_cb(clone!(@strong this => move |index| { this.recording_list.set_make_widget_cb(clone!(@strong this => move |index| {
let recording = &this.recordings.borrow()[index]; let recording = &this.recordings.borrow()[index];
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&recording.work.get_title())); row.set_title(Some(&recording.work.get_title()));
row.set_subtitle(Some(&recording.get_performers())); row.set_subtitle(Some(&recording.get_performers()));

View file

@ -4,7 +4,7 @@ use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::rc::Rc; use std::rc::Rc;
@ -155,7 +155,7 @@ impl PlayerScreen {
let playlist_item = &this.playlist.borrow()[item_index]; let playlist_item = &this.playlist.borrow()[item_index];
let recording = &playlist_item.track_set.recording; let recording = &playlist_item.track_set.recording;
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_activatable(false); row.set_activatable(false);
row.set_selectable(false); row.set_selectable(false);
row.set_title(Some(&recording.work.get_title())); row.set_title(Some(&recording.work.get_title()));
@ -179,7 +179,7 @@ impl PlayerScreen {
parts.join(", ") parts.join(", ")
}; };
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_selectable(false); row.set_selectable(false);
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&title)); row.set_title(Some(&title));

View file

@ -8,7 +8,7 @@ use gio::prelude::*;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -92,7 +92,7 @@ impl RecordingScreen {
title_parts.join(", ") title_parts.join(", ")
}; };
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_title(Some(&title)); row.set_title(Some(&title));
row.upcast() row.upcast()

View file

@ -7,7 +7,7 @@ use gio::prelude::*;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -74,7 +74,7 @@ impl WorkScreen {
this.recording_list.set_make_widget_cb(clone!(@strong this => move |index| { this.recording_list.set_make_widget_cb(clone!(@strong this => move |index| {
let recording = &this.recordings.borrow()[index]; let recording = &this.recordings.borrow()[index];
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&recording.work.get_title())); row.set_title(Some(&recording.work.get_title()));
row.set_subtitle(Some(&recording.get_performers())); row.set_subtitle(Some(&recording.get_performers()));

View file

@ -6,7 +6,7 @@ use crate::widgets::{Navigator, NavigatorScreen};
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -65,7 +65,7 @@ impl EnsembleSelector {
})); }));
this.selector.set_make_widget(clone!(@strong this => move |ensemble| { this.selector.set_make_widget(clone!(@strong this => move |ensemble| {
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&ensemble.name)); row.set_title(Some(&ensemble.name));

View file

@ -6,7 +6,7 @@ use crate::widgets::{Navigator, NavigatorScreen};
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -65,7 +65,7 @@ impl InstrumentSelector {
})); }));
this.selector.set_make_widget(clone!(@strong this => move |instrument| { this.selector.set_make_widget(clone!(@strong this => move |instrument| {
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&instrument.name)); row.set_title(Some(&instrument.name));

View file

@ -6,7 +6,7 @@ use crate::widgets::{Navigator, NavigatorScreen};
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -65,7 +65,7 @@ impl PersonSelector {
})); }));
this.selector.set_make_widget(clone!(@strong this => move |person| { this.selector.set_make_widget(clone!(@strong this => move |person| {
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&person.name_lf())); row.set_title(Some(&person.name_lf()));

View file

@ -6,7 +6,7 @@ use crate::widgets::{Navigator, NavigatorScreen};
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -75,7 +75,7 @@ impl RecordingSelector {
})); }));
this.selector.set_make_widget(clone!(@strong this => move |recording| { this.selector.set_make_widget(clone!(@strong this => move |recording| {
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&recording.get_performers())); row.set_title(Some(&recording.get_performers()));

View file

@ -6,7 +6,7 @@ use crate::widgets::{Navigator, NavigatorScreen};
use gettextrs::gettext; use gettextrs::gettext;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -75,7 +75,7 @@ impl WorkSelector {
})); }));
this.selector.set_make_widget(clone!(@strong this => move |work| { this.selector.set_make_widget(clone!(@strong this => move |work| {
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&work.title)); row.set_title(Some(&work.title));

View file

@ -128,6 +128,8 @@ impl Navigator {
} }
pub fn reset(&self) { pub fn reset(&self) {
self.widget.set_visible_child_name("empty_screen");
for screen in self.screens.replace(Vec::new()) { for screen in self.screens.replace(Vec::new()) {
screen.detach_navigator(); screen.detach_navigator();
self.old_screens.borrow_mut().push(screen); self.old_screens.borrow_mut().push(screen);

View file

@ -5,7 +5,7 @@ use std::rc::Rc;
/// A window hosting a navigator. /// A window hosting a navigator.
pub struct NavigatorWindow { pub struct NavigatorWindow {
window: libhandy::Window, window: libadwaita::Window,
navigator: Rc<Navigator>, navigator: Rc<Navigator>,
} }
@ -14,11 +14,11 @@ impl NavigatorWindow {
pub fn new<S: NavigatorScreen + 'static>(initial_screen: Rc<S>) -> Rc<Self> { pub fn new<S: NavigatorScreen + 'static>(initial_screen: Rc<S>) -> Rc<Self> {
// Create UI // Create UI
let window = libhandy::Window::new(); let window = libadwaita::Window::new();
window.set_default_size(600, 424); window.set_default_size(600, 424);
let placeholder = gtk::Label::new(None); let placeholder = gtk::Label::new(None);
let navigator = Navigator::new(&window, &placeholder); let navigator = Navigator::new(&window, &placeholder);
libhandy::WindowExt::set_child(&window, Some(&navigator.widget)); libadwaita::WindowExt::set_child(&window, Some(&navigator.widget));
let this = Rc::new(Self { window, navigator }); let this = Rc::new(Self { window, navigator });

View file

@ -4,7 +4,7 @@ use crate::database::*;
use glib::clone; use glib::clone;
use gtk::prelude::*; use gtk::prelude::*;
use gtk_macros::get_widget; use gtk_macros::get_widget;
use libhandy::prelude::*; use libadwaita::prelude::*;
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
@ -64,7 +64,7 @@ impl PoeList {
this.list.set_make_widget_cb(clone!(@strong this => move |index| { this.list.set_make_widget_cb(clone!(@strong this => move |index| {
let poe = &this.data.borrow()[index]; let poe = &this.data.borrow()[index];
let row = libhandy::ActionRow::new(); let row = libadwaita::ActionRow::new();
row.set_activatable(true); row.set_activatable(true);
row.set_title(Some(&poe.get_title())); row.set_title(Some(&poe.get_title()));

View file

@ -13,9 +13,9 @@ use std::rc::Rc;
pub struct Window { pub struct Window {
backend: Rc<Backend>, backend: Rc<Backend>,
window: libhandy::ApplicationWindow, window: libadwaita::ApplicationWindow,
stack: gtk::Stack, stack: gtk::Stack,
leaflet: libhandy::Leaflet, leaflet: libadwaita::Leaflet,
sidebar_box: gtk::Box, sidebar_box: gtk::Box,
poe_list: Rc<PoeList>, poe_list: Rc<PoeList>,
navigator: Rc<Navigator>, navigator: Rc<Navigator>,
@ -27,11 +27,11 @@ impl Window {
pub fn new(app: &gtk::Application) -> Rc<Self> { pub fn new(app: &gtk::Application) -> Rc<Self> {
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/window.ui"); let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/window.ui");
get_widget!(builder, libhandy::ApplicationWindow, window); get_widget!(builder, libadwaita::ApplicationWindow, window);
get_widget!(builder, gtk::Stack, stack); get_widget!(builder, gtk::Stack, stack);
get_widget!(builder, gtk::Button, select_music_library_path_button); get_widget!(builder, gtk::Button, select_music_library_path_button);
get_widget!(builder, gtk::Box, content_box); get_widget!(builder, gtk::Box, content_box);
get_widget!(builder, libhandy::Leaflet, leaflet); get_widget!(builder, libadwaita::Leaflet, leaflet);
get_widget!(builder, gtk::Button, add_button); get_widget!(builder, gtk::Button, add_button);
get_widget!(builder, gtk::Box, sidebar_box); get_widget!(builder, gtk::Box, sidebar_box);
get_widget!(builder, gtk::Box, empty_screen); get_widget!(builder, gtk::Box, empty_screen);
@ -65,15 +65,17 @@ impl Window {
result.window.set_application(Some(app)); result.window.set_application(Some(app));
select_music_library_path_button.connect_clicked(clone!(@strong result => move |_| { select_music_library_path_button.connect_clicked(clone!(@strong result => move |_| {
let dialog = gtk::FileChooserNative::new( let dialog = gtk::FileChooserDialog::new(
Some(&gettext("Select music library folder")), Some(&gettext("Select music library folder")),
Some(&result.window), Some(&result.window),
gtk::FileChooserAction::SelectFolder, gtk::FileChooserAction::SelectFolder,
None, &[
None); (&gettext("Cancel"), gtk::ResponseType::Cancel),
(&gettext("Select"), gtk::ResponseType::Accept),
]);
dialog.connect_response(clone!(@strong result => move |dialog, response| { dialog.connect_response(clone!(@strong result => move |dialog, response| {
if response == gtk::ResponseType::Accept { if let gtk::ResponseType::Accept = response {
if let Some(file) = dialog.get_file() { if let Some(file) = dialog.get_file() {
if let Some(path) = file.get_path() { if let Some(path) = file.get_path() {
let context = glib::MainContext::default(); let context = glib::MainContext::default();
@ -84,6 +86,8 @@ impl Window {
} }
} }
} }
dialog.hide();
})); }));
dialog.show(); dialog.show();