use termion::event::Key;
use std::io::Write;
use std::sync::{Arc, Mutex};
use std::path::PathBuf;
use std::ffi::OsString;
use crate::files::{File, Files, PathBufExt};
use crate::fscache::FsCache;
use crate::listview::ListView;
use crate::hbox::HBox;
use crate::widget::Widget;
use crate::tabview::{TabView, Tabbable};
use crate::preview::{Previewer, AsyncWidget};
use crate::fail::{HResult, HError, ErrorLog};
use crate::widget::{Events, WidgetCore};
use crate::proclist::ProcView;
use crate::bookmarks::BMPopup;
use crate::term;
use crate::term::ScreenExt;
use crate::foldview::LogView;
use crate::coordinates::Coordinates;
#[derive(PartialEq)]
pub enum FileBrowserWidgets {
FileList(AsyncWidget<ListView<Files>>),
Previewer(Previewer),
}
impl Widget for FileBrowserWidgets {
fn get_core(&self) -> HResult<&WidgetCore> {
match self {
FileBrowserWidgets::FileList(widget) => widget.get_core(),
FileBrowserWidgets::Previewer(widget) => widget.get_core()
}
}
fn get_core_mut(&mut self) -> HResult<&mut WidgetCore> {
match self {
FileBrowserWidgets::FileList(widget) => widget.get_core_mut(),
FileBrowserWidgets::Previewer(widget) => widget.get_core_mut()
}
}
fn set_coordinates(&mut self, coordinates: &Coordinates) -> HResult<()> {
match self {
FileBrowserWidgets::FileList(widget) => widget.set_coordinates(coordinates),
FileBrowserWidgets::Previewer(widget) => widget.set_coordinates(coordinates),
}
}
fn refresh(&mut self) -> HResult<()> {
match self {
FileBrowserWidgets::FileList(widget) => widget.refresh(),
FileBrowserWidgets::Previewer(widget) => widget.refresh()
}
}
fn get_drawlist(&self) -> HResult<String> {
match self {
FileBrowserWidgets::FileList(widget) => widget.get_drawlist(),
FileBrowserWidgets::Previewer(widget) => widget.get_drawlist()
}
}
}
pub struct FileBrowser {
pub columns: HBox<FileBrowserWidgets>,
pub cwd: File,
pub prev_cwd: Option<File>,
core: WidgetCore,
proc_view: Arc<Mutex<ProcView>>,
bookmarks: Arc<Mutex<BMPopup>>,
log_view: Arc<Mutex<LogView>>,
fs_cache: FsCache,
}
impl Tabbable for TabView<FileBrowser> {
fn new_tab(&mut self) -> HResult<()> {
let cur_tab = self.active_tab_();
let settings = cur_tab.fs_cache.tab_settings.read()?.clone();
let cache = cur_tab.fs_cache.new_client(settings).ok();
let mut tab = FileBrowser::new(&self.active_tab_().core, cache)?;
let proc_view = cur_tab.proc_view.clone();
let bookmarks = cur_tab.bookmarks.clone();
let log_view = cur_tab.log_view.clone();
tab.proc_view = proc_view;
tab.bookmarks = bookmarks;
tab.log_view = log_view;
self.push_widget(tab)?;
self.active = self.widgets.len() - 1;
Ok(())
}
fn close_tab(&mut self) -> HResult<()> {
self.close_tab_().log();
Ok(())
}
fn next_tab(&mut self) -> HResult<()> {
self.next_tab_();
Ok(())
}
fn goto_tab(&mut self, index: usize) -> HResult<()> {
self.goto_tab_(index)
}
fn get_tab_names(&self) -> Vec<Option<String>> {
self.widgets.iter().map(|filebrowser| {
let path = filebrowser.cwd.path();
let last_dir = path.components().last().unwrap();
let dir_name = last_dir.as_os_str().to_string_lossy().to_string();
Some(dir_name)
}).collect()
}
fn active_tab(& self) -> & dyn Widget {
self.active_tab_()
}
fn active_tab_mut(&mut self) -> &mut dyn Widget {
self.active_tab_mut_()
}
fn on_tab_switch(&mut self) -> HResult<()> {
self.active_tab_mut().refresh()
}
fn on_key_sub(&mut self, key: Key) -> HResult<()> {
match key {
Key::Char('!') => {
let tab_dirs = self.widgets.iter().map(|w| w.cwd.clone())
.collect::<Vec