Revision control
++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
++ // Qt-Security score:significant reason:default
++
++ #include "qteditorfactory_p.h"
++ #include "qtpropertybrowserutils_p.h"
++
++ #include <QtWidgets/qabstractitemview.h>
++ #include <QtWidgets/qapplication.h>
++ #include <QtWidgets/qboxlayout.h>
++ #include <QtWidgets/qcolordialog.h>
++ #include <QtWidgets/qcombobox.h>
++ #include <QtWidgets/qdatetimeedit.h>
++ #include <QtWidgets/qfontdialog.h>
++ #include <QtWidgets/qkeysequenceedit.h>
++ #include <QtWidgets/qlabel.h>
++ #include <QtWidgets/qlayoutitem.h>
++ #include <QtWidgets/qlineedit.h>
++ #include <QtWidgets/qmenu.h>
++ #include <QtWidgets/qscrollbar.h>
++ #include <QtWidgets/qspinbox.h>
++ #include <QtWidgets/qtoolbutton.h>
++
++ #include <QtGui/qevent.h>
++ #include <QtGui/qvalidator.h>
++
++ #include <QtCore/qhash.h>
++ #include <QtCore/qregularexpression.h>
++
++ QT_BEGIN_NAMESPACE
++
++ // Set a hard coded left margin to account for the indentation
++ // of the tree view icon when switching to an editor
++
++ static inline void setupTreeViewEditorMargin(QLayout *lt)
++ {
++ enum { DecorationMargin = 4 };
++ if (QApplication::layoutDirection() == Qt::LeftToRight)
++ lt->setContentsMargins(DecorationMargin, 0, 0, 0);
++ else
++ lt->setContentsMargins(0, 0, DecorationMargin, 0);
++ }
++
++ // ---------- EditorFactoryPrivate :
++ // Base class for editor factory private classes. Manages mapping of properties to editors and vice versa.
++
++ template <class Editor>
++ class EditorFactoryPrivate
++ {
++ public:
++
++ using EditorList = QList<Editor *>;
++ using PropertyToEditorListMap = QHash<QtProperty *, EditorList>;
++ using EditorToPropertyMap = QHash<Editor *, QtProperty *>;
++
++ Editor *createEditor(QtProperty *property, QWidget *parent);
++ void initializeEditor(QtProperty *property, Editor *e);
++ void slotEditorDestroyed(QObject *object);
++
++ void deleteEditors();
++
++ PropertyToEditorListMap m_createdEditors;
++ };
++
++ template <class Editor>
++ Editor *EditorFactoryPrivate<Editor>::createEditor(QtProperty *property, QWidget *parent)
++ {
++ auto *editor = new Editor(parent);
++ initializeEditor(property, editor);
++ return editor;
++ }
++
++ template <class Editor>
++ void EditorFactoryPrivate<Editor>::initializeEditor(QtProperty *property, Editor *editor)
++ {
++ auto it = m_createdEditors.find(property);
++ if (it == m_createdEditors.end())
++ it = m_createdEditors.insert(property, EditorList());
++ it.value().append(editor);
++ }
++
++ template <class Editor>
++ void EditorFactoryPrivate<Editor>::slotEditorDestroyed(QObject *object)
++ {
++ auto pred = [object] (const Editor *e) { return object == e; };
++ for (auto it = m_createdEditors.begin(), end = m_createdEditors.end(); it != end; ++it) {
++ auto &editorList = it.value();
++ auto listIt = std::find_if(editorList.cbegin(), editorList.cend(), pred);
++ if (listIt != editorList.cend()) {
++ editorList.erase(listIt);
++ if (editorList.isEmpty())
++ m_createdEditors.erase(it) ;
++ break;
++ }
++ }
++ }
++
++ template <class Editor>
++ void EditorFactoryPrivate<Editor>::deleteEditors()
++ {
++ for (auto it = m_createdEditors.begin(), end = m_createdEditors.end(); it != end; ++it)
++ qDeleteAll(it.value());
++ m_createdEditors.clear();
++ }
++
++ // ------------ QtSpinBoxFactory
++
++ class QtSpinBoxFactoryPrivate : public EditorFactoryPrivate<QSpinBox>
++ {
++ QtSpinBoxFactory *q_ptr = nullptr;
++ Q_DECLARE_PUBLIC(QtSpinBoxFactory)
++ public:
++
++ void slotPropertyChanged(QtProperty *property, int value);
++ void slotRangeChanged(QtProperty *property, int min, int max);
++ void slotSingleStepChanged(QtProperty *property, int step);
++ void slotSetValue(QtProperty *property, int value);
++ };
++
++ void QtSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.cend())
++ return;
++ for (QSpinBox *editor : it.value()) {
++ if (editor->value() != value) {
++ editor->blockSignals(true);
++ editor->setValue(value);
++ editor->blockSignals(false);
++ }
++ }
++ }
++
++ void QtSpinBoxFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.cend())
++ return;
++
++ QtIntPropertyManager *manager = q_ptr->propertyManager(property);
++ if (!manager)
++ return;
++
++ for (QSpinBox *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setRange(min, max);
++ editor->setValue(manager->value(property));
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.cend())
++ return;
++ for (QSpinBox *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setSingleStep(step);
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtSpinBoxFactoryPrivate::slotSetValue(QtProperty *property, int value)
++ {
++ if (QtIntPropertyManager *manager = q_ptr->propertyManager(property))
++ manager->setValue(property, value);
++ }
++
++ /*!
++ \class QtSpinBoxFactory
++ \internal
++ \inmodule QtDesigner
++ \since 4.4
++
++ \brief The QtSpinBoxFactory class provides QSpinBox widgets for
++ properties created by QtIntPropertyManager objects.
++
++ \sa QtAbstractEditorFactory, QtIntPropertyManager
++ */
++
++ /*!
++ Creates a factory with the given \a parent.
++ */
++ QtSpinBoxFactory::QtSpinBoxFactory(QObject *parent)
++ : QtAbstractEditorFactory<QtIntPropertyManager>(parent), d_ptr(new QtSpinBoxFactoryPrivate())
++ {
++ d_ptr->q_ptr = this;
++
++ }
++
++ /*!
++ Destroys this factory, and all the widgets it has created.
++ */
++ QtSpinBoxFactory::~QtSpinBoxFactory()
++ {
++ d_ptr->deleteEditors();
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtSpinBoxFactory::connectPropertyManager(QtIntPropertyManager *manager)
++ {
++ connect(manager, &QtIntPropertyManager::valueChanged,
++ this, [this](QtProperty *property, int value)
++ { d_ptr->slotPropertyChanged(property, value); });
++ connect(manager, &QtIntPropertyManager::rangeChanged,
++ this, [this](QtProperty *property, int min, int max)
++ { d_ptr->slotRangeChanged(property, min, max); });
++ connect(manager, &QtIntPropertyManager::singleStepChanged,
++ this, [this](QtProperty *property, int value)
++ { d_ptr->slotSingleStepChanged(property, value); });
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ QWidget *QtSpinBoxFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property,
++ QWidget *parent)
++ {
++ QSpinBox *editor = d_ptr->createEditor(property, parent);
++ editor->setSingleStep(manager->singleStep(property));
++ editor->setRange(manager->minimum(property), manager->maximum(property));
++ editor->setValue(manager->value(property));
++ editor->setKeyboardTracking(false);
++
++ connect(editor, &QSpinBox::valueChanged,
++ this, [this, property](int value) { d_ptr->slotSetValue(property, value); });
++ connect(editor, &QObject::destroyed,
++ this, [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
++ return editor;
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtSpinBoxFactory::disconnectPropertyManager(QtIntPropertyManager *manager)
++ {
++ disconnect(manager, &QtIntPropertyManager::valueChanged, this, nullptr);
++ disconnect(manager, &QtIntPropertyManager::rangeChanged, this, nullptr);
++ disconnect(manager, &QtIntPropertyManager::singleStepChanged, this, nullptr);
++ }
++
++ // QtSliderFactory
++
++ class QtSliderFactoryPrivate : public EditorFactoryPrivate<QSlider>
++ {
++ QtSliderFactory *q_ptr = nullptr;
++ Q_DECLARE_PUBLIC(QtSliderFactory)
++ public:
++ void slotPropertyChanged(QtProperty *property, int value);
++ void slotRangeChanged(QtProperty *property, int min, int max);
++ void slotSingleStepChanged(QtProperty *property, int step);
++ void slotSetValue(QtProperty *property, int value);
++ };
++
++ void QtSliderFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.cend())
++ return;
++ for (QSlider *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setValue(value);
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtSliderFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.cend())
++ return;
++
++ QtIntPropertyManager *manager = q_ptr->propertyManager(property);
++ if (!manager)
++ return;
++
++ for (QSlider *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setRange(min, max);
++ editor->setValue(manager->value(property));
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtSliderFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.cend())
++ return;
++ for (QSlider *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setSingleStep(step);
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtSliderFactoryPrivate::slotSetValue(QtProperty *property, int value)
++ {
++ if (QtIntPropertyManager *manager = q_ptr->propertyManager(property))
++ manager->setValue(property, value);
++ }
++
++ /*!
++ \class QtSliderFactory
++ \internal
++ \inmodule QtDesigner
++ \since 4.4
++
++ \brief The QtSliderFactory class provides QSlider widgets for
++ properties created by QtIntPropertyManager objects.
++
++ \sa QtAbstractEditorFactory, QtIntPropertyManager
++ */
++
++ /*!
++ Creates a factory with the given \a parent.
++ */
++ QtSliderFactory::QtSliderFactory(QObject *parent)
++ : QtAbstractEditorFactory<QtIntPropertyManager>(parent), d_ptr(new QtSliderFactoryPrivate())
++ {
++ d_ptr->q_ptr = this;
++
++ }
++
++ /*!
++ Destroys this factory, and all the widgets it has created.
++ */
++ QtSliderFactory::~QtSliderFactory()
++ {
++ d_ptr->deleteEditors();
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtSliderFactory::connectPropertyManager(QtIntPropertyManager *manager)
++ {
++ connect(manager, &QtIntPropertyManager::valueChanged,
++ this, [this](QtProperty *property, int value)
++ { d_ptr->slotPropertyChanged(property, value); });
++ connect(manager, &QtIntPropertyManager::rangeChanged,
++ this, [this](QtProperty *property, int min, int max)
++ { d_ptr->slotRangeChanged(property, min, max); });
++ connect(manager, &QtIntPropertyManager::singleStepChanged,
++ this, [this](QtProperty *property, int value)
++ { d_ptr->slotSingleStepChanged(property, value); });
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ QWidget *QtSliderFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property,
++ QWidget *parent)
++ {
++ auto *editor = new QSlider(Qt::Horizontal, parent);
++ d_ptr->initializeEditor(property, editor);
++ editor->setSingleStep(manager->singleStep(property));
++ editor->setRange(manager->minimum(property), manager->maximum(property));
++ editor->setValue(manager->value(property));
++
++ connect(editor, &QSlider::valueChanged,
++ this, [this, property](int value) { d_ptr->slotSetValue(property, value); });
++ connect(editor, &QObject::destroyed,
++ this, [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
++ return editor;
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtSliderFactory::disconnectPropertyManager(QtIntPropertyManager *manager)
++ {
++ disconnect(manager, &QtIntPropertyManager::valueChanged, this, nullptr);
++ disconnect(manager, &QtIntPropertyManager::rangeChanged, this, nullptr);
++ disconnect(manager, &QtIntPropertyManager::singleStepChanged, this, nullptr);
++ }
++
++ // QtSliderFactory
++
++ class QtScrollBarFactoryPrivate : public EditorFactoryPrivate<QScrollBar>
++ {
++ QtScrollBarFactory *q_ptr = nullptr;
++ Q_DECLARE_PUBLIC(QtScrollBarFactory)
++ public:
++ void slotPropertyChanged(QtProperty *property, int value);
++ void slotRangeChanged(QtProperty *property, int min, int max);
++ void slotSingleStepChanged(QtProperty *property, int step);
++ void slotSetValue(QtProperty *property, int value);
++ };
++
++ void QtScrollBarFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.cend())
++ return;
++
++ for (QScrollBar *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setValue(value);
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtScrollBarFactoryPrivate::slotRangeChanged(QtProperty *property, int min, int max)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.cend())
++ return;
++
++ QtIntPropertyManager *manager = q_ptr->propertyManager(property);
++ if (!manager)
++ return;
++
++ for (QScrollBar *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setRange(min, max);
++ editor->setValue(manager->value(property));
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtScrollBarFactoryPrivate::slotSingleStepChanged(QtProperty *property, int step)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.cend())
++ return;
++ for (QScrollBar *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setSingleStep(step);
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtScrollBarFactoryPrivate::slotSetValue(QtProperty *property, int value)
++ {
++ if (QtIntPropertyManager *manager = q_ptr->propertyManager(property))
++ manager->setValue(property, value);
++ }
++
++ /*!
++ \class QtScrollBarFactory
++ \internal
++ \inmodule QtDesigner
++ \since 4.4
++
++ \brief The QtScrollBarFactory class provides QScrollBar widgets for
++ properties created by QtIntPropertyManager objects.
++
++ \sa QtAbstractEditorFactory, QtIntPropertyManager
++ */
++
++ /*!
++ Creates a factory with the given \a parent.
++ */
++ QtScrollBarFactory::QtScrollBarFactory(QObject *parent)
++ : QtAbstractEditorFactory<QtIntPropertyManager>(parent), d_ptr(new QtScrollBarFactoryPrivate())
++ {
++ d_ptr->q_ptr = this;
++
++ }
++
++ /*!
++ Destroys this factory, and all the widgets it has created.
++ */
++ QtScrollBarFactory::~QtScrollBarFactory()
++ {
++ d_ptr->deleteEditors();
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtScrollBarFactory::connectPropertyManager(QtIntPropertyManager *manager)
++ {
++ connect(manager, &QtIntPropertyManager::valueChanged,
++ this, [this](QtProperty *property, int value)
++ { d_ptr->slotPropertyChanged(property, value); });
++ connect(manager, &QtIntPropertyManager::rangeChanged,
++ this, [this](QtProperty *property, int min, int max)
++ { d_ptr->slotRangeChanged(property, min, max); });
++ connect(manager, &QtIntPropertyManager::singleStepChanged,
++ this, [this](QtProperty *property, int value)
++ { d_ptr->slotSingleStepChanged(property, value); });
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ QWidget *QtScrollBarFactory::createEditor(QtIntPropertyManager *manager, QtProperty *property,
++ QWidget *parent)
++ {
++ auto *editor = new QScrollBar(Qt::Horizontal, parent);
++ d_ptr->initializeEditor(property, editor);
++ editor->setSingleStep(manager->singleStep(property));
++ editor->setRange(manager->minimum(property), manager->maximum(property));
++ editor->setValue(manager->value(property));
++ connect(editor, &QScrollBar::valueChanged,
++ this, [this, property](int value) { d_ptr->slotSetValue(property, value); });
++ connect(editor, &QObject::destroyed,
++ this, [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
++ return editor;
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtScrollBarFactory::disconnectPropertyManager(QtIntPropertyManager *manager)
++ {
++ disconnect(manager, &QtIntPropertyManager::valueChanged, this, nullptr);
++ disconnect(manager, &QtIntPropertyManager::rangeChanged, this, nullptr);
++ disconnect(manager, &QtIntPropertyManager::singleStepChanged, this, nullptr);
++ }
++
++ // QtCheckBoxFactory
++
++ class QtCheckBoxFactoryPrivate : public EditorFactoryPrivate<QtBoolEdit>
++ {
++ QtCheckBoxFactory *q_ptr = nullptr;
++ Q_DECLARE_PUBLIC(QtCheckBoxFactory)
++ public:
++ void slotPropertyChanged(QtProperty *property, bool value);
++ void slotSetValue(QtProperty *property, bool value);
++ };
++
++ void QtCheckBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, bool value)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.cend())
++ return;
++
++ for (QtBoolEdit *editor : it.value()) {
++ editor->blockCheckBoxSignals(true);
++ editor->setChecked(value);
++ editor->blockCheckBoxSignals(false);
++ }
++ }
++
++ void QtCheckBoxFactoryPrivate::slotSetValue(QtProperty *property, bool value)
++ {
++ if (QtBoolPropertyManager *manager = q_ptr->propertyManager(property))
++ manager->setValue(property, value);
++ }
++
++ /*!
++ \class QtCheckBoxFactory
++ \internal
++ \inmodule QtDesigner
++ \since 4.4
++
++ \brief The QtCheckBoxFactory class provides QCheckBox widgets for
++ properties created by QtBoolPropertyManager objects.
++
++ \sa QtAbstractEditorFactory, QtBoolPropertyManager
++ */
++
++ /*!
++ Creates a factory with the given \a parent.
++ */
++ QtCheckBoxFactory::QtCheckBoxFactory(QObject *parent)
++ : QtAbstractEditorFactory<QtBoolPropertyManager>(parent), d_ptr(new QtCheckBoxFactoryPrivate())
++ {
++ d_ptr->q_ptr = this;
++
++ }
++
++ /*!
++ Destroys this factory, and all the widgets it has created.
++ */
++ QtCheckBoxFactory::~QtCheckBoxFactory()
++ {
++ d_ptr->deleteEditors();
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtCheckBoxFactory::connectPropertyManager(QtBoolPropertyManager *manager)
++ {
++ connect(manager, &QtBoolPropertyManager::valueChanged,
++ this, [this](QtProperty *property, bool value)
++ { d_ptr->slotPropertyChanged(property, value); });
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ QWidget *QtCheckBoxFactory::createEditor(QtBoolPropertyManager *manager, QtProperty *property,
++ QWidget *parent)
++ {
++ QtBoolEdit *editor = d_ptr->createEditor(property, parent);
++ editor->setChecked(manager->value(property));
++
++ connect(editor, &QtBoolEdit::toggled,
++ this, [this, property](bool value) { d_ptr->slotSetValue(property, value); });
++ connect(editor, &QObject::destroyed,
++ this, [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
++ return editor;
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtCheckBoxFactory::disconnectPropertyManager(QtBoolPropertyManager *manager)
++ {
++ disconnect(manager, &QtBoolPropertyManager::valueChanged, this, nullptr);
++ }
++
++ // QtDoubleSpinBoxFactory
++
++ class QtDoubleSpinBoxFactoryPrivate : public EditorFactoryPrivate<QDoubleSpinBox>
++ {
++ QtDoubleSpinBoxFactory *q_ptr = nullptr;
++ Q_DECLARE_PUBLIC(QtDoubleSpinBoxFactory)
++ public:
++
++ void slotPropertyChanged(QtProperty *property, double value);
++ void slotRangeChanged(QtProperty *property, double min, double max);
++ void slotSingleStepChanged(QtProperty *property, double step);
++ void slotDecimalsChanged(QtProperty *property, int prec);
++ void slotSetValue(QtProperty *property, double value);
++ };
++
++ void QtDoubleSpinBoxFactoryPrivate::slotPropertyChanged(QtProperty *property, double value)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.cend())
++ return;
++ for (QDoubleSpinBox *editor : it.value()) {
++ if (editor->value() != value) {
++ editor->blockSignals(true);
++ editor->setValue(value);
++ editor->blockSignals(false);
++ }
++ }
++ }
++
++ void QtDoubleSpinBoxFactoryPrivate::slotRangeChanged(QtProperty *property,
++ double min, double max)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.cend())
++ return;
++
++ QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
++ if (!manager)
++ return;
++
++ for (QDoubleSpinBox *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setRange(min, max);
++ editor->setValue(manager->value(property));
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtDoubleSpinBoxFactoryPrivate::slotSingleStepChanged(QtProperty *property, double step)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.cend())
++ return;
++
++ QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
++ if (!manager)
++ return;
++
++ for (QDoubleSpinBox *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setSingleStep(step);
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtDoubleSpinBoxFactoryPrivate::slotDecimalsChanged(QtProperty *property, int prec)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.constEnd())
++ return;
++
++ QtDoublePropertyManager *manager = q_ptr->propertyManager(property);
++ if (!manager)
++ return;
++
++ for (QDoubleSpinBox *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setDecimals(prec);
++ editor->setValue(manager->value(property));
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtDoubleSpinBoxFactoryPrivate::slotSetValue(QtProperty *property, double value)
++ {
++ if (QtDoublePropertyManager *manager = q_ptr->propertyManager(property))
++ manager->setValue(property, value);
++ }
++
++ /*! \class QtDoubleSpinBoxFactory
++ \internal
++ \inmodule QtDesigner
++ \since 4.4
++
++ \brief The QtDoubleSpinBoxFactory class provides QDoubleSpinBox
++ widgets for properties created by QtDoublePropertyManager objects.
++
++ \sa QtAbstractEditorFactory, QtDoublePropertyManager
++ */
++
++ /*!
++ Creates a factory with the given \a parent.
++ */
++ QtDoubleSpinBoxFactory::QtDoubleSpinBoxFactory(QObject *parent)
++ : QtAbstractEditorFactory<QtDoublePropertyManager>(parent), d_ptr(new QtDoubleSpinBoxFactoryPrivate())
++ {
++ d_ptr->q_ptr = this;
++
++ }
++
++ /*!
++ Destroys this factory, and all the widgets it has created.
++ */
++ QtDoubleSpinBoxFactory::~QtDoubleSpinBoxFactory()
++ {
++ d_ptr->deleteEditors();
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtDoubleSpinBoxFactory::connectPropertyManager(QtDoublePropertyManager *manager)
++ {
++ connect(manager, &QtDoublePropertyManager::valueChanged,
++ this, [this](QtProperty *property, double value)
++ { d_ptr->slotPropertyChanged(property, value); });
++ connect(manager, &QtDoublePropertyManager::rangeChanged,
++ this, [this](QtProperty *property, double min, double max)
++ { d_ptr->slotRangeChanged(property, min, max); });
++ connect(manager, &QtDoublePropertyManager::singleStepChanged,
++ this, [this](QtProperty *property, double value)
++ { d_ptr->slotSingleStepChanged(property, value); });
++ connect(manager, &QtDoublePropertyManager::decimalsChanged,
++ this, [this](QtProperty *property, int value)
++ { d_ptr->slotDecimalsChanged(property, value); });
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ QWidget *QtDoubleSpinBoxFactory::createEditor(QtDoublePropertyManager *manager,
++ QtProperty *property, QWidget *parent)
++ {
++ QDoubleSpinBox *editor = d_ptr->createEditor(property, parent);
++ editor->setSingleStep(manager->singleStep(property));
++ editor->setDecimals(manager->decimals(property));
++ editor->setRange(manager->minimum(property), manager->maximum(property));
++ editor->setValue(manager->value(property));
++ editor->setKeyboardTracking(false);
++
++ connect(editor, &QDoubleSpinBox::valueChanged,
++ this, [this, property](double value) { d_ptr->slotSetValue(property, value); });
++ connect(editor, &QObject::destroyed,
++ this, [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
++ return editor;
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtDoubleSpinBoxFactory::disconnectPropertyManager(QtDoublePropertyManager *manager)
++ {
++ disconnect(manager, &QtDoublePropertyManager::valueChanged, this, nullptr);
++ disconnect(manager, &QtDoublePropertyManager::rangeChanged, this, nullptr);
++ disconnect(manager, &QtDoublePropertyManager::singleStepChanged, this, nullptr);
++ disconnect(manager, &QtDoublePropertyManager::decimalsChanged, this, nullptr);
++ }
++
++ // QtLineEditFactory
++
++ class QtLineEditFactoryPrivate : public EditorFactoryPrivate<QLineEdit>
++ {
++ QtLineEditFactory *q_ptr = nullptr;
++ Q_DECLARE_PUBLIC(QtLineEditFactory)
++ public:
++
++ void slotPropertyChanged(QtProperty *property, const QString &value);
++ void slotRegExpChanged(QtProperty *property, const QRegularExpression ®Exp);
++ void slotSetValue(QtProperty *property, const QString &value);
++ };
++
++ void QtLineEditFactoryPrivate::slotPropertyChanged(QtProperty *property,
++ const QString &value)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.constEnd())
++ return;
++
++ for (QLineEdit *editor : it.value()) {
++ if (editor->text() != value)
++ editor->setText(value);
++ }
++ }
++
++ void QtLineEditFactoryPrivate::slotRegExpChanged(QtProperty *property,
++ const QRegularExpression ®Exp)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.constEnd())
++ return;
++
++ QtStringPropertyManager *manager = q_ptr->propertyManager(property);
++ if (!manager)
++ return;
++
++ for (QLineEdit *editor : it.value()) {
++ editor->blockSignals(true);
++ const QValidator *oldValidator = editor->validator();
++ QValidator *newValidator = nullptr;
++ if (regExp.isValid()) {
++ newValidator = new QRegularExpressionValidator(regExp, editor);
++ }
++ editor->setValidator(newValidator);
++ delete oldValidator;
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtLineEditFactoryPrivate::slotSetValue(QtProperty *property, const QString &value)
++ {
++ if (QtStringPropertyManager *manager = q_ptr->propertyManager(property))
++ manager->setValue(property, value);
++ }
++
++ /*!
++ \class QtLineEditFactory
++ \internal
++ \inmodule QtDesigner
++ \since 4.4
++
++ \brief The QtLineEditFactory class provides QLineEdit widgets for
++ properties created by QtStringPropertyManager objects.
++
++ \sa QtAbstractEditorFactory, QtStringPropertyManager
++ */
++
++ /*!
++ Creates a factory with the given \a parent.
++ */
++ QtLineEditFactory::QtLineEditFactory(QObject *parent)
++ : QtAbstractEditorFactory<QtStringPropertyManager>(parent), d_ptr(new QtLineEditFactoryPrivate())
++ {
++ d_ptr->q_ptr = this;
++
++ }
++
++ /*!
++ Destroys this factory, and all the widgets it has created.
++ */
++ QtLineEditFactory::~QtLineEditFactory()
++ {
++ d_ptr->deleteEditors();
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtLineEditFactory::connectPropertyManager(QtStringPropertyManager *manager)
++ {
++ connect(manager, &QtStringPropertyManager::valueChanged,
++ this, [this](QtProperty *property, const QString &value)
++ { d_ptr->slotPropertyChanged(property, value); });
++ connect(manager, &QtStringPropertyManager::regExpChanged,
++ this, [this](QtProperty *property, const QRegularExpression &value)
++ { d_ptr->slotRegExpChanged(property, value); });
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ QWidget *QtLineEditFactory::createEditor(QtStringPropertyManager *manager,
++ QtProperty *property, QWidget *parent)
++ {
++ QLineEdit *editor = d_ptr->createEditor(property, parent);
++ QRegularExpression regExp = manager->regExp(property);
++ if (regExp.isValid() && !regExp.pattern().isEmpty()) {
++ auto *validator = new QRegularExpressionValidator(regExp, editor);
++ editor->setValidator(validator);
++ }
++ editor->setText(manager->value(property));
++
++ connect(editor, &QLineEdit::textEdited,
++ this, [this, property](const QString &value) { d_ptr->slotSetValue(property, value); });
++ connect(editor, &QObject::destroyed,
++ this, [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
++ return editor;
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtLineEditFactory::disconnectPropertyManager(QtStringPropertyManager *manager)
++ {
++ disconnect(manager, &QtStringPropertyManager::valueChanged, this, nullptr);
++ disconnect(manager, &QtStringPropertyManager::regExpChanged, this, nullptr);
++ }
++
++ // QtDateEditFactory
++
++ class QtDateEditFactoryPrivate : public EditorFactoryPrivate<QDateEdit>
++ {
++ QtDateEditFactory *q_ptr = nullptr;
++ Q_DECLARE_PUBLIC(QtDateEditFactory)
++ public:
++
++ void slotPropertyChanged(QtProperty *property, QDate value);
++ void slotRangeChanged(QtProperty *property, QDate min, QDate max);
++ void slotSetValue(QtProperty *property, QDate value);
++ };
++
++ void QtDateEditFactoryPrivate::slotPropertyChanged(QtProperty *property, QDate value)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.constEnd())
++ return;
++ for (QDateEdit *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setDate(value);
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtDateEditFactoryPrivate::slotRangeChanged(QtProperty *property, QDate min, QDate max)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.constEnd())
++ return;
++
++ QtDatePropertyManager *manager = q_ptr->propertyManager(property);
++ if (!manager)
++ return;
++
++ for (QDateEdit *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setDateRange(min, max);
++ editor->setDate(manager->value(property));
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtDateEditFactoryPrivate::slotSetValue(QtProperty *property, QDate value)
++ {
++ if (QtDatePropertyManager *manager = q_ptr->propertyManager(property))
++ manager->setValue(property, value);
++ }
++
++ /*!
++ \class QtDateEditFactory
++ \internal
++ \inmodule QtDesigner
++ \since 4.4
++
++ \brief The QtDateEditFactory class provides QDateEdit widgets for
++ properties created by QtDatePropertyManager objects.
++
++ \sa QtAbstractEditorFactory, QtDatePropertyManager
++ */
++
++ /*!
++ Creates a factory with the given \a parent.
++ */
++ QtDateEditFactory::QtDateEditFactory(QObject *parent)
++ : QtAbstractEditorFactory<QtDatePropertyManager>(parent), d_ptr(new QtDateEditFactoryPrivate())
++ {
++ d_ptr->q_ptr = this;
++
++ }
++
++ /*!
++ Destroys this factory, and all the widgets it has created.
++ */
++ QtDateEditFactory::~QtDateEditFactory()
++ {
++ d_ptr->deleteEditors();
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtDateEditFactory::connectPropertyManager(QtDatePropertyManager *manager)
++ {
++ connect(manager, &QtDatePropertyManager::valueChanged,
++ this, [this](QtProperty *property, QDate value)
++ { d_ptr->slotPropertyChanged(property, value); });
++ connect(manager, &QtDatePropertyManager::rangeChanged,
++ this, [this](QtProperty *property, QDate min, QDate max)
++ { d_ptr->slotRangeChanged(property, min, max); });
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ QWidget *QtDateEditFactory::createEditor(QtDatePropertyManager *manager, QtProperty *property,
++ QWidget *parent)
++ {
++ QDateEdit *editor = d_ptr->createEditor(property, parent);
++ editor->setDisplayFormat(QtPropertyBrowserUtils::dateFormat());
++ editor->setCalendarPopup(true);
++ editor->setDateRange(manager->minimum(property), manager->maximum(property));
++ editor->setDate(manager->value(property));
++
++ connect(editor, &QDateEdit::dateChanged,
++ this, [this, property](QDate value) { d_ptr->slotSetValue(property, value); });
++ connect(editor, &QObject::destroyed,
++ this, [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
++ return editor;
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtDateEditFactory::disconnectPropertyManager(QtDatePropertyManager *manager)
++ {
++ disconnect(manager, &QtDatePropertyManager::valueChanged, this, nullptr);
++ disconnect(manager, &QtDatePropertyManager::rangeChanged, this, nullptr);
++ }
++
++ // QtTimeEditFactory
++
++ class QtTimeEditFactoryPrivate : public EditorFactoryPrivate<QTimeEdit>
++ {
++ QtTimeEditFactory *q_ptr = nullptr;
++ Q_DECLARE_PUBLIC(QtTimeEditFactory)
++ public:
++
++ void slotPropertyChanged(QtProperty *property, QTime value);
++ void slotSetValue(QtProperty *property, QTime value);
++ };
++
++ void QtTimeEditFactoryPrivate::slotPropertyChanged(QtProperty *property, QTime value)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.constEnd())
++ return;
++ for (QTimeEdit *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setTime(value);
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtTimeEditFactoryPrivate::slotSetValue(QtProperty *property, QTime value)
++ {
++ if (QtTimePropertyManager *manager = q_ptr->propertyManager(property))
++ manager->setValue(property, value);
++ }
++
++ /*!
++ \class QtTimeEditFactory
++ \internal
++ \inmodule QtDesigner
++ \since 4.4
++
++ \brief The QtTimeEditFactory class provides QTimeEdit widgets for
++ properties created by QtTimePropertyManager objects.
++
++ \sa QtAbstractEditorFactory, QtTimePropertyManager
++ */
++
++ /*!
++ Creates a factory with the given \a parent.
++ */
++ QtTimeEditFactory::QtTimeEditFactory(QObject *parent)
++ : QtAbstractEditorFactory<QtTimePropertyManager>(parent), d_ptr(new QtTimeEditFactoryPrivate())
++ {
++ d_ptr->q_ptr = this;
++
++ }
++
++ /*!
++ Destroys this factory, and all the widgets it has created.
++ */
++ QtTimeEditFactory::~QtTimeEditFactory()
++ {
++ d_ptr->deleteEditors();
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtTimeEditFactory::connectPropertyManager(QtTimePropertyManager *manager)
++ {
++ connect(manager, &QtTimePropertyManager::valueChanged,
++ this, [this](QtProperty *property, QTime value)
++ { d_ptr->slotPropertyChanged(property, value); });
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ QWidget *QtTimeEditFactory::createEditor(QtTimePropertyManager *manager, QtProperty *property,
++ QWidget *parent)
++ {
++ QTimeEdit *editor = d_ptr->createEditor(property, parent);
++ editor->setDisplayFormat(QtPropertyBrowserUtils::timeFormat());
++ editor->setTime(manager->value(property));
++
++ connect(editor, &QTimeEdit::timeChanged,
++ this, [this, property](QTime value) { d_ptr->slotSetValue(property, value); });
++ connect(editor, &QObject::destroyed,
++ this, [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
++ return editor;
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtTimeEditFactory::disconnectPropertyManager(QtTimePropertyManager *manager)
++ {
++ disconnect(manager, &QtTimePropertyManager::valueChanged, this, nullptr);
++ }
++
++ // QtDateTimeEditFactory
++
++ class QtDateTimeEditFactoryPrivate : public EditorFactoryPrivate<QDateTimeEdit>
++ {
++ QtDateTimeEditFactory *q_ptr = nullptr;
++ Q_DECLARE_PUBLIC(QtDateTimeEditFactory)
++ public:
++
++ void slotPropertyChanged(QtProperty *property, const QDateTime &value);
++ void slotSetValue(QtProperty *property, const QDateTime &value);
++
++ };
++
++ void QtDateTimeEditFactoryPrivate::slotPropertyChanged(QtProperty *property,
++ const QDateTime &value)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.constEnd())
++ return;
++
++ for (QDateTimeEdit *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setDateTime(value);
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtDateTimeEditFactoryPrivate::slotSetValue(QtProperty *property, const QDateTime &value)
++ {
++ if (QtDateTimePropertyManager *manager = q_ptr->propertyManager(property))
++ manager->setValue(property, value);
++ }
++
++ /*!
++ \class QtDateTimeEditFactory
++ \internal
++ \inmodule QtDesigner
++ \since 4.4
++
++ \brief The QtDateTimeEditFactory class provides QDateTimeEdit
++ widgets for properties created by QtDateTimePropertyManager objects.
++
++ \sa QtAbstractEditorFactory, QtDateTimePropertyManager
++ */
++
++ /*!
++ Creates a factory with the given \a parent.
++ */
++ QtDateTimeEditFactory::QtDateTimeEditFactory(QObject *parent)
++ : QtAbstractEditorFactory<QtDateTimePropertyManager>(parent), d_ptr(new QtDateTimeEditFactoryPrivate())
++ {
++ d_ptr->q_ptr = this;
++
++ }
++
++ /*!
++ Destroys this factory, and all the widgets it has created.
++ */
++ QtDateTimeEditFactory::~QtDateTimeEditFactory()
++ {
++ d_ptr->deleteEditors();
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtDateTimeEditFactory::connectPropertyManager(QtDateTimePropertyManager *manager)
++ {
++ connect(manager, &QtDateTimePropertyManager::valueChanged,
++ this, [this](QtProperty *property, const QDateTime &value)
++ { d_ptr->slotPropertyChanged(property, value); });
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ QWidget *QtDateTimeEditFactory::createEditor(QtDateTimePropertyManager *manager,
++ QtProperty *property, QWidget *parent)
++ {
++ QDateTimeEdit *editor = d_ptr->createEditor(property, parent);
++ editor->setDisplayFormat(QtPropertyBrowserUtils::dateTimeFormat());
++ editor->setDateTime(manager->value(property));
++
++ connect(editor, &QDateTimeEdit::dateTimeChanged,
++ this, [this, property](const QDateTime &value) { d_ptr->slotSetValue(property, value); });
++ connect(editor, &QObject::destroyed,
++ this, [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
++ return editor;
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtDateTimeEditFactory::disconnectPropertyManager(QtDateTimePropertyManager *manager)
++ {
++ disconnect(manager, &QtDateTimePropertyManager::valueChanged, this, nullptr);
++ }
++
++ // QtKeySequenceEditorFactory
++
++ class QtKeySequenceEditorFactoryPrivate : public EditorFactoryPrivate<QKeySequenceEdit>
++ {
++ QtKeySequenceEditorFactory *q_ptr = nullptr;
++ Q_DECLARE_PUBLIC(QtKeySequenceEditorFactory)
++ public:
++
++ void slotPropertyChanged(QtProperty *property, const QKeySequence &value);
++ void slotSetValue(QtProperty *property, const QKeySequence &value);
++ };
++
++ void QtKeySequenceEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
++ const QKeySequence &value)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.constEnd())
++ return;
++
++ for (QKeySequenceEdit *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setKeySequence(value);
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtKeySequenceEditorFactoryPrivate::slotSetValue(QtProperty *property, const QKeySequence &value)
++ {
++ if (QtKeySequencePropertyManager *manager = q_ptr->propertyManager(property))
++ manager->setValue(property, value);
++ }
++
++ /*!
++ \class QtKeySequenceEditorFactory
++ \internal
++ \inmodule QtDesigner
++ \since 4.4
++
++ \brief The QtKeySequenceEditorFactory class provides editor
++ widgets for properties created by QtKeySequencePropertyManager objects.
++
++ \sa QtAbstractEditorFactory
++ */
++
++ /*!
++ Creates a factory with the given \a parent.
++ */
++ QtKeySequenceEditorFactory::QtKeySequenceEditorFactory(QObject *parent)
++ : QtAbstractEditorFactory<QtKeySequencePropertyManager>(parent), d_ptr(new QtKeySequenceEditorFactoryPrivate())
++ {
++ d_ptr->q_ptr = this;
++
++ }
++
++ /*!
++ Destroys this factory, and all the widgets it has created.
++ */
++ QtKeySequenceEditorFactory::~QtKeySequenceEditorFactory()
++ {
++ d_ptr->deleteEditors();
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtKeySequenceEditorFactory::connectPropertyManager(QtKeySequencePropertyManager *manager)
++ {
++ connect(manager, &QtKeySequencePropertyManager::valueChanged,
++ this, [this](QtProperty *property, const QKeySequence &value)
++ { d_ptr->slotPropertyChanged(property, value); });
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ QWidget *QtKeySequenceEditorFactory::createEditor(QtKeySequencePropertyManager *manager,
++ QtProperty *property, QWidget *parent)
++ {
++ QKeySequenceEdit *editor = d_ptr->createEditor(property, parent);
++ editor->setKeySequence(manager->value(property));
++
++ connect(editor, &QKeySequenceEdit::keySequenceChanged,
++ this, [this, property](const QKeySequence &value) { d_ptr->slotSetValue(property, value); });
++ connect(editor, &QObject::destroyed,
++ this, [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
++ return editor;
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtKeySequenceEditorFactory::disconnectPropertyManager(QtKeySequencePropertyManager *manager)
++ {
++ disconnect(manager, &QtKeySequencePropertyManager::valueChanged, this, nullptr);
++ }
++
++ // QtCharEdit
++
++ class QtCharEdit : public QWidget
++ {
++ Q_OBJECT
++ public:
++ QtCharEdit(QWidget *parent = nullptr);
++
++ QChar value() const;
++ bool eventFilter(QObject *o, QEvent *e) override;
++ public Q_SLOTS:
++ void setValue(const QChar &value);
++ Q_SIGNALS:
++ void valueChanged(const QChar &value);
++ protected:
++ void focusInEvent(QFocusEvent *e) override;
++ void focusOutEvent(QFocusEvent *e) override;
++ void keyPressEvent(QKeyEvent *e) override;
++ void keyReleaseEvent(QKeyEvent *e) override;
++ bool event(QEvent *e) override;
++ private slots:
++ void slotClearChar();
++ private:
++ void handleKeyEvent(QKeyEvent *e);
++
++ QChar m_value;
++ QLineEdit *m_lineEdit;
++ };
++
++ QtCharEdit::QtCharEdit(QWidget *parent)
++ : QWidget(parent), m_lineEdit(new QLineEdit(this))
++ {
++ auto *layout = new QHBoxLayout(this);
++ layout->addWidget(m_lineEdit);
++ layout->setContentsMargins(QMargins());
++ m_lineEdit->installEventFilter(this);
++ m_lineEdit->setReadOnly(true);
++ m_lineEdit->setFocusProxy(this);
++ setFocusPolicy(m_lineEdit->focusPolicy());
++ setAttribute(Qt::WA_InputMethodEnabled);
++ }
++
++ bool QtCharEdit::eventFilter(QObject *o, QEvent *e)
++ {
++ if (o == m_lineEdit && e->type() == QEvent::ContextMenu) {
++ QContextMenuEvent *c = static_cast<QContextMenuEvent *>(e);
++ QMenu *menu = m_lineEdit->createStandardContextMenu();
++ const auto actions = menu->actions();
++ for (QAction *action : actions) {
++ action->setShortcut(QKeySequence());
++ QString actionString = action->text();
++ const auto pos = actionString.lastIndexOf(QLatin1Char('\t'));
++ if (pos > 0)
++ actionString = actionString.remove(pos, actionString.size() - pos);
++ action->setText(actionString);
++ }
++ QAction *actionBefore = nullptr;
++ if (!actions.empty())
++ actionBefore = actions[0];
++ auto *clearAction = new QAction(tr("Clear Char"), menu);
++ menu->insertAction(actionBefore, clearAction);
++ menu->insertSeparator(actionBefore);
++ clearAction->setEnabled(!m_value.isNull());
++ connect(clearAction, &QAction::triggered, this, &QtCharEdit::slotClearChar);
++ menu->exec(c->globalPos());
++ delete menu;
++ e->accept();
++ return true;
++ }
++
++ return QWidget::eventFilter(o, e);
++ }
++
++ void QtCharEdit::slotClearChar()
++ {
++ if (m_value.isNull())
++ return;
++ setValue(QChar());
++ emit valueChanged(m_value);
++ }
++
++ void QtCharEdit::handleKeyEvent(QKeyEvent *e)
++ {
++ const int key = e->key();
++ switch (key) {
++ case Qt::Key_Control:
++ case Qt::Key_Shift:
++ case Qt::Key_Meta:
++ case Qt::Key_Alt:
++ case Qt::Key_Super_L:
++ case Qt::Key_Return:
++ return;
++ default:
++ break;
++ }
++
++ const QString text = e->text();
++ if (text.size() != 1)
++ return;
++
++ const QChar c = text.at(0);
++ if (!c.isPrint())
++ return;
++
++ if (m_value == c)
++ return;
++
++ m_value = c;
++ const QString str = m_value.isNull() ? QString() : QString(m_value);
++ m_lineEdit->setText(str);
++ e->accept();
++ emit valueChanged(m_value);
++ }
++
++ void QtCharEdit::setValue(const QChar &value)
++ {
++ if (value == m_value)
++ return;
++
++ m_value = value;
++ QString str = value.isNull() ? QString() : QString(value);
++ m_lineEdit->setText(str);
++ }
++
++ QChar QtCharEdit::value() const
++ {
++ return m_value;
++ }
++
++ void QtCharEdit::focusInEvent(QFocusEvent *e)
++ {
++ m_lineEdit->event(e);
++ m_lineEdit->selectAll();
++ QWidget::focusInEvent(e);
++ }
++
++ void QtCharEdit::focusOutEvent(QFocusEvent *e)
++ {
++ m_lineEdit->event(e);
++ QWidget::focusOutEvent(e);
++ }
++
++ void QtCharEdit::keyPressEvent(QKeyEvent *e)
++ {
++ handleKeyEvent(e);
++ e->accept();
++ }
++
++ void QtCharEdit::keyReleaseEvent(QKeyEvent *e)
++ {
++ m_lineEdit->event(e);
++ }
++
++ bool QtCharEdit::event(QEvent *e)
++ {
++ switch(e->type()) {
++ case QEvent::Shortcut:
++ case QEvent::ShortcutOverride:
++ case QEvent::KeyRelease:
++ e->accept();
++ return true;
++ default:
++ break;
++ }
++ return QWidget::event(e);
++ }
++
++ // QtCharEditorFactory
++
++ class QtCharEditorFactoryPrivate : public EditorFactoryPrivate<QtCharEdit>
++ {
++ QtCharEditorFactory *q_ptr = nullptr;
++ Q_DECLARE_PUBLIC(QtCharEditorFactory)
++ public:
++
++ void slotPropertyChanged(QtProperty *property, const QChar &value);
++ void slotSetValue(QtProperty *property, const QChar &value);
++
++ };
++
++ void QtCharEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
++ const QChar &value)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.constEnd())
++ return;
++
++ for (QtCharEdit *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setValue(value);
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtCharEditorFactoryPrivate::slotSetValue(QtProperty *property, const QChar &value)
++ {
++ if (QtCharPropertyManager *manager = q_ptr->propertyManager(property))
++ manager->setValue(property, value);
++ }
++
++ /*!
++ \class QtCharEditorFactory
++ \internal
++ \inmodule QtDesigner
++ \since 4.4
++
++ \brief The QtCharEditorFactory class provides editor
++ widgets for properties created by QtCharPropertyManager objects.
++
++ \sa QtAbstractEditorFactory
++ */
++
++ /*!
++ Creates a factory with the given \a parent.
++ */
++ QtCharEditorFactory::QtCharEditorFactory(QObject *parent)
++ : QtAbstractEditorFactory<QtCharPropertyManager>(parent), d_ptr(new QtCharEditorFactoryPrivate())
++ {
++ d_ptr->q_ptr = this;
++
++ }
++
++ /*!
++ Destroys this factory, and all the widgets it has created.
++ */
++ QtCharEditorFactory::~QtCharEditorFactory()
++ {
++ d_ptr->deleteEditors();
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtCharEditorFactory::connectPropertyManager(QtCharPropertyManager *manager)
++ {
++ connect(manager, &QtCharPropertyManager::valueChanged,
++ this, [this](QtProperty *property, const QChar &value)
++ { d_ptr->slotPropertyChanged(property, value); });
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ QWidget *QtCharEditorFactory::createEditor(QtCharPropertyManager *manager,
++ QtProperty *property, QWidget *parent)
++ {
++ QtCharEdit *editor = d_ptr->createEditor(property, parent);
++ editor->setValue(manager->value(property));
++
++ connect(editor, &QtCharEdit::valueChanged,
++ this, [this, property](const QChar &value) { d_ptr->slotSetValue(property, value); });
++ connect(editor, &QObject::destroyed,
++ this, [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
++ return editor;
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtCharEditorFactory::disconnectPropertyManager(QtCharPropertyManager *manager)
++ {
++ disconnect(manager, &QtCharPropertyManager::valueChanged, this, nullptr);
++ }
++
++ // QtEnumEditorFactory
++
++ class QtEnumEditorFactoryPrivate : public EditorFactoryPrivate<QComboBox>
++ {
++ QtEnumEditorFactory *q_ptr = nullptr;
++ Q_DECLARE_PUBLIC(QtEnumEditorFactory)
++ public:
++
++ void slotPropertyChanged(QtProperty *property, int value);
++ void slotEnumNamesChanged(QtProperty *property, const QStringList &);
++ void slotEnumIconsChanged(QtProperty *property, const QMap<int, QIcon> &);
++ void slotSetValue(QtProperty *property, int value);
++ };
++
++ void QtEnumEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, int value)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.constEnd())
++ return;
++
++ for (QComboBox *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->setCurrentIndex(value);
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtEnumEditorFactoryPrivate::slotEnumNamesChanged(QtProperty *property,
++ const QStringList &enumNames)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.constEnd())
++ return;
++
++ QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
++ if (!manager)
++ return;
++
++ QMap<int, QIcon> enumIcons = manager->enumIcons(property);
++
++ for (QComboBox *editor : it.value()) {
++ editor->blockSignals(true);
++ editor->clear();
++ editor->addItems(enumNames);
++ const auto nameCount = enumNames.size();
++ for (qsizetype i = 0; i < nameCount; i++)
++ editor->setItemIcon(i, enumIcons.value(i));
++ editor->setCurrentIndex(manager->value(property));
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtEnumEditorFactoryPrivate::slotEnumIconsChanged(QtProperty *property,
++ const QMap<int, QIcon> &enumIcons)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.constEnd())
++ return;
++
++ QtEnumPropertyManager *manager = q_ptr->propertyManager(property);
++ if (!manager)
++ return;
++
++ const QStringList enumNames = manager->enumNames(property);
++ for (QComboBox *editor : it.value()) {
++ editor->blockSignals(true);
++ const auto nameCount = enumNames.size();
++ for (qsizetype i = 0; i < nameCount; i++)
++ editor->setItemIcon(i, enumIcons.value(i));
++ editor->setCurrentIndex(manager->value(property));
++ editor->blockSignals(false);
++ }
++ }
++
++ void QtEnumEditorFactoryPrivate::slotSetValue(QtProperty *property, int value)
++ {
++ if (QtEnumPropertyManager *manager = q_ptr->propertyManager(property))
++ manager->setValue(property, value);
++ }
++
++ /*!
++ \class QtEnumEditorFactory
++ \internal
++ \inmodule QtDesigner
++ \since 4.4
++
++ \brief The QtEnumEditorFactory class provides QComboBox widgets for
++ properties created by QtEnumPropertyManager objects.
++
++ \sa QtAbstractEditorFactory, QtEnumPropertyManager
++ */
++
++ /*!
++ Creates a factory with the given \a parent.
++ */
++ QtEnumEditorFactory::QtEnumEditorFactory(QObject *parent)
++ : QtAbstractEditorFactory<QtEnumPropertyManager>(parent), d_ptr(new QtEnumEditorFactoryPrivate())
++ {
++ d_ptr->q_ptr = this;
++
++ }
++
++ /*!
++ Destroys this factory, and all the widgets it has created.
++ */
++ QtEnumEditorFactory::~QtEnumEditorFactory()
++ {
++ d_ptr->deleteEditors();
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtEnumEditorFactory::connectPropertyManager(QtEnumPropertyManager *manager)
++ {
++ connect(manager, &QtEnumPropertyManager::valueChanged,
++ this, [this](QtProperty *property, int value)
++ { d_ptr->slotPropertyChanged(property, value); });
++ connect(manager, &QtEnumPropertyManager::enumNamesChanged,
++ this, [this](QtProperty *property, const QStringList &value)
++ { d_ptr->slotEnumNamesChanged(property, value); });
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ QWidget *QtEnumEditorFactory::createEditor(QtEnumPropertyManager *manager, QtProperty *property,
++ QWidget *parent)
++ {
++ QComboBox *editor = d_ptr->createEditor(property, parent);
++ editor->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
++ editor->view()->setTextElideMode(Qt::ElideRight);
++ QStringList enumNames = manager->enumNames(property);
++ editor->addItems(enumNames);
++ QMap<int, QIcon> enumIcons = manager->enumIcons(property);
++ const auto enumNamesCount = enumNames.size();
++ for (qsizetype i = 0; i < enumNamesCount; i++)
++ editor->setItemIcon(i, enumIcons.value(i));
++ editor->setCurrentIndex(manager->value(property));
++
++ connect(editor, &QComboBox::currentIndexChanged,
++ this, [this, property](int value) { d_ptr->slotSetValue(property, value); });
++ connect(editor, &QObject::destroyed,
++ this, [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
++ return editor;
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtEnumEditorFactory::disconnectPropertyManager(QtEnumPropertyManager *manager)
++ {
++ disconnect(manager, &QtEnumPropertyManager::valueChanged, this, nullptr);
++ disconnect(manager, &QtEnumPropertyManager::enumNamesChanged, this, nullptr);
++ }
++
++ // QtCursorEditorFactory
++
++ class QtCursorEditorFactoryPrivate
++ {
++ QtCursorEditorFactory *q_ptr = nullptr;
++ Q_DECLARE_PUBLIC(QtCursorEditorFactory)
++ public:
++ void slotPropertyChanged(QtProperty *property, const QCursor &cursor);
++ void slotEnumChanged(QtProperty *property, int value);
++ void slotEditorDestroyed(QObject *object);
++
++ QtEnumEditorFactory *m_enumEditorFactory = nullptr;
++ QtEnumPropertyManager *m_enumPropertyManager = nullptr;
++
++ QHash<QtProperty *, QtProperty *> m_propertyToEnum;
++ QHash<QtProperty *, QtProperty *> m_enumToProperty;
++ QHash<QtProperty *, QWidgetList > m_enumToEditors;
++ QHash<QWidget *, QtProperty *> m_editorToEnum;
++ bool m_updatingEnum = false;
++ };
++
++ void QtCursorEditorFactoryPrivate::slotPropertyChanged(QtProperty *property, const QCursor &cursor)
++ {
++ // update enum property
++ QtProperty *enumProp = m_propertyToEnum.value(property);
++ if (!enumProp)
++ return;
++
++ m_updatingEnum = true;
++ auto *cdb = QtCursorDatabase::instance();
++ m_enumPropertyManager->setValue(enumProp, cdb->cursorToValue(cursor));
++ m_updatingEnum = false;
++ }
++
++ void QtCursorEditorFactoryPrivate::slotEnumChanged(QtProperty *property, int value)
++ {
++ if (m_updatingEnum)
++ return;
++ // update cursor property
++ QtProperty *prop = m_enumToProperty.value(property);
++ if (!prop)
++ return;
++ QtCursorPropertyManager *cursorManager = q_ptr->propertyManager(prop);
++ if (!cursorManager)
++ return;
++ #ifndef QT_NO_CURSOR
++ auto *cdb = QtCursorDatabase::instance();
++ cursorManager->setValue(prop, QCursor(cdb->valueToCursor(value)));
++ #endif
++ }
++
++ void QtCursorEditorFactoryPrivate::slotEditorDestroyed(QObject *object)
++ {
++ // remove from m_editorToEnum map;
++ // remove from m_enumToEditors map;
++ // if m_enumToEditors doesn't contains more editors delete enum property;
++ for (auto itEditor = m_editorToEnum.cbegin(), ecend = m_editorToEnum.cend(); itEditor != ecend; ++itEditor)
++ if (itEditor.key() == object) {
++ QWidget *editor = itEditor.key();
++ QtProperty *enumProp = itEditor.value();
++ m_editorToEnum.remove(editor);
++ m_enumToEditors[enumProp].removeAll(editor);
++ if (m_enumToEditors[enumProp].isEmpty()) {
++ m_enumToEditors.remove(enumProp);
++ QtProperty *property = m_enumToProperty.value(enumProp);
++ m_enumToProperty.remove(enumProp);
++ m_propertyToEnum.remove(property);
++ delete enumProp;
++ }
++ return;
++ }
++ }
++
++ /*!
++ \class QtCursorEditorFactory
++ \internal
++ \inmodule QtDesigner
++ \since 4.4
++
++ \brief The QtCursorEditorFactory class provides QComboBox widgets for
++ properties created by QtCursorPropertyManager objects.
++
++ \sa QtAbstractEditorFactory, QtCursorPropertyManager
++ */
++
++ /*!
++ Creates a factory with the given \a parent.
++ */
++ QtCursorEditorFactory::QtCursorEditorFactory(QObject *parent)
++ : QtAbstractEditorFactory<QtCursorPropertyManager>(parent), d_ptr(new QtCursorEditorFactoryPrivate())
++ {
++ d_ptr->q_ptr = this;
++
++ d_ptr->m_enumEditorFactory = new QtEnumEditorFactory(this);
++ d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this);
++ connect(d_ptr->m_enumPropertyManager, &QtEnumPropertyManager::valueChanged,
++ this, [this](QtProperty *property, int value)
++ { d_ptr->slotEnumChanged(property, value); });
++ d_ptr->m_enumEditorFactory->addPropertyManager(d_ptr->m_enumPropertyManager);
++ }
++
++ /*!
++ Destroys this factory, and all the widgets it has created.
++ */
++ QtCursorEditorFactory::~QtCursorEditorFactory() = default;
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtCursorEditorFactory::connectPropertyManager(QtCursorPropertyManager *manager)
++ {
++ connect(manager, &QtCursorPropertyManager::valueChanged,
++ this, [this](QtProperty *property, const QCursor &value)
++ { d_ptr->slotPropertyChanged(property, value); });
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ QWidget *QtCursorEditorFactory::createEditor(QtCursorPropertyManager *manager, QtProperty *property,
++ QWidget *parent)
++ {
++ QtProperty *enumProp = d_ptr->m_propertyToEnum.value(property, nullptr);
++ if (enumProp == nullptr) {
++ enumProp = d_ptr->m_enumPropertyManager->addProperty(property->propertyName());
++ auto *cdb = QtCursorDatabase::instance();
++ d_ptr->m_enumPropertyManager->setEnumNames(enumProp, cdb->cursorShapeNames());
++ d_ptr->m_enumPropertyManager->setEnumIcons(enumProp, cdb->cursorShapeIcons());
++ #ifndef QT_NO_CURSOR
++ d_ptr->m_enumPropertyManager->setValue(enumProp, cdb->cursorToValue(manager->value(property)));
++ #endif
++ d_ptr->m_propertyToEnum[property] = enumProp;
++ d_ptr->m_enumToProperty[enumProp] = property;
++ }
++ QtAbstractEditorFactoryBase *af = d_ptr->m_enumEditorFactory;
++ QWidget *editor = af->createEditor(enumProp, parent);
++ d_ptr->m_enumToEditors[enumProp].append(editor);
++ d_ptr->m_editorToEnum[editor] = enumProp;
++ connect(editor, &QObject::destroyed,
++ this, [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
++ return editor;
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtCursorEditorFactory::disconnectPropertyManager(QtCursorPropertyManager *manager)
++ {
++ disconnect(manager, &QtCursorPropertyManager::valueChanged, this, nullptr);
++ }
++
++ // QtColorEditWidget
++
++ class QtColorEditWidget : public QWidget {
++ Q_OBJECT
++
++ public:
++ QtColorEditWidget(QWidget *parent);
++
++ bool eventFilter(QObject *obj, QEvent *ev) override;
++
++ public Q_SLOTS:
++ void setValue(QColor value);
++
++ private Q_SLOTS:
++ void buttonClicked();
++
++ Q_SIGNALS:
++ void valueChanged(const QColor &value);
++
++ private:
++ void updateColor();
++
++ QColor m_color;
++ QLabel *m_pixmapLabel;
++ QLabel *m_label;
++ QToolButton *m_button;
++ };
++
++ QtColorEditWidget::QtColorEditWidget(QWidget *parent) :
++ QWidget(parent),
++ m_pixmapLabel(new QLabel),
++ m_label(new QLabel),
++ m_button(new QToolButton)
++ {
++ auto *lt = new QHBoxLayout(this);
++ setupTreeViewEditorMargin(lt);
++ lt->setSpacing(0);
++ lt->addWidget(m_pixmapLabel);
++ lt->addWidget(m_label);
++ lt->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
++
++ m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
++ m_button->setFixedWidth(20);
++ setFocusProxy(m_button);
++ setFocusPolicy(m_button->focusPolicy());
++ m_button->setText(tr("..."));
++ m_button->installEventFilter(this);
++ connect(m_button, &QAbstractButton::clicked, this, &QtColorEditWidget::buttonClicked);
++ lt->addWidget(m_button);
++ updateColor();
++ }
++
++ void QtColorEditWidget::setValue(QColor c)
++ {
++ if (m_color != c) {
++ m_color = c;
++ updateColor();
++ }
++ }
++
++ void QtColorEditWidget::updateColor()
++ {
++ const auto pm =
++ QtPropertyBrowserUtils::brushValuePixmap(QBrush(m_color),
++ QtPropertyBrowserUtils::itemViewIconSize,
++ devicePixelRatioF());
++ m_pixmapLabel->setPixmap(pm);
++ m_label->setText(QtPropertyBrowserUtils::colorValueText(m_color));
++ }
++
++ void QtColorEditWidget::buttonClicked()
++ {
++ const QColor newColor = QColorDialog::getColor(m_color, this, QString(), QColorDialog::ShowAlphaChannel);
++ if (newColor.isValid() && newColor != m_color) {
++ setValue(newColor);
++ emit valueChanged(m_color);
++ }
++ }
++
++ bool QtColorEditWidget::eventFilter(QObject *obj, QEvent *ev)
++ {
++ if (obj == m_button) {
++ switch (ev->type()) {
++ case QEvent::KeyPress:
++ case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate
++ switch (static_cast<const QKeyEvent*>(ev)->key()) {
++ case Qt::Key_Escape:
++ case Qt::Key_Enter:
++ case Qt::Key_Return:
++ ev->ignore();
++ return true;
++ default:
++ break;
++ }
++ }
++ break;
++ default:
++ break;
++ }
++ }
++ return QWidget::eventFilter(obj, ev);
++ }
++
++ // QtColorEditorFactoryPrivate
++
++ class QtColorEditorFactoryPrivate : public EditorFactoryPrivate<QtColorEditWidget>
++ {
++ QtColorEditorFactory *q_ptr = nullptr;
++ Q_DECLARE_PUBLIC(QtColorEditorFactory)
++ public:
++
++ void slotPropertyChanged(QtProperty *property, QColor value);
++ void slotSetValue(QtProperty *property, QColor value);
++ };
++
++ void QtColorEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
++ QColor value)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.constEnd())
++ return;
++
++ for (QtColorEditWidget *e : it.value())
++ e->setValue(value);
++ }
++
++ void QtColorEditorFactoryPrivate::slotSetValue(QtProperty *property, QColor value)
++ {
++ if (QtColorPropertyManager *manager = q_ptr->propertyManager(property))
++ manager->setValue(property, value);
++ }
++
++ /*!
++ \class QtColorEditorFactory
++ \internal
++ \inmodule QtDesigner
++ \since 4.4
++
++ \brief The QtColorEditorFactory class provides color editing for
++ properties created by QtColorPropertyManager objects.
++
++ \sa QtAbstractEditorFactory, QtColorPropertyManager
++ */
++
++ /*!
++ Creates a factory with the given \a parent.
++ */
++ QtColorEditorFactory::QtColorEditorFactory(QObject *parent) :
++ QtAbstractEditorFactory<QtColorPropertyManager>(parent),
++ d_ptr(new QtColorEditorFactoryPrivate())
++ {
++ d_ptr->q_ptr = this;
++ }
++
++ /*!
++ Destroys this factory, and all the widgets it has created.
++ */
++ QtColorEditorFactory::~QtColorEditorFactory()
++ {
++ d_ptr->deleteEditors();
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtColorEditorFactory::connectPropertyManager(QtColorPropertyManager *manager)
++ {
++ connect(manager, &QtColorPropertyManager::valueChanged,
++ this, [this](QtProperty *property, QColor value)
++ { d_ptr->slotPropertyChanged(property, value); });
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ QWidget *QtColorEditorFactory::createEditor(QtColorPropertyManager *manager,
++ QtProperty *property, QWidget *parent)
++ {
++ QtColorEditWidget *editor = d_ptr->createEditor(property, parent);
++ editor->setValue(manager->value(property));
++ connect(editor, &QtColorEditWidget::valueChanged,
++ this, [this, property](QColor value) { d_ptr->slotSetValue(property, value); });
++ connect(editor, &QObject::destroyed,
++ this, [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
++ return editor;
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtColorEditorFactory::disconnectPropertyManager(QtColorPropertyManager *manager)
++ {
++ disconnect(manager, &QtColorPropertyManager::valueChanged, this, nullptr);
++ }
++
++ // QtFontEditWidget
++
++ class QtFontEditWidget : public QWidget {
++ Q_OBJECT
++
++ public:
++ QtFontEditWidget(QWidget *parent);
++
++ bool eventFilter(QObject *obj, QEvent *ev) override;
++
++ public Q_SLOTS:
++ void setValue(const QFont &value);
++
++ private Q_SLOTS:
++ void buttonClicked();
++
++ Q_SIGNALS:
++ void valueChanged(const QFont &value);
++
++ private:
++ void updateFont();
++
++ QFont m_font;
++ QLabel *m_pixmapLabel;
++ QLabel *m_label;
++ QToolButton *m_button;
++ };
++
++ QtFontEditWidget::QtFontEditWidget(QWidget *parent) :
++ QWidget(parent),
++ m_pixmapLabel(new QLabel),
++ m_label(new QLabel),
++ m_button(new QToolButton)
++ {
++ auto *lt = new QHBoxLayout(this);
++ setupTreeViewEditorMargin(lt);
++ lt->setSpacing(0);
++ lt->addWidget(m_pixmapLabel);
++ lt->addWidget(m_label);
++ lt->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored));
++
++ m_button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
++ m_button->setFixedWidth(20);
++ setFocusProxy(m_button);
++ setFocusPolicy(m_button->focusPolicy());
++ m_button->setText(tr("..."));
++ m_button->installEventFilter(this);
++ connect(m_button, &QAbstractButton::clicked, this, &QtFontEditWidget::buttonClicked);
++ lt->addWidget(m_button);
++ updateFont();
++ }
++
++ void QtFontEditWidget::updateFont()
++ {
++ const auto pm = QtPropertyBrowserUtils::fontValuePixmap(
++ m_font, QtPropertyBrowserUtils::itemViewIconSize, devicePixelRatioF());
++ m_pixmapLabel->setPixmap(pm);
++ m_label->setText(QtPropertyBrowserUtils::fontValueText(m_font));
++ }
++
++ void QtFontEditWidget::setValue(const QFont &f)
++ {
++ if (m_font != f) {
++ m_font = f;
++ updateFont();
++ }
++ }
++
++ void QtFontEditWidget::buttonClicked()
++ {
++ bool ok = false;
++ QFont newFont = QFontDialog::getFont(&ok, m_font, this, tr("Select Font"));
++ if (ok && newFont != m_font) {
++ QFont f = m_font;
++ // prevent mask for unchanged attributes, don't change other attributes (like kerning, etc...)
++ if (m_font.family() != newFont.family())
++ f.setFamily(newFont.family());
++ if (m_font.pointSize() != newFont.pointSize())
++ f.setPointSize(newFont.pointSize());
++ if (m_font.bold() != newFont.bold())
++ f.setBold(newFont.bold());
++ if (m_font.italic() != newFont.italic())
++ f.setItalic(newFont.italic());
++ if (m_font.underline() != newFont.underline())
++ f.setUnderline(newFont.underline());
++ if (m_font.strikeOut() != newFont.strikeOut())
++ f.setStrikeOut(newFont.strikeOut());
++ setValue(f);
++ emit valueChanged(m_font);
++ }
++ }
++
++ bool QtFontEditWidget::eventFilter(QObject *obj, QEvent *ev)
++ {
++ if (obj == m_button) {
++ switch (ev->type()) {
++ case QEvent::KeyPress:
++ case QEvent::KeyRelease: { // Prevent the QToolButton from handling Enter/Escape meant control the delegate
++ switch (static_cast<const QKeyEvent*>(ev)->key()) {
++ case Qt::Key_Escape:
++ case Qt::Key_Enter:
++ case Qt::Key_Return:
++ ev->ignore();
++ return true;
++ default:
++ break;
++ }
++ }
++ break;
++ default:
++ break;
++ }
++ }
++ return QWidget::eventFilter(obj, ev);
++ }
++
++ // QtFontEditorFactoryPrivate
++
++ class QtFontEditorFactoryPrivate : public EditorFactoryPrivate<QtFontEditWidget>
++ {
++ QtFontEditorFactory *q_ptr = nullptr;
++ Q_DECLARE_PUBLIC(QtFontEditorFactory)
++ public:
++
++ void slotPropertyChanged(QtProperty *property, const QFont &value);
++ void slotSetValue(QtProperty *property, const QFont &value);
++ };
++
++ void QtFontEditorFactoryPrivate::slotPropertyChanged(QtProperty *property,
++ const QFont &value)
++ {
++ const auto it = m_createdEditors.constFind(property);
++ if (it == m_createdEditors.constEnd())
++ return;
++
++ for (QtFontEditWidget *e : it.value())
++ e->setValue(value);
++ }
++
++ void QtFontEditorFactoryPrivate::slotSetValue(QtProperty *property, const QFont &value)
++ {
++ if (QtFontPropertyManager *manager = q_ptr->propertyManager(property))
++ manager->setValue(property, value);
++ }
++
++ /*!
++ \class QtFontEditorFactory
++ \internal
++ \inmodule QtDesigner
++ \since 4.4
++
++ \brief The QtFontEditorFactory class provides font editing for
++ properties created by QtFontPropertyManager objects.
++
++ \sa QtAbstractEditorFactory, QtFontPropertyManager
++ */
++
++ /*!
++ Creates a factory with the given \a parent.
++ */
++ QtFontEditorFactory::QtFontEditorFactory(QObject *parent) :
++ QtAbstractEditorFactory<QtFontPropertyManager>(parent),
++ d_ptr(new QtFontEditorFactoryPrivate())
++ {
++ d_ptr->q_ptr = this;
++ }
++
++ /*!
++ Destroys this factory, and all the widgets it has created.
++ */
++ QtFontEditorFactory::~QtFontEditorFactory()
++ {
++ d_ptr->deleteEditors();
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtFontEditorFactory::connectPropertyManager(QtFontPropertyManager *manager)
++ {
++ connect(manager, &QtFontPropertyManager::valueChanged,
++ this, [this](QtProperty *property, const QFont &value)
++ { d_ptr->slotPropertyChanged(property, value); });
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ QWidget *QtFontEditorFactory::createEditor(QtFontPropertyManager *manager,
++ QtProperty *property, QWidget *parent)
++ {
++ QtFontEditWidget *editor = d_ptr->createEditor(property, parent);
++ editor->setValue(manager->value(property));
++ connect(editor, &QtFontEditWidget::valueChanged,
++ this, [this, property](const QFont &value) { d_ptr->slotSetValue(property, value); });
++ connect(editor, &QObject::destroyed,
++ this, [this](QObject *object) { d_ptr->slotEditorDestroyed(object); });
++ return editor;
++ }
++
++ /*!
++ \internal
++
++ Reimplemented from the QtAbstractEditorFactory class.
++ */
++ void QtFontEditorFactory::disconnectPropertyManager(QtFontPropertyManager *manager)
++ {
++ disconnect(manager, &QtFontPropertyManager::valueChanged, this, nullptr);
++ }
++
++ QT_END_NAMESPACE
++
++ #include "moc_qteditorfactory_p.cpp"
++ #include "qteditorfactory.moc"