// 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 #ifndef QTPROPERTYBROWSER_H #define QTPROPERTYBROWSER_H #include #include QT_BEGIN_NAMESPACE class QtAbstractPropertyManager; class QtPropertyPrivate; class QtProperty { public: virtual ~QtProperty(); QList subProperties() const; QtAbstractPropertyManager *propertyManager() const; QString toolTip() const { return valueToolTip(); } // Compatibility QString valueToolTip() const; QString descriptionToolTip() const; QString statusTip() const; QString whatsThis() const; QString propertyName() const; bool isEnabled() const; bool isModified() const; bool hasValue() const; QIcon valueIcon() const; QString valueText() const; void setToolTip(const QString &text) { setValueToolTip(text); } // Compatibility void setValueToolTip(const QString &text); void setDescriptionToolTip(const QString &text); void setStatusTip(const QString &text); void setWhatsThis(const QString &text); void setPropertyName(const QString &text); void setEnabled(bool enable); void setModified(bool modified); void addSubProperty(QtProperty *property); void insertSubProperty(QtProperty *property, QtProperty *afterProperty); void removeSubProperty(QtProperty *property); protected: explicit QtProperty(QtAbstractPropertyManager *manager); void propertyChanged(); private: friend class QtAbstractPropertyManager; QScopedPointer d_ptr; }; class QtAbstractPropertyManagerPrivate; class QtAbstractPropertyManager : public QObject { Q_OBJECT public: explicit QtAbstractPropertyManager(QObject *parent = 0); ~QtAbstractPropertyManager(); QSet properties() const; void clear() const; QtProperty *addProperty(const QString &name = QString()); Q_SIGNALS: void propertyInserted(QtProperty *property, QtProperty *parent, QtProperty *after); void propertyChanged(QtProperty *property); void propertyRemoved(QtProperty *property, QtProperty *parent); void propertyDestroyed(QtProperty *property); protected: virtual bool hasValue(const QtProperty *property) const; virtual QIcon valueIcon(const QtProperty *property) const; virtual QString valueText(const QtProperty *property) const; virtual void initializeProperty(QtProperty *property) = 0; virtual void uninitializeProperty(QtProperty *property); virtual QtProperty *createProperty(); private: friend class QtProperty; QScopedPointer d_ptr; Q_DECLARE_PRIVATE(QtAbstractPropertyManager) Q_DISABLE_COPY_MOVE(QtAbstractPropertyManager) }; class QtAbstractEditorFactoryBase : public QObject { Q_OBJECT public: virtual QWidget *createEditor(QtProperty *property, QWidget *parent) = 0; protected: explicit QtAbstractEditorFactoryBase(QObject *parent = 0) : QObject(parent) {} virtual void breakConnection(QtAbstractPropertyManager *manager) = 0; protected Q_SLOTS: virtual void managerDestroyed(QObject *manager) = 0; friend class QtAbstractPropertyBrowser; }; template class QtAbstractEditorFactory : public QtAbstractEditorFactoryBase { public: explicit QtAbstractEditorFactory(QObject *parent) : QtAbstractEditorFactoryBase(parent) {} QWidget *createEditor(QtProperty *property, QWidget *parent) override { for (PropertyManager *manager : std::as_const(m_managers)) { if (manager == property->propertyManager()) { return createEditor(manager, property, parent); } } return 0; } void addPropertyManager(PropertyManager *manager) { if (m_managers.contains(manager)) return; m_managers.insert(manager); connectPropertyManager(manager); connect(manager, &QObject::destroyed, this, &QtAbstractEditorFactory::managerDestroyed); } void removePropertyManager(PropertyManager *manager) { if (!m_managers.contains(manager)) return; disconnect(manager, &QObject::destroyed, this, &QtAbstractEditorFactory::managerDestroyed); disconnectPropertyManager(manager); m_managers.remove(manager); } QSet propertyManagers() const { return m_managers; } PropertyManager *propertyManager(QtProperty *property) const { QtAbstractPropertyManager *manager = property->propertyManager(); for (PropertyManager *m : std::as_const(m_managers)) { if (m == manager) { return m; } } return 0; } protected: virtual void connectPropertyManager(PropertyManager *manager) = 0; virtual QWidget *createEditor(PropertyManager *manager, QtProperty *property, QWidget *parent) = 0; virtual void disconnectPropertyManager(PropertyManager *manager) = 0; void managerDestroyed(QObject *manager) override { for (PropertyManager *m : std::as_const(m_managers)) { if (m == manager) { m_managers.remove(m); return; } } } private: void breakConnection(QtAbstractPropertyManager *manager) override { for (PropertyManager *m : std::as_const(m_managers)) { if (m == manager) { removePropertyManager(m); return; } } } private: QSet m_managers; friend class QtAbstractPropertyEditor; }; class QtAbstractPropertyBrowser; class QtBrowserItemPrivate; class QtBrowserItem { public: QtProperty *property() const; QtBrowserItem *parent() const; QList children() const; QtAbstractPropertyBrowser *browser() const; private: explicit QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent); ~QtBrowserItem(); QScopedPointer d_ptr; friend class QtAbstractPropertyBrowserPrivate; }; class QtAbstractPropertyBrowserPrivate; class QtAbstractPropertyBrowser : public QWidget { Q_OBJECT public: explicit QtAbstractPropertyBrowser(QWidget *parent = 0); ~QtAbstractPropertyBrowser(); QList properties() const; QList items(QtProperty *property) const; QtBrowserItem *topLevelItem(QtProperty *property) const; QList topLevelItems() const; void clear(); template void setFactoryForManager(PropertyManager *manager, QtAbstractEditorFactory *factory) { QtAbstractPropertyManager *abstractManager = manager; QtAbstractEditorFactoryBase *abstractFactory = factory; if (addFactory(abstractManager, abstractFactory)) factory->addPropertyManager(manager); } void unsetFactoryForManager(QtAbstractPropertyManager *manager); QtBrowserItem *currentItem() const; void setCurrentItem(QtBrowserItem *); Q_SIGNALS: void currentItemChanged(QtBrowserItem *); public Q_SLOTS: QtBrowserItem *addProperty(QtProperty *property); QtBrowserItem *insertProperty(QtProperty *property, QtProperty *afterProperty); void removeProperty(QtProperty *property); protected: virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) = 0; virtual void itemRemoved(QtBrowserItem *item) = 0; // can be tooltip, statustip, whatsthis, name, icon, text. virtual void itemChanged(QtBrowserItem *item) = 0; virtual QWidget *createEditor(QtProperty *property, QWidget *parent); private: bool addFactory(QtAbstractPropertyManager *abstractManager, QtAbstractEditorFactoryBase *abstractFactory); QScopedPointer d_ptr; Q_DECLARE_PRIVATE(QtAbstractPropertyBrowser) Q_DISABLE_COPY_MOVE(QtAbstractPropertyBrowser) }; QT_END_NAMESPACE #endif // QTPROPERTYBROWSER_H