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