diff options
Diffstat (limited to 'src/gui/generate.rs')
| -rw-r--r-- | src/gui/generate.rs | 154 |
1 files changed, 147 insertions, 7 deletions
diff --git a/src/gui/generate.rs b/src/gui/generate.rs index 9fe9e3f..a7eb9e5 100644 --- a/src/gui/generate.rs +++ b/src/gui/generate.rs @@ -1,6 +1,13 @@ use gtk::prelude::*; +use gtk::glib; use super::state::{View, ViewManager}; +use std::sync::Arc; +use std::sync::Mutex; use std::rc::Rc; +use std::thread; + +use crate::index::Index; +use crate::index::GenState; pub struct Generate { vm : Rc<ViewManager> @@ -15,16 +22,149 @@ impl View for Generate { self.vm = vm } - fn make_current(&self) -> gtk::Box { - let center = gtk::Box::new(gtk::Orientation::Vertical, 10); - let main = gtk::Box::new(gtk::Orientation::Horizontal, 10); - let label = gtk::Label::new(Some("Generate")); + fn make_current(&self) -> Option<gtk::Box> { + let target_dir = Arc::new(Mutex::new(String::new())); + let index_file = Arc::new(Mutex::new(String::new())); + let (index_tx, index_rx) = std::sync::mpsc::channel(); + let load_next = Rc::new(Mutex::new(false)); + + let splash = gtk::Window::new(gtk::WindowType::Popup); + splash.set_type_hint(gtk::gdk::WindowTypeHint::Splashscreen); + splash.set_decorated(false); + splash.set_position(gtk::WindowPosition::Center); + splash.set_resizable(false); + splash.set_size_request(600, 200); + + let main = gtk::Box::new(gtk::Orientation::Vertical, 10); + main.set_widget_name("generate"); + let title = gtk::Label::new(Some("Generate Index")); + title.set_widget_name("title"); + + let step = gtk::Label::new(Some("Choose A Target Directory")); + step.set_halign(gtk::Align::Start); + let btn = gtk::Button::with_label("Choose"); + btn.set_sensitive(false); + let header = gtk::Box::new(gtk::Orientation::Horizontal, 0); + + let pick = gtk::FileChooserWidget::builder() + .create_folders(false) + .action(gtk::FileChooserAction::SelectFolder) + .build(); + + header.pack_start(&step, true, true, 10); + header.pack_start(&btn, false, false, 10); + + main.pack_start(&title, false, false, 0); + main.pack_start(&header, false, false, 0); + main.pack_start(&pick, true, true, 0); + + splash.add(&main); + + pick.connect_selection_changed(glib::clone!(@weak btn => move |pick| { + if pick.file().is_some() || pick.current_name().is_some() { + btn.set_sensitive(true); + } else { + btn.set_sensitive(false); + } + })); + + { + let target_dir = Arc::clone(&target_dir); + let index_file = Arc::clone(&index_file); + let load_next = Rc::clone(&load_next); + btn.connect_clicked(glib::clone!( + @weak splash, + @weak header, + @weak step, + @weak pick, + @weak main => move |btn| { + let td = { target_dir.lock().unwrap().clone() }; + + if td.is_empty() { + let uri = pick.uri().unwrap(); + let path = uri.as_str().trim_start_matches("file://"); + let mut target_dir = target_dir.lock().unwrap(); + *target_dir = path.to_string(); + step.set_text("Create A Index File"); + btn.set_label("Create"); + pick.set_action(gtk::FileChooserAction::Save); + } else { + let mut path = pick.current_folder().unwrap().to_str().unwrap().to_string(); + path += "/"; + path += pick.current_name().unwrap().to_string().as_str(); + *index_file.lock().unwrap() = path; + + main.remove(&header); + main.remove(&pick); + + let progress = gtk::ProgressBar::builder() + .ellipsize(gtk::pango::EllipsizeMode::Middle) + .show_text(true) + .text("Generating") + .build(); + + progress.set_margin(20); + main.pack_start(&progress, true, false, 0); + + let (tx, rx) = glib::MainContext::channel(glib::Priority::default()); + { + let target_dir = Arc::clone(&target_dir); + let index_file = Arc::clone(&index_file); + let index_tx = index_tx.clone(); + thread::spawn(move || { + let path = target_dir.lock().unwrap().to_string(); + let idx = Index::generate(path.as_str(), |s, p| { + let text = match s { + GenState::Fetching => { "Fetching" } + GenState::Parsing => { "Parsing" } + GenState::Merging => { "Merging" } + }; + tx.send(Some((text, p))).ok(); + }); + tx.send(Some(("Saving", 100))).ok(); + idx.save(index_file.lock().unwrap().to_string()); + tx.send(None).ok(); + index_tx.send(idx) + }); + } + + let load_next = Rc::clone(&load_next); + rx.attach(None, glib::clone!( + @weak splash, + @weak progress, + @weak main => @default-return glib::Continue(false), move |value| match value { + Some((s, p)) => { + progress.pulse(); + progress.set_fraction(f64::from(p) / 100.0); + progress.set_text(Some(s)); + glib::Continue(true) + } + None => { + splash.close(); + *load_next.lock().unwrap() = true; + glib::Continue(false) + } + })); + + main.show_all(); + } + })); + } - main.pack_start(&label, false, false, 0); + let vm = Rc::clone(&self.vm); + splash.connect_hide(move |_| { + if *load_next.lock().unwrap() { + let idx = index_rx.recv().unwrap(); + vm.set_index(idx); + vm.set_current_view("search"); + } else if vm.get_current_view() == "generate" { + vm.set_current_view("welcome") + } + }); - center.pack_start(&main, true, false, 0); + splash.show_all(); - center + None } } |