Add user-defined context actions
This commit is contained in:
parent
23b5d98dcc
commit
39281a6336
8 changed files with 305 additions and 9 deletions
83
src/context_action.rs
Normal file
83
src/context_action.rs
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{mime_app, spawn_detached::spawn_detached};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
|
||||
pub enum ContextActionSelection {
|
||||
#[default]
|
||||
#[serde(alias = "any")]
|
||||
Any,
|
||||
#[serde(alias = "files")]
|
||||
Files,
|
||||
#[serde(alias = "folders")]
|
||||
Folders,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
|
||||
#[serde(default)]
|
||||
pub struct ContextActionPreset {
|
||||
pub name: String,
|
||||
pub confirm: bool,
|
||||
pub selection: ContextActionSelection,
|
||||
pub steps: Vec<String>,
|
||||
}
|
||||
|
||||
impl ContextActionPreset {
|
||||
pub fn matches_selection(&self, selected: usize, selected_dir: usize) -> bool {
|
||||
if selected == 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
match self.selection {
|
||||
ContextActionSelection::Any => true,
|
||||
ContextActionSelection::Files => selected_dir == 0,
|
||||
ContextActionSelection::Folders => selected_dir == selected,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(&self, paths: &[PathBuf]) {
|
||||
if self.steps.is_empty() {
|
||||
log::warn!("context action {:?} has no steps", self.name);
|
||||
return;
|
||||
}
|
||||
|
||||
for step in &self.steps {
|
||||
let Some(commands) = mime_app::exec_to_command(step, paths) else {
|
||||
log::warn!(
|
||||
"failed to parse context action {:?}: invalid Exec {:?}",
|
||||
self.name,
|
||||
step
|
||||
);
|
||||
return;
|
||||
};
|
||||
|
||||
for mut command in commands {
|
||||
if let Err(err) = spawn_detached(&mut command) {
|
||||
log::warn!(
|
||||
"failed to run context action {:?} step {:?}: {}",
|
||||
self.name,
|
||||
step,
|
||||
err
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn action_name(actions: &[ContextActionPreset], action: usize) -> Option<String> {
|
||||
actions.get(action).map(|preset| preset.name.clone())
|
||||
}
|
||||
|
||||
pub fn run(actions: &[ContextActionPreset], action: usize, paths: &[PathBuf]) {
|
||||
if let Some(preset) = actions.get(action) {
|
||||
preset.run(paths);
|
||||
} else {
|
||||
log::warn!("invalid context action index `{action}`");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue