diff options
| author | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2025-02-17 16:26:08 +0200 |
|---|---|---|
| committer | Tarja Sundqvist <tarja.sundqvist@qt.io> | 2025-02-17 16:26:08 +0200 |
| commit | cfddbca409e52e1244d5bcd87949d9d8b502ea12 (patch) | |
| tree | 1f261e5b0de8b51d8cbaec696f10036b7df62b6e /src | |
| parent | 4cac43295cd2a1aa24d7cc3b55d739e25194b3e0 (diff) | |
| parent | d7616cc4fcf8006522af6e1114ffd1e208d5b3a5 (diff) | |
Merge tag 'v6.5.5-lts' into tqtc/lts-6.5-opensourcev6.5.5-lts-lgpl
Qt 6.5.5-lts release
Conflicts solved:
dependencies.yaml
src/tools/ifcodegen/templates/backend_qtro/CMakeLists.txt.tpl
src/tools/ifcodegen/templates/backend_simulator/CMakeLists.txt.tpl
src/tools/ifcodegen/templates/frontend/CMakeLists.txt.tpl
src/tools/ifcodegen/templates/qmlplugin/CMakeLists.txt.tpl
src/tools/ifcodegen/templates/server_qtro/CMakeLists.txt.tpl
src/tools/ifcodegen/templates/server_qtro_simulator/CMakeLists.txt.tpl
src/tools/ifcodegen/templates/test/CMakeLists.txt.tpl
Change-Id: I3018daf9098a16ff792f74df3be464e7e1865b2e
Diffstat (limited to 'src')
27 files changed, 183 insertions, 114 deletions
diff --git a/src/interfaceframework/doc/src/ifcodegen/generator-usage.qdoc b/src/interfaceframework/doc/src/ifcodegen/generator-usage.qdoc index cd953ee6..45644c51 100644 --- a/src/interfaceframework/doc/src/ifcodegen/generator-usage.qdoc +++ b/src/interfaceframework/doc/src/ifcodegen/generator-usage.qdoc @@ -319,7 +319,7 @@ \li Main IDL file \li Interface \li The typeIcon is a 16x16 icon used in the Navigator Pane within Qt Design Studio. - \note The icon needs to be copied to the correct folder by a custom qmake rule. + \note The icon needs to be copied to the correct folder by a custom build rule. \row \li \code @designer: {libraryIcon: "images/climate.png"} @@ -327,7 +327,7 @@ \li Main IDL file \li Interface \li The libraryIcon is shown in the Library within Qt Design Studio. - \note The icon needs to be copied to the correct folder by a custom qmake rule. + \note The icon needs to be copied to the correct folder by a custom build rule. \row \li \code @config: { configurationId: "vehiclefunctions"} @@ -536,6 +536,11 @@ \li A standard Qt \c{.pri} file that contains all the generated files. Use this \c{.pri} file to include the generated files into a qmake project. \row + \li CMakeLists.txt + \li File to integrate with the CMake build system. This file defines the rules + how to build the generated files with CMake. In addition extra variables + can be exposed by using \l {qt6_set_ifcodegen_variable}. + \row \li qml/{{module|qml_type|replace('.', '/')}}/plugins.qmltypes \li QML code-completion file for use in QtCreator. \row @@ -572,6 +577,11 @@ \li A standard Qt \c{.pri} file that contains all the generated files. Use this \c{.pri} file to include the generated files into a qmake project. \row + \li CMakeLists.txt + \li File to integrate with the CMake build system. This file defines the rules + how to build the generated files with CMake. In addition extra variables + can be exposed by using \l {qt6_set_ifcodegen_variable}. + \row \li plugins.qmltypes \li QML code-completion file for use in QtCreator. \row @@ -601,6 +611,11 @@ \li A standard Qt \c{.pri} file that contains all the generated files. Use this \c{.pri} file to include the generated files into a qmake project. \row + \li CMakeLists.txt + \li File to integrate with the CMake build system. This file defines the rules + how to build the generated files with CMake. In addition extra variables + can be exposed by using \l {qt6_set_ifcodegen_variable}. + \row \li {{module.module_name|lower}}_simulation.qml \li QML simulation file that loads the interface specific QML simulation files. \row @@ -625,9 +640,9 @@ \section2 QtRemoteObjects Backend - The backend_qtro template is only available if qmake finds the QtRemoteObjects module. This - remote object backend is a client for connecting to the remote backend server; not the location - to implement the actual backend logic. + The backend_qtro template is only available if the QtRemoteObjects module was detected when building + the qtinterfaceframework repository. This backend is a client for connecting to the remote backend + server; not the location to implement the actual backend logic. \table 100% \header @@ -647,6 +662,11 @@ file to include the generated files into a qmake project. Also includes the \c{.rep} file to the project and calls the remote object compiler. \row + \li CMakeLists.txt + \li File to integrate with the CMake build system. This file defines the rules + how to build the generated files with CMake. In addition extra variables + can be exposed by using \l {qt6_set_ifcodegen_variable}. + \row \li {{interface|lower}}backend.h/cpp \li Files containing the implementation of the remote object backend. Establishes the connection and initializes the remote object replica. @@ -664,9 +684,9 @@ \section2 QtRemoteObjects Server - The server_qtro template is only available if qmake finds the QtRemoteObjects module. The - code produced only contains the source classes to inherit and the code for establishing the - connection. The developer must implement the actual backend logic. + The server_qtro template is only available if the QtRemoteObjects module was detected when building + the qtinterfaceframework repository. The code produced only contains the source classes to inherit + and the code for establishing the connection. The developer must implement the actual backend logic. \table 100% \header @@ -682,6 +702,11 @@ file to include the generated files into a qmake project. Also includes the \c{.rep} file to the project and calls the remote object compiler. \row + \li CMakeLists.txt + \li File to integrate with the CMake build system. This file defines the rules + how to build the generated files with CMake. In addition extra variables + can be exposed by using \l {qt6_set_ifcodegen_variable}. + \row \li {{interface|lower}}.rep \li The input file for the Qt’s \l [QtRemoteObjects] {Qt Remote Objects Compiler} {replica compiler} to produce the @@ -695,10 +720,10 @@ \section2 QtRemoteObjects Simulation Server - The server_qtro_simulator template is only available if qmake finds the QtRemoteObjects module. - The code produced contains a fully-implemented server that may use the same implementation as - the backend_simulator template, which uses the QIfSimulationEngine to implement the simulation - behavior in QML. + The server_qtro template is only available if the QtRemoteObjects module was detected when building + the qtinterfaceframework repository. The code produced contains a fully-implemented server that + may use the same implementation as the backend_simulator template, which uses the QIfSimulationEngine + to implement the simulation behavior in QML. By default a QCoreApplication is used in the generated server and enables the server to be run headless. To also allow instantiating UI controls inside the simulation QML code, the @@ -736,6 +761,11 @@ file to include the generated files into a qmake project. Also includes the \c{.rep} file to the project and calls the remote object compiler. \row + \li CMakeLists.txt + \li File to integrate with the CMake build system. This file defines the rules + how to build the generated files with CMake. In addition extra variables + can be exposed by using \l {qt6_set_ifcodegen_variable}. + \row \li {{interface|lower}}.rep \li The input file for the Qt’s \l [QtRemoteObjects] {Qt Remote Objects Compiler} {replica compiler} to produce the diff --git a/src/interfaceframework/doc/src/ifcodegen/template-syntax.qdoc b/src/interfaceframework/doc/src/ifcodegen/template-syntax.qdoc index 780f9824..4d947cae 100644 --- a/src/interfaceframework/doc/src/ifcodegen/template-syntax.qdoc +++ b/src/interfaceframework/doc/src/ifcodegen/template-syntax.qdoc @@ -14,7 +14,7 @@ \nextpage Use the Generator This page is about the Jinja template engine. While the most detailed description of the template -language can be found at \l {http://jinja.pocoo.org/docs/dev/templates/}{Jinja documentation}, +language can be found in the \l {https://jinja.palletsprojects.com/en/3.1.x/templates/}{Jinja documentation}, some basic concepts are given in this article. diff --git a/src/interfaceframework/qifabstractfeature.cpp b/src/interfaceframework/qifabstractfeature.cpp index 5aff3e0a..d5d072ad 100644 --- a/src/interfaceframework/qifabstractfeature.cpp +++ b/src/interfaceframework/qifabstractfeature.cpp @@ -737,9 +737,9 @@ bool QIfAbstractFeature::acceptServiceObject(QIfServiceObject *serviceObject) When reimplementing please keep in mind to connect all signals before calling this function. e.g. - /code + \code void SimpleFeature::connectToServiceObject(QIfServiceObject *serviceObject) - { + { SimpleFeatureBackendInterface *backend = backend(serviceObject); if (!backend) return; @@ -752,8 +752,8 @@ bool QIfAbstractFeature::acceptServiceObject(QIfServiceObject *serviceObject) QIfAbstractFeature::connectToServiceObject(serviceObject); // Additional initialization functions can be added here - } - /endcode + } + \endcode \sa acceptServiceObject(), disconnectFromServiceObject(), clearServiceObject() */ diff --git a/src/interfaceframework/qifconfiguration.cpp b/src/interfaceframework/qifconfiguration.cpp index 5b424605..eecb8e93 100644 --- a/src/interfaceframework/qifconfiguration.cpp +++ b/src/interfaceframework/qifconfiguration.cpp @@ -35,12 +35,17 @@ QIfConfigurationManager *QIfConfigurationManager::instance() return &s_manager; } +QIfConfigurationManager::~QIfConfigurationManager() +{ + qDeleteAll(m_settingsHash.constBegin(), m_settingsHash.constEnd()); +} QIfAbstractFeature::DiscoveryMode discoveryModeFromString(const QString &modeString) { QMetaEnum me = QMetaEnum::fromType<QIfAbstractFeature::DiscoveryMode>(); + QByteArray modeStringUtf8 = modeString.toUtf8(); bool ok = false; - int value = me.keyToValue(modeString.toUtf8().constData(), &ok); + int value = me.keyToValue(modeStringUtf8, &ok); if (ok) { return static_cast<QIfAbstractFeature::DiscoveryMode>(value); } else { @@ -61,9 +66,11 @@ QVariantMap QIfConfigurationManager::readGroup(QSettings *settings, QAnyStringVi { QVariantMap map; settings->beginGroup(group); - for (const QString& key : settings->childKeys()) + const auto keys = settings->childKeys(); + const auto groups = settings->childGroups(); + for (const QString& key : keys) map.insert(key, settings->value(key)); - for (const QString& group : settings->childGroups()) + for (const QString& group : groups) map.insert(group, readGroup(settings, group)); settings->endGroup(); return map; @@ -75,7 +82,8 @@ void QIfConfigurationManager::readInitialSettings(const QString &configPath) QSettings settings(configPath, QSettings::IniFormat); - for (const QString& group : settings.childGroups()) { + const auto groups = settings.childGroups(); + for (const QString& group : groups) { auto settingsObject = new QIfSettingsObject; settings.beginGroup(group); @@ -95,8 +103,10 @@ void QIfConfigurationManager::readInitialSettings(const QString &configPath) if (discoveryModeVariant.isValid()) { auto discoveryMode = discoveryModeFromString(discoveryModeVariant.toString()); - if (discoveryMode == QIfAbstractFeature::InvalidAutoDiscovery) + if (discoveryMode == QIfAbstractFeature::InvalidAutoDiscovery) { + delete settingsObject; return; + } settingsObject->discoveryMode = discoveryMode; settingsObject->discoveryModeSet = true; } @@ -316,7 +326,7 @@ bool QIfConfigurationManager::setServiceObject(QIfSettingsObject *so, QIfService return true; } -void QIfConfigurationManager::parseEnv(const QByteArray &rulesSrc, std::function<void(const QString &, const QString &)> func) +void QIfConfigurationManager::parseEnv(const QByteArray &rulesSrc, const std::function<void(const QString &, const QString &)> &func) { const QString content = QString::fromLocal8Bit(rulesSrc); const auto lines = content.split(QLatin1Char(';')); diff --git a/src/interfaceframework/qifconfiguration_p.h b/src/interfaceframework/qifconfiguration_p.h index b3013581..bce8c1b5 100644 --- a/src/interfaceframework/qifconfiguration_p.h +++ b/src/interfaceframework/qifconfiguration_p.h @@ -54,6 +54,7 @@ class Q_QTINTERFACEFRAMEWORK_EXPORT QIfConfigurationManager { public: static QIfConfigurationManager *instance(); + ~QIfConfigurationManager(); void readInitialSettings(const QString &configPath); QIfSettingsObject *settingsObject(const QString &group, bool create = false); @@ -70,7 +71,7 @@ public: bool setServiceObject(QIfSettingsObject *so, QIfServiceObject *serviceObject); QVariantMap readGroup(QSettings *settings, QAnyStringView group); - void parseEnv(const QByteArray &rulesSrc, std::function<void(const QString &, const QString &)> func); + void parseEnv(const QByteArray &rulesSrc, const std::function<void (const QString &, const QString &)> &func); QHash<QString, QIfSettingsObject*> m_settingsHash; QHash<QString, QIfConfiguration*> m_configurationHash; diff --git a/src/interfaceframework/qiffilterandbrowsemodel.cpp b/src/interfaceframework/qiffilterandbrowsemodel.cpp index 9df810cd..d26c8928 100644 --- a/src/interfaceframework/qiffilterandbrowsemodel.cpp +++ b/src/interfaceframework/qiffilterandbrowsemodel.cpp @@ -105,7 +105,7 @@ void QIfFilterAndBrowseModelPrivate::clearToDefaults() QIfPagingModelPrivate::resetModel(); } -void QIfFilterAndBrowseModelPrivate::onCanGoForwardChanged(const QUuid &identifier, const QVector<bool> &indexes, int start) +void QIfFilterAndBrowseModelPrivate::onCanGoForwardChanged(QUuid identifier, const QVector<bool> &indexes, int start) { if (m_identifier != identifier) return; @@ -118,7 +118,7 @@ void QIfFilterAndBrowseModelPrivate::onCanGoForwardChanged(const QUuid &identifi m_canGoForward[start + i] = indexes.at(i); } -void QIfFilterAndBrowseModelPrivate::onCanGoBackChanged(const QUuid &identifier, bool canGoBack) +void QIfFilterAndBrowseModelPrivate::onCanGoBackChanged(QUuid identifier, bool canGoBack) { if (m_identifier != identifier) return; @@ -131,7 +131,7 @@ void QIfFilterAndBrowseModelPrivate::onCanGoBackChanged(const QUuid &identifier, emit q->canGoBackChanged(m_canGoBack); } -void QIfFilterAndBrowseModelPrivate::onContentTypeChanged(const QUuid &identifier, const QString &contentType) +void QIfFilterAndBrowseModelPrivate::onContentTypeChanged(QUuid identifier, const QString &contentType) { if (m_identifier != identifier) return; @@ -158,7 +158,7 @@ void QIfFilterAndBrowseModelPrivate::onAvailableContentTypesChanged(const QStrin emit q->availableContentTypesChanged(contentTypes); } -void QIfFilterAndBrowseModelPrivate::onQueryIdentifiersChanged(const QUuid &identifier, const QSet<QString> &queryIdentifiers) +void QIfFilterAndBrowseModelPrivate::onQueryIdentifiersChanged(QUuid identifier, const QSet<QString> &queryIdentifiers) { if (m_identifier != identifier) return; diff --git a/src/interfaceframework/qiffilterandbrowsemodel.h b/src/interfaceframework/qiffilterandbrowsemodel.h index 9a4626f3..c903a826 100644 --- a/src/interfaceframework/qiffilterandbrowsemodel.h +++ b/src/interfaceframework/qiffilterandbrowsemodel.h @@ -78,10 +78,10 @@ protected: private: Q_DECLARE_PRIVATE(QIfFilterAndBrowseModel) - Q_PRIVATE_SLOT(d_func(), void onCanGoForwardChanged(const QUuid &identifier, const QVector<bool> &indexes, int start)) - Q_PRIVATE_SLOT(d_func(), void onCanGoBackChanged(const QUuid &identifier, bool canGoBack)) - Q_PRIVATE_SLOT(d_func(), void onQueryIdentifiersChanged(const QUuid &identifier, const QSet<QString> &queryIdentifiers)) - Q_PRIVATE_SLOT(d_func(), void onContentTypeChanged(const QUuid &identifier, const QString &contentType)) + Q_PRIVATE_SLOT(d_func(), void onCanGoForwardChanged(QUuid identifier, const QVector<bool> &indexes, int start)) + Q_PRIVATE_SLOT(d_func(), void onCanGoBackChanged(QUuid identifier, bool canGoBack)) + Q_PRIVATE_SLOT(d_func(), void onQueryIdentifiersChanged(QUuid identifier, const QSet<QString> &queryIdentifiers)) + Q_PRIVATE_SLOT(d_func(), void onContentTypeChanged(QUuid identifier, const QString &contentType)) Q_PRIVATE_SLOT(d_func(), void onAvailableContentTypesChanged(const QStringList &contentTypes)) }; diff --git a/src/interfaceframework/qiffilterandbrowsemodel_p.h b/src/interfaceframework/qiffilterandbrowsemodel_p.h index c7090225..1264bbad 100644 --- a/src/interfaceframework/qiffilterandbrowsemodel_p.h +++ b/src/interfaceframework/qiffilterandbrowsemodel_p.h @@ -40,11 +40,11 @@ public: void parseQuery(); void setupFilter(QIfAbstractQueryTerm* queryTerm, const QList<QIfOrderTerm> &orderTerms); void clearToDefaults() override; - void onCanGoForwardChanged(const QUuid &identifier, const QVector<bool> &indexes, int start); - void onCanGoBackChanged(const QUuid &identifier, bool canGoBack); - void onContentTypeChanged(const QUuid &identifier, const QString &contentType); + void onCanGoForwardChanged(QUuid identifier, const QVector<bool> &indexes, int start); + void onCanGoBackChanged(QUuid identifier, bool canGoBack); + void onContentTypeChanged(QUuid identifier, const QString &contentType); void onAvailableContentTypesChanged(const QStringList &contentTypes); - void onQueryIdentifiersChanged(const QUuid &identifier, const QSet<QString> &queryIdentifiers); + void onQueryIdentifiersChanged(QUuid identifier, const QSet<QString> &queryIdentifiers); QIfFilterAndBrowseModelInterface *searchBackend() const; void updateContentType(const QString &contentType); diff --git a/src/interfaceframework/qifpagingmodel.cpp b/src/interfaceframework/qifpagingmodel.cpp index 0a12ebe7..d7285c84 100644 --- a/src/interfaceframework/qifpagingmodel.cpp +++ b/src/interfaceframework/qifpagingmodel.cpp @@ -65,7 +65,7 @@ void QIfPagingModelPrivate::onInitializationDone() resetModel(); } -void QIfPagingModelPrivate::onCapabilitiesChanged(const QUuid &identifier, QtInterfaceFrameworkModule::ModelCapabilities capabilities) +void QIfPagingModelPrivate::onCapabilitiesChanged(QUuid identifier, QtInterfaceFrameworkModule::ModelCapabilities capabilities) { if (!identifier.isNull() && identifier != m_identifier) return; @@ -78,7 +78,7 @@ void QIfPagingModelPrivate::onCapabilitiesChanged(const QUuid &identifier, QtInt emit q->capabilitiesChanged(capabilities); } -void QIfPagingModelPrivate::onDataFetched(const QUuid &identifier, const QList<QVariant> &items, int start, bool moreAvailable) +void QIfPagingModelPrivate::onDataFetched(QUuid identifier, const QList<QVariant> &items, int start, bool moreAvailable) { if (!identifier.isNull() && (!items.count() || identifier != m_identifier)) return; @@ -112,7 +112,7 @@ void QIfPagingModelPrivate::onDataFetched(const QUuid &identifier, const QList<Q } } -void QIfPagingModelPrivate::onCountChanged(const QUuid &identifier, int new_length) +void QIfPagingModelPrivate::onCountChanged(QUuid identifier, int new_length) { if (m_loadingType != QIfPagingModel::DataChanged || (!identifier.isNull() && identifier != m_identifier) || m_itemList.count() == new_length) return; @@ -126,7 +126,7 @@ void QIfPagingModelPrivate::onCountChanged(const QUuid &identifier, int new_leng m_availableChunks.resize(new_length / m_chunkSize + 1); } -void QIfPagingModelPrivate::onDataChanged(const QUuid &identifier, const QList<QVariant> &data, int start, int count) +void QIfPagingModelPrivate::onDataChanged(QUuid identifier, const QList<QVariant> &data, int start, int count) { if (!identifier.isNull() && identifier != m_identifier) return; diff --git a/src/interfaceframework/qifpagingmodel.h b/src/interfaceframework/qifpagingmodel.h index c768894c..4d45ff0a 100644 --- a/src/interfaceframework/qifpagingmodel.h +++ b/src/interfaceframework/qifpagingmodel.h @@ -88,10 +88,10 @@ protected: private: Q_DECLARE_PRIVATE(QIfPagingModel) - Q_PRIVATE_SLOT(d_func(), void onCapabilitiesChanged(const QUuid &identifier, QtInterfaceFrameworkModule::ModelCapabilities capabilities)) - Q_PRIVATE_SLOT(d_func(), void onDataFetched(const QUuid &identifer, const QList<QVariant> &items, int start, bool moreAvailable)) - Q_PRIVATE_SLOT(d_func(), void onCountChanged(const QUuid &identifier, int new_length)) - Q_PRIVATE_SLOT(d_func(), void onDataChanged(const QUuid &identifier, const QList<QVariant> &data, int start, int count)) + Q_PRIVATE_SLOT(d_func(), void onCapabilitiesChanged(QUuid identifier, QtInterfaceFrameworkModule::ModelCapabilities capabilities)) + Q_PRIVATE_SLOT(d_func(), void onDataFetched(QUuid identifer, const QList<QVariant> &items, int start, bool moreAvailable)) + Q_PRIVATE_SLOT(d_func(), void onCountChanged(QUuid identifier, int new_length)) + Q_PRIVATE_SLOT(d_func(), void onDataChanged(QUuid identifier, const QList<QVariant> &data, int start, int count)) Q_PRIVATE_SLOT(d_func(), void onFetchMoreThresholdReached()) }; diff --git a/src/interfaceframework/qifpagingmodel_p.h b/src/interfaceframework/qifpagingmodel_p.h index 322916d2..b35539ca 100644 --- a/src/interfaceframework/qifpagingmodel_p.h +++ b/src/interfaceframework/qifpagingmodel_p.h @@ -37,10 +37,10 @@ public: void initialize() override; void onInitializationDone(); - void onCapabilitiesChanged(const QUuid &identifier, QtInterfaceFrameworkModule::ModelCapabilities capabilities); - void onDataFetched(const QUuid &identifier, const QList<QVariant> &items, int start, bool moreAvailable); - void onCountChanged(const QUuid &identifier, int new_length); - void onDataChanged(const QUuid &identifier, const QList<QVariant> &data, int start, int count); + void onCapabilitiesChanged(QUuid identifier, QtInterfaceFrameworkModule::ModelCapabilities capabilities); + void onDataFetched(QUuid identifier, const QList<QVariant> &items, int start, bool moreAvailable); + void onCountChanged(QUuid identifier, int new_length); + void onDataChanged(QUuid identifier, const QList<QVariant> &data, int start, int count); void onFetchMoreThresholdReached(); virtual void resetModel(); virtual void clearToDefaults(); diff --git a/src/interfaceframework/qifpendingreply.h b/src/interfaceframework/qifpendingreply.h index 7149dd5e..73ee362f 100644 --- a/src/interfaceframework/qifpendingreply.h +++ b/src/interfaceframework/qifpendingreply.h @@ -114,17 +114,15 @@ public: else if (failed) failed(); } else { - QSharedPointer<QIfPendingReplyWatcher> w = m_watcher; + QWeakPointer<QIfPendingReplyWatcher> w = m_watcher; if (success) { QObject::connect(watcher(), &QIfPendingReplyWatcher::replySuccess, watcher(), [success, w]() { - success(w->value().value<T>()); - }); - } - if (failed) { - QObject::connect(watcher(), &QIfPendingReplyWatcher::replyFailed, watcher(), [failed]() { - failed(); + if (w) + success(w.toStrongRef()->value().value<T>()); }); } + if (failed) + QObject::connect(watcher(), &QIfPendingReplyWatcher::replyFailed, watcher(), failed); } } @@ -163,17 +161,15 @@ public: else if (failed) failed(); } else { - QSharedPointer<QIfPendingReplyWatcher> w = m_watcher; + QWeakPointer<QIfPendingReplyWatcher> w = m_watcher; if (success) { QObject::connect(watcher(), &QIfPendingReplyWatcher::replySuccess, watcher(), [success, w]() { - success(w->value()); - }); - } - if (failed) { - QObject::connect(watcher(), &QIfPendingReplyWatcher::replyFailed, watcher(), [failed]() { - failed(); + if (w) + success(w.toStrongRef()->value()); }); } + if (failed) + QObject::connect(watcher(), &QIfPendingReplyWatcher::replyFailed, watcher(), failed); } } @@ -208,17 +204,10 @@ public: else if (failed) failed(); } else { - QSharedPointer<QIfPendingReplyWatcher> w = m_watcher; - if (success) { - QObject::connect(watcher(), &QIfPendingReplyWatcher::replySuccess, watcher(), [success, w]() { - success(); - }); - } - if (failed) { - QObject::connect(watcher(), &QIfPendingReplyWatcher::replyFailed, watcher(), [failed]() { - failed(); - }); - } + if (success) + QObject::connect(watcher(), &QIfPendingReplyWatcher::replySuccess, watcher(), success); + if (failed) + QObject::connect(watcher(), &QIfPendingReplyWatcher::replyFailed, watcher(), failed); } } diff --git a/src/interfaceframework/qifproxyserviceobject.cpp b/src/interfaceframework/qifproxyserviceobject.cpp index 54b7b865..a8c1eb7e 100644 --- a/src/interfaceframework/qifproxyserviceobject.cpp +++ b/src/interfaceframework/qifproxyserviceobject.cpp @@ -43,12 +43,14 @@ QIfProxyServiceObjectPrivate::QIfProxyServiceObjectPrivate(const QHash<QString, /*! Creates a new QIfProxyServiceObject for the given \a interface. + The \a parent argument is sent to the QIfServiceObject constructor. + This can be used to load a backend which is derived from QIfServiceInterface and supposed to be loaded as a plugin, but is part of the same library and can be loaded directly instead. e.g. within a autotest */ -QIfProxyServiceObject::QIfProxyServiceObject(QIfServiceInterface *interface) - : QIfServiceObject() +QIfProxyServiceObject::QIfProxyServiceObject(QIfServiceInterface *interface, QObject *parent) + : QIfServiceObject(parent) , d_ptr(new QIfProxyServiceObjectPrivate(interface)) { } @@ -59,12 +61,17 @@ QIfProxyServiceObject::QIfProxyServiceObject(QIfServiceInterface *interface) This can be used to directly connect a feature class to the backend implementing the QIfFeatureInterface. */ -QIfProxyServiceObject::QIfProxyServiceObject(const QHash<QString, QIfFeatureInterface*> &interfaceMap) - : QIfServiceObject() +QIfProxyServiceObject::QIfProxyServiceObject(const QHash<QString, QIfFeatureInterface*> &interfaceMap, QObject *parent) + : QIfServiceObject(parent) , d_ptr(new QIfProxyServiceObjectPrivate(interfaceMap)) { } +QIfProxyServiceObject::~QIfProxyServiceObject() +{ + delete d_ptr; +} + /*! \reimp */ diff --git a/src/interfaceframework/qifproxyserviceobject.h b/src/interfaceframework/qifproxyserviceobject.h index 87429d18..046ed1a1 100644 --- a/src/interfaceframework/qifproxyserviceobject.h +++ b/src/interfaceframework/qifproxyserviceobject.h @@ -20,8 +20,9 @@ class Q_QTINTERFACEFRAMEWORK_EXPORT QIfProxyServiceObject : public QIfServiceObj Q_OBJECT public: - explicit QIfProxyServiceObject(QIfServiceInterface *interface); - explicit QIfProxyServiceObject(const QHash<QString, QIfFeatureInterface*> &interfaceMap); + explicit QIfProxyServiceObject(QIfServiceInterface *interface, QObject *parent = nullptr); + explicit QIfProxyServiceObject(const QHash<QString, QIfFeatureInterface*> &interfaceMap, QObject *parent = nullptr); + ~QIfProxyServiceObject() override; QStringList interfaces() const override; QIfFeatureInterface *interfaceInstance(const QString &interface) const override; diff --git a/src/interfaceframework/qifqmlconversion_helper.cpp b/src/interfaceframework/qifqmlconversion_helper.cpp index 6d2a1a59..5aa65507 100644 --- a/src/interfaceframework/qifqmlconversion_helper.cpp +++ b/src/interfaceframework/qifqmlconversion_helper.cpp @@ -12,13 +12,6 @@ QT_BEGIN_NAMESPACE -namespace qtif_helper { - static const QString valueLiteral = QStringLiteral("value"); - static const QString typeLiteral = QStringLiteral("type"); -} - -using namespace qtif_helper; - void qtif_qmlOrCppWarning(const QObject *obj, const char *errorString) { qtif_qmlOrCppWarning(obj, QLatin1String(errorString)); @@ -65,6 +58,9 @@ void qtif_qmlOrCppWarning(const QObject *obj, const QString &errorString) */ QVariant qtif_convertFromJSON(const QVariant &value) { + static const QString valueLiteral = QStringLiteral("value"); + static const QString typeLiteral = QStringLiteral("type"); + QVariant val = value; // First try to convert the values to a Map or a List // This is needed as it could also store a QStringList or a Hash @@ -83,7 +79,7 @@ QVariant qtif_convertFromJSON(const QVariant &value) QString enumValue = value.toString(); const int lastIndex = enumValue.lastIndexOf(QStringLiteral("::")); const QString className = enumValue.left(lastIndex) + QStringLiteral("*"); - enumValue = enumValue.right(enumValue.size() - lastIndex - 2); + QByteArray enumValueUtf8 = enumValue.right(enumValue.size() - lastIndex - 2).toUtf8(); QMetaType metaType = QMetaType::fromName(className.toLatin1()); const QMetaObject *mo = metaType.metaObject(); if (Q_UNLIKELY(!mo)) { @@ -96,7 +92,7 @@ QVariant qtif_convertFromJSON(const QVariant &value) for (int i = mo->enumeratorOffset(); i < mo->enumeratorCount(); ++i) { QMetaEnum me = mo->enumerator(i); bool ok = false; - int value = me.keysToValue(enumValue.toLatin1(), &ok); + int value = me.keysToValue(enumValueUtf8, &ok); if (ok) { return QVariant(QMetaType::fromName((QLatin1String(me.scope()) + QStringLiteral("::") + QLatin1String(me.enumName())).toLatin1()), &value); } @@ -114,6 +110,8 @@ QVariant qtif_convertFromJSON(const QVariant &value) } void *gadget = metaType.create(); + auto cleanup = qScopeGuard([gadget, metaType] { metaType.destroy(gadget); }); + if (!Q_UNLIKELY(gadget)) { qWarning("Couldn't create a new instance of %s", metaType.name()); return QVariant(); diff --git a/src/interfaceframework/qifserviceinterface.h b/src/interfaceframework/qifserviceinterface.h index a6c39789..8ee21c16 100644 --- a/src/interfaceframework/qifserviceinterface.h +++ b/src/interfaceframework/qifserviceinterface.h @@ -43,6 +43,7 @@ public: T inst = qif_interface_cast<T>(interfaceInstance(interfaceName)); return inst; } + }; #define QIfServiceInterface_iid "org.qt-project.interfaceframework.QIfServiceInterface/1.0" diff --git a/src/interfaceframework/qifservicemanager.cpp b/src/interfaceframework/qifservicemanager.cpp index 9585bba7..e4596e6e 100644 --- a/src/interfaceframework/qifservicemanager.cpp +++ b/src/interfaceframework/qifservicemanager.cpp @@ -247,7 +247,7 @@ void QIfServiceManagerPrivate::registerBackend(const QString &fileName, const QJ addBackend(backend); } -void QIfServiceManagerPrivate::registerStaticBackend(QStaticPlugin plugin) +void QIfServiceManagerPrivate::registerStaticBackend(const QStaticPlugin &plugin) { QVariantMap backendMetaData = plugin.metaData().value(metaDataLiteral).toVariant().toMap(); const char* pluginName = plugin.instance()->metaObject()->className(); @@ -527,8 +527,8 @@ QIfServiceInterface *QIfServiceManagerPrivate::loadServiceBackendInterface(struc For more information about QIfServiceManager and how it works, see its \l{QIfServiceManager}{C++ documentation}. */ -QIfServiceManager::QIfServiceManager() - : QAbstractListModel(nullptr) +QIfServiceManager::QIfServiceManager(QObject *parent) + : QAbstractListModel(parent) , d_ptr(new QIfServiceManagerPrivate(this)) { QtInterfaceFrameworkModule::registerTypes(); @@ -540,7 +540,7 @@ QIfServiceManager::QIfServiceManager() */ QIfServiceManager *QIfServiceManager::instance() { - static auto *instance = new QIfServiceManager(); + static auto *instance = new QIfServiceManager(qApp); return instance; } @@ -551,6 +551,12 @@ QIfServiceManager *QIfServiceManager::create(QQmlEngine *, QJSEngine *) return manager; } +QIfServiceManager::~QIfServiceManager() +{ + unloadAllBackends(); + delete d_ptr; +} + /*! \qmlmethod list<ServiceObject> ServiceManager::findServiceByInterface(interface, searchFlags, preferredBackends) @@ -595,6 +601,8 @@ QList<QIfServiceObject *> QIfServiceManager::findServiceByInterface(const QStrin one interface, supported by the backend. The \a backendType indicates the type of the backend and influences whether the backend can be found by the Feature's auto discovery option. + The ownership of \a serviceBackendInterface is transferred to the QIfServiceManager. + Returns \c true if the backend was successfully registered; otherwise \c false. \sa QIfServiceInterface diff --git a/src/interfaceframework/qifservicemanager.h b/src/interfaceframework/qifservicemanager.h index cea53dbe..c6be3a45 100644 --- a/src/interfaceframework/qifservicemanager.h +++ b/src/interfaceframework/qifservicemanager.h @@ -46,6 +46,7 @@ public: static QIfServiceManager *instance(); static QIfServiceManager *create(QQmlEngine *, QJSEngine *); + ~QIfServiceManager() override; Q_INVOKABLE QList<QIfServiceObject*> findServiceByInterface(const QString &interface, QIfServiceManager::SearchFlags searchFlags = IncludeAll, const QStringList &preferredBackends = QStringList()); Q_INVOKABLE bool hasInterface(const QString &interface) const; @@ -59,7 +60,7 @@ public: QHash<int, QByteArray> roleNames() const override; private: - explicit QIfServiceManager(); + explicit QIfServiceManager(QObject *parent = nullptr); QIfServiceManagerPrivate * const d_ptr; Q_DECLARE_PRIVATE(QIfServiceManager) }; diff --git a/src/interfaceframework/qifservicemanager_p.h b/src/interfaceframework/qifservicemanager_p.h index 2c69ad1a..aa8dd25a 100644 --- a/src/interfaceframework/qifservicemanager_p.h +++ b/src/interfaceframework/qifservicemanager_p.h @@ -61,7 +61,7 @@ public: QList<QIfServiceObject*> findServiceByInterface(const QString &interface, QIfServiceManager::SearchFlags searchFlags, const QStringList &preferredBackends) const; void searchPlugins(); - void registerStaticBackend(QStaticPlugin plugin); + void registerStaticBackend(const QStaticPlugin &plugin); void registerBackend(const QString &fileName, const QJsonObject &metaData); bool registerBackend(QObject *serviceBackendInterface, const QStringList &interfaces, QIfServiceManager::BackendType backendType); void addBackend(struct Backend *backend); diff --git a/src/interfaceframework/qifsimulationengine.cpp b/src/interfaceframework/qifsimulationengine.cpp index e4c89d5f..7056afb4 100644 --- a/src/interfaceframework/qifsimulationengine.cpp +++ b/src/interfaceframework/qifsimulationengine.cpp @@ -18,11 +18,11 @@ QT_BEGIN_NAMESPACE namespace qtif_helper { - static const QString qrcUrlLiteral = QStringLiteral("qrc:"); - static const QString qrcLiteral = QStringLiteral("qrc"); - static const QString resourceLiteral = QStringLiteral(":/"); - QUrl toQmlUrl(const QString &path) { + static const QString qrcUrlLiteral = QStringLiteral("qrc:"); + static const QString qrcLiteral = QStringLiteral("qrc"); + static const QString resourceLiteral = QStringLiteral(":/"); + if (path.startsWith(qrcUrlLiteral)) return path; else if (path.startsWith(resourceLiteral)) @@ -214,14 +214,23 @@ using namespace qtif_helper; \endcode */ +/*! + Constructs a new QIfSimulationEngine with the given \a parent. +*/ QIfSimulationEngine::QIfSimulationEngine(QObject *parent) : QIfSimulationEngine(QString(), parent) { } +/*! + Constructs a new QIfSimulationEngine with the given \a identifier and \a parent. + + The \a identifier can be used to override the simulation QML file or the simulation data file. + \sa Runtime Override +*/ QIfSimulationEngine::QIfSimulationEngine(const QString &identifier, QObject *parent) : QQmlApplicationEngine (parent) - , m_globalObject(new QIfSimulationGlobalObject) + , m_globalObject(new QIfSimulationGlobalObject(this)) , m_identifier(identifier) { rootContext()->setContextProperty(QStringLiteral("IfSimulator"), m_globalObject); diff --git a/src/interfaceframework/qifsimulationglobalobject.cpp b/src/interfaceframework/qifsimulationglobalobject.cpp index dc9a3fb1..9dbe032d 100644 --- a/src/interfaceframework/qifsimulationglobalobject.cpp +++ b/src/interfaceframework/qifsimulationglobalobject.cpp @@ -244,7 +244,7 @@ void QIfSimulationGlobalObject::setSimulationData(const QVariant &simulationData } /*! - \qmlmethod IfSimulator::findData(object data, string interface) + \qmlmethod var IfSimulator::findData(object data, string interface) Searches for the key \a interface within \a data and returns the stored values. Returns undefined if no data was found for this \a interface. @@ -278,7 +278,7 @@ QVariantMap QIfSimulationGlobalObject::findData(const QVariantMap &data, const Q } /*! - \qmlmethod IfSimulator::initializeDefault(object data, QObject* object) + \qmlmethod void IfSimulator::initializeDefault(object data, QObject* object) Applies the default values read from \a data to \a object. @@ -287,15 +287,16 @@ QVariantMap QIfSimulationGlobalObject::findData(const QVariantMap &data, const Q void QIfSimulationGlobalObject::initializeDefault(const QVariantMap &data, QObject *object) { for (auto i = data.constBegin(); i != data.constEnd(); ++i) { + QByteArray key = i.key().toLatin1(); const QVariant defVal = defaultValue(i.value().toMap()); if (defVal.isValid()) { - QVariant currentValue = object->property(i.key().toLatin1()); + QVariant currentValue = object->property(key); if (QIfPagingModelInterface *model = currentValue.value<QIfPagingModelInterface*>()) { QVariantList list = defVal.toList(); for (auto i = list.crbegin(); i != list.crend(); ++i) QMetaObject::invokeMethod(model, "insert", createArgument(int(0)), createArgument(*i)); } else { - object->setProperty(i.key().toLatin1(), defVal); + object->setProperty(key, defVal); } } @@ -309,14 +310,14 @@ void QIfSimulationGlobalObject::initializeDefault(const QVariantMap &data, QObje if (defVal.isValid()) { QObject *zoneObject = map->value(zone).value<QObject*>(); if (zoneObject) - zoneObject->setProperty(i.key().toLatin1(), defVal); + zoneObject->setProperty(key, defVal); } } } } /*! - \qmlmethod IfSimulator::defaultValue(object data, string zone) + \qmlmethod var IfSimulator::defaultValue(object data, string zone) Provides the default value stored in \a data for the given \a zone. If \a zone is undefined or the data doesn't provide a default value for the given \a zone, it returns the unzoned default @@ -330,7 +331,7 @@ QVariant QIfSimulationGlobalObject::defaultValue(const QVariantMap &data, const } /*! - \qmlmethod IfSimulator::constraint(object data, string zone) + \qmlmethod string IfSimulator::constraint(object data, string zone) Searches for all boundary settings in \a data for the given \a zone and returns the constraint (which is enforced for newly set values) in a human readable form. @@ -371,7 +372,7 @@ QString QIfSimulationGlobalObject::constraint(const QVariantMap &data, const QSt } /*! - \qmlmethod IfSimulator::checkSettings(object data, var value, string zone) + \qmlmethod bool IfSimulator::checkSettings(object data, var value, string zone) Searches for all boundary settings in \a data for the given \a zone and returns whether the provided \a value meets this constraint. @@ -442,7 +443,7 @@ bool QIfSimulationGlobalObject::checkSettings(const QVariantMap &data, const QVa } /*! - \qmlmethod IfSimulator::parseDomainValue(object data, string domain, string zone) + \qmlmethod var IfSimulator::parseDomainValue(object data, string domain, string zone) Search for the \a domain in \a data for the given \a zone. If \a zone is undefined or the data doesn't provide this domain for the given \a zone, it returns the unzoned domain diff --git a/src/interfaceframework/queryparser/qifqueryparser_p.h b/src/interfaceframework/queryparser/qifqueryparser_p.h index 180e9e1e..7dc4659b 100644 --- a/src/interfaceframework/queryparser/qifqueryparser_p.h +++ b/src/interfaceframework/queryparser/qifqueryparser_p.h @@ -689,6 +689,5 @@ void QIfQueryParser::setErrorString(const QString &error) QT_END_NAMESPACE - #endif // QIFQUERYPARSER_P_H diff --git a/src/tools/ifcodegen/deploy-virtualenv-files.txt b/src/tools/ifcodegen/deploy-virtualenv-files.txt index a5cf0f66..13ab3a93 100644 --- a/src/tools/ifcodegen/deploy-virtualenv-files.txt +++ b/src/tools/ifcodegen/deploy-virtualenv-files.txt @@ -59,6 +59,7 @@ configparser.py contextlib.py crypt.py csv.py +dataclasses.py datetime.py decimal.py difflib.py diff --git a/src/tools/ifcodegen/templates/backend_qtro/backend.cpp.tpl b/src/tools/ifcodegen/templates/backend_qtro/backend.cpp.tpl index fd9a796d..75e28f89 100644 --- a/src/tools/ifcodegen/templates/backend_qtro/backend.cpp.tpl +++ b/src/tools/ifcodegen/templates/backend_qtro/backend.cpp.tpl @@ -62,7 +62,7 @@ void {{zone_class}}::sync() {% for property in interface.properties %} {% if not property.type.is_model %} QRemoteObjectPendingReply<{{property|return_type}}> {{property}}Reply = m_parent->m_replica->{{property|getter_name}}(m_zone); - auto {{property}}Watcher = new QRemoteObjectPendingCallWatcher({{property}}Reply); + auto {{property}}Watcher = new QRemoteObjectPendingCallWatcher({{property}}Reply, this); connect({{property}}Watcher, &QRemoteObjectPendingCallWatcher::finished, this, [this](QRemoteObjectPendingCallWatcher *self) mutable { if (self->error() == QRemoteObjectPendingCallWatcher::NoError) { m_{{property}} = self->returnValue().value<{{property|return_type}}>(); @@ -176,7 +176,7 @@ void {{class}}::syncZones() if (m_replica.isNull()) return; QRemoteObjectPendingReply<QStringList> zoneReply = m_replica->availableZones(); - auto zoneWatcher = new QRemoteObjectPendingCallWatcher(zoneReply); + auto zoneWatcher = new QRemoteObjectPendingCallWatcher(zoneReply, this); connect(zoneWatcher, &QRemoteObjectPendingCallWatcher::finished, this, [this, zoneReply](QRemoteObjectPendingCallWatcher *self) mutable { if (self->error() == QRemoteObjectPendingCallWatcher::NoError) { if (!m_synced) { diff --git a/src/tools/ifcodegen/templates/frontend/interface.cpp.tpl b/src/tools/ifcodegen/templates/frontend/interface.cpp.tpl index 1a0e52ab..a1607e10 100644 --- a/src/tools/ifcodegen/templates/frontend/interface.cpp.tpl +++ b/src/tools/ifcodegen/templates/frontend/interface.cpp.tpl @@ -61,6 +61,18 @@ {% endif %} } +{{class}}Private::~{{class}}Private() +{ +{% for property in interface.properties %} +{% if property.type.is_model %} + if (m_{{property}}) { + delete m_{{property}}->serviceObject(); + delete m_{{property}}; + } +{% endif %} +{% endfor %} +} + /*! \internal */ {{class}}Private *{{class}}Private::get({{class}} *v) { diff --git a/src/tools/ifcodegen/templates/frontend/interface_p.h.tpl b/src/tools/ifcodegen/templates/frontend/interface_p.h.tpl index 10895c54..bfb51b57 100644 --- a/src/tools/ifcodegen/templates/frontend/interface_p.h.tpl +++ b/src/tools/ifcodegen/templates/frontend/interface_p.h.tpl @@ -56,6 +56,7 @@ public: {{class}}Private(const QString &interface, {{class}} *parent); {% endif %} {% endif %} + ~{{class}}Private(); static {{class}}Private *get({{class}} *p); static const {{class}}Private *get(const {{class}} *p); diff --git a/src/tools/ifcodegen/templates/test/tst_test.cpp.tpl b/src/tools/ifcodegen/templates/test/tst_test.cpp.tpl index 0261605a..01a6ef84 100644 --- a/src/tools/ifcodegen/templates/test/tst_test.cpp.tpl +++ b/src/tools/ifcodegen/templates/test/tst_test.cpp.tpl @@ -34,8 +34,8 @@ class {{interface}}TestBackend : public {{interface}}BackendInterface Q_OBJECT public: - {{interface}}TestBackend() - : {{interface}}BackendInterface() + {{interface}}TestBackend(QObject *parent = nullptr) + : {{interface}}BackendInterface(parent) {% for property in interface.properties %} {% if property.type.is_model %} {% if interface_zoned %} @@ -167,7 +167,7 @@ public: explicit {{interface}}TestServiceObject(QObject *parent=nullptr) : QIfServiceObject(parent), m_name(QLatin1String("")) { - m_backend = new {{interface}}TestBackend; + m_backend = new {{interface}}TestBackend(this); m_interfaces << {{module.module_name|upperfirst}}_{{interface}}_iid; } |
