text: /****************************************************************************
  **
  ** This file is part of a Qt Solutions component.
  ** 
  ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
  ** 
  ** Contact:  Qt Software Information (qt-info@nokia.com)
  ** 
  ** Commercial Usage  
  ** Licensees holding valid Qt Commercial licenses may use this file in
  ** accordance with the Qt Solutions Commercial License Agreement provided
  ** with the Software or, alternatively, in accordance with the terms
  ** contained in a written agreement between you and Nokia.
  ** 
  ** GNU Lesser General Public License Usage
  ** Alternatively, this file may be used under the terms of the GNU Lesser
  ** General Public License version 2.1 as published by the Free Software
  ** Foundation and appearing in the file LICENSE.LGPL included in the
  ** packaging of this file.  Please review the following information to
  ** ensure the GNU Lesser General Public License version 2.1 requirements
  ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  ** 
  ** In addition, as a special exception, Nokia gives you certain
  ** additional rights. These rights are described in the Nokia Qt LGPL
  ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
  ** package.
  ** 
  ** GNU General Public License Usage 
  ** Alternatively, this file may be used under the terms of the GNU
  ** General Public License version 3.0 as published by the Free Software
  ** Foundation and appearing in the file LICENSE.GPL included in the
  ** packaging of this file.  Please review the following information to
  ** ensure the GNU General Public License version 3.0 requirements will be
  ** met: http://www.gnu.org/copyleft/gpl.html.
  ** 
  ** Please note Third Party Software included with Qt Solutions may impose
  ** additional restrictions and it is the user's responsibility to ensure
  ** that they have met the licensing requirements of the GPL, LGPL, or Qt
  ** Solutions Commercial license and the relevant license of the Third
  ** Party Software they are using.
  ** 
  ** If you are unsure which license is appropriate for your use, please
  ** contact the sales department at qt-sales@nokia.com.
  ** 
  ****************************************************************************/
  
  /****************************************************************************
  **
  ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
  ** Contact: Qt Software Information (qt-info@nokia.com)
  **
  ** This file is part of the tools applications of the Qt Toolkit.
  **
  ** $QT_BEGIN_LICENSE:LGPL$
  ** No Commercial Usage
  ** This file contains pre-release code and may not be distributed.
  ** You may use this file in accordance with the terms and conditions
  ** contained in the either Technology Preview License Agreement or the
  ** Beta Release License Agreement.
  **
  ** GNU Lesser General Public License Usage
  ** Alternatively, this file may be used under the terms of the GNU Lesser
  ** General Public License version 2.1 as published by the Free Software
  ** Foundation and appearing in the file LICENSE.LGPL included in the
  ** packaging of this file.  Please review the following information to
  ** ensure the GNU Lesser General Public License version 2.1 requirements
  ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  **
  ** In addition, as a special exception, Nokia gives you certain
  ** additional rights. These rights are described in the Nokia Qt LGPL
  ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
  ** package.
  **
  ** GNU General Public License Usage
  ** Alternatively, this file may be used under the terms of the GNU
  ** General Public License version 3.0 as published by the Free Software
  ** Foundation and appearing in the file LICENSE.GPL included in the
  ** packaging of this file.  Please review the following information to
  ** ensure the GNU General Public License version 3.0 requirements will be
  ** met: http://www.gnu.org/copyleft/gpl.html.
  **
  ** If you are unsure which license is appropriate for your use, please
  ** contact the sales department at qt-sales@nokia.com.
  ** $QT_END_LICENSE$
  **
  ****************************************************************************/
  
  #ifndef QTPROPERTYBROWSER_H
  #define QTPROPERTYBROWSER_H
  
  #include <QtGui/QWidget>
  #include <QtCore/QSet>
  
  #if QT_VERSION >= 0x040400
  QT_BEGIN_NAMESPACE
  #endif
  
  #if defined(Q_WS_WIN)
  #  if !defined(QT_QTPROPERTYBROWSER_EXPORT) && !defined(QT_QTPROPERTYBROWSER_IMPORT)
  #    define QT_QTPROPERTYBROWSER_EXPORT
  #  elif defined(QT_QTPROPERTYBROWSER_IMPORT)
  #    if defined(QT_QTPROPERTYBROWSER_EXPORT)
  #      undef QT_QTPROPERTYBROWSER_EXPORT
  #    endif
  #    define QT_QTPROPERTYBROWSER_EXPORT __declspec(dllimport)
  #  elif defined(QT_QTPROPERTYBROWSER_EXPORT)
  #    undef QT_QTPROPERTYBROWSER_EXPORT
  #    define QT_QTPROPERTYBROWSER_EXPORT __declspec(dllexport)
  #  endif
  #else
  #  define QT_QTPROPERTYBROWSER_EXPORT
  #endif
  
  
  class QtAbstractPropertyManager;
  class QtPropertyPrivate;
  
  class QT_QTPROPERTYBROWSER_EXPORT QtProperty
  {
  public:
      virtual ~QtProperty();
  
      QList<QtProperty *> subProperties() const;
  
      QtAbstractPropertyManager *propertyManager() const;
  
      QString toolTip() const;
      QString statusTip() const;
      QString whatsThis() const;
      QString propertyName() const;
  
      bool isEnabled() const;
      bool isModified() const;
      bool isBold() const;
  
      bool hasValue() const;
      QIcon valueIcon() const;
      QString valueText() const;
  
      void setToolTip(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 setBold(bool bold);
  
      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;
      QtPropertyPrivate *d_ptr;
  };
  
  class QtAbstractPropertyManagerPrivate;
  
  class QT_QTPROPERTYBROWSER_EXPORT QtAbstractPropertyManager : public QObject
  {
      Q_OBJECT
  public:
  
      explicit QtAbstractPropertyManager(QObject *parent = 0);
      ~QtAbstractPropertyManager();
  
      QSet<QtProperty *> 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;
      QtAbstractPropertyManagerPrivate *d_ptr;
      Q_DECLARE_PRIVATE(QtAbstractPropertyManager)
      Q_DISABLE_COPY(QtAbstractPropertyManager)
  };
  
  class QT_QTPROPERTYBROWSER_EXPORT 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 PropertyManager>
  class QtAbstractEditorFactory : public QtAbstractEditorFactoryBase
  {
  public:
      explicit QtAbstractEditorFactory(QObject *parent) : QtAbstractEditorFactoryBase(parent) {}
      QWidget *createEditor(QtProperty *property, QWidget *parent)
      {
          QSetIterator<PropertyManager *> it(m_managers);
          while (it.hasNext()) {
              PropertyManager *manager = it.next();
              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, SIGNAL(destroyed(QObject *)),
                      this, SLOT(managerDestroyed(QObject *)));
      }
      void removePropertyManager(PropertyManager *manager)
      {
          if (!m_managers.contains(manager))
              return;
          disconnect(manager, SIGNAL(destroyed(QObject *)),
                      this, SLOT(managerDestroyed(QObject *)));
          disconnectPropertyManager(manager);
          m_managers.remove(manager);
      }
      QSet<PropertyManager *> propertyManagers() const
      {
          return m_managers;
      }
      PropertyManager *propertyManager(QtProperty *property) const
      {
          QtAbstractPropertyManager *manager = property->propertyManager();
          QSetIterator<PropertyManager *> itManager(m_managers);
          while (itManager.hasNext()) {
              PropertyManager *m = itManager.next();
              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)
      {
          QSetIterator<PropertyManager *> it(m_managers);
          while (it.hasNext()) {
              PropertyManager *m = it.next();
              if (m == manager) {
                  m_managers.remove(m);
                  return;
              }
          }
      }
  private:
      void breakConnection(QtAbstractPropertyManager *manager)
      {
          QSetIterator<PropertyManager *> it(m_managers);
          while (it.hasNext()) {
              PropertyManager *m = it.next();
              if (m == manager) {
                  removePropertyManager(m);
                  return;
              }
          }
      }
  private:
      QSet<PropertyManager *> m_managers;
      friend class QtAbstractPropertyEditor;
  };
  
  class QtAbstractPropertyBrowser;
  class QtBrowserItemPrivate;
  
  class QT_QTPROPERTYBROWSER_EXPORT QtBrowserItem
  {
  public:
      QtProperty *property() const;
      QtBrowserItem *parent() const;
      QList<QtBrowserItem *> children() const;
      QtAbstractPropertyBrowser *browser() const;
  private:
      explicit QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent);
      ~QtBrowserItem();
      QtBrowserItemPrivate *d_ptr;
      friend class QtAbstractPropertyBrowserPrivate;
  };
  
  class QtAbstractPropertyBrowserPrivate;
  
  class QT_QTPROPERTYBROWSER_EXPORT QtAbstractPropertyBrowser : public QWidget
  {
      Q_OBJECT
  public:
  
      explicit QtAbstractPropertyBrowser(QWidget *parent = 0);
      ~QtAbstractPropertyBrowser();
  
      QList<QtProperty *> properties() const;
      QList<QtBrowserItem *> items(QtProperty *property) const;
      QtBrowserItem *topLevelItem(QtProperty *property) const;
      QList<QtBrowserItem *> topLevelItems() const;
      void clear();
  
      template <class PropertyManager>
      void setFactoryForManager(PropertyManager *manager,
                      QtAbstractEditorFactory<PropertyManager> *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);
  
      QtAbstractPropertyBrowserPrivate *d_ptr;
      Q_DECLARE_PRIVATE(QtAbstractPropertyBrowser)
      Q_DISABLE_COPY(QtAbstractPropertyBrowser)
      Q_PRIVATE_SLOT(d_func(), void slotPropertyInserted(QtProperty *,
                              QtProperty *, QtProperty *))
      Q_PRIVATE_SLOT(d_func(), void slotPropertyRemoved(QtProperty *,
                              QtProperty *))
      Q_PRIVATE_SLOT(d_func(), void slotPropertyDestroyed(QtProperty *))
      Q_PRIVATE_SLOT(d_func(), void slotPropertyDataChanged(QtProperty *))
  
  };
  
  #if QT_VERSION >= 0x040400
  QT_END_NAMESPACE
  #endif
  
  #endif // QTPROPERTYBROWSER_H
  