File indexing completed on 2024-04-14 04:56:32

0001 /*
0002     The main window of Smb4K
0003 
0004     SPDX-FileCopyrightText: 2008-2024 Alexander Reinholdt <alexander.reinholdt@kdemail.net>
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 // application specific includes
0009 #include "smb4kmainwindow.h"
0010 #include "core/smb4kclient.h"
0011 #include "core/smb4kfile.h"
0012 #include "core/smb4kglobal.h"
0013 #include "core/smb4khost.h"
0014 #include "core/smb4kmounter.h"
0015 #include "core/smb4ksettings.h"
0016 #include "core/smb4kshare.h"
0017 #include "core/smb4ksynchronizer.h"
0018 #include "core/smb4kwalletmanager.h"
0019 #include "core/smb4kworkgroup.h"
0020 #include "smb4kbookmarkmenu.h"
0021 #include "smb4knetworkbrowserdockwidget.h"
0022 #include "smb4kpassworddialog.h"
0023 #include "smb4kprofilesmenu.h"
0024 #include "smb4ksharesviewdockwidget.h"
0025 #include "smb4ksystemtray.h"
0026 
0027 // Qt includes
0028 #include <QApplication>
0029 #include <QDockWidget>
0030 #include <QMenu>
0031 #include <QMenuBar>
0032 #include <QStatusBar>
0033 #include <QTabBar>
0034 #include <QTimer>
0035 
0036 // KDE includes
0037 #include <KConfigDialog>
0038 #include <KIconLoader>
0039 #include <KLocalizedString>
0040 #include <KMessageBox>
0041 #include <KPluginFactory>
0042 #include <KPluginMetaData>
0043 #include <KStandardAction>
0044 #include <KXMLGUIFactory>
0045 
0046 using namespace Smb4KGlobal;
0047 
0048 Smb4KMainWindow::Smb4KMainWindow()
0049     : KXmlGuiWindow()
0050 {
0051     setStandardToolBarMenuEnabled(true);
0052     createStandardStatusBarAction();
0053     setDockNestingEnabled(true);
0054     setupActions();
0055     setupGUI(QSize(800, 500), Default, QStringLiteral("smb4k_shell.rc"));
0056     setupView();
0057     setupMenuBar();
0058     setupStatusBar();
0059 
0060     switch (Smb4KSettings::mainWindowTabOrientation()) {
0061     case Smb4KSettings::EnumMainWindowTabOrientation::Top: {
0062         setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
0063         break;
0064     }
0065     case Smb4KSettings::EnumMainWindowTabOrientation::Bottom: {
0066         setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::South);
0067         break;
0068     }
0069     case Smb4KSettings::EnumMainWindowTabOrientation::Left: {
0070         setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::West);
0071         break;
0072     }
0073     case Smb4KSettings::EnumMainWindowTabOrientation::Right: {
0074         setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::East);
0075         break;
0076     }
0077     default: {
0078         break;
0079     }
0080     }
0081 
0082     m_systemTrayWidget = new Smb4KSystemTray(this);
0083     m_passwordDialog = new Smb4KPasswordDialog(this);
0084 
0085     m_focusWidget = nullptr;
0086     m_timerId = 0;
0087     m_quitting = false;
0088 
0089     KConfigGroup configGroup(Smb4KSettings::self()->config(), QStringLiteral("MainWindow"));
0090     setAutoSaveSettings(configGroup, true);
0091 
0092     connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit, this, &Smb4KMainWindow::saveSettings);
0093 
0094     connect(Smb4KClient::self(), &Smb4KClient::requestCredentials, this, &Smb4KMainWindow::slotCredentialsRequested);
0095     connect(Smb4KMounter::self(), &Smb4KMounter::requestCredentials, this, &Smb4KMainWindow::slotCredentialsRequested);
0096 }
0097 
0098 Smb4KMainWindow::~Smb4KMainWindow()
0099 {
0100 }
0101 
0102 void Smb4KMainWindow::setupActions()
0103 {
0104     QAction *quitAction = KStandardAction::quit(this, &Smb4KMainWindow::slotQuit, actionCollection());
0105     actionCollection()->addAction(QStringLiteral("quit_action"), quitAction);
0106 
0107     QAction *configureAction = KStandardAction::preferences(this, SLOT(slotConfigDialog()), actionCollection());
0108     actionCollection()->addAction(QStringLiteral("configure_action"), configureAction);
0109 
0110     KActionMenu *dockWidgetsMenu = new KActionMenu(KDE::icon(QStringLiteral("tab-duplicate")), i18n("Dock Widgets"), actionCollection());
0111     actionCollection()->addAction(QStringLiteral("dock_widgets_menu"), dockWidgetsMenu);
0112 
0113     m_bookmarkMenu = new Smb4KBookmarkMenu(Smb4KBookmarkMenu::MainWindow, this);
0114     QAction *addBookmarkAction = new QAction(KDE::icon(QStringLiteral("bookmark-new")), i18n("Add &Bookmark"), actionCollection());
0115     addBookmarkAction->setEnabled(false);
0116     actionCollection()->addAction(QStringLiteral("bookmarks_menu"), m_bookmarkMenu);
0117     actionCollection()->addAction(QStringLiteral("bookmark_action"), addBookmarkAction);
0118     connect(addBookmarkAction, &QAction::triggered, this, &Smb4KMainWindow::slotAddBookmarks);
0119     connect(m_bookmarkMenu, &Smb4KBookmarkMenu::addBookmark, this, &Smb4KMainWindow::slotAddBookmarks);
0120 
0121     Smb4KProfilesMenu *profiles = new Smb4KProfilesMenu(this);
0122     actionCollection()->addAction(QStringLiteral("profiles_menu"), profiles);
0123 }
0124 
0125 void Smb4KMainWindow::setupStatusBar()
0126 {
0127     // Set up the progress bar.
0128     m_progressBar = new QProgressBar(statusBar());
0129     m_progressBar->setFixedWidth(100);
0130     m_progressBar->setMaximum(0);
0131     m_progressBar->setMinimum(0);
0132     m_progressBar->setFixedHeight(statusBar()->fontMetrics().height());
0133     m_progressBar->setAlignment(Qt::AlignCenter);
0134     m_progressBar->setVisible(false);
0135 
0136     // Set the icon on the right side that represents the initial
0137     // state of the wallet manager.
0138     m_passwordIcon = new QLabel(statusBar());
0139     m_passwordIcon->setContentsMargins(0, 0, 0, 0);
0140     m_passwordIcon->setAlignment(Qt::AlignCenter);
0141 
0142     // The feedback icon.
0143     m_feedbackIcon = new QLabel(statusBar());
0144     m_feedbackIcon->setContentsMargins(0, 0, 0, 0);
0145     m_feedbackIcon->setAlignment(Qt::AlignCenter);
0146 
0147     statusBar()->addPermanentWidget(m_progressBar);
0148     statusBar()->addPermanentWidget(m_feedbackIcon);
0149     statusBar()->addPermanentWidget(m_passwordIcon);
0150 
0151     slotWalletManagerInitialized();
0152     setupMountIndicator();
0153 
0154     //
0155     // Connections
0156     //
0157     connect(Smb4KClient::self(), &Smb4KClient::aboutToStart, this, &Smb4KMainWindow::slotClientAboutToStart);
0158     connect(Smb4KClient::self(), &Smb4KClient::finished, this, &Smb4KMainWindow::slotClientFinished);
0159 
0160     connect(Smb4KWalletManager::self(), &Smb4KWalletManager::initialized, this, &Smb4KMainWindow::slotWalletManagerInitialized);
0161 
0162     connect(Smb4KMounter::self(), &Smb4KMounter::mounted, this, &Smb4KMainWindow::slotVisualMountFeedback);
0163     connect(Smb4KMounter::self(), &Smb4KMounter::unmounted, this, &Smb4KMainWindow::slotVisualUnmountFeedback);
0164     connect(Smb4KMounter::self(), &Smb4KMounter::aboutToStart, this, &Smb4KMainWindow::slotMounterAboutToStart);
0165     connect(Smb4KMounter::self(), &Smb4KMounter::finished, this, &Smb4KMainWindow::slotMounterFinished);
0166 
0167     connect(Smb4KSynchronizer::self(), &Smb4KSynchronizer::aboutToStart, this, &Smb4KMainWindow::slotSynchronizerAboutToStart);
0168     connect(Smb4KSynchronizer::self(), &Smb4KSynchronizer::finished, this, &Smb4KMainWindow::slotSynchronizerFinished);
0169 }
0170 
0171 void Smb4KMainWindow::setupView()
0172 {
0173     //
0174     // We do not set a central widget, because it causes "problems"
0175     // with the dock widgets. We have the nested dock widget property
0176     // set to true, so we can arrange the dock widgets as we like,
0177     // nonetheless.
0178     //
0179 
0180     KActionMenu *dockWidgetsMenu = qobject_cast<KActionMenu *>(actionCollection()->action(QStringLiteral("dock_widgets_menu")));
0181 
0182     m_networkBrowserDockWidget = new Smb4KNetworkBrowserDockWidget(i18n("Network Neighborhood"), this);
0183     m_networkBrowserDockWidget->setObjectName(QStringLiteral("NetworkBrowserDockWidget"));
0184     m_networkBrowserDockWidget->setAllowedAreas(Qt::LeftDockWidgetArea);
0185     m_networkBrowserDockWidget->widget()->installEventFilter(this);
0186 
0187     connect(m_networkBrowserDockWidget, &Smb4KNetworkBrowserDockWidget::visibilityChanged, this, &Smb4KMainWindow::slotNetworkBrowserVisibilityChanged);
0188 
0189     addDockWidget(Qt::LeftDockWidgetArea, m_networkBrowserDockWidget);
0190     dockWidgetsMenu->addAction(m_networkBrowserDockWidget->toggleViewAction());
0191     plugActionList(QStringLiteral("network_menu"), m_networkBrowserDockWidget->actionCollection()->actions());
0192 
0193     m_sharesViewDockWidget = new Smb4KSharesViewDockWidget(i18n("Mounted Shares"), this);
0194     m_sharesViewDockWidget->setObjectName(QStringLiteral("SharesViewDockWidget"));
0195     m_sharesViewDockWidget->setAllowedAreas(Qt::LeftDockWidgetArea);
0196     m_sharesViewDockWidget->widget()->installEventFilter(this);
0197 
0198     connect(m_sharesViewDockWidget, &Smb4KSharesViewDockWidget::visibilityChanged, this, &Smb4KMainWindow::slotSharesViewVisibilityChanged);
0199 
0200     addDockWidget(Qt::LeftDockWidgetArea, m_sharesViewDockWidget);
0201     dockWidgetsMenu->addAction(m_sharesViewDockWidget->toggleViewAction());
0202     plugActionList(QStringLiteral("shares_menu"), m_sharesViewDockWidget->actionCollection()->actions());
0203 
0204     // KMessageWidget *messageWidget = new KMessageWidget();
0205     // messageWidget->setMessageType(KMessageWidget::Positive);
0206     // messageWidget->setText(i18n("Test ..."));
0207     //
0208     // QDockWidget *messageDockWidget = new QDockWidget(this);
0209     // messageDockWidget->setObjectName(QStringLiteral("MessageDockWidget"));
0210     // messageDockWidget->setWidget(messageWidget);
0211     // messageDockWidget->setTitleBarWidget(new QWidget());
0212     // messageDockWidget->setFeatures(QDockWidget::NoDockWidgetFeatures);
0213     // messageDockWidget->setContentsMargins(0, 0, 0, 0);
0214     //
0215     // addDockWidget(Qt::TopDockWidgetArea, messageDockWidget);
0216 
0217     KConfigGroup configGroup(Smb4KSettings::self()->config(), QStringLiteral("MainWindow"));
0218 
0219     if (!configGroup.hasKey(QStringLiteral("FirstStartup"))) {
0220         QList<QDockWidget *> docks = findChildren<QDockWidget *>();
0221 
0222         for (int i = 1; i < docks.size(); ++i) {
0223             tabifyDockWidget(docks.at(i - 1), docks.at(i));
0224         }
0225 
0226         configGroup.writeEntry(QStringLiteral("FirstStartup"), true);
0227     }
0228 }
0229 
0230 void Smb4KMainWindow::setupMenuBar()
0231 {
0232     // Get the "Bookmarks" menu
0233     QList<QAction *> actions = menuBar()->actions();
0234     QListIterator<QAction *> it(actions);
0235 
0236     while (it.hasNext()) {
0237         QAction *action = it.next();
0238 
0239         if (action->objectName() == QStringLiteral("bookmarks")) {
0240             action->setMenu(m_bookmarkMenu->menu());
0241             break;
0242         } else {
0243             continue;
0244         }
0245     }
0246 }
0247 
0248 void Smb4KMainWindow::loadSettings()
0249 {
0250     switch (Smb4KSettings::mainWindowTabOrientation()) {
0251     case Smb4KSettings::EnumMainWindowTabOrientation::Top: {
0252         setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
0253         break;
0254     }
0255     case Smb4KSettings::EnumMainWindowTabOrientation::Bottom: {
0256         setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::South);
0257         break;
0258     }
0259     case Smb4KSettings::EnumMainWindowTabOrientation::Left: {
0260         setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::West);
0261         break;
0262     }
0263     case Smb4KSettings::EnumMainWindowTabOrientation::Right: {
0264         setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::East);
0265         break;
0266     }
0267     default: {
0268         break;
0269     }
0270     }
0271 
0272     m_networkBrowserDockWidget->loadSettings();
0273     m_sharesViewDockWidget->loadSettings();
0274 
0275     m_bookmarkMenu->refreshMenu();
0276 
0277     // Check the state of the password handler and the wallet settings and
0278     // set the pixmap in the status bar accordingly.
0279     slotWalletManagerInitialized();
0280 
0281     // Set up the mount indicator icon.
0282     setupMountIndicator();
0283 }
0284 
0285 void Smb4KMainWindow::saveSettings()
0286 {
0287     qDebug() << "Smb4KMainWindow::saveSettings()";
0288 
0289     m_networkBrowserDockWidget->saveSettings();
0290     m_sharesViewDockWidget->saveSettings();
0291 
0292     Smb4KSettings::setStartMainWindowDocked(!isVisible());
0293     Smb4KSettings::self()->save();
0294 }
0295 
0296 bool Smb4KMainWindow::queryClose()
0297 {
0298     qDebug() << "Smb4KMainWindow::queryClose()";
0299 
0300     if (!m_quitting && !qApp->isSavingSession() && isVisible()) {
0301         // This part has been copied from JuK application.
0302         KMessageBox::information(this,
0303                                  i18n("<qt>Closing the main window will keep Smb4K running in the system tray.<br>"
0304                                       "Use <i>Quit</i> from the <i>File</i> menu to quit the application.</qt>"),
0305                                  i18n("Docking"),
0306                                  QStringLiteral("DockToSystemTrayInfo"));
0307         setVisible(false);
0308         return false;
0309     }
0310 
0311     return true;
0312 }
0313 
0314 bool Smb4KMainWindow::eventFilter(QObject *obj, QEvent *e)
0315 {
0316     switch (e->type()) {
0317     case QEvent::FocusIn: {
0318         //
0319         // Check if the widget that has the focus belongs to the network
0320         // browser widget
0321         //
0322         QObjectList networkBrowserDockWidgetChildren = m_networkBrowserDockWidget->children();
0323 
0324         for (QObject *object : networkBrowserDockWidgetChildren) {
0325             if (object == obj) {
0326                 m_focusWidget = m_networkBrowserDockWidget;
0327                 setupDynamicActionList(m_networkBrowserDockWidget);
0328                 break;
0329             }
0330         }
0331 
0332         //
0333         // Check if the widget that has the focus belongs to the shares
0334         // view
0335         //
0336         QObjectList sharesViewDockWidgetChildren = m_sharesViewDockWidget->children();
0337 
0338         for (QObject *object : sharesViewDockWidgetChildren) {
0339             if (object == obj) {
0340                 m_focusWidget = m_sharesViewDockWidget;
0341                 setupDynamicActionList(m_sharesViewDockWidget);
0342                 break;
0343             }
0344         }
0345         break;
0346     }
0347     default: {
0348         break;
0349     }
0350     }
0351 
0352     return KXmlGuiWindow::eventFilter(obj, e);
0353 }
0354 
0355 void Smb4KMainWindow::setupMountIndicator()
0356 {
0357     QStringList overlays;
0358 
0359     if (mountedSharesList().size() == 0) {
0360         m_feedbackIcon->setToolTip(i18n("There are currently no shares mounted."));
0361     } else {
0362         overlays << QStringLiteral("emblem-mounted");
0363         m_feedbackIcon->setToolTip(i18np("There is currently %1 share mounted.", "There are currently %1 shares mounted.", mountedSharesList().size()));
0364     }
0365 
0366     m_feedbackIcon->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("folder-network"), KIconLoader::Small, 0, KIconLoader::DefaultState, overlays));
0367 }
0368 
0369 void Smb4KMainWindow::setupDynamicActionList(QDockWidget *dock)
0370 {
0371     if (dock) {
0372         //
0373         // Remove all connections to Smb4KMainWindow::slotEnableBookmarkAction() and
0374         // disable the bookmark action.
0375         //
0376         disconnect(this, SLOT(slotEnableBookmarkAction()));
0377         actionCollection()->action(QStringLiteral("bookmark_action"))->setEnabled(false);
0378 
0379         //
0380         // Disable the bookmark action
0381         //
0382         m_bookmarkMenu->setBookmarkActionEnabled(false);
0383 
0384         //
0385         // Prepare the dynamic action list for the main window
0386         //
0387         QList<QAction *> dynamicList;
0388         QList<QAction *> actionsList;
0389 
0390         if (dock == m_networkBrowserDockWidget) {
0391             actionsList = m_networkBrowserDockWidget->actionCollection()->actions();
0392         } else if (dock == m_sharesViewDockWidget) {
0393             actionsList = m_sharesViewDockWidget->actionCollection()->actions();
0394         }
0395 
0396         for (QAction *action : qAsConst(actionsList)) {
0397             if (action->objectName() == QStringLiteral("bookmark_action")) {
0398                 m_bookmarkMenu->setBookmarkActionEnabled(action->isEnabled());
0399                 connect(action, &QAction::changed, this, &Smb4KMainWindow::slotEnableBookmarkAction);
0400                 continue;
0401             } else if (action->objectName() == QStringLiteral("filemanager_action")) {
0402                 continue;
0403             } else if (action->objectName() == QStringLiteral("konsole_action")) {
0404                 continue;
0405             } else if (action->objectName() == QStringLiteral("icon_view_action")) {
0406                 continue;
0407             } else if (action->objectName() == QStringLiteral("list_view_action")) {
0408                 continue;
0409             }
0410 
0411             dynamicList << action;
0412         }
0413 
0414         //
0415         // Remove old and insert new dynamic action list
0416         //
0417         unplugActionList(QStringLiteral("dynamic_list"));
0418         plugActionList(QStringLiteral("dynamic_list"), dynamicList);
0419     }
0420 }
0421 
0422 void Smb4KMainWindow::timerEvent(QTimerEvent *event)
0423 {
0424     Q_UNUSED(event);
0425 
0426     if (!m_requestQueue.isEmpty()) {
0427         if (!m_passwordDialog->isVisible()) {
0428             NetworkItemPtr networkItem = m_requestQueue.takeFirst();
0429 
0430             if (networkItem && m_passwordDialog->setNetworkItem(networkItem)) {
0431                 m_passwordDialog->show();
0432             }
0433         }
0434     } else {
0435         killTimer(m_timerId);
0436         m_timerId = 0;
0437     }
0438 }
0439 
0440 /////////////////////////////////////////////////////////////////////////////
0441 // SLOT IMPLEMENTATIONS
0442 /////////////////////////////////////////////////////////////////////////////
0443 
0444 void Smb4KMainWindow::slotQuit()
0445 {
0446     m_quitting = true;
0447     // saveSettings();
0448     close();
0449     QCoreApplication::quit();
0450 }
0451 
0452 void Smb4KMainWindow::slotConfigDialog()
0453 {
0454     if (KConfigDialog::showDialog(QStringLiteral("ConfigDialog"))) {
0455         return;
0456     }
0457 
0458     KPluginMetaData metaData(QStringLiteral("smb4kconfigdialog"));
0459     KPluginFactory::Result<KPluginFactory> result = KPluginFactory::loadFactory(metaData);
0460 
0461     if (result.errorReason == KPluginFactory::NO_PLUGIN_ERROR) {
0462         QPointer<KConfigDialog> dlg = result.plugin->create<KConfigDialog>(this);
0463 
0464         if (dlg) {
0465             connect(dlg, &KConfigDialog::settingsChanged, this, &Smb4KMainWindow::loadSettings, Qt::UniqueConnection);
0466             connect(dlg, &KConfigDialog::settingsChanged, m_systemTrayWidget, &Smb4KSystemTray::loadSettings, Qt::UniqueConnection);
0467             dlg->show();
0468         }
0469     } else {
0470         KMessageBox::error(nullptr, result.errorString);
0471         return;
0472     }
0473 }
0474 
0475 void Smb4KMainWindow::slotAddBookmarks()
0476 {
0477     //
0478     // If we have a widget that has the focus, trigger its 'Add Bookmark'
0479     // action to add bookmarks.
0480     //
0481     if (m_focusWidget) {
0482         if (m_focusWidget == m_networkBrowserDockWidget) {
0483             QAction *action = m_networkBrowserDockWidget->actionCollection()->action(QStringLiteral("bookmark_action"));
0484 
0485             // Only trigger the action if it is enabled
0486             if (action && action->isEnabled()) {
0487                 action->trigger();
0488             }
0489         } else if (m_focusWidget == m_sharesViewDockWidget) {
0490             QAction *action = m_sharesViewDockWidget->actionCollection()->action(QStringLiteral("bookmark_action"));
0491 
0492             // Only trigger the action if it is enabled
0493             if (action && action->isEnabled()) {
0494                 action->trigger();
0495             }
0496         }
0497     }
0498 }
0499 
0500 void Smb4KMainWindow::slotWalletManagerInitialized()
0501 {
0502     if (Smb4KWalletManager::self()->useWalletSystem()) {
0503         if (KIconLoader::global()->hasIcon(QStringLiteral("kwalletmanager"))) {
0504             m_passwordIcon->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("kwalletmanager"), KIconLoader::Small, 0, KIconLoader::DefaultState));
0505         } else {
0506             m_passwordIcon->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("security-high"), KIconLoader::Small, 0, KIconLoader::DefaultState));
0507         }
0508 
0509         m_passwordIcon->setToolTip(i18n("The wallet is used."));
0510     } else {
0511         m_passwordIcon->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-password"), KIconLoader::Small, 0, KIconLoader::DefaultState));
0512         m_passwordIcon->setToolTip(i18n("The password dialog is used."));
0513     }
0514 }
0515 
0516 void Smb4KMainWindow::slotClientAboutToStart(const NetworkItemPtr &item, int process)
0517 {
0518     Q_ASSERT(item);
0519 
0520     switch (process) {
0521     case LookupDomains: {
0522         statusBar()->showMessage(i18n("Looking for workgroups and domains..."), 0);
0523         break;
0524     }
0525     case LookupDomainMembers: {
0526         WorkgroupPtr workgroup = item.staticCast<Smb4KWorkgroup>();
0527         statusBar()->showMessage(i18n("Looking for hosts in domain %1...", workgroup->workgroupName()), 0);
0528         break;
0529     }
0530     case LookupShares: {
0531         HostPtr host = item.staticCast<Smb4KHost>();
0532         statusBar()->showMessage(i18n("Looking for shares provided by host %1...", host->hostName()), 0);
0533         break;
0534     }
0535     case LookupFiles: {
0536         QString message;
0537 
0538         switch (item->type()) {
0539         case Share: {
0540             message = i18n("Looking for files and directories in %1...", item.staticCast<Smb4KShare>()->displayString());
0541             break;
0542         }
0543         case FileOrDirectory: {
0544             FilePtr file = item.staticCast<Smb4KFile>();
0545 
0546             for (const SharePtr &share : sharesList()) {
0547                 // FIXME: Use QUrl::matches() here. Additionally, we do not really need the workgroup.
0548                 if (share->workgroupName() == file->workgroupName() && share->hostName() == file->hostName() && share->shareName() == file->shareName()) {
0549                     message = i18n("Looking for files and directories in %1...", share->displayString());
0550                     break;
0551                 }
0552             }
0553 
0554             break;
0555         }
0556         default: {
0557             break;
0558         }
0559         }
0560 
0561         statusBar()->showMessage(message, 0);
0562 
0563         break;
0564     }
0565     case WakeUp: {
0566         statusBar()->showMessage(i18n("Waking up remote hosts..."), 0);
0567         break;
0568     }
0569     case PrintFile: {
0570         SharePtr share = item.staticCast<Smb4KShare>();
0571         statusBar()->showMessage(i18n("Sending file to printer %1...", share->displayString()), 0);
0572         break;
0573     }
0574     case NetworkSearch: {
0575         statusBar()->showMessage(i18n("Searching..."), 0);
0576         break;
0577     }
0578     default: {
0579         break;
0580     }
0581     }
0582 
0583     if (!m_progressBar->isVisible()) {
0584         m_progressBar->setVisible(true);
0585     }
0586 }
0587 
0588 void Smb4KMainWindow::slotClientFinished(const NetworkItemPtr &item, int process)
0589 {
0590     Q_UNUSED(item);
0591     Q_UNUSED(process);
0592 
0593     if (!Smb4KClient::self()->isRunning() && !Smb4KMounter::self()->isRunning() && !Smb4KSynchronizer::self()->isRunning()) {
0594         m_progressBar->setVisible(false);
0595         m_progressBar->reset();
0596         statusBar()->showMessage(i18n("Done."), 2000);
0597     }
0598 }
0599 
0600 void Smb4KMainWindow::slotMounterAboutToStart(int process)
0601 {
0602     // Tell the user which action is performed by the mounter:
0603     // mounting, unmounting or waking up.
0604     switch (process) {
0605     case MountShare: {
0606         statusBar()->showMessage(i18n("Mounting..."), 0);
0607         break;
0608     }
0609     case UnmountShare: {
0610         statusBar()->showMessage(i18n("Unmounting..."), 0);
0611         break;
0612     }
0613     case WakeUp: {
0614         statusBar()->showMessage(i18n("Waking up host..."), 0);
0615         break;
0616     }
0617     default: {
0618         break;
0619     }
0620     }
0621 
0622     if (!m_progressBar->isVisible()) {
0623         m_progressBar->setVisible(true);
0624     }
0625 }
0626 
0627 void Smb4KMainWindow::slotMounterFinished(int process)
0628 {
0629     Q_UNUSED(process);
0630 
0631     QTimer::singleShot(250, this, [&]() {
0632         if (!Smb4KClient::self()->isRunning() && !Smb4KMounter::self()->isRunning() && !Smb4KSynchronizer::self()->isRunning()) {
0633             m_progressBar->setVisible(false);
0634             m_progressBar->reset();
0635             statusBar()->showMessage(i18n("Done."), 2000);
0636         }
0637     });
0638 }
0639 
0640 void Smb4KMainWindow::slotVisualMountFeedback(const SharePtr &share)
0641 {
0642     if (share) {
0643         m_feedbackIcon->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-ok"), KIconLoader::Small, 0, KIconLoader::DefaultState));
0644         m_feedbackIcon->setToolTip(i18n("%1 has been mounted successfully.", share->displayString()));
0645 
0646         QList<QTabBar *> list = findChildren<QTabBar *>();
0647 
0648         for (int i = 0; i < list.size(); ++i) {
0649             if (list.at(i)->count() != 0) {
0650                 for (int j = 0; j < list.at(i)->count(); ++j) {
0651                     if (QString::compare(m_sharesViewDockWidget->windowTitle(), list.at(i)->tabText(j)) == 0 && list.at(i)->currentIndex() != j) {
0652                         list.at(i)->setTabTextColor(j, palette().highlightedText().color());
0653                         break;
0654                     }
0655                 }
0656             }
0657         }
0658 
0659         QTimer::singleShot(2000, this, &Smb4KMainWindow::slotEndVisualFeedback);
0660     }
0661 }
0662 
0663 void Smb4KMainWindow::slotVisualUnmountFeedback(const SharePtr &share)
0664 {
0665     if (share) {
0666         m_feedbackIcon->setPixmap(KIconLoader::global()->loadIcon(QStringLiteral("dialog-ok"), KIconLoader::Small, 0, KIconLoader::DefaultState));
0667         m_feedbackIcon->setToolTip(i18n("%1 has been unmounted successfully.", share->displayString()));
0668 
0669         QList<QTabBar *> list = findChildren<QTabBar *>();
0670 
0671         for (int i = 0; i < list.size(); ++i) {
0672             if (list.at(i)->count() != 0) {
0673                 for (int j = 0; j < list.at(i)->count(); ++j) {
0674                     if (QString::compare(m_sharesViewDockWidget->windowTitle(), list.at(i)->tabText(j)) == 0 && list.at(i)->currentIndex() != j) {
0675                         list.at(i)->setTabTextColor(j, palette().highlightedText().color());
0676                         break;
0677                     }
0678                 }
0679             }
0680         }
0681 
0682         QTimer::singleShot(2000, this, &Smb4KMainWindow::slotEndVisualFeedback);
0683     }
0684 }
0685 
0686 void Smb4KMainWindow::slotEndVisualFeedback()
0687 {
0688     QList<QTabBar *> list = findChildren<QTabBar *>();
0689 
0690     for (int i = 0; i < list.size(); ++i) {
0691         if (list.at(i)->count() != 0) {
0692             for (int j = 0; j < list.at(i)->count(); ++j) {
0693                 if (QString::compare(m_sharesViewDockWidget->windowTitle(), list.at(i)->tabText(j)) == 0) {
0694                     list.at(i)->setTabTextColor(j, palette().text().color());
0695                     break;
0696                 }
0697             }
0698         }
0699     }
0700 
0701     setupMountIndicator();
0702 }
0703 
0704 void Smb4KMainWindow::slotSynchronizerAboutToStart(const QString &destination)
0705 {
0706     statusBar()->showMessage(i18n("Synchronizing %1", destination), 0);
0707 
0708     if (!m_progressBar->isVisible()) {
0709         m_progressBar->setVisible(true);
0710     }
0711 }
0712 
0713 void Smb4KMainWindow::slotSynchronizerFinished(const QString &destination)
0714 {
0715     Q_UNUSED(destination);
0716 
0717     if (!Smb4KClient::self()->isRunning() && !Smb4KMounter::self()->isRunning() && !Smb4KSynchronizer::self()->isRunning()) {
0718         m_progressBar->setVisible(false);
0719         m_progressBar->reset();
0720         statusBar()->showMessage(i18n("Done."), 2000);
0721     }
0722 }
0723 
0724 void Smb4KMainWindow::slotEnableBookmarkAction()
0725 {
0726     //
0727     // Get the focused widget's 'Add Bookmark' action and read its
0728     // isEnabled() property. Set the action of the main window and the
0729     // bookmark menu respectively.
0730     //
0731     if (m_focusWidget) {
0732         if (m_focusWidget == m_networkBrowserDockWidget) {
0733             QAction *action = m_networkBrowserDockWidget->actionCollection()->action(QStringLiteral("bookmark_action"));
0734 
0735             if (action) {
0736                 // Bookmark action of the main window
0737                 actionCollection()->action(QStringLiteral("bookmark_action"))->setEnabled(action->isEnabled());
0738 
0739                 // Bookmark action of the bookmark menu
0740                 m_bookmarkMenu->setBookmarkActionEnabled(action->isEnabled());
0741             }
0742         } else if (m_focusWidget == m_sharesViewDockWidget) {
0743             QAction *action = m_sharesViewDockWidget->actionCollection()->action(QStringLiteral("bookmark_action"));
0744 
0745             if (action) {
0746                 // Bookmark action of the main window
0747                 actionCollection()->action(QStringLiteral("bookmark_action"))->setEnabled(action->isEnabled());
0748 
0749                 // Bookmark action of the bookmark menu
0750                 m_bookmarkMenu->setBookmarkActionEnabled(action->isEnabled());
0751             }
0752         }
0753     }
0754 }
0755 
0756 void Smb4KMainWindow::slotNetworkBrowserVisibilityChanged(bool visible)
0757 {
0758     if (visible) {
0759         m_networkBrowserDockWidget->widget()->setFocus();
0760     } else {
0761         m_networkBrowserDockWidget->widget()->clearFocus();
0762     }
0763 }
0764 
0765 void Smb4KMainWindow::slotSharesViewVisibilityChanged(bool visible)
0766 {
0767     if (visible) {
0768         m_sharesViewDockWidget->widget()->setFocus();
0769     } else {
0770         m_sharesViewDockWidget->widget()->clearFocus();
0771     }
0772 }
0773 
0774 void Smb4KMainWindow::slotCredentialsRequested(const NetworkItemPtr &networkItem)
0775 {
0776     m_requestQueue.append(networkItem);
0777 
0778     if (m_timerId == 0) {
0779         m_timerId = startTimer(500);
0780     }
0781 }