Restore edit and delete menus

This commit is contained in:
Elias Projahn 2020-11-17 16:48:21 +01:00
parent a93c7276d2
commit 40050b3ac3
12 changed files with 253 additions and 144 deletions

View file

@ -27,11 +27,12 @@
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuButton" id="menu_button"> <object class="GtkMenuButton">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="focus-on-click">False</property> <property name="focus-on-click">False</property>
<property name="receives-default">True</property> <property name="receives-default">True</property>
<property name="menu-model">menu</property>
<child> <child>
<object class="GtkImage"> <object class="GtkImage">
<property name="visible">True</property> <property name="visible">True</property>
@ -200,4 +201,16 @@
</packing> </packing>
</child> </child>
</object> </object>
<menu id="menu">
<section>
<item>
<attribute name="label" translatable="yes">Edit ensemble</attribute>
<attribute name="action">widget.edit</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Delete ensemble</attribute>
<attribute name="action">widget.delete</attribute>
</item>
</section>
</menu>
</interface> </interface>

View file

@ -27,11 +27,12 @@
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuButton" id="menu_button"> <object class="GtkMenuButton">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="focus-on-click">False</property> <property name="focus-on-click">False</property>
<property name="receives-default">True</property> <property name="receives-default">True</property>
<property name="menu-model">menu</property>
<child> <child>
<object class="GtkImage"> <object class="GtkImage">
<property name="visible">True</property> <property name="visible">True</property>
@ -258,4 +259,16 @@
</packing> </packing>
</child> </child>
</object> </object>
<menu id="menu">
<section>
<item>
<attribute name="label" translatable="yes">Edit person</attribute>
<attribute name="action">widget.edit</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Delete person</attribute>
<attribute name="action">widget.delete</attribute>
</item>
</section>
</menu>
</interface> </interface>

View file

@ -27,11 +27,12 @@
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuButton" id="menu_button"> <object class="GtkMenuButton">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="focus-on-click">False</property> <property name="focus-on-click">False</property>
<property name="receives-default">True</property> <property name="receives-default">True</property>
<property name="menu-model">menu</property>
<child> <child>
<object class="GtkImage"> <object class="GtkImage">
<property name="visible">True</property> <property name="visible">True</property>
@ -159,4 +160,26 @@
</packing> </packing>
</child> </child>
</object> </object>
<menu id="menu">
<section>
<item>
<attribute name="label" translatable="yes">Edit recording</attribute>
<attribute name="action">widget.edit</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Delete recording</attribute>
<attribute name="action">widget.delete</attribute>
</item>
</section>
<section>
<item>
<attribute name="label" translatable="yes">Edit tracks</attribute>
<attribute name="action">widget.edit-tracks</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Delete tracks</attribute>
<attribute name="action">widget.delete-tracks</attribute>
</item>
</section>
</menu>
</interface> </interface>

View file

@ -27,11 +27,12 @@
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuButton" id="menu_button"> <object class="GtkMenuButton">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">True</property> <property name="can-focus">True</property>
<property name="focus-on-click">False</property> <property name="focus-on-click">False</property>
<property name="receives-default">True</property> <property name="receives-default">True</property>
<property name="menu-model">menu</property>
<child> <child>
<object class="GtkImage"> <object class="GtkImage">
<property name="visible">True</property> <property name="visible">True</property>
@ -200,4 +201,16 @@
</packing> </packing>
</child> </child>
</object> </object>
<menu id="menu">
<section>
<item>
<attribute name="label" translatable="yes">Edit work</attribute>
<attribute name="action">widget.edit</attribute>
</item>
<item>
<attribute name="label" translatable="yes">Delete work</attribute>
<attribute name="action">widget.delete</attribute>
</item>
</section>
</menu>
</interface> </interface>

View file

@ -63,8 +63,8 @@ where
let c = glib::MainContext::default(); let c = glib::MainContext::default();
c.spawn_local(async move { c.spawn_local(async move {
clone.backend.db().update_ensemble(ensemble.clone()).await.unwrap(); clone.backend.db().update_ensemble(ensemble.clone()).await.unwrap();
clone.window.close();
(clone.callback)(ensemble.clone()); (clone.callback)(ensemble.clone());
clone.window.close();
}); });
})); }));

View file

@ -44,8 +44,9 @@ impl RecordingEditorDialog {
editor.set_selected_cb(clone!(@strong this => move |recording| { editor.set_selected_cb(clone!(@strong this => move |recording| {
if let Some(cb) = &*this.selected_cb.borrow() { if let Some(cb) = &*this.selected_cb.borrow() {
cb(recording); cb(recording);
this.window.close();
} }
this.window.close();
})); }));
this this

View file

@ -44,8 +44,9 @@ impl WorkEditorDialog {
editor.set_saved_cb(clone!(@strong this => move |work| { editor.set_saved_cb(clone!(@strong this => move |work| {
if let Some(cb) = &*this.saved_cb.borrow() { if let Some(cb) = &*this.saved_cb.borrow() {
cb(work); cb(work);
this.window.close();
} }
this.window.close();
})); }));
this this

View file

@ -1,8 +1,10 @@
use super::*; use super::*;
use crate::backend::*; use crate::backend::*;
use crate::database::*; use crate::database::*;
use crate::dialogs::EnsembleEditor;
use crate::widgets::*; use crate::widgets::*;
use gettextrs::gettext; use gettextrs::gettext;
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;
@ -12,6 +14,8 @@ use std::rc::Rc;
pub struct EnsembleScreen { pub struct EnsembleScreen {
backend: Rc<Backend>, backend: Rc<Backend>,
window: gtk::Window,
ensemble: Ensemble,
widget: gtk::Box, widget: gtk::Box,
stack: gtk::Stack, stack: gtk::Stack,
recording_list: Rc<List<Recording>>, recording_list: Rc<List<Recording>>,
@ -19,36 +23,29 @@ pub struct EnsembleScreen {
} }
impl EnsembleScreen { impl EnsembleScreen {
pub fn new(backend: Rc<Backend>, ensemble: Ensemble) -> Rc<Self> { pub fn new<W>(backend: Rc<Backend>, window: &W, ensemble: Ensemble) -> Rc<Self>
where
W: IsA<gtk::Window>,
{
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/ensemble_screen.ui"); let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/ensemble_screen.ui");
get_widget!(builder, gtk::Box, widget); get_widget!(builder, gtk::Box, widget);
get_widget!(builder, libhandy::HeaderBar, header); get_widget!(builder, libhandy::HeaderBar, header);
get_widget!(builder, gtk::Button, back_button); get_widget!(builder, gtk::Button, back_button);
get_widget!(builder, gtk::MenuButton, menu_button);
get_widget!(builder, gtk::SearchEntry, search_entry); get_widget!(builder, gtk::SearchEntry, search_entry);
get_widget!(builder, gtk::Stack, stack); get_widget!(builder, gtk::Stack, stack);
get_widget!(builder, gtk::Frame, recording_frame); get_widget!(builder, gtk::Frame, recording_frame);
header.set_title(Some(&ensemble.name)); header.set_title(Some(&ensemble.name));
let edit_menu_item = gio::MenuItem::new(Some(&gettext("Edit ensemble")), None); let edit_action = gio::SimpleAction::new("edit", None);
edit_menu_item.set_action_and_target_value( let delete_action = gio::SimpleAction::new("delete", None);
Some("win.edit-ensemble"),
Some(&glib::Variant::from(ensemble.id)),
);
let delete_menu_item = gio::MenuItem::new(Some(&gettext("Delete ensemble")), None); let actions = gio::SimpleActionGroup::new();
delete_menu_item.set_action_and_target_value( actions.add_action(&edit_action);
Some("win.delete-ensemble"), actions.add_action(&delete_action);
Some(&glib::Variant::from(ensemble.id)),
);
let menu = gio::Menu::new(); widget.insert_action_group("widget", Some(&actions));
menu.append_item(&edit_menu_item);
menu.append_item(&delete_menu_item);
menu_button.set_menu_model(Some(&menu));
let recording_list = List::new(&gettext("No recordings found.")); let recording_list = List::new(&gettext("No recordings found."));
@ -83,6 +80,8 @@ impl EnsembleScreen {
let result = Rc::new(Self { let result = Rc::new(Self {
backend, backend,
window: window.clone().upcast(),
ensemble,
widget, widget,
stack, stack,
recording_list, recording_list,
@ -105,17 +104,29 @@ impl EnsembleScreen {
.set_selected(clone!(@strong result => move |recording| { .set_selected(clone!(@strong result => move |recording| {
let navigator = result.navigator.borrow().clone(); let navigator = result.navigator.borrow().clone();
if let Some(navigator) = navigator { if let Some(navigator) = navigator {
navigator.push(RecordingScreen::new(result.backend.clone(), recording.clone())); navigator.push(RecordingScreen::new(result.backend.clone(), &result.window, recording.clone()));
} }
})); }));
edit_action.connect_activate(clone!(@strong result => move |_, _| {
EnsembleEditor::new(result.backend.clone(), &result.window, Some(result.ensemble.clone()), |_| {}).show();
}));
delete_action.connect_activate(clone!(@strong result => move |_, _| {
let context = glib::MainContext::default();
let clone = result.clone();
context.spawn_local(async move {
clone.backend.db().delete_ensemble(clone.ensemble.id).await.unwrap();
});
}));
let context = glib::MainContext::default(); let context = glib::MainContext::default();
let clone = result.clone(); let clone = result.clone();
context.spawn_local(async move { context.spawn_local(async move {
let recordings = clone let recordings = clone
.backend .backend
.db() .db()
.get_recordings_for_ensemble(ensemble.id as u32) .get_recordings_for_ensemble(clone.ensemble.id)
.await .await
.unwrap(); .unwrap();

View file

@ -1,8 +1,10 @@
use super::*; use super::*;
use crate::backend::*; use crate::backend::*;
use crate::database::*; use crate::database::*;
use crate::dialogs::PersonEditor;
use crate::widgets::*; use crate::widgets::*;
use gettextrs::gettext; use gettextrs::gettext;
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;
@ -12,6 +14,8 @@ use std::rc::Rc;
pub struct PersonScreen { pub struct PersonScreen {
backend: Rc<Backend>, backend: Rc<Backend>,
window: gtk::Window,
person: Person,
widget: gtk::Box, widget: gtk::Box,
stack: gtk::Stack, stack: gtk::Stack,
work_list: Rc<List<Work>>, work_list: Rc<List<Work>>,
@ -20,13 +24,15 @@ pub struct PersonScreen {
} }
impl PersonScreen { impl PersonScreen {
pub fn new(backend: Rc<Backend>, person: Person) -> Rc<Self> { pub fn new<W>(backend: Rc<Backend>, window: &W, person: Person) -> Rc<Self>
where
W: IsA<gtk::Window>,
{
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/person_screen.ui"); let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/person_screen.ui");
get_widget!(builder, gtk::Box, widget); get_widget!(builder, gtk::Box, widget);
get_widget!(builder, libhandy::HeaderBar, header); get_widget!(builder, libhandy::HeaderBar, header);
get_widget!(builder, gtk::Button, back_button); get_widget!(builder, gtk::Button, back_button);
get_widget!(builder, gtk::MenuButton, menu_button);
get_widget!(builder, gtk::SearchEntry, search_entry); get_widget!(builder, gtk::SearchEntry, search_entry);
get_widget!(builder, gtk::Stack, stack); get_widget!(builder, gtk::Stack, stack);
get_widget!(builder, gtk::Box, work_box); get_widget!(builder, gtk::Box, work_box);
@ -36,23 +42,14 @@ impl PersonScreen {
header.set_title(Some(&person.name_fl())); header.set_title(Some(&person.name_fl()));
let edit_menu_item = gio::MenuItem::new(Some(&gettext("Edit person")), None); let edit_action = gio::SimpleAction::new("edit", None);
edit_menu_item.set_action_and_target_value( let delete_action = gio::SimpleAction::new("delete", None);
Some("win.edit-person"),
Some(&glib::Variant::from(person.id)),
);
let delete_menu_item = gio::MenuItem::new(Some(&gettext("Delete person")), None); let actions = gio::SimpleActionGroup::new();
delete_menu_item.set_action_and_target_value( actions.add_action(&edit_action);
Some("win.delete-person"), actions.add_action(&delete_action);
Some(&glib::Variant::from(person.id)),
);
let menu = gio::Menu::new(); widget.insert_action_group("widget", Some(&actions));
menu.append_item(&edit_menu_item);
menu.append_item(&delete_menu_item);
menu_button.set_menu_model(Some(&menu));
let work_list = List::new(&gettext("No works found.")); let work_list = List::new(&gettext("No works found."));
@ -106,6 +103,8 @@ impl PersonScreen {
let result = Rc::new(Self { let result = Rc::new(Self {
backend, backend,
window: window.clone().upcast(),
person,
widget, widget,
stack, stack,
work_list, work_list,
@ -131,7 +130,7 @@ impl PersonScreen {
result.recording_list.clear_selection(); result.recording_list.clear_selection();
let navigator = result.navigator.borrow().clone(); let navigator = result.navigator.borrow().clone();
if let Some(navigator) = navigator { if let Some(navigator) = navigator {
navigator.push(WorkScreen::new(result.backend.clone(), work.clone())); navigator.push(WorkScreen::new(result.backend.clone(), &result.window, work.clone()));
} }
})); }));
@ -141,23 +140,35 @@ impl PersonScreen {
result.work_list.clear_selection(); result.work_list.clear_selection();
let navigator = result.navigator.borrow().clone(); let navigator = result.navigator.borrow().clone();
if let Some(navigator) = navigator { if let Some(navigator) = navigator {
navigator.push(RecordingScreen::new(result.backend.clone(), recording.clone())); navigator.push(RecordingScreen::new(result.backend.clone(), &result.window, recording.clone()));
} }
})); }));
edit_action.connect_activate(clone!(@strong result => move |_, _| {
PersonEditor::new(result.backend.clone(), &result.window, Some(result.person.clone()), |_| {}).show();
}));
delete_action.connect_activate(clone!(@strong result => move |_, _| {
let context = glib::MainContext::default();
let clone = result.clone();
context.spawn_local(async move {
clone.backend.db().delete_person(clone.person.id).await.unwrap();
});
}));
let context = glib::MainContext::default(); let context = glib::MainContext::default();
let clone = result.clone(); let clone = result.clone();
context.spawn_local(async move { context.spawn_local(async move {
let works = clone let works = clone
.backend .backend
.db() .db()
.get_works(person.id as u32) .get_works(clone.person.id as u32)
.await .await
.unwrap(); .unwrap();
let recordings = clone let recordings = clone
.backend .backend
.db() .db()
.get_recordings_for_person(person.id as u32) .get_recordings_for_person(clone.person.id as u32)
.await .await
.unwrap(); .unwrap();

View file

@ -1,8 +1,10 @@
use crate::backend::*; use crate::backend::*;
use crate::database::*; use crate::database::*;
use crate::dialogs::{RecordingEditorDialog, TracksEditor};
use crate::player::*; use crate::player::*;
use crate::widgets::*; use crate::widgets::*;
use gettextrs::gettext; use gettextrs::gettext;
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;
@ -12,6 +14,8 @@ use std::rc::Rc;
pub struct RecordingScreen { pub struct RecordingScreen {
backend: Rc<Backend>, backend: Rc<Backend>,
window: gtk::Window,
recording: Recording,
widget: gtk::Box, widget: gtk::Box,
stack: gtk::Stack, stack: gtk::Stack,
tracks: RefCell<Vec<Track>>, tracks: RefCell<Vec<Track>>,
@ -19,13 +23,15 @@ pub struct RecordingScreen {
} }
impl RecordingScreen { impl RecordingScreen {
pub fn new(backend: Rc<Backend>, recording: Recording) -> Rc<Self> { pub fn new<W>(backend: Rc<Backend>, window: &W, recording: Recording) -> Rc<Self>
where
W: IsA<gtk::Window>,
{
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/recording_screen.ui"); let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/recording_screen.ui");
get_widget!(builder, gtk::Box, widget); get_widget!(builder, gtk::Box, widget);
get_widget!(builder, libhandy::HeaderBar, header); get_widget!(builder, libhandy::HeaderBar, header);
get_widget!(builder, gtk::Button, back_button); get_widget!(builder, gtk::Button, back_button);
get_widget!(builder, gtk::MenuButton, menu_button);
get_widget!(builder, gtk::Stack, stack); get_widget!(builder, gtk::Stack, stack);
get_widget!(builder, gtk::Frame, frame); get_widget!(builder, gtk::Frame, frame);
get_widget!(builder, gtk::Button, add_to_playlist_button); get_widget!(builder, gtk::Button, add_to_playlist_button);
@ -33,46 +39,36 @@ impl RecordingScreen {
header.set_title(Some(&recording.work.get_title())); header.set_title(Some(&recording.work.get_title()));
header.set_subtitle(Some(&recording.get_performers())); header.set_subtitle(Some(&recording.get_performers()));
let edit_menu_item = gio::MenuItem::new(Some(&gettext("Edit recording")), None); let edit_action = gio::SimpleAction::new("edit", None);
edit_menu_item.set_action_and_target_value( let delete_action = gio::SimpleAction::new("delete", None);
Some("win.edit-recording"), let edit_tracks_action = gio::SimpleAction::new("edit-tracks", None);
Some(&glib::Variant::from(recording.id)), let delete_tracks_action = gio::SimpleAction::new("delete-tracks", None);
);
let delete_menu_item = gio::MenuItem::new(Some(&gettext("Delete recording")), None); let actions = gio::SimpleActionGroup::new();
delete_menu_item.set_action_and_target_value( actions.add_action(&edit_action);
Some("win.delete-recording"), actions.add_action(&delete_action);
Some(&glib::Variant::from(recording.id)), actions.add_action(&edit_tracks_action);
); actions.add_action(&delete_tracks_action);
let edit_tracks_menu_item = gio::MenuItem::new(Some(&gettext("Edit tracks")), None); widget.insert_action_group("widget", Some(&actions));
edit_tracks_menu_item.set_action_and_target_value(
Some("win.edit-tracks"),
Some(&glib::Variant::from(recording.id)),
);
let delete_tracks_menu_item = gio::MenuItem::new(Some(&gettext("Delete tracks")), None);
delete_tracks_menu_item.set_action_and_target_value(
Some("win.delete-tracks"),
Some(&glib::Variant::from(recording.id)),
);
let menu = gio::Menu::new();
menu.append_item(&edit_menu_item);
menu.append_item(&delete_menu_item);
menu.append_item(&edit_tracks_menu_item);
menu.append_item(&delete_tracks_menu_item);
menu_button.set_menu_model(Some(&menu));
let recording = Rc::new(recording);
let list = List::new(&gettext("No tracks found.")); let list = List::new(&gettext("No tracks found."));
frame.add(&list.widget);
list.set_make_widget( let result = Rc::new(Self {
clone!(@strong recording => move |track: &Track| { backend,
window: window.clone().upcast(),
recording,
widget,
stack,
tracks: RefCell::new(Vec::new()),
navigator: RefCell::new(None),
});
list.set_make_widget(clone!(@strong result => move |track: &Track| {
let mut title_parts = Vec::<String>::new(); let mut title_parts = Vec::<String>::new();
for part in &track.work_parts { for part in &track.work_parts {
title_parts.push(recording.work.parts[*part].title.clone()); title_parts.push(result.recording.work.parts[*part].title.clone());
} }
let title = if title_parts.is_empty() { let title = if title_parts.is_empty() {
@ -96,18 +92,7 @@ impl RecordingScreen {
vbox.add(&file_name_label); vbox.add(&file_name_label);
vbox.upcast() vbox.upcast()
}), }));
);
frame.add(&list.widget);
let result = Rc::new(Self {
backend,
widget,
stack,
tracks: RefCell::new(Vec::new()),
navigator: RefCell::new(None),
});
back_button.connect_clicked(clone!(@strong result => move |_| { back_button.connect_clicked(clone!(@strong result => move |_| {
let navigator = result.navigator.borrow().clone(); let navigator = result.navigator.borrow().clone();
@ -116,22 +101,49 @@ impl RecordingScreen {
} }
})); }));
add_to_playlist_button.connect_clicked( add_to_playlist_button.connect_clicked(clone!(@strong result => move |_| {
clone!(@strong result, @strong recording => move |_| {
if let Some(player) = result.backend.get_player() { if let Some(player) = result.backend.get_player() {
player.add_item(PlaylistItem { player.add_item(PlaylistItem {
recording: (*recording).clone(), recording: result.recording.clone(),
tracks: result.tracks.borrow().clone(), tracks: result.tracks.borrow().clone(),
}).unwrap(); }).unwrap();
} }
}), }));
);
edit_action.connect_activate(clone!(@strong result => move |_, _| {
RecordingEditorDialog::new(result.backend.clone(), &result.window, Some(result.recording.clone())).show();
}));
delete_action.connect_activate(clone!(@strong result => move |_, _| {
let context = glib::MainContext::default();
let clone = result.clone();
context.spawn_local(async move {
clone.backend.db().delete_recording(clone.recording.id).await.unwrap();
});
}));
edit_tracks_action.connect_activate(clone!(@strong result => move |_, _| {
TracksEditor::new(result.backend.clone(), &result.window, Some(result.recording.clone()), result.tracks.borrow().clone()).show();
}));
delete_tracks_action.connect_activate(clone!(@strong result => move |_, _| {
let context = glib::MainContext::default();
let clone = result.clone();
context.spawn_local(async move {
clone.backend.db().delete_tracks(clone.recording.id).await.unwrap();
});
}));
let context = glib::MainContext::default(); let context = glib::MainContext::default();
let clone = result.clone(); let clone = result.clone();
let id = recording.id;
context.spawn_local(async move { context.spawn_local(async move {
let tracks = clone.backend.db().get_tracks(id as u32).await.unwrap(); let tracks = clone
.backend
.db()
.get_tracks(clone.recording.id)
.await
.unwrap();
list.show_items(tracks.clone()); list.show_items(tracks.clone());
clone.stack.set_visible_child_name("content"); clone.stack.set_visible_child_name("content");
clone.tracks.replace(tracks); clone.tracks.replace(tracks);

View file

@ -1,8 +1,10 @@
use super::*; use super::*;
use crate::backend::*; use crate::backend::*;
use crate::database::*; use crate::database::*;
use crate::dialogs::WorkEditorDialog;
use crate::widgets::*; use crate::widgets::*;
use gettextrs::gettext; use gettextrs::gettext;
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;
@ -12,6 +14,8 @@ use std::rc::Rc;
pub struct WorkScreen { pub struct WorkScreen {
backend: Rc<Backend>, backend: Rc<Backend>,
window: gtk::Window,
work: Work,
widget: gtk::Box, widget: gtk::Box,
stack: gtk::Stack, stack: gtk::Stack,
recording_list: Rc<List<Recording>>, recording_list: Rc<List<Recording>>,
@ -19,13 +23,15 @@ pub struct WorkScreen {
} }
impl WorkScreen { impl WorkScreen {
pub fn new(backend: Rc<Backend>, work: Work) -> Rc<Self> { pub fn new<W>(backend: Rc<Backend>, window: &W, work: Work) -> Rc<Self>
where
W: IsA<gtk::Window>,
{
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/work_screen.ui"); let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/work_screen.ui");
get_widget!(builder, gtk::Box, widget); get_widget!(builder, gtk::Box, widget);
get_widget!(builder, libhandy::HeaderBar, header); get_widget!(builder, libhandy::HeaderBar, header);
get_widget!(builder, gtk::Button, back_button); get_widget!(builder, gtk::Button, back_button);
get_widget!(builder, gtk::MenuButton, menu_button);
get_widget!(builder, gtk::SearchEntry, search_entry); get_widget!(builder, gtk::SearchEntry, search_entry);
get_widget!(builder, gtk::Stack, stack); get_widget!(builder, gtk::Stack, stack);
get_widget!(builder, gtk::Frame, recording_frame); get_widget!(builder, gtk::Frame, recording_frame);
@ -33,23 +39,14 @@ impl WorkScreen {
header.set_title(Some(&work.title)); header.set_title(Some(&work.title));
header.set_subtitle(Some(&work.composer.name_fl())); header.set_subtitle(Some(&work.composer.name_fl()));
let edit_menu_item = gio::MenuItem::new(Some(&gettext("Edit work")), None); let edit_action = gio::SimpleAction::new("edit", None);
edit_menu_item.set_action_and_target_value( let delete_action = gio::SimpleAction::new("delete", None);
Some("win.edit-work"),
Some(&glib::Variant::from(work.id)),
);
let delete_menu_item = gio::MenuItem::new(Some(&gettext("Delete work")), None); let actions = gio::SimpleActionGroup::new();
delete_menu_item.set_action_and_target_value( actions.add_action(&edit_action);
Some("win.delete-work"), actions.add_action(&delete_action);
Some(&glib::Variant::from(work.id)),
);
let menu = gio::Menu::new(); widget.insert_action_group("widget", Some(&actions));
menu.append_item(&edit_menu_item);
menu.append_item(&delete_menu_item);
menu_button.set_menu_model(Some(&menu));
let recording_list = List::new(&gettext("No recordings found.")); let recording_list = List::new(&gettext("No recordings found."));
@ -82,6 +79,8 @@ impl WorkScreen {
let result = Rc::new(Self { let result = Rc::new(Self {
backend, backend,
window: window.clone().upcast(),
work,
widget, widget,
stack, stack,
recording_list, recording_list,
@ -104,17 +103,29 @@ impl WorkScreen {
.set_selected(clone!(@strong result => move |recording| { .set_selected(clone!(@strong result => move |recording| {
let navigator = result.navigator.borrow().clone(); let navigator = result.navigator.borrow().clone();
if let Some(navigator) = navigator { if let Some(navigator) = navigator {
navigator.push(RecordingScreen::new(result.backend.clone(), recording.clone())); navigator.push(RecordingScreen::new(result.backend.clone(), &result.window, recording.clone()));
} }
})); }));
edit_action.connect_activate(clone!(@strong result => move |_, _| {
WorkEditorDialog::new(result.backend.clone(), &result.window, Some(result.work.clone())).show();
}));
delete_action.connect_activate(clone!(@strong result => move |_, _| {
let context = glib::MainContext::default();
let clone = result.clone();
context.spawn_local(async move {
clone.backend.db().delete_work(clone.work.id).await.unwrap();
});
}));
let context = glib::MainContext::default(); let context = glib::MainContext::default();
let clone = result.clone(); let clone = result.clone();
context.spawn_local(async move { context.spawn_local(async move {
let recordings = clone let recordings = clone
.backend .backend
.db() .db()
.get_recordings_for_work(work.id as u32) .get_recordings_for_work(clone.work.id as u32)
.await .await
.unwrap(); .unwrap();

View file

@ -161,10 +161,10 @@ impl Window {
result.leaflet.set_visible_child(&result.navigator.widget); result.leaflet.set_visible_child(&result.navigator.widget);
match poe { match poe {
PersonOrEnsemble::Person(person) => { PersonOrEnsemble::Person(person) => {
result.navigator.clone().replace(PersonScreen::new(result.backend.clone(), person.clone())); result.navigator.clone().replace(PersonScreen::new(result.backend.clone(), &result.window, person.clone()));
} }
PersonOrEnsemble::Ensemble(ensemble) => { PersonOrEnsemble::Ensemble(ensemble) => {
result.navigator.clone().replace(EnsembleScreen::new(result.backend.clone(), ensemble.clone())); result.navigator.clone().replace(EnsembleScreen::new(result.backend.clone(), &result.window, ensemble.clone()));
} }
} }
})); }));