mirror of
https://github.com/qelectrotech/qelectrotech-source-mirror.git
synced 2026-10-03 09:14:12 +02:00
Scripting: qet.currentFolio(), and one undo step per script run in the editor
A script started from the editor had no way to know which folio is on screen, and each qet.* call was its own undo step, so a script that adds twenty items needed twenty Ctrl+Z to take back. qet.currentFolio() returns the folio shown in the editor; through --run, which has no view, the first folio, or -1 when there is none. A run from the editor is now one undo macro, named after the script. A run that changed nothing leaves no empty entry behind. qet.undo() and qet.redo() inside a grouped run say why they cannot work (QUndoStack ignores them inside a macro) instead of failing silently. --run is unchanged: one step per call, so scripts that call qet.undo() keep working. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include <QFileInfo>
|
||||
#include <QObject>
|
||||
#include <QTextStream>
|
||||
#include <QUndoStack>
|
||||
|
||||
#ifdef QET_HAS_SCRIPTING
|
||||
#include <QJSEngine>
|
||||
@@ -162,6 +163,20 @@ bool runOnProject(const QString &scriptPath, QETProject *project, DiagramView *v
|
||||
}
|
||||
});
|
||||
|
||||
// From the editor, a run is one undo step: a script that places
|
||||
// twenty items is undone with one Ctrl+Z, not twenty. Headless --run
|
||||
// keeps one step per call, which is what a script calling qet.undo()
|
||||
// itself relies on. QUndoStack keeps an empty macro as a blank entry
|
||||
// (and marks the project modified), so a script that changed nothing
|
||||
// has its macro taken off again: an obsolete command is deleted by
|
||||
// QUndoStack::undo() instead of being undone onto the redo side.
|
||||
QUndoStack *stack = (view && project) ? project->undoStack() : nullptr;
|
||||
if (stack) {
|
||||
stack->beginMacro(QObject::tr("Script : %1")
|
||||
.arg(QFileInfo(scriptPath).completeBaseName()));
|
||||
api->setUndoGrouped(true);
|
||||
}
|
||||
|
||||
QJSValue result = engine.evaluate(source, scriptPath);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mtx);
|
||||
@@ -170,6 +185,18 @@ bool runOnProject(const QString &scriptPath, QETProject *project, DiagramView *v
|
||||
cv.notify_one();
|
||||
watchdog.join();
|
||||
|
||||
if (stack) {
|
||||
api->setUndoGrouped(false);
|
||||
stack->endMacro();
|
||||
// Always the top of the undo side once the macro is closed, even
|
||||
// when beginMacro() dropped a redo tail and count() went down.
|
||||
const QUndoCommand *macro = stack->command(stack->index() - 1);
|
||||
if (macro && macro->childCount() == 0) {
|
||||
const_cast<QUndoCommand *>(macro)->setObsolete(true);
|
||||
stack->undo();
|
||||
}
|
||||
}
|
||||
|
||||
if (result.isError()) {
|
||||
const QString message = QStringLiteral("Script error: %1:%2: %3")
|
||||
.arg(scriptPath)
|
||||
|
||||
Reference in New Issue
Block a user