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