File indexing completed on 2024-04-28 16:44:04

0001 /*
0002  *   SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
0003  *
0004  *   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 #include "ApplicationAddonsModel.h"
0008 #include "libdiscover_debug.h"
0009 #include "utils.h"
0010 #include <Transaction/TransactionModel.h>
0011 #include <resources/AbstractResource.h>
0012 #include <resources/ResourcesModel.h>
0013 
0014 ApplicationAddonsModel::ApplicationAddonsModel(QObject *parent)
0015     : QAbstractListModel(parent)
0016     , m_app(nullptr)
0017 {
0018     // new QAbstractItemModelTester(this, this);
0019 
0020     connect(TransactionModel::global(), &TransactionModel::transactionRemoved, this, &ApplicationAddonsModel::transactionOver);
0021     connect(ResourcesModel::global(), &ResourcesModel::resourceDataChanged, this, [this](AbstractResource *resource, const QVector<QByteArray> &properties) {
0022         if (!properties.contains("state"))
0023             return;
0024 
0025         const QString appstreamId = resource->appstreamId();
0026         if (kContains(m_initial, [&appstreamId](const PackageState &state) {
0027                 return appstreamId == state.packageName();
0028             })) {
0029             resetState();
0030         }
0031     });
0032 }
0033 
0034 QHash<int, QByteArray> ApplicationAddonsModel::roleNames() const
0035 {
0036     QHash<int, QByteArray> roles = QAbstractItemModel::roleNames();
0037     roles.insert(Qt::CheckStateRole, "checked");
0038     roles.insert(PackageNameRole, "packageName");
0039     return roles;
0040 }
0041 
0042 void ApplicationAddonsModel::setApplication(AbstractResource *app)
0043 {
0044     if (app == m_app)
0045         return;
0046 
0047     if (m_app)
0048         disconnect(m_app, nullptr, this, nullptr);
0049 
0050     m_app = app;
0051     resetState();
0052     if (m_app) {
0053         connect(m_app, &QObject::destroyed, this, [this]() {
0054             setApplication(nullptr);
0055         });
0056     }
0057     Q_EMIT applicationChanged();
0058 }
0059 
0060 void ApplicationAddonsModel::resetState()
0061 {
0062     beginResetModel();
0063     m_state.clear();
0064     m_initial = m_app ? m_app->addonsInformation() : QList<PackageState>();
0065     endResetModel();
0066 
0067     Q_EMIT stateChanged();
0068 }
0069 
0070 AbstractResource *ApplicationAddonsModel::application() const
0071 {
0072     return m_app;
0073 }
0074 
0075 int ApplicationAddonsModel::rowCount(const QModelIndex &parent) const
0076 {
0077     return parent.isValid() ? 0 : m_initial.size();
0078 }
0079 
0080 QVariant ApplicationAddonsModel::data(const QModelIndex &index, int role) const
0081 {
0082     if (!index.isValid() || index.row() >= m_initial.size())
0083         return QVariant();
0084 
0085     switch (role) {
0086     case Qt::DisplayRole:
0087         return m_initial[index.row()].name();
0088     case Qt::ToolTipRole:
0089         return m_initial[index.row()].description();
0090     case PackageNameRole:
0091         return m_initial[index.row()].packageName();
0092     case Qt::CheckStateRole: {
0093         const PackageState init = m_initial[index.row()];
0094         const AddonList::State state = m_state.addonState(init.name());
0095         if (state == AddonList::None) {
0096             return init.isInstalled() ? Qt::Checked : Qt::Unchecked;
0097         } else {
0098             return state == AddonList::ToInstall ? Qt::Checked : Qt::Unchecked;
0099         }
0100     }
0101     }
0102 
0103     return QVariant();
0104 }
0105 
0106 void ApplicationAddonsModel::discardChanges()
0107 {
0108     // dataChanged should suffice, but it doesn't
0109     beginResetModel();
0110     m_state.clear();
0111     Q_EMIT stateChanged();
0112     endResetModel();
0113 }
0114 
0115 void ApplicationAddonsModel::applyChanges()
0116 {
0117     ResourcesModel::global()->installApplication(m_app, m_state);
0118 }
0119 
0120 void ApplicationAddonsModel::changeState(const QString &packageName, bool installed)
0121 {
0122     auto it = m_initial.constBegin();
0123     for (; it != m_initial.constEnd(); ++it) {
0124         if (it->packageName() == packageName)
0125             break;
0126     }
0127     Q_ASSERT(it != m_initial.constEnd());
0128 
0129     const bool restored = it->isInstalled() == installed;
0130 
0131     if (restored)
0132         m_state.resetAddon(packageName);
0133     else
0134         m_state.addAddon(packageName, installed);
0135 
0136     Q_EMIT stateChanged();
0137 }
0138 
0139 bool ApplicationAddonsModel::hasChanges() const
0140 {
0141     return !m_state.isEmpty();
0142 }
0143 
0144 bool ApplicationAddonsModel::isEmpty() const
0145 {
0146     return m_initial.isEmpty();
0147 }
0148 
0149 void ApplicationAddonsModel::transactionOver(Transaction *t)
0150 {
0151     if (t->resource() != m_app)
0152         return;
0153 
0154     resetState();
0155 }
0156 
0157 #include "moc_ApplicationAddonsModel.cpp"