diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 2571ca06..64af1d17 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1,132 +1,134 @@ set(KNewStuffCore_SRCS author.cpp commentsmodel.cpp cache.cpp downloadmanager.cpp engine.cpp entryinternal.cpp + entrywrapper.cpp imageloader.cpp installation.cpp itemsmodel.cpp provider.cpp security.cpp tagsfilterchecker.cpp xmlloader.cpp errorcode.cpp # A system by which queries can be passed to the user, and responses # gathered, depending on implementation. See question.h for details. question.cpp questionmanager.cpp questionlistener.cpp # A set of minimal KJob based classes, designed to replace the # more powerful KIO based system in places where KIO is not available # for one reason or another. jobs/downloadjob.cpp jobs/filecopyjob.cpp jobs/filecopyworker.cpp jobs/httpjob.cpp jobs/httpworker.cpp ../attica/atticaprovider.cpp ../staticxml/staticxmlprovider.cpp ../upload/atticahelper.cpp ) ecm_qt_declare_logging_category(KNewStuffCore_SRCS HEADER knewstuffcore_debug.h IDENTIFIER KNEWSTUFFCORE CATEGORY_NAME org.kde.knewstuff.core) add_library(KF5NewStuffCore ${KNewStuffCore_SRCS} ) add_library(KF5::NewStuffCore ALIAS KF5NewStuffCore ) ecm_generate_export_header(KF5NewStuffCore EXPORT_FILE_NAME knewstuffcore_export.h BASE_NAME KNewStuffCore GROUP_BASE_NAME KF VERSION ${KF5_VERSION} DEPRECATED_BASE_VERSION 0 DEPRECATION_VERSIONS 5.31 5.36 5.53 ) # TODO: add support for EXCLUDE_DEPRECATED_BEFORE_AND_AT # needs fixing of undeprecated API being still implemented using own deprecated API # The src/ dir is needed for the entry.h header. This only happens because some # code in Core uses an enum from KNS3::Entry target_include_directories(KF5NewStuffCore PUBLIC "$" INTERFACE "$") target_link_libraries(KF5NewStuffCore PUBLIC KF5::Attica # For interacting with ocs providers, public for uploaddialog slots KF5::CoreAddons Qt5::Xml PRIVATE KF5::Archive # For decompressing archives KF5::I18n # For translations KF5::ConfigCore Qt5::Gui # For QImage ) set_target_properties(KF5NewStuffCore PROPERTIES VERSION ${KNEWSTUFF_VERSION_STRING} SOVERSION ${KNEWSTUFF_SOVERSION} EXPORT_NAME NewStuffCore ) ecm_generate_headers(KNewStuffCore_CamelCase_HEADERS HEADER_NAMES Author Cache DownloadManager Engine EntryInternal + EntryWrapper ErrorCode Installation ItemsModel Provider Question QuestionListener QuestionManager Security TagsFilterChecker XmlLoader REQUIRED_HEADERS KNewStuffCore_HEADERS PREFIX KNSCore ) install(TARGETS KF5NewStuffCore EXPORT KF5NewStuffCoreTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS}) install(FILES ${KNewStuffCore_CamelCase_HEADERS} DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/KNewStuff3/KNSCore COMPONENT Devel) install(FILES ${KNewStuffCore_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/knewstuffcore_export.h DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/KNewStuff3/knscore COMPONENT Devel) if(BUILD_QCH) ecm_add_qch( KF5NewStuffCore_QCH NAME KNewStuffCore BASE_NAME KF5NewStuffCore VERSION ${KF5_VERSION} ORG_DOMAIN org.kde SOURCES ${KNewStuffCore_HEADERS} LINK_QCHS KF5Attica_QCH KF5CoreAddons_QCH BLANK_MACROS KNEWSTUFFCORE_EXPORT KNEWSTUFFCORE_DEPRECATED KNEWSTUFFCORE_DEPRECATED_EXPORT "KNEWSTUFFCORE_DEPRECATED_VERSION(x, y, t)" TAGFILE_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR} QCH_INSTALL_DESTINATION ${KDE_INSTALL_QTQCHDIR} COMPONENT Devel ) endif() include(ECMGeneratePriFile) ecm_generate_pri_file(BASE_NAME KNewStuffCore LIB_NAME KF5NewStuffCore DEPS "Attica" FILENAME_VAR COREPRI_FILENAME INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF5}/KNewStuff3) install(FILES ${COREPRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR}) diff --git a/src/core/entrywrapper.cpp b/src/core/entrywrapper.cpp new file mode 100644 index 00000000..54249032 --- /dev/null +++ b/src/core/entrywrapper.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2020 Dan Leinir Turthra Jensen + * + * 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) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * 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 Lesser General Public + * License along with this library. If not, see . + * + */ + +#include "entrywrapper.h" + +namespace KNSCore { + class EntryWrapper::Private { + public: + Private(const EntryInternal& entry + ) + : entry(entry) + {} + EntryInternal entry; + }; +} + +KNSCore::EntryWrapper::EntryWrapper(const KNSCore::EntryInternal& entry, QObject* parent) + : QObject(parent) + , d(new Private(entry)) +{} + +KNSCore::EntryWrapper::~EntryWrapper() +{ + delete d; +} + +KNSCore::EntryInternal KNSCore::EntryWrapper::entry() const +{ + return d->entry; +} diff --git a/src/core/entrywrapper.h b/src/core/entrywrapper.h new file mode 100644 index 00000000..39a86492 --- /dev/null +++ b/src/core/entrywrapper.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 Dan Leinir Turthra Jensen + * + * 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) version 3, or any + * later version accepted by the membership of KDE e.V. (or its + * successor approved by the membership of KDE e.V.), which shall + * act as a proxy defined in Section 6 of version 3 of the license. + * + * 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 Lesser General Public + * License along with this library. If not, see . + * + */ + +#ifndef ENTRYWRAPPER_H +#define ENTRYWRAPPER_H + +#include + +#include "entryinternal.h" +#include "knewstuffcore_export.h" + +namespace KNSCore +{ +// This is for passing an entryinternal through qml, particularly useful for lists +// such as changedEntries. This is supposed to closely approximate the current +// codepaths used in client code (which expects a list of entries), but for KF6 +// we will want to turn this into a model instead, probably with some handy +// iteration assistance for use in places which would previously use the lists. +/// TODO KF6 see above (in short, make this class irrelevant so it can be removed) + +/** + * @short Wraps a KNSCore::EntryInternal in a QObject for passing through Qt Quick + * + * For those places where we need to pass a KNSCore::EntryInternal through Qt Quick, + * this class wraps such objects in a QObject, and provides the ability to interact + * with the data through that. + * + * Since that class is not a QObject (and can't easily be turned into one), until major + * upheaval becomes possible in Frameworks 6, this class will have to do. + * @since 5.67 + */ +class KNEWSTUFFCORE_EXPORT EntryWrapper : public QObject +{ + Q_OBJECT +public: + explicit EntryWrapper(const EntryInternal& entry, QObject *parent = nullptr); + virtual ~EntryWrapper(); + + /** + * Get a copy of the wrapped-up entry + * @return A copy of the entry + */ + EntryInternal entry() const; +private: + class Private; + Private *d; +}; +} +Q_DECLARE_METATYPE(KNSCore::EntryWrapper*) + +#endif//ENTRYWRAPPER_H diff --git a/src/qtquick/qml/Button.qml b/src/qtquick/qml/Button.qml index 8c648196..60df558e 100644 --- a/src/qtquick/qml/Button.qml +++ b/src/qtquick/qml/Button.qml @@ -1,123 +1,128 @@ /* * Copyright (C) 2019 Dan Leinir Turthra Jensen * * 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) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * 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 Lesser General Public * License along with this library. If not, see . * */ /** * @brief A button which when clicked will open a dialog with a NewStuff.Page at the base * * This component is equivalent to the old Button * @see KNewStuff::Button * @since 5.63 */ import QtQuick 2.11 import QtQuick.Controls 2.11 as QtControls import org.kde.newstuff 1.62 as NewStuff QtControls.Button { id: component /* * The configuration file is not aliased, because then we end up initialising the * KNSCore::Engine immediately the Button is shown, which we want to avoid (as that * is effectively a phone-home scenario, and causes internet traffic in situations * where it would not seem likely that there should be any). * If we want, in the future, to add some status display to Button (such as "there * are updates to be had" or somesuch, then we can do this, but until that choice is * made, let's not) */ /** * The configuration file to use for this button */ property string configFile: ghnsDialog.configFile /** * Set the text that should appear on the button. Will be set as * i18n("Download New %1..."). * * @note For the sake of consistency, you should NOT override the text propety, just set this one */ property string downloadNewWhat: i18nc("Used to contruct the button's label (which will become Download New 'this value'...)", "Stuff") text: i18n("Download New %1...", downloadNewWhat) /** * The default view mode of the dialog spawned by this button. This should be * set using the NewStuff.Page.ViewMode enum * @see NewStuff.Page.ViewMode */ property alias viewMode: ghnsDialog.viewMode /** * emitted when the Hot New Stuff dialog is about to be shown, usually * as a result of the user having click on the button */ signal aboutToShowDialog(); /** * The engine which handles the content in this Button */ property alias engine: ghnsDialog.engine /** * Contains the entries which have been changed. * @note This is cleared when the dialog is shown, so the changed entries are those * changed since the dialog was opened most recently (rather than the lifetime * of the instance of the Button component) */ - property alias changedEntries: ghnsDialog.changedEntries + property var changedEntries + Binding { + target: component + property: "changedEntries" + value: ghnsDialog.engine.changedEntries + } /** * If this is true (default is false), the button will be shown when the Kiosk settings are such * that Get Hot New Stuff is disallowed (and any other time enabled is set to false). * Usually you would want to leave this alone, but occasionally you may have a reason to * leave a button in place that the user is unable to enable. */ property bool visibleWhenDisabled: false /** * Show the dialog (same as clicking the button), if allowed by the Kiosk settings */ function showDialog() { if (ghnsDialog.engine.allowedByKiosk) { ghnsDialog.engine.configFile = component.configFile component.aboutToShowDialog(); ghnsDialog.open(); } else { // make some noise, because silently doing nothing is a bit annoying } } onClicked: { showDialog(); } icon.name: "get-hot-new-stuff" visible: enabled || visibleWhenDisabled enabled: ghnsDialog.engine.allowedByKiosk onEnabledChanged: { // If the user resets this when kiosk has disallowed ghns, force enabled back to false if (enabled === true && ghnsDialog.engine.allowedByKiosk === false) { enabled = false; } } NewStuff.Dialog { id: ghnsDialog } } diff --git a/src/qtquick/qmlplugin.cpp b/src/qtquick/qmlplugin.cpp index 6f60aeaa..4fe94932 100644 --- a/src/qtquick/qmlplugin.cpp +++ b/src/qtquick/qmlplugin.cpp @@ -1,58 +1,67 @@ /* * Copyright (C) 2016 Dan Leinir Turthra Jensen * * 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) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * 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 Lesser General Public * License along with this library. If not, see . * */ #include "qmlplugin.h" #include "quickengine.h" #include "quickitemsmodel.h" #include "quickquestionlistener.h" #include "author.h" #include "categoriesmodel.h" #include "commentsmodel.h" #include "downloadlinkinfo.h" +#include "entrywrapper.h" #include "provider.h" #include "question.h" #include #include void QmlPlugins::initializeEngine(QQmlEngine *engine, const char *) { Q_UNUSED(engine); } void QmlPlugins::registerTypes(const char *uri) { + const char* coreUri{"org.kde.newstuff.core"}; + + // Initial version qmlRegisterType(uri, 1, 0, "Engine"); qmlRegisterType(uri, 1, 0, "ItemsModel"); + + // Version 1.62 qmlRegisterType(uri, 1, 62, "Author"); qmlRegisterType(uri, 1, 62, "CommentsModel"); qmlRegisterUncreatableType(uri, 1, 0, "DownloadLinkInfo", QStringLiteral("This should only be created by the ItemsModel, and is associated with one entry in that model")); qmlRegisterUncreatableType(uri, 1, 0, "CategoriesModel", QStringLiteral("This should only be created by the Engine, and provides the categories available in that engine")); - qmlRegisterUncreatableMetaObject(KNSCore::Provider::staticMetaObject, "org.kde.newstuff.core", 1, 62, "Provider", QLatin1String("Error: this only exists to forward enums")); - qmlRegisterUncreatableMetaObject(KNSCore::Question::staticMetaObject, "org.kde.newstuff.core", 1, 62, "Question", QLatin1String("Error: this only exists to forward enums")); + qmlRegisterUncreatableMetaObject(KNSCore::Provider::staticMetaObject, coreUri, 1, 62, "Provider", QLatin1String("Error: this only exists to forward enums")); + qmlRegisterUncreatableMetaObject(KNSCore::Question::staticMetaObject, coreUri, 1, 62, "Question", QLatin1String("Error: this only exists to forward enums")); qmlRegisterSingletonType(uri, 1, 62, "QuickQuestionListener", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * { Q_UNUSED(scriptEngine) engine->setObjectOwnership(KNewStuffQuick::QuickQuestionListener::instance(), QQmlEngine::CppOwnership); return KNewStuffQuick::QuickQuestionListener::instance(); }); + + // Version 1.67 + qmlRegisterUncreatableType(coreUri, 1, 67, "EntryWrapper", QStringLiteral("This should only be created by the Engine, and wraps EntryInternal objects for passing through Qt Quick")); } diff --git a/src/qtquick/quickengine.cpp b/src/qtquick/quickengine.cpp index 3ae7666d..fd4ceae7 100644 --- a/src/qtquick/quickengine.cpp +++ b/src/qtquick/quickengine.cpp @@ -1,243 +1,274 @@ /* * Copyright (C) 2016 Dan Leinir Turthra Jensen * * 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) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * 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 Lesser General Public * License along with this library. If not, see . * */ #include "quickengine.h" #include #include #include "categoriesmodel.h" +#include "entrywrapper.h" #include "quickquestionlistener.h" #include "engine.h" class Engine::Private { public: Private() : engine(nullptr) , categoriesModel(nullptr) {} KNSCore::Engine *engine; bool isLoading{false}; CategoriesModel *categoriesModel; QString configFile; + KNSCore::EntryInternal::List changedEntries; + static KNSCore::EntryWrapper *getChangedEntry(QQmlListProperty* property, int i) + { + KNSCore::EntryWrapper *entry{nullptr}; + if (property) { + Private* d = static_cast(property->data); + if (d) { + if (i >= 0 && i < d->changedEntries.count()) { + // Lifetime management for these objects should be done by the consumer, + // but are also parented for auto-delete on application shutdown + entry = new KNSCore::EntryWrapper(d->changedEntries[i], property->object); + } + } + } + return entry; + } + static int getChangedEntriesCount(QQmlListProperty* property) + { + int count{0}; + if (property) { + Private* d = static_cast(property->data); + if (d) { + count = d->changedEntries.count(); + } + } + return count; + } }; Engine::Engine(QObject *parent) : QObject(parent) , d(new Private) { } Engine::~Engine() { delete d; } bool Engine::allowedByKiosk() const { return KAuthorized::authorize(QStringLiteral("ghns")); } QString Engine::configFile() const { return d->configFile; } void Engine::setConfigFile(const QString &newFile) { if (d->configFile != newFile) { d->isLoading = true; emit isLoadingChanged(); d->configFile = newFile; emit configFileChanged(); if (allowedByKiosk()) { if (!d->engine) { d->engine = new KNSCore::Engine(this); connect(d->engine, &KNSCore::Engine::signalProvidersLoaded, this, [=](){ d->isLoading = false; emit isLoadingChanged(); }); connect(d->engine, &KNSCore::Engine::signalMessage, this, &Engine::message); connect(d->engine, &KNSCore::Engine::signalIdle, this, &Engine::idleMessage); connect(d->engine, &KNSCore::Engine::signalBusy, this, &Engine::busyMessage); connect(d->engine, &KNSCore::Engine::signalError, this, &Engine::errorMessage); connect(d->engine, &KNSCore::Engine::signalErrorCode, this, [=](const KNSCore::ErrorCode &errorCode, const QString &message, const QVariant &/*metadata*/) { if (errorCode == KNSCore::ProviderError) { // This means loading the providers file failed entirely and we cannot complete the // initialisation. It also means the engine is done loading, but that nothing will // work, and we need to inform the user of this. d->isLoading = false; emit isLoadingChanged(); } emit errorMessage(message); }); connect(d->engine, &KNSCore::Engine::signalEntryChanged, this, [this](const KNSCore::EntryInternal &entry){ + if (d->changedEntries.contains(entry) ) { + d->changedEntries.removeAll(entry); + } d->changedEntries << entry; emit changedEntriesChanged(); }); emit engineChanged(); KNewStuffQuick::QuickQuestionListener::instance(); d->categoriesModel = new CategoriesModel(this); emit categoriesChanged(); } d->engine->init(d->configFile); d->engine->setSortMode(KNSCore::Provider::Downloads); emit engineInitialized(); } else { // This is not an error message in the proper sense, and the message is not intended to look like an error (as there is really // nothing the user can do to fix it, and we just tell them so they're not wondering what's wrong) emit message(i18nc("An informational message which is shown to inform the user they are not authorized to use GetHotNewStuff functionality", "You are not authorized to Get Hot New Stuff. If you think this is in error, please contact the person in charge of your permissions.")); } } } QObject *Engine::engine() const { return d->engine; } bool Engine::isLoading() const { return d->isLoading; } bool Engine::hasAdoptionCommand() const { if (d->engine) { return d->engine->hasAdoptionCommand(); } return false; } QString Engine::name() const { if (d->engine) { return d->engine->name(); } return QString{}; } QObject *Engine::categories() const { return d->categoriesModel; } QStringList Engine::categoriesFilter() const { if (d->engine) { return d->engine->categoriesFilter(); } return QStringList{}; } void Engine::setCategoriesFilter(const QStringList &newCategoriesFilter) { if (d->engine) { // This ensures that if we somehow end up with any empty entries (such as the default // option in the categories dropdowns), our list will remain empty. QStringList filter{newCategoriesFilter}; filter.removeAll({}); if (d->engine->categoriesFilter() != filter) { d->engine->setCategoriesFilter(filter); emit categoriesFilterChanged(); } } } void Engine::resetCategoriesFilter() { if (d->engine) { d->engine->setCategoriesFilter(d->engine->categories()); } } int Engine::filter() const { if (d->engine) { d->engine->filter(); } return 0; } void Engine::setFilter(int newFilter) { if (d->engine && d->engine->filter() != newFilter) { d->engine->setFilter(static_cast(newFilter)); emit filterChanged(); } } int Engine::sortOrder() const { if (d->engine) { return d->engine->sortMode(); } return 0; } void Engine::setSortOrder(int newSortOrder) { if (d->engine && d->engine->sortMode() != newSortOrder) { d->engine->setSortMode(static_cast(newSortOrder)); emit sortOrderChanged(); } } QString Engine::searchTerm() const { if (d->engine) { return d->engine->searchTerm(); } return QString{}; } void Engine::setSearchTerm(const QString &newSearchTerm) { if (d->engine && d->engine->searchTerm() != newSearchTerm) { d->engine->setSearchTerm(newSearchTerm); emit searchTermChanged(); } } void Engine::resetSearchTerm() { setSearchTerm(QString{}); } -KNSCore::EntryInternal::List Engine::changedEntries() const +QQmlListProperty Engine::changedEntries() { - return d->changedEntries; + return QQmlListProperty(this, d, &Private::getChangedEntriesCount, &Private::getChangedEntry); } int Engine::changedEntriesCount() const { return d->changedEntries.count(); } void Engine::resetChangedEntries() { d->changedEntries.clear(); emit changedEntriesChanged(); } diff --git a/src/qtquick/quickengine.h b/src/qtquick/quickengine.h index b0343fde..31eaf844 100644 --- a/src/qtquick/quickengine.h +++ b/src/qtquick/quickengine.h @@ -1,120 +1,122 @@ /* * Copyright (C) 2016 Dan Leinir Turthra Jensen * * 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) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * 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 Lesser General Public * License along with this library. If not, see . * */ #ifndef ENGINE_H #define ENGINE_H #include -#include +#include + +#include "entrywrapper.h" /** * @short Encapsulates a KNSCore::Engine for use in Qt Quick * * This class takes care of initialisation of a KNSCore::Engine when assigned a config file. * The actual KNSCore:Engine can be read through the Engine::engine property. * * @see ItemsModel */ class Engine : public QObject { Q_OBJECT Q_PROPERTY(bool allowedByKiosk READ allowedByKiosk CONSTANT) Q_PROPERTY(QString configFile READ configFile WRITE setConfigFile NOTIFY configFileChanged) Q_PROPERTY(QObject* engine READ engine NOTIFY engineChanged) /** * Whether or not the engine is performing its initial loading operations * @since 5.65 */ Q_PROPERTY(bool isLoading READ isLoading NOTIFY isLoadingChanged) Q_PROPERTY(bool hasAdoptionCommand READ hasAdoptionCommand NOTIFY engineInitialized) Q_PROPERTY(QString name READ name NOTIFY engineInitialized) Q_PROPERTY(QObject* categories READ categories NOTIFY categoriesChanged) Q_PROPERTY(QStringList categoriesFilter READ categoriesFilter WRITE setCategoriesFilter RESET resetCategoriesFilter NOTIFY categoriesFilterChanged) Q_PROPERTY(int filter READ filter WRITE setFilter NOTIFY filterChanged) Q_PROPERTY(int sortOrder READ sortOrder WRITE setSortOrder NOTIFY sortOrderChanged) Q_PROPERTY(QString searchTerm READ searchTerm WRITE setSearchTerm RESET resetSearchTerm NOTIFY searchTermChanged) - Q_PROPERTY(KNSCore::EntryInternal::List changedEntries READ changedEntries RESET resetChangedEntries NOTIFY changedEntriesChanged) + Q_PROPERTY(QQmlListProperty changedEntries READ changedEntries NOTIFY changedEntriesChanged) Q_PROPERTY(int changedEntriesCount READ changedEntriesCount NOTIFY changedEntriesChanged) public: explicit Engine(QObject *parent = nullptr); virtual ~Engine(); bool allowedByKiosk() const; QString configFile() const; void setConfigFile(const QString &newFile); Q_SIGNAL void configFileChanged(); QObject *engine() const; Q_SIGNAL void engineChanged(); /** * Whether or not the engine is performing its initial loading operations * @since 5.65 */ bool isLoading() const; /** * Fired when the isLoading value changes * @since 5.65 */ Q_SIGNAL void isLoadingChanged(); bool hasAdoptionCommand() const; QString name() const; Q_SIGNAL void engineInitialized(); QObject *categories() const; Q_SIGNAL void categoriesChanged(); QStringList categoriesFilter() const; void setCategoriesFilter(const QStringList &newCategoriesFilter); Q_INVOKABLE void resetCategoriesFilter(); Q_SIGNAL void categoriesFilterChanged(); int filter() const; void setFilter(int newFilter); Q_SIGNAL void filterChanged(); int sortOrder() const; void setSortOrder(int newSortOrder); Q_SIGNAL void sortOrderChanged(); QString searchTerm() const; void setSearchTerm(const QString &newSearchTerm); Q_INVOKABLE void resetSearchTerm(); Q_SIGNAL void searchTermChanged(); - KNSCore::EntryInternal::List changedEntries() const; + QQmlListProperty changedEntries(); Q_INVOKABLE void resetChangedEntries(); Q_SIGNAL void changedEntriesChanged(); int changedEntriesCount() const; Q_SIGNALS: void message(const QString &message); void idleMessage(const QString &message); void busyMessage(const QString &message); void errorMessage(const QString &message); private: class Private; Private *d; }; #endif//ENGINE_H