Remove support for separate part composers

This commit is contained in:
Elias Projahn 2021-02-07 10:02:30 +01:00
parent aeed44248e
commit fdc5bc72a8
5 changed files with 10 additions and 109 deletions

View file

@ -1,28 +1,21 @@
use crate::selectors::PersonSelector;
use crate::navigator::{NavigationHandle, Screen};
use crate::widgets::Widget;
use gettextrs::gettext;
use glib::clone;
use gtk::prelude::*;
use gtk_macros::get_widget;
use libadwaita::prelude::*;
use musicus_backend::db::{Person, WorkPart};
use std::cell::RefCell;
use musicus_backend::db::WorkPart;
use std::rc::Rc;
/// A dialog for creating or editing a work part.
/// A dialog for creating or editing a work section.
pub struct WorkPartEditor {
handle: NavigationHandle<WorkPart>,
widget: gtk::Box,
title_entry: gtk::Entry,
composer_row: libadwaita::ActionRow,
reset_composer_button: gtk::Button,
composer: RefCell<Option<Person>>,
}
impl Screen<Option<WorkPart>, WorkPart> for WorkPartEditor {
impl Screen<Option<WorkPart>, WorkPart> for WorkPartEditor {
/// Create a new part editor and optionally initialize it.
fn new(part: Option<WorkPart>, handle: NavigationHandle<WorkPart>) -> Rc<Self> {
fn new(section: Option<WorkPart>, handle: NavigationHandle<WorkPart>) -> Rc<Self> {
// Create UI
let builder = gtk::Builder::from_resource("/de/johrpan/musicus/ui/work_part_editor.ui");
@ -31,25 +24,15 @@ impl Screen<Option<WorkPart>, WorkPart> for WorkPartEditor {
get_widget!(builder, gtk::Button, back_button);
get_widget!(builder, gtk::Button, save_button);
get_widget!(builder, gtk::Entry, title_entry);
get_widget!(builder, gtk::Button, composer_button);
get_widget!(builder, libadwaita::ActionRow, composer_row);
get_widget!(builder, gtk::Button, reset_composer_button);
let composer = match part {
Some(part) => {
title_entry.set_text(&part.title);
part.composer
}
None => None,
};
if let Some(section) = section {
title_entry.set_text(&section.title);
}
let this = Rc::new(Self {
handle,
widget,
title_entry,
composer_row,
reset_composer_button,
composer: RefCell::new(composer),
});
// Connect signals and callbacks
@ -59,54 +42,17 @@ impl Screen<Option<WorkPart>, WorkPart> for WorkPartEditor {
}));
save_button.connect_clicked(clone!(@weak this => move |_| {
let part = WorkPart {
let section = WorkPart {
title: this.title_entry.get_text().unwrap().to_string(),
composer: this.composer.borrow().clone(),
};
this.handle.pop(Some(part));
this.handle.pop(Some(section));
}));
composer_button.connect_clicked(clone!(@strong this => move |_| {
spawn!(@clone this, async move {
if let Some(person) = push!(this.handle, PersonSelector).await {
this.show_composer(Some(&person));
this.composer.replace(Some(person.to_owned()));
}
});
}));
this.reset_composer_button
.connect_clicked(clone!(@strong this => move |_| {
this.composer.replace(None);
this.show_composer(None);
}));
// Initialize
if let Some(composer) = &*this.composer.borrow() {
this.show_composer(Some(composer));
}
this
}
}
impl WorkPartEditor {
/// Update the UI according to person.
fn show_composer(&self, person: Option<&Person>) {
if let Some(person) = person {
self.composer_row.set_title(Some(&gettext("Composer")));
self.composer_row.set_subtitle(Some(&person.name_fl()));
self.reset_composer_button.show();
} else {
self.composer_row.set_title(Some(&gettext("Select a composer")));
self.composer_row.set_subtitle(None);
self.reset_composer_button.hide();
}
}
}
impl Widget for WorkPartEditor {
fn get_widget(&self) -> gtk::Widget {
self.widget.clone().upcast()

View file

@ -25,8 +25,7 @@ CREATE TABLE "work_parts" (
"id" BIGINT NOT NULL PRIMARY KEY,
"work" TEXT NOT NULL REFERENCES "works"("id") ON DELETE CASCADE,
"part_index" BIGINT NOT NULL,
"title" TEXT NOT NULL,
"composer" TEXT REFERENCES "persons"("id")
"title" TEXT NOT NULL
);
CREATE TABLE "work_sections" (

View file

@ -79,7 +79,6 @@ table! {
work -> Text,
part_index -> BigInt,
title -> Text,
composer -> Nullable<Text>,
}
}
@ -110,7 +109,6 @@ joinable!(recordings -> works (work));
joinable!(track_sets -> mediums (medium));
joinable!(track_sets -> recordings (recording));
joinable!(tracks -> track_sets (track_set));
joinable!(work_parts -> persons (composer));
joinable!(work_parts -> works (work));
joinable!(work_sections -> works (work));
joinable!(works -> persons (composer));

View file

@ -41,7 +41,6 @@ struct WorkPartRow {
pub work: String,
pub part_index: i64,
pub title: String,
pub composer: Option<String>,
}
/// Table row data for a work section.
@ -58,7 +57,6 @@ struct WorkSectionRow {
#[serde(rename_all = "camelCase")]
pub struct WorkPart {
pub title: String,
pub composer: Option<Person>,
}
/// A heading between work parts.
@ -123,14 +121,6 @@ impl Database {
}
}
for part in &work.parts {
if let Some(person) = &part.composer {
if self.get_person(&person.id)?.is_none() {
self.update_person(person.clone())?;
}
}
}
// Add the actual work.
let row: WorkRow = work.clone().into();
@ -163,7 +153,6 @@ impl Database {
work: work_id.to_string(),
part_index: index as i64,
title: part.title,
composer: part.composer.map(|person| person.id),
};
diesel::insert_into(work_parts::table)
@ -237,17 +226,6 @@ impl Database {
for part_row in part_rows {
parts.push(WorkPart {
title: part_row.title,
composer: match part_row.composer {
Some(composer) => Some(
self.get_person(&composer)?
.ok_or(Error::Other(format!(
"Failed to get person ({}) for work ({}).",
composer,
row.id,
)))?
),
None => None,
},
});
}

View file

@ -66,26 +66,6 @@
</child>
</object>
</child>
<child>
<object class="AdwActionRow" id="composer_row">
<property name="activatable">True</property>
<property name="title" translatable="yes">Select a composer</property>
<property name="activatable-widget">composer_button</property>
<child>
<object class="GtkButton" id="reset_composer_button">
<property name="visible">false</property>
<property name="icon-name">user-trash-symbolic</property>
<property name="valign">center</property>
</object>
</child>
<child>
<object class="GtkButton" id="composer_button">
<property name="label" translatable="yes">Select</property>
<property name="valign">center</property>
</object>
</child>
</object>
</child>
</object>
</child>
</object>