123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971 |
- /****************************************************************************
- **
- ** Copyright (C) 2016 The Qt Company Ltd.
- ** Contact: https://www.qt.io/licensing/
- **
- ** This file is part of the tools applications of the Qt Toolkit.
- **
- ** $QT_BEGIN_LICENSE:LGPL$
- ** Commercial License Usage
- ** Licensees holding valid commercial Qt licenses may use this file in
- ** accordance with the commercial license agreement provided with the
- ** Software or, alternatively, in accordance with the terms contained in
- ** a written agreement between you and The Qt Company. For licensing terms
- ** and conditions see https://www.qt.io/terms-conditions. For further
- ** information use the contact form at https://www.qt.io/contact-us.
- **
- ** GNU Lesser General Public License Usage
- ** Alternatively, this file may be used under the terms of the GNU Lesser
- ** General Public License version 3 as published by the Free Software
- ** Foundation and appearing in the file LICENSE.LGPL3 included in the
- ** packaging of this file. Please review the following information to
- ** ensure the GNU Lesser General Public License version 3 requirements
- ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
- **
- ** GNU General Public License Usage
- ** Alternatively, this file may be used under the terms of the GNU
- ** General Public License version 2.0 or (at your option) the GNU General
- ** Public license version 3 or any later version approved by the KDE Free
- ** Qt Foundation. The licenses are as published by the Free Software
- ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
- ** included in the packaging of this file. Please review the following
- ** information to ensure the GNU General Public License requirements will
- ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
- ** https://www.gnu.org/licenses/gpl-3.0.html.
- **
- ** $QT_END_LICENSE$
- **
- ****************************************************************************/
- #include "qtpropertybrowser.h"
- #include <QtCore/QSet>
- #include <QtCore/QMap>
- #include <QtGui/QIcon>
- #if defined(Q_CC_MSVC)
- # pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */
- #endif
- QT_BEGIN_NAMESPACE
- class QtPropertyPrivate
- {
- public:
- QtPropertyPrivate(QtAbstractPropertyManager *manager) : m_enabled(true), m_modified(false), m_manager(manager) {}
- QtProperty *q_ptr;
- QSet<QtProperty *> m_parentItems;
- QList<QtProperty *> m_subItems;
- QString m_valueToolTip;
- QString m_descriptionToolTip;
- QString m_statusTip;
- QString m_whatsThis;
- QString m_name;
- bool m_enabled;
- bool m_modified;
- QtAbstractPropertyManager * const m_manager;
- };
- class QtAbstractPropertyManagerPrivate
- {
- QtAbstractPropertyManager *q_ptr;
- Q_DECLARE_PUBLIC(QtAbstractPropertyManager)
- public:
- void propertyDestroyed(QtProperty *property);
- void propertyChanged(QtProperty *property) const;
- void propertyRemoved(QtProperty *property,
- QtProperty *parentProperty) const;
- void propertyInserted(QtProperty *property, QtProperty *parentProperty,
- QtProperty *afterProperty) const;
- QSet<QtProperty *> m_properties;
- };
- /*!
- \class QtProperty
- \internal
- \inmodule QtDesigner
- \since 4.4
- \brief The QtProperty class encapsulates an instance of a property.
- Properties are created by objects of QtAbstractPropertyManager
- subclasses; a manager can create properties of a given type, and
- is used in conjunction with the QtAbstractPropertyBrowser class. A
- property is always owned by the manager that created it, which can
- be retrieved using the propertyManager() function.
- QtProperty contains the most common property attributes, and
- provides functions for retrieving as well as setting their values:
- \table
- \header \li Getter \li Setter
- \row
- \li propertyName() \li setPropertyName()
- \row
- \li statusTip() \li setStatusTip()
- \row
- \li descriptionToolTip() \li setDescriptionToolTip()
- \row
- \li valueToolTip() \li setValueToolTip()
- \row
- \li toolTip() \deprecated in 5.6 \li setToolTip() \deprecated in 5.6
- \row
- \li whatsThis() \li setWhatsThis()
- \row
- \li isEnabled() \li setEnabled()
- \row
- \li isModified() \li setModified()
- \row
- \li valueText() \li Nop
- \row
- \li valueIcon() \li Nop
- \endtable
- It is also possible to nest properties: QtProperty provides the
- addSubProperty(), insertSubProperty() and removeSubProperty() functions to
- manipulate the set of subproperties. Use the subProperties()
- function to retrieve a property's current set of subproperties.
- Note that nested properties are not owned by the parent property,
- i.e. each subproperty is owned by the manager that created it.
- \sa QtAbstractPropertyManager, QtBrowserItem
- */
- /*!
- Creates a property with the given \a manager.
- This constructor is only useful when creating a custom QtProperty
- subclass (e.g. QtVariantProperty). To create a regular QtProperty
- object, use the QtAbstractPropertyManager::addProperty()
- function instead.
- \sa QtAbstractPropertyManager::addProperty()
- */
- QtProperty::QtProperty(QtAbstractPropertyManager *manager)
- : d_ptr(new QtPropertyPrivate(manager))
- {
- d_ptr->q_ptr = this;
- }
- /*!
- Destroys this property.
- Note that subproperties are detached but not destroyed, i.e. they
- can still be used in another context.
- \sa QtAbstractPropertyManager::clear()
- */
- QtProperty::~QtProperty()
- {
- for (QtProperty *property : qAsConst(d_ptr->m_parentItems))
- property->d_ptr->m_manager->d_ptr->propertyRemoved(this, property);
- d_ptr->m_manager->d_ptr->propertyDestroyed(this);
- for (QtProperty *property : qAsConst(d_ptr->m_subItems))
- property->d_ptr->m_parentItems.remove(this);
- for (QtProperty *property : qAsConst(d_ptr->m_parentItems))
- property->d_ptr->m_subItems.removeAll(this);
- }
- /*!
- Returns the set of subproperties.
- Note that subproperties are not owned by \e this property, but by
- the manager that created them.
- \sa insertSubProperty(), removeSubProperty()
- */
- QList<QtProperty *> QtProperty::subProperties() const
- {
- return d_ptr->m_subItems;
- }
- /*!
- Returns a pointer to the manager that owns this property.
- */
- QtAbstractPropertyManager *QtProperty::propertyManager() const
- {
- return d_ptr->m_manager;
- }
- /* Note: As of 17.7.2015 for Qt 5.6, the existing 'toolTip' of the Property
- * Browser solution was split into valueToolTip() and descriptionToolTip()
- * to be able to implement custom tool tip for QTBUG-45442. This could
- * be back-ported to the solution. */
- /*!
- Returns the property value's tool tip.
- This is suitable for tool tips over the value (item delegate).
- \since 5.6
- \sa setValueToolTip()
- */
- QString QtProperty::valueToolTip() const
- {
- return d_ptr->m_valueToolTip;
- }
- /*!
- Returns the property description's tool tip.
- This is suitable for tool tips over the description (label).
- \since 5.6
- \sa setDescriptionToolTip()
- */
- QString QtProperty::descriptionToolTip() const
- {
- return d_ptr->m_descriptionToolTip;
- }
- /*!
- Returns the property's status tip.
- \sa setStatusTip()
- */
- QString QtProperty::statusTip() const
- {
- return d_ptr->m_statusTip;
- }
- /*!
- Returns the property's "What's This" help text.
- \sa setWhatsThis()
- */
- QString QtProperty::whatsThis() const
- {
- return d_ptr->m_whatsThis;
- }
- /*!
- Returns the property's name.
- \sa setPropertyName()
- */
- QString QtProperty::propertyName() const
- {
- return d_ptr->m_name;
- }
- /*!
- Returns whether the property is enabled.
- \sa setEnabled()
- */
- bool QtProperty::isEnabled() const
- {
- return d_ptr->m_enabled;
- }
- /*!
- Returns whether the property is modified.
- \sa setModified()
- */
- bool QtProperty::isModified() const
- {
- return d_ptr->m_modified;
- }
- /*!
- Returns whether the property has a value.
- \sa QtAbstractPropertyManager::hasValue()
- */
- bool QtProperty::hasValue() const
- {
- return d_ptr->m_manager->hasValue(this);
- }
- /*!
- Returns an icon representing the current state of this property.
- If the given property type can not generate such an icon, this
- function returns an invalid icon.
- \sa QtAbstractPropertyManager::valueIcon()
- */
- QIcon QtProperty::valueIcon() const
- {
- return d_ptr->m_manager->valueIcon(this);
- }
- /*!
- Returns a string representing the current state of this property.
- If the given property type can not generate such a string, this
- function returns an empty string.
- \sa QtAbstractPropertyManager::valueText()
- */
- QString QtProperty::valueText() const
- {
- return d_ptr->m_manager->valueText(this);
- }
- /*!
- Sets the property value's tool tip to the given \a text.
- \since 5.6
- \sa valueToolTip()
- */
- void QtProperty::setValueToolTip(const QString &text)
- {
- if (d_ptr->m_valueToolTip == text)
- return;
- d_ptr->m_valueToolTip = text;
- propertyChanged();
- }
- /*!
- Sets the property description's tool tip to the given \a text.
- \since 5.6
- \sa descriptionToolTip()
- */
- void QtProperty::setDescriptionToolTip(const QString &text)
- {
- if (d_ptr->m_descriptionToolTip == text)
- return;
- d_ptr->m_descriptionToolTip = text;
- propertyChanged();
- }
- /*!
- Sets the property's status tip to the given \a text.
- \sa statusTip()
- */
- void QtProperty::setStatusTip(const QString &text)
- {
- if (d_ptr->m_statusTip == text)
- return;
- d_ptr->m_statusTip = text;
- propertyChanged();
- }
- /*!
- Sets the property's "What's This" help text to the given \a text.
- \sa whatsThis()
- */
- void QtProperty::setWhatsThis(const QString &text)
- {
- if (d_ptr->m_whatsThis == text)
- return;
- d_ptr->m_whatsThis = text;
- propertyChanged();
- }
- /*!
- \fn void QtProperty::setPropertyName(const QString &name)
- Sets the property's name to the given \a name.
- \sa propertyName()
- */
- void QtProperty::setPropertyName(const QString &text)
- {
- if (d_ptr->m_name == text)
- return;
- d_ptr->m_name = text;
- propertyChanged();
- }
- /*!
- Enables or disables the property according to the passed \a enable value.
- \sa isEnabled()
- */
- void QtProperty::setEnabled(bool enable)
- {
- if (d_ptr->m_enabled == enable)
- return;
- d_ptr->m_enabled = enable;
- propertyChanged();
- }
- /*!
- Sets the property's modified state according to the passed \a modified value.
- \sa isModified()
- */
- void QtProperty::setModified(bool modified)
- {
- if (d_ptr->m_modified == modified)
- return;
- d_ptr->m_modified = modified;
- propertyChanged();
- }
- /*!
- Appends the given \a property to this property's subproperties.
- If the given \a property already is added, this function does
- nothing.
- \sa insertSubProperty(), removeSubProperty()
- */
- void QtProperty::addSubProperty(QtProperty *property)
- {
- QtProperty *after = 0;
- if (d_ptr->m_subItems.count() > 0)
- after = d_ptr->m_subItems.last();
- insertSubProperty(property, after);
- }
- /*!
- \fn void QtProperty::insertSubProperty(QtProperty *property, QtProperty *precedingProperty)
- Inserts the given \a property after the specified \a
- precedingProperty into this property's list of subproperties. If
- \a precedingProperty is 0, the specified \a property is inserted
- at the beginning of the list.
- If the given \a property already is inserted, this function does
- nothing.
- \sa addSubProperty(), removeSubProperty()
- */
- void QtProperty::insertSubProperty(QtProperty *property,
- QtProperty *afterProperty)
- {
- if (!property)
- return;
- if (property == this)
- return;
- // traverse all children of item. if this item is a child of item then cannot add.
- QList<QtProperty *> pendingList = property->subProperties();
- QMap<QtProperty *, bool> visited;
- while (!pendingList.isEmpty()) {
- QtProperty *i = pendingList.first();
- if (i == this)
- return;
- pendingList.removeFirst();
- if (visited.contains(i))
- continue;
- visited[i] = true;
- pendingList += i->subProperties();
- }
- pendingList = subProperties();
- int pos = 0;
- int newPos = 0;
- QtProperty *properAfterProperty = 0;
- while (pos < pendingList.count()) {
- QtProperty *i = pendingList.at(pos);
- if (i == property)
- return; // if item is already inserted in this item then cannot add.
- if (i == afterProperty) {
- newPos = pos + 1;
- properAfterProperty = afterProperty;
- }
- pos++;
- }
- d_ptr->m_subItems.insert(newPos, property);
- property->d_ptr->m_parentItems.insert(this);
- d_ptr->m_manager->d_ptr->propertyInserted(property, this, properAfterProperty);
- }
- /*!
- Removes the given \a property from the list of subproperties
- without deleting it.
- \sa addSubProperty(), insertSubProperty()
- */
- void QtProperty::removeSubProperty(QtProperty *property)
- {
- if (!property)
- return;
- d_ptr->m_manager->d_ptr->propertyRemoved(property, this);
- QList<QtProperty *> pendingList = subProperties();
- int pos = 0;
- while (pos < pendingList.count()) {
- if (pendingList.at(pos) == property) {
- d_ptr->m_subItems.removeAt(pos);
- property->d_ptr->m_parentItems.remove(this);
- return;
- }
- pos++;
- }
- }
- /*!
- \internal
- */
- void QtProperty::propertyChanged()
- {
- d_ptr->m_manager->d_ptr->propertyChanged(this);
- }
- ////////////////////////////////
- void QtAbstractPropertyManagerPrivate::propertyDestroyed(QtProperty *property)
- {
- if (m_properties.contains(property)) {
- emit q_ptr->propertyDestroyed(property);
- q_ptr->uninitializeProperty(property);
- m_properties.remove(property);
- }
- }
- void QtAbstractPropertyManagerPrivate::propertyChanged(QtProperty *property) const
- {
- emit q_ptr->propertyChanged(property);
- }
- void QtAbstractPropertyManagerPrivate::propertyRemoved(QtProperty *property,
- QtProperty *parentProperty) const
- {
- emit q_ptr->propertyRemoved(property, parentProperty);
- }
- void QtAbstractPropertyManagerPrivate::propertyInserted(QtProperty *property,
- QtProperty *parentProperty, QtProperty *afterProperty) const
- {
- emit q_ptr->propertyInserted(property, parentProperty, afterProperty);
- }
- /*!
- \class QtAbstractPropertyManager
- \internal
- \inmodule QtDesigner
- \since 4.4
- \brief The QtAbstractPropertyManager provides an interface for
- property managers.
- A manager can create and manage properties of a given type, and is
- used in conjunction with the QtAbstractPropertyBrowser class.
- When using a property browser widget, the properties are created
- and managed by implementations of the QtAbstractPropertyManager
- class. To ensure that the properties' values will be displayed
- using suitable editing widgets, the managers are associated with
- objects of QtAbstractEditorFactory subclasses. The property browser
- will use these associations to determine which factories it should
- use to create the preferred editing widgets.
- The QtAbstractPropertyManager class provides common functionality
- like creating a property using the addProperty() function, and
- retrieving the properties created by the manager using the
- properties() function. The class also provides signals that are
- emitted when the manager's properties change: propertyInserted(),
- propertyRemoved(), propertyChanged() and propertyDestroyed().
- QtAbstractPropertyManager subclasses are supposed to provide their
- own type specific API. Note that several ready-made
- implementations are available:
- \list
- \li QtBoolPropertyManager
- \li QtColorPropertyManager
- \li QtDatePropertyManager
- \li QtDateTimePropertyManager
- \li QtDoublePropertyManager
- \li QtEnumPropertyManager
- \li QtFlagPropertyManager
- \li QtFontPropertyManager
- \li QtGroupPropertyManager
- \li QtIntPropertyManager
- \li QtPointPropertyManager
- \li QtRectPropertyManager
- \li QtSizePropertyManager
- \li QtSizePolicyPropertyManager
- \li QtStringPropertyManager
- \li QtTimePropertyManager
- \li QtVariantPropertyManager
- \endlist
- \sa QtAbstractEditorFactoryBase, QtAbstractPropertyBrowser, QtProperty
- */
- /*!
- \fn void QtAbstractPropertyManager::propertyInserted(QtProperty *newProperty,
- QtProperty *parentProperty, QtProperty *precedingProperty)
- This signal is emitted when a new subproperty is inserted into an
- existing property, passing pointers to the \a newProperty, \a
- parentProperty and \a precedingProperty as parameters.
- If \a precedingProperty is 0, the \a newProperty was inserted at
- the beginning of the \a parentProperty's subproperties list.
- Note that signal is emitted only if the \a parentProperty is created
- by this manager.
- \sa QtAbstractPropertyBrowser::itemInserted()
- */
- /*!
- \fn void QtAbstractPropertyManager::propertyChanged(QtProperty *property)
- This signal is emitted whenever a property's data changes, passing
- a pointer to the \a property as parameter.
- Note that signal is only emitted for properties that are created by
- this manager.
- \sa QtAbstractPropertyBrowser::itemChanged()
- */
- /*!
- \fn void QtAbstractPropertyManager::propertyRemoved(QtProperty *property, QtProperty *parent)
- This signal is emitted when a subproperty is removed, passing
- pointers to the removed \a property and the \a parent property as
- parameters.
- Note that signal is emitted only when the \a parent property is
- created by this manager.
- \sa QtAbstractPropertyBrowser::itemRemoved()
- */
- /*!
- \fn void QtAbstractPropertyManager::propertyDestroyed(QtProperty *property)
- This signal is emitted when the specified \a property is about to
- be destroyed.
- Note that signal is only emitted for properties that are created
- by this manager.
- \sa clear(), uninitializeProperty()
- */
- /*!
- \fn void QtAbstractPropertyBrowser::currentItemChanged(QtBrowserItem *current)
- This signal is emitted when the current item changes. The current item is specified by \a current.
- \sa QtAbstractPropertyBrowser::setCurrentItem()
- */
- /*!
- Creates an abstract property manager with the given \a parent.
- */
- QtAbstractPropertyManager::QtAbstractPropertyManager(QObject *parent)
- : QObject(parent), d_ptr(new QtAbstractPropertyManagerPrivate)
- {
- d_ptr->q_ptr = this;
- }
- /*!
- Destroys the manager. All properties created by the manager are
- destroyed.
- */
- QtAbstractPropertyManager::~QtAbstractPropertyManager()
- {
- clear();
- }
- /*!
- Destroys all the properties that this manager has created.
- \sa propertyDestroyed(), uninitializeProperty()
- */
- void QtAbstractPropertyManager::clear() const
- {
- while (!d_ptr->m_properties.isEmpty())
- delete *d_ptr->m_properties.cbegin();
- }
- /*!
- Returns the set of properties created by this manager.
- \sa addProperty()
- */
- QSet<QtProperty *> QtAbstractPropertyManager::properties() const
- {
- return d_ptr->m_properties;
- }
- /*!
- Returns whether the given \a property has a value.
- The default implementation of this function returns true.
- \sa QtProperty::hasValue()
- */
- bool QtAbstractPropertyManager::hasValue(const QtProperty *property) const
- {
- Q_UNUSED(property);
- return true;
- }
- /*!
- Returns an icon representing the current state of the given \a
- property.
- The default implementation of this function returns an invalid
- icon.
- \sa QtProperty::valueIcon()
- */
- QIcon QtAbstractPropertyManager::valueIcon(const QtProperty *property) const
- {
- Q_UNUSED(property);
- return QIcon();
- }
- /*!
- Returns a string representing the current state of the given \a
- property.
- The default implementation of this function returns an empty
- string.
- \sa QtProperty::valueText()
- */
- QString QtAbstractPropertyManager::valueText(const QtProperty *property) const
- {
- Q_UNUSED(property);
- return QString();
- }
- /*!
- Creates a property with the given \a name which then is owned by this manager.
- Internally, this function calls the createProperty() and
- initializeProperty() functions.
- \sa initializeProperty(), properties()
- */
- /// <summary>
- /// 添加属性到列表中
- /// </summary>
- /// <param name="name"></param>
- /// <returns></returns>
- QtProperty *QtAbstractPropertyManager::addProperty(const QString &name)
- {
- QtProperty *property = createProperty();
- // 创建属性
- if (property)
- {
- // 设置属性名称
- property->setPropertyName(name);
- // 数据结构中保存此属性
- d_ptr->m_properties.insert(property);
- // 初始化本属性
- initializeProperty(property);
- }
- // 创建完毕后,返回
- return property;
- }
- /*!
- Creates a property.
- The base implementation produce QtProperty instances; Reimplement
- this function to make this manager produce objects of a QtProperty
- subclass.
- \sa addProperty(), initializeProperty()
- */
- QtProperty *QtAbstractPropertyManager::createProperty()
- {
- return new QtProperty(this);
- }
- /*!
- \fn void QtAbstractPropertyManager::initializeProperty(QtProperty *property) = 0
- This function is called whenever a new valid property pointer has
- been created, passing the pointer as parameter.
- The purpose is to let the manager know that the \a property has
- been created so that it can provide additional attributes for the
- new property, e.g. QtIntPropertyManager adds \l
- {QtIntPropertyManager::value()}{value}, \l
- {QtIntPropertyManager::minimum()}{minimum} and \l
- {QtIntPropertyManager::maximum()}{maximum} attributes. Since each manager
- subclass adds type specific attributes, this function is pure
- virtual and must be reimplemented when deriving from the
- QtAbstractPropertyManager class.
- \sa addProperty(), createProperty()
- */
- /*!
- This function is called just before the specified \a property is destroyed.
- The purpose is to let the property manager know that the \a
- property is being destroyed so that it can remove the property's
- additional attributes.
- \sa clear(), propertyDestroyed()
- */
- void QtAbstractPropertyManager::uninitializeProperty(QtProperty *property)
- {
- Q_UNUSED(property);
- }
- ////////////////////////////////////
- /*!
- \class QtAbstractEditorFactoryBase
- \internal
- \inmodule QtDesigner
- \since 4.4
- \brief The QtAbstractEditorFactoryBase provides an interface for
- editor factories.
- An editor factory is a class that is able to create an editing
- widget of a specified type (e.g. line edits or comboboxes) for a
- given QtProperty object, and it is used in conjunction with the
- QtAbstractPropertyManager and QtAbstractPropertyBrowser classes.
- When using a property browser widget, the properties are created
- and managed by implementations of the QtAbstractPropertyManager
- class. To ensure that the properties' values will be displayed
- using suitable editing widgets, the managers are associated with
- objects of QtAbstractEditorFactory subclasses. The property browser
- will use these associations to determine which factories it should
- use to create the preferred editing widgets.
- Typically, an editor factory is created by subclassing the
- QtAbstractEditorFactory template class which inherits
- QtAbstractEditorFactoryBase. But note that several ready-made
- implementations are available:
- \list
- \li QtCheckBoxFactory
- \li QtDateEditFactory
- \li QtDateTimeEditFactory
- \li QtDoubleSpinBoxFactory
- \li QtEnumEditorFactory
- \li QtLineEditFactory
- \li QtScrollBarFactory
- \li QtSliderFactory
- \li QtSpinBoxFactory
- \li QtTimeEditFactory
- \li QtVariantEditorFactory
- \endlist
- \sa QtAbstractPropertyManager, QtAbstractPropertyBrowser
- */
- /*!
- \fn virtual QWidget *QtAbstractEditorFactoryBase::createEditor(QtProperty *property,
- QWidget *parent) = 0
- Creates an editing widget (with the given \a parent) for the given
- \a property.
- This function is reimplemented in QtAbstractEditorFactory template class
- which also provides a pure virtual convenience overload of this
- function enabling access to the property's manager.
- \sa QtAbstractEditorFactory::createEditor()
- */
- /*!
- \fn QtAbstractEditorFactoryBase::QtAbstractEditorFactoryBase(QObject *parent = 0)
- Creates an abstract editor factory with the given \a parent.
- */
- /*!
- \fn virtual void QtAbstractEditorFactoryBase::breakConnection(QtAbstractPropertyManager *manager) = 0
- \internal
- Detaches property manager from factory.
- This method is reimplemented in QtAbstractEditorFactory template subclass.
- You don't need to reimplement it in your subclasses. Instead implement more convenient
- QtAbstractEditorFactory::disconnectPropertyManager() which gives you access to particular manager subclass.
- */
- /*!
- \fn virtual void QtAbstractEditorFactoryBase::managerDestroyed(QObject *manager) = 0
- \internal
- This method is called when property manager is being destroyed.
- Basically it notifies factory not to produce editors for properties owned by \a manager.
- You don't need to reimplement it in your subclass. This method is implemented in
- QtAbstractEditorFactory template subclass.
- */
- /*!
- \class QtAbstractEditorFactory
- \internal
- \inmodule QtDesigner
- \since 4.4
- \brief The QtAbstractEditorFactory is the base template class for editor
- factories.
- An editor factory is a class that is able to create an editing
- widget of a specified type (e.g. line edits or comboboxes) for a
- given QtProperty object, and it is used in conjunction with the
- QtAbstractPropertyManager and QtAbstractPropertyBrowser classes.
- Note that the QtAbstractEditorFactory functions are using the
- PropertyManager template argument class which can be any
- QtAbstractPropertyManager subclass. For example:
- \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 0
- Note that QtSpinBoxFactory by definition creates editing widgets
- \e only for properties created by QtIntPropertyManager.
- When using a property browser widget, the properties are created
- and managed by implementations of the QtAbstractPropertyManager
- class. To ensure that the properties' values will be displayed
- using suitable editing widgets, the managers are associated with
- objects of QtAbstractEditorFactory subclasses. The property browser will
- use these associations to determine which factories it should use
- to create the preferred editing widgets.
- A QtAbstractEditorFactory object is capable of producing editors for
- several property managers at the same time. To create an
- association between this factory and a given manager, use the
- addPropertyManager() function. Use the removePropertyManager() function to make
- this factory stop producing editors for a given property
- manager. Use the propertyManagers() function to retrieve the set of
- managers currently associated with this factory.
- Several ready-made implementations of the QtAbstractEditorFactory class
- are available:
- \list
- \li QtCheckBoxFactory
- \li QtDateEditFactory
- \li QtDateTimeEditFactory
- \li QtDoubleSpinBoxFactory
- \li QtEnumEditorFactory
- \li QtLineEditFactory
- \li QtScrollBarFactory
- \li QtSliderFactory
- \li QtSpinBoxFactory
- \li QtTimeEditFactory
- \li QtVariantEditorFactory
- \endlist
- When deriving from the QtAbstractEditorFactory class, several pure virtual
- functions must be implemented: the connectPropertyManager() function is
- used by the factory to connect to the given manager's signals, the
- createEditor() function is supposed to create an editor for the
- given property controlled by the given manager, and finally the
- disconnectPropertyManager() function is used by the factory to disconnect
- from the specified manager's signals.
- \sa QtAbstractEditorFactoryBase, QtAbstractPropertyManager
- */
- /*!
- \fn QtAbstractEditorFactory::QtAbstractEditorFactory(QObject *parent = 0)
- Creates an editor factory with the given \a parent.
- \sa addPropertyManager()
- */
- /*!
- \fn QWidget *QtAbstractEditorFactory::createEditor(QtProperty *property, QWidget *parent)
- Creates an editing widget (with the given \a parent) for the given
- \a property.
- */
- /*!
- \fn void QtAbstractEditorFactory::addPropertyManager(PropertyManager *manager)
- Adds the given \a manager to this factory's set of managers,
- making this factory produce editing widgets for properties created
- by the given manager.
- The PropertyManager type is a template argument class, and represents the chosen
- QtAbstractPropertyManager subclass.
- \sa propertyManagers(), removePropertyManager()
- */
- /*!
- \fn void QtAbstractEditorFactory::removePropertyManager(PropertyManager *manager)
- Removes the given \a manager from this factory's set of
- managers. The PropertyManager type is a template argument class, and may be
- any QtAbstractPropertyManager subclass.
- \sa propertyManagers(), addPropertyManager()
- */
- /*!
- \fn virtual void QtAbstractEditorFactory::connectPropertyManager(PropertyManager *manager) = 0
- Connects this factory to the given \a manager's signals. The
- PropertyManager type is a template argument class, and represents
- the chosen QtAbstractPropertyManager subclass.
- This function is used internally by the addPropertyManager() function, and
- makes it possible to update an editing widget when the associated
- property's data changes. This is typically done in custom slots
- responding to the signals emitted by the property's manager,
- e.g. QtIntPropertyManager::valueChanged() and
- QtIntPropertyManager::rangeChanged().
- \sa propertyManagers(), disconnectPropertyManager()
- */
- /*!
- \fn virtual QWidget *QtAbstractEditorFactory::createEditor(PropertyManager *manager, QtProperty *property,
- QWidget *parent) = 0
- Creates an editing widget with the given \a parent for the
- specified \a property created by the given \a manager. The
- PropertyManager type is a template argument class, and represents
- the chosen QtAbstractPropertyManager subclass.
- This function must be implemented in derived classes: It is
- recommended to store a pointer to the widget and map it to the
- given \a property, since the widget must be updated whenever the
- associated property's data changes. This is typically done in
- custom slots responding to the signals emitted by the property's
- manager, e.g. QtIntPropertyManager::valueChanged() and
- QtIntPropertyManager::rangeChanged().
- \sa connectPropertyManager()
- */
- /*!
- \fn virtual void QtAbstractEditorFactory::disconnectPropertyManager(PropertyManager *manager) = 0
- Disconnects this factory from the given \a manager's signals. The
- PropertyManager type is a template argument class, and represents
- the chosen QtAbstractPropertyManager subclass.
- This function is used internally by the removePropertyManager() function.
- \sa propertyManagers(), connectPropertyManager()
- */
- /*!
- \fn QSet<PropertyManager *> QtAbstractEditorFactory::propertyManagers() const
- Returns the factory's set of associated managers. The
- PropertyManager type is a template argument class, and represents
- the chosen QtAbstractPropertyManager subclass.
- \sa addPropertyManager(), removePropertyManager()
- */
- /*!
- \fn PropertyManager *QtAbstractEditorFactory::propertyManager(QtProperty *property) const
- Returns the property manager for the given \a property, or 0 if
- the given \a property doesn't belong to any of this factory's
- registered managers.
- The PropertyManager type is a template argument class, and represents the chosen
- QtAbstractPropertyManager subclass.
- \sa propertyManagers()
- */
- /*!
- \fn virtual void QtAbstractEditorFactory::managerDestroyed(QObject *manager)
- \internal
- */
- ////////////////////////////////////
- class QtBrowserItemPrivate
- {
- public:
- QtBrowserItemPrivate(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent)
- : m_browser(browser), m_property(property), m_parent(parent), q_ptr(0) {}
- void addChild(QtBrowserItem *index, QtBrowserItem *after);
- void removeChild(QtBrowserItem *index);
- QtAbstractPropertyBrowser * const m_browser;
- QtProperty *m_property;
- QtBrowserItem *m_parent;
- QtBrowserItem *q_ptr;
- QList<QtBrowserItem *> m_children;
- };
- void QtBrowserItemPrivate::addChild(QtBrowserItem *index, QtBrowserItem *after)
- {
- if (m_children.contains(index))
- return;
- int idx = m_children.indexOf(after) + 1; // we insert after returned idx, if it was -1 then we set idx to 0;
- m_children.insert(idx, index);
- }
- void QtBrowserItemPrivate::removeChild(QtBrowserItem *index)
- {
- m_children.removeAll(index);
- }
- /*!
- \class QtBrowserItem
- \internal
- \inmodule QtDesigner
- \since 4.4
- \brief The QtBrowserItem class represents a property in
- a property browser instance.
- Browser items are created whenever a QtProperty is inserted to the
- property browser. A QtBrowserItem uniquely identifies a
- browser's item. Thus, if the same QtProperty is inserted multiple
- times, each occurrence gets its own unique QtBrowserItem. The
- items are owned by QtAbstractPropertyBrowser and automatically
- deleted when they are removed from the browser.
- You can traverse a browser's properties by calling parent() and
- children(). The property and the browser associated with an item
- are available as property() and browser().
- \sa QtAbstractPropertyBrowser, QtProperty
- */
- /*!
- Returns the property which is accosiated with this item. Note that
- several items can be associated with the same property instance in
- the same property browser.
- \sa QtAbstractPropertyBrowser::items()
- */
- QtProperty *QtBrowserItem::property() const
- {
- return d_ptr->m_property;
- }
- /*!
- Returns the parent item of \e this item. Returns 0 if \e this item
- is associated with top-level property in item's property browser.
- \sa children()
- */
- QtBrowserItem *QtBrowserItem::parent() const
- {
- return d_ptr->m_parent;
- }
- /*!
- Returns the children items of \e this item. The properties
- reproduced from children items are always the same as
- reproduced from associated property' children, for example:
- \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 1
- The \e childrenItems list represents the same list as \e childrenProperties.
- */
- QList<QtBrowserItem *> QtBrowserItem::children() const
- {
- return d_ptr->m_children;
- }
- /*!
- Returns the property browser which owns \e this item.
- */
- QtAbstractPropertyBrowser *QtBrowserItem::browser() const
- {
- return d_ptr->m_browser;
- }
- QtBrowserItem::QtBrowserItem(QtAbstractPropertyBrowser *browser, QtProperty *property, QtBrowserItem *parent)
- : d_ptr(new QtBrowserItemPrivate(browser, property, parent))
- {
- d_ptr->q_ptr = this;
- }
- QtBrowserItem::~QtBrowserItem()
- {
- }
- ////////////////////////////////////
- typedef QMap<QtAbstractPropertyBrowser *, QMap<QtAbstractPropertyManager *,
- QtAbstractEditorFactoryBase *> > Map1;
- typedef QMap<QtAbstractPropertyManager *, QMap<QtAbstractEditorFactoryBase *,
- QList<QtAbstractPropertyBrowser *> > > Map2;
- Q_GLOBAL_STATIC(Map1, m_viewToManagerToFactory)
- Q_GLOBAL_STATIC(Map2, m_managerToFactoryToViews)
- class QtAbstractPropertyBrowserPrivate
- {
- QtAbstractPropertyBrowser *q_ptr;
- Q_DECLARE_PUBLIC(QtAbstractPropertyBrowser)
- public:
- QtAbstractPropertyBrowserPrivate();
- void insertSubTree(QtProperty *property,
- QtProperty *parentProperty);
- void removeSubTree(QtProperty *property,
- QtProperty *parentProperty);
- void createBrowserIndexes(QtProperty *property, QtProperty *parentProperty, QtProperty *afterProperty);
- void removeBrowserIndexes(QtProperty *property, QtProperty *parentProperty);
- QtBrowserItem *createBrowserIndex(QtProperty *property, QtBrowserItem *parentIndex, QtBrowserItem *afterIndex);
- void removeBrowserIndex(QtBrowserItem *index);
- void clearIndex(QtBrowserItem *index);
- void slotPropertyInserted(QtProperty *property,
- QtProperty *parentProperty, QtProperty *afterProperty);
- void slotPropertyRemoved(QtProperty *property, QtProperty *parentProperty);
- void slotPropertyDestroyed(QtProperty *property);
- void slotPropertyDataChanged(QtProperty *property);
- QList<QtProperty *> m_subItems;
- QMap<QtAbstractPropertyManager *, QList<QtProperty *> > m_managerToProperties;
- QMap<QtProperty *, QList<QtProperty *> > m_propertyToParents;
- QMap<QtProperty *, QtBrowserItem *> m_topLevelPropertyToIndex;
- QList<QtBrowserItem *> m_topLevelIndexes;
- QMap<QtProperty *, QList<QtBrowserItem *> > m_propertyToIndexes;
- QtBrowserItem *m_currentItem;
- };
- QtAbstractPropertyBrowserPrivate::QtAbstractPropertyBrowserPrivate() :
- m_currentItem(0)
- {
- }
- void QtAbstractPropertyBrowserPrivate::insertSubTree(QtProperty *property,
- QtProperty *parentProperty)
- {
- if (m_propertyToParents.contains(property)) {
- // property was already inserted, so its manager is connected
- // and all its children are inserted and theirs managers are connected
- // we just register new parent (parent has to be new).
- m_propertyToParents[property].append(parentProperty);
- // don't need to update m_managerToProperties map since
- // m_managerToProperties[manager] already contains property.
- return;
- }
- QtAbstractPropertyManager *manager = property->propertyManager();
- if (m_managerToProperties[manager].isEmpty()) {
- // connect manager's signals
- q_ptr->connect(manager, SIGNAL(propertyInserted(QtProperty *,
- QtProperty *, QtProperty *)),
- q_ptr, SLOT(slotPropertyInserted(QtProperty *,
- QtProperty *, QtProperty *)));
- q_ptr->connect(manager, SIGNAL(propertyRemoved(QtProperty *,
- QtProperty *)),
- q_ptr, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
- q_ptr->connect(manager, SIGNAL(propertyDestroyed(QtProperty*)),
- q_ptr, SLOT(slotPropertyDestroyed(QtProperty*)));
- q_ptr->connect(manager, SIGNAL(propertyChanged(QtProperty*)),
- q_ptr, SLOT(slotPropertyDataChanged(QtProperty*)));
- }
- m_managerToProperties[manager].append(property);
- m_propertyToParents[property].append(parentProperty);
- const QList<QtProperty *> subList = property->subProperties();
- for (QtProperty *subProperty : subList)
- insertSubTree(subProperty, property);
- }
- void QtAbstractPropertyBrowserPrivate::removeSubTree(QtProperty *property,
- QtProperty *parentProperty)
- {
- if (!m_propertyToParents.contains(property)) {
- // ASSERT
- return;
- }
- m_propertyToParents[property].removeAll(parentProperty);
- if (!m_propertyToParents[property].isEmpty())
- return;
- m_propertyToParents.remove(property);
- QtAbstractPropertyManager *manager = property->propertyManager();
- m_managerToProperties[manager].removeAll(property);
- if (m_managerToProperties[manager].isEmpty()) {
- // disconnect manager's signals
- q_ptr->disconnect(manager, SIGNAL(propertyInserted(QtProperty *,
- QtProperty *, QtProperty *)),
- q_ptr, SLOT(slotPropertyInserted(QtProperty *,
- QtProperty *, QtProperty *)));
- q_ptr->disconnect(manager, SIGNAL(propertyRemoved(QtProperty *,
- QtProperty *)),
- q_ptr, SLOT(slotPropertyRemoved(QtProperty*,QtProperty*)));
- q_ptr->disconnect(manager, SIGNAL(propertyDestroyed(QtProperty*)),
- q_ptr, SLOT(slotPropertyDestroyed(QtProperty*)));
- q_ptr->disconnect(manager, SIGNAL(propertyChanged(QtProperty*)),
- q_ptr, SLOT(slotPropertyDataChanged(QtProperty*)));
- m_managerToProperties.remove(manager);
- }
- const QList<QtProperty *> subList = property->subProperties();
- for (QtProperty *subProperty : subList)
- removeSubTree(subProperty, property);
- }
- void QtAbstractPropertyBrowserPrivate::createBrowserIndexes(QtProperty *property, QtProperty *parentProperty, QtProperty *afterProperty)
- {
- QMap<QtBrowserItem *, QtBrowserItem *> parentToAfter;
- if (afterProperty) {
- QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
- m_propertyToIndexes.constFind(afterProperty);
- if (it == m_propertyToIndexes.constEnd())
- return;
- for (QtBrowserItem *idx : it.value()) {
- QtBrowserItem *parentIdx = idx->parent();
- if ((parentProperty && parentIdx && parentIdx->property() == parentProperty) || (!parentProperty && !parentIdx))
- parentToAfter[idx->parent()] = idx;
- }
- } else if (parentProperty) {
- QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
- m_propertyToIndexes.find(parentProperty);
- if (it == m_propertyToIndexes.constEnd())
- return;
- for (QtBrowserItem *idx : it.value())
- parentToAfter[idx] = 0;
- } else {
- parentToAfter[0] = 0;
- }
- const QMap<QtBrowserItem *, QtBrowserItem *>::ConstIterator pcend = parentToAfter.constEnd();
- for (QMap<QtBrowserItem *, QtBrowserItem *>::ConstIterator it = parentToAfter.constBegin(); it != pcend; ++it)
- createBrowserIndex(property, it.key(), it.value());
- }
- QtBrowserItem *QtAbstractPropertyBrowserPrivate::createBrowserIndex(QtProperty *property,
- QtBrowserItem *parentIndex, QtBrowserItem *afterIndex)
- {
- QtBrowserItem *newIndex = new QtBrowserItem(q_ptr, property, parentIndex);
- if (parentIndex) {
- parentIndex->d_ptr->addChild(newIndex, afterIndex);
- } else {
- m_topLevelPropertyToIndex[property] = newIndex;
- m_topLevelIndexes.insert(m_topLevelIndexes.indexOf(afterIndex) + 1, newIndex);
- }
- m_propertyToIndexes[property].append(newIndex);
- q_ptr->itemInserted(newIndex, afterIndex);
- const QList<QtProperty *> subItems = property->subProperties();
- QtBrowserItem *afterChild = 0;
- for (QtProperty *child : subItems)
- afterChild = createBrowserIndex(child, newIndex, afterChild);
- return newIndex;
- }
- void QtAbstractPropertyBrowserPrivate::removeBrowserIndexes(QtProperty *property, QtProperty *parentProperty)
- {
- QList<QtBrowserItem *> toRemove;
- QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
- m_propertyToIndexes.constFind(property);
- if (it == m_propertyToIndexes.constEnd())
- return;
- for (QtBrowserItem *idx : it.value()) {
- QtBrowserItem *parentIdx = idx->parent();
- if ((parentProperty && parentIdx && parentIdx->property() == parentProperty) || (!parentProperty && !parentIdx))
- toRemove.append(idx);
- }
- for (QtBrowserItem *index : qAsConst(toRemove))
- removeBrowserIndex(index);
- }
- void QtAbstractPropertyBrowserPrivate::removeBrowserIndex(QtBrowserItem *index)
- {
- QList<QtBrowserItem *> children = index->children();
- for (int i = children.count(); i > 0; i--) {
- removeBrowserIndex(children.at(i - 1));
- }
- q_ptr->itemRemoved(index);
- if (index->parent()) {
- index->parent()->d_ptr->removeChild(index);
- } else {
- m_topLevelPropertyToIndex.remove(index->property());
- m_topLevelIndexes.removeAll(index);
- }
- QtProperty *property = index->property();
- m_propertyToIndexes[property].removeAll(index);
- if (m_propertyToIndexes[property].isEmpty())
- m_propertyToIndexes.remove(property);
- delete index;
- }
- void QtAbstractPropertyBrowserPrivate::clearIndex(QtBrowserItem *index)
- {
- const QList<QtBrowserItem *> children = index->children();
- for (QtBrowserItem *item : children)
- clearIndex(item);
- delete index;
- }
- void QtAbstractPropertyBrowserPrivate::slotPropertyInserted(QtProperty *property,
- QtProperty *parentProperty, QtProperty *afterProperty)
- {
- if (!m_propertyToParents.contains(parentProperty))
- return;
- createBrowserIndexes(property, parentProperty, afterProperty);
- insertSubTree(property, parentProperty);
- //q_ptr->propertyInserted(property, parentProperty, afterProperty);
- }
- void QtAbstractPropertyBrowserPrivate::slotPropertyRemoved(QtProperty *property,
- QtProperty *parentProperty)
- {
- if (!m_propertyToParents.contains(parentProperty))
- return;
- removeSubTree(property, parentProperty); // this line should be probably moved down after propertyRemoved call
- //q_ptr->propertyRemoved(property, parentProperty);
- removeBrowserIndexes(property, parentProperty);
- }
- void QtAbstractPropertyBrowserPrivate::slotPropertyDestroyed(QtProperty *property)
- {
- if (!m_subItems.contains(property))
- return;
- q_ptr->removeProperty(property);
- }
- void QtAbstractPropertyBrowserPrivate::slotPropertyDataChanged(QtProperty *property)
- {
- if (!m_propertyToParents.contains(property))
- return;
- QMap<QtProperty *, QList<QtBrowserItem *> >::ConstIterator it =
- m_propertyToIndexes.find(property);
- if (it == m_propertyToIndexes.constEnd())
- return;
- const QList<QtBrowserItem *> indexes = it.value();
- for (QtBrowserItem *idx : indexes)
- q_ptr->itemChanged(idx);
- //q_ptr->propertyChanged(property);
- }
- /*!
- \class QtAbstractPropertyBrowser
- \internal
- \inmodule QtDesigner
- \since 4.4
- \brief QtAbstractPropertyBrowser provides a base class for
- implementing property browsers.
- A property browser is a widget that enables the user to edit a
- given set of properties. Each property is represented by a label
- specifying the property's name, and an editing widget (e.g. a line
- edit or a combobox) holding its value. A property can have zero or
- more subproperties.
- \image qtpropertybrowser.png
- The top level properties can be retrieved using the
- properties() function. To traverse each property's
- subproperties, use the QtProperty::subProperties() function. In
- addition, the set of top level properties can be manipulated using
- the addProperty(), insertProperty() and removeProperty()
- functions. Note that the QtProperty class provides a corresponding
- set of functions making it possible to manipulate the set of
- subproperties as well.
- To remove all the properties from the property browser widget, use
- the clear() function. This function will clear the editor, but it
- will not delete the properties since they can still be used in
- other editors.
- The properties themselves are created and managed by
- implementations of the QtAbstractPropertyManager class. A manager
- can handle (i.e. create and manage) properties of a given type. In
- the property browser the managers are associated with
- implementations of the QtAbstractEditorFactory: A factory is a
- class able to create an editing widget of a specified type.
- When using a property browser widget, managers must be created for
- each of the required property types before the properties
- themselves can be created. To ensure that the properties' values
- will be displayed using suitable editing widgets, the managers
- must be associated with objects of the preferred factory
- implementations using the setFactoryForManager() function. The
- property browser will use these associations to determine which
- factory it should use to create the preferred editing widget.
- Note that a factory can be associated with many managers, but a
- manager can only be associated with one single factory within the
- context of a single property browser. The associations between
- managers and factories can at any time be removed using the
- unsetFactoryForManager() function.
- Whenever the property data changes or a property is inserted or
- removed, the itemChanged(), itemInserted() or
- itemRemoved() functions are called, respectively. These
- functions must be reimplemented in derived classes in order to
- update the property browser widget. Be aware that some property
- instances can appear several times in an abstract tree
- structure. For example:
- \table 100%
- \row
- \li
- \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 2
- \li \image qtpropertybrowser-duplicate.png
- \endtable
- The addProperty() function returns a QtBrowserItem that uniquely
- identifies the created item.
- To make a property editable in the property browser, the
- createEditor() function must be called to provide the
- property with a suitable editing widget.
- Note that there are two ready-made property browser
- implementations:
- \list
- \li QtGroupBoxPropertyBrowser
- \li QtTreePropertyBrowser
- \endlist
- \sa QtAbstractPropertyManager, QtAbstractEditorFactoryBase
- */
- /*!
- \fn void QtAbstractPropertyBrowser::setFactoryForManager(PropertyManager *manager,
- QtAbstractEditorFactory<PropertyManager> *factory)
- Connects the given \a manager to the given \a factory, ensuring
- that properties of the \a manager's type will be displayed with an
- editing widget suitable for their value.
- For example:
- \snippet doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp 3
- In this example the \c myInteger property's value is displayed
- with a QSpinBox widget, while the \c myDouble property's value is
- displayed with a QDoubleSpinBox widget.
- Note that a factory can be associated with many managers, but a
- manager can only be associated with one single factory. If the
- given \a manager already is associated with another factory, the
- old association is broken before the new one established.
- This function ensures that the given \a manager and the given \a
- factory are compatible, and it automatically calls the
- QtAbstractEditorFactory::addPropertyManager() function if necessary.
- \sa unsetFactoryForManager()
- */
- /*!
- \fn virtual void QtAbstractPropertyBrowser::itemInserted(QtBrowserItem *insertedItem,
- QtBrowserItem *precedingItem) = 0
- This function is called to update the widget whenever a property
- is inserted or added to the property browser, passing pointers to
- the \a insertedItem of property and the specified
- \a precedingItem as parameters.
- If \a precedingItem is 0, the \a insertedItem was put at
- the beginning of its parent item's list of subproperties. If
- the parent of \a insertedItem is 0, the \a insertedItem was added as a top
- level property of \e this property browser.
- This function must be reimplemented in derived classes. Note that
- if the \a insertedItem's property has subproperties, this
- method will be called for those properties as soon as the current call is finished.
- \sa insertProperty(), addProperty()
- */
- /*!
- \fn virtual void QtAbstractPropertyBrowser::itemRemoved(QtBrowserItem *item) = 0
- This function is called to update the widget whenever a property
- is removed from the property browser, passing the pointer to the
- \a item of the property as parameters. The passed \a item is
- deleted just after this call is finished.
- If the the parent of \a item is 0, the removed \a item was a
- top level property in this editor.
- This function must be reimplemented in derived classes. Note that
- if the removed \a item's property has subproperties, this
- method will be called for those properties just before the current call is started.
- \sa removeProperty()
- */
- /*!
- \fn virtual void QtAbstractPropertyBrowser::itemChanged(QtBrowserItem *item) = 0
- This function is called whenever a property's data changes,
- passing a pointer to the \a item of property as parameter.
- This function must be reimplemented in derived classes in order to
- update the property browser widget whenever a property's name,
- tool tip, status tip, "what's this" text, value text or value icon
- changes.
- Note that if the property browser contains several occurrences of
- the same property, this method will be called once for each
- occurrence (with a different item each time).
- \sa QtProperty, items()
- */
- /*!
- Creates an abstract property browser with the given \a parent.
- */
- QtAbstractPropertyBrowser::QtAbstractPropertyBrowser(QWidget *parent)
- : QWidget(parent), d_ptr(new QtAbstractPropertyBrowserPrivate)
- {
- d_ptr->q_ptr = this;
- }
- /*!
- Destroys the property browser, and destroys all the items that were
- created by this property browser.
- Note that the properties that were displayed in the editor are not
- deleted since they still can be used in other editors. Neither
- does the destructor delete the property managers and editor
- factories that were used by this property browser widget unless
- this widget was their parent.
- \sa QtAbstractPropertyManager::~QtAbstractPropertyManager()
- */
- QtAbstractPropertyBrowser::~QtAbstractPropertyBrowser()
- {
- const QList<QtBrowserItem *> indexes = topLevelItems();
- for (QtBrowserItem *item : indexes)
- d_ptr->clearIndex(item);
- }
- /*!
- Returns the property browser's list of top level properties.
- To traverse the subproperties, use the QtProperty::subProperties()
- function.
- \sa addProperty(), insertProperty(), removeProperty()
- */
- QList<QtProperty *> QtAbstractPropertyBrowser::properties() const
- {
- return d_ptr->m_subItems;
- }
- /*!
- Returns the property browser's list of all items associated
- with the given \a property.
- There is one item per instance of the property in the browser.
- \sa topLevelItem()
- */
- QList<QtBrowserItem *> QtAbstractPropertyBrowser::items(QtProperty *property) const
- {
- return d_ptr->m_propertyToIndexes.value(property);
- }
- /*!
- Returns the top-level items associated with the given \a property.
- Returns 0 if \a property wasn't inserted into this property
- browser or isn't a top-level one.
- \sa topLevelItems(), items()
- */
- QtBrowserItem *QtAbstractPropertyBrowser::topLevelItem(QtProperty *property) const
- {
- return d_ptr->m_topLevelPropertyToIndex.value(property);
- }
- /*!
- Returns the list of top-level items.
- \sa topLevelItem()
- */
- QList<QtBrowserItem *> QtAbstractPropertyBrowser::topLevelItems() const
- {
- return d_ptr->m_topLevelIndexes;
- }
- /*!
- Removes all the properties from the editor, but does not delete
- them since they can still be used in other editors.
- \sa removeProperty(), QtAbstractPropertyManager::clear()
- */
- void QtAbstractPropertyBrowser::clear()
- {
- const QList<QtProperty *> subList = properties();
- for (auto rit = subList.crbegin(), rend = subList.crend(); rit != rend; ++rit)
- removeProperty(*rit);
- }
- /*!
- Appends the given \a property (and its subproperties) to the
- property browser's list of top level properties. Returns the item
- created by property browser which is associated with the \a property.
- In order to get all children items created by the property
- browser in this call, the returned item should be traversed.
- If the specified \a property is already added, this function does
- nothing and returns 0.
- \sa insertProperty(), QtProperty::addSubProperty(), properties()
- */
- QtBrowserItem *QtAbstractPropertyBrowser::addProperty(QtProperty *property)
- {
- QtProperty *afterProperty = 0;
- if (d_ptr->m_subItems.count() > 0)
- afterProperty = d_ptr->m_subItems.last();
- return insertProperty(property, afterProperty);
- }
- /*!
- \fn QtBrowserItem *QtAbstractPropertyBrowser::insertProperty(QtProperty *property,
- QtProperty *afterProperty)
- Inserts the given \a property (and its subproperties) after
- the specified \a afterProperty in the browser's list of top
- level properties. Returns item created by property browser which
- is associated with the \a property. In order to get all children items
- created by the property browser in this call returned item should be traversed.
- If the specified \a afterProperty is 0, the given \a property is
- inserted at the beginning of the list. If \a property is
- already inserted, this function does nothing and returns 0.
- \sa addProperty(), QtProperty::insertSubProperty(), properties()
- */
- QtBrowserItem *QtAbstractPropertyBrowser::insertProperty(QtProperty *property,
- QtProperty *afterProperty)
- {
- if (!property)
- return 0;
- // if item is already inserted in this item then cannot add.
- QList<QtProperty *> pendingList = properties();
- int pos = 0;
- int newPos = 0;
- while (pos < pendingList.count()) {
- QtProperty *prop = pendingList.at(pos);
- if (prop == property)
- return 0;
- if (prop == afterProperty) {
- newPos = pos + 1;
- }
- pos++;
- }
- d_ptr->createBrowserIndexes(property, 0, afterProperty);
- // traverse inserted subtree and connect to manager's signals
- d_ptr->insertSubTree(property, 0);
- d_ptr->m_subItems.insert(newPos, property);
- //propertyInserted(property, 0, properAfterProperty);
- return topLevelItem(property);
- }
- /*!
- Removes the specified \a property (and its subproperties) from the
- property browser's list of top level properties. All items
- that were associated with the given \a property and its children
- are deleted.
- Note that the properties are \e not deleted since they can still
- be used in other editors.
- \sa clear(), QtProperty::removeSubProperty(), properties()
- */
- void QtAbstractPropertyBrowser::removeProperty(QtProperty *property)
- {
- if (!property)
- return;
- QList<QtProperty *> pendingList = properties();
- int pos = 0;
- while (pos < pendingList.count()) {
- if (pendingList.at(pos) == property) {
- d_ptr->m_subItems.removeAt(pos); //perhaps this two lines
- d_ptr->removeSubTree(property, 0); //should be moved down after propertyRemoved call.
- //propertyRemoved(property, 0);
- d_ptr->removeBrowserIndexes(property, 0);
- // when item is deleted, item will call removeItem for top level items,
- // and itemRemoved for nested items.
- return;
- }
- pos++;
- }
- }
- /*!
- Creates an editing widget (with the given \a parent) for the given
- \a property according to the previously established associations
- between property managers and editor factories.
- If the property is created by a property manager which was not
- associated with any of the existing factories in \e this property
- editor, the function returns 0.
- To make a property editable in the property browser, the
- createEditor() function must be called to provide the
- property with a suitable editing widget.
- Reimplement this function to provide additional decoration for the
- editing widgets created by the installed factories.
- \sa setFactoryForManager()
- */
- QWidget *QtAbstractPropertyBrowser::createEditor(QtProperty *property,
- QWidget *parent)
- {
- QtAbstractEditorFactoryBase *factory = 0;
- QtAbstractPropertyManager *manager = property->propertyManager();
- if (m_viewToManagerToFactory()->contains(this) &&
- (*m_viewToManagerToFactory())[this].contains(manager)) {
- factory = (*m_viewToManagerToFactory())[this][manager];
- }
- if (!factory)
- return 0;
- QWidget *w = factory->createEditor(property, parent);
- // Since some editors can be QComboBoxes, and we changed their focus policy in Qt 5
- // to make them feel more native on Mac, we need to relax the focus policy to something
- // more permissive to keep the combo box from losing focus, allowing it to stay alive,
- // when the user clicks on it to show the popup.
- if (w)
- w->setFocusPolicy(Qt::WheelFocus);
- return w;
- }
- bool QtAbstractPropertyBrowser::addFactory(QtAbstractPropertyManager *abstractManager,
- QtAbstractEditorFactoryBase *abstractFactory)
- {
- bool connectNeeded = false;
- if (!m_managerToFactoryToViews()->contains(abstractManager) ||
- !(*m_managerToFactoryToViews())[abstractManager].contains(abstractFactory)) {
- connectNeeded = true;
- } else if ((*m_managerToFactoryToViews())[abstractManager][abstractFactory]
- .contains(this)) {
- return connectNeeded;
- }
- if (m_viewToManagerToFactory()->contains(this) &&
- (*m_viewToManagerToFactory())[this].contains(abstractManager)) {
- unsetFactoryForManager(abstractManager);
- }
- (*m_managerToFactoryToViews())[abstractManager][abstractFactory].append(this);
- (*m_viewToManagerToFactory())[this][abstractManager] = abstractFactory;
- return connectNeeded;
- }
- /*!
- Removes the association between the given \a manager and the
- factory bound to it, automatically calling the
- QtAbstractEditorFactory::removePropertyManager() function if necessary.
- \sa setFactoryForManager()
- */
- void QtAbstractPropertyBrowser::unsetFactoryForManager(QtAbstractPropertyManager *manager)
- {
- if (!m_viewToManagerToFactory()->contains(this) ||
- !(*m_viewToManagerToFactory())[this].contains(manager)) {
- return;
- }
- QtAbstractEditorFactoryBase *abstractFactory =
- (*m_viewToManagerToFactory())[this][manager];
- (*m_viewToManagerToFactory())[this].remove(manager);
- if ((*m_viewToManagerToFactory())[this].isEmpty()) {
- (*m_viewToManagerToFactory()).remove(this);
- }
- (*m_managerToFactoryToViews())[manager][abstractFactory].removeAll(this);
- if ((*m_managerToFactoryToViews())[manager][abstractFactory].isEmpty()) {
- (*m_managerToFactoryToViews())[manager].remove(abstractFactory);
- abstractFactory->breakConnection(manager);
- if ((*m_managerToFactoryToViews())[manager].isEmpty()) {
- (*m_managerToFactoryToViews()).remove(manager);
- }
- }
- }
- /*!
- Returns the current item in the property browser.
- \sa setCurrentItem()
- */
- QtBrowserItem *QtAbstractPropertyBrowser::currentItem() const
- {
- return d_ptr->m_currentItem;
- }
- /*!
- Sets the current item in the property browser to \a item.
- \sa currentItem(), currentItemChanged()
- */
- void QtAbstractPropertyBrowser::setCurrentItem(QtBrowserItem *item)
- {
- QtBrowserItem *oldItem = d_ptr->m_currentItem;
- d_ptr->m_currentItem = item;
- if (oldItem != item)
- emit currentItemChanged(item);
- }
- QT_END_NAMESPACE
- #include "moc_qtpropertybrowser.cpp"
|