diff --git a/autotests/kcolorschemetest.cpp b/autotests/kcolorschemetest.cpp --- a/autotests/kcolorschemetest.cpp +++ b/autotests/kcolorschemetest.cpp @@ -33,11 +33,11 @@ void benchConstruction_data() { KColorSchemeManager manager; - if (!manager.model()->rowCount()) { + if (manager.model()->rowCount() <= 1) { QSKIP("no scheme files found, cannot run benchmark"); } - const auto anyScheme = manager.model()->index(0, 0).data(Qt::UserRole).toString(); + const auto anyScheme = manager.model()->index(1, 0).data(Qt::UserRole).toString(); QVERIFY(QFile::exists(anyScheme)); QTest::addColumn("file"); diff --git a/src/kcolorschememanager.h b/src/kcolorschememanager.h --- a/src/kcolorschememanager.h +++ b/src/kcolorschememanager.h @@ -36,7 +36,8 @@ * A small helper to get access to all available color schemes and activating a scheme in the * QApplication. This is useful for applications which want to provide a selection of custom color * schemes to their user. For example it is very common for photo and painting applications to use - * a dark color scheme even if the default is a light scheme. + * a dark color scheme even if the default is a light scheme. Since version 5.67 it also allows + * going back to following the system color scheme. * * The KColorSchemeManager provides access to a QAbstractItemModel which holds all the available * schemes. A possible usage looks like the following: @@ -72,14 +73,17 @@ * A QAbstractItemModel of all available color schemes. * * The model provides the name of the scheme in Qt::DisplayRole, a preview - * in Qt::DelegateRole and the full path to the scheme file in Qt::UserRole. + * in Qt::DelegateRole and the full path to the scheme file in Qt::UserRole. The system theme + * has an empty Qt::UserRole. * * @return Model of all available color schemes. */ QAbstractItemModel *model() const; /** * Returns the model index for the scheme with the given @p name. If no such - * scheme exists an invalid index is returned. + * scheme exists an invalid index is returned. If you pass an empty + * string the index that is equivalent to going back to following the system scheme is returned + * for versions 5.67 and newer. * @see model */ QModelIndex indexForScheme(const QString &name) const; @@ -90,7 +94,7 @@ * referenced by this action is activated. * * The color scheme with the same name as @p selectedSchemeName will be checked. If none - * of the available color schemes has the same name, no action will be checked. + * of the available color schemes has the same name, the system theme entry will be checked. * * 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. @@ -105,15 +109,20 @@ KActionMenu *createSchemeSelectionMenu(const QIcon &icon, const QString &text, const QString &selectedSchemeName, QObject *parent); KActionMenu *createSchemeSelectionMenu(const QString &text, const QString &selectedSchemeName, QObject *parent); KActionMenu *createSchemeSelectionMenu(const QString &selectedSchemeName, QObject *parent); + /** + * @since 5.67 + */ + KActionMenu *createSchemeSelectionMenu(QObject *parent); public Q_SLOTS: /** * @brief Activates the KColorScheme identified by the provided @p index. * * Installs the KColorScheme as the QApplication's QPalette. * * @param index The index for the KColorScheme to activate. - * The index must reference the QAbstractItemModel provided by @link model @endlink + * The index must reference the QAbstractItemModel provided by @link model @endlink. Since + * version 5.67 passing an invalid index activates the system scheme. * @see model() */ void activateScheme(const QModelIndex &index); diff --git a/src/kcolorschememanager.cpp b/src/kcolorschememanager.cpp --- a/src/kcolorschememanager.cpp +++ b/src/kcolorschememanager.cpp @@ -22,14 +22,18 @@ #include #include #include +#include #include #include #include #include #include #include #include +#include + +constexpr int defaultSchemeRow = 0; KColorSchemeManagerPrivate::KColorSchemeManagerPrivate() : model(new KColorSchemeModel()) @@ -102,6 +106,7 @@ std::sort(m_data.begin(), m_data.end(), [](const KColorSchemeModelData & first, const KColorSchemeModelData & second) { return first.name < second.name; }); + m_data.insert(defaultSchemeRow, {i18n("Default"), QString(), QIcon::fromTheme("edit-undo")}); endResetModel(); } @@ -153,7 +158,11 @@ QModelIndex KColorSchemeManager::indexForScheme(const QString &name) const { - for (int i = 0; i < d->model->rowCount(); ++i) { + // Empty string is mapped to "reset to the system scheme" + if (name.isEmpty()) { + return d->model->index(defaultSchemeRow); + } + for (int i = 1; i < d->model->rowCount(); ++i) { QModelIndex index = d->model->index(i); if (index.data().toString() == name) { return index; @@ -166,28 +175,29 @@ { 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()))); + connect(group, &QActionGroup::triggered, this, [this](QAction * action) { + activateScheme(d->model->index(action->data().toInt())); }); for (int i = 0; i < d->model->rowCount(); ++i) { QModelIndex index = d->model->index(i); QAction *action = new QAction(index.data(Qt::DisplayRole).toString(), menu); - action->setData(index.data(Qt::UserRole)); + action->setData(index.row()); action->setActionGroup(group); action->setCheckable(true); if (index.data().toString() == selectedSchemeName) { action->setChecked(true); } menu->addAction(action); } - + if (!group->checkedAction()) { + // If no (valid) color scheme has been selected we select the default one + group->actions()[defaultSchemeRow]->setChecked(true); + } connect(menu->menu(), &QMenu::aboutToShow, group, [this, group] { const auto actions = group->actions(); for (QAction *action : actions) { if (action->icon().isNull()) { - action->setIcon(d->model->createPreview(action->data().toString())); + action->setIcon(d->model->index(action->data().toInt()).data(Qt::DecorationRole).value()); } } }); @@ -197,23 +207,28 @@ KActionMenu *KColorSchemeManager::createSchemeSelectionMenu(const QString &text, const QString &selectedSchemeName, QObject *parent) { - return createSchemeSelectionMenu(QIcon(), text, selectedSchemeName, parent); + return createSchemeSelectionMenu(QIcon::fromTheme("preferences-desktop-color"), text, selectedSchemeName, parent); } KActionMenu *KColorSchemeManager::createSchemeSelectionMenu(const QString &selectedSchemeName, QObject *parent) { - return createSchemeSelectionMenu(QIcon(), QString(), selectedSchemeName, parent); + return createSchemeSelectionMenu(QIcon::fromTheme("preferences-desktop-color"), i18n("Color Scheme"), selectedSchemeName, parent); +} + +KActionMenu *KColorSchemeManager::createSchemeSelectionMenu (QObject *parent) +{ + return createSchemeSelectionMenu(QIcon::fromTheme("preferences-desktop-color"), i18n("Color Scheme"), QString(), parent); } void KColorSchemeManager::activateScheme(const QModelIndex &index) { - if (!index.isValid()) { - return; - } - if (index.model() != d->model.data()) { - return; - } - // hint for the style to synchronize the color scheme with the window manager/compositor + // hint for plasma-integration to synchronize the color scheme with the window manager/compositor + // The property needs to be set before the palette change because is is checked upon the + // ApplicationPaletteChange event. qApp->setProperty("KDE_COLOR_SCHEME_PATH", index.data(Qt::UserRole)); - qApp->setPalette(KColorScheme::createApplicationPalette(KSharedConfig::openConfig(index.data(Qt::UserRole).toString()))); + if (index.isValid() && index.model() == d->model.data() && index.row() != defaultSchemeRow) { + qApp->setPalette(KColorScheme::createApplicationPalette(KSharedConfig::openConfig(index.data(Qt::UserRole).toString()))); + } else { + qApp->setPalette(qApp->style()->standardPalette()); + } }