aboutsummaryrefslogtreecommitdiff
path: root/src/gui/form/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/form/mod.rs')
-rw-r--r--src/gui/form/mod.rs115
1 files changed, 81 insertions, 34 deletions
diff --git a/src/gui/form/mod.rs b/src/gui/form/mod.rs
index 68e6539..bb43ef5 100644
--- a/src/gui/form/mod.rs
+++ b/src/gui/form/mod.rs
@@ -1,22 +1,24 @@
mod repetition;
+mod utils;
use gtk4 as gtk;
use anyhow::Result;
-use chrono::{NaiveDate, NaiveTime};
+use chrono::{Duration, NaiveDate};
use gtk::glib;
use gtk::prelude::*;
use rusqlite::Connection;
+use std::collections::HashSet;
use thiserror::Error;
use uuid::Uuid;
use crate::{
db,
gui::{update, update::Msg, App},
- model::{event, event::Event},
+ model::{event, event::Event, repetition::Repetition},
};
-pub async fn repetition_dialog(app: &App, date: NaiveDate, event: Event) {
+pub async fn repetition_dialog(app: &App, date: NaiveDate, event: &Event) {
let dialog = gtk::Dialog::builder()
.transient_for(&*app.window)
.modal(true)
@@ -38,17 +40,28 @@ pub async fn repetition_dialog(app: &App, date: NaiveDate, event: Event) {
lines.append(&button);
let tx = app.tx.clone();
button.connect_clicked(glib::clone!(@weak dialog, @strong event => move |_| {
- update::send(tx.clone(), Msg::ShowUpdateRepetitionForm { date, event: event.clone() });
+ update::send(tx.clone(), Msg::ShowUpdateRepetitionForm { date, event_id: event.id });
dialog.close()
}));
let button = gtk::Button::builder()
.label("Toutes les occurences")
+ .margin_bottom(10)
.build();
lines.append(&button);
let tx = app.tx.clone();
button.connect_clicked(glib::clone!(@weak dialog, @strong event => move |_| {
- update::send(tx.clone(), Msg::ShowUpdateForm { event: event.clone() });
+ update::send(tx.clone(), Msg::ShowUpdateForm { event_id: event.id });
+ dialog.close()
+ }));
+
+ let button = gtk::Button::builder()
+ .label("À partir de cette occurence")
+ .build();
+ lines.append(&button);
+ let tx = app.tx.clone();
+ button.connect_clicked(glib::clone!(@weak dialog, @strong event => move |_| {
+ update::send(tx.clone(), Msg::ShowUpdateFromOccurence { date, event_id: event.id });
dialog.close()
}));
@@ -60,6 +73,7 @@ pub enum Target {
New { date: NaiveDate },
Update { event: Event },
UpdateRepetition { event: Event, date: NaiveDate },
+ UpdateFromOccurence { event: Event, date: NaiveDate },
}
pub async fn show(app: &App, target: Target) {
@@ -67,6 +81,7 @@ pub async fn show(app: &App, target: Target) {
Target::New { .. } => None,
Target::Update { ref event } => Some(event.clone()),
Target::UpdateRepetition { ref event, .. } => Some(event.clone()),
+ Target::UpdateFromOccurence { ref event, .. } => Some(event.clone()),
};
let title = if event.is_some() {
@@ -91,6 +106,7 @@ pub async fn show(app: &App, target: Target) {
let columns = gtk::Box::builder()
.orientation(gtk::Orientation::Horizontal)
+ .spacing(10)
.build();
lines.append(&columns);
@@ -101,37 +117,42 @@ pub async fn show(app: &App, target: Target) {
.build();
columns.append(&column1);
- let name = event.as_ref().map(|e| entry(&e.name)).unwrap_or_default();
- column1.append(&label("Événement"));
+ let name = event
+ .as_ref()
+ .map(|e| utils::entry(&e.name))
+ .unwrap_or_default();
+ column1.append(&utils::label("Événement"));
column1.append(&name);
let date = match target {
Target::New { date } => date,
Target::Update { ref event } => event.date,
Target::UpdateRepetition { date, .. } => date,
+ Target::UpdateFromOccurence { date, .. } => date,
};
- let date = entry(&date.format(event::DATE_FORMAT).to_string());
- column1.append(&label("Jour"));
+ let date = utils::entry(&date.format(event::DATE_FORMAT).to_string());
+ column1.append(&utils::label("Jour"));
column1.append(&date);
let start = event
.as_ref()
- .map(|e| time_entry(e.start))
- .unwrap_or_else(|| entry(""));
- column1.append(&label("Début"));
+ .map(|e| utils::time_entry(e.start))
+ .unwrap_or_else(|| utils::entry(""));
+ column1.append(&utils::label("Début"));
column1.append(&start);
let end = event
.as_ref()
- .map(|e| time_entry(e.end))
- .unwrap_or_else(|| entry(""));
- column1.append(&label("Fin"));
+ .map(|e| utils::time_entry(e.end))
+ .unwrap_or_else(|| utils::entry(""));
+ column1.append(&utils::label("Fin"));
column1.append(&end);
// Second column
let repetition = match target {
Target::Update { ref event } => event.repetition.as_ref(),
+ Target::UpdateFromOccurence { ref event, .. } => event.repetition.as_ref(),
_ => None,
};
let repetition_model = repetition::view(repetition);
@@ -143,6 +164,7 @@ pub async fn show(app: &App, target: Target) {
Target::New { .. } => "Créer",
Target::Update { .. } => "Modifier",
Target::UpdateRepetition { .. } => "Modifier l’occurence",
+ Target::UpdateFromOccurence { .. } => "Modifier à partir de l’occurence",
};
let button = gtk::Button::builder()
@@ -153,7 +175,13 @@ pub async fn show(app: &App, target: Target) {
let conn = app.conn.clone();
let tx = app.tx.clone();
button.connect_clicked(glib::clone!(@weak dialog, @strong target, @strong event => move |_| {
- match repetition::validate(&repetition_model) {
+ let removed_occurences = match &target {
+ Target::Update { event, .. } => {
+ event.repetition.as_ref().map(|r| r.removed_occurences.clone()).unwrap_or_default()
+ },
+ _ => HashSet::new(),
+ };
+ match repetition::validate(&repetition_model, removed_occurences) {
Ok(repetition) => {
let id = match &target {
Target::Update {event} => event.id,
@@ -200,6 +228,24 @@ pub async fn show(app: &App, target: Target) {
Err(err) => eprintln!("Error when updating repetition: {}", err)
}
}
+ Target::UpdateFromOccurence { date, event } => {
+ match update_repetition_until(&conn, *date - Duration::days(1), event) {
+ Ok(updated) => {
+ match db::insert(&conn, &new) {
+ Ok(_) => {
+ update::send(tx.clone(), Msg::UpdateRepeatedFrom {
+ old: event.clone(),
+ updated,
+ new
+ });
+ dialog.close()
+ },
+ Err(err) => eprintln!("Error when inserting event: {}", err)
+ }
+ },
+ Err(err) => eprintln!("Error when updating event: {}", err)
+ }
+ }
}
}
None => eprintln!("Event is not valid.")
@@ -212,6 +258,7 @@ pub async fn show(app: &App, target: Target) {
if let Some(event) = event {
let label = match target {
Target::Update { .. } => "Supprimer",
+ Target::UpdateFromOccurence { .. } => "Supprimer à partir de l’occurence",
_ => "Supprimer l’occurence",
};
let button = gtk::Button::builder().label(label).build();
@@ -231,6 +278,15 @@ pub async fn show(app: &App, target: Target) {
}
}
}
+ Target::UpdateFromOccurence { date, .. } => {
+ match update_repetition_until(&conn, date - Duration::days(1), &event) {
+ Ok(updated) => {
+ update::send(tx.clone(), Msg::UpdateEvent { old: event.clone(), new: updated });
+ dialog.close()
+ },
+ Err(err) => eprintln!("Error when updating event: {}", err)
+ }
+ }
_ => {
let operation = db::delete(&conn, &event.id);
if operation.is_ok() {
@@ -273,22 +329,13 @@ fn delete_repetition_occurence(
}
}
-fn time_entry(time: Option<NaiveTime>) -> gtk::Entry {
- entry(
- &time
- .map(event::pprint_time)
- .unwrap_or_else(|| "".to_string()),
- )
-}
-
-fn entry(text: &str) -> gtk::Entry {
- gtk::Entry::builder().text(text).margin_bottom(10).build()
-}
-
-fn label(text: &str) -> gtk::Label {
- gtk::Label::builder()
- .label(text)
- .halign(gtk::Align::Start)
- .margin_bottom(5)
- .build()
+fn update_repetition_until(conn: &Connection, date: NaiveDate, event: &Event) -> Result<Event> {
+ let mut with_repetition_until = event.clone();
+ with_repetition_until.repetition = event.repetition.as_ref().map(|r| Repetition {
+ frequency: r.frequency.clone(),
+ removed_occurences: r.removed_occurences.clone(),
+ until: Some(date),
+ });
+ db::update(conn, &with_repetition_until)?;
+ Ok(with_repetition_until)
}