diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,12 @@ set(REQUIRED_QT_VERSION 5.11.0) find_package(Qt5Core ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE) +find_package(Qt5Qml ${REQUIRED_QT_VERSION} NO_MODULE) +set_package_properties(Qt5Qml PROPERTIES + TYPE OPTIONAL + PURPOSE "Build QML import for KItemModels" +) include(GenerateExportHeader) diff --git a/autotests/CMakeLists.txt b/autotests/CMakeLists.txt --- a/autotests/CMakeLists.txt +++ b/autotests/CMakeLists.txt @@ -27,6 +27,13 @@ LINK_LIBRARIES KF5::ItemModels Qt5::Test Qt5::Widgets proxymodeltestsuite ) +if (${Qt5Qml_FOUND}) + ecm_add_tests( + kconcatenaterows_qml.cpp + LINK_LIBRARIES KF5::ItemModels Qt5::Test Qt5::Qml + ) +endif() + #we need additional sources for this test, can't use it in ecm_add_tests ecm_add_test(kselectionproxymodel_smoketest.cpp ${proxyModelSmokeTestSources} TEST_NAME "kselectionproxymodel_smoketest" diff --git a/autotests/concatenaterowstest.qml b/autotests/concatenaterowstest.qml new file mode 100644 --- /dev/null +++ b/autotests/concatenaterowstest.qml @@ -0,0 +1,16 @@ +import QtQuick 2.0 +import org.kde.kitemmodels 1.0 + +KConcatenateRowsProxyModel { + id: myModel + ListModel { + ListElement { name: "a" } + ListElement { name: "b" } + } + ListModel { + ListElement { name: "c" } + ListElement { name: "d" } + } +} + + diff --git a/autotests/kconcatenaterows_qml.cpp b/autotests/kconcatenaterows_qml.cpp new file mode 100644 --- /dev/null +++ b/autotests/kconcatenaterows_qml.cpp @@ -0,0 +1,58 @@ +/* + Copyright (C) 2019 David Edmundson + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 Lesser 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 + +#include +#include + +#include + +#include + +class tst_KConcatenateRowsQml : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void testQmlLoad(); +}; + +void tst_KConcatenateRowsQml::testQmlLoad() +{ + + QQmlApplicationEngine app; + app.load(QFINDTESTDATA("concatenaterowstest.qml")); + + QCOMPARE(app.rootObjects().count(), 1); + + auto concatModel = qobject_cast(app.rootObjects().first()); + QVERIFY(concatModel); + + QCOMPARE(concatModel->rowCount(), 4); + + + QCOMPARE(concatModel->data(concatModel->index(0, 0)).toString(), "a"); + QCOMPARE(concatModel->data(concatModel->index(1, 0)).toString(), "b"); + QCOMPARE(concatModel->data(concatModel->index(2, 0)).toString(), "c"); + QCOMPARE(concatModel->data(concatModel->index(3, 0)).toString(), "d"); +} + +QTEST_MAIN(tst_KConcatenateRowsQml) + +#include "kconcatenaterows_qml.moc" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,100 +1,4 @@ - -set(kitemmodels_SRCS - kbreadcrumbselectionmodel.cpp - kcheckableproxymodel.cpp - kconcatenaterowsproxymodel.cpp - kdescendantsproxymodel.cpp - kextracolumnsproxymodel.cpp - klinkitemselectionmodel.cpp - kmodelindexproxymapper.cpp - krearrangecolumnsproxymodel.cpp - krecursivefilterproxymodel.cpp - kselectionproxymodel.cpp -) - -ecm_qt_declare_logging_category(kitemmodels_SRCS HEADER kitemmodels_debug.h IDENTIFIER KITEMMODELS_LOG CATEGORY_NAME kf5.kitemmodels) - -add_library(KF5ItemModels ${kitemmodels_SRCS}) -generate_export_header(KF5ItemModels BASE_NAME KItemModels) -add_library(KF5::ItemModels ALIAS KF5ItemModels) - -target_include_directories(KF5ItemModels INTERFACE "$") - -target_link_libraries(KF5ItemModels PUBLIC Qt5::Core) - -set_target_properties(KF5ItemModels PROPERTIES VERSION ${KITEMMODELS_VERSION_STRING} - SOVERSION ${KITEMMODELS_SOVERSION} - EXPORT_NAME ItemModels -) - -ecm_generate_headers(KItemModels_HEADERS - HEADER_NAMES - KBreadcrumbSelectionModel - KConcatenateRowsProxyModel - KCheckableProxyModel - KExtraColumnsProxyModel - KLinkItemSelectionModel - KRearrangeColumnsProxyModel - KRecursiveFilterProxyModel - KDescendantsProxyModel - KModelIndexProxyMapper - KSelectionProxyModel - - REQUIRED_HEADERS KItemModels_HEADERS -) - -find_package(PythonModuleGeneration) - -if (PythonModuleGeneration_FOUND) - ecm_generate_python_binding( - TARGET KF5::ItemModels - PYTHONNAMESPACE PyKF5 - MODULENAME KItemModels - SIP_DEPENDS - QtCore/QtCoremod.sip - HEADERS - kbreadcrumbselectionmodel.h - kconcatenaterowsproxymodel.h - kcheckableproxymodel.h - kextracolumnsproxymodel.h - klinkitemselectionmodel.h - krearrangecolumnsproxymodel.h - krecursivefilterproxymodel.h - kdescendantsproxymodel.h - kmodelindexproxymapper.h - kselectionproxymodel.h - ) +add_subdirectory(core) +if (${Qt5Qml_FOUND}) + add_subdirectory(qml) endif() - -install(TARGETS KF5ItemModels EXPORT KF5ItemModelsTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS}) - -install(FILES - ${CMAKE_CURRENT_BINARY_DIR}/kitemmodels_export.h - ${KItemModels_HEADERS} - DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/KItemModels COMPONENT Devel -) - -if(BUILD_QCH) - ecm_add_qch( - KF5ItemModels_QCH - NAME KItemModels - BASE_NAME KF5ItemModels - VERSION ${KF5_VERSION} - ORG_DOMAIN org.kde - SOURCES # using only public headers, to cover only public API - ${KItemModels_HEADERS} - MD_MAINPAGE "${CMAKE_SOURCE_DIR}/README.md" - IMAGE_DIRS "${CMAKE_SOURCE_DIR}/docs/pics" - LINK_QCHS - Qt5Core_QCH - BLANK_MACROS - KITEMMODELS_EXPORT - TAGFILE_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR} - QCH_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR} - COMPONENT Devel - ) -endif() - -include(ECMGeneratePriFile) -ecm_generate_pri_file(BASE_NAME KItemModels LIB_NAME KF5ItemModels DEPS "core" FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF5}/KItemModels) -install(FILES ${PRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR}) diff --git a/src/CMakeLists.txt b/src/core/CMakeLists.txt copy from src/CMakeLists.txt copy to src/core/CMakeLists.txt diff --git a/src/kbihash_p.h b/src/core/kbihash_p.h rename from src/kbihash_p.h rename to src/core/kbihash_p.h diff --git a/src/kbreadcrumbselectionmodel.h b/src/core/kbreadcrumbselectionmodel.h rename from src/kbreadcrumbselectionmodel.h rename to src/core/kbreadcrumbselectionmodel.h diff --git a/src/kbreadcrumbselectionmodel.cpp b/src/core/kbreadcrumbselectionmodel.cpp rename from src/kbreadcrumbselectionmodel.cpp rename to src/core/kbreadcrumbselectionmodel.cpp diff --git a/src/kcheckableproxymodel.h b/src/core/kcheckableproxymodel.h rename from src/kcheckableproxymodel.h rename to src/core/kcheckableproxymodel.h diff --git a/src/kcheckableproxymodel.cpp b/src/core/kcheckableproxymodel.cpp rename from src/kcheckableproxymodel.cpp rename to src/core/kcheckableproxymodel.cpp diff --git a/src/kconcatenaterowsproxymodel.h b/src/core/kconcatenaterowsproxymodel.h rename from src/kconcatenaterowsproxymodel.h rename to src/core/kconcatenaterowsproxymodel.h --- a/src/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/kconcatenaterowsproxymodel.cpp b/src/core/kconcatenaterowsproxymodel.cpp rename from src/kconcatenaterowsproxymodel.cpp rename to src/core/kconcatenaterowsproxymodel.cpp --- a/src/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/kdescendantsproxymodel.h b/src/core/kdescendantsproxymodel.h rename from src/kdescendantsproxymodel.h rename to src/core/kdescendantsproxymodel.h diff --git a/src/kdescendantsproxymodel.cpp b/src/core/kdescendantsproxymodel.cpp rename from src/kdescendantsproxymodel.cpp rename to src/core/kdescendantsproxymodel.cpp diff --git a/src/kextracolumnsproxymodel.h b/src/core/kextracolumnsproxymodel.h rename from src/kextracolumnsproxymodel.h rename to src/core/kextracolumnsproxymodel.h diff --git a/src/kextracolumnsproxymodel.cpp b/src/core/kextracolumnsproxymodel.cpp rename from src/kextracolumnsproxymodel.cpp rename to src/core/kextracolumnsproxymodel.cpp diff --git a/src/klinkitemselectionmodel.h b/src/core/klinkitemselectionmodel.h rename from src/klinkitemselectionmodel.h rename to src/core/klinkitemselectionmodel.h diff --git a/src/klinkitemselectionmodel.cpp b/src/core/klinkitemselectionmodel.cpp rename from src/klinkitemselectionmodel.cpp rename to src/core/klinkitemselectionmodel.cpp diff --git a/src/kmodelindexproxymapper.h b/src/core/kmodelindexproxymapper.h rename from src/kmodelindexproxymapper.h rename to src/core/kmodelindexproxymapper.h diff --git a/src/kmodelindexproxymapper.cpp b/src/core/kmodelindexproxymapper.cpp rename from src/kmodelindexproxymapper.cpp rename to src/core/kmodelindexproxymapper.cpp diff --git a/src/krearrangecolumnsproxymodel.h b/src/core/krearrangecolumnsproxymodel.h rename from src/krearrangecolumnsproxymodel.h rename to src/core/krearrangecolumnsproxymodel.h diff --git a/src/krearrangecolumnsproxymodel.cpp b/src/core/krearrangecolumnsproxymodel.cpp rename from src/krearrangecolumnsproxymodel.cpp rename to src/core/krearrangecolumnsproxymodel.cpp diff --git a/src/krecursivefilterproxymodel.h b/src/core/krecursivefilterproxymodel.h rename from src/krecursivefilterproxymodel.h rename to src/core/krecursivefilterproxymodel.h diff --git a/src/krecursivefilterproxymodel.cpp b/src/core/krecursivefilterproxymodel.cpp rename from src/krecursivefilterproxymodel.cpp rename to src/core/krecursivefilterproxymodel.cpp diff --git a/src/kselectionproxymodel.h b/src/core/kselectionproxymodel.h rename from src/kselectionproxymodel.h rename to src/core/kselectionproxymodel.h diff --git a/src/kselectionproxymodel.cpp b/src/core/kselectionproxymodel.cpp rename from src/kselectionproxymodel.cpp rename to src/core/kselectionproxymodel.cpp diff --git a/src/kvoidpointerfactory_p.h b/src/core/kvoidpointerfactory_p.h rename from src/kvoidpointerfactory_p.h rename to src/core/kvoidpointerfactory_p.h 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