File indexing completed on 2023-11-26 04:58:11
0001 /* 0002 smb4ksharesmenu - Shares menu 0003 0004 SPDX-FileCopyrightText: 2011-2022 Alexander Reinholdt <alexander.reinholdt@kdemail.net> 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 // application specific includes 0009 #include "smb4ksharesmenu.h" 0010 #include "core/smb4kbookmarkhandler.h" 0011 #include "core/smb4kcustomoptionsmanager.h" 0012 #include "core/smb4kglobal.h" 0013 #include "core/smb4kmounter.h" 0014 #include "core/smb4kshare.h" 0015 #include "core/smb4ksynchronizer.h" 0016 #include "smb4kbookmarkdialog.h" 0017 #include "smb4kcustomsettingseditor.h" 0018 #include "smb4kpreviewdialog.h" 0019 #include "smb4ksynchronizationdialog.h" 0020 0021 #if defined(Q_OS_LINUX) 0022 #include "smb4kmountsettings_linux.h" 0023 #elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) 0024 #include "smb4kmountsettings_bsd.h" 0025 #endif 0026 0027 // Qt includes 0028 #include <QMap> 0029 #include <QMenu> 0030 #include <QPointer> 0031 #include <QStandardPaths> 0032 #include <QString> 0033 #include <QStringList> 0034 #include <QVariant> 0035 0036 // KDE includes 0037 #include <KIconLoader> 0038 #include <KLocalizedString> 0039 0040 using namespace Smb4KGlobal; 0041 0042 Smb4KSharesMenu::Smb4KSharesMenu(QObject *parent) 0043 : KActionMenu(KDE::icon(QStringLiteral("folder-network"), QStringList(QStringLiteral("emblem-mounted"))), i18n("Mounted Shares"), parent) 0044 { 0045 // 0046 // Set up action group for the shares menus 0047 // 0048 m_menus = new QActionGroup(menu()); 0049 0050 // 0051 // Set up action group for the shares actions 0052 // 0053 m_actions = new QActionGroup(menu()); 0054 0055 // 0056 // Add the Unmount All action 0057 // 0058 m_unmountAll = new QAction(KDE::icon(QStringLiteral("system-run")), i18n("U&nmount All"), menu()); 0059 m_unmountAll->setEnabled(false); 0060 connect(m_unmountAll, SIGNAL(triggered(bool)), SLOT(slotUnmountAllShares())); 0061 addAction(m_unmountAll); 0062 0063 // 0064 // Add the separator 0065 // 0066 m_separator = addSeparator(); 0067 0068 // 0069 // Connections 0070 // 0071 connect(m_actions, SIGNAL(triggered(QAction *)), SLOT(slotShareAction(QAction *))); 0072 0073 connect(Smb4KMounter::self(), SIGNAL(mounted(SharePtr)), SLOT(slotShareMounted(SharePtr))); 0074 connect(Smb4KMounter::self(), SIGNAL(unmounted(SharePtr)), SLOT(slotShareUnmounted(SharePtr))); 0075 connect(Smb4KMounter::self(), SIGNAL(mountedSharesListChanged()), SLOT(slotMountedSharesListChanged())); 0076 } 0077 0078 Smb4KSharesMenu::~Smb4KSharesMenu() 0079 { 0080 } 0081 0082 void Smb4KSharesMenu::refreshMenu() 0083 { 0084 // 0085 // Delete all shares from the menu 0086 // 0087 while (!m_menus->actions().isEmpty()) { 0088 QAction *shareMenu = m_menus->actions().takeFirst(); 0089 removeAction(shareMenu); 0090 delete shareMenu; 0091 } 0092 0093 // 0094 // Add share menus, if necessary 0095 // 0096 if (!mountedSharesList().isEmpty()) { 0097 for (const SharePtr &share : mountedSharesList()) { 0098 addShareToMenu(share); 0099 } 0100 } 0101 0102 // 0103 // Make the separator visible, if necessary 0104 // 0105 m_separator->setVisible(!m_menus->actions().isEmpty()); 0106 0107 // 0108 // Enable or disable the Unmount All action, depending on the number of 0109 // mounted shares present. 0110 // 0111 m_unmountAll->setEnabled(((!onlyForeignMountedShares() || Smb4KMountSettings::unmountForeignShares()) && !m_menus->actions().isEmpty())); 0112 0113 // 0114 // Make sure the correct menu entries are shown 0115 // 0116 menu()->update(); 0117 0118 // 0119 // Work around a display glitch were the first bookmark 0120 // might not be shown (see also BUG 442187) 0121 // 0122 menu()->adjustSize(); 0123 QCoreApplication::processEvents(); 0124 } 0125 0126 void Smb4KSharesMenu::addShareToMenu(const SharePtr &share) 0127 { 0128 // 0129 // For sorting purposes, get the display strings of all 0130 // shares that are already in the action menu. 0131 // 0132 QStringList displayNames; 0133 0134 for (QAction *entry : m_menus->actions()) { 0135 displayNames << entry->data().toMap().value(QStringLiteral("text")).toString(); 0136 } 0137 0138 // 0139 // Add the display string of the current share as well 0140 // 0141 displayNames << share->displayString(); 0142 0143 // 0144 // Sort the display strings 0145 // 0146 displayNames.sort(); 0147 0148 // 0149 // Create the share menu 0150 // 0151 KActionMenu *shareMenu = new KActionMenu(share->displayString(), menu()); 0152 shareMenu->setIcon(share->icon()); 0153 0154 QMap<QString, QVariant> data; 0155 data[QStringLiteral("text")] = share->displayString(); 0156 data[QStringLiteral("mountpoint")] = share->path(); 0157 0158 shareMenu->setData(data); 0159 m_menus->addAction(shareMenu); 0160 0161 // 0162 // Add the unmount action to the menu 0163 // 0164 QAction *unmount = new QAction(KDE::icon(QStringLiteral("media-eject")), i18n("Unmount"), shareMenu->menu()); 0165 0166 QMap<QString, QVariant> unmountData; 0167 unmountData[QStringLiteral("type")] = QStringLiteral("unmount"); 0168 unmountData[QStringLiteral("mountpoint")] = share->path(); 0169 0170 unmount->setData(unmountData); 0171 unmount->setEnabled(!share->isForeign() || Smb4KMountSettings::unmountForeignShares()); 0172 shareMenu->addAction(unmount); 0173 m_actions->addAction(unmount); 0174 0175 // 0176 // Add a separator 0177 // 0178 shareMenu->addSeparator(); 0179 0180 // 0181 // Add the bookmark action to the menu 0182 // 0183 QAction *addBookmark = new QAction(KDE::icon(QStringLiteral("bookmark-new")), i18n("Add Bookmark"), shareMenu->menu()); 0184 0185 QMap<QString, QVariant> bookmarkData; 0186 bookmarkData[QStringLiteral("type")] = QStringLiteral("bookmark"); 0187 bookmarkData[QStringLiteral("mountpoint")] = share->path(); 0188 0189 addBookmark->setData(bookmarkData); 0190 shareMenu->addAction(addBookmark); 0191 m_actions->addAction(addBookmark); 0192 0193 // 0194 // Add the custom options action to the menau 0195 // 0196 QAction *addCustomOptions = new QAction(KDE::icon(QStringLiteral("settings-configure")), i18n("Add &Custom Settings"), shareMenu->menu()); 0197 0198 QMap<QString, QVariant> customOptionsData; 0199 customOptionsData[QStringLiteral("type")] = QStringLiteral("options"); 0200 customOptionsData[QStringLiteral("mountpoint")] = share->path(); 0201 0202 addCustomOptions->setData(customOptionsData); 0203 shareMenu->addAction(addCustomOptions); 0204 m_actions->addAction(addCustomOptions); 0205 0206 // 0207 // Add the synchronization action to the menu 0208 // 0209 QAction *synchronize = new QAction(KDE::icon(QStringLiteral("folder-sync")), i18n("Synchronize"), shareMenu->menu()); 0210 0211 QMap<QString, QVariant> syncData; 0212 syncData[QStringLiteral("type")] = QStringLiteral("sync"); 0213 syncData[QStringLiteral("mountpoint")] = share->path(); 0214 0215 synchronize->setData(syncData); 0216 synchronize->setEnabled(!QStandardPaths::findExecutable(QStringLiteral("rsync")).isEmpty() && !share->isInaccessible()); 0217 shareMenu->addAction(synchronize); 0218 m_actions->addAction(synchronize); 0219 0220 // 0221 // Add a separator 0222 // 0223 shareMenu->addSeparator(); 0224 0225 // 0226 // Add the Open with Konsole action to the menu 0227 // 0228 QAction *konsole = new QAction(KDE::icon(QStringLiteral("utilities-terminal")), i18n("Open with Konsole"), shareMenu->menu()); 0229 0230 QMap<QString, QVariant> konsoleData; 0231 konsoleData[QStringLiteral("type")] = QStringLiteral("konsole"); 0232 konsoleData[QStringLiteral("mountpoint")] = share->path(); 0233 0234 konsole->setData(konsoleData); 0235 konsole->setEnabled(!QStandardPaths::findExecutable(QStringLiteral("konsole")).isEmpty() && !share->isInaccessible()); 0236 shareMenu->addAction(konsole); 0237 m_actions->addAction(konsole); 0238 0239 // 0240 // Add the Open with Filemanager action to the menu 0241 // 0242 QAction *filemanager = new QAction(KDE::icon(QStringLiteral("system-file-manager")), i18n("Open with File Manager"), shareMenu->menu()); 0243 0244 QMap<QString, QVariant> fileManagerData; 0245 fileManagerData[QStringLiteral("type")] = QStringLiteral("filemanager"); 0246 fileManagerData[QStringLiteral("mountpoint")] = share->path(); 0247 0248 filemanager->setData(fileManagerData); 0249 filemanager->setEnabled(!share->isInaccessible()); 0250 shareMenu->addAction(filemanager); 0251 m_actions->addAction(filemanager); 0252 0253 // 0254 // Add the share menu to the action menu at the right place 0255 // 0256 if (displayNames.size() == 1) { 0257 addAction(shareMenu); 0258 } else { 0259 int index = displayNames.indexOf(share->displayString(), 0); 0260 0261 if (index != displayNames.size() - 1) { 0262 QString displayStringBefore = displayNames.at(index + 1); 0263 0264 for (QAction *action : m_menus->actions()) { 0265 if (action->data().toMap().value(QStringLiteral("text")).toString() == displayStringBefore) { 0266 insertAction(action, shareMenu); 0267 break; 0268 } 0269 } 0270 } else { 0271 addAction(shareMenu); 0272 } 0273 } 0274 } 0275 0276 void Smb4KSharesMenu::removeShareFromMenu(const SharePtr &share) 0277 { 0278 // 0279 // Remove the share from the action group and the menu and delete 0280 // it. We do not need to take care of the actions in the menu. They 0281 // are delete with their parent. 0282 // 0283 for (int i = 0; i < m_menus->actions().size(); ++i) { 0284 if (m_menus->actions().at(i)->data().toMap().value(QStringLiteral("mountpoint")).toString() == share->path()) { 0285 QAction *menuAction = m_menus->actions().takeAt(i); 0286 removeAction(menuAction); 0287 delete menuAction; 0288 break; 0289 } 0290 } 0291 } 0292 0293 ///////////////////////////////////////////////////////////////////////////// 0294 // SLOT IMPLEMENTATIONS 0295 ///////////////////////////////////////////////////////////////////////////// 0296 0297 void Smb4KSharesMenu::slotShareMounted(const SharePtr &share) 0298 { 0299 addShareToMenu(share); 0300 } 0301 0302 void Smb4KSharesMenu::slotShareUnmounted(const SharePtr &share) 0303 { 0304 removeShareFromMenu(share); 0305 } 0306 0307 void Smb4KSharesMenu::slotUnmountAllShares() 0308 { 0309 // 0310 // Unmount all shares 0311 // 0312 Smb4KMounter::self()->unmountAllShares(false); 0313 } 0314 0315 void Smb4KSharesMenu::slotMountedSharesListChanged() 0316 { 0317 // 0318 // Enable or disable the Unmount All action 0319 // 0320 m_unmountAll->setEnabled(((!onlyForeignMountedShares() || Smb4KMountSettings::unmountForeignShares()) && !m_menus->actions().isEmpty())); 0321 0322 // 0323 // Make the separator visible, if necessary 0324 // 0325 m_separator->setVisible(!m_menus->actions().isEmpty()); 0326 0327 // 0328 // Make sure the correct menu entries are shown 0329 // 0330 menu()->update(); 0331 0332 // 0333 // Work around a display glitch were the first bookmark 0334 // might not be shown (see also BUG 442187) 0335 // 0336 menu()->adjustSize(); 0337 QCoreApplication::processEvents(); 0338 } 0339 0340 void Smb4KSharesMenu::slotShareAction(QAction *action) 0341 { 0342 // 0343 // Create a share 0344 // 0345 SharePtr share; 0346 0347 // 0348 // Check that we have a share related action 0349 // 0350 if (action->data().toMap().contains(QStringLiteral("type"))) { 0351 share = findShareByPath(action->data().toMap().value(QStringLiteral("mountpoint")).toString()); 0352 } 0353 0354 // 0355 // Now process the action 0356 // 0357 if (share) { 0358 QString type = action->data().toMap().value(QStringLiteral("type")).toString(); 0359 0360 if (type == QStringLiteral("unmount")) { 0361 Smb4KMounter::self()->unmountShare(share, false); 0362 } else if (type == QStringLiteral("bookmark")) { 0363 QPointer<Smb4KBookmarkDialog> bookmarkDialog = new Smb4KBookmarkDialog(); 0364 if (bookmarkDialog->setShares(QList<SharePtr>({share}))) { 0365 bookmarkDialog->open(); 0366 } else { 0367 delete bookmarkDialog; 0368 } 0369 } else if (type == QStringLiteral("options")) { 0370 QPointer<Smb4KCustomSettingsEditor> customSettingsEditor = new Smb4KCustomSettingsEditor(); 0371 if (customSettingsEditor->setNetworkItem(share)) { 0372 customSettingsEditor->open(); 0373 } else { 0374 delete customSettingsEditor; 0375 } 0376 } else if (type == QStringLiteral("sync")) { 0377 QPointer<Smb4KSynchronizationDialog> synchronizationDialog = new Smb4KSynchronizationDialog(); 0378 if (synchronizationDialog->setShare(share)) { 0379 synchronizationDialog->open(); 0380 } else { 0381 delete synchronizationDialog; 0382 } 0383 } else if (type == QStringLiteral("konsole")) { 0384 openShare(share, Smb4KGlobal::Konsole); 0385 } else if (type == QStringLiteral("filemanager")) { 0386 openShare(share, Smb4KGlobal::FileManager); 0387 } 0388 } 0389 }