Commit Graph

20 Commits

Author SHA1 Message Date
ispyisail ce6a88c98c Fix the MSVC build: QPrinter built through ?: in live mode print
MSVC stopped with C2280 at liveserver.cpp:861 (issue #1333): it copies
the result of the ?: expression, and QPrinter cannot be copied. GCC and
Clang build the object in place under C++17, so Linux and CI built.

QPrinter(info) gives the same printer in both cases: info is only set
when printing to a printer, and QPrinter() itself constructs with an
empty QPrinterInfo (qprinter.cpp, QPrinter::QPrinter(PrinterMode)).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 22:32:43 +13:00
ispyisail 16173c2070 Merge pull request #1316 from ispyisail/perf/live-timing
Add an optional timing log for live mode
2026-10-05 22:14:50 +13:00
ispyisail db9ba6c1ca Merge remote-tracking branch 'upstream/master' into perf/live-timing
# Conflicts:
#	sources/scripting/liveserver.cpp
2026-10-05 21:36:17 +13:00
ispyisail 33f7d27388 Merge remote-tracking branch 'upstream/master' into feature/live-remember
# Conflicts:
#	lang/qet_en.ts
2026-10-05 21:35:52 +13:00
ispyisail 0bb0ea225f Live mode print: draw at 96 dpi, as the PDF export does
At the printer's own resolution (600-1200 dpi) symbols and texts were
replayed many times too big next to the wires and grid. Seen on a test
print to PDF; the same page now matches qet_export's PDF.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 20:34:14 +13:00
ispyisail 0df8ca5b3c Live mode: print, save/close, changes, snapshot; house-style layout rules; saved symbol index
QElectroTech (LiveServer):
- print: folios to the default (or a named) printer with no print dialog,
  always after asking the user (paper cannot be undone); or to a new PDF
  file. Rendered as the PDF export draws a folio (no grid, no terminals).
- save_project (own file, or save as a new file, never over one) and
  close_project (only without unsaved changes: never discards work).
- changes: the undo history, each step marked assistant or user, with
  "since" to ask what changed after a point.
- snapshot: a copy of the open project as on screen, for a check to read,
  without saving it or changing its file.
- qet.elementTextGeometry(): where a symbol's text is drawn on the folio.

qet MCP server:
- qet_live_print, qet_live_save_project, qet_live_close_project,
  qet_live_changes, qet_live_layout_check (snapshot + qet_layout_check, no
  "run this script?" window); write paths never overwrite.
- Layout rules from the house style, for file and live checks alike:
  label_on_wire, four_way_junction, misaligned_branch.
- The element index is saved under ~/.cache/qet-mcp: a new server process
  loads 8839 symbols in 0.4 s instead of parsing them for 6.9 s; the
  change check is a third faster.
- qet_about lists the installation's standard symbols
  (standard-symbols.json in QElectroTech's data folder) when there are any.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 20:34:14 +13:00
ispyisail 550dcdda71 Live mode: remember the start warning and "always" across restarts
Live mode asked at every start (the "Mode direct" warning) and forgot
"always" for scripts when QElectroTech closed, so a user who works
with an assistant every day re-enabled it every day. Both are now
opt-in and remembered: the warning has a "Ne plus demander au
démarrage" checkbox (scripting/live_skip_warning), and the ask-first
choice is saved (scripting/live_ask_first; the Assistant panel's
checkbox and "Toujours" in the script window). The status bar still
shows live mode whenever it is open. Switching live mode off in the
settings clears "don't ask again", so turning it back on warns again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 19:11:47 +13:00
ispyisail ad20eb94ba Live mode: open a saved project, switch between open projects
open_project opens a .qet and makes it current, as File > Open does but
with no file dialog and no error windows: a missing, unreadable or
foreign file is refused in the answer. A project already open is only
made current. switch_project makes another open project current, by its
index or its file. status now lists every open project (index, title,
file, folios, unsaved changes, current), so the assistant sees what it
can switch to. MCP: qet_live_open_project, qet_live_switch_project; both
paths go through the workspace policy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 19:00:13 +13:00
ispyisail 42b1e43e4a Live mode: create a new project (new_project, qet_live_new_project)
An assistant in live mode could only work on the project already open.
new_project makes one as File > New does -- this installation's
new-folio defaults, optional title and number of folios -- and makes it
the current project, so the next request works on it. An optional
absolute path saves it at once, never over an existing file: QElectroTech
refuses, and the MCP server refuses before asking (a new never-overwrite
class in its path policy, so an "overwrite" flag cannot get round it).

Pages and links across pages already worked through scripts
(qet.addFolio, setFolioTitle, linkElements across folios); the tool's
description now says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 18:48:38 +13:00
ispyisail e77a175fc9 Live mode: optional timing of each request (QET_LIVE_PERF_LOG)
A request with "timing": true gets queue, confirm and exec times in its
answer; with QET_LIVE_PERF_LOG set, QElectroTech also appends one JSON
line per request, with the time until the folio is next painted. The
qet MCP server logs its side of each live call to the same file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 18:32:42 +13:00
ispyisail 5859bc3353 Live mode: English text, the right settings tab, folio-only screenshot
Reported on #1178 after a first try of live mode on macOS:

- The English interface showed the live-mode setting in French. The
  strings were in lang/qet_en.ts but untranslated. This fills in English
  for live mode, the script buttons, the macro recorder and the Connect
  an AI assistant dialog (101 entries); other features' untranslated
  English entries are left for their own change.
- The setting is on Configurer QElectroTech > Général > Projets, but the
  start-up warning, the MCP server's error and its README all said
  "Configurer > Général". All three now name the Projects tab, and the
  README and the server name the English menus and buttons.
- qet_live_screenshot grabbed the whole viewport, so a tall window around
  a landscape folio came back mostly empty. It now crops to the folio's
  frame and title block where they are on screen (the whole viewport if
  the folio is scrolled out of sight), and says so in cropped_to_folio.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 09:14:57 +13:00
ispyisail e23fc2aaad Add a macro recorder: record a task by hand, for an assistant to script
Projet > Scripts > Enregistrer une macro (also in command search and the
shortcut bar) records what is done on the current project until clicked
again. Under <data folder>/recordings/<id>/ it saves the whole project
before and after, the folio and selection at the start, and each step from
the undo history -- its name, the commands inside it, the folio, what was
selected, and the folio after it. No editing command is taught to the
recorder, and nothing new walks the scene: the files are QElectroTech's
own serialisation.

While recording, the status bar shows "● Enregistrement : N étapes" with
Arrêter. At the end a box says where it went and offers "Copier la demande
pour l'assistant": a ready-made request naming the recording, to paste
into the assistant's chat, since QElectroTech cannot send it anything
itself. qet-assistant.json lists the recordings, and live status says
whether one is under way and which was last.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 14:10:50 +13:00
ispyisail 7694f4833d Merge branch 'feature/script-live' into feature/script-live-ask-first 2026-10-02 13:03:34 +13:00
ispyisail 124173514d Live mode: advertise the channel in qet-assistant.json
The socket name and token now go in the "live" part of the one file the
qet MCP server reads about this QElectroTech, rather than in a
live-session.json of their own, and are cleared when the channel closes.
The file also says whether the live setting is on.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 13:03:33 +13:00
ispyisail da312fa467 Merge branch 'feature/script-live' into feature/script-live-ask-first 2026-10-02 11:57:53 +13:00
ispyisail 7d91e8fdf1 Live mode: find the open project while QElectroTech is not the active window
While the user types to the assistant, QElectroTech is not the active
application, and QMdiArea then reports no active sub-window: status said
no project was open and every run was refused. Make the sub-window it
remembers active again before handling a request; the focus stays where
the user put it. Found with the Windows package under Wine; reproduced on
Linux with another window focused.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 11:57:53 +13:00
ispyisail 78ee9ccbaa Merge branch 'feature/script-live' into feature/script-live-ask-first 2026-10-02 11:15:15 +13:00
ispyisail e7b699b59a Live mode: close each connection once it is answered
The qet MCP server connects once per request. On Windows a named pipe's
disconnection reaches QLocalSocket late, so the second of two quick calls
was turned away as "another assistant is already connected". Found
testing the Windows package under Wine with a Windows-side client.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-02 11:15:15 +13:00
ispyisail 3083654ad3 Live mode: ask first, an Assistant log, commands, folios, screenshot
A script the assistant writes on the spot is shown to the user before it
runs: Exécuter, Refuser, or Toujours pour cette session. Stored scripts
run as a click would. The choice is per session and never saved.

An "Assistant" dock lists every action with the time, ✓ or ✗, and its
undo step; the script, its log or its error show on hover and on a
double-click. It opens with live mode and holds the ask-first box.

The assistant may also:
- trigger an editor command from an allow-list of ones that open no
  dialog and that undo can take back (selection, zoom, rotate, snap,
  group, reset wires); saving, deleting, exporting and the rest are
  refused;
- show another folio;
- undo the newest step only if it made it ("Assistant : …");
- take a picture of the folio on screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 10:43:19 +13:00
ispyisail 2fb14c5bd0 Live mode: an AI assistant acts on the open project while the user watches
A new setting, Configurer QElectroTech > Général > "Autoriser un assistant
IA à agir sur le projet ouvert", off by default. Off, nothing changes:
no channel is opened. On, every start shows a warning first -- Continuer,
Pas pour cette session, or Désactiver -- and nothing can connect until
the user answers Continuer. It waits for any other start-up question to
be answered, so the two never stack.

Accepted, LiveServer opens a local socket only the user's account can
use, with a random name and token written to live-session.json in the
data folder for the qet MCP server, and removed when the channel closes.
One JSON request per line: status (project, folio on screen, selection,
last undo step, stored scripts), run_script and run_stored. Requests are
queued out of the socket handler before they run (the lesson of PR #861).

Each run is one undo step named "Assistant : <name>". The status bar
shows the mode and the assistant's last action with a ✓ or ✗ and the
time, and an Arrêter button that closes the channel for the session.
Unticking the setting closes it at once.

QetScripting::runSource() runs script text and, for a live run, returns
what qet.log() wrote, the error with its line and the undo step instead
of showing boxes; qet.showMessage() is logged rather than opening a box
nobody asked for.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 10:41:29 +13:00