diff options
author | Dominik Holland <dominik.holland@pelagicore.com> | 2018-06-22 14:16:31 +0200 |
---|---|---|
committer | Dominik Holland <dominik.holland@pelagicore.com> | 2018-07-16 06:25:31 +0000 |
commit | a060afede95b2d87b3ba24963a36d50158fd2a6b (patch) | |
tree | 88b5f48a9d0f01ebaa4ec369fba2925c222b5441 | |
parent | ea17f5cf9b5029101876c97c956d468e93e8f969 (diff) |
Use the new QIviPagingModel for the model type in qface files
This extends the templates to return a QIviPagingModel for
all model types and also generate the backend interface
for all the models in the backend_simulator template.
The test template is extended to also generate a test for
the model where an item is fetched from the frontend and
the data provided by the backend.
Task-number: AUTOSUITE-421
Change-Id: I1eb26ddcf6d448559221925dd69701e137e5f8a0
Reviewed-by: Antti Hölttä <ahoelttae@luxoft.com>
23 files changed, 341 insertions, 373 deletions
diff --git a/src/tools/ivigenerator/common/qtivi_macros.j2 b/src/tools/ivigenerator/common/qtivi_macros.j2 index 5f4be7b..1cb9e0d 100644 --- a/src/tools/ivigenerator/common/qtivi_macros.j2 +++ b/src/tools/ivigenerator/common/qtivi_macros.j2 @@ -80,7 +80,7 @@ QIviPendingReply<{{operation|return_type}}> {{scope}}{{operation}}({{join_params {# property declaration, Q_PROPERTY(...) #} {% macro property(property, notify = true) %} -{% if property.readonly or property.const %} +{% if property.readonly or property.const or property.type.is_model %} {% set write = '' %} {% else %} {% set write = ' WRITE ' + property|setter_name %} @@ -129,7 +129,7 @@ void {{scope}}{{property|setter_name}}({{property|parameter_type}}{{zone}}) {# helper macro for defining a property notifier and a corresponding callback. # This is an internal function and not intended to be used inside a template. #} -{% macro _prop_notify(property, class, zoned, prefix) %} +{% macro _prop_notify(property, class, zoned, prefix, model_interface) %} {% if prefix|count %} {% set prop = prefix + property|upperfirst %} {% else %} @@ -145,23 +145,28 @@ void {{scope}}{{property|setter_name}}({{property|parameter_type}}{{zone}}) {% else %} {% set zone = '' %} {% endif %} -void {{scope}}{{prop}}Changed({{property|parameter_type}}{{zone}}) +{% if property.type.is_model and model_interface %} +{% set type = 'QIviPagingModelInterface *'+property.name %} +{% else %} +{% set type = property|parameter_type %} +{% endif %} +void {{scope}}{{prop}}Changed({{type}}{{zone}}) {%- endmacro %} {# signal declaration for property notifier. # pass the class parameter in order to add the scope:: -specifier. # use zoned to add the zone-specifier #} -{% macro prop_notify(property, class = '', zoned = false) %} -{{_prop_notify(property, class, zoned, '')}} +{% macro prop_notify(property, class = '', zoned = false, model_interface = false) %} +{{_prop_notify(property, class, zoned, '', model_interface)}} {%- endmacro %} {# callback slot declaration for property notifier. # pass the class parameter in order to add the scope:: -specifier. # use zoned to add the zone-specifier #} -{% macro on_prop_changed(property, class = '', zoned = false) %} -{{_prop_notify(property, class, zoned, 'on')}} +{% macro on_prop_changed(property, class = '', zoned = false, model_interface = false) %} +{{_prop_notify(property, class, zoned, 'on', model_interface)}} {%- endmacro %} diff --git a/src/tools/ivigenerator/generate.py b/src/tools/ivigenerator/generate.py index 4838a22..6278d74 100755 --- a/src/tools/ivigenerator/generate.py +++ b/src/tools/ivigenerator/generate.py @@ -165,7 +165,7 @@ def test_type_value(symbol): values_string = ', '.join(test_type_value(e) for e in symbol.type.reference.fields) return '{0}{1}({2})'.format(prefix, symbol.type, values_string) elif symbol.type.is_model: - return 'new {0}{1}Model()'.format(prefix, symbol.type.nested) + return 'new QIviPagingModel()' return 'XXX' def default_value(symbol, zone='='): @@ -176,7 +176,8 @@ def default_value(symbol, zone='='): if symbol.type.is_model: nested = symbol.type.nested # TODO: find a way of passing parent object - return 'new {0}Model(parent)'.format(nested) + return 'nullptr' + #return 'new {0}Model(parent)'.format(nested) if 'config_simulator' in symbol.tags and 'default' in symbol.tags['config_simulator']: res = symbol.tags['config_simulator']['default'] if isinstance(res, dict): @@ -222,7 +223,7 @@ def parameter_type(symbol): if nested.is_primitive: return '{0}VariantModel *{1}'.format(prefix, symbol) elif nested.is_complex: - return '{0}{1}Model *{2}'.format(prefix, nested, symbol) + return 'QIviPagingModel *{0}'.format(symbol) else: return 'const {0}{1} &{2}'.format(prefix, symbol.type, symbol) return 'QFace Error: Unknown parameter {0} of type {1}'.format(symbol, symbol.type) @@ -251,7 +252,7 @@ def return_type(symbol): if nested.is_primitive: return '{0}VariantModel *'.format(prefix) elif nested.is_complex: - return '{0}{1}Model *'.format(prefix, nested) + return 'QIviPagingModel *' else: return '{0}{1}'.format(prefix, symbol.type) return 'QFace Error: Unknown symbol {0} of type {1}'.format(symbol, symbol.type) diff --git a/src/tools/ivigenerator/ivigenerator.pro b/src/tools/ivigenerator/ivigenerator.pro index 47f3bf4..5e4df1c 100644 --- a/src/tools/ivigenerator/ivigenerator.pro +++ b/src/tools/ivigenerator/ivigenerator.pro @@ -26,16 +26,15 @@ templates_frontend.files += \ templates_frontend/modulefactory.cpp.tpl \ templates_frontend/modulefactory.h.tpl \ templates_frontend/struct.cpp.tpl \ - templates_frontend/struct.h.tpl \ - templates_frontend/structmodel.cpp.tpl \ - templates_frontend/structmodel.h.tpl \ - templates_frontend/structmodel_p.h.tpl + templates_frontend/struct.h.tpl templates_frontend.path = $$[QT_HOST_BINS]/ivigenerator/templates_frontend templates_backend_simulator.files += \ templates_backend_simulator/backend.cpp.tpl \ templates_backend_simulator/backend.h.tpl \ templates_backend_simulator/backend_range.cpp.tpl \ + templates_backend_simulator/pagingmodel.h.tpl \ + templates_backend_simulator/pagingmodel.cpp.tpl \ templates_backend_simulator/plugin.cpp.tpl \ templates_backend_simulator/plugin.h.tpl \ templates_backend_simulator/plugin.json \ @@ -90,7 +89,8 @@ templates_test.files += \ templates_test/tst_test.h.tpl \ templates_test/tst_test.cpp.tpl \ templates_test/module.pri.tpl \ - templates_test/main.cpp.tpl + templates_test/main.cpp.tpl \ + templates_test/pagingmodel.h.tpl templates_test.path = $$[QT_HOST_BINS]/ivigenerator/templates_test generator.files += \ diff --git a/src/tools/ivigenerator/templates_backend_simulator/backend.cpp.tpl b/src/tools/ivigenerator/templates_backend_simulator/backend.cpp.tpl index 9867d9a..fc44f05 100644 --- a/src/tools/ivigenerator/templates_backend_simulator/backend.cpp.tpl +++ b/src/tools/ivigenerator/templates_backend_simulator/backend.cpp.tpl @@ -43,18 +43,18 @@ {% set interface_zoned = interface.tags.config and interface.tags.config.zoned %} #include "{{class|lower}}.h" -{% for property in interface.properties %} -{% if property.type.is_model %} -#include "{{property|model_type|lower}}.h" -{% endif %} -{% endfor %} - #include <QDebug> {% if 'simulator' in features %} #include <QtSimulator> {% endif %} +{% for property in interface.properties %} +{% if property.type.is_model %} +{% include "pagingmodel.cpp.tpl" %} +{% endif %} +{% endfor %} + QT_BEGIN_NAMESPACE /*! @@ -66,7 +66,11 @@ QT_BEGIN_NAMESPACE : {{class}}Interface(parent) {% for property in interface.properties %} {% if not property.tags.config_simulator or not property.tags.config_simulator.zoned %} +{% if property.type.is_model %} + , m_{{ property }}(new {{property|upperfirst}}Model(this)) +{% else %} , m_{{ property }}({{property|default_value}}) +{% endif %} {% endif %} {% endfor %} {% if 'simulator' in features %} @@ -80,7 +84,11 @@ QT_BEGIN_NAMESPACE ZoneBackend {{zone_name}}Zone; {% for property in interface.properties %} {% if property.tags.config_simulator and property.tags.config_simulator.zoned %} +{% if property.type.is_model %} + {{zone_name}}Zone.{{property}} = new {{property|upperfirst}}Model(this); +{% else %} {{zone_name}}Zone.{{property}} = {{property|default_value(zone_name)}}; +{% endif %} {% endif %} {% endfor %} m_zoneMap.insert("{{zone_id}}", {{zone_name}}Zone); @@ -162,7 +170,7 @@ void {{class}}::initialize() } {% for property in interface.properties %} -{% if not property.readonly and not property.const %} +{% if not property.readonly and not property.const and not property.type.is_model %} /*! \fn virtual {{ivi.prop_setter(property, class, interface_zoned)}} diff --git a/src/tools/ivigenerator/templates_backend_simulator/backend.h.tpl b/src/tools/ivigenerator/templates_backend_simulator/backend.h.tpl index 3ca00cd..2276a2c 100644 --- a/src/tools/ivigenerator/templates_backend_simulator/backend.h.tpl +++ b/src/tools/ivigenerator/templates_backend_simulator/backend.h.tpl @@ -52,6 +52,12 @@ #include "{{class|lower}}interface.h" {% endif %} +{% for property in interface.properties %} +{% if property.type.is_model %} +{% include "pagingmodel.h.tpl" %} +{% endif %} +{% endfor %} + QT_BEGIN_NAMESPACE {% if 'simulator' in features %} @@ -74,7 +80,7 @@ public: void initialize() override; public Q_SLOTS: {% for property in interface.properties %} -{% if not property.readonly and not property.const %} +{% if not property.readonly and not property.const and not property.type.is_model %} virtual {{ivi.prop_setter(property, zoned = interface_zoned)}} override; {% endif %} {% endfor %} @@ -86,7 +92,11 @@ public Q_SLOTS: protected: {% for property in interface.properties %} {% if not property.tags.config_simulator or not property.tags.config_simulator.zoned %} - {{ property|return_type }} m_{{ property }}; +{% if property.type.is_model %} +QIviPagingModelInterface *m_{{ property }}; +{% else %} +{{ property|return_type }} m_{{ property }}; +{% endif %} {% endif %} {% endfor %} @@ -94,7 +104,11 @@ protected: struct ZoneBackend { {% for property in interface.properties %} {% if property.tags.config_simulator and property.tags.config_simulator.zoned %} - {{ property|return_type }} {{ property }}; +{% if property.type.is_model %} +QIviPagingModelInterface *{{ property }}; +{% else %} +{{ property|return_type }} {{ property }}; +{% endif %} {% endif %} {% endfor %} }; diff --git a/src/tools/ivigenerator/templates_backend_simulator/pagingmodel.cpp.tpl b/src/tools/ivigenerator/templates_backend_simulator/pagingmodel.cpp.tpl new file mode 100644 index 0000000..99700e8 --- /dev/null +++ b/src/tools/ivigenerator/templates_backend_simulator/pagingmodel.cpp.tpl @@ -0,0 +1,84 @@ +{# +# Copyright (C) 2018 Pelagicore AG. +# Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB) +# Contact: https://www.qt.io/licensing/ +# +# This file is part of the QtIvi module of the Qt Toolkit. +# +# $QT_BEGIN_LICENSE:LGPL-QTAS$ +# Commercial License Usage +# Licensees holding valid commercial Qt Automotive Suite licenses may use +# this file in accordance with the commercial license agreement provided +# with the Software or, alternatively, in accordance with the terms +# contained in a written agreement between you and The Qt Company. For +# licensing terms and conditions see https://www.qt.io/terms-conditions. +# For further information use the contact form at https://www.qt.io/contact-us. +# +# GNU Lesser General Public License Usage +# Alternatively, this file may be used under the terms of the GNU Lesser +# General Public License version 3 as published by the Free Software +# Foundation and appearing in the file LICENSE.LGPL3 included in the +# packaging of this file. Please review the following information to +# ensure the GNU Lesser General Public License version 3 requirements +# will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +# +# GNU General Public License Usage +# Alternatively, this file may be used under the terms of the GNU +# General Public License version 2.0 or (at your option) the GNU General +# Public license version 3 or any later version approved by the KDE Free +# Qt Foundation. The licenses are as published by the Free Software +# Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +# included in the packaging of this file. Please review the following +# information to ensure the GNU General Public License requirements will +# be met: https://www.gnu.org/licenses/gpl-2.0.html and +# https://www.gnu.org/licenses/gpl-3.0.html. +# +# $QT_END_LICENSE$ +# +# SPDX-License-Identifier: LGPL-3.0 +#} +{% set class = '{0}Model'.format(property|upperfirst) %} + +#include "{{property.type.nested|lower}}.h" +#include <QtDebug> + +{{class}}::{{class}}(QObject* parent) + : QIviPagingModelInterface(parent) +{ + for(int i=0; i < 100; i++) + m_list.append(QVariant::fromValue({{property.type.nested|test_type_value}})); +} + +/*! \internal */ +{{class}}::~{{class}}() +{ +} + +void {{class}}::initialize() +{ + emit initializationDone(); +} + +void {{class}}::registerInstance(const QUuid &identifier) +{ + qCritical() << "REGISTER" << identifier; + + emit countChanged(identifier, 100); +} + +void {{class}}::unregisterInstance(const QUuid &identifier) +{ + qCritical() << "UNREGISTER" << identifier; +} + +void {{class}}::fetchData(const QUuid &identifier, int start, int count) +{ + qCritical() << "FETCH" << identifier << start << count; + + QVariantList list; + int max = qMin(start + count, m_list.count()); + for(int i=start; i < max; i++) + list.append(m_list.at(i)); + + emit dataFetched(identifier, list, start, max < m_list.count()); +} diff --git a/src/tools/ivigenerator/templates_frontend/structmodel_p.h.tpl b/src/tools/ivigenerator/templates_backend_simulator/pagingmodel.h.tpl index 1852e25..7f1e174 100644 --- a/src/tools/ivigenerator/templates_frontend/structmodel_p.h.tpl +++ b/src/tools/ivigenerator/templates_backend_simulator/pagingmodel.h.tpl @@ -1,5 +1,6 @@ {# -# Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). +# Copyright (C) 2018 Pelagicore AG. +# Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB) # Contact: https://www.qt.io/licensing/ # # This file is part of the QtIvi module of the Qt Toolkit. @@ -36,44 +37,24 @@ # # SPDX-License-Identifier: LGPL-3.0 #} -{% set class = '{0}Model'.format(struct) %} -{% set oncedefine = '{0}_{1}PRIVATE_H_'.format(module.module_name|upper, class|upper) %} -{% include 'generated_comment.cpp.tpl' %} +{% set class = '{0}Model'.format(property|upperfirst) %} -#ifndef {{oncedefine}} -#define {{oncedefine}} +#include <QIviPagingModelInterface> -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "{{struct|lower}}.h" - -#include <QtCore/private/qabstractitemmodel_p.h> -#include <QVector> - -QT_BEGIN_NAMESPACE - -class {{class}}; - -class {{class}}Private : public QAbstractItemModelPrivate +class {{class}} : public QIviPagingModelInterface { + Q_OBJECT public: - {{class}}Private(); - ~{{class}}Private(); + explicit {{class}}(QObject *parent = nullptr); + ~{{class}}(); - QVector<{{struct}}> m_data; + void initialize() override; + void registerInstance(const QUuid &identifier) override; + void unregisterInstance(const QUuid &identifier) override; - Q_DECLARE_PUBLIC({{class}}) -}; + void fetchData(const QUuid &identifier, int start, int count) override; -QT_END_NAMESPACE +private: + QVariantList m_list; +}; -#endif // {{oncedefine}} diff --git a/src/tools/ivigenerator/templates_control_panel/interface.cpp.tpl b/src/tools/ivigenerator/templates_control_panel/interface.cpp.tpl index db89c84..b3a7cee 100644 --- a/src/tools/ivigenerator/templates_control_panel/interface.cpp.tpl +++ b/src/tools/ivigenerator/templates_control_panel/interface.cpp.tpl @@ -70,9 +70,11 @@ QT_BEGIN_NAMESPACE {% for zone_name, zone_id in zones.items() %} addZone(QLatin1String("{{zone_id}}")); {% for property in interface.properties %} + {% if not property.type.is_model %} {% if property.tags.config_simulator and property.tags.config_simulator.zoned %} m_zoneHash[QLatin1String("{{zone_id}}")]->m_{{property}} = {{property|default_value(zone_name)}}; {% endif %} + {% endif %} {% endfor %} {% endfor %} {% else %} @@ -96,21 +98,25 @@ QT_BEGIN_NAMESPACE while (i != m_zoneHash.constEnd()) { i.value()->m_worker = client; {% for property in interface.properties %} +{% if not property.type.is_model %} {% set function_name = property|setter_name %} {% if property.readonly or property.const %} {% set function_name = property.name + 'Changed' %} {% endif %} m_worker->call("{{function_name}}", i.value()->m_{{property}}, i.value()->m_currentZone); +{% endif %} {% endfor %} ++i; } {% else %} {% for property in interface.properties %} +{% if not property.type.is_model %} {% set function_name = property|setter_name %} {% if property.readonly or property.const %} {% set function_name = property.name + 'Changed' %} {% endif %} m_worker->call("{{function_name}}", m_{{property}}); +{% endif %} {% endfor %} {% endif %} }); @@ -166,6 +172,7 @@ QVariantMap {{class}}::zoneAt() const {% endif %} {% for property in interface.properties %} +{% if not property.type.is_model %} {{ivi.prop_getter(property, class)}} { return m_{{property}}; @@ -210,6 +217,7 @@ QVariantMap {{class}}::zoneAt() const } {% endif %} +{% endif %} {% endfor %} {% for signal in interface.signals %} diff --git a/src/tools/ivigenerator/templates_control_panel/interface.h.tpl b/src/tools/ivigenerator/templates_control_panel/interface.h.tpl index b273d1e..3d94fe9 100644 --- a/src/tools/ivigenerator/templates_control_panel/interface.h.tpl +++ b/src/tools/ivigenerator/templates_control_panel/interface.h.tpl @@ -66,7 +66,9 @@ class {{exportsymbol}} {{class}} : public QObject { Q_PROPERTY(QVariantMap zoneAt READ zoneAt NOTIFY zonesChanged) {% endif %} {% for property in interface.properties %} +{% if not property.type.is_model %} Q_PROPERTY({{property|return_type}} {{property}} READ {{property|getter_name}} WRITE {{property|setter_name}} NOTIFY {{property}}Changed) +{% endif %} {% endfor %} Q_CLASSINFO("IviPropertyDomains", "{{ interface.properties|json_domain|replace("\"", "\\\"") }}") public: @@ -86,14 +88,18 @@ public: QVariantMap zoneAt() const; {% endif %} {% for property in interface.properties %} +{% if not property.type.is_model %} {{ivi.prop_getter(property)}}; +{% endif %} {% endfor %} public Q_SLOTS: {% for property in interface.properties %} +{% if not property.type.is_model %} {{ivi.prop_setter(property)}}; -{% if interface_zoned %} +{% if interface_zoned %} {{ivi.prop_setter(property, zoned = true)}}; +{% endif %} {% endif %} {% endfor %} {% for signal in interface.signals %} @@ -109,7 +115,9 @@ Q_SIGNALS: void zonesChanged(); {% endif %} {% for property in interface.properties %} +{% if not property.type.is_model %} {{ivi.prop_notify(property)}}; +{% endif %} {% endfor %} private Q_SLOTS: @@ -121,7 +129,9 @@ private Q_SLOTS: private: QSimulatorConnectionWorker *worker(); {% for property in interface.properties %} +{% if not property.type.is_model %} {{ property|return_type }} m_{{ property }}; +{% endif %} {% endfor %} {% if interface_zoned %} QHash<QString,{{class}}*> m_zoneHash; diff --git a/src/tools/ivigenerator/templates_control_panel/module.cpp.tpl b/src/tools/ivigenerator/templates_control_panel/module.cpp.tpl index deec4b3..9499109 100644 --- a/src/tools/ivigenerator/templates_control_panel/module.cpp.tpl +++ b/src/tools/ivigenerator/templates_control_panel/module.cpp.tpl @@ -93,9 +93,6 @@ void {{class}}::registerTypes() qRegisterMetaType<{{class}}::{{enum|flag_type}}>(); qRegisterMetaTypeStreamOperators<{{class}}::{{enum|flag_type}}>(); {% endfor %} -{% for struct in module.structs %} - qRegisterMetaType<{{struct}}>(); -{% endfor %} } /*! \internal */ diff --git a/src/tools/ivigenerator/templates_frontend.yaml b/src/tools/ivigenerator/templates_frontend.yaml index f993e80..aca230e 100644 --- a/src/tools/ivigenerator/templates_frontend.yaml +++ b/src/tools/ivigenerator/templates_frontend.yaml @@ -28,9 +28,3 @@ generate_rules: template_file: 'struct.h.tpl' - dest_file: '{{struct|lower}}.cpp' template_file: 'struct.cpp.tpl' - - dest_file: '{{struct|lower}}model.h' - template_file: 'structmodel.h.tpl' - - dest_file: '{{struct|lower}}model_p.h' - template_file: 'structmodel_p.h.tpl' - - dest_file: '{{struct|lower}}model.cpp' - template_file: 'structmodel.cpp.tpl' diff --git a/src/tools/ivigenerator/templates_frontend/backendinterface.h.tpl b/src/tools/ivigenerator/templates_frontend/backendinterface.h.tpl index 83aeb58..c38abe1 100644 --- a/src/tools/ivigenerator/templates_frontend/backendinterface.h.tpl +++ b/src/tools/ivigenerator/templates_frontend/backendinterface.h.tpl @@ -62,6 +62,7 @@ #include <QtIviCore/{{base_class}}> #include <QtIviCore/QIviPendingReply> +#include <QtIviCore/QIviPagingModelInterface> QT_BEGIN_NAMESPACE @@ -73,7 +74,7 @@ public: ~{{class}}(); {% for property in interface.properties %} -{% if not property.readonly and not property.const %} +{% if not property.readonly and not property.const and not property.type.is_model %} virtual {{ivi.prop_setter(property, zoned = interface.tags.config.zoned)}} = 0; {% endif %} {% endfor %} @@ -86,7 +87,7 @@ Q_SIGNALS: {{ivi.signal(signal, zoned = interface.tags.config.zoned)}}; {% endfor %} {% for property in interface.properties %} - {{ivi.prop_notify(property, zoned = interface.tags.config.zoned)}}; + {{ivi.prop_notify(property, zoned = interface.tags.config.zoned, model_interface = true)}}; {% endfor %} }; diff --git a/src/tools/ivigenerator/templates_frontend/interface.cpp.tpl b/src/tools/ivigenerator/templates_frontend/interface.cpp.tpl index 1344082..2ee21f2 100644 --- a/src/tools/ivigenerator/templates_frontend/interface.cpp.tpl +++ b/src/tools/ivigenerator/templates_frontend/interface.cpp.tpl @@ -44,14 +44,9 @@ #include "{{class|lower}}_p.h" #include "{{class|lower}}backendinterface.h" -{% for property in interface.properties %} -{% if property.type.is_model %} -#include "{{property|model_type|lower}}.h" -{% endif %} -{% endfor %} - #include <QQmlEngine> #include <QIviServiceObject> +#include <QIviProxyServiceObject> QT_BEGIN_NAMESPACE @@ -133,6 +128,12 @@ const {{class}}Private *{{class}}Private::get(const {{class}} *v) void {{class}}Private::clearToDefaults() { {% for property in interface.properties %} +{% if property.type.is_model %} + if (m_{{property}}) { + delete m_{{property}}->serviceObject(); + delete m_{{property}}; + } +{% endif %} m_{{property}} = {{property|default_type_value}}; {% endfor %} } @@ -140,7 +141,7 @@ void {{class}}Private::clearToDefaults() {% for property in interface.properties %} /*! \internal */ {% if interface.tags.config.zoned %} -void {{class}}Private::on{{property|upperfirst}}Changed({{property|parameter_type}}, const QString &zone) +{{ivi.on_prop_changed(property, class+"Private", interface.tags.config.zoned, true)}} { auto q = getParent(); auto f = qobject_cast<{{class}}*>(q->zoneAt(zone)); @@ -148,7 +149,7 @@ void {{class}}Private::on{{property|upperfirst}}Changed({{property|parameter_typ f = q; if (f->zone() != zone) return; -{% if not module.tags.config.disablePrivateIVI %} +{% if not module.tags.config.disablePrivateIVI and not property.type.is_model %} if (Q_UNLIKELY(m_propertyOverride)) { const int pi = f->metaObject()->indexOfProperty("{{property}}"); if (m_propertyOverride->isOverridden(pi)) { @@ -158,19 +159,55 @@ void {{class}}Private::on{{property|upperfirst}}Changed({{property|parameter_typ } } {% endif %} +{% if property.type.is_model %} + {{property|return_type}} old = {{class}}Private::get(f)->m_{{property}}; + if ({{property}}) { + auto model = new QIviPagingModel(); + model->setServiceObject(new QIviProxyServiceObject({ {QIviPagingModel_iid, {{property}} } }));; + {{class}}Private::get(f)->m_{{property}} = model; + emit f->{{property}}Changed(model); + } else { + {{class}}Private::get(f)->m_{{property}} = nullptr; + emit f->{{property}}Changed(nullptr); + } + if (old) { + delete old->serviceObject(); + delete old; + } +{% else %} if ({{class}}Private::get(f)->m_{{property}} != {{property}}) { {{class}}Private::get(f)->m_{{property}} = {{property}}; emit f->{{property}}Changed({{property}}); } +{% endif %} } {% else %} -void {{class}}Private::on{{property|upperfirst}}Changed({{property|parameter_type}}) +{{ivi.on_prop_changed(property, class+"Private", interface.tags.config.zoned, true)}} { +{% if property.type.is_model %} + {{property|return_type}} old = m_{{property}}; + if ({{property}}) { + auto model = new QIviPagingModel(); + model->setServiceObject(new QIviProxyServiceObject({ {QIviPagingModel_iid, {{property}} } })); + m_{{property}} = model; + auto q = getParent(); + emit q->{{property}}Changed(model); + } else { + m_{{property}} = nullptr; + auto q = getParent(); + emit q->{{property}}Changed(nullptr); + } + if (old) { + delete old->serviceObject(); + delete old; + } +{% else %} if (m_{{property}} != {{property}}) { auto q = getParent(); m_{{property}} = {{property}}; emit q->{{property}}Changed({{property}}); } +{% endif %} } {% endif %} @@ -301,7 +338,7 @@ void {{class}}::registerQmlTypes(const QString& uri, int majorVersion, int minor {% endif %} return d->m_{{property}}; } -{% if not property.readonly and not property.const %} +{% if not property.readonly and not property.const and not property.type.is_model %} {{ivi.prop_setter(property, class)}} { diff --git a/src/tools/ivigenerator/templates_frontend/interface.h.tpl b/src/tools/ivigenerator/templates_frontend/interface.h.tpl index 6db880a..9688336 100644 --- a/src/tools/ivigenerator/templates_frontend/interface.h.tpl +++ b/src/tools/ivigenerator/templates_frontend/interface.h.tpl @@ -62,6 +62,7 @@ #include <QtIviCore/{{base_class}}> #include <QtIviCore/QIviPendingReply> +#include <QtIviCore/QIviPagingModel> QT_BEGIN_NAMESPACE @@ -96,7 +97,7 @@ public Q_SLOTS: {{ ivi.operation(operation) }}; {% endfor %} {% for property in interface.properties %} -{% if not property.readonly and not property.const %} +{% if not property.readonly and not property.const and not property.type.is_model %} {{ivi.prop_setter(property)}}; {% endif %} {% endfor %} @@ -125,9 +126,9 @@ private: {% else %} {% for property in interface.properties %} {% if interface.tags.config.zoned %} - Q_PRIVATE_SLOT(d_func(), void on{{property|upperfirst}}Changed({{property|parameter_type}}, const QString &)) + Q_PRIVATE_SLOT(d_func(), {{ivi.on_prop_changed(property, "", true, true)}}) {% else %} - Q_PRIVATE_SLOT(d_func(), void on{{property|upperfirst}}Changed({{property|parameter_type}})) + Q_PRIVATE_SLOT(d_func(), {{ivi.on_prop_changed(property, "", false, true)}}) {% endif %} {% endfor %} Q_DECLARE_PRIVATE({{class}}) diff --git a/src/tools/ivigenerator/templates_frontend/interface_p.h.tpl b/src/tools/ivigenerator/templates_frontend/interface_p.h.tpl index b51c749..eb39306 100644 --- a/src/tools/ivigenerator/templates_frontend/interface_p.h.tpl +++ b/src/tools/ivigenerator/templates_frontend/interface_p.h.tpl @@ -67,6 +67,7 @@ {% else %} #include <QtIviCore/private/{{base_class|lower}}_p.h> {% endif %} +#include <QIviPagingModelInterface> QT_BEGIN_NAMESPACE @@ -96,7 +97,7 @@ public: void clearToDefaults(); {% for property in interface.properties %} - {{ivi.on_prop_changed(property, zoned = interface.tags.config.zoned)}}; + {{ivi.on_prop_changed(property, zoned = interface.tags.config.zoned, model_interface = true)}}; {% endfor %} {% for signal in interface.signals %} void on{{signal|upperfirst}}({{ivi.join_params(signal, zoned = interface.tags.config.zoned)}}); diff --git a/src/tools/ivigenerator/templates_frontend/module.cpp.tpl b/src/tools/ivigenerator/templates_frontend/module.cpp.tpl index 96c9e4e..0431aa5 100644 --- a/src/tools/ivigenerator/templates_frontend/module.cpp.tpl +++ b/src/tools/ivigenerator/templates_frontend/module.cpp.tpl @@ -45,9 +45,6 @@ {% for interface in module.interfaces %} #include "{{interface|lower}}.h" {% endfor %} -{% for struct in module.structs %} -#include "{{struct|lower}}model.h" -{% endfor %} #include <QtIviCore/QIviPendingReply> #include <QQmlEngine> #include <QDebug> @@ -113,10 +110,8 @@ void {{class}}::registerTypes() {% endfor %} {% for struct in module.structs %} qRegisterMetaType<{{struct}}>(); - qRegisterMetaType<{{struct}}Model*>(); qRegisterMetaTypeStreamOperators<{{struct}}>(); qIviRegisterPendingReplyType<{{struct}}>(); - qIviRegisterPendingReplyType<{{struct}}Model*>(); {% endfor %} } diff --git a/src/tools/ivigenerator/templates_frontend/module.h.tpl b/src/tools/ivigenerator/templates_frontend/module.h.tpl index 12c1dcb..5595eaa 100644 --- a/src/tools/ivigenerator/templates_frontend/module.h.tpl +++ b/src/tools/ivigenerator/templates_frontend/module.h.tpl @@ -53,10 +53,6 @@ QT_BEGIN_NAMESPACE -{% for struct in module.structs %} -class {{struct}}Model; -{% endfor %} - class {{exportsymbol}} {{class}} : public QObject { Q_OBJECT public: diff --git a/src/tools/ivigenerator/templates_frontend/module.pri.tpl b/src/tools/ivigenerator/templates_frontend/module.pri.tpl index 839b8ca..61b772e 100644 --- a/src/tools/ivigenerator/templates_frontend/module.pri.tpl +++ b/src/tools/ivigenerator/templates_frontend/module.pri.tpl @@ -49,8 +49,6 @@ HEADERS += \ {% endfor %} {% for struct in module.structs %} $$PWD/{{struct|lower}}.h \ - $$PWD/{{struct|lower}}model.h \ - $$PWD/{{struct|lower}}model_p.h \ {% endfor %} $$PWD/{{module.module_name|lower}}module.h \ $$PWD/{{module.module_name|lower}}modulefactory.h \ @@ -63,7 +61,6 @@ SOURCES += \ {% endfor %} {% for struct in module.structs %} $$PWD/{{struct|lower}}.cpp \ - $$PWD/{{struct|lower}}model.cpp \ {% endfor %} $$PWD/{{module.module_name|lower}}module.cpp \ $$PWD/{{module.module_name|lower}}modulefactory.cpp diff --git a/src/tools/ivigenerator/templates_frontend/struct.cpp.tpl b/src/tools/ivigenerator/templates_frontend/struct.cpp.tpl index 16b8d16..43ec933 100644 --- a/src/tools/ivigenerator/templates_frontend/struct.cpp.tpl +++ b/src/tools/ivigenerator/templates_frontend/struct.cpp.tpl @@ -142,7 +142,6 @@ bool operator==(const {{class}} &left, const {{class}} &right) Q_DECL_NOTHROW { if (left.d == right.d) return true; - //FIX me for inheritance return ( {% for field in struct.fields %} left.{{field}}() == right.{{field}}() {% if not loop.last %}&&{% endif %} @@ -158,7 +157,6 @@ bool operator!=(const {{class}} &left, const {{class}} &right) Q_DECL_NOTHROW QDataStream &operator<<(QDataStream &stream, const {{class}} &obj) { - //FIX me for inheritance {% for field in struct.fields %} stream << obj.{{field}}(); {% endfor %} @@ -167,7 +165,6 @@ QDataStream &operator<<(QDataStream &stream, const {{class}} &obj) QDataStream &operator>>(QDataStream &stream, {{class}} &obj) { - //FIX me for inheritance {% for field in struct.fields %} stream >> obj.d->m_{{field}}; {% endfor %} diff --git a/src/tools/ivigenerator/templates_frontend/structmodel.cpp.tpl b/src/tools/ivigenerator/templates_frontend/structmodel.cpp.tpl deleted file mode 100644 index a372e78..0000000 --- a/src/tools/ivigenerator/templates_frontend/structmodel.cpp.tpl +++ /dev/null @@ -1,222 +0,0 @@ -{# -# Copyright (C) 2018 Pelagicore AG. -# Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB) -# Contact: https://www.qt.io/licensing/ -# -# This file is part of the QtIvi module of the Qt Toolkit. -# -# $QT_BEGIN_LICENSE:LGPL-QTAS$ -# Commercial License Usage -# Licensees holding valid commercial Qt Automotive Suite licenses may use -# this file in accordance with the commercial license agreement provided -# with the Software or, alternatively, in accordance with the terms -# contained in a written agreement between you and The Qt Company. For -# licensing terms and conditions see https://www.qt.io/terms-conditions. -# For further information use the contact form at https://www.qt.io/contact-us. -# -# GNU Lesser General Public License Usage -# Alternatively, this file may be used under the terms of the GNU Lesser -# General Public License version 3 as published by the Free Software -# Foundation and appearing in the file LICENSE.LGPL3 included in the -# packaging of this file. Please review the following information to -# ensure the GNU Lesser General Public License version 3 requirements -# will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -# -# GNU General Public License Usage -# Alternatively, this file may be used under the terms of the GNU -# General Public License version 2.0 or (at your option) the GNU General -# Public license version 3 or any later version approved by the KDE Free -# Qt Foundation. The licenses are as published by the Free Software -# Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -# included in the packaging of this file. Please review the following -# information to ensure the GNU General Public License requirements will -# be met: https://www.gnu.org/licenses/gpl-2.0.html and -# https://www.gnu.org/licenses/gpl-3.0.html. -# -# $QT_END_LICENSE$ -# -# SPDX-License-Identifier: LGPL-3.0 -#} -{% set class = '{0}Model'.format(struct) %} -{% include 'generated_comment.cpp.tpl' %} - -#include "{{class|lower}}.h" -#include "{{class|lower}}_p.h" - -QT_BEGIN_NAMESPACE - -/*! \internal */ -{{class}}Private::{{class}}Private() - : QAbstractItemModelPrivate() -{ -} - -/*! \internal */ -{{class}}Private::~{{class}}Private() -{ -} - - -{{class}}::{{class}}(QObject* parent) - : QAbstractListModel(parent) -{ -} - -/*! \internal */ -{{class}}::~{{class}}() -{ -} - -QHash<int, QByteArray> {{class}}::roleNames() const -{ - auto res = QAbstractItemModel::roleNames(); -{% for field in struct.fields %} - res.insert({{field|upperfirst}}, "{{field}}"); -{% endfor %} - return res; -} - -int {{class}}::count() const -{ - Q_D(const {{class}}); - - return d->m_data.count(); -} - -int {{class}}::rowCount(const QModelIndex &parent) const -{ - Q_D(const {{class}}); - - return parent.isValid() ? 0 : d->m_data.count(); -} - -QVariant {{class}}::data(const QModelIndex &index, int role) const -{ - Q_D(const {{class}}); - if (index.row() < 0 || index.row() >= d->m_data.count()) - return {}; - - const {{struct}} &data = d->m_data.at(index.row()); - switch(role) { -{% for field in struct.fields %} - case {{field|upperfirst}}: return qVariantFromValue<{{field|return_type}}>(data.{{field}}()); -{% endfor %} - default: break; - } - - return {}; -} - -bool {{class}}::setData(const QModelIndex &index, const QVariant &value, int role) -{ - Q_D({{class}}); - if (index.row() < 0 || index.row() >= d->m_data.count()) - return false; - {{struct}} &data = d->m_data[index.row()]; - switch(role) { -{% for field in struct.fields %} - case {{field|upperfirst}}: -{% if field.readonly or field.const %} - return false; -{% else %} - data.set{{field|upperfirst}}(value.value<{{field|return_type}}>()); - break; -{% endif %} -{% endfor %} - default: return false; - } - Q_EMIT dataChanged(index, index, QVector<int>() << role); - return true; -} - -bool {{class}}::insertRows(int row, int count, const QModelIndex &parent) -{ - Q_D({{class}}); - if (row < 0 || row >= d->m_data.size() || count < 0 || parent.isValid()) - return false; - beginInsertRows(parent, row, row + count - 1); - d->m_data.insert(row, count, {}); - endInsertRows(); - Q_EMIT countChanged(d->m_data.count()); - return true; -} - -bool {{class}}::removeRows(int row, int count, const QModelIndex &parent) -{ - Q_D({{class}}); - if (row < 0 || row >= d->m_data.size() || count < 0 || parent.isValid()) - return false; - beginInsertRows(parent, row, row + count - 1); - while (count) { - d->m_data.remove(row); - --count; - } - endInsertRows(); - Q_EMIT countChanged(d->m_data.count()); - return true; -} - -bool {{class}}::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) -{ - Q_D({{class}}); - if (sourceRow < 0 || sourceRow >= d->m_data.size() || count < 0 || sourceParent.isValid()) - return false; - if (destinationChild < 0 || destinationChild > d->m_data.size() || destinationParent.isValid()) - return false; - if (!beginMoveRows(sourceParent, sourceRow, sourceRow + count - 1, destinationParent, destinationChild)) - return false; - QVector<{{struct}}> data; - for (int i = 0; i < count; i++) { - data << d->m_data.at(sourceRow); - d->m_data.remove(sourceRow); - } - if (destinationChild >= d->m_data.size()) - d->m_data << data; - else { - d->m_data.insert(destinationChild, count, {}); - for (int i = 0; i < count; i++) - d->m_data[destinationChild + 1] = data[i]; - } - endMoveRows(); - return true; -} - -{{struct}} {{class}}::at(int index) const -{ - Q_D(const {{class}}); - if (index < 0 || index >= d->m_data.count()) - return {}; - return d->m_data.at(index); -} - -void {{class}}::append(const {{struct}}& data) -{ - Q_D({{class}}); - beginInsertRows({}, d->m_data.count(), d->m_data.count()); - d->m_data << data; - endInsertRows(); - Q_EMIT countChanged(d->m_data.count()); -} - -{{struct}} {{class}}::append({% for field in struct.fields %}{% if not loop.first %}, {% endif %}{{field|return_type}} {{field}}{% endfor %}) -{ - auto data = {{struct}}({% for field in struct.fields %}{% if not loop.first %}, {% endif %}{{field}}{% endfor %}); - append(data); - return data; -} - -void {{class}}::remove(int index) -{ - Q_D({{class}}); - if (index < 0 || index >= d->m_data.count()) { - beginRemoveRows({}, index, index); - d->m_data.remove(index); - endRemoveRows(); - Q_EMIT countChanged(d->m_data.count()); - } -} - - -QT_END_NAMESPACE - -#include "moc_{{class|lower}}.cpp" diff --git a/src/tools/ivigenerator/templates_frontend/structmodel.h.tpl b/src/tools/ivigenerator/templates_test/pagingmodel.h.tpl index 24ca9a3..9b00586 100644 --- a/src/tools/ivigenerator/templates_frontend/structmodel.h.tpl +++ b/src/tools/ivigenerator/templates_test/pagingmodel.h.tpl @@ -37,59 +37,53 @@ # # SPDX-License-Identifier: LGPL-3.0 #} -{% set class = '{0}Model'.format(struct) %} -{% set oncedefine = '{0}_{1}_H_'.format(module.module_name|upper, class|upper) %} -{% set exportsymbol = 'Q_{0}_EXPORT'.format(module.module_name|upper) %} -{% include 'generated_comment.cpp.tpl' %} +{% set class = '{0}Model'.format(property|upperfirst) %} -#ifndef {{oncedefine}} -#define {{oncedefine}} +#include "{{property.type.nested|lower}}.h" +#include <QtDebug> -#include "{{struct|lower}}.h" -#include <QAbstractListModel> +#include <QIviPagingModelInterface> -QT_BEGIN_NAMESPACE - -class {{class}}Private; - -class {{exportsymbol}} {{class}} : public QAbstractListModel +class {{class}} : public QIviPagingModelInterface { Q_OBJECT - Q_PROPERTY(int count READ count NOTIFY countChanged) public: - enum Roles { - {% for field in struct.fields %} - {{field|upperfirst}}{% if loop.first %} = Qt::UserRole{% endif %}, - {% endfor %} - }; - Q_ENUM(Roles); + explicit {{class}}(QObject *parent = nullptr) + : QIviPagingModelInterface(parent) + { + for(int i=0; i < 100; i++) + m_list.append(QVariant::fromValue({{property.type.nested|test_type_value}})); + } + + ~{{class}}() + { + } - explicit {{class}}(QObject *parent = nullptr); - ~{{class}}(); + void initialize() override + { + emit initializationDone(); + } - int count() const; + void registerInstance(const QUuid &identifier) override + { + emit countChanged(identifier, 100); + } - QHash<int, QByteArray> roleNames() const override; - int rowCount(const QModelIndex& parent) const override; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole) override; - bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override; - bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override; + void unregisterInstance(const QUuid &identifier) override + { + Q_UNUSED(identifier); + } - Q_INVOKABLE {{struct}} at(int index) const; - Q_INVOKABLE void append(const {{struct}}& data); - Q_INVOKABLE {{struct}} append({% for field in struct.fields %}{% if not loop.first %}, {% endif %}{{field|return_type}} {{field}}{% endfor %}); - Q_INVOKABLE void remove(int index); + void fetchData(const QUuid &identifier, int start, int count) override + { + QVariantList list; + int max = qMin(start + count, m_list.count()); + for(int i=start; i < max; i++) + list.append(m_list.at(i)); -Q_SIGNALS: - void countChanged(int count); + emit dataFetched(identifier, list, start, max < m_list.count()); + } private: - Q_DECLARE_PRIVATE({{class}}) + QVariantList m_list; }; - -QT_END_NAMESPACE - - -#endif // {{oncedefine}} diff --git a/src/tools/ivigenerator/templates_test/tst_test.cpp.tpl b/src/tools/ivigenerator/templates_test/tst_test.cpp.tpl index 35ab010..58d1e4f 100644 --- a/src/tools/ivigenerator/templates_test/tst_test.cpp.tpl +++ b/src/tools/ivigenerator/templates_test/tst_test.cpp.tpl @@ -48,9 +48,9 @@ #include <{{interface|lower}}backendinterface.h> {% for property in interface.properties %} -{% if property.is_model and property.type.nested.is_complex %} -#include <{{property.type.nested.type|lower}}model.h> -{% endif %} +{% if property.type.is_model %} +{% include "pagingmodel.h.tpl" %} +{% endif %} {% endfor %} class {{interface}}TestBackend : public {{interface}}BackendInterface @@ -61,7 +61,11 @@ public: {{interface}}TestBackend() : {{interface}}BackendInterface() {% for property in interface.properties %} +{% if property.type.is_model %} + , m_{{property}}(new {{property|upperfirst}}Model(this)) +{% else %} , m_{{property}}({{property|default_type_value}}) +{% endif %} {% endfor %} { {% if interface.tags.config.zoned %} @@ -100,6 +104,7 @@ public: {% if interface.tags.config.zoned %} {% for property in interface.properties %} +{% if not property.type.is_model %} void set{{property|upperfirst}}({{property|parameter_type}}{% if interface_zoned %}, const QString &z{% endif %}) {% if not property.readonly and not property.const %}override{%endif%} { @@ -116,9 +121,11 @@ public: emit {{property}}Changed(m_zone{{property|upperfirst}}[z], z); } } +{% endif %} {% endfor %} {% else %} {% for property in interface.properties %} +{% if not property.type.is_model %} void set{{property|upperfirst}}({{property|parameter_type}}{% if interface_zoned %}, const QString &z{% endif %}) {% if not property.readonly and not property.const %}override{%endif%} { @@ -127,6 +134,7 @@ public: emit {{property}}Changed(m_{{property}}); } } +{% endif %} {% endfor%} {% endif %} @@ -153,12 +161,20 @@ public: private: {% for property in interface.properties %} - {{property|return_type}} m_{{property}}; +{% if property.type.is_model %} + QIviPagingModelInterface *m_{{ property }}; +{% else %} + {{ property|return_type }} m_{{ property }}; +{% endif %} {% endfor %} {% if interface.tags.config.zoned %} {% for property in interface.properties %} +{% if property.type.is_model %} + QMap<QString, QIviPagingModelInterface *> m_zone{{property|upperfirst}}; +{% else %} QMap<QString, {{property|return_type}}> m_zone{{property|upperfirst}}; +{% endif %} {% endfor %} {% endif %} @@ -268,7 +284,7 @@ void {{interface}}Test::testWithoutBackend() //Test that the current value of a property is the type default value; QCOMPARE({{property}}Value, {{property}}DefaultValue); -{% if not property.readonly and not property.const %} +{% if not property.readonly and not property.const and not property.type.is_model %} //Test that this is still the case if we try to change it, as we don't //have a connected backend QSignalSpy {{property}}Spy(&cc, SIGNAL({{property}}Changed({{property|return_type}}))); @@ -300,7 +316,7 @@ void {{interface}}Test::testInvalidBackend() //Test that the current value of a property is the type default value; QCOMPARE({{property}}Value, {{property}}DefaultValue); -{% if not property.readonly and not property.const %} +{% if not property.readonly and not property.const and not property.type.is_model %} //Test that this is still the case if we try to change it, as we don't //have a connected backend QSignalSpy {{property}}Spy(&cc, SIGNAL({{property}}Changed({{property|return_type}}))); @@ -323,12 +339,14 @@ void {{interface}}Test::testClearServiceObject() manager->registerService(service, service->interfaces()); {% for property in interface.properties %} +{% if not property.type.is_model %} {{property|parameter_type}}TestValue = {{property|test_type_value}}; {% if interface_zoned %} service->testBackend()->set{{property|upperfirst}}({{property}}TestValue, QString()); {% else %} service->testBackend()->set{{property|upperfirst}}({{property}}TestValue); {% endif %} +{% endif %} {% endfor %} {{interface}} cc; @@ -339,13 +357,17 @@ void {{interface}}Test::testClearServiceObject() {% endif %} {% for property in interface.properties %} +{% if not property.type.is_model %} QCOMPARE(cc.{{property|getter_name}}(), {{property}}TestValue); +{% endif %} {% endfor %} cc.setServiceObject(nullptr); {% for property in interface.properties %} +{% if not property.type.is_model %} QCOMPARE(cc.{{property|getter_name}}(), {{property|default_type_value}}); +{% endif %} {% endfor %} {% if interface.tags.config.zoned %} @@ -362,6 +384,7 @@ void {{interface}}Test::testChangeFromBackend() cc.startAutoDiscovery(); {% for property in interface.properties %} +{% if not property.type.is_model %} //Test {{property}} QSignalSpy {{property}}Spy(&cc, SIGNAL({{property}}Changed({{property|return_type}}))); QCOMPARE({{property}}Spy.count(), 0); @@ -371,10 +394,11 @@ void {{interface}}Test::testChangeFromBackend() service->testBackend()->set{{property|upperfirst}}({{property}}TestValue, QString()); {% else %} service->testBackend()->set{{property|upperfirst}}({{property}}TestValue); -{% endif %} +{% endif %} QCOMPARE({{property}}Spy.count(), 1); QCOMPARE(cc.{{property|getter_name}}(), {{property}}TestValue); +{% endif %} {% endfor %} } @@ -387,7 +411,7 @@ void {{interface}}Test::testChangeFromFrontend() cc.startAutoDiscovery(); {% for property in interface.properties %} -{% if not property.readonly and not property.const %} +{% if not property.readonly and not property.const and not property.type.is_model %} //Test {{property}} QSignalSpy {{property}}Spy(&cc, SIGNAL({{property}}Changed({{property|return_type}}))); QCOMPARE({{property}}Spy.count(), 0); @@ -442,4 +466,42 @@ void {{interface}}Test::testSignals() {% endfor %} } +{% set once = false %} +{% for property in interface.properties if not once %} +{% if property.type.is_model %} +{% set once = true %} +void {{interface}}Test::testModels() +{ + {{interface}}TestServiceObject *service = new {{interface}}TestServiceObject(); + manager->registerService(service, service->interfaces()); + + {{interface}} cc; +{% for property in interface.properties %} +{% if property.type.is_model %} + //Test {{property}}Model without ServiceObject + QCOMPARE(cc.{{property|getter_name}}(), nullptr); + QSignalSpy {{property}}Spy(&cc, SIGNAL({{property}}Changed({{property|return_type}}))); +{% endif %} +{% endfor %} + + cc.startAutoDiscovery(); + QVERIFY(cc.isValid()); + +{% for property in interface.properties %} +{% if property.type.is_model %} + QCOMPARE({{property}}Spy.count(), 1); + //Test {{property}}Model + QIviPagingModel *{{property}} = cc.{{property|getter_name}}(); + QVERIFY({{property}}); + QVERIFY({{property}}->isValid()); + QVERIFY({{property}}->serviceObject()); + + QVERIFY({{property}}->rowCount()); + QCOMPARE({{property}}->at<{{property.type.nested}}>(0), {{property.type.nested|test_type_value}}); +{% endif %} +{% endfor %} +} +{% endif %} +{% endfor %} + #include "tst_{{interface|lower}}.moc" diff --git a/src/tools/ivigenerator/templates_test/tst_test.h.tpl b/src/tools/ivigenerator/templates_test/tst_test.h.tpl index 714fa6f..5da656c 100644 --- a/src/tools/ivigenerator/templates_test/tst_test.h.tpl +++ b/src/tools/ivigenerator/templates_test/tst_test.h.tpl @@ -60,6 +60,13 @@ private slots: void testChangeFromFrontend(); void testMethods(); void testSignals(); +{% set once = false %} +{% for property in interface.properties if not once %} +{% if property.type.is_model %} +{% set once = true %} + void testModels(); +{% endif %} +{% endfor %} private: QIviServiceManager *manager; |