File indexing completed on 2024-04-21 15:42:57

0001 /***************************************************************************
0002     smb4ksharesmenu  -  Shares menu
0003                              -------------------
0004     begin                : Mon Sep 05 2011
0005     copyright            : (C) 2011-2019 by Alexander Reinholdt
0006     email                : alexander.reinholdt@kdemail.net
0007  ***************************************************************************/
0008 
0009 /***************************************************************************
0010  *   This program is free software; you can redistribute it and/or modify  *
0011  *   it under the terms of the GNU General Public License as published by  *
0012  *   the Free Software Foundation; either version 2 of the License, or     *
0013  *   (at your option) any later version.                                   *
0014  *                                                                         *
0015  *   This program is distributed in the hope that it will be useful, but   *
0016  *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
0017  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
0018  *   General Public License for more details.                              *
0019  *                                                                         *
0020  *   You should have received a copy of the GNU General Public License     *
0021  *   along with this program; if not, write to the                         *
0022  *   Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston,*
0023  *   MA 02110-1335, USA                                                    *
0024  ***************************************************************************/
0025 
0026 #ifdef HAVE_CONFIG_H
0027 #include <config.h>
0028 #endif
0029 
0030 // application specific includes
0031 #include "smb4ksharesmenu.h"
0032 #include "core/smb4kshare.h"
0033 #include "core/smb4kmounter.h"
0034 #include "core/smb4kglobal.h"
0035 #include "core/smb4ksynchronizer.h"
0036 #include "core/smb4kbookmarkhandler.h"
0037 
0038 #if defined(Q_OS_LINUX)
0039 #include "smb4kmountsettings_linux.h"
0040 #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
0041 #include "smb4kmountsettings_bsd.h"
0042 #endif
0043 
0044 // Qt includes
0045 #include <QMap>
0046 #include <QVariant>
0047 #include <QString>
0048 #include <QStringList>
0049 #include <QStandardPaths>
0050 #include <QMenu>
0051 
0052 // KDE includes
0053 #include <KIconThemes/KIconLoader>
0054 #include <KI18n/KLocalizedString>
0055 
0056 using namespace Smb4KGlobal;
0057 
0058 
0059 Smb4KSharesMenu::Smb4KSharesMenu(QWidget *parentWidget, QObject *parent)
0060 : KActionMenu(KDE::icon("folder-network", QStringList("emblem-mounted")), i18n("Mounted Shares"), parent),
0061   m_parent_widget(parentWidget)
0062 {
0063   // 
0064   // Set up action group for the shares menus
0065   // 
0066   m_menus = new QActionGroup(menu());
0067 
0068   // 
0069   // Set up action group for the shares actions
0070   // 
0071   m_actions = new QActionGroup(menu());
0072 
0073   // 
0074   // Setup the menu
0075   // 
0076   setupMenu();
0077 
0078   //
0079   // Connections
0080   // 
0081   connect(m_actions, SIGNAL(triggered(QAction*)), SLOT(slotShareAction(QAction*)));
0082   connect(Smb4KMounter::self(), SIGNAL(mountedSharesListChanged()), SLOT(slotMountedSharesListChanged()));
0083 }
0084 
0085 
0086 Smb4KSharesMenu::~Smb4KSharesMenu()
0087 {
0088 }
0089 
0090 
0091 void Smb4KSharesMenu::refreshMenu()
0092 {
0093   //
0094   // Delete all entries from the menu
0095   //
0096   while (!menu()->actions().isEmpty())
0097   {
0098     QAction *action = menu()->actions().takeFirst();
0099     removeAction(action);
0100     delete action;
0101   }
0102   
0103   //
0104   // Clear the rest of the menu
0105   //
0106   if (!menu()->isEmpty())
0107   {
0108     menu()->clear();
0109   }
0110   
0111   //
0112   // Set up the menu
0113   // 
0114   setupMenu();
0115   
0116   //
0117   // Make sure the correct menu entries are shown
0118   //
0119   menu()->update();
0120 }
0121 
0122 
0123 void Smb4KSharesMenu::setupMenu()
0124 {
0125   //
0126   // Add the Unmount All action
0127   //
0128   QAction *unmount_all = new QAction(KDE::icon("system-run"), i18n("U&nmount All"), menu());
0129   unmount_all->setEnabled(false);
0130   connect(unmount_all, SIGNAL(triggered(bool)), SLOT(slotUnmountAllShares()));
0131   addAction(unmount_all);
0132 
0133   // 
0134   // Add a separator
0135   //
0136   addSeparator();
0137 
0138   //
0139   // Add the share entries
0140   // 
0141   QStringList displayNames;
0142   
0143   for (const SharePtr &share : mountedSharesList())
0144   {
0145     // Do not process null pointers
0146     if (!share)
0147     {
0148       continue;
0149     }
0150     
0151     // Add the display name to the list
0152     displayNames << share->displayString();
0153     
0154     // Create the share menu
0155     KActionMenu *shareMenu = new KActionMenu(share->displayString(), menu());
0156     shareMenu->setIcon(share->icon());
0157     
0158     QMap<QString,QVariant> data;
0159     data["text"] = share->displayString();
0160     
0161     shareMenu->setData(data);
0162     m_menus->addAction(shareMenu);
0163     
0164     // Add the unmount action to the menu
0165     QAction *unmount = new QAction(KDE::icon("media-eject"), i18n("Unmount"), shareMenu->menu());
0166     
0167     QMap<QString,QVariant> unmountData;
0168     unmountData["type"] = "unmount";
0169     unmountData["mountpoint"] = share->path();
0170     
0171     unmount->setData(unmountData);
0172     unmount->setEnabled(!share->isForeign() || Smb4KMountSettings::unmountForeignShares());
0173     shareMenu->addAction(unmount);
0174     m_actions->addAction(unmount);
0175     
0176     // Add a separator
0177     shareMenu->addSeparator();
0178     
0179     // Add the bookmark action to the menu
0180     QAction *addBookmark = new QAction(KDE::icon("bookmark-new"), i18n("Add Bookmark"), shareMenu->menu());
0181     
0182     QMap<QString,QVariant> bookmarkData;
0183     bookmarkData["type"] = "bookmark";
0184     bookmarkData["mountpoint"] = share->path();
0185     
0186     addBookmark->setData(bookmarkData);
0187     shareMenu->addAction(addBookmark);
0188     m_actions->addAction(addBookmark);
0189     
0190     // Add the synchronization action to the menu
0191     QAction *synchronize = new QAction(KDE::icon("folder-sync"), i18n("Synchronize"), shareMenu->menu());
0192     
0193     QMap<QString,QVariant> syncData;
0194     syncData["type"] = "sync";
0195     syncData["mountpoint"] = share->path();
0196     
0197     synchronize->setData(syncData);
0198     synchronize->setEnabled(!QStandardPaths::findExecutable("rsync").isEmpty() && !share->isInaccessible());
0199     shareMenu->addAction(synchronize);
0200     m_actions->addAction(synchronize);
0201     
0202     // Add a separator
0203     shareMenu->addSeparator();
0204     
0205     // Add the Open with Konsole action to the menu
0206     QAction *konsole = new QAction(KDE::icon("utilities-terminal"), i18n("Open with Konsole"), shareMenu->menu());
0207     
0208     QMap<QString,QVariant> konsoleData;
0209     konsoleData["type"] = "konsole";
0210     konsoleData["mountpoint"] = share->path();
0211     
0212     konsole->setData(konsoleData);
0213     konsole->setEnabled(!QStandardPaths::findExecutable("konsole").isEmpty() && !share->isInaccessible());
0214     shareMenu->addAction(konsole);
0215     m_actions->addAction(konsole);
0216     
0217     // Add the Open with Filemanager action to the menu
0218     QAction *filemanager = new QAction(KDE::icon("system-file-manager"), i18n("Open with File Manager"), shareMenu->menu());
0219     
0220     QMap<QString,QVariant> fmData;
0221     fmData["type"] = "filemanager";
0222     fmData["mountpoint"] = share->path();
0223     
0224     filemanager->setData(fmData);
0225     filemanager->setEnabled(!share->isInaccessible());
0226     shareMenu->addAction(filemanager);
0227     m_actions->addAction(filemanager);
0228   }
0229   
0230   //
0231   // Sort the display names and add the share menus to the menu
0232   // in the sorted order.
0233   // 
0234   displayNames.sort();
0235   
0236   for (const QString &name : displayNames)
0237   {
0238     for (QAction *action : m_menus->actions())
0239     {
0240       if (action->data().toMap().value("text").toString() == name)
0241       {
0242         addAction(action);
0243         break;
0244       }
0245     }
0246   }
0247   
0248   //
0249   // Enable or disable the Unmount All action, depending on the number of 
0250   // mounted shares present.
0251   //
0252   unmount_all->setEnabled(((!onlyForeignMountedShares() || Smb4KMountSettings::unmountForeignShares()) && !m_menus->actions().isEmpty()));
0253 }
0254 
0255 
0256 /////////////////////////////////////////////////////////////////////////////
0257 // SLOT IMPLEMENTATIONS
0258 /////////////////////////////////////////////////////////////////////////////
0259 
0260 void Smb4KSharesMenu::slotMountedSharesListChanged()
0261 {
0262   //
0263   // Refresh the menu
0264   //
0265   refreshMenu();
0266 }
0267 
0268 
0269 void Smb4KSharesMenu::slotUnmountAllShares()
0270 {
0271   Smb4KMounter::self()->unmountAllShares(false);
0272 }
0273 
0274 
0275 void Smb4KSharesMenu::slotShareAction(QAction *action)
0276 {
0277   //
0278   // Create a share
0279   //
0280   SharePtr share;
0281   
0282   // 
0283   // Check that we have a share related action
0284   // 
0285   if (action->data().toMap().contains("type"))
0286   {
0287     share = findShareByPath(action->data().toMap().value("mountpoint").toString());
0288   }
0289   
0290   //
0291   // Now process the action
0292   //
0293   if (share)
0294   {
0295     QString type = action->data().toMap().value("type").toString();
0296     QString mountpoint = action->data().toMap().value("mountpoint").toString();
0297     
0298     if (type == "unmount")
0299     {
0300       Smb4KMounter::self()->unmountShare(share, false);
0301     }
0302     else if (type == "bookmark")
0303     {
0304       Smb4KBookmarkHandler::self()->addBookmark(share);
0305     }
0306     else if (type == "sync")
0307     {
0308       Smb4KSynchronizer::self()->synchronize(share);
0309     }
0310     else if (type == "konsole")
0311     {
0312       openShare(share, Smb4KGlobal::Konsole);
0313     }
0314     else if (type == "filemanager")
0315     {
0316       openShare(share, Smb4KGlobal::FileManager);
0317     }
0318   }
0319 }
0320