Handle file selections in activity

This commit is contained in:
veeso 2021-05-15 17:03:44 +02:00
parent d96558c3df
commit 2b3acee97c
12 changed files with 496 additions and 369 deletions

View file

@ -26,51 +26,34 @@
* SOFTWARE.
*/
// locals
use super::{FileTransferActivity, FsEntry, LogLevel};
use std::path::PathBuf;
use tuirealm::{Payload, Value};
use super::{FileTransferActivity, FsEntry, LogLevel, SelectedEntry};
use std::path::{Path, PathBuf};
impl FileTransferActivity {
/// ### action_local_copy
///
/// Copy file on local
pub(crate) fn action_local_copy(&mut self, input: String) {
match self.get_local_file_state() {
Some(Payload::One(Value::Usize(idx))) => {
match self.get_local_selected_entries() {
SelectedEntry::One(entry) => {
let dest_path: PathBuf = PathBuf::from(input);
let entry: FsEntry = self.local().get(idx).unwrap().clone();
match self.host.copy(&entry, dest_path.as_path()) {
Ok(_) => {
self.log(
LogLevel::Info,
format!(
"Copied \"{}\" to \"{}\"",
entry.get_abs_path().display(),
dest_path.display()
),
);
// Reload entries
let wrkdir: PathBuf = self.local().wrkdir.clone();
self.local_scan(wrkdir.as_path());
}
Err(err) => self.log_and_alert(
LogLevel::Error,
format!(
"Could not copy \"{}\" to \"{}\": {}",
entry.get_abs_path().display(),
dest_path.display(),
err
),
),
self.local_copy_file(&entry, dest_path.as_path());
// Reload entries
self.reload_local_dir();
}
SelectedEntry::Multi(entries) => {
// Try to copy each file to Input/{FILE_NAME}
let base_path: PathBuf = PathBuf::from(input);
// Iter files
for entry in entries.iter() {
let mut dest_path: PathBuf = base_path.clone();
dest_path.push(entry.get_name());
self.local_copy_file(entry, dest_path.as_path());
}
// Reload entries
self.reload_local_dir();
}
Some(Payload::Vec(_)) => {
self.log_and_alert(
LogLevel::Warn,
format!("Copy is not supported when using seleection"),
);
}
_ => {}
SelectedEntry::None => {}
}
}
@ -78,40 +61,74 @@ impl FileTransferActivity {
///
/// Copy file on remote
pub(crate) fn action_remote_copy(&mut self, input: String) {
match self.get_local_file_state() {
Some(Payload::One(Value::Usize(idx))) => {
match self.get_remote_selected_entries() {
SelectedEntry::One(entry) => {
let dest_path: PathBuf = PathBuf::from(input);
let entry: FsEntry = self.remote().get(idx).unwrap().clone();
match self.client.as_mut().copy(&entry, dest_path.as_path()) {
Ok(_) => {
self.log(
LogLevel::Info,
format!(
"Copied \"{}\" to \"{}\"",
entry.get_abs_path().display(),
dest_path.display()
),
);
self.reload_remote_dir();
}
Err(err) => self.log_and_alert(
LogLevel::Error,
format!(
"Could not copy \"{}\" to \"{}\": {}",
entry.get_abs_path().display(),
dest_path.display(),
err
),
),
}
self.remote_copy_file(&entry, dest_path.as_path());
// Reload entries
self.reload_remote_dir();
}
Some(Payload::Vec(_)) => {
self.log_and_alert(
LogLevel::Warn,
format!("Copy is not supported when using seleection"),
SelectedEntry::Multi(entries) => {
// Try to copy each file to Input/{FILE_NAME}
let base_path: PathBuf = PathBuf::from(input);
// Iter files
for entry in entries.iter() {
let mut dest_path: PathBuf = base_path.clone();
dest_path.push(entry.get_name());
self.remote_copy_file(entry, dest_path.as_path());
}
// Reload entries
self.reload_remote_dir();
}
SelectedEntry::None => {}
}
}
fn local_copy_file(&mut self, entry: &FsEntry, dest: &Path) {
match self.host.copy(entry, dest) {
Ok(_) => {
self.log(
LogLevel::Info,
format!(
"Copied \"{}\" to \"{}\"",
entry.get_abs_path().display(),
dest.display()
),
);
}
_ => {}
Err(err) => self.log_and_alert(
LogLevel::Error,
format!(
"Could not copy \"{}\" to \"{}\": {}",
entry.get_abs_path().display(),
dest.display(),
err
),
),
}
}
fn remote_copy_file(&mut self, entry: &FsEntry, dest: &Path) {
match self.client.as_mut().copy(entry, dest) {
Ok(_) => {
self.log(
LogLevel::Info,
format!(
"Copied \"{}\" to \"{}\"",
entry.get_abs_path().display(),
dest.display()
),
);
}
Err(err) => self.log_and_alert(
LogLevel::Error,
format!(
"Could not copy \"{}\" to \"{}\": {}",
entry.get_abs_path().display(),
dest.display(),
err
),
),
}
}
}

View file

@ -26,70 +26,90 @@
* SOFTWARE.
*/
// locals
use super::{FileTransferActivity, FsEntry, LogLevel};
use std::path::PathBuf;
use tuirealm::{Payload, Value};
use super::{FileTransferActivity, FsEntry, LogLevel, SelectedEntry};
impl FileTransferActivity {
pub(crate) fn action_local_delete(&mut self) {
// Get selection
let selection: Vec<usize> = match self.get_local_file_state() {
Some(Payload::One(Value::Usize(idx))) => vec![idx],
Some(Payload::Vec(list)) => list.into_iter().map(|x| {
match x {
Value::Usize(x) => x,
_ => panic!("File selection contains non-usize value"),
}
}),
}
let entry: Option<FsEntry> = self.get_local_file_entry().cloned();
if let Some(entry) = entry {
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();
self.local_scan(p.as_path());
// Log
self.log(
LogLevel::Info,
format!("Removed file \"{}\"", full_path.display()),
);
}
Err(err) => {
self.log_and_alert(
LogLevel::Error,
format!("Could not delete file \"{}\": {}", full_path.display(), err),
);
}
match self.get_local_selected_entries() {
SelectedEntry::One(entry) => {
// Delete file
self.local_remove_file(&entry);
// Reload
self.reload_local_dir();
}
SelectedEntry::Multi(entries) => {
// Iter files
for entry in entries.iter() {
// Delete file
self.local_remove_file(entry);
}
// Reload entries
self.reload_local_dir();
}
SelectedEntry::None => {}
}
}
pub(crate) fn action_remote_delete(&mut self) {
if let Some(idx) = self.get_remote_file_state() {
// Check if file entry exists
let entry = self.remote().get(idx).cloned();
if let Some(entry) = entry {
let full_path: PathBuf = entry.get_abs_path();
match self.get_remote_selected_entries() {
SelectedEntry::One(entry) => {
// Delete file
match self.client.remove(&entry) {
Ok(_) => {
self.reload_remote_dir();
self.log(
LogLevel::Info,
format!("Removed file \"{}\"", full_path.display()),
);
}
Err(err) => {
self.log_and_alert(
LogLevel::Error,
format!("Could not delete file \"{}\": {}", full_path.display(), err),
);
}
self.remote_remove_file(&entry);
// Reload
self.reload_remote_dir();
}
SelectedEntry::Multi(entries) => {
// Iter files
for entry in entries.iter() {
// Delete file
self.remote_remove_file(entry);
}
// Reload entries
self.reload_remote_dir();
}
SelectedEntry::None => {}
}
}
pub(crate) fn local_remove_file(&mut self, entry: &FsEntry) {
match self.host.remove(&entry) {
Ok(_) => {
// Log
self.log(
LogLevel::Info,
format!("Removed file \"{}\"", entry.get_abs_path().display()),
);
}
Err(err) => {
self.log_and_alert(
LogLevel::Error,
format!(
"Could not delete file \"{}\": {}",
entry.get_abs_path().display(),
err
),
);
}
}
}
pub(crate) fn remote_remove_file(&mut self, entry: &FsEntry) {
match self.client.remove(&entry) {
Ok(_) => {
self.log(
LogLevel::Info,
format!("Removed file \"{}\"", entry.get_abs_path().display()),
);
}
Err(err) => {
self.log_and_alert(
LogLevel::Error,
format!(
"Could not delete file \"{}\": {}",
entry.get_abs_path().display(),
err
),
);
}
}
}

View file

@ -26,51 +26,54 @@
* SOFTWARE.
*/
// locals
use super::{FileTransferActivity, FsEntry, LogLevel};
use std::path::PathBuf;
use super::{FileTransferActivity, FsEntry, LogLevel, SelectedEntry};
impl FileTransferActivity {
pub(crate) fn action_edit_local_file(&mut self) {
if self.get_local_file_entry().is_some() {
let fsentry: FsEntry = self.get_local_file_entry().unwrap().clone();
let entries: Vec<FsEntry> = match self.get_local_selected_entries() {
SelectedEntry::One(entry) => vec![entry],
SelectedEntry::Multi(entries) => entries,
SelectedEntry::None => vec![],
};
// Edit all entries
for entry in entries.iter() {
// Check if file
if fsentry.is_file() {
if entry.is_file() {
self.log(
LogLevel::Info,
format!("Opening file \"{}\"...", fsentry.get_abs_path().display()),
format!("Opening file \"{}\"...", entry.get_abs_path().display()),
);
// Edit file
match self.edit_local_file(fsentry.get_abs_path().as_path()) {
Ok(_) => {
// Reload directory
let pwd: PathBuf = self.local().wrkdir.clone();
self.local_scan(pwd.as_path());
}
Err(err) => self.log_and_alert(LogLevel::Error, err),
if let Err(err) = self.edit_local_file(entry.get_abs_path().as_path()) {
self.log_and_alert(LogLevel::Error, err);
}
}
}
// Reload entries
self.reload_local_dir();
}
pub(crate) fn action_edit_remote_file(&mut self) {
if self.get_remote_file_entry().is_some() {
let fsentry: FsEntry = self.get_remote_file_entry().unwrap().clone();
let entries: Vec<FsEntry> = match self.get_remote_selected_entries() {
SelectedEntry::One(entry) => vec![entry],
SelectedEntry::Multi(entries) => entries,
SelectedEntry::None => vec![],
};
// Edit all entries
for entry in entries.iter() {
// Check if file
if let FsEntry::File(file) = fsentry.clone() {
if let FsEntry::File(file) = entry {
self.log(
LogLevel::Info,
format!("Opening file \"{}\"...", fsentry.get_abs_path().display()),
format!("Opening file \"{}\"...", entry.get_abs_path().display()),
);
// Edit file
match self.edit_remote_file(&file) {
Ok(_) => {
// Reload directory
let pwd: PathBuf = self.remote().wrkdir.clone();
self.remote_scan(pwd.as_path());
}
Err(err) => self.log_and_alert(LogLevel::Error, err),
if let Err(err) = self.edit_remote_file(&file) {
self.log_and_alert(LogLevel::Error, err);
}
}
}
// Reload entries
self.reload_remote_dir();
}
}

View file

@ -27,7 +27,6 @@
*/
// locals
use super::{FileTransferActivity, LogLevel};
use std::path::PathBuf;
impl FileTransferActivity {
pub(crate) fn action_local_exec(&mut self, input: String) {
@ -35,8 +34,8 @@ impl FileTransferActivity {
Ok(output) => {
// Reload files
self.log(LogLevel::Info, format!("\"{}\": {}", input, output));
let wrkdir: PathBuf = self.local().wrkdir.clone();
self.local_scan(wrkdir.as_path());
// Reload entries
self.reload_local_dir();
}
Err(err) => {
// Report err

View file

@ -27,7 +27,7 @@
*/
// locals
use super::super::browser::FileExplorerTab;
use super::{FileTransferActivity, FsEntry, LogLevel};
use super::{FileTransferActivity, FsEntry, SelectedEntry};
use std::path::PathBuf;
@ -46,12 +46,12 @@ impl FileTransferActivity {
}
}
pub(crate) fn action_find_changedir(&mut self, idx: usize) {
pub(crate) fn action_find_changedir(&mut self) {
// Match entry
if let Some(entry) = self.found().as_ref().unwrap().get(idx) {
if let SelectedEntry::One(entry) = self.get_found_selected_entries() {
// 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(),
FsEntry::Directory(dir) => dir.abs_path,
FsEntry::File(file) => match file.abs_path.parent() {
None => PathBuf::from("."),
Some(p) => p.to_path_buf(),
@ -69,78 +69,60 @@ impl FileTransferActivity {
}
}
pub(crate) fn action_find_transfer(&mut self, idx: usize, name: Option<String>) {
let entry: Option<FsEntry> = self.found().as_ref().unwrap().get(idx).cloned();
if let Some(entry) = entry {
// Download file
match self.browser.tab() {
pub(crate) fn action_find_transfer(&mut self, save_as: Option<String>) {
let wrkdir: PathBuf = match self.browser.tab() {
FileExplorerTab::FindLocal | FileExplorerTab::Local => self.remote().wrkdir.clone(),
FileExplorerTab::FindRemote | FileExplorerTab::Remote => self.local().wrkdir.clone(),
};
match self.get_found_selected_entries() {
SelectedEntry::One(entry) => match self.browser.tab() {
FileExplorerTab::FindLocal | FileExplorerTab::Local => {
let wrkdir: PathBuf = self.remote().wrkdir.clone();
self.filetransfer_send(&entry.get_realfile(), wrkdir.as_path(), name);
self.filetransfer_send(&entry.get_realfile(), wrkdir.as_path(), save_as);
}
FileExplorerTab::FindRemote | FileExplorerTab::Remote => {
let wrkdir: PathBuf = self.local().wrkdir.clone();
self.filetransfer_recv(&entry.get_realfile(), wrkdir.as_path(), name);
self.filetransfer_recv(&entry.get_realfile(), wrkdir.as_path(), save_as);
}
},
SelectedEntry::Multi(entries) => {
// In case of selection: save multiple files in wrkdir/input
let mut dest_path: PathBuf = wrkdir;
if let Some(save_as) = save_as {
dest_path.push(save_as);
}
// Iter files
for entry in entries.iter() {
self.filetransfer_recv(&entry.get_realfile(), dest_path.as_path(), None);
}
}
SelectedEntry::None => {}
}
}
pub(crate) fn action_find_delete(&mut self, idx: usize) {
let entry: Option<FsEntry> = self.found().as_ref().unwrap().get(idx).cloned();
if let Some(entry) = entry {
// Download file
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();
self.local_scan(p.as_path());
// Log
self.log(
LogLevel::Info,
format!("Removed file \"{}\"", full_path.display()),
);
}
Err(err) => {
self.log_and_alert(
LogLevel::Error,
format!(
"Could not delete file \"{}\": {}",
full_path.display(),
err
),
);
}
}
}
FileExplorerTab::FindRemote | FileExplorerTab::Remote => {
let full_path: PathBuf = entry.get_abs_path();
pub(crate) fn action_find_delete(&mut self) {
match self.get_found_selected_entries() {
SelectedEntry::One(entry) => {
// Delete file
self.remove_found_file(&entry);
}
SelectedEntry::Multi(entries) => {
// Iter files
for entry in entries.iter() {
// Delete file
match self.client.remove(&entry) {
Ok(_) => {
self.reload_remote_dir();
self.log(
LogLevel::Info,
format!("Removed file \"{}\"", full_path.display()),
);
}
Err(err) => {
self.log_and_alert(
LogLevel::Error,
format!(
"Could not delete file \"{}\": {}",
full_path.display(),
err
),
);
}
}
self.remove_found_file(entry);
}
}
SelectedEntry::None => {}
}
}
fn remove_found_file(&mut self, entry: &FsEntry) {
match self.browser.tab() {
FileExplorerTab::FindLocal | FileExplorerTab::Local => {
self.local_remove_file(entry);
}
FileExplorerTab::FindRemote | FileExplorerTab::Remote => {
self.remote_remove_file(entry);
}
}
}
}

View file

@ -35,8 +35,8 @@ impl FileTransferActivity {
Ok(_) => {
// Reload files
self.log(LogLevel::Info, format!("Created directory \"{}\"", input));
let wrkdir: PathBuf = self.local().wrkdir.clone();
self.local_scan(wrkdir.as_path());
// Reload entries
self.reload_local_dir();
}
Err(err) => {
// Report err

View file

@ -40,40 +40,114 @@ pub(crate) mod newfile;
pub(crate) mod rename;
pub(crate) mod save;
pub(crate) enum SelectedEntry {
One(FsEntry),
Multi(Vec<FsEntry>),
None,
}
enum SelectedEntryIndex {
One(usize),
Multi(Vec<usize>),
None,
}
impl From<Option<&FsEntry>> for SelectedEntry {
fn from(opt: Option<&FsEntry>) -> Self {
match opt {
Some(e) => SelectedEntry::One(e.clone()),
None => SelectedEntry::None,
}
}
}
impl From<Vec<&FsEntry>> for SelectedEntry {
fn from(files: Vec<&FsEntry>) -> Self {
SelectedEntry::Multi(files.into_iter().cloned().collect())
}
}
impl FileTransferActivity {
/// ### get_local_file_entry
/// ### get_local_selected_entries
///
/// Get local file entry
pub(crate) fn get_local_file_entry(&self) -> Option<&FsEntry> {
match self.get_local_file_state() {
Some(Payload::One(Value::Usize(idx))) => self.local().get(idx),
_ => None,
pub(crate) fn get_local_selected_entries(&self) -> SelectedEntry {
match self.get_selected_index(super::COMPONENT_EXPLORER_LOCAL) {
SelectedEntryIndex::One(idx) => SelectedEntry::from(self.local().get(idx)),
SelectedEntryIndex::Multi(files) => {
let files: Vec<&FsEntry> = files
.iter()
.map(|x| self.local().get(*x)) // Usize to Option<FsEntry>
.filter(|x| x.is_some()) // Get only some values
.map(|x| x.unwrap()) // Option to FsEntry
.collect();
SelectedEntry::from(files)
}
SelectedEntryIndex::None => SelectedEntry::None,
}
}
/// ### get_remote_file_entry
/// ### get_remote_selected_entries
///
/// Get remote file entry
pub(crate) fn get_remote_file_entry(&self) -> Option<&FsEntry> {
match self.get_remote_file_state() {
Some(Payload::One(Value::Usize(idx))) => self.remote().get(idx),
_ => None,
pub(crate) fn get_remote_selected_entries(&self) -> SelectedEntry {
match self.get_selected_index(super::COMPONENT_EXPLORER_REMOTE) {
SelectedEntryIndex::One(idx) => SelectedEntry::from(self.remote().get(idx)),
SelectedEntryIndex::Multi(files) => {
let files: Vec<&FsEntry> = files
.iter()
.map(|x| self.remote().get(*x)) // Usize to Option<FsEntry>
.filter(|x| x.is_some()) // Get only some values
.map(|x| x.unwrap()) // Option to FsEntry
.collect();
SelectedEntry::from(files)
}
SelectedEntryIndex::None => SelectedEntry::None,
}
}
/// ### get_remote_selected_entries
///
/// Get remote file entry
pub(crate) fn get_found_selected_entries(&self) -> SelectedEntry {
match self.get_selected_index(super::COMPONENT_EXPLORER_FIND) {
SelectedEntryIndex::One(idx) => {
SelectedEntry::from(self.found().as_ref().unwrap().get(idx))
}
SelectedEntryIndex::Multi(files) => {
let files: Vec<&FsEntry> = files
.iter()
.map(|x| self.found().as_ref().unwrap().get(*x)) // Usize to Option<FsEntry>
.filter(|x| x.is_some()) // Get only some values
.map(|x| x.unwrap()) // Option to FsEntry
.collect();
SelectedEntry::from(files)
}
SelectedEntryIndex::None => SelectedEntry::None,
}
}
// -- private
/// ### get_local_file_state
///
/// Get index of selected file in the local tab
fn get_local_file_state(&self) -> Option<Payload> {
self.view.get_state(super::COMPONENT_EXPLORER_LOCAL)
}
/// ### get_remote_file_state
///
/// Get index of selected file in the remote file
fn get_remote_file_state(&self) -> Option<Payload> {
self.view.get_state(super::COMPONENT_EXPLORER_REMOTE)
fn get_selected_index(&self, component: &str) -> SelectedEntryIndex {
eprintln!(
"INDEX FOR {}: {:?}",
component,
self.view.get_state(component)
);
match self.view.get_state(component) {
Some(Payload::One(Value::Usize(idx))) => SelectedEntryIndex::One(idx),
Some(Payload::Vec(files)) => {
let list: Vec<usize> = files
.iter()
.map(|x| match x {
Value::Usize(v) => *v,
_ => 0,
})
.collect();
SelectedEntryIndex::Multi(list)
}
_ => SelectedEntryIndex::None,
}
}
}

View file

@ -59,8 +59,7 @@ impl FileTransferActivity {
);
}
// Reload files
let path: PathBuf = self.local().wrkdir.clone();
self.local_scan(path.as_path());
self.reload_local_dir();
}
pub(crate) fn action_remote_newfile(&mut self, input: String) {
@ -119,8 +118,7 @@ impl FileTransferActivity {
);
}
// Reload files
let path: PathBuf = self.remote().wrkdir.clone();
self.remote_scan(path.as_path());
self.reload_remote_dir();
}
}
}

View file

@ -26,77 +26,103 @@
* SOFTWARE.
*/
// locals
use super::{FileTransferActivity, FsEntry, LogLevel};
use std::path::PathBuf;
use super::{FileTransferActivity, FsEntry, LogLevel, SelectedEntry};
use std::path::{Path, PathBuf};
impl FileTransferActivity {
pub(crate) fn action_local_rename(&mut self, input: String) {
let entry: Option<FsEntry> = self.get_local_file_entry().cloned();
if let Some(entry) = entry {
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();
wrkdir.push(dst_path);
dst_path = wrkdir;
match self.get_local_selected_entries() {
SelectedEntry::One(entry) => {
let dest_path: PathBuf = PathBuf::from(input);
self.local_rename_file(&entry, dest_path.as_path());
// Reload entries
self.reload_local_dir();
}
let full_path: PathBuf = entry.get_abs_path();
// Rename file or directory and report status as popup
match self.host.rename(&entry, dst_path.as_path()) {
Ok(_) => {
// Reload files
let path: PathBuf = self.local().wrkdir.clone();
self.local_scan(path.as_path());
// Log
self.log(
LogLevel::Info,
format!(
"Renamed file \"{}\" to \"{}\"",
full_path.display(),
dst_path.display()
),
);
}
Err(err) => {
self.log_and_alert(
LogLevel::Error,
format!("Could not rename file \"{}\": {}", full_path.display(), err),
);
SelectedEntry::Multi(entries) => {
// Try to copy each file to Input/{FILE_NAME}
let base_path: PathBuf = PathBuf::from(input);
// Iter files
for entry in entries.iter() {
let mut dest_path: PathBuf = base_path.clone();
dest_path.push(entry.get_name());
self.local_rename_file(entry, dest_path.as_path());
}
// Reload entries
self.reload_local_dir();
}
SelectedEntry::None => {}
}
}
pub(crate) fn action_remote_rename(&mut self, input: String) {
if let Some(idx) = self.get_remote_file_state() {
let entry = self.remote().get(idx).cloned();
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()) {
Ok(_) => {
// Reload files
let path: PathBuf = self.remote().wrkdir.clone();
self.remote_scan(path.as_path());
// Log
self.log(
LogLevel::Info,
format!(
"Renamed file \"{}\" to \"{}\"",
full_path.display(),
dst_path.display()
),
);
}
Err(err) => {
self.log_and_alert(
LogLevel::Error,
format!("Could not rename file \"{}\": {}", full_path.display(), err),
);
}
}
match self.get_remote_selected_entries() {
SelectedEntry::One(entry) => {
let dest_path: PathBuf = PathBuf::from(input);
self.remote_rename_file(&entry, dest_path.as_path());
// Reload entries
self.reload_remote_dir();
}
SelectedEntry::Multi(entries) => {
// Try to copy each file to Input/{FILE_NAME}
let base_path: PathBuf = PathBuf::from(input);
// Iter files
for entry in entries.iter() {
let mut dest_path: PathBuf = base_path.clone();
dest_path.push(entry.get_name());
self.remote_rename_file(entry, dest_path.as_path());
}
// Reload entries
self.reload_remote_dir();
}
SelectedEntry::None => {}
}
}
fn local_rename_file(&mut self, entry: &FsEntry, dest: &Path) {
match self.host.rename(entry, dest) {
Ok(_) => {
self.log(
LogLevel::Info,
format!(
"Moved \"{}\" to \"{}\"",
entry.get_abs_path().display(),
dest.display()
),
);
}
Err(err) => self.log_and_alert(
LogLevel::Error,
format!(
"Could not move \"{}\" to \"{}\": {}",
entry.get_abs_path().display(),
dest.display(),
err
),
),
}
}
fn remote_rename_file(&mut self, entry: &FsEntry, dest: &Path) {
match self.client.as_mut().rename(entry, dest) {
Ok(_) => {
self.log(
LogLevel::Info,
format!(
"Moved \"{}\" to \"{}\"",
entry.get_abs_path().display(),
dest.display()
),
);
}
Err(err) => self.log_and_alert(
LogLevel::Error,
format!(
"Could not move \"{}\" to \"{}\": {}",
entry.get_abs_path().display(),
dest.display(),
err
),
),
}
}
}

View file

@ -26,31 +26,65 @@
* SOFTWARE.
*/
// locals
use super::{FileTransferActivity, FsEntry};
use super::{FileTransferActivity, SelectedEntry};
use std::path::PathBuf;
impl FileTransferActivity {
pub(crate) fn action_local_saveas(&mut self, input: String) {
if let Some(idx) = self.get_local_file_state() {
// 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();
// Call upload; pass realfile, keep link name
self.filetransfer_send(&file.get_realfile(), wrkdir.as_path(), Some(input));
}
}
self.action_local_send_file(Some(input));
}
pub(crate) fn action_remote_saveas(&mut self, input: String) {
if let Some(idx) = self.get_remote_file_state() {
// 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();
// Call upload; pass realfile, keep link name
self.filetransfer_recv(&file.get_realfile(), wrkdir.as_path(), Some(input));
self.action_remote_recv_file(Some(input));
}
pub(crate) fn action_local_send(&mut self) {
self.action_local_send_file(None);
}
pub(crate) fn action_remote_recv(&mut self) {
self.action_remote_recv_file(None);
}
fn action_local_send_file(&mut self, save_as: Option<String>) {
let wrkdir: PathBuf = self.remote().wrkdir.clone();
match self.get_local_selected_entries() {
SelectedEntry::One(entry) => {
self.filetransfer_send(&entry.get_realfile(), wrkdir.as_path(), save_as);
}
SelectedEntry::Multi(entries) => {
// In case of selection: save multiple files in wrkdir/input
let mut dest_path: PathBuf = wrkdir;
if let Some(save_as) = save_as {
dest_path.push(save_as);
}
// Iter files
for entry in entries.iter() {
self.filetransfer_send(&entry.get_realfile(), dest_path.as_path(), None);
}
}
SelectedEntry::None => {}
}
}
fn action_remote_recv_file(&mut self, save_as: Option<String>) {
let wrkdir: PathBuf = self.local().wrkdir.clone();
match self.get_remote_selected_entries() {
SelectedEntry::One(entry) => {
self.filetransfer_recv(&entry.get_realfile(), wrkdir.as_path(), save_as);
}
SelectedEntry::Multi(entries) => {
// In case of selection: save multiple files in wrkdir/input
let mut dest_path: PathBuf = wrkdir;
if let Some(save_as) = save_as {
dest_path.push(save_as);
}
// Iter files
for entry in entries.iter() {
self.filetransfer_recv(&entry.get_realfile(), dest_path.as_path(), None);
}
}
SelectedEntry::None => {}
}
}
}

View file

@ -145,6 +145,11 @@ impl FileTransferActivity {
}
}
pub(super) fn reload_local_dir(&mut self) {
let wrkdir: PathBuf = self.local().wrkdir.clone();
self.local_scan(wrkdir.as_path());
}
/// ### filetransfer_send
///
/// Send fs entry to remote.
@ -257,8 +262,7 @@ impl FileTransferActivity {
}
}
// Scan dir on remote
let path: PathBuf = self.remote().wrkdir.clone();
self.remote_scan(path.as_path());
self.reload_remote_dir();
// If aborted; show popup
if self.transfer.aborted {
// Log abort

View file

@ -29,10 +29,10 @@
extern crate bytesize;
// locals
use super::{
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,
actions::SelectedEntry, 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,
COMPONENT_LIST_FILEINFO, COMPONENT_LOG_BOX, COMPONENT_PROGRESS_BAR, COMPONENT_RADIO_DELETE,
COMPONENT_RADIO_DISCONNECT, COMPONENT_RADIO_QUIT, COMPONENT_RADIO_SORTING,
COMPONENT_TEXT_ERROR, COMPONENT_TEXT_FATAL, COMPONENT_TEXT_HELP,
@ -101,18 +101,8 @@ impl FileTransferActivity {
}
}
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_SPACE) => {
// Get pwd
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();
let name: String = file.get_name().to_string();
// Call upload; pass realfile, keep link name
self.filetransfer_send(&file.get_realfile(), wrkdir.as_path(), Some(name));
self.update_remote_filelist()
} else {
None
}
self.action_local_send();
self.update_remote_filelist()
}
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_A) => {
// Toggle hidden files
@ -121,8 +111,7 @@ impl FileTransferActivity {
self.update_local_filelist()
}
(COMPONENT_EXPLORER_LOCAL, &MSG_KEY_CHAR_I) => {
let file: Option<FsEntry> = self.get_local_file_entry().cloned();
if let Some(file) = file {
if let SelectedEntry::One(file) = self.get_local_selected_entries() {
self.mount_file_info(&file);
}
None
@ -175,17 +164,8 @@ impl FileTransferActivity {
}
}
(COMPONENT_EXPLORER_REMOTE, &MSG_KEY_SPACE) => {
// Get file and clone (due to mutable / immutable stuff...)
if self.get_remote_file_entry().is_some() {
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();
self.filetransfer_recv(&file.get_realfile(), wrkdir.as_path(), Some(name));
self.update_local_filelist()
} else {
None
}
self.action_remote_recv();
self.update_local_filelist()
}
(COMPONENT_EXPLORER_REMOTE, &MSG_KEY_BACKSPACE) => {
// Go to previous directory
@ -204,8 +184,7 @@ impl FileTransferActivity {
self.update_remote_filelist()
}
(COMPONENT_EXPLORER_REMOTE, &MSG_KEY_CHAR_I) => {
let file: Option<FsEntry> = self.get_remote_file_entry().cloned();
if let Some(file) = file {
if let SelectedEntry::One(file) = self.get_remote_selected_entries() {
self.mount_file_info(&file);
}
None
@ -324,9 +303,9 @@ impl FileTransferActivity {
self.finalize_find();
None
}
(COMPONENT_EXPLORER_FIND, Msg::OnSubmit(Payload::One(Value::Usize(idx)))) => {
(COMPONENT_EXPLORER_FIND, Msg::OnSubmit(_)) => {
// Find changedir
self.action_find_changedir(*idx);
self.action_find_changedir();
// Umount find
self.umount_find();
// Finalize find
@ -340,17 +319,12 @@ impl FileTransferActivity {
}
(COMPONENT_EXPLORER_FIND, &MSG_KEY_SPACE) => {
// Get entry
match self.view.get_state(COMPONENT_EXPLORER_FIND) {
Some(Payload::One(Value::Usize(idx))) => {
self.action_find_transfer(idx, None);
// Reload files
match self.browser.tab() {
// NOTE: swapped by purpose
FileExplorerTab::FindLocal => self.update_remote_filelist(),
FileExplorerTab::FindRemote => self.update_local_filelist(),
_ => None,
}
}
self.action_find_transfer(None);
// Reload files
match self.browser.tab() {
// NOTE: swapped by purpose
FileExplorerTab::FindLocal => self.update_remote_filelist(),
FileExplorerTab::FindRemote => self.update_local_filelist(),
_ => None,
}
}
@ -540,11 +514,7 @@ impl FileTransferActivity {
FileExplorerTab::Remote => self.action_remote_saveas(input.to_string()),
FileExplorerTab::FindLocal | FileExplorerTab::FindRemote => {
// Get entry
if let Some(Payload::One(Value::Usize(idx))) =
self.view.get_state(COMPONENT_EXPLORER_FIND)
{
self.action_find_transfer(idx, Some(input.to_string()));
}
self.action_find_transfer(Some(input.to_string()));
}
}
self.umount_saveas();
@ -579,7 +549,7 @@ impl FileTransferActivity {
if let Some(Payload::One(Value::Usize(idx))) =
self.view.get_state(COMPONENT_EXPLORER_FIND)
{
self.action_find_delete(idx);
self.action_find_delete();
// Reload entries
self.found_mut().unwrap().del_entry(idx);
self.update_find_list();