File indexing completed on 2024-04-21 05:01:41
0001 /* 0002 This class provides the interface for Plasma and QtQuick 0003 0004 SPDX-FileCopyrightText: 2013-2023 Alexander Reinholdt <alexander.reinholdt@kdemail.net> 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 // application specific includes 0009 #include "smb4kdeclarative.h" 0010 #include "core/smb4kbasicnetworkitem.h" 0011 #include "core/smb4kbookmark.h" 0012 #include "core/smb4kbookmarkhandler.h" 0013 #include "core/smb4kclient.h" 0014 #include "core/smb4khost.h" 0015 #include "core/smb4kmounter.h" 0016 #include "core/smb4kprofilemanager.h" 0017 #include "core/smb4kshare.h" 0018 #include "core/smb4ksynchronizer.h" 0019 #include "core/smb4kworkgroup.h" 0020 #include "smb4k/smb4kcustomsettingseditor.h" 0021 #include "smb4k/smb4khomesuserdialog.h" 0022 #include "smb4k/smb4kpassworddialog.h" 0023 #include "smb4k/smb4kpreviewdialog.h" 0024 #include "smb4k/smb4kprintdialog.h" 0025 #include "smb4k/smb4ksynchronizationdialog.h" 0026 #include "smb4kbookmarkdialog.h" 0027 #include "smb4kbookmarkeditor.h" 0028 #include "smb4kbookmarkobject.h" 0029 #include "smb4kmountdialog.h" 0030 #include "smb4knetworkobject.h" 0031 #include "smb4kprofileobject.h" 0032 0033 // 0034 // Qt includes 0035 #include <QDebug> 0036 #include <QPointer> 0037 0038 // KDE includes 0039 #include <KConfigDialog> 0040 #include <KMessageBox> 0041 #include <KPluginFactory> 0042 #include <KPluginMetaData> 0043 0044 class Smb4KDeclarativePrivate 0045 { 0046 public: 0047 QList<Smb4KNetworkObject *> workgroupObjects; 0048 QList<Smb4KNetworkObject *> hostObjects; 0049 QList<Smb4KNetworkObject *> shareObjects; 0050 QList<Smb4KNetworkObject *> mountedObjects; 0051 QList<Smb4KBookmarkObject *> bookmarkObjects; 0052 QList<Smb4KBookmarkObject *> bookmarkCategoryObjects; 0053 QList<Smb4KProfileObject *> profileObjects; 0054 QList<NetworkItemPtr> requestQueue; 0055 QPointer<Smb4KPasswordDialog> passwordDialog; 0056 int timerId; 0057 }; 0058 0059 Smb4KDeclarative::Smb4KDeclarative(QObject *parent) 0060 : QObject(parent) 0061 , d(new Smb4KDeclarativePrivate) 0062 { 0063 d->passwordDialog = new Smb4KPasswordDialog(); 0064 d->timerId = 0; 0065 0066 connect(Smb4KClient::self(), &Smb4KClient::workgroups, this, &Smb4KDeclarative::slotWorkgroupsListChanged); 0067 connect(Smb4KClient::self(), &Smb4KClient::hosts, this, &Smb4KDeclarative::slotHostsListChanged); 0068 connect(Smb4KClient::self(), &Smb4KClient::shares, this, &Smb4KDeclarative::slotSharesListChanged); 0069 connect(Smb4KClient::self(), &Smb4KClient::aboutToStart, this, &Smb4KDeclarative::busy); 0070 connect(Smb4KClient::self(), &Smb4KClient::finished, this, &Smb4KDeclarative::idle); 0071 connect(Smb4KClient::self(), &Smb4KClient::requestCredentials, this, &Smb4KDeclarative::slotCredentialsRequested); 0072 0073 connect(Smb4KMounter::self(), &Smb4KMounter::mountedSharesListChanged, this, &Smb4KDeclarative::slotMountedSharesListChanged); 0074 connect(Smb4KMounter::self(), &Smb4KMounter::aboutToStart, this, &Smb4KDeclarative::busy); 0075 connect(Smb4KMounter::self(), &Smb4KMounter::finished, this, &Smb4KDeclarative::idle); 0076 connect(Smb4KMounter::self(), &Smb4KMounter::requestCredentials, this, &Smb4KDeclarative::slotCredentialsRequested); 0077 0078 connect(Smb4KBookmarkHandler::self(), &Smb4KBookmarkHandler::updated, this, &Smb4KDeclarative::slotBookmarksListChanged); 0079 0080 connect(Smb4KProfileManager::self(), &Smb4KProfileManager::profilesListChanged, this, &Smb4KDeclarative::slotProfilesListChanged); 0081 connect(Smb4KProfileManager::self(), &Smb4KProfileManager::activeProfileChanged, this, &Smb4KDeclarative::slotActiveProfileChanged); 0082 connect(Smb4KProfileManager::self(), &Smb4KProfileManager::profileUsageChanged, this, &Smb4KDeclarative::slotProfileUsageChanged); 0083 0084 // 0085 // Do the initial loading of items 0086 // 0087 slotBookmarksListChanged(); 0088 slotProfilesListChanged(Smb4KProfileManager::self()->profilesList()); 0089 slotActiveProfileChanged(Smb4KProfileManager::self()->activeProfile()); 0090 slotProfileUsageChanged(Smb4KProfileManager::self()->useProfiles()); 0091 } 0092 0093 Smb4KDeclarative::~Smb4KDeclarative() 0094 { 0095 qDeleteAll(d->workgroupObjects); 0096 d->workgroupObjects.clear(); 0097 0098 qDeleteAll(d->hostObjects); 0099 d->hostObjects.clear(); 0100 0101 qDeleteAll(d->shareObjects); 0102 d->shareObjects.clear(); 0103 0104 qDeleteAll(d->mountedObjects); 0105 d->mountedObjects.clear(); 0106 0107 qDeleteAll(d->bookmarkObjects); 0108 d->bookmarkObjects.clear(); 0109 0110 qDeleteAll(d->bookmarkCategoryObjects); 0111 d->bookmarkCategoryObjects.clear(); 0112 0113 qDeleteAll(d->profileObjects); 0114 d->profileObjects.clear(); 0115 } 0116 0117 QQmlListProperty<Smb4KNetworkObject> Smb4KDeclarative::workgroups() 0118 { 0119 return QQmlListProperty<Smb4KNetworkObject>(this, &d->workgroupObjects); 0120 } 0121 0122 QQmlListProperty<Smb4KNetworkObject> Smb4KDeclarative::hosts() 0123 { 0124 return QQmlListProperty<Smb4KNetworkObject>(this, &d->hostObjects); 0125 } 0126 0127 QQmlListProperty<Smb4KNetworkObject> Smb4KDeclarative::shares() 0128 { 0129 return QQmlListProperty<Smb4KNetworkObject>(this, &d->shareObjects); 0130 } 0131 0132 QQmlListProperty<Smb4KNetworkObject> Smb4KDeclarative::mountedShares() 0133 { 0134 return QQmlListProperty<Smb4KNetworkObject>(this, &d->mountedObjects); 0135 } 0136 0137 QQmlListProperty<Smb4KBookmarkObject> Smb4KDeclarative::bookmarks() 0138 { 0139 return QQmlListProperty<Smb4KBookmarkObject>(this, &d->bookmarkObjects); 0140 } 0141 0142 QQmlListProperty<Smb4KBookmarkObject> Smb4KDeclarative::bookmarkCategories() 0143 { 0144 return QQmlListProperty<Smb4KBookmarkObject>(this, &d->bookmarkCategoryObjects); 0145 } 0146 0147 QQmlListProperty<Smb4KProfileObject> Smb4KDeclarative::profiles() 0148 { 0149 return QQmlListProperty<Smb4KProfileObject>(this, &d->profileObjects); 0150 } 0151 0152 void Smb4KDeclarative::lookup(Smb4KNetworkObject *object) 0153 { 0154 if (object) { 0155 switch (object->type()) { 0156 case Smb4KNetworkObject::Network: { 0157 Smb4KClient::self()->lookupDomains(); 0158 break; 0159 } 0160 case Smb4KNetworkObject::Workgroup: { 0161 // Check if the workgroup is known. 0162 WorkgroupPtr workgroup = Smb4KGlobal::findWorkgroup(object->url().host().toUpper()); 0163 0164 if (workgroup) { 0165 Smb4KClient::self()->lookupDomainMembers(workgroup); 0166 } 0167 0168 break; 0169 } 0170 case Smb4KNetworkObject::Host: { 0171 // Check if the host is known. 0172 HostPtr host = Smb4KGlobal::findHost(object->url().host().toUpper()); 0173 0174 if (host) { 0175 Smb4KClient::self()->lookupShares(host); 0176 } 0177 0178 break; 0179 } 0180 case Smb4KNetworkObject::Share: { 0181 break; 0182 } 0183 default: { 0184 // Shares are ignored 0185 break; 0186 } 0187 } 0188 } else { 0189 // If the object is 0, scan the whole network. 0190 Smb4KClient::self()->lookupDomains(); 0191 } 0192 } 0193 0194 Smb4KNetworkObject *Smb4KDeclarative::findNetworkItem(const QUrl &url, int type) 0195 { 0196 Smb4KNetworkObject *object = nullptr; 0197 0198 if (url.isValid()) { 0199 switch (type) { 0200 case Smb4KNetworkObject::Workgroup: { 0201 for (Smb4KNetworkObject *obj : qAsConst(d->workgroupObjects)) { 0202 if (url == obj->url()) { 0203 object = obj; 0204 break; 0205 } else { 0206 continue; 0207 } 0208 } 0209 break; 0210 } 0211 case Smb4KNetworkObject::Host: { 0212 for (Smb4KNetworkObject *obj : qAsConst(d->hostObjects)) { 0213 if (url == obj->url()) { 0214 object = obj; 0215 break; 0216 } else { 0217 continue; 0218 } 0219 } 0220 break; 0221 } 0222 case Smb4KNetworkObject::Share: { 0223 for (Smb4KNetworkObject *obj : qAsConst(d->shareObjects)) { 0224 if (url == obj->url()) { 0225 object = obj; 0226 break; 0227 } else { 0228 continue; 0229 } 0230 } 0231 break; 0232 } 0233 default: { 0234 break; 0235 } 0236 } 0237 } 0238 0239 return object; 0240 } 0241 0242 void Smb4KDeclarative::openMountDialog() 0243 { 0244 QPointer<Smb4KMountDialog> mountDialog = new Smb4KMountDialog(); 0245 mountDialog->open(); 0246 } 0247 0248 void Smb4KDeclarative::mountShare(Smb4KNetworkObject *object) 0249 { 0250 if (object && object->type() == Smb4KNetworkObject::Share) { 0251 SharePtr share = Smb4KGlobal::findShare(object->url(), object->workgroupName()); 0252 0253 if (share) { 0254 if (share->isHomesShare()) { 0255 QPointer<Smb4KHomesUserDialog> homesUserDialog = new Smb4KHomesUserDialog(); 0256 bool proceed = false; 0257 0258 if (homesUserDialog->setShare(share)) { 0259 // We want to get a return value here, so we use exec() 0260 if (homesUserDialog->exec() == QDialog::Accepted) { 0261 proceed = true; 0262 } 0263 } 0264 0265 delete homesUserDialog; 0266 0267 if (!proceed) { 0268 return; 0269 } 0270 } 0271 0272 Smb4KMounter::self()->mountShare(share); 0273 } 0274 } 0275 } 0276 0277 void Smb4KDeclarative::mountBookmark(Smb4KBookmarkObject *object) 0278 { 0279 if (object) { 0280 BookmarkPtr bookmark = Smb4KBookmarkHandler::self()->findBookmarkByUrl(object->url()); 0281 0282 SharePtr share = SharePtr(new Smb4KShare()); 0283 share->setUrl(object->url()); 0284 share->setWorkgroupName(object->workgroupName()); 0285 share->setHostIpAddress(object->hostIpAddress()); 0286 0287 Smb4KMounter::self()->mountShare(share); 0288 0289 share.clear(); 0290 } 0291 } 0292 0293 void Smb4KDeclarative::unmount(Smb4KNetworkObject *object) 0294 { 0295 if (object && object->type()) { 0296 if (object->mountpoint().isValid()) { 0297 SharePtr share = Smb4KGlobal::findShareByPath(object->mountpoint().path()); 0298 0299 if (share) { 0300 Smb4KMounter::self()->unmountShare(share); 0301 } 0302 } 0303 } 0304 } 0305 0306 void Smb4KDeclarative::unmountAll() 0307 { 0308 Smb4KMounter::self()->unmountAllShares(false); 0309 } 0310 0311 bool Smb4KDeclarative::isShareMounted(const QUrl &url) 0312 { 0313 QList<SharePtr> shares = Smb4KGlobal::findShareByUrl(url); 0314 0315 for (const SharePtr &share : qAsConst(shares)) { 0316 if (!share->isForeign()) { 0317 return true; 0318 } 0319 } 0320 0321 return false; 0322 } 0323 0324 void Smb4KDeclarative::print(Smb4KNetworkObject *object) 0325 { 0326 if (object && object->type() == Smb4KNetworkObject::Share) { 0327 SharePtr printer = Smb4KGlobal::findShare(object->url(), object->workgroupName()); 0328 0329 if (printer) { 0330 QPointer<Smb4KPrintDialog> printDialog = new Smb4KPrintDialog(); 0331 0332 if (printDialog->setPrinterShare(printer)) { 0333 printDialog->open(); 0334 } else { 0335 delete printDialog; 0336 } 0337 } 0338 } 0339 } 0340 0341 void Smb4KDeclarative::addBookmark(Smb4KNetworkObject *object) 0342 { 0343 if (object) { 0344 QList<SharePtr> shares; 0345 0346 SharePtr share = Smb4KGlobal::findShare(object->url(), object->workgroupName()); 0347 0348 if (share) { 0349 shares << share; 0350 } else { 0351 QList<SharePtr> mountedShares = Smb4KGlobal::findShareByUrl(object->url()); 0352 0353 if (!mountedShares.isEmpty()) { 0354 shares << mountedShares.first(); 0355 } 0356 } 0357 0358 if (!shares.isEmpty()) { 0359 QPointer<Smb4KBookmarkDialog> bookmarkDialog = new Smb4KBookmarkDialog(); 0360 0361 if (bookmarkDialog->setShares(shares)) { 0362 bookmarkDialog->open(); 0363 } else { 0364 delete bookmarkDialog; 0365 } 0366 } 0367 } 0368 } 0369 0370 void Smb4KDeclarative::removeBookmark(Smb4KBookmarkObject *object) 0371 { 0372 if (object) { 0373 // 0374 // Find the bookmark in the list and remove it. 0375 // 0376 BookmarkPtr bookmark = Smb4KBookmarkHandler::self()->findBookmarkByUrl(object->url()); 0377 0378 if (bookmark) { 0379 Smb4KBookmarkHandler::self()->removeBookmark(bookmark); 0380 } 0381 } 0382 } 0383 0384 void Smb4KDeclarative::editBookmarks() 0385 { 0386 QPointer<Smb4KBookmarkEditor> bookmarkEditor = new Smb4KBookmarkEditor(); 0387 bookmarkEditor->open(); 0388 } 0389 0390 void Smb4KDeclarative::synchronize(Smb4KNetworkObject *object) 0391 { 0392 if (object && object->type() == Smb4KNetworkObject::Share) { 0393 for (const SharePtr &share : Smb4KGlobal::mountedSharesList()) { 0394 if (share->url() == object->url()) { 0395 QPointer<Smb4KSynchronizationDialog> synchronizationDialog = new Smb4KSynchronizationDialog(); 0396 if (synchronizationDialog->setShare(share)) { 0397 synchronizationDialog->open(); 0398 } else { 0399 delete synchronizationDialog; 0400 } 0401 } 0402 } 0403 } 0404 } 0405 0406 void Smb4KDeclarative::openCustomOptionsDialog(Smb4KNetworkObject *object) 0407 { 0408 if (object) { 0409 NetworkItemPtr networkItem; 0410 0411 switch (object->type()) { 0412 case Smb4KNetworkObject::Host: { 0413 for (const HostPtr &host : Smb4KGlobal::hostsList()) { 0414 if (host->url() == object->url()) { 0415 networkItem = host; 0416 break; 0417 } 0418 } 0419 break; 0420 } 0421 case Smb4KNetworkObject::Share: { 0422 for (const SharePtr &share : Smb4KGlobal::sharesList()) { 0423 if (share->url() == object->url()) { 0424 networkItem = share; 0425 break; 0426 } 0427 } 0428 break; 0429 } 0430 default: { 0431 break; 0432 } 0433 } 0434 0435 if (!networkItem.isNull()) { 0436 QPointer<Smb4KCustomSettingsEditor> customSettingsEditor = new Smb4KCustomSettingsEditor(); 0437 if (customSettingsEditor->setNetworkItem(networkItem)) { 0438 customSettingsEditor->open(); 0439 } else { 0440 delete customSettingsEditor; 0441 } 0442 } 0443 } 0444 } 0445 0446 void Smb4KDeclarative::startClient() 0447 { 0448 Smb4KClient::self()->start(); 0449 } 0450 0451 void Smb4KDeclarative::abortClient() 0452 { 0453 Smb4KClient::self()->abort(); 0454 } 0455 0456 void Smb4KDeclarative::startMounter() 0457 { 0458 Smb4KMounter::self()->start(); 0459 } 0460 0461 void Smb4KDeclarative::abortMounter() 0462 { 0463 Smb4KMounter::self()->abort(); 0464 } 0465 0466 QString Smb4KDeclarative::activeProfile() const 0467 { 0468 QString activeProfile; 0469 0470 for (Smb4KProfileObject *profile : qAsConst(d->profileObjects)) { 0471 if (profile->isActiveProfile()) { 0472 activeProfile = profile->profileName(); 0473 break; 0474 } else { 0475 continue; 0476 } 0477 } 0478 0479 return activeProfile; 0480 } 0481 0482 void Smb4KDeclarative::setActiveProfile(const QString &profile) 0483 { 0484 Smb4KProfileManager::self()->setActiveProfile(profile); 0485 } 0486 0487 bool Smb4KDeclarative::profileUsage() const 0488 { 0489 return Smb4KProfileManager::self()->useProfiles(); 0490 } 0491 0492 void Smb4KDeclarative::preview(Smb4KNetworkObject *object) 0493 { 0494 if (object->type() == Smb4KNetworkObject::Share) { 0495 SharePtr share = Smb4KGlobal::findShare(object->url(), object->workgroupName()); 0496 0497 if (share) { 0498 QPointer<Smb4KPreviewDialog> previewDialog = new Smb4KPreviewDialog(); 0499 0500 if (previewDialog->setShare(share)) { 0501 previewDialog->open(); 0502 } else { 0503 delete previewDialog; 0504 } 0505 } 0506 } 0507 } 0508 0509 void Smb4KDeclarative::openConfigurationDialog() 0510 { 0511 // 0512 // Check if the configuration dialog exists and try to show it. 0513 // 0514 if (KConfigDialog::exists(QStringLiteral("Smb4KConfigDialog"))) { 0515 KConfigDialog::showDialog(QStringLiteral("Smb4KConfigDialog")); 0516 return; 0517 } 0518 0519 // 0520 // If the dialog does not exist, load and show it: 0521 // 0522 KPluginMetaData metaData(QStringLiteral("smb4kconfigdialog")); 0523 KPluginFactory::Result<KPluginFactory> result = KPluginFactory::loadFactory(metaData); 0524 0525 if (result.errorReason == KPluginFactory::NO_PLUGIN_ERROR) { 0526 QPointer<KConfigDialog> dlg = result.plugin->create<KConfigDialog>(); 0527 0528 if (dlg) { 0529 dlg->setObjectName(QStringLiteral("Smb4KConfigDialog")); 0530 dlg->show(); 0531 } 0532 } 0533 } 0534 0535 void Smb4KDeclarative::timerEvent(QTimerEvent *event) 0536 { 0537 Q_UNUSED(event); 0538 0539 if (!d->requestQueue.isEmpty()) { 0540 if (!d->passwordDialog->isVisible()) { 0541 NetworkItemPtr networkItem = d->requestQueue.takeFirst(); 0542 0543 if (networkItem && d->passwordDialog->setNetworkItem(networkItem)) { 0544 d->passwordDialog->show(); 0545 } 0546 } 0547 } else { 0548 killTimer(d->timerId); 0549 d->timerId = 0; 0550 } 0551 } 0552 0553 void Smb4KDeclarative::slotWorkgroupsListChanged() 0554 { 0555 qDeleteAll(d->workgroupObjects); 0556 d->workgroupObjects.clear(); 0557 0558 for (const WorkgroupPtr &workgroup : Smb4KGlobal::workgroupsList()) { 0559 d->workgroupObjects << new Smb4KNetworkObject(workgroup.data()); 0560 } 0561 0562 Q_EMIT workgroupsListChanged(); 0563 } 0564 0565 void Smb4KDeclarative::slotHostsListChanged() 0566 { 0567 qDeleteAll(d->hostObjects); 0568 d->hostObjects.clear(); 0569 0570 for (const HostPtr &host : Smb4KGlobal::hostsList()) { 0571 d->hostObjects << new Smb4KNetworkObject(host.data()); 0572 } 0573 0574 Q_EMIT hostsListChanged(); 0575 } 0576 0577 void Smb4KDeclarative::slotSharesListChanged() 0578 { 0579 qDeleteAll(d->shareObjects); 0580 d->shareObjects.clear(); 0581 0582 for (const SharePtr &share : Smb4KGlobal::sharesList()) { 0583 d->shareObjects << new Smb4KNetworkObject(share.data()); 0584 } 0585 0586 Q_EMIT sharesListChanged(); 0587 } 0588 0589 void Smb4KDeclarative::slotMountedSharesListChanged() 0590 { 0591 qDeleteAll(d->mountedObjects); 0592 d->mountedObjects.clear(); 0593 0594 for (const SharePtr &mountedShare : Smb4KGlobal::mountedSharesList()) { 0595 d->mountedObjects << new Smb4KNetworkObject(mountedShare.data()); 0596 } 0597 0598 Q_EMIT mountedSharesListChanged(); 0599 } 0600 0601 void Smb4KDeclarative::slotBookmarksListChanged() 0602 { 0603 qDeleteAll(d->bookmarkObjects); 0604 d->bookmarkObjects.clear(); 0605 0606 qDeleteAll(d->bookmarkCategoryObjects); 0607 d->bookmarkCategoryObjects.clear(); 0608 0609 QList<BookmarkPtr> bookmarksList = Smb4KBookmarkHandler::self()->bookmarkList(); 0610 QStringList categoriesList = Smb4KBookmarkHandler::self()->categoryList(); 0611 0612 for (const BookmarkPtr &bookmark : qAsConst(bookmarksList)) { 0613 d->bookmarkObjects << new Smb4KBookmarkObject(bookmark.data()); 0614 } 0615 0616 for (const QString &category : qAsConst(categoriesList)) { 0617 d->bookmarkCategoryObjects << new Smb4KBookmarkObject(category); 0618 } 0619 0620 Q_EMIT bookmarksListChanged(); 0621 } 0622 0623 void Smb4KDeclarative::slotProfilesListChanged(const QStringList &profiles) 0624 { 0625 qDeleteAll(d->profileObjects); 0626 d->profileObjects.clear(); 0627 0628 for (const QString &p : profiles) { 0629 Smb4KProfileObject *profile = new Smb4KProfileObject(); 0630 profile->setProfileName(p); 0631 0632 if (QString::compare(p, Smb4KProfileManager::self()->activeProfile()) == 0) { 0633 profile->setActiveProfile(true); 0634 } else { 0635 profile->setActiveProfile(false); 0636 } 0637 0638 d->profileObjects << profile; 0639 } 0640 0641 Q_EMIT profilesListChanged(); 0642 } 0643 0644 void Smb4KDeclarative::slotActiveProfileChanged(const QString &activeProfile) 0645 { 0646 for (Smb4KProfileObject *profile : qAsConst(d->profileObjects)) { 0647 if (QString::compare(profile->profileName(), activeProfile) == 0) { 0648 profile->setActiveProfile(true); 0649 } else { 0650 profile->setActiveProfile(false); 0651 } 0652 } 0653 0654 Q_EMIT activeProfileChanged(); 0655 } 0656 0657 void Smb4KDeclarative::slotProfileUsageChanged(bool /*use*/) 0658 { 0659 Q_EMIT profileUsageChanged(); 0660 } 0661 0662 void Smb4KDeclarative::slotCredentialsRequested(const NetworkItemPtr &networkItem) 0663 { 0664 d->requestQueue.append(networkItem); 0665 0666 if (d->timerId == 0) { 0667 d->timerId = startTimer(500); 0668 } 0669 }