Commit 63875cdd authored by Kevin Ottens's avatar Kevin Ottens

Revert "KCModule: Indicate when a setting has been changed from the default or previous value"

This reverts commit 11186c05.
parent 441f270c
......@@ -12,7 +12,6 @@ set(kconfigwidgets_SRCS
krecentfilesaction.cpp
kstandardaction.cpp
ktipdialog.cpp
settingsstatusindicator.cpp
)
ecm_qt_declare_logging_category(kconfigwidgets_SRCS
HEADER kconfigwidgets_debug.h
......
......@@ -3,7 +3,6 @@
* Copyright (C) 2003 Benjamin C Meyer (ben+kdelibs at meyerhome dot net)
* Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
* Copyright (C) 2017 Friedrich W. H. Kossebau <kossebau@kde.org>
* Copyright (C) 2020 Kevin Ottens <kevin.ottens@enioka.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -22,11 +21,8 @@
*/
#include "kconfigdialogmanager.h"
#include "kconfigdialogmanager_p.h"
#include "kconfigwidgets_debug.h"
#include "settingsstatusindicator_p.h"
#include <QComboBox>
#include <QGroupBox>
#include <QLabel>
......@@ -42,6 +38,32 @@ typedef QHash<QString, QByteArray> MyHash;
Q_GLOBAL_STATIC(MyHash, s_propertyMap)
Q_GLOBAL_STATIC(MyHash, s_changedMap)
class KConfigDialogManagerPrivate
{
public:
KConfigDialogManagerPrivate(KConfigDialogManager *q) : q(q), insideGroupBox(false) { }
public:
KConfigDialogManager * const q;
/**
* KConfigSkeleton object used to store settings
*/
KCoreConfigSkeleton *m_conf = nullptr;
/**
* Dialog being managed
*/
QWidget *m_dialog = nullptr;
QHash<QString, QWidget *> knownWidget;
QHash<QString, QWidget *> buddyWidget;
QSet<QWidget *> allExclusiveGroupBoxes;
bool insideGroupBox : 1;
bool trackChanges : 1;
};
KConfigDialogManager::KConfigDialogManager(QWidget *parent, KCoreConfigSkeleton *conf)
: QObject(parent), d(new KConfigDialogManagerPrivate(this))
{
......@@ -204,8 +226,6 @@ void KConfigDialogManager::setupWidget(QWidget *widget, KConfigSkeletonItem *ite
if (!item->isEqual(property(widget))) {
setProperty(widget, item->property());
}
d->updateWidgetIndicator(item->name(), widget);
}
bool KConfigDialogManager::parseChildren(const QWidget *widget, bool trackChanges)
......@@ -216,8 +236,8 @@ bool KConfigDialogManager::parseChildren(const QWidget *widget, bool trackChange
return valueChanged;
}
const QMetaMethod onWidgetModifiedSlot = metaObject()->method(metaObject()->indexOfSlot("onWidgetModified()"));
Q_ASSERT(onWidgetModifiedSlot.isValid() && metaObject()->indexOfSlot("onWidgetModified()")>=0);
const QMetaMethod widgetModifiedSignal = metaObject()->method(metaObject()->indexOfSignal("widgetModified()"));
Q_ASSERT(widgetModifiedSignal.isValid() && metaObject()->indexOfSignal("widgetModified()")>=0);
for (QObject *object : listOfChildren) {
if (!object->isWidgetType()) {
......@@ -246,7 +266,7 @@ bool KConfigDialogManager::parseChildren(const QWidget *widget, bool trackChange
const QList<QAbstractButton *> buttons = childWidget->findChildren<QAbstractButton *>();
for (QAbstractButton *button : buttons) {
connect(button, &QAbstractButton::toggled,
this, [this] { d->onWidgetModified(); });
this, &KConfigDialogManager::widgetModified);
}
}
......@@ -268,7 +288,7 @@ bool KConfigDialogManager::parseChildren(const QWidget *widget, bool trackChange
const QMetaProperty property = metaObject->property(indexOfProperty);
const QMetaMethod notifySignal = property.notifySignal();
if (notifySignal.isValid()) {
connect(childWidget, notifySignal, this, onWidgetModifiedSlot);
connect(childWidget, notifySignal, this, widgetModifiedSignal);
changeSignalFound = true;
}
}
......@@ -277,7 +297,7 @@ bool KConfigDialogManager::parseChildren(const QWidget *widget, bool trackChange
}
} else {
connect(childWidget, propertyChangeSignal,
this, SLOT(onWidgetModified()));
this, SIGNAL(widgetModified()));
changeSignalFound = true;
}
......@@ -368,7 +388,6 @@ void KConfigDialogManager::updateWidgets()
if (changed) {
QTimer::singleShot(0, this, &KConfigDialogManager::widgetModified);
d->updateAllWidgetIndicators();
}
}
......@@ -377,7 +396,6 @@ void KConfigDialogManager::updateWidgetsDefault()
bool bUseDefaults = d->m_conf->useDefaults(true);
updateWidgets();
d->m_conf->useDefaults(bUseDefaults);
d->updateAllWidgetIndicators();
}
void KConfigDialogManager::updateSettings()
......@@ -405,7 +423,6 @@ void KConfigDialogManager::updateSettings()
if (changed) {
d->m_conf->save();
emit settingsChanged();
d->updateAllWidgetIndicators();
}
}
......@@ -584,57 +601,3 @@ bool KConfigDialogManager::isDefault() const
return result;
}
KConfigDialogManagerPrivate::KConfigDialogManagerPrivate(KConfigDialogManager *q)
: q(q)
, insideGroupBox(false)
{
}
void KConfigDialogManagerPrivate::onWidgetModified()
{
const auto widget = qobject_cast<QWidget*>(q->sender());
Q_ASSERT(widget && widget->objectName().startsWith("kcfg_"));
const auto configId = widget->objectName().mid(5);
updateWidgetIndicator(configId, widget);
emit q->widgetModified();
}
void KConfigDialogManagerPrivate::updateWidgetIndicator(const QString &configId, QWidget *widget)
{
const auto item = m_conf->findItem(configId);
Q_ASSERT(item);
const auto widgetValue = q->property(widget);
const auto defaultValue = [item] {
item->swapDefault();
const auto value = item->property();
item->swapDefault();
return value;
}();
auto indicator = indicatorWidgets.value(configId);
const auto defaulted = widgetValue == defaultValue;
if (defaulted) {
delete indicator;
indicatorWidgets.remove(configId);
} else if (!indicator){
indicator = new SettingStatusIndicator(widget->parentWidget());
indicator->setTrackedWidget(widget);
QObject::connect(indicator, &SettingStatusIndicator::clicked, widget, [=] {
q->setProperty(widget, defaultValue);
emit q->widgetModified();
});
indicatorWidgets.insert(configId, indicator);
}
}
void KConfigDialogManagerPrivate::updateAllWidgetIndicators()
{
QHashIterator<QString, QWidget *> it(knownWidget);
while (it.hasNext()) {
it.next();
updateWidgetIndicator(it.key(), it.value());
}
}
#include "moc_kconfigdialogmanager.cpp"
......@@ -381,10 +381,8 @@ private:
* KConfigDialogManager KConfigDialogManagerPrivate class.
*/
KConfigDialogManagerPrivate *const d;
friend class KConfigDialogManagerPrivate;
Q_DISABLE_COPY(KConfigDialogManager)
Q_PRIVATE_SLOT(d, void onWidgetModified())
};
#endif // KCONFIGDIALOGMANAGER_H
......
/*
* This file is part of the KDE libraries
* Copyright (C) 2003 Benjamin C Meyer (ben+kdelibs at meyerhome dot net)
* Copyright (C) 2003 Waldo Bastian <bastian@kde.org>
* Copyright (C) 2017 Friedrich W. H. Kossebau <kossebau@kde.org>
* Copyright (C) 2020 Kevin Ottens <kevin.ottens@enioka.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KCONFIGDIALOGMANAGER_P_H
#define KCONFIGDIALOGMANAGER_P_H
#include <QHash>
#include <QSet>
#include <QString>
class QWidget;
class KConfigDialogManager;
class KCoreConfigSkeleton;
class SettingStatusIndicator;
class KConfigDialogManagerPrivate
{
public:
KConfigDialogManagerPrivate(KConfigDialogManager *q);
void onWidgetModified();
void updateWidgetIndicator(const QString &configId, QWidget *widget);
void updateAllWidgetIndicators();
public:
KConfigDialogManager * const q;
/**
* KConfigSkeleton object used to store settings
*/
KCoreConfigSkeleton *m_conf = nullptr;
/**
* Dialog being managed
*/
QWidget *m_dialog = nullptr;
QHash<QString, QWidget *> knownWidget;
QHash<QString, QWidget *> buddyWidget;
QHash<QString, SettingStatusIndicator *> indicatorWidgets;
QSet<QWidget *> allExclusiveGroupBoxes;
bool insideGroupBox : 1;
bool trackChanges : 1;
};
#endif // KCONFIGDIALOGMANAGER_P_H
/*
* This file is part of the KDE libraries
* Copyright (C) 2020 Kevin Ottens <kevin.ottens@enioka.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "settingsstatusindicator_p.h"
#include <QEvent>
#include <QIcon>
#include <QPainter>
#include <QRegularExpression>
#include <QVariant>
namespace {
constexpr const int INDICATOR_ICON_SIZE = 16;
constexpr const int INDICATOR_SIZE = INDICATOR_ICON_SIZE + 8;
constexpr const char *originalPosProperty = "originalPos";
constexpr const char *originalWidthProperty = "originalWidth";
bool isWidgetAtParentEdge(QWidget *widget)
{
const auto leftToRight = widget->isLeftToRight();
if (leftToRight) {
const auto right = widget->pos().x() + widget->width();
const auto parentWidth = widget->parentWidget()->width();
return right == parentWidth;
} else {
return widget->pos().x() == 0;
}
}
int widgetForcedWidth(QWidget *widget)
{
// We actually respect the minimum size hint to avoid the widget looking odd
// worst case scenario the indicator isn't visible if the widget is ending at the very
// edge of the window and is already too small to be resized, it's a very unlikely case
// though, when reaching the edge it's often greedy in space anyway
return qMax(widget->width() - INDICATOR_SIZE, widget->minimumSizeHint().width());
}
int widgetExpectedWidth(QWidget *widget)
{
if (isWidgetAtParentEdge(widget)) {
return widgetForcedWidth(widget);
} else {
return widget->width();
}
}
}
SettingStatusIndicator::SettingStatusIndicator(QWidget *parent)
: QToolButton(parent)
{
setAutoRaise(true);
setIconSize({INDICATOR_ICON_SIZE, INDICATOR_ICON_SIZE});
setIcon(QIcon::fromTheme("edit-reset"));
setFocusPolicy(Qt::NoFocus);
setVisible(true);
}
SettingStatusIndicator::~SettingStatusIndicator()
{
setTrackedWidget(nullptr); // This will neatly reset the width offset
}
void SettingStatusIndicator::setTrackedWidget(QWidget *widget)
{
if (m_trackedWidget == widget) {
return;
}
if (m_trackedWidget) {
resetWidthOffset();
m_trackedWidget->removeEventFilter(this);
}
m_trackedWidget = widget;
if (!m_trackedWidget) {
return;
}
forceWidthOffset();
applyLayout();
setVisible(m_trackedWidget->isVisible());
m_trackedWidget->installEventFilter(this);
}
bool SettingStatusIndicator::eventFilter(QObject *watched, QEvent *event)
{
Q_UNUSED(watched)
if (event->type() == QEvent::Resize && !m_forcingSize) {
if (forceWidthOffset()) {
return true;
}
}
switch (event->type()) {
case QEvent::Resize:
case QEvent::Move:
applyLayout();
break;
case QEvent::Show:
setVisible(true);
break;
case QEvent::Hide:
setVisible(false);
break;
default:
break;
}
return false;
}
bool SettingStatusIndicator::forceWidthOffset()
{
// Force resizing only when necessary
if (!isWidgetAtParentEdge(m_trackedWidget)) {
return false;
}
m_forcingSize = true;
m_trackedWidget->setProperty(originalWidthProperty, m_trackedWidget->width());
m_trackedWidget->setProperty(originalPosProperty, m_trackedWidget->pos());
m_trackedWidget->resize(widgetForcedWidth(m_trackedWidget), m_trackedWidget->height());
if (!m_trackedWidget->isLeftToRight()) {
m_trackedWidget->move(m_trackedWidget->pos() + QPoint(INDICATOR_SIZE, 0));
}
m_forcingSize = false;
return true;
}
void SettingStatusIndicator::resetWidthOffset()
{
const auto originalWidth = m_trackedWidget->property(originalWidthProperty);
const auto originalPos = m_trackedWidget->property(originalPosProperty);
if (originalWidth.isValid()) {
Q_ASSERT(originalPos.isValid());
m_forcingSize = true;
auto size = m_trackedWidget->size();
size.setWidth(originalWidth.toInt());
m_trackedWidget->resize(size);
m_trackedWidget->move(originalPos.toPoint());
m_trackedWidget->setProperty(originalWidthProperty, QVariant());
m_trackedWidget->setProperty(originalPosProperty, QVariant());
m_forcingSize = false;
}
}
void SettingStatusIndicator::applyLayout()
{
resize(INDICATOR_SIZE, INDICATOR_SIZE);
const auto leftToRight = m_trackedWidget->isLeftToRight();
auto x = leftToRight ? m_trackedWidget->pos().x() + m_trackedWidget->width()
: m_trackedWidget->pos().x() - width();
const auto y = m_trackedWidget->pos().y() + (m_trackedWidget->height() - height()) / 2.0f;
// We didn't get resized which means we're not at the border of the window
// then we try to vertically line up with other indicators
const auto originalWidth = m_trackedWidget->property(originalWidthProperty);
if (!originalWidth.isValid() || m_trackedWidget->width() == originalWidth.toInt()) {
const auto re = QRegularExpression("^kcfg_");
const auto children = m_trackedWidget->parentWidget()->findChildren<QWidget*>(re, Qt::FindDirectChildrenOnly);
const auto xValues = [=] {
auto result = QVector<int>();
result.reserve(children.size());
std::transform(children.cbegin(), children.cend(),
std::back_inserter(result),
[=](QWidget *w) {
const auto localX = leftToRight ? widgetExpectedWidth(w) : -width();
return w->pos().x() + localX;
});
return result;
}();
if (leftToRight) {
x = *std::max_element(xValues.cbegin(), xValues.cend());
} else {
x = *std::min_element(xValues.cbegin(), xValues.cend());
}
}
move(x, y);
}
/*
* This file is part of the KDE libraries
* Copyright (C) 2020 Kevin Ottens <kevin.ottens@enioka.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef SETTINGSSTATUSINDICATOR_P_H
#define SETTINGSSTATUSINDICATOR_P_H
#include <QToolButton>
#include <QPointer>
class SettingStatusIndicator : public QToolButton
{
Q_OBJECT
public:
explicit SettingStatusIndicator(QWidget *parent);
~SettingStatusIndicator() override;
void setTrackedWidget(QWidget *widget);
protected:
bool eventFilter(QObject *watched, QEvent *event) override;
private:
bool forceWidthOffset();
void resetWidthOffset();
void applyLayout();
QPointer<QWidget> m_trackedWidget;
bool m_forcingSize = false;
};
#endif // SETTINGSSTATUSINDICATOR_P_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment