diff options
author | Eike Ziller <eike.ziller@qt.io> | 2019-04-16 16:46:36 +0200 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2019-05-09 11:19:43 +0000 |
commit | e0d38ae4140d6101b483fde25158fc94b34a3a64 (patch) | |
tree | 9137897e6cc85c195ff76ebedc9de0d9a447a168 /src/plugins/coreplugin | |
parent | 0c5837a1114ef526727748a0db956f0758597350 (diff) | |
download | qt-creator-e0d38ae4140d6101b483fde25158fc94b34a3a64.tar.gz |
Export Wizard values to JavaScript macro
Registers a new function "value('name')", available to the wizard json
files, which returns the value of the variable "name" as a JavaScript
object. So, variables with a string value are actual JavaScript strings,
booleans are booleans, lists are lists, and dictionaries are
dictionaries.
The patch also makes it actually possible to assign JSON lists and
dictionaries to values.
This removes some hacks involving creating complex JavaScript objects
through string substitution.
Change-Id: I4ac6da22bc5bccc9fadee97694c2fa14d44c9307
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src/plugins/coreplugin')
-rw-r--r-- | src/plugins/coreplugin/jsexpander.cpp | 59 | ||||
-rw-r--r-- | src/plugins/coreplugin/jsexpander.h | 35 | ||||
-rw-r--r-- | src/plugins/coreplugin/mainwindow.cpp | 39 |
3 files changed, 100 insertions, 33 deletions
diff --git a/src/plugins/coreplugin/jsexpander.cpp b/src/plugins/coreplugin/jsexpander.cpp index effa3464cc..5aa9279c7c 100644 --- a/src/plugins/coreplugin/jsexpander.cpp +++ b/src/plugins/coreplugin/jsexpander.cpp @@ -34,8 +34,26 @@ #include <QDebug> #include <QJSEngine> -namespace Core { +#include <unordered_map> + +namespace std { +template<> struct hash<QString> +{ + using argument_type = QString; + using result_type = size_t; + result_type operator()(const argument_type &v) const + { + return hash<string>()(v.toStdString()); + } +}; +} // namespace std + +using ExtensionMap = std::unordered_map<QString, Core::JsExpander::ObjectFactory>; +Q_GLOBAL_STATIC(ExtensionMap, globalJsExtensions); +static Core::JsExpander *globalExpander = nullptr; + +namespace Core { namespace Internal { class JsExpanderPrivate { @@ -45,9 +63,14 @@ public: } // namespace Internal -static Internal::JsExpanderPrivate *d; +void JsExpander::registerGlobalObject(const QString &name, const ObjectFactory &factory) +{ + globalJsExtensions->insert({name, factory}); + if (globalExpander) + globalExpander->registerObject(name, factory()); +} -void JsExpander::registerQObjectForJs(const QString &name, QObject *obj) +void JsExpander::registerObject(const QString &name, QObject *obj) { QJSValue jsObj = d->m_engine.newQObject(obj); d->m_engine.globalObject().setProperty(name, jsObj); @@ -77,16 +100,21 @@ QString JsExpander::evaluate(const QString &expression, QString *errorMessage) return QString(); } -JsExpander::JsExpander() +QJSEngine &JsExpander::engine() { - d = new Internal::JsExpanderPrivate; - Utils::globalMacroExpander()->registerPrefix("JS", + return d->m_engine; +} + +void JsExpander::registerForExpander(Utils::MacroExpander *macroExpander) +{ + macroExpander->registerPrefix( + "JS", QCoreApplication::translate("Core::JsExpander", "Evaluate simple JavaScript statements.<br>" "The statements may not contain '{' nor '}' characters."), - [](QString in) -> QString { + [this](QString in) -> QString { QString errorMessage; - QString result = JsExpander::evaluate(in, &errorMessage); + QString result = evaluate(in, &errorMessage); if (!errorMessage.isEmpty()) { qWarning() << errorMessage; return errorMessage; @@ -94,8 +122,21 @@ JsExpander::JsExpander() return result; } }); +} - registerQObjectForJs(QLatin1String("Util"), new Internal::UtilsJsExtension); +JsExpander *JsExpander::createGlobalJsExpander() +{ + globalExpander = new JsExpander(); + registerGlobalObject<Internal::UtilsJsExtension>("Util"); + globalExpander->registerForExpander(Utils::globalMacroExpander()); + return globalExpander; +} + +JsExpander::JsExpander() +{ + d = new Internal::JsExpanderPrivate; + for (const std::pair<const QString, ObjectFactory> &obj : *globalJsExtensions) + registerObject(obj.first, obj.second()); } JsExpander::~JsExpander() diff --git a/src/plugins/coreplugin/jsexpander.h b/src/plugins/coreplugin/jsexpander.h index 087f494ac0..df8c6bceea 100644 --- a/src/plugins/coreplugin/jsexpander.h +++ b/src/plugins/coreplugin/jsexpander.h @@ -27,26 +27,51 @@ #include "core_global.h" +#include <functional> + QT_BEGIN_NAMESPACE +class QJSEngine; class QObject; class QString; QT_END_NAMESPACE +namespace Utils { +class MacroExpander; +} + namespace Core { -namespace Internal { class MainWindow; } +namespace Internal { +class MainWindow; +class JsExpanderPrivate; +} // namespace Internal class CORE_EXPORT JsExpander { public: - static void registerQObjectForJs(const QString &name, QObject *obj); - - static QString evaluate(const QString &expression, QString *errorMessage = nullptr); + using ObjectFactory = std::function<QObject *()>; -private: JsExpander(); ~JsExpander(); + template <class T> + static void registerGlobalObject(const QString &name) + { + registerGlobalObject(name, []{ return new T; }); + } + + static void registerGlobalObject(const QString &name, const ObjectFactory &factory); + + void registerObject(const QString &name, QObject *obj); + QString evaluate(const QString &expression, QString *errorMessage = nullptr); + + QJSEngine &engine(); + void registerForExpander(Utils::MacroExpander *macroExpander); + +private: + static JsExpander *createGlobalJsExpander(); + + Internal::JsExpanderPrivate *d; friend class Core::Internal::MainWindow; }; diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index 2e8b5f2ad1..d35477f6b5 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -100,25 +100,26 @@ namespace Internal { enum { debugMainWindow = 0 }; -MainWindow::MainWindow() : - AppMainWindow(), - m_coreImpl(new ICore(this)), - m_lowPrioAdditionalContexts(Constants::C_GLOBAL), - m_settingsDatabase(new SettingsDatabase(QFileInfo(PluginManager::settings()->fileName()).path(), - QLatin1String(Constants::IDE_CASED_ID), - this)), - m_progressManager(new ProgressManagerPrivate), - m_jsExpander(new JsExpander), - m_vcsManager(new VcsManager), - m_modeStack(new FancyTabWidget(this)), - m_generalSettings(new GeneralSettings), - m_systemSettings(new SystemSettings), - m_shortcutSettings(new ShortcutSettings), - m_toolSettings(new ToolSettings), - m_mimeTypeSettings(new MimeTypeSettings), - m_systemEditor(new SystemEditor), - m_toggleLeftSideBarButton(new QToolButton), - m_toggleRightSideBarButton(new QToolButton) +MainWindow::MainWindow() + : AppMainWindow() + , m_coreImpl(new ICore(this)) + , m_lowPrioAdditionalContexts(Constants::C_GLOBAL) + , m_settingsDatabase( + new SettingsDatabase(QFileInfo(PluginManager::settings()->fileName()).path(), + QLatin1String(Constants::IDE_CASED_ID), + this)) + , m_progressManager(new ProgressManagerPrivate) + , m_jsExpander(JsExpander::createGlobalJsExpander()) + , m_vcsManager(new VcsManager) + , m_modeStack(new FancyTabWidget(this)) + , m_generalSettings(new GeneralSettings) + , m_systemSettings(new SystemSettings) + , m_shortcutSettings(new ShortcutSettings) + , m_toolSettings(new ToolSettings) + , m_mimeTypeSettings(new MimeTypeSettings) + , m_systemEditor(new SystemEditor) + , m_toggleLeftSideBarButton(new QToolButton) + , m_toggleRightSideBarButton(new QToolButton) { (void) new DocumentManager(this); |