diff --git a/discover/assets.qrc b/discover/assets.qrc
--- a/discover/assets.qrc
+++ b/discover/assets.qrc
@@ -2,6 +2,5 @@
banners/banner.svg
- banners/coffee.jpg
diff --git a/discover/autotests/updateandinstall.qml b/discover/autotests/updateandinstall.qml
--- a/discover/autotests/updateandinstall.qml
+++ b/discover/autotests/updateandinstall.qml
@@ -32,6 +32,7 @@
{
var updatePage = appRoot.stack.currentItem;
compare(typeName(updatePage), "UpdatesPage")
+ verify(waitForSignal(updatePage, "stateChanged"))
compare(updatePage.state, "has-updates", "to update")
var button = findChild(updatePage, "Button")
verify(!button.isActive)
diff --git a/discover/qml/ApplicationPage.qml b/discover/qml/ApplicationPage.qml
--- a/discover/qml/ApplicationPage.qml
+++ b/discover/qml/ApplicationPage.qml
@@ -242,6 +242,20 @@
Layout.bottomMargin: Kirigami.Units.largeSpacing
}
+ Repeater {
+ model: application.objects
+ delegate: Loader {
+ property QtObject resource: appInfo.application
+ source: modelData
+ }
+ }
+
+ Item {
+ height: addonsButton.height
+ width: 5
+ }
+
+ // Details/metadata
Rectangle {
color: Kirigami.Theme.linkColor
Layout.fillWidth: true
diff --git a/libdiscover/backends/CMakeLists.txt b/libdiscover/backends/CMakeLists.txt
--- a/libdiscover/backends/CMakeLists.txt
+++ b/libdiscover/backends/CMakeLists.txt
@@ -28,7 +28,7 @@
message(WARNING "BUILD_FlatpakBackend enabled but Flatpak=${FLATPAK_FOUND} or AppStreamQt=${AppStreamQt_FOUND} not found")
endif()
-option(BUILD_SnapBackend "Build Snap support. Still a proof of concept" "OFF")
+option(BUILD_SnapBackend "Build Snap support." "ON")
if(BUILD_SnapBackend)
find_package(Snapd)
set_package_properties(Snapd PROPERTIES
diff --git a/libdiscover/backends/SnapBackend/CMakeLists.txt b/libdiscover/backends/SnapBackend/CMakeLists.txt
--- a/libdiscover/backends/SnapBackend/CMakeLists.txt
+++ b/libdiscover/backends/SnapBackend/CMakeLists.txt
@@ -1,6 +1,6 @@
add_subdirectory(libsnapclient)
-add_library(snap-backend MODULE SnapResource.cpp SnapBackend.cpp SnapReviewsBackend.cpp SnapTransaction.cpp)
+add_library(snap-backend MODULE SnapResource.cpp SnapBackend.cpp SnapReviewsBackend.cpp SnapTransaction.cpp snapui.qrc)
target_link_libraries(snap-backend Qt5::Core KF5::CoreAddons KF5::ConfigCore Discover::Common Snapd::Core)
install(TARGETS snap-backend DESTINATION ${PLUGIN_INSTALL_DIR}/discover)
diff --git a/libdiscover/backends/SnapBackend/SnapResource.h b/libdiscover/backends/SnapBackend/SnapResource.h
--- a/libdiscover/backends/SnapBackend/SnapResource.h
+++ b/libdiscover/backends/SnapBackend/SnapResource.h
@@ -27,10 +27,12 @@
#include
class SnapBackend;
+class QAbstractItemModel;
class SnapResource : public AbstractResource
{
Q_OBJECT
+Q_PROPERTY(QStringList objects MEMBER m_objects CONSTANT)
public:
explicit SnapResource(QSharedPointer snap, AbstractResource::State state, SnapBackend* parent);
~SnapResource() override = default;
@@ -62,12 +64,15 @@
QDate releaseDate() const override;
+ Q_SCRIPTABLE QAbstractItemModel* plugs(QObject* parents);
+
public:
void gotIcon();
AbstractResource::State m_state;
QSharedPointer m_snap;
mutable QVariant m_icon;
+ const QStringList m_objects;
};
#endif // SNAPRESOURCE_H
diff --git a/libdiscover/backends/SnapBackend/SnapResource.cpp b/libdiscover/backends/SnapBackend/SnapResource.cpp
--- a/libdiscover/backends/SnapBackend/SnapResource.cpp
+++ b/libdiscover/backends/SnapBackend/SnapResource.cpp
@@ -24,11 +24,40 @@
#include
#include
#include
+#include
+#include
+#include
+#include
-SnapResource::SnapResource(QSharedPointer snap, AbstractResource::State state, SnapBackend* parent)
- : AbstractResource(parent)
+QDebug operator<<(QDebug debug, const QSnapdPlug& plug)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace() << "QSnapdPlug(";
+ debug.nospace() << "name:" << plug.name() << ',';
+ debug.nospace() << "snap:" << plug.snap() << ',';
+ debug.nospace() << "interface:" << plug.interface() << ',';
+ debug.nospace() << "connectionCount:" << plug.connectionCount();
+ debug.nospace() << ')';
+ return debug;
+}
+
+QDebug operator<<(QDebug debug, const QSnapdSlot& slot)
+{
+ QDebugStateSaver saver(debug);
+ debug.nospace() << "QSnapdSlot(";
+ debug.nospace() << "name:" << slot.name() << ',';
+ debug.nospace() << "snap:" << slot.snap() << ',';
+ debug.nospace() << "interface:" << slot.interface() << ',';
+ debug.nospace() << "connectionCount:" << slot.connectionCount();
+ debug.nospace() << ')';
+ return debug;
+}
+
+SnapResource::SnapResource(QSharedPointer snap, AbstractResource::State state, SnapBackend* backend)
+ : AbstractResource(backend)
, m_state(state)
, m_snap(snap)
+ , m_objects({ QStringLiteral("qrc:/snapui/PermissionsButton.qml") })
{
setObjectName(snap->name());
}
@@ -192,3 +221,48 @@
{
return {};
}
+
+QAbstractItemModel* SnapResource::plugs(QObject* p)
+{
+ QStandardItemModel* model = new QStandardItemModel(p);
+ if (!isInstalled())
+ return model;
+
+ model->setItemRoleNames(model->roleNames().unite(
+ { {Qt::CheckStateRole, "checked"} }
+ ));
+ connect(model, &QStandardItemModel::itemChanged, this, [this](QStandardItem* item){
+ auto backend = qobject_cast(parent());
+ const QString name = item->data().toString();
+
+ //TODO: look up for which package offers the slot instead of core?
+ if (item->checkState() == Qt::Checked) {
+ auto req = backend->client()->connectInterface(m_snap->name(), name, QStringLiteral("core"), name);
+ req->runAsync();
+ } else {
+ auto req = backend->client()->disconnectInterface(m_snap->name(), name, QStringLiteral("core"), name);
+ req->runAsync();
+ }
+ });
+
+ auto backend = qobject_cast(parent());
+ auto req = backend->client()->getInterfaces();
+ req->runSync();
+
+ for (int i = 0; iplugCount(); ++i) {
+ const QScopedPointer plug(req->plug(i));
+ if (plug->snap() == m_snap->name()) {
+ auto item = new QStandardItem;
+ if (plug->label().isEmpty())
+ item->setText(plug->name());
+ else
+ item->setText(i18n("%1 - %2", plug->name(), plug->label()));
+
+ item->setCheckable(true);
+ item->setCheckState(plug->connectionCount()>0 ? Qt::Checked : Qt::Unchecked);
+ item->setData(plug->name());
+ model->appendRow(item);
+ }
+ }
+ return model;
+}