diff --git a/src/backend.rs b/src/backend.rs index 30ae0f1..ae1f9af 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -13,12 +13,16 @@ enum BackendAction { DeleteInstrument(i64, Sender>), GetInstruments(Sender>>), UpdateWork(WorkInsertion, Sender>), + GetWorkDescription(i64, Sender>), + DeleteWork(i64, Sender>), GetWorkDescriptions(i64, Sender>>), UpdateEnsemble(Ensemble, Sender>), GetEnsemble(i64, Sender>), DeleteEnsemble(i64, Sender>), GetEnsembles(Sender>>), UpdateRecording(RecordingInsertion, Sender>), + GetRecordingDescription(i64, Sender>), + DeleteRecording(i64, Sender>), GetRecordingsForPerson(i64, Sender>>), GetRecordingsForEnsemble(i64, Sender>>), GetRecordingsForWork(i64, Sender>>), @@ -86,6 +90,16 @@ impl Backend { .send(db.update_work(work)) .expect("Failed to send result from database thread!"); } + GetWorkDescription(id, sender) => { + sender + .send(db.get_work_description(id)) + .expect("Failed to send result from database thread!"); + } + DeleteWork(id, sender) => { + sender + .send(db.delete_work(id)) + .expect("Failed to send result from database thread!"); + } GetWorkDescriptions(id, sender) => { sender .send(db.get_work_descriptions(id)) @@ -116,6 +130,16 @@ impl Backend { .send(db.update_recording(recording)) .expect("Failed to send result from database thread!"); } + GetRecordingDescription(id, sender) => { + sender + .send(db.get_recording_description(id)) + .expect("Failed to send result from database thread!"); + } + DeleteRecording(id, sender) => { + sender + .send(db.delete_recording(id)) + .expect("Failed to send result from database thread!"); + } GetRecordingsForPerson(id, sender) => { sender .send(db.get_recordings_for_person(id)) @@ -196,6 +220,18 @@ impl Backend { receiver.await? } + pub async fn get_work_description(&self, id: i64) -> Result { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(GetWorkDescription(id, sender))?; + receiver.await? + } + + pub async fn delete_work(&self, id: i64) -> Result<()> { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(DeleteWork(id, sender))?; + receiver.await? + } + pub async fn get_work_descriptions(&self, person_id: i64) -> Result> { let (sender, receiver) = oneshot::channel(); self.action_sender @@ -234,6 +270,19 @@ impl Backend { receiver.await? } + pub async fn get_recording_description(&self, id: i64) -> Result { + let (sender, receiver) = oneshot::channel(); + self.action_sender + .send(GetRecordingDescription(id, sender))?; + receiver.await? + } + + pub async fn delete_recording(&self, id: i64) -> Result<()> { + let (sender, receiver) = oneshot::channel(); + self.action_sender.send(DeleteRecording(id, sender))?; + receiver.await? + } + pub async fn get_recordings_for_person( &self, person_id: i64, diff --git a/src/screens/ensemble_screen.rs b/src/screens/ensemble_screen.rs index ccd2446..29e29d7 100644 --- a/src/screens/ensemble_screen.rs +++ b/src/screens/ensemble_screen.rs @@ -32,6 +32,24 @@ impl EnsembleScreen { header.set_title(Some(&ensemble.name)); + let edit_menu_item = gio::MenuItem::new(Some("Edit ensemble"), None); + edit_menu_item.set_action_and_target_value( + Some("win.edit-ensemble"), + Some(&glib::Variant::from(ensemble.id)), + ); + + let delete_menu_item = gio::MenuItem::new(Some("Delete ensemble"), None); + delete_menu_item.set_action_and_target_value( + Some("win.delete-ensemble"), + Some(&glib::Variant::from(ensemble.id)), + ); + + let menu = gio::Menu::new(); + menu.append_item(&edit_menu_item); + menu.append_item(&delete_menu_item); + + menu_button.set_menu_model(Some(&menu)); + let recording_list = List::new( |recording: &RecordingDescription| { let work_label = gtk::Label::new(Some(&recording.work.get_title())); diff --git a/src/screens/person_screen.rs b/src/screens/person_screen.rs index a4ef0c3..dee8ca5 100644 --- a/src/screens/person_screen.rs +++ b/src/screens/person_screen.rs @@ -35,6 +35,24 @@ impl PersonScreen { header.set_title(Some(&person.name_fl())); + let edit_menu_item = gio::MenuItem::new(Some("Edit person"), None); + edit_menu_item.set_action_and_target_value( + Some("win.edit-person"), + Some(&glib::Variant::from(person.id)), + ); + + let delete_menu_item = gio::MenuItem::new(Some("Delete person"), None); + delete_menu_item.set_action_and_target_value( + Some("win.delete-person"), + Some(&glib::Variant::from(person.id)), + ); + + let menu = gio::Menu::new(); + menu.append_item(&edit_menu_item); + menu.append_item(&delete_menu_item); + + menu_button.set_menu_model(Some(&menu)); + let work_list = List::new( |work: &WorkDescription| { let label = gtk::Label::new(Some(&work.title)); diff --git a/src/screens/recording_screen.rs b/src/screens/recording_screen.rs index 2c1d503..4158a69 100644 --- a/src/screens/recording_screen.rs +++ b/src/screens/recording_screen.rs @@ -26,6 +26,24 @@ impl RecordingScreen { header.set_title(Some(&recording.work.get_title())); header.set_subtitle(Some(&recording.get_performers())); + let edit_menu_item = gio::MenuItem::new(Some("Edit recording"), None); + edit_menu_item.set_action_and_target_value( + Some("win.edit-recording"), + Some(&glib::Variant::from(recording.id)), + ); + + let delete_menu_item = gio::MenuItem::new(Some("Delete recording"), None); + delete_menu_item.set_action_and_target_value( + Some("win.delete-recording"), + Some(&glib::Variant::from(recording.id)), + ); + + let menu = gio::Menu::new(); + menu.append_item(&edit_menu_item); + menu.append_item(&delete_menu_item); + + menu_button.set_menu_model(Some(&menu)); + let result = Rc::new(Self { widget, navigator: RefCell::new(None), diff --git a/src/screens/work_screen.rs b/src/screens/work_screen.rs index 1c38f30..cdefe15 100644 --- a/src/screens/work_screen.rs +++ b/src/screens/work_screen.rs @@ -32,6 +32,24 @@ impl WorkScreen { header.set_title(Some(&work.title)); header.set_subtitle(Some(&work.composer.name_fl())); + let edit_menu_item = gio::MenuItem::new(Some("Edit work"), None); + edit_menu_item.set_action_and_target_value( + Some("win.edit-work"), + Some(&glib::Variant::from(work.id)), + ); + + let delete_menu_item = gio::MenuItem::new(Some("Delete work"), None); + delete_menu_item.set_action_and_target_value( + Some("win.delete-work"), + Some(&glib::Variant::from(work.id)), + ); + + let menu = gio::Menu::new(); + menu.append_item(&edit_menu_item); + menu.append_item(&delete_menu_item); + + menu_button.set_menu_model(Some(&menu)); + let recording_list = List::new( |recording: &RecordingDescription| { let work_label = gtk::Label::new(Some(&recording.work.get_title())); diff --git a/src/window.rs b/src/window.rs index 31a7c71..2a322da 100644 --- a/src/window.rs +++ b/src/window.rs @@ -174,6 +174,70 @@ impl Window { }) ); + action!( + result.window, + "edit-work", + Some(glib::VariantTy::new("x").unwrap()), + clone!(@strong result => move |_, id| { + let id = id.unwrap().get().unwrap(); + let result = result.clone(); + let c = glib::MainContext::default(); + c.spawn_local(async move { + let work = result.backend.get_work_description(id).await.unwrap(); + WorkEditor::new(result.backend.clone(), &result.window, Some(work), clone!(@strong result => move |_| { + result.reload(); + })).show(); + }); + }) + ); + + action!( + result.window, + "delete-work", + Some(glib::VariantTy::new("x").unwrap()), + clone!(@strong result => move |_, id| { + let id = id.unwrap().get().unwrap(); + let result = result.clone(); + let c = glib::MainContext::default(); + c.spawn_local(async move { + result.backend.delete_work(id).await.unwrap(); + result.reload(); + }); + }) + ); + + action!( + result.window, + "edit-recording", + Some(glib::VariantTy::new("x").unwrap()), + clone!(@strong result => move |_, id| { + let id = id.unwrap().get().unwrap(); + let result = result.clone(); + let c = glib::MainContext::default(); + c.spawn_local(async move { + let recording = result.backend.get_recording_description(id).await.unwrap(); + RecordingEditor::new(result.backend.clone(), &result.window, Some(recording), clone!(@strong result => move |_| { + result.reload(); + })).show(); + }); + }) + ); + + action!( + result.window, + "delete-recording", + Some(glib::VariantTy::new("x").unwrap()), + clone!(@strong result => move |_, id| { + let id = id.unwrap().get().unwrap(); + let result = result.clone(); + let c = glib::MainContext::default(); + c.spawn_local(async move { + result.backend.delete_recording(id).await.unwrap(); + result.reload(); + }); + }) + ); + result }