1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the tools applications of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QTPROPERTYBROWSER_H
41 #define QTPROPERTYBROWSER_H
42 
43 #include <QtWidgets/QWidget>
44 #include <QtCore/QSet>
45 
46 QT_BEGIN_NAMESPACE
47 
48 class QtAbstractPropertyManager;
49 class QtPropertyPrivate;
50 
51 class QtProperty
52 {
53 public:
54     virtual ~QtProperty();
55 
56     QList<QtProperty *> subProperties() const;
57 
58     QtAbstractPropertyManager *propertyManager() const;
59 
toolTip()60     QString toolTip() const { return valueToolTip(); } // Compatibility
61     QString valueToolTip() const;
62     QString descriptionToolTip() const;
63     QString statusTip() const;
64     QString whatsThis() const;
65     QString propertyName() const;
66     bool isEnabled() const;
67     bool isModified() const;
68 
69     bool hasValue() const;
70     QIcon valueIcon() const;
71     QString valueText() const;
72 
setToolTip(const QString & text)73     void setToolTip(const QString &text) { setValueToolTip(text); }  // Compatibility
74     void setValueToolTip(const QString &text);
75     void setDescriptionToolTip(const QString &text);
76     void setStatusTip(const QString &text);
77     void setWhatsThis(const QString &text);
78     void setPropertyName(const QString &text);
79     void setEnabled(bool enable);
80     void setModified(bool modified);
81 
82     void addSubProperty(QtProperty *property);
83     void insertSubProperty(QtProperty *property, QtProperty *afterProperty);
84     void removeSubProperty(QtProperty *property);
85 protected:
86     explicit QtProperty(QtAbstractPropertyManager *manager);
87     void propertyChanged();
88 private:
89     friend class QtAbstractPropertyManager;
90     QScopedPointer<QtPropertyPrivate> d_ptr;
91 };
92 
93 class QtAbstractPropertyManagerPrivate;
94 
95 class QtAbstractPropertyManager : public QObject
96 {
97     Q_OBJECT
98 public:
99 
100     explicit QtAbstractPropertyManager(QObject *parent = 0);
101     ~QtAbstractPropertyManager();
102 
103     QSet<QtProperty *> properties() const;
104     void clear() const;
105 
106     QtProperty *addProperty(const QString &name = QString());
107 Q_SIGNALS:
108 
109     void propertyInserted(QtProperty *property,
110                 QtProperty *parent, QtProperty *after);
111     void propertyChanged(QtProperty *property);
112     void propertyRemoved(QtProperty *property, QtProperty *parent);
113     void propertyDestroyed(QtProperty *property);
114 protected:
115     virtual bool hasValue(const QtProperty *property) const;
116     virtual QIcon valueIcon(const QtProperty *property) const;
117     virtual QString valueText(const QtProperty *property) const;
118     virtual void initializeProperty(QtProperty *property) = 0;
119     virtual void uninitializeProperty(QtProperty *property);
120     virtual QtProperty *createProperty();
121 private:
122     friend class QtProperty;
123     QScopedPointer<QtAbstractPropertyManagerPrivate> d_ptr;
124     Q_DECLARE_PRIVATE(QtAbstractPropertyManager)
125     Q_DISABLE_COPY_MOVE(QtAbstractPropertyManager)
126 };
127 
128 class QtAbstractEditorFactoryBase : public QObject
129 {
130     Q_OBJECT
131 public:
132     virtual QWidget *createEditor(QtProperty *property, QWidget *parent) = 0;
133 protected:
134     explicit QtAbstractEditorFactoryBase(QObject *parent = 0)
QObject(parent)135         : QObject(parent) {}
136 
137     virtual void breakConnection(QtAbstractPropertyManager *manager) = 0;
138 protected Q_SLOTS:
139     virtual void managerDestroyed(QObject *manager) = 0;
140 
141     friend class QtAbstractPropertyBrowser;
142 };
143 
144 template <class PropertyManager>
145 class QtAbstractEditorFactory : public QtAbstractEditorFactoryBase
146 {
147 public:
QtAbstractEditorFactory(QObject * parent)148     explicit QtAbstractEditorFactory(QObject *parent) : QtAbstractEditorFactoryBase(parent) {}
createEditor(QtProperty * property,QWidget * parent)149     QWidget *createEditor(QtProperty *property, QWidget *parent)
150     {
151         for (PropertyManager *manager : qAsConst(m_managers)) {
152             if (manager == property->propertyManager()) {
153                 return createEditor(manager, property, parent);
154             }
155         }
156         return 0;
157     }
addPropertyManager(PropertyManager * manager)158     void addPropertyManager(PropertyManager *manager)
159     {
160         if (m_managers.contains(manager))
161             return;
162         m_managers.insert(manager);
163         connectPropertyManager(manager);
164         connect(manager, SIGNAL(destroyed(QObject *)),
165                     this, SLOT(managerDestroyed(QObject *)));
166     }
removePropertyManager(PropertyManager * manager)167     void removePropertyManager(PropertyManager *manager)
168     {
169         if (!m_managers.contains(manager))
170             return;
171         disconnect(manager, SIGNAL(destroyed(QObject *)),
172                     this, SLOT(managerDestroyed(QObject *)));
173         disconnectPropertyManager(manager);
174         m_managers.remove(manager);
175     }
propertyManagers()176     QSet<PropertyManager *> propertyManagers() const
177     {
178         return m_managers;
179     }
propertyManager(QtProperty * property)180     PropertyManager *propertyManager(QtProperty *property) const
181     {
182         QtAbstractPropertyManager *manager = property->propertyManager();
183         for (PropertyManager *m : qAsConst(m_managers)) {
184             if (m == manager) {
185                 return m;
186             }
187         }
188         return 0;
189     }
190 protected:
191     virtual void connectPropertyManager(PropertyManager *manager) = 0;
192     virtual QWidget *createEditor(PropertyManager *manager, QtProperty *property,
193                 QWidget *parent) = 0;
194     virtual void disconnectPropertyManager(PropertyManager *manager) = 0;
managerDestroyed(QObject * manager)195     void managerDestroyed(QObject *manager)
196     {
197         for (PropertyManager *m : qAsConst(m_managers)) {
198             if (m == manager) {
199                 m_managers.remove(m);
200                 return;
201             }
202         }
203     }
204 private:
breakConnection(QtAbstractPropertyManager * manager)205     void breakConnection(QtAbstractPropertyManager *manager)
206     {
207         for (PropertyManager *m : qAsConst(m_managers)) {
208             if (m == manager) {
209                 removePropertyManager(m);
210                 return;
211             }
212         }
213     }
214 private:
215     QSet<PropertyManager *> m_managers;
216     friend class QtAbstractPropertyEditor;
217 };
218 
219 class QtAbstractPropertyBrowser;
220 class QtBrowserItemPrivate;
221 
222 class QtBrowserItem
223 {
224 public:
225     QtProperty *property() const;
226     QtBrowserItem *parent() const;
227     QList<QtBrowserItem *> children() const;
228     QtAbstractPropertyBrowser *browser() const;
229 private:
230     explicit QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent);
231     ~QtBrowserItem();
232     QScopedPointer<QtBrowserItemPrivate> d_ptr;
233     friend class QtAbstractPropertyBrowserPrivate;
234 };
235 
236 class QtAbstractPropertyBrowserPrivate;
237 
238 class QtAbstractPropertyBrowser : public QWidget
239 {
240     Q_OBJECT
241 public:
242 
243     explicit QtAbstractPropertyBrowser(QWidget *parent = 0);
244     ~QtAbstractPropertyBrowser();
245 
246     QList<QtProperty *> properties() const;
247     QList<QtBrowserItem *> items(QtProperty *property) const;
248     QtBrowserItem *topLevelItem(QtProperty *property) const;
249     QList<QtBrowserItem *> topLevelItems() const;
250     void clear();
251 
252     template <class PropertyManager>
setFactoryForManager(PropertyManager * manager,QtAbstractEditorFactory<PropertyManager> * factory)253     void setFactoryForManager(PropertyManager *manager,
254                     QtAbstractEditorFactory<PropertyManager> *factory) {
255         QtAbstractPropertyManager *abstractManager = manager;
256         QtAbstractEditorFactoryBase *abstractFactory = factory;
257 
258         if (addFactory(abstractManager, abstractFactory))
259             factory->addPropertyManager(manager);
260     }
261 
262     void unsetFactoryForManager(QtAbstractPropertyManager *manager);
263 
264     QtBrowserItem *currentItem() const;
265     void setCurrentItem(QtBrowserItem *);
266 
267 Q_SIGNALS:
268     void currentItemChanged(QtBrowserItem *);
269 
270 public Q_SLOTS:
271 
272     QtBrowserItem *addProperty(QtProperty *property);
273     QtBrowserItem *insertProperty(QtProperty *property, QtProperty *afterProperty);
274     void removeProperty(QtProperty *property);
275 
276 protected:
277 
278     virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) = 0;
279     virtual void itemRemoved(QtBrowserItem *item) = 0;
280     // can be tooltip, statustip, whatsthis, name, icon, text.
281     virtual void itemChanged(QtBrowserItem *item) = 0;
282 
283     virtual QWidget *createEditor(QtProperty *property, QWidget *parent);
284 private:
285 
286     bool addFactory(QtAbstractPropertyManager *abstractManager,
287                 QtAbstractEditorFactoryBase *abstractFactory);
288 
289     QScopedPointer<QtAbstractPropertyBrowserPrivate> d_ptr;
290     Q_DECLARE_PRIVATE(QtAbstractPropertyBrowser)
291     Q_DISABLE_COPY_MOVE(QtAbstractPropertyBrowser)
292     Q_PRIVATE_SLOT(d_func(), void slotPropertyInserted(QtProperty *,
293                             QtProperty *, QtProperty *))
294     Q_PRIVATE_SLOT(d_func(), void slotPropertyRemoved(QtProperty *,
295                             QtProperty *))
296     Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
297     Q_PRIVATE_SLOT(d_func(), void slotPropertyDataChanged(QtProperty *))
298 
299 };
300 
301 QT_END_NAMESPACE
302 
303 #endif // QTPROPERTYBROWSER_H
304