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 <QtWidgets/QLineEdit> 46 #include <QtCore/QSet> 47 48 typedef QLineEdit::EchoMode EchoMode; 49 50 QT_BEGIN_NAMESPACE 51 52 class QtAbstractPropertyManager; 53 class QtPropertyPrivate; 54 55 class QtProperty 56 { 57 public: 58 virtual ~QtProperty(); 59 60 QList<QtProperty *> subProperties() const; 61 62 QtAbstractPropertyManager *propertyManager() const; 63 64 QString toolTip() const; 65 QString statusTip() const; 66 QString whatsThis() const; 67 QString propertyName() const; 68 bool isEnabled() const; 69 bool isModified() const; 70 71 bool hasValue() const; 72 QIcon valueIcon() const; 73 QString valueText() const; 74 QString displayText() const; 75 76 void setToolTip(const QString &text); 77 void setStatusTip(const QString &text); 78 void setWhatsThis(const QString &text); 79 void setPropertyName(const QString &text); 80 void setEnabled(bool enable); 81 void setModified(bool modified); 82 83 void addSubProperty(QtProperty *property); 84 void insertSubProperty(QtProperty *property, QtProperty *afterProperty); 85 void removeSubProperty(QtProperty *property); 86 protected: 87 explicit QtProperty(QtAbstractPropertyManager *manager); 88 void propertyChanged(); 89 private: 90 friend class QtAbstractPropertyManager; 91 QtPropertyPrivate *d_ptr; 92 }; 93 94 class QtAbstractPropertyManagerPrivate; 95 96 class QtAbstractPropertyManager : public QObject 97 { 98 Q_OBJECT 99 public: 100 101 explicit QtAbstractPropertyManager(QObject *parent = 0); 102 ~QtAbstractPropertyManager(); 103 104 QSet<QtProperty *> properties() const; 105 void clear() const; 106 107 QtProperty *addProperty(const QString &name = QString()); 108 Q_SIGNALS: 109 110 void propertyInserted(QtProperty *property, 111 QtProperty *parent, QtProperty *after); 112 void propertyChanged(QtProperty *property); 113 void propertyRemoved(QtProperty *property, QtProperty *parent); 114 void propertyDestroyed(QtProperty *property); 115 protected: 116 virtual bool hasValue(const QtProperty *property) const; 117 virtual QIcon valueIcon(const QtProperty *property) const; 118 virtual QString valueText(const QtProperty *property) const; 119 virtual QString displayText(const QtProperty *property) const; 120 virtual EchoMode echoMode(const QtProperty *) const; 121 virtual void initializeProperty(QtProperty *property) = 0; 122 virtual void uninitializeProperty(QtProperty *property); 123 virtual QtProperty *createProperty(); 124 private: 125 friend class QtProperty; 126 QtAbstractPropertyManagerPrivate *d_ptr; 127 Q_DECLARE_PRIVATE(QtAbstractPropertyManager) 128 Q_DISABLE_COPY(QtAbstractPropertyManager) 129 }; 130 131 class QtAbstractEditorFactoryBase : public QObject 132 { 133 Q_OBJECT 134 public: 135 virtual QWidget *createEditor(QtProperty *property, QWidget *parent) = 0; 136 protected: 137 explicit QtAbstractEditorFactoryBase(QObject *parent = 0) QObject(parent)138 : QObject(parent) {} 139 140 virtual void breakConnection(QtAbstractPropertyManager *manager) = 0; 141 protected Q_SLOTS: 142 virtual void managerDestroyed(QObject *manager) = 0; 143 144 friend class QtAbstractPropertyBrowser; 145 }; 146 147 template <class PropertyManager> 148 class QtAbstractEditorFactory : public QtAbstractEditorFactoryBase 149 { 150 public: QtAbstractEditorFactory(QObject * parent)151 explicit QtAbstractEditorFactory(QObject *parent) : QtAbstractEditorFactoryBase(parent) {} createEditor(QtProperty * property,QWidget * parent)152 QWidget *createEditor(QtProperty *property, QWidget *parent) 153 { 154 QSetIterator<PropertyManager *> it(m_managers); 155 while (it.hasNext()) { 156 PropertyManager *manager = it.next(); 157 if (manager == property->propertyManager()) { 158 return createEditor(manager, property, parent); 159 } 160 } 161 return 0; 162 } addPropertyManager(PropertyManager * manager)163 void addPropertyManager(PropertyManager *manager) 164 { 165 if (m_managers.contains(manager)) 166 return; 167 m_managers.insert(manager); 168 connectPropertyManager(manager); 169 connect(manager, SIGNAL(destroyed(QObject *)), 170 this, SLOT(managerDestroyed(QObject *))); 171 } removePropertyManager(PropertyManager * manager)172 void removePropertyManager(PropertyManager *manager) 173 { 174 if (!m_managers.contains(manager)) 175 return; 176 disconnect(manager, SIGNAL(destroyed(QObject *)), 177 this, SLOT(managerDestroyed(QObject *))); 178 disconnectPropertyManager(manager); 179 m_managers.remove(manager); 180 } propertyManagers()181 QSet<PropertyManager *> propertyManagers() const 182 { 183 return m_managers; 184 } propertyManager(QtProperty * property)185 PropertyManager *propertyManager(QtProperty *property) const 186 { 187 QtAbstractPropertyManager *manager = property->propertyManager(); 188 QSetIterator<PropertyManager *> itManager(m_managers); 189 while (itManager.hasNext()) { 190 PropertyManager *m = itManager.next(); 191 if (m == manager) { 192 return m; 193 } 194 } 195 return 0; 196 } 197 protected: 198 virtual void connectPropertyManager(PropertyManager *manager) = 0; 199 virtual QWidget *createEditor(PropertyManager *manager, QtProperty *property, 200 QWidget *parent) = 0; 201 virtual void disconnectPropertyManager(PropertyManager *manager) = 0; managerDestroyed(QObject * manager)202 void managerDestroyed(QObject *manager) 203 { 204 QSetIterator<PropertyManager *> it(m_managers); 205 while (it.hasNext()) { 206 PropertyManager *m = it.next(); 207 if (m == manager) { 208 m_managers.remove(m); 209 return; 210 } 211 } 212 } 213 private: breakConnection(QtAbstractPropertyManager * manager)214 void breakConnection(QtAbstractPropertyManager *manager) 215 { 216 QSetIterator<PropertyManager *> it(m_managers); 217 while (it.hasNext()) { 218 PropertyManager *m = it.next(); 219 if (m == manager) { 220 removePropertyManager(m); 221 return; 222 } 223 } 224 } 225 private: 226 QSet<PropertyManager *> m_managers; 227 friend class QtAbstractPropertyEditor; 228 }; 229 230 class QtAbstractPropertyBrowser; 231 class QtBrowserItemPrivate; 232 233 class QtBrowserItem 234 { 235 public: 236 QtProperty *property() const; 237 QtBrowserItem *parent() const; 238 QList<QtBrowserItem *> children() const; 239 QtAbstractPropertyBrowser *browser() const; 240 private: 241 explicit QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent); 242 ~QtBrowserItem(); 243 QtBrowserItemPrivate *d_ptr; 244 friend class QtAbstractPropertyBrowserPrivate; 245 }; 246 247 class QtAbstractPropertyBrowserPrivate; 248 249 class QtAbstractPropertyBrowser : public QWidget 250 { 251 Q_OBJECT 252 public: 253 254 explicit QtAbstractPropertyBrowser(QWidget *parent = 0); 255 ~QtAbstractPropertyBrowser(); 256 257 QList<QtProperty *> properties() const; 258 QList<QtBrowserItem *> items(QtProperty *property) const; 259 QtBrowserItem *topLevelItem(QtProperty *property) const; 260 QList<QtBrowserItem *> topLevelItems() const; 261 void clear(); 262 263 template <class PropertyManager> setFactoryForManager(PropertyManager * manager,QtAbstractEditorFactory<PropertyManager> * factory)264 void setFactoryForManager(PropertyManager *manager, 265 QtAbstractEditorFactory<PropertyManager> *factory) { 266 QtAbstractPropertyManager *abstractManager = manager; 267 QtAbstractEditorFactoryBase *abstractFactory = factory; 268 269 if (addFactory(abstractManager, abstractFactory)) 270 factory->addPropertyManager(manager); 271 } 272 273 void unsetFactoryForManager(QtAbstractPropertyManager *manager); 274 275 QtBrowserItem *currentItem() const; 276 void setCurrentItem(QtBrowserItem *); 277 278 Q_SIGNALS: 279 void currentItemChanged(QtBrowserItem *); 280 281 public Q_SLOTS: 282 283 QtBrowserItem *addProperty(QtProperty *property); 284 QtBrowserItem *insertProperty(QtProperty *property, QtProperty *afterProperty); 285 void removeProperty(QtProperty *property); 286 287 protected: 288 289 virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem) = 0; 290 virtual void itemRemoved(QtBrowserItem *item) = 0; 291 // can be tooltip, statustip, whatsthis, name, icon, text. 292 virtual void itemChanged(QtBrowserItem *item) = 0; 293 294 virtual QWidget *createEditor(QtProperty *property, QWidget *parent); 295 private: 296 297 bool addFactory(QtAbstractPropertyManager *abstractManager, 298 QtAbstractEditorFactoryBase *abstractFactory); 299 300 QtAbstractPropertyBrowserPrivate *d_ptr; 301 Q_DECLARE_PRIVATE(QtAbstractPropertyBrowser) 302 Q_DISABLE_COPY(QtAbstractPropertyBrowser) 303 Q_PRIVATE_SLOT(d_func(), void slotPropertyInserted(QtProperty *, 304 QtProperty *, QtProperty *)) 305 Q_PRIVATE_SLOT(d_func(), void slotPropertyRemoved(QtProperty *, 306 QtProperty *)) 307 Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *)) 308 Q_PRIVATE_SLOT(d_func(), void slotPropertyDataChanged(QtProperty *)) 309 310 }; 311 312 QT_END_NAMESPACE 313 314 #endif // QTPROPERTYBROWSER_H 315