Skip to content

Commit

Permalink
Hook configuration changes up to configuration and save them to back …
Browse files Browse the repository at this point in the history
…to the file
  • Loading branch information
savannidgerinel committed Jan 10, 2020
1 parent b92d634 commit a4cc7f6
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 37 deletions.
40 changes: 40 additions & 0 deletions gtk/src/components/basics.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use gtk::prelude::*;

use crate::components::validated_text_entry::ValidatedTextEntry;
use crate::conversions::{
parse_distance, parse_duration, parse_hours_minutes, render_distance, render_duration,
Expand Down Expand Up @@ -55,3 +57,41 @@ pub fn duration_edit_c(
on_update,
)
}

pub fn setting_with_label_c<A: IsA<gtk::Widget>>(label: &str, selector: A) -> gtk::Box {
let widget = gtk::Box::new(gtk::Orientation::Horizontal, 5);
widget.pack_start(&gtk::Label::new(Some(label)), false, false, 5);
widget.pack_start(&selector, false, false, 5);

widget
}

pub fn entry_setting_c(label: &str, current: &str, on_changed: Box<dyn Fn(&str)>) -> gtk::Box {
let entry = gtk::Entry::new();
entry.set_text(current);
entry.connect_changed(move |v| match v.get_text() {
Some(ref s) => on_changed(s),
None => (),
});

setting_with_label_c(label, entry)
}

pub fn pulldown_setting_c(
label: &str,
options: Vec<(&str, &str)>,
current: &str,
on_changed: Box<dyn Fn(&str)>,
) -> gtk::Box {
let combo = gtk::ComboBoxText::new();
for (id, option) in options.iter() {
combo.append(Some(id), option);
}
combo.set_active_id(Some(current));
combo.connect_changed(move |s| match s.get_active_id() {
Some(val) => on_changed(val.as_str()),
None => (),
});

setting_with_label_c(label, combo)
}
3 changes: 3 additions & 0 deletions gtk/src/components/main_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ impl MainWindow {
pub fn update_from(&mut self, message: Message) {
match message {
Message::ChangeRange { range, records } => self.history.update_from(range, records),
Message::ChangeLanguage(_) => (),
Message::ChangeTimezone(_) => (),
Message::ChangeUnits(_) => (),
Message::RecordsUpdated { range, records } => self.history.update_from(range, records),
}
}
Expand Down
1 change: 1 addition & 0 deletions gtk/src/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mod time_distance_row;
mod validated_text_entry;
mod weight;

pub use basics::*;
pub use date_selector::DateSelector;
pub use day::Day;
pub use history::History;
Expand Down
90 changes: 60 additions & 30 deletions gtk/src/components/preferences.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use gtk::prelude::*;
use std::sync::{Arc, RwLock};

use crate::components::setting_c;
use crate::components::{entry_setting_c, pulldown_setting_c};
use crate::context::AppContext;

pub struct Preferences {
Expand All @@ -10,37 +10,67 @@ pub struct Preferences {

impl Preferences {
pub fn new(ctx: Arc<RwLock<AppContext>>) -> Preferences {
let config = ctx.read().unwrap().get_configuration();
let ctx_ = ctx.read().unwrap();
let widget = gtk::Box::new(gtk::Orientation::Vertical, 5);

widget.pack_start(
&setting_c(
"Language",
vec![("en", "English"), ("eo", "Esperanto")],
config.language.as_str(),
),
false,
false,
50,
);

widget.pack_start(
&setting_c("Timezone", tz_list(), config.timezone.name()),
false,
false,
50,
);

widget.pack_start(
&setting_c(
"Units",
vec![("SI", "SI (kg, km, m/s)"), ("USA", "USA (lbs, mi, mph)")],
config.units.as_str(),
),
false,
false,
50,
);
{
let ctx = ctx.clone();
widget.pack_start(
&entry_setting_c(
"Database path",
ctx_.get_series_path(),
Box::new(move |s| ctx.write().unwrap().set_series_path(s)),
),
false,
false,
5,
);
}

{
let ctx = ctx.clone();
widget.pack_start(
&pulldown_setting_c(
"Language",
vec![("en", "English"), ("eo", "Esperanto")],
ctx_.get_language(),
Box::new(move |s| ctx.write().unwrap().set_language(s)),
),
false,
false,
5,
);
}

{
let ctx = ctx.clone();
widget.pack_start(
&pulldown_setting_c(
"Timezone",
tz_list(),
ctx_.get_timezone().name(),
Box::new(move |s| ctx.write().unwrap().set_timezone(s.parse().unwrap())),
),
false,
false,
5,
);
}

{
let ctx = ctx.clone();
widget.pack_start(
&pulldown_setting_c(
"Units",
vec![("SI", "SI (kg, km, m/s)"), ("USA", "USA (lbs, mi, mph)")],
ctx_.get_units(),
Box::new(move |s| ctx.write().unwrap().set_units(s)),
),
false,
false,
5,
);
}

let w = Preferences { widget };

Expand Down
11 changes: 10 additions & 1 deletion gtk/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use serde::{Deserialize, Serialize};
use std::env;
use std::fs::File;
use std::io::Write;
use std::path;

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Configuration {
pub series_path: path::PathBuf,
pub timezone: chrono_tz::Tz,
pub language: String,
pub timezone: chrono_tz::Tz,
pub units: String,
}

Expand All @@ -18,4 +19,12 @@ impl Configuration {
.expect(&format!("cannot open configuration file: {}", &config_path));
serde_yaml::from_reader(config_file).expect("invalid configuration file")
}

pub fn save_to_yaml(&self) {
let config_path = env::var("CONFIG").unwrap_or("config.yaml".to_string());
let s = serde_yaml::to_string(&self).unwrap();
let mut config_file = File::create(config_path.clone())
.expect(&format!("cannot open configuration file: {}", &config_path));
let _ = config_file.write(s.as_bytes());
}
}
44 changes: 38 additions & 6 deletions gtk/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use chrono::Utc;
use chrono_tz;
use glib::Sender;
use std::path::PathBuf;

use super::config::Configuration;
use super::errors::Result;
Expand All @@ -16,8 +17,9 @@ pub enum Message {
range: DateRange,
records: Vec<Record<TraxRecord>>,
},
//ChangeLanguage,
//ChangeTimezone(chrono_tz::Tz),
ChangeLanguage(String),
ChangeTimezone(chrono_tz::Tz),
ChangeUnits(String),
RecordsUpdated {
range: DateRange,
records: Vec<Record<TraxRecord>>,
Expand Down Expand Up @@ -52,16 +54,46 @@ impl AppContext {
})
}

pub fn get_series_path(&self) -> &str {
self.config.series_path.to_str().unwrap()
}

pub fn set_series_path(&mut self, path: &str) {
self.config.series_path = PathBuf::from(path);
}

pub fn get_language(&self) -> &str {
&self.config.language
}

pub fn set_language(&mut self, language: &str) {
self.config.language = String::from(language);
self.config.save_to_yaml();
self.send_notifications(Message::ChangeLanguage(self.config.language.clone()));
}

pub fn get_timezone(&self) -> chrono_tz::Tz {
self.config.timezone
}

pub fn get_range(&self) -> DateRange {
self.range.clone()
pub fn set_timezone(&mut self, timezone: chrono_tz::Tz) {
self.config.timezone = timezone;
self.config.save_to_yaml();
self.send_notifications(Message::ChangeTimezone(self.config.timezone.clone()));
}

pub fn get_units(&self) -> &str {
&self.config.units
}

pub fn get_configuration(&self) -> Configuration {
self.config.clone()
pub fn set_units(&mut self, units: &str) {
self.config.units = String::from(units);
self.config.save_to_yaml();
self.send_notifications(Message::ChangeUnits(self.config.units.clone()));
}

pub fn get_range(&self) -> DateRange {
self.range.clone()
}

pub fn get_history(&self) -> Result<Vec<Record<TraxRecord>>> {
Expand Down

0 comments on commit a4cc7f6

Please sign in to comment.