Commit eca66b8f authored by Aleix Pol Gonzalez's avatar Aleix Pol Gonzalez 🐧

Allow the user to set which applications backend is preferred

It will be used on the initial page and when searching
parent bb35e1ef
......@@ -96,8 +96,8 @@ static void filterDupes(QVector<AbstractResource *> &resources)
}
for(auto it = resources.begin(); it != resources.end(); ) {
const auto name = (*it)->backend()->metaObject()->className();
if (qstrcmp(name, "PackageKitBackend")!=0 && dupeUri.contains((*it)->appstreamId()))
const auto backend = (*it)->backend();
if (backend != ResourcesModel::global()->currentApplicationBackend() && dupeUri.contains((*it)->appstreamId()))
it = resources.erase(it);
else
++it;
......
......@@ -128,6 +128,30 @@ DiscoverPage {
}
}
ToolButton {
text: i18n("Application Sources")
menu: Menu {
id: backendsMenu
}
enabled: menu.items.length>0
Instantiator {
model: ResourcesModel.applicationBackends
delegate: MenuItem {
text: modelData.displayName
checkable: true
checked: ResourcesModel.currentApplicationBackend == modelData
onTriggered: ResourcesModel.currentApplicationBackend = modelData
}
onObjectAdded: {
backendsMenu.insertItem(index, object)
}
onObjectRemoved: {
object.destroy()
}
}
}
ToolButton {
text: i18n("Help...")
menu: Menu {
......
......@@ -61,6 +61,7 @@ public:
AbstractResource * resourceForFile(const QUrl & ) override;
void checkForUpdates() override;
QString displayName() const override;
bool hasApplications() const override { return true; }
private Q_SLOTS:
void onFetchMetadataFinished(FlatpakInstallation *flatpakInstallation, FlatpakResource *resource, const QByteArray &metadata);
......
......@@ -71,6 +71,8 @@ class DISCOVERCOMMON_EXPORT PackageKitBackend : public AbstractResourcesBackend
void checkForUpdates() override;
QString displayName() const override;
bool hasApplications() const override { return true; }
public Q_SLOTS:
void reloadPackageList();
void refreshDatabase();
......
......@@ -52,6 +52,7 @@ public:
bool isFetching() const override { return m_fetching; }
SnapSocket* socket() { return &m_socket; }
void checkForUpdates() override {}
bool hasApplications() const override { return true; }
private:
void setFetching(bool fetching);
......
......@@ -173,6 +173,8 @@ class DISCOVERCOMMON_EXPORT AbstractResourcesBackend : public QObject
*/
virtual QVector<Category*> category() const { return {}; }
virtual bool hasApplications() const { return false; }
public Q_SLOTS:
/**
* This gets called when the backend should install an application.
......
......@@ -30,12 +30,15 @@
#include <KActionCollection>
#include "Transaction/TransactionModel.h"
#include "Category/CategoryModel.h"
#include "utils.h"
#include <QDebug>
#include <QCoreApplication>
#include <QThread>
#include <QAction>
#include <QMetaProperty>
#include <KLocalizedString>
#include <KSharedConfig>
#include <KConfigGroup>
ResourcesModel *ResourcesModel::s_self = nullptr;
......@@ -53,6 +56,7 @@ ResourcesModel::ResourcesModel(QObject* parent, bool load)
{
init(load);
connect(this, &ResourcesModel::allInitialized, this, &ResourcesModel::fetchingChanged);
connect(this, &ResourcesModel::backendsChanged, this, &ResourcesModel::initApplicationsBackend);
}
void ResourcesModel::init(bool load)
......@@ -131,6 +135,7 @@ void ResourcesModel::callerFetchingChanged()
int idx = m_backends.indexOf(backend);
Q_ASSERT(idx>=0);
m_backends.removeAt(idx);
// Q_EMIT backendsChanged();
CategoryModel::global()->blacklistPlugin(backend->name());
backend->deleteLater();
return;
......@@ -318,8 +323,11 @@ AggregatedResultsStream * ResourcesModel::findResourceByPackageName(const QUrl&
AggregatedResultsStream* ResourcesModel::search(const AbstractResourcesBackend::Filters& search)
{
QSet<ResultsStream*> streams;
const bool allBackends = search.roles.contains("origin");
foreach(auto backend, m_backends) {
streams << backend->search(search);
if (!backend->hasApplications() || ResourcesModel::global()->currentApplicationBackend() == backend || allBackends)
streams << backend->search(search);
}
return new AggregatedResultsStream(streams);
}
......@@ -340,3 +348,43 @@ void ResourcesModel::checkForUpdates()
for(auto backend: qAsConst(m_backends))
backend->checkForUpdates();
}
QVector<AbstractResourcesBackend *> ResourcesModel::applicationBackends() const
{
return kFilter<QVector<AbstractResourcesBackend*>>(m_backends, [](AbstractResourcesBackend* b){ return b->hasApplications(); });
}
QVariantList ResourcesModel::applicationBackendsVariant() const
{
return kTransform<QVariantList>(applicationBackends(), [](AbstractResourcesBackend* b) {return QVariant::fromValue<QObject*>(b);});
}
AbstractResourcesBackend* ResourcesModel::currentApplicationBackend() const
{
return m_currentApplicationBackend;
}
void ResourcesModel::setCurrentApplicationBackend(AbstractResourcesBackend* backend)
{
if (backend != m_currentApplicationBackend) {
KConfigGroup settings(KSharedConfig::openConfig(), "ResourcesModel");
if (backend)
settings.writeEntry("currentApplicationBackend", backend->name());
else
settings.deleteEntry("currentApplicationBackend");
qDebug() << "setting currentApplicationBackend" << backend;
m_currentApplicationBackend = backend;
Q_EMIT currentApplicationBackendChanged(backend);
}
}
void ResourcesModel::initApplicationsBackend()
{
KConfigGroup settings(KSharedConfig::openConfig(), "ResourcesModel");
const QString name = settings.readEntry<QString>("currentApplicationBackend", QStringLiteral("packagekit-backend"));
const auto backends = applicationBackends();
auto idx = kIndexOf(backends, [name](AbstractResourcesBackend* b) { return b->name() == name; });
setCurrentApplicationBackend(backends.value(idx, nullptr));
}
......@@ -52,6 +52,8 @@ class DISCOVERCOMMON_EXPORT ResourcesModel : public QObject
Q_OBJECT
Q_PROPERTY(int updatesCount READ updatesCount NOTIFY updatesCountChanged)
Q_PROPERTY(bool isFetching READ isFetching NOTIFY fetchingChanged)
Q_PROPERTY(QVariantList applicationBackends READ applicationBackendsVariant NOTIFY backendsChanged)
Q_PROPERTY(AbstractResourcesBackend* currentApplicationBackend READ currentApplicationBackend WRITE setCurrentApplicationBackend NOTIFY currentApplicationBackendChanged)
public:
/** This constructor should be only used by unit tests.
* @p backendName defines what backend will be loaded when the backend is constructed.
......@@ -76,6 +78,11 @@ class DISCOVERCOMMON_EXPORT ResourcesModel : public QObject
AbstractResource* resourceForFile(const QUrl &/*url*/);
void checkForUpdates();
QVariantList applicationBackendsVariant() const;
QVector<AbstractResourcesBackend*> applicationBackends() const;
void setCurrentApplicationBackend(AbstractResourcesBackend* backend);
AbstractResourcesBackend* currentApplicationBackend() const;
public Q_SLOTS:
void installApplication(AbstractResource* app, const AddonList& addons);
void installApplication(AbstractResource* app);
......@@ -90,6 +97,7 @@ class DISCOVERCOMMON_EXPORT ResourcesModel : public QObject
void resourceDataChanged(AbstractResource* resource, const QVector<QByteArray>& properties);
void resourceRemoved(AbstractResource* resource);
void passiveMessage(const QString &message);
void currentApplicationBackendChanged(AbstractResourcesBackend* currentApplicationBackend);
private Q_SLOTS:
void callerFetchingChanged();
......@@ -102,11 +110,13 @@ class DISCOVERCOMMON_EXPORT ResourcesModel : public QObject
void init(bool load);
void addResourcesBackend(AbstractResourcesBackend* backend);
void registerBackendByName(const QString& name);
void initApplicationsBackend();
QVector< AbstractResourcesBackend* > m_backends;
int m_initializingBackends;
KActionCollection* m_actionCollection;
QList<QAction*> m_ownActions;
AbstractResourcesBackend* m_currentApplicationBackend;
static ResourcesModel* s_self;
};
......
......@@ -47,6 +47,18 @@ static T kFilter(const Q &input, _UnaryOperation op)
return ret;
}
template <typename Q, typename W>
static int kIndexOf(const Q& list, W func)
{
int i = 0;
for (auto it = list.constBegin(), itEnd = list.constEnd(); it!=itEnd; ++it) {
if (func(*it))
return i;
++i;
}
return -1;
}
class ElapsedDebug : private QElapsedTimer
{
public:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment