diff --git a/app_state.py b/app_state.py index e33761a..7dc62fe 100644 --- a/app_state.py +++ b/app_state.py @@ -8,7 +8,7 @@ so later rebinding would only ever be seen by the module that did it. import configparser import os -VERSION = "0.0.0.068" +VERSION = "0.0.0.069" PROPERTIES_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "editor.properties") DEFAULT_GRID_SIZE = 10 DEFAULT_ADD_TIMESTAMP = True diff --git a/manage_kits.py b/manage_kits.py index 6145753..ac3268e 100644 --- a/manage_kits.py +++ b/manage_kits.py @@ -21,12 +21,14 @@ from tkinter import messagebox, ttk import app_state import palette import sax_file +import schema NOT_DECLARED = "—" # em dash, for a column with nothing to report NO_CHECKSUM = "(no checksum)" REMOVE_ACTION = "REMOVE from app" SECTION_TAG = "section" +UNAVAILABLE_TAG = "unavailable" CHECKBOX_SIZE = 13 @@ -128,10 +130,17 @@ def collect_rows(): required = sax_file.required_kit_names() installed = palette.list_kits() - # A kit the schema declares but Sedona home does not hold still gets a row: it is the - # clearest place to see that the file points at something missing. others = [name for name in installed if name not in declared_names] + suitable = [] + unsuitable = [] + for name in others: + deps = schema.read_kit_dependencies(name) + if all(d in declared_names for d in deps): + suitable.append(name) + else: + unsuitable.append(name) + groups = [ ("Installed kits", [ (name, checksum) for name, checksum in declared if name in required @@ -139,7 +148,7 @@ def collect_rows(): ("Installed but not used kits", [ (name, checksum) for name, checksum in declared if name not in required ]), - ("Kits to be installed", [(name, None) for name in others]), + ("Kits available on the computer", [(name, None) for name in suitable]), ] rows = [] @@ -173,9 +182,30 @@ def collect_rows(): "latest_text": column_label(*latest) if latest else NOT_DECLARED, "options": options, "choice": 0, - # The tick reflects the file as it stands: declared kits start ticked. "checked": is_declared, + "unavailable": False, }) + + if unsuitable: + rows.append({"section": "Other kits on the computer (dependencies not in app)"}) + for name in unsuitable: + builds = palette.kit_builds(name) + latest = builds[0] if builds else None + rows.append({ + "kit": name, + "declared": False, + "required": False, + "checksum": None, + "builds": builds, + "latest": latest, + "installed_text": NOT_DECLARED, + "latest_text": column_label(*latest) if latest else NOT_DECLARED, + "options": [("Not available", None)], + "choice": 0, + "checked": False, + "unavailable": True, + }) + return rows @@ -239,6 +269,7 @@ class KitsPanel: self.table.pack(fill=tk.BOTH, expand=True) self.table.tag_configure(SECTION_TAG, background="#dcdcdc") + self.table.tag_configure(UNAVAILABLE_TAG, foreground="#999999") self.boxes = { (True, True): make_checkbox_image(True, True), @@ -315,8 +346,10 @@ class KitsPanel: "", "end", values=(row["section"], "", "", ""), tags=(SECTION_TAG,), ) continue + tags = (UNAVAILABLE_TAG,) if row.get("unavailable") else () item = self.table.insert( "", "end", image=self._row_image(row), values=self._row_values(row), + tags=tags, ) self.row_by_item[item] = row @@ -378,6 +411,8 @@ class KitsPanel: item = self.table.identify_row(event.y) if item not in self.row_by_item: return + if self.row_by_item[item].get("unavailable"): + return column = self.table.identify_column(event.x) if column == "#0":