diff --git a/res/resources.xml b/res/resources.xml
index d5e16e9..d866eb3 100644
--- a/res/resources.xml
+++ b/res/resources.xml
@@ -5,5 +5,6 @@
ui/instrument_editor.ui
ui/person_editor.ui
ui/window.ui
+ ui/work_editor.ui
diff --git a/res/ui/work_editor.ui b/res/ui/work_editor.ui
new file mode 100644
index 0000000..507f36a
--- /dev/null
+++ b/res/ui/work_editor.ui
@@ -0,0 +1,388 @@
+
+
+
+
+
+
diff --git a/src/dialogs/mod.rs b/src/dialogs/mod.rs
index 3ab4e11..ca9e250 100644
--- a/src/dialogs/mod.rs
+++ b/src/dialogs/mod.rs
@@ -5,4 +5,7 @@ pub mod instrument_editor;
pub use instrument_editor::*;
pub mod person_editor;
-pub use person_editor::*;
\ No newline at end of file
+pub use person_editor::*;
+
+pub mod work_editor;
+pub use work_editor::*;
\ No newline at end of file
diff --git a/src/dialogs/work_editor.rs b/src/dialogs/work_editor.rs
new file mode 100644
index 0000000..055aaf8
--- /dev/null
+++ b/src/dialogs/work_editor.rs
@@ -0,0 +1,176 @@
+use crate::database::*;
+use glib::clone;
+use gtk::prelude::*;
+use gtk_macros::get_widget;
+use std::cell::RefCell;
+use std::convert::TryInto;
+use std::rc::Rc;
+
+struct PartOrSection {
+ part: Option,
+ section: Option,
+}
+
+impl PartOrSection {
+ pub fn part(part: WorkPartDescription) -> Self {
+ PartOrSection {
+ part: Some(part),
+ section: None,
+ }
+ }
+
+ pub fn section(section: WorkSectionDescription) -> Self {
+ PartOrSection {
+ part: None,
+ section: Some(section),
+ }
+ }
+
+ pub fn is_part(&self) -> bool {
+ self.part.is_some()
+ }
+
+ pub fn unwrap_part(&self) -> WorkPartDescription {
+ self.part.as_ref().unwrap().clone()
+ }
+
+ pub fn unwrap_section(&self) -> WorkSectionDescription {
+ self.section.as_ref().unwrap().clone()
+ }
+}
+
+pub struct WorkEditor {
+ window: gtk::Window,
+ save_button: gtk::Button,
+ id: i64,
+ title_entry: gtk::Entry,
+ composer: RefCell