File indexing completed on 2024-05-12 05:12:50
0001 /* 0002 This file is part of Akregator. 0003 0004 SPDX-FileCopyrightText: 2005 Frank Osterfeld <osterfeld@kde.org> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0 0007 */ 0008 0009 #include "actionmanagerimpl.h" 0010 #include "akregator_part.h" 0011 #include "akregatorconfig.h" 0012 #include "articlelistview.h" 0013 #include "feed.h" 0014 #include "fetchqueue.h" 0015 #include "folder.h" 0016 #include "kernel.h" 0017 #include "mainwidget.h" 0018 #include "subscriptionlistview.h" 0019 #include "tabwidget.h" 0020 #include "trayicon.h" 0021 #include "treenode.h" 0022 #include "treenodevisitor.h" 0023 0024 #include <WebEngineViewer/ZoomActionMenu> 0025 0026 #include "akregator_debug.h" 0027 #include <KActionCollection> 0028 #include <KActionMenu> 0029 #include <KColorSchemeMenu> 0030 #include <KGuiItem> 0031 #include <KLocalizedString> 0032 #include <KStandardAction> 0033 #include <KStandardShortcut> 0034 #include <KToggleAction> 0035 #include <QAction> 0036 #include <QActionGroup> 0037 #include <QKeySequence> 0038 #include <QMenu> 0039 #include <kxmlguifactory.h> 0040 0041 #include <KColorSchemeManager> 0042 #include <QWidget> 0043 0044 using namespace Akregator; 0045 0046 class ActionManagerImpl::NodeSelectVisitor : public TreeNodeVisitor 0047 { 0048 public: 0049 NodeSelectVisitor(ActionManagerImpl *manager) 0050 : m_manager(manager) 0051 { 0052 } 0053 0054 bool visitFeed(Feed *node) override 0055 { 0056 QAction *remove = m_manager->action(QStringLiteral("feed_remove")); 0057 if (remove) { 0058 remove->setEnabled(true); 0059 } 0060 QAction *hp = m_manager->action(QStringLiteral("feed_homepage")); 0061 if (hp) { 0062 hp->setEnabled(!node->htmlUrl().isEmpty()); 0063 } 0064 m_manager->action(QStringLiteral("feed_fetch"))->setText(i18n("&Fetch Feed")); 0065 m_manager->action(QStringLiteral("feed_remove"))->setText(i18n("&Delete Feed")); 0066 m_manager->action(QStringLiteral("feed_modify"))->setText(i18n("&Edit Feed...")); 0067 m_manager->action(QStringLiteral("feed_mark_all_as_read"))->setText(i18n("&Mark Feed as Read")); 0068 0069 return true; 0070 } 0071 0072 bool visitFolder(Folder *node) override 0073 { 0074 QAction *remove = m_manager->action(QStringLiteral("feed_remove")); 0075 if (remove) { 0076 remove->setEnabled(node->parent()); // root nodes must not be deleted 0077 } 0078 QAction *hp = m_manager->action(QStringLiteral("feed_homepage")); 0079 if (hp) { 0080 hp->setEnabled(false); 0081 } 0082 0083 m_manager->action(QStringLiteral("feed_fetch"))->setText(i18n("&Fetch Feeds")); 0084 m_manager->action(QStringLiteral("feed_remove"))->setText(i18n("&Delete Folder")); 0085 m_manager->action(QStringLiteral("feed_modify"))->setText(i18n("&Rename Folder")); 0086 m_manager->action(QStringLiteral("feed_mark_all_as_read"))->setText(i18n("&Mark Feeds as Read")); 0087 0088 return true; 0089 } 0090 0091 private: 0092 ActionManagerImpl *const m_manager; 0093 }; 0094 0095 class ActionManagerImpl::ActionManagerImplPrivate 0096 { 0097 public: 0098 [[nodiscard]] QString quickSearchLineText() const; 0099 NodeSelectVisitor *nodeSelectVisitor = nullptr; 0100 ArticleListView *articleList = nullptr; 0101 SubscriptionListView *subscriptionListView = nullptr; 0102 MainWidget *mainWidget = nullptr; 0103 Part *part = nullptr; 0104 TrayIcon *trayIcon = nullptr; 0105 KActionMenu *tagMenu = nullptr; 0106 KActionCollection *actionCollection = nullptr; 0107 TabWidget *tabWidget = nullptr; 0108 PimCommon::ShareServiceUrlManager *shareServiceManager = nullptr; 0109 WebEngineViewer::ZoomActionMenu *zoomActionMenu = nullptr; 0110 QAction *mQuickSearchAction = nullptr; 0111 }; 0112 0113 void ActionManagerImpl::slotSettingsChanged() 0114 { 0115 QAction *a = action(QStringLiteral("feed_hide_read")); 0116 if (!a) { 0117 qCCritical(AKREGATOR_LOG) << "Action not found"; 0118 return; 0119 } 0120 a->setChecked(Settings::hideReadFeeds()); 0121 0122 a = action(QStringLiteral("feed_lock_in_place")); 0123 if (!a) { 0124 qCCritical(AKREGATOR_LOG) << "Action not found"; 0125 return; 0126 } 0127 a->setChecked(Settings::lockFeedsInPlace()); 0128 0129 a = action(QStringLiteral("auto_expand_folders")); 0130 if (!a) { 0131 qCCritical(AKREGATOR_LOG) << "Action not found"; 0132 return; 0133 } 0134 a->setChecked(Settings::autoExpandFolders()); 0135 } 0136 0137 void ActionManagerImpl::slotNodeSelected(TreeNode *node) 0138 { 0139 if (node) { 0140 d->nodeSelectVisitor->visit(node); 0141 } 0142 } 0143 0144 ActionManagerImpl::ActionManagerImpl(Part *part, QObject *parent) 0145 : ActionManager(parent) 0146 , d(new ActionManagerImplPrivate) 0147 { 0148 d->nodeSelectVisitor = new NodeSelectVisitor(this); 0149 d->part = part; 0150 d->subscriptionListView = nullptr; 0151 d->articleList = nullptr; 0152 d->trayIcon = nullptr; 0153 d->mainWidget = nullptr; 0154 d->tabWidget = nullptr; 0155 d->tagMenu = nullptr; 0156 d->actionCollection = part->actionCollection(); 0157 d->shareServiceManager = new PimCommon::ShareServiceUrlManager(this); 0158 initPart(); 0159 } 0160 0161 ActionManagerImpl::~ActionManagerImpl() 0162 { 0163 delete d->nodeSelectVisitor; 0164 } 0165 0166 void ActionManagerImpl::setTrayIcon(TrayIcon *trayIcon) 0167 { 0168 if (trayIcon == nullptr) { 0169 d->trayIcon = nullptr; 0170 return; 0171 } 0172 if (d->trayIcon) { 0173 return; 0174 } else { 0175 d->trayIcon = trayIcon; 0176 } 0177 0178 QMenu *traypop = trayIcon->contextMenu(); 0179 0180 if (QAction *act = actionCollection()->action(QStringLiteral("feed_fetch_all"))) { 0181 traypop->addAction(act); 0182 } 0183 if (QAction *act = actionCollection()->action(QStringLiteral("options_configure"))) { 0184 traypop->addAction(act); 0185 } 0186 } 0187 0188 void ActionManagerImpl::initPart() 0189 { 0190 QAction *action = d->actionCollection->addAction(QStringLiteral("file_import")); 0191 action->setText(i18n("&Import Feeds...")); 0192 action->setIcon(QIcon::fromTheme(QStringLiteral("document-import"))); 0193 connect(action, &QAction::triggered, d->part, &Part::fileImport); 0194 action = d->actionCollection->addAction(QStringLiteral("file_export")); 0195 action->setText(i18n("&Export Feeds...")); 0196 action->setIcon(QIcon::fromTheme(QStringLiteral("document-export"))); 0197 connect(action, &QAction::triggered, d->part, &Part::fileExport); 0198 0199 QAction *configure = d->actionCollection->addAction(QStringLiteral("options_configure")); 0200 configure->setText(i18n("&Configure Akregator...")); 0201 configure->setIcon(QIcon::fromTheme(QStringLiteral("configure"))); 0202 connect(configure, &QAction::triggered, d->part, &Part::showOptions); 0203 0204 KStandardAction::configureNotifications(d->part, &Part::showNotificationOptions, d->actionCollection); // options_configure_notifications 0205 } 0206 0207 void ActionManagerImpl::initMainWidget(MainWidget *mainWidget) 0208 { 0209 if (d->mainWidget) { 0210 return; 0211 } 0212 0213 d->mainWidget = mainWidget; 0214 0215 KActionCollection *coll = actionCollection(); 0216 0217 // Feed/Feed Group popup menu 0218 QAction *action = coll->addAction(QStringLiteral("feed_homepage")); 0219 action->setText(i18n("&Open Homepage")); 0220 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotOpenHomepage); 0221 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::Key_H)); 0222 0223 action = coll->addAction(QStringLiteral("reload_all_tabs")); 0224 action->setIcon(QIcon::fromTheme(QStringLiteral("view-refresh"))); 0225 action->setText(i18n("Reload All Tabs")); 0226 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotReloadAllTabs); 0227 coll->setDefaultShortcut(action, QKeySequence(Qt::SHIFT | Qt::Key_F5)); 0228 0229 action = coll->addAction(QStringLiteral("feed_add")); 0230 action->setIcon(QIcon::fromTheme(QStringLiteral("feed-subscribe"))); 0231 action->setText(i18n("&Add Feed...")); 0232 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotFeedAdd); 0233 coll->setDefaultShortcut(action, QKeySequence(Qt::Key_Insert)); 0234 0235 action = coll->addAction(QStringLiteral("feed_add_group")); 0236 action->setIcon(QIcon::fromTheme(QStringLiteral("folder-new"))); 0237 action->setText(i18n("Ne&w Folder...")); 0238 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotFeedAddGroup); 0239 coll->setDefaultShortcut(action, QKeySequence(Qt::SHIFT | Qt::Key_Insert)); 0240 0241 action = coll->addAction(QStringLiteral("feed_remove")); 0242 action->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete"))); 0243 action->setText(i18n("&Delete Feed")); 0244 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotFeedRemove); 0245 coll->setDefaultShortcut(action, QKeySequence(Qt::ALT | Qt::Key_Delete)); 0246 0247 action = coll->addAction(QStringLiteral("feed_modify")); 0248 action->setIcon(QIcon::fromTheme(QStringLiteral("document-properties"))); 0249 action->setText(i18n("&Edit Feed...")); 0250 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotFeedModify); 0251 coll->setDefaultShortcut(action, QKeySequence(Qt::Key_F2)); 0252 0253 // toolbar / View 0254 0255 const auto viewMode = static_cast<MainWidget::ViewMode>(Settings::viewMode()); 0256 auto group = new QActionGroup(this); 0257 action = coll->addAction(QStringLiteral("normal_view")); 0258 action->setCheckable(true); 0259 action->setChecked(viewMode == MainWidget::NormalView); 0260 group->addAction(action); 0261 action->setIcon(QIcon::fromTheme(QStringLiteral("view-split-top-bottom"))); 0262 action->setText(i18n("&Normal View")); 0263 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotNormalView); 0264 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_1)); 0265 0266 action = coll->addAction(QStringLiteral("widescreen_view")); 0267 action->setCheckable(true); 0268 action->setChecked(viewMode == MainWidget::WidescreenView); 0269 group->addAction(action); 0270 action->setIcon(QIcon::fromTheme(QStringLiteral("view-split-left-right"))); 0271 action->setText(i18n("&Widescreen View")); 0272 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotWidescreenView); 0273 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_2)); 0274 0275 action = coll->addAction(QStringLiteral("combined_view")); 0276 action->setCheckable(true); 0277 action->setChecked(viewMode == MainWidget::CombinedView); 0278 group->addAction(action); 0279 action->setIcon(QIcon::fromTheme(QStringLiteral("view-list-text"))); 0280 action->setText(i18n("C&ombined View")); 0281 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotCombinedView); 0282 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_3)); 0283 0284 // toolbar / feed menu 0285 action = coll->addAction(QStringLiteral("feed_fetch")); 0286 action->setIcon(QIcon::fromTheme(QStringLiteral("go-down"))); 0287 action->setText(i18n("&Fetch Feed")); 0288 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotFetchCurrentFeed); 0289 coll->setDefaultShortcuts(action, KStandardShortcut::shortcut(KStandardShortcut::Reload)); 0290 0291 action = coll->addAction(QStringLiteral("feed_fetch_all")); 0292 action->setIcon(QIcon::fromTheme(QStringLiteral("go-bottom"))); 0293 action->setText(i18n("Fe&tch All Feeds")); 0294 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotFetchAllFeeds); 0295 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::Key_L)); 0296 0297 QAction *stopAction = coll->addAction(QStringLiteral("feed_stop")); 0298 stopAction->setIcon(QIcon::fromTheme(QStringLiteral("process-stop"))); 0299 stopAction->setText(i18n("C&ancel Feed Fetches")); 0300 connect(stopAction, &QAction::triggered, Kernel::self()->fetchQueue(), &FetchQueue::slotAbort); 0301 coll->setDefaultShortcut(stopAction, QKeySequence(Qt::Key_Escape)); 0302 stopAction->setEnabled(false); 0303 0304 action = coll->addAction(QStringLiteral("feed_mark_all_as_read")); 0305 action->setIcon(QIcon::fromTheme(QStringLiteral("mail-mark-read"))); 0306 action->setText(i18n("&Mark Feed as Read")); 0307 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotMarkAllRead); 0308 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::Key_R)); 0309 0310 action = coll->addAction(QStringLiteral("feed_mark_all_feeds_as_read")); 0311 action->setIcon(QIcon::fromTheme(QStringLiteral("mail-mark-read"))); 0312 action->setText(i18n("Ma&rk All Feeds as Read")); 0313 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotMarkAllFeedsRead); 0314 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_R)); 0315 0316 // Settings menu 0317 auto sqf = coll->add<KToggleAction>(QStringLiteral("show_quick_filter")); 0318 sqf->setText(i18n("Show Quick Filter")); 0319 connect(sqf, &QAction::triggered, d->mainWidget, &MainWidget::slotToggleShowQuickFilter); 0320 sqf->setChecked(Settings::showQuickFilter()); 0321 0322 action = coll->addAction(QStringLiteral("article_open")); 0323 action->setIcon(QIcon::fromTheme(QStringLiteral("tab-new"))); 0324 action->setText(i18n("Open in Tab")); 0325 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotOpenSelectedArticles); 0326 coll->setDefaultShortcut(action, QKeySequence(Qt::SHIFT | Qt::Key_Return)); 0327 0328 action = coll->addAction(QStringLiteral("article_open_in_background")); 0329 action->setIcon(QIcon::fromTheme(QStringLiteral("tab-new"))); 0330 action->setText(i18n("Open in Background Tab")); 0331 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotOpenSelectedArticlesInBackground); 0332 coll->setDefaultShortcut(action, QKeySequence(Qt::Key_Return)); 0333 0334 action = coll->addAction(QStringLiteral("article_open_external")); 0335 action->setIcon(QIcon::fromTheme(QStringLiteral("window-new"))); 0336 action->setText(i18n("Open in External Browser")); 0337 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotOpenSelectedArticlesInBrowser); 0338 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_Return)); 0339 0340 action = coll->addAction(QStringLiteral("article_copy_link_address")); 0341 action->setText(i18n("Copy Link Address")); 0342 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotCopyLinkAddress); 0343 0344 action = coll->addAction(QStringLiteral("go_prev_unread_article")); 0345 action->setIcon(QIcon::fromTheme(QStringLiteral("go-previous"))); 0346 action->setText(i18n("Pre&vious Unread Article")); 0347 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotPrevUnreadArticle); 0348 coll->setDefaultShortcuts(action, QList<QKeySequence>() << QKeySequence(Qt::Key_Minus) << QKeySequence(Qt::Key_Minus | Qt::KeypadModifier)); 0349 0350 action = coll->addAction(QStringLiteral("go_next_unread_article")); 0351 action->setIcon(QIcon::fromTheme(QStringLiteral("go-next"))); 0352 action->setText(i18n("Ne&xt Unread Article")); 0353 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotNextUnreadArticle); 0354 coll->setDefaultShortcuts(action, 0355 QList<QKeySequence>() << QKeySequence(Qt::Key_Plus) << QKeySequence(Qt::Key_Plus | Qt::KeypadModifier) 0356 << QKeySequence(Qt::Key_Equal) << QKeySequence(Qt::Key_Equal | Qt::KeypadModifier)); 0357 0358 action = coll->addAction(QStringLiteral("article_delete")); 0359 action->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete"))); 0360 action->setText(i18n("&Delete")); 0361 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotArticleDelete); 0362 coll->setDefaultShortcut(action, QKeySequence(Qt::Key_Delete)); 0363 0364 auto statusMenu = coll->add<KActionMenu>(QStringLiteral("article_set_status")); 0365 statusMenu->setText(i18n("&Mark As")); 0366 statusMenu->setEnabled(false); 0367 0368 action = coll->addAction(QStringLiteral("article_set_status_read")); 0369 action->setText(i18nc("as in: mark as read", "&Read")); 0370 action->setIcon(QIcon::fromTheme(QStringLiteral("mail-mark-read"))); 0371 action->setToolTip(i18n("Mark selected article as read")); 0372 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::Key_E)); 0373 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotSetSelectedArticleRead); 0374 statusMenu->addAction(action); 0375 0376 action = coll->addAction(QStringLiteral("article_set_status_new")); 0377 action->setText(i18nc("as in: mark as new", "&New")); 0378 action->setIcon(QIcon::fromTheme(QStringLiteral("mail-mark-unread-new"))); 0379 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::Key_N)); 0380 action->setToolTip(i18n("Mark selected article as new")); 0381 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotSetSelectedArticleNew); 0382 statusMenu->addAction(action); 0383 0384 action = coll->addAction(QStringLiteral("article_set_status_unread")); 0385 action->setText(i18nc("as in: mark as unread", "&Unread")); 0386 action->setIcon(QIcon::fromTheme(QStringLiteral("mail-mark-unread"))); 0387 action->setToolTip(i18n("Mark selected article as unread")); 0388 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::Key_U)); 0389 connect(action, &QAction::triggered, d->mainWidget, &MainWidget::slotSetSelectedArticleUnread); 0390 statusMenu->addAction(action); 0391 0392 auto importantAction = coll->add<KToggleAction>(QStringLiteral("article_set_status_important")); 0393 importantAction->setText(i18n("&Mark as Important")); 0394 importantAction->setIcon(QIcon::fromTheme(QStringLiteral("mail-mark-important"))); 0395 const QList<QKeySequence> importantSC = {QKeySequence(Qt::CTRL | Qt::Key_I), QKeySequence(Qt::Key_I)}; 0396 coll->setDefaultShortcuts(importantAction, importantSC); 0397 importantAction->setCheckedState(KGuiItem(i18n("Remove &Important Mark"))); 0398 connect(importantAction, &QAction::triggered, d->mainWidget, &MainWidget::slotArticleToggleKeepFlag); 0399 0400 action = coll->addAction(QStringLiteral("feedstree_move_up")); 0401 action->setText(i18n("Move Node Up")); 0402 connect(action, &QAction::triggered, mainWidget, &MainWidget::slotMoveCurrentNodeUp); 0403 coll->setDefaultShortcut(action, QKeySequence(Qt::SHIFT | Qt::ALT | Qt::Key_Up)); 0404 0405 action = coll->addAction(QStringLiteral("feedstree_move_down")); 0406 action->setText(i18n("Move Node Down")); 0407 connect(action, &QAction::triggered, mainWidget, &MainWidget::slotMoveCurrentNodeDown); 0408 coll->setDefaultShortcut(action, QKeySequence(Qt::SHIFT | Qt::ALT | Qt::Key_Down)); 0409 0410 action = coll->addAction(QStringLiteral("move_node_left")); 0411 action->setText(i18n("Move Node Left")); 0412 connect(action, &QAction::triggered, mainWidget, &MainWidget::slotMoveCurrentNodeLeft); 0413 coll->setDefaultShortcut(action, QKeySequence(Qt::SHIFT | Qt::ALT | Qt::Key_Left)); 0414 0415 action = coll->addAction(QStringLiteral("feedstree_move_right")); 0416 action->setText(i18n("Move Node Right")); 0417 connect(action, &QAction::triggered, mainWidget, &MainWidget::slotMoveCurrentNodeRight); 0418 coll->setDefaultShortcut(action, QKeySequence(Qt::SHIFT | Qt::ALT | Qt::Key_Right)); 0419 0420 action = coll->addAction(QStringLiteral("file_sendlink")); 0421 action->setIcon(QIcon::fromTheme(QStringLiteral("mail-message-new"))); 0422 action->setText(i18n("Send &Link Address...")); 0423 connect(action, &QAction::triggered, mainWidget, &MainWidget::slotSendLink); 0424 0425 action = coll->addAction(QStringLiteral("file_sendfile")); 0426 action->setIcon(QIcon::fromTheme(QStringLiteral("mail-message-new"))); 0427 action->setText(i18n("Send &File...")); 0428 connect(action, &QAction::triggered, mainWidget, &MainWidget::slotSendFile); 0429 0430 coll->addAction(QStringLiteral("share_serviceurl"), d->shareServiceManager->menu()); 0431 connect(d->shareServiceManager, &PimCommon::ShareServiceUrlManager::serviceUrlSelected, this, &ActionManagerImpl::slotServiceUrlSelected); 0432 0433 d->mQuickSearchAction = new QAction(i18n("Set Focus to Quick Search"), this); 0434 // If change shortcut change Panel::setQuickSearchClickMessage(...) message 0435 coll->setDefaultShortcut(d->mQuickSearchAction, QKeySequence(Qt::ALT | Qt::Key_Q)); 0436 coll->addAction(QStringLiteral("focus_to_quickseach"), d->mQuickSearchAction); 0437 connect(d->mQuickSearchAction, &QAction::triggered, mainWidget, &MainWidget::slotFocusQuickSearch); 0438 0439 auto manager = new KColorSchemeManager(this); 0440 coll->addAction(QStringLiteral("colorscheme_menu"), KColorSchemeMenu::createMenu(manager, this)); 0441 0442 setArticleActionsEnabled(false); 0443 } 0444 0445 void ActionManagerImpl::slotServiceUrlSelected(PimCommon::ShareServiceUrlManager::ServiceType type) 0446 { 0447 if (d->mainWidget) { 0448 QString title; 0449 QString link; 0450 d->mainWidget->currentArticleInfo(link, title); 0451 const QUrl url = d->shareServiceManager->generateServiceUrl(link, title, type); 0452 d->shareServiceManager->openUrl(url); 0453 } 0454 } 0455 0456 void ActionManagerImpl::initArticleListView(ArticleListView *articleList) 0457 { 0458 if (d->articleList) { 0459 return; 0460 } else { 0461 d->articleList = articleList; 0462 } 0463 0464 QAction *action = actionCollection()->addAction(QStringLiteral("go_previous_article")); 0465 action->setText(i18n("&Previous Article")); 0466 connect(action, &QAction::triggered, articleList, &ArticleListView::slotPreviousArticle); 0467 actionCollection()->setDefaultShortcut(action, QKeySequence(Qt::Key_Left)); 0468 action = actionCollection()->addAction(QStringLiteral("go_next_article")); 0469 action->setText(i18n("&Next Article")); 0470 connect(action, &QAction::triggered, articleList, &ArticleListView::slotNextArticle); 0471 actionCollection()->setDefaultShortcut(action, QKeySequence(Qt::Key_Right)); 0472 } 0473 0474 void ActionManagerImpl::initSubscriptionListView(SubscriptionListView *subscriptionListView) 0475 { 0476 if (d->subscriptionListView) { 0477 return; 0478 } else { 0479 d->subscriptionListView = subscriptionListView; 0480 } 0481 0482 KActionCollection *coll = actionCollection(); 0483 0484 QAction *action = coll->addAction(QStringLiteral("go_prev_feed")); 0485 action->setText(i18n("&Previous Feed")); 0486 connect(action, &QAction::triggered, subscriptionListView, &SubscriptionListView::slotPrevFeed); 0487 coll->setDefaultShortcut(action, QKeySequence(Qt::Key_P)); 0488 0489 action = coll->addAction(QStringLiteral("go_next_feed")); 0490 action->setText(i18n("&Next Feed")); 0491 connect(action, &QAction::triggered, subscriptionListView, &SubscriptionListView::slotNextFeed); 0492 coll->setDefaultShortcut(action, QKeySequence(Qt::Key_N)); 0493 0494 action = coll->addAction(QStringLiteral("go_next_unread_feed")); 0495 action->setIcon(QIcon::fromTheme(QStringLiteral("go-down"))); 0496 action->setText(i18n("N&ext Unread Feed")); 0497 connect(action, &QAction::triggered, subscriptionListView, &SubscriptionListView::slotNextUnreadFeed); 0498 coll->setDefaultShortcut(action, QKeySequence(Qt::ALT | Qt::Key_Plus)); 0499 0500 action = coll->addAction(QStringLiteral("go_prev_unread_feed")); 0501 action->setIcon(QIcon::fromTheme(QStringLiteral("go-up"))); 0502 action->setText(i18n("Prev&ious Unread Feed")); 0503 connect(action, &QAction::triggered, subscriptionListView, &SubscriptionListView::slotPrevUnreadFeed); 0504 coll->setDefaultShortcut(action, QKeySequence(Qt::ALT | Qt::Key_Minus)); 0505 0506 action = coll->addAction(QStringLiteral("feedstree_home")); 0507 action->setText(i18n("Go to Top of Tree")); 0508 connect(action, &QAction::triggered, subscriptionListView, &SubscriptionListView::slotItemBegin); 0509 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::Key_Home)); 0510 0511 action = coll->addAction(QStringLiteral("feedstree_end")); 0512 action->setText(i18n("Go to Bottom of Tree")); 0513 connect(action, &QAction::triggered, subscriptionListView, &SubscriptionListView::slotItemEnd); 0514 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::Key_End)); 0515 0516 action = coll->addAction(QStringLiteral("feedstree_left")); 0517 action->setText(i18n("Go Left in Tree")); 0518 connect(action, &QAction::triggered, subscriptionListView, &SubscriptionListView::slotItemLeft); 0519 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::Key_Left)); 0520 0521 action = coll->addAction(QStringLiteral("feedstree_right")); 0522 action->setText(i18n("Go Right in Tree")); 0523 connect(action, &QAction::triggered, subscriptionListView, &SubscriptionListView::slotItemRight); 0524 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::Key_Right)); 0525 0526 action = coll->addAction(QStringLiteral("feedstree_up")); 0527 action->setText(i18n("Go Up in Tree")); 0528 connect(action, &QAction::triggered, subscriptionListView, &SubscriptionListView::slotItemUp); 0529 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::Key_Up)); 0530 0531 action = coll->addAction(QStringLiteral("feedstree_down")); 0532 action->setText(i18n("Go Down in Tree")); 0533 connect(action, &QAction::triggered, subscriptionListView, &SubscriptionListView::slotItemDown); 0534 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::Key_Down)); 0535 0536 action = coll->addAction(QStringLiteral("feed_hide_read")); 0537 action->setCheckable(true); 0538 action->setText(i18n("Hide Read Feeds")); 0539 action->setChecked(Settings::hideReadFeeds()); 0540 connect(action, &QAction::triggered, subscriptionListView, &SubscriptionListView::slotSetHideReadFeeds); 0541 0542 action = coll->addAction(QStringLiteral("feed_lock_in_place")); 0543 action->setCheckable(true); 0544 action->setText(i18n("Lock Feeds In Place")); 0545 action->setChecked(Settings::lockFeedsInPlace()); 0546 connect(action, &QAction::triggered, subscriptionListView, &SubscriptionListView::slotSetLockFeedsInPlace); 0547 0548 action = coll->addAction(QStringLiteral("auto_expand_folders")); 0549 action->setCheckable(true); 0550 action->setText(i18n("Auto-expand folders with unread articles")); 0551 action->setChecked(Settings::autoExpandFolders()); 0552 connect(action, &QAction::triggered, subscriptionListView, &SubscriptionListView::slotSetAutoExpandFolders); 0553 } 0554 0555 void ActionManagerImpl::initTabWidget(TabWidget *tabWidget) 0556 { 0557 if (d->tabWidget) { 0558 return; 0559 } else { 0560 d->tabWidget = tabWidget; 0561 } 0562 0563 KActionCollection *coll = actionCollection(); 0564 0565 QAction *action = coll->addAction(QStringLiteral("select_next_tab")); 0566 action->setText(i18n("Select Next Tab")); 0567 connect(action, &QAction::triggered, d->tabWidget, &TabWidget::slotNextTab); 0568 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::Key_Period)); 0569 0570 action = coll->addAction(QStringLiteral("select_previous_tab")); 0571 action->setText(i18n("Select Previous Tab")); 0572 connect(action, &QAction::triggered, d->tabWidget, &TabWidget::slotPreviousTab); 0573 coll->setDefaultShortcut(action, QKeySequence(Qt::Key_Comma | Qt::CTRL)); 0574 0575 action = coll->addAction(QStringLiteral("tab_detach")); 0576 action->setIcon(QIcon::fromTheme(QStringLiteral("tab-detach"))); 0577 action->setText(i18n("Detach Tab")); 0578 connect(action, &QAction::triggered, d->tabWidget, &TabWidget::slotDetachTab); 0579 coll->setDefaultShortcut(action, QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_B)); 0580 0581 action = KStandardAction::copy(d->tabWidget, &TabWidget::slotCopy, coll); 0582 coll->addAction(QStringLiteral("viewer_copy"), action); 0583 0584 action = KStandardAction::print(d->tabWidget, &TabWidget::slotPrint, coll); 0585 coll->addAction(QStringLiteral("viewer_print"), action); 0586 0587 action = KStandardAction::printPreview(d->tabWidget, &TabWidget::slotPrintPreview, coll); 0588 coll->addAction(QStringLiteral("viewer_printpreview"), action); 0589 0590 action = coll->addAction(QStringLiteral("tab_mute")); 0591 action->setText(i18n("Mute")); 0592 connect(action, &QAction::triggered, d->tabWidget, &TabWidget::slotMute); 0593 0594 action = coll->addAction(QStringLiteral("tab_unmute")); 0595 action->setText(i18n("Unmute")); 0596 connect(action, &QAction::triggered, d->tabWidget, &TabWidget::slotUnMute); 0597 0598 action = new QAction(i18n("Speak Text"), this); 0599 action->setIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-text-to-speech"))); 0600 coll->addAction(QStringLiteral("speak_text"), action); 0601 connect(action, &QAction::triggered, d->tabWidget, &TabWidget::slotTextToSpeech); 0602 0603 action = new QAction(QIcon::fromTheme(QStringLiteral("edit-find")), i18n("&Find in Message..."), this); 0604 coll->addAction(QStringLiteral("find_in_messages"), action); 0605 connect(action, &QAction::triggered, d->tabWidget, &TabWidget::slotFindTextInHtml); 0606 coll->setDefaultShortcut(action, KStandardShortcut::find().first()); 0607 0608 action = coll->addAction(QStringLiteral("tab_copylinkaddress")); 0609 action->setText(i18n("Copy Link Address")); 0610 connect(action, &QAction::triggered, d->tabWidget, &TabWidget::slotCopyLinkAddress); 0611 0612 action = coll->addAction(QStringLiteral("tab_remove")); 0613 action->setIcon(QIcon::fromTheme(QStringLiteral("tab-close"))); 0614 action->setText(i18n("Close Tab")); 0615 connect(action, &QAction::triggered, d->tabWidget, &TabWidget::slotCloseTab); 0616 coll->setDefaultShortcuts(action, KStandardShortcut::close()); 0617 0618 d->zoomActionMenu = new WebEngineViewer::ZoomActionMenu(this); 0619 connect(d->zoomActionMenu, &WebEngineViewer::ZoomActionMenu::zoomChanged, d->tabWidget, &TabWidget::slotZoomChanged); 0620 0621 d->zoomActionMenu->setActionCollection(coll); 0622 d->zoomActionMenu->createZoomActions(); 0623 0624 QString actionname; 0625 for (int i = 1; i < 10; ++i) { 0626 actionname = QString::asprintf("activate_tab_%02d", i); 0627 action = new QAction(i18n("Activate Tab %1", i), this); 0628 coll->addAction(actionname, action); 0629 coll->setDefaultShortcut(action, QKeySequence(QStringLiteral("Alt+%1").arg(i))); 0630 connect(action, &QAction::triggered, d->tabWidget, &TabWidget::slotActivateTab); 0631 } 0632 action = coll->addAction(QStringLiteral("savelinkas")); 0633 action->setText(i18n("&Save Link As...")); 0634 connect(action, &QAction::triggered, d->tabWidget, &TabWidget::slotSaveLinkAs); 0635 0636 action = coll->addAction(QStringLiteral("copylinkaddress")); 0637 action->setText(i18n("Copy &Link Address")); 0638 connect(action, &QAction::triggered, d->tabWidget, &TabWidget::slotCopyLinkAddress); 0639 0640 action = new QAction(i18n("Copy Image Location"), this); 0641 action->setIcon(QIcon::fromTheme(QStringLiteral("view-media-visualization"))); 0642 coll->addAction(QStringLiteral("copy_image_location"), action); 0643 coll->setShortcutsConfigurable(action, false); 0644 connect(action, &QAction::triggered, d->tabWidget, &TabWidget::slotCopyImageLocation); 0645 0646 // save Image On Disk 0647 action = new QAction(i18n("Save Image On Disk..."), this); 0648 coll->addAction(QStringLiteral("saveas_imageurl"), action); 0649 coll->setShortcutsConfigurable(action, false); 0650 connect(action, &QAction::triggered, d->tabWidget, &TabWidget::slotSaveImageOnDisk); 0651 } 0652 0653 QWidget *ActionManagerImpl::container(const QString &name) 0654 { 0655 if (d->part->factory()) { 0656 return d->part->factory()->container(name, d->part); 0657 } else { 0658 return nullptr; 0659 } 0660 } 0661 0662 KActionCollection *ActionManagerImpl::actionCollection() const 0663 { 0664 return d->actionCollection; 0665 } 0666 0667 QAction *ActionManagerImpl::action(const QString &name) 0668 { 0669 return d->actionCollection ? d->actionCollection->action(name) : nullptr; 0670 } 0671 0672 void ActionManagerImpl::setArticleActionsEnabled(bool enabled){ 0673 #undef setActionEnabled 0674 #define setActionEnabled(name) \ 0675 { \ 0676 QAction *const a = action(name); \ 0677 if (a) { \ 0678 a->setEnabled(enabled); \ 0679 } \ 0680 } 0681 setActionEnabled(QStringLiteral("article_open")) setActionEnabled(QStringLiteral("article_open_external")) 0682 setActionEnabled(QStringLiteral("article_set_status_important")) setActionEnabled(QStringLiteral("article_set_status")) 0683 setActionEnabled(QStringLiteral("article_delete")) setActionEnabled(QStringLiteral("file_sendlink")) 0684 setActionEnabled(QStringLiteral("file_sendfile")) setActionEnabled(QStringLiteral("article_open_in_background")) 0685 setActionEnabled(QStringLiteral("share_serviceurl")) 0686 #undef setActionEnabled 0687 } 0688 0689 WebEngineViewer::ZoomActionMenu *ActionManagerImpl::zoomActionMenu() const 0690 { 0691 return d->zoomActionMenu; 0692 } 0693 0694 QString ActionManagerImpl::quickSearchLineText() const 0695 { 0696 return d->quickSearchLineText(); 0697 } 0698 0699 QString ActionManagerImpl::ActionManagerImplPrivate::quickSearchLineText() const 0700 { 0701 return mQuickSearchAction->shortcut().toString(); 0702 } 0703 0704 #include "moc_actionmanagerimpl.cpp"