Skip to content

feat: integrate interactive annotations into main (+ CI binary-build fixes)#7

Merged
BenHuddart merged 9 commits into
mainfrom
feature/annotations-to-main
Jul 6, 2026
Merged

feat: integrate interactive annotations into main (+ CI binary-build fixes)#7
BenHuddart merged 9 commits into
mainfrom
feature/annotations-to-main

Conversation

@BenHuddart

Copy link
Copy Markdown
Owner

Why

The interactive-annotations feature (PR #2, feature/gui-annotations) never reached main: it was merged into the v1 branch (feature/pyside-gui-editor) 11 seconds after that branch had already been snapshotted into main via PR #1. So every release to date — including the v1.4.0 desktop build — shipped the older recognizer with none of the annotation work. Symptom: annotations don't parse correctly in the built app.

This brings that work onto current main via a real merge (Git auto-merged all code; the only textual conflict was one docs paragraph, resolved to keep both the GLE-setup and annotations tab descriptions).

What lands

From PR #2:

  • Interactive annotations — overlay on the preview (add / drag / edit / delete), a Texts panel with two-way selection sync, driven by a GLE print-based calibration protocol (gui/geometry.py, gui/annotations.py, gui/panels/texts_panel.py).
  • SVG vector preview by default (sticky PNG fallback).
  • Named data columns / editable sidecar headers in the Data dock.
  • Recognizer/writer hardening incl. real-file annotation recovery and the import-vs-reference data-safety invariant.

Also included (folds in PR #6)

The CI fixes required for this release to actually build installers — otherwise v1.5.0 would hit the same failures v1.4.0 did:

  • release.yml: actions: write so the release can dispatch the binary build (was HTTP 403).
  • .gitignore + packaging/gleplot.spec: the hand-authored spec was swallowed by the *.spec rule and never committed (build died with "Spec file not found").

PR #6 is superseded by this PR and can be closed.

Validation

  • Full suite: 1265 passed, 2 skipped (up from 1036 — ~230 new annotation/SVG/column tests run green alongside the GLE-setup tests). Both features verified to coexist in the auto-merged main_window.py / preview.py.
  • GUI --smoke-test passes; annotation + GLE-setup modules import cleanly.
  • CI binary build already verified on the fix branch (preview-windows / preview-macos-arm build + smoke-test green).

On merge: semantic-release cuts v1.5.0, which auto-dispatches release-binaries.yml and attaches the Windows .exe + macOS arm64 .dmg.

🤖 Generated with Claude Code

BenHuddart and others added 9 commits July 4, 2026 15:12
E1: GLE print-based calibration protocol injected into preview temp
scripts only; per-axes data/cm/pixel transforms with log-axis support
(PreviewGeometry, geometry_ready signal, never blocks rendering).

E2: SVG vector preview as default with QtSvg validation, sticky PNG
fallback and View-menu toggle; Cairo-safe font injection for SVG mode
(GLE default PostScript font silently truncates Cairo output at exit
0); frozen view_mapping contract for the annotation overlay.

E3: generated .dat sidecars carry sanitized named headers by default;
column_names round-trip through model/writer/recognizer; GLE auto-key
from headers neutralized with explicit key clauses (byte-identical
rendering verified).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
F1: AnnotationOverlay on the live preview - transparent hit-areas over
rendered text, drag with ghost and anti-jump sequencing around the
debounced re-render, mid-render drag preservation, inline editing,
add-text mode (shortcut T, Esc cancels), Delete removal, log-axis
inverse mapping, pan suspension while hovering items.

F2: TextsPanel property tab (content, position, color, size,
alignment; honest disabled state for fields GLE never renders).

MF integration: Texts tab wired with loop-free two-way selection sync
between panel and overlay, surviving re-render rebuilds, with
cross-axes retargeting.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… fix

G1: double-click header renaming for figure-owned sidecars with full
propagation (table, combos, series column_names, next save); external
referenced files stay read-only - gleplot never rewrites user source
data.

G2: guide sections for on-canvas annotations, preview rendering modes,
and named headers; README/rst sync; example regenerated with three
synthetic annotations, verified warning-free parse and real GLE
compile.

Fix: .gitignore ignored *.gle and data_*.dat repo-wide, so the shipped
example figure was never actually committed (docs referenced files
absent from clones). Negation patterns added; example files tracked.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Data safety (critical): import-vs-reference classification now trusts
only the gleplot metadata block; the filename heuristic is removed, so
hand-written .gle files can never cause gleplot to rewrite a user data
file (reviewer repro: md5-unchanged guarantee test). Loader: all-
missing first rows are data not headers; multi-word whitespace headers
fall back to positional names with a warning. Panel ownership resolves
by sidecar basename, fixing stale propagation after Save As.

Overlay: annotations disarm in read-only GLE-preview mode (drags there
mutated the hidden document); undo/redo actions stay authoritative in
preview mode; figure_replaced aborts active interactions (no phantom
items after undo mid-drag); mapping fingerprints abort drags across
PNG/SVG switches (no wrong-space commits); degenerate calibrations
(non-positive log bounds, zero ranges) are skipped with warnings, not
clamped; Texts panel rejects non-finite coordinates and no longer
clobbers focused editors; orphaned-dict commits drop silently.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Text clusters: set hei/color/just are now optional and sticky across
clusters (matching GLE interpreter semantics; writer suppresses
redundant set lines to keep the fixed point); blank lines between
clusters no longer abort recognition; TeX markup in write strings
round-trips byte-exact.

Column headers: GLE-style indexed comment blocks (! c N = name) are
recovered as column names with full-coverage validation and unicode
preserved; last-comment-line fallback retained; both display-only so
vouched sidecar round-trips stay byte-identical.

Texts panel: selection changes during list rebuilds are explicitly
guarded (spurious currentRowChanged during QListWidget.clear); remove
flow guard aligned; field-isolation audit encoded as tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts:
#	docs/guides/GUI_EDITOR.md
@BenHuddart BenHuddart merged commit 07a2d4c into main Jul 6, 2026
4 checks passed
@BenHuddart BenHuddart deleted the feature/annotations-to-main branch July 6, 2026 06:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant