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:
parent
1a08bfbcdc
commit
ab28f9227e
705
Cargo.lock
generated
705
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -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" }
|
||||
|
34
src/main.rs
34
src/main.rs
@ -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 {
|
||||
|
@ -1 +1,2 @@
|
||||
pub mod events;
|
||||
pub mod events;
|
||||
pub mod ical_bridge;
|
@ -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
43
src/model/ical_bridge.rs
Normal 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),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user