| 
									
										
										
										
											2020-10-09 12:22:02 +02:00
										 |  |  | use super::backend::Backend;
 | 
					
						
							| 
									
										
										
										
											2020-09-28 15:02:19 +02:00
										 |  |  | use super::database::*;
 | 
					
						
							|  |  |  | use super::dialogs::*;
 | 
					
						
							| 
									
										
										
										
											2020-09-27 21:58:42 +02:00
										 |  |  | use gio::prelude::*;
 | 
					
						
							| 
									
										
										
										
											2020-09-28 15:02:19 +02:00
										 |  |  | use glib::clone;
 | 
					
						
							| 
									
										
										
										
											2020-09-27 21:58:42 +02:00
										 |  |  | use gtk::prelude::*;
 | 
					
						
							|  |  |  | use gtk_macros::{action, get_widget};
 | 
					
						
							| 
									
										
										
										
											2020-09-28 20:51:56 +02:00
										 |  |  | use libhandy::prelude::*;
 | 
					
						
							|  |  |  | use libhandy::HeaderBarExt;
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  | use std::cell::{Cell, RefCell};
 | 
					
						
							| 
									
										
										
										
											2020-09-28 20:09:49 +02:00
										 |  |  | use std::convert::TryInto;
 | 
					
						
							| 
									
										
										
										
											2020-09-28 15:02:19 +02:00
										 |  |  | use std::rc::Rc;
 | 
					
						
							| 
									
										
										
										
											2020-09-27 21:58:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  | #[derive(Clone)]
 | 
					
						
							|  |  |  | enum PersonOrEnsemble {
 | 
					
						
							|  |  |  |     Person(Person),
 | 
					
						
							|  |  |  |     Ensemble(Ensemble),
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | impl PersonOrEnsemble {
 | 
					
						
							|  |  |  |     pub fn get_title(&self) -> String {
 | 
					
						
							|  |  |  |         match self {
 | 
					
						
							|  |  |  |             PersonOrEnsemble::Person(person) => person.name_lf(),
 | 
					
						
							|  |  |  |             PersonOrEnsemble::Ensemble(ensemble) => ensemble.name.clone(),
 | 
					
						
							|  |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  | #[derive(Clone)]
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  | enum WindowState {
 | 
					
						
							|  |  |  |     Loading,
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |     Selection(Vec<PersonOrEnsemble>),
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |     OverviewScreenLoading(PersonOrEnsemble),
 | 
					
						
							|  |  |  |     OverviewScreen(
 | 
					
						
							|  |  |  |         PersonOrEnsemble,
 | 
					
						
							|  |  |  |         Vec<WorkDescription>,
 | 
					
						
							|  |  |  |         Vec<RecordingDescription>,
 | 
					
						
							|  |  |  |         String,
 | 
					
						
							|  |  |  |     ),
 | 
					
						
							|  |  |  |     WorkScreenLoading(PersonOrEnsemble, WorkDescription),
 | 
					
						
							| 
									
										
										
										
											2020-10-11 18:03:40 +02:00
										 |  |  |     WorkScreen(
 | 
					
						
							|  |  |  |         PersonOrEnsemble,
 | 
					
						
							|  |  |  |         WorkDescription,
 | 
					
						
							|  |  |  |         Vec<RecordingDescription>,
 | 
					
						
							|  |  |  |         String,
 | 
					
						
							|  |  |  |     ),
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |     RecordingScreenLoading(PersonOrEnsemble, RecordingDescription),
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-27 21:58:42 +02:00
										 |  |  | pub struct Window {
 | 
					
						
							| 
									
										
										
										
											2020-09-28 20:51:56 +02:00
										 |  |  |     window: libhandy::ApplicationWindow,
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  |     state: RefCell<WindowState>,
 | 
					
						
							| 
									
										
										
										
											2020-10-09 12:22:02 +02:00
										 |  |  |     backend: Rc<Backend>,
 | 
					
						
							| 
									
										
										
										
											2020-09-28 20:51:56 +02:00
										 |  |  |     leaflet: libhandy::Leaflet,
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |     sidebar_stack: gtk::Stack,
 | 
					
						
							| 
									
										
										
										
											2020-09-28 20:09:49 +02:00
										 |  |  |     person_search_entry: gtk::SearchEntry,
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |     sidebar_list: gtk::ListBox,
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |     main_stack: gtk::Stack,
 | 
					
						
							|  |  |  |     overview_header: libhandy::HeaderBar,
 | 
					
						
							|  |  |  |     overview_header_menu_button: gtk::MenuButton,
 | 
					
						
							|  |  |  |     overview_search_entry: gtk::SearchEntry,
 | 
					
						
							|  |  |  |     overview_stack: gtk::Stack,
 | 
					
						
							|  |  |  |     overview_work_box: gtk::Box,
 | 
					
						
							|  |  |  |     overview_work_list: gtk::ListBox,
 | 
					
						
							|  |  |  |     overview_recording_box: gtk::Box,
 | 
					
						
							|  |  |  |     overview_recording_list: gtk::ListBox,
 | 
					
						
							|  |  |  |     work_details_header: libhandy::HeaderBar,
 | 
					
						
							|  |  |  |     work_details_stack: gtk::Stack,
 | 
					
						
							| 
									
										
										
										
											2020-10-11 18:03:40 +02:00
										 |  |  |     work_details_recording_list: gtk::ListBox,
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |     recording_details_header: libhandy::HeaderBar,
 | 
					
						
							|  |  |  |     recording_details_stack: gtk::Stack,
 | 
					
						
							|  |  |  |     sidebar_list_row_activated_handler_id: Cell<Option<glib::SignalHandlerId>>,
 | 
					
						
							|  |  |  |     overview_work_list_row_activated_handler_id: Cell<Option<glib::SignalHandlerId>>,
 | 
					
						
							|  |  |  |     overview_recording_list_row_activated_handler_id: Cell<Option<glib::SignalHandlerId>>,
 | 
					
						
							| 
									
										
										
										
											2020-10-11 18:03:40 +02:00
										 |  |  |     work_details_recording_list_row_activated_handler_id: Cell<Option<glib::SignalHandlerId>>,
 | 
					
						
							| 
									
										
										
										
											2020-09-27 21:58:42 +02:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | impl Window {
 | 
					
						
							| 
									
										
										
										
											2020-09-28 15:02:19 +02:00
										 |  |  |     pub fn new(app: >k::Application) -> Rc<Self> {
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |         use WindowState::*;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-27 21:58:42 +02:00
										 |  |  |         let builder = gtk::Builder::from_resource("/de/johrpan/musicus_editor/ui/window.ui");
 | 
					
						
							| 
									
										
										
										
											2020-09-28 20:51:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         get_widget!(builder, libhandy::ApplicationWindow, window);
 | 
					
						
							|  |  |  |         get_widget!(builder, libhandy::Leaflet, leaflet);
 | 
					
						
							| 
									
										
										
										
											2020-09-28 20:09:49 +02:00
										 |  |  |         get_widget!(builder, gtk::SearchEntry, person_search_entry);
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |         get_widget!(builder, gtk::Stack, sidebar_stack);
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |         get_widget!(builder, gtk::ListBox, sidebar_list);
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |         get_widget!(builder, gtk::Stack, main_stack);
 | 
					
						
							|  |  |  |         get_widget!(builder, libhandy::HeaderBar, overview_header);
 | 
					
						
							|  |  |  |         get_widget!(builder, gtk::MenuButton, overview_header_menu_button);
 | 
					
						
							|  |  |  |         get_widget!(builder, gtk::SearchEntry, overview_search_entry);
 | 
					
						
							|  |  |  |         get_widget!(builder, gtk::Stack, overview_stack);
 | 
					
						
							|  |  |  |         get_widget!(builder, gtk::Box, overview_work_box);
 | 
					
						
							|  |  |  |         get_widget!(builder, gtk::ListBox, overview_work_list);
 | 
					
						
							|  |  |  |         get_widget!(builder, gtk::Box, overview_recording_box);
 | 
					
						
							|  |  |  |         get_widget!(builder, gtk::ListBox, overview_recording_list);
 | 
					
						
							|  |  |  |         get_widget!(builder, libhandy::HeaderBar, work_details_header);
 | 
					
						
							|  |  |  |         get_widget!(builder, gtk::Button, work_details_back_button);
 | 
					
						
							|  |  |  |         get_widget!(builder, gtk::Stack, work_details_stack);
 | 
					
						
							| 
									
										
										
										
											2020-10-11 18:03:40 +02:00
										 |  |  |         get_widget!(builder, gtk::ListBox, work_details_recording_list);
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |         get_widget!(builder, libhandy::HeaderBar, recording_details_header);
 | 
					
						
							|  |  |  |         get_widget!(builder, gtk::Button, recording_details_back_button);
 | 
					
						
							|  |  |  |         get_widget!(builder, gtk::Stack, recording_details_stack);
 | 
					
						
							| 
									
										
										
										
											2020-09-27 21:58:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-09 12:22:02 +02:00
										 |  |  |         let backend = Backend::new("test.sqlite");
 | 
					
						
							| 
									
										
										
										
											2020-09-28 15:02:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         let result = Rc::new(Window {
 | 
					
						
							|  |  |  |             window: window,
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  |             state: RefCell::new(Loading),
 | 
					
						
							| 
									
										
										
										
											2020-10-09 12:22:02 +02:00
										 |  |  |             backend: Rc::new(backend),
 | 
					
						
							| 
									
										
										
										
											2020-09-28 20:51:56 +02:00
										 |  |  |             leaflet: leaflet,
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |             sidebar_stack: sidebar_stack,
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |             sidebar_list: sidebar_list,
 | 
					
						
							| 
									
										
										
										
											2020-09-28 20:09:49 +02:00
										 |  |  |             person_search_entry: person_search_entry,
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |             main_stack: main_stack,
 | 
					
						
							|  |  |  |             overview_header: overview_header,
 | 
					
						
							|  |  |  |             overview_header_menu_button: overview_header_menu_button,
 | 
					
						
							|  |  |  |             overview_search_entry: overview_search_entry,
 | 
					
						
							|  |  |  |             overview_stack: overview_stack,
 | 
					
						
							|  |  |  |             overview_work_box: overview_work_box,
 | 
					
						
							|  |  |  |             overview_work_list: overview_work_list,
 | 
					
						
							|  |  |  |             overview_recording_box: overview_recording_box,
 | 
					
						
							|  |  |  |             overview_recording_list: overview_recording_list,
 | 
					
						
							|  |  |  |             work_details_header: work_details_header,
 | 
					
						
							|  |  |  |             work_details_stack: work_details_stack,
 | 
					
						
							| 
									
										
										
										
											2020-10-11 18:03:40 +02:00
										 |  |  |             work_details_recording_list: work_details_recording_list,
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |             recording_details_header: recording_details_header,
 | 
					
						
							|  |  |  |             recording_details_stack: recording_details_stack,
 | 
					
						
							|  |  |  |             sidebar_list_row_activated_handler_id: Cell::new(None),
 | 
					
						
							|  |  |  |             overview_work_list_row_activated_handler_id: Cell::new(None),
 | 
					
						
							|  |  |  |             overview_recording_list_row_activated_handler_id: Cell::new(None),
 | 
					
						
							| 
									
										
										
										
											2020-10-11 18:03:40 +02:00
										 |  |  |             work_details_recording_list_row_activated_handler_id: Cell::new(None),
 | 
					
						
							| 
									
										
										
										
											2020-09-27 21:58:42 +02:00
										 |  |  |         });
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-28 23:33:48 +02:00
										 |  |  |         action!(
 | 
					
						
							|  |  |  |             result.window,
 | 
					
						
							|  |  |  |             "back",
 | 
					
						
							|  |  |  |             clone!(@strong result => move |_, _| {
 | 
					
						
							|  |  |  |                 result.back();
 | 
					
						
							|  |  |  |             })
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-28 15:02:19 +02:00
										 |  |  |         action!(
 | 
					
						
							|  |  |  |             result.window,
 | 
					
						
							|  |  |  |             "add-person",
 | 
					
						
							|  |  |  |             clone!(@strong result => move |_, _| {
 | 
					
						
							| 
									
										
										
										
											2020-10-09 12:22:02 +02:00
										 |  |  |                 PersonEditor::new(result.backend.clone(), &result.window, None, clone!(@strong result => move |_| {
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                    result.clone().set_state(Loading);
 | 
					
						
							| 
									
										
										
										
											2020-09-28 20:09:49 +02:00
										 |  |  |                 })).show();
 | 
					
						
							| 
									
										
										
										
											2020-09-28 15:02:19 +02:00
										 |  |  |             })
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-28 15:08:24 +02:00
										 |  |  |         action!(
 | 
					
						
							|  |  |  |             result.window,
 | 
					
						
							|  |  |  |             "add-instrument",
 | 
					
						
							|  |  |  |             clone!(@strong result => move |_, _| {
 | 
					
						
							| 
									
										
										
										
											2020-10-09 12:22:02 +02:00
										 |  |  |                 InstrumentEditor::new(result.backend.clone(), &result.window, None, |instrument| {
 | 
					
						
							| 
									
										
										
										
											2020-09-28 15:08:24 +02:00
										 |  |  |                     println!("{:?}", instrument);
 | 
					
						
							|  |  |  |                 }).show();
 | 
					
						
							|  |  |  |             })
 | 
					
						
							|  |  |  |         );
 | 
					
						
							| 
									
										
										
										
											2020-09-27 21:58:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-28 16:00:51 +02:00
										 |  |  |         action!(
 | 
					
						
							|  |  |  |             result.window,
 | 
					
						
							|  |  |  |             "add-work",
 | 
					
						
							|  |  |  |             clone!(@strong result => move |_, _| {
 | 
					
						
							| 
									
										
										
										
											2020-10-09 12:22:02 +02:00
										 |  |  |                 WorkEditor::new(result.backend.clone(), &result.window, None, clone!(@strong result => move |_| {
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                     result.clone().set_state(Loading);
 | 
					
						
							| 
									
										
										
										
											2020-09-28 20:09:49 +02:00
										 |  |  |                 })).show();
 | 
					
						
							| 
									
										
										
										
											2020-09-28 16:00:51 +02:00
										 |  |  |             })
 | 
					
						
							|  |  |  |         );
 | 
					
						
							| 
									
										
										
										
											2020-09-27 21:58:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-28 15:14:05 +02:00
										 |  |  |         action!(
 | 
					
						
							|  |  |  |             result.window,
 | 
					
						
							|  |  |  |             "add-ensemble",
 | 
					
						
							|  |  |  |             clone!(@strong result => move |_, _| {
 | 
					
						
							| 
									
										
										
										
											2020-10-09 12:22:02 +02:00
										 |  |  |                 EnsembleEditor::new(result.backend.clone(), &result.window, None, |ensemble| {
 | 
					
						
							| 
									
										
										
										
											2020-09-28 15:14:05 +02:00
										 |  |  |                     println!("{:?}", ensemble);
 | 
					
						
							|  |  |  |                 }).show();
 | 
					
						
							|  |  |  |             })
 | 
					
						
							|  |  |  |         );
 | 
					
						
							| 
									
										
										
										
											2020-09-27 21:58:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-09 23:02:50 +02:00
										 |  |  |         action!(
 | 
					
						
							|  |  |  |             result.window,
 | 
					
						
							|  |  |  |             "add-recording",
 | 
					
						
							|  |  |  |             clone!(@strong result => move |_, _| {
 | 
					
						
							|  |  |  |                 RecordingEditor::new(result.backend.clone(), &result.window, None, clone!(@strong result => move |_| {
 | 
					
						
							|  |  |  |                     result.clone().set_state(Loading);
 | 
					
						
							|  |  |  |                 })).show();
 | 
					
						
							|  |  |  |             })
 | 
					
						
							|  |  |  |         );
 | 
					
						
							| 
									
										
										
										
											2020-09-27 21:58:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-28 23:33:48 +02:00
										 |  |  |         action!(
 | 
					
						
							|  |  |  |             result.window,
 | 
					
						
							|  |  |  |             "edit-person",
 | 
					
						
							|  |  |  |             Some(glib::VariantTy::new("x").unwrap()),
 | 
					
						
							|  |  |  |             clone!(@strong result => move |_, id| {
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:13:15 +02:00
										 |  |  |                 let id = id.unwrap().get().unwrap();
 | 
					
						
							|  |  |  |                 let result = result.clone();
 | 
					
						
							|  |  |  |                 let c = glib::MainContext::default();
 | 
					
						
							|  |  |  |                 c.spawn_local(async move {
 | 
					
						
							|  |  |  |                     let person = result.backend.get_person(id).await.unwrap();
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                     PersonEditor::new(result.backend.clone(), &result.window, Some(person), clone!(@strong result => move |_| {
 | 
					
						
							|  |  |  |                         result.clone().set_state(Loading);
 | 
					
						
							| 
									
										
										
										
											2020-10-09 12:22:02 +02:00
										 |  |  |                     })).show();
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:13:15 +02:00
										 |  |  |                 });
 | 
					
						
							| 
									
										
										
										
											2020-09-28 23:33:48 +02:00
										 |  |  |             })
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         action!(
 | 
					
						
							|  |  |  |             result.window,
 | 
					
						
							|  |  |  |             "delete-person",
 | 
					
						
							|  |  |  |             Some(glib::VariantTy::new("x").unwrap()),
 | 
					
						
							|  |  |  |             clone!(@strong result => move |_, id| {
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:13:15 +02:00
										 |  |  |                 let id = id.unwrap().get().unwrap();
 | 
					
						
							|  |  |  |                 let result = result.clone();
 | 
					
						
							|  |  |  |                 let c = glib::MainContext::default();
 | 
					
						
							|  |  |  |                 c.spawn_local(async move {
 | 
					
						
							|  |  |  |                     result.backend.delete_person(id).await.unwrap();
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                     result.clone().set_state(Loading);
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:13:15 +02:00
										 |  |  |                 });
 | 
					
						
							| 
									
										
										
										
											2020-09-28 23:33:48 +02:00
										 |  |  |             })
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |         action!(
 | 
					
						
							|  |  |  |             result.window,
 | 
					
						
							|  |  |  |             "edit-ensemble",
 | 
					
						
							|  |  |  |             Some(glib::VariantTy::new("x").unwrap()),
 | 
					
						
							|  |  |  |             clone!(@strong result => move |_, id| {
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:13:15 +02:00
										 |  |  |                 let id = id.unwrap().get().unwrap();
 | 
					
						
							|  |  |  |                 let result = result.clone();
 | 
					
						
							|  |  |  |                 let c = glib::MainContext::default();
 | 
					
						
							|  |  |  |                 c.spawn_local(async move {
 | 
					
						
							|  |  |  |                     let ensemble = result.backend.get_ensemble(id).await.unwrap();
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |                     EnsembleEditor::new(result.backend.clone(), &result.window, Some(ensemble), clone!(@strong result => move |_| {
 | 
					
						
							|  |  |  |                         result.clone().set_state(Loading);
 | 
					
						
							|  |  |  |                     })).show();
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:13:15 +02:00
										 |  |  |                 });
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |             })
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         action!(
 | 
					
						
							|  |  |  |             result.window,
 | 
					
						
							|  |  |  |             "delete-ensemble",
 | 
					
						
							|  |  |  |             Some(glib::VariantTy::new("x").unwrap()),
 | 
					
						
							|  |  |  |             clone!(@strong result => move |_, id| {
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:13:15 +02:00
										 |  |  |                 let id = id.unwrap().get().unwrap();
 | 
					
						
							|  |  |  |                 let result = result.clone();
 | 
					
						
							|  |  |  |                 let c = glib::MainContext::default();
 | 
					
						
							|  |  |  |                 c.spawn_local(async move {
 | 
					
						
							|  |  |  |                     result.backend.delete_ensemble(id).await.unwrap();
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |                     result.clone().set_state(Loading);
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:13:15 +02:00
										 |  |  |                 });
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |             })
 | 
					
						
							|  |  |  |         );
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |         result
 | 
					
						
							|  |  |  |             .person_search_entry
 | 
					
						
							|  |  |  |             .connect_search_changed(clone!(@strong result => move |_| {
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |                 result.sidebar_list.invalidate_filter();
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |             }));
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |         result.overview_search_entry.connect_search_changed(clone!(@strong result => move |_| {
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  |             match result.get_state() {
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 OverviewScreen(poe, works, recordings, _) => {
 | 
					
						
							|  |  |  |                     result.clone().set_state(OverviewScreen(poe, works.clone(), recordings.clone(), result.overview_search_entry.get_text().to_string()));
 | 
					
						
							|  |  |  |                 },
 | 
					
						
							|  |  |  |                 _ => (),
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  |         }));
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         work_details_back_button.connect_clicked(clone!(@strong result => move |_| {
 | 
					
						
							|  |  |  |             match result.get_state() {
 | 
					
						
							|  |  |  |                 WorkScreenLoading(poe, _) => {
 | 
					
						
							|  |  |  |                     result.clone().set_state(OverviewScreenLoading(poe));
 | 
					
						
							|  |  |  |                 },
 | 
					
						
							| 
									
										
										
										
											2020-10-11 18:03:40 +02:00
										 |  |  |                 WorkScreen(poe, _, _, _) => {
 | 
					
						
							|  |  |  |                     result.clone().set_state(OverviewScreenLoading(poe));
 | 
					
						
							|  |  |  |                 },
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 _ => (),
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  |         }));
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         recording_details_back_button.connect_clicked(clone!(@strong result => move |_| {
 | 
					
						
							|  |  |  |             match result.get_state() {
 | 
					
						
							|  |  |  |                 RecordingScreenLoading(poe, _) => {
 | 
					
						
							|  |  |  |                     result.clone().set_state(OverviewScreenLoading(poe));
 | 
					
						
							|  |  |  |                 },
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  |                 _ => (),
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  |         }));
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-28 15:02:19 +02:00
										 |  |  |         result.window.set_application(Some(app));
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |         result.clone().set_state(Loading);
 | 
					
						
							| 
									
										
										
										
											2020-09-27 21:58:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-28 15:02:19 +02:00
										 |  |  |         result
 | 
					
						
							| 
									
										
										
										
											2020-09-27 21:58:42 +02:00
										 |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pub fn present(&self) {
 | 
					
						
							|  |  |  |         self.window.present();
 | 
					
						
							|  |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2020-09-28 20:09:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  |     fn get_state(&self) -> WindowState {
 | 
					
						
							|  |  |  |         self.state.borrow().clone()
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |     fn set_state(self: Rc<Self>, state: WindowState) {
 | 
					
						
							|  |  |  |         use WindowState::*;
 | 
					
						
							| 
									
										
										
										
											2020-09-28 20:09:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  |         self.state.replace(state.clone());
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |         match state {
 | 
					
						
							|  |  |  |             Loading => {
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:13:15 +02:00
										 |  |  |                 let self_ = self.clone();
 | 
					
						
							|  |  |  |                 let c = glib::MainContext::default();
 | 
					
						
							|  |  |  |                 c.spawn_local(async move {
 | 
					
						
							|  |  |  |                     let persons = self_.backend.get_persons().await.unwrap();
 | 
					
						
							|  |  |  |                     let ensembles = self_.backend.get_ensembles().await.unwrap();
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:13:15 +02:00
										 |  |  |                     let mut poes: Vec<PersonOrEnsemble> = Vec::new();
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:13:15 +02:00
										 |  |  |                     for person in &persons {
 | 
					
						
							|  |  |  |                         poes.push(PersonOrEnsemble::Person(person.clone()));
 | 
					
						
							|  |  |  |                     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     for ensemble in &ensembles {
 | 
					
						
							|  |  |  |                         poes.push(PersonOrEnsemble::Ensemble(ensemble.clone()));
 | 
					
						
							|  |  |  |                     }
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:13:15 +02:00
										 |  |  |                     self_.clone().set_state(Selection(poes));
 | 
					
						
							|  |  |  |                 });
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                 self.sidebar_stack.set_visible_child_name("loading");
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 self.main_stack.set_visible_child_name("empty_screen");
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                 self.leaflet.set_visible_child_name("sidebar");
 | 
					
						
							|  |  |  |             }
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |             Selection(poes) => {
 | 
					
						
							|  |  |  |                 for child in self.sidebar_list.get_children() {
 | 
					
						
							|  |  |  |                     self.sidebar_list.remove(&child);
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                 }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |                 for (index, poe) in poes.iter().enumerate() {
 | 
					
						
							|  |  |  |                     let label = gtk::Label::new(Some(&poe.get_title()));
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:26:36 +02:00
										 |  |  |                     label.set_ellipsize(pango::EllipsizeMode::End);
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                     label.set_halign(gtk::Align::Start);
 | 
					
						
							|  |  |  |                     let row = SelectorRow::new(index.try_into().unwrap(), &label);
 | 
					
						
							|  |  |  |                     row.show_all();
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |                     self.sidebar_list.insert(&row, -1);
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                 }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 match self.sidebar_list_row_activated_handler_id.take() {
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |                     Some(id) => self.sidebar_list.disconnect(id),
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                     None => (),
 | 
					
						
							|  |  |  |                 }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |                 let handler_id = self.sidebar_list.connect_row_activated(
 | 
					
						
							|  |  |  |                     clone!(@strong self as self_, @strong poes => move |_, row| {
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                         let row = row.get_child().unwrap().downcast::<SelectorRow>().unwrap();
 | 
					
						
							|  |  |  |                         let index: usize = row.get_index().try_into().unwrap();
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |                         let poe = poes[index].clone();
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                         self_.clone().set_state(OverviewScreenLoading(poe));
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                     }),
 | 
					
						
							|  |  |  |                 );
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 self.sidebar_list_row_activated_handler_id
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                     .set(Some(handler_id));
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |                 self.sidebar_list.set_filter_func(Some(Box::new(
 | 
					
						
							|  |  |  |                     clone!(@strong self as self_, @strong poes => move |row| {
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                         let row = row.get_child().unwrap().downcast::<SelectorRow>().unwrap();
 | 
					
						
							|  |  |  |                         let index: usize = row.get_index().try_into().unwrap();
 | 
					
						
							|  |  |  |                         let search = self_.person_search_entry.get_text().to_string().to_lowercase();
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |                         search.is_empty() || poes[index]
 | 
					
						
							|  |  |  |                             .get_title()
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                             .to_lowercase()
 | 
					
						
							|  |  |  |                             .contains(&search)
 | 
					
						
							|  |  |  |                     }),
 | 
					
						
							|  |  |  |                 )));
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 self.sidebar_stack.set_visible_child_name("content");
 | 
					
						
							|  |  |  |                 self.main_stack.set_visible_child_name("empty_screen");
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                 self.leaflet.set_visible_child_name("sidebar");
 | 
					
						
							|  |  |  |             }
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |             OverviewScreenLoading(poe) => {
 | 
					
						
							|  |  |  |                 match poe.clone() {
 | 
					
						
							|  |  |  |                     PersonOrEnsemble::Person(person) => {
 | 
					
						
							|  |  |  |                         self.overview_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)),
 | 
					
						
							|  |  |  |                         );
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                         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)),
 | 
					
						
							|  |  |  |                         );
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                         let menu = gio::Menu::new();
 | 
					
						
							|  |  |  |                         menu.append_item(&edit_menu_item);
 | 
					
						
							|  |  |  |                         menu.append_item(&delete_menu_item);
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                         self.overview_header_menu_button.set_menu_model(Some(&menu));
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:13:15 +02:00
										 |  |  |                         let self_ = self.clone();
 | 
					
						
							|  |  |  |                         let c = glib::MainContext::default();
 | 
					
						
							|  |  |  |                         c.spawn_local(async move {
 | 
					
						
							|  |  |  |                             let works = self_
 | 
					
						
							|  |  |  |                                 .backend
 | 
					
						
							|  |  |  |                                 .get_work_descriptions(person.id)
 | 
					
						
							|  |  |  |                                 .await
 | 
					
						
							|  |  |  |                                 .unwrap();
 | 
					
						
							|  |  |  |                             let recordings = self_
 | 
					
						
							|  |  |  |                                 .backend
 | 
					
						
							|  |  |  |                                 .get_recordings_for_person(person.id)
 | 
					
						
							|  |  |  |                                 .await
 | 
					
						
							|  |  |  |                                 .unwrap();
 | 
					
						
							|  |  |  |                             self_.clone().set_state(OverviewScreen(
 | 
					
						
							|  |  |  |                                 poe.clone(),
 | 
					
						
							|  |  |  |                                 works.clone(),
 | 
					
						
							|  |  |  |                                 recordings,
 | 
					
						
							|  |  |  |                                 String::from(""),
 | 
					
						
							|  |  |  |                             ));
 | 
					
						
							|  |  |  |                         });
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                     }
 | 
					
						
							|  |  |  |                     PersonOrEnsemble::Ensemble(ensemble) => {
 | 
					
						
							|  |  |  |                         self.overview_header.set_title(Some(&ensemble.name));
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                         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)),
 | 
					
						
							|  |  |  |                         );
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                         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)),
 | 
					
						
							|  |  |  |                         );
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                         let menu = gio::Menu::new();
 | 
					
						
							|  |  |  |                         menu.append_item(&edit_menu_item);
 | 
					
						
							|  |  |  |                         menu.append_item(&delete_menu_item);
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                         self.overview_header_menu_button.set_menu_model(Some(&menu));
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:13:15 +02:00
										 |  |  |                         let self_ = self.clone();
 | 
					
						
							|  |  |  |                         let c = glib::MainContext::default();
 | 
					
						
							|  |  |  |                         c.spawn_local(async move {
 | 
					
						
							|  |  |  |                             let recordings = self_
 | 
					
						
							|  |  |  |                                 .backend
 | 
					
						
							|  |  |  |                                 .get_recordings_for_ensemble(ensemble.id)
 | 
					
						
							|  |  |  |                                 .await
 | 
					
						
							|  |  |  |                                 .unwrap();
 | 
					
						
							|  |  |  |                             self_.clone().set_state(OverviewScreen(
 | 
					
						
							|  |  |  |                                 poe.clone(),
 | 
					
						
							|  |  |  |                                 Vec::new(),
 | 
					
						
							|  |  |  |                                 recordings,
 | 
					
						
							|  |  |  |                                 String::from(""),
 | 
					
						
							|  |  |  |                             ));
 | 
					
						
							|  |  |  |                         });
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                     }
 | 
					
						
							|  |  |  |                 }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 self.overview_search_entry.set_text("");
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 self.overview_stack.set_visible_child_name("loading");
 | 
					
						
							|  |  |  |                 self.main_stack.set_visible_child_name("overview_screen");
 | 
					
						
							| 
									
										
										
										
											2020-10-10 12:01:22 +02:00
										 |  |  |                 self.leaflet.set_visible_child_name("content");
 | 
					
						
							|  |  |  |             }
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |             OverviewScreen(poe, works, recordings, search) => {
 | 
					
						
							|  |  |  |                 for child in self.overview_work_list.get_children() {
 | 
					
						
							|  |  |  |                     self.overview_work_list.remove(&child);
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                 }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 for child in self.overview_recording_list.get_children() {
 | 
					
						
							|  |  |  |                     self.overview_recording_list.remove(&child);
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:22:45 +02:00
										 |  |  |                 }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                 if works.is_empty() {
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                     self.overview_work_box.hide();
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                 } else {
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                     self.overview_work_box.show();
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                 }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 for (index, work) in works.iter().enumerate() {
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  |                     if search.is_empty() || work.title.to_lowercase().contains(&search) {
 | 
					
						
							|  |  |  |                         let label = gtk::Label::new(Some(&work.title));
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                         label.set_ellipsize(pango::EllipsizeMode::End);
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  |                         label.set_halign(gtk::Align::Start);
 | 
					
						
							|  |  |  |                         let row = SelectorRow::new(index.try_into().unwrap(), &label);
 | 
					
						
							|  |  |  |                         row.show_all();
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                         self.overview_work_list.insert(&row, -1);
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  |                     }
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                 }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 match self.overview_work_list_row_activated_handler_id.take() {
 | 
					
						
							|  |  |  |                     Some(id) => self.overview_work_list.disconnect(id),
 | 
					
						
							| 
									
										
										
										
											2020-10-10 01:16:21 +02:00
										 |  |  |                     None => (),
 | 
					
						
							|  |  |  |                 }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 let handler_id = self.overview_work_list.connect_row_activated(
 | 
					
						
							|  |  |  |                     clone!(@strong self as self_, @strong works, @strong poe => move |_, row| {
 | 
					
						
							|  |  |  |                         self_.overview_recording_list.unselect_all();
 | 
					
						
							| 
									
										
										
										
											2020-10-10 01:16:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         let row = row.get_child().unwrap().downcast::<SelectorRow>().unwrap();
 | 
					
						
							|  |  |  |                         let index: usize = row.get_index().try_into().unwrap();
 | 
					
						
							|  |  |  |                         let work = works[index].clone();
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                         self_.clone().set_state(WorkScreenLoading(poe.clone(), work));
 | 
					
						
							| 
									
										
										
										
											2020-10-10 01:16:21 +02:00
										 |  |  |                     }),
 | 
					
						
							|  |  |  |                 );
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 self.overview_work_list_row_activated_handler_id
 | 
					
						
							| 
									
										
										
										
											2020-10-10 01:16:21 +02:00
										 |  |  |                     .set(Some(handler_id));
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                 if recordings.is_empty() {
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                     self.overview_recording_box.hide();
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                 } else {
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                     self.overview_recording_box.show();
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                 }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:22:45 +02:00
										 |  |  |                 for (index, recording) in recordings.iter().enumerate() {
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                     let work_text = recording.work.get_title();
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  |                     let performers_text = recording.get_performers();
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:22:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                     if search.is_empty()
 | 
					
						
							|  |  |  |                         || (work_text.to_lowercase().contains(&search)
 | 
					
						
							|  |  |  |                             || performers_text.to_lowercase().contains(&search))
 | 
					
						
							|  |  |  |                     {
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  |                         let work_label = gtk::Label::new(Some(&work_text));
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:22:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  |                         work_label.set_ellipsize(pango::EllipsizeMode::End);
 | 
					
						
							|  |  |  |                         work_label.set_halign(gtk::Align::Start);
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:22:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  |                         let performers_label = gtk::Label::new(Some(&performers_text));
 | 
					
						
							|  |  |  |                         performers_label.set_ellipsize(pango::EllipsizeMode::End);
 | 
					
						
							|  |  |  |                         performers_label.set_opacity(0.5);
 | 
					
						
							|  |  |  |                         performers_label.set_halign(gtk::Align::Start);
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:22:45 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  |                         let vbox = gtk::Box::new(gtk::Orientation::Vertical, 0);
 | 
					
						
							|  |  |  |                         vbox.add(&work_label);
 | 
					
						
							|  |  |  |                         vbox.add(&performers_label);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         let row = SelectorRow::new(index.try_into().unwrap(), &vbox);
 | 
					
						
							|  |  |  |                         row.show_all();
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                         self.overview_recording_list.insert(&row, -1);
 | 
					
						
							| 
									
										
										
										
											2020-10-10 11:32:30 +02:00
										 |  |  |                     }
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:22:45 +02:00
										 |  |  |                 }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 match self.overview_recording_list_row_activated_handler_id.take() {
 | 
					
						
							|  |  |  |                     Some(id) => self.overview_recording_list.disconnect(id),
 | 
					
						
							| 
									
										
										
										
											2020-10-10 01:16:21 +02:00
										 |  |  |                     None => (),
 | 
					
						
							|  |  |  |                 }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 let handler_id = self.overview_recording_list.connect_row_activated(
 | 
					
						
							|  |  |  |                     clone!(@strong self as self_, @strong recordings, @strong poe => move |_, row| {
 | 
					
						
							|  |  |  |                         self_.overview_work_list.unselect_all();
 | 
					
						
							| 
									
										
										
										
											2020-10-10 01:16:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |                         let row = row.get_child().unwrap().downcast::<SelectorRow>().unwrap();
 | 
					
						
							|  |  |  |                         let index: usize = row.get_index().try_into().unwrap();
 | 
					
						
							|  |  |  |                         let recording = recordings[index].clone();
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                         self_.clone().set_state(RecordingScreenLoading(poe.clone(), recording));
 | 
					
						
							| 
									
										
										
										
											2020-10-10 01:16:21 +02:00
										 |  |  |                     }),
 | 
					
						
							|  |  |  |                 );
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 self.overview_recording_list_row_activated_handler_id
 | 
					
						
							| 
									
										
										
										
											2020-10-10 01:16:21 +02:00
										 |  |  |                     .set(Some(handler_id));
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 self.overview_stack.set_visible_child_name("content");
 | 
					
						
							|  |  |  |                 self.main_stack.set_visible_child_name("overview_screen");
 | 
					
						
							|  |  |  |                 self.leaflet.set_visible_child_name("content");
 | 
					
						
							|  |  |  |             }
 | 
					
						
							|  |  |  |             WorkScreenLoading(poe, work) => {
 | 
					
						
							|  |  |  |                 self.work_details_header
 | 
					
						
							|  |  |  |                     .set_title(Some(&work.composer.name_fl()));
 | 
					
						
							|  |  |  |                 self.work_details_header.set_subtitle(Some(&work.title));
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:13:15 +02:00
										 |  |  |                 let c = glib::MainContext::default();
 | 
					
						
							|  |  |  |                 let self_ = self.clone();
 | 
					
						
							|  |  |  |                 c.spawn_local(async move {
 | 
					
						
							|  |  |  |                     let recordings = self_
 | 
					
						
							|  |  |  |                         .backend
 | 
					
						
							|  |  |  |                         .get_recordings_for_work(work.id)
 | 
					
						
							|  |  |  |                         .await
 | 
					
						
							|  |  |  |                         .unwrap();
 | 
					
						
							|  |  |  |                     self_.clone().set_state(WorkScreen(
 | 
					
						
							|  |  |  |                         poe.clone(),
 | 
					
						
							|  |  |  |                         work.clone(),
 | 
					
						
							|  |  |  |                         recordings,
 | 
					
						
							|  |  |  |                         String::new(),
 | 
					
						
							|  |  |  |                     ));
 | 
					
						
							|  |  |  |                 });
 | 
					
						
							| 
									
										
										
										
											2020-10-11 18:03:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 self.work_details_stack.set_visible_child_name("loading");
 | 
					
						
							|  |  |  |                 self.main_stack
 | 
					
						
							|  |  |  |                     .set_visible_child_name("work_details_screen");
 | 
					
						
							|  |  |  |                 self.leaflet.set_visible_child_name("content");
 | 
					
						
							|  |  |  |             }
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:30:06 +02:00
										 |  |  |             WorkScreen(poe, _, recordings, search) => {
 | 
					
						
							| 
									
										
										
										
											2020-10-11 18:03:40 +02:00
										 |  |  |                 for child in self.work_details_recording_list.get_children() {
 | 
					
						
							|  |  |  |                     self.work_details_recording_list.remove(&child);
 | 
					
						
							|  |  |  |                 }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 for (index, recording) in recordings.iter().enumerate() {
 | 
					
						
							|  |  |  |                     let work_text = recording.work.get_title();
 | 
					
						
							|  |  |  |                     let performers_text = recording.get_performers();
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if search.is_empty()
 | 
					
						
							|  |  |  |                         || (work_text.to_lowercase().contains(&search)
 | 
					
						
							|  |  |  |                             || performers_text.to_lowercase().contains(&search))
 | 
					
						
							|  |  |  |                     {
 | 
					
						
							|  |  |  |                         let work_label = gtk::Label::new(Some(&work_text));
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         work_label.set_ellipsize(pango::EllipsizeMode::End);
 | 
					
						
							|  |  |  |                         work_label.set_halign(gtk::Align::Start);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         let performers_label = gtk::Label::new(Some(&performers_text));
 | 
					
						
							|  |  |  |                         performers_label.set_ellipsize(pango::EllipsizeMode::End);
 | 
					
						
							|  |  |  |                         performers_label.set_opacity(0.5);
 | 
					
						
							|  |  |  |                         performers_label.set_halign(gtk::Align::Start);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         let vbox = gtk::Box::new(gtk::Orientation::Vertical, 0);
 | 
					
						
							|  |  |  |                         vbox.add(&work_label);
 | 
					
						
							|  |  |  |                         vbox.add(&performers_label);
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         let row = SelectorRow::new(index.try_into().unwrap(), &vbox);
 | 
					
						
							|  |  |  |                         row.show_all();
 | 
					
						
							|  |  |  |                         self.work_details_recording_list.insert(&row, -1);
 | 
					
						
							|  |  |  |                     }
 | 
					
						
							|  |  |  |                 }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-11 19:53:36 +02:00
										 |  |  |                 match self
 | 
					
						
							|  |  |  |                     .work_details_recording_list_row_activated_handler_id
 | 
					
						
							|  |  |  |                     .take()
 | 
					
						
							|  |  |  |                 {
 | 
					
						
							| 
									
										
										
										
											2020-10-11 18:03:40 +02:00
										 |  |  |                     Some(id) => self.work_details_recording_list.disconnect(id),
 | 
					
						
							|  |  |  |                     None => (),
 | 
					
						
							|  |  |  |                 }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 let handler_id = self.work_details_recording_list.connect_row_activated(
 | 
					
						
							|  |  |  |                     clone!(@strong self as self_, @strong recordings, @strong poe => move |_, row| {
 | 
					
						
							|  |  |  |                         self_.overview_work_list.unselect_all();
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         let row = row.get_child().unwrap().downcast::<SelectorRow>().unwrap();
 | 
					
						
							|  |  |  |                         let index: usize = row.get_index().try_into().unwrap();
 | 
					
						
							|  |  |  |                         let recording = recordings[index].clone();
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                         self_.clone().set_state(RecordingScreenLoading(poe.clone(), recording));
 | 
					
						
							|  |  |  |                     }),
 | 
					
						
							|  |  |  |                 );
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 self.work_details_recording_list_row_activated_handler_id
 | 
					
						
							|  |  |  |                     .set(Some(handler_id));
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 self.work_details_stack.set_visible_child_name("content");
 | 
					
						
							|  |  |  |                 self.main_stack
 | 
					
						
							|  |  |  |                     .set_visible_child_name("work_details_screen");
 | 
					
						
							|  |  |  |                 self.leaflet.set_visible_child_name("content");
 | 
					
						
							|  |  |  |             }
 | 
					
						
							| 
									
										
										
										
											2020-10-11 21:30:06 +02:00
										 |  |  |             RecordingScreenLoading(_, recording) => {
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |                 self.recording_details_header
 | 
					
						
							|  |  |  |                     .set_title(Some(&recording.work.get_title()));
 | 
					
						
							|  |  |  |                 self.recording_details_header
 | 
					
						
							|  |  |  |                     .set_subtitle(Some(&recording.get_performers()));
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 self.recording_details_stack
 | 
					
						
							|  |  |  |                     .set_visible_child_name("loading");
 | 
					
						
							|  |  |  |                 self.main_stack
 | 
					
						
							|  |  |  |                     .set_visible_child_name("recording_details_screen");
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |                 self.leaflet.set_visible_child_name("content");
 | 
					
						
							|  |  |  |             }
 | 
					
						
							| 
									
										
										
										
											2020-09-29 00:10:52 +02:00
										 |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-28 23:33:48 +02:00
										 |  |  |     fn back(&self) {
 | 
					
						
							| 
									
										
										
										
											2020-10-10 13:55:14 +02:00
										 |  |  |         self.main_stack.set_visible_child_name("empty_screen");
 | 
					
						
							| 
									
										
										
										
											2020-10-09 20:19:46 +02:00
										 |  |  |         self.leaflet.set_visible_child_name("sidebar");
 | 
					
						
							| 
									
										
										
										
											2020-09-28 20:09:49 +02:00
										 |  |  |     }
 | 
					
						
							| 
									
										
										
										
											2020-09-27 21:58:42 +02:00
										 |  |  | }
 |