File indexing completed on 2024-05-19 16:31:38
0001 /* 0002 * SPDX-FileCopyrightText: 2015 Dominik Haumann <dhaumann@kde.org> 0003 * 0004 * SPDX-License-Identifier: LGPL-2.1-or-later 0005 */ 0006 #include "QuotaListModel.h" 0007 0008 #include <QDebug> 0009 0010 QuotaListModel::QuotaListModel(QObject *parent) 0011 : QAbstractListModel(parent) 0012 { 0013 } 0014 0015 namespace 0016 { 0017 /** 0018 * QML data roles. 0019 */ 0020 enum { 0021 DetailsRole = Qt::UserRole, 0022 IconRole, 0023 FreeStringRole, 0024 UsedStringRole, 0025 MountPointRole, 0026 UsageRole, 0027 }; 0028 } 0029 0030 QHash<int, QByteArray> QuotaListModel::roleNames() const 0031 { 0032 QHash<int, QByteArray> roles; 0033 roles[DetailsRole] = "details"; 0034 roles[IconRole] = "icon"; 0035 roles[FreeStringRole] = "free"; 0036 roles[UsedStringRole] = "used"; 0037 roles[MountPointRole] = "mountPoint"; 0038 roles[UsageRole] = "usage"; 0039 0040 return roles; 0041 } 0042 0043 QVariant QuotaListModel::data(const QModelIndex &index, int role) const 0044 { 0045 if (!index.isValid() || index.row() >= m_items.size()) { 0046 return QVariant(); 0047 } 0048 0049 const auto item = m_items[index.row()]; 0050 0051 switch (role) { 0052 case DetailsRole: 0053 return item.mountString(); 0054 case IconRole: 0055 return item.iconName(); 0056 case FreeStringRole: 0057 return item.freeString(); 0058 case UsedStringRole: 0059 return item.usedString(); 0060 case MountPointRole: 0061 return item.mountPoint(); 0062 case UsageRole: 0063 return item.usage(); 0064 } 0065 0066 return QVariant(); 0067 } 0068 0069 int QuotaListModel::rowCount(const QModelIndex &index) const 0070 { 0071 if (!index.isValid()) { 0072 return m_items.size(); 0073 } 0074 0075 return 0; 0076 } 0077 0078 bool QuotaListModel::setData(const QModelIndex &index, const QVariant &variant, int role) 0079 { 0080 Q_UNUSED(role) 0081 0082 const int row = index.row(); 0083 if (index.isValid() && row < m_items.size()) { 0084 const QuotaItem item = variant.value<QuotaItem>(); 0085 0086 // This assert makes sure that changing items modify the correct item: 0087 // therefore, the unique identifier 'mountPoint()' is used. If that 0088 // is not the case, the newly inserted row must have an empty mountPoint(). 0089 Q_ASSERT(item.mountPoint() == m_items[row].mountPoint() || m_items[row].mountPoint().isEmpty()); 0090 0091 if (m_items[row] != item) { 0092 m_items[row] = item; 0093 Q_EMIT dataChanged(index, index); 0094 return true; 0095 } 0096 } 0097 0098 return false; 0099 } 0100 0101 bool QuotaListModel::insertRows(int row, int count, const QModelIndex &parent) 0102 { 0103 // only top-level items are supported 0104 if (parent.isValid()) { 0105 return false; 0106 } 0107 0108 beginInsertRows(QModelIndex(), row, row + count - 1); 0109 m_items.insert(row, count, QuotaItem()); 0110 endInsertRows(); 0111 0112 return true; 0113 } 0114 0115 bool QuotaListModel::removeRows(int row, int count, const QModelIndex &parent) 0116 { 0117 // only top-level items are valid 0118 if (parent.isValid() || (row + count) >= m_items.size()) { 0119 return false; 0120 } 0121 0122 beginRemoveRows(QModelIndex(), row, row + count - 1); 0123 m_items.remove(row, count); 0124 endRemoveRows(); 0125 0126 return true; 0127 } 0128 0129 void QuotaListModel::clear() 0130 { 0131 beginResetModel(); 0132 m_items.clear(); 0133 endResetModel(); 0134 } 0135 0136 namespace 0137 { 0138 QStringList mountPoints(const QVector<QuotaItem> &items) 0139 { 0140 QStringList list; 0141 for (auto &item : items) { 0142 list.append(item.mountPoint()); 0143 } 0144 return list; 0145 } 0146 0147 int indexOfMountPoint(const QString &mountPoint, const QVector<QuotaItem> &items) 0148 { 0149 for (int i = 0; i < items.size(); ++i) { 0150 if (mountPoint == items[i].mountPoint()) { 0151 return i; 0152 } 0153 } 0154 return -1; 0155 } 0156 } 0157 0158 void QuotaListModel::updateItems(const QVector<QuotaItem> &items) 0159 { 0160 QStringList unusedMountPoints = mountPoints(m_items); 0161 0162 // merge existing and new mount points 0163 for (auto &item : items) { 0164 // remove still used item from unused list 0165 unusedMountPoints.removeOne(item.mountPoint()); 0166 0167 // insert or modify m_items 0168 int row = indexOfMountPoint(item.mountPoint(), m_items); 0169 if (row < 0) { 0170 // new item: append on end 0171 row = m_items.size(); 0172 insertRow(row); 0173 } 0174 setData(createIndex(row, 0), QVariant::fromValue(item)); 0175 } 0176 0177 // remove mount points, that do not exist anymore 0178 for (const auto &mountPoint : unusedMountPoints) { 0179 const int row = indexOfMountPoint(mountPoint, m_items); 0180 Q_ASSERT(row >= 0); 0181 removeRow(row); 0182 } 0183 }