W29: Confirmation dialog (P1 audit gap)
The F9 audit found that Cmd::OptionsConfirm was a single-boolean toggle (cycle on/off) instead of MC's proper confirmation dialog with per-operation checkboxes. The ConfirmDialog already existed in confirm_dialog.rs with 4 toggles (delete, overwrite, execute, exit) but wasn't wired into the F9 menu. Wire the existing ConfirmDialog: - DialogState::Confirm(Box<ConfirmDialog>) variant - Cmd::OptionsConfirm now opens the dialog pre-populated with the current safe_delete / safe_execute settings - Dispatch handler processes ConfirmResult::Confirm by saving the settings to runtime.safe_delete / safe_execute - Added RuntimeConfig::safe_execute field with default Some(false) - Added dialog_title() and render() arms for DialogState::Confirm Tests: 1393 pass, zero warnings.
This commit is contained in:
@@ -306,6 +306,8 @@ pub struct RuntimeConfig {
|
||||
pub auto_save_setup: Option<bool>,
|
||||
/// Require an explicit confirmation before delete.
|
||||
pub safe_delete: Option<bool>,
|
||||
/// Require an explicit confirmation before executing commands.
|
||||
pub safe_execute: Option<bool>,
|
||||
/// Pause and display output after a shell command finishes.
|
||||
pub pause_after_run: Option<bool>,
|
||||
}
|
||||
@@ -326,6 +328,7 @@ impl Default for RuntimeConfig {
|
||||
verbose_ops: Some(false),
|
||||
auto_save_setup: Some(false),
|
||||
safe_delete: Some(true),
|
||||
safe_execute: Some(false),
|
||||
pause_after_run: Some(false),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -985,6 +985,7 @@ Err(e) => self.status.set_error(format!("view: {e}")),
|
||||
| Some(DialogState::Encoding(_))
|
||||
| Some(DialogState::Connection(_))
|
||||
| Some(DialogState::Sort(_))
|
||||
| Some(DialogState::Confirm(_))
|
||||
| Some(DialogState::Progress(_)) => {
|
||||
// These are closed by their own apply_*_outcome
|
||||
// helpers before this function is called; they
|
||||
@@ -1420,6 +1421,7 @@ fn dialog_label(d: &DialogState) -> String {
|
||||
DialogState::Encoding(_) => "Display encoding".to_string(),
|
||||
DialogState::Connection(_) => "Network connection".to_string(),
|
||||
DialogState::Sort(_) => "Sort order".to_string(),
|
||||
DialogState::Confirm(_) => "Confirmation".to_string(),
|
||||
DialogState::Progress(_) => "Progress".to_string(),
|
||||
}
|
||||
}
|
||||
@@ -951,6 +951,29 @@ impl FileManager {
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
Some(DialogState::Confirm(d)) => {
|
||||
use crate::filemanager::confirm_dialog::ConfirmResult;
|
||||
let r = d.handle_key(key);
|
||||
match r {
|
||||
ConfirmResult::Confirm(settings) => {
|
||||
self.runtime.safe_delete = Some(settings.confirm_delete);
|
||||
self.runtime.safe_execute = Some(settings.confirm_execute);
|
||||
self.status.set_message(format!(
|
||||
"Confirm: delete={} overwrite={} execute={} exit={}",
|
||||
if settings.confirm_delete { "ON" } else { "off" },
|
||||
if settings.confirm_overwrite { "ON" } else { "off" },
|
||||
if settings.confirm_execute { "ON" } else { "off" },
|
||||
if settings.confirm_exit { "ON" } else { "off" },
|
||||
));
|
||||
self.dialog = None;
|
||||
}
|
||||
ConfirmResult::Cancel => {
|
||||
self.dialog = None;
|
||||
}
|
||||
ConfirmResult::Running => {}
|
||||
}
|
||||
consumed = true;
|
||||
}
|
||||
None => return false,
|
||||
}
|
||||
// Apply captured outcomes.
|
||||
|
||||
@@ -356,6 +356,8 @@ pub enum DialogState {
|
||||
Connection(Box<ConnectionDialog>),
|
||||
/// Alt-Shift-T — sort order dialog.
|
||||
Sort(Box<sort_dialog::SortDialog>),
|
||||
/// F9 → Options → Confirmation — per-operation confirm toggles.
|
||||
Confirm(Box<confirm_dialog::ConfirmDialog>),
|
||||
/// F5/F6/F8 — live progress dialog for background copy/move/delete.
|
||||
Progress(Box<crate::ops::progress::ProgressDialog>),
|
||||
}
|
||||
@@ -418,6 +420,7 @@ impl DialogState {
|
||||
DialogState::Encoding(_) => false,
|
||||
DialogState::Connection(_) => false,
|
||||
DialogState::Sort(_) => false,
|
||||
DialogState::Confirm(_) => false,
|
||||
DialogState::Progress(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,6 +180,7 @@ impl FileManager {
|
||||
DialogState::Encoding(d) => d.render(frame, dialog_area, &self.theme),
|
||||
DialogState::Connection(d) => d.render(frame, dialog_area, &self.theme),
|
||||
DialogState::Sort(d) => d.render(frame, dialog_area, &self.theme),
|
||||
DialogState::Confirm(d) => d.render(frame, dialog_area, &self.theme),
|
||||
DialogState::Progress(d) => d.render(frame, dialog_area, &self.theme),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user