File indexing completed on 2024-04-14 14:18:23

0001 /*
0002     SPDX-FileCopyrightText: 2000 Matthias Elter <elter@kde.org>
0003     SPDX-FileCopyrightText: 2003 Daniel Molkentin <molkentin@kde.org>
0004     SPDX-FileCopyrightText: 2003, 2006 Matthias Kretz <kretz@kde.org>
0005     SPDX-FileCopyrightText: 2021 Alexander Lohnau <alexander.lohnau@gmx.de>
0006 
0007     SPDX-License-Identifier: LGPL-2.0-or-later
0008 */
0009 
0010 #ifndef KCMULTIDIALOG_H
0011 #define KCMULTIDIALOG_H
0012 
0013 #include <QScrollArea>
0014 #include <QScrollBar>
0015 
0016 #include <KPageDialog>
0017 #include <KPluginMetaData>
0018 #include <kcmoduleinfo.h>
0019 
0020 class KCMultiDialogPrivate;
0021 
0022 /**
0023  * @short A class that offers a KPageDialog containing arbitrary
0024  *        KControl Modules.
0025  *
0026  * @author Matthias Elter <elter@kde.org>, Daniel Molkentin <molkentin@kde.org>
0027  */
0028 class KCMUTILS_EXPORT KCMultiDialog : public KPageDialog
0029 {
0030     Q_OBJECT
0031     Q_DECLARE_PRIVATE(KCMultiDialog)
0032 
0033 public:
0034     /**
0035      * Constructs a new KCMultiDialog
0036      *
0037      * @param parent The parent widget
0038      **/
0039     explicit KCMultiDialog(QWidget *parent = nullptr);
0040 
0041     /**
0042      * Destructor
0043      **/
0044     ~KCMultiDialog() override;
0045 
0046 #if KCMUTILS_ENABLE_DEPRECATED_SINCE(5, 85)
0047     /**
0048      * Add a module.
0049      *
0050      * The module is added according to its KCModuleInfo::weight(). The weight determines where in the list
0051      * the module will appear. Lighter modules on top, heavier modules at the bottom.
0052      *
0053      * @param module Specify the name of the module that is to be added
0054      *               to the list of modules the dialog will show.
0055      *
0056      * @param args The arguments that should be given to the KCModule when it is created
0057      *
0058      * @returns The @see KPageWidgetItem associated with the new dialog page.
0059      * @deprecated Since 5.85, use @p addModule(const KPluginMetaData &metaData) instead
0060      **/
0061     KCMUTILS_DEPRECATED_VERSION(5, 85, "use addModule(const KPluginMetaData &metaData) instead")
0062     KPageWidgetItem *addModule(const QString &module, const QStringList &args = QStringList());
0063 #endif
0064 
0065     /**
0066      * @since 5.84
0067      * @overload
0068      */
0069     KPageWidgetItem *addModule(const KPluginMetaData &metaData);
0070 
0071     /**
0072      * Add a module to the dialog. Its position will be determined based on the @c X-KDE-Weight value.
0073      * @param metaData KPluginMetaData that will be used to load the plugin
0074      * @param args The arguments that should be given to the KCModule when it is created
0075      * @since 5.85
0076      */
0077     KPageWidgetItem *addModule(const KPluginMetaData &metaData, const QStringList &args); // TODO KF6 merge with overload
0078 
0079 #if KCMUTILS_ENABLE_DEPRECATED_SINCE(5, 85)
0080     /**
0081      * Add a module.
0082      *
0083      * The module is added according to its KCModuleInfo::weight(). The weight determines where in the list
0084      * the module will appear. Lighter modules on top, heavier modules at the bottom.
0085      *
0086      * @param moduleinfo Pass a KCModuleInfo object which will be
0087      *                   used for creating the module. It will be added
0088      *                   to the list of modules the dialog will show.
0089      *
0090      * @param parent The @see KPageWidgetItem that should appear as parents
0091      *               in the tree view or a 0 pointer if there is no parent.
0092      *
0093      * @param args The arguments that should be given to the KCModule when it is created
0094      * @deprecated Since 5.85, use @p addModule(const KPluginMetaData &metaData) instead
0095      **/
0096     KCMUTILS_DEPRECATED_VERSION(5, 85, "use addModule(const KPluginMetaData &metaData) instead")
0097     KPageWidgetItem *addModule(const KCModuleInfo &moduleinfo, KPageWidgetItem *parent = nullptr, const QStringList &args = QStringList());
0098 #endif
0099 
0100     /**
0101      * Removes all modules from the dialog.
0102      */
0103     void clear();
0104 
0105 Q_SIGNALS:
0106     /**
0107      * Emitted after all KCModules have been told to save their configuration.
0108      *
0109      * The applyClicked and okClicked signals are emitted before the
0110      * configuration is saved.
0111      */
0112     void configCommitted();
0113 
0114 #if KCMUTILS_ENABLE_DEPRECATED_SINCE(5, 85)
0115     /**
0116      * Emitted after the KCModules have been told to save their configuration.
0117      * It is emitted once for every instance the KCMs that were changed belong
0118      * to.
0119      *
0120      * You can make use of this if you have more than one component in your
0121      * application. componentName tells you the instance that has to reload its
0122      * configuration.
0123      *
0124      * The applyClicked and okClicked signals are emitted before the
0125      * configuration is saved.
0126      *
0127      * @param componentName The name of the instance that needs to reload its
0128      *                     configuration.
0129      * @deprecated Since 5.85, use @p KCMultiDialog::configCommitted() instead
0130      */
0131     KCMUTILS_DEPRECATED_VERSION(5, 85, "use KCMultiDialog::configCommitted() instead")
0132     void configCommitted(const QByteArray &componentName);
0133 #endif
0134 
0135 protected:
0136     /**
0137      * This constructor can be used by subclasses to provide a custom KPageWidget.
0138      */
0139     KCMultiDialog(KPageWidget *pageWidget, QWidget *parent, Qt::WindowFlags flags = Qt::WindowFlags());
0140     KCMultiDialog(KCMultiDialogPrivate &dd, KPageWidget *pageWidget, QWidget *parent, Qt::WindowFlags flags = Qt::WindowFlags());
0141 
0142     KCMultiDialogPrivate *const d_ptr;
0143 
0144     void closeEvent(QCloseEvent *event) override;
0145     void showEvent(QShowEvent *event) override;
0146 
0147 protected Q_SLOTS:
0148     /**
0149      * This slot is called when the user presses the "Default" Button.
0150      * You can reimplement it if needed.
0151      *
0152      * @note Make sure you call the original implementation.
0153      **/
0154     void slotDefaultClicked();
0155 
0156     /**
0157      * This slot is called when the user presses the "Reset" Button.
0158      * You can reimplement it if needed.
0159      *
0160      * @note Make sure you call the original implementation.
0161      */
0162     void slotUser1Clicked();
0163 
0164     /**
0165      * This slot is called when the user presses the "Apply" Button.
0166      * You can reimplement it if needed.
0167      *
0168      * @note Make sure you call the original implementation.
0169      **/
0170     void slotApplyClicked();
0171 
0172     /**
0173      * This slot is called when the user presses the "OK" Button.
0174      * You can reimplement it if needed.
0175      *
0176      * @note Make sure you call the original implementation.
0177      **/
0178     void slotOkClicked();
0179 
0180     /**
0181      * This slot is called when the user presses the "Help" Button.
0182      * It reads the X-DocPath field of the currently selected KControl
0183      * module's .desktop file to find the path to the documentation,
0184      * which it then attempts to load.
0185      *
0186      * You can reimplement this slot if needed.
0187      *
0188      * @note Make sure you call the original implementation.
0189      **/
0190     void slotHelpClicked();
0191 
0192 private:
0193     Q_PRIVATE_SLOT(d_func(), void _k_slotCurrentPageChanged(KPageWidgetItem *, KPageWidgetItem *))
0194     Q_PRIVATE_SLOT(d_func(), void _k_clientChanged())
0195     Q_PRIVATE_SLOT(d_func(), void _k_updateHeader(bool use, const QString &message))
0196 };
0197 
0198 /**
0199  * @brief Custom QScrollArea class that doesn't limit its size hint
0200  *
0201  * See original QScrollArea::sizeHint() function,
0202  * where the size hint is bound by 36*24 font heights
0203  *
0204  * Workaround for https://bugreports.qt.io/browse/QTBUG-10459
0205  */
0206 
0207 class UnboundScrollArea : public QScrollArea
0208 {
0209     Q_OBJECT
0210 public:
0211     QSize sizeHint() const override
0212     {
0213         if (widget()) {
0214             // Try to avoid horizontal scrollbar, which just scrolls a scrollbar width.
0215             // We always need to reserve space for the vertical scroll bar,
0216             // because we can’t know here whether vertical scrolling will be used.
0217             QSize withScrollbar = widget()->sizeHint();
0218             withScrollbar.rwidth() += verticalScrollBar()->sizeHint().width() + 4;
0219             return withScrollbar;
0220         } else {
0221             return QScrollArea::sizeHint();
0222         }
0223     }
0224 
0225     UnboundScrollArea(QWidget *w)
0226         : QScrollArea(w)
0227     {
0228     }
0229     ~UnboundScrollArea() override = default;
0230 };
0231 
0232 #endif