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>
This commit is contained in:
ispyisail
2026-10-03 09:14:57 +13:00
parent 25084a44da
commit 5859bc3353
5 changed files with 145 additions and 116 deletions
+106 -98
View File
@@ -461,127 +461,127 @@
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="47"/>
<source>Connecter un assistant IA</source>
<translation type="unfinished"></translation>
<translation>Connect an AI assistant</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="62"/>
<source>Un assistant IA (Claude, GitHub Copilot, Gemini…) peut ouvrir, vérifier et modifier vos schémas grâce au serveur MCP de QElectroTech, qui fonctionne sur cet ordinateur. Copiez le texte ci-dessous dans la configuration de votre assistant. &lt;a href=&quot;%1&quot;&gt;Guide détaillé&lt;/a&gt;</source>
<translation type="unfinished"></translation>
<translation>An AI assistant (Claude, GitHub Copilot, Gemini…) can open, check and edit your diagrams through QElectroTech&apos;s MCP server, which runs on this computer. Copy the text below into your assistant&apos;s configuration. &lt;a href=&quot;%1&quot;&gt;Detailed guide&lt;/a&gt;</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="74"/>
<source>&lt;b&gt;Le serveur MCP n&apos;est pas installé avec cette version de QElectroTech.&lt;/b&gt; Le guide explique comment l&apos;obtenir.</source>
<translation type="unfinished"></translation>
<translation>&lt;b&gt;The MCP server is not installed with this version of QElectroTech.&lt;/b&gt; The guide explains how to get it.</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="85"/>
<source>&lt;b&gt;Python n&apos;est peut-être pas installé.&lt;/b&gt; Seul le raccourci « python » du Microsoft Store a été trouvé : sans Python, il ouvre le Store au lieu de lancer le serveur.</source>
<translation type="unfinished"></translation>
<translation>&lt;b&gt;Python may not be installed.&lt;/b&gt; Only the Microsoft Store “python” shortcut was found: without Python, it opens the Store instead of starting the server.</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="89"/>
<source>&lt;b&gt;Python est introuvable sur cet ordinateur&lt;/b&gt; (commande « %1 »). Le serveur en a besoin.</source>
<translation type="unfinished"></translation>
<translation>&lt;b&gt;Python was not found on this computer&lt;/b&gt; (command “%1”). The server needs it.</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="92"/>
<source>Relancez l&apos;installateur de QElectroTech et cochez « Python pour l&apos;assistant IA », ou installez Python depuis python.org.</source>
<translation type="unfinished"></translation>
<translation>Run the QElectroTech installer again and tick “Python for the AI assistant”, or install Python from python.org.</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="96"/>
<source>Installez Python 3 avec le gestionnaire de paquets de votre système.</source>
<translation type="unfinished"></translation>
<translation>Install Python 3 with your system&apos;s package manager.</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="112"/>
<source>Assistant :</source>
<translation type="unfinished"></translation>
<translation>Assistant:</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="116"/>
<source>Le dossier de vos schémas</source>
<translation type="unfinished"></translation>
<translation>Your diagrams folder</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="117"/>
<source>Parcourir…</source>
<translation type="unfinished"></translation>
<translation>Browse…</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="120"/>
<source>Dossier accessible :</source>
<translation type="unfinished"></translation>
<translation>Folder it can use:</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="122"/>
<source>Autoriser l&apos;assistant à modifier les schémas</source>
<translation type="unfinished"></translation>
<translation>Allow the assistant to edit diagrams</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="127"/>
<source>L&apos;assistant ne peut lire et écrire que dans ce dossier. Sans modification autorisée, il peut seulement lire, comparer et exporter. Un assistant lit le texte des projets (repères, notes…) : un texte écrit comme une instruction peut l&apos;influencer. Laissez les modifications désactivées pour les schémas reçus d&apos;autres personnes.</source>
<translation type="unfinished"></translation>
<translation>The assistant can only read and write in this folder. Without editing allowed, it can only read, compare and export. An assistant reads the text in projects (labels, notes…): text written as an instruction can influence it. Leave editing off for diagrams you received from other people.</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="149"/>
<source>Copier</source>
<translation type="unfinished"></translation>
<translation>Copy</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="169"/>
<source>Si le fichier contient déjà d&apos;autres serveurs, ajoutez seulement l&apos;entrée « qet ».</source>
<translation type="unfinished"></translation>
<translation>If the file already lists other servers, add only the “qet” entry.</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="178"/>
<source>Choisissez d&apos;abord le dossier de vos schémas.</source>
<translation type="unfinished"></translation>
<translation>Choose your diagrams folder first.</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="187"/>
<source>Dossier accessible à l&apos;assistant</source>
<translation type="unfinished"></translation>
<translation>Folder the assistant can use</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="195"/>
<source>Copié</source>
<translation type="unfinished"></translation>
<translation>Copied</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="202"/>
<source>Dans Claude Desktop : Paramètres → Développeur → Modifier la configuration. Puis quittez et relancez Claude.</source>
<translation type="unfinished"></translation>
<translation>In Claude Desktop: Settings → Developer → Edit Config. Then quit and restart Claude.</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="205"/>
<source>Enregistrez-le sous le nom .mcp.json dans le dossier de vos schémas.</source>
<translation type="unfinished"></translation>
<translation>Save it as .mcp.json in your diagrams folder.</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="207"/>
<source>Enregistrez-le sous le nom .vscode/mcp.json dans le dossier ouvert dans VS Code. Copilot utilise les outils en mode agent.</source>
<translation type="unfinished"></translation>
<translation>Save it as .vscode/mcp.json in the folder open in VS Code. Copilot uses the tools in agent mode.</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="210"/>
<source>Ajoutez-le au fichier .cursor/mcp.json de votre dossier personnel.</source>
<translation type="unfinished"></translation>
<translation>Add it to the .cursor/mcp.json file in your home folder.</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="213"/>
<source>Ajoutez-le au fichier .gemini/settings.json de votre dossier personnel. Gemini CLI demande de faire confiance au dossier la première fois.</source>
<translation type="unfinished"></translation>
<translation>Add it to the .gemini/settings.json file in your home folder. Gemini CLI asks you to trust the folder the first time.</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="217"/>
<source>Ajoutez-le au fichier .codex/config.toml de votre dossier personnel.</source>
<translation type="unfinished"></translation>
<translation>Add it to the .codex/config.toml file in your home folder.</translation>
</message>
<message>
<location filename="../sources/ui/aiassistantdialog.cpp" line="220"/>
<source>Dans LM Studio : onglet Program → Install → Edit mcp.json.</source>
<translation type="unfinished"></translation>
<translation>In LM Studio: Program tab → Install → Edit mcp.json.</translation>
</message>
</context>
<context>
@@ -5335,12 +5335,12 @@ Vous pouvez spécifier ici la valeur par défaut de ce champ pour les éléments
<message>
<location filename="../sources/ui/configpage/generalconfigurationpage.ui" line="280"/>
<source>Autoriser un assistant IA à agir sur le projet ouvert (mode direct)</source>
<translation type="unfinished"></translation>
<translation>Allow an AI assistant to act on the open project (live mode)</translation>
</message>
<message>
<location filename="../sources/ui/configpage/generalconfigurationpage.ui" line="283"/>
<source>Un assistant connecté par le serveur MCP peut alors exécuter des scripts sur le projet ouvert, sous vos yeux. Un avertissement est affiché à chaque démarrage tant que ce réglage est activé. Prend effet au prochain démarrage ; le décocher coupe la connexion tout de suite.</source>
<translation type="unfinished"></translation>
<translation>An assistant connected through the MCP server can then run scripts on the open project, as you watch. A warning is shown at every start while this setting is on. Takes effect at the next start; unticking it closes the connection at once.</translation>
</message>
<message>
<location filename="../sources/ui/configpage/generalconfigurationpage.ui" line="342"/>
@@ -6777,7 +6777,7 @@ Please use the advanced editor for this.</translation>
<message>
<location filename="../sources/scripting/liveserver.cpp" line="108"/>
<source>Mode direct</source>
<translation type="unfinished"></translation>
<translation>Live mode</translation>
</message>
<message>
<location filename="../sources/scripting/liveserver.cpp" line="109"/>
@@ -6785,59 +6785,63 @@ Please use the advanced editor for this.</translation>
Chaque action s&apos;annule d&apos;un Ctrl+Z, et le bouton « Arrêter » de la barre d&apos;état coupe la connexion.
Ce réglage se trouve dans Configurer QElectroTech &gt; Général.</source>
<translation type="unfinished"></translation>
Ce réglage se trouve dans Configurer QElectroTech &gt; Général &gt; Projets.</source>
<translation>Live mode is on: a connected AI assistant will be able to run scripts on the open project.
Each action is undone with one Ctrl+Z, and the “Stop” button in the status bar closes the connection.
This setting is in Configure QElectroTech &gt; General &gt; Projects.</translation>
</message>
<message>
<location filename="../sources/scripting/liveserver.cpp" line="115"/>
<source>&amp;Continuer</source>
<translation type="unfinished"></translation>
<translation>&amp;Continue</translation>
</message>
<message>
<location filename="../sources/scripting/liveserver.cpp" line="116"/>
<source>&amp;Pas pour cette session</source>
<translation type="unfinished"></translation>
<translation>&amp;Not this session</translation>
</message>
<message>
<location filename="../sources/scripting/liveserver.cpp" line="117"/>
<source>&amp;Désactiver</source>
<translation type="unfinished"></translation>
<translation>&amp;Turn off</translation>
</message>
<message>
<location filename="../sources/scripting/liveserver.cpp" line="353"/>
<location filename="../sources/scripting/liveserver.cpp" line="491"/>
<source>script</source>
<translation type="unfinished"></translation>
<translation>script</translation>
</message>
<message>
<location filename="../sources/scripting/liveserver.cpp" line="455"/>
<source>Assistant : %1</source>
<translation type="unfinished"></translation>
<translation>Assistant: %1</translation>
</message>
<message>
<location filename="../sources/scripting/liveserver.cpp" line="487"/>
<source>L&apos;assistant veut exécuter un script</source>
<translation type="unfinished"></translation>
<translation>The assistant wants to run a script</translation>
</message>
<message>
<location filename="../sources/scripting/liveserver.cpp" line="490"/>
<source>« %1 » sur le projet ouvert. Une fois exécuté, Ctrl+Z l&apos;annule.</source>
<translation type="unfinished"></translation>
<translation>“%1” on the open project. Once it has run, Ctrl+Z undoes it.</translation>
</message>
<message>
<location filename="../sources/scripting/liveserver.cpp" line="498"/>
<source>&amp;Exécuter</source>
<translation type="unfinished"></translation>
<translation>&amp;Run</translation>
</message>
<message>
<location filename="../sources/scripting/liveserver.cpp" line="499"/>
<source>&amp;Refuser</source>
<translation type="unfinished"></translation>
<translation>&amp;Decline</translation>
</message>
<message>
<location filename="../sources/scripting/liveserver.cpp" line="500"/>
<source>&amp;Toujours pour cette session</source>
<translation type="unfinished"></translation>
<translation>&amp;Always this session</translation>
</message>
</context>
<context>
@@ -6845,12 +6849,12 @@ Ce réglage se trouve dans Configurer QElectroTech &gt; Général.</source>
<message>
<location filename="../sources/scripting/macrorecorder.cpp" line="198"/>
<source>Macro du %1</source>
<translation type="unfinished"></translation>
<translation>Macro of %1</translation>
</message>
<message>
<location filename="../sources/scripting/macrorecorder.cpp" line="206"/>
<source>projet fermé pendant l&apos;enregistrement : pas de after.qet</source>
<translation type="unfinished"></translation>
<translation>project closed during the recording: no after.qet</translation>
</message>
<message numerus="yes">
<location filename="../sources/scripting/macrorecorder.cpp" line="232"/>
@@ -9909,32 +9913,32 @@ Hold Ctrl while moving to place freely.</translation>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="748"/>
<source>Enregistrer une macro</source>
<translation type="unfinished"></translation>
<translation>Record a macro</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="751"/>
<source>Enregistre ce que vous faites sur le projet, pour qu&apos;un assistant IA en fasse un script ; recliquez pour arrêter</source>
<translation type="unfinished"></translation>
<translation>Records what you do on the project, for an AI assistant to make a script of; click again to stop</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="764"/>
<source>Gérer les scripts…</source>
<translation type="unfinished"></translation>
<translation>Manage scripts…</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="765"/>
<source>Écrire un script et en faire un bouton avec une icône</source>
<translation type="unfinished"></translation>
<translation>Write a script and make it a button with an icon</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="782"/>
<source>Ouvrir le dossier des scripts</source>
<translation type="unfinished"></translation>
<translation>Open the scripts folder</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="784"/>
<source>Chaque fichier .js de ce dossier qui commence par un en-tête // ==QETScript== devient un bouton</source>
<translation type="unfinished"></translation>
<translation>Every .js file in this folder that starts with a // ==QETScript== header becomes a button</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="801"/>
@@ -10246,7 +10250,7 @@ Hold Ctrl while moving to place freely.</translation>
<location filename="../sources/qetdiagrameditor.cpp" line="1300"/>
<source>Scripts</source>
<comment>toolbar title</comment>
<translation type="unfinished"></translation>
<translation>Scripts</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="1374"/>
@@ -10267,7 +10271,7 @@ Hold Ctrl while moving to place freely.</translation>
<location filename="../sources/qetdiagrameditor.cpp" line="1428"/>
<location filename="../sources/qetdiagrameditor.cpp" line="3924"/>
<source>Scripts</source>
<translation type="unfinished"></translation>
<translation>Scripts</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="1605"/>
@@ -10538,18 +10542,18 @@ Enable scripts? This setting can be changed in Configure QElectroTech &gt; Gener
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="3938"/>
<source>Ignoré : %1</source>
<translation type="unfinished"></translation>
<translation>Ignored: %1</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="3972"/>
<location filename="../sources/qetdiagrameditor.cpp" line="4032"/>
<source>Arrêter</source>
<translation type="unfinished"></translation>
<translation>Stop</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="3973"/>
<source>Arrêter l&apos;enregistrement de la macro</source>
<translation type="unfinished"></translation>
<translation>Stop recording the macro</translation>
</message>
<message numerus="yes">
<location filename="../sources/qetdiagrameditor.cpp" line="3983"/>
@@ -10562,7 +10566,7 @@ Enable scripts? This setting can be changed in Configure QElectroTech &gt; Gener
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="3998"/>
<source>Macro enregistrée</source>
<translation type="unfinished"></translation>
<translation>Macro recorded</translation>
</message>
<message numerus="yes">
<location filename="../sources/qetdiagrameditor.cpp" line="3999"/>
@@ -10577,53 +10581,53 @@ Pour en faire un script, demandez-le à votre assistant IA : le bouton ci-dessou
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="4007"/>
<source>&amp;Copier la demande pour l&apos;assistant</source>
<translation type="unfinished"></translation>
<translation>&amp;Copy the request for the assistant</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="4008"/>
<source>&amp;Ouvrir le dossier</source>
<translation type="unfinished"></translation>
<translation>&amp;Open the folder</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="4014"/>
<source>Demande copiée : collez-la dans la fenêtre de l&apos;assistant</source>
<translation type="unfinished"></translation>
<translation>Request copied: paste it into the assistant&apos;s window</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="4033"/>
<source>Couper la connexion de l&apos;assistant pour le reste de la session</source>
<translation type="unfinished"></translation>
<translation>Close the assistant&apos;s connection for the rest of the session</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="4042"/>
<source>Mode direct : assistant connecté</source>
<translation type="unfinished"></translation>
<translation>Live mode: assistant connected</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="4043"/>
<source>Mode direct : en attente d&apos;un assistant</source>
<translation type="unfinished"></translation>
<translation>Live mode: waiting for an assistant</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="4051"/>
<location filename="../sources/qetdiagrameditor.cpp" line="4095"/>
<source>Assistant</source>
<translation type="unfinished"></translation>
<translation>Assistant</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="4055"/>
<source>Demander avant d&apos;exécuter un script écrit par l&apos;assistant</source>
<translation type="unfinished"></translation>
<translation>Ask before running a script the assistant wrote</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="4057"/>
<source>Pour cette session seulement : chaque démarrage redemande</source>
<translation type="unfinished"></translation>
<translation>For this session only: every start asks again</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="4112"/>
<source>Mode direct : %1 %2 à %3</source>
<translation type="unfinished"></translation>
<translation>Live mode: %1 %2 at %3</translation>
</message>
<message>
<location filename="../sources/qetdiagrameditor.cpp" line="4155"/>
@@ -11520,13 +11524,13 @@ the conditions are not valid</translation>
<message>
<location filename="../sources/qetmainwindow.cpp" line="125"/>
<source>Connecter un assistant IA...</source>
<translation type="unfinished"></translation>
<translation>Connect an AI assistant...</translation>
</message>
<message>
<location filename="../sources/qetmainwindow.cpp" line="126"/>
<source>Affiche la configuration qui permet à un assistant IA d&apos;utiliser QElectroTech</source>
<comment>status bar tip</comment>
<translation type="unfinished"></translation>
<translation>Shows the setup that lets an AI assistant use QElectroTech</translation>
</message>
<message>
<location filename="../sources/qetmainwindow.cpp" line="133"/>
@@ -14237,12 +14241,12 @@ To enable it: Configure QElectroTech &gt; General &gt; Projects, or set the QET_
<message>
<location filename="../sources/scripting/qetscripting.cpp" line="186"/>
<source>Assistant : %1</source>
<translation type="unfinished"></translation>
<translation>Assistant: %1</translation>
</message>
<message>
<location filename="../sources/scripting/qetscripting.cpp" line="187"/>
<source>Script : %1</source>
<translation type="unfinished"></translation>
<translation>Script: %1</translation>
</message>
<message numerus="yes">
<location filename="../sources/undocommand/groupitemscommand.cpp" line="55"/>
@@ -15258,7 +15262,7 @@ Create your own text using the following variables:
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="375"/>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="382"/>
<source>Gérer les scripts</source>
<translation type="unfinished"></translation>
<translation>Manage scripts</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="54"/>
@@ -15268,37 +15272,37 @@ Create your own text using the following variables:
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="55"/>
<source>Supp&amp;rimer</source>
<translation type="unfinished"></translation>
<translation>&amp;Delete</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="64"/>
<source>Le texte du bouton</source>
<translation type="unfinished"></translation>
<translation>The button&apos;s text</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="66"/>
<source>vide : les initiales du nom ; builtin:&lt;nom&gt; : une icône du thème</source>
<translation type="unfinished"></translation>
<translation>empty: the name&apos;s initials; builtin:&lt;name&gt;: an icon of the theme</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="69"/>
<source>Choisir une image (SVG ou PNG)…</source>
<translation type="unfinished"></translation>
<translation>Choose an image (SVG or PNG)…</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="76"/>
<source>Toujours</source>
<translation type="unfinished"></translation>
<translation>Always</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="77"/>
<source>Avec une sélection</source>
<translation type="unfinished"></translation>
<translation>With a selection</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="78"/>
<source>Avec un conducteur sélectionné</source>
<translation type="unfinished"></translation>
<translation>With a conductor selected</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="81"/>
@@ -15308,32 +15312,32 @@ Create your own text using the following variables:
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="82"/>
<source>Icône :</source>
<translation type="unfinished"></translation>
<translation>Icon:</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="83"/>
<source>Info-bulle :</source>
<translation type="unfinished"></translation>
<translation>Tooltip:</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="84"/>
<source>Raccourci :</source>
<translation type="unfinished"></translation>
<translation>Shortcut:</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="85"/>
<source>Actif :</source>
<translation type="unfinished"></translation>
<translation>Enabled:</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="96"/>
<source>&amp;Tester</source>
<translation type="unfinished"></translation>
<translation>&amp;Test</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="97"/>
<source>Enregistre puis exécute le script sur le projet courant (Ctrl+Z annule l&apos;exécution)</source>
<translation type="unfinished"></translation>
<translation>Saves, then runs the script on the current project (Ctrl+Z undoes the run)</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="99"/>
@@ -15343,7 +15347,7 @@ Create your own text using the following variables:
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="100"/>
<source>Ouvrir le &amp;dossier</source>
<translation type="unfinished"></translation>
<translation>Open the &amp;folder</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="101"/>
@@ -15353,22 +15357,22 @@ Create your own text using the following variables:
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="113"/>
<source>Script (l&apos;objet qet ; qet.currentFolio() est le folio affiché) :</source>
<translation type="unfinished"></translation>
<translation>Script (the qet object; qet.currentFolio() is the sheet shown):</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="186"/>
<source>Pas de bouton : %1</source>
<translation type="unfinished"></translation>
<translation>No button: %1</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="216"/>
<source>Pas de bouton pour ce fichier : %1</source>
<translation type="unfinished"></translation>
<translation>No button for this file: %1</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="243"/>
<source>Nouveau script</source>
<translation type="unfinished"></translation>
<translation>New script</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="244"/>
@@ -15377,57 +15381,61 @@ Create your own text using the following variables:
var f = qet.currentFolio();
qet.addText(f, &quot;Texte&quot;, 40, 40);
</source>
<translation type="unfinished"></translation>
<translation>// qet.currentFolio() is the sheet shown; one click is undone
// with a single Ctrl+Z. List of calls: qet.apiSignatures()
var f = qet.currentFolio();
qet.addText(f, &quot;Text&quot;, 40, 40);
</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="251"/>
<source>Pas encore enregistré</source>
<translation type="unfinished"></translation>
<translation>Not saved yet</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="265"/>
<source>Le script doit avoir un nom.</source>
<translation type="unfinished"></translation>
<translation>The script needs a name.</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="284"/>
<source>Non enregistré : %1</source>
<translation type="unfinished"></translation>
<translation>Not saved: %1</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="292"/>
<source>Impossible d&apos;écrire %1</source>
<translation type="unfinished"></translation>
<translation>Cannot write %1</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="308"/>
<source>Supprimer le script</source>
<translation type="unfinished"></translation>
<translation>Delete the script</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="309"/>
<source>Supprimer « %1 » et son bouton ?</source>
<translation type="unfinished"></translation>
<translation>Delete “%1” and its button?</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="342"/>
<source>Icône du script</source>
<translation type="unfinished"></translation>
<translation>Script icon</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="343"/>
<source>Images (*.svg *.png)</source>
<translation type="unfinished"></translation>
<translation>Images (*.svg *.png)</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="352"/>
<source>Impossible de copier %1</source>
<translation type="unfinished"></translation>
<translation>Cannot copy %1</translation>
</message>
<message>
<location filename="../sources/scripting/scriptmanagerdialog.cpp" line="383"/>
<source>Le script affiché n&apos;est pas enregistré. Enregistrer ?</source>
<translation type="unfinished"></translation>
<translation>The script shown is not saved. Save it?</translation>
</message>
</context>
<context>
+12 -10
View File
@@ -44,7 +44,7 @@ here read the model.
| `qet_about` | **start here** — where QElectroTech keeps things, what is switched on, the stored scripts, the calls a script can make (from `qet-assistant.json`) |
| `qet_script_api` | **what a script can call** — every `qet.*` call of this build, and the header that makes a script a button |
| `qet_script_test` | **try a script** on a copy of a project: what it would change, what it logged, its errors |
| `qet_script_install` | **make a button** — store a script (and an SVG icon) where QElectroTech shows it in Projet > Scripts and the Scripts toolbar |
| `qet_script_install` | **make a button** — store a script (and an SVG icon) where QElectroTech shows it in Project > Scripts and the Scripts toolbar |
| `qet_script_list`, `qet_script_read`, `qet_script_remove` | the stored scripts: list, read one to change it, delete one |
| `qet_recording_list`, `qet_recording_read`, `qet_recording_check`, `qet_recording_remove` | **macro recordings** — what you did by hand, and whether a script does the same |
@@ -271,7 +271,7 @@ with `qet_about`.
## Script buttons
QElectroTech turns every `.js` file in its scripts folder that starts with a
`// ==QETScript==` header into a command with an icon: in Projet > Scripts,
`// ==QETScript==` header into a command with an icon: in Project > Scripts,
on the Scripts toolbar, in command search and in the shortcut bar. A person
can write that file by hand; an assistant uses the tools above. Both end
with the same file, and an open QElectroTech picks it up without a restart.
@@ -304,7 +304,7 @@ stored script runs with the user's rights when they click it.
## Macro recordings: from something done by hand to a button
In QElectroTech, Projet > Scripts > Enregistrer une macro records what you
In QElectroTech, Project > Scripts > Record a macro records what you
do on a project until you click it again. It saves the project before and
after, and each step from the undo history with the folio after it. At Stop
it offers to copy a ready-made request; paste that into the assistant.
@@ -329,27 +329,29 @@ QElectroTech, in front of you, so you can watch, stop or undo:
| | |
|---|---|
| `qet_live_status` | what is on screen: project, folio, selection, last undo step, stored scripts |
| `qet_live_run_script` | run script text on the open project: one undo step named "Assistant : …" |
| `qet_live_run_script` | run script text on the open project: one undo step named "Assistant: …" |
| `qet_live_run_stored` | press a stored script's button |
| `qet_live_command` | an editor command from an allow-list that opens no dialog: selection, zoom, rotate, snap, group, reset wires |
| `qet_live_show_folio` | show another folio |
| `qet_live_undo_last` | undo the newest step, only if the assistant made it |
| `qet_live_screenshot` | a picture of the folio on screen, as an MCP image |
| `qet_live_screenshot` | a picture of the folio on screen, as an MCP image, cropped to the folio |
A script the assistant writes on the spot is shown to you first, with
*Exécuter*, *Refuser* or *Toujours pour cette session*; the Assistant
*Run*, *Decline* or *Always this session*; the Assistant
panel lists everything it did.
QElectroTech only listens when three things are true:
1. the server has `QET_ENABLE_SCRIPTING=1`, as for editing;
2. in QElectroTech, Configurer > Général > "Autoriser un assistant IA à agir
sur le projet ouvert" is ticked (off by default);
3. at this start, you answered *Continuer* to the warning QElectroTech shows
2. in QElectroTech, Settings > Configure QElectroTech > General, on the
Projects tab, "Allow an AI assistant to act on the open project (live
mode)" is ticked (off by default; in French, Configurer QElectroTech >
Général > Projets);
3. at this start, you answered *Continue* to the warning QElectroTech shows
every time it starts with that setting on.
While it listens, the status bar says so and shows the assistant's last
action, with an *Arrêter* button that closes the channel for the rest of
action, with a *Stop* button that closes the channel for the rest of
the session. Each action is one Ctrl+Z. A script's `qet.showMessage()` is
logged instead of opening a box nobody asked for.
+7 -5
View File
@@ -3064,13 +3064,15 @@ def _live_session() -> dict:
if not info.get("running"):
why = "QElectroTech is not running"
elif not features.get("live_mode_setting"):
why = ("live mode is off: in QElectroTech, Configurer QElectroTech > "
"Général > \"Autoriser un assistant IA à agir sur le projet "
"ouvert\", then restart it")
why = ("live mode is off: in QElectroTech, tick Settings > Configure "
"QElectroTech > General > Projects > \"Allow an AI assistant to "
"act on the open project (live mode)\" (in French: Configurer "
"QElectroTech > Général > Projets), then restart it")
else:
why = ("live mode is on but not open for this session: answer "
"\"Continuer\" in the warning QElectroTech shows at start, or "
"restart it if \"Pas pour cette session\" or Arrêter was chosen")
"\"Continue\" (\"Continuer\") in the warning QElectroTech shows "
"at start, or restart it if \"Not this session\" or \"Stop\" "
"was chosen")
raise ValueError(f"no QElectroTech is listening for an assistant: {why}.")
return live
+1 -1
View File
@@ -3101,7 +3101,7 @@ class LiveClient(unittest.TestCase):
with self.assertRaisesRegex(ValueError, "live mode is off"):
m.tool_live_status()
self.info(None)
with self.assertRaisesRegex(ValueError, "Continuer"):
with self.assertRaisesRegex(ValueError, "Continue"):
m.tool_live_status()
def test_requests_carry_the_token_and_the_script_id(self):
+19 -2
View File
@@ -110,7 +110,8 @@ void LiveServer::askAndStart(QWidget *parent)
"pourra exécuter des scripts sur le projet ouvert.\n\n"
"Chaque action s'annule d'un Ctrl+Z, et le bouton "
"« Arrêter » de la barre d'état coupe la connexion.\n\n"
"Ce réglage se trouve dans Configurer QElectroTech > Général."),
"Ce réglage se trouve dans Configurer QElectroTech > Général > "
"Projets."),
QMessageBox::NoButton, parent);
QPushButton *go = box.addButton(tr("&Continuer"), QMessageBox::AcceptRole);
box.addButton(tr("&Pas pour cette session"), QMessageBox::RejectRole);
@@ -465,7 +466,22 @@ QJsonObject LiveServer::screenshot()
QETDiagramEditor *e = editor();
DiagramView *view = e ? e->currentDiagramView() : nullptr;
if (!view) return failure(QStringLiteral("no folio is shown in QElectroTech"));
const QPixmap pixmap = view->grab();
// Only the part of the folio (frame and title block) that is on
// screen: a tall or wide window around a zoomed-out folio would
// otherwise give mostly empty background. The whole viewport when
// the folio is scrolled out of sight.
QRect area = view->viewport()->rect();
bool cropped = false;
if (Diagram *diagram = view->diagram()) {
const QRect folio = view->mapFromScene(
diagram->border_and_titleblock.borderAndTitleBlockRect()).boundingRect()
.adjusted(-1, -1, 1, 1).intersected(area);
if (!folio.isEmpty()) {
cropped = folio != area;
area = folio;
}
}
const QPixmap pixmap = view->viewport()->grab(area);
QByteArray png;
QBuffer buffer(&png);
buffer.open(QIODevice::WriteOnly);
@@ -473,6 +489,7 @@ QJsonObject LiveServer::screenshot()
return {{QStringLiteral("ok"), true},
{QStringLiteral("width"), pixmap.width()},
{QStringLiteral("height"), pixmap.height()},
{QStringLiteral("cropped_to_folio"), cropped},
{QStringLiteral("png_base64"), QString::fromLatin1(png.toBase64())}};
}