many improvements

* latest iced
* read events from ical files (using the  icalendar crate)
* ical files specified on command line (using clap, bit overkill)

Signed-off-by: Fabrizio Iannetti <fabrizio.iannetti@gmail.com>
This commit is contained in:
Fabrizio Iannetti 2023-07-09 18:49:42 +02:00
parent 1a08bfbcdc
commit ab28f9227e
8 changed files with 476 additions and 372 deletions

705
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,10 @@ tracing = ["dep:lttng-ust"]
iced = { path = "../iced", features = ["advanced"] }
chrono = "0.4"
lttng-ust = { version = "0.1.0", optional = true }
icalendar = "0.15.4"
directories = "5.0.1"
clap = { version = "4.3.11", features = ["derive"] }
[build-dependencies]
lttng-ust-generate = "0.1.0"
#lttng-ust-generate = "0.1.0"
lttng-ust-generate = { path = "../lttng-ust-rs/lttng-ust-generate" }

View File

@ -4,10 +4,15 @@ mod model;
use ui::calendar;
use model::events::EventsCollection;
use model::ical_bridge::load_calendar;
use chrono::{Datelike, NaiveDate, Months, Utc};
use calendar::{CalendarMonthView, CalendarYearView, CalendarParams };
use std::path;
use clap;
use clap::Parser;
use iced::{
alignment,
executor,
@ -23,8 +28,21 @@ use iced::widget::{
//use iced::button;
use iced::theme;
struct CalendarFlags {
calendar_paths: std::vec::Vec<path::PathBuf>,
}
#[derive(Parser, Debug)]
#[command(version, about)]
struct CliArgs {
files: Vec<String>,
}
pub fn main() -> iced::Result {
CalendarApp::run(Settings::default())
let args = CliArgs::parse();
let calendar_files = args.files.iter().map(|arg| path::PathBuf::from(arg)).collect();
//let calendar_files = vec![path::PathBuf::from("/home/fab/calendario.ics")];
CalendarApp::run(Settings::with_flags(CalendarFlags {calendar_paths: calendar_files}))
}
#[derive(Default)]
@ -118,15 +136,19 @@ impl Application for CalendarApp {
type Executor = executor::Default;
type Message = Message;
type Theme = iced::Theme;
type Flags = ();
type Flags = CalendarFlags;
fn new(_flags: Self::Flags) -> (Self, Command<Message>) {
let month = Utc::today().naive_local();
(CalendarApp {
fn new(flags: Self::Flags) -> (Self, Command<Message>) {
let month = Utc::now().date_naive();
let mut ret = (CalendarApp {
month,
events: EventsCollection::new(),
..CalendarApp::default()
}, Command::none())
}, Command::none());
for calendar_path in flags.calendar_paths {
load_calendar(&calendar_path, &mut ret.0.events);
}
ret
}
fn title(&self) -> String {

View File

@ -1 +1,2 @@
pub mod events;
pub mod events;
pub mod ical_bridge;

View File

@ -10,16 +10,6 @@ pub struct Event {
pub end: NaiveDate,
}
//impl Clone for Event {
// fn clone(&self) -> Self {
// Event {
// text: self.text.clone(),
// begin: self.begin,
// end: self.end,
// }
// }
//}
//
impl Event {
pub fn is_in_day(&self, day: NaiveDate) -> bool {
day >= self.begin && day <= self.end
@ -49,36 +39,14 @@ impl EventsCollection {
pub fn new() -> Self {
EventsCollection {
// TODO: hard-coded events
events: vec![
Event {
text: String::from("pentecoste"),
begin: NaiveDate::from_ymd_opt(2023, 05, 30).unwrap(),
end: NaiveDate::from_ymd_opt(2023, 06, 09).unwrap(),
},
Event {
text: String::from("estate"),
begin: NaiveDate::from_ymd_opt(2023, 07, 31).unwrap(),
end: NaiveDate::from_ymd_opt(2023, 09, 11).unwrap(),
},
Event {
text: String::from("event one"),
begin: NaiveDate::from_ymd_opt(2023, 07, 31).unwrap(),
end: NaiveDate::from_ymd_opt(2023, 08, 03).unwrap(),
},
Event {
text: String::from("event two"),
begin: NaiveDate::from_ymd_opt(2023, 08, 02).unwrap(),
end: NaiveDate::from_ymd_opt(2023, 08, 04).unwrap(),
},
Event {
text: String::from("event three"),
begin: NaiveDate::from_ymd_opt(2023, 08, 05).unwrap(),
end: NaiveDate::from_ymd_opt(2023, 08, 06).unwrap(),
},
],
events: Vec::new(),
}
}
pub fn create(self: &mut Self, begin: NaiveDate, end: NaiveDate, text: &str) {
self.events.push(Event {text: text.to_string(), begin, end});
}
pub fn is_any_in_day(&self, day: NaiveDate) -> Option<Event> {
for ev_day in &self.events {
if ev_day.is_in_day(day) {

43
src/model/ical_bridge.rs Normal file
View File

@ -0,0 +1,43 @@
use icalendar;
use icalendar::{Component, DatePerhapsTime, CalendarDateTime, CalendarComponent};
use chrono::NaiveDate;
use crate::EventsCollection;
use std::fs;
fn cdt_as_date(cdt: &CalendarDateTime) -> NaiveDate {
match cdt {
CalendarDateTime::Floating(ndt) => ndt.date(),
CalendarDateTime::Utc(ud) => ud.naive_local().date(),
CalendarDateTime::WithTimezone{date_time, tzid: _} => date_time.date(),
}
}
fn as_date(cal_date: &DatePerhapsTime) -> NaiveDate {
match cal_date {
DatePerhapsTime::DateTime(cdt) => cdt_as_date(cdt),
DatePerhapsTime::Date(nd) => nd.clone()
}
}
fn create_event(events: &mut EventsCollection, event: &icalendar::Event) {
events.create(as_date(&event.get_start().unwrap()), as_date(&event.get_end().unwrap()).pred_opt().unwrap(), event.get_summary().unwrap());
}
pub fn load_calendar(calendar_path: &std::path::Path, events: &mut EventsCollection) {
let mut calendar = icalendar::Calendar::new();
let contents = fs::read_to_string(calendar_path)
.expect("Could not read the calendar");
let res = icalendar::parser::read_calendar(&contents);
match res {
Ok(parsed_calendar) => { calendar.extend(parsed_calendar.components); }
Err(e) => println!("{}", e)
}
for cc in calendar.iter() {
match cc {
CalendarComponent::Event(event) => create_event(events, event),
_ => (),
}
}
}

View File

@ -46,14 +46,6 @@ impl CellGrid {
}
}
pub fn num_rows(&self) -> u32 {
return self.num_y;
}
pub fn num_cols(&self) -> u32 {
return self.num_x;
}
pub fn rows(&self) -> Self {
CellGrid::new(self.x, self.y, self.width, self.height, 1, self.num_y)
}

View File

@ -10,7 +10,7 @@
use iced::advanced::{layout, renderer};
use iced::advanced::widget::{Tree, Widget};
use iced::{Color, Element, Length, Point, Rectangle, alignment};
use iced::{Color, Element, Length, Rectangle, alignment};
use iced::advanced::text::{self, Text, LineHeight, Shaping};
use chrono::{NaiveDate, Datelike, Duration, Local, Months};
use super::basics::CellGrid;
@ -111,7 +111,7 @@ fn render_events_in_row(
LineHeight::default(),
renderer.default_font(),
row_bounds.size(),
Shaping::default()).1;
Shaping::default()).height;
let last_day = first_day + Duration::days(num_days - 1);
let all_events = events.within(first_day, last_day);
@ -136,7 +136,8 @@ fn render_events_in_row(
// start of event
ev_bar.bounds.x = cell.x;
ev_bar.bounds.y = ev_y;
} else if ev_bar.ev.end == current_day {
}
if ev_bar.ev.end == current_day {
// end of event -> set width
ev_bar.bounds.width = cell.x + cell.width - ev_bar.bounds.x;
}