File indexing completed on 2024-04-28 05:11:02

0001 /*
0002     This file is part of Akregator.
0003 
0004     SPDX-FileCopyrightText: 2004 Stanislav Karchebny <Stanislav.Karchebny@kdemail.net>
0005     SPDX-FileCopyrightText: 2004 Sashmit Bhaduri <smt@vfemail.net>
0006     SPDX-FileCopyrightText: 2005 Frank Osterfeld <osterfeld@kde.org>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
0009 */
0010 
0011 #pragma once
0012 
0013 #include "akregatorpart_export.h"
0014 #include "articleviewer-ng/webengine/articleviewerwebenginewidgetng.h"
0015 #include "feed.h"
0016 
0017 #include <QUrl>
0018 
0019 #include <QPointer>
0020 #include <QWidget>
0021 
0022 #include <QSharedPointer>
0023 
0024 class KConfig;
0025 class KConfigGroup;
0026 
0027 class QDomDocument;
0028 class QSplitter;
0029 
0030 namespace Akregator
0031 {
0032 class WebEngineFrame;
0033 class AbstractSelectionController;
0034 class ActionManagerImpl;
0035 class ArticleListView;
0036 class ArticleViewerWidget;
0037 class Folder;
0038 class FeedList;
0039 class FeedListManagementImpl;
0040 class Frame;
0041 class Part;
0042 class SearchBar;
0043 class SubscriptionListView;
0044 class TabWidget;
0045 class MainFrame;
0046 class DownloadArticleJob;
0047 /**
0048  * This is the main widget of the view, containing tree view, article list, viewer etc.
0049  */
0050 class AKREGATORPART_EXPORT MainWidget : public QWidget
0051 {
0052     Q_OBJECT
0053 public:
0054     /** constructor
0055     @param part the Akregator::Part which contains this widget
0056     @param parent parent widget
0057     @param actionManager Akregator specific implementation of ActionManager
0058     @param name the name of the widget (@ref QWidget )
0059     */
0060     MainWidget(Akregator::Part *part, QWidget *parent, ActionManagerImpl *actionManager, const QString &name);
0061 
0062     /** destructor.  Note that cleanups should be done in
0063     slotOnShutdown(), so we don't risk accessing self-deleting objects after deletion. */
0064     ~MainWidget() override;
0065 
0066     /** saves settings. Make sure that the Settings singleton is not destroyed yet when saveSettings is called */
0067     void saveSettings();
0068 
0069     /** Adds the feeds in @c doc to the "Imported Folder"
0070     @param doc the DOM tree (OPML) of the feeds to import */
0071     void importFeedList(const QDomDocument &doc);
0072 
0073     /**
0074      * @return the displayed Feed List in OPML format
0075      */
0076     [[nodiscard]] QDomDocument feedListToOPML();
0077 
0078     void setFeedList(const QSharedPointer<FeedList> &feedList);
0079 
0080     /**
0081      * Add a feed to a group.
0082      * @param url The URL of the feed to add.
0083      * @param group The name of the folder into which the feed is added.
0084      * If the group does not exist, it is created.
0085      * The feed is added as the last member of the group.
0086      */
0087     void addFeedToGroup(const QString &url, const QString &group);
0088 
0089     [[nodiscard]] QSharedPointer<FeedList> allFeedsList()
0090     {
0091         return m_feedList;
0092     }
0093 
0094     /** session management **/
0095     void readProperties(const KConfigGroup &config);
0096     void saveProperties(KConfigGroup &config);
0097 
0098     // Returns true if networking is available
0099     [[nodiscard]] bool isNetworkAvailable() const;
0100 
0101     enum ViewMode { NormalView = 0, WidescreenView, CombinedView };
0102 
0103     ViewMode viewMode() const
0104     {
0105         return m_viewMode;
0106     }
0107 
0108     void currentArticleInfo(QString &link, QString &title);
0109     void updateQuickSearchLineText();
0110 Q_SIGNALS:
0111     /** emitted when the unread count of "All Feeds" was changed */
0112     void signalUnreadCountChanged(int);
0113 
0114     /** emitted when the articles selected changed */
0115     void signalArticlesSelected(const QList<Akregator::Article> &);
0116 
0117 public Q_SLOTS:
0118 
0119     /** opens the current article (currentItem) in external browser
0120     TODO: use selected instead of current? */
0121     void slotOpenSelectedArticlesInBrowser();
0122 
0123     /** opens current article in new tab, background/foreground depends on settings TODO: use selected instead of current? */
0124     void slotOpenSelectedArticles();
0125     void slotOpenSelectedArticlesInBackground();
0126 
0127     void slotOnShutdown();
0128 
0129     /** selected tree node has changed */
0130     void slotNodeSelected(Akregator::TreeNode *node);
0131 
0132     /** the article selection has changed */
0133     void slotArticleSelected(const Akregator::Article &);
0134 
0135     void ensureArticleTabVisible();
0136 
0137     /** emits @ref signalUnreadCountChanged(int) */
0138     void slotSetTotalUnread();
0139 
0140     /** copies the link of current article to clipboard
0141      */
0142     void slotCopyLinkAddress();
0143 
0144     void slotRequestNewFrame(int &frameId);
0145 
0146     /** adds a new feed to the feed tree */
0147     void slotFeedAdd();
0148     /** adds a feed group to the feed tree */
0149     void slotFeedAddGroup();
0150     /** removes the currently selected feed (ask for confirmation)*/
0151     void slotFeedRemove();
0152     /** calls the properties dialog for feeds, starts renaming for feed groups */
0153     void slotFeedModify();
0154     /** fetches the currently selected feed */
0155     void slotFetchCurrentFeed();
0156     /** starts fetching of all feeds in the tree */
0157     void slotFetchAllFeeds();
0158     /** marks all articles in the currently selected feed as read */
0159     void slotMarkAllRead();
0160     /** marks all articles in all feeds in the tree as read */
0161     void slotMarkAllFeedsRead();
0162     /** opens the homepage of the currently selected feed */
0163     void slotOpenHomepage();
0164 
0165     /** reloads all open tabs */
0166     void slotReloadAllTabs();
0167 
0168     /** toggles the keep flag of the currently selected article */
0169     void slotArticleToggleKeepFlag(bool enabled);
0170     /** deletes the currently selected article */
0171     void slotArticleDelete();
0172     /** marks the currently selected article as read */
0173     void slotSetSelectedArticleRead();
0174     /** marks the currently selected article as unread */
0175     void slotSetSelectedArticleUnread();
0176     /** marks the currently selected article as new */
0177     void slotSetSelectedArticleNew();
0178     /** marks the currently selected article as read after a user-set delay */
0179     void slotSetCurrentArticleReadDelayed();
0180 
0181     /** switches view mode to normal view */
0182     void slotNormalView();
0183     /** switches view mode to widescreen view */
0184     void slotWidescreenView();
0185     /** switches view mode to combined view */
0186     void slotCombinedView();
0187     /** toggles the visibility of the filter bar */
0188     void slotToggleShowQuickFilter();
0189 
0190     /** selects the previous unread article in the article list */
0191     void slotPrevUnreadArticle();
0192     /** selects the next unread article in the article list */
0193     void slotNextUnreadArticle();
0194 
0195     void slotMoveCurrentNodeUp();
0196     void slotMoveCurrentNodeDown();
0197     void slotMoveCurrentNodeLeft();
0198     void slotMoveCurrentNodeRight();
0199 
0200     void slotSendLink();
0201     void slotSendFile();
0202 
0203     void slotNetworkStatusChanged(bool status);
0204 
0205     void slotFocusQuickSearch();
0206 
0207 protected:
0208     void sendArticle(bool attach = false);
0209 
0210     void addFeed(const QString &url, TreeNode *after, Folder *parent, bool autoExec = true);
0211 
0212 protected Q_SLOTS:
0213 
0214     /** special behaviour in article list view (TODO: move code there?) */
0215     void slotMouseButtonPressed(int button, const QUrl &);
0216 
0217     /** opens the link of an article in the external browser */
0218     void slotOpenArticleInBrowser(const Akregator::Article &article);
0219 
0220     void slotDoIntervalFetches();
0221     void slotDeleteExpiredArticles();
0222 
0223     void slotFetchingStarted();
0224     void slotFetchingStopped();
0225 
0226     void slotFramesChanged();
0227 
0228 private Q_SLOTS:
0229     void slotShowStatusBarMessage(const QString &msg);
0230     void slotCurrentFrameChanged(int frameId);
0231     void slotArticleAction(Akregator::ArticleViewerWebEngine::ArticleAction type, const QString &articleId, const QString &feed);
0232     void slotSettingsChanged();
0233 
0234 private:
0235     void slotSetFocusToViewer();
0236     void sendArticle(const QByteArray &text, const QString &title, bool attach);
0237     void deleteExpiredArticles(const QSharedPointer<FeedList> &feedList);
0238     void connectFrame(Akregator::WebEngineFrame *frame);
0239     void cleanUpDownloadFile();
0240     /** ask for confirmation when marking feed(s) as read */
0241     [[nodiscard]] bool confirmMarkFeedAsRead(bool isSingleFeed, bool isGroup);
0242 
0243     /** opens current article in new tab, background/foreground depends on settings TODO: use selected instead of current? */
0244     void openSelectedArticles(bool openInBackground);
0245 
0246     AbstractSelectionController *m_selectionController;
0247     QSharedPointer<FeedList> m_feedList;
0248 
0249     SubscriptionListView *m_feedListView = nullptr;
0250     ArticleListView *m_articleListView = nullptr;
0251 
0252     ArticleViewerWidget *m_articleViewer = nullptr;
0253     TabWidget *m_tabWidget = nullptr;
0254 
0255     QWidget *m_mainTab = nullptr;
0256     MainFrame *m_mainFrame = nullptr;
0257 
0258     SearchBar *m_searchBar = nullptr;
0259 
0260     QSplitter *m_articleSplitter = nullptr;
0261     QSplitter *m_horizontalSplitter = nullptr;
0262 
0263     Akregator::Part *m_part = nullptr;
0264     ViewMode m_viewMode = NormalView;
0265 
0266     QTimer *m_fetchTimer = nullptr;
0267     QTimer *m_expiryTimer = nullptr;
0268     QTimer *m_markReadTimer = nullptr;
0269 
0270     bool m_shuttingDown = false;
0271     bool m_displayingAboutPage = false;
0272 
0273     ActionManagerImpl *m_actionManager = nullptr;
0274     FeedListManagementImpl *const m_feedListManagementInterface = nullptr;
0275 
0276     QWidget *m_articleWidget = nullptr;
0277     QList<QPointer<Akregator::DownloadArticleJob>> mListDownloadArticleJobs;
0278 };
0279 } // namespace Akregator