diff options
-rw-r--r-- | src/cli/mod.rs | 19 | ||||
-rw-r--r-- | src/gui/calendar.rs | 62 | ||||
-rw-r--r-- | src/gui/form/mod.rs | 295 | ||||
-rw-r--r-- | src/gui/form/repetition.rs | 4 | ||||
-rw-r--r-- | src/main.rs | 5 | ||||
-rw-r--r-- | src/model/event.rs | 2 |
6 files changed, 238 insertions, 149 deletions
diff --git a/src/cli/mod.rs b/src/cli/mod.rs index e7439b5..2248fde 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -2,8 +2,8 @@ use anyhow::Result; use chrono::{Local, NaiveDate, NaiveDateTime, TimeZone}; use rusqlite::Connection; -use crate::{db, model::event}; use crate::model::event::Event; +use crate::{db, model::event}; pub fn today(conn: &Connection) -> Result<String> { let today = Local::now().date_naive(); @@ -33,13 +33,11 @@ pub fn start_between(conn: &Connection, from: NaiveDateTime, to: NaiveDateTime) println!("{events:?}"); let events: Vec<Event> = events .iter() - .filter(|e| { - match e.start { - None => false, - Some(t) => { - let dt = NaiveDateTime::new(e.date, t); - dt >= from && dt < to - } + .filter(|e| match e.start { + None => false, + Some(t) => { + let dt = NaiveDateTime::new(e.date, t); + dt >= from && dt < to } }) .map(|e| e.clone()) @@ -53,7 +51,10 @@ fn between_inclusive(conn: &Connection, from: NaiveDate, to: NaiveDate) -> Resul let repetitions = event::repetitions_between(&recurring_events, from, to); for (date, original_events) in repetitions.iter() { for original_event in original_events { - let event = Event { date: *date, ..original_event.clone() }; + let event = Event { + date: *date, + ..original_event.clone() + }; events.push(event); } } diff --git a/src/gui/calendar.rs b/src/gui/calendar.rs index 38f5d55..5181116 100644 --- a/src/gui/calendar.rs +++ b/src/gui/calendar.rs @@ -33,16 +33,29 @@ pub fn create( } let repetitions = event::repetitions_between(recurring_events, start_date, end_date); - attach_days(tx.clone(), &grid, start_date, today, events, &repetitions, categories, default_color); + attach_days( + tx.clone(), + &grid, + start_date, + today, + events, + &repetitions, + categories, + default_color, + ); let event_controller_key = gtk::EventControllerKey::new(); - event_controller_key.connect_key_released(glib::clone!(#[strong] tx, move |_, _, keycode, _| { - match keycode { - 111 => update::send(tx.clone(), Msg::SelectPreviousWeek), // UP - 116 => update::send(tx.clone(), Msg::SelectNextWeek), // DOWN - _ => () + event_controller_key.connect_key_released(glib::clone!( + #[strong] + tx, + move |_, _, keycode, _| { + match keycode { + 111 => update::send(tx.clone(), Msg::SelectPreviousWeek), // UP + 116 => update::send(tx.clone(), Msg::SelectNextWeek), // DOWN + _ => (), + } } - })); + )); grid.add_controller(event_controller_key); grid @@ -141,11 +154,15 @@ pub fn day_entry( vbox.add_css_class("g-Calendar__Day"); let gesture = gtk::GestureClick::new(); - gesture.connect_pressed(glib::clone!(#[strong] tx, move |_, n, _, _| { - if n == 2 { - update::send(tx.clone(), Msg::ShowAddForm { date }); + gesture.connect_pressed(glib::clone!( + #[strong] + tx, + move |_, n, _, _| { + if n == 2 { + update::send(tx.clone(), Msg::ShowAddForm { date }); + } } - })); + )); vbox.add_controller(gesture); if date == today { @@ -236,25 +253,36 @@ fn day_events( }} ", background_color - ).as_str() + ) + .as_str(), ); hbox.style_context() .add_provider(&provider, gtk::STYLE_PROVIDER_PRIORITY_APPLICATION); hbox.style_context().add_class("event"); let gesture = gtk::GestureClick::new(); - gesture.connect_pressed( - glib::clone!(#[strong] event, #[strong] tx, move |gesture, n, _, _| { + gesture.connect_pressed(glib::clone!( + #[strong] + event, + #[strong] + tx, + move |gesture, n, _, _| { gesture.set_state(gtk::EventSequenceState::Claimed); if n == 2 { if event.repetition.is_some() { - update::send(tx.clone(), Msg::ShowRepetitionDialog { date, event_id: event.id }); + update::send( + tx.clone(), + Msg::ShowRepetitionDialog { + date, + event_id: event.id, + }, + ); } else { update::send(tx.clone(), Msg::ShowUpdateForm { event_id: event.id }); } } - }), - ); + } + )); hbox.add_controller(gesture); let event_txt = &event.pprint(); diff --git a/src/gui/form/mod.rs b/src/gui/form/mod.rs index dbaf879..e05bb78 100644 --- a/src/gui/form/mod.rs +++ b/src/gui/form/mod.rs @@ -39,16 +39,22 @@ pub async fn repetition_dialog(app: &App, date: NaiveDate, event: &Event) { .build(); 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_id: event.id }); - dialog.close() - } - ) - ); + button.connect_clicked(glib::clone!( + #[weak] + dialog, + #[strong] + event, + move |_| { + update::send( + tx.clone(), + Msg::ShowUpdateRepetitionForm { + date, + event_id: event.id, + }, + ); + dialog.close() + } + )); let button = gtk::Button::builder() .label("Toutes les occurences") @@ -56,32 +62,38 @@ pub async fn repetition_dialog(app: &App, date: NaiveDate, event: &Event) { .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_id: event.id }); - dialog.close() - } - ) - ); + button.connect_clicked(glib::clone!( + #[weak] + dialog, + #[strong] + event, + move |_| { + 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() - } - ) - ); + button.connect_clicked(glib::clone!( + #[weak] + dialog, + #[strong] + event, + move |_| { + update::send( + tx.clone(), + Msg::ShowUpdateFromOccurence { + date, + event_id: event.id, + }, + ); + dialog.close() + } + )); dialog.run_future().await; } @@ -211,97 +223,128 @@ pub async fn show(app: &App, target: Target) { let conn = app.conn.clone(); let tx = app.tx.clone(); let categories = app.categories.clone(); - button.connect_clicked( - glib::clone!( - #[weak] dialog, - #[strong] target, - #[strong] categories, - move |_| { - 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, - _ => Uuid::new_v4(), - }; - - // Find category id from selected id - let category = categories.iter().find(|c| c.name == dropdown_categories[category_dropdown.selected() as usize]).map(|c| c.id); - - match event::validate(id, date.buffer().text().to_string(), name.buffer().text().to_string(), start.buffer().text().to_string(), end.buffer().text().to_string(), repetition, category) { - Some(new) => { - match &target { - Target::New {..} => { - match db::events::insert(&conn, &new) { - Ok(_) => { - update::send(tx.clone(), Msg::AddEvent { new }); - dialog.close() - }, - Err(err) => eprintln!("Error when inserting event: {}", err) - } + button.connect_clicked(glib::clone!( + #[weak] + dialog, + #[strong] + target, + #[strong] + categories, + move |_| { + 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, + _ => Uuid::new_v4(), + }; + + // Find category id from selected id + let category = categories + .iter() + .find(|c| { + c.name == dropdown_categories[category_dropdown.selected() as usize] + }) + .map(|c| c.id); + + match event::validate( + id, + date.buffer().text().to_string(), + name.buffer().text().to_string(), + start.buffer().text().to_string(), + end.buffer().text().to_string(), + repetition, + category, + ) { + Some(new) => { + match &target { + Target::New { .. } => match db::events::insert(&conn, &new) { + Ok(_) => { + update::send(tx.clone(), Msg::AddEvent { new }); + dialog.close() } - Target::Update {event} => { - match db::events::update(&conn, &new) { - Ok(_) => { - update::send(tx.clone(), Msg::UpdateEvent { old: event.clone(), new }); - dialog.close() + Err(err) => eprintln!("Error when inserting event: {}", err), + }, + Target::Update { event } => match db::events::update(&conn, &new) { + Ok(_) => { + update::send( + tx.clone(), + Msg::UpdateEvent { + old: event.clone(), + new, }, - Err(err) => eprintln!("Error when updating event: {}", err) - } + ); + dialog.close() } - Target::UpdateRepetition { event, date } => { - // TODO: improve intermediate error state - match delete_repetition_occurence(&conn, event, *date) { - Ok(occurence) => { - match db::events::insert(&conn, &new) { - Ok(_) => { - update::send(tx.clone(), Msg::UpdateEventOccurence { - event: event.clone(), - occurence, - date: *date, - new - }) - } - Err(err) => eprintln!("Error when updating repetition: {}", err) - }; - dialog.close() - }, - Err(err) => eprintln!("Error when updating repetition: {}", err) + Err(err) => eprintln!("Error when updating event: {}", err), + }, + Target::UpdateRepetition { event, date } => { + // TODO: improve intermediate error state + match delete_repetition_occurence(&conn, event, *date) { + Ok(occurence) => { + match db::events::insert(&conn, &new) { + Ok(_) => update::send( + tx.clone(), + Msg::UpdateEventOccurence { + event: event.clone(), + occurence, + date: *date, + new, + }, + ), + Err(err) => eprintln!( + "Error when updating repetition: {}", + err + ), + }; + dialog.close() + } + 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::events::insert(&conn, &new) { - Ok(_) => { - update::send(tx.clone(), Msg::UpdateRepeatedFrom { - old: event.clone(), - updated, - new - }); - dialog.close() + } + Target::UpdateFromOccurence { date, event } => { + match update_repetition_until( + &conn, + *date - Duration::days(1), + event, + ) { + Ok(updated) => match db::events::insert(&conn, &new) { + Ok(_) => { + update::send( + tx.clone(), + Msg::UpdateRepeatedFrom { + old: event.clone(), + updated, + new, }, - Err(err) => eprintln!("Error when inserting event: {}", err) - } - }, - Err(err) => eprintln!("Error when updating event: {}", err) - } + ); + dialog.close() + } + Err(err) => { + eprintln!("Error when inserting event: {}", err) + } + }, + Err(err) => eprintln!("Error when updating event: {}", err), } } } - None => eprintln!("Event is not valid.") } - }, - Err(message) => eprintln!("{}", message) + None => eprintln!("Event is not valid."), + } } + Err(message) => eprintln!("{}", message), } - ) - ); + } + )); if let Some(event) = event { let label = match target { @@ -313,13 +356,22 @@ pub async fn show(app: &App, target: Target) { lines.append(&button); let conn = app.conn.clone(); let tx = app.tx.clone(); - button.connect_clicked( - glib::clone!(#[weak] dialog, move |_| { + button.connect_clicked(glib::clone!( + #[weak] + dialog, + move |_| { match target { Target::UpdateRepetition { date, .. } => { match delete_repetition_occurence(&conn, &event, date) { Ok(occurence) => { - update::send(tx.clone(), Msg::DeleteOccurence { event: event.clone(), date, occurence }); + update::send( + tx.clone(), + Msg::DeleteOccurence { + event: event.clone(), + date, + occurence, + }, + ); dialog.close() } Err(err) => { @@ -330,16 +382,27 @@ 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 }); + update::send( + tx.clone(), + Msg::UpdateEvent { + old: event.clone(), + new: updated, + }, + ); dialog.close() - }, - Err(err) => eprintln!("Error when updating event: {}", err) + } + Err(err) => eprintln!("Error when updating event: {}", err), } } _ => { let operation = db::events::delete(&conn, &event.id); if operation.is_ok() { - update::send(tx.clone(), Msg::DeleteEvent { event: event.clone() }); + update::send( + tx.clone(), + Msg::DeleteEvent { + event: event.clone(), + }, + ); dialog.close() } } diff --git a/src/gui/form/repetition.rs b/src/gui/form/repetition.rs index ca8379a..4ed9803 100644 --- a/src/gui/form/repetition.rs +++ b/src/gui/form/repetition.rs @@ -17,9 +17,7 @@ static WEEKDAYS_STR: [&str; 7] = [ static WEEKDAYS: [Weekday; 7] = [Mon, Tue, Wed, Thu, Fri, Sat, Sun]; -static WEEKS_STR: [&str; 4] = [ - "1er", "2ème", "3ème", "4ème" -]; +static WEEKS_STR: [&str; 4] = ["1er", "2ème", "3ème", "4ème"]; static WEEKS: [u8; 4] = [1, 2, 3, 4]; diff --git a/src/main.rs b/src/main.rs index 4e2a5f2..8eafd77 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,7 +27,7 @@ fn main() -> Result<()> { let Opt { db_path, list_today, - start_between + start_between, } = Opt::parse(); let conn = db::init(&db_path)?; if list_today { @@ -35,9 +35,8 @@ fn main() -> Result<()> { } else { match start_between.and_then(cli::parse_timestamp_range) { Some((from, to)) => print!("{}", cli::start_between(&conn, from, to)?), - None => gui::run(conn) + None => gui::run(conn), } }; Ok(()) } - diff --git a/src/model/event.rs b/src/model/event.rs index dc052fe..3e5cc76 100644 --- a/src/model/event.rs +++ b/src/model/event.rs @@ -1,4 +1,4 @@ -use chrono::{NaiveDate, NaiveTime, NaiveDateTime, Local, TimeZone}; +use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime, TimeZone}; use std::collections::HashMap; use uuid::Uuid; |