File indexing completed on 2024-04-21 04:57:56

0001 /*
0002     This file is part of Akregator.
0003 
0004     SPDX-FileCopyrightText: 2004 Teemu Rytilahti <tpr@d5k.net>
0005     SPDX-FileCopyrightText: 2023 Stefano Crocco <stefano.crocco@alice.it>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later WITH LicenseRef-Qt-exception
0008 */
0009 
0010 #ifndef KONQFEEDICON_H
0011 #define KONQFEEDICON_H
0012 
0013 #include <QPointer>
0014 #include <konq_kpart_plugin.h>
0015 #include <QMenu>
0016 
0017 #include "asyncselectorinterface.h"
0018 
0019 #if QT_VERSION_MAJOR < 6
0020 #include <KParts/SelectorInterface>
0021 #endif
0022 
0023 /**
0024 @author Teemu Rytilahti
0025 */
0026 class KUrlLabel;
0027 
0028 namespace KParts
0029 {
0030 class StatusBarExtension;
0031 class ReadOnlyPart;
0032 }
0033 
0034 namespace Akregator
0035 {
0036     /**
0037      * Class representing a feed
0038      */
0039     class Feed
0040     {
0041     public:
0042         /**
0043          * @brief Default constructor
0044          */
0045         Feed() {}
0046 
0047         /**
0048          * @brief Constructor
0049          * @param url the feed URL
0050          * @param title the feed title
0051          * @param mimeType the feed mime type
0052          */
0053         Feed(const QString &url, const QString &title, const QString &mimeType) : m_url(url), m_title(title), m_mimeType(mimeType) {}
0054 
0055         /**
0056          * @brief The feed URL
0057          * @return the feed URL
0058          */
0059         const QString &url() const
0060         {
0061             return m_url;
0062         }
0063 
0064         /**
0065          * @brief The feed title
0066          * @return the feed title
0067          */
0068         const QString &title() const
0069         {
0070             return m_title;
0071         }
0072 
0073         /**
0074          * @brief The feed mime type
0075          * @return the feed mime type
0076          */
0077         const QString &mimeType() const
0078         {
0079             return m_mimeType;
0080         }
0081 
0082     private:
0083         QString m_url; ///<The feed URL
0084         QString m_title; ///<The feed title
0085         QString m_mimeType; ///<The feed mime type
0086     };
0087 
0088     typedef QList<Feed> FeedList;
0089 
0090 /**
0091  * @brief Class handling detection of feeds in a page and displaying of the feeds icon in the statusbar.
0092  *
0093  * Currently, this class needs to support two different APIs for the part:
0094  * - the old, _synchronous_, KParts::SelectorInterface interface implemented by KHtmlPart and KWebkitPart
0095  * - the new, _asynchronous_ AsyncSelectorInterface interface implemented by WebEnginePart
0096  * The only difference in the two cases is in the slot called to update the feeds icon after a page finished
0097  * loading:
0098  * - updateFeedIcon() is used for the _synchronous_ API
0099  * - updateFeedIconAsync() is used for the _asynchronous_ API.
0100  */
0101 class KonqFeedIcon : public KonqParts::Plugin
0102 {
0103     Q_OBJECT
0104 
0105 public:
0106 
0107     /**
0108      * @brief Constructor
0109      */
0110     KonqFeedIcon(QObject *parent, const QVariantList &args);
0111 
0112     /**
0113      * @brief Destructor
0114      */
0115     ~KonqFeedIcon() override;
0116 
0117 private:
0118 
0119     /**
0120      * @brief Adds the feed icon to the status bar
0121      */
0122     void addFeedIcon();
0123 
0124     /**
0125      * @brief Whether the part current URL is suitable for looking for feeds
0126      *
0127      * Unusable URLs are: invalid URLs, URLs with empty scheme and URLs corresponding to local protocols
0128      * (according to `KProtocolInfo::protocolClass`)
0129      * @return `true` if the part's current URL can be searched for feeds and `false` otherwise
0130      */
0131     bool isUrlUsable() const;
0132 
0133     QMenu* createMenuForFeed(const Feed &feed, QWidget *parent, bool addSection = false);
0134 
0135     static QAction* actionTitleForFeed(const QString &title, QWidget *parent);
0136 
0137     typedef AsyncSelectorInterface::Element Element;
0138     /**
0139      * @brief Fills the feeds list from the list of `link` elements found in a page
0140      * @param linkNodes the list of link nodes contained in the page
0141      * @note Not all elements in @p linkNodes actually represents a feed: FeedDetector::extractFromLinkTags() will
0142      * be used to select the ones to use
0143      */
0144     void fillFeedList(const QList<Element> &linkNodes);
0145 
0146     /**
0147      * @brief The part associated with this instance of the plugin
0148      */
0149     QPointer<KParts::ReadOnlyPart> m_part;
0150 
0151     /**
0152      * @brief The widget displaying the feed icon
0153      */
0154     KUrlLabel *m_feedIcon;
0155 
0156     /**
0157      * @brief The status bar extension
0158      */
0159     KParts::StatusBarExtension *m_statusBarEx;
0160 
0161     /**
0162      * @brief The list of feeds found in the page
0163      */
0164     FeedList m_feedList;
0165 
0166     /**
0167      * @brief The popup menu used to add feeds to Akregator
0168      */
0169     QPointer<QMenu> m_menu;
0170 
0171 private slots:
0172 
0173     /**
0174      * @brief Displays the context menu
0175      */
0176     void contextMenu();
0177 
0178 #if QT_VERSION_MAJOR < 6
0179     /**
0180      * @brief Looks for feed links in the page using the _synchronous_ interface and adds the feed widget to the status bar if needed
0181      * @note This function is _synchronous_
0182      * @warning This should only be called after making sure the part supports the `KParts::SelectorInterface` interface
0183      */
0184     void updateFeedIcon();
0185 #endif
0186 
0187     /**
0188      * @brief Looks for feed links in the page using the _asynchronous_ interface and adds the feed widget to the status bar if needed
0189      * @note This function is _asynchronous_
0190      * @warning This should only be called after making sure the part supports the AsyncSelectorInterface interface
0191      */
0192     void updateFeedIconAsync();
0193 
0194     /**
0195      * @brief Removes the feed widget from the status bar
0196      */
0197     void removeFeedIcon();
0198 
0199     /**
0200      * @brief Adds all the feeds in the current page to Akgregator
0201      */
0202     void addAllFeeds();
0203 
0204     void copyFeedUrlToClipboard(const QString &url);
0205 
0206     void openFeedUrl(const QString &url, const QString &mimeType);
0207 
0208     /**
0209      * @brief Adds the feed with the given URL to Akregator
0210      * @param url the feed url
0211      */
0212     void addFeedToAkregator(const QString &url);
0213 };
0214 
0215 }
0216 #endif