mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-09-27 12:34:14 +02:00
0920e82188
Extends the scripting surface from the previous commit with exactly the three things explicitly scoped out there, per follow-up direction: editing geometry, undo integration, and driving the GUI -- the last one narrowed to select/zoom/message after discussion, since "invoke any menu action by name" would let a script trigger a modal QDialog::exec() with nobody there to dismiss it, the same hang class investigated for bugtracker #882. ## New capabilities - addElement/setElementPosition/moveElement/deleteElement, through the same undo commands the GUI itself uses: AddGraphicsObjectCommand (the same one drag-from-collection-panel placement uses), QPropertyUndoCommand on the standard `pos` property, and DeleteQGraphicsItemCommand (refuses a non-deletable terminal, same as the Delete key). - undo/redo/canUndo/canRedo against the project's real QUndoStack -- the same one QETDiagramEditor's Ctrl+Z is wired to via undo_group.activeStack(), not a parallel mechanism. - selectElement/deselectAll (scene state, no view required -- works headless), zoomFit/zoomToContent/zoomReset (need the active DiagramView, so false headless where there is nothing to zoom), and showMessage (a modal QET::QetMessageBox::information -- safe headless because non-interactive mode is already on for the whole process before any script runs). ## Two real bugs caught by testing this, not assumed away 1. save() was still going through the same reopen-from-disk path as every export method: it opened a *second*, unmodified copy of the project from its file on disk and rewrote that. addElement() and friends operate on the live in-memory project, so nothing they did ever reached the saved file -- an element counted correctly in memory and then silently vanished from the output. Fixed by having save() write m_project->toXml() directly, the only method that touches the live instance rather than a fresh copy of the file. 2. A script calling setElementPosition() then moveElement() on the same element produced a saved position that didn't match either call, and undo/redo didn't step through them independently. Traced to QPropertyUndoCommand::mergeWith() (pre-existing, not new): consecutive commands on the same object+property merge when their text() also matches, and both calls build the identical "Déplacer %1" text for a given element -- exactly the same collapsing dragging an item repeatedly gets. Not a bug in the new code; a wrong assumption in the first test. Re-verified against the correct, merge-aware expectation: add -> merged move -> undo (back to first position) -> undo (element removed) -> redo (element back) -> redo (merged move reapplied) landed at the exact predicted final position, read back from the saved XML. ## Verified Qt6, build clean from a fresh reconfigure, ctest 6/6. - Headless: addElement returns a real uuid and the count updates; select/set-position/move all report correctly; the merge-aware undo/redo/save round trip above, confirmed against the saved file's actual XML, not just in-memory counters. - Corpus: the existing read-model smoke script re-run against all 24 shipped example projects on the fixed binary, 0 failures. - zoomFit correctly returns false headless (no view to act on), confirming the "narrowed GUI-driving" scope holds in code, not just in the doc comment. - GUI: running the add-only script via "Exécuter un script..." marked the project [modifié] in the title bar, the same change-tracking path a manual edit goes through -- consistent with the undo command actually being pushed onto the project's real stack rather than some side channel invisible to the rest of the application. Refs #162. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
66 lines
2.1 KiB
C++
66 lines
2.1 KiB
C++
/*
|
|
Copyright 2006-2026 The QElectroTech Team
|
|
This file is part of QElectroTech.
|
|
|
|
QElectroTech is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
QElectroTech is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#ifndef QET_SCRIPTING_H
|
|
#define QET_SCRIPTING_H
|
|
|
|
#include <QStringList>
|
|
|
|
class QETProject;
|
|
class DiagramView;
|
|
|
|
/**
|
|
@brief JavaScript scripting entry points (bugtracker #162).
|
|
|
|
A script sees a single global, `qet` (see QetScriptApi): reading the
|
|
model, exporting, editing geometry through the real undo commands, and
|
|
a narrow set of navigation/messaging calls. See QetScriptApi's class
|
|
comment for the exact scope and why each group of capability stops
|
|
where it does.
|
|
*/
|
|
namespace QetScripting {
|
|
|
|
/**
|
|
@brief True if @p args is a `--run <script.js> <project.qet>`
|
|
invocation.
|
|
*/
|
|
bool isRunRequest(const QStringList &args);
|
|
|
|
/**
|
|
@brief Run the script named in @p args against the project also
|
|
named there, headless.
|
|
Usage: qelectrotech --run <script.js> <project.qet>
|
|
@return process exit code: 0 on success, 1 if the project failed to
|
|
open or the script threw, 2 on a usage error.
|
|
*/
|
|
int run(const QStringList &args);
|
|
|
|
/**
|
|
@brief Run @p scriptPath against an already-open @p project (the
|
|
"Run Script..." GUI macro path). Errors go to stderr; there is no
|
|
modal reporting in this first version.
|
|
@param view the active DiagramView, so the script's zoom methods
|
|
have something to act on; nullptr from the headless entry point,
|
|
where they become no-ops (see QetScriptApi).
|
|
@return true if the script ran without throwing.
|
|
*/
|
|
bool runOnProject(const QString &scriptPath, QETProject *project, DiagramView *view = nullptr);
|
|
|
|
}
|
|
|
|
#endif // QET_SCRIPTING_H
|