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 }