From b05021a218af1226b943503c9ed488220dc594a4 Mon Sep 17 00:00:00 2001
From: Maximilian Moser <maximilian.moser@tuwien.ac.at>
Date: Mon, 26 Feb 2024 12:42:27 +0100
Subject: [PATCH] Enable active management of formats

* allow marking focussed format as (E)ndangered or (S)afe
---
 formatscaper/resultman.py | 49 ++++++++++++++++++++++++++++-----------
 1 file changed, 36 insertions(+), 13 deletions(-)

diff --git a/formatscaper/resultman.py b/formatscaper/resultman.py
index ac03853..f21affd 100755
--- a/formatscaper/resultman.py
+++ b/formatscaper/resultman.py
@@ -2,11 +2,12 @@
 
 import argparse
 import enum
+from typing import Optional
 
 import urwid as uw
 from urwid.command_map import Command
 
-from core.utils import Format, load_formats, load_results
+from core.utils import Format, load_formats, load_results, store_formats
 
 
 # helper functions
@@ -20,6 +21,22 @@ def fallback_key_handler(key: str) -> None:
         # as this action only makes sense then
         columns.set_focus(left)
 
+    elif key in ["S", "E"]:
+        # formats_list is a ScrollBar wrapping a ListBox for the buttons
+        selected = formats_list.original_widget.focus
+
+        if selected is not None:
+            # each SimpleButton has a format and is wrapped in an AttrMap
+            format = selected.original_widget.format
+            new_value = key == "E"
+
+            if format.endangered != new_value:
+                global formats_modified
+
+                selected.set_attr_map({None: "endangered" if new_value else "safe"})
+                format.endangered = new_value
+                formats_modified = True
+
 
 class FormatFilter(enum.Enum):
     """Filter settings for file formats."""
@@ -44,6 +61,7 @@ class SimpleButton(uw.Button):
 
     button_left = uw.Text("*")
     button_right = uw.Text(" ")
+    format: Optional[Format] = None
 
 
 # parsing CLI arguments
@@ -78,7 +96,7 @@ current_filter = FormatFilter(args.filter)
 
 
 # loading formats & results
-formats, all_results = [], []
+formats, formats_modified, all_results, format_record_files = [], False, [], {}
 try:
     formats = list(load_formats(args.formats).values())
 except Exception as e:
@@ -106,6 +124,7 @@ palette = [
     ("darkbg", "", "black"),
     ("reversed", "bold,standout", ""),
     ("endangered", "white", "dark red"),
+    ("safe", "", "black"),
 ]
 
 uw.command_map["j"] = Command.DOWN
@@ -207,31 +226,32 @@ def create_format_buttons(filter: FormatFilter):
         elif filter == FormatFilter.SAFE and format.endangered:
             continue
 
-        attribute = "endangered" if format.endangered else "darkbg"
+        attribute = "endangered" if format.endangered else "safe"
         button = SimpleButton(format.name)
+        button.format = format
         uw.connect_signal(button, "click", handle_select_format, user_args=[format])
         format_buttons.append(uw.AttrMap(button, attribute, focus_map="reversed"))
 
     return format_buttons
 
 
-formats = uw.ScrollBar(
+formats_list = uw.ScrollBar(
     uw.ListBox(uw.SimpleFocusListWalker(create_format_buttons(current_filter)))
 )
-formats._command_map["l"] = "activate"
+formats_list._command_map["l"] = "activate"
 formats_label = uw.Filler(uw.AttrMap(uw.Text("FORMATS", align="center"), "border"))
-left = uw.Pile([("pack", formats_label), formats])
+left = uw.Pile([("pack", formats_label), formats_list])
 
 help_text = f"""
 Formatscaper results manager help
 
-Up/Down/j/k/^d/^u: navigate up and down
-Enter/Space/l: select current format
-Esc/h/q: go back to formats list
-Q: quit
-
-
------------------------------
++---------------------------------------------------------------+
+| Up/Down/j/k/^d/^u:   navigate up and down                     |
+| Enter/Space/l:       select current format                    |
+| Esc/h/q:             go back to formats list                  |
+| S/E:                 mark focussed format as safe/endangered  |
+| Q/^c:                quit with/without saving changes         |
++---------------------------------------------------------------+
 
 Loaded {len(all_results):,} results for {len(format_record_files):,} formats
 """
@@ -250,5 +270,8 @@ loop = uw.MainLoop(top, palette, unhandled_input=fallback_key_handler)
 
 try:
     loop.run()
+    if formats_modified:
+        store_formats(formats, args.formats)
+
 except KeyboardInterrupt:
     loop.stop()
-- 
GitLab