Script buttons: stored scripts become commands with an icon

Every .js file in the "scripts" folder of the user's data folder that
starts with a // ==QETScript== header becomes a command: in Projet >
Scripts, as a button on a new Scripts toolbar, and, because it is
registered with ShortcutManager as diagrameditor.script.<file name>, in
the shortcut settings, the shortcut bar (S) and command search. The
header gives its name, icon (a file next to the script or a theme icon;
a tile with its initials otherwise), tooltip, default shortcut and when
it is enabled (always, with a selection, with a conductor selected).

The folder is watched, so a script added, edited or deleted while QET is
open appears, changes or goes without a restart. A file with a header
that cannot be used gets no button; the Scripts menu lists it with the
reason. The menu also opens the folder, and holds "Exécuter un script…".

A click runs the script on the current project as one undo step named
after it, and asks to switch scripting on first, like "Exécuter un
script…" does: scripting stays off by default.

ShortcutManager::unregisterAction() takes a command out of the lists
when its script is deleted, and lets it come back under a new name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ispyisail
2026-10-02 09:01:02 +13:00
parent b7ce89944e
commit e03e523069
12 changed files with 737 additions and 28 deletions
+27
View File
@@ -95,6 +95,33 @@ void ShortcutManager::registerAction(QObject *target, const QString &id,
target->setProperty("shortcut", QVariant::fromValue(savedSequence(id, it->default_sequence)));
}
/**
@brief ShortcutManager::unregisterAction
Forget \a target under \a id, and the id itself once no live target is
left. For commands that come and go while the application runs, such
as a stored script deleted from its folder: without this its id stays
listed in the shortcut settings, the shortcut bar and command search,
and its first description stays fixed even after it is renamed. The
user's saved shortcut for the id is kept, so the command picks it up
again if it comes back.
*/
void ShortcutManager::unregisterAction(QObject *target, const QString &id)
{
auto it = m_entries.find(id);
if (it == m_entries.end()) {
return;
}
QList<QPointer<QObject>> &targets = it->targets;
targets.erase(std::remove_if(targets.begin(), targets.end(),
[target](const QPointer<QObject> &t) {
return t.isNull() || t.data() == target; }),
targets.end());
if (targets.isEmpty()) {
m_entries.erase(it);
m_order.removeAll(id);
}
}
/**
@return every registered shortcut, in registration order, along with its
currently effective sequence -- for display in the Shortcuts config page.