File indexing completed on 2024-04-28 05:26:46

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 "utils.h"
0009 #include <Transaction/TransactionModel.h>
0010 #include <resources/AbstractResource.h>
0011 #include <resources/ResourcesModel.h>
0012 
0013 ApplicationAddonsModel::ApplicationAddonsModel(QObject *parent)
0014     : QAbstractListModel(parent)
0015     , m_app(nullptr)
0016 {
0017     // new QAbstractItemModelTester(this, this);
0018 
0019     connect(TransactionModel::global(), &TransactionModel::transactionRemoved, this, &ApplicationAddonsModel::transactionOver);
0020     connect(ResourcesModel::global(), &ResourcesModel::resourceDataChanged, this, [this](AbstractResource *resource, const QVector<QByteArray> &properties) {
0021         if (!properties.contains("state")) {
0022             return;
0023         }
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 
0048     if (m_app) {
0049         disconnect(m_app, nullptr, this, nullptr);
0050     }
0051 
0052     m_app = app;
0053     resetState();
0054     if (m_app) {
0055         connect(m_app, &QObject::destroyed, this, [this]() {
0056             setApplication(nullptr);
0057         });
0058     }
0059     Q_EMIT applicationChanged();
0060 }
0061 
0062 void ApplicationAddonsModel::resetState()
0063 {
0064     beginResetModel();
0065     m_state.clear();
0066     m_initial = m_app ? m_app->addonsInformation() : QList<PackageState>();
0067     endResetModel();
0068 
0069     Q_EMIT stateChanged();
0070 }
0071 
0072 AbstractResource *ApplicationAddonsModel::application() const
0073 {
0074     return m_app;
0075 }
0076 
0077 int ApplicationAddonsModel::rowCount(const QModelIndex &parent) const
0078 {
0079     return parent.isValid() ? 0 : m_initial.size();
0080 }
0081 
0082 QVariant ApplicationAddonsModel::data(const QModelIndex &index, int role) const
0083 {
0084     if (!index.isValid() || index.row() >= m_initial.size()) {
0085         return QVariant();
0086     }
0087 
0088     const auto &packageState = m_initial[index.row()];
0089 
0090     switch (role) {
0091     case Qt::DisplayRole:
0092         return packageState.name();
0093     case Qt::ToolTipRole:
0094         return packageState.description();
0095     case PackageNameRole:
0096         return packageState.packageName();
0097     case Qt::CheckStateRole: {
0098         const AddonList::State state = m_state.addonState(packageState.name());
0099         if (state == AddonList::None) {
0100             return packageState.isInstalled() ? Qt::Checked : Qt::Unchecked;
0101         } else {
0102             return state == AddonList::ToInstall ? Qt::Checked : Qt::Unchecked;
0103         }
0104     }
0105     }
0106 
0107     return QVariant();
0108 }
0109 
0110 void ApplicationAddonsModel::discardChanges()
0111 {
0112     // dataChanged should suffice, but it doesn't
0113     beginResetModel();
0114     m_state.clear();
0115     Q_EMIT stateChanged();
0116     endResetModel();
0117 }
0118 
0119 void ApplicationAddonsModel::applyChanges()
0120 {
0121     ResourcesModel::global()->installApplication(m_app, m_state);
0122 }
0123 
0124 void ApplicationAddonsModel::changeState(const QString &packageName, bool installed)
0125 {
0126     auto it = std::find_if(m_initial.constBegin(), m_initial.constEnd(), [packageName](const auto &packageState) {
0127         return packageState.packageName() == packageName;
0128     });
0129     Q_ASSERT(it != m_initial.constEnd());
0130     const auto &packageState = *it;
0131 
0132     const bool restored = packageState.isInstalled() == installed;
0133 
0134     if (restored) {
0135         m_state.resetAddon(packageName);
0136     } else {
0137         m_state.addAddon(packageName, installed);
0138     }
0139 
0140     Q_EMIT stateChanged();
0141 }
0142 
0143 bool ApplicationAddonsModel::hasChanges() const
0144 {
0145     return !m_state.isEmpty();
0146 }
0147 
0148 bool ApplicationAddonsModel::isEmpty() const
0149 {
0150     return m_initial.isEmpty();
0151 }
0152 
0153 void ApplicationAddonsModel::transactionOver(Transaction *t)
0154 {
0155     if (t->resource() != m_app) {
0156         return;
0157     }
0158 
0159     resetState();
0160 }
0161 
0162 #include "moc_ApplicationAddonsModel.cpp"