File indexing completed on 2024-10-13 04:31:31
0001 /* 0002 smb4kbookmarkmenu - Bookmark 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 "smb4kbookmarkmenu.h" 0010 #include "core/smb4kbookmark.h" 0011 #include "core/smb4kbookmarkhandler.h" 0012 #include "core/smb4kglobal.h" 0013 #include "core/smb4kmounter.h" 0014 #include "core/smb4ksettings.h" 0015 #include "core/smb4kshare.h" 0016 0017 // Qt includes 0018 #include <QDebug> 0019 #include <QMap> 0020 #include <QMapIterator> 0021 #include <QMenu> 0022 0023 // KDE includes 0024 #include <KIconLoader> 0025 #include <KLocalizedString> 0026 0027 using namespace Smb4KGlobal; 0028 0029 Smb4KBookmarkMenu::Smb4KBookmarkMenu(int type, QObject *parent) 0030 : KActionMenu(KDE::icon(QStringLiteral("folder-favorites")), i18n("Bookmarks"), parent) 0031 { 0032 m_categories = new QActionGroup(menu()); 0033 m_bookmarks = new QActionGroup(menu()); 0034 m_mountActions = new QActionGroup(menu()); 0035 0036 m_editBookmarks = new QAction(KDE::icon(QStringLiteral("bookmarks-organize")), i18n("&Edit Bookmarks"), menu()); 0037 m_editBookmarks->setEnabled(!Smb4KBookmarkHandler::self()->bookmarkList().isEmpty()); 0038 connect(m_editBookmarks, SIGNAL(triggered(bool)), SLOT(slotEditActionTriggered(bool))); 0039 addAction(m_editBookmarks); 0040 0041 if (type == MainWindow) { 0042 m_addBookmark = new QAction(KDE::icon(QStringLiteral("bookmark-new")), i18n("Add &Bookmark"), menu()); 0043 m_addBookmark->setEnabled(false); 0044 connect(m_addBookmark, SIGNAL(triggered(bool)), SLOT(slotAddActionTriggered(bool))); 0045 addAction(m_addBookmark); 0046 } else { 0047 m_addBookmark = nullptr; 0048 } 0049 0050 m_toplevelMount = new QAction(KDE::icon(QStringLiteral("media-mount")), i18n("Mount Bookmarks"), menu()); 0051 addAction(m_toplevelMount); 0052 m_mountActions->addAction(m_toplevelMount); 0053 0054 m_separator = addSeparator(); 0055 m_separator->setVisible(!Smb4KBookmarkHandler::self()->bookmarkList().isEmpty()); 0056 0057 loadBookmarks(); 0058 adjustMountActions(); 0059 0060 connect(Smb4KBookmarkHandler::self(), &Smb4KBookmarkHandler::updated, this, &Smb4KBookmarkMenu::loadBookmarks); 0061 connect(Smb4KMounter::self(), &Smb4KMounter::mounted, this, &Smb4KBookmarkMenu::slotEnableBookmark); 0062 connect(Smb4KMounter::self(), &Smb4KMounter::unmounted, this, &Smb4KBookmarkMenu::slotEnableBookmark); 0063 connect(m_bookmarks, &QActionGroup::triggered, this, &Smb4KBookmarkMenu::slotBookmarkActionTriggered); 0064 connect(m_mountActions, &QActionGroup::triggered, this, &Smb4KBookmarkMenu::slotMountActionTriggered); 0065 } 0066 0067 Smb4KBookmarkMenu::~Smb4KBookmarkMenu() 0068 { 0069 } 0070 0071 void Smb4KBookmarkMenu::refreshMenu() 0072 { 0073 loadBookmarks(); 0074 } 0075 0076 void Smb4KBookmarkMenu::loadBookmarks() 0077 { 0078 while (!m_categories->actions().isEmpty()) { 0079 QAction *category = m_categories->actions().takeFirst(); 0080 removeAction(category); 0081 delete category; 0082 } 0083 0084 while (!m_bookmarks->actions().isEmpty()) { 0085 QAction *bookmark = m_bookmarks->actions().takeFirst(); 0086 removeAction(bookmark); 0087 delete bookmark; 0088 } 0089 0090 QStringList categories = Smb4KBookmarkHandler::self()->categoryList(); 0091 categories.sort(); 0092 0093 KActionMenu *categoryMenu = nullptr; 0094 QMap<QString, QAction *> topLevelActions; 0095 0096 for (const QString &category : qAsConst(categories)) { 0097 if (!category.isEmpty()) { 0098 categoryMenu = new KActionMenu(category, menu()); 0099 categoryMenu->setIcon(KDE::icon(QStringLiteral("folder-favorites"))); 0100 0101 addAction(categoryMenu); 0102 m_categories->addAction(categoryMenu); 0103 0104 topLevelActions[QStringLiteral("00_") + category] = categoryMenu; 0105 0106 QAction *categoryMount = new QAction(KDE::icon(QStringLiteral("media-mount")), i18n("Mount Bookmarks"), categoryMenu->menu()); 0107 categoryMount->setData(category); 0108 0109 categoryMenu->addAction(categoryMount); 0110 m_mountActions->addAction(categoryMount); 0111 0112 categoryMenu->addSeparator(); 0113 } else { 0114 categoryMenu = this; 0115 } 0116 0117 QMap<QString, QAction *> actionMap; 0118 QList<BookmarkPtr> categoryBookmarks = Smb4KBookmarkHandler::self()->bookmarkList(category); 0119 0120 for (const BookmarkPtr &bookmark : qAsConst(categoryBookmarks)) { 0121 QAction *bookmarkAction = new QAction(categoryMenu->menu()); 0122 bookmarkAction->setIcon(bookmark->icon()); 0123 0124 QString displayName; 0125 0126 if (Smb4KSettings::showCustomBookmarkLabel() && !bookmark->label().isEmpty()) { 0127 displayName = bookmark->label(); 0128 } else { 0129 displayName = bookmark->displayString(); 0130 } 0131 0132 bookmarkAction->setText(displayName); 0133 0134 QVariant variant = QVariant::fromValue(*bookmark.data()); 0135 bookmarkAction->setData(variant); 0136 0137 m_bookmarks->addAction(bookmarkAction); 0138 0139 QList<SharePtr> mountedShares = findShareByUrl(bookmark->url()); 0140 0141 if (!mountedShares.isEmpty()) { 0142 for (const SharePtr &share : qAsConst(mountedShares)) { 0143 if (!share->isForeign()) { 0144 bookmarkAction->setEnabled(false); 0145 break; 0146 } 0147 } 0148 } 0149 0150 if (!category.isEmpty()) { 0151 actionMap[displayName] = bookmarkAction; 0152 } else { 0153 topLevelActions[QStringLiteral("01_") + displayName] = bookmarkAction; 0154 } 0155 } 0156 0157 QMapIterator<QString, QAction *> it(actionMap); 0158 0159 while (it.hasNext()) { 0160 it.next(); 0161 if (!category.isEmpty()) { 0162 categoryMenu->addAction(it.value()); 0163 } 0164 } 0165 } 0166 0167 QMapIterator<QString, QAction *> it(topLevelActions); 0168 0169 while (it.hasNext()) { 0170 QAction *action = it.next().value(); 0171 addAction(action); 0172 } 0173 0174 adjustMountActions(); 0175 0176 m_editBookmarks->setEnabled(!Smb4KBookmarkHandler::self()->bookmarkList().isEmpty()); 0177 m_separator->setVisible(!Smb4KBookmarkHandler::self()->bookmarkList().isEmpty()); 0178 0179 menu()->update(); 0180 } 0181 0182 void Smb4KBookmarkMenu::setBookmarkActionEnabled(bool enable) 0183 { 0184 m_addBookmark->setEnabled(enable); 0185 } 0186 0187 void Smb4KBookmarkMenu::adjustMountActions() 0188 { 0189 QList<BookmarkPtr> toplevelBookmarks = Smb4KBookmarkHandler::self()->bookmarkList(QStringLiteral("")); 0190 0191 if (!toplevelBookmarks.isEmpty()) { 0192 int mountedBookmarks = 0; 0193 0194 for (const BookmarkPtr &bookmark : qAsConst(toplevelBookmarks)) { 0195 QList<SharePtr> mountedShares = findShareByUrl(bookmark->url()); 0196 0197 for (const SharePtr &share : qAsConst(mountedShares)) { 0198 if (!share->isForeign()) { 0199 mountedBookmarks++; 0200 break; 0201 } 0202 } 0203 } 0204 0205 m_toplevelMount->setVisible(true); 0206 m_toplevelMount->setEnabled(mountedBookmarks != toplevelBookmarks.size()); 0207 } else { 0208 m_toplevelMount->setVisible(false); 0209 m_toplevelMount->setEnabled(false); 0210 } 0211 0212 QList<QAction *> allMountActions = m_mountActions->actions(); 0213 QStringList allCategories = Smb4KBookmarkHandler::self()->categoryList(); 0214 int mountedBookmarks = 0; 0215 0216 for (const QString &category : qAsConst(allCategories)) { 0217 QList<BookmarkPtr> bookmarks = Smb4KBookmarkHandler::self()->bookmarkList(category); 0218 0219 for (const BookmarkPtr &bookmark : bookmarks) { 0220 QList<SharePtr> mountedShares = findShareByUrl(bookmark->url()); 0221 0222 if (!mountedShares.isEmpty()) { 0223 for (const SharePtr &share : qAsConst(mountedShares)) { 0224 if (!share->isForeign()) { 0225 mountedBookmarks++; 0226 break; 0227 } 0228 } 0229 } 0230 } 0231 0232 for (QAction *action : allMountActions) { 0233 if (action->data().toString() == category) { 0234 action->setEnabled(bookmarks.size() != mountedBookmarks); 0235 break; 0236 } 0237 } 0238 0239 mountedBookmarks = 0; 0240 } 0241 } 0242 0243 ///////////////////////////////////////////////////////////////////////////// 0244 // SLOT IMPLEMENTATIONS 0245 ///////////////////////////////////////////////////////////////////////////// 0246 0247 void Smb4KBookmarkMenu::slotEditActionTriggered(bool checked) 0248 { 0249 Q_UNUSED(checked); 0250 0251 QPointer<Smb4KBookmarkEditor> bookmarkEditor = new Smb4KBookmarkEditor(menu()); 0252 bookmarkEditor->open(); 0253 } 0254 0255 void Smb4KBookmarkMenu::slotAddActionTriggered(bool /*checked*/) 0256 { 0257 Q_EMIT addBookmark(); 0258 } 0259 0260 void Smb4KBookmarkMenu::slotMountActionTriggered(QAction *action) 0261 { 0262 QList<BookmarkPtr> bookmarks; 0263 0264 if (action == m_toplevelMount) { 0265 bookmarks = Smb4KBookmarkHandler::self()->bookmarkList(QStringLiteral("")); 0266 } else { 0267 bookmarks = Smb4KBookmarkHandler::self()->bookmarkList(action->data().toString()); 0268 } 0269 0270 QList<SharePtr> mounts; 0271 0272 for (const BookmarkPtr &bookmark : qAsConst(bookmarks)) { 0273 SharePtr share = SharePtr(new Smb4KShare()); 0274 share->setUrl(bookmark->url()); 0275 share->setWorkgroupName(bookmark->workgroupName()); 0276 share->setHostIpAddress(bookmark->hostIpAddress()); 0277 mounts << share; 0278 } 0279 0280 Smb4KMounter::self()->mountShares(mounts); 0281 0282 while (!mounts.isEmpty()) { 0283 mounts.takeFirst().clear(); 0284 } 0285 } 0286 0287 void Smb4KBookmarkMenu::slotBookmarkActionTriggered(QAction *action) 0288 { 0289 Smb4KBookmark bookmark = action->data().value<Smb4KBookmark>(); 0290 0291 SharePtr share = SharePtr(new Smb4KShare()); 0292 share->setUrl(bookmark.url()); 0293 share->setWorkgroupName(bookmark.workgroupName()); 0294 share->setHostIpAddress(bookmark.hostIpAddress()); 0295 0296 Smb4KMounter::self()->mountShare(share); 0297 0298 share.clear(); 0299 } 0300 0301 void Smb4KBookmarkMenu::slotEnableBookmark(const SharePtr &share) 0302 { 0303 if (!share->isForeign() && !m_bookmarks->actions().isEmpty()) { 0304 QList<QAction *> actions = m_bookmarks->actions(); 0305 0306 for (QAction *a : qAsConst(actions)) { 0307 QUrl bookmarkUrl = a->data().value<Smb4KBookmark>().url(); 0308 0309 if (share->url().matches(bookmarkUrl, QUrl::RemoveUserInfo | QUrl::RemovePort)) { 0310 a->setEnabled(!share->isMounted()); 0311 break; 0312 } 0313 } 0314 0315 adjustMountActions(); 0316 } 0317 }