File indexing completed on 2023-10-01 08:44:24
0001 /*************************************************************************** 0002 smb4kbookmarkmenu - Bookmark menu 0003 ------------------- 0004 begin : Sat Apr 02 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 "smb4kbookmarkmenu.h" 0032 #include "core/smb4kbookmark.h" 0033 #include "core/smb4kshare.h" 0034 #include "core/smb4kbookmarkhandler.h" 0035 #include "core/smb4kmounter.h" 0036 #include "core/smb4ksettings.h" 0037 #include "core/smb4kglobal.h" 0038 0039 // Qt includes 0040 #include <QDebug> 0041 #include <QMenu> 0042 #include <QLatin1String> 0043 0044 // KDE includes 0045 #include <KIconThemes/KIconLoader> 0046 #include <KI18n/KLocalizedString> 0047 0048 using namespace Smb4KGlobal; 0049 0050 0051 Smb4KBookmarkMenu::Smb4KBookmarkMenu(int type, QWidget *parentWidget, QObject *parent) 0052 : KActionMenu(KDE::icon("folder-favorites"), i18n("Bookmarks"), parent), m_type(type), 0053 m_parent_widget(parentWidget) 0054 { 0055 // 0056 // Set up the action group for the actions 0057 // 0058 m_actions = new QActionGroup(menu()); 0059 0060 // 0061 // Set up the action group for the bookmarks 0062 // 0063 m_bookmarks = new QActionGroup(menu()); 0064 0065 // Set up the menu 0066 setupMenu(); 0067 0068 // Connections 0069 connect(Smb4KBookmarkHandler::self(), SIGNAL(updated()), SLOT(slotBookmarksUpdated())); 0070 connect(Smb4KMounter::self(), SIGNAL(mounted(SharePtr)), SLOT(slotEnableBookmark(SharePtr))); 0071 connect(Smb4KMounter::self(), SIGNAL(unmounted(SharePtr)), SLOT(slotEnableBookmark(SharePtr))); 0072 connect(m_actions, SIGNAL(triggered(QAction*)), SLOT(slotGroupActionTriggered(QAction*))); 0073 connect(m_bookmarks, SIGNAL(triggered(QAction*)), SLOT(slotBookmarkActionTriggered(QAction*))); 0074 } 0075 0076 0077 Smb4KBookmarkMenu::~Smb4KBookmarkMenu() 0078 { 0079 } 0080 0081 0082 void Smb4KBookmarkMenu::refreshMenu() 0083 { 0084 // 0085 // Delete all entries from the menu 0086 // 0087 while (!menu()->actions().isEmpty()) 0088 { 0089 QAction *action = menu()->actions().takeFirst(); 0090 removeAction(action); 0091 delete action; 0092 } 0093 0094 // 0095 // Clear the rest of the menu 0096 // 0097 if (!menu()->isEmpty()) 0098 { 0099 menu()->clear(); 0100 } 0101 0102 // 0103 // Set up the menu 0104 // 0105 setupMenu(); 0106 0107 // 0108 // Make sure the correct menu entries are shown 0109 // 0110 menu()->update(); 0111 } 0112 0113 0114 void Smb4KBookmarkMenu::setBookmarkActionEnabled(bool enable) 0115 { 0116 QAction *action = menu()->findChild<QAction *>("add_action"); 0117 0118 if (action) 0119 { 0120 action->setEnabled(enable); 0121 } 0122 } 0123 0124 0125 void Smb4KBookmarkMenu::setupMenu() 0126 { 0127 // 0128 // Depending on the type chosen, some global actions need to be inserted 0129 // into the menu. These actions are always enabled. 0130 // 0131 switch (m_type) 0132 { 0133 case MainWindow: 0134 { 0135 QAction *editBookmarksAction = new QAction(KDE::icon("bookmarks-organize"), i18n("&Edit Bookmarks"), menu()); 0136 editBookmarksAction->setObjectName("edit_action"); 0137 QMap<QString,QVariant> editInfo; 0138 editInfo["type"] = "edit"; 0139 editBookmarksAction->setData(editInfo); 0140 connect(editBookmarksAction, SIGNAL(triggered(bool)), SLOT(slotEditActionTriggered(bool))); 0141 addAction(editBookmarksAction); 0142 m_actions->addAction(editBookmarksAction); 0143 0144 QAction *addBookmarkAction = new QAction(KDE::icon("bookmark-new"), i18n("Add &Bookmark"), menu()); 0145 addBookmarkAction->setObjectName("add_action"); 0146 QMap<QString,QVariant> addInfo; 0147 addInfo["type"] = "add"; 0148 addBookmarkAction->setData(addInfo); 0149 addBookmarkAction->setEnabled(false); 0150 connect(addBookmarkAction, SIGNAL(triggered(bool)), SLOT(slotAddActionTriggered(bool))); 0151 addAction(addBookmarkAction); 0152 m_actions->addAction(addBookmarkAction); 0153 0154 break; 0155 } 0156 case SystemTray: 0157 { 0158 QAction *editBookmarksAction = new QAction(KDE::icon("bookmarks-organize"), i18n("&Edit Bookmarks"), menu()); 0159 editBookmarksAction->setObjectName("edit_action"); 0160 QMap<QString,QVariant> editInfo; 0161 editInfo["type"] = "edit"; 0162 editBookmarksAction->setData(editInfo); 0163 connect(editBookmarksAction, SIGNAL(triggered(bool)), SLOT(slotEditActionTriggered(bool))); 0164 addAction(editBookmarksAction); 0165 m_actions->addAction(editBookmarksAction); 0166 0167 break; 0168 } 0169 default: 0170 { 0171 break; 0172 } 0173 } 0174 0175 // 0176 // Get the list of groups 0177 // 0178 QStringList allGroups = Smb4KBookmarkHandler::self()->groupsList(); 0179 allGroups.sort(); 0180 0181 // 0182 // Insert a toplevel mount action, if necessary. Crucial for this is that there are 0183 // no (non-empty) groups defined. Enable it if not all toplevel bookmarks are mounted. 0184 // 0185 if (allGroups.isEmpty() || (allGroups.size() == 1 && allGroups.first().isEmpty())) 0186 { 0187 QAction *toplevelMount = new QAction(KDE::icon("media-mount"), i18n("Mount All Bookmarks"), menu()); 0188 toplevelMount->setObjectName("toplevel_mount"); 0189 QMap<QString,QVariant> mountInfo; 0190 mountInfo["type"] = "toplevel_mount"; 0191 toplevelMount->setData(mountInfo); 0192 connect(toplevelMount, SIGNAL(triggered(bool)), SLOT(slotToplevelMountActionTriggered(bool))); 0193 addAction(toplevelMount); 0194 m_actions->addAction(toplevelMount); 0195 0196 QList<BookmarkPtr> bookmarks = Smb4KBookmarkHandler::self()->bookmarksList(); 0197 int mountedBookmarks = 0; 0198 0199 for (const BookmarkPtr &bookmark : bookmarks) 0200 { 0201 QList<SharePtr> mountedShares = findShareByUrl(bookmark->url()); 0202 0203 if (!mountedShares.isEmpty()) 0204 { 0205 for (const SharePtr &share : mountedShares) 0206 { 0207 if (!share->isForeign()) 0208 { 0209 mountedBookmarks++; 0210 break; 0211 } 0212 else 0213 { 0214 continue; 0215 } 0216 } 0217 } 0218 } 0219 0220 toplevelMount->setEnabled(mountedBookmarks != bookmarks.size()); 0221 } 0222 0223 // 0224 // Add a separator 0225 // 0226 addSeparator(); 0227 0228 // 0229 // Now add the groups and their bookmarks 0230 // 0231 for (const QString &group : allGroups) 0232 { 0233 if (!group.isEmpty()) 0234 { 0235 // Group menu entry 0236 KActionMenu *bookmarkGroupMenu = new KActionMenu(group, menu()); 0237 bookmarkGroupMenu->setIcon(KDE::icon("folder-favorites")); 0238 QMap<QString,QVariant> menuInfo; 0239 menuInfo["type"] = "group_menu"; 0240 menuInfo["group"] = group; 0241 bookmarkGroupMenu->setData(menuInfo); 0242 addAction(bookmarkGroupMenu); 0243 0244 // Mount action for the group 0245 QAction *bookmarkGroupMount = new QAction(KDE::icon("media-mount"), i18n("Mount All Bookmarks"), bookmarkGroupMenu->menu()); 0246 QMap<QString,QVariant> groupMountInfo; 0247 groupMountInfo["type"] = "group_mount"; 0248 groupMountInfo["group"] = group; 0249 bookmarkGroupMount->setData(groupMountInfo); 0250 bookmarkGroupMenu->addAction(bookmarkGroupMount); 0251 m_actions->addAction(bookmarkGroupMount); 0252 0253 // Get the list of bookmarks belonging to this group. 0254 // Use it to decide whether the group mount action should be enabled 0255 // (only if not all bookmarks belonging to this group are mounted) and 0256 // to sort the bookmarks. 0257 QList<BookmarkPtr> bookmarks = Smb4KBookmarkHandler::self()->bookmarksList(group); 0258 QStringList sortedBookmarks; 0259 int mountedBookmarks = 0; 0260 0261 for (const BookmarkPtr &bookmark : bookmarks) 0262 { 0263 QAction *bookmarkAction = 0; 0264 0265 if (Smb4KSettings::showCustomBookmarkLabel() && !bookmark->label().isEmpty()) 0266 { 0267 bookmarkAction = new QAction(bookmark->icon(), bookmark->label(), bookmarkGroupMenu->menu()); 0268 bookmarkAction->setObjectName(bookmark->url().toDisplayString()); 0269 QMap<QString,QVariant> bookmarkInfo; 0270 bookmarkInfo["type"] = "bookmark"; 0271 bookmarkInfo["group"] = group; 0272 bookmarkInfo["url"] = bookmark->url(); 0273 bookmarkInfo["text"] = bookmark->label(); 0274 bookmarkAction->setData(bookmarkInfo); 0275 m_bookmarks->addAction(bookmarkAction); 0276 sortedBookmarks << bookmark->label(); 0277 } 0278 else 0279 { 0280 bookmarkAction = new QAction(bookmark->icon(), bookmark->displayString(), bookmarkGroupMenu->menu()); 0281 bookmarkAction->setObjectName(bookmark->url().toDisplayString()); 0282 QMap<QString,QVariant> bookmarkInfo; 0283 bookmarkInfo["type"] = "bookmark"; 0284 bookmarkInfo["group"] = group; 0285 bookmarkInfo["url"] = bookmark->url(); 0286 bookmarkInfo["text"] = bookmark->displayString(); 0287 bookmarkAction->setData(bookmarkInfo); 0288 m_bookmarks->addAction(bookmarkAction); 0289 sortedBookmarks << bookmark->displayString(); 0290 } 0291 0292 QList<SharePtr> mountedShares = findShareByUrl(bookmark->url()); 0293 0294 if (!mountedShares.isEmpty()) 0295 { 0296 for (const SharePtr &share : mountedShares) 0297 { 0298 if (!share->isForeign()) 0299 { 0300 bookmarkAction->setEnabled(false); 0301 mountedBookmarks++; 0302 break; 0303 } 0304 else 0305 { 0306 continue; 0307 } 0308 } 0309 } 0310 } 0311 0312 bookmarkGroupMount->setEnabled(mountedBookmarks != bookmarks.size()); 0313 sortedBookmarks.sort(); 0314 0315 // Add a separator 0316 bookmarkGroupMenu->addSeparator(); 0317 0318 // Insert the sorted bookmarks into the group menu 0319 QList<QAction *> actions = m_bookmarks->actions(); 0320 0321 for (const QString &b : sortedBookmarks) 0322 { 0323 for (QAction *a : actions) 0324 { 0325 if (a->text() == b) 0326 { 0327 bookmarkGroupMenu->addAction(a); 0328 break; 0329 } 0330 else 0331 { 0332 continue; 0333 } 0334 } 0335 } 0336 } 0337 } 0338 0339 // 0340 // Add all bookmarks that have no group 0341 // Sort the bookmarks before. 0342 // 0343 QList<BookmarkPtr> bookmarks = Smb4KBookmarkHandler::self()->bookmarksList(""); 0344 QStringList sortedBookmarks; 0345 0346 for (const BookmarkPtr &bookmark : bookmarks) 0347 { 0348 QAction *bookmarkAction = 0; 0349 0350 if (Smb4KSettings::showCustomBookmarkLabel() && !bookmark->label().isEmpty()) 0351 { 0352 bookmarkAction = new QAction(bookmark->icon(), bookmark->label(), menu()); 0353 bookmarkAction->setObjectName(bookmark->url().toDisplayString()); 0354 QMap<QString,QVariant> bookmarkInfo; 0355 bookmarkInfo["type"] = "bookmark"; 0356 bookmarkInfo["group"] = ""; 0357 bookmarkInfo["url"] = bookmark->url(); 0358 bookmarkInfo["text"] = bookmark->label(); 0359 bookmarkAction->setData(bookmarkInfo); 0360 m_bookmarks->addAction(bookmarkAction); 0361 sortedBookmarks << bookmark->label(); 0362 } 0363 else 0364 { 0365 bookmarkAction = new QAction(bookmark->icon(), bookmark->displayString(), menu()); 0366 bookmarkAction->setObjectName(bookmark->url().toDisplayString()); 0367 QMap<QString,QVariant> bookmarkInfo; 0368 bookmarkInfo["type"] = "bookmark"; 0369 bookmarkInfo["group"] = ""; 0370 bookmarkInfo["url"] = bookmark->url(); 0371 bookmarkInfo["text"] = bookmark->displayString(); 0372 bookmarkAction->setData(bookmarkInfo); 0373 m_bookmarks->addAction(bookmarkAction); 0374 sortedBookmarks << bookmark->displayString(); 0375 } 0376 0377 QList<SharePtr> mountedShares = findShareByUrl(bookmark->url()); 0378 0379 if (!mountedShares.isEmpty()) 0380 { 0381 for (const SharePtr &share : mountedShares) 0382 { 0383 if (!share->isForeign()) 0384 { 0385 bookmarkAction->setEnabled(false); 0386 break; 0387 } 0388 else 0389 { 0390 continue; 0391 } 0392 } 0393 } 0394 } 0395 0396 sortedBookmarks.sort(); 0397 0398 QList<QAction *> actions = m_bookmarks->actions(); 0399 0400 for (const QString &b : sortedBookmarks) 0401 { 0402 for (QAction *a : actions) 0403 { 0404 if (a->data().toMap().value("text").toString() == b) 0405 { 0406 addAction(a); 0407 break; 0408 } 0409 else 0410 { 0411 continue; 0412 } 0413 } 0414 } 0415 } 0416 0417 0418 ///////////////////////////////////////////////////////////////////////////// 0419 // SLOT IMPLEMENTATIONS 0420 ///////////////////////////////////////////////////////////////////////////// 0421 0422 void Smb4KBookmarkMenu::slotEditActionTriggered(bool /*checked*/) 0423 { 0424 Smb4KBookmarkHandler::self()->editBookmarks(); 0425 } 0426 0427 0428 void Smb4KBookmarkMenu::slotAddActionTriggered(bool /*checked*/) 0429 { 0430 emit addBookmark(); 0431 } 0432 0433 0434 void Smb4KBookmarkMenu::slotToplevelMountActionTriggered(bool /*checked*/) 0435 { 0436 // 0437 // Mount all top level bookmarks. 0438 // This slot will only be called if there are no groups defined. 0439 // 0440 QList<BookmarkPtr> bookmarks = Smb4KBookmarkHandler::self()->bookmarksList(); 0441 QList<SharePtr> mounts; 0442 0443 for (const BookmarkPtr &bookmark : bookmarks) 0444 { 0445 // FIXME: Check if the bookmarked share has already been mounted. 0446 SharePtr share = SharePtr(new Smb4KShare()); 0447 share->setHostName(bookmark->hostName()); 0448 share->setShareName(bookmark->shareName()); 0449 share->setWorkgroupName(bookmark->workgroupName()); 0450 share->setHostIpAddress(bookmark->hostIpAddress()); 0451 share->setLogin(bookmark->login()); 0452 mounts << share; 0453 } 0454 0455 Smb4KMounter::self()->mountShares(mounts); 0456 0457 while (!mounts.isEmpty()) 0458 { 0459 mounts.takeFirst().clear(); 0460 } 0461 } 0462 0463 0464 void Smb4KBookmarkMenu::slotGroupActionTriggered(QAction *action) 0465 { 0466 if (action->data().toMap().value("type").toString() == "group_mount") 0467 { 0468 // 0469 // Mount all bookmarks of one group 0470 // 0471 QList<BookmarkPtr> bookmarks = Smb4KBookmarkHandler::self()->bookmarksList(action->data().toMap().value("group").toString()); 0472 QList<SharePtr> mounts; 0473 0474 for (const BookmarkPtr &bookmark : bookmarks) 0475 { 0476 // FIXME: Check if the bookmarked share has already been mounted. 0477 SharePtr share = SharePtr(new Smb4KShare()); 0478 share->setHostName(bookmark->hostName()); 0479 share->setShareName(bookmark->shareName()); 0480 share->setWorkgroupName(bookmark->workgroupName()); 0481 share->setHostIpAddress(bookmark->hostIpAddress()); 0482 share->setLogin(bookmark->login()); 0483 mounts << share; 0484 } 0485 0486 Smb4KMounter::self()->mountShares(mounts); 0487 0488 while (!mounts.isEmpty()) 0489 { 0490 mounts.takeFirst().clear(); 0491 } 0492 } 0493 } 0494 0495 0496 void Smb4KBookmarkMenu::slotBookmarkActionTriggered(QAction *action) 0497 { 0498 QMap<QString,QVariant> info = action->data().toMap(); 0499 QString bookmarkGroup = info.value("group").toString(); 0500 QUrl url = info.value("url").toUrl(); 0501 0502 BookmarkPtr bookmark = Smb4KBookmarkHandler::self()->findBookmarkByUrl(url); 0503 0504 if (bookmark && bookmarkGroup == bookmark->groupName()) 0505 { 0506 SharePtr share = SharePtr(new Smb4KShare()); 0507 share->setHostName(bookmark->hostName()); 0508 share->setShareName(bookmark->shareName()); 0509 share->setWorkgroupName(bookmark->workgroupName()); 0510 share->setHostIpAddress(bookmark->hostIpAddress()); 0511 share->setLogin(bookmark->login()); 0512 Smb4KMounter::self()->mountShare(share); 0513 share.clear(); 0514 } 0515 } 0516 0517 0518 void Smb4KBookmarkMenu::slotBookmarksUpdated() 0519 { 0520 refreshMenu(); 0521 } 0522 0523 0524 void Smb4KBookmarkMenu::slotEnableBookmark(const SharePtr &share) 0525 { 0526 if (!share->isForeign() && !m_bookmarks->actions().isEmpty()) 0527 { 0528 // 0529 // Enable or disable the bookmark 0530 // 0531 QList<QAction *> actions = m_bookmarks->actions(); 0532 QString bookmarkGroup; 0533 0534 for (QAction *a : actions) 0535 { 0536 QUrl bookmarkUrl = a->data().toMap().value("url").toUrl(); 0537 0538 if (share->url().matches(bookmarkUrl, QUrl::RemoveUserInfo|QUrl::RemovePort)) 0539 { 0540 a->setEnabled(!share->isMounted()); 0541 bookmarkGroup = a->data().toMap().value("group").toString(); 0542 break; 0543 } 0544 } 0545 0546 // 0547 // Check if all bookmarks belonging to this group are 0548 // mounted. Enable the respective mount action if necessary. 0549 // 0550 bool allMounted = true; 0551 0552 for (QAction *a : actions) 0553 { 0554 if (a->data().toMap().value("group").toString() == bookmarkGroup && a->isEnabled()) 0555 { 0556 allMounted = false; 0557 break; 0558 } 0559 else 0560 { 0561 continue; 0562 } 0563 } 0564 0565 QList<QAction *> allActions = m_actions->actions(); 0566 0567 for (QAction *a : allActions) 0568 { 0569 if (a->data().toMap().value("type").toString() == "toplevel_mount" && bookmarkGroup.isEmpty()) 0570 { 0571 a->setEnabled(!allMounted); 0572 break; 0573 } 0574 else if (a->data().toMap().value("type").toString() == "group_mount" && 0575 a->data().toMap().value("group").toString() == bookmarkGroup) 0576 { 0577 a->setEnabled(!allMounted); 0578 break; 0579 } 0580 else 0581 { 0582 continue; 0583 } 0584 } 0585 } 0586 } 0587