diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,8 +18,14 @@ set(REQUIRED_QT_VERSION 5.11.0) find_package(Qt5Core ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE) +find_package(Qt5Qml ${REQUIRED_QT_VERSION} NO_MODULE) include(ECMGenerateExportHeader) +set_package_properties(Qt5Qml PROPERTIES + TYPE OPTIONAL + PURPOSE "Build QML import for KItemModels" +) + include(ECMSetupVersion) include(ECMGenerateHeaders) include(ECMAddQch) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1 +1,4 @@ add_subdirectory(core) +if (${Qt5Qml_FOUND}) + add_subdirectory(qml) +endif() diff --git a/src/core/kconcatenaterowsproxymodel.h b/src/core/kconcatenaterowsproxymodel.h --- a/src/core/kconcatenaterowsproxymodel.h +++ b/src/core/kconcatenaterowsproxymodel.h @@ -92,6 +92,11 @@ */ Q_SCRIPTABLE void removeSourceModel(QAbstractItemModel *sourceModel); + /** + * The currently set source models + */ + QList sources() const; + /** * Returns the proxy index for a given source index * @param sourceIndex an index coming from any of the source models @@ -133,6 +138,12 @@ */ int columnCount(const QModelIndex &parent = QModelIndex()) const override; + /** + * The roles names for the first source model is returned here + * @reimp + */ + QHash roleNames() const override; + private: Q_PRIVATE_SLOT(d, void slotRowsAboutToBeInserted(const QModelIndex &, int start, int end)) Q_PRIVATE_SLOT(d, void slotRowsInserted(const QModelIndex &, int start, int end)) diff --git a/src/core/kconcatenaterowsproxymodel.cpp b/src/core/kconcatenaterowsproxymodel.cpp --- a/src/core/kconcatenaterowsproxymodel.cpp +++ b/src/core/kconcatenaterowsproxymodel.cpp @@ -149,6 +149,14 @@ return d->m_models.at(0)->columnCount(QModelIndex()); } +QHash KConcatenateRowsProxyModel::roleNames() const +{ + if (d->m_models.isEmpty()) { + return {}; + } + return d->m_models.at(0)->roleNames(); +} + QModelIndex KConcatenateRowsProxyModel::index(int row, int column, const QModelIndex &parent) const { if(row < 0) { @@ -212,6 +220,13 @@ } } +QList KConcatenateRowsProxyModel::sources() const +{ + return d->m_models; +} + + + void KConcatenateRowsProxyModel::removeSourceModel(QAbstractItemModel *sourceModel) { Q_ASSERT(d->m_models.contains(sourceModel)); diff --git a/src/qml/CMakeLists.txt b/src/qml/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/src/qml/CMakeLists.txt @@ -0,0 +1,13 @@ +set(corebindings_SRCS + plugin.cpp + kconcatenaterowsproxymodel_qml.cpp +) + +add_library(itemmodelsplugin SHARED ${corebindings_SRCS}) +target_link_libraries(itemmodelsplugin + Qt5::Qml + KF5::ItemModels +) + +install(TARGETS itemmodelsplugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kitemmodels) +install(FILES qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/kitemmodels) diff --git a/src/qml/kconcatenaterowsproxymodel_qml.h b/src/qml/kconcatenaterowsproxymodel_qml.h new file mode 100644 --- /dev/null +++ b/src/qml/kconcatenaterowsproxymodel_qml.h @@ -0,0 +1,46 @@ +/* + Copyright (c) 2019 David Edmundson + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +//This class exposes KConcatenateRowsProxyModel in a more QML friendly way + +#pragma once + +#include +#include +#include + +class KConcatenateRowsProxyModelQml : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQmlListProperty sources READ sources) + Q_CLASSINFO("DefaultProperty", "sources") +public: + KConcatenateRowsProxyModelQml(QObject *wrappedObject = 0); + ~KConcatenateRowsProxyModelQml(); + + QQmlListProperty sources(); + + static void appendSource(QQmlListProperty*, QAbstractItemModel*); + static int sourceCount(QQmlListProperty*); + static QAbstractItemModel* source(QQmlListProperty*, int); + static void clear(QQmlListProperty*); + +private: + KConcatenateRowsProxyModel *q; +}; diff --git a/src/qml/kconcatenaterowsproxymodel_qml.cpp b/src/qml/kconcatenaterowsproxymodel_qml.cpp new file mode 100644 --- /dev/null +++ b/src/qml/kconcatenaterowsproxymodel_qml.cpp @@ -0,0 +1,68 @@ +/* + Copyright (c) 2019 David Edmundson + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#include "kconcatenaterowsproxymodel_qml.h" + +KConcatenateRowsProxyModelQml::KConcatenateRowsProxyModelQml(QObject *wrappedObject): + QObject(wrappedObject), + q(qobject_cast(wrappedObject)) +{ +} + +KConcatenateRowsProxyModelQml::~KConcatenateRowsProxyModelQml() +{} + +QQmlListProperty KConcatenateRowsProxyModelQml::sources() +{ + return QQmlListProperty(this, q, + &KConcatenateRowsProxyModelQml::appendSource, + &KConcatenateRowsProxyModelQml::sourceCount, + &KConcatenateRowsProxyModelQml::source, + &KConcatenateRowsProxyModelQml::clear); +} + +void KConcatenateRowsProxyModelQml::appendSource(QQmlListProperty* list, QAbstractItemModel* newItem) +{ + auto q = static_cast(list->data); + q->addSourceModel(newItem); +} + +int KConcatenateRowsProxyModelQml::sourceCount(QQmlListProperty* list) +{ + auto q = static_cast(list->data); + return q->sources().count(); +} + +QAbstractItemModel* KConcatenateRowsProxyModelQml::source(QQmlListProperty* list, int index) +{ + auto q = static_cast(list->data); + return q->sources().at(index); +} + +void KConcatenateRowsProxyModelQml::clear(QQmlListProperty* list) +{ + auto q = static_cast(list->data); + const auto sources = q->sources(); + for (auto s: sources) { + q->removeSourceModel(s); + } +} + + + diff --git a/src/qml/plugin.h b/src/qml/plugin.h new file mode 100644 --- /dev/null +++ b/src/qml/plugin.h @@ -0,0 +1,33 @@ +/* + Copyright (c) 2019 David Edmundson + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#pragma once + +#include +#include + +class Plugin : public QQmlExtensionPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") + +public: + void initializeEngine(QQmlEngine *engine, const char *uri) override; + void registerTypes(const char *uri) override; +}; diff --git a/src/qml/plugin.cpp b/src/qml/plugin.cpp new file mode 100644 --- /dev/null +++ b/src/qml/plugin.cpp @@ -0,0 +1,37 @@ +/* + Copyright (c) 2019 David Edmundson + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + +#include "plugin.h" + +#include +#include + +#include "kconcatenaterowsproxymodel_qml.h" + +void Plugin::initializeEngine(QQmlEngine *engine, const char *uri) +{ +} + +void Plugin::registerTypes(const char *uri) +{ + qmlRegisterType(); + qmlRegisterExtendedType("org.kde.kitemmodels", 1,0, "KConcatenateRowsProxyModel"); +} + + diff --git a/src/qml/qmldir b/src/qml/qmldir new file mode 100644 --- /dev/null +++ b/src/qml/qmldir @@ -0,0 +1,2 @@ +module org.kde.kitemmodels +plugin itemmodelsplugin diff --git a/tests/qml/concatenaterows.qml b/tests/qml/concatenaterows.qml new file mode 100644 --- /dev/null +++ b/tests/qml/concatenaterows.qml @@ -0,0 +1,26 @@ +import QtQuick 2.0 +import org.kde.kitemmodels 1.0 + +ListView { + model: KConcatenateRowsProxyModel { + id: myModel + ListModel { + ListElement { name: "a" } + ListElement { name: "b" } + } + ListModel { + ListElement { name: "c" } + ListElement { name: "d" } + } + } + + delegate: Text { + text: model.name + } + + Component.onCompleted : { + console.log(myModel.rowCount()) + } +} + +