File indexing completed on 2023-12-03 05:04:26
0001 /* 0002 The network neighborhood browser dock widget 0003 0004 SPDX-FileCopyrightText: 2018-2023 Alexander Reinholdt <alexander.reinholdt@kdemail.net> 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 // application specific includes 0009 #include "smb4knetworkbrowserdockwidget.h" 0010 #include "core/smb4kclient.h" 0011 #include "core/smb4khost.h" 0012 #include "core/smb4kmounter.h" 0013 #include "core/smb4ksettings.h" 0014 #include "core/smb4kshare.h" 0015 #include "core/smb4kwalletmanager.h" 0016 #include "core/smb4kworkgroup.h" 0017 #include "smb4kbookmarkdialog.h" 0018 #include "smb4kcustomsettingseditor.h" 0019 #include "smb4kmountdialog.h" 0020 #include "smb4knetworkbrowseritem.h" 0021 #include "smb4kpreviewdialog.h" 0022 #include "smb4kprintdialog.h" 0023 #include "smb4ktooltip.h" 0024 0025 // Qt includes 0026 #include <QApplication> 0027 #include <QHeaderView> 0028 #include <QMenu> 0029 #include <QPointer> 0030 #include <QTreeWidgetItemIterator> 0031 #include <QVBoxLayout> 0032 0033 // KDE includes 0034 #include <KDualAction> 0035 #include <KGuiItem> 0036 #include <KIconLoader> 0037 #include <KLocalizedString> 0038 0039 using namespace Smb4KGlobal; 0040 0041 Smb4KNetworkBrowserDockWidget::Smb4KNetworkBrowserDockWidget(const QString &title, QWidget *parent) 0042 : QDockWidget(title, parent) 0043 { 0044 // 0045 // The network browser widget 0046 // 0047 QWidget *mainWidget = new QWidget(this); 0048 QVBoxLayout *mainWidgetLayout = new QVBoxLayout(mainWidget); 0049 mainWidgetLayout->setContentsMargins(0, 0, 0, 0); 0050 0051 m_networkBrowser = new Smb4KNetworkBrowser(mainWidget); 0052 m_searchToolBar = new Smb4KNetworkSearchToolBar(mainWidget); 0053 m_searchToolBar->setVisible(false); 0054 0055 mainWidgetLayout->addWidget(m_networkBrowser); 0056 mainWidgetLayout->addWidget(m_searchToolBar); 0057 0058 setWidget(mainWidget); 0059 0060 // 0061 // The action collection 0062 // 0063 m_actionCollection = new KActionCollection(this); 0064 0065 // 0066 // The context menu 0067 // 0068 m_contextMenu = new KActionMenu(this); 0069 0070 // 0071 // Search underway? 0072 // 0073 m_searchRunning = false; 0074 0075 // 0076 // Set up the actions 0077 // 0078 setupActions(); 0079 0080 // 0081 // Load the settings 0082 // 0083 loadSettings(); 0084 0085 // 0086 // Connections 0087 // 0088 connect(m_networkBrowser, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotContextMenuRequested(QPoint))); 0089 connect(m_networkBrowser, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(slotItemActivated(QTreeWidgetItem *, int))); 0090 connect(m_networkBrowser, SIGNAL(itemSelectionChanged()), this, SLOT(slotItemSelectionChanged())); 0091 0092 connect(m_searchToolBar, SIGNAL(closeSearchBar()), this, SLOT(slotHideSearchToolBar())); 0093 connect(m_searchToolBar, SIGNAL(search(QString)), this, SLOT(slotPerformSearch(QString))); 0094 connect(m_searchToolBar, SIGNAL(abort()), this, SLOT(slotStopSearch())); 0095 connect(m_searchToolBar, SIGNAL(jumpToResult(QString)), this, SLOT(slotJumpToResult(QString))); 0096 connect(m_searchToolBar, SIGNAL(clearSearchResults()), this, SLOT(slotClearSearchResults())); 0097 0098 connect(Smb4KClient::self(), SIGNAL(aboutToStart(NetworkItemPtr, int)), this, SLOT(slotClientAboutToStart(NetworkItemPtr, int))); 0099 connect(Smb4KClient::self(), SIGNAL(finished(NetworkItemPtr, int)), this, SLOT(slotClientFinished(NetworkItemPtr, int))); 0100 connect(Smb4KClient::self(), SIGNAL(workgroups()), this, SLOT(slotWorkgroups())); 0101 connect(Smb4KClient::self(), SIGNAL(hosts(WorkgroupPtr)), this, SLOT(slotWorkgroupMembers(WorkgroupPtr))); 0102 connect(Smb4KClient::self(), SIGNAL(shares(HostPtr)), this, SLOT(slotShares(HostPtr))); 0103 connect(Smb4KClient::self(), SIGNAL(searchResults(QList<SharePtr>)), this, SLOT(slotSearchResults(QList<SharePtr>))); 0104 0105 connect(Smb4KMounter::self(), SIGNAL(mounted(SharePtr)), this, SLOT(slotShareMounted(SharePtr))); 0106 connect(Smb4KMounter::self(), SIGNAL(unmounted(SharePtr)), this, SLOT(slotShareUnmounted(SharePtr))); 0107 connect(Smb4KMounter::self(), SIGNAL(aboutToStart(int)), this, SLOT(slotMounterAboutToStart(int))); 0108 connect(Smb4KMounter::self(), SIGNAL(finished(int)), this, SLOT(slotMounterFinished(int))); 0109 } 0110 0111 Smb4KNetworkBrowserDockWidget::~Smb4KNetworkBrowserDockWidget() 0112 { 0113 } 0114 0115 void Smb4KNetworkBrowserDockWidget::setupActions() 0116 { 0117 // 0118 // Rescan and abort dual action 0119 // 0120 KDualAction *rescanAbortAction = new KDualAction(this); 0121 rescanAbortAction->setInactiveIcon(KDE::icon(QStringLiteral("view-refresh"))); 0122 rescanAbortAction->setInactiveText(i18n("Scan Netwo&rk")); 0123 rescanAbortAction->setActiveIcon(KDE::icon(QStringLiteral("process-stop"))); 0124 rescanAbortAction->setActiveText(i18n("&Abort")); 0125 rescanAbortAction->setAutoToggle(false); 0126 rescanAbortAction->setEnabled(true); 0127 0128 connect(rescanAbortAction, SIGNAL(triggered(bool)), this, SLOT(slotRescanAbortActionTriggered(bool))); 0129 0130 m_actionCollection->addAction(QStringLiteral("rescan_abort_action"), rescanAbortAction); 0131 m_actionCollection->setDefaultShortcut(rescanAbortAction, QKeySequence::Refresh); 0132 0133 // 0134 // Search action 0135 // 0136 QAction *searchAction = new QAction(KDE::icon(QStringLiteral("search")), i18n("&Search"), this); 0137 0138 connect(searchAction, SIGNAL(triggered(bool)), this, SLOT(slotShowSearchToolBar())); 0139 0140 m_actionCollection->addAction(QStringLiteral("search_action"), searchAction); 0141 m_actionCollection->setDefaultShortcut(searchAction, QKeySequence::Find); 0142 0143 // 0144 // Separator 0145 // 0146 QAction *separator1 = new QAction(this); 0147 separator1->setSeparator(true); 0148 0149 m_actionCollection->addAction(QStringLiteral("network_separator1"), separator1); 0150 0151 // 0152 // Bookmark action 0153 // 0154 QAction *bookmarkAction = new QAction(KDE::icon(QStringLiteral("bookmark-new")), i18n("Add &Bookmark"), this); 0155 bookmarkAction->setEnabled(false); 0156 0157 connect(bookmarkAction, SIGNAL(triggered(bool)), this, SLOT(slotAddBookmark(bool))); 0158 0159 m_actionCollection->addAction(QStringLiteral("bookmark_action"), bookmarkAction); 0160 m_actionCollection->setDefaultShortcut(bookmarkAction, QKeySequence(i18n("Ctrl+B"))); 0161 0162 // 0163 // Add custom options action 0164 // 0165 QAction *customAction = new QAction(KDE::icon(QStringLiteral("settings-configure")), i18n("Add &Custom Settings"), this); 0166 customAction->setEnabled(false); 0167 0168 connect(customAction, SIGNAL(triggered(bool)), this, SLOT(slotAddCustomSettings(bool))); 0169 0170 m_actionCollection->addAction(QStringLiteral("custom_action"), customAction); 0171 m_actionCollection->setDefaultShortcut(customAction, QKeySequence(i18n("Ctrl+C"))); 0172 0173 // 0174 // Mount dialog action 0175 // 0176 QAction *manualAction = 0177 new QAction(KDE::icon(QStringLiteral("view-form"), QStringList(QStringLiteral("emblem-mounted"))), i18n("&Open Mount Dialog"), this); 0178 manualAction->setEnabled(true); 0179 0180 connect(manualAction, SIGNAL(triggered(bool)), this, SLOT(slotMountManually(bool))); 0181 0182 m_actionCollection->addAction(QStringLiteral("mount_manually_action"), manualAction); 0183 m_actionCollection->setDefaultShortcut(manualAction, QKeySequence(i18n("Ctrl+O"))); 0184 0185 // 0186 // Separator 0187 // 0188 QAction *separator2 = new QAction(this); 0189 separator2->setSeparator(true); 0190 0191 m_actionCollection->addAction(QStringLiteral("network_separator2"), separator2); 0192 0193 // 0194 // Authentication action 0195 // 0196 QAction *authAction = new QAction(KDE::icon(QStringLiteral("dialog-password")), i18n("Au&thentication"), this); 0197 authAction->setEnabled(false); 0198 0199 connect(authAction, SIGNAL(triggered(bool)), this, SLOT(slotAuthentication(bool))); 0200 0201 m_actionCollection->addAction(QStringLiteral("authentication_action"), authAction); 0202 m_actionCollection->setDefaultShortcut(authAction, QKeySequence(i18n("Ctrl+T"))); 0203 0204 // 0205 // Preview action 0206 // 0207 QAction *previewAction = new QAction(KDE::icon(QStringLiteral("view-list-icons")), i18n("Pre&view"), this); 0208 previewAction->setEnabled(false); 0209 0210 connect(previewAction, SIGNAL(triggered(bool)), this, SLOT(slotPreview(bool))); 0211 0212 m_actionCollection->addAction(QStringLiteral("preview_action"), previewAction); 0213 m_actionCollection->setDefaultShortcut(previewAction, QKeySequence(i18n("Ctrl+V"))); 0214 0215 // 0216 // Print action 0217 // 0218 QAction *printAction = new QAction(KDE::icon(QStringLiteral("printer")), i18n("&Print File"), this); 0219 printAction->setEnabled(false); 0220 0221 connect(printAction, SIGNAL(triggered(bool)), this, SLOT(slotPrint(bool))); 0222 0223 m_actionCollection->addAction(QStringLiteral("print_action"), printAction); 0224 m_actionCollection->setDefaultShortcut(printAction, QKeySequence(i18n("Ctrl+P"))); 0225 0226 // 0227 // Mount/unmount action 0228 // 0229 KDualAction *mountAction = new KDualAction(this); 0230 KGuiItem mountItem(i18n("&Mount"), KDE::icon(QStringLiteral("media-mount"))); 0231 KGuiItem unmountItem(i18n("&Unmount"), KDE::icon(QStringLiteral("media-eject"))); 0232 mountAction->setActiveGuiItem(mountItem); 0233 mountAction->setInactiveGuiItem(unmountItem); 0234 mountAction->setActive(true); 0235 mountAction->setAutoToggle(false); 0236 mountAction->setEnabled(false); 0237 0238 connect(mountAction, SIGNAL(triggered(bool)), this, SLOT(slotMountActionTriggered(bool))); 0239 connect(mountAction, SIGNAL(activeChanged(bool)), this, SLOT(slotMountActionChanged(bool))); 0240 0241 m_actionCollection->addAction(QStringLiteral("mount_action"), mountAction); 0242 m_actionCollection->setDefaultShortcut(mountAction, QKeySequence(i18n("Ctrl+M"))); 0243 0244 // 0245 // Plug the actions into the context menu 0246 // 0247 QList<QAction *> actionsList = m_actionCollection->actions(); 0248 0249 for (QAction *action : qAsConst(actionsList)) { 0250 m_contextMenu->addAction(action); 0251 } 0252 } 0253 0254 void Smb4KNetworkBrowserDockWidget::loadSettings() 0255 { 0256 // 0257 // Load icon size 0258 // 0259 int iconSize = Smb4KSettings::networkBrowserIconSize(); 0260 m_networkBrowser->setIconSize(QSize(iconSize, iconSize)); 0261 0262 // 0263 // Show/hide columns 0264 // 0265 m_networkBrowser->setColumnHidden(Smb4KNetworkBrowser::IP, !Smb4KSettings::showIPAddress()); 0266 m_networkBrowser->setColumnHidden(Smb4KNetworkBrowser::Type, !Smb4KSettings::showType()); 0267 m_networkBrowser->setColumnHidden(Smb4KNetworkBrowser::Comment, !Smb4KSettings::showComment()); 0268 0269 KConfigGroup configGroup(Smb4KSettings::self()->config(), "NetworkBrowserPart"); 0270 0271 if (configGroup.exists()) { 0272 QMap<int, int> map; 0273 map.insert(configGroup.readEntry("ColumnPositionNetwork", (int)Smb4KNetworkBrowser::Network), Smb4KNetworkBrowser::Network); 0274 map.insert(configGroup.readEntry("ColumnPositionType", (int)Smb4KNetworkBrowser::Type), Smb4KNetworkBrowser::Type); 0275 map.insert(configGroup.readEntry("ColumnPositionIP", (int)Smb4KNetworkBrowser::IP), Smb4KNetworkBrowser::IP); 0276 map.insert(configGroup.readEntry("ColumnPositionComment", (int)Smb4KNetworkBrowser::Comment), Smb4KNetworkBrowser::Comment); 0277 0278 QMap<int, int>::const_iterator it = map.constBegin(); 0279 0280 while (it != map.constEnd()) { 0281 if (it.key() != m_networkBrowser->header()->visualIndex(it.value())) { 0282 m_networkBrowser->header()->moveSection(m_networkBrowser->header()->visualIndex(it.value()), it.key()); 0283 } 0284 0285 ++it; 0286 } 0287 } 0288 0289 KConfigGroup completionGroup(Smb4KSettings::self()->config(), "CompletionItems"); 0290 0291 if (completionGroup.exists()) { 0292 m_searchToolBar->setCompletionItems(completionGroup.readEntry("SearchItemCompletion", QStringList())); 0293 } 0294 0295 // 0296 // Does anything has to be changed with the marked shares? 0297 // 0298 for (const SharePtr &share : mountedSharesList()) { 0299 // We do not need to use slotShareUnmounted() here, too, 0300 // because slotShareMounted() will take care of everything 0301 // we need here. 0302 slotShareMounted(share); 0303 } 0304 0305 // 0306 // Adjust the actions, if needed 0307 // 0308 slotItemSelectionChanged(); 0309 } 0310 0311 void Smb4KNetworkBrowserDockWidget::saveSettings() 0312 { 0313 KConfigGroup configGroup(Smb4KSettings::self()->config(), "NetworkBrowserPart"); 0314 configGroup.writeEntry("ColumnPositionNetwork", m_networkBrowser->header()->visualIndex(Smb4KNetworkBrowser::Network)); 0315 configGroup.writeEntry("ColumnPositionType", m_networkBrowser->header()->visualIndex(Smb4KNetworkBrowser::Type)); 0316 configGroup.writeEntry("ColumnPositionIP", m_networkBrowser->header()->visualIndex(Smb4KNetworkBrowser::IP)); 0317 configGroup.writeEntry("ColumnPositionComment", m_networkBrowser->header()->visualIndex(Smb4KNetworkBrowser::Comment)); 0318 configGroup.sync(); 0319 0320 KConfigGroup completionGroup(Smb4KSettings::self()->config(), "CompletionItems"); 0321 completionGroup.writeEntry("SearchItemCompletion", m_searchToolBar->completionItems()); 0322 completionGroup.sync(); 0323 } 0324 0325 KActionCollection *Smb4KNetworkBrowserDockWidget::actionCollection() 0326 { 0327 return m_actionCollection; 0328 } 0329 0330 void Smb4KNetworkBrowserDockWidget::slotContextMenuRequested(const QPoint &pos) 0331 { 0332 m_contextMenu->menu()->popup(m_networkBrowser->viewport()->mapToGlobal(pos)); 0333 } 0334 0335 void Smb4KNetworkBrowserDockWidget::slotItemActivated(QTreeWidgetItem *item, int /*column*/) 0336 { 0337 // 0338 // Process the activated item 0339 // 0340 if (QApplication::keyboardModifiers() == Qt::NoModifier && m_networkBrowser->selectedItems().size() == 1) { 0341 Smb4KNetworkBrowserItem *browserItem = static_cast<Smb4KNetworkBrowserItem *>(item); 0342 0343 if (browserItem) { 0344 switch (browserItem->type()) { 0345 case Workgroup: { 0346 if (browserItem->isExpanded()) { 0347 Smb4KClient::self()->lookupDomainMembers(browserItem->workgroupItem()); 0348 } 0349 break; 0350 } 0351 case Host: { 0352 if (browserItem->isExpanded()) { 0353 Smb4KClient::self()->lookupShares(browserItem->hostItem()); 0354 } 0355 break; 0356 } 0357 case Share: { 0358 if (!browserItem->shareItem()->isPrinter()) { 0359 slotMountActionTriggered(false); // boolean is ignored 0360 } else { 0361 slotPrint(false); // boolean is ignored 0362 } 0363 break; 0364 } 0365 default: { 0366 break; 0367 } 0368 } 0369 } 0370 } 0371 } 0372 0373 void Smb4KNetworkBrowserDockWidget::slotItemSelectionChanged() 0374 { 0375 QList<QTreeWidgetItem *> selectedItems = m_networkBrowser->selectedItems(); 0376 0377 if (selectedItems.size() > 1) { 0378 // 0379 // In this case there are only shares selected, because all other items 0380 // are automatically deselected in extended selection mode. 0381 // 0382 // For deciding which function the mount action should have, we use 0383 // the number of unmounted shares. If that is identical with the items.size(), 0384 // it will mount the items, otherwise it will unmount them. 0385 // 0386 // The print action will be enabled when at least one printer was marked. 0387 // 0388 int unmountedShares = selectedItems.size(); 0389 int printerShares = 0; 0390 0391 for (QTreeWidgetItem *selectedItem : qAsConst(selectedItems)) { 0392 Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>(selectedItem); 0393 0394 if (item) { 0395 if (item->shareItem()->isMounted() && !item->shareItem()->isForeign()) { 0396 unmountedShares--; 0397 } 0398 0399 if (item->shareItem()->isPrinter()) { 0400 printerShares++; 0401 } 0402 } 0403 } 0404 0405 qobject_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("rescan_abort_action")))->setInactiveText(i18n("Scan Netwo&rk")); 0406 m_actionCollection->action(QStringLiteral("bookmark_action"))->setEnabled(true); 0407 m_actionCollection->action(QStringLiteral("authentication_action"))->setEnabled(true); 0408 m_actionCollection->action(QStringLiteral("custom_action"))->setEnabled(true); 0409 m_actionCollection->action(QStringLiteral("preview_action"))->setEnabled(true); 0410 m_actionCollection->action(QStringLiteral("print_action"))->setEnabled(printerShares != 0); 0411 qobject_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("mount_action")))->setActive(unmountedShares == selectedItems.size()); 0412 m_actionCollection->action(QStringLiteral("mount_action"))->setEnabled(true); 0413 } else if (selectedItems.size() == 1) { 0414 Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>(selectedItems.first()); 0415 0416 if (item) { 0417 switch (item->type()) { 0418 case Host: { 0419 qobject_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("rescan_abort_action")))->setInactiveText(i18n("Scan Compute&r")); 0420 m_actionCollection->action(QStringLiteral("bookmark_action"))->setEnabled(false); 0421 m_actionCollection->action(QStringLiteral("authentication_action"))->setEnabled(true); 0422 m_actionCollection->action(QStringLiteral("custom_action"))->setEnabled(true); 0423 m_actionCollection->action(QStringLiteral("preview_action"))->setEnabled(false); 0424 m_actionCollection->action(QStringLiteral("print_action"))->setEnabled(false); 0425 qobject_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("mount_action")))->setActive(true); 0426 m_actionCollection->action(QStringLiteral("mount_action"))->setEnabled(false); 0427 break; 0428 } 0429 case Share: { 0430 qobject_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("rescan_abort_action")))->setInactiveText(i18n("Scan Compute&r")); 0431 m_actionCollection->action(QStringLiteral("bookmark_action"))->setEnabled(!item->shareItem()->isPrinter()); 0432 m_actionCollection->action(QStringLiteral("authentication_action"))->setEnabled(true); 0433 m_actionCollection->action(QStringLiteral("custom_action"))->setEnabled(!item->shareItem()->isPrinter()); 0434 m_actionCollection->action(QStringLiteral("preview_action"))->setEnabled(!item->shareItem()->isPrinter()); 0435 m_actionCollection->action(QStringLiteral("print_action"))->setEnabled(item->shareItem()->isPrinter()); 0436 0437 if (!item->shareItem()->isPrinter()) { 0438 if (!item->shareItem()->isMounted() || item->shareItem()->isForeign()) { 0439 qobject_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("mount_action")))->setActive(true); 0440 m_actionCollection->action(QStringLiteral("mount_action"))->setEnabled(true); 0441 } else if (item->shareItem()->isMounted() && !item->shareItem()->isForeign()) { 0442 qobject_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("mount_action")))->setActive(false); 0443 m_actionCollection->action(QStringLiteral("mount_action"))->setEnabled(true); 0444 } else { 0445 qobject_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("mount_action")))->setActive(true); 0446 m_actionCollection->action(QStringLiteral("mount_action"))->setEnabled(false); 0447 } 0448 } else { 0449 qobject_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("mount_action")))->setActive(true); 0450 m_actionCollection->action(QStringLiteral("mount_action"))->setEnabled(false); 0451 } 0452 break; 0453 } 0454 default: { 0455 qobject_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("rescan_abort_action")))->setInactiveText(i18n("Scan Wo&rkgroup")); 0456 m_actionCollection->action(QStringLiteral("bookmark_action"))->setEnabled(false); 0457 m_actionCollection->action(QStringLiteral("authentication_action"))->setEnabled(false); 0458 m_actionCollection->action(QStringLiteral("custom_action"))->setEnabled(false); 0459 m_actionCollection->action(QStringLiteral("preview_action"))->setEnabled(false); 0460 m_actionCollection->action(QStringLiteral("print_action"))->setEnabled(false); 0461 qobject_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("mount_action")))->setActive(true); 0462 m_actionCollection->action(QStringLiteral("mount_action"))->setEnabled(false); 0463 break; 0464 } 0465 } 0466 } 0467 } else { 0468 qobject_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("rescan_abort_action")))->setInactiveText(i18n("Scan Netwo&rk")); 0469 m_actionCollection->action(QStringLiteral("bookmark_action"))->setEnabled(false); 0470 m_actionCollection->action(QStringLiteral("authentication_action"))->setEnabled(false); 0471 m_actionCollection->action(QStringLiteral("custom_action"))->setEnabled(false); 0472 m_actionCollection->action(QStringLiteral("preview_action"))->setEnabled(false); 0473 m_actionCollection->action(QStringLiteral("print_action"))->setEnabled(false); 0474 qobject_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("mount_action")))->setActive(true); 0475 m_actionCollection->action(QStringLiteral("mount_action"))->setEnabled(false); 0476 } 0477 } 0478 0479 void Smb4KNetworkBrowserDockWidget::slotClientAboutToStart(const NetworkItemPtr & /*item*/, int process) 0480 { 0481 // 0482 // Get the rescan/abort action 0483 // 0484 KDualAction *rescanAbortAction = static_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("rescan_abort_action"))); 0485 0486 // 0487 // Make adjustments 0488 // 0489 if (rescanAbortAction) { 0490 rescanAbortAction->setActive(true); 0491 m_actionCollection->setDefaultShortcut(rescanAbortAction, QKeySequence::Cancel); 0492 } 0493 0494 // 0495 // Set the active status of the search tool bar 0496 // 0497 if (process == NetworkSearch) { 0498 m_searchToolBar->setActiveState(true); 0499 } 0500 } 0501 0502 void Smb4KNetworkBrowserDockWidget::slotClientFinished(const NetworkItemPtr & /*item*/, int process) 0503 { 0504 // 0505 // Get the rescan/abort action 0506 // 0507 KDualAction *rescanAbortAction = static_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("rescan_abort_action"))); 0508 0509 // 0510 // Make adjustments 0511 // 0512 if (rescanAbortAction) { 0513 rescanAbortAction->setActive(false); 0514 m_actionCollection->setDefaultShortcut(rescanAbortAction, QKeySequence::Refresh); 0515 } 0516 0517 // 0518 // Set the active status of the search tool bar 0519 // 0520 if (process == NetworkSearch) { 0521 m_searchToolBar->setActiveState(false); 0522 } 0523 } 0524 0525 void Smb4KNetworkBrowserDockWidget::slotWorkgroups() 0526 { 0527 if (!workgroupsList().isEmpty()) { 0528 // 0529 // Remove obsolete workgroups and update existing ones 0530 // 0531 QTreeWidgetItemIterator itemIt(m_networkBrowser, QTreeWidgetItemIterator::All); 0532 0533 while (*itemIt) { 0534 Smb4KNetworkBrowserItem *networkItem = static_cast<Smb4KNetworkBrowserItem *>(*itemIt); 0535 0536 if (networkItem->type() == Workgroup) { 0537 WorkgroupPtr workgroup = findWorkgroup(networkItem->workgroupItem()->workgroupName()); 0538 0539 if (workgroup) { 0540 networkItem->update(); 0541 0542 // Update the master browser 0543 for (int i = 0; i < networkItem->childCount(); ++i) { 0544 Smb4KNetworkBrowserItem *host = static_cast<Smb4KNetworkBrowserItem *>(networkItem->child(i)); 0545 host->update(); 0546 } 0547 } else { 0548 delete networkItem; 0549 } 0550 } 0551 0552 ++itemIt; 0553 } 0554 0555 // 0556 // Add new workgroups to the tree widget 0557 // 0558 for (const WorkgroupPtr &workgroup : workgroupsList()) { 0559 QList<QTreeWidgetItem *> items = m_networkBrowser->findItems(workgroup->workgroupName(), Qt::MatchFixedString, Smb4KNetworkBrowser::Network); 0560 0561 if (items.isEmpty()) { 0562 (void)new Smb4KNetworkBrowserItem(m_networkBrowser, workgroup); 0563 } 0564 } 0565 0566 // 0567 // Sort the items 0568 // 0569 m_networkBrowser->sortItems(Smb4KNetworkBrowser::Network, Qt::AscendingOrder); 0570 0571 // 0572 // Update the tooltip 0573 // 0574 m_networkBrowser->toolTip()->update(); 0575 } else { 0576 // 0577 // Clear the tree widget 0578 // 0579 m_networkBrowser->clear(); 0580 } 0581 } 0582 0583 void Smb4KNetworkBrowserDockWidget::slotWorkgroupMembers(const WorkgroupPtr &workgroup) 0584 { 0585 if (workgroup) { 0586 // 0587 // Find the right workgroup 0588 // 0589 QList<QTreeWidgetItem *> workgroups = 0590 m_networkBrowser->findItems(workgroup->workgroupName(), Qt::MatchFixedString | Qt::MatchRecursive, Smb4KNetworkBrowser::Network); 0591 Smb4KNetworkBrowserItem *workgroupItem = nullptr; 0592 0593 for (QTreeWidgetItem *item : qAsConst(workgroups)) { 0594 Smb4KNetworkBrowserItem *tempWorkgroup = static_cast<Smb4KNetworkBrowserItem *>(item); 0595 0596 if (tempWorkgroup->type() == Workgroup && tempWorkgroup->workgroupItem()->workgroupName() == workgroup->workgroupName()) { 0597 workgroupItem = tempWorkgroup; 0598 break; 0599 } 0600 } 0601 0602 // 0603 // Process the hosts 0604 // 0605 if (workgroupItem) { 0606 // 0607 // Remove obsolete hosts and update existing ones 0608 // 0609 QTreeWidgetItemIterator hostIt(workgroupItem); 0610 0611 while (*hostIt) { 0612 Smb4KNetworkBrowserItem *hostItem = static_cast<Smb4KNetworkBrowserItem *>(*hostIt); 0613 0614 if (hostItem->type() == Host) { 0615 HostPtr host = findHost(hostItem->hostItem()->hostName(), hostItem->hostItem()->workgroupName()); 0616 0617 if (host) { 0618 hostItem->update(); 0619 } else { 0620 delete hostItem; 0621 } 0622 } 0623 0624 ++hostIt; 0625 } 0626 0627 // 0628 // Add new hosts to the workgroup item and remove obsolete workgroups if 0629 // necessary. Honor the auto-expand feature. 0630 // 0631 QList<HostPtr> members = workgroupMembers(workgroup); 0632 0633 if (!members.isEmpty()) { 0634 for (const HostPtr &host : qAsConst(members)) { 0635 bool foundHost = false; 0636 0637 for (int i = 0; i < workgroupItem->childCount(); ++i) { 0638 Smb4KNetworkBrowserItem *hostItem = static_cast<Smb4KNetworkBrowserItem *>(workgroupItem->child(i)); 0639 0640 if (hostItem->hostItem()->hostName() == host->hostName()) { 0641 foundHost = true; 0642 break; 0643 } 0644 } 0645 0646 if (!foundHost) { 0647 (void)new Smb4KNetworkBrowserItem(workgroupItem, host); 0648 } 0649 } 0650 0651 // 0652 // Auto-expand the workgroup item, if applicable 0653 // 0654 if (Smb4KSettings::autoExpandNetworkItems() && !workgroupItem->isExpanded() && !m_searchRunning) { 0655 m_networkBrowser->expandItem(workgroupItem); 0656 } 0657 } else { 0658 // 0659 // Remove empty workgroup. 0660 // 0661 delete workgroupItem; 0662 } 0663 0664 // 0665 // Sort the items 0666 // 0667 m_networkBrowser->sortItems(Smb4KNetworkBrowser::Network, Qt::AscendingOrder); 0668 0669 // 0670 // Update the tooltip 0671 // 0672 m_networkBrowser->toolTip()->update(); 0673 } 0674 } 0675 } 0676 0677 void Smb4KNetworkBrowserDockWidget::slotShares(const HostPtr &host) 0678 { 0679 if (host) { 0680 // 0681 // Find the right host 0682 // 0683 QList<QTreeWidgetItem *> hosts = m_networkBrowser->findItems(host->hostName(), Qt::MatchFixedString | Qt::MatchRecursive, Smb4KNetworkBrowser::Network); 0684 Smb4KNetworkBrowserItem *hostItem = nullptr; 0685 0686 for (QTreeWidgetItem *item : qAsConst(hosts)) { 0687 Smb4KNetworkBrowserItem *tempHost = static_cast<Smb4KNetworkBrowserItem *>(item); 0688 0689 if (tempHost->type() == Host && tempHost->hostItem()->workgroupName() == host->workgroupName()) { 0690 hostItem = tempHost; 0691 break; 0692 } 0693 } 0694 0695 // 0696 // Process the shares 0697 // 0698 if (hostItem) { 0699 // 0700 // Remove obsolete shares and update existing ones 0701 // 0702 QTreeWidgetItemIterator shareIt(hostItem); 0703 0704 while (*shareIt) { 0705 Smb4KNetworkBrowserItem *shareItem = static_cast<Smb4KNetworkBrowserItem *>(*shareIt); 0706 0707 if (shareItem->type() == Share) { 0708 SharePtr share = findShare(shareItem->shareItem()->url(), shareItem->shareItem()->workgroupName()); 0709 0710 if (share) { 0711 shareItem->update(); 0712 } else { 0713 delete shareItem; 0714 } 0715 } 0716 0717 ++shareIt; 0718 } 0719 0720 // 0721 // Add new shares to the host item. The host will not be removed from the 0722 // view when it has no shares. Honor the auto-expand feature. 0723 // 0724 QList<SharePtr> shares = sharedResources(host); 0725 0726 if (!shares.isEmpty()) { 0727 for (const SharePtr &share : qAsConst(shares)) { 0728 bool foundShare = false; 0729 0730 for (int i = 0; i < hostItem->childCount(); ++i) { 0731 Smb4KNetworkBrowserItem *shareItem = static_cast<Smb4KNetworkBrowserItem *>(hostItem->child(i)); 0732 0733 if (shareItem->shareItem()->url().toString(QUrl::RemoveUserInfo | QUrl::RemovePort) 0734 == share->url().toString(QUrl::RemoveUserInfo | QUrl::RemovePort)) { 0735 foundShare = true; 0736 break; 0737 } 0738 } 0739 0740 if (!foundShare) { 0741 (void)new Smb4KNetworkBrowserItem(hostItem, share); 0742 } 0743 } 0744 0745 // 0746 // Auto-expand the host item, if applicable 0747 // 0748 if (Smb4KSettings::autoExpandNetworkItems() && !hostItem->isExpanded() && !m_searchRunning) { 0749 m_networkBrowser->expandItem(hostItem); 0750 } 0751 } 0752 } 0753 0754 // 0755 // Sort the items 0756 // 0757 m_networkBrowser->sortItems(Smb4KNetworkBrowser::Network, Qt::AscendingOrder); 0758 0759 // 0760 // Update the tooltip 0761 // 0762 m_networkBrowser->toolTip()->update(); 0763 } 0764 } 0765 0766 void Smb4KNetworkBrowserDockWidget::slotRescanAbortActionTriggered(bool checked) 0767 { 0768 Q_UNUSED(checked); 0769 0770 // 0771 // Get the Rescan/Abort action 0772 // 0773 KDualAction *rescanAbortAction = static_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("rescan_abort_action"))); 0774 0775 // 0776 // Get the selected items 0777 // 0778 QList<QTreeWidgetItem *> selectedItems = m_networkBrowser->selectedItems(); 0779 0780 // 0781 // Perform actions according to the state of the action and the number of 0782 // selected items. 0783 // 0784 if (!rescanAbortAction->isActive()) { 0785 if (selectedItems.size() == 1) { 0786 Smb4KNetworkBrowserItem *browserItem = static_cast<Smb4KNetworkBrowserItem *>(selectedItems.first()); 0787 0788 if (browserItem) { 0789 switch (browserItem->type()) { 0790 case Workgroup: { 0791 Smb4KClient::self()->lookupDomainMembers(browserItem->workgroupItem()); 0792 break; 0793 } 0794 case Host: { 0795 Smb4KClient::self()->lookupShares(browserItem->hostItem()); 0796 break; 0797 } 0798 case Share: { 0799 Smb4KNetworkBrowserItem *parentItem = static_cast<Smb4KNetworkBrowserItem *>(browserItem->parent()); 0800 Smb4KClient::self()->lookupShares(parentItem->hostItem()); 0801 break; 0802 } 0803 default: { 0804 break; 0805 } 0806 } 0807 } 0808 } else { 0809 // 0810 // If several items are selected or no selected items, 0811 // only the network can be scanned. 0812 // 0813 Smb4KClient::self()->lookupDomains(); 0814 } 0815 } else { 0816 // 0817 // Stop all actions performed by the client 0818 // 0819 if (Smb4KClient::self()->isRunning()) { 0820 Smb4KClient::self()->abort(); 0821 } 0822 } 0823 } 0824 0825 void Smb4KNetworkBrowserDockWidget::slotAddBookmark(bool checked) 0826 { 0827 Q_UNUSED(checked); 0828 0829 QList<QTreeWidgetItem *> selectedItems = m_networkBrowser->selectedItems(); 0830 QList<SharePtr> shares; 0831 0832 if (!selectedItems.isEmpty()) { 0833 for (QTreeWidgetItem *selectedItem : selectedItems) { 0834 Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>(selectedItem); 0835 0836 if (item && item->type() == Share && !item->shareItem()->isPrinter()) { 0837 shares << item->shareItem(); 0838 } 0839 } 0840 } else { 0841 return; 0842 } 0843 0844 if (!shares.isEmpty()) { 0845 QPointer<Smb4KBookmarkDialog> bookmarkDialog = new Smb4KBookmarkDialog(); 0846 0847 if (bookmarkDialog->setShares(shares)) { 0848 bookmarkDialog->open(); 0849 } 0850 } 0851 } 0852 0853 void Smb4KNetworkBrowserDockWidget::slotMountManually(bool checked) 0854 { 0855 Q_UNUSED(checked); 0856 0857 QPointer<Smb4KMountDialog> mountDialog = new Smb4KMountDialog(); 0858 mountDialog->open(); 0859 } 0860 0861 void Smb4KNetworkBrowserDockWidget::slotAuthentication(bool checked) 0862 { 0863 Q_UNUSED(checked); 0864 0865 QList<QTreeWidgetItem *> selectedItems = m_networkBrowser->selectedItems(); 0866 0867 for (QTreeWidgetItem *selectedItem : qAsConst(selectedItems)) { 0868 Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>(selectedItem); 0869 0870 if (item) { 0871 switch (item->type()) { 0872 case Host: { 0873 Smb4KWalletManager::self()->showPasswordDialog(item->hostItem()); 0874 break; 0875 } 0876 case Share: { 0877 Smb4KWalletManager::self()->showPasswordDialog(item->shareItem()); 0878 break; 0879 } 0880 default: { 0881 break; 0882 } 0883 } 0884 } 0885 } 0886 } 0887 0888 void Smb4KNetworkBrowserDockWidget::slotAddCustomSettings(bool checked) 0889 { 0890 Q_UNUSED(checked); 0891 0892 QList<QTreeWidgetItem *> selectedItems = m_networkBrowser->selectedItems(); 0893 0894 for (QTreeWidgetItem *selectedItem : qAsConst(selectedItems)) { 0895 Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>(selectedItem); 0896 0897 QPointer<Smb4KCustomSettingsEditor> customSettingsEditor = new Smb4KCustomSettingsEditor(); 0898 if (customSettingsEditor->setNetworkItem(item->networkItem())) { 0899 customSettingsEditor->open(); 0900 } else { 0901 delete customSettingsEditor; 0902 } 0903 } 0904 } 0905 0906 void Smb4KNetworkBrowserDockWidget::slotPreview(bool checked) 0907 { 0908 Q_UNUSED(checked); 0909 0910 QList<QTreeWidgetItem *> selectedItems = m_networkBrowser->selectedItems(); 0911 0912 for (QTreeWidgetItem *selectedItem : qAsConst(selectedItems)) { 0913 Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>(selectedItem); 0914 0915 if (item && item->type() == Share && !item->shareItem()->isPrinter()) { 0916 QPointer<Smb4KPreviewDialog> previewDialog = new Smb4KPreviewDialog(); 0917 0918 if (previewDialog->setShare(item->shareItem())) { 0919 previewDialog->open(); 0920 } 0921 } 0922 } 0923 } 0924 0925 void Smb4KNetworkBrowserDockWidget::slotPrint(bool checked) 0926 { 0927 Q_UNUSED(checked); 0928 0929 QList<QTreeWidgetItem *> selectedItems = m_networkBrowser->selectedItems(); 0930 0931 for (QTreeWidgetItem *selectedItem : qAsConst(selectedItems)) { 0932 Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>(selectedItem); 0933 0934 if (item && item->shareItem()->isPrinter()) { 0935 QPointer<Smb4KPrintDialog> printDialog = new Smb4KPrintDialog(); 0936 0937 if (printDialog->setPrinterShare(item->shareItem())) { 0938 printDialog->open(); 0939 } else { 0940 delete printDialog; 0941 } 0942 } 0943 } 0944 } 0945 0946 void Smb4KNetworkBrowserDockWidget::slotMountActionTriggered(bool checked) 0947 { 0948 Q_UNUSED(checked); 0949 0950 QList<QTreeWidgetItem *> selectedItems = m_networkBrowser->selectedItems(); 0951 QList<SharePtr> unmountedShares, mountedShares; 0952 0953 for (QTreeWidgetItem *selectedItem : qAsConst(selectedItems)) { 0954 Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>(selectedItem); 0955 0956 if (item && item->type() == Share && !item->shareItem()->isPrinter()) { 0957 if (item->shareItem()->isMounted()) { 0958 mountedShares << item->shareItem(); 0959 } else { 0960 unmountedShares << item->shareItem(); 0961 } 0962 } 0963 } 0964 0965 if (!mountedShares.isEmpty()) { 0966 Smb4KMounter::self()->unmountShares(mountedShares); 0967 } else { 0968 Smb4KMounter::self()->mountShares(unmountedShares); 0969 } 0970 } 0971 0972 void Smb4KNetworkBrowserDockWidget::slotMountActionChanged(bool active) 0973 { 0974 // 0975 // Get the mount action 0976 // 0977 KDualAction *mountAction = static_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("mount_action"))); 0978 0979 // 0980 // Change the shortcuts depending on the value of the 'active' argument 0981 // 0982 if (mountAction) { 0983 if (active) { 0984 m_actionCollection->setDefaultShortcut(mountAction, QKeySequence(i18n("Ctrl+M"))); 0985 } else { 0986 m_actionCollection->setDefaultShortcut(mountAction, QKeySequence(i18n("Ctrl+U"))); 0987 } 0988 } 0989 } 0990 0991 void Smb4KNetworkBrowserDockWidget::slotShareMounted(const SharePtr &share) 0992 { 0993 QTreeWidgetItemIterator it(m_networkBrowser); 0994 0995 while (*it) { 0996 Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>(*it); 0997 0998 if (item->type() == Share) { 0999 if (QString::compare(item->shareItem()->url().toString(QUrl::RemoveUserInfo | QUrl::RemovePort), 1000 share->url().toString(QUrl::RemoveUserInfo | QUrl::RemovePort), 1001 Qt::CaseInsensitive) 1002 == 0) { 1003 item->update(); 1004 break; 1005 } 1006 } 1007 1008 ++it; 1009 } 1010 } 1011 1012 void Smb4KNetworkBrowserDockWidget::slotShareUnmounted(const SharePtr &share) 1013 { 1014 QTreeWidgetItemIterator it(m_networkBrowser); 1015 1016 while (*it) { 1017 Smb4KNetworkBrowserItem *item = static_cast<Smb4KNetworkBrowserItem *>(*it); 1018 1019 if (item->type() == Share) { 1020 if (QString::compare(item->shareItem()->url().toString(QUrl::RemoveUserInfo | QUrl::RemovePort), 1021 share->url().toString(QUrl::RemoveUserInfo | QUrl::RemovePort), 1022 Qt::CaseInsensitive) 1023 == 0) { 1024 item->update(); 1025 break; 1026 } 1027 } 1028 1029 ++it; 1030 } 1031 } 1032 1033 void Smb4KNetworkBrowserDockWidget::slotMounterAboutToStart(int /*process*/) 1034 { 1035 // 1036 // Unused at the moment 1037 // 1038 } 1039 1040 void Smb4KNetworkBrowserDockWidget::slotMounterFinished(int process) 1041 { 1042 // 1043 // Get the mount/unmount action 1044 // 1045 KDualAction *mountAction = static_cast<KDualAction *>(m_actionCollection->action(QStringLiteral("mount_action"))); 1046 1047 // 1048 // Make adjustments 1049 // 1050 if (mountAction) { 1051 switch (process) { 1052 case MountShare: { 1053 mountAction->setActive(false); 1054 break; 1055 } 1056 case UnmountShare: { 1057 mountAction->setActive(true); 1058 break; 1059 } 1060 default: { 1061 break; 1062 } 1063 } 1064 } 1065 } 1066 1067 void Smb4KNetworkBrowserDockWidget::slotShowSearchToolBar() 1068 { 1069 // 1070 // Show the search toolbar 1071 // 1072 m_searchToolBar->setVisible(true); 1073 1074 // 1075 // Set the focus to the search item input 1076 // 1077 m_searchToolBar->prepareInput(); 1078 } 1079 1080 void Smb4KNetworkBrowserDockWidget::slotHideSearchToolBar() 1081 { 1082 // 1083 // Prevent another dock widget from stealing the focus when 1084 // the search tool bar is hidden 1085 // 1086 m_networkBrowser->setFocus(); 1087 1088 // 1089 // Hide the search toolbar 1090 // 1091 m_searchToolBar->setVisible(false); 1092 } 1093 1094 void Smb4KNetworkBrowserDockWidget::slotPerformSearch(const QString &item) 1095 { 1096 // 1097 // Prevent another dock widget from stealing the focus when 1098 // the search item input is disabled 1099 // 1100 m_networkBrowser->setFocus(); 1101 1102 // 1103 // Clear the selections in the network browser 1104 // 1105 m_networkBrowser->clearSelection(); 1106 1107 // 1108 // A global search is underway 1109 // 1110 m_searchRunning = true; 1111 1112 // 1113 // Start the search 1114 // 1115 Smb4KClient::self()->search(item); 1116 } 1117 1118 void Smb4KNetworkBrowserDockWidget::slotStopSearch() 1119 { 1120 // 1121 // Stop the network search 1122 // 1123 Smb4KClient::self()->abort(); 1124 1125 // 1126 // A global search finished 1127 // 1128 m_searchRunning = false; 1129 } 1130 1131 void Smb4KNetworkBrowserDockWidget::slotSearchResults(const QList<SharePtr> &shares) 1132 { 1133 // 1134 // A global search finished 1135 // 1136 m_searchRunning = false; 1137 1138 // 1139 // Process the search results 1140 // 1141 QTreeWidgetItemIterator it(m_networkBrowser); 1142 1143 while (*it) { 1144 Smb4KNetworkBrowserItem *networkItem = static_cast<Smb4KNetworkBrowserItem *>(*it); 1145 1146 if (networkItem->type() == Share) { 1147 for (const SharePtr &share : shares) { 1148 if (networkItem->shareItem() == share) { 1149 // 1150 // Select the search result 1151 // 1152 networkItem->setSelected(true); 1153 1154 // 1155 // Expand the branch of the network tree where a search result 1156 // was retrieved 1157 // 1158 if (!networkItem->parent()->isExpanded()) { 1159 m_networkBrowser->expandItem(networkItem->parent()); 1160 } 1161 1162 if (!networkItem->parent()->parent()->isExpanded()) { 1163 m_networkBrowser->expandItem(networkItem->parent()->parent()); 1164 } 1165 } 1166 } 1167 } 1168 1169 it++; 1170 } 1171 1172 // 1173 // Pass the search results to the search toolbar 1174 // 1175 m_searchToolBar->setSearchResults(shares); 1176 } 1177 1178 void Smb4KNetworkBrowserDockWidget::slotJumpToResult(const QString &url) 1179 { 1180 // 1181 // Find the share item with URL url 1182 // 1183 QTreeWidgetItemIterator it(m_networkBrowser); 1184 1185 while (*it) { 1186 Smb4KNetworkBrowserItem *networkItem = static_cast<Smb4KNetworkBrowserItem *>(*it); 1187 1188 if (networkItem->type() == Share && networkItem->shareItem()->url().toString() == url) { 1189 m_networkBrowser->setCurrentItem(networkItem); 1190 break; 1191 } 1192 1193 it++; 1194 } 1195 } 1196 1197 void Smb4KNetworkBrowserDockWidget::slotClearSearchResults() 1198 { 1199 m_networkBrowser->clearSelection(); 1200 }