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