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"