Return item open to tab handler

This commit is contained in:
Jeremy Soller 2024-02-26 14:11:45 -07:00
parent 0ce43dfcf5
commit a936cd4a6d
7 changed files with 137 additions and 102 deletions

View file

@ -17,9 +17,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Message { pub enum Message {
DialogMessage(DialogMessage), DialogMessage(DialogMessage),
DialogOpen, DialogOpen(DialogKind),
DialogResult(DialogResult), DialogResult(DialogResult),
DialogSave,
} }
pub struct App { pub struct App {
@ -61,10 +60,10 @@ impl Application for App {
return dialog.update(dialog_message); return dialog.update(dialog_message);
} }
} }
Message::DialogOpen => { Message::DialogOpen(dialog_kind) => {
if self.dialog_opt.is_none() { if self.dialog_opt.is_none() {
let (dialog, command) = Dialog::new( let (dialog, command) = Dialog::new(
DialogKind::OpenFile, dialog_kind,
None, None,
Message::DialogMessage, Message::DialogMessage,
Message::DialogResult, Message::DialogResult,
@ -77,20 +76,6 @@ impl Application for App {
self.dialog_opt = None; self.dialog_opt = None;
self.result_opt = Some(result); self.result_opt = Some(result);
} }
Message::DialogSave => {
if self.dialog_opt.is_none() {
let (dialog, command) = Dialog::new(
DialogKind::SaveFile {
filename: "README.md".to_string(),
},
None,
Message::DialogMessage,
Message::DialogResult,
);
self.dialog_opt = Some(dialog);
return command;
}
}
} }
Command::none() Command::none()
@ -106,16 +91,39 @@ impl Application for App {
fn view(&self) -> Element<Message> { fn view(&self) -> Element<Message> {
let mut column = widget::column().spacing(8); let mut column = widget::column().spacing(8);
{ {
let mut button = widget::button::standard("Open Dialog"); let mut button = widget::button::standard("Open File");
if self.dialog_opt.is_none() { if self.dialog_opt.is_none() {
button = button.on_press(Message::DialogOpen); button = button.on_press(Message::DialogOpen(DialogKind::OpenFile));
} }
column = column.push(button); column = column.push(button);
} }
{ {
let mut button = widget::button::standard("Save Dialog"); let mut button = widget::button::standard("Open Multiple Files");
if self.dialog_opt.is_none() { if self.dialog_opt.is_none() {
button = button.on_press(Message::DialogSave); button = button.on_press(Message::DialogOpen(DialogKind::OpenMultipleFiles));
}
column = column.push(button);
}
{
let mut button = widget::button::standard("Open Folder");
if self.dialog_opt.is_none() {
button = button.on_press(Message::DialogOpen(DialogKind::OpenFolder));
}
column = column.push(button);
}
{
let mut button = widget::button::standard("Open Multiple Folders");
if self.dialog_opt.is_none() {
button = button.on_press(Message::DialogOpen(DialogKind::OpenMultipleFolders));
}
column = column.push(button);
}
{
let mut button = widget::button::standard("Save File");
if self.dialog_opt.is_none() {
button = button.on_press(Message::DialogOpen(DialogKind::SaveFile {
filename: "test".to_string()
}));
} }
column = column.push(button); column = column.push(button);
} }

View file

@ -50,8 +50,7 @@ check-json: (check '--message-format=json')
dev *args: dev *args:
cargo fmt cargo fmt
cargo test cargo test
cargo build --profile release-with-debug just run {{args}}
env RUST_LOG=cosmic_files=debug RUST_BACKTRACE=full target/release-with-debug/cosmic-files {{args}}
# Run with debug logs # Run with debug logs
run *args: run *args:

View file

@ -30,6 +30,7 @@ use crate::{
fl, home_dir, fl, home_dir,
key_bind::{key_binds, KeyBind}, key_bind::{key_binds, KeyBind},
menu, menu,
util,
operation::Operation, operation::Operation,
tab::{self, ItemMetadata, Location, Tab}, tab::{self, ItemMetadata, Location, Tab},
}; };
@ -850,29 +851,47 @@ impl Application for App {
Message::TabMessage(entity_opt, tab_message) => { Message::TabMessage(entity_opt, tab_message) => {
let entity = entity_opt.unwrap_or_else(|| self.tab_model.active()); let entity = entity_opt.unwrap_or_else(|| self.tab_model.active());
//TODO: move to Command?
if let tab::Message::ContextMenu(_point_opt) = tab_message { if let tab::Message::ContextMenu(_point_opt) = tab_message {
// Disable side context page // Disable side context page
self.core.window.show_context = false; self.core.window.show_context = false;
} }
let tab_command = match self.tab_model.data_mut::<Tab>(entity) { let tab_commands = match self.tab_model.data_mut::<Tab>(entity) {
Some(tab) => tab.update(tab_message, self.modifiers), Some(tab) => tab.update(tab_message, self.modifiers),
_ => tab::Command::None, _ => Vec::new(),
}; };
match tab_command {
tab::Command::None => {} let mut commands = Vec::new();
tab::Command::Action(action) => { for tab_command in tab_commands {
return self.update(action.message(Some(entity))); match tab_command {
} tab::Command::Action(action) => {
tab::Command::ChangeLocation(tab_title, tab_path) => { commands.push(self.update(action.message(Some(entity))));
self.tab_model.text_set(entity, tab_title); }
return Command::batch([ tab::Command::ChangeLocation(tab_title, tab_path) => {
self.update_title(), self.tab_model.text_set(entity, tab_title);
self.update_watcher(), commands.push(Command::batch([
self.rescan_tab(entity, tab_path), self.update_title(),
]); self.update_watcher(),
self.rescan_tab(entity, tab_path),
]));
}
tab::Command::OpenFile(item_path) => {
let mut command = util::open_command(&item_path);
match command.spawn() {
Ok(_) => (),
Err(err) => {
log::warn!(
"failed to open {:?}: {}",
item_path,
err
);
}
}
}
} }
} }
return Command::batch(commands);
} }
Message::TabNew => { Message::TabNew => {
let active = self.tab_model.active(); let active = self.tab_model.active();

View file

@ -53,6 +53,10 @@ impl DialogKind {
} }
} }
pub fn is_dir(&self) -> bool {
matches!(self, Self::OpenFolder | Self::OpenMultipleFolders)
}
pub fn multiple(&self) -> bool { pub fn multiple(&self) -> bool {
matches!(self, Self::OpenMultipleFiles | Self::OpenMultipleFolders) matches!(self, Self::OpenMultipleFiles | Self::OpenMultipleFolders)
} }
@ -456,6 +460,14 @@ impl Application for App {
if !paths.is_empty() { if !paths.is_empty() {
self.result_opt = Some(DialogResult::Open(paths)); self.result_opt = Some(DialogResult::Open(paths));
return window::close(self.main_window_id()); return window::close(self.main_window_id());
} else if self.flags.kind.is_dir() {
match &self.tab.location {
Location::Path(tab_path) => {
self.result_opt = Some(DialogResult::Open(vec![tab_path.clone()]));
return window::close(self.main_window_id());
},
_ => {}
}
} }
} }
Message::Save => { Message::Save => {
@ -479,7 +491,7 @@ impl Application for App {
_ => None, _ => None,
}; };
let tab_command = self.tab.update(tab_message, self.modifiers); let tab_commands = self.tab.update(tab_message, self.modifiers);
// Update filename box when anything is selected // Update filename box when anything is selected
if let DialogKind::SaveFile { filename } = &mut self.flags.kind { if let DialogKind::SaveFile { filename } = &mut self.flags.kind {
@ -494,15 +506,21 @@ impl Application for App {
} }
} }
match tab_command { let mut commands = Vec::new();
tab::Command::None => {} for tab_command in tab_commands {
tab::Command::Action(action) => { match tab_command {
log::warn!("Action {:?} not supported in dialog", action); tab::Command::Action(action) => {
} log::warn!("Action {:?} not supported in dialog", action);
tab::Command::ChangeLocation(_tab_title, _tab_path) => { }
return Command::batch([self.update_watcher(), self.rescan_tab()]); tab::Command::ChangeLocation(_tab_title, _tab_path) => {
commands.push(Command::batch([self.update_watcher(), self.rescan_tab()]));
}
tab::Command::OpenFile(_item_path) => {
commands.push(self.update(Message::Open));
}
} }
} }
return Command::batch(commands);
} }
Message::TabRescan(mut items) => { Message::TabRescan(mut items) => {
// Select based on filename // Select based on filename

View file

@ -20,6 +20,7 @@ mod mime_icon;
mod mouse_area; mod mouse_area;
mod operation; mod operation;
mod tab; mod tab;
mod util;
pub fn home_dir() -> PathBuf { pub fn home_dir() -> PathBuf {
match dirs::home_dir() { match dirs::home_dir() {

View file

@ -162,42 +162,6 @@ fn hidden_attribute(metadata: &Metadata) -> bool {
metadata.file_attributes() & FILE_ATTRIBUTE_HIDDEN == FILE_ATTRIBUTE_HIDDEN metadata.file_attributes() & FILE_ATTRIBUTE_HIDDEN == FILE_ATTRIBUTE_HIDDEN
} }
#[cfg(target_os = "linux")]
fn open_command(path: &PathBuf) -> process::Command {
let mut command = process::Command::new("xdg-open");
command.arg(path);
command
}
#[cfg(target_os = "macos")]
fn open_command(path: &PathBuf) -> process::Command {
let mut command = process::Command::new("open");
command.arg(path);
command
}
#[cfg(target_os = "redox")]
fn open_command(path: &PathBuf) -> process::Command {
let mut command = process::Command::new("launcher");
command.arg(path);
command
}
#[cfg(target_os = "windows")]
fn open_command(path: &PathBuf) -> process::Command {
use std::os::windows::process::CommandExt;
let mut command = process::Command::new("cmd");
command
.arg("/c")
.arg("start")
.raw_arg("\"\"")
.arg(path)
.creation_flags(0x08000000);
command
}
pub fn scan_path(tab_path: &PathBuf, sizes: IconSizes) -> Vec<Item> { pub fn scan_path(tab_path: &PathBuf, sizes: IconSizes) -> Vec<Item> {
let mut items = Vec::new(); let mut items = Vec::new();
match fs::read_dir(tab_path) { match fs::read_dir(tab_path) {
@ -392,9 +356,9 @@ impl Location {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Command { pub enum Command {
None,
Action(Action), Action(Action),
ChangeLocation(String, Location), ChangeLocation(String, Location),
OpenFile(PathBuf),
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@ -612,7 +576,8 @@ impl Tab {
} }
} }
pub fn update(&mut self, message: Message, modifiers: Modifiers) -> Command { pub fn update(&mut self, message: Message, modifiers: Modifiers) -> Vec<Command> {
let mut commands = Vec::new();
let mut cd = None; let mut cd = None;
let mut history_i_opt = None; let mut history_i_opt = None;
match message { match message {
@ -626,19 +591,10 @@ impl Tab {
match self.location { match self.location {
Location::Path(_) => { Location::Path(_) => {
if item.path.is_dir() { if item.path.is_dir() {
//TODO: allow opening multiple tabs?
cd = Some(Location::Path(item.path.clone())); cd = Some(Location::Path(item.path.clone()));
} else if !self.dialog.is_some() { } else {
let mut command = open_command(&item.path); commands.push(Command::OpenFile(item.path.clone()));
match command.spawn() {
Ok(_) => (),
Err(err) => {
log::warn!(
"failed to open {:?}: {}",
item.path,
err
);
}
}
} }
} }
Location::Trash => { Location::Trash => {
@ -669,7 +625,7 @@ impl Tab {
// Close context menu // Close context menu
self.context_menu = None; self.context_menu = None;
return Command::Action(action); commands.push(Command::Action(action));
} }
Message::ContextMenu(point_opt) => { Message::ContextMenu(point_opt) => {
self.context_menu = point_opt; self.context_menu = point_opt;
@ -795,13 +751,10 @@ impl Tab {
self.history_i = self.history.len(); self.history_i = self.history.len();
self.history.push(location.clone()); self.history.push(location.clone());
} }
Command::ChangeLocation(self.title(), location) commands.push(Command::ChangeLocation(self.title(), location));
} else {
Command::None
} }
} else {
Command::None
} }
commands
} }
pub fn location_view(&self, core: &Core) -> Element<Message> { pub fn location_view(&self, core: &Core) -> Element<Message> {

37
src/util.rs Normal file
View file

@ -0,0 +1,37 @@
use std::{path::PathBuf, process};
#[cfg(target_os = "linux")]
pub fn open_command(path: &PathBuf) -> process::Command {
let mut command = process::Command::new("xdg-open");
command.arg(path);
command
}
#[cfg(target_os = "macos")]
pub fn open_command(path: &PathBuf) -> process::Command {
let mut command = process::Command::new("open");
command.arg(path);
command
}
#[cfg(target_os = "redox")]
pub fn open_command(path: &PathBuf) -> process::Command {
let mut command = process::Command::new("launcher");
command.arg(path);
command
}
#[cfg(target_os = "windows")]
pub fn open_command(path: &PathBuf) -> process::Command {
use std::os::windows::process::CommandExt;
let mut command = process::Command::new("cmd");
command
.arg("/c")
.arg("start")
.raw_arg("\"\"")
.arg(path)
.creation_flags(0x08000000);
command
}