1 /*
2 appearanceconfigwidget.cpp
3
4 This file is part of kleopatra, the KDE key manager
5 SPDX-FileCopyrightText: 2002, 2004, 2008 Klarälvdalens Datakonsult AB
6 SPDX-FileCopyrightText: 2002, 2003 Marc Mutz <mutz@kde.org>
7
8 SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include <config-kleopatra.h>
12
13 #include "appearanceconfigwidget.h"
14 #include "ui_appearanceconfigwidget.h"
15
16 #include "tagspreferences.h"
17 #include "tooltippreferences.h"
18
19 #include <QGpgME/Protocol>
20 #include <Libkleo/KeyFilterManager>
21 #include <Libkleo/Dn>
22 #include <Libkleo/DNAttributeOrderConfigWidget>
23
24 #include <KIconDialog>
25 #include <QIcon>
26
27 #include <KConfig>
28 #include <KLocalizedString>
29 #include <KConfigGroup>
30
31 #include <QColor>
32 #include <QFont>
33 #include <QString>
34 #include <QRegularExpression>
35 #include <QApplication>
36 #include <QColorDialog>
37 #include <QFontDialog>
38
39 #include <algorithm>
40
41 using namespace Kleo;
42 using namespace Kleo::Config;
43
44 enum {
45 HasNameRole = Qt::UserRole + 0x1234, /*!< Records that the user has assigned a name (to avoid comparing with i18n-strings) */
46 HasFontRole, /*!< Records that the user has chosen completely different font (as opposed to italic/bold/strikeout) */
47 IconNameRole, /*!< Records the name of the icon (since QIcon won't give it out again, once set) */
48 MayChangeNameRole,
49 MayChangeForegroundRole,
50 MayChangeBackgroundRole,
51 MayChangeFontRole,
52 MayChangeItalicRole,
53 MayChangeBoldRole,
54 MayChangeStrikeOutRole,
55 MayChangeIconRole,
56
57 EndDummy
58 };
59
tryToFindFontFor(const QListWidgetItem * item)60 static QFont tryToFindFontFor(const QListWidgetItem *item)
61 {
62 if (item)
63 if (const QListWidget *const lw = item->listWidget()) {
64 return lw->font();
65 }
66 return QApplication::font("QListWidget");
67 }
68
is(const QListWidgetItem * item,bool (QFont::* func)()const)69 static bool is(const QListWidgetItem *item, bool (QFont::*func)() const)
70 {
71 if (!item) {
72 return false;
73 }
74 const QVariant v = item->data(Qt::FontRole);
75 if (!v.isValid() || v.type() != QVariant::Font) {
76 return false;
77 }
78 return (v.value<QFont>().*func)();
79 }
80
is_italic(const QListWidgetItem * item)81 static bool is_italic(const QListWidgetItem *item)
82 {
83 return is(item, &QFont::italic);
84 }
is_bold(const QListWidgetItem * item)85 static bool is_bold(const QListWidgetItem *item)
86 {
87 return is(item, &QFont::bold);
88 }
is_strikeout(const QListWidgetItem * item)89 static bool is_strikeout(const QListWidgetItem *item)
90 {
91 return is(item, &QFont::strikeOut);
92 }
93
set(QListWidgetItem * item,bool on,void (QFont::* func)(bool))94 static void set(QListWidgetItem *item, bool on, void (QFont::*func)(bool))
95 {
96 if (!item) {
97 return;
98 }
99 const QVariant v = item->data(Qt::FontRole);
100 QFont font = v.isValid() && v.type() == QVariant::Font ? v.value<QFont>() : tryToFindFontFor(item);
101 (font.*func)(on);
102 item->setData(Qt::FontRole, font);
103 }
104
set_italic(QListWidgetItem * item,bool on)105 static void set_italic(QListWidgetItem *item, bool on)
106 {
107 set(item, on, &QFont::setItalic);
108 }
set_bold(QListWidgetItem * item,bool on)109 static void set_bold(QListWidgetItem *item, bool on)
110 {
111 set(item, on, &QFont::setBold);
112 }
set_strikeout(QListWidgetItem * item,bool on)113 static void set_strikeout(QListWidgetItem *item, bool on)
114 {
115 set(item, on, &QFont::setStrikeOut);
116 }
117
apply_config(const KConfigGroup & group,QListWidgetItem * item)118 static void apply_config(const KConfigGroup &group, QListWidgetItem *item)
119 {
120 if (!item) {
121 return;
122 }
123
124 const QString name = group.readEntry("Name");
125 item->setText(name.isEmpty() ? i18nc("Key filter without user-assigned name", "<unnamed>") : name);
126 item->setData(HasNameRole, !name.isEmpty());
127 item->setData(MayChangeNameRole, !group.isEntryImmutable("Name"));
128
129 const QColor fg = group.readEntry("foreground-color", QColor());
130 item->setData(Qt::ForegroundRole, fg.isValid() ? QBrush(fg) : QVariant());
131 item->setData(MayChangeForegroundRole, !group.isEntryImmutable("foreground-color"));
132
133 const QColor bg = group.readEntry("background-color", QColor());
134 item->setData(Qt::BackgroundRole, bg.isValid() ? QBrush(bg) : QVariant());
135 item->setData(MayChangeBackgroundRole, !group.isEntryImmutable("background-color"));
136
137 const QFont defaultFont = tryToFindFontFor(item);
138 if (group.hasKey("font")) {
139 const QFont font = group.readEntry("font", defaultFont);
140 item->setData(Qt::FontRole, font != defaultFont ? font : QVariant());
141 item->setData(HasFontRole, font != defaultFont);
142 } else {
143 QFont font = defaultFont;
144 font.setStrikeOut(group.readEntry("font-strikeout", false));
145 font.setItalic(group.readEntry("font-italic", false));
146 font.setBold(group.readEntry("font-bold", false));
147 item->setData(Qt::FontRole, font);
148 item->setData(HasFontRole, false);
149 }
150 item->setData(MayChangeFontRole, !group.isEntryImmutable("font"));
151 item->setData(MayChangeItalicRole, !group.isEntryImmutable("font-italic"));
152 item->setData(MayChangeBoldRole, !group.isEntryImmutable("font-bold"));
153 item->setData(MayChangeStrikeOutRole, !group.isEntryImmutable("font-strikeout"));
154
155 const QString iconName = group.readEntry("icon");
156 item->setData(Qt::DecorationRole, iconName.isEmpty() ? QVariant() : QIcon::fromTheme(iconName));
157 item->setData(IconNameRole, iconName.isEmpty() ? QVariant() : iconName);
158 item->setData(MayChangeIconRole, !group.isEntryImmutable("icon"));
159 }
160
erase_if_allowed(QListWidgetItem * item,int role,int allowRole)161 static void erase_if_allowed(QListWidgetItem *item, int role, int allowRole)
162 {
163 if (item && item->data(allowRole).toBool()) {
164 item->setData(role, QVariant());
165 }
166 }
167
168 #if 0
169 static void erase_if_allowed(QListWidgetItem *item, const int role[], size_t numRoles, int allowRole)
170 {
171 if (item && item->data(allowRole).toBool())
172 for (unsigned int i = 0; i < numRoles; ++i) {
173 item->setData(role[i], QVariant());
174 }
175 }
176
177 static void erase_if_allowed(QListWidgetItem *item, int role, const int allowRole[], size_t numAllowRoles)
178 {
179 if (!item) {
180 return;
181 }
182 for (unsigned int i = 0; i < numAllowRoles; ++i)
183 if (!item->data(allowRole[i]).toBool()) {
184 return;
185 }
186 item->setData(role, QVariant());
187 }
188 #endif
189
erase_if_allowed(QListWidgetItem * item,const int role[],size_t numRoles,const int allowRole[],size_t numAllowRoles)190 static void erase_if_allowed(QListWidgetItem *item, const int role[], size_t numRoles, const int allowRole[], size_t numAllowRoles)
191 {
192 if (!item) {
193 return;
194 }
195 for (unsigned int i = 0; i < numAllowRoles; ++i)
196 if (!item->data(allowRole[i]).toBool()) {
197 return;
198 }
199 for (unsigned int i = 0; i < numRoles; ++i) {
200 item->setData(role[i], QVariant());
201 }
202 }
203
set_default_appearance(QListWidgetItem * item)204 static void set_default_appearance(QListWidgetItem *item)
205 {
206 if (!item) {
207 return;
208 }
209 erase_if_allowed(item, Qt::ForegroundRole, MayChangeForegroundRole);
210 erase_if_allowed(item, Qt::BackgroundRole, MayChangeBackgroundRole);
211 erase_if_allowed(item, Qt::DecorationRole, MayChangeIconRole);
212 static const int fontRoles[] = { Qt::FontRole, HasFontRole };
213 static const int fontAllowRoles[] = {
214 MayChangeFontRole,
215 MayChangeItalicRole,
216 MayChangeBoldRole,
217 MayChangeStrikeOutRole,
218 };
219 erase_if_allowed(item, fontRoles, sizeof(fontRoles) / sizeof(int), fontAllowRoles, sizeof(fontAllowRoles) / sizeof(int));
220 }
221
writeOrDelete(KConfigGroup & group,const char * key,const QVariant & value)222 static void writeOrDelete(KConfigGroup &group, const char *key, const QVariant &value)
223 {
224 if (value.isValid()) {
225 group.writeEntry(key, value);
226 } else {
227 group.deleteEntry(key);
228 }
229 }
230
brush2color(const QVariant & v)231 static QVariant brush2color(const QVariant &v)
232 {
233 if (v.isValid()) {
234 if (v.type() == QVariant::Color) {
235 return v;
236 } else if (v.type() == QVariant::Brush) {
237 return v.value<QBrush>().color();
238 }
239 }
240 return QVariant();
241 }
242
save_to_config(const QListWidgetItem * item,KConfigGroup & group)243 static void save_to_config(const QListWidgetItem *item, KConfigGroup &group)
244 {
245 if (!item) {
246 return;
247 }
248 writeOrDelete(group, "Name", item->data(HasNameRole).toBool() ? item->text() : QVariant());
249 writeOrDelete(group, "foreground-color", brush2color(item->data(Qt::ForegroundRole)));
250 writeOrDelete(group, "background-color", brush2color(item->data(Qt::BackgroundRole)));
251 writeOrDelete(group, "icon", item->data(IconNameRole));
252
253 group.deleteEntry("font");
254 group.deleteEntry("font-strikeout");
255 group.deleteEntry("font-italic");
256 group.deleteEntry("font-bold");
257
258 if (item->data(HasFontRole).toBool()) {
259 writeOrDelete(group, "font", item->data(Qt::FontRole));
260 return;
261 }
262
263 if (is_strikeout(item)) {
264 group.writeEntry("font-strikeout", true);
265 }
266 if (is_italic(item)) {
267 group.writeEntry("font-italic", true);
268 }
269 if (is_bold(item)) {
270 group.writeEntry("font-bold", true);
271 }
272 }
273
kiosk_enable(QWidget * w,const QListWidgetItem * item,int allowRole)274 static void kiosk_enable(QWidget *w, const QListWidgetItem *item, int allowRole)
275 {
276 if (!w) {
277 return;
278 }
279 if (item && !item->data(allowRole).toBool()) {
280 w->setEnabled(false);
281 w->setToolTip(i18n("This parameter has been locked down by the system administrator."));
282 } else {
283 w->setEnabled(item);
284 w->setToolTip(QString());
285 }
286 }
287
288 class AppearanceConfigWidget::Private : public Ui_AppearanceConfigWidget
289 {
290 friend class ::Kleo::Config::AppearanceConfigWidget;
291 AppearanceConfigWidget *const q;
292 public:
Private(AppearanceConfigWidget * qq)293 explicit Private(AppearanceConfigWidget *qq)
294 : Ui_AppearanceConfigWidget(),
295 q(qq),
296 dnOrderWidget(nullptr)
297 {
298 setupUi(q);
299
300 if (QLayout *const l = q->layout()) {
301 l->setContentsMargins(0, 0, 0, 0);
302 }
303
304 auto w = new QWidget;
305 dnOrderWidget = Kleo::DNAttributeMapper::instance()->configWidget(w);
306 dnOrderWidget->setObjectName(QStringLiteral("dnOrderWidget"));
307 (new QVBoxLayout(w))->addWidget(dnOrderWidget);
308
309 tabWidget->addTab(w, i18n("DN-Attribute Order"));
310
311 connect(dnOrderWidget, &DNAttributeOrderConfigWidget::changed, q, &AppearanceConfigWidget::changed);
312
313 connect(iconButton, SIGNAL(clicked()), q, SLOT(slotIconClicked()));
314 #ifndef QT_NO_COLORDIALOG
315 connect(foregroundButton, SIGNAL(clicked()), q, SLOT(slotForegroundClicked()));
316 connect(backgroundButton, SIGNAL(clicked()), q, SLOT(slotBackgroundClicked()));
317 #else
318 foregroundButton->hide();
319 backgroundButton->hide();
320 #endif
321 #ifndef QT_NO_FONTDIALOG
322 connect(fontButton, SIGNAL(clicked()), q, SLOT(slotFontClicked()));
323 #else
324 fontButton->hide();
325 #endif
326 connect(categoriesLV, SIGNAL(itemSelectionChanged()), q, SLOT(slotSelectionChanged()));
327 connect(defaultLookPB, SIGNAL(clicked()), q, SLOT(slotDefaultClicked()));
328 connect(italicCB, SIGNAL(toggled(bool)), q, SLOT(slotItalicToggled(bool)));
329 connect(boldCB, SIGNAL(toggled(bool)), q, SLOT(slotBoldToggled(bool)));
330 connect(strikeoutCB, SIGNAL(toggled(bool)), q, SLOT(slotStrikeOutToggled(bool)));
331 connect(tooltipValidityCheckBox, SIGNAL(toggled(bool)), q, SLOT(slotTooltipValidityChanged(bool)));
332 connect(tooltipOwnerCheckBox, SIGNAL(toggled(bool)), q, SLOT(slotTooltipOwnerChanged(bool)));
333 connect(tooltipDetailsCheckBox, SIGNAL(toggled(bool)), q, SLOT(slotTooltipDetailsChanged(bool)));
334 connect(useTagsCheckBox, SIGNAL(toggled(bool)), q, SLOT(slotUseTagsChanged(bool)));
335 }
336
337 private:
338 void enableDisableActions(QListWidgetItem *item);
339 QListWidgetItem *selectedItem() const;
340
341 private:
342 void slotIconClicked();
343 #ifndef QT_NO_COLORDIALOG
344 void slotForegroundClicked();
345 void slotBackgroundClicked();
346 #endif
347 #ifndef QT_NO_FONTDIALOG
348 void slotFontClicked();
349 #endif
350 void slotSelectionChanged();
351 void slotDefaultClicked();
352 void slotItalicToggled(bool);
353 void slotBoldToggled(bool);
354 void slotStrikeOutToggled(bool);
355 void slotTooltipValidityChanged(bool);
356 void slotTooltipOwnerChanged(bool);
357 void slotTooltipDetailsChanged(bool);
358 void slotUseTagsChanged(bool);
359
360 private:
361 Kleo::DNAttributeOrderConfigWidget *dnOrderWidget;
362 };
363
AppearanceConfigWidget(QWidget * p,Qt::WindowFlags f)364 AppearanceConfigWidget::AppearanceConfigWidget(QWidget *p, Qt::WindowFlags f)
365 : QWidget(p, f), d(new Private(this))
366 {
367 // load();
368 }
369
~AppearanceConfigWidget()370 AppearanceConfigWidget::~AppearanceConfigWidget() {}
371
slotSelectionChanged()372 void AppearanceConfigWidget::Private::slotSelectionChanged()
373 {
374 enableDisableActions(selectedItem());
375 }
376
selectedItem() const377 QListWidgetItem *AppearanceConfigWidget::Private::selectedItem() const
378 {
379 const QList<QListWidgetItem *> items = categoriesLV->selectedItems();
380 return items.empty() ? nullptr : items.front();
381 }
382
enableDisableActions(QListWidgetItem * item)383 void AppearanceConfigWidget::Private::enableDisableActions(QListWidgetItem *item)
384 {
385 kiosk_enable(iconButton, item, MayChangeIconRole);
386 #ifndef QT_NO_COLORDIALOG
387 kiosk_enable(foregroundButton, item, MayChangeForegroundRole);
388 kiosk_enable(backgroundButton, item, MayChangeBackgroundRole);
389 #endif
390 #ifndef QT_NO_FONTDIALOG
391 kiosk_enable(fontButton, item, MayChangeFontRole);
392 #endif
393 kiosk_enable(italicCB, item, MayChangeItalicRole);
394 kiosk_enable(boldCB, item, MayChangeBoldRole);
395 kiosk_enable(strikeoutCB, item, MayChangeStrikeOutRole);
396
397 defaultLookPB->setEnabled(item);
398
399 italicCB->setChecked(is_italic(item));
400 boldCB->setChecked(is_bold(item));
401 strikeoutCB->setChecked(is_strikeout(item));
402 }
403
slotDefaultClicked()404 void AppearanceConfigWidget::Private::slotDefaultClicked()
405 {
406
407 QListWidgetItem *const item = selectedItem();
408 if (!item) {
409 return;
410 }
411
412 set_default_appearance(item);
413 enableDisableActions(item);
414
415 Q_EMIT q->changed();
416 }
417
defaults()418 void AppearanceConfigWidget::defaults()
419 {
420
421 // This simply means "default look for every category"
422 for (int i = 0, end = d->categoriesLV->count(); i != end; ++i) {
423 set_default_appearance(d->categoriesLV->item(i));
424 }
425 d->tooltipValidityCheckBox->setChecked(true);
426 d->tooltipOwnerCheckBox->setChecked(false);
427 d->tooltipDetailsCheckBox->setChecked(false);
428
429 d->dnOrderWidget->defaults();
430
431 Q_EMIT changed();
432 }
433
load()434 void AppearanceConfigWidget::load()
435 {
436
437 d->dnOrderWidget->load();
438
439 d->categoriesLV->clear();
440 KSharedConfigPtr config = KSharedConfig::openConfig(QStringLiteral("libkleopatrarc"));
441 if (!config) {
442 return;
443 }
444 const QStringList groups = config->groupList().filter(QRegularExpression(QStringLiteral("^Key Filter #\\d+$")));
445 for (const QString &group : groups) {
446 //QListWidgetItem * item = new QListWidgetItem( d->categoriesLV );
447 apply_config(KConfigGroup(config, group), new QListWidgetItem(d->categoriesLV));
448 }
449
450 const TooltipPreferences prefs;
451 d->tooltipValidityCheckBox->setChecked(prefs.showValidity());
452 d->tooltipOwnerCheckBox->setChecked(prefs.showOwnerInformation());
453 d->tooltipDetailsCheckBox->setChecked(prefs.showCertificateDetails());
454
455 const TagsPreferences tagsPrefs;
456 d->useTagsCheckBox->setChecked(tagsPrefs.useTags());
457 }
458
save()459 void AppearanceConfigWidget::save()
460 {
461
462 d->dnOrderWidget->save();
463
464 TooltipPreferences prefs;
465 prefs.setShowValidity(d->tooltipValidityCheckBox->isChecked());
466 prefs.setShowOwnerInformation(d->tooltipOwnerCheckBox->isChecked());
467 prefs.setShowCertificateDetails(d->tooltipDetailsCheckBox->isChecked());
468 prefs.save();
469
470 KSharedConfigPtr config = KSharedConfig::openConfig(QStringLiteral("libkleopatrarc"));
471 if (!config) {
472 return;
473 }
474 // We know (assume) that the groups in the config object haven't changed,
475 // so we just iterate over them and over the listviewitems, and map one-to-one.
476 const QStringList groups = config->groupList().filter(QRegularExpression(QStringLiteral("^Key Filter #\\d+$")));
477 #if 0
478 if (groups.isEmpty()) {
479 // If we created the default categories ourselves just now, then we need to make up their list
480 Q3ListViewItemIterator lvit(categoriesLV);
481 for (; lvit.current(); ++lvit) {
482 groups << lvit.current()->text(0);
483 }
484 }
485 #endif
486 for (int i = 0, end = std::min(groups.size(), d->categoriesLV->count()); i != end; ++i) {
487 const QListWidgetItem *const item = d->categoriesLV->item(i);
488 Q_ASSERT(item);
489 KConfigGroup group(config, groups[i]);
490 save_to_config(item, group);
491 }
492
493 TagsPreferences tagsPrefs;
494 tagsPrefs.setUseTags(d->useTagsCheckBox->isChecked());
495
496 config->sync();
497 KeyFilterManager::instance()->reload();
498 }
499
slotIconClicked()500 void AppearanceConfigWidget::Private::slotIconClicked()
501 {
502 QListWidgetItem *const item = selectedItem();
503 if (!item) {
504 return;
505 }
506
507 const QString iconName = KIconDialog::getIcon( /* repeating default arguments begin */
508 KIconLoader::Desktop, KIconLoader::Application, false, 0, false,
509 /* repeating default arguments end */
510 q);
511 if (iconName.isEmpty()) {
512 return;
513 }
514
515 item->setIcon(QIcon::fromTheme(iconName));
516 item->setData(IconNameRole, iconName);
517 Q_EMIT q->changed();
518 }
519
520 #ifndef QT_NO_COLORDIALOG
slotForegroundClicked()521 void AppearanceConfigWidget::Private::slotForegroundClicked()
522 {
523 QListWidgetItem *const item = selectedItem();
524 if (!item) {
525 return;
526 }
527
528 const QVariant v = brush2color(item->data(Qt::ForegroundRole));
529
530 const QColor initial = v.isValid() ? v.value<QColor>() : categoriesLV->palette().color(QPalette::Normal, QPalette::Text);
531 const QColor c = QColorDialog::getColor(initial, q);
532
533 if (c.isValid()) {
534 item->setData(Qt::ForegroundRole, QBrush(c));
535 Q_EMIT q->changed();
536 }
537 }
538
slotBackgroundClicked()539 void AppearanceConfigWidget::Private::slotBackgroundClicked()
540 {
541 QListWidgetItem *const item = selectedItem();
542 if (!item) {
543 return;
544 }
545
546 const QVariant v = brush2color(item->data(Qt::BackgroundRole));
547
548 const QColor initial = v.isValid() ? v.value<QColor>() : categoriesLV->palette().color(QPalette::Normal, QPalette::Base);
549 const QColor c = QColorDialog::getColor(initial, q);
550
551 if (c.isValid()) {
552 item->setData(Qt::BackgroundRole, QBrush(c));
553 Q_EMIT q->changed();
554 }
555 }
556 #endif // QT_NO_COLORDIALOG
557
558 #ifndef QT_NO_FONTDIALOG
slotFontClicked()559 void AppearanceConfigWidget::Private::slotFontClicked()
560 {
561 QListWidgetItem *const item = selectedItem();
562 if (!item) {
563 return;
564 }
565
566 const QVariant v = item->data(Qt::FontRole);
567
568 bool ok = false;
569 const QFont defaultFont = tryToFindFontFor(item);
570 const QFont initial = v.isValid() && v.type() == QVariant::Font ? v.value<QFont>() : defaultFont;
571 QFont f = QFontDialog::getFont(&ok, initial, q);
572 if (!ok) {
573 return;
574 }
575
576 // disallow circumventing KIOSK:
577 if (!item->data(MayChangeItalicRole).toBool()) {
578 f.setItalic(initial.italic());
579 }
580 if (!item->data(MayChangeBoldRole).toBool()) {
581 f.setBold(initial.bold());
582 }
583 if (!item->data(MayChangeStrikeOutRole).toBool()) {
584 f.setStrikeOut(initial.strikeOut());
585 }
586
587 item->setData(Qt::FontRole, f != defaultFont ? f : QVariant());
588 item->setData(HasFontRole, true);
589 Q_EMIT q->changed();
590 }
591 #endif // QT_NO_FONTDIALOG
592
slotItalicToggled(bool on)593 void AppearanceConfigWidget::Private::slotItalicToggled(bool on)
594 {
595 set_italic(selectedItem(), on);
596 Q_EMIT q->changed();
597 }
598
slotBoldToggled(bool on)599 void AppearanceConfigWidget::Private::slotBoldToggled(bool on)
600 {
601 set_bold(selectedItem(), on);
602 Q_EMIT q->changed();
603 }
604
slotStrikeOutToggled(bool on)605 void AppearanceConfigWidget::Private::slotStrikeOutToggled(bool on)
606 {
607 set_strikeout(selectedItem(), on);
608 Q_EMIT q->changed();
609 }
610
slotTooltipValidityChanged(bool)611 void AppearanceConfigWidget::Private::slotTooltipValidityChanged(bool)
612 {
613 Q_EMIT q->changed();
614 }
615
slotTooltipOwnerChanged(bool)616 void AppearanceConfigWidget::Private::slotTooltipOwnerChanged(bool)
617 {
618 Q_EMIT q->changed();
619 }
620
slotTooltipDetailsChanged(bool)621 void AppearanceConfigWidget::Private::slotTooltipDetailsChanged(bool)
622 {
623 Q_EMIT q->changed();
624 }
625
slotUseTagsChanged(bool)626 void AppearanceConfigWidget::Private::slotUseTagsChanged(bool)
627 {
628 Q_EMIT q->changed();
629 }
630
631 #include "moc_appearanceconfigwidget.cpp"
632