1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** Contact: Qt Software Information ([email protected])
|
---|
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 [email protected].
|
---|
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"
|
---|