KConfigWidgets

kconfigdialogmanager.cpp
1 /*
2  This file is part of the KDE libraries
3  SPDX-FileCopyrightText: 2003 Benjamin C Meyer <ben+kdelibs at meyerhome dot net>
4  SPDX-FileCopyrightText: 2003 Waldo Bastian <[email protected]>
5  SPDX-FileCopyrightText: 2017 Friedrich W. H. Kossebau <[email protected]>
6  SPDX-FileCopyrightText: 2020 Kevin Ottens <[email protected]>
7  SPDX-FileCopyrightText: 2020 Cyril Rossi <[email protected]>
8 
9  SPDX-License-Identifier: LGPL-2.0-or-later
10 */
11 
12 #include "kconfigdialogmanager.h"
13 #include "kconfigdialogmanager_p.h"
14 #include "kconfigwidgets_debug.h"
15 
16 #include <QComboBox>
17 #include <QGroupBox>
18 #include <QLabel>
19 #include <QLayout>
20 #include <QMetaObject>
21 #include <QMetaProperty>
22 #include <QRadioButton>
23 #include <QTimer>
24 
25 #include <KConfigSkeleton>
26 
28 Q_GLOBAL_STATIC(MyHash, s_propertyMap)
29 Q_GLOBAL_STATIC(MyHash, s_changedMap)
30 
32  : QObject(parent)
33  , d(new KConfigDialogManagerPrivate(this))
34 {
35  d->m_conf = conf;
36  d->m_dialog = parent;
37  init(true);
38 }
39 
40 #if KCONFIGWIDGETS_BUILD_DEPRECATED_SINCE(5, 84)
42  : QObject(parent)
43  , d(new KConfigDialogManagerPrivate(this))
44 {
45  d->m_conf = conf;
46  d->m_dialog = parent;
47  init(true);
48 }
49 #endif
50 
52 
53 // KF6: Drop this and get signals only from metaObject and/or widget's dynamic properties kcfg_property/kcfg_propertyNotify
55 {
56  if (s_propertyMap()->isEmpty()) {
57  s_propertyMap()->insert(QStringLiteral("KButtonGroup"), "current");
58  s_propertyMap()->insert(QStringLiteral("KColorButton"), "color");
59  s_propertyMap()->insert(QStringLiteral("KColorCombo"), "color");
60  s_propertyMap()->insert(QStringLiteral("KKeySequenceWidget"), "keySequence");
61  }
62 
63  if (s_changedMap()->isEmpty()) {
64  // QT
65  s_changedMap()->insert(QStringLiteral("QCheckBox"), SIGNAL(stateChanged(int)));
66  s_changedMap()->insert(QStringLiteral("QPushButton"), SIGNAL(clicked(bool)));
67  s_changedMap()->insert(QStringLiteral("QRadioButton"), SIGNAL(toggled(bool)));
68  s_changedMap()->insert(QStringLiteral("QGroupBox"), SIGNAL(toggled(bool)));
69  s_changedMap()->insert(QStringLiteral("QComboBox"), SIGNAL(activated(int)));
70  s_changedMap()->insert(QStringLiteral("QDateEdit"), SIGNAL(dateChanged(QDate)));
71  s_changedMap()->insert(QStringLiteral("QTimeEdit"), SIGNAL(timeChanged(QTime)));
72  s_changedMap()->insert(QStringLiteral("QDateTimeEdit"), SIGNAL(dateTimeChanged(QDateTime)));
73  s_changedMap()->insert(QStringLiteral("QDial"), SIGNAL(valueChanged(int)));
74  s_changedMap()->insert(QStringLiteral("QDoubleSpinBox"), SIGNAL(valueChanged(double)));
75  s_changedMap()->insert(QStringLiteral("QLineEdit"), SIGNAL(textChanged(QString)));
76  s_changedMap()->insert(QStringLiteral("QSlider"), SIGNAL(valueChanged(int)));
77  s_changedMap()->insert(QStringLiteral("QSpinBox"), SIGNAL(valueChanged(int)));
78  s_changedMap()->insert(QStringLiteral("QTextEdit"), SIGNAL(textChanged()));
79  s_changedMap()->insert(QStringLiteral("QTextBrowser"), SIGNAL(sourceChanged(QString)));
80  s_changedMap()->insert(QStringLiteral("QPlainTextEdit"), SIGNAL(textChanged()));
81  s_changedMap()->insert(QStringLiteral("QTabWidget"), SIGNAL(currentChanged(int)));
82 
83  // KDE
84  s_changedMap()->insert(QStringLiteral("KComboBox"), SIGNAL(activated(int)));
85  s_changedMap()->insert(QStringLiteral("KFontComboBox"), SIGNAL(activated(int)));
86  s_changedMap()->insert(QStringLiteral("KFontRequester"), SIGNAL(fontSelected(QFont)));
87  s_changedMap()->insert(QStringLiteral("KFontChooser"), SIGNAL(fontSelected(QFont)));
88  s_changedMap()->insert(QStringLiteral("KColorCombo"), SIGNAL(activated(QColor)));
89  s_changedMap()->insert(QStringLiteral("KColorButton"), SIGNAL(changed(QColor)));
90  s_changedMap()->insert(QStringLiteral("KDatePicker"), SIGNAL(dateSelected(QDate)));
91  s_changedMap()->insert(QStringLiteral("KDateWidget"), SIGNAL(changed(QDate)));
92  s_changedMap()->insert(QStringLiteral("KDateTimeWidget"), SIGNAL(valueChanged(QDateTime)));
93  s_changedMap()->insert(QStringLiteral("KEditListWidget"), SIGNAL(changed()));
94  s_changedMap()->insert(QStringLiteral("KListWidget"), SIGNAL(itemSelectionChanged()));
95  s_changedMap()->insert(QStringLiteral("KLineEdit"), SIGNAL(textChanged(QString)));
96  s_changedMap()->insert(QStringLiteral("KRestrictedLine"), SIGNAL(textChanged(QString)));
97  s_changedMap()->insert(QStringLiteral("KTextEdit"), SIGNAL(textChanged()));
98  s_changedMap()->insert(QStringLiteral("KUrlRequester"), SIGNAL(textChanged(QString)));
99  s_changedMap()->insert(QStringLiteral("KUrlComboRequester"), SIGNAL(textChanged(QString)));
100  s_changedMap()->insert(QStringLiteral("KUrlComboBox"), SIGNAL(urlActivated(QUrl)));
101  s_changedMap()->insert(QStringLiteral("KButtonGroup"), SIGNAL(changed(int)));
102  }
103 }
104 
106 {
107  initMaps();
108  return s_propertyMap();
109 }
110 
111 #if KCONFIGWIDGETS_BUILD_DEPRECATED_SINCE(5, 32)
113 {
114  initMaps();
115  return s_changedMap();
116 }
117 #endif
118 
119 void KConfigDialogManager::init(bool trackChanges)
120 {
121  initMaps();
122  d->trackChanges = trackChanges;
123 
124  // Go through all of the children of the widgets and find all known widgets
125  (void)parseChildren(d->m_dialog, trackChanges);
126 }
127 
129 {
130  (void)parseChildren(widget, true);
131 }
132 
134 {
135  QVariant minValue = item->minValue();
136  if (minValue.isValid()) {
137  // KSelector is using this property
138  if (widget->metaObject()->indexOfProperty("minValue") != -1) {
139  widget->setProperty("minValue", minValue);
140  }
141  if (widget->metaObject()->indexOfProperty("minimum") != -1) {
142  widget->setProperty("minimum", minValue);
143  }
144  }
145  QVariant maxValue = item->maxValue();
146  if (maxValue.isValid()) {
147  // KSelector is using this property
148  if (widget->metaObject()->indexOfProperty("maxValue") != -1) {
149  widget->setProperty("maxValue", maxValue);
150  }
151  if (widget->metaObject()->indexOfProperty("maximum") != -1) {
152  widget->setProperty("maximum", maxValue);
153  }
154  }
155 
156  if (widget->whatsThis().isEmpty()) {
157  QString whatsThis = item->whatsThis();
158  if (!whatsThis.isEmpty()) {
159  widget->setWhatsThis(whatsThis);
160  }
161  }
162 
163  if (widget->toolTip().isEmpty()) {
164  QString toolTip = item->toolTip();
165  if (!toolTip.isEmpty()) {
166  widget->setToolTip(toolTip);
167  }
168  }
169 
170  // If it is a QGroupBox with only autoExclusive buttons
171  // and has no custom property and the config item type
172  // is an integer, assume we want to save the index like we did with
173  // KButtonGroup instead of if it is checked or not
174  QGroupBox *gb = qobject_cast<QGroupBox *>(widget);
175  if (gb && getCustomProperty(gb).isEmpty()) {
176  const KConfigSkeletonItem *item = d->m_conf->findItem(widget->objectName().mid(5));
177  if (item->property().type() == QVariant::Int) {
178  QObjectList children = gb->children();
179  children.removeAll(gb->layout());
180  const QList<QAbstractButton *> buttons = gb->findChildren<QAbstractButton *>();
181  bool allAutoExclusiveDirectChildren = true;
182  for (QAbstractButton *button : buttons) {
183  allAutoExclusiveDirectChildren = allAutoExclusiveDirectChildren && button->autoExclusive() && button->parent() == gb;
184  }
185  if (allAutoExclusiveDirectChildren) {
186  d->allExclusiveGroupBoxes << widget;
187  }
188  }
189  }
190 
191  if (!item->isEqual(property(widget))) {
192  setProperty(widget, item->property());
193  }
194 
195  d->updateWidgetIndicator(item->name(), widget);
196 }
197 
198 bool KConfigDialogManager::parseChildren(const QWidget *widget, bool trackChanges)
199 {
200  bool valueChanged = false;
201  const QList<QObject *> listOfChildren = widget->children();
202  if (listOfChildren.isEmpty()) { //?? XXX
203  return valueChanged;
204  }
205 
206  const QMetaMethod onWidgetModifiedSlot = metaObject()->method(metaObject()->indexOfSlot("onWidgetModified()"));
207  Q_ASSERT(onWidgetModifiedSlot.isValid() && metaObject()->indexOfSlot("onWidgetModified()") >= 0);
208 
209  for (QObject *object : listOfChildren) {
210  if (!object->isWidgetType()) {
211  continue; // Skip non-widgets
212  }
213 
214  QWidget *childWidget = static_cast<QWidget *>(object);
215 
216  QString widgetName = childWidget->objectName();
217  bool bParseChildren = true;
218  bool bSaveInsideGroupBox = d->insideGroupBox;
219 
220  if (widgetName.startsWith(QLatin1String("kcfg_"))) {
221  // This is one of our widgets!
222  QString configId = widgetName.mid(5);
223  KConfigSkeletonItem *item = d->m_conf->findItem(configId);
224  if (item) {
225  d->knownWidget.insert(configId, childWidget);
226 
227  setupWidget(childWidget, item);
228 
229  if (trackChanges) {
230  bool changeSignalFound = false;
231 
232  if (d->allExclusiveGroupBoxes.contains(childWidget)) {
233  const QList<QAbstractButton *> buttons = childWidget->findChildren<QAbstractButton *>();
234  for (QAbstractButton *button : buttons) {
235  connect(button, &QAbstractButton::toggled, this, [this] {
236  d->onWidgetModified();
237  });
238  }
239  }
240 
241  QByteArray propertyChangeSignal = getCustomPropertyChangedSignal(childWidget);
242  if (propertyChangeSignal.isEmpty()) {
243  propertyChangeSignal = getUserPropertyChangedSignal(childWidget);
244  }
245 
246  if (propertyChangeSignal.isEmpty()) {
247  // get the change signal from the meta object
248  const QMetaObject *metaObject = childWidget->metaObject();
249  QByteArray userproperty = getCustomProperty(childWidget);
250  if (userproperty.isEmpty()) {
251  userproperty = getUserProperty(childWidget);
252  }
253  if (!userproperty.isEmpty()) {
254  const int indexOfProperty = metaObject->indexOfProperty(userproperty.constData());
255  if (indexOfProperty != -1) {
256  const QMetaProperty property = metaObject->property(indexOfProperty);
257  const QMetaMethod notifySignal = property.notifySignal();
258  if (notifySignal.isValid()) {
259  connect(childWidget, notifySignal, this, onWidgetModifiedSlot);
260  changeSignalFound = true;
261  }
262  }
263  } else {
264  qCWarning(KCONFIG_WIDGETS_LOG) << "Don't know how to monitor widget" << childWidget->metaObject()->className() << "for changes!";
265  }
266  } else {
267  connect(childWidget, propertyChangeSignal.constData(), this, SLOT(onWidgetModified()));
268  changeSignalFound = true;
269  }
270 
271  if (changeSignalFound) {
272  QComboBox *cb = qobject_cast<QComboBox *>(childWidget);
273  if (cb && cb->isEditable()) {
275  }
276  }
277  }
278  QGroupBox *gb = qobject_cast<QGroupBox *>(childWidget);
279  if (!gb) {
280  bParseChildren = false;
281  } else {
282  d->insideGroupBox = true;
283  }
284  } else {
285  qCWarning(KCONFIG_WIDGETS_LOG) << "A widget named" << widgetName << "was found but there is no setting named" << configId;
286  }
287  } else if (QLabel *label = qobject_cast<QLabel *>(childWidget)) {
288  QWidget *buddy = label->buddy();
289  if (!buddy) {
290  continue;
291  }
292  QString buddyName = buddy->objectName();
293  if (buddyName.startsWith(QLatin1String("kcfg_"))) {
294  // This is one of our widgets!
295  QString configId = buddyName.mid(5);
296  d->buddyWidget.insert(configId, childWidget);
297  }
298  }
299  // kf5: commented out to reduce debug output
300  // #ifndef NDEBUG
301  // else if (!widgetName.isEmpty() && trackChanges)
302  // {
303  // QHash<QString, QByteArray>::const_iterator changedIt = s_changedMap()->constFind(childWidget->metaObject()->className());
304  // if (changedIt != s_changedMap()->constEnd())
305  // {
306  // if ((!d->insideGroupBox || !qobject_cast<QRadioButton*>(childWidget)) &&
307  // !qobject_cast<QGroupBox*>(childWidget) &&!qobject_cast<QTabWidget*>(childWidget) )
308  // qCDebug(KCONFIG_WIDGETS_LOG) << "Widget '" << widgetName << "' (" << childWidget->metaObject()->className() << ") remains unmanaged.";
309  // }
310  // }
311  // #endif
312 
313  if (bParseChildren) {
314  // this widget is not known as something we can store.
315  // Maybe we can store one of its children.
316  valueChanged |= parseChildren(childWidget, trackChanges);
317  }
318  d->insideGroupBox = bSaveInsideGroupBox;
319  }
320  return valueChanged;
321 }
322 
324 {
325  bool changed = false;
326  bool bSignalsBlocked = signalsBlocked();
327  blockSignals(true);
328 
329  QWidget *widget;
330  QHashIterator<QString, QWidget *> it(d->knownWidget);
331  while (it.hasNext()) {
332  it.next();
333  widget = it.value();
334 
335  KConfigSkeletonItem *item = d->m_conf->findItem(it.key());
336  if (!item) {
337  qCWarning(KCONFIG_WIDGETS_LOG) << "The setting" << it.key() << "has disappeared!";
338  continue;
339  }
340 
341  if (!item->isEqual(property(widget))) {
342  setProperty(widget, item->property());
343  // qCDebug(KCONFIG_WIDGETS_LOG) << "The setting" << it.key() << "[" << widget->className() << "] has changed";
344  changed = true;
345  }
346  if (item->isImmutable()) {
347  widget->setEnabled(false);
348  QWidget *buddy = d->buddyWidget.value(it.key(), nullptr);
349  if (buddy) {
350  buddy->setEnabled(false);
351  }
352  }
353  }
354  blockSignals(bSignalsBlocked);
355 
356  if (changed) {
358  d->updateAllWidgetIndicators();
359  }
360 }
361 
363 {
364  bool bUseDefaults = d->m_conf->useDefaults(true);
365  updateWidgets();
366  d->m_conf->useDefaults(bUseDefaults);
367  d->updateAllWidgetIndicators();
368 }
369 
371 {
372  d->setDefaultsIndicatorsVisible(enabled);
373 }
374 
376 {
377  bool changed = false;
378 
379  QWidget *widget;
380  QHashIterator<QString, QWidget *> it(d->knownWidget);
381  while (it.hasNext()) {
382  it.next();
383  widget = it.value();
384 
385  KConfigSkeletonItem *item = d->m_conf->findItem(it.key());
386  if (!item) {
387  qCWarning(KCONFIG_WIDGETS_LOG) << "The setting" << it.key() << "has disappeared!";
388  continue;
389  }
390 
391  QVariant fromWidget = property(widget);
392  if (!item->isEqual(fromWidget)) {
393  item->setProperty(fromWidget);
394  changed = true;
395  }
396  }
397  if (changed) {
398  d->m_conf->save();
400  d->updateAllWidgetIndicators();
401  }
402 }
403 
405 {
406  MyHash *map = s_propertyMap();
407  const QMetaObject *metaObject = widget->metaObject();
408  const QString className(QLatin1String(metaObject->className()));
409  auto it = map->find(className);
410  if (it == map->end()) {
411  const QMetaProperty userProp = metaObject->userProperty();
412  if (userProp.isValid()) {
413  it = map->insert(className, userProp.name());
414  // qCDebug(KCONFIG_WIDGETS_LOG) << "class name: '" << className
415  //<< " 's USER property: " << metaProperty.name() << endl;
416  } else {
417  return QByteArray(); // no USER property
418  }
419  }
420 
421  const QComboBox *cb = qobject_cast<const QComboBox *>(widget);
422  if (cb) {
423  const char *qcomboUserPropertyName = cb->QComboBox::metaObject()->userProperty().name();
424  const int qcomboUserPropertyIndex = qcomboUserPropertyName ? cb->QComboBox::metaObject()->indexOfProperty(qcomboUserPropertyName) : -1;
425  const char *widgetUserPropertyName = metaObject->userProperty().name();
426  const int widgetUserPropertyIndex = widgetUserPropertyName ? cb->metaObject()->indexOfProperty(widgetUserPropertyName) : -1;
427 
428  // no custom user property set on subclass of QComboBox?
429  if (qcomboUserPropertyIndex == widgetUserPropertyIndex) {
430  return QByteArray(); // use the q/kcombobox special code
431  }
432  }
433 
434  return it != map->end() ? it.value() : QByteArray{};
435 }
436 
438 {
439  QVariant prop(widget->property("kcfg_property"));
440  if (prop.isValid()) {
441  if (!prop.canConvert(QVariant::ByteArray)) {
442  qCWarning(KCONFIG_WIDGETS_LOG) << "kcfg_property on" << widget->metaObject()->className() << "is not of type ByteArray";
443  } else {
444  return prop.toByteArray();
445  }
446  }
447  return QByteArray();
448 }
449 
451 {
452  const QString className = QLatin1String(widget->metaObject()->className());
453  auto changedIt = s_changedMap()->constFind(className);
454 
455  if (changedIt == s_changedMap()->constEnd()) {
456  // If the class name of the widget wasn't in the monitored widgets map, then look for
457  // it again using the super class name. This fixes a problem with using QtRuby/Korundum
458  // widgets with KConfigXT where 'Qt::Widget' wasn't being seen a the real deal, even
459  // though it was a 'QWidget'.
460  if (widget->metaObject()->superClass()) {
461  const QString parentClassName = QLatin1String(widget->metaObject()->superClass()->className());
462  changedIt = s_changedMap()->constFind(parentClassName);
463  }
464  }
465 
466  return (changedIt == s_changedMap()->constEnd()) ? QByteArray() : *changedIt;
467 }
468 
470 {
471  QVariant prop(widget->property("kcfg_propertyNotify"));
472  if (prop.isValid()) {
473  if (!prop.canConvert(QVariant::ByteArray)) {
474  qCWarning(KCONFIG_WIDGETS_LOG) << "kcfg_propertyNotify on" << widget->metaObject()->className() << "is not of type ByteArray";
475  } else {
476  return prop.toByteArray();
477  }
478  }
479  return QByteArray();
480 }
481 
483 {
484  if (d->allExclusiveGroupBoxes.contains(w)) {
485  const QList<QAbstractButton *> buttons = w->findChildren<QAbstractButton *>();
486  if (v.toInt() < buttons.count()) {
487  buttons[v.toInt()]->setChecked(true);
488  }
489  return;
490  }
491 
492  QByteArray userproperty = getCustomProperty(w);
493  if (userproperty.isEmpty()) {
494  userproperty = getUserProperty(w);
495  }
496  if (userproperty.isEmpty()) {
497  QComboBox *cb = qobject_cast<QComboBox *>(w);
498  if (cb) {
499  if (cb->isEditable()) {
500  int i = cb->findText(v.toString());
501  if (i != -1) {
502  cb->setCurrentIndex(i);
503  } else {
504  cb->setEditText(v.toString());
505  }
506  } else {
507  cb->setCurrentIndex(v.toInt());
508  }
509  return;
510  }
511  }
512  if (userproperty.isEmpty()) {
513  qCWarning(KCONFIG_WIDGETS_LOG) << w->metaObject()->className() << "widget not handled!";
514  return;
515  }
516 
517  w->setProperty(userproperty.constData(), v);
518 }
519 
521 {
522  if (d->allExclusiveGroupBoxes.contains(w)) {
523  const QList<QAbstractButton *> buttons = w->findChildren<QAbstractButton *>();
524  for (int i = 0; i < buttons.count(); ++i) {
525  if (buttons[i]->isChecked()) {
526  return i;
527  }
528  }
529  return -1;
530  }
531 
532  QByteArray userproperty = getCustomProperty(w);
533  if (userproperty.isEmpty()) {
534  userproperty = getUserProperty(w);
535  }
536  if (userproperty.isEmpty()) {
537  QComboBox *cb = qobject_cast<QComboBox *>(w);
538  if (cb) {
539  if (cb->isEditable()) {
540  return QVariant(cb->currentText());
541  } else {
542  return QVariant(cb->currentIndex());
543  }
544  }
545  }
546  if (userproperty.isEmpty()) {
547  qCWarning(KCONFIG_WIDGETS_LOG) << w->metaObject()->className() << "widget not handled!";
548  return QVariant();
549  }
550 
551  return w->property(userproperty.constData());
552 }
553 
555 {
556  QWidget *widget;
557  QHashIterator<QString, QWidget *> it(d->knownWidget);
558  while (it.hasNext()) {
559  it.next();
560  widget = it.value();
561 
562  KConfigSkeletonItem *item = d->m_conf->findItem(it.key());
563  if (!item) {
564  qCWarning(KCONFIG_WIDGETS_LOG) << "The setting" << it.key() << "has disappeared!";
565  continue;
566  }
567 
568  if (!item->isEqual(property(widget))) {
569  // qCDebug(KCONFIG_WIDGETS_LOG) << "Widget for '" << it.key() << "' has changed.";
570  return true;
571  }
572  }
573  return false;
574 }
575 
577 {
578  QWidget *widget;
579  QHashIterator<QString, QWidget *> it(d->knownWidget);
580  while (it.hasNext()) {
581  it.next();
582  widget = it.value();
583 
584  KConfigSkeletonItem *item = d->m_conf->findItem(it.key());
585  if (!item) {
586  qCWarning(KCONFIG_WIDGETS_LOG) << "The setting" << it.key() << "has disappeared!";
587  continue;
588  }
589 
590  if (property(widget) != item->getDefault()) {
591  return false;
592  }
593  }
594  return true;
595 }
596 
597 KConfigDialogManagerPrivate::KConfigDialogManagerPrivate(KConfigDialogManager *qq)
598  : q(qq)
599  , insideGroupBox(false)
600  , defaultsIndicatorsVisible(false)
601 {
602 }
603 
604 void KConfigDialogManagerPrivate::setDefaultsIndicatorsVisible(bool enabled)
605 {
606  if (defaultsIndicatorsVisible != enabled) {
607  defaultsIndicatorsVisible = enabled;
608  updateAllWidgetIndicators();
609  }
610 }
611 
612 void KConfigDialogManagerPrivate::onWidgetModified()
613 {
614  const auto widget = qobject_cast<QWidget *>(q->sender());
615  Q_ASSERT(widget);
616 
617  const QLatin1String prefix("kcfg_");
618  QString configId = widget->objectName();
619  if (configId.startsWith(prefix)) {
620  configId.remove(0, prefix.size());
621  updateWidgetIndicator(configId, widget);
622  } else {
623  auto *parent = qobject_cast<QWidget *>(widget->parent());
624  Q_ASSERT(parent);
625  configId = parent->objectName();
626  Q_ASSERT(configId.startsWith(prefix));
627  configId.remove(0, prefix.size());
628  updateWidgetIndicator(configId, parent);
629  }
630 
631  Q_EMIT q->widgetModified();
632 }
633 
634 void KConfigDialogManagerPrivate::updateWidgetIndicator(const QString &configId, QWidget *widget)
635 {
636  const auto item = m_conf->findItem(configId);
637  Q_ASSERT(item);
638 
639  const auto widgetValue = q->property(widget);
640  const auto defaultValue = item->getDefault();
641 
642  const auto defaulted = widgetValue == defaultValue;
643 
644  if (allExclusiveGroupBoxes.contains(widget)) {
645  const QList<QAbstractButton *> buttons = widget->findChildren<QAbstractButton *>();
646  for (int i = 0; i < buttons.count(); i++) {
647  const auto value = widgetValue.toInt() == i && !defaulted && defaultsIndicatorsVisible;
648  buttons.at(i)->setProperty("_kde_highlight_neutral", value);
649  buttons.at(i)->update();
650  }
651  } else {
652  widget->setProperty("_kde_highlight_neutral", !defaulted && defaultsIndicatorsVisible);
653  widget->update();
654  }
655 }
656 
657 void KConfigDialogManagerPrivate::updateAllWidgetIndicators()
658 {
659  QHashIterator<QString, QWidget *> it(knownWidget);
660  while (it.hasNext()) {
661  it.next();
662  updateWidgetIndicator(it.key(), it.value());
663  }
664 }
665 
666 #include "moc_kconfigdialogmanager.cpp"
static QHash< QString, QByteArray > * propertyMap()
Retrieve the map between widgets class names and the USER properties used for the configuration value...
virtual QVariant maxValue() const
bool isValid() const const
virtual QVariant property() const=0
void setupWidget(QWidget *widget, KConfigSkeletonItem *item)
Setup secondary widget properties.
~KConfigDialogManager() override
Destructor.
Q_EMITQ_EMIT
typedef QObjectList
virtual void setProperty(const QVariant &p)=0
int count(const T &value) const const
QLayout * layout() const const
QMetaProperty userProperty() const const
bool isValid() const const
void update()
QString toolTip() const
void setCurrentIndex(int index)
QString name() const
QByteArray toByteArray() const const
void setProperty(QWidget *w, const QVariant &v)
Set a property.
const T & value() const const
static QHash< QString, QByteArray > * changedMap()
Retrieve the map between widgets class names and signals that are listened to detect changes in the c...
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void toggled(bool checked)
Q_GLOBAL_STATIC(Internal::StaticControl, s_instance) class ControlPrivate
void setEditText(const QString &text)
bool signalsBlocked() const const
QString whatsThis() const
void widgetModified()
If retrieveSettings() was told to track changes then if any known setting was changed this signal wil...
QVariant::Type type() const const
bool blockSignals(bool block)
static void initMaps()
Initializes the property maps.
QHashIterator::Item next()
void updateWidgets()
Traverse the specified widgets, sets the state of all known widgets according to the state in the set...
bool isEmpty() const const
QList< T > findChildren(const QString &name, Qt::FindChildOptions options) const const
void updateWidgetsDefault()
Traverse the specified widgets, sets the state of all known widgets according to the default state in...
const T & at(int i) const const
QMetaMethod method(int index) const const
const QMetaObject * superClass() const const
int toInt(bool *ok) const const
bool isEmpty() const const
bool hasChanged() const
Returns whether the current state of the known widgets are different from the state in the config obj...
QByteArray getUserPropertyChangedSignal(const QWidget *widget) const
Finds the changed signal of the USER property using Qt's MetaProperty system.
KConfigDialogManager(QWidget *parent, KCoreConfigSkeleton *conf)
Constructor.
virtual QVariant minValue() const
QVariant property(QWidget *w) const
Retrieve a property.
bool isDefault() const
Returns whether the current state of the known widgets are the same as the default state in the confi...
void setEnabled(bool)
bool isValid() const const
virtual const QMetaObject * metaObject() const const
QString & remove(int position, int n)
bool hasNext() const const
bool canConvert(int targetTypeId) const const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
const char * className() const const
void settingsChanged()
One or more of the settings have been saved (such as when the user clicks on the Apply button).
Provides a means of automatically retrieving, saving and resetting KConfigSkeleton based settings in ...
bool setProperty(const char *name, const QVariant &value)
QVariant getDefault() const
void addWidget(QWidget *widget)
Add additional widgets to manage.
const char * name() const const
void updateSettings()
Traverse the specified widgets, saving the settings of all known widgets in the settings object.
int findText(const QString &text, Qt::MatchFlags flags) const const
bool isEmpty() const const
bool isEditable() const const
QMetaProperty property(int index) const const
const char * constData() const const
bool isImmutable() const
void init(bool trackChanges)
QByteArray getCustomPropertyChangedSignal(const QWidget *widget) const
Find the changed signal of the property to use for a widget by querying the "kcfg_propertyNotify" pro...
QByteArray getUserProperty(const QWidget *widget) const
Finds the USER property name using Qt's MetaProperty system, and caches it in the property map (the c...
QByteArray getCustomProperty(const QWidget *widget) const
Find the property to use for a widget by querying the "kcfg_property" property of the widget.
virtual bool isEqual(const QVariant &p) const=0
int indexOfProperty(const char *name) const const
QString mid(int position, int n) const const
void setDefaultsIndicatorsVisible(bool enabled)
Show or hide an indicator when settings have changed from their default value.
void editTextChanged(const QString &text)
const Key & key() const const
QObject * parent() const const
const QObjectList & children() const const
QString toString() const const
QVariant property(const char *name) const const
bool parseChildren(const QWidget *widget, bool trackChanges)
Recursive function that finds all known children.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Fri Dec 1 2023 04:14:03 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.