File indexing completed on 2024-05-12 16:59:53
0001 /* 0002 SPDX-FileCopyrightText: 2020 Harald Sitter <sitter@kde.org> 0003 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 */ 0005 0006 #include "smbmountmodel.h" 0007 0008 #include <QDebug> 0009 #include <QIcon> 0010 #include <QMetaEnum> 0011 #include <Solid/DeviceInterface> 0012 #include <Solid/DeviceNotifier> 0013 #include <Solid/NetworkShare> 0014 #include <Solid/StorageAccess> 0015 0016 SmbMountModel::SmbMountModel(QObject *parent) 0017 : QAbstractListModel(parent) 0018 { 0019 connect(Solid::DeviceNotifier::instance(), &Solid::DeviceNotifier::deviceAdded, this, &SmbMountModel::addDevice); 0020 connect(Solid::DeviceNotifier::instance(), &Solid::DeviceNotifier::deviceRemoved, this, &SmbMountModel::removeDevice); 0021 metaObject()->invokeMethod(this, &SmbMountModel::reloadData); 0022 } 0023 0024 SmbMountModel::~SmbMountModel() = default; 0025 0026 int SmbMountModel::rowCount(const QModelIndex &parent) const 0027 { 0028 Q_UNUSED(parent) 0029 return m_devices.size(); 0030 } 0031 0032 QVariant SmbMountModel::data(const QModelIndex &index, int intRole) const 0033 { 0034 if (!index.isValid()) { 0035 return {}; 0036 } 0037 0038 Q_ASSERT(index.row() < m_devices.count()); 0039 0040 static QMetaEnum roleEnum = QMetaEnum::fromType<Role>(); 0041 if (roleEnum.valueToKey(intRole) == nullptr) { 0042 return {}; 0043 } 0044 const auto role = static_cast<Role>(intRole); 0045 0046 const Solid::Device &device = m_devices.at(index.row()); 0047 switch (role) { 0048 case Role::Share: 0049 return device.as<Solid::NetworkShare>()->url(); 0050 case Role::Path: 0051 return device.as<Solid::StorageAccess>()->filePath(); 0052 case Role::Accessible: 0053 return device.as<Solid::StorageAccess>()->isAccessible(); 0054 } 0055 0056 return {}; 0057 } 0058 0059 void SmbMountModel::addDevice(const QString &udi) 0060 { 0061 auto it = deviceForUdi(udi); 0062 if (it != m_devices.constEnd()) { 0063 return; // already in the list 0064 } 0065 0066 Solid::Device device(udi); 0067 if (!device.is<Solid::NetworkShare>()) { 0068 return; 0069 } 0070 0071 beginInsertRows(QModelIndex(), m_devices.count(), m_devices.count()); 0072 m_devices.append(device); 0073 endInsertRows(); 0074 } 0075 0076 void SmbMountModel::removeDevice(const QString &udi) 0077 { 0078 auto it = deviceForUdi(udi); 0079 if (it == m_devices.constEnd()) { 0080 return; // untracked udi 0081 } 0082 0083 const int index = static_cast<int>(std::distance(m_devices.constBegin(), it)); 0084 beginRemoveRows(QModelIndex(), index, index); 0085 m_devices.removeAt(index); 0086 endRemoveRows(); 0087 } 0088 0089 void SmbMountModel::reloadData() 0090 { 0091 beginResetModel(); 0092 m_devices.clear(); 0093 const auto devices = Solid::Device::listFromType(Solid::DeviceInterface::NetworkShare); 0094 for (auto it = devices.begin(); it != devices.end(); ++it) { 0095 if (!it->is<Solid::NetworkShare>()) { 0096 // Workaround in case listFromType still gives incorrect types. 0097 // https://bugs.kde.org/show_bug.cgi?id=419220 0098 continue; 0099 } 0100 switch (it->as<Solid::NetworkShare>()->type()) { 0101 case Solid::NetworkShare::Cifs: 0102 m_devices.append(*it); 0103 continue; 0104 case Solid::NetworkShare::Nfs: 0105 case Solid::NetworkShare::Unknown: 0106 continue; 0107 } 0108 } 0109 endResetModel(); 0110 } 0111 0112 bool SmbMountModel::hasChildren(const QModelIndex &parent) const 0113 { 0114 return !parent.isValid() ? false : (rowCount(parent) > 0); 0115 } 0116 0117 QHash<int, QByteArray> SmbMountModel::roleNames() const 0118 { 0119 static QHash<int, QByteArray> roles; 0120 if (!roles.isEmpty()) { 0121 return roles; 0122 } 0123 0124 const QMetaEnum roleEnum = QMetaEnum::fromType<Role>(); 0125 for (int i = 0; i < roleEnum.keyCount(); ++i) { 0126 const int value = roleEnum.value(i); 0127 Q_ASSERT(value != -1); 0128 roles[static_cast<int>(value)] = QByteArray("ROLE_") + roleEnum.valueToKey(value); 0129 } 0130 return roles; 0131 }