tools/shared/qtpropertybrowser/qtpropertybrowser.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the tools applications of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qtpropertybrowser.h"
       
    43 #include <QtCore/QSet>
       
    44 #include <QtCore/QMap>
       
    45 #include <QtGui/QIcon>
       
    46 
       
    47 #if defined(Q_CC_MSVC)
       
    48 #    pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */
       
    49 #endif
       
    50 
       
    51 QT_BEGIN_NAMESPACE
       
    52 
       
    53 class QtPropertyPrivate
       
    54 {
       
    55 public:
       
    56     QtPropertyPrivate(QtAbstractPropertyManager *manager) : m_enabled(true), m_modified(false), m_manager(manager) {}
       
    57     QtProperty *q_ptr;
       
    58 
       
    59     QSet<QtProperty *> m_parentItems;
       
    60     QList<QtProperty *> m_subItems;
       
    61 
       
    62     QString m_toolTip;
       
    63     QString m_statusTip;
       
    64     QString m_whatsThis;
       
    65     QString m_name;
       
    66     bool m_enabled;
       
    67     bool m_modified;
       
    68 
       
    69     QtAbstractPropertyManager * const m_manager;
       
    70 };
       
    71 
       
    72 class QtAbstractPropertyManagerPrivate
       
    73 {
       
    74     QtAbstractPropertyManager *q_ptr;
       
    75     Q_DECLARE_PUBLIC(QtAbstractPropertyManager)
       
    76 public:
       
    77     void propertyDestroyed(QtProperty *property);
       
    78     void propertyChanged(QtProperty *property) const;
       
    79     void propertyRemoved(QtProperty *property,
       
    80                 QtProperty *parentProperty) const;
       
    81     void propertyInserted(QtProperty *property, QtProperty *parentProperty,
       
    82                 QtProperty *afterProperty) const;
       
    83 
       
    84     QSet<QtProperty *> m_properties;
       
    85 };
       
    86 
       
    87 /*!
       
    88     \class QtProperty
       
    89     \internal
       
    90     \inmodule QtDesigner
       
    91     \since 4.4
       
    92 
       
    93     \brief The QtProperty class encapsulates an instance of a property.
       
    94 
       
    95     Properties are created by objects of QtAbstractPropertyManager
       
    96     subclasses; a manager can create properties of a given type, and
       
    97     is used in conjunction with the QtAbstractPropertyBrowser class. A
       
    98     property is always owned by the manager that created it, which can
       
    99     be retrieved using the propertyManager() function.
       
   100 
       
   101     QtProperty contains the most common property attributes, and
       
   102     provides functions for retrieving as well as setting their values:
       
   103 
       
   104     \table
       
   105     \header \o Getter \o Setter
       
   106     \row
       
   107     \o propertyName() \o setPropertyName()
       
   108     \row
       
   109     \o statusTip() \o setStatusTip()
       
   110     \row
       
   111     \o toolTip() \o setToolTip()
       
   112     \row
       
   113     \o whatsThis() \o setWhatsThis()
       
   114     \row
       
   115     \o isEnabled() \o setEnabled()
       
   116     \row
       
   117     \o isModified() \o setModified()
       
   118     \row
       
   119     \o valueText() \o Nop
       
   120     \row
       
   121     \o valueIcon() \o Nop
       
   122     \endtable
       
   123 
       
   124     It is also possible to nest properties: QtProperty provides the
       
   125     addSubProperty(), insertSubProperty() and removeSubProperty() functions to
       
   126     manipulate the set of subproperties. Use the subProperties()
       
   127     function to retrieve a property's current set of subproperties.
       
   128     Note that nested properties are not owned by the parent property,
       
   129     i.e. each subproperty is owned by the manager that created it.
       
   130 
       
   131     \sa QtAbstractPropertyManager, QtBrowserItem
       
   132 */
       
   133 
       
   134 /*!
       
   135     Creates a property with the given \a manager.
       
   136 
       
   137     This constructor is only useful when creating a custom QtProperty
       
   138     subclass (e.g. QtVariantProperty). To create a regular QtProperty
       
   139     object, use the QtAbstractPropertyManager::addProperty()
       
   140     function instead.
       
   141 
       
   142     \sa QtAbstractPropertyManager::addProperty()
       
   143 */
       
   144 QtProperty::QtProperty(QtAbstractPropertyManager *manager)
       
   145     : d_ptr(new QtPropertyPrivate(manager))
       
   146 {
       
   147     d_ptr->q_ptr = this;
       
   148 }
       
   149 
       
   150 /*!
       
   151     Destroys this property.
       
   152 
       
   153     Note that subproperties are detached but not destroyed, i.e. they
       
   154     can still be used in another context.
       
   155 
       
   156     \sa QtAbstractPropertyManager::clear()
       
   157 
       
   158 */
       
   159 QtProperty::~QtProperty()
       
   160 {
       
   161     QSetIterator<QtProperty *> itParent(d_ptr->m_parentItems);
       
   162     while (itParent.hasNext()) {
       
   163         QtProperty *property = itParent.next();
       
   164         property->d_ptr->m_manager->d_ptr->propertyRemoved(this, property);
       
   165     }
       
   166 
       
   167     d_ptr->m_manager->d_ptr->propertyDestroyed(this);
       
   168 
       
   169     QListIterator<QtProperty *> itChild(d_ptr->m_subItems);
       
   170     while (itChild.hasNext()) {
       
   171         QtProperty *property = itChild.next();
       
   172         property->d_ptr->m_parentItems.remove(this);
       
   173     }
       
   174 
       
   175     itParent.toFront();
       
   176     while (itParent.hasNext()) {
       
   177         QtProperty *property = itParent.next();
       
   178         property->d_ptr->m_subItems.removeAll(this);
       
   179     }
       
   180 }
       
   181 
       
   182 /*!
       
   183     Returns the set of subproperties.
       
   184 
       
   185     Note that subproperties are not owned by \e this property, but by
       
   186     the manager that created them.
       
   187 
       
   188     \sa insertSubProperty(), removeSubProperty()
       
   189 */
       
   190 QList<QtProperty *> QtProperty::subProperties() const
       
   191 {
       
   192     return d_ptr->m_subItems;
       
   193 }
       
   194 
       
   195 /*!
       
   196     Returns a pointer to the manager that owns this property.
       
   197 */
       
   198 QtAbstractPropertyManager *QtProperty::propertyManager() const
       
   199 {
       
   200     return d_ptr->m_manager;
       
   201 }
       
   202 
       
   203 /*!
       
   204     Returns the property's  tool tip.
       
   205 
       
   206     \sa setToolTip()
       
   207 */
       
   208 QString QtProperty::toolTip() const
       
   209 {
       
   210     return d_ptr->m_toolTip;
       
   211 }
       
   212 
       
   213 /*!
       
   214     Returns the property's status tip.
       
   215 
       
   216     \sa setStatusTip()
       
   217 */
       
   218 QString QtProperty::statusTip() const
       
   219 {
       
   220     return d_ptr->m_statusTip;
       
   221 }
       
   222 
       
   223 /*!
       
   224     Returns the property's "What's This" help text.
       
   225 
       
   226     \sa setWhatsThis()
       
   227 */
       
   228 QString QtProperty::whatsThis() const
       
   229 {
       
   230     return d_ptr->m_whatsThis;
       
   231 }
       
   232 
       
   233 /*!
       
   234     Returns the property's name.
       
   235 
       
   236     \sa setPropertyName()
       
   237 */
       
   238 QString QtProperty::propertyName() const
       
   239 {
       
   240     return d_ptr->m_name;
       
   241 }
       
   242 
       
   243 /*!
       
   244     Returns whether the property is enabled.
       
   245 
       
   246     \sa setEnabled()
       
   247 */
       
   248 bool QtProperty::isEnabled() const
       
   249 {
       
   250     return d_ptr->m_enabled;
       
   251 }
       
   252 
       
   253 /*!
       
   254     Returns whether the property is modified.
       
   255 
       
   256     \sa setModified()
       
   257 */
       
   258 bool QtProperty::isModified() const
       
   259 {
       
   260     return d_ptr->m_modified;
       
   261 }
       
   262 
       
   263 /*!
       
   264     Returns whether the property has a value.
       
   265 
       
   266     \sa QtAbstractPropertyManager::hasValue()
       
   267 */
       
   268 bool QtProperty::hasValue() const
       
   269 {
       
   270     return d_ptr->m_manager->hasValue(this);
       
   271 }
       
   272 
       
   273 /*!
       
   274     Returns an icon representing the current state of this property.
       
   275 
       
   276     If the given property type can not generate such an icon, this
       
   277     function returns an invalid icon.
       
   278 
       
   279     \sa QtAbstractPropertyManager::valueIcon()
       
   280 */
       
   281 QIcon QtProperty::valueIcon() const
       
   282 {
       
   283     return d_ptr->m_manager->valueIcon(this);
       
   284 }
       
   285 
       
   286 /*!
       
   287     Returns a string representing the current state of this property.
       
   288 
       
   289     If the given property type can not generate such a string, this
       
   290     function returns an empty string.
       
   291 
       
   292     \sa QtAbstractPropertyManager::valueText()
       
   293 */
       
   294 QString QtProperty::valueText() const
       
   295 {
       
   296     return d_ptr->m_manager->valueText(this);
       
   297 }
       
   298 
       
   299 /*!
       
   300     Sets the property's tool tip to the given \a text.
       
   301 
       
   302     \sa toolTip()
       
   303 */
       
   304 void QtProperty::setToolTip(const QString &text)
       
   305 {
       
   306     if (d_ptr->m_toolTip == text)
       
   307         return;
       
   308 
       
   309     d_ptr->m_toolTip = text;
       
   310     propertyChanged();
       
   311 }
       
   312 
       
   313 /*!
       
   314     Sets the property's status tip to the given \a text.
       
   315 
       
   316     \sa statusTip()
       
   317 */
       
   318 void QtProperty::setStatusTip(const QString &text)
       
   319 {
       
   320     if (d_ptr->m_statusTip == text)
       
   321         return;
       
   322 
       
   323     d_ptr->m_statusTip = text;
       
   324     propertyChanged();
       
   325 }
       
   326 
       
   327 /*!
       
   328     Sets the property's "What's This" help text to the given \a text.
       
   329 
       
   330     \sa whatsThis()
       
   331 */
       
   332 void QtProperty::setWhatsThis(const QString &text)
       
   333 {
       
   334     if (d_ptr->m_whatsThis == text)
       
   335         return;
       
   336 
       
   337     d_ptr->m_whatsThis = text;
       
   338     propertyChanged();
       
   339 }
       
   340 
       
   341 /*!
       
   342     \fn void QtProperty::setPropertyName(const QString &name)
       
   343 
       
   344     Sets the property's  name to the given \a name.
       
   345 
       
   346     \sa propertyName()
       
   347 */
       
   348 void QtProperty::setPropertyName(const QString &text)
       
   349 {
       
   350     if (d_ptr->m_name == text)
       
   351         return;
       
   352 
       
   353     d_ptr->m_name = text;
       
   354     propertyChanged();
       
   355 }
       
   356 
       
   357 /*!
       
   358     Enables or disables the property according to the passed \a enable value.
       
   359 
       
   360     \sa isEnabled()
       
   361 */
       
   362 void QtProperty::setEnabled(bool enable)
       
   363 {
       
   364     if (d_ptr->m_enabled == enable)
       
   365         return;
       
   366 
       
   367     d_ptr->m_enabled = enable;
       
   368     propertyChanged();
       
   369 }
       
   370 
       
   371 /*!
       
   372     Sets the property's modified state according to the passed \a modified value.
       
   373 
       
   374     \sa isModified()
       
   375 */
       
   376 void QtProperty::setModified(bool modified)
       
   377 {
       
   378     if (d_ptr->m_modified == modified)
       
   379         return;
       
   380 
       
   381     d_ptr->m_modified = modified;
       
   382     propertyChanged();
       
   383 }
       
   384 
       
   385 /*!
       
   386     Appends the given \a property to this property's subproperties.
       
   387 
       
   388     If the given \a property already is added, this function does
       
   389     nothing.
       
   390 
       
   391     \sa insertSubProperty(), removeSubProperty()
       
   392 */
       
   393 void QtProperty::addSubProperty(QtProperty *property)
       
   394 {
       
   395     QtProperty *after = 0;
       
   396     if (d_ptr->m_subItems.count() > 0)
       
   397         after = d_ptr->m_subItems.last();
       
   398     insertSubProperty(property, after);
       
   399 }
       
   400 
       
   401 /*!
       
   402     \fn void QtProperty::insertSubProperty(QtProperty *property, QtProperty *precedingProperty)
       
   403 
       
   404     Inserts the given \a property after the specified \a
       
   405     precedingProperty into this property's list of subproperties.  If
       
   406     \a precedingProperty is 0, the specified \a property is inserted
       
   407     at the beginning of the list.
       
   408 
       
   409     If the given \a property already is inserted, this function does
       
   410     nothing.
       
   411 
       
   412     \sa addSubProperty(), removeSubProperty()
       
   413 */
       
   414 void QtProperty::insertSubProperty(QtProperty *property,
       
   415             QtProperty *afterProperty)
       
   416 {
       
   417     if (!property)
       
   418         return;
       
   419 
       
   420     if (property == this)
       
   421         return;
       
   422 
       
   423     // traverse all children of item. if this item is a child of item then cannot add.
       
   424     QList<QtProperty *> pendingList = property->subProperties();
       
   425     QMap<QtProperty *, bool> visited;
       
   426     while (!pendingList.isEmpty()) {
       
   427         QtProperty *i = pendingList.first();
       
   428         if (i == this)
       
   429             return;
       
   430         pendingList.removeFirst();
       
   431         if (visited.contains(i))
       
   432             continue;
       
   433         visited[i] = true;
       
   434         pendingList += i->subProperties();
       
   435     }
       
   436 
       
   437     pendingList = subProperties();
       
   438     int pos = 0;
       
   439     int newPos = 0;
       
   440     QtProperty *properAfterProperty = 0;
       
   441     while (pos < pendingList.count()) {
       
   442         QtProperty *i = pendingList.at(pos);
       
   443         if (i == property)
       
   444             return; // if item is already inserted in this item then cannot add.
       
   445         if (i == afterProperty) {
       
   446             newPos = pos + 1;
       
   447             properAfterProperty = afterProperty;
       
   448         }
       
   449         pos++;
       
   450     }
       
   451 
       
   452     d_ptr->m_subItems.insert(newPos, property);
       
   453     property->d_ptr->m_parentItems.insert(this);
       
   454 
       
   455     d_ptr->m_manager->d_ptr->propertyInserted(property, this, properAfterProperty);
       
   456 }
       
   457 
       
   458 /*!
       
   459     Removes the given \a property from the list of subproperties
       
   460     without deleting it.
       
   461 
       
   462     \sa addSubProperty(), insertSubProperty()
       
   463 */
       
   464 void QtProperty::removeSubProperty(QtProperty *property)
       
   465 {
       
   466     if (!property)
       
   467         return;
       
   468 
       
   469     d_ptr->m_manager->d_ptr->propertyRemoved(property, this);
       
   470 
       
   471     QList<QtProperty *> pendingList = subProperties();
       
   472     int pos = 0;
       
   473     while (pos < pendingList.count()) {
       
   474         if (pendingList.at(pos) == property) {
       
   475             d_ptr->m_subItems.removeAt(pos);
       
   476             property->d_ptr->m_parentItems.remove(this);
       
   477 
       
   478             return;
       
   479         }
       
   480         pos++;
       
   481     }
       
   482 }
       
   483 
       
   484 /*!
       
   485     \internal
       
   486 */
       
   487 void QtProperty::propertyChanged()
       
   488 {
       
   489     d_ptr->m_manager->d_ptr->propertyChanged(this);
       
   490 }
       
   491 
       
   492 ////////////////////////////////
       
   493 
       
   494 void QtAbstractPropertyManagerPrivate::propertyDestroyed(QtProperty *property)
       
   495 {
       
   496     if (m_properties.contains(property)) {
       
   497         emit q_ptr->propertyDestroyed(property);
       
   498         q_ptr->uninitializeProperty(property);
       
   499         m_properties.remove(property);
       
   500     }
       
   501 }
       
   502 
       
   503 void QtAbstractPropertyManagerPrivate::propertyChanged(QtProperty *property) const
       
   504 {
       
   505     emit q_ptr->propertyChanged(property);
       
   506 }
       
   507 
       
   508 void QtAbstractPropertyManagerPrivate::propertyRemoved(QtProperty *property,
       
   509             QtProperty *parentProperty) const
       
   510 {
       
   511     emit q_ptr->propertyRemoved(property, parentProperty);
       
   512 }
       
   513 
       
   514 void QtAbstractPropertyManagerPrivate::propertyInserted(QtProperty *property,
       
   515             QtProperty *parentProperty, QtProperty *afterProperty) const
       
   516 {
       
   517     emit q_ptr->propertyInserted(property, parentProperty, afterProperty);
       
   518 }
       
   519 
       
   520 /*!
       
   521     \class QtAbstractPropertyManager
       
   522     \internal
       
   523     \inmodule QtDesigner
       
   524     \since 4.4
       
   525 
       
   526     \brief The QtAbstractPropertyManager provides an interface for
       
   527     property managers.
       
   528 
       
   529     A manager can create and manage properties of a given type, and is
       
   530     used in conjunction with the QtAbstractPropertyBrowser class.
       
   531 
       
   532     When using a property browser widget, the properties are created
       
   533     and managed by implementations of the QtAbstractPropertyManager
       
   534     class. To ensure that the properties' values will be displayed
       
   535     using suitable editing widgets, the managers are associated with
       
   536     objects of QtAbstractEditorFactory subclasses. The property browser
       
   537     will use these associations to determine which factories it should
       
   538     use to create the preferred editing widgets.
       
   539 
       
   540     The QtAbstractPropertyManager class provides common functionality
       
   541     like creating a property using the addProperty() function, and
       
   542     retrieving the properties created by the manager using the
       
   543     properties() function. The class also provides signals that are
       
   544     emitted when the manager's properties change: propertyInserted(),
       
   545     propertyRemoved(), propertyChanged() and propertyDestroyed().
       
   546 
       
   547     QtAbstractPropertyManager subclasses are supposed to provide their
       
   548     own type specific API. Note that several ready-made
       
   549     implementations are available:
       
   550 
       
   551     \list
       
   552     \o QtBoolPropertyManager
       
   553     \o QtColorPropertyManager
       
   554     \o QtDatePropertyManager
       
   555     \o QtDateTimePropertyManager
       
   556     \o QtDoublePropertyManager
       
   557     \o QtEnumPropertyManager
       
   558     \o QtFlagPropertyManager
       
   559     \o QtFontPropertyManager
       
   560     \o QtGroupPropertyManager
       
   561     \o QtIntPropertyManager
       
   562     \o QtPointPropertyManager
       
   563     \o QtRectPropertyManager
       
   564     \o QtSizePropertyManager
       
   565     \o QtSizePolicyPropertyManager
       
   566     \o QtStringPropertyManager
       
   567     \o QtTimePropertyManager
       
   568     \o QtVariantPropertyManager
       
   569     \endlist
       
   570 
       
   571     \sa QtAbstractEditorFactoryBase, QtAbstractPropertyBrowser, QtProperty
       
   572 */
       
   573 
       
   574 /*!
       
   575     \fn void QtAbstractPropertyManager::propertyInserted(QtProperty *newProperty,
       
   576                 QtProperty *parentProperty, QtProperty *precedingProperty)
       
   577 
       
   578     This signal is emitted when a new subproperty is inserted into an
       
   579     existing property, passing pointers to the \a newProperty, \a
       
   580     parentProperty and \a precedingProperty as parameters.
       
   581 
       
   582     If \a precedingProperty is 0, the \a newProperty was inserted at
       
   583     the beginning of the \a parentProperty's subproperties list.
       
   584 
       
   585     Note that signal is emitted only if the \a parentProperty is created
       
   586     by this manager.
       
   587 
       
   588     \sa QtAbstractPropertyBrowser::itemInserted()
       
   589 */
       
   590 
       
   591 /*!
       
   592     \fn void QtAbstractPropertyManager::propertyChanged(QtProperty *property)
       
   593 
       
   594     This signal is emitted whenever a property's data changes, passing
       
   595     a pointer to the \a property as parameter.
       
   596 
       
   597     Note that signal is only emitted for properties that are created by
       
   598     this manager.
       
   599 
       
   600     \sa QtAbstractPropertyBrowser::itemChanged()
       
   601 */
       
   602 
       
   603 /*!
       
   604     \fn void QtAbstractPropertyManager::propertyRemoved(QtProperty *property, QtProperty *parent)
       
   605 
       
   606     This signal is emitted when a subproperty is removed, passing
       
   607     pointers to the removed \a property and the \a parent property as
       
   608     parameters.
       
   609 
       
   610     Note that signal is emitted only when the \a parent property is
       
   611     created by this manager.
       
   612 
       
   613     \sa QtAbstractPropertyBrowser::itemRemoved()
       
   614 */
       
   615 
       
   616 /*!
       
   617     \fn void QtAbstractPropertyManager::propertyDestroyed(QtProperty *property)
       
   618 
       
   619     This signal is emitted when the specified \a property is about to
       
   620     be destroyed.
       
   621 
       
   622     Note that signal is only emitted for properties that are created
       
   623     by this manager.
       
   624 
       
   625     \sa clear(), uninitializeProperty()
       
   626 */
       
   627 
       
   628 /*!
       
   629     \fn void QtAbstractPropertyBrowser::currentItemChanged(QtBrowserItem *current)
       
   630 
       
   631     This signal is emitted when the current item changes. The current item is specified by \a current.
       
   632 
       
   633     \sa QtAbstractPropertyBrowser::setCurrentItem()
       
   634 */
       
   635 
       
   636 /*!
       
   637     Creates an abstract property manager with the given \a parent.
       
   638 */
       
   639 QtAbstractPropertyManager::QtAbstractPropertyManager(QObject *parent)
       
   640     : QObject(parent), d_ptr(new QtAbstractPropertyManagerPrivate)
       
   641 {
       
   642     d_ptr->q_ptr = this;
       
   643 
       
   644 }
       
   645 
       
   646 /*!
       
   647     Destroys the manager. All properties created by the manager are
       
   648     destroyed.
       
   649 */
       
   650 QtAbstractPropertyManager::~QtAbstractPropertyManager()
       
   651 {
       
   652     clear();
       
   653 }
       
   654 
       
   655 /*!
       
   656     Destroys all the properties that this manager has created.
       
   657 
       
   658     \sa propertyDestroyed(), uninitializeProperty()
       
   659 */
       
   660 void QtAbstractPropertyManager::clear() const
       
   661 {
       
   662     while (!properties().isEmpty()) {
       
   663         QSetIterator<QtProperty *> itProperty(properties());
       
   664         QtProperty *prop = itProperty.next();
       
   665         delete prop;
       
   666     }
       
   667 }
       
   668 
       
   669 /*!
       
   670     Returns the set of properties created by this manager.
       
   671 
       
   672     \sa addProperty()
       
   673 */
       
   674 QSet<QtProperty *> QtAbstractPropertyManager::properties() const
       
   675 {
       
   676     return d_ptr->m_properties;
       
   677 }
       
   678 
       
   679 /*!
       
   680     Returns whether the given \a property has a value.
       
   681 
       
   682     The default implementation of this function returns true.
       
   683 
       
   684     \sa QtProperty::hasValue()
       
   685 */
       
   686 bool QtAbstractPropertyManager::hasValue(const QtProperty *property) const
       
   687 {
       
   688     Q_UNUSED(property)
       
   689     return true;
       
   690 }
       
   691 
       
   692 /*!
       
   693     Returns an icon representing the current state of the given \a
       
   694     property.
       
   695 
       
   696     The default implementation of this function returns an invalid
       
   697     icon.
       
   698 
       
   699     \sa QtProperty::valueIcon()
       
   700 */
       
   701 QIcon QtAbstractPropertyManager::valueIcon(const QtProperty *property) const
       
   702 {
       
   703     Q_UNUSED(property)
       
   704     return QIcon();
       
   705 }
       
   706 
       
   707 /*!
       
   708     Returns a string representing the current state of the given \a
       
   709     property.
       
   710 
       
   711     The default implementation of this function returns an empty
       
   712     string.
       
   713 
       
   714     \sa QtProperty::valueText()
       
   715 */
       
   716 QString QtAbstractPropertyManager::valueText(const QtProperty *property) const
       
   717 {
       
   718     Q_UNUSED(property)
       
   719     return QString();
       
   720 }
       
   721 
       
   722 /*!
       
   723     Creates a property with the given \a name which then is owned by this manager.
       
   724 
       
   725     Internally, this function calls the createProperty() and
       
   726     initializeProperty() functions.
       
   727 
       
   728     \sa initializeProperty(), properties()
       
   729 */
       
   730 QtProperty *QtAbstractPropertyManager::addProperty(const QString &name)
       
   731 {
       
   732     QtProperty *property = createProperty();
       
   733     if (property) {
       
   734         property->setPropertyName(name);
       
   735         d_ptr->m_properties.insert(property);
       
   736         initializeProperty(property);
       
   737     }
       
   738     return property;
       
   739 }
       
   740 
       
   741 /*!
       
   742     Creates a property.
       
   743 
       
   744     The base implementation produce QtProperty instances; Reimplement
       
   745     this function to make this manager produce objects of a QtProperty
       
   746     subclass.
       
   747 
       
   748     \sa addProperty(), initializeProperty()
       
   749 */
       
   750 QtProperty *QtAbstractPropertyManager::createProperty()
       
   751 {
       
   752     return new QtProperty(this);
       
   753 }
       
   754 
       
   755 /*!
       
   756     \fn void QtAbstractPropertyManager::initializeProperty(QtProperty *property) = 0
       
   757 
       
   758     This function is called whenever a new valid property pointer has
       
   759     been created, passing the pointer as parameter.
       
   760 
       
   761     The purpose is to let the manager know that the \a property has
       
   762     been created so that it can provide additional attributes for the
       
   763     new property, e.g. QtIntPropertyManager adds \l
       
   764     {QtIntPropertyManager::value()}{value}, \l
       
   765     {QtIntPropertyManager::minimum()}{minimum} and \l
       
   766     {QtIntPropertyManager::maximum()}{maximum} attributes. Since each manager
       
   767     subclass adds type specific attributes, this function is pure
       
   768     virtual and must be reimplemented when deriving from the
       
   769     QtAbstractPropertyManager class.
       
   770 
       
   771     \sa addProperty(), createProperty()
       
   772 */
       
   773 
       
   774 /*!
       
   775     This function is called just before the specified \a property is destroyed.
       
   776 
       
   777     The purpose is to let the property manager know that the \a
       
   778     property is being destroyed so that it can remove the property's
       
   779     additional attributes.
       
   780 
       
   781     \sa clear(),  propertyDestroyed()
       
   782 */
       
   783 void QtAbstractPropertyManager::uninitializeProperty(QtProperty *property)
       
   784 {
       
   785     Q_UNUSED(property)
       
   786 }
       
   787 
       
   788 ////////////////////////////////////
       
   789 
       
   790 /*!
       
   791     \class QtAbstractEditorFactoryBase
       
   792     \internal
       
   793     \inmodule QtDesigner
       
   794     \since 4.4
       
   795 
       
   796     \brief The QtAbstractEditorFactoryBase provides an interface for
       
   797     editor factories.
       
   798 
       
   799     An editor factory is a class that is able to create an editing
       
   800     widget of a specified type (e.g. line edits or comboboxes) for a
       
   801     given QtProperty object, and it is used in conjunction with the
       
   802     QtAbstractPropertyManager and QtAbstractPropertyBrowser classes.
       
   803 
       
   804     When using a property browser widget, the properties are created
       
   805     and managed by implementations of the QtAbstractPropertyManager
       
   806     class. To ensure that the properties' values will be displayed
       
   807     using suitable editing widgets, the managers are associated with
       
   808     objects of QtAbstractEditorFactory subclasses. The property browser
       
   809     will use these associations to determine which factories it should
       
   810     use to create the preferred editing widgets.
       
   811 
       
   812     Typically, an editor factory is created by subclassing the
       
   813     QtAbstractEditorFactory template class which inherits
       
   814     QtAbstractEditorFactoryBase. But note that several ready-made
       
   815     implementations are available:
       
   816 
       
   817     \list
       
   818     \o QtCheckBoxFactory
       
   819     \o QtDateEditFactory
       
   820     \o QtDateTimeEditFactory
       
   821     \o QtDoubleSpinBoxFactory
       
   822     \o QtEnumEditorFactory
       
   823     \o QtLineEditFactory
       
   824     \o QtScrollBarFactory
       
   825     \o QtSliderFactory
       
   826     \o QtSpinBoxFactory
       
   827     \o QtTimeEditFactory
       
   828     \o QtVariantEditorFactory
       
   829     \endlist
       
   830 
       
   831     \sa QtAbstractPropertyManager, QtAbstractPropertyBrowser
       
   832 */
       
   833 
       
   834 /*!
       
   835     \fn virtual QWidget *QtAbstractEditorFactoryBase::createEditor(QtProperty *property,
       
   836         QWidget *parent) = 0
       
   837 
       
   838     Creates an editing widget (with the given \a parent) for the given
       
   839     \a property.
       
   840 
       
   841     This function is reimplemented in QtAbstractEditorFactory template class
       
   842     which also provides a pure virtual convenience overload of this
       
   843     function enabling access to the property's manager.
       
   844 
       
   845     \sa  QtAbstractEditorFactory::createEditor()
       
   846 */
       
   847 
       
   848 /*!
       
   849     \fn QtAbstractEditorFactoryBase::QtAbstractEditorFactoryBase(QObject *parent = 0)
       
   850 
       
   851     Creates an abstract editor factory with the given \a parent.
       
   852 */
       
   853 
       
   854 /*!
       
   855     \fn virtual void QtAbstractEditorFactoryBase::breakConnection(QtAbstractPropertyManager *manager) = 0
       
   856 
       
   857     \internal
       
   858 
       
   859     Detaches property manager from factory.
       
   860     This method is reimplemented in QtAbstractEditorFactory template subclass.
       
   861     You don't need to reimplement it in your subclasses. Instead implement more convenient
       
   862     QtAbstractEditorFactory::disconnectPropertyManager() which gives you access to particular manager subclass.
       
   863 */
       
   864 
       
   865 /*!
       
   866     \fn virtual void QtAbstractEditorFactoryBase::managerDestroyed(QObject *manager) = 0
       
   867 
       
   868     \internal
       
   869 
       
   870     This method is called when property manager is being destroyed.
       
   871     Basically it notifies factory not to produce editors for properties owned by \a manager.
       
   872     You don't need to reimplement it in your subclass. This method is implemented in
       
   873     QtAbstractEditorFactory template subclass.
       
   874 */
       
   875 
       
   876 /*!
       
   877     \class QtAbstractEditorFactory
       
   878     \internal
       
   879     \inmodule QtDesigner
       
   880     \since 4.4
       
   881 
       
   882     \brief The QtAbstractEditorFactory is the base template class for editor
       
   883     factories.
       
   884 
       
   885     An editor factory is a class that is able to create an editing
       
   886     widget of a specified type (e.g. line edits or comboboxes) for a
       
   887     given QtProperty object, and it is used in conjunction with the
       
   888     QtAbstractPropertyManager and QtAbstractPropertyBrowser classes.
       
   889 
       
   890     Note that the QtAbstractEditorFactory functions are using the
       
   891     PropertyManager template argument class which can be any
       
   892     QtAbstractPropertyManager subclass. For example:
       
   893 
       
   894     \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 0
       
   895 
       
   896     Note that QtSpinBoxFactory by definition creates editing widgets
       
   897     \e only for properties created by QtIntPropertyManager.
       
   898 
       
   899     When using a property browser widget, the properties are created
       
   900     and managed by implementations of the QtAbstractPropertyManager
       
   901     class. To ensure that the properties' values will be displayed
       
   902     using suitable editing widgets, the managers are associated with
       
   903     objects of QtAbstractEditorFactory subclasses. The property browser will
       
   904     use these associations to determine which factories it should use
       
   905     to create the preferred editing widgets.
       
   906 
       
   907     A QtAbstractEditorFactory object is capable of producing editors for
       
   908     several property managers at the same time. To create an
       
   909     association between this factory and a given manager, use the
       
   910     addPropertyManager() function. Use the removePropertyManager() function to make
       
   911     this factory stop producing editors for a given property
       
   912     manager. Use the propertyManagers() function to retrieve the set of
       
   913     managers currently associated with this factory.
       
   914 
       
   915     Several ready-made implementations of the QtAbstractEditorFactory class
       
   916     are available:
       
   917 
       
   918     \list
       
   919     \o QtCheckBoxFactory
       
   920     \o QtDateEditFactory
       
   921     \o QtDateTimeEditFactory
       
   922     \o QtDoubleSpinBoxFactory
       
   923     \o QtEnumEditorFactory
       
   924     \o QtLineEditFactory
       
   925     \o QtScrollBarFactory
       
   926     \o QtSliderFactory
       
   927     \o QtSpinBoxFactory
       
   928     \o QtTimeEditFactory
       
   929     \o QtVariantEditorFactory
       
   930     \endlist
       
   931 
       
   932     When deriving from the QtAbstractEditorFactory class, several pure virtual
       
   933     functions must be implemented: the connectPropertyManager() function is
       
   934     used by the factory to connect to the given manager's signals, the
       
   935     createEditor() function is supposed to create an editor for the
       
   936     given property controlled by the given manager, and finally the
       
   937     disconnectPropertyManager() function is used by the factory to disconnect
       
   938     from the specified manager's signals.
       
   939 
       
   940     \sa QtAbstractEditorFactoryBase, QtAbstractPropertyManager
       
   941 */
       
   942 
       
   943 /*!
       
   944     \fn QtAbstractEditorFactory::QtAbstractEditorFactory(QObject *parent = 0)
       
   945 
       
   946     Creates an editor factory with the given \a parent.
       
   947 
       
   948     \sa addPropertyManager()
       
   949 */
       
   950 
       
   951 /*!
       
   952     \fn QWidget *QtAbstractEditorFactory::createEditor(QtProperty *property, QWidget *parent)
       
   953 
       
   954     Creates an editing widget (with the given \a parent) for the given
       
   955     \a property.
       
   956 */
       
   957 
       
   958 /*!
       
   959     \fn void QtAbstractEditorFactory::addPropertyManager(PropertyManager *manager)
       
   960 
       
   961     Adds the given \a manager to this factory's set of managers,
       
   962     making this factory produce editing widgets for properties created
       
   963     by the given manager.
       
   964 
       
   965     The PropertyManager type is a template argument class, and represents the chosen
       
   966     QtAbstractPropertyManager subclass.
       
   967 
       
   968     \sa propertyManagers(), removePropertyManager()
       
   969 */
       
   970 
       
   971 /*!
       
   972     \fn void QtAbstractEditorFactory::removePropertyManager(PropertyManager *manager)
       
   973 
       
   974     Removes the given \a manager from this factory's set of
       
   975     managers. The PropertyManager type is a template argument class, and may be
       
   976     any QtAbstractPropertyManager subclass.
       
   977 
       
   978     \sa propertyManagers(), addPropertyManager()
       
   979 */
       
   980 
       
   981 /*!
       
   982     \fn virtual void QtAbstractEditorFactory::connectPropertyManager(PropertyManager *manager) = 0
       
   983 
       
   984     Connects this factory to the given \a manager's signals.  The
       
   985     PropertyManager type is a template argument class, and represents
       
   986     the chosen QtAbstractPropertyManager subclass.
       
   987 
       
   988     This function is used internally by the addPropertyManager() function, and
       
   989     makes it possible to update an editing widget when the associated
       
   990     property's data changes. This is typically done in custom slots
       
   991     responding to the signals emitted by the property's manager,
       
   992     e.g. QtIntPropertyManager::valueChanged() and
       
   993     QtIntPropertyManager::rangeChanged().
       
   994 
       
   995     \sa propertyManagers(), disconnectPropertyManager()
       
   996 */
       
   997 
       
   998 /*!
       
   999     \fn virtual QWidget *QtAbstractEditorFactory::createEditor(PropertyManager *manager, QtProperty *property,
       
  1000                 QWidget *parent) = 0
       
  1001 
       
  1002     Creates an editing widget with the given \a parent for the
       
  1003     specified \a property created by the given \a manager. The
       
  1004     PropertyManager type is a template argument class, and represents
       
  1005     the chosen QtAbstractPropertyManager subclass.
       
  1006 
       
  1007     This function must be implemented in derived classes: It is
       
  1008     recommended to store a pointer to the widget and map it to the
       
  1009     given \a property, since the widget must be updated whenever the
       
  1010     associated property's data changes. This is typically done in
       
  1011     custom slots responding to the signals emitted by the property's
       
  1012     manager, e.g. QtIntPropertyManager::valueChanged() and
       
  1013     QtIntPropertyManager::rangeChanged().
       
  1014 
       
  1015     \sa connectPropertyManager()
       
  1016 */
       
  1017 
       
  1018 /*!
       
  1019     \fn virtual void QtAbstractEditorFactory::disconnectPropertyManager(PropertyManager *manager) = 0
       
  1020 
       
  1021     Disconnects this factory from the given \a manager's signals. The
       
  1022     PropertyManager type is a template argument class, and represents
       
  1023     the chosen QtAbstractPropertyManager subclass.
       
  1024 
       
  1025     This function is used internally by the removePropertyManager() function.
       
  1026 
       
  1027     \sa propertyManagers(), connectPropertyManager()
       
  1028 */
       
  1029 
       
  1030 /*!
       
  1031     \fn QSet<PropertyManager *> QtAbstractEditorFactory::propertyManagers() const
       
  1032 
       
  1033     Returns the factory's set of associated managers.  The
       
  1034     PropertyManager type is a template argument class, and represents
       
  1035     the chosen QtAbstractPropertyManager subclass.
       
  1036 
       
  1037     \sa addPropertyManager(), removePropertyManager()
       
  1038 */
       
  1039 
       
  1040 /*!
       
  1041     \fn PropertyManager *QtAbstractEditorFactory::propertyManager(QtProperty *property) const
       
  1042 
       
  1043     Returns the property manager for the given \a property, or 0 if
       
  1044     the given \a property doesn't belong to any of this factory's
       
  1045     registered managers.
       
  1046 
       
  1047     The PropertyManager type is a template argument class, and represents the chosen
       
  1048     QtAbstractPropertyManager subclass.
       
  1049 
       
  1050     \sa propertyManagers()
       
  1051 */
       
  1052 
       
  1053 /*!
       
  1054     \fn virtual void QtAbstractEditorFactory::managerDestroyed(QObject *manager)
       
  1055 
       
  1056     \internal
       
  1057     \reimp
       
  1058 */
       
  1059 
       
  1060 ////////////////////////////////////
       
  1061 class QtBrowserItemPrivate
       
  1062 {
       
  1063 public:
       
  1064     QtBrowserItemPrivate(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent)
       
  1065         : m_browser(browser), m_property(property), m_parent(parent), q_ptr(0) {}
       
  1066 
       
  1067     void addChild(QtBrowserItem *index, QtBrowserItem *after);
       
  1068     void removeChild(QtBrowserItem *index);
       
  1069 
       
  1070     QtAbstractPropertyBrowser * const m_browser;
       
  1071     QtProperty *m_property;
       
  1072     QtBrowserItem *m_parent;
       
  1073 
       
  1074     QtBrowserItem *q_ptr;
       
  1075 
       
  1076     QList<QtBrowserItem *> m_children;
       
  1077 
       
  1078 };
       
  1079 
       
  1080 void QtBrowserItemPrivate::addChild(QtBrowserItem *index, QtBrowserItem *after)
       
  1081 {
       
  1082     if (m_children.contains(index))
       
  1083         return;
       
  1084     int idx = m_children.indexOf(after) + 1; // we insert after returned idx, if it was -1 then we set idx to 0;
       
  1085     m_children.insert(idx, index);
       
  1086 }
       
  1087 
       
  1088 void QtBrowserItemPrivate::removeChild(QtBrowserItem *index)
       
  1089 {
       
  1090     m_children.removeAll(index);
       
  1091 }
       
  1092 
       
  1093 
       
  1094 /*!
       
  1095     \class QtBrowserItem
       
  1096     \internal
       
  1097     \inmodule QtDesigner
       
  1098     \since 4.4
       
  1099 
       
  1100     \brief The QtBrowserItem class represents a property in
       
  1101     a property browser instance.
       
  1102 
       
  1103     Browser items are created whenever a QtProperty is inserted to the
       
  1104     property browser. A QtBrowserItem uniquely identifies a
       
  1105     browser's item. Thus, if the same QtProperty is inserted multiple
       
  1106     times, each occurrence gets its own unique QtBrowserItem. The
       
  1107     items are owned by QtAbstractPropertyBrowser and automatically
       
  1108     deleted when they are removed from the browser.
       
  1109 
       
  1110     You can traverse a browser's properties by calling parent() and
       
  1111     children(). The property and the browser associated with an item
       
  1112     are available as property() and browser().
       
  1113 
       
  1114     \sa QtAbstractPropertyBrowser, QtProperty
       
  1115 */
       
  1116 
       
  1117 /*!
       
  1118     Returns the property which is accosiated with this item. Note that
       
  1119     several items can be associated with the same property instance in
       
  1120     the same property browser.
       
  1121 
       
  1122     \sa QtAbstractPropertyBrowser::items()
       
  1123 */
       
  1124 
       
  1125 QtProperty *QtBrowserItem::property() const
       
  1126 {
       
  1127     return d_ptr->m_property;
       
  1128 }
       
  1129 
       
  1130 /*!
       
  1131     Returns the parent item of \e this item. Returns 0 if \e this item
       
  1132     is associated with top-level property in item's property browser.
       
  1133 
       
  1134     \sa children()
       
  1135 */
       
  1136 
       
  1137 QtBrowserItem *QtBrowserItem::parent() const
       
  1138 {
       
  1139     return d_ptr->m_parent;
       
  1140 }
       
  1141 
       
  1142 /*!
       
  1143     Returns the children items of \e this item. The properties
       
  1144     reproduced from children items are always the same as
       
  1145     reproduced from associated property' children, for example:
       
  1146 
       
  1147     \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 1
       
  1148 
       
  1149     The \e childrenItems list represents the same list as \e childrenProperties.
       
  1150 */
       
  1151 
       
  1152 QList<QtBrowserItem *> QtBrowserItem::children() const
       
  1153 {
       
  1154     return d_ptr->m_children;
       
  1155 }
       
  1156 
       
  1157 /*!
       
  1158     Returns the property browser which owns \e this item.
       
  1159 */
       
  1160 
       
  1161 QtAbstractPropertyBrowser *QtBrowserItem::browser() const
       
  1162 {
       
  1163     return d_ptr->m_browser;
       
  1164 }
       
  1165 
       
  1166 QtBrowserItem::QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent)
       
  1167     : d_ptr(new QtBrowserItemPrivate(browser, property, parent))
       
  1168 {
       
  1169     d_ptr->q_ptr = this;
       
  1170 }
       
  1171 
       
  1172 QtBrowserItem::~QtBrowserItem()
       
  1173 {
       
  1174 }
       
  1175 
       
  1176 
       
  1177 ////////////////////////////////////
       
  1178 
       
  1179 typedef QMap<QtAbstractPropertyBrowser *, QMap<QtAbstractPropertyManager *,
       
  1180                             QtAbstractEditorFactoryBase *> > Map1;
       
  1181 typedef QMap<QtAbstractPropertyManager *, QMap<QtAbstractEditorFactoryBase *,
       
  1182                             QList<QtAbstractPropertyBrowser *> > > Map2;
       
  1183 Q_GLOBAL_STATIC(Map1, m_viewToManagerToFactory)
       
  1184 Q_GLOBAL_STATIC(Map2, m_managerToFactoryToViews)
       
  1185 
       
  1186 class QtAbstractPropertyBrowserPrivate
       
  1187 {
       
  1188     QtAbstractPropertyBrowser *q_ptr;
       
  1189     Q_DECLARE_PUBLIC(QtAbstractPropertyBrowser)
       
  1190 public:
       
  1191     QtAbstractPropertyBrowserPrivate();
       
  1192 
       
  1193     void insertSubTree(QtProperty *property,
       
  1194             QtProperty *parentProperty);
       
  1195     void removeSubTree(QtProperty *property,
       
  1196             QtProperty *parentProperty);
       
  1197     void createBrowserIndexes(QtProperty *property, QtProperty *parentProperty, QtProperty *afterProperty);
       
  1198     void removeBrowserIndexes(QtProperty *property, QtProperty *parentProperty);
       
  1199     QtBrowserItem *createBrowserIndex(QtProperty *property, QtBrowserItem *parentIndex, QtBrowserItem *afterIndex);
       
  1200     void removeBrowserIndex(QtBrowserItem *index);
       
  1201     void clearIndex(QtBrowserItem *index);
       
  1202 
       
  1203     void slotPropertyInserted(QtProperty *property,
       
  1204             QtProperty *parentProperty, QtProperty *afterProperty);
       
  1205     void slotPropertyRemoved(QtProperty *property, QtProperty *parentProperty);
       
  1206     void slotPropertyDestroyed(QtProperty *property);
       
  1207     void slotPropertyDataChanged(QtProperty *property);
       
  1208 
       
  1209     QList<QtProperty *> m_subItems;
       
  1210     QMap<QtAbstractPropertyManager *, QList<QtProperty *> > m_managerToProperties;
       
  1211     QMap<QtProperty *, QList<QtProperty *> > m_propertyToParents;
       
  1212 
       
  1213     QMap<QtProperty *, QtBrowserItem *> m_topLevelPropertyToIndex;
       
  1214     QList<QtBrowserItem *> m_topLevelIndexes;
       
  1215     QMap<QtProperty *, QList<QtBrowserItem *> > m_propertyToIndexes;
       
  1216 
       
  1217     QtBrowserItem *m_currentItem;
       
  1218 };
       
  1219 
       
  1220 QtAbstractPropertyBrowserPrivate::QtAbstractPropertyBrowserPrivate() :
       
  1221    m_currentItem(0)
       
  1222 {
       
  1223 }
       
  1224 
       
  1225 void QtAbstractPropertyBrowserPrivate::insertSubTree(QtProperty *property,
       
  1226             QtProperty *parentProperty)
       
  1227 {
       
  1228     if (m_propertyToParents.contains(property)) {
       
  1229         // property was already inserted, so its manager is connected
       
  1230         // and all its children are inserted and theirs managers are connected
       
  1231         // we just register new parent (parent has to be new).
       
  1232         m_propertyToParents[property].append(parentProperty);
       
  1233         // don't need to update m_managerToProperties map since
       
  1234         // m_managerToProperties[manager] already contains property.
       
  1235         return;
       
  1236     }
       
  1237     QtAbstractPropertyManager *manager = property->propertyManager();
       
  1238     if (m_managerToProperties[manager].isEmpty()) {
       
  1239         // connect manager's signals
       
  1240         q_ptr->connect(manager, SIGNAL(propertyInserted(QtProperty *,
       
  1241                             QtProperty *, QtProperty *)),
       
  1242                 q_ptr, SLOT(slotPropertyInserted(QtProperty *,
       
  1243                             QtProperty *, QtProperty *)));
       
  1244         q_ptr->connect(manager, SIGNAL(propertyRemoved(QtProperty *,
       
  1245                             QtProperty *)),
       
  1246                 q_ptr, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *)));
       
  1247         q_ptr->connect(manager, SIGNAL(propertyDestroyed(QtProperty *)),
       
  1248                 q_ptr, SLOT(slotPropertyDestroyed(QtProperty *)));
       
  1249         q_ptr->connect(manager, SIGNAL(propertyChanged(QtProperty *)),
       
  1250                 q_ptr, SLOT(slotPropertyDataChanged(QtProperty *)));
       
  1251     }
       
  1252     m_managerToProperties[manager].append(property);
       
  1253     m_propertyToParents[property].append(parentProperty);
       
  1254 
       
  1255     QList<QtProperty *> subList = property->subProperties();
       
  1256     QListIterator<QtProperty *> itSub(subList);
       
  1257     while (itSub.hasNext()) {
       
  1258         QtProperty *subProperty = itSub.next();
       
  1259         insertSubTree(subProperty, property);
       
  1260     }
       
  1261 }
       
  1262 
       
  1263 void QtAbstractPropertyBrowserPrivate::removeSubTree(QtProperty *property,
       
  1264             QtProperty *parentProperty)
       
  1265 {
       
  1266     if (!m_propertyToParents.contains(property)) {
       
  1267         // ASSERT
       
  1268         return;
       
  1269     }
       
  1270 
       
  1271     m_propertyToParents[property].removeAll(parentProperty);
       
  1272     if (!m_propertyToParents[property].isEmpty())
       
  1273         return;
       
  1274 
       
  1275     m_propertyToParents.remove(property);
       
  1276     QtAbstractPropertyManager *manager = property->propertyManager();
       
  1277     m_managerToProperties[manager].removeAll(property);
       
  1278     if (m_managerToProperties[manager].isEmpty()) {
       
  1279         // disconnect manager's signals
       
  1280         q_ptr->disconnect(manager, SIGNAL(propertyInserted(QtProperty *,
       
  1281                             QtProperty *, QtProperty *)),
       
  1282                 q_ptr, SLOT(slotPropertyInserted(QtProperty *,
       
  1283                             QtProperty *, QtProperty *)));
       
  1284         q_ptr->disconnect(manager, SIGNAL(propertyRemoved(QtProperty *,
       
  1285                             QtProperty *)),
       
  1286                 q_ptr, SLOT(slotPropertyRemoved(QtProperty *, QtProperty *)));
       
  1287         q_ptr->disconnect(manager, SIGNAL(propertyDestroyed(QtProperty *)),
       
  1288                 q_ptr, SLOT(slotPropertyDestroyed(QtProperty *)));
       
  1289         q_ptr->disconnect(manager, SIGNAL(propertyChanged(QtProperty *)),
       
  1290                 q_ptr, SLOT(slotPropertyDataChanged(QtProperty *)));
       
  1291 
       
  1292         m_managerToProperties.remove(manager);
       
  1293     }
       
  1294 
       
  1295     QList<QtProperty *> subList = property->subProperties();
       
  1296     QListIterator<QtProperty *> itSub(subList);
       
  1297     while (itSub.hasNext()) {
       
  1298         QtProperty *subProperty = itSub.next();
       
  1299         removeSubTree(subProperty, property);
       
  1300     }
       
  1301 }
       
  1302 
       
  1303 void QtAbstractPropertyBrowserPrivate::createBrowserIndexes(QtProperty *property, QtProperty *parentProperty, QtProperty *afterProperty)
       
  1304 {
       
  1305     QMap<QtBrowserItem *, QtBrowserItem *> parentToAfter;
       
  1306     if (afterProperty) {
       
  1307         QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
       
  1308             m_propertyToIndexes.find(afterProperty);
       
  1309         if (it == m_propertyToIndexes.constEnd())
       
  1310             return;
       
  1311 
       
  1312         QList<QtBrowserItem *> indexes = it.value();
       
  1313         QListIterator<QtBrowserItem *> itIndex(indexes);
       
  1314         while (itIndex.hasNext()) {
       
  1315             QtBrowserItem *idx = itIndex.next();
       
  1316             QtBrowserItem *parentIdx = idx->parent();
       
  1317             if ((parentProperty && parentIdx && parentIdx->property() == parentProperty) || (!parentProperty && !parentIdx))
       
  1318                 parentToAfter[idx->parent()] = idx;
       
  1319         }
       
  1320     } else if (parentProperty) {
       
  1321         QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
       
  1322                 m_propertyToIndexes.find(parentProperty);
       
  1323         if (it == m_propertyToIndexes.constEnd())
       
  1324             return;
       
  1325 
       
  1326         QList<QtBrowserItem *> indexes = it.value();
       
  1327         QListIterator<QtBrowserItem *> itIndex(indexes);
       
  1328         while (itIndex.hasNext()) {
       
  1329             QtBrowserItem *idx = itIndex.next();
       
  1330             parentToAfter[idx] = 0;
       
  1331         }
       
  1332     } else {
       
  1333         parentToAfter[0] = 0;
       
  1334     }
       
  1335 
       
  1336     const QMap<QtBrowserItem *, QtBrowserItem *>::ConstIterator pcend = parentToAfter.constEnd();
       
  1337     for (QMap<QtBrowserItem *, QtBrowserItem *>::ConstIterator it = parentToAfter.constBegin(); it != pcend; ++it)
       
  1338         createBrowserIndex(property, it.key(), it.value());
       
  1339 }
       
  1340 
       
  1341 QtBrowserItem *QtAbstractPropertyBrowserPrivate::createBrowserIndex(QtProperty *property,
       
  1342         QtBrowserItem *parentIndex, QtBrowserItem *afterIndex)
       
  1343 {
       
  1344     QtBrowserItem *newIndex = new QtBrowserItem(q_ptr, property, parentIndex);
       
  1345     if (parentIndex) {
       
  1346         parentIndex->d_ptr->addChild(newIndex, afterIndex);
       
  1347     } else {
       
  1348         m_topLevelPropertyToIndex[property] = newIndex;
       
  1349         m_topLevelIndexes.insert(m_topLevelIndexes.indexOf(afterIndex) + 1, newIndex);
       
  1350     }
       
  1351     m_propertyToIndexes[property].append(newIndex);
       
  1352 
       
  1353     q_ptr->itemInserted(newIndex, afterIndex);
       
  1354 
       
  1355     QList<QtProperty *> subItems = property->subProperties();
       
  1356     QListIterator<QtProperty *> itChild(subItems);
       
  1357     QtBrowserItem *afterChild = 0;
       
  1358     while (itChild.hasNext()) {
       
  1359         QtProperty *child = itChild.next();
       
  1360         afterChild = createBrowserIndex(child, newIndex, afterChild);
       
  1361     }
       
  1362     return newIndex;
       
  1363 }
       
  1364 
       
  1365 void QtAbstractPropertyBrowserPrivate::removeBrowserIndexes(QtProperty *property, QtProperty *parentProperty)
       
  1366 {
       
  1367     QList<QtBrowserItem *> toRemove;
       
  1368     QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
       
  1369         m_propertyToIndexes.find(property);
       
  1370     if (it == m_propertyToIndexes.constEnd())
       
  1371         return;
       
  1372 
       
  1373     QList<QtBrowserItem *> indexes = it.value();
       
  1374     QListIterator<QtBrowserItem *> itIndex(indexes);
       
  1375     while (itIndex.hasNext()) {
       
  1376         QtBrowserItem *idx = itIndex.next();
       
  1377         QtBrowserItem *parentIdx = idx->parent();
       
  1378         if ((parentProperty && parentIdx && parentIdx->property() == parentProperty) || (!parentProperty && !parentIdx))
       
  1379             toRemove.append(idx);
       
  1380     }
       
  1381 
       
  1382     QListIterator<QtBrowserItem *> itRemove(toRemove);
       
  1383     while (itRemove.hasNext()) {
       
  1384         QtBrowserItem *index = itRemove.next();
       
  1385         removeBrowserIndex(index);
       
  1386     }
       
  1387 }
       
  1388 
       
  1389 void QtAbstractPropertyBrowserPrivate::removeBrowserIndex(QtBrowserItem *index)
       
  1390 {
       
  1391     QList<QtBrowserItem *> children = index->children();
       
  1392     for (int i = children.count(); i > 0; i--) {
       
  1393         removeBrowserIndex(children.at(i - 1));
       
  1394     }
       
  1395 
       
  1396     q_ptr->itemRemoved(index);
       
  1397 
       
  1398     if (index->parent()) {
       
  1399         index->parent()->d_ptr->removeChild(index);
       
  1400     } else {
       
  1401         m_topLevelPropertyToIndex.remove(index->property());
       
  1402         m_topLevelIndexes.removeAll(index);
       
  1403     }
       
  1404 
       
  1405     QtProperty *property = index->property();
       
  1406 
       
  1407     m_propertyToIndexes[property].removeAll(index);
       
  1408     if (m_propertyToIndexes[property].isEmpty())
       
  1409         m_propertyToIndexes.remove(property);
       
  1410 
       
  1411     delete index;
       
  1412 }
       
  1413 
       
  1414 void QtAbstractPropertyBrowserPrivate::clearIndex(QtBrowserItem *index)
       
  1415 {
       
  1416     QList<QtBrowserItem *> children = index->children();
       
  1417     QListIterator<QtBrowserItem *> itChild(children);
       
  1418     while (itChild.hasNext()) {
       
  1419         clearIndex(itChild.next());
       
  1420     }
       
  1421     delete index;
       
  1422 }
       
  1423 
       
  1424 void QtAbstractPropertyBrowserPrivate::slotPropertyInserted(QtProperty *property,
       
  1425         QtProperty *parentProperty, QtProperty *afterProperty)
       
  1426 {
       
  1427     if (!m_propertyToParents.contains(parentProperty))
       
  1428         return;
       
  1429     createBrowserIndexes(property, parentProperty, afterProperty);
       
  1430     insertSubTree(property, parentProperty);
       
  1431     //q_ptr->propertyInserted(property, parentProperty, afterProperty);
       
  1432 }
       
  1433 
       
  1434 void QtAbstractPropertyBrowserPrivate::slotPropertyRemoved(QtProperty *property,
       
  1435         QtProperty *parentProperty)
       
  1436 {
       
  1437     if (!m_propertyToParents.contains(parentProperty))
       
  1438         return;
       
  1439     removeSubTree(property, parentProperty); // this line should be probably moved down after propertyRemoved call
       
  1440     //q_ptr->propertyRemoved(property, parentProperty);
       
  1441     removeBrowserIndexes(property, parentProperty);
       
  1442 }
       
  1443 
       
  1444 void QtAbstractPropertyBrowserPrivate::slotPropertyDestroyed(QtProperty *property)
       
  1445 {
       
  1446     if (!m_subItems.contains(property))
       
  1447         return;
       
  1448     q_ptr->removeProperty(property);
       
  1449 }
       
  1450 
       
  1451 void QtAbstractPropertyBrowserPrivate::slotPropertyDataChanged(QtProperty *property)
       
  1452 {
       
  1453     if (!m_propertyToParents.contains(property))
       
  1454         return;
       
  1455 
       
  1456     QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
       
  1457             m_propertyToIndexes.find(property);
       
  1458     if (it == m_propertyToIndexes.constEnd())
       
  1459         return;
       
  1460 
       
  1461     QList<QtBrowserItem *> indexes = it.value();
       
  1462     QListIterator<QtBrowserItem *> itIndex(indexes);
       
  1463     while (itIndex.hasNext()) {
       
  1464         QtBrowserItem *idx = itIndex.next();
       
  1465         q_ptr->itemChanged(idx);
       
  1466     }
       
  1467     //q_ptr->propertyChanged(property);
       
  1468 }
       
  1469 
       
  1470 /*!
       
  1471     \class QtAbstractPropertyBrowser
       
  1472     \internal
       
  1473     \inmodule QtDesigner
       
  1474     \since 4.4
       
  1475 
       
  1476     \brief QtAbstractPropertyBrowser provides a base class for
       
  1477     implementing property browsers.
       
  1478 
       
  1479     A property browser is a widget that enables the user to edit a
       
  1480     given set of properties.  Each property is represented by a label
       
  1481     specifying the property's name, and an editing widget (e.g. a line
       
  1482     edit or a combobox) holding its value. A property can have zero or
       
  1483     more subproperties.
       
  1484 
       
  1485     \image qtpropertybrowser.png
       
  1486 
       
  1487     The top level properties can be retrieved using the
       
  1488     properties() function. To traverse each property's
       
  1489     subproperties, use the QtProperty::subProperties() function. In
       
  1490     addition, the set of top level properties can be manipulated using
       
  1491     the addProperty(), insertProperty() and removeProperty()
       
  1492     functions. Note that the QtProperty class provides a corresponding
       
  1493     set of functions making it possible to manipulate the set of
       
  1494     subproperties as well.
       
  1495 
       
  1496     To remove all the properties from the property browser widget, use
       
  1497     the clear() function. This function will clear the editor, but it
       
  1498     will not delete the properties since they can still be used in
       
  1499     other editors.
       
  1500 
       
  1501     The properties themselves are created and managed by
       
  1502     implementations of the QtAbstractPropertyManager class. A manager
       
  1503     can handle (i.e. create and manage) properties of a given type. In
       
  1504     the property browser the managers are associated with
       
  1505     implementations of the QtAbstractEditorFactory: A factory is a
       
  1506     class able to create an editing widget of a specified type.
       
  1507 
       
  1508     When using a property browser widget, managers must be created for
       
  1509     each of the required property types before the properties
       
  1510     themselves can be created. To ensure that the properties' values
       
  1511     will be displayed using suitable editing widgets, the managers
       
  1512     must be associated with objects of the preferred factory
       
  1513     implementations using the setFactoryForManager() function. The
       
  1514     property browser will use these associations to determine which
       
  1515     factory it should use to create the preferred editing widget.
       
  1516 
       
  1517     Note that a factory can be associated with many managers, but a
       
  1518     manager can only be associated with one single factory within the
       
  1519     context of a single property browser.  The associations between
       
  1520     managers and factories can at any time be removed using the
       
  1521     unsetFactoryForManager() function.
       
  1522 
       
  1523     Whenever the property data changes or a property is inserted or
       
  1524     removed, the itemChanged(), itemInserted() or
       
  1525     itemRemoved() functions are called, respectively. These
       
  1526     functions must be reimplemented in derived classes in order to
       
  1527     update the property browser widget. Be aware that some property
       
  1528     instances can appear several times in an abstract tree
       
  1529     structure. For example:
       
  1530 
       
  1531     \table 100%
       
  1532     \row
       
  1533     \o
       
  1534     \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 2
       
  1535     \o  \image qtpropertybrowser-duplicate.png
       
  1536     \endtable
       
  1537 
       
  1538     The addProperty() function returns a QtBrowserItem that uniquely
       
  1539     identifies the created item.
       
  1540 
       
  1541     To make a property editable in the property browser, the
       
  1542     createEditor() function must be called to provide the
       
  1543     property with a suitable editing widget.
       
  1544 
       
  1545     Note that there are two ready-made property browser
       
  1546     implementations:
       
  1547 
       
  1548     \list
       
  1549         \o QtGroupBoxPropertyBrowser
       
  1550         \o QtTreePropertyBrowser
       
  1551     \endlist
       
  1552 
       
  1553     \sa QtAbstractPropertyManager, QtAbstractEditorFactoryBase
       
  1554 */
       
  1555 
       
  1556 /*!
       
  1557     \fn void QtAbstractPropertyBrowser::setFactoryForManager(PropertyManager *manager,
       
  1558                     QtAbstractEditorFactory<PropertyManager> *factory)
       
  1559 
       
  1560     Connects the given \a manager to the given \a factory, ensuring
       
  1561     that properties of the \a manager's type will be displayed with an
       
  1562     editing widget suitable for their value.
       
  1563 
       
  1564     For example:
       
  1565 
       
  1566     \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 3
       
  1567 
       
  1568     In this example the \c myInteger property's value is displayed
       
  1569     with a QSpinBox widget, while the \c myDouble property's value is
       
  1570     displayed with a QDoubleSpinBox widget.
       
  1571 
       
  1572     Note that a factory can be associated with many managers, but a
       
  1573     manager can only be associated with one single factory.  If the
       
  1574     given \a manager already is associated with another factory, the
       
  1575     old association is broken before the new one established.
       
  1576 
       
  1577     This function ensures that the given \a manager and the given \a
       
  1578     factory are compatible, and it automatically calls the
       
  1579     QtAbstractEditorFactory::addPropertyManager() function if necessary.
       
  1580 
       
  1581     \sa unsetFactoryForManager()
       
  1582 */
       
  1583 
       
  1584 /*!
       
  1585     \fn virtual void QtAbstractPropertyBrowser::itemInserted(QtBrowserItem *insertedItem,
       
  1586         QtBrowserItem *precedingItem) = 0
       
  1587 
       
  1588     This function is called to update the widget whenever a property
       
  1589     is inserted or added to the property browser, passing pointers to
       
  1590     the \a insertedItem of property and the specified
       
  1591     \a precedingItem as parameters.
       
  1592 
       
  1593     If \a precedingItem is 0, the \a insertedItem was put at
       
  1594     the beginning of its parent item's list of subproperties. If
       
  1595     the parent of \a insertedItem is 0, the \a insertedItem was added as a top
       
  1596     level property of \e this property browser.
       
  1597 
       
  1598     This function must be reimplemented in derived classes. Note that
       
  1599     if the \a insertedItem's property has subproperties, this
       
  1600     method will be called for those properties as soon as the current call is finished.
       
  1601 
       
  1602     \sa insertProperty(), addProperty()
       
  1603 */
       
  1604 
       
  1605 /*!
       
  1606     \fn virtual void QtAbstractPropertyBrowser::itemRemoved(QtBrowserItem *item) = 0
       
  1607 
       
  1608     This function is called to update the widget whenever a property
       
  1609     is removed from the property browser, passing the pointer to the
       
  1610     \a item of the property as parameters. The passed \a item is
       
  1611     deleted just after this call is finished.
       
  1612 
       
  1613     If the the parent of \a item is 0, the removed \a item was a
       
  1614     top level property in this editor.
       
  1615 
       
  1616     This function must be reimplemented in derived classes. Note that
       
  1617     if the removed \a item's property has subproperties, this
       
  1618     method will be called for those properties just before the current call is started.
       
  1619 
       
  1620     \sa removeProperty()
       
  1621 */
       
  1622 
       
  1623 /*!
       
  1624     \fn virtual void QtAbstractPropertyBrowser::itemChanged(QtBrowserItem *item) = 0
       
  1625 
       
  1626     This function is called whenever a property's data changes,
       
  1627     passing a pointer to the \a item of property as parameter.
       
  1628 
       
  1629     This function must be reimplemented in derived classes in order to
       
  1630     update the property browser widget whenever a property's name,
       
  1631     tool tip, status tip, "what's this" text, value text or value icon
       
  1632     changes.
       
  1633 
       
  1634     Note that if the property browser contains several occurrences of
       
  1635     the same property, this method will be called once for each
       
  1636     occurrence (with a different item each time).
       
  1637 
       
  1638     \sa QtProperty, items()
       
  1639 */
       
  1640 
       
  1641 /*!
       
  1642     Creates an abstract property browser with the given \a parent.
       
  1643 */
       
  1644 QtAbstractPropertyBrowser::QtAbstractPropertyBrowser(QWidget *parent)
       
  1645     : QWidget(parent), d_ptr(new QtAbstractPropertyBrowserPrivate)
       
  1646 {
       
  1647     d_ptr->q_ptr = this;
       
  1648 
       
  1649 }
       
  1650 
       
  1651 /*!
       
  1652     Destroys the property browser, and destroys all the items that were
       
  1653     created by this property browser.
       
  1654 
       
  1655     Note that the properties that were displayed in the editor are not
       
  1656     deleted since they still can be used in other editors. Neither
       
  1657     does the destructor delete the property managers and editor
       
  1658     factories that were used by this property browser widget unless
       
  1659     this widget was their parent.
       
  1660 
       
  1661     \sa QtAbstractPropertyManager::~QtAbstractPropertyManager()
       
  1662 */
       
  1663 QtAbstractPropertyBrowser::~QtAbstractPropertyBrowser()
       
  1664 {
       
  1665     QList<QtBrowserItem *> indexes = topLevelItems();
       
  1666     QListIterator<QtBrowserItem *> itItem(indexes);
       
  1667     while (itItem.hasNext())
       
  1668         d_ptr->clearIndex(itItem.next());
       
  1669 }
       
  1670 
       
  1671 /*!
       
  1672     Returns the property browser's list of top level properties.
       
  1673 
       
  1674     To traverse the subproperties, use the QtProperty::subProperties()
       
  1675     function.
       
  1676 
       
  1677     \sa addProperty(), insertProperty(), removeProperty()
       
  1678 */
       
  1679 QList<QtProperty *> QtAbstractPropertyBrowser::properties() const
       
  1680 {
       
  1681     return d_ptr->m_subItems;
       
  1682 }
       
  1683 
       
  1684 /*!
       
  1685     Returns the property browser's list of all items associated
       
  1686     with the given \a property.
       
  1687 
       
  1688     There is one item per instance of the property in the browser.
       
  1689 
       
  1690     \sa topLevelItem()
       
  1691 */
       
  1692 
       
  1693 QList<QtBrowserItem *> QtAbstractPropertyBrowser::items(QtProperty *property) const
       
  1694 {
       
  1695     return d_ptr->m_propertyToIndexes.value(property);
       
  1696 }
       
  1697 
       
  1698 /*!
       
  1699     Returns the top-level items associated with the given \a property.
       
  1700 
       
  1701     Returns 0 if \a property wasn't inserted into this property
       
  1702     browser or isn't a top-level one.
       
  1703 
       
  1704     \sa topLevelItems(), items()
       
  1705 */
       
  1706 
       
  1707 QtBrowserItem *QtAbstractPropertyBrowser::topLevelItem(QtProperty *property) const
       
  1708 {
       
  1709     return d_ptr->m_topLevelPropertyToIndex.value(property);
       
  1710 }
       
  1711 
       
  1712 /*!
       
  1713     Returns the list of top-level items.
       
  1714 
       
  1715     \sa topLevelItem()
       
  1716 */
       
  1717 
       
  1718 QList<QtBrowserItem *> QtAbstractPropertyBrowser::topLevelItems() const
       
  1719 {
       
  1720     return d_ptr->m_topLevelIndexes;
       
  1721 }
       
  1722 
       
  1723 /*!
       
  1724     Removes all the properties from the editor, but does not delete
       
  1725     them since they can still be used in other editors.
       
  1726 
       
  1727     \sa removeProperty(), QtAbstractPropertyManager::clear()
       
  1728 */
       
  1729 void QtAbstractPropertyBrowser::clear()
       
  1730 {
       
  1731     QList<QtProperty *> subList = properties();
       
  1732     QListIterator<QtProperty *> itSub(subList);
       
  1733     itSub.toBack();
       
  1734     while (itSub.hasPrevious()) {
       
  1735         QtProperty *property = itSub.previous();
       
  1736         removeProperty(property);
       
  1737     }
       
  1738 }
       
  1739 
       
  1740 /*!
       
  1741     Appends the given \a property (and its subproperties) to the
       
  1742     property browser's list of top level properties. Returns the item
       
  1743     created by property browser which is associated with the \a property.
       
  1744     In order to get all children items created by the property
       
  1745     browser in this call, the returned item should be traversed.
       
  1746 
       
  1747     If the specified \a property is already added, this function does
       
  1748     nothing and returns 0.
       
  1749 
       
  1750     \sa insertProperty(), QtProperty::addSubProperty(), properties()
       
  1751 */
       
  1752 QtBrowserItem *QtAbstractPropertyBrowser::addProperty(QtProperty *property)
       
  1753 {
       
  1754     QtProperty *afterProperty = 0;
       
  1755     if (d_ptr->m_subItems.count() > 0)
       
  1756         afterProperty = d_ptr->m_subItems.last();
       
  1757     return insertProperty(property, afterProperty);
       
  1758 }
       
  1759 
       
  1760 /*!
       
  1761     \fn QtBrowserItem *QtAbstractPropertyBrowser::insertProperty(QtProperty *property,
       
  1762             QtProperty *afterProperty)
       
  1763 
       
  1764     Inserts the given \a property (and its subproperties) after
       
  1765     the specified \a afterProperty in the browser's list of top
       
  1766     level properties. Returns item created by property browser which
       
  1767     is associated with the \a property. In order to get all children items
       
  1768     created by the property browser in this call returned item should be traversed.
       
  1769 
       
  1770     If the specified \a afterProperty is 0, the given \a property is
       
  1771     inserted at the beginning of the list.  If \a property is
       
  1772     already inserted, this function does nothing and returns 0.
       
  1773 
       
  1774     \sa addProperty(), QtProperty::insertSubProperty(), properties()
       
  1775 */
       
  1776 QtBrowserItem *QtAbstractPropertyBrowser::insertProperty(QtProperty *property,
       
  1777             QtProperty *afterProperty)
       
  1778 {
       
  1779     if (!property)
       
  1780         return 0;
       
  1781 
       
  1782     // if item is already inserted in this item then cannot add.
       
  1783     QList<QtProperty *> pendingList = properties();
       
  1784     int pos = 0;
       
  1785     int newPos = 0;
       
  1786     QtProperty *properAfterProperty = 0;
       
  1787     while (pos < pendingList.count()) {
       
  1788         QtProperty *prop = pendingList.at(pos);
       
  1789         if (prop == property)
       
  1790             return 0;
       
  1791         if (prop == afterProperty) {
       
  1792             newPos = pos + 1;
       
  1793             properAfterProperty = afterProperty;
       
  1794         }
       
  1795         pos++;
       
  1796     }
       
  1797     d_ptr->createBrowserIndexes(property, 0, afterProperty);
       
  1798 
       
  1799     // traverse inserted subtree and connect to manager's signals
       
  1800     d_ptr->insertSubTree(property, 0);
       
  1801 
       
  1802     d_ptr->m_subItems.insert(newPos, property);
       
  1803     //propertyInserted(property, 0, properAfterProperty);
       
  1804     return topLevelItem(property);
       
  1805 }
       
  1806 
       
  1807 /*!
       
  1808     Removes the specified \a property (and its subproperties) from the
       
  1809     property browser's list of top level properties. All items
       
  1810     that were associated with the given \a property and its children
       
  1811     are deleted.
       
  1812 
       
  1813     Note that the properties are \e not deleted since they can still
       
  1814     be used in other editors.
       
  1815 
       
  1816     \sa clear(), QtProperty::removeSubProperty(), properties()
       
  1817 */
       
  1818 void QtAbstractPropertyBrowser::removeProperty(QtProperty *property)
       
  1819 {
       
  1820     if (!property)
       
  1821         return;
       
  1822 
       
  1823     QList<QtProperty *> pendingList = properties();
       
  1824     int pos = 0;
       
  1825     while (pos < pendingList.count()) {
       
  1826         if (pendingList.at(pos) == property) {
       
  1827             d_ptr->m_subItems.removeAt(pos); //perhaps this two lines
       
  1828             d_ptr->removeSubTree(property, 0); //should be moved down after propertyRemoved call.
       
  1829             //propertyRemoved(property, 0);
       
  1830 
       
  1831             d_ptr->removeBrowserIndexes(property, 0);
       
  1832 
       
  1833             // when item is deleted, item will call removeItem for top level items,
       
  1834             // and itemRemoved for nested items.
       
  1835 
       
  1836             return;
       
  1837         }
       
  1838         pos++;
       
  1839     }
       
  1840 }
       
  1841 
       
  1842 /*!
       
  1843     Creates an editing widget (with the given \a parent) for the given
       
  1844     \a property according to the previously established associations
       
  1845     between property managers and editor factories.
       
  1846 
       
  1847     If the property is created by a property manager which was not
       
  1848     associated with any of the existing factories in \e this property
       
  1849     editor, the function returns 0.
       
  1850 
       
  1851     To make a property editable in the property browser, the
       
  1852     createEditor() function must be called to provide the
       
  1853     property with a suitable editing widget.
       
  1854 
       
  1855     Reimplement this function to provide additional decoration for the
       
  1856     editing widgets created by the installed factories.
       
  1857 
       
  1858     \sa setFactoryForManager()
       
  1859 */
       
  1860 QWidget *QtAbstractPropertyBrowser::createEditor(QtProperty *property,
       
  1861                 QWidget *parent)
       
  1862 {
       
  1863     QtAbstractEditorFactoryBase *factory = 0;
       
  1864     QtAbstractPropertyManager *manager = property->propertyManager();
       
  1865 
       
  1866     if (m_viewToManagerToFactory()->contains(this) &&
       
  1867         (*m_viewToManagerToFactory())[this].contains(manager)) {
       
  1868         factory = (*m_viewToManagerToFactory())[this][manager];
       
  1869     }
       
  1870 
       
  1871     if (!factory)
       
  1872         return 0;
       
  1873     return factory->createEditor(property, parent);
       
  1874 }
       
  1875 
       
  1876 bool QtAbstractPropertyBrowser::addFactory(QtAbstractPropertyManager *abstractManager,
       
  1877             QtAbstractEditorFactoryBase *abstractFactory)
       
  1878 {
       
  1879     bool connectNeeded = false;
       
  1880     if (!m_managerToFactoryToViews()->contains(abstractManager) ||
       
  1881         !(*m_managerToFactoryToViews())[abstractManager].contains(abstractFactory)) {
       
  1882         connectNeeded = true;
       
  1883     } else if ((*m_managerToFactoryToViews())[abstractManager][abstractFactory]
       
  1884                     .contains(this)) {
       
  1885         return connectNeeded;
       
  1886     }
       
  1887 
       
  1888     if (m_viewToManagerToFactory()->contains(this) &&
       
  1889         (*m_viewToManagerToFactory())[this].contains(abstractManager)) {
       
  1890         unsetFactoryForManager(abstractManager);
       
  1891     }
       
  1892 
       
  1893     (*m_managerToFactoryToViews())[abstractManager][abstractFactory].append(this);
       
  1894     (*m_viewToManagerToFactory())[this][abstractManager] = abstractFactory;
       
  1895 
       
  1896     return connectNeeded;
       
  1897 }
       
  1898 
       
  1899 /*!
       
  1900     Removes the association between the given \a manager and the
       
  1901     factory bound to it, automatically calling the
       
  1902     QtAbstractEditorFactory::removePropertyManager() function if necessary.
       
  1903 
       
  1904     \sa setFactoryForManager()
       
  1905 */
       
  1906 void QtAbstractPropertyBrowser::unsetFactoryForManager(QtAbstractPropertyManager *manager)
       
  1907 {
       
  1908     if (!m_viewToManagerToFactory()->contains(this) ||
       
  1909         !(*m_viewToManagerToFactory())[this].contains(manager)) {
       
  1910         return;
       
  1911     }
       
  1912 
       
  1913     QtAbstractEditorFactoryBase *abstractFactory =
       
  1914                 (*m_viewToManagerToFactory())[this][manager];
       
  1915     (*m_viewToManagerToFactory())[this].remove(manager);
       
  1916     if ((*m_viewToManagerToFactory())[this].isEmpty()) {
       
  1917         (*m_viewToManagerToFactory()).remove(this);
       
  1918     }
       
  1919 
       
  1920     (*m_managerToFactoryToViews())[manager][abstractFactory].removeAll(this);
       
  1921     if ((*m_managerToFactoryToViews())[manager][abstractFactory].isEmpty()) {
       
  1922         (*m_managerToFactoryToViews())[manager].remove(abstractFactory);
       
  1923         abstractFactory->breakConnection(manager);
       
  1924         if ((*m_managerToFactoryToViews())[manager].isEmpty()) {
       
  1925             (*m_managerToFactoryToViews()).remove(manager);
       
  1926         }
       
  1927     }
       
  1928 }
       
  1929 
       
  1930 /*!
       
  1931     Returns the current item in the property browser.
       
  1932 
       
  1933     \sa setCurrentItem()
       
  1934 */
       
  1935 QtBrowserItem *QtAbstractPropertyBrowser::currentItem() const
       
  1936 {
       
  1937     return d_ptr->m_currentItem;
       
  1938 }
       
  1939 
       
  1940 /*!
       
  1941     Sets the current item in the property browser to \a item.
       
  1942 
       
  1943     \sa currentItem(), currentItemChanged()
       
  1944 */
       
  1945 void QtAbstractPropertyBrowser::setCurrentItem(QtBrowserItem *item)
       
  1946 {
       
  1947     QtBrowserItem *oldItem = d_ptr->m_currentItem;
       
  1948     d_ptr->m_currentItem = item;
       
  1949     if (oldItem != item)
       
  1950         emit  currentItemChanged(item);
       
  1951 }
       
  1952 
       
  1953 QT_END_NAMESPACE
       
  1954 
       
  1955 #include "moc_qtpropertybrowser.cpp"