diff --git a/src/ui/activities/filetransfer_activity/actions.rs b/src/ui/activities/filetransfer_activity/actions.rs index 976f36e..64ad5e0 100644 --- a/src/ui/activities/filetransfer_activity/actions.rs +++ b/src/ui/activities/filetransfer_activity/actions.rs @@ -26,7 +26,7 @@ * SOFTWARE. */ // locals -use super::{FileExplorerTab, FileTransferActivity, FsEntry, LogLevel}; +use super::{browser::FileExplorerTab, FileTransferActivity, FsEntry, LogLevel}; use tuirealm::{Payload, Value}; // externals use std::path::PathBuf; @@ -130,7 +130,7 @@ impl FileTransferActivity { /// /// Go to previous directory from localhost pub(super) fn action_go_to_previous_local_dir(&mut self, block_sync: bool) { - if let Some(d) = self.local.popd() { + if let Some(d) = self.local_mut().popd() { self.local_changedir(d.as_path(), false); // Check whether to sync if self.browser.sync_browsing && !block_sync { @@ -143,7 +143,7 @@ impl FileTransferActivity { /// /// Go to previous directory from remote host pub(super) fn action_go_to_previous_remote_dir(&mut self, block_sync: bool) { - if let Some(d) = self.remote.popd() { + if let Some(d) = self.remote_mut().popd() { self.remote_changedir(d.as_path(), false); // Check whether to sync if self.browser.sync_browsing && !block_sync { @@ -157,7 +157,7 @@ impl FileTransferActivity { /// Go to upper directory on local host pub(super) fn action_go_to_local_upper_dir(&mut self, block_sync: bool) { // Get pwd - let path: PathBuf = self.local.wrkdir.clone(); + let path: PathBuf = self.local().wrkdir.clone(); // Go to parent directory if let Some(parent) = path.as_path().parent() { self.local_changedir(parent, true); @@ -173,7 +173,7 @@ impl FileTransferActivity { /// Go to upper directory on remote host pub(super) fn action_go_to_remote_upper_dir(&mut self, block_sync: bool) { // Get pwd - let path: PathBuf = self.remote.wrkdir.clone(); + let path: PathBuf = self.remote().wrkdir.clone(); // Go to parent directory if let Some(parent) = path.as_path().parent() { self.remote_changedir(parent, true); @@ -190,7 +190,7 @@ impl FileTransferActivity { pub(super) fn action_local_copy(&mut self, input: String) { if let Some(idx) = self.get_local_file_idx() { let dest_path: PathBuf = PathBuf::from(input); - let entry: FsEntry = self.local.get(idx).unwrap().clone(); + let entry: FsEntry = self.local().get(idx).unwrap().clone(); match self.host.copy(&entry, dest_path.as_path()) { Ok(_) => { self.log( @@ -202,7 +202,7 @@ impl FileTransferActivity { ), ); // Reload entries - let wrkdir: PathBuf = self.local.wrkdir.clone(); + let wrkdir: PathBuf = self.local().wrkdir.clone(); self.local_scan(wrkdir.as_path()); } Err(err) => self.log_and_alert( @@ -224,7 +224,7 @@ impl FileTransferActivity { pub(super) fn action_remote_copy(&mut self, input: String) { if let Some(idx) = self.get_remote_file_idx() { let dest_path: PathBuf = PathBuf::from(input); - let entry: FsEntry = self.remote.get(idx).unwrap().clone(); + let entry: FsEntry = self.remote().get(idx).unwrap().clone(); match self.client.as_mut().copy(&entry, dest_path.as_path()) { Ok(_) => { self.log( @@ -255,7 +255,7 @@ impl FileTransferActivity { Ok(_) => { // Reload files self.log(LogLevel::Info, format!("Created directory \"{}\"", input)); - let wrkdir: PathBuf = self.local.wrkdir.clone(); + let wrkdir: PathBuf = self.local().wrkdir.clone(); self.local_scan(wrkdir.as_path()); } Err(err) => { @@ -294,7 +294,7 @@ impl FileTransferActivity { let mut dst_path: PathBuf = PathBuf::from(input); // Check if path is relative if dst_path.as_path().is_relative() { - let mut wrkdir: PathBuf = self.local.wrkdir.clone(); + let mut wrkdir: PathBuf = self.local().wrkdir.clone(); wrkdir.push(dst_path); dst_path = wrkdir; } @@ -303,7 +303,7 @@ impl FileTransferActivity { match self.host.rename(&entry, dst_path.as_path()) { Ok(_) => { // Reload files - let path: PathBuf = self.local.wrkdir.clone(); + let path: PathBuf = self.local().wrkdir.clone(); self.local_scan(path.as_path()); // Log self.log( @@ -327,14 +327,18 @@ impl FileTransferActivity { pub(super) fn action_remote_rename(&mut self, input: String) { if let Some(idx) = self.get_remote_file_idx() { - if let Some(entry) = self.remote.get(idx) { + let entry = match self.remote().get(idx) { + None => None, + Some(e) => Some(e.clone()), + }; + if let Some(entry) = entry { let dst_path: PathBuf = PathBuf::from(input); let full_path: PathBuf = entry.get_abs_path(); // Rename file or directory and report status as popup - match self.client.as_mut().rename(entry, dst_path.as_path()) { + match self.client.as_mut().rename(&entry, dst_path.as_path()) { Ok(_) => { // Reload files - let path: PathBuf = self.remote.wrkdir.clone(); + let path: PathBuf = self.remote().wrkdir.clone(); self.remote_scan(path.as_path()); // Log self.log( @@ -365,7 +369,7 @@ impl FileTransferActivity { match self.host.remove(&entry) { Ok(_) => { // Reload files - let p: PathBuf = self.local.wrkdir.clone(); + let p: PathBuf = self.local().wrkdir.clone(); self.local_scan(p.as_path()); // Log self.log( @@ -386,10 +390,14 @@ impl FileTransferActivity { pub(super) fn action_remote_delete(&mut self) { if let Some(idx) = self.get_remote_file_idx() { // Check if file entry exists - if let Some(entry) = self.remote.get(idx) { + let entry = match self.remote().get(idx) { + None => None, + Some(e) => Some(e.clone()), + }; + if let Some(entry) = entry { let full_path: PathBuf = entry.get_abs_path(); // Delete file - match self.client.remove(entry) { + match self.client.remove(&entry) { Ok(_) => { self.reload_remote_dir(); self.log( @@ -411,9 +419,9 @@ impl FileTransferActivity { pub(super) fn action_local_saveas(&mut self, input: String) { if let Some(idx) = self.get_local_file_idx() { // Get pwd - let wrkdir: PathBuf = self.remote.wrkdir.clone(); - if self.local.get(idx).is_some() { - let file: FsEntry = self.local.get(idx).unwrap().clone(); + let wrkdir: PathBuf = self.remote().wrkdir.clone(); + if self.local().get(idx).is_some() { + let file: FsEntry = self.local().get(idx).unwrap().clone(); // Call upload; pass realfile, keep link name self.filetransfer_send(&file.get_realfile(), wrkdir.as_path(), Some(input)); } @@ -423,9 +431,9 @@ impl FileTransferActivity { pub(super) fn action_remote_saveas(&mut self, input: String) { if let Some(idx) = self.get_remote_file_idx() { // Get pwd - let wrkdir: PathBuf = self.local.wrkdir.clone(); - if self.remote.get(idx).is_some() { - let file: FsEntry = self.remote.get(idx).unwrap().clone(); + let wrkdir: PathBuf = self.local().wrkdir.clone(); + if self.remote().get(idx).is_some() { + let file: FsEntry = self.remote().get(idx).unwrap().clone(); // Call upload; pass realfile, keep link name self.filetransfer_recv(&file.get_realfile(), wrkdir.as_path(), Some(input)); } @@ -435,7 +443,7 @@ impl FileTransferActivity { pub(super) fn action_local_newfile(&mut self, input: String) { // Check if file exists let mut file_exists: bool = false; - for file in self.local.iter_files_all() { + for file in self.local().iter_files_all() { if input == file.get_name() { file_exists = true; } @@ -461,14 +469,14 @@ impl FileTransferActivity { ); } // Reload files - let path: PathBuf = self.local.wrkdir.clone(); + let path: PathBuf = self.local().wrkdir.clone(); self.local_scan(path.as_path()); } pub(super) fn action_remote_newfile(&mut self, input: String) { // Check if file exists let mut file_exists: bool = false; - for file in self.remote.iter_files_all() { + for file in self.remote().iter_files_all() { if input == file.get_name() { file_exists = true; } @@ -521,7 +529,7 @@ impl FileTransferActivity { ); } // Reload files - let path: PathBuf = self.remote.wrkdir.clone(); + let path: PathBuf = self.remote().wrkdir.clone(); self.remote_scan(path.as_path()); } } @@ -535,7 +543,7 @@ impl FileTransferActivity { Ok(output) => { // Reload files self.log(LogLevel::Info, format!("\"{}\": {}", input, output)); - let wrkdir: PathBuf = self.local.wrkdir.clone(); + let wrkdir: PathBuf = self.local().wrkdir.clone(); self.local_scan(wrkdir.as_path()); } Err(err) => { @@ -581,7 +589,7 @@ impl FileTransferActivity { pub(super) fn action_find_changedir(&mut self, idx: usize) { // Match entry - if let Some(entry) = self.found.as_ref().unwrap().get(idx) { + if let Some(entry) = self.found().as_ref().unwrap().get(idx) { // Get path: if a directory, use directory path; if it is a File, get parent path let path: PathBuf = match entry { FsEntry::Directory(dir) => dir.abs_path.clone(), @@ -591,7 +599,7 @@ impl FileTransferActivity { }, }; // Change directory - match self.tab { + match self.browser.tab() { FileExplorerTab::FindLocal | FileExplorerTab::Local => { self.local_changedir(path.as_path(), true) } @@ -603,16 +611,16 @@ impl FileTransferActivity { } pub(super) fn action_find_transfer(&mut self, idx: usize, name: Option) { - let entry: Option = self.found.as_ref().unwrap().get(idx).cloned(); + let entry: Option = self.found().as_ref().unwrap().get(idx).cloned(); if let Some(entry) = entry { // Download file - match self.tab { + match self.browser.tab() { FileExplorerTab::FindLocal | FileExplorerTab::Local => { - let wrkdir: PathBuf = self.remote.wrkdir.clone(); + let wrkdir: PathBuf = self.remote().wrkdir.clone(); self.filetransfer_send(&entry.get_realfile(), wrkdir.as_path(), name); } FileExplorerTab::FindRemote | FileExplorerTab::Remote => { - let wrkdir: PathBuf = self.local.wrkdir.clone(); + let wrkdir: PathBuf = self.local().wrkdir.clone(); self.filetransfer_recv(&entry.get_realfile(), wrkdir.as_path(), name); } } @@ -620,17 +628,17 @@ impl FileTransferActivity { } pub(super) fn action_find_delete(&mut self, idx: usize) { - let entry: Option = self.found.as_ref().unwrap().get(idx).cloned(); + let entry: Option = self.found().as_ref().unwrap().get(idx).cloned(); if let Some(entry) = entry { // Download file - match self.tab { + match self.browser.tab() { FileExplorerTab::FindLocal | FileExplorerTab::Local => { let full_path: PathBuf = entry.get_abs_path(); // Delete file or directory and report status as popup match self.host.remove(&entry) { Ok(_) => { // Reload files - let p: PathBuf = self.local.wrkdir.clone(); + let p: PathBuf = self.local().wrkdir.clone(); self.local_scan(p.as_path()); // Log self.log( @@ -690,7 +698,7 @@ impl FileTransferActivity { match self.edit_local_file(fsentry.get_abs_path().as_path()) { Ok(_) => { // Reload directory - let pwd: PathBuf = self.local.wrkdir.clone(); + let pwd: PathBuf = self.local().wrkdir.clone(); self.local_scan(pwd.as_path()); } Err(err) => self.log_and_alert(LogLevel::Error, err), @@ -712,7 +720,7 @@ impl FileTransferActivity { match self.edit_remote_file(&file) { Ok(_) => { // Reload directory - let pwd: PathBuf = self.remote.wrkdir.clone(); + let pwd: PathBuf = self.remote().wrkdir.clone(); self.remote_scan(pwd.as_path()); } Err(err) => self.log_and_alert(LogLevel::Error, err), @@ -727,7 +735,7 @@ impl FileTransferActivity { pub(super) fn get_local_file_entry(&self) -> Option<&FsEntry> { match self.get_local_file_idx() { None => None, - Some(idx) => self.local.get(idx), + Some(idx) => self.local().get(idx), } } @@ -737,7 +745,7 @@ impl FileTransferActivity { pub(super) fn get_remote_file_entry(&self) -> Option<&FsEntry> { match self.get_remote_file_idx() { None => None, - Some(idx) => self.remote.get(idx), + Some(idx) => self.remote().get(idx), } } diff --git a/src/ui/activities/filetransfer_activity/browser.rs b/src/ui/activities/filetransfer_activity/browser.rs new file mode 100644 index 0000000..df64876 --- /dev/null +++ b/src/ui/activities/filetransfer_activity/browser.rs @@ -0,0 +1,177 @@ +//! ## FileTransferActivity +//! +//! `filetransfer_activiy` is the module which implements the Filetransfer activity, which is the main activity afterall + +/** + * MIT License + * + * termscp - Copyright (c) 2021 Christian Visintin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +use crate::fs::explorer::{builder::FileExplorerBuilder, FileExplorer, FileSorting, GroupDirs}; +use crate::fs::FsEntry; +use crate::system::config_client::ConfigClient; + +/// ## FileExplorerTab +/// +/// File explorer tab +#[derive(Clone, Copy)] +pub(super) enum FileExplorerTab { + Local, + Remote, + FindLocal, // Find result tab + FindRemote, // Find result tab +} + +/// ## Browser +/// +/// Browser contains the browser options +pub(super) struct Browser { + local: FileExplorer, // Local File explorer state + remote: FileExplorer, // Remote File explorer state + found: Option, // File explorer for find result + tab: FileExplorerTab, // Current selected tab + pub sync_browsing: bool, +} + +impl Browser { + /// ### new + /// + /// Build a new `Browser` struct + pub(super) fn new(cli: Option<&ConfigClient>) -> Self { + Self { + local: Self::build_local_explorer(cli), + remote: Self::build_remote_explorer(cli), + found: None, + tab: FileExplorerTab::Local, + sync_browsing: false, + } + } + + pub fn local(&self) -> &FileExplorer { + &self.local + } + + pub fn local_mut(&mut self) -> &mut FileExplorer { + &mut self.local + } + + pub fn remote(&self) -> &FileExplorer { + &self.remote + } + + pub fn remote_mut(&mut self) -> &mut FileExplorer { + &mut self.remote + } + + pub fn found(&self) -> Option<&FileExplorer> { + self.found.as_ref() + } + + pub fn found_mut(&mut self) -> Option<&mut FileExplorer> { + self.found.as_mut() + } + + pub fn set_found(&mut self, files: Vec) { + let mut explorer = Self::build_found_explorer(); + explorer.set_files(files); + self.found = Some(explorer); + } + + pub fn del_found(&mut self) { + self.found = None; + } + + pub(super) fn tab(&self) -> FileExplorerTab { + self.tab + } + + /// ### change_tab + /// + /// Update tab value + pub(super) fn change_tab(&mut self, tab: FileExplorerTab) { + self.tab = tab; + } + + /// ### toggle_sync_browsing + /// + /// Invert the current state for the sync browsing + pub fn toggle_sync_browsing(&mut self) { + self.sync_browsing = !self.sync_browsing; + } + + /// ### build_local_explorer + /// + /// Build a file explorer with local host setup + pub fn build_local_explorer(cli: Option<&ConfigClient>) -> FileExplorer { + let mut builder = Self::build_explorer(cli); + if let Some(cli) = cli { + builder.with_formatter(cli.get_local_file_fmt().as_deref()); + } + builder.build() + } + + /// ### build_remote_explorer + /// + /// Build a file explorer with remote host setup + pub fn build_remote_explorer(cli: Option<&ConfigClient>) -> FileExplorer { + let mut builder = Self::build_explorer(cli); + if let Some(cli) = cli { + builder.with_formatter(cli.get_remote_file_fmt().as_deref()); + } + builder.build() + } + + /// ### build_explorer + /// + /// Build explorer reading configuration from `ConfigClient` + fn build_explorer(cli: Option<&ConfigClient>) -> FileExplorerBuilder { + let mut builder: FileExplorerBuilder = FileExplorerBuilder::new(); + // Set common keys + builder + .with_file_sorting(FileSorting::ByName) + .with_stack_size(16); + match &cli { + Some(cli) => { + builder // Build according to current configuration + .with_group_dirs(cli.get_group_dirs()) + .with_hidden_files(cli.get_show_hidden_files()); + } + None => { + builder // Build default + .with_group_dirs(Some(GroupDirs::First)); + } + }; + builder + } + + /// ### build_found_explorer + /// + /// Build explorer reading from `ConfigClient`, for found result (has some differences) + fn build_found_explorer() -> FileExplorer { + FileExplorerBuilder::new() + .with_file_sorting(FileSorting::ByName) + .with_group_dirs(Some(GroupDirs::First)) + .with_hidden_files(true) + .with_stack_size(0) + .with_formatter(Some("{NAME} {SYMLINK}")) + .build() + } +} diff --git a/src/ui/activities/filetransfer_activity/misc.rs b/src/ui/activities/filetransfer_activity/misc.rs index 2925f8d..ec174ac 100644 --- a/src/ui/activities/filetransfer_activity/misc.rs +++ b/src/ui/activities/filetransfer_activity/misc.rs @@ -23,13 +23,14 @@ */ // Locals use super::{ConfigClient, FileTransferActivity, LogLevel, LogRecord}; -use crate::fs::explorer::{builder::FileExplorerBuilder, FileExplorer, FileSorting, GroupDirs}; use crate::system::environment; use crate::system::sshkey_storage::SshKeyStorage; // Ext use std::env; use std::path::{Path, PathBuf}; +const LOG_CAPACITY: usize = 256; + impl FileTransferActivity { /// ### log /// @@ -38,7 +39,7 @@ impl FileTransferActivity { // Create log record let record: LogRecord = LogRecord::new(level, msg); //Check if history overflows the size - if self.log_records.len() + 1 > self.log_size { + if self.log_records.len() + 1 > LOG_CAPACITY { self.log_records.pop_back(); // Start cleaning events from back } // Eventually push front the new record @@ -91,64 +92,6 @@ impl FileTransferActivity { } } - /// ### build_explorer - /// - /// Build explorer reading configuration from `ConfigClient` - fn build_explorer(cli: Option<&ConfigClient>) -> FileExplorerBuilder { - let mut builder: FileExplorerBuilder = FileExplorerBuilder::new(); - // Set common keys - builder - .with_file_sorting(FileSorting::ByName) - .with_stack_size(16); - match &cli { - Some(cli) => { - builder // Build according to current configuration - .with_group_dirs(cli.get_group_dirs()) - .with_hidden_files(cli.get_show_hidden_files()); - } - None => { - builder // Build default - .with_group_dirs(Some(GroupDirs::First)); - } - }; - builder - } - - /// ### build_local_explorer - /// - /// Build a file explorer with local host setup - pub(super) fn build_local_explorer(cli: Option<&ConfigClient>) -> FileExplorer { - let mut builder = Self::build_explorer(cli); - if let Some(cli) = cli { - builder.with_formatter(cli.get_local_file_fmt().as_deref()); - } - builder.build() - } - - /// ### build_remote_explorer - /// - /// Build a file explorer with remote host setup - pub(super) fn build_remote_explorer(cli: Option<&ConfigClient>) -> FileExplorer { - let mut builder = Self::build_explorer(cli); - if let Some(cli) = cli { - builder.with_formatter(cli.get_remote_file_fmt().as_deref()); - } - builder.build() - } - - /// ### build_found_explorer - /// - /// Build explorer reading from `ConfigClient`, for found result (has some differences) - pub(super) fn build_found_explorer() -> FileExplorer { - FileExplorerBuilder::new() - .with_file_sorting(FileSorting::ByName) - .with_group_dirs(Some(GroupDirs::First)) - .with_hidden_files(true) - .with_stack_size(0) - .with_formatter(Some("{NAME} {SYMLINK}")) - .build() - } - /// ### setup_text_editor /// /// Set text editor to use @@ -182,7 +125,7 @@ impl FileTransferActivity { pub(super) fn local_to_abs_path(&self, path: &Path) -> PathBuf { match path.is_relative() { true => { - let mut d: PathBuf = self.local.wrkdir.clone(); + let mut d: PathBuf = self.local().wrkdir.clone(); d.push(path); d } @@ -196,7 +139,7 @@ impl FileTransferActivity { pub(super) fn remote_to_abs_path(&self, path: &Path) -> PathBuf { match path.is_relative() { true => { - let mut wrkdir: PathBuf = self.remote.wrkdir.clone(); + let mut wrkdir: PathBuf = self.remote().wrkdir.clone(); wrkdir.push(path); wrkdir } diff --git a/src/ui/activities/filetransfer_activity/mod.rs b/src/ui/activities/filetransfer_activity/mod.rs index 2bb84f8..23c3632 100644 --- a/src/ui/activities/filetransfer_activity/mod.rs +++ b/src/ui/activities/filetransfer_activity/mod.rs @@ -27,6 +27,7 @@ */ // This module is split into files, cause it's just too big mod actions; +mod browser; mod misc; mod session; mod update; @@ -48,6 +49,7 @@ use crate::fs::explorer::FileExplorer; use crate::fs::FsEntry; use crate::host::Localhost; use crate::system::config_client::ConfigClient; +use browser::Browser; // Includes use chrono::{DateTime, Local}; @@ -87,16 +89,6 @@ const COMPONENT_RADIO_SORTING: &str = "RADIO_SORTING"; const COMPONENT_SPAN_STATUS_BAR: &str = "STATUS_BAR"; const COMPONENT_LIST_FILEINFO: &str = "LIST_FILEINFO"; -/// ## FileExplorerTab -/// -/// File explorer tab -enum FileExplorerTab { - Local, - Remote, - FindLocal, // Find result tab - FindRemote, // Find result tab -} - /// ## LogLevel /// /// Log level type @@ -203,30 +195,6 @@ impl Default for TransferStates { } } -/// ## Browser -/// -/// Browser contains the browser options -struct Browser { - pub sync_browsing: bool, -} - -impl Default for Browser { - fn default() -> Self { - Self { - sync_browsing: false, - } - } -} - -impl Browser { - /// ### toggle_sync_browsing - /// - /// Invert the current state for the sync browsing - pub fn toggle_sync_browsing(&mut self) { - self.sync_browsing = !self.sync_browsing; - } -} - /// ## FileTransferActivity /// /// FileTransferActivity is the data holder for the file transfer activity @@ -236,14 +204,9 @@ pub struct FileTransferActivity { view: View, // View host: Localhost, // Localhost client: Box, // File transfer client - local: FileExplorer, // Local File explorer state - remote: FileExplorer, // Remote File explorer state - found: Option, // File explorer for find result - tab: FileExplorerTab, // Current selected tab + browser: Browser, // Browser log_records: VecDeque, // Log records - log_size: usize, // Log records size (max) transfer: TransferStates, // Transfer states - browser: Browser, // Browser states } impl FileTransferActivity { @@ -267,16 +230,35 @@ impl FileTransferActivity { Self::make_ssh_storage(config_client.as_ref()), )), }, - local: Self::build_local_explorer(config_client.as_ref()), - remote: Self::build_remote_explorer(config_client.as_ref()), - found: None, - tab: FileExplorerTab::Local, + browser: Browser::new(config_client.as_ref()), log_records: VecDeque::with_capacity(256), // 256 events is enough I guess - log_size: 256, // Must match with capacity transfer: TransferStates::default(), - browser: Browser::default(), } } + + pub(crate) fn local(&self) -> &FileExplorer { + self.browser.local() + } + + pub(crate) fn local_mut(&mut self) -> &mut FileExplorer { + self.browser.local_mut() + } + + pub(crate) fn remote(&self) -> &FileExplorer { + self.browser.remote() + } + + pub(crate) fn remote_mut(&mut self) -> &mut FileExplorer { + self.browser.remote_mut() + } + + pub(crate) fn found(&self) -> Option<&FileExplorer> { + self.browser.found() + } + + pub(crate) fn found_mut(&mut self) -> Option<&mut FileExplorer> { + self.browser.found_mut() + } } /** @@ -301,7 +283,7 @@ impl Activity for FileTransferActivity { let pwd: PathBuf = self.host.pwd(); // Get files at current wd self.local_scan(pwd.as_path()); - self.local.wrkdir = pwd; + self.local_mut().wrkdir = pwd; // Configure text editor self.setup_text_editor(); // init view diff --git a/src/ui/activities/filetransfer_activity/session.rs b/src/ui/activities/filetransfer_activity/session.rs index 052ecfb..d1c66d1 100644 --- a/src/ui/activities/filetransfer_activity/session.rs +++ b/src/ui/activities/filetransfer_activity/session.rs @@ -141,7 +141,7 @@ impl FileTransferActivity { if let Ok(pwd) = self.client.pwd() { self.remote_scan(pwd.as_path()); // Set wrkdir - self.remote.wrkdir = pwd; + self.remote_mut().wrkdir = pwd; } } @@ -257,7 +257,7 @@ impl FileTransferActivity { } } // Scan dir on remote - let path: PathBuf = self.remote.wrkdir.clone(); + let path: PathBuf = self.remote().wrkdir.clone(); self.remote_scan(path.as_path()); // If aborted; show popup if self.transfer.aborted { @@ -664,7 +664,7 @@ impl FileTransferActivity { match self.host.scan_dir(path) { Ok(files) => { // Set files and sort (sorting is implicit) - self.local.set_files(files); + self.local_mut().set_files(files); } Err(err) => { self.log_and_alert( @@ -682,7 +682,7 @@ impl FileTransferActivity { match self.client.list_dir(path) { Ok(files) => { // Set files and sort (sorting is implicit) - self.remote.set_files(files); + self.remote_mut().set_files(files); } Err(err) => { self.log_and_alert( @@ -698,7 +698,7 @@ impl FileTransferActivity { /// Change directory for local pub(super) fn local_changedir(&mut self, path: &Path, push: bool) { // Get current directory - let prev_dir: PathBuf = self.local.wrkdir.clone(); + let prev_dir: PathBuf = self.local().wrkdir.clone(); // Change directory match self.host.change_wrkdir(path) { Ok(_) => { @@ -709,10 +709,10 @@ impl FileTransferActivity { // Reload files self.local_scan(path); // Set wrkdir - self.local.wrkdir = PathBuf::from(path); + self.local_mut().wrkdir = PathBuf::from(path); // Push prev_dir to stack if push { - self.local.pushd(prev_dir.as_path()) + self.local_mut().pushd(prev_dir.as_path()) } } Err(err) => { @@ -727,7 +727,7 @@ impl FileTransferActivity { pub(super) fn remote_changedir(&mut self, path: &Path, push: bool) { // Get current directory - let prev_dir: PathBuf = self.remote.wrkdir.clone(); + let prev_dir: PathBuf = self.remote().wrkdir.clone(); // Change directory match self.client.as_mut().change_dir(path) { Ok(_) => { @@ -738,10 +738,10 @@ impl FileTransferActivity { // Update files self.remote_scan(path); // Set wrkdir - self.remote.wrkdir = PathBuf::from(path); + self.remote_mut().wrkdir = PathBuf::from(path); // Push prev_dir to stack if push { - self.remote.pushd(prev_dir.as_path()) + self.remote_mut().pushd(prev_dir.as_path()) } } Err(err) => { diff --git a/src/ui/activities/filetransfer_activity/update.rs b/src/ui/activities/filetransfer_activity/update.rs index 2d81cbe..2281599 100644 --- a/src/ui/activities/filetransfer_activity/update.rs +++ b/src/ui/activities/filetransfer_activity/update.rs @@ -29,7 +29,7 @@ extern crate bytesize; // locals use super::{ - FileExplorerTab, FileTransferActivity, LogLevel, COMPONENT_EXPLORER_FIND, + browser::FileExplorerTab, FileTransferActivity, LogLevel, COMPONENT_EXPLORER_FIND, COMPONENT_EXPLORER_LOCAL, COMPONENT_EXPLORER_REMOTE, COMPONENT_INPUT_COPY, COMPONENT_INPUT_EXEC, COMPONENT_INPUT_FIND, COMPONENT_INPUT_GOTO, COMPONENT_INPUT_MKDIR, COMPONENT_INPUT_NEWFILE, COMPONENT_INPUT_RENAME, COMPONENT_INPUT_SAVEAS, @@ -68,7 +68,7 @@ impl FileTransferActivity { (COMPONENT_EXPLORER_LOCAL, &MSG_KEY_RIGHT) => { // Change tab self.view.active(COMPONENT_EXPLORER_REMOTE); - self.tab = FileExplorerTab::Remote; + self.browser.change_tab(FileExplorerTab::Remote); None } (COMPONENT_EXPLORER_LOCAL, &MSG_KEY_BACKSPACE) => { @@ -83,7 +83,7 @@ impl FileTransferActivity { (COMPONENT_EXPLORER_LOCAL, Msg::OnSubmit(Payload::One(Value::Usize(idx)))) => { // Match selected file let mut entry: Option = None; - if let Some(e) = self.local.get(*idx) { + if let Some(e) = self.local().get(*idx) { entry = Some(e.clone()); } if let Some(entry) = entry { @@ -102,7 +102,7 @@ impl FileTransferActivity { } (COMPONENT_EXPLORER_LOCAL, &MSG_KEY_SPACE) => { // Get pwd - let wrkdir: PathBuf = self.remote.wrkdir.clone(); + let wrkdir: PathBuf = self.remote().wrkdir.clone(); // Get file and clone (due to mutable / immutable stuff...) if self.get_local_file_entry().is_some() { let file: FsEntry = self.get_local_file_entry().unwrap().clone(); @@ -116,7 +116,7 @@ impl FileTransferActivity { } (COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_A) => { // Toggle hidden files - self.local.toggle_hidden_files(); + self.local_mut().toggle_hidden_files(); // Reload file list component self.update_local_filelist() } @@ -129,7 +129,7 @@ impl FileTransferActivity { } (COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_L) => { // Reload directory - let pwd: PathBuf = self.local.wrkdir.clone(); + let pwd: PathBuf = self.local().wrkdir.clone(); self.local_scan(pwd.as_path()); // Reload file list component self.update_local_filelist() @@ -151,13 +151,13 @@ impl FileTransferActivity { (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_LEFT) => { // Change tab self.view.active(COMPONENT_EXPLORER_LOCAL); - self.tab = FileExplorerTab::Local; + self.browser.change_tab(FileExplorerTab::Local); None } (COMPONENT_EXPLORER_REMOTE, Msg::OnSubmit(Payload::One(Value::Usize(idx)))) => { // Match selected file let mut entry: Option = None; - if let Some(e) = self.remote.get(*idx) { + if let Some(e) = self.remote().get(*idx) { entry = Some(e.clone()); } if let Some(entry) = entry { @@ -180,7 +180,7 @@ impl FileTransferActivity { let file: FsEntry = self.get_remote_file_entry().unwrap().clone(); let name: String = file.get_name().to_string(); // Call upload; pass realfile, keep link name - let wrkdir: PathBuf = self.local.wrkdir.clone(); + let wrkdir: PathBuf = self.local().wrkdir.clone(); self.filetransfer_recv(&file.get_realfile(), wrkdir.as_path(), Some(name)); self.update_local_filelist() } else { @@ -199,7 +199,7 @@ impl FileTransferActivity { } (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_A) => { // Toggle hidden files - self.remote.toggle_hidden_files(); + self.remote_mut().toggle_hidden_files(); // Reload file list component self.update_remote_filelist() } @@ -212,7 +212,7 @@ impl FileTransferActivity { } (COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_L) => { // Reload directory - let pwd: PathBuf = self.remote.wrkdir.clone(); + let pwd: PathBuf = self.remote().wrkdir.clone(); self.remote_scan(pwd.as_path()); // Reload file list component self.update_remote_filelist() @@ -332,7 +332,7 @@ impl FileTransferActivity { // Finalize find self.finalize_find(); // Reload files - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => self.update_local_filelist(), FileExplorerTab::Remote => self.update_remote_filelist(), _ => None, @@ -344,7 +344,7 @@ impl FileTransferActivity { Some(Payload::One(Value::Usize(idx))) => { self.action_find_transfer(idx, None); // Reload files - match self.tab { + match self.browser.tab() { // NOTE: swapped by purpose FileExplorerTab::FindLocal => self.update_remote_filelist(), FileExplorerTab::FindRemote => self.update_local_filelist(), @@ -372,14 +372,14 @@ impl FileTransferActivity { } (COMPONENT_INPUT_COPY, Msg::OnSubmit(Payload::One(Value::Str(input)))) => { // Copy file - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => self.action_local_copy(input.to_string()), FileExplorerTab::Remote => self.action_remote_copy(input.to_string()), _ => panic!("Found tab doesn't support COPY"), } self.umount_copy(); // Reload files - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => self.update_local_filelist(), FileExplorerTab::Remote => self.update_remote_filelist(), _ => None, @@ -392,14 +392,14 @@ impl FileTransferActivity { } (COMPONENT_INPUT_EXEC, Msg::OnSubmit(Payload::One(Value::Str(input)))) => { // Exex command - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => self.action_local_exec(input.to_string()), FileExplorerTab::Remote => self.action_remote_exec(input.to_string()), _ => panic!("Found tab doesn't support EXEC"), } self.umount_exec(); // Reload files - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => self.update_local_filelist(), FileExplorerTab::Remote => self.update_remote_filelist(), _ => None, @@ -413,7 +413,7 @@ impl FileTransferActivity { (COMPONENT_INPUT_FIND, Msg::OnSubmit(Payload::One(Value::Str(input)))) => { self.umount_find_input(); // Find - let res: Result, String> = match self.tab { + let res: Result, String> = match self.browser.tab() { FileExplorerTab::Local => self.action_local_find(input.to_string()), FileExplorerTab::Remote => self.action_remote_find(input.to_string()), _ => panic!("Trying to search for files, while already in a find result"), @@ -426,18 +426,16 @@ impl FileTransferActivity { } Ok(files) => { // Create explorer and load files - let mut explorer = Self::build_found_explorer(); - explorer.set_files(files); - self.found = Some(explorer); + self.browser.set_found(files); // Mount result widget self.mount_find(input); self.update_find_list(); // Initialize tab - self.tab = match self.tab { + self.browser.change_tab(match self.browser.tab() { FileExplorerTab::Local => FileExplorerTab::FindLocal, FileExplorerTab::Remote => FileExplorerTab::FindRemote, _ => FileExplorerTab::FindLocal, - }; + }); } } None @@ -448,7 +446,7 @@ impl FileTransferActivity { None } (COMPONENT_INPUT_GOTO, Msg::OnSubmit(Payload::One(Value::Str(input)))) => { - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => { self.action_change_local_dir(input.to_string(), false) } @@ -461,14 +459,14 @@ impl FileTransferActivity { self.umount_goto(); // Reload files if sync if self.browser.sync_browsing { - match self.tab { + match self.browser.tab() { FileExplorerTab::Remote => self.update_local_filelist(), FileExplorerTab::Local => self.update_remote_filelist(), _ => None, }; } // Reload files - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => self.update_local_filelist(), FileExplorerTab::Remote => self.update_remote_filelist(), _ => None, @@ -480,14 +478,14 @@ impl FileTransferActivity { None } (COMPONENT_INPUT_MKDIR, Msg::OnSubmit(Payload::One(Value::Str(input)))) => { - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => self.action_local_mkdir(input.to_string()), FileExplorerTab::Remote => self.action_remote_mkdir(input.to_string()), _ => panic!("Found tab doesn't support MKDIR"), } self.umount_mkdir(); // Reload files - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => self.update_local_filelist(), FileExplorerTab::Remote => self.update_remote_filelist(), _ => None, @@ -499,14 +497,14 @@ impl FileTransferActivity { None } (COMPONENT_INPUT_NEWFILE, Msg::OnSubmit(Payload::One(Value::Str(input)))) => { - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => self.action_local_newfile(input.to_string()), FileExplorerTab::Remote => self.action_remote_newfile(input.to_string()), _ => panic!("Found tab doesn't support NEWFILE"), } self.umount_newfile(); // Reload files - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => self.update_local_filelist(), FileExplorerTab::Remote => self.update_remote_filelist(), _ => None, @@ -518,14 +516,14 @@ impl FileTransferActivity { None } (COMPONENT_INPUT_RENAME, Msg::OnSubmit(Payload::One(Value::Str(input)))) => { - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => self.action_local_rename(input.to_string()), FileExplorerTab::Remote => self.action_remote_rename(input.to_string()), _ => panic!("Found tab doesn't support RENAME"), } self.umount_rename(); // Reload files - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => self.update_local_filelist(), FileExplorerTab::Remote => self.update_remote_filelist(), _ => None, @@ -537,7 +535,7 @@ impl FileTransferActivity { None } (COMPONENT_INPUT_SAVEAS, Msg::OnSubmit(Payload::One(Value::Str(input)))) => { - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => self.action_local_saveas(input.to_string()), FileExplorerTab::Remote => self.action_remote_saveas(input.to_string()), FileExplorerTab::FindLocal | FileExplorerTab::FindRemote => { @@ -551,7 +549,7 @@ impl FileTransferActivity { } self.umount_saveas(); // Reload files - match self.tab { + match self.browser.tab() { // NOTE: Swapped is intentional FileExplorerTab::Local => self.update_remote_filelist(), FileExplorerTab::Remote => self.update_local_filelist(), @@ -573,7 +571,7 @@ impl FileTransferActivity { } (COMPONENT_RADIO_DELETE, Msg::OnSubmit(Payload::One(Value::Usize(0)))) => { // Choice is 'YES' - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => self.action_local_delete(), FileExplorerTab::Remote => self.action_remote_delete(), FileExplorerTab::FindLocal | FileExplorerTab::FindRemote => { @@ -583,14 +581,14 @@ impl FileTransferActivity { { self.action_find_delete(idx); // Reload entries - self.found.as_mut().unwrap().del_entry(idx); + self.found_mut().unwrap().del_entry(idx); self.update_find_list(); } } } self.umount_radio_delete(); // Reload files - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => self.update_local_filelist(), FileExplorerTab::Remote => self.update_remote_filelist(), FileExplorerTab::FindLocal => self.update_local_filelist(), @@ -633,15 +631,15 @@ impl FileTransferActivity { 3 => FileSorting::BySize, _ => FileSorting::ByName, }; - match self.tab { - FileExplorerTab::Local => self.local.sort_by(sorting), - FileExplorerTab::Remote => self.remote.sort_by(sorting), + match self.browser.tab() { + FileExplorerTab::Local => self.local_mut().sort_by(sorting), + FileExplorerTab::Remote => self.remote_mut().sort_by(sorting), _ => panic!("Found result doesn't support SORTING"), } // Update status bar self.refresh_status_bar(); // Reload files - match self.tab { + match self.browser.tab() { FileExplorerTab::Local => self.update_local_filelist(), FileExplorerTab::Remote => self.update_remote_filelist(), _ => None, @@ -700,16 +698,16 @@ impl FileTransferActivity { "{}:{} ", hostname, FileTransferActivity::elide_wrkdir_path( - self.local.wrkdir.as_path(), + self.local().wrkdir.as_path(), hostname.as_str(), width ) .display() ); let files: Vec = self - .local + .local() .iter_files() - .map(|x: &FsEntry| self.local.fmt_file(x)) + .map(|x: &FsEntry| self.local().fmt_file(x)) .collect(); // Update let props = FileListPropsBuilder::from(props) @@ -741,16 +739,16 @@ impl FileTransferActivity { "{}:{} ", params.address, FileTransferActivity::elide_wrkdir_path( - self.remote.wrkdir.as_path(), + self.remote().wrkdir.as_path(), params.address.as_str(), width ) .display() ); let files: Vec = self - .remote + .remote() .iter_files() - .map(|x: &FsEntry| self.remote.fmt_file(x)) + .map(|x: &FsEntry| self.remote().fmt_file(x)) .collect(); // Update let props = FileListPropsBuilder::from(props) @@ -849,13 +847,13 @@ impl FileTransferActivity { /// Finalize find process fn finalize_find(&mut self) { // Set found to none - self.found = None; + self.browser.del_found(); // Restore tab - self.tab = match self.tab { + self.browser.change_tab(match self.browser.tab() { FileExplorerTab::FindLocal => FileExplorerTab::Local, FileExplorerTab::FindRemote => FileExplorerTab::Remote, _ => FileExplorerTab::Local, - }; + }); } fn update_find_list(&mut self) -> Option<(String, Msg)> { @@ -865,11 +863,10 @@ impl FileTransferActivity { let title: String = props.texts.title.clone().unwrap_or_default(); // Prepare files let files: Vec = self - .found - .as_ref() + .found() .unwrap() .iter_files() - .map(|x: &FsEntry| self.found.as_ref().unwrap().fmt_file(x)) + .map(|x: &FsEntry| self.found().unwrap().fmt_file(x)) .collect(); let props = FileListPropsBuilder::from(props) .with_files(Some(title), files) diff --git a/src/ui/activities/filetransfer_activity/view.rs b/src/ui/activities/filetransfer_activity/view.rs index 3cd50c1..bee6c03 100644 --- a/src/ui/activities/filetransfer_activity/view.rs +++ b/src/ui/activities/filetransfer_activity/view.rs @@ -31,7 +31,7 @@ extern crate hostname; #[cfg(any(target_os = "unix", target_os = "macos", target_os = "linux"))] extern crate users; // locals -use super::{Context, FileExplorerTab, FileTransferActivity}; +use super::{browser::FileExplorerTab, Context, FileTransferActivity}; use crate::fs::explorer::FileSorting; use crate::fs::FsEntry; use crate::ui::components::{ @@ -150,7 +150,7 @@ impl FileTransferActivity { } // Draw explorers // @! Local explorer (Find or default) - match self.tab { + match self.browser.tab() { FileExplorerTab::FindLocal => { self.view .render(super::COMPONENT_EXPLORER_FIND, f, tabs_chunks[0]) @@ -160,7 +160,7 @@ impl FileTransferActivity { .render(super::COMPONENT_EXPLORER_LOCAL, f, tabs_chunks[0]), } // @! Remote explorer (Find or default) - match self.tab { + match self.browser.tab() { FileExplorerTab::FindRemote => { self.view .render(super::COMPONENT_EXPLORER_FIND, f, tabs_chunks[1]) @@ -486,7 +486,7 @@ impl FileTransferActivity { pub(super) fn mount_find(&mut self, search: &str) { // Get color - let color: Color = match self.tab { + let color: Color = match self.browser.tab() { FileExplorerTab::Local | FileExplorerTab::FindLocal => Color::Yellow, FileExplorerTab::Remote | FileExplorerTab::FindRemote => Color::LightBlue, }; @@ -634,9 +634,9 @@ impl FileTransferActivity { } pub(super) fn mount_file_sorting(&mut self) { - let sorting: FileSorting = match self.tab { - FileExplorerTab::Local => self.local.get_file_sorting(), - FileExplorerTab::Remote => self.remote.get_file_sorting(), + let sorting: FileSorting = match self.browser.tab() { + FileExplorerTab::Local => self.local().get_file_sorting(), + FileExplorerTab::Remote => self.remote().get_file_sorting(), _ => panic!("You can't mount file sorting when in found result"), }; let index: usize = match sorting { @@ -821,14 +821,14 @@ impl FileTransferActivity { TextSpanBuilder::new(" Localhost file sorting: ") .with_foreground(Color::LightYellow) .build(), - TextSpanBuilder::new(Self::get_file_sorting_str(self.local.get_file_sorting())) + TextSpanBuilder::new(Self::get_file_sorting_str(self.local().get_file_sorting())) .with_foreground(Color::LightYellow) .reversed() .build(), TextSpanBuilder::new(" Remote host file sorting: ") .with_foreground(Color::LightBlue) .build(), - TextSpanBuilder::new(Self::get_file_sorting_str(self.remote.get_file_sorting())) + TextSpanBuilder::new(Self::get_file_sorting_str(self.remote().get_file_sorting())) .with_foreground(Color::LightBlue) .reversed() .build(),