From 61888396a5ff2b32d8def44aa1f5fc6be2fb0cb4 Mon Sep 17 00:00:00 2001 From: "arda.aydin@ontrol.com.tr" Date: Wed, 9 Sep 2026 08:20:09 +0300 Subject: [PATCH] Kit Manager: split available kits by dependency compatibility Renamed "Kits to be installed" to "Kits available on the computer" for kits whose dependencies are all in the app. Kits with unmet dependencies go into a greyed-out "Other kits on the computer" section that cannot be selected or ticked. Co-Authored-By: Claude Opus 4.6 --- app_state.py | 2 +- manage_kits.py | 43 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 5 deletions(-) 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":