File indexing completed on 2024-05-19 05:00:55

0001 /*
0002     This file is part of the KDE project.
0003 
0004     SPDX-FileCopyrightText: 2020 Stefano Crocco <stefano.crocco@alice.it>
0005 
0006     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0007 */
0008 
0009 #ifndef USERAGENT_H
0010 #define USERAGENT_H
0011 
0012 #include <KCModule>
0013 #include <KSharedConfig>
0014 
0015 #include <QDialog>
0016 #include <QScopedPointer>
0017 #include <QTimer>
0018 
0019 class QTreeWidgetItem;
0020 
0021 namespace Ui
0022 {
0023 class UserAgent;
0024 }
0025 
0026 /**
0027  * KCM which allows the user to configure the user agent string.
0028  *
0029  * It allows to choose a default user agent string and to create customized templates
0030  */
0031 class UserAgent : public KCModule
0032 {
0033     Q_OBJECT
0034 
0035 public:
0036     //TODO KF6: when dropping compatibility with KF5, remove QVariantList argument
0037     /**
0038      * @brief Constructor
0039      *
0040      * @param parent the parent widget
0041      * @param md as in `KCModule` constructor
0042      * @param args as in `KCModule` constructor
0043      */
0044     UserAgent(QObject *parent, const KPluginMetaData &md={}, const QVariantList &args={});
0045 
0046     /**
0047      * @brief Destructor
0048      */
0049     ~UserAgent();
0050 
0051 #if QT_VERSION_MAJOR < 6
0052     void setNeedsSave(bool needs) {emit changed(needs);}
0053 #endif
0054 
0055 public slots:
0056 
0057     /**
0058      * @brief Loads the settings from the configuration files
0059      *
0060      * It fills the templates widget, enables or disable the custom user agent check box
0061      * and fills the custom user agent string
0062      */
0063     void load() override;
0064 
0065     /**
0066      * @brief Resets the KCM to its default values
0067      */
0068     void defaults() override;
0069 
0070     /**
0071      * @brief Saves the user settings
0072      *
0073      */
0074     void save() override;
0075 
0076 private slots:
0077 
0078     /**
0079      * @brief Slot called when the user toggles the "Use custom user agent string" checkbox
0080      *
0081      * It enables or disables the custom user agent widget and the button to use the selected template
0082      * as custom user agent string
0083      * @param on whether the custom user agent should be enabled or disabled
0084      */
0085     void toggleCustomUA(bool on);
0086 
0087     /**
0088      * @brief Enables or disables the "use selected template" button
0089      *
0090      * The button is enabled if the use of a custom user agent is enabled and the template widget
0091      * has an item selected; otherwise it's disabled.
0092      */
0093     void enableDisableUseSelectedTemplateBtn();
0094 
0095     /**
0096      * @brief Fills the custom user agent lineedit with the selected template
0097      */
0098     void useSelectedTemplate();
0099 
0100     /**
0101      * @brief Fills the custom user agent lineedit with the double clicked template
0102      *
0103      * @param it the item the user doubled clicked on
0104      */
0105     void useDblClickedTemplate(QTreeWidgetItem *it, int);
0106 
0107     /**
0108      * @brief Creates a new template
0109      *
0110      * The user is shown a dialog to choose the name of the new template
0111      */
0112     void createNewTemplate();
0113 
0114     /**
0115      * @brief Creates a new template with the same content as the selected template
0116      *
0117      * The user is shown a dialog to choose the name of the new template
0118      */
0119     void duplicateTemplate();
0120 
0121     /**
0122      * @brief Delete the currently selected template
0123      */
0124     void deleteTemplate();
0125 
0126     /**
0127      * @brief Starts editing the currently selected template value
0128      *
0129      * Editing happens inline
0130      */
0131     void editTemplate();
0132 
0133     /**
0134      * @brief Starts renaming the currently selected template value
0135      *
0136      * Renaming happens inline
0137      */
0138     void renameTemplate();
0139 
0140     /**
0141      * @brief Enables or disables buttons depending on whether the template widget has a selection or not
0142      */
0143     void templateSelectionChanged();
0144 
0145     /**
0146      * @brief Slot called when the name or contents of a template changed
0147      *
0148      * It uses checkTemplatesValidity() to check if all templates are still valid and emits the `changed()` signal.
0149      * @param col the column which has changed
0150      */
0151     void templateChanged(QTreeWidgetItem*, int col);
0152 
0153     /**
0154      * @brief Checks whether the templates are valid
0155      *
0156      * If the templates aren't valid, the user is shown a messagewidget warning him of the problems.
0157      *
0158      * Templates are valid if they all have a name and there aren't duplicate names.
0159      * @note A template with an empty user agent string is considered valid, as the user may want not to
0160      * send an user agent string
0161      */
0162     void checkTemplatesValidity();
0163 
0164 private:
0165 
0166     /**
0167      * @brief Whether or not the user has choose to enable a custom User Agent
0168      *
0169      * @return `true` if the user has enabled the use of a custom User Agent and
0170      * `false` if he chose to use the default User Agent.
0171      */
0172     bool useCustomUserAgent() const;
0173 
0174     /**
0175      * @brief Type representing templates with a name and a user agent string
0176      */
0177     using TemplateMap = QMap<QString, QString>;
0178 
0179     /**
0180      * @brief Fills the template widget with the given entries
0181      * @note All existing entries are removed from the template widgets before adding the new ones
0182      * @param templates the templates to insert in the widget
0183      */
0184     void fillTemplateWidget(const TemplateMap &templates);
0185 
0186     /**
0187      * @brief Fills the custom user agent lineedit with the given string
0188      */
0189     void useTemplate(const QString &templ);
0190 
0191     /**
0192      * @brief The selected item in the template widget
0193      *
0194      * @return The selected item in the template widget or `nullptr` if there's no selection
0195      */
0196     QTreeWidgetItem* selectedTemplate() const;
0197 
0198     /**
0199      * @brief Creates a new template
0200      *
0201      * This method is used by `createNewTemplate` and `duplicateTemplate` and does the following:
0202      * - asks the user for the name of the new template
0203      * - creates the `QTreeWidgetItem` item for the new template, with the chosen name
0204      * - selects the new item
0205      * @return the new item or `nullptr` if the user chose to cancel the operation
0206      */
0207     QTreeWidgetItem* createNewTemplateInternal();
0208 
0209     /**
0210      * @brief Converts the contents of the template widget to a TemplateMap
0211      *
0212      * @return A TemplateMap where the first column represents the keys and the second the values
0213      */
0214     TemplateMap templatesFromUI() const;
0215 
0216     /**
0217      * @brief Writes the templates to the config file
0218      */
0219     void saveTemplates();
0220 
0221     /**
0222      * @brief The user agent string used by WebEnginePart by default.
0223      *
0224      * @return The default WebEnginePart user agent string
0225      * @internal
0226      * @note Obtaining this string isn't easy because, once `QWebEngineProfile::setHttpUserAgent` has been called,
0227      * `QWebEngineProfile` doesn't provide a way to get the original value. To avoid this problem, a new `QWebEngineProfile`
0228      * could be created; however, this would be a waste of resources, so the following alternative approach is used:
0229      * - we assume that if someone called `QWebEngineProfile::setHttpUserAgent` on the default profile, it also set a
0230      * dynamic property called `defaultUserAgent` on the profile
0231      * - if the default profile has the `defaultUserAgent` dynamic property, its contents are used as default user agent string
0232      * - if the default profile doesn't have the `defaultUserAgent` dynamic property, we assume that `QWebEngineProfile::setHttpUserAgent`
0233      * hasn't been called and use `QWebEngineProfile::httpUserAgent()` as default user agent string
0234      */
0235     static QString defaultUserAgent();
0236 
0237 private:
0238     /**
0239      * @brief The UI object
0240      */
0241     QScopedPointer<Ui::UserAgent> m_ui;
0242 
0243     /**
0244      * @brief The main config object
0245      */
0246     KSharedConfig::Ptr m_config;
0247 
0248     /**
0249      * @brief The config object where templates are saved
0250      */
0251     KSharedConfig::Ptr m_templatesConfig;
0252 };
0253 
0254 #endif // USERAGENT_H