Finally a workaround to access singletons in the JS console

This commit is contained in:
Robert Griebl
2023-10-06 23:59:24 +02:00
parent 6df845ad61
commit a20c9091cd
2 changed files with 23 additions and 6 deletions

View File

@@ -307,6 +307,10 @@ std::tuple<QString, bool> ScriptManager::executeString(const QString &s)
{
Q_ASSERT(m_engine);
// Evaluating 's' via QQmlExpression would be straight forward, but this is problematic due
// to QTBUG-33514 (singletons are not available inside QQmlExpressions) and BrickStore relying
// heavily on singletons.
const char *script =
"import BrickStore\n"
"import BrickLink\n"
@@ -315,20 +319,32 @@ std::tuple<QString, bool> ScriptManager::executeString(const QString &s)
" property var bl: BrickLink\n"
" property var bs: BrickStore\n"
" property string help: \"Use 'bl'/'bs' to access the BrickLink/BrickStore singletons\"\n"
" property var __result\n"
" property var __error\n"
" Component.onCompleted: {\n"
" try { __result = function() { return ${SCRIPT} }() }\n"
" catch (error) { __error = error }\n"
" }\n"
"}\n";
QQmlComponent component(m_engine);
component.setData(script, QUrl());
if (component.status() == QQmlComponent::Error)
return { u"JS compile error: "_qs + component.errorString(), false };
component.setData(QByteArray(script).replace("${SCRIPT}", s.toUtf8()), QUrl());
if (component.status() == QQmlComponent::Error) {
QStringList errorStrings;
const auto errors = component.errors();
errorStrings.reserve(errors.size());
for (const auto &e : errors)
errorStrings << e.description();
return { u"JS compile error: "_qs + errorStrings.join(u", "_qs), false };
}
m_rootObject = component.create();
QQmlExpression e(m_engine->rootContext(), m_rootObject, s);
QQmlExpression e(m_engine->rootContext(), m_rootObject, u"if (__error) throw __error; __result"_qs);
bool isUndefined = false;
auto result = e.evaluate(&isUndefined);
if (e.hasError())
return { e.error().toString(), false };
return { e.error().description(), false };
else if (isUndefined)
return { QString { }, true };
else