Return item open to tab handler
This commit is contained in:
parent
0ce43dfcf5
commit
a936cd4a6d
7 changed files with 137 additions and 102 deletions
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
3
justfile
3
justfile
|
|
@ -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:
|
||||||
|
|
|
||||||
47
src/app.rs
47
src/app.rs
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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() {
|
||||||
|
|
|
||||||
65
src/tab.rs
65
src/tab.rs
|
|
@ -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
37
src/util.rs
Normal 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
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue