Krita Source Code Documentation
Loading...
Searching...
No Matches
KisWidgetConnectionUtils.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2022 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
8
9#include <QMetaObject>
10#include <QMetaProperty>
11#include <QAbstractButton>
12#include <QAction>
13#include <QComboBox>
14#include <QButtonGroup>
15#include <QSpinBox>
16#include <QDoubleSpinBox>
17#include <QLineEdit>
18#include <QSlider>
19#include <QCheckBox>
20#include <QGroupBox>
21#include "kis_debug.h"
24#include "KisAngleSelector.h"
25#include "kis_color_button.h"
27
33#define SANITY_CHECK_PROPERTY_EXISTS(prop) Q_ASSERT(prop.isValid())
34#define SANITY_CHECK_PROPERTY_EXISTS_AND_WRITABLE(prop) do { Q_ASSERT(prop.isValid()); Q_ASSERT(prop.isWritable()); } while (0)
35#define SANITY_CHECK_PROPERTY_METATYPE_REGISTERED(prop) do { \
36 const int metaTypeId = QMetaType::type(prop.typeName()); \
37 if (metaTypeId <= 0) { \
38 qWarning().nospace() << "WARNING: metatype for property \"" << prop.name() << "\" is not register. Please register type \"" << prop.typeName() << "\""; \
39 } \
40 Q_ASSERT(metaTypeId > 0); \
41 Q_ASSERT(QMetaType::isRegistered(metaTypeId)); \
42} while (0)
43
44class ConnectButtonStateHelper : public QObject
45{
46 Q_OBJECT
47public:
48
49 ConnectButtonStateHelper(QAbstractButton *parent)
50 : QObject(parent),
51 m_button(parent)
52 {
53 }
54public Q_SLOTS:
55 void updateState(const CheckBoxState &state) {
56 QSignalBlocker b(m_button);
57 m_button->setEnabled(state.enabled);
58 m_button->setChecked(state.value);
59
60 // TODO: verify if the two properties are equal or the control is disabled
61 }
62
63private:
64 QAbstractButton *m_button;
65};
66
67class ConnectGroupBoxStateHelper : public QObject
68{
69 Q_OBJECT
70public:
71
72 ConnectGroupBoxStateHelper(QGroupBox *parent)
73 : QObject(parent),
74 m_button(parent)
75 {
76 }
77public Q_SLOTS:
78 void updateState(const CheckBoxState &state) {
79 QSignalBlocker b(m_button);
80 m_button->setEnabled(state.enabled);
81 m_button->setChecked(state.value);
82
83 // TODO: verify if the two properties are equal or the control is disabled
84 }
85
86private:
87 QGroupBox *m_button;
88};
89
90class ConnectComboBoxStateHelper : public QObject
91{
92 Q_OBJECT
93public:
94
95 ConnectComboBoxStateHelper(QComboBox *parent)
96 : QObject(parent),
97 m_comboBox(parent)
98 {
99 }
100public Q_SLOTS:
101 void updateState(const ComboBoxState &state) {
102 QSignalBlocker b(m_comboBox);
103
104 while (m_comboBox->count() > 0) {
105 m_comboBox->removeItem(0);
106 }
107
108 m_comboBox->addItems(state.items);
109 m_comboBox->setCurrentIndex(state.currentIndex);
110 m_comboBox->setEnabled(state.enabled);
111
112 // TODO: verify if the two properties are equal or the control is disabled
113 }
114
115private:
116 QComboBox *m_comboBox;
117};
118
119
120namespace KisWidgetConnectionUtils {
121
122template<typename Button>
123void connectButtonLikeControl(Button *button, QObject *source, const char *property)
124{
125 const QMetaObject* meta = source->metaObject();
126 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
128
129 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
130
131 QMetaMethod signal = prop.notifySignal();
132
133 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
134 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("bool"));
135
136 const QMetaObject* dstMeta = button->metaObject();
137
138 QMetaMethod updateSlot = dstMeta->method(
139 dstMeta->indexOfSlot("setChecked(bool)"));
140 QObject::connect(source, signal, button, updateSlot);
141
142 button->setChecked(prop.read(source).toBool());
143
144 if (prop.isWritable()) {
145 QObject::connect(button, &Button::toggled,
146 source, [prop, source] (bool value) { prop.write(source, value); });
147 }
148}
149
150void connectControl(QAbstractButton *button, QObject *source, const char *property)
151{
153}
154
155void connectControl(QAction *button, QObject *source, const char *property)
156{
158}
159
160void connectControl(QCheckBox *button, QObject *source, const char *property)
161{
163}
164
165void connectControl(QGroupBox *button, QObject *source, const char *property)
166{
168}
169
170void connectControl(QSpinBox *spinBox, QObject *source, const char *property)
171{
172 const QMetaObject* meta = source->metaObject();
173 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
175
176 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
177
178 QMetaMethod signal = prop.notifySignal();
179
180 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
181 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("int"));
182
183 const QMetaObject* dstMeta = spinBox->metaObject();
184
185 QMetaMethod updateSlot = dstMeta->method(
186 dstMeta->indexOfSlot("setValue(int)"));
187 QObject::connect(source, signal, spinBox, updateSlot);
188
189 spinBox->setValue(prop.read(source).toInt());
190
191 if (prop.isWritable()) {
192 QObject::connect(spinBox, qOverload<int>(&QSpinBox::valueChanged),
193 source, [prop, source] (int value) { prop.write(source, value); });
194 }
195}
196
197void connectControl(QSlider *slider, QObject *source, const char *property)
198{
199 const QMetaObject* meta = source->metaObject();
200 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
202
203 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
204
205 QMetaMethod signal = prop.notifySignal();
206
207 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
208 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("int"));
209
210 const QMetaObject* dstMeta = slider->metaObject();
211
212 QMetaMethod updateSlot = dstMeta->method(
213 dstMeta->indexOfSlot("setValue(int)"));
214 QObject::connect(source, signal, slider, updateSlot);
215
216 slider->setValue(prop.read(source).toInt());
217
218 if (prop.isWritable()) {
219 QObject::connect(slider, qOverload<int>(&QSlider::valueChanged),
220 source, [prop, source] (int value) { prop.write(source, value); });
221 }
222}
223
224void connectControl(QDoubleSpinBox *spinBox, QObject *source, const char *property)
225{
226 const QMetaObject* meta = source->metaObject();
227 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
229
230 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
231
232 QMetaMethod signal = prop.notifySignal();
233
234 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
235 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("qreal"));
236
237 const QMetaObject* dstMeta = spinBox->metaObject();
238
239 QMetaMethod updateSlot = dstMeta->method(
240 dstMeta->indexOfSlot("setValue(qreal)"));
241 QObject::connect(source, signal, spinBox, updateSlot);
242
243 spinBox->setValue(prop.read(source).toReal());
244
245 if (prop.isWritable()) {
246 QObject::connect(spinBox, qOverload<qreal>(&QDoubleSpinBox::valueChanged),
247 source, [prop, source] (qreal value) { prop.write(source, value); });
248 }
249}
250
251class ConnectIntSpinBoxStateHelper : public QObject
252{
253 Q_OBJECT
254public:
255
257 : QObject(parent),
258 m_spinBox(parent)
259 {
260 }
261public Q_SLOTS:
263 QSignalBlocker b(m_spinBox);
264
265 m_spinBox->setEnabled(state.enabled);
266 m_spinBox->setRange(state.min, state.max);
267 m_spinBox->setValue(state.value);
268 }
269
270private:
271 QSpinBox *m_spinBox;
272};
273
274
275void connectControlState(QSpinBox *spinBox, QObject *source, const char *readStateProperty, const char *writeProperty)
276{
277 const QMetaObject* meta = source->metaObject();
278 QMetaProperty readStateProp = meta->property(meta->indexOfProperty(readStateProperty));
279 SANITY_CHECK_PROPERTY_EXISTS(readStateProp);
280
281 KIS_SAFE_ASSERT_RECOVER_RETURN(readStateProp.hasNotifySignal());
282
283 QMetaMethod signal = readStateProp.notifySignal();
284
285 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
286 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("IntSpinBoxState"));
287
289
290 const QMetaObject* dstMeta = helper->metaObject();
291
292 QMetaMethod updateSlot = dstMeta->method(
293 dstMeta->indexOfSlot("setState(IntSpinBoxState)"));
294 QObject::connect(source, signal, helper, updateSlot);
295
296 helper->setState(readStateProp.read(source).value<IntSpinBoxState>());
297
298 QMetaProperty writeProp = meta->property(meta->indexOfProperty(writeProperty));
300 if (writeProp.isWritable()) {
301 QObject::connect(spinBox, qOverload<int>(&QSpinBox::valueChanged),
302 source, [writeProp, source] (int value) { writeProp.write(source, value); });
303 }
304}
305
307{
308 Q_OBJECT
309public:
310
311 ConnectDoubleSpinBoxStateHelper(QDoubleSpinBox *parent)
312 : QObject(parent),
313 m_spinBox(parent)
314 {
315 }
316public Q_SLOTS:
318 QSignalBlocker b(m_spinBox);
319
320 m_spinBox->setEnabled(state.enabled);
321 m_spinBox->setRange(state.min, state.max);
322 m_spinBox->setValue(state.value);
323 }
324
325private:
326 QDoubleSpinBox *m_spinBox;
327};
328
329
330void connectControlState(QDoubleSpinBox *spinBox, QObject *source, const char *readStateProperty, const char *writeProperty)
331{
332 const QMetaObject* meta = source->metaObject();
333 QMetaProperty readStateProp = meta->property(meta->indexOfProperty(readStateProperty));
334 SANITY_CHECK_PROPERTY_EXISTS(readStateProp);
335
336 KIS_SAFE_ASSERT_RECOVER_RETURN(readStateProp.hasNotifySignal());
337
338 QMetaMethod signal = readStateProp.notifySignal();
339
340 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
341 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("DoubleSpinBoxState"));
342
344
345 const QMetaObject* dstMeta = helper->metaObject();
346
347 QMetaMethod updateSlot = dstMeta->method(
348 dstMeta->indexOfSlot("setState(DoubleSpinBoxState)"));
349 QObject::connect(source, signal, helper, updateSlot);
350
351 helper->setState(readStateProp.read(source).value<DoubleSpinBoxState>());
352
353 QMetaProperty writeProp = meta->property(meta->indexOfProperty(writeProperty));
355 if (writeProp.isWritable()) {
356 QObject::connect(spinBox, qOverload<qreal>(&QDoubleSpinBox::valueChanged),
357 source, [writeProp, source] (qreal value) { writeProp.write(source, value); });
358 }
359}
360
361
362void connectControl(KisMultipliersDoubleSliderSpinBox *spinBox, QObject *source, const char *property)
363{
364 const QMetaObject* meta = source->metaObject();
365 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
367
368 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
369
370 QMetaMethod signal = prop.notifySignal();
371
372 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
373 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("qreal"));
374
375 const QMetaObject* dstMeta = spinBox->metaObject();
376
377 QMetaMethod updateSlot = dstMeta->method(
378 dstMeta->indexOfSlot("setValue(qreal)"));
379 QObject::connect(source, signal, spinBox, updateSlot);
380
381 spinBox->setValue(prop.read(source).toReal());
382
383 if (prop.isWritable()) {
384 QObject::connect(spinBox, qOverload<qreal>(&KisMultipliersDoubleSliderSpinBox::valueChanged),
385 source, [prop, source] (qreal value) { prop.write(source, value); });
386 }
387}
388
389
390class ConnectButtonGroupHelper : public QObject
391{
392 Q_OBJECT
393public:
394
395 ConnectButtonGroupHelper(QButtonGroup *parent)
396 : QObject(parent),
397 m_buttonGroup(parent)
398 {
399 QObject::connect(m_buttonGroup, qOverload<QAbstractButton *>(&QButtonGroup::buttonClicked), this, &ConnectButtonGroupHelper::slotButtonClicked);
400 }
401public Q_SLOTS:
402 void updateState(int value) {
403 QAbstractButton *btn = m_buttonGroup->button(value);
405 btn->setChecked(true);
406 }
407
409 QAbstractButton *btn = m_buttonGroup->button(state.value);
411 btn->setChecked(true);
412
413 Q_FOREACH (QAbstractButton *btn, m_buttonGroup->buttons()) {
414 btn->setEnabled(state.enabled);
415 }
416 }
417
418 void slotButtonClicked(QAbstractButton *btn) {
419 int id = m_buttonGroup->id(btn);
421
422 Q_EMIT idClicked(id);
423 }
424
425Q_SIGNALS:
426 // this signal was added only in Qt 5.15
427 void idClicked(int id);
428
429private:
430 QButtonGroup *m_buttonGroup;
431};
432
433void connectControl(QButtonGroup *group, QObject *source, const char *property)
434{
435 const QMetaObject* meta = source->metaObject();
436 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
438
439 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
440
441 QMetaMethod signal = prop.notifySignal();
442
443 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
444 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("int"));
445
446
448
449 const QMetaObject* dstMeta = helper->metaObject();
450
451 QMetaMethod updateSlot = dstMeta->method(
452 dstMeta->indexOfSlot("updateState(int)"));
453 QObject::connect(source, signal, helper, updateSlot);
454
455 helper->updateState(prop.read(source).toInt());
456
457 if (prop.isWritable()) {
458 QObject::connect(helper, &ConnectButtonGroupHelper::idClicked,
459 source, [prop, source] (int value) { prop.write(source, value); });
460 }
461}
462
463void connectControlState(QButtonGroup *group, QObject *source, const char *readStateProperty, const char *writeProperty)
464{
465 const QMetaObject* meta = source->metaObject();
466 QMetaProperty readStateProp = meta->property(meta->indexOfProperty(readStateProperty));
467 SANITY_CHECK_PROPERTY_EXISTS(readStateProp);
468
469 KIS_SAFE_ASSERT_RECOVER_RETURN(readStateProp.hasNotifySignal());
470
471 QMetaMethod signal = readStateProp.notifySignal();
472
473 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
474 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("ButtonGroupState"));
475
477
478 const QMetaObject* dstMeta = helper->metaObject();
479
480 QMetaMethod updateSlot = dstMeta->method(
481 dstMeta->indexOfSlot("updateState(ButtonGroupState)"));
482 QObject::connect(source, signal, helper, updateSlot);
483
484 helper->updateState(readStateProp.read(source).value<ButtonGroupState>());
485
486 QMetaProperty writeProp = meta->property(meta->indexOfProperty(writeProperty));
488
489 if (writeProp.isWritable()) {
490 QObject::connect(helper, &ConnectButtonGroupHelper::idClicked,
491 source, [writeProp, source] (int value) { writeProp.write(source, value); });
492 }
493}
494
495void connectControlState(QAbstractButton *button, QObject *source, const char *readStatePropertyName, const char *writePropertyName)
496{
497 const QMetaObject* meta = source->metaObject();
498 QMetaProperty readStateProp = meta->property(meta->indexOfProperty(readStatePropertyName));
499 SANITY_CHECK_PROPERTY_EXISTS(readStateProp);
500
501 KIS_SAFE_ASSERT_RECOVER_RETURN(readStateProp.hasNotifySignal());
502
503 QMetaMethod signal = readStateProp.notifySignal();
504
505 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
506 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("CheckBoxState"));
507
509
510 const QMetaObject* dstMeta = helper->metaObject();
511
512 QMetaMethod updateSlot = dstMeta->method(
513 dstMeta->indexOfSlot("updateState(CheckBoxState)"));
514 QObject::connect(source, signal, helper, updateSlot);
515
516 helper->updateState(readStateProp.read(source).value<CheckBoxState>());
517
518 QMetaProperty writeProp = meta->property(meta->indexOfProperty(writePropertyName));
520 if (writeProp.isWritable()) {
521 button->connect(button, &QAbstractButton::toggled,
522 source, [writeProp, source] (bool value) { writeProp.write(source, value); });
523 }
524}
525
526void connectControlState(QGroupBox *button, QObject *source, const char *readStatePropertyName, const char *writePropertyName)
527{
528 const QMetaObject* meta = source->metaObject();
529 QMetaProperty readStateProp = meta->property(meta->indexOfProperty(readStatePropertyName));
530 SANITY_CHECK_PROPERTY_EXISTS(readStateProp);
531
532 KIS_SAFE_ASSERT_RECOVER_RETURN(readStateProp.hasNotifySignal());
533
534 QMetaMethod signal = readStateProp.notifySignal();
535
536 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
537 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("CheckBoxState"));
538
540
541 const QMetaObject* dstMeta = helper->metaObject();
542
543 QMetaMethod updateSlot = dstMeta->method(
544 dstMeta->indexOfSlot("updateState(CheckBoxState)"));
545 QObject::connect(source, signal, helper, updateSlot);
546
547 helper->updateState(readStateProp.read(source).value<CheckBoxState>());
548
549 QMetaProperty writeProp = meta->property(meta->indexOfProperty(writePropertyName));
551 if (writeProp.isWritable()) {
552 button->connect(button, &QGroupBox::toggled,
553 source, [writeProp, source] (bool value) { writeProp.write(source, value); });
554 }
555}
556
557
558void connectControlState(QComboBox *button, QObject *source, const char *readStatePropertyName, const char *writePropertyName)
559{
560 const QMetaObject* meta = source->metaObject();
561 QMetaProperty readStateProp = meta->property(meta->indexOfProperty(readStatePropertyName));
562 SANITY_CHECK_PROPERTY_EXISTS(readStateProp);
563
564 KIS_SAFE_ASSERT_RECOVER_RETURN(readStateProp.hasNotifySignal());
565
566 QMetaMethod signal = readStateProp.notifySignal();
567
568 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
569 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("ComboBoxState"));
570
572
573 const QMetaObject* dstMeta = helper->metaObject();
574
575 QMetaMethod updateSlot = dstMeta->method(
576 dstMeta->indexOfSlot("updateState(ComboBoxState)"));
577 QObject::connect(source, signal, helper, updateSlot);
578
579 helper->updateState(readStateProp.read(source).value<ComboBoxState>());
580
581 QMetaProperty writeProp = meta->property(meta->indexOfProperty(writePropertyName));
583
590
591 if (writeProp.isWritable()) {
592 QObject::connect(button, qOverload<int>(&QComboBox::currentIndexChanged),
593 source, [writeProp, source] (int value) { writeProp.write(source, value); });
594 }
595}
596
597void connectControl(QComboBox *button, QObject *source, const char *property)
598{
599 const QMetaObject* meta = source->metaObject();
600 QMetaProperty stateProp = meta->property(meta->indexOfProperty(property));
602
603 KIS_SAFE_ASSERT_RECOVER_RETURN(stateProp.hasNotifySignal());
604
605 QMetaMethod signal = stateProp.notifySignal();
606
607 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
608 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("int"));
609
610 const QMetaObject* dstMeta = button->metaObject();
611
612 QMetaMethod updateSlot = dstMeta->method(
613 dstMeta->indexOfSlot("setCurrentIndex(int)"));
614 QObject::connect(source, signal, button, updateSlot);
615
616 button->setCurrentIndex(stateProp.read(source).value<int>());
617
618 if (stateProp.isWritable()) {
619 // see a comment in connectControlState(QComboBox *button, ...)
621 QObject::connect(button, qOverload<int>(&QComboBox::currentIndexChanged),
622 source, [stateProp, source] (int value) { stateProp.write(source, value); });
623 }
624}
625
626class ConnectSpacingWidgetHelper : public QObject
627{
628 Q_OBJECT
629public:
630
638public Q_SLOTS:
642
646
647Q_SIGNALS:
648 // this signal was added only in Qt 5.15
650
651private:
653};
654
655void connectControl(KisSpacingSelectionWidget *widget, QObject *source, const char *property)
656{
657 const QMetaObject* meta = source->metaObject();
658 QMetaProperty stateProp = meta->property(meta->indexOfProperty(property));
660
661 KIS_SAFE_ASSERT_RECOVER_RETURN(stateProp.hasNotifySignal());
662
663 QMetaMethod signal = stateProp.notifySignal();
664
665 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
666 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("SpacingState"));
667
669
670 const QMetaObject* dstMeta = helper->metaObject();
671
672 QMetaMethod updateSlot = dstMeta->method(
673 dstMeta->indexOfSlot("slotPropertyChanged(SpacingState)"));
674 QObject::connect(source, signal, helper, updateSlot);
675
676 helper->slotPropertyChanged(stateProp.read(source).value<SpacingState>());
677
678 if (stateProp.isWritable()) {
679 QObject::connect(helper, &ConnectSpacingWidgetHelper::sigWidgetChanged,
680 source, [stateProp, source] (SpacingState value) { stateProp.write(source, QVariant::fromValue(value)); });
681 }
682}
683
684void connectControl(KisAngleSelector *widget, QObject *source, const char *property)
685{
686 const QMetaObject* meta = source->metaObject();
687 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
689
690 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
691
692 QMetaMethod signal = prop.notifySignal();
693
694 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
695 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("qreal"));
696
697 const QMetaObject* dstMeta = widget->metaObject();
698
699 QMetaMethod updateSlot = dstMeta->method(
700 dstMeta->indexOfSlot("setAngle(qreal)"));
701 QObject::connect(source, signal, widget, updateSlot);
702
703 widget->setAngle(prop.read(source).toReal());
704
705 if (prop.isWritable()) {
706 QObject::connect(widget, &KisAngleSelector::angleChanged,
707 source, [prop, source] (qreal value) { prop.write(source, value); });
708 }
709}
710
711void connectControl(QLineEdit *widget, QObject *source, const char *property)
712{
713 const QMetaObject* meta = source->metaObject();
714 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
716
717 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
718
719 QMetaMethod signal = prop.notifySignal();
720
721 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
722 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("QString"));
723
724 const QMetaObject* dstMeta = widget->metaObject();
725
726 QMetaMethod updateSlot = dstMeta->method(
727 dstMeta->indexOfSlot("setText(QString)"));
728 QObject::connect(source, signal, widget, updateSlot);
729
730 widget->setText(prop.read(source).toString());
731
732 if (prop.isWritable()) {
733 QObject::connect(widget, &QLineEdit::textChanged,
734 source, [prop, source] (const QString &value) { prop.write(source, value); });
735 }
736}
737
738void connectControl(KisFileNameRequester *widget, QObject *source, const char *property)
739{
740 const QMetaObject* meta = source->metaObject();
741 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
743
744 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
745
746 QMetaMethod signal = prop.notifySignal();
747
748 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
749 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("QString"));
750
751 const QMetaObject* dstMeta = widget->metaObject();
752
753 QMetaMethod updateSlot = dstMeta->method(
754 dstMeta->indexOfSlot("setFileName(QString)"));
755 QObject::connect(source, signal, widget, updateSlot);
756
757 widget->setFileName(prop.read(source).toString());
758
759 if (prop.isWritable()) {
760 QObject::connect(widget, &KisFileNameRequester::textChanged,
761 source, [prop, source] (const QString &value) {
762 prop.write(source, value); });
763 }
764}
765
766void connectControl(KisColorButton *widget, QObject *source, const char *property)
767{
768 const QMetaObject* meta = source->metaObject();
769 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
771
772 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
773
774 QMetaMethod signal = prop.notifySignal();
775
776 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
777 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("KoColor"));
778
779 const QMetaObject* dstMeta = widget->metaObject();
780
781 QMetaMethod updateSlot = dstMeta->method(
782 dstMeta->indexOfSlot("setColor(KoColor)"));
783 QObject::connect(source, signal, widget, updateSlot);
784
785 widget->setColor(prop.read(source).value<KoColor>());
786
787 if (prop.isWritable()) {
788 QObject::connect(widget, &KisColorButton::changed,
789 source, [prop, source] (const KoColor &value) {
790 prop.write(source, QVariant::fromValue(value)); });
791 }
792}
793
794void connectWidgetVisibleToProperty(QWidget* widget, QObject* source, const char* property)
795{
796 const QMetaObject* meta = source->metaObject();
797 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
799
800 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
801
802 QMetaMethod signal = prop.notifySignal();
803
804 const QMetaObject* dstMeta = widget->metaObject();
805
806 QMetaMethod updateSlot = dstMeta->method(
807 dstMeta->indexOfSlot("setVisible(bool)"));
808
809 QObject::connect(source, signal, widget, updateSlot);
810 widget->setVisible(prop.read(source).toBool());
811}
812
813void connectWidgetEnabledToProperty(QWidget* widget, QObject* source, const char* property)
814{
815 const QMetaObject* meta = source->metaObject();
816 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
818
819 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
820
821 QMetaMethod signal = prop.notifySignal();
822
823 const QMetaObject* dstMeta = widget->metaObject();
824
825 QMetaMethod updateSlot = dstMeta->method(
826 dstMeta->indexOfSlot("setEnabled(bool)"));
827
828 QObject::connect(source, signal, widget, updateSlot);
829 widget->setEnabled(prop.read(source).toBool());
830}
831
832}
833
834#include <KisWidgetConnectionUtils.moc>
float value(const T *src, size_t ch)
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
#define SANITY_CHECK_PROPERTY_EXISTS(prop)
#define SANITY_CHECK_PROPERTY_METATYPE_REGISTERED(prop)
#define SANITY_CHECK_PROPERTY_EXISTS_AND_WRITABLE(prop)
ConnectButtonStateHelper(QAbstractButton *parent)
void updateState(const CheckBoxState &state)
void updateState(const ComboBoxState &state)
void updateState(const CheckBoxState &state)
A widget with several options to select an angle.
void setAngle(qreal newAngle)
Sets the current angle.
void angleChanged(qreal angle)
A pushbutton to display or allow user selection of a color.
void setColor(const KoColor &c)
void changed(const KoColor &newColor)
void textChanged(const QString &fileName)
void setFileName(const QString &path)
void setValue(qreal value)
Set the value, don't use setValue()
void setSpacing(bool isAuto, qreal spacing)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
QString button(const QWheelEvent &ev)
void connectControl(KisCompositeOpListWidget *widget, QObject *source, const char *property)
void connectButtonLikeControl(Button *button, QObject *source, const char *property)
void connectControlState(QSpinBox *spinBox, QObject *source, const char *readStateProperty, const char *writeProperty)
void connectWidgetVisibleToProperty(QWidget *widget, QObject *source, const char *property)
void connectWidgetEnabledToProperty(QWidget *widget, QObject *source, const char *property)