use std::fs::File; use std::path::PathBuf; use std::sync::{Arc, Mutex}; use std::thread; use crate::file_tab::FileTab; use crate::line_index::LineIndex; pub struct IndexingState { pub indexing: Arc>, pub progress: Arc>, } impl IndexingState { pub fn new() -> Self { Self { indexing: Arc::new(Mutex::new(false)), progress: Arc::new(Mutex::new(0.0)), } } pub fn is_indexing(&self) -> bool { *self.indexing.lock().unwrap() } fn start_indexing(&self) { *self.indexing.lock().unwrap() = true; *self.progress.lock().unwrap() = 0.0; } fn finish_indexing(&self) { *self.indexing.lock().unwrap() = false; } } pub fn open_file_dialog(indexing_state: &IndexingState) -> Option { let path = rfd::FileDialog::new() .add_filter("Log Files", &["log", "txt"]) .add_filter("All Files", &["*"]) .pick_file()?; open_file(path, indexing_state) } fn open_file(path: PathBuf, indexing_state: &IndexingState) -> Option { indexing_state.start_indexing(); // Background indexing for progress indication let indexing = Arc::clone(&indexing_state.indexing); let progress = Arc::clone(&indexing_state.progress); let path_clone = path.clone(); thread::spawn(move || { if let Ok(_index) = LineIndex::build(&path_clone) { *progress.lock().unwrap() = 1.0; } *indexing.lock().unwrap() = false; }); // Build index and create tab let index = LineIndex::build(&path).ok()?; let file = File::open(&path).ok()?; let tab = FileTab::new(path, index, file); indexing_state.finish_indexing(); Some(tab) } pub fn close_tab(tabs: &mut Vec, active_index: &mut usize, index: usize) { if index < tabs.len() { tabs.remove(index); if *active_index >= tabs.len() && !tabs.is_empty() { *active_index = tabs.len() - 1; } } }