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