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 <noreply@anthropic.com>
This commit is contained in:
2026-09-09 08:20:09 +03:00
co-authored by Claude Opus 4.6
parent 4591353453
commit 61888396a5
2 changed files with 40 additions and 5 deletions
+1 -1
View File
@@ -8,7 +8,7 @@ so later rebinding would only ever be seen by the module that did it.
import configparser import configparser
import os 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") PROPERTIES_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "editor.properties")
DEFAULT_GRID_SIZE = 10 DEFAULT_GRID_SIZE = 10
DEFAULT_ADD_TIMESTAMP = True DEFAULT_ADD_TIMESTAMP = True
+39 -4
View File
@@ -21,12 +21,14 @@ from tkinter import messagebox, ttk
import app_state import app_state
import palette import palette
import sax_file import sax_file
import schema
NOT_DECLARED = "—" # em dash, for a column with nothing to report NOT_DECLARED = "—" # em dash, for a column with nothing to report
NO_CHECKSUM = "(no checksum)" NO_CHECKSUM = "(no checksum)"
REMOVE_ACTION = "REMOVE from app" REMOVE_ACTION = "REMOVE from app"
SECTION_TAG = "section" SECTION_TAG = "section"
UNAVAILABLE_TAG = "unavailable"
CHECKBOX_SIZE = 13 CHECKBOX_SIZE = 13
@@ -128,10 +130,17 @@ def collect_rows():
required = sax_file.required_kit_names() required = sax_file.required_kit_names()
installed = palette.list_kits() 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] 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 = [ groups = [
("Installed kits", [ ("Installed kits", [
(name, checksum) for name, checksum in declared if name in required (name, checksum) for name, checksum in declared if name in required
@@ -139,7 +148,7 @@ def collect_rows():
("Installed but not used kits", [ ("Installed but not used kits", [
(name, checksum) for name, checksum in declared if name not in required (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 = [] rows = []
@@ -173,9 +182,30 @@ def collect_rows():
"latest_text": column_label(*latest) if latest else NOT_DECLARED, "latest_text": column_label(*latest) if latest else NOT_DECLARED,
"options": options, "options": options,
"choice": 0, "choice": 0,
# The tick reflects the file as it stands: declared kits start ticked.
"checked": is_declared, "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 return rows
@@ -239,6 +269,7 @@ class KitsPanel:
self.table.pack(fill=tk.BOTH, expand=True) self.table.pack(fill=tk.BOTH, expand=True)
self.table.tag_configure(SECTION_TAG, background="#dcdcdc") self.table.tag_configure(SECTION_TAG, background="#dcdcdc")
self.table.tag_configure(UNAVAILABLE_TAG, foreground="#999999")
self.boxes = { self.boxes = {
(True, True): make_checkbox_image(True, True), (True, True): make_checkbox_image(True, True),
@@ -315,8 +346,10 @@ class KitsPanel:
"", "end", values=(row["section"], "", "", ""), tags=(SECTION_TAG,), "", "end", values=(row["section"], "", "", ""), tags=(SECTION_TAG,),
) )
continue continue
tags = (UNAVAILABLE_TAG,) if row.get("unavailable") else ()
item = self.table.insert( item = self.table.insert(
"", "end", image=self._row_image(row), values=self._row_values(row), "", "end", image=self._row_image(row), values=self._row_values(row),
tags=tags,
) )
self.row_by_item[item] = row self.row_by_item[item] = row
@@ -378,6 +411,8 @@ class KitsPanel:
item = self.table.identify_row(event.y) item = self.table.identify_row(event.y)
if item not in self.row_by_item: if item not in self.row_by_item:
return return
if self.row_by_item[item].get("unavailable"):
return
column = self.table.identify_column(event.x) column = self.table.identify_column(event.x)
if column == "#0": if column == "#0":