File indexing completed on 2024-05-19 05:29:58
0001 /* 0002 SPDX-FileCopyrightText: 2020-2022 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 "ksambasharemodel.h" 0007 0008 #include <QApplication> // for kpropertiesdialog parenting 0009 #include <QDBusPendingCallWatcher> 0010 #include <QMetaEnum> 0011 0012 #include <KPropertiesDialog> 0013 #include <KSambaShare> 0014 0015 #include "org.freedesktop.Avahi.Server.h" 0016 0017 KSambaShareModel::KSambaShareModel(QObject *parent) 0018 : QAbstractListModel(parent) 0019 { 0020 connect(KSambaShare::instance(), &KSambaShare::changed, this, &KSambaShareModel::reloadData); 0021 metaObject()->invokeMethod(this, &KSambaShareModel::reloadData); 0022 } 0023 0024 KSambaShareModel::~KSambaShareModel() = default; 0025 0026 int KSambaShareModel::rowCount(const QModelIndex &parent) const 0027 { 0028 Q_UNUSED(parent) 0029 return m_list.size(); 0030 } 0031 0032 QVariant KSambaShareModel::data(const QModelIndex &index, int intRole) const 0033 { 0034 if (!index.isValid()) { 0035 return QVariant(); 0036 } 0037 0038 Q_ASSERT(index.row() < m_list.length()); 0039 0040 static QMetaEnum roleEnum = QMetaEnum::fromType<Role>(); 0041 if (roleEnum.valueToKey(intRole) == nullptr) { 0042 return QVariant(); 0043 } 0044 const auto role = static_cast<Role>(intRole); 0045 0046 const KSambaShareData &share = m_list.at(index.row()); 0047 switch (role) { 0048 case Role::Name: 0049 return share.name(); 0050 case Role::Path: 0051 return share.path(); 0052 case Role::Comment: 0053 return share.comment(); 0054 case Role::ShareUrl: { 0055 if (m_fqdn.isEmpty()) { 0056 return QVariant(); 0057 } 0058 QUrl url; 0059 url.setScheme(QStringLiteral("smb")); 0060 url.setHost(m_fqdn); 0061 url.setPath(QStringLiteral("/") + share.name()); 0062 return url; 0063 } 0064 } 0065 0066 return QVariant(); 0067 } 0068 0069 Q_INVOKABLE void KSambaShareModel::showPropertiesDialog(int index) 0070 { 0071 auto dialog = new KPropertiesDialog(QUrl::fromUserInput(m_list.at(index).path()), QApplication::activeWindow()); 0072 dialog->setFileNameReadOnly(true); 0073 dialog->showFileSharingPage(); 0074 dialog->show(); 0075 } 0076 0077 void KSambaShareModel::reloadData() 0078 { 0079 beginResetModel(); 0080 m_list.clear(); 0081 const auto samba = KSambaShare::instance(); 0082 const QStringList sharedDirectories = samba->sharedDirectories(); 0083 for (const auto &path : sharedDirectories) { 0084 m_list += samba->getSharesByPath(path); 0085 } 0086 endResetModel(); 0087 0088 // Reload FQDN 0089 m_fqdn.clear(); 0090 auto avahi = new OrgFreedesktopAvahiServerInterface(QStringLiteral("org.freedesktop.Avahi"), QStringLiteral("/"), QDBusConnection::systemBus(), this); 0091 auto watcher = new QDBusPendingCallWatcher(avahi->GetHostNameFqdn(), this); 0092 connect(watcher, &QDBusPendingCallWatcher::finished, this, [this, avahi, watcher] { 0093 watcher->deleteLater(); 0094 avahi->deleteLater(); 0095 QDBusPendingReply<QString> reply = *watcher; 0096 if (reply.isError()) { 0097 // When Avahi isn't available there's not really a good way to resolve the FQDN. The user could drive 0098 // resolution through LLMNR or NetBios or some other ad-hoc system, neither provide us with an easy 0099 // way to get their configured FQDN. We are therefor opting to not render URLs in that scenario since 0100 // we can't get a name that will reliably work. 0101 m_fqdn.clear(); 0102 return; 0103 } 0104 m_fqdn = reply.argumentAt(0).toString(); 0105 Q_EMIT dataChanged(createIndex(0, 0), createIndex(m_list.count(), 0), {static_cast<int>(Role::ShareUrl)}); 0106 }); 0107 } 0108 0109 bool KSambaShareModel::hasChildren(const QModelIndex &parent) const 0110 { 0111 return !parent.isValid() ? false : (rowCount(parent) > 0); 0112 } 0113 0114 QHash<int, QByteArray> KSambaShareModel::roleNames() const 0115 { 0116 static QHash<int, QByteArray> roles; 0117 if (!roles.isEmpty()) { 0118 return roles; 0119 } 0120 0121 const QMetaEnum roleEnum = QMetaEnum::fromType<Role>(); 0122 for (int i = 0; i < roleEnum.keyCount(); ++i) { 0123 const int value = roleEnum.value(i); 0124 Q_ASSERT(value != -1); 0125 roles[static_cast<int>(value)] = QByteArray("ROLE_") + roleEnum.valueToKey(value); 0126 } 0127 return roles; 0128 } 0129 0130 #include "moc_ksambasharemodel.cpp"