diff --git a/src/kcolorschememanager.h b/src/kcolorschememanager.h --- a/src/kcolorschememanager.h +++ b/src/kcolorschememanager.h @@ -106,6 +106,26 @@ KActionMenu *createSchemeSelectionMenu(const QString &text, const QString &selectedSchemeName, QObject *parent); KActionMenu *createSchemeSelectionMenu(const QString &selectedSchemeName, QObject *parent); + /** + * Creates a KActionMenu populated with all the available color schemes and a "System" which refers to the + * system scheme. + * All actions are in an action group and when one of the actions is triggered the scheme + * referenced by this action is activated. + * + * The KActionMenu will not be updated in case the installed color schemes change. It's the + * task of the user of the KActionMenu to monitor for changes if required. + * + * Actions have model indices as their data + * + * @param icon The icon to use for the KActionMenu + * @param text The text to use for the KActionMenu + * @param selectedSchemeName The name of the color scheme to select, if empty, system default is selected + * @param parent The parent of the KActionMenu + * @return KActionMenu populated with all available color schemes. + * @see activateScheme + */ + KActionMenu *createSchemeSelectionMenuWithDefaultEntry(const QIcon &icon, const QString &text, const QString &selectedSchemeName, QObject *parent); + public Q_SLOTS: /** * @brief Activates the KColorScheme identified by the provided @p index. diff --git a/src/kcolorschememanager.cpp b/src/kcolorschememanager.cpp --- a/src/kcolorschememanager.cpp +++ b/src/kcolorschememanager.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,63 @@ { } +KActionMenu *KColorSchemeManagerPrivate::createSchemeMenu(const QIcon &icon, const QString &name, const QString &selectedSchemeName, bool defaultEntry, QObject *parent) +{ + KActionMenu *menu = new KActionMenu(icon, name, parent); + QActionGroup *group = new QActionGroup(menu); + + if (defaultEntry) { + const KSharedConfigPtr config = KSharedConfig::openConfig(QStringLiteral("kdeglobals")); + const QString systemScheme = KConfigGroup(config, "General").readEntry("ColorScheme", QString()); + const QModelIndexList modelList = model->match(model->index(0), Qt::DisplayRole, systemScheme, 1, Qt::MatchExactly); + const QModelIndex index = modelList.value(0, QModelIndex()); + + if (index.isValid()) { + QAction *const resetAction = new QAction(index.data(Qt::DecorationRole).value(), + i18n("Default (%1)", systemScheme), + menu); + resetAction->setCheckable(true); + resetAction->setData(index); + resetAction->setActionGroup(group); + resetAction->setChecked(selectedSchemeName.isEmpty()); + + menu->addAction(resetAction); + menu->addSeparator(); + } else { + defaultEntry = false; + } + } + + // check again, to see if defaultEntry was unset above + if (defaultEntry) { + QObject::connect(group, &QActionGroup::triggered, [](QAction *action) { + const QString schemePath = action->data().toModelIndex().data(Qt::UserRole).toString(); + // hint for the style to synchronize the color scheme with the window manager/compositor + qApp->setProperty("KDE_COLOR_SCHEME_PATH", schemePath); + qApp->setPalette(KColorScheme::createApplicationPalette(KSharedConfig::openConfig(schemePath))); + }); + } else { + QObject::connect(group, &QActionGroup::triggered, [](QAction *action) { + qApp->setProperty("KDE_COLOR_SCHEME_PATH", action->data()); + qApp->setPalette(KColorScheme::createApplicationPalette(KSharedConfig::openConfig(action->data().toString()))); + }); + } + + for (int i = 0; i < model->rowCount(); ++i) { + QModelIndex index = model->index(i); + QAction *action = new QAction(index.data(Qt::DecorationRole).value(), index.data().toString(), menu); + action->setData(defaultEntry ? index : index.data(Qt::UserRole)); + action->setActionGroup(group); + action->setCheckable(true); + if (index.data().toString() == selectedSchemeName) { + action->setChecked(true); + } + menu->addAction(action); + } + + return menu; +} + KColorSchemeModel::KColorSchemeModel(QObject *parent) : QAbstractListModel(parent) { @@ -157,37 +215,25 @@ KActionMenu *KColorSchemeManager::createSchemeSelectionMenu(const QIcon &icon, const QString &name, const QString &selectedSchemeName, QObject *parent) { - KActionMenu *menu = new KActionMenu(icon, name, parent); - QActionGroup *group = new QActionGroup(menu); - connect(group, &QActionGroup::triggered, [](QAction * action) { - // hint for the style to synchronize the color scheme with the window manager/compositor - qApp->setProperty("KDE_COLOR_SCHEME_PATH", action->data()); - qApp->setPalette(KColorScheme::createApplicationPalette(KSharedConfig::openConfig(action->data().toString()))); - }); - for (int i = 0; i < d->model->rowCount(); ++i) { - QModelIndex index = d->model->index(i); - QAction *action = new QAction(index.data(Qt::DecorationRole).value(), index.data().toString(), menu); - action->setData(index.data(Qt::UserRole)); - action->setActionGroup(group); - action->setCheckable(true); - if (index.data().toString() == selectedSchemeName) { - action->setChecked(true); - } - menu->addAction(action); - } - return menu; + return d->createSchemeMenu(icon, name, selectedSchemeName, false, parent); } KActionMenu *KColorSchemeManager::createSchemeSelectionMenu(const QString &text, const QString &selectedSchemeName, QObject *parent) { - return createSchemeSelectionMenu(QIcon(), text, selectedSchemeName, parent); + return d->createSchemeMenu(QIcon(), text, selectedSchemeName, false, parent); } KActionMenu *KColorSchemeManager::createSchemeSelectionMenu(const QString &selectedSchemeName, QObject *parent) { - return createSchemeSelectionMenu(QIcon(), QString(), selectedSchemeName, parent); + return d->createSchemeMenu(QIcon(), QString(), selectedSchemeName, false, parent); } +KActionMenu *KColorSchemeManager::createSchemeSelectionMenuWithDefaultEntry(const QIcon &icon, const QString &name, const QString &selectedSchemeName, QObject *parent) +{ + return d->createSchemeMenu(icon, name, selectedSchemeName, true, parent); +} + + void KColorSchemeManager::activateScheme(const QModelIndex &index) { if (!index.isValid()) { diff --git a/src/kcolorschememanager_p.h b/src/kcolorschememanager_p.h --- a/src/kcolorschememanager_p.h +++ b/src/kcolorschememanager_p.h @@ -47,6 +47,7 @@ { public: KColorSchemeManagerPrivate(); + KActionMenu *createSchemeMenu(const QIcon &icon, const QString &name, const QString &selectedSchemeName, bool defaultEntry, QObject *parent); QScopedPointer model; }; diff --git a/tests/kcolorschemedemo.cpp b/tests/kcolorschemedemo.cpp --- a/tests/kcolorschemedemo.cpp +++ b/tests/kcolorschemedemo.cpp @@ -43,7 +43,8 @@ QToolButton *button = new QToolButton(box); button->setIcon(QIcon::fromTheme(QStringLiteral("fill-color"))); - button->setMenu(manager->createSchemeSelectionMenu(QStringLiteral("Oxygen"), button)->menu()); + button->setMenu(manager->createSchemeSelectionMenuWithDefaultEntry({}, {}, {}, button)->menu()); + box->addButton(button, QDialogButtonBox::InvalidRole); QVBoxLayout *layout = new QVBoxLayout(this);