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 "kis_debug.h"
23#include "KisAngleSelector.h"
24#include "kis_color_button.h"
26
32#define SANITY_CHECK_PROPERTY_EXISTS(prop) Q_ASSERT(prop.isValid())
33#define SANITY_CHECK_PROPERTY_EXISTS_AND_WRITABLE(prop) do { Q_ASSERT(prop.isValid()); Q_ASSERT(prop.isWritable()); } while (0)
34#define SANITY_CHECK_PROPERTY_METATYPE_REGISTERED(prop) do { \
35 const int metaTypeId = QMetaType::type(prop.typeName()); \
36 if (metaTypeId <= 0) { \
37 qWarning().nospace() << "WARNING: metatype for property \"" << prop.name() << "\" is not register. Please register type \"" << prop.typeName() << "\""; \
38 } \
39 Q_ASSERT(metaTypeId > 0); \
40 Q_ASSERT(QMetaType::isRegistered(metaTypeId)); \
41} while (0)
42
43class ConnectButtonStateHelper : public QObject
44{
45 Q_OBJECT
46public:
47
48 ConnectButtonStateHelper(QAbstractButton *parent)
49 : QObject(parent),
50 m_button(parent)
51 {
52 }
53public Q_SLOTS:
54 void updateState(const CheckBoxState &state) {
55 QSignalBlocker b(m_button);
56 m_button->setEnabled(state.enabled);
57 m_button->setChecked(state.value);
58
59 // TODO: verify if the two properties are equal or the control is disabled
60 }
61
62private:
63 QAbstractButton *m_button;
64};
65
66class ConnectComboBoxStateHelper : public QObject
67{
68 Q_OBJECT
69public:
70
71 ConnectComboBoxStateHelper(QComboBox *parent)
72 : QObject(parent),
73 m_comboBox(parent)
74 {
75 }
76public Q_SLOTS:
77 void updateState(const ComboBoxState &state) {
78 QSignalBlocker b(m_comboBox);
79
80 while (m_comboBox->count() > 0) {
81 m_comboBox->removeItem(0);
82 }
83
84 m_comboBox->addItems(state.items);
85 m_comboBox->setCurrentIndex(state.currentIndex);
86 m_comboBox->setEnabled(state.enabled);
87
88 // TODO: verify if the two properties are equal or the control is disabled
89 }
90
91private:
92 QComboBox *m_comboBox;
93};
94
95
97
98template<typename Button>
99void connectButtonLikeControl(Button *button, QObject *source, const char *property)
100{
101 const QMetaObject* meta = source->metaObject();
102 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
104
105 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
106
107 QMetaMethod signal = prop.notifySignal();
108
109 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
110 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("bool"));
111
112 const QMetaObject* dstMeta = button->metaObject();
113
114 QMetaMethod updateSlot = dstMeta->method(
115 dstMeta->indexOfSlot("setChecked(bool)"));
116 QObject::connect(source, signal, button, updateSlot);
117
118 button->setChecked(prop.read(source).toBool());
119
120 if (prop.isWritable()) {
121 QObject::connect(button, &Button::toggled,
122 source, [prop, source] (bool value) { prop.write(source, value); });
123 }
124}
125
126void connectControl(QAbstractButton *button, QObject *source, const char *property)
127{
129}
130
131void connectControl(QAction *button, QObject *source, const char *property)
132{
134}
135
136void connectControl(QCheckBox *button, QObject *source, const char *property)
137{
139}
140
141void connectControl(QSpinBox *spinBox, QObject *source, const char *property)
142{
143 const QMetaObject* meta = source->metaObject();
144 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
146
147 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
148
149 QMetaMethod signal = prop.notifySignal();
150
151 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
152 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("int"));
153
154 const QMetaObject* dstMeta = spinBox->metaObject();
155
156 QMetaMethod updateSlot = dstMeta->method(
157 dstMeta->indexOfSlot("setValue(int)"));
158 QObject::connect(source, signal, spinBox, updateSlot);
159
160 spinBox->setValue(prop.read(source).toInt());
161
162 if (prop.isWritable()) {
163 QObject::connect(spinBox, qOverload<int>(&QSpinBox::valueChanged),
164 source, [prop, source] (int value) { prop.write(source, value); });
165 }
166}
167
168void connectControl(QSlider *slider, QObject *source, const char *property)
169{
170 const QMetaObject* meta = source->metaObject();
171 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
173
174 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
175
176 QMetaMethod signal = prop.notifySignal();
177
178 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
179 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("int"));
180
181 const QMetaObject* dstMeta = slider->metaObject();
182
183 QMetaMethod updateSlot = dstMeta->method(
184 dstMeta->indexOfSlot("setValue(int)"));
185 QObject::connect(source, signal, slider, updateSlot);
186
187 slider->setValue(prop.read(source).toInt());
188
189 if (prop.isWritable()) {
190 QObject::connect(slider, qOverload<int>(&QSlider::valueChanged),
191 source, [prop, source] (int value) { prop.write(source, value); });
192 }
193}
194
195void connectControl(QDoubleSpinBox *spinBox, QObject *source, const char *property)
196{
197 const QMetaObject* meta = source->metaObject();
198 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
200
201 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
202
203 QMetaMethod signal = prop.notifySignal();
204
205 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
206 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("qreal"));
207
208 const QMetaObject* dstMeta = spinBox->metaObject();
209
210 QMetaMethod updateSlot = dstMeta->method(
211 dstMeta->indexOfSlot("setValue(qreal)"));
212 QObject::connect(source, signal, spinBox, updateSlot);
213
214 spinBox->setValue(prop.read(source).toReal());
215
216 if (prop.isWritable()) {
217 QObject::connect(spinBox, qOverload<qreal>(&QDoubleSpinBox::valueChanged),
218 source, [prop, source] (qreal value) { prop.write(source, value); });
219 }
220}
221
222class ConnectIntSpinBoxStateHelper : public QObject
223{
224 Q_OBJECT
225public:
226
228 : QObject(parent),
229 m_spinBox(parent)
230 {
231 }
232public Q_SLOTS:
234 QSignalBlocker b(m_spinBox);
235
236 m_spinBox->setEnabled(state.enabled);
237 m_spinBox->setRange(state.min, state.max);
238 m_spinBox->setValue(state.value);
239 }
240
241private:
242 QSpinBox *m_spinBox;
243};
244
245
246void connectControlState(QSpinBox *spinBox, QObject *source, const char *readStateProperty, const char *writeProperty)
247{
248 const QMetaObject* meta = source->metaObject();
249 QMetaProperty readStateProp = meta->property(meta->indexOfProperty(readStateProperty));
250 SANITY_CHECK_PROPERTY_EXISTS(readStateProp);
251
252 KIS_SAFE_ASSERT_RECOVER_RETURN(readStateProp.hasNotifySignal());
253
254 QMetaMethod signal = readStateProp.notifySignal();
255
256 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
257 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("IntSpinBoxState"));
258
260
261 const QMetaObject* dstMeta = helper->metaObject();
262
263 QMetaMethod updateSlot = dstMeta->method(
264 dstMeta->indexOfSlot("setState(IntSpinBoxState)"));
265 QObject::connect(source, signal, helper, updateSlot);
266
267 helper->setState(readStateProp.read(source).value<IntSpinBoxState>());
268
269 QMetaProperty writeProp = meta->property(meta->indexOfProperty(writeProperty));
271 if (writeProp.isWritable()) {
272 QObject::connect(spinBox, qOverload<int>(&QSpinBox::valueChanged),
273 source, [writeProp, source] (int value) { writeProp.write(source, value); });
274 }
275}
276
278{
279 Q_OBJECT
280public:
281
282 ConnectDoubleSpinBoxStateHelper(QDoubleSpinBox *parent)
283 : QObject(parent),
284 m_spinBox(parent)
285 {
286 }
287public Q_SLOTS:
289 QSignalBlocker b(m_spinBox);
290
291 m_spinBox->setEnabled(state.enabled);
292 m_spinBox->setRange(state.min, state.max);
293 m_spinBox->setValue(state.value);
294 }
295
296private:
297 QDoubleSpinBox *m_spinBox;
298};
299
300
301void connectControlState(QDoubleSpinBox *spinBox, QObject *source, const char *readStateProperty, const char *writeProperty)
302{
303 const QMetaObject* meta = source->metaObject();
304 QMetaProperty readStateProp = meta->property(meta->indexOfProperty(readStateProperty));
305 SANITY_CHECK_PROPERTY_EXISTS(readStateProp);
306
307 KIS_SAFE_ASSERT_RECOVER_RETURN(readStateProp.hasNotifySignal());
308
309 QMetaMethod signal = readStateProp.notifySignal();
310
311 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
312 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("DoubleSpinBoxState"));
313
315
316 const QMetaObject* dstMeta = helper->metaObject();
317
318 QMetaMethod updateSlot = dstMeta->method(
319 dstMeta->indexOfSlot("setState(DoubleSpinBoxState)"));
320 QObject::connect(source, signal, helper, updateSlot);
321
322 helper->setState(readStateProp.read(source).value<DoubleSpinBoxState>());
323
324 QMetaProperty writeProp = meta->property(meta->indexOfProperty(writeProperty));
326 if (writeProp.isWritable()) {
327 QObject::connect(spinBox, qOverload<qreal>(&QDoubleSpinBox::valueChanged),
328 source, [writeProp, source] (qreal value) { writeProp.write(source, value); });
329 }
330}
331
332
333void connectControl(KisMultipliersDoubleSliderSpinBox *spinBox, QObject *source, const char *property)
334{
335 const QMetaObject* meta = source->metaObject();
336 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
338
339 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
340
341 QMetaMethod signal = prop.notifySignal();
342
343 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
344 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("qreal"));
345
346 const QMetaObject* dstMeta = spinBox->metaObject();
347
348 QMetaMethod updateSlot = dstMeta->method(
349 dstMeta->indexOfSlot("setValue(qreal)"));
350 QObject::connect(source, signal, spinBox, updateSlot);
351
352 spinBox->setValue(prop.read(source).toReal());
353
354 if (prop.isWritable()) {
355 QObject::connect(spinBox, qOverload<qreal>(&KisMultipliersDoubleSliderSpinBox::valueChanged),
356 source, [prop, source] (qreal value) { prop.write(source, value); });
357 }
358}
359
360
361class ConnectButtonGroupHelper : public QObject
362{
363 Q_OBJECT
364public:
365
366 ConnectButtonGroupHelper(QButtonGroup *parent)
367 : QObject(parent),
368 m_buttonGroup(parent)
369 {
370 QObject::connect(m_buttonGroup, qOverload<QAbstractButton *>(&QButtonGroup::buttonClicked), this, &ConnectButtonGroupHelper::slotButtonClicked);
371 }
372public Q_SLOTS:
373 void updateState(int value) {
374 QAbstractButton *btn = m_buttonGroup->button(value);
376 btn->setChecked(true);
377 }
378
380 QAbstractButton *btn = m_buttonGroup->button(state.value);
382 btn->setChecked(true);
383
384 Q_FOREACH (QAbstractButton *btn, m_buttonGroup->buttons()) {
385 btn->setEnabled(state.enabled);
386 }
387 }
388
389 void slotButtonClicked(QAbstractButton *btn) {
390 int id = m_buttonGroup->id(btn);
392
393 Q_EMIT idClicked(id);
394 }
395
396Q_SIGNALS:
397 // this signal was added only in Qt 5.15
398 void idClicked(int id);
399
400private:
401 QButtonGroup *m_buttonGroup;
402};
403
404void connectControl(QButtonGroup *group, QObject *source, const char *property)
405{
406 const QMetaObject* meta = source->metaObject();
407 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
409
410 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
411
412 QMetaMethod signal = prop.notifySignal();
413
414 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
415 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("int"));
416
417
419
420 const QMetaObject* dstMeta = helper->metaObject();
421
422 QMetaMethod updateSlot = dstMeta->method(
423 dstMeta->indexOfSlot("updateState(int)"));
424 QObject::connect(source, signal, helper, updateSlot);
425
426 helper->updateState(prop.read(source).toInt());
427
428 if (prop.isWritable()) {
429 QObject::connect(helper, &ConnectButtonGroupHelper::idClicked,
430 source, [prop, source] (int value) { prop.write(source, value); });
431 }
432}
433
434void connectControlState(QButtonGroup *group, QObject *source, const char *readStateProperty, const char *writeProperty)
435{
436 const QMetaObject* meta = source->metaObject();
437 QMetaProperty readStateProp = meta->property(meta->indexOfProperty(readStateProperty));
438 SANITY_CHECK_PROPERTY_EXISTS(readStateProp);
439
440 KIS_SAFE_ASSERT_RECOVER_RETURN(readStateProp.hasNotifySignal());
441
442 QMetaMethod signal = readStateProp.notifySignal();
443
444 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
445 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("ButtonGroupState"));
446
448
449 const QMetaObject* dstMeta = helper->metaObject();
450
451 QMetaMethod updateSlot = dstMeta->method(
452 dstMeta->indexOfSlot("updateState(ButtonGroupState)"));
453 QObject::connect(source, signal, helper, updateSlot);
454
455 helper->updateState(readStateProp.read(source).value<ButtonGroupState>());
456
457 QMetaProperty writeProp = meta->property(meta->indexOfProperty(writeProperty));
459
460 if (writeProp.isWritable()) {
461 QObject::connect(helper, &ConnectButtonGroupHelper::idClicked,
462 source, [writeProp, source] (int value) { writeProp.write(source, value); });
463 }
464}
465
466void connectControlState(QAbstractButton *button, QObject *source, const char *readStatePropertyName, const char *writePropertyName)
467{
468 const QMetaObject* meta = source->metaObject();
469 QMetaProperty readStateProp = meta->property(meta->indexOfProperty(readStatePropertyName));
470 SANITY_CHECK_PROPERTY_EXISTS(readStateProp);
471
472 KIS_SAFE_ASSERT_RECOVER_RETURN(readStateProp.hasNotifySignal());
473
474 QMetaMethod signal = readStateProp.notifySignal();
475
476 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
477 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("CheckBoxState"));
478
480
481 const QMetaObject* dstMeta = helper->metaObject();
482
483 QMetaMethod updateSlot = dstMeta->method(
484 dstMeta->indexOfSlot("updateState(CheckBoxState)"));
485 QObject::connect(source, signal, helper, updateSlot);
486
487 helper->updateState(readStateProp.read(source).value<CheckBoxState>());
488
489 QMetaProperty writeProp = meta->property(meta->indexOfProperty(writePropertyName));
491 if (writeProp.isWritable()) {
492 button->connect(button, &QAbstractButton::toggled,
493 source, [writeProp, source] (bool value) { writeProp.write(source, value); });
494 }
495}
496
497
498void connectControlState(QComboBox *button, QObject *source, const char *readStatePropertyName, const char *writePropertyName)
499{
500 const QMetaObject* meta = source->metaObject();
501 QMetaProperty readStateProp = meta->property(meta->indexOfProperty(readStatePropertyName));
502 SANITY_CHECK_PROPERTY_EXISTS(readStateProp);
503
504 KIS_SAFE_ASSERT_RECOVER_RETURN(readStateProp.hasNotifySignal());
505
506 QMetaMethod signal = readStateProp.notifySignal();
507
508 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
509 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("ComboBoxState"));
510
512
513 const QMetaObject* dstMeta = helper->metaObject();
514
515 QMetaMethod updateSlot = dstMeta->method(
516 dstMeta->indexOfSlot("updateState(ComboBoxState)"));
517 QObject::connect(source, signal, helper, updateSlot);
518
519 helper->updateState(readStateProp.read(source).value<ComboBoxState>());
520
521 QMetaProperty writeProp = meta->property(meta->indexOfProperty(writePropertyName));
523
530
531 if (writeProp.isWritable()) {
532 QObject::connect(button, qOverload<int>(&QComboBox::currentIndexChanged),
533 source, [writeProp, source] (int value) { writeProp.write(source, value); });
534 }
535}
536
537void connectControl(QComboBox *button, QObject *source, const char *property)
538{
539 const QMetaObject* meta = source->metaObject();
540 QMetaProperty stateProp = meta->property(meta->indexOfProperty(property));
542
543 KIS_SAFE_ASSERT_RECOVER_RETURN(stateProp.hasNotifySignal());
544
545 QMetaMethod signal = stateProp.notifySignal();
546
547 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
548 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("int"));
549
550 const QMetaObject* dstMeta = button->metaObject();
551
552 QMetaMethod updateSlot = dstMeta->method(
553 dstMeta->indexOfSlot("setCurrentIndex(int)"));
554 QObject::connect(source, signal, button, updateSlot);
555
556 button->setCurrentIndex(stateProp.read(source).value<int>());
557
558 if (stateProp.isWritable()) {
559 // see a comment in connectControlState(QComboBox *button, ...)
561 QObject::connect(button, qOverload<int>(&QComboBox::currentIndexChanged),
562 source, [stateProp, source] (int value) { stateProp.write(source, value); });
563 }
564}
565
566class ConnectSpacingWidgetHelper : public QObject
567{
568 Q_OBJECT
569public:
570
578public Q_SLOTS:
582
586
587Q_SIGNALS:
588 // this signal was added only in Qt 5.15
590
591private:
593};
594
595void connectControl(KisSpacingSelectionWidget *widget, QObject *source, const char *property)
596{
597 const QMetaObject* meta = source->metaObject();
598 QMetaProperty stateProp = meta->property(meta->indexOfProperty(property));
600
601 KIS_SAFE_ASSERT_RECOVER_RETURN(stateProp.hasNotifySignal());
602
603 QMetaMethod signal = stateProp.notifySignal();
604
605 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
606 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("SpacingState"));
607
609
610 const QMetaObject* dstMeta = helper->metaObject();
611
612 QMetaMethod updateSlot = dstMeta->method(
613 dstMeta->indexOfSlot("slotPropertyChanged(SpacingState)"));
614 QObject::connect(source, signal, helper, updateSlot);
615
616 helper->slotPropertyChanged(stateProp.read(source).value<SpacingState>());
617
618 if (stateProp.isWritable()) {
619 QObject::connect(helper, &ConnectSpacingWidgetHelper::sigWidgetChanged,
620 source, [stateProp, source] (SpacingState value) { stateProp.write(source, QVariant::fromValue(value)); });
621 }
622}
623
624void connectControl(KisAngleSelector *widget, QObject *source, const char *property)
625{
626 const QMetaObject* meta = source->metaObject();
627 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
629
630 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
631
632 QMetaMethod signal = prop.notifySignal();
633
634 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
635 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("qreal"));
636
637 const QMetaObject* dstMeta = widget->metaObject();
638
639 QMetaMethod updateSlot = dstMeta->method(
640 dstMeta->indexOfSlot("setAngle(qreal)"));
641 QObject::connect(source, signal, widget, updateSlot);
642
643 widget->setAngle(prop.read(source).toReal());
644
645 if (prop.isWritable()) {
646 QObject::connect(widget, &KisAngleSelector::angleChanged,
647 source, [prop, source] (qreal value) { prop.write(source, value); });
648 }
649}
650
651void connectControl(QLineEdit *widget, QObject *source, const char *property)
652{
653 const QMetaObject* meta = source->metaObject();
654 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
656
657 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
658
659 QMetaMethod signal = prop.notifySignal();
660
661 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
662 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("QString"));
663
664 const QMetaObject* dstMeta = widget->metaObject();
665
666 QMetaMethod updateSlot = dstMeta->method(
667 dstMeta->indexOfSlot("setText(QString)"));
668 QObject::connect(source, signal, widget, updateSlot);
669
670 widget->setText(prop.read(source).toString());
671
672 if (prop.isWritable()) {
673 QObject::connect(widget, &QLineEdit::textChanged,
674 source, [prop, source] (const QString &value) { prop.write(source, value); });
675 }
676}
677
678void connectControl(KisFileNameRequester *widget, QObject *source, const char *property)
679{
680 const QMetaObject* meta = source->metaObject();
681 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
683
684 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
685
686 QMetaMethod signal = prop.notifySignal();
687
688 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
689 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("QString"));
690
691 const QMetaObject* dstMeta = widget->metaObject();
692
693 QMetaMethod updateSlot = dstMeta->method(
694 dstMeta->indexOfSlot("setFileName(QString)"));
695 QObject::connect(source, signal, widget, updateSlot);
696
697 widget->setFileName(prop.read(source).toString());
698
699 if (prop.isWritable()) {
700 QObject::connect(widget, &KisFileNameRequester::textChanged,
701 source, [prop, source] (const QString &value) {
702 prop.write(source, value); });
703 }
704}
705
706void connectControl(KisColorButton *widget, QObject *source, const char *property)
707{
708 const QMetaObject* meta = source->metaObject();
709 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
711
712 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
713
714 QMetaMethod signal = prop.notifySignal();
715
716 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterCount() >= 1);
717 KIS_SAFE_ASSERT_RECOVER_RETURN(signal.parameterType(0) == QMetaType::type("KoColor"));
718
719 const QMetaObject* dstMeta = widget->metaObject();
720
721 QMetaMethod updateSlot = dstMeta->method(
722 dstMeta->indexOfSlot("setColor(KoColor)"));
723 QObject::connect(source, signal, widget, updateSlot);
724
725 widget->setColor(prop.read(source).value<KoColor>());
726
727 if (prop.isWritable()) {
728 QObject::connect(widget, &KisColorButton::changed,
729 source, [prop, source] (const KoColor &value) {
730 prop.write(source, QVariant::fromValue(value)); });
731 }
732}
733
734void connectWidgetVisibleToProperty(QWidget* widget, QObject* source, const char* property)
735{
736 const QMetaObject* meta = source->metaObject();
737 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
739
740 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
741
742 QMetaMethod signal = prop.notifySignal();
743
744 const QMetaObject* dstMeta = widget->metaObject();
745
746 QMetaMethod updateSlot = dstMeta->method(
747 dstMeta->indexOfSlot("setVisible(bool)"));
748
749 QObject::connect(source, signal, widget, updateSlot);
750 widget->setVisible(prop.read(source).toBool());
751}
752
753void connectWidgetEnabledToProperty(QWidget* widget, QObject* source, const char* property)
754{
755 const QMetaObject* meta = source->metaObject();
756 QMetaProperty prop = meta->property(meta->indexOfProperty(property));
758
759 KIS_SAFE_ASSERT_RECOVER_RETURN(prop.hasNotifySignal());
760
761 QMetaMethod signal = prop.notifySignal();
762
763 const QMetaObject* dstMeta = widget->metaObject();
764
765 QMetaMethod updateSlot = dstMeta->method(
766 dstMeta->indexOfSlot("setEnabled(bool)"));
767
768 QObject::connect(source, signal, widget, updateSlot);
769 widget->setEnabled(prop.read(source).toBool());
770}
771
772}
773
774#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)
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
ConnectButtonStateHelper(QAbstractButton *parent)
void updateState(const CheckBoxState &state)
void updateState(const ComboBoxState &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)