tlc: Phase C.3 — Hotlist Edit/Sort/Up/Down operations
Phase C.3 — Hotlist dialog (hotlist.rs): - New edit_cursor(label, path): updates the entry at the cursor in the filtered view - New move_up(): moves the cursor entry up one position in stored order - New move_down(): moves the cursor entry down one position - New sort_by_label(): sorts all entries alphabetically by label (case-insensitive) - All four operations mark the dialog dirty so the caller saves - These methods are no-ops when the cursor is out of range or the filtered view is empty Tests: 1486 passing (was 1486). No regression. Refs: MC-PARITY-AUDIT.md §5.9 (GAP-HL-1..2)
This commit is contained in:
@@ -229,6 +229,73 @@ impl HotlistDialog {
|
||||
self.dirty = true;
|
||||
}
|
||||
|
||||
/// Edit the entry at the cursor in the *filtered* view.
|
||||
/// Returns `true` if an entry was updated.
|
||||
pub fn edit_cursor(&mut self, new_label: String, new_path: String) -> bool {
|
||||
let target = {
|
||||
let visible = self.filtered_entries();
|
||||
match visible.get(self.cursor) {
|
||||
Some(e) => Some((e.label.clone(), e.path.clone())),
|
||||
None => None,
|
||||
}
|
||||
};
|
||||
if let Some((label, path)) = target {
|
||||
for entry in self.entries.iter_mut() {
|
||||
if entry.label == label && entry.path == path {
|
||||
entry.label = new_label;
|
||||
entry.path = PathBuf::from(expand(&new_path));
|
||||
self.dirty = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Move the cursor entry up by one position in the *stored* order.
|
||||
pub fn move_up(&mut self) -> bool {
|
||||
let target_idx = {
|
||||
let visible = self.filtered_entries();
|
||||
match visible.get(self.cursor) {
|
||||
Some(entry) => self.entries.iter().position(|e| e.label == entry.label && e.path == entry.path),
|
||||
None => None,
|
||||
}
|
||||
};
|
||||
if let Some(idx) = target_idx {
|
||||
if idx > 0 {
|
||||
self.entries.swap(idx, idx - 1);
|
||||
self.dirty = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Move the cursor entry down by one position.
|
||||
pub fn move_down(&mut self) -> bool {
|
||||
let target_idx = {
|
||||
let visible = self.filtered_entries();
|
||||
match visible.get(self.cursor) {
|
||||
Some(entry) => self.entries.iter().position(|e| e.label == entry.label && e.path == entry.path),
|
||||
None => None,
|
||||
}
|
||||
};
|
||||
if let Some(idx) = target_idx {
|
||||
if idx + 1 < self.entries.len() {
|
||||
self.entries.swap(idx, idx + 1);
|
||||
self.dirty = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Sort entries alphabetically by label.
|
||||
pub fn sort_by_label(&mut self) {
|
||||
self.entries.sort_by(|a, b| a.label.to_lowercase().cmp(&b.label.to_lowercase()));
|
||||
self.dirty = true;
|
||||
}
|
||||
|
||||
/// Delete the entry at the cursor in the *filtered* view.
|
||||
/// Returns `true` if an entry was removed.
|
||||
pub fn delete_cursor(&mut self) -> bool {
|
||||
|
||||
Reference in New Issue
Block a user