1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qteditorfactory.h"
5#include "qtpropertybrowserutils_p.h"
6
7#include <QtCore/QHash>
8#include <QtCore/QRegularExpression>
9#include <QtGui/QKeyEvent>
10#include <QtGui/QRegularExpressionValidator>
11#include <QtWidgets/QAbstractItemView>
12#include <QtWidgets/QApplication>
13#include <QtWidgets/QBoxLayout>
14#include <QtWidgets/QColorDialog>
15#include <QtWidgets/QComboBox>
16#include <QtWidgets/QDateTimeEdit>
17#include <QtWidgets/QFontDialog>
18#include <QtWidgets/QKeySequenceEdit>
19#include <QtWidgets/QLabel>
20#include <QtWidgets/QLineEdit>
21#include <QtWidgets/QMenu>
22#include <QtWidgets/QScrollBar>
23#include <QtWidgets/QSpacerItem>
24#include <QtWidgets/QSpinBox>
25#include <QtWidgets/QToolButton>
26
27#if defined(Q_CC_MSVC)
28# pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */
29#endif
30
31QT_BEGIN_NAMESPACE
32
33// Set a hard coded left margin to account for the indentation
34// of the tree view icon when switching to an editor
35
36static inline void setupTreeViewEditorMargin(QLayout *lt)
37{
38 enum { DecorationMargin = 4 };
39 if (QApplication::layoutDirection() == Qt::LeftToRight)
40 lt->setContentsMargins(left: DecorationMargin, top: 0, right: 0, bottom: 0);
41 else
42 lt->setContentsMargins(left: 0, top: 0, right: DecorationMargin, bottom: 0);
43}
44
45// ---------- EditorFactoryPrivate :
46// Base class for editor factory private classes. Manages mapping of properties to editors and vice versa.
47
48template <class Editor>
49class EditorFactoryPrivate
50{
51public:
52
53 using EditorList = QList<Editor *>;
54 using PropertyToEditorListMap = QHash<QtProperty *, EditorList>;
55 using EditorToPropertyMap = QHash<Editor *, QtProperty *>;
56
57 Editor *createEditor(QtProperty *property, QWidget *parent);
58 void initializeEditor(QtProperty *property, Editor *e);
59 void slotEditorDestroyed(QObject *object);
60
61 PropertyToEditorListMap m_createdEditors;
62 EditorToPropertyMap m_editorToProperty;
63};
64
65template <class Editor>
66Editor *EditorFactoryPrivate<Editor>::createEditor(QtProperty *property, QWidget *parent)
67{
68 auto *editor = new Editor(parent);
69 initializeEditor(property, e: editor);
70 return editor;
71}
72
73template <class Editor>
74void EditorFactoryPrivate<Editor>::initializeEditor(QtProperty *property, Editor *editor)
75{
76 auto it = m_createdEditors.find(property);
77 if (it == m_createdEditors.end())
78 it = m_createdEditors.insert(property, EditorList());
79 it.value().append(editor);
80 m_editorToProperty.insert(editor, property);
81}
82
83template <class Editor>
84void EditorFactoryPrivate<Editor>::slotEditorDestroyed(QObject *object)
85{
86 const auto ecend = m_editorToProperty.end();
87 for (auto itEditor = m_editorToProperty.begin(); itEditor != ecend; ++itEditor) {
88 if (itEditor.key() == object) {
89 Editor *editor = itEditor.key();
90 QtProperty *property = itEditor.value();
91 const auto pit = m_createdEditors.find(property);
92 if (pit != m_createdEditors.end()) {
93 pit.value().removeAll(editor);
94 if (pit.value().isEmpty())
95 m_createdEditors.erase(pit);
96 }
97 m_editorToProperty.erase(itEditor);
98 return;
99 }
100 }
101}
102
103// ------------ QtSpinBoxFactory
104
105class QtSpinBoxFactoryPrivate : public EditorFactoryPrivate<QSpinBox>
106{
107 QtSpinBoxFactory *q_ptr;
108 Q_DECLARE_PUBLIC(QtSpinBoxFactory)
109public:
110
111 void slotPropertyChanged(QtProperty *property, int value);
112 void slotRangeChanged(QtProperty *property, int min, int max);
113 void slotSingleStepChanged(QtProperty *property, int step);
114 void slotSetValue(int value);
115};
116
117void QtSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
118{
119 const auto it = m_createdEditors.constFind(key: property);
120 if (it == m_createdEditors.cend())
121 return;
122 for (QSpinBox *editor : it.value()) {
123 if (editor->value() != value) {
124 editor->blockSignals(b: true);
125 editor->setValue(value);
126 editor->blockSignals(b: false);
127 }
128 }
129}
130
131void QtSpinBoxFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max)
132{
133 const auto it = m_createdEditors.constFind(key: property);
134 if (it == m_createdEditors.cend())
135 return;
136
137 QtIntPropertyManager *manager = q_ptr->propertyManager(property);
138 if (!manager)
139 return;
140
141 for (QSpinBox *editor : it.value()) {
142 editor->blockSignals(b: true);
143 editor->setRange(min, max);
144 editor->setValue(manager->value(property));
145 editor->blockSignals(b: false);
146 }
147}
148
149void QtSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step)
150{
151 const auto it = m_createdEditors.constFind(key: property);
152 if (it == m_createdEditors.cend())
153 return;
154 for (QSpinBox *editor : it.value()) {
155 editor->blockSignals(b: true);
156 editor->setSingleStep(step);
157 editor->blockSignals(b: false);
158 }
159}
160
161void QtSpinBoxFactoryPrivate::slotSetValue(int value)
162{
163 QObject *object = q_ptr->sender();
164 for (auto itEditor = m_editorToProperty.cbegin(), ecend = m_editorToProperty.cend(); itEditor != ecend; ++itEditor) {
165 if (itEditor.key() == object) {
166 QtProperty *property = itEditor.value();
167 QtIntPropertyManager *manager = q_ptr->propertyManager(property);
168 if (!manager)
169 return;
170 manager->setValue(property, val: value);
171 return;
172 }
173 }
174}
175
176/*!
177 \class QtSpinBoxFactory
178 \internal
179 \inmodule QtDesigner
180 \since 4.4
181
182 \brief The QtSpinBoxFactory class provides QSpinBox widgets for
183 properties created by QtIntPropertyManager objects.
184
185 \sa QtAbstractEditorFactory, QtIntPropertyManager
186*/
187
188/*!
189 Creates a factory with the given \a parent.
190*/
191QtSpinBoxFactory::QtSpinBoxFactory(QObject *parent)
192 : QtAbstractEditorFactory<QtIntPropertyManager>(parent), d_ptr(new QtSpinBoxFactoryPrivate())
193{
194 d_ptr->q_ptr = this;
195
196}
197
198/*!
199 Destroys this factory, and all the widgets it has created.
200*/
201QtSpinBoxFactory::~QtSpinBoxFactory()
202{
203 qDeleteAll(c: d_ptr->m_editorToProperty.keys());
204}
205
206/*!
207 \internal
208
209 Reimplemented from the QtAbstractEditorFactory class.
210*/
211void QtSpinBoxFactory::connectPropertyManager(QtIntPropertyManager *manager)
212{
213 connect(sender: manager, signal: &QtIntPropertyManager::valueChanged,
214 context: this, slot: [this](QtProperty *property, int value)
215 { d_ptr->slotPropertyChanged(property, value); });
216 connect(sender: manager, signal: &QtIntPropertyManager::rangeChanged,
217 context: this, slot: [this](QtProperty *property, int min, int max)
218 { d_ptr->slotRangeChanged(property, min, max); });
219 connect(sender: manager, signal: &QtIntPropertyManager::singleStepChanged,
220 context: this, slot: [this](QtProperty *property, int value)
221 { d_ptr->slotSingleStepChanged(property, step: value); });
222}
223
224/*!
225 \internal
226
227 Reimplemented from the QtAbstractEditorFactory class.
228*/
229QWidget *QtSpinBoxFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property,
230 QWidget *parent)
231{
232 QSpinBox *editor = d_ptr->createEditor(property, parent);
233 editor->setSingleStep(manager->singleStep(property));
234 editor->setRange(min: manager->minimum(property), max: manager->maximum(property));
235 editor->setValue(manager->value(property));
236 editor->setKeyboardTracking(false);
237
238 connect(sender: editor, signal: &QSpinBox::valueChanged,
239 context: this, slot: [this](int value) { d_ptr->slotSetValue(value); });
240 connect(sender: editor, signal: &QObject::destroyed,
241 context: this, slot: [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
242 return editor;
243}
244
245/*!
246 \internal
247
248 Reimplemented from the QtAbstractEditorFactory class.
249*/
250void QtSpinBoxFactory::disconnectPropertyManager(QtIntPropertyManager *manager)
251{
252 disconnect(sender: manager, signal: &QtIntPropertyManager::valueChanged, receiver: this, zero: nullptr);
253 disconnect(sender: manager, signal: &QtIntPropertyManager::rangeChanged, receiver: this, zero: nullptr);
254 disconnect(sender: manager, signal: &QtIntPropertyManager::singleStepChanged, receiver: this, zero: nullptr);
255}
256
257// QtSliderFactory
258
259class QtSliderFactoryPrivate : public EditorFactoryPrivate<QSlider>
260{
261 QtSliderFactory *q_ptr;
262 Q_DECLARE_PUBLIC(QtSliderFactory)
263public:
264 void slotPropertyChanged(QtProperty *property, int value);
265 void slotRangeChanged(QtProperty *property, int min, int max);
266 void slotSingleStepChanged(QtProperty *property, int step);
267 void slotSetValue(int value);
268};
269
270void QtSliderFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
271{
272 const auto it = m_createdEditors.constFind(key: property);
273 if (it == m_createdEditors.cend())
274 return;
275 for (QSlider *editor : it.value()) {
276 editor->blockSignals(b: true);
277 editor->setValue(value);
278 editor->blockSignals(b: false);
279 }
280}
281
282void QtSliderFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max)
283{
284 const auto it = m_createdEditors.constFind(key: property);
285 if (it == m_createdEditors.cend())
286 return;
287
288 QtIntPropertyManager *manager = q_ptr->propertyManager(property);
289 if (!manager)
290 return;
291
292 for (QSlider *editor : it.value()) {
293 editor->blockSignals(b: true);
294 editor->setRange(min, max);
295 editor->setValue(manager->value(property));
296 editor->blockSignals(b: false);
297 }
298}
299
300void QtSliderFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step)
301{
302 const auto it = m_createdEditors.constFind(key: property);
303 if (it == m_createdEditors.cend())
304 return;
305 for (QSlider *editor : it.value()) {
306 editor->blockSignals(b: true);
307 editor->setSingleStep(step);
308 editor->blockSignals(b: false);
309 }
310}
311
312void QtSliderFactoryPrivate::slotSetValue(int value)
313{
314 QObject *object = q_ptr->sender();
315 for (auto itEditor = m_editorToProperty.cbegin(), ecend = m_editorToProperty.cend(); itEditor != ecend; ++itEditor ) {
316 if (itEditor.key() == object) {
317 QtProperty *property = itEditor.value();
318 QtIntPropertyManager *manager = q_ptr->propertyManager(property);
319 if (!manager)
320 return;
321 manager->setValue(property, val: value);
322 return;
323 }
324 }
325}
326
327/*!
328 \class QtSliderFactory
329 \internal
330 \inmodule QtDesigner
331 \since 4.4
332
333 \brief The QtSliderFactory class provides QSlider widgets for
334 properties created by QtIntPropertyManager objects.
335
336 \sa QtAbstractEditorFactory, QtIntPropertyManager
337*/
338
339/*!
340 Creates a factory with the given \a parent.
341*/
342QtSliderFactory::QtSliderFactory(QObject *parent)
343 : QtAbstractEditorFactory<QtIntPropertyManager>(parent), d_ptr(new QtSliderFactoryPrivate())
344{
345 d_ptr->q_ptr = this;
346
347}
348
349/*!
350 Destroys this factory, and all the widgets it has created.
351*/
352QtSliderFactory::~QtSliderFactory()
353{
354 qDeleteAll(c: d_ptr->m_editorToProperty.keys());
355}
356
357/*!
358 \internal
359
360 Reimplemented from the QtAbstractEditorFactory class.
361*/
362void QtSliderFactory::connectPropertyManager(QtIntPropertyManager *manager)
363{
364 connect(sender: manager, signal: &QtIntPropertyManager::valueChanged,
365 context: this, slot: [this](QtProperty *property, int value)
366 { d_ptr->slotPropertyChanged(property, value); });
367 connect(sender: manager, signal: &QtIntPropertyManager::rangeChanged,
368 context: this, slot: [this](QtProperty *property, int min, int max)
369 { d_ptr->slotRangeChanged(property, min, max); });
370 connect(sender: manager, signal: &QtIntPropertyManager::singleStepChanged,
371 context: this, slot: [this](QtProperty *property, int value)
372 { d_ptr->slotSingleStepChanged(property, step: value); });
373}
374
375/*!
376 \internal
377
378 Reimplemented from the QtAbstractEditorFactory class.
379*/
380QWidget *QtSliderFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property,
381 QWidget *parent)
382{
383 auto *editor = new QSlider(Qt::Horizontal, parent);
384 d_ptr->initializeEditor(property, editor);
385 editor->setSingleStep(manager->singleStep(property));
386 editor->setRange(min: manager->minimum(property), max: manager->maximum(property));
387 editor->setValue(manager->value(property));
388
389 connect(sender: editor, signal: &QSlider::valueChanged,
390 context: this, slot: [this](int value) { d_ptr->slotSetValue(value); });
391 connect(sender: editor, signal: &QObject::destroyed,
392 context: this, slot: [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
393 return editor;
394}
395
396/*!
397 \internal
398
399 Reimplemented from the QtAbstractEditorFactory class.
400*/
401void QtSliderFactory::disconnectPropertyManager(QtIntPropertyManager *manager)
402{
403 disconnect(sender: manager, signal: &QtIntPropertyManager::valueChanged, receiver: this, zero: nullptr);
404 disconnect(sender: manager, signal: &QtIntPropertyManager::rangeChanged, receiver: this, zero: nullptr);
405 disconnect(sender: manager, signal: &QtIntPropertyManager::singleStepChanged, receiver: this, zero: nullptr);
406}
407
408// QtSliderFactory
409
410class QtScrollBarFactoryPrivate : public EditorFactoryPrivate<QScrollBar>
411{
412 QtScrollBarFactory *q_ptr;
413 Q_DECLARE_PUBLIC(QtScrollBarFactory)
414public:
415 void slotPropertyChanged(QtProperty *property, int value);
416 void slotRangeChanged(QtProperty *property, int min, int max);
417 void slotSingleStepChanged(QtProperty *property, int step);
418 void slotSetValue(int value);
419};
420
421void QtScrollBarFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
422{
423 const auto it = m_createdEditors.constFind(key: property);
424 if (it == m_createdEditors.cend())
425 return;
426
427 for (QScrollBar *editor : it.value()) {
428 editor->blockSignals(b: true);
429 editor->setValue(value);
430 editor->blockSignals(b: false);
431 }
432}
433
434void QtScrollBarFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max)
435{
436 const auto it = m_createdEditors.constFind(key: property);
437 if (it == m_createdEditors.cend())
438 return;
439
440 QtIntPropertyManager *manager = q_ptr->propertyManager(property);
441 if (!manager)
442 return;
443
444 for (QScrollBar *editor : it.value()) {
445 editor->blockSignals(b: true);
446 editor->setRange(min, max);
447 editor->setValue(manager->value(property));
448 editor->blockSignals(b: false);
449 }
450}
451
452void QtScrollBarFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step)
453{
454 const auto it = m_createdEditors.constFind(key: property);
455 if (it == m_createdEditors.cend())
456 return;
457 for (QScrollBar *editor : it.value()) {
458 editor->blockSignals(b: true);
459 editor->setSingleStep(step);
460 editor->blockSignals(b: false);
461 }
462}
463
464void QtScrollBarFactoryPrivate::slotSetValue(int value)
465{
466 QObject *object = q_ptr->sender();
467 for (auto itEditor = m_editorToProperty.cbegin(), ecend = m_editorToProperty.cend(); itEditor != ecend; ++itEditor)
468 if (itEditor.key() == object) {
469 QtProperty *property = itEditor.value();
470 QtIntPropertyManager *manager = q_ptr->propertyManager(property);
471 if (!manager)
472 return;
473 manager->setValue(property, val: value);
474 return;
475 }
476}
477
478/*!
479 \class QtScrollBarFactory
480 \internal
481 \inmodule QtDesigner
482 \since 4.4
483
484 \brief The QtScrollBarFactory class provides QScrollBar widgets for
485 properties created by QtIntPropertyManager objects.
486
487 \sa QtAbstractEditorFactory, QtIntPropertyManager
488*/
489
490/*!
491 Creates a factory with the given \a parent.
492*/
493QtScrollBarFactory::QtScrollBarFactory(QObject *parent)
494 : QtAbstractEditorFactory<QtIntPropertyManager>(parent), d_ptr(new QtScrollBarFactoryPrivate())
495{
496 d_ptr->q_ptr = this;
497
498}
499
500/*!
501 Destroys this factory, and all the widgets it has created.
502*/
503QtScrollBarFactory::~QtScrollBarFactory()
504{
505 qDeleteAll(c: d_ptr->m_editorToProperty.keys());
506}
507
508/*!
509 \internal
510
511 Reimplemented from the QtAbstractEditorFactory class.
512*/
513void QtScrollBarFactory::connectPropertyManager(QtIntPropertyManager *manager)
514{
515 connect(sender: manager, signal: &QtIntPropertyManager::valueChanged,
516 context: this, slot: [this](QtProperty *property, int value)
517 { d_ptr->slotPropertyChanged(property, value); });
518 connect(sender: manager, signal: &QtIntPropertyManager::rangeChanged,
519 context: this, slot: [this](QtProperty *property, int min, int max)
520 { d_ptr->slotRangeChanged(property, min, max); });
521 connect(sender: manager, signal: &QtIntPropertyManager::singleStepChanged,
522 context: this, slot: [this](QtProperty *property, int value)
523 { d_ptr->slotSingleStepChanged(property, step: value); });
524}
525
526/*!
527 \internal
528
529 Reimplemented from the QtAbstractEditorFactory class.
530*/
531QWidget *QtScrollBarFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property,
532 QWidget *parent)
533{
534 auto *editor = new QScrollBar(Qt::Horizontal, parent);
535 d_ptr->initializeEditor(property, editor);
536 editor->setSingleStep(manager->singleStep(property));
537 editor->setRange(min: manager->minimum(property), max: manager->maximum(property));
538 editor->setValue(manager->value(property));
539 connect(sender: editor, signal: &QScrollBar::valueChanged,
540 context: this, slot: [this](int value) { d_ptr->slotSetValue(value); });
541 connect(sender: editor, signal: &QObject::destroyed,
542 context: this, slot: [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
543 return editor;
544}
545
546/*!
547 \internal
548
549 Reimplemented from the QtAbstractEditorFactory class.
550*/
551void QtScrollBarFactory::disconnectPropertyManager(QtIntPropertyManager *manager)
552{
553 disconnect(sender: manager, signal: &QtIntPropertyManager::valueChanged, receiver: this, zero: nullptr);
554 disconnect(sender: manager, signal: &QtIntPropertyManager::rangeChanged, receiver: this, zero: nullptr);
555 disconnect(sender: manager, signal: &QtIntPropertyManager::singleStepChanged, receiver: this, zero: nullptr);
556}
557
558// QtCheckBoxFactory
559
560class QtCheckBoxFactoryPrivate : public EditorFactoryPrivate<QtBoolEdit>
561{
562 QtCheckBoxFactory *q_ptr;
563 Q_DECLARE_PUBLIC(QtCheckBoxFactory)
564public:
565 void slotPropertyChanged(QtProperty *property, bool value);
566 void slotSetValue(bool value);
567};
568
569void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, bool value)
570{
571 const auto it = m_createdEditors.constFind(key: property);
572 if (it == m_createdEditors.cend())
573 return;
574
575 for (QtBoolEdit *editor : it.value()) {
576 editor->blockCheckBoxSignals(block: true);
577 editor->setChecked(value);
578 editor->blockCheckBoxSignals(block: false);
579 }
580}
581
582void QtCheckBoxFactoryPrivate::slotSetValue(bool value)
583{
584 QObject *object = q_ptr->sender();
585
586 for (auto itEditor = m_editorToProperty.cbegin(), ecend = m_editorToProperty.cend(); itEditor != ecend; ++itEditor)
587 if (itEditor.key() == object) {
588 QtProperty *property = itEditor.value();
589 QtBoolPropertyManager *manager = q_ptr->propertyManager(property);
590 if (!manager)
591 return;
592 manager->setValue(property, val: value);
593 return;
594 }
595}
596
597/*!
598 \class QtCheckBoxFactory
599 \internal
600 \inmodule QtDesigner
601 \since 4.4
602
603 \brief The QtCheckBoxFactory class provides QCheckBox widgets for
604 properties created by QtBoolPropertyManager objects.
605
606 \sa QtAbstractEditorFactory, QtBoolPropertyManager
607*/
608
609/*!
610 Creates a factory with the given \a parent.
611*/
612QtCheckBoxFactory::QtCheckBoxFactory(QObject *parent)
613 : QtAbstractEditorFactory<QtBoolPropertyManager>(parent), d_ptr(new QtCheckBoxFactoryPrivate())
614{
615 d_ptr->q_ptr = this;
616
617}
618
619/*!
620 Destroys this factory, and all the widgets it has created.
621*/
622QtCheckBoxFactory::~QtCheckBoxFactory()
623{
624 qDeleteAll(c: d_ptr->m_editorToProperty.keys());
625}
626
627/*!
628 \internal
629
630 Reimplemented from the QtAbstractEditorFactory class.
631*/
632void QtCheckBoxFactory::connectPropertyManager(QtBoolPropertyManager *manager)
633{
634 connect(sender: manager, signal: &QtBoolPropertyManager::valueChanged,
635 context: this, slot: [this](QtProperty *property, bool value)
636 { d_ptr->slotPropertyChanged(property, value); });
637}
638
639/*!
640 \internal
641
642 Reimplemented from the QtAbstractEditorFactory class.
643*/
644QWidget *QtCheckBoxFactory::createEditor(QtBoolPropertyManager *manager, QtProperty *property,
645 QWidget *parent)
646{
647 QtBoolEdit *editor = d_ptr->createEditor(property, parent);
648 editor->setChecked(manager->value(property));
649
650 connect(sender: editor, signal: &QtBoolEdit::toggled,
651 context: this, slot: [this](bool value) { d_ptr->slotSetValue(value); });
652 connect(sender: editor, signal: &QObject::destroyed,
653 context: this, slot: [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
654 return editor;
655}
656
657/*!
658 \internal
659
660 Reimplemented from the QtAbstractEditorFactory class.
661*/
662void QtCheckBoxFactory::disconnectPropertyManager(QtBoolPropertyManager *manager)
663{
664 disconnect(sender: manager, signal: &QtBoolPropertyManager::valueChanged, receiver: this, zero: nullptr);
665}
666
667// QtDoubleSpinBoxFactory
668
669class QtDoubleSpinBoxFactoryPrivate : public EditorFactoryPrivate<QDoubleSpinBox>
670{
671 QtDoubleSpinBoxFactory *q_ptr;
672 Q_DECLARE_PUBLIC(QtDoubleSpinBoxFactory)
673public:
674
675 void slotPropertyChanged(QtProperty *property, double value);
676 void slotRangeChanged(QtProperty *property, double min, double max);
677 void slotSingleStepChanged(QtProperty *property, double step);
678 void slotDecimalsChanged(QtProperty *property, int prec);
679 void slotSetValue(double value);
680};
681
682void QtDoubleSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, double value)
683{
684 const auto it = m_createdEditors.constFind(key: property);
685 if (it == m_createdEditors.cend())
686 return;
687 for (QDoubleSpinBox *editor : it.value()) {
688 if (editor->value() != value) {
689 editor->blockSignals(b: true);
690 editor->setValue(value);
691 editor->blockSignals(b: false);
692 }
693 }
694}
695
696void QtDoubleSpinBoxFactoryPrivate::slotRangeChanged(QtProperty *property,
697 double min, double max)
698{
699 const auto it = m_createdEditors.constFind(key: property);
700 if (it == m_createdEditors.cend())
701 return;
702
703 QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
704 if (!manager)
705 return;
706
707 for (QDoubleSpinBox *editor : it.value()) {
708 editor->blockSignals(b: true);
709 editor->setRange(min, max);
710 editor->setValue(manager->value(property));
711 editor->blockSignals(b: false);
712 }
713}
714
715void QtDoubleSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty *property, double step)
716{
717 const auto it = m_createdEditors.constFind(key: property);
718 if (it == m_createdEditors.cend())
719 return;
720
721 QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
722 if (!manager)
723 return;
724
725 for (QDoubleSpinBox *editor : it.value()) {
726 editor->blockSignals(b: true);
727 editor->setSingleStep(step);
728 editor->blockSignals(b: false);
729 }
730}
731
732void QtDoubleSpinBoxFactoryPrivate::slotDecimalsChanged(QtProperty *property, int prec)
733{
734 const auto it = m_createdEditors.constFind(key: property);
735 if (it == m_createdEditors.constEnd())
736 return;
737
738 QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
739 if (!manager)
740 return;
741
742 for (QDoubleSpinBox *editor : it.value()) {
743 editor->blockSignals(b: true);
744 editor->setDecimals(prec);
745 editor->setValue(manager->value(property));
746 editor->blockSignals(b: false);
747 }
748}
749
750void QtDoubleSpinBoxFactoryPrivate::slotSetValue(double value)
751{
752 QObject *object = q_ptr->sender();
753 for (auto itEditor = m_editorToProperty.cbegin(), itcend = m_editorToProperty.cend(); itEditor != itcend; ++itEditor) {
754 if (itEditor.key() == object) {
755 QtProperty *property = itEditor.value();
756 QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
757 if (!manager)
758 return;
759 manager->setValue(property, val: value);
760 return;
761 }
762 }
763}
764
765/*! \class QtDoubleSpinBoxFactory
766 \internal
767 \inmodule QtDesigner
768 \since 4.4
769
770 \brief The QtDoubleSpinBoxFactory class provides QDoubleSpinBox
771 widgets for properties created by QtDoublePropertyManager objects.
772
773 \sa QtAbstractEditorFactory, QtDoublePropertyManager
774*/
775
776/*!
777 Creates a factory with the given \a parent.
778*/
779QtDoubleSpinBoxFactory::QtDoubleSpinBoxFactory(QObject *parent)
780 : QtAbstractEditorFactory<QtDoublePropertyManager>(parent), d_ptr(new QtDoubleSpinBoxFactoryPrivate())
781{
782 d_ptr->q_ptr = this;
783
784}
785
786/*!
787 Destroys this factory, and all the widgets it has created.
788*/
789QtDoubleSpinBoxFactory::~QtDoubleSpinBoxFactory()
790{
791 qDeleteAll(c: d_ptr->m_editorToProperty.keys());
792}
793
794/*!
795 \internal
796
797 Reimplemented from the QtAbstractEditorFactory class.
798*/
799void QtDoubleSpinBoxFactory::connectPropertyManager(QtDoublePropertyManager *manager)
800{
801 connect(sender: manager, signal: &QtDoublePropertyManager::valueChanged,
802 context: this, slot: [this](QtProperty *property, double value)
803 { d_ptr->slotPropertyChanged(property, value); });
804 connect(sender: manager, signal: &QtDoublePropertyManager::rangeChanged,
805 context: this, slot: [this](QtProperty *property, double min, double max)
806 { d_ptr->slotRangeChanged(property, min, max); });
807 connect(sender: manager, signal: &QtDoublePropertyManager::singleStepChanged,
808 context: this, slot: [this](QtProperty *property, double value)
809 { d_ptr->slotSingleStepChanged(property, step: value); });
810 connect(sender: manager, signal: &QtDoublePropertyManager::decimalsChanged,
811 context: this, slot: [this](QtProperty *property, int value)
812 { d_ptr->slotDecimalsChanged(property, prec: value); });
813}
814
815/*!
816 \internal
817
818 Reimplemented from the QtAbstractEditorFactory class.
819*/
820QWidget *QtDoubleSpinBoxFactory::createEditor(QtDoublePropertyManager *manager,
821 QtProperty *property, QWidget *parent)
822{
823 QDoubleSpinBox *editor = d_ptr->createEditor(property, parent);
824 editor->setSingleStep(manager->singleStep(property));
825 editor->setDecimals(manager->decimals(property));
826 editor->setRange(min: manager->minimum(property), max: manager->maximum(property));
827 editor->setValue(manager->value(property));
828 editor->setKeyboardTracking(false);
829
830 connect(sender: editor, signal: &QDoubleSpinBox::valueChanged,
831 context: this, slot: [this](double value) { d_ptr->slotSetValue(value); });
832 connect(sender: editor, signal: &QObject::destroyed,
833 context: this, slot: [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
834 return editor;
835}
836
837/*!
838 \internal
839
840 Reimplemented from the QtAbstractEditorFactory class.
841*/
842void QtDoubleSpinBoxFactory::disconnectPropertyManager(QtDoublePropertyManager *manager)
843{
844 disconnect(sender: manager, signal: &QtDoublePropertyManager::valueChanged, receiver: this, zero: nullptr);
845 disconnect(sender: manager, signal: &QtDoublePropertyManager::rangeChanged, receiver: this, zero: nullptr);
846 disconnect(sender: manager, signal: &QtDoublePropertyManager::singleStepChanged, receiver: this, zero: nullptr);
847 disconnect(sender: manager, signal: &QtDoublePropertyManager::decimalsChanged, receiver: this, zero: nullptr);
848}
849
850// QtLineEditFactory
851
852class QtLineEditFactoryPrivate : public EditorFactoryPrivate<QLineEdit>
853{
854 QtLineEditFactory *q_ptr;
855 Q_DECLARE_PUBLIC(QtLineEditFactory)
856public:
857
858 void slotPropertyChanged(QtProperty *property, const QString &value);
859 void slotRegExpChanged(QtProperty *property, const QRegularExpression &regExp);
860 void slotSetValue(const QString &value);
861};
862
863void QtLineEditFactoryPrivate::slotPropertyChanged(QtProperty *property,
864 const QString &value)
865{
866 const auto it = m_createdEditors.constFind(key: property);
867 if (it == m_createdEditors.constEnd())
868 return;
869
870 for (QLineEdit *editor : it.value()) {
871 if (editor->text() != value)
872 editor->setText(value);
873 }
874}
875
876void QtLineEditFactoryPrivate::slotRegExpChanged(QtProperty *property,
877 const QRegularExpression &regExp)
878{
879 const auto it = m_createdEditors.constFind(key: property);
880 if (it == m_createdEditors.constEnd())
881 return;
882
883 QtStringPropertyManager *manager = q_ptr->propertyManager(property);
884 if (!manager)
885 return;
886
887 for (QLineEdit *editor : it.value()) {
888 editor->blockSignals(b: true);
889 const QValidator *oldValidator = editor->validator();
890 QValidator *newValidator = nullptr;
891 if (regExp.isValid()) {
892 newValidator = new QRegularExpressionValidator(regExp, editor);
893 }
894 editor->setValidator(newValidator);
895 if (oldValidator)
896 delete oldValidator;
897 editor->blockSignals(b: false);
898 }
899}
900
901void QtLineEditFactoryPrivate::slotSetValue(const QString &value)
902{
903 QObject *object = q_ptr->sender();
904 for (auto itEditor = m_editorToProperty.cbegin(), ecend = m_editorToProperty.cend(); itEditor != ecend; ++itEditor)
905 if (itEditor.key() == object) {
906 QtProperty *property = itEditor.value();
907 QtStringPropertyManager *manager = q_ptr->propertyManager(property);
908 if (!manager)
909 return;
910 manager->setValue(property, val: value);
911 return;
912 }
913}
914
915/*!
916 \class QtLineEditFactory
917 \internal
918 \inmodule QtDesigner
919 \since 4.4
920
921 \brief The QtLineEditFactory class provides QLineEdit widgets for
922 properties created by QtStringPropertyManager objects.
923
924 \sa QtAbstractEditorFactory, QtStringPropertyManager
925*/
926
927/*!
928 Creates a factory with the given \a parent.
929*/
930QtLineEditFactory::QtLineEditFactory(QObject *parent)
931 : QtAbstractEditorFactory<QtStringPropertyManager>(parent), d_ptr(new QtLineEditFactoryPrivate())
932{
933 d_ptr->q_ptr = this;
934
935}
936
937/*!
938 Destroys this factory, and all the widgets it has created.
939*/
940QtLineEditFactory::~QtLineEditFactory()
941{
942 qDeleteAll(c: d_ptr->m_editorToProperty.keys());
943}
944
945/*!
946 \internal
947
948 Reimplemented from the QtAbstractEditorFactory class.
949*/
950void QtLineEditFactory::connectPropertyManager(QtStringPropertyManager *manager)
951{
952 connect(sender: manager, signal: &QtStringPropertyManager::valueChanged,
953 context: this, slot: [this](QtProperty *property, const QString &value)
954 { d_ptr->slotPropertyChanged(property, value); });
955 connect(sender: manager, signal: &QtStringPropertyManager::regExpChanged,
956 context: this, slot: [this](QtProperty *property, const QRegularExpression &value)
957 { d_ptr->slotRegExpChanged(property, regExp: value); });
958}
959
960/*!
961 \internal
962
963 Reimplemented from the QtAbstractEditorFactory class.
964*/
965QWidget *QtLineEditFactory::createEditor(QtStringPropertyManager *manager,
966 QtProperty *property, QWidget *parent)
967{
968 QLineEdit *editor = d_ptr->createEditor(property, parent);
969 QRegularExpression regExp = manager->regExp(property);
970 if (regExp.isValid() && !regExp.pattern().isEmpty()) {
971 auto *validator = new QRegularExpressionValidator(regExp, editor);
972 editor->setValidator(validator);
973 }
974 editor->setText(manager->value(property));
975
976 connect(sender: editor, signal: &QLineEdit::textEdited,
977 context: this, slot: [this](const QString &value) { d_ptr->slotSetValue(value); });
978 connect(sender: editor, signal: &QObject::destroyed,
979 context: this, slot: [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
980 return editor;
981}
982
983/*!
984 \internal
985
986 Reimplemented from the QtAbstractEditorFactory class.
987*/
988void QtLineEditFactory::disconnectPropertyManager(QtStringPropertyManager *manager)
989{
990 disconnect(sender: manager, signal: &QtStringPropertyManager::valueChanged, receiver: this, zero: nullptr);
991 disconnect(sender: manager, signal: &QtStringPropertyManager::regExpChanged, receiver: this, zero: nullptr);
992}
993
994// QtDateEditFactory
995
996class QtDateEditFactoryPrivate : public EditorFactoryPrivate<QDateEdit>
997{
998 QtDateEditFactory *q_ptr;
999 Q_DECLARE_PUBLIC(QtDateEditFactory)
1000public:
1001
1002 void slotPropertyChanged(QtProperty *property, QDate value);
1003 void slotRangeChanged(QtProperty *property, QDate min, QDate max);
1004 void slotSetValue(QDate value);
1005};
1006
1007void QtDateEditFactoryPrivate::slotPropertyChanged(QtProperty *property, QDate value)
1008{
1009 const auto it = m_createdEditors.constFind(key: property);
1010 if (it == m_createdEditors.constEnd())
1011 return;
1012 for (QDateEdit *editor : it.value()) {
1013 editor->blockSignals(b: true);
1014 editor->setDate(value);
1015 editor->blockSignals(b: false);
1016 }
1017}
1018
1019void QtDateEditFactoryPrivate::slotRangeChanged(QtProperty *property, QDate min, QDate max)
1020{
1021 const auto it = m_createdEditors.constFind(key: property);
1022 if (it == m_createdEditors.constEnd())
1023 return;
1024
1025 QtDatePropertyManager *manager = q_ptr->propertyManager(property);
1026 if (!manager)
1027 return;
1028
1029 for (QDateEdit *editor : it.value()) {
1030 editor->blockSignals(b: true);
1031 editor->setDateRange(min, max);
1032 editor->setDate(manager->value(property));
1033 editor->blockSignals(b: false);
1034 }
1035}
1036
1037void QtDateEditFactoryPrivate::slotSetValue(QDate value)
1038{
1039 QObject *object = q_ptr->sender();
1040 for (auto itEditor = m_editorToProperty.cbegin(), ecend = m_editorToProperty.cend(); itEditor != ecend; ++itEditor)
1041 if (itEditor.key() == object) {
1042 QtProperty *property = itEditor.value();
1043 QtDatePropertyManager *manager = q_ptr->propertyManager(property);
1044 if (!manager)
1045 return;
1046 manager->setValue(property, val: value);
1047 return;
1048 }
1049}
1050
1051/*!
1052 \class QtDateEditFactory
1053 \internal
1054 \inmodule QtDesigner
1055 \since 4.4
1056
1057 \brief The QtDateEditFactory class provides QDateEdit widgets for
1058 properties created by QtDatePropertyManager objects.
1059
1060 \sa QtAbstractEditorFactory, QtDatePropertyManager
1061*/
1062
1063/*!
1064 Creates a factory with the given \a parent.
1065*/
1066QtDateEditFactory::QtDateEditFactory(QObject *parent)
1067 : QtAbstractEditorFactory<QtDatePropertyManager>(parent), d_ptr(new QtDateEditFactoryPrivate())
1068{
1069 d_ptr->q_ptr = this;
1070
1071}
1072
1073/*!
1074 Destroys this factory, and all the widgets it has created.
1075*/
1076QtDateEditFactory::~QtDateEditFactory()
1077{
1078 qDeleteAll(c: d_ptr->m_editorToProperty.keys());
1079}
1080
1081/*!
1082 \internal
1083
1084 Reimplemented from the QtAbstractEditorFactory class.
1085*/
1086void QtDateEditFactory::connectPropertyManager(QtDatePropertyManager *manager)
1087{
1088 connect(sender: manager, signal: &QtDatePropertyManager::valueChanged,
1089 context: this, slot: [this](QtProperty *property, const QDate &value)
1090 { d_ptr->slotPropertyChanged(property, value); });
1091 connect(sender: manager, signal: &QtDatePropertyManager::rangeChanged,
1092 context: this, slot: [this](QtProperty *property, const QDate &min, const QDate &max)
1093 { d_ptr->slotRangeChanged(property, min, max); });
1094}
1095
1096/*!
1097 \internal
1098
1099 Reimplemented from the QtAbstractEditorFactory class.
1100*/
1101QWidget *QtDateEditFactory::createEditor(QtDatePropertyManager *manager, QtProperty *property,
1102 QWidget *parent)
1103{
1104 QDateEdit *editor = d_ptr->createEditor(property, parent);
1105 editor->setDisplayFormat(QtPropertyBrowserUtils::dateFormat());
1106 editor->setCalendarPopup(true);
1107 editor->setDateRange(min: manager->minimum(property), max: manager->maximum(property));
1108 editor->setDate(manager->value(property));
1109
1110 connect(sender: editor, signal: &QDateEdit::dateChanged,
1111 context: this, slot: [this](const QDate &value) { d_ptr->slotSetValue(value); });
1112 connect(sender: editor, signal: &QObject::destroyed,
1113 context: this, slot: [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
1114 return editor;
1115}
1116
1117/*!
1118 \internal
1119
1120 Reimplemented from the QtAbstractEditorFactory class.
1121*/
1122void QtDateEditFactory::disconnectPropertyManager(QtDatePropertyManager *manager)
1123{
1124 disconnect(sender: manager, signal: &QtDatePropertyManager::valueChanged, receiver: this, zero: nullptr);
1125 disconnect(sender: manager, signal: &QtDatePropertyManager::rangeChanged, receiver: this, zero: nullptr);
1126}
1127
1128// QtTimeEditFactory
1129
1130class QtTimeEditFactoryPrivate : public EditorFactoryPrivate<QTimeEdit>
1131{
1132 QtTimeEditFactory *q_ptr;
1133 Q_DECLARE_PUBLIC(QtTimeEditFactory)
1134public:
1135
1136 void slotPropertyChanged(QtProperty *property, QTime value);
1137 void slotSetValue(QTime value);
1138};
1139
1140void QtTimeEditFactoryPrivate::slotPropertyChanged(QtProperty *property, QTime value)
1141{
1142 const auto it = m_createdEditors.constFind(key: property);
1143 if (it == m_createdEditors.constEnd())
1144 return;
1145 for (QTimeEdit *editor : it.value()) {
1146 editor->blockSignals(b: true);
1147 editor->setTime(value);
1148 editor->blockSignals(b: false);
1149 }
1150}
1151
1152void QtTimeEditFactoryPrivate::slotSetValue(QTime value)
1153{
1154 QObject *object = q_ptr->sender();
1155 for (auto itEditor = m_editorToProperty.cbegin(), ecend = m_editorToProperty.cend(); itEditor != ecend; ++itEditor)
1156 if (itEditor.key() == object) {
1157 QtProperty *property = itEditor.value();
1158 QtTimePropertyManager *manager = q_ptr->propertyManager(property);
1159 if (!manager)
1160 return;
1161 manager->setValue(property, val: value);
1162 return;
1163 }
1164}
1165
1166/*!
1167 \class QtTimeEditFactory
1168 \internal
1169 \inmodule QtDesigner
1170 \since 4.4
1171
1172 \brief The QtTimeEditFactory class provides QTimeEdit widgets for
1173 properties created by QtTimePropertyManager objects.
1174
1175 \sa QtAbstractEditorFactory, QtTimePropertyManager
1176*/
1177
1178/*!
1179 Creates a factory with the given \a parent.
1180*/
1181QtTimeEditFactory::QtTimeEditFactory(QObject *parent)
1182 : QtAbstractEditorFactory<QtTimePropertyManager>(parent), d_ptr(new QtTimeEditFactoryPrivate())
1183{
1184 d_ptr->q_ptr = this;
1185
1186}
1187
1188/*!
1189 Destroys this factory, and all the widgets it has created.
1190*/
1191QtTimeEditFactory::~QtTimeEditFactory()
1192{
1193 qDeleteAll(c: d_ptr->m_editorToProperty.keys());
1194}
1195
1196/*!
1197 \internal
1198
1199 Reimplemented from the QtAbstractEditorFactory class.
1200*/
1201void QtTimeEditFactory::connectPropertyManager(QtTimePropertyManager *manager)
1202{
1203 connect(sender: manager, signal: &QtTimePropertyManager::valueChanged,
1204 context: this, slot: [this](QtProperty *property, const QTime &value)
1205 { d_ptr->slotPropertyChanged(property, value); });
1206}
1207
1208/*!
1209 \internal
1210
1211 Reimplemented from the QtAbstractEditorFactory class.
1212*/
1213QWidget *QtTimeEditFactory::createEditor(QtTimePropertyManager *manager, QtProperty *property,
1214 QWidget *parent)
1215{
1216 QTimeEdit *editor = d_ptr->createEditor(property, parent);
1217 editor->setDisplayFormat(QtPropertyBrowserUtils::timeFormat());
1218 editor->setTime(manager->value(property));
1219
1220 connect(sender: editor, signal: &QTimeEdit::timeChanged,
1221 context: this, slot: [this](const QTime &value) { d_ptr->slotSetValue(value); });
1222 connect(sender: editor, signal: &QObject::destroyed,
1223 context: this, slot: [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
1224 return editor;
1225}
1226
1227/*!
1228 \internal
1229
1230 Reimplemented from the QtAbstractEditorFactory class.
1231*/
1232void QtTimeEditFactory::disconnectPropertyManager(QtTimePropertyManager *manager)
1233{
1234 disconnect(sender: manager, signal: &QtTimePropertyManager::valueChanged, receiver: this, zero: nullptr);
1235}
1236
1237// QtDateTimeEditFactory
1238
1239class QtDateTimeEditFactoryPrivate : public EditorFactoryPrivate<QDateTimeEdit>
1240{
1241 QtDateTimeEditFactory *q_ptr;
1242 Q_DECLARE_PUBLIC(QtDateTimeEditFactory)
1243public:
1244
1245 void slotPropertyChanged(QtProperty *property, const QDateTime &value);
1246 void slotSetValue(const QDateTime &value);
1247
1248};
1249
1250void QtDateTimeEditFactoryPrivate::slotPropertyChanged(QtProperty *property,
1251 const QDateTime &value)
1252{
1253 const auto it = m_createdEditors.constFind(key: property);
1254 if (it == m_createdEditors.constEnd())
1255 return;
1256
1257 for (QDateTimeEdit *editor : it.value()) {
1258 editor->blockSignals(b: true);
1259 editor->setDateTime(value);
1260 editor->blockSignals(b: false);
1261 }
1262}
1263
1264void QtDateTimeEditFactoryPrivate::slotSetValue(const QDateTime &value)
1265{
1266 QObject *object = q_ptr->sender();
1267 for (auto itEditor = m_editorToProperty.cbegin(), ecend = m_editorToProperty.cend(); itEditor != ecend; ++itEditor)
1268 if (itEditor.key() == object) {
1269 QtProperty *property = itEditor.value();
1270 QtDateTimePropertyManager *manager = q_ptr->propertyManager(property);
1271 if (!manager)
1272 return;
1273 manager->setValue(property, val: value);
1274 return;
1275 }
1276}
1277
1278/*!
1279 \class QtDateTimeEditFactory
1280 \internal
1281 \inmodule QtDesigner
1282 \since 4.4
1283
1284 \brief The QtDateTimeEditFactory class provides QDateTimeEdit
1285 widgets for properties created by QtDateTimePropertyManager objects.
1286
1287 \sa QtAbstractEditorFactory, QtDateTimePropertyManager
1288*/
1289
1290/*!
1291 Creates a factory with the given \a parent.
1292*/
1293QtDateTimeEditFactory::QtDateTimeEditFactory(QObject *parent)
1294 : QtAbstractEditorFactory<QtDateTimePropertyManager>(parent), d_ptr(new QtDateTimeEditFactoryPrivate())
1295{
1296 d_ptr->q_ptr = this;
1297
1298}
1299
1300/*!
1301 Destroys this factory, and all the widgets it has created.
1302*/
1303QtDateTimeEditFactory::~QtDateTimeEditFactory()
1304{
1305 qDeleteAll(c: d_ptr->m_editorToProperty.keys());
1306}
1307
1308/*!
1309 \internal
1310
1311 Reimplemented from the QtAbstractEditorFactory class.
1312*/
1313void QtDateTimeEditFactory::connectPropertyManager(QtDateTimePropertyManager *manager)
1314{
1315 connect(sender: manager, signal: &QtDateTimePropertyManager::valueChanged,
1316 context: this, slot: [this](QtProperty *property, const QDateTime &value)
1317 { d_ptr->slotPropertyChanged(property, value); });
1318}
1319
1320/*!
1321 \internal
1322
1323 Reimplemented from the QtAbstractEditorFactory class.
1324*/
1325QWidget *QtDateTimeEditFactory::createEditor(QtDateTimePropertyManager *manager,
1326 QtProperty *property, QWidget *parent)
1327{
1328 QDateTimeEdit *editor = d_ptr->createEditor(property, parent);
1329 editor->setDisplayFormat(QtPropertyBrowserUtils::dateTimeFormat());
1330 editor->setDateTime(manager->value(property));
1331
1332 connect(sender: editor, signal: &QDateTimeEdit::dateTimeChanged,
1333 context: this, slot: [this](const QDateTime &value) { d_ptr->slotSetValue(value); });
1334 connect(sender: editor, signal: &QObject::destroyed,
1335 context: this, slot: [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
1336 return editor;
1337}
1338
1339/*!
1340 \internal
1341
1342 Reimplemented from the QtAbstractEditorFactory class.
1343*/
1344void QtDateTimeEditFactory::disconnectPropertyManager(QtDateTimePropertyManager *manager)
1345{
1346 disconnect(sender: manager, signal: &QtDateTimePropertyManager::valueChanged, receiver: this, zero: nullptr);
1347}
1348
1349// QtKeySequenceEditorFactory
1350
1351class QtKeySequenceEditorFactoryPrivate : public EditorFactoryPrivate<QKeySequenceEdit>
1352{
1353 QtKeySequenceEditorFactory *q_ptr;
1354 Q_DECLARE_PUBLIC(QtKeySequenceEditorFactory)
1355public:
1356
1357 void slotPropertyChanged(QtProperty *property, const QKeySequence &value);
1358 void slotSetValue(const QKeySequence &value);
1359};
1360
1361void QtKeySequenceEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
1362 const QKeySequence &value)
1363{
1364 const auto it = m_createdEditors.constFind(key: property);
1365 if (it == m_createdEditors.constEnd())
1366 return;
1367
1368 for (QKeySequenceEdit *editor : it.value()) {
1369 editor->blockSignals(b: true);
1370 editor->setKeySequence(value);
1371 editor->blockSignals(b: false);
1372 }
1373}
1374
1375void QtKeySequenceEditorFactoryPrivate::slotSetValue(const QKeySequence &value)
1376{
1377 QObject *object = q_ptr->sender();
1378 for (auto itEditor = m_editorToProperty.cbegin(), ecend = m_editorToProperty.cend(); itEditor != ecend; ++itEditor)
1379 if (itEditor.key() == object) {
1380 QtProperty *property = itEditor.value();
1381 QtKeySequencePropertyManager *manager = q_ptr->propertyManager(property);
1382 if (!manager)
1383 return;
1384 manager->setValue(property, val: value);
1385 return;
1386 }
1387}
1388
1389/*!
1390 \class QtKeySequenceEditorFactory
1391 \internal
1392 \inmodule QtDesigner
1393 \since 4.4
1394
1395 \brief The QtKeySequenceEditorFactory class provides editor
1396 widgets for properties created by QtKeySequencePropertyManager objects.
1397
1398 \sa QtAbstractEditorFactory
1399*/
1400
1401/*!
1402 Creates a factory with the given \a parent.
1403*/
1404QtKeySequenceEditorFactory::QtKeySequenceEditorFactory(QObject *parent)
1405 : QtAbstractEditorFactory<QtKeySequencePropertyManager>(parent), d_ptr(new QtKeySequenceEditorFactoryPrivate())
1406{
1407 d_ptr->q_ptr = this;
1408
1409}
1410
1411/*!
1412 Destroys this factory, and all the widgets it has created.
1413*/
1414QtKeySequenceEditorFactory::~QtKeySequenceEditorFactory()
1415{
1416 qDeleteAll(c: d_ptr->m_editorToProperty.keys());
1417}
1418
1419/*!
1420 \internal
1421
1422 Reimplemented from the QtAbstractEditorFactory class.
1423*/
1424void QtKeySequenceEditorFactory::connectPropertyManager(QtKeySequencePropertyManager *manager)
1425{
1426 connect(sender: manager, signal: &QtKeySequencePropertyManager::valueChanged,
1427 context: this, slot: [this](QtProperty *property, const QKeySequence &value)
1428 { d_ptr->slotPropertyChanged(property, value); });
1429}
1430
1431/*!
1432 \internal
1433
1434 Reimplemented from the QtAbstractEditorFactory class.
1435*/
1436QWidget *QtKeySequenceEditorFactory::createEditor(QtKeySequencePropertyManager *manager,
1437 QtProperty *property, QWidget *parent)
1438{
1439 QKeySequenceEdit *editor = d_ptr->createEditor(property, parent);
1440 editor->setKeySequence(manager->value(property));
1441
1442 connect(sender: editor, signal: &QKeySequenceEdit::keySequenceChanged,
1443 context: this, slot: [this](const QKeySequence &value) { d_ptr->slotSetValue(value); });
1444 connect(sender: editor, signal: &QObject::destroyed,
1445 context: this, slot: [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
1446 return editor;
1447}
1448
1449/*!
1450 \internal
1451
1452 Reimplemented from the QtAbstractEditorFactory class.
1453*/
1454void QtKeySequenceEditorFactory::disconnectPropertyManager(QtKeySequencePropertyManager *manager)
1455{
1456 disconnect(sender: manager, signal: &QtKeySequencePropertyManager::valueChanged, receiver: this, zero: nullptr);
1457}
1458
1459// QtCharEdit
1460
1461class QtCharEdit : public QWidget
1462{
1463 Q_OBJECT
1464public:
1465 QtCharEdit(QWidget *parent = 0);
1466
1467 QChar value() const;
1468 bool eventFilter(QObject *o, QEvent *e) override;
1469public Q_SLOTS:
1470 void setValue(const QChar &value);
1471Q_SIGNALS:
1472 void valueChanged(const QChar &value);
1473protected:
1474 void focusInEvent(QFocusEvent *e) override;
1475 void focusOutEvent(QFocusEvent *e) override;
1476 void keyPressEvent(QKeyEvent *e) override;
1477 void keyReleaseEvent(QKeyEvent *e) override;
1478 bool event(QEvent *e) override;
1479private slots:
1480 void slotClearChar();
1481private:
1482 void handleKeyEvent(QKeyEvent *e);
1483
1484 QChar m_value;
1485 QLineEdit *m_lineEdit;
1486};
1487
1488QtCharEdit::QtCharEdit(QWidget *parent)
1489 : QWidget(parent), m_lineEdit(new QLineEdit(this))
1490{
1491 auto *layout = new QHBoxLayout(this);
1492 layout->addWidget(m_lineEdit);
1493 layout->setContentsMargins(QMargins());
1494 m_lineEdit->installEventFilter(filterObj: this);
1495 m_lineEdit->setReadOnly(true);
1496 m_lineEdit->setFocusProxy(this);
1497 setFocusPolicy(m_lineEdit->focusPolicy());
1498 setAttribute(Qt::WA_InputMethodEnabled);
1499}
1500
1501bool QtCharEdit::eventFilter(QObject *o, QEvent *e)
1502{
1503 if (o == m_lineEdit && e->type() == QEvent::ContextMenu) {
1504 QContextMenuEvent *c = static_cast<QContextMenuEvent *>(e);
1505 QMenu *menu = m_lineEdit->createStandardContextMenu();
1506 const auto actions = menu->actions();
1507 for (QAction *action : actions) {
1508 action->setShortcut(QKeySequence());
1509 QString actionString = action->text();
1510 const int pos = actionString.lastIndexOf(c: QLatin1Char('\t'));
1511 if (pos > 0)
1512 actionString = actionString.remove(i: pos, len: actionString.size() - pos);
1513 action->setText(actionString);
1514 }
1515 QAction *actionBefore = nullptr;
1516 if (actions.size() > 0)
1517 actionBefore = actions[0];
1518 auto *clearAction = new QAction(tr(s: "Clear Char"), menu);
1519 menu->insertAction(before: actionBefore, action: clearAction);
1520 menu->insertSeparator(before: actionBefore);
1521 clearAction->setEnabled(!m_value.isNull());
1522 connect(sender: clearAction, signal: &QAction::triggered, context: this, slot: &QtCharEdit::slotClearChar);
1523 menu->exec(pos: c->globalPos());
1524 delete menu;
1525 e->accept();
1526 return true;
1527 }
1528
1529 return QWidget::eventFilter(watched: o, event: e);
1530}
1531
1532void QtCharEdit::slotClearChar()
1533{
1534 if (m_value.isNull())
1535 return;
1536 setValue(QChar());
1537 emit valueChanged(value: m_value);
1538}
1539
1540void QtCharEdit::handleKeyEvent(QKeyEvent *e)
1541{
1542 const int key = e->key();
1543 switch (key) {
1544 case Qt::Key_Control:
1545 case Qt::Key_Shift:
1546 case Qt::Key_Meta:
1547 case Qt::Key_Alt:
1548 case Qt::Key_Super_L:
1549 case Qt::Key_Return:
1550 return;
1551 default:
1552 break;
1553 }
1554
1555 const QString text = e->text();
1556 if (text.size() != 1)
1557 return;
1558
1559 const QChar c = text.at(i: 0);
1560 if (!c.isPrint())
1561 return;
1562
1563 if (m_value == c)
1564 return;
1565
1566 m_value = c;
1567 const QString str = m_value.isNull() ? QString() : QString(m_value);
1568 m_lineEdit->setText(str);
1569 e->accept();
1570 emit valueChanged(value: m_value);
1571}
1572
1573void QtCharEdit::setValue(const QChar &value)
1574{
1575 if (value == m_value)
1576 return;
1577
1578 m_value = value;
1579 QString str = value.isNull() ? QString() : QString(value);
1580 m_lineEdit->setText(str);
1581}
1582
1583QChar QtCharEdit::value() const
1584{
1585 return m_value;
1586}
1587
1588void QtCharEdit::focusInEvent(QFocusEvent *e)
1589{
1590 m_lineEdit->event(e);
1591 m_lineEdit->selectAll();
1592 QWidget::focusInEvent(event: e);
1593}
1594
1595void QtCharEdit::focusOutEvent(QFocusEvent *e)
1596{
1597 m_lineEdit->event(e);
1598 QWidget::focusOutEvent(event: e);
1599}
1600
1601void QtCharEdit::keyPressEvent(QKeyEvent *e)
1602{
1603 handleKeyEvent(e);
1604 e->accept();
1605}
1606
1607void QtCharEdit::keyReleaseEvent(QKeyEvent *e)
1608{
1609 m_lineEdit->event(e);
1610}
1611
1612bool QtCharEdit::event(QEvent *e)
1613{
1614 switch(e->type()) {
1615 case QEvent::Shortcut:
1616 case QEvent::ShortcutOverride:
1617 case QEvent::KeyRelease:
1618 e->accept();
1619 return true;
1620 default:
1621 break;
1622 }
1623 return QWidget::event(event: e);
1624}
1625
1626// QtCharEditorFactory
1627
1628class QtCharEditorFactoryPrivate : public EditorFactoryPrivate<QtCharEdit>
1629{
1630 QtCharEditorFactory *q_ptr;
1631 Q_DECLARE_PUBLIC(QtCharEditorFactory)
1632public:
1633
1634 void slotPropertyChanged(QtProperty *property, const QChar &value);
1635 void slotSetValue(const QChar &value);
1636
1637};
1638
1639void QtCharEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
1640 const QChar &value)
1641{
1642 const auto it = m_createdEditors.constFind(key: property);
1643 if (it == m_createdEditors.constEnd())
1644 return;
1645
1646 for (QtCharEdit *editor : it.value()) {
1647 editor->blockSignals(b: true);
1648 editor->setValue(value);
1649 editor->blockSignals(b: false);
1650 }
1651}
1652
1653void QtCharEditorFactoryPrivate::slotSetValue(const QChar &value)
1654{
1655 QObject *object = q_ptr->sender();
1656 for (auto itEditor = m_editorToProperty.cbegin(), ecend = m_editorToProperty.cend(); itEditor != ecend; ++itEditor)
1657 if (itEditor.key() == object) {
1658 QtProperty *property = itEditor.value();
1659 QtCharPropertyManager *manager = q_ptr->propertyManager(property);
1660 if (!manager)
1661 return;
1662 manager->setValue(property, val: value);
1663 return;
1664 }
1665}
1666
1667/*!
1668 \class QtCharEditorFactory
1669 \internal
1670 \inmodule QtDesigner
1671 \since 4.4
1672
1673 \brief The QtCharEditorFactory class provides editor
1674 widgets for properties created by QtCharPropertyManager objects.
1675
1676 \sa QtAbstractEditorFactory
1677*/
1678
1679/*!
1680 Creates a factory with the given \a parent.
1681*/
1682QtCharEditorFactory::QtCharEditorFactory(QObject *parent)
1683 : QtAbstractEditorFactory<QtCharPropertyManager>(parent), d_ptr(new QtCharEditorFactoryPrivate())
1684{
1685 d_ptr->q_ptr = this;
1686
1687}
1688
1689/*!
1690 Destroys this factory, and all the widgets it has created.
1691*/
1692QtCharEditorFactory::~QtCharEditorFactory()
1693{
1694 qDeleteAll(c: d_ptr->m_editorToProperty.keys());
1695}
1696
1697/*!
1698 \internal
1699
1700 Reimplemented from the QtAbstractEditorFactory class.
1701*/
1702void QtCharEditorFactory::connectPropertyManager(QtCharPropertyManager *manager)
1703{
1704 connect(sender: manager, signal: &QtCharPropertyManager::valueChanged,
1705 context: this, slot: [this](QtProperty *property, const QChar &value)
1706 { d_ptr->slotPropertyChanged(property, value); });
1707}
1708
1709/*!
1710 \internal
1711
1712 Reimplemented from the QtAbstractEditorFactory class.
1713*/
1714QWidget *QtCharEditorFactory::createEditor(QtCharPropertyManager *manager,
1715 QtProperty *property, QWidget *parent)
1716{
1717 QtCharEdit *editor = d_ptr->createEditor(property, parent);
1718 editor->setValue(manager->value(property));
1719
1720 connect(sender: editor, signal: &QtCharEdit::valueChanged,
1721 context: this, slot: [this](const QChar &value) { d_ptr->slotSetValue(value); });
1722 connect(sender: editor, signal: &QObject::destroyed,
1723 context: this, slot: [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
1724 return editor;
1725}
1726
1727/*!
1728 \internal
1729
1730 Reimplemented from the QtAbstractEditorFactory class.
1731*/
1732void QtCharEditorFactory::disconnectPropertyManager(QtCharPropertyManager *manager)
1733{
1734 disconnect(sender: manager, signal: &QtCharPropertyManager::valueChanged, receiver: this, zero: nullptr);
1735}
1736
1737// QtEnumEditorFactory
1738
1739class QtEnumEditorFactoryPrivate : public EditorFactoryPrivate<QComboBox>
1740{
1741 QtEnumEditorFactory *q_ptr;
1742 Q_DECLARE_PUBLIC(QtEnumEditorFactory)
1743public:
1744
1745 void slotPropertyChanged(QtProperty *property, int value);
1746 void slotEnumNamesChanged(QtProperty *property, const QStringList &);
1747 void slotEnumIconsChanged(QtProperty *property, const QMap<int, QIcon> &);
1748 void slotSetValue(int value);
1749};
1750
1751void QtEnumEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
1752{
1753 const auto it = m_createdEditors.constFind(key: property);
1754 if (it == m_createdEditors.constEnd())
1755 return;
1756
1757 for (QComboBox *editor : it.value()) {
1758 editor->blockSignals(b: true);
1759 editor->setCurrentIndex(value);
1760 editor->blockSignals(b: false);
1761 }
1762}
1763
1764void QtEnumEditorFactoryPrivate::slotEnumNamesChanged(QtProperty *property,
1765 const QStringList &enumNames)
1766{
1767 const auto it = m_createdEditors.constFind(key: property);
1768 if (it == m_createdEditors.constEnd())
1769 return;
1770
1771 QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
1772 if (!manager)
1773 return;
1774
1775 QMap<int, QIcon> enumIcons = manager->enumIcons(property);
1776
1777 for (QComboBox *editor : it.value()) {
1778 editor->blockSignals(b: true);
1779 editor->clear();
1780 editor->addItems(texts: enumNames);
1781 const int nameCount = enumNames.size();
1782 for (int i = 0; i < nameCount; i++)
1783 editor->setItemIcon(index: i, icon: enumIcons.value(key: i));
1784 editor->setCurrentIndex(manager->value(property));
1785 editor->blockSignals(b: false);
1786 }
1787}
1788
1789void QtEnumEditorFactoryPrivate::slotEnumIconsChanged(QtProperty *property,
1790 const QMap<int, QIcon> &enumIcons)
1791{
1792 const auto it = m_createdEditors.constFind(key: property);
1793 if (it == m_createdEditors.constEnd())
1794 return;
1795
1796 QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
1797 if (!manager)
1798 return;
1799
1800 const QStringList enumNames = manager->enumNames(property);
1801 for (QComboBox *editor : it.value()) {
1802 editor->blockSignals(b: true);
1803 const int nameCount = enumNames.size();
1804 for (int i = 0; i < nameCount; i++)
1805 editor->setItemIcon(index: i, icon: enumIcons.value(key: i));
1806 editor->setCurrentIndex(manager->value(property));
1807 editor->blockSignals(b: false);
1808 }
1809}
1810
1811void QtEnumEditorFactoryPrivate::slotSetValue(int value)
1812{
1813 QObject *object = q_ptr->sender();
1814 for (auto itEditor = m_editorToProperty.cbegin(), ecend = m_editorToProperty.cend(); itEditor != ecend; ++itEditor)
1815 if (itEditor.key() == object) {
1816 QtProperty *property = itEditor.value();
1817 QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
1818 if (!manager)
1819 return;
1820 manager->setValue(property, val: value);
1821 return;
1822 }
1823}
1824
1825/*!
1826 \class QtEnumEditorFactory
1827 \internal
1828 \inmodule QtDesigner
1829 \since 4.4
1830
1831 \brief The QtEnumEditorFactory class provides QComboBox widgets for
1832 properties created by QtEnumPropertyManager objects.
1833
1834 \sa QtAbstractEditorFactory, QtEnumPropertyManager
1835*/
1836
1837/*!
1838 Creates a factory with the given \a parent.
1839*/
1840QtEnumEditorFactory::QtEnumEditorFactory(QObject *parent)
1841 : QtAbstractEditorFactory<QtEnumPropertyManager>(parent), d_ptr(new QtEnumEditorFactoryPrivate())
1842{
1843 d_ptr->q_ptr = this;
1844
1845}
1846
1847/*!
1848 Destroys this factory, and all the widgets it has created.
1849*/
1850QtEnumEditorFactory::~QtEnumEditorFactory()
1851{
1852 qDeleteAll(c: d_ptr->m_editorToProperty.keys());
1853}
1854
1855/*!
1856 \internal
1857
1858 Reimplemented from the QtAbstractEditorFactory class.
1859*/
1860void QtEnumEditorFactory::connectPropertyManager(QtEnumPropertyManager *manager)
1861{
1862 connect(sender: manager, signal: &QtEnumPropertyManager::valueChanged,
1863 context: this, slot: [this](QtProperty *property, int value)
1864 { d_ptr->slotPropertyChanged(property, value); });
1865 connect(sender: manager, signal: &QtEnumPropertyManager::enumNamesChanged,
1866 context: this, slot: [this](QtProperty *property, const QStringList &value)
1867 { d_ptr->slotEnumNamesChanged(property, enumNames: value); });
1868}
1869
1870/*!
1871 \internal
1872
1873 Reimplemented from the QtAbstractEditorFactory class.
1874*/
1875QWidget *QtEnumEditorFactory::createEditor(QtEnumPropertyManager *manager, QtProperty *property,
1876 QWidget *parent)
1877{
1878 QComboBox *editor = d_ptr->createEditor(property, parent);
1879 editor->setSizePolicy(hor: QSizePolicy::Ignored, ver: QSizePolicy::Fixed);
1880 editor->view()->setTextElideMode(Qt::ElideRight);
1881 QStringList enumNames = manager->enumNames(property);
1882 editor->addItems(texts: enumNames);
1883 QMap<int, QIcon> enumIcons = manager->enumIcons(property);
1884 const int enumNamesCount = enumNames.size();
1885 for (int i = 0; i < enumNamesCount; i++)
1886 editor->setItemIcon(index: i, icon: enumIcons.value(key: i));
1887 editor->setCurrentIndex(manager->value(property));
1888
1889 connect(sender: editor, signal: &QComboBox::currentIndexChanged,
1890 context: this, slot: [this](int value) { d_ptr->slotSetValue(value); });
1891 connect(sender: editor, signal: &QObject::destroyed,
1892 context: this, slot: [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
1893 return editor;
1894}
1895
1896/*!
1897 \internal
1898
1899 Reimplemented from the QtAbstractEditorFactory class.
1900*/
1901void QtEnumEditorFactory::disconnectPropertyManager(QtEnumPropertyManager *manager)
1902{
1903 disconnect(sender: manager, signal: &QtEnumPropertyManager::valueChanged, receiver: this, zero: nullptr);
1904 disconnect(sender: manager, signal: &QtEnumPropertyManager::enumNamesChanged, receiver: this, zero: nullptr);
1905}
1906
1907// QtCursorEditorFactory
1908
1909class QtCursorEditorFactoryPrivate
1910{
1911 QtCursorEditorFactory *q_ptr;
1912 Q_DECLARE_PUBLIC(QtCursorEditorFactory)
1913public:
1914 QtCursorEditorFactoryPrivate();
1915
1916 void slotPropertyChanged(QtProperty *property, const QCursor &cursor);
1917 void slotEnumChanged(QtProperty *property, int value);
1918 void slotEditorDestroyed(QObject *object);
1919
1920 QtEnumEditorFactory *m_enumEditorFactory;
1921 QtEnumPropertyManager *m_enumPropertyManager;
1922
1923 QHash<QtProperty *, QtProperty *> m_propertyToEnum;
1924 QHash<QtProperty *, QtProperty *> m_enumToProperty;
1925 QHash<QtProperty *, QWidgetList > m_enumToEditors;
1926 QHash<QWidget *, QtProperty *> m_editorToEnum;
1927 bool m_updatingEnum;
1928};
1929
1930QtCursorEditorFactoryPrivate::QtCursorEditorFactoryPrivate()
1931 : m_updatingEnum(false)
1932{
1933
1934}
1935
1936void QtCursorEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, const QCursor &cursor)
1937{
1938 // update enum property
1939 QtProperty *enumProp = m_propertyToEnum.value(key: property);
1940 if (!enumProp)
1941 return;
1942
1943 m_updatingEnum = true;
1944 auto *cdb = QtCursorDatabase::instance();
1945 m_enumPropertyManager->setValue(property: enumProp, val: cdb->cursorToValue(cursor));
1946 m_updatingEnum = false;
1947}
1948
1949void QtCursorEditorFactoryPrivate::slotEnumChanged(QtProperty *property, int value)
1950{
1951 if (m_updatingEnum)
1952 return;
1953 // update cursor property
1954 QtProperty *prop = m_enumToProperty.value(key: property);
1955 if (!prop)
1956 return;
1957 QtCursorPropertyManager *cursorManager = q_ptr->propertyManager(property: prop);
1958 if (!cursorManager)
1959 return;
1960#ifndef QT_NO_CURSOR
1961 auto *cdb = QtCursorDatabase::instance();
1962 cursorManager->setValue(property: prop, val: QCursor(cdb->valueToCursor(value)));
1963#endif
1964}
1965
1966void QtCursorEditorFactoryPrivate::slotEditorDestroyed(QObject *object)
1967{
1968 // remove from m_editorToEnum map;
1969 // remove from m_enumToEditors map;
1970 // if m_enumToEditors doesn't contains more editors delete enum property;
1971 for (auto itEditor = m_editorToEnum.cbegin(), ecend = m_editorToEnum.cend(); itEditor != ecend; ++itEditor)
1972 if (itEditor.key() == object) {
1973 QWidget *editor = itEditor.key();
1974 QtProperty *enumProp = itEditor.value();
1975 m_editorToEnum.remove(key: editor);
1976 m_enumToEditors[enumProp].removeAll(t: editor);
1977 if (m_enumToEditors[enumProp].isEmpty()) {
1978 m_enumToEditors.remove(key: enumProp);
1979 QtProperty *property = m_enumToProperty.value(key: enumProp);
1980 m_enumToProperty.remove(key: enumProp);
1981 m_propertyToEnum.remove(key: property);
1982 delete enumProp;
1983 }
1984 return;
1985 }
1986}
1987
1988/*!
1989 \class QtCursorEditorFactory
1990 \internal
1991 \inmodule QtDesigner
1992 \since 4.4
1993
1994 \brief The QtCursorEditorFactory class provides QComboBox widgets for
1995 properties created by QtCursorPropertyManager objects.
1996
1997 \sa QtAbstractEditorFactory, QtCursorPropertyManager
1998*/
1999
2000/*!
2001 Creates a factory with the given \a parent.
2002*/
2003QtCursorEditorFactory::QtCursorEditorFactory(QObject *parent)
2004 : QtAbstractEditorFactory<QtCursorPropertyManager>(parent), d_ptr(new QtCursorEditorFactoryPrivate())
2005{
2006 d_ptr->q_ptr = this;
2007
2008 d_ptr->m_enumEditorFactory = new QtEnumEditorFactory(this);
2009 d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this);
2010 connect(sender: d_ptr->m_enumPropertyManager, signal: &QtEnumPropertyManager::valueChanged,
2011 context: this, slot: [this](QtProperty *property, int value)
2012 { d_ptr->slotEnumChanged(property, value); });
2013 d_ptr->m_enumEditorFactory->addPropertyManager(manager: d_ptr->m_enumPropertyManager);
2014}
2015
2016/*!
2017 Destroys this factory, and all the widgets it has created.
2018*/
2019QtCursorEditorFactory::~QtCursorEditorFactory()
2020{
2021}
2022
2023/*!
2024 \internal
2025
2026 Reimplemented from the QtAbstractEditorFactory class.
2027*/
2028void QtCursorEditorFactory::connectPropertyManager(QtCursorPropertyManager *manager)
2029{
2030 connect(sender: manager, signal: &QtCursorPropertyManager::valueChanged,
2031 context: this, slot: [this](QtProperty *property, const QCursor &value)
2032 { d_ptr->slotPropertyChanged(property, cursor: value); });
2033}
2034
2035/*!
2036 \internal
2037
2038 Reimplemented from the QtAbstractEditorFactory class.
2039*/
2040QWidget *QtCursorEditorFactory::createEditor(QtCursorPropertyManager *manager, QtProperty *property,
2041 QWidget *parent)
2042{
2043 QtProperty *enumProp = nullptr;
2044 if (d_ptr->m_propertyToEnum.contains(key: property)) {
2045 enumProp = d_ptr->m_propertyToEnum[property];
2046 } else {
2047 enumProp = d_ptr->m_enumPropertyManager->addProperty(name: property->propertyName());
2048 auto *cdb = QtCursorDatabase::instance();
2049 d_ptr->m_enumPropertyManager->setEnumNames(property: enumProp, names: cdb->cursorShapeNames());
2050 d_ptr->m_enumPropertyManager->setEnumIcons(property: enumProp, icons: cdb->cursorShapeIcons());
2051#ifndef QT_NO_CURSOR
2052 d_ptr->m_enumPropertyManager->setValue(property: enumProp, val: cdb->cursorToValue(cursor: manager->value(property)));
2053#endif
2054 d_ptr->m_propertyToEnum[property] = enumProp;
2055 d_ptr->m_enumToProperty[enumProp] = property;
2056 }
2057 QtAbstractEditorFactoryBase *af = d_ptr->m_enumEditorFactory;
2058 QWidget *editor = af->createEditor(property: enumProp, parent);
2059 d_ptr->m_enumToEditors[enumProp].append(t: editor);
2060 d_ptr->m_editorToEnum[editor] = enumProp;
2061 connect(sender: editor, signal: &QObject::destroyed,
2062 context: this, slot: [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
2063 return editor;
2064}
2065
2066/*!
2067 \internal
2068
2069 Reimplemented from the QtAbstractEditorFactory class.
2070*/
2071void QtCursorEditorFactory::disconnectPropertyManager(QtCursorPropertyManager *manager)
2072{
2073 disconnect(sender: manager, signal: &QtCursorPropertyManager::valueChanged, receiver: this, zero: nullptr);
2074}
2075
2076// QtColorEditWidget
2077
2078class QtColorEditWidget : public QWidget {
2079 Q_OBJECT
2080
2081public:
2082 QtColorEditWidget(QWidget *parent);
2083
2084 bool eventFilter(QObject *obj, QEvent *ev) override;
2085
2086public Q_SLOTS:
2087 void setValue(const QColor &value);
2088
2089private Q_SLOTS:
2090 void buttonClicked();
2091
2092Q_SIGNALS:
2093 void valueChanged(const QColor &value);
2094
2095private:
2096 QColor m_color;
2097 QLabel *m_pixmapLabel;
2098 QLabel *m_label;
2099 QToolButton *m_button;
2100};
2101
2102QtColorEditWidget::QtColorEditWidget(QWidget *parent) :
2103 QWidget(parent),
2104 m_pixmapLabel(new QLabel),
2105 m_label(new QLabel),
2106 m_button(new QToolButton)
2107{
2108 auto *lt = new QHBoxLayout(this);
2109 setupTreeViewEditorMargin(lt);
2110 lt->setSpacing(0);
2111 lt->addWidget(m_pixmapLabel);
2112 lt->addWidget(m_label);
2113 lt->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
2114
2115 m_button->setSizePolicy(hor: QSizePolicy::Fixed, ver: QSizePolicy::Ignored);
2116 m_button->setFixedWidth(20);
2117 setFocusProxy(m_button);
2118 setFocusPolicy(m_button->focusPolicy());
2119 m_button->setText(tr(s: "..."));
2120 m_button->installEventFilter(filterObj: this);
2121 connect(sender: m_button, signal: &QAbstractButton::clicked, context: this, slot: &QtColorEditWidget::buttonClicked);
2122 lt->addWidget(m_button);
2123 m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::brushValuePixmap(b: QBrush(m_color)));
2124 m_label->setText(QtPropertyBrowserUtils::colorValueText(c: m_color));
2125}
2126
2127void QtColorEditWidget::setValue(const QColor &c)
2128{
2129 if (m_color != c) {
2130 m_color = c;
2131 m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::brushValuePixmap(b: QBrush(c)));
2132 m_label->setText(QtPropertyBrowserUtils::colorValueText(c));
2133 }
2134}
2135
2136void QtColorEditWidget::buttonClicked()
2137{
2138 const QColor newColor = QColorDialog::getColor(initial: m_color, parent: this, title: QString(), options: QColorDialog::ShowAlphaChannel);
2139 if (newColor.isValid() && newColor != m_color) {
2140 setValue(newColor);
2141 emit valueChanged(value: m_color);
2142 }
2143}
2144
2145bool QtColorEditWidget::eventFilter(QObject *obj, QEvent *ev)
2146{
2147 if (obj == m_button) {
2148 switch (ev->type()) {
2149 case QEvent::KeyPress:
2150 case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate
2151 switch (static_cast<const QKeyEvent*>(ev)->key()) {
2152 case Qt::Key_Escape:
2153 case Qt::Key_Enter:
2154 case Qt::Key_Return:
2155 ev->ignore();
2156 return true;
2157 default:
2158 break;
2159 }
2160 }
2161 break;
2162 default:
2163 break;
2164 }
2165 }
2166 return QWidget::eventFilter(watched: obj, event: ev);
2167}
2168
2169// QtColorEditorFactoryPrivate
2170
2171class QtColorEditorFactoryPrivate : public EditorFactoryPrivate<QtColorEditWidget>
2172{
2173 QtColorEditorFactory *q_ptr;
2174 Q_DECLARE_PUBLIC(QtColorEditorFactory)
2175public:
2176
2177 void slotPropertyChanged(QtProperty *property, const QColor &value);
2178 void slotSetValue(const QColor &value);
2179};
2180
2181void QtColorEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
2182 const QColor &value)
2183{
2184 const auto it = m_createdEditors.constFind(key: property);
2185 if (it == m_createdEditors.constEnd())
2186 return;
2187
2188 for (QtColorEditWidget *e : it.value())
2189 e->setValue(value);
2190}
2191
2192void QtColorEditorFactoryPrivate::slotSetValue(const QColor &value)
2193{
2194 QObject *object = q_ptr->sender();
2195 for (auto itEditor = m_editorToProperty.cbegin(), ecend = m_editorToProperty.cend(); itEditor != ecend; ++itEditor)
2196 if (itEditor.key() == object) {
2197 QtProperty *property = itEditor.value();
2198 QtColorPropertyManager *manager = q_ptr->propertyManager(property);
2199 if (!manager)
2200 return;
2201 manager->setValue(property, val: value);
2202 return;
2203 }
2204}
2205
2206/*!
2207 \class QtColorEditorFactory
2208 \internal
2209 \inmodule QtDesigner
2210 \since 4.4
2211
2212 \brief The QtColorEditorFactory class provides color editing for
2213 properties created by QtColorPropertyManager objects.
2214
2215 \sa QtAbstractEditorFactory, QtColorPropertyManager
2216*/
2217
2218/*!
2219 Creates a factory with the given \a parent.
2220*/
2221QtColorEditorFactory::QtColorEditorFactory(QObject *parent) :
2222 QtAbstractEditorFactory<QtColorPropertyManager>(parent),
2223 d_ptr(new QtColorEditorFactoryPrivate())
2224{
2225 d_ptr->q_ptr = this;
2226}
2227
2228/*!
2229 Destroys this factory, and all the widgets it has created.
2230*/
2231QtColorEditorFactory::~QtColorEditorFactory()
2232{
2233 qDeleteAll(c: d_ptr->m_editorToProperty.keys());
2234}
2235
2236/*!
2237 \internal
2238
2239 Reimplemented from the QtAbstractEditorFactory class.
2240*/
2241void QtColorEditorFactory::connectPropertyManager(QtColorPropertyManager *manager)
2242{
2243 connect(sender: manager, signal: &QtColorPropertyManager::valueChanged,
2244 context: this, slot: [this](QtProperty *property, const QColor &value)
2245 { d_ptr->slotPropertyChanged(property, value); });
2246}
2247
2248/*!
2249 \internal
2250
2251 Reimplemented from the QtAbstractEditorFactory class.
2252*/
2253QWidget *QtColorEditorFactory::createEditor(QtColorPropertyManager *manager,
2254 QtProperty *property, QWidget *parent)
2255{
2256 QtColorEditWidget *editor = d_ptr->createEditor(property, parent);
2257 editor->setValue(manager->value(property));
2258 connect(sender: editor, signal: &QtColorEditWidget::valueChanged,
2259 context: this, slot: [this](const QColor &value) { d_ptr->slotSetValue(value); });
2260 connect(sender: editor, signal: &QObject::destroyed,
2261 context: this, slot: [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
2262 return editor;
2263}
2264
2265/*!
2266 \internal
2267
2268 Reimplemented from the QtAbstractEditorFactory class.
2269*/
2270void QtColorEditorFactory::disconnectPropertyManager(QtColorPropertyManager *manager)
2271{
2272 disconnect(sender: manager, signal: &QtColorPropertyManager::valueChanged, receiver: this, zero: nullptr);
2273}
2274
2275// QtFontEditWidget
2276
2277class QtFontEditWidget : public QWidget {
2278 Q_OBJECT
2279
2280public:
2281 QtFontEditWidget(QWidget *parent);
2282
2283 bool eventFilter(QObject *obj, QEvent *ev) override;
2284
2285public Q_SLOTS:
2286 void setValue(const QFont &value);
2287
2288private Q_SLOTS:
2289 void buttonClicked();
2290
2291Q_SIGNALS:
2292 void valueChanged(const QFont &value);
2293
2294private:
2295 QFont m_font;
2296 QLabel *m_pixmapLabel;
2297 QLabel *m_label;
2298 QToolButton *m_button;
2299};
2300
2301QtFontEditWidget::QtFontEditWidget(QWidget *parent) :
2302 QWidget(parent),
2303 m_pixmapLabel(new QLabel),
2304 m_label(new QLabel),
2305 m_button(new QToolButton)
2306{
2307 auto *lt = new QHBoxLayout(this);
2308 setupTreeViewEditorMargin(lt);
2309 lt->setSpacing(0);
2310 lt->addWidget(m_pixmapLabel);
2311 lt->addWidget(m_label);
2312 lt->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
2313
2314 m_button->setSizePolicy(hor: QSizePolicy::Fixed, ver: QSizePolicy::Ignored);
2315 m_button->setFixedWidth(20);
2316 setFocusProxy(m_button);
2317 setFocusPolicy(m_button->focusPolicy());
2318 m_button->setText(tr(s: "..."));
2319 m_button->installEventFilter(filterObj: this);
2320 connect(sender: m_button, signal: &QAbstractButton::clicked, context: this, slot: &QtFontEditWidget::buttonClicked);
2321 lt->addWidget(m_button);
2322 m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::fontValuePixmap(f: m_font));
2323 m_label->setText(QtPropertyBrowserUtils::fontValueText(f: m_font));
2324}
2325
2326void QtFontEditWidget::setValue(const QFont &f)
2327{
2328 if (m_font != f) {
2329 m_font = f;
2330 m_pixmapLabel->setPixmap(QtPropertyBrowserUtils::fontValuePixmap(f));
2331 m_label->setText(QtPropertyBrowserUtils::fontValueText(f));
2332 }
2333}
2334
2335void QtFontEditWidget::buttonClicked()
2336{
2337 bool ok = false;
2338 QFont newFont = QFontDialog::getFont(ok: &ok, initial: m_font, parent: this, title: tr(s: "Select Font"));
2339 if (ok && newFont != m_font) {
2340 QFont f = m_font;
2341 // prevent mask for unchanged attributes, don't change other attributes (like kerning, etc...)
2342 if (m_font.family() != newFont.family())
2343 f.setFamily(newFont.family());
2344 if (m_font.pointSize() != newFont.pointSize())
2345 f.setPointSize(newFont.pointSize());
2346 if (m_font.bold() != newFont.bold())
2347 f.setBold(newFont.bold());
2348 if (m_font.italic() != newFont.italic())
2349 f.setItalic(newFont.italic());
2350 if (m_font.underline() != newFont.underline())
2351 f.setUnderline(newFont.underline());
2352 if (m_font.strikeOut() != newFont.strikeOut())
2353 f.setStrikeOut(newFont.strikeOut());
2354 setValue(f);
2355 emit valueChanged(value: m_font);
2356 }
2357}
2358
2359bool QtFontEditWidget::eventFilter(QObject *obj, QEvent *ev)
2360{
2361 if (obj == m_button) {
2362 switch (ev->type()) {
2363 case QEvent::KeyPress:
2364 case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate
2365 switch (static_cast<const QKeyEvent*>(ev)->key()) {
2366 case Qt::Key_Escape:
2367 case Qt::Key_Enter:
2368 case Qt::Key_Return:
2369 ev->ignore();
2370 return true;
2371 default:
2372 break;
2373 }
2374 }
2375 break;
2376 default:
2377 break;
2378 }
2379 }
2380 return QWidget::eventFilter(watched: obj, event: ev);
2381}
2382
2383// QtFontEditorFactoryPrivate
2384
2385class QtFontEditorFactoryPrivate : public EditorFactoryPrivate<QtFontEditWidget>
2386{
2387 QtFontEditorFactory *q_ptr;
2388 Q_DECLARE_PUBLIC(QtFontEditorFactory)
2389public:
2390
2391 void slotPropertyChanged(QtProperty *property, const QFont &value);
2392 void slotSetValue(const QFont &value);
2393};
2394
2395void QtFontEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
2396 const QFont &value)
2397{
2398 const auto it = m_createdEditors.constFind(key: property);
2399 if (it == m_createdEditors.constEnd())
2400 return;
2401
2402 for (QtFontEditWidget *e : it.value())
2403 e->setValue(value);
2404}
2405
2406void QtFontEditorFactoryPrivate::slotSetValue(const QFont &value)
2407{
2408 QObject *object = q_ptr->sender();
2409 for (auto itEditor = m_editorToProperty.cbegin(), ecend = m_editorToProperty.cend(); itEditor != ecend; ++itEditor)
2410 if (itEditor.key() == object) {
2411 QtProperty *property = itEditor.value();
2412 QtFontPropertyManager *manager = q_ptr->propertyManager(property);
2413 if (!manager)
2414 return;
2415 manager->setValue(property, val: value);
2416 return;
2417 }
2418}
2419
2420/*!
2421 \class QtFontEditorFactory
2422 \internal
2423 \inmodule QtDesigner
2424 \since 4.4
2425
2426 \brief The QtFontEditorFactory class provides font editing for
2427 properties created by QtFontPropertyManager objects.
2428
2429 \sa QtAbstractEditorFactory, QtFontPropertyManager
2430*/
2431
2432/*!
2433 Creates a factory with the given \a parent.
2434*/
2435QtFontEditorFactory::QtFontEditorFactory(QObject *parent) :
2436 QtAbstractEditorFactory<QtFontPropertyManager>(parent),
2437 d_ptr(new QtFontEditorFactoryPrivate())
2438{
2439 d_ptr->q_ptr = this;
2440}
2441
2442/*!
2443 Destroys this factory, and all the widgets it has created.
2444*/
2445QtFontEditorFactory::~QtFontEditorFactory()
2446{
2447 qDeleteAll(c: d_ptr->m_editorToProperty.keys());
2448}
2449
2450/*!
2451 \internal
2452
2453 Reimplemented from the QtAbstractEditorFactory class.
2454*/
2455void QtFontEditorFactory::connectPropertyManager(QtFontPropertyManager *manager)
2456{
2457 connect(sender: manager, signal: &QtFontPropertyManager::valueChanged,
2458 context: this, slot: [this](QtProperty *property, const QFont &value)
2459 { d_ptr->slotPropertyChanged(property, value); });
2460}
2461
2462/*!
2463 \internal
2464
2465 Reimplemented from the QtAbstractEditorFactory class.
2466*/
2467QWidget *QtFontEditorFactory::createEditor(QtFontPropertyManager *manager,
2468 QtProperty *property, QWidget *parent)
2469{
2470 QtFontEditWidget *editor = d_ptr->createEditor(property, parent);
2471 editor->setValue(manager->value(property));
2472 connect(sender: editor, signal: &QtFontEditWidget::valueChanged,
2473 context: this, slot: [this](const QFont &value) { d_ptr->slotSetValue(value); });
2474 connect(sender: editor, signal: &QObject::destroyed,
2475 context: this, slot: [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
2476 return editor;
2477}
2478
2479/*!
2480 \internal
2481
2482 Reimplemented from the QtAbstractEditorFactory class.
2483*/
2484void QtFontEditorFactory::disconnectPropertyManager(QtFontPropertyManager *manager)
2485{
2486 disconnect(sender: manager, signal: &QtFontPropertyManager::valueChanged, receiver: this, zero: nullptr);
2487}
2488
2489QT_END_NAMESPACE
2490
2491#include "moc_qteditorfactory.cpp"
2492#include "qteditorfactory.moc"
2493

source code of qttools/src/shared/qtpropertybrowser/qteditorfactory.cpp