diff --git a/src/kconfigdialog.h b/src/kconfigdialog.h --- a/src/kconfigdialog.h +++ b/src/kconfigdialog.h @@ -91,6 +91,33 @@ void settingsChanged(const QString &dialogName); public: + /** + * Options for handling and displaying pages. + */ + enum PageOption { + /** + * Page should not adapt to the content widget in any way. + * This means scrolling may be required to view the entire content. + * + * Page will also not be managed by KConfigDialogManager. + */ + NoPageOptions = 0, + + /** + * KConfigDialogManager should manage the page. + * @see KConfigDialogManager + */ + ManagePage = 1, + + /** + * Page should be resized by default to show the entire content. + * Scrolling may still be required on displays that cannot fit the + * entire content. + */ + FitPageSize = 2 + }; + Q_DECLARE_FLAGS(PageOptions, PageOption) + /** * @param parent - The parent of this object. Even though the class * deletes itself the parent should be set so the dialog can be centered @@ -134,6 +161,27 @@ const QString &header = QString(), bool manage = true); + /** + * Adds page to the dialog and to KConfigDialogManager. When an + * application is done adding pages show() should be called to + * display the dialog. + * @param page - Pointer to the page that is to be added to the dialog. + * This object is reparented. + * @param itemName - Name of the page. + * @param options - Options to apply to the added page. + * @param pixmapName - Name of the icon that should be used, if needed, when + * displaying the page. The string may either be the name of a themed + * icon (e.g. "document-save"), which the internal icon loader will be + * used to retrieve, or an absolute path to the pixmap on disk. + * @param header - Header text use in the list modes. Ignored in Tabbed + * mode. If empty, the itemName text is used when needed. + * @returns The KPageWidgetItem associated with the page. + */ + KPageWidgetItem *addPage(QWidget *page, const QString &itemName, + PageOptions options, + const QString &pixmapName = QString(), + const QString &header = QString()); + /** * Adds page to the dialog that is managed by a custom KConfigDialogManager. * This is useful for dialogs that contain settings spread over more than @@ -157,6 +205,31 @@ const QString &pixmapName = QString(), const QString &header = QString()); + /** + * Adds page to the dialog that is managed by a custom KConfigDialogManager. + * This is useful for dialogs that contain settings spread over more than + * one configuration file and thus have/need more than one KConfigSkeleton. + * When an application is done adding pages show() should be called to + * display the dialog. + * @param page - Pointer to the page that is to be added to the dialog. + * This object is reparented. + * @param config - Config object containing corresponding settings. + * @param itemName - Name of the page. + * @param options - Options to apply to the added page. + * @param pixmapName - Name of the icon that should be used, if needed, when + * displaying the page. The string may either be the name of a themed + * icon (e.g. "document-save"), which the internal icon loader will be + * used to retrieve, or an absolute path to the pixmap on disk. + * @param header - Header text use in the list modes. Ignored in Tabbed + * mode. If empty, the itemName text is used when needed. + * @returns The KPageWidgetItem associated with the page. + */ + KPageWidgetItem *addPage(QWidget *page, KCoreConfigSkeleton *config, + const QString &itemName, + PageOptions options, + const QString &pixmapName = QString(), + const QString &header = QString()); + /** * See if a dialog with the name 'name' already exists. * @see showDialog() @@ -273,5 +346,6 @@ Q_DISABLE_COPY(KConfigDialog) }; -#endif //KCONFIGDIALOG_H +Q_DECLARE_OPERATORS_FOR_FLAGS(KConfigDialog::PageOptions) +#endif //KCONFIGDIALOG_H diff --git a/src/kconfigdialog.cpp b/src/kconfigdialog.cpp --- a/src/kconfigdialog.cpp +++ b/src/kconfigdialog.cpp @@ -37,6 +37,7 @@ #include #include #include +#include class Q_DECL_HIDDEN KConfigDialog::KConfigDialogPrivate { @@ -80,6 +81,7 @@ } KPageWidgetItem *addPageInternal(QWidget *page, const QString &itemName, + PageOptions options, const QString &pixmapName, const QString &header); void setupManagerConnections(KConfigDialogManager *manager); @@ -122,13 +124,29 @@ const QString &pixmapName, const QString &header, bool manage) +{ + PageOptions options = NoPageOptions; + if (manage) { + options |= ManagePage; + } + + return addPage(page, itemName, options, pixmapName, header); +} + +KPageWidgetItem *KConfigDialog::addPage(QWidget *page, + const QString &itemName, + PageOptions options, + const QString &pixmapName, + const QString &header) { Q_ASSERT(page); if (!page) { return nullptr; } - KPageWidgetItem *item = d->addPageInternal(page, itemName, pixmapName, header); + KPageWidgetItem *item = d->addPageInternal(page, itemName, options, pixmapName, header); + + const bool manage = options & ManagePage; if (manage) { d->manager->addWidget(page); } @@ -149,13 +167,23 @@ const QString &itemName, const QString &pixmapName, const QString &header) +{ + return addPage(page, config, itemName, NoPageOptions, pixmapName, header); +} + +KPageWidgetItem *KConfigDialog::addPage(QWidget *page, + KCoreConfigSkeleton *config, + const QString &itemName, + PageOptions options, + const QString &pixmapName, + const QString &header) { Q_ASSERT(page); if (!page) { return nullptr; } - KPageWidgetItem *item = d->addPageInternal(page, itemName, pixmapName, header); + KPageWidgetItem *item = d->addPageInternal(page, itemName, options, pixmapName, header); d->managerForPage[page] = new KConfigDialogManager(page, config); d->setupManagerConnections(d->managerForPage[page]); @@ -170,23 +198,51 @@ return item; } +// Helper class overriding sizeHint() in QScrollArea to fit the content QWidget. +class FittingScrollArea : public QScrollArea +{ +public: + FittingScrollArea(QWidget* parent) + : QScrollArea(parent) + {} + + QSize sizeHint() const override + { + const QWidget* const contentWidget = widget(); + if (contentWidget == nullptr) { + return QScrollArea::sizeHint(); + } + + const int width = contentWidget->sizeHint().width() + verticalScrollBar()->width(); + const int height = contentWidget->sizeHint().height() + horizontalScrollBar()->height(); + return QSize(width, height); + } +}; + KPageWidgetItem *KConfigDialog::KConfigDialogPrivate::addPageInternal(QWidget *page, const QString &itemName, + PageOptions options, const QString &pixmapName, const QString &header) { QWidget *frame = new QWidget(q); QVBoxLayout *boxLayout = new QVBoxLayout(frame); boxLayout->setMargin(0); boxLayout->setMargin(0); - QScrollArea *scroll = new QScrollArea(q); + QScrollArea *scroll = nullptr; + if (options & FitPageSize) { + scroll = new FittingScrollArea(q); + scroll->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ); + } else { + scroll = new QScrollArea(q); + scroll->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ); + } scroll->setFrameShape(QFrame::NoFrame); scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); scroll->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); scroll->setWidget(page); scroll->setWidgetResizable(true); - scroll->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding ); boxLayout->addWidget(scroll); KPageWidgetItem *item = new KPageWidgetItem(frame, itemName);