1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the Qt Solutions component.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** You may use this file under the terms of the BSD license as follows:
10 **
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
13 ** met:
14 **   * Redistributions of source code must retain the above copyright
15 **     notice, this list of conditions and the following disclaimer.
16 **   * Redistributions in binary form must reproduce the above copyright
17 **     notice, this list of conditions and the following disclaimer in
18 **     the documentation and/or other materials provided with the
19 **     distribution.
20 **   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 **     of its contributors may be used to endorse or promote products derived
22 **     from this software without specific prior written permission.
23 **
24 **
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 
42 #ifndef QTPROPERTYBROWSER_H
43 #define QTPROPERTYBROWSER_H
44 
45 #include <QWidget>
46 #include <QSet>
47 #include <QLineEdit>
48 
49 #if QT_VERSION >= 0x040400
50 QT_BEGIN_NAMESPACE
51 #endif
52 
53 #if defined(Q_OS_WIN)
54 #  if !defined(QT_QTPROPERTYBROWSER_EXPORT) && !defined(QT_QTPROPERTYBROWSER_IMPORT)
55 #    define QT_QTPROPERTYBROWSER_EXPORT
56 #  elif defined(QT_QTPROPERTYBROWSER_IMPORT)
57 #    if defined(QT_QTPROPERTYBROWSER_EXPORT)
58 #      undef QT_QTPROPERTYBROWSER_EXPORT
59 #    endif
60 #    define QT_QTPROPERTYBROWSER_EXPORT __declspec(dllimport)
61 #  elif defined(QT_QTPROPERTYBROWSER_EXPORT)
62 #    undef QT_QTPROPERTYBROWSER_EXPORT
63 #    define QT_QTPROPERTYBROWSER_EXPORT __declspec(dllexport)
64 #  endif
65 #else
66 #  define QT_QTPROPERTYBROWSER_EXPORT
67 #endif
68 
69 typedef QLineEdit::EchoMode EchoMode;
70 
71 class QtAbstractPropertyManager;
72 class QtPropertyPrivate;
73 
74 class QT_QTPROPERTYBROWSER_EXPORT QtProperty
75 {
76 public:
77     virtual ~QtProperty();
78 
79     QList<QtProperty *> subProperties() const;
80 
81     QtAbstractPropertyManager *propertyManager() const;
82 
83     QString toolTip() const;
84     QString statusTip() const;
85     QString whatsThis() const;
86     QString propertyName() const;
87     bool isEnabled() const;
88     bool isModified() const;
89 
90     bool hasValue() const;
91     QIcon valueIcon() const;
92     QString valueText() const;
93     QString displayText() const;
94 
95     void setToolTip(const QString &text);
96     void setStatusTip(const QString &text);
97     void setWhatsThis(const QString &text);
98     void setPropertyName(const QString &text);
99     void setEnabled(bool enable);
100     void setModified(bool modified);
101 
102     void addSubProperty(QtProperty *property);
103     void insertSubProperty(QtProperty *property, QtProperty *afterProperty);
104     void removeSubProperty(QtProperty *property);
105 protected:
106     explicit QtProperty(QtAbstractPropertyManager *manager);
107     void propertyChanged();
108 private:
109     friend class QtAbstractPropertyManager;
110     QtPropertyPrivate *d_ptr;
111 };
112 
113 class QtAbstractPropertyManagerPrivate;
114 
115 class QT_QTPROPERTYBROWSER_EXPORT QtAbstractPropertyManager : public QObject
116 {
117     Q_OBJECT
118 public:
119 
120     explicit QtAbstractPropertyManager(QObject *parent = 0);
121     ~QtAbstractPropertyManager();
122 
123     QSet<QtProperty *> properties() const;
124     void clear() const;
125 
126     QtProperty *addProperty(const QString &name = QString());
127 Q_SIGNALS:
128 
129     void propertyInserted(QtProperty *property,
130                 QtProperty *parent, QtProperty *after);
131     void propertyChanged(QtProperty *property);
132     void propertyRemoved(QtProperty *property, QtProperty *parent);
133     void propertyDestroyed(QtProperty *property);
134 protected:
135     virtual bool hasValue(const QtProperty *property) const;
136     virtual QIcon valueIcon(const QtProperty *property) const;
137     virtual QString valueText(const QtProperty *property) const;
138     virtual QString displayText(const QtProperty *property) const;
139     virtual EchoMode echoMode(const QtProperty *) const;
140     virtual void initializeProperty(QtProperty *property) = 0;
141     virtual void uninitializeProperty(QtProperty *property);
142     virtual QtProperty *createProperty();
143 private:
144     friend class QtProperty;
145     QtAbstractPropertyManagerPrivate *d_ptr;
146     Q_DECLARE_PRIVATE(QtAbstractPropertyManager)
147     Q_DISABLE_COPY(QtAbstractPropertyManager)
148 };
149 
150 class QT_QTPROPERTYBROWSER_EXPORT QtAbstractEditorFactoryBase : public QObject
151 {
152     Q_OBJECT
153 public:
154     virtual QWidget *createEditor(QtProperty *property, QWidget *parent) = 0;
155 protected:
156     explicit QtAbstractEditorFactoryBase(QObject *parent = 0)
QObject(parent)157         : QObject(parent) {}
158 
159     virtual void breakConnection(QtAbstractPropertyManager *manager) = 0;
160 protected Q_SLOTS:
161     virtual void managerDestroyed(QObject *manager) = 0;
162 
163     friend class QtAbstractPropertyBrowser;
164 };
165 
166 template <class PropertyManager>
167 class QtAbstractEditorFactory : public QtAbstractEditorFactoryBase
168 {
169 public:
QtAbstractEditorFactory(QObject * parent)170     explicit QtAbstractEditorFactory(QObject *parent) : QtAbstractEditorFactoryBase(parent) {}
createEditor(QtProperty * property,QWidget * parent)171     QWidget *createEditor(QtProperty *property, QWidget *parent)
172     {
173         QSetIterator<PropertyManager *> it(m_managers);
174         while (it.hasNext()) {
175             PropertyManager *manager = it.next();
176             if (manager == property->propertyManager()) {
177                 return createEditor(manager, property, parent);
178             }
179         }
180         return 0;
181     }
addPropertyManager(PropertyManager * manager)182     void addPropertyManager(PropertyManager *manager)
183     {
184         if (m_managers.contains(manager))
185             return;
186         m_managers.insert(manager);
187         connectPropertyManager(manager);
188         connect(manager, SIGNAL(destroyed(QObject *)),
189                     this, SLOT(managerDestroyed(QObject *)));
190     }
removePropertyManager(PropertyManager * manager)191     void removePropertyManager(PropertyManager *manager)
192     {
193         if (!m_managers.contains(manager))
194             return;
195         disconnect(manager, SIGNAL(destroyed(QObject *)),
196                     this, SLOT(managerDestroyed(QObject *)));
197         disconnectPropertyManager(manager);
198         m_managers.remove(manager);
199     }
propertyManagers()200     QSet<PropertyManager *> propertyManagers() const
201     {
202         return m_managers;
203     }
propertyManager(QtProperty * property)204     PropertyManager *propertyManager(QtProperty *property) const
205     {
206         QtAbstractPropertyManager *manager = property->propertyManager();
207         QSetIterator<PropertyManager *> itManager(m_managers);
208         while (itManager.hasNext()) {
209             PropertyManager *m = itManager.next();
210             if (m == manager) {
211                 return m;
212             }
213         }
214         return 0;
215     }
216 protected:
217     virtual void connectPropertyManager(PropertyManager *manager) = 0;
218     virtual QWidget *createEditor(PropertyManager *manager, QtProperty *property,
219                 QWidget *parent) = 0;
220     virtual void disconnectPropertyManager(PropertyManager *manager) = 0;
managerDestroyed(QObject * manager)221     void managerDestroyed(QObject *manager)
222     {
223         QSetIterator<PropertyManager *> it(m_managers);
224         while (it.hasNext()) {
225             PropertyManager *m = it.next();
226             if (m == manager) {
227                 m_managers.remove(m);
228                 return;
229             }
230         }
231     }
232 private:
breakConnection(QtAbstractPropertyManager * manager)233     void breakConnection(QtAbstractPropertyManager *manager)
234     {
235         QSetIterator<PropertyManager *> it(m_managers);
236         while (it.hasNext()) {
237             PropertyManager *m = it.next();
238             if (m == manager) {
239                 removePropertyManager(m);
240                 return;
241             }
242         }
243     }
244 private:
245     QSet<PropertyManager *> m_managers;
246     friend class QtAbstractPropertyEditor;
247 };
248 
249 class QtAbstractPropertyBrowser;
250 class QtBrowserItemPrivate;
251 
252 class QT_QTPROPERTYBROWSER_EXPORT QtBrowserItem
253 {
254 public:
255     QtProperty *property() const;
256     QtBrowserItem *parent() const;
257     QList<QtBrowserItem *> children() const;
258     QtAbstractPropertyBrowser *browser() const;
259 private:
260     explicit QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent);
261     ~QtBrowserItem();
262     QtBrowserItemPrivate *d_ptr;
263     friend class QtAbstractPropertyBrowserPrivate;
264 };
265 
266 class QtAbstractPropertyBrowserPrivate;
267 
268 class QT_QTPROPERTYBROWSER_EXPORT QtAbstractPropertyBrowser : public QWidget
269 {
270     Q_OBJECT
271 public:
272 
273     explicit QtAbstractPropertyBrowser(QWidget *parent = 0);
274     ~QtAbstractPropertyBrowser();
275 
276     QList<QtProperty *> properties() const;
277     QList<QtBrowserItem *> items(QtProperty *property) const;
278     QtBrowserItem *topLevelItem(QtProperty *property) const;
279     QList<QtBrowserItem *> topLevelItems() const;
280     void clear();
281 
282     template <class PropertyManager>
setFactoryForManager(PropertyManager * manager,QtAbstractEditorFactory<PropertyManager> * factory)283     void setFactoryForManager(PropertyManager *manager,
284                     QtAbstractEditorFactory<PropertyManager> *factory) {
285         QtAbstractPropertyManager *abstractManager = manager;
286         QtAbstractEditorFactoryBase *abstractFactory = factory;
287 
288         if (addFactory(abstractManager, abstractFactory))
289             factory->addPropertyManager(manager);
290     }
291 
292     void unsetFactoryForManager(QtAbstractPropertyManager *manager);
293 
294     QtBrowserItem *currentItem() const;
295     void setCurrentItem(QtBrowserItem *);
296 
297 Q_SIGNALS:
298     void currentItemChanged(QtBrowserItem *);
299 
300 public Q_SLOTS:
301 
302     QtBrowserItem *addProperty(QtProperty *property);
303     QtBrowserItem *insertProperty(QtProperty *property, QtProperty *afterProperty);
304     void removeProperty(QtProperty *property);
305 
306 protected:
307 
308     virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) = 0;
309     virtual void itemRemoved(QtBrowserItem *item) = 0;
310     // can be tooltip, statustip, whatsthis, name, icon, text.
311     virtual void itemChanged(QtBrowserItem *item) = 0;
312 
313     virtual QWidget *createEditor(QtProperty *property, QWidget *parent);
314 private:
315 
316     bool addFactory(QtAbstractPropertyManager *abstractManager,
317                 QtAbstractEditorFactoryBase *abstractFactory);
318 
319     QtAbstractPropertyBrowserPrivate *d_ptr;
320     Q_DECLARE_PRIVATE(QtAbstractPropertyBrowser)
321     Q_DISABLE_COPY(QtAbstractPropertyBrowser)
322     Q_PRIVATE_SLOT(d_func(), void slotPropertyInserted(QtProperty *,
323                             QtProperty *, QtProperty *))
324     Q_PRIVATE_SLOT(d_func(), void slotPropertyRemoved(QtProperty *,
325                             QtProperty *))
326     Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
327     Q_PRIVATE_SLOT(d_func(), void slotPropertyDataChanged(QtProperty *))
328 
329 };
330 
331 #if QT_VERSION >= 0x040400
332 QT_END_NAMESPACE
333 #endif
334 
335 #endif // QTPROPERTYBROWSER_H
336