File indexing completed on 2023-12-03 05:04:25

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