qtpropertymanager.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the Qt Solutions component.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** You may use this file under the terms of the BSD license as follows:
10 **
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
13 ** met:
14 ** * Redistributions of source code must retain the above copyright
15 ** notice, this list of conditions and the following disclaimer.
16 ** * Redistributions in binary form must reproduce the above copyright
17 ** notice, this list of conditions and the following disclaimer in
18 ** the documentation and/or other materials provided with the
19 ** distribution.
20 ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 ** of its contributors may be used to endorse or promote products derived
22 ** from this software without specific prior written permission.
23 **
24 **
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40 
41 
42 #include "qtpropertymanager.h"
44 #include <QDateTime>
45 #include <QLocale>
46 #include <QMap>
47 #include <QTimer>
48 #include <QIcon>
49 #include <QMetaEnum>
50 #include <QFontDatabase>
51 #include <QStyleOption>
52 #include <QStyle>
53 #include <QApplication>
54 #include <QPainter>
55 #include <QLabel>
56 #include <QCheckBox>
57 #include <QLineEdit>
58 
59 #include <limits.h>
60 #include <float.h>
61 
62 #if defined(Q_CC_MSVC)
63 # pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */
64 #endif
65 
66 QT_BEGIN_NAMESPACE
67 
68 template <class PrivateData, class Value>
69 static void setSimpleMinimumData(PrivateData* data, const Value& minVal)
70 {
71  data->minVal = minVal;
72 
73  if (data->maxVal < data->minVal)
74  {
75  data->maxVal = data->minVal;
76  }
77 
78  if (data->val < data->minVal)
79  {
80  data->val = data->minVal;
81  }
82 }
83 
84 template <class PrivateData, class Value>
85 static void setSimpleMaximumData(PrivateData* data, const Value& maxVal)
86 {
87  data->maxVal = maxVal;
88 
89  if (data->minVal > data->maxVal)
90  {
91  data->minVal = data->maxVal;
92  }
93 
94  if (data->val > data->maxVal)
95  {
96  data->val = data->maxVal;
97  }
98 }
99 
100 template <class PrivateData, class Value>
101 static void setSizeMinimumData(PrivateData* data, const Value& newMinVal)
102 {
103  data->minVal = newMinVal;
104 
105  if (data->maxVal.width() < data->minVal.width())
106  {
107  data->maxVal.setWidth(data->minVal.width());
108  }
109 
110  if (data->maxVal.height() < data->minVal.height())
111  {
112  data->maxVal.setHeight(data->minVal.height());
113  }
114 
115  if (data->val.width() < data->minVal.width())
116  {
117  data->val.setWidth(data->minVal.width());
118  }
119 
120  if (data->val.height() < data->minVal.height())
121  {
122  data->val.setHeight(data->minVal.height());
123  }
124 }
125 
126 template <class PrivateData, class Value>
127 static void setSizeMaximumData(PrivateData* data, const Value& newMaxVal)
128 {
129  data->maxVal = newMaxVal;
130 
131  if (data->minVal.width() > data->maxVal.width())
132  {
133  data->minVal.setWidth(data->maxVal.width());
134  }
135 
136  if (data->minVal.height() > data->maxVal.height())
137  {
138  data->minVal.setHeight(data->maxVal.height());
139  }
140 
141  if (data->val.width() > data->maxVal.width())
142  {
143  data->val.setWidth(data->maxVal.width());
144  }
145 
146  if (data->val.height() > data->maxVal.height())
147  {
148  data->val.setHeight(data->maxVal.height());
149  }
150 }
151 
152 template <class SizeValue>
153 static SizeValue qBoundSize(const SizeValue& minVal, const SizeValue& val, const SizeValue& maxVal)
154 {
155  SizeValue croppedVal = val;
156 
157  if (minVal.width() > val.width())
158  {
159  croppedVal.setWidth(minVal.width());
160  }
161  else if (maxVal.width() < val.width())
162  {
163  croppedVal.setWidth(maxVal.width());
164  }
165 
166  if (minVal.height() > val.height())
167  {
168  croppedVal.setHeight(minVal.height());
169  }
170  else if (maxVal.height() < val.height())
171  {
172  croppedVal.setHeight(maxVal.height());
173  }
174 
175  return croppedVal;
176 }
177 
178 // Match the exact signature of qBound for VS 6.
179 QSize qBound(QSize minVal, QSize val, QSize maxVal)
180 {
181  return qBoundSize(minVal, val, maxVal);
182 }
183 
184 QSizeF qBound(QSizeF minVal, QSizeF val, QSizeF maxVal)
185 {
186  return qBoundSize(minVal, val, maxVal);
187 }
188 
189 namespace
190 {
191  template <class Value>
192  void orderBorders(Value& minVal, Value& maxVal)
193  {
194  if (minVal > maxVal)
195  {
196  qSwap(minVal, maxVal);
197  }
198  }
199 
200  template <class Value>
201  static void orderSizeBorders(Value& minVal, Value& maxVal)
202  {
203  Value fromSize = minVal;
204  Value toSize = maxVal;
205 
206  if (fromSize.width() > toSize.width())
207  {
208  fromSize.setWidth(maxVal.width());
209  toSize.setWidth(minVal.width());
210  }
211 
212  if (fromSize.height() > toSize.height())
213  {
214  fromSize.setHeight(maxVal.height());
215  toSize.setHeight(minVal.height());
216  }
217 
218  minVal = fromSize;
219  maxVal = toSize;
220  }
221 
222  void orderBorders(QSize& minVal, QSize& maxVal)
223  {
224  orderSizeBorders(minVal, maxVal);
225  }
226 
227  void orderBorders(QSizeF& minVal, QSizeF& maxVal)
228  {
229  orderSizeBorders(minVal, maxVal);
230  }
231 
232 }
233 
234 ////////
235 
236 template <class Value, class PrivateData>
237 static Value getData(const QMap<const QtProperty*, PrivateData>& propertyMap,
238  Value PrivateData::*data,
239  const QtProperty* property, const Value& defaultValue = Value())
240 {
241  using PropertyToData = QMap<const QtProperty*, PrivateData>;
242  using PropertyToDataConstIterator = typename PropertyToData::const_iterator;
243  const PropertyToDataConstIterator it = propertyMap.constFind(property);
244 
245  if (it == propertyMap.constEnd())
246  {
247  return defaultValue;
248  }
249 
250  return it.value().*data;
251 }
252 
253 template <class Value, class PrivateData>
254 static Value getValue(const QMap<const QtProperty*, PrivateData>& propertyMap,
255  const QtProperty* property, const Value& defaultValue = Value())
256 {
257  return getData<Value>(propertyMap, &PrivateData::val, property, defaultValue);
258 }
259 
260 template <class Value, class PrivateData>
261 static Value getMinimum(const QMap<const QtProperty*, PrivateData>& propertyMap,
262  const QtProperty* property, const Value& defaultValue = Value())
263 {
264  return getData<Value>(propertyMap, &PrivateData::minVal, property, defaultValue);
265 }
266 
267 template <class Value, class PrivateData>
268 static Value getMaximum(const QMap<const QtProperty*, PrivateData>& propertyMap,
269  const QtProperty* property, const Value& defaultValue = Value())
270 {
271  return getData<Value>(propertyMap, &PrivateData::maxVal, property, defaultValue);
272 }
273 
274 template <class ValueChangeParameter, class Value, class PropertyManager>
275 static void setSimpleValue(QMap<const QtProperty*, Value>& propertyMap,
276  PropertyManager* manager,
277  void (PropertyManager::*propertyChangedSignal)(QtProperty*),
278  void (PropertyManager::*valueChangedSignal)(QtProperty*, ValueChangeParameter),
279  QtProperty* property, const Value& val)
280 {
281  using PropertyToData = QMap<const QtProperty*, Value>;
282  using PropertyToDataIterator = typename PropertyToData::iterator;
283  const PropertyToDataIterator it = propertyMap.find(property);
284 
285  if (it == propertyMap.end())
286  {
287  return;
288  }
289 
290  if (it.value() == val)
291  {
292  return;
293  }
294 
295  it.value() = val;
296 
297  emit(manager->*propertyChangedSignal)(property);
298  emit(manager->*valueChangedSignal)(property, val);
299 }
300 
301 template <class ValueChangeParameter, class PropertyManagerPrivate, class PropertyManager, class Value>
302 static void setValueInRange(PropertyManager* manager, PropertyManagerPrivate* managerPrivate,
303  void (PropertyManager::*propertyChangedSignal)(QtProperty*),
304  void (PropertyManager::*valueChangedSignal)(QtProperty*, ValueChangeParameter),
305  QtProperty* property, const Value& val,
306  void (PropertyManagerPrivate::*setSubPropertyValue)(QtProperty*, ValueChangeParameter))
307 {
308  using PrivateData = typename PropertyManagerPrivate::Data;
309  using PropertyToData = QMap<const QtProperty*, PrivateData>;
310  using PropertyToDataIterator = typename PropertyToData::iterator;
311  const PropertyToDataIterator it = managerPrivate->m_values.find(property);
312 
313  if (it == managerPrivate->m_values.end())
314  {
315  return;
316  }
317 
318  PrivateData& data = it.value();
319 
320  if (data.val == val)
321  {
322  return;
323  }
324 
325  const Value oldVal = data.val;
326 
327  data.val = qBound(data.minVal, val, data.maxVal);
328 
329  if (data.val == oldVal)
330  {
331  return;
332  }
333 
334  if (setSubPropertyValue)
335  {
336  (managerPrivate->*setSubPropertyValue)(property, data.val);
337  }
338 
339  emit(manager->*propertyChangedSignal)(property);
340  emit(manager->*valueChangedSignal)(property, data.val);
341 }
342 
343 template <class ValueChangeParameter, class PropertyManagerPrivate, class PropertyManager, class Value>
344 static void setBorderValues(PropertyManager* manager, PropertyManagerPrivate* managerPrivate,
345  void (PropertyManager::*propertyChangedSignal)(QtProperty*),
346  void (PropertyManager::*valueChangedSignal)(QtProperty*, ValueChangeParameter),
347  void (PropertyManager::*rangeChangedSignal)(QtProperty*, ValueChangeParameter, ValueChangeParameter),
348  QtProperty* property, const Value& minVal, const Value& maxVal,
349  void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty*,
350  ValueChangeParameter, ValueChangeParameter, ValueChangeParameter))
351 {
352  using PrivateData = typename PropertyManagerPrivate::Data;
353  using PropertyToData = QMap<const QtProperty*, PrivateData>;
354  using PropertyToDataIterator = typename PropertyToData::iterator;
355  const PropertyToDataIterator it = managerPrivate->m_values.find(property);
356 
357  if (it == managerPrivate->m_values.end())
358  {
359  return;
360  }
361 
362  Value fromVal = minVal;
363  Value toVal = maxVal;
364  orderBorders(fromVal, toVal);
365 
366  PrivateData& data = it.value();
367 
368  if (data.minVal == fromVal && data.maxVal == toVal)
369  {
370  return;
371  }
372 
373  const Value oldVal = data.val;
374 
375  data.setMinimumValue(fromVal);
376  data.setMaximumValue(toVal);
377 
378  emit(manager->*rangeChangedSignal)(property, data.minVal, data.maxVal);
379 
380  if (setSubPropertyRange)
381  {
382  (managerPrivate->*setSubPropertyRange)(property, data.minVal, data.maxVal, data.val);
383  }
384 
385  if (data.val == oldVal)
386  {
387  return;
388  }
389 
390  emit(manager->*propertyChangedSignal)(property);
391  emit(manager->*valueChangedSignal)(property, data.val);
392 }
393 
394 template <class ValueChangeParameter, class PropertyManagerPrivate, class PropertyManager, class Value, class PrivateData>
395 static void setBorderValue(PropertyManager* manager, PropertyManagerPrivate* managerPrivate,
396  void (PropertyManager::*propertyChangedSignal)(QtProperty*),
397  void (PropertyManager::*valueChangedSignal)(QtProperty*, ValueChangeParameter),
398  void (PropertyManager::*rangeChangedSignal)(QtProperty*, ValueChangeParameter, ValueChangeParameter),
399  QtProperty* property,
400  Value(PrivateData::*getRangeVal)() const,
401  void (PrivateData::*setRangeVal)(ValueChangeParameter), const Value& borderVal,
402  void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty*,
403  ValueChangeParameter, ValueChangeParameter, ValueChangeParameter))
404 {
405  using PropertyToData = QMap<const QtProperty*, PrivateData>;
406  using PropertyToDataIterator = typename PropertyToData::iterator;
407  const PropertyToDataIterator it = managerPrivate->m_values.find(property);
408 
409  if (it == managerPrivate->m_values.end())
410  {
411  return;
412  }
413 
414  PrivateData& data = it.value();
415 
416  if ((data.*getRangeVal)() == borderVal)
417  {
418  return;
419  }
420 
421  const Value oldVal = data.val;
422 
423  (data.*setRangeVal)(borderVal);
424 
425  emit(manager->*rangeChangedSignal)(property, data.minVal, data.maxVal);
426 
427  if (setSubPropertyRange)
428  {
429  (managerPrivate->*setSubPropertyRange)(property, data.minVal, data.maxVal, data.val);
430  }
431 
432  if (data.val == oldVal)
433  {
434  return;
435  }
436 
437  emit(manager->*propertyChangedSignal)(property);
438  emit(manager->*valueChangedSignal)(property, data.val);
439 }
440 
441 template <class ValueChangeParameter, class PropertyManagerPrivate, class PropertyManager, class Value, class PrivateData>
442 static void setMinimumValue(PropertyManager* manager, PropertyManagerPrivate* managerPrivate,
443  void (PropertyManager::*propertyChangedSignal)(QtProperty*),
444  void (PropertyManager::*valueChangedSignal)(QtProperty*, ValueChangeParameter),
445  void (PropertyManager::*rangeChangedSignal)(QtProperty*, ValueChangeParameter, ValueChangeParameter),
446  QtProperty* property, const Value& minVal)
447 {
448  void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty*,
449  ValueChangeParameter, ValueChangeParameter, ValueChangeParameter) = 0;
450  setBorderValue<ValueChangeParameter, PropertyManagerPrivate, PropertyManager, Value, PrivateData>(manager, managerPrivate,
451  propertyChangedSignal, valueChangedSignal, rangeChangedSignal,
452  property, &PropertyManagerPrivate::Data::minimumValue, &PropertyManagerPrivate::Data::setMinimumValue, minVal, setSubPropertyRange);
453 }
454 
455 template <class ValueChangeParameter, class PropertyManagerPrivate, class PropertyManager, class Value, class PrivateData>
456 static void setMaximumValue(PropertyManager* manager, PropertyManagerPrivate* managerPrivate,
457  void (PropertyManager::*propertyChangedSignal)(QtProperty*),
458  void (PropertyManager::*valueChangedSignal)(QtProperty*, ValueChangeParameter),
459  void (PropertyManager::*rangeChangedSignal)(QtProperty*, ValueChangeParameter, ValueChangeParameter),
460  QtProperty* property, const Value& maxVal)
461 {
462  void (PropertyManagerPrivate::*setSubPropertyRange)(QtProperty*,
463  ValueChangeParameter, ValueChangeParameter, ValueChangeParameter) = 0;
464  setBorderValue<ValueChangeParameter, PropertyManagerPrivate, PropertyManager, Value, PrivateData>(manager, managerPrivate,
465  propertyChangedSignal, valueChangedSignal, rangeChangedSignal,
466  property, &PropertyManagerPrivate::Data::maximumValue, &PropertyManagerPrivate::Data::setMaximumValue, maxVal, setSubPropertyRange);
467 }
468 
469 class QtMetaEnumWrapper : public QObject
470 {
471  Q_OBJECT
472  Q_PROPERTY(QSizePolicy::Policy policy READ policy)
473 public:
474  QSizePolicy::Policy policy() const
475  {
476  return QSizePolicy::Ignored;
477  }
478 private:
479  QtMetaEnumWrapper(QObject* parent) : QObject(parent) {}
480 };
481 
483 {
484 public:
486 
487  QStringList policyEnumNames() const
488  {
489  return m_policyEnumNames;
490  }
491  QStringList languageEnumNames() const
492  {
493  return m_languageEnumNames;
494  }
495  QStringList countryEnumNames(QLocale::Language language) const
496  {
497  return m_countryEnumNames.value(language);
498  }
499 
500  QSizePolicy::Policy indexToSizePolicy(int index) const;
501  int sizePolicyToIndex(QSizePolicy::Policy policy) const;
502 
503  void indexToLocale(int languageIndex, int countryIndex, QLocale::Language* language, QLocale::Country* country) const;
504  void localeToIndex(QLocale::Language language, QLocale::Country country, int* languageIndex, int* countryIndex) const;
505 
506 private:
507  void initLocale();
508 
509  QStringList m_policyEnumNames;
510  QStringList m_languageEnumNames;
511  QMap<QLocale::Language, QStringList> m_countryEnumNames;
512  QMap<int, QLocale::Language> m_indexToLanguage;
513  QMap<QLocale::Language, int> m_languageToIndex;
514  QMap<int, QMap<int, QLocale::Country> > m_indexToCountry;
515  QMap<QLocale::Language, QMap<QLocale::Country, int> > m_countryToIndex;
516  QMetaEnum m_policyEnum;
517 };
518 
519 static QList<QLocale::Country> sortCountries(const QList<QLocale::Country>& countries)
520 {
521  QMultiMap<QString, QLocale::Country> nameToCountry;
522  QListIterator<QLocale::Country> itCountry(countries);
523 
524  while (itCountry.hasNext())
525  {
526  QLocale::Country country = itCountry.next();
527  nameToCountry.insert(QLocale::countryToString(country), country);
528  }
529 
530  return nameToCountry.values();
531 }
532 
533 void QtMetaEnumProvider::initLocale()
534 {
535  QMultiMap<QString, QLocale::Language> nameToLanguage;
536  QLocale::Language language = QLocale::C;
537 
538  while (language <= QLocale::LastLanguage)
539  {
540  QLocale locale(language);
541 
542  if (locale.language() == language)
543  {
544  nameToLanguage.insert(QLocale::languageToString(language), language);
545  }
546 
547  language = (QLocale::Language)((uint)language + 1); // ++language
548  }
549 
550  const QLocale system = QLocale::system();
551 
552  if (!nameToLanguage.contains(QLocale::languageToString(system.language())))
553  {
554  nameToLanguage.insert(QLocale::languageToString(system.language()), system.language());
555  }
556 
557  QList<QLocale::Language> languages = nameToLanguage.values();
558  QListIterator<QLocale::Language> itLang(languages);
559 
560  while (itLang.hasNext())
561  {
562  QLocale::Language language = itLang.next();
563  QList<QLocale::Country> countries;
564  countries = QLocale::countriesForLanguage(language);
565 
566  if (countries.isEmpty() && language == system.language())
567  {
568  countries << system.country();
569  }
570 
571  if (!countries.isEmpty() && !m_languageToIndex.contains(language))
572  {
573  countries = sortCountries(countries);
574  int langIdx = m_languageEnumNames.count();
575  m_indexToLanguage[langIdx] = language;
576  m_languageToIndex[language] = langIdx;
577  QStringList countryNames;
578  QListIterator<QLocale::Country> it(countries);
579  int countryIdx = 0;
580 
581  while (it.hasNext())
582  {
583  QLocale::Country country = it.next();
584  countryNames << QLocale::countryToString(country);
585  m_indexToCountry[langIdx][countryIdx] = country;
586  m_countryToIndex[language][country] = countryIdx;
587  ++countryIdx;
588  }
589 
590  m_languageEnumNames << QLocale::languageToString(language);
591  m_countryEnumNames[language] = countryNames;
592  }
593  }
594 }
595 
597 {
598  QMetaProperty p;
599 
600  p = QtMetaEnumWrapper::staticMetaObject.property(
601  QtMetaEnumWrapper::staticMetaObject.propertyOffset() + 0);
602  m_policyEnum = p.enumerator();
603  const int keyCount = m_policyEnum.keyCount();
604 
605  for (int i = 0; i < keyCount; i++)
606  {
607  m_policyEnumNames << QLatin1String(m_policyEnum.key(i));
608  }
609 
610  initLocale();
611 }
612 
613 QSizePolicy::Policy QtMetaEnumProvider::indexToSizePolicy(int index) const
614 {
615  return static_cast<QSizePolicy::Policy>(m_policyEnum.value(index));
616 }
617 
618 int QtMetaEnumProvider::sizePolicyToIndex(QSizePolicy::Policy policy) const
619 {
620  const int keyCount = m_policyEnum.keyCount();
621 
622  for (int i = 0; i < keyCount; i++)
623  if (indexToSizePolicy(i) == policy)
624  {
625  return i;
626  }
627 
628  return -1;
629 }
630 
631 void QtMetaEnumProvider::indexToLocale(int languageIndex, int countryIndex, QLocale::Language* language, QLocale::Country* country) const
632 {
633  QLocale::Language l = QLocale::C;
634  QLocale::Country c = QLocale::AnyCountry;
635 
636  if (m_indexToLanguage.contains(languageIndex))
637  {
638  l = m_indexToLanguage[languageIndex];
639 
640  if (m_indexToCountry.contains(languageIndex) && m_indexToCountry[languageIndex].contains(countryIndex))
641  {
642  c = m_indexToCountry[languageIndex][countryIndex];
643  }
644  }
645 
646  if (language)
647  {
648  *language = l;
649  }
650 
651  if (country)
652  {
653  *country = c;
654  }
655 }
656 
657 void QtMetaEnumProvider::localeToIndex(QLocale::Language language, QLocale::Country country, int* languageIndex, int* countryIndex) const
658 {
659  int l = -1;
660  int c = -1;
661 
662  if (m_languageToIndex.contains(language))
663  {
664  l = m_languageToIndex[language];
665 
666  if (m_countryToIndex.contains(language) && m_countryToIndex[language].contains(country))
667  {
668  c = m_countryToIndex[language][country];
669  }
670  }
671 
672  if (languageIndex)
673  {
674  *languageIndex = l;
675  }
676 
677  if (countryIndex)
678  {
679  *countryIndex = c;
680  }
681 }
682 
683 Q_GLOBAL_STATIC(QtMetaEnumProvider, metaEnumProvider)
684 
685 // QtGroupPropertyManager
686 
687 /*!
688  \class QtGroupPropertyManager
689 
690  \brief The QtGroupPropertyManager provides and manages group properties.
691 
692  This class is intended to provide a grouping element without any value.
693 
694  \sa QtAbstractPropertyManager
695 */
696 
697 /*!
698  Creates a manager with the given \a parent.
699 */
701  : QtAbstractPropertyManager(parent)
702 {
703 
704 }
705 
706 /*!
707  Destroys this manager, and all the properties it has created.
708 */
710 {
711 
712 }
713 
714 /*!
715  \reimp
716 */
717 bool QtGroupPropertyManager::hasValue(const QtProperty* property) const
718 {
719  Q_UNUSED(property)
720  return false;
721 }
722 
723 /*!
724  \reimp
725 */
727 {
728  Q_UNUSED(property)
729 }
730 
731 /*!
732  \reimp
733 */
735 {
736  Q_UNUSED(property)
737 }
738 
739 // QtIntPropertyManager
740 
742 {
743  QtIntPropertyManager* q_ptr;
744  Q_DECLARE_PUBLIC(QtIntPropertyManager)
745 public:
746 
747  struct Data
748  {
749  Data() : val(0), minVal(-INT_MAX), maxVal(INT_MAX), singleStep(1), readOnly(false) {}
750  int val;
751  int minVal;
752  int maxVal;
754  bool readOnly;
755  int minimumValue() const
756  {
757  return minVal;
758  }
759  int maximumValue() const
760  {
761  return maxVal;
762  }
763  void setMinimumValue(int newMinVal)
764  {
765  setSimpleMinimumData(this, newMinVal);
766  }
767  void setMaximumValue(int newMaxVal)
768  {
769  setSimpleMaximumData(this, newMaxVal);
770  }
771  };
772 
773  using PropertyValueMap = QMap<const QtProperty*, Data>;
775 };
776 
777 /*!
778  \class QtIntPropertyManager
779 
780  \brief The QtIntPropertyManager provides and manages int properties.
781 
782  An int property has a current value, and a range specifying the
783  valid values. The range is defined by a minimum and a maximum
784  value.
785 
786  The property's value and range can be retrieved using the value(),
787  minimum() and maximum() functions, and can be set using the
788  setValue(), setMinimum() and setMaximum() slots. Alternatively,
789  the range can be defined in one go using the setRange() slot.
790 
791  In addition, QtIntPropertyManager provides the valueChanged() signal which
792  is emitted whenever a property created by this manager changes,
793  and the rangeChanged() signal which is emitted whenever such a
794  property changes its range of valid values.
795 
796  \sa QtAbstractPropertyManager, QtSpinBoxFactory, QtSliderFactory, QtScrollBarFactory
797 */
798 
799 /*!
800  \fn void QtIntPropertyManager::valueChanged(QtProperty *property, int value)
801 
802  This signal is emitted whenever a property created by this manager
803  changes its value, passing a pointer to the \a property and the new
804  \a value as parameters.
805 
806  \sa setValue()
807 */
808 
809 /*!
810  \fn void QtIntPropertyManager::rangeChanged(QtProperty *property, int minimum, int maximum)
811 
812  This signal is emitted whenever a property created by this manager
813  changes its range of valid values, passing a pointer to the
814  \a property and the new \a minimum and \a maximum values.
815 
816  \sa setRange()
817 */
818 
819 /*!
820  \fn void QtIntPropertyManager::singleStepChanged(QtProperty *property, int step)
821 
822  This signal is emitted whenever a property created by this manager
823  changes its single step property, passing a pointer to the
824  \a property and the new \a step value
825 
826  \sa setSingleStep()
827 */
828 
829 /*!
830  Creates a manager with the given \a parent.
831 */
833  : QtAbstractPropertyManager(parent)
834 {
835  d_ptr = new QtIntPropertyManagerPrivate;
836  d_ptr->q_ptr = this;
837 }
838 
839 /*!
840  Destroys this manager, and all the properties it has created.
841 */
843 {
844  clear();
845  delete d_ptr;
846 }
847 
848 /*!
849  Returns the given \a property's value.
850 
851  If the given property is not managed by this manager, this
852  function returns 0.
853 
854  \sa setValue()
855 */
856 int QtIntPropertyManager::value(const QtProperty* property) const
857 {
858  return getValue<int>(d_ptr->m_values, property, 0);
859 }
860 
861 /*!
862  Returns the given \a property's minimum value.
863 
864  \sa setMinimum(), maximum(), setRange()
865 */
866 int QtIntPropertyManager::minimum(const QtProperty* property) const
867 {
868  return getMinimum<int>(d_ptr->m_values, property, 0);
869 }
870 
871 /*!
872  Returns the given \a property's maximum value.
873 
874  \sa setMaximum(), minimum(), setRange()
875 */
876 int QtIntPropertyManager::maximum(const QtProperty* property) const
877 {
878  return getMaximum<int>(d_ptr->m_values, property, 0);
879 }
880 
881 /*!
882  Returns the given \a property's step value.
883 
884  The step is typically used to increment or decrement a property value while pressing an arrow key.
885 
886  \sa setSingleStep()
887 */
889 {
890  return getData<int>(d_ptr->m_values, &QtIntPropertyManagerPrivate::Data::singleStep, property, 0);
891 }
892 
893 /*!
894  Returns read-only status of the property.
895 
896  When property is read-only it's value can be selected and copied from editor but not modified.
897 
898  \sa QtIntPropertyManager::setReadOnly
899 */
900 bool QtIntPropertyManager::isReadOnly(const QtProperty* property) const
901 {
902  return getData<bool>(d_ptr->m_values, &QtIntPropertyManagerPrivate::Data::readOnly, property, false);
903 }
904 
905 /*!
906  \reimp
907 */
908 QString QtIntPropertyManager::valueText(const QtProperty* property) const
909 {
910  const QtIntPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
911 
912  if (it == d_ptr->m_values.constEnd())
913  {
914  return QString();
915  }
916 
917  return QString::number(it.value().val);
918 }
919 
920 /*!
921  \fn void QtIntPropertyManager::setValue(QtProperty *property, int value)
922 
923  Sets the value of the given \a property to \a value.
924 
925  If the specified \a value is not valid according to the given \a
926  property's range, the \a value is adjusted to the nearest valid
927  value within the range.
928 
929  \sa value(), setRange(), valueChanged()
930 */
932 {
933  void (QtIntPropertyManagerPrivate::*setSubPropertyValue)(QtProperty*, int) = 0;
934  setValueInRange<int, QtIntPropertyManagerPrivate, QtIntPropertyManager, int>(this, d_ptr,
937  property, val, setSubPropertyValue);
938 }
939 
940 /*!
941  Sets the minimum value for the given \a property to \a minVal.
942 
943  When setting the minimum value, the maximum and current values are
944  adjusted if necessary (ensuring that the range remains valid and
945  that the current value is within the range).
946 
947  \sa minimum(), setRange(), rangeChanged()
948 */
949 void QtIntPropertyManager::setMinimum(QtProperty* property, int minVal)
950 {
951  setMinimumValue<int, QtIntPropertyManagerPrivate, QtIntPropertyManager, int, QtIntPropertyManagerPrivate::Data>(this, d_ptr,
955  property, minVal);
956 }
957 
958 /*!
959  Sets the maximum value for the given \a property to \a maxVal.
960 
961  When setting maximum value, the minimum and current values are
962  adjusted if necessary (ensuring that the range remains valid and
963  that the current value is within the range).
964 
965  \sa maximum(), setRange(), rangeChanged()
966 */
967 void QtIntPropertyManager::setMaximum(QtProperty* property, int maxVal)
968 {
969  setMaximumValue<int, QtIntPropertyManagerPrivate, QtIntPropertyManager, int, QtIntPropertyManagerPrivate::Data>(this, d_ptr,
973  property, maxVal);
974 }
975 
976 /*!
977  \fn void QtIntPropertyManager::setRange(QtProperty *property, int minimum, int maximum)
978 
979  Sets the range of valid values.
980 
981  This is a convenience function defining the range of valid values
982  in one go; setting the \a minimum and \a maximum values for the
983  given \a property with a single function call.
984 
985  When setting a new range, the current value is adjusted if
986  necessary (ensuring that the value remains within range).
987 
988  \sa setMinimum(), setMaximum(), rangeChanged()
989 */
990 void QtIntPropertyManager::setRange(QtProperty* property, int minVal, int maxVal)
991 {
992  void (QtIntPropertyManagerPrivate::*setSubPropertyRange)(QtProperty*, int, int, int) = 0;
993  setBorderValues<int, QtIntPropertyManagerPrivate, QtIntPropertyManager, int>(this, d_ptr,
997  property, minVal, maxVal, setSubPropertyRange);
998 }
999 
1000 /*!
1001  Sets the step value for the given \a property to \a step.
1002 
1003  The step is typically used to increment or decrement a property value while pressing an arrow key.
1004 
1005  \sa singleStep()
1006 */
1008 {
1009  const QtIntPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
1010 
1011  if (it == d_ptr->m_values.end())
1012  {
1013  return;
1014  }
1015 
1017 
1018  if (step < 0)
1019  {
1020  step = 0;
1021  }
1022 
1023  if (data.singleStep == step)
1024  {
1025  return;
1026  }
1027 
1028  data.singleStep = step;
1029 
1030  it.value() = data;
1031 
1032  emit singleStepChanged(property, data.singleStep);
1033 }
1034 
1035 /*!
1036  Sets read-only status of the property.
1037 
1038  \sa QtIntPropertyManager::setReadOnly
1039 */
1040 void QtIntPropertyManager::setReadOnly(QtProperty* property, bool readOnly)
1041 {
1042  const QtIntPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
1043 
1044  if (it == d_ptr->m_values.end())
1045  {
1046  return;
1047  }
1048 
1050 
1051  if (data.readOnly == readOnly)
1052  {
1053  return;
1054  }
1055 
1056  data.readOnly = readOnly;
1057  it.value() = data;
1058 
1059  emit propertyChanged(property);
1060  emit readOnlyChanged(property, data.readOnly);
1061 }
1062 
1063 /*!
1064  \reimp
1065 */
1067 {
1068  d_ptr->m_values[property] = QtIntPropertyManagerPrivate::Data();
1069 }
1070 
1071 /*!
1072  \reimp
1073 */
1075 {
1076  d_ptr->m_values.remove(property);
1077 }
1078 
1079 // QtDoublePropertyManager
1080 
1082 {
1083  QtDoublePropertyManager* q_ptr;
1084  Q_DECLARE_PUBLIC(QtDoublePropertyManager)
1085 public:
1086 
1087  struct Data
1088  {
1089  Data() : val(0), minVal(-INT_MAX), maxVal(INT_MAX), singleStep(1), decimals(2), readOnly(false) {}
1090  double val;
1091  double minVal;
1092  double maxVal;
1093  double singleStep;
1095  bool readOnly;
1096  double minimumValue() const
1097  {
1098  return minVal;
1099  }
1100  double maximumValue() const
1101  {
1102  return maxVal;
1103  }
1104  void setMinimumValue(double newMinVal)
1105  {
1106  setSimpleMinimumData(this, newMinVal);
1107  }
1108  void setMaximumValue(double newMaxVal)
1109  {
1110  setSimpleMaximumData(this, newMaxVal);
1111  }
1112  };
1113 
1114  using PropertyValueMap = QMap<const QtProperty*, Data>;
1116 };
1117 
1118 /*!
1119  \class QtDoublePropertyManager
1120 
1121  \brief The QtDoublePropertyManager provides and manages double properties.
1122 
1123  A double property has a current value, and a range specifying the
1124  valid values. The range is defined by a minimum and a maximum
1125  value.
1126 
1127  The property's value and range can be retrieved using the value(),
1128  minimum() and maximum() functions, and can be set using the
1129  setValue(), setMinimum() and setMaximum() slots.
1130  Alternatively, the range can be defined in one go using the
1131  setRange() slot.
1132 
1133  In addition, QtDoublePropertyManager provides the valueChanged() signal
1134  which is emitted whenever a property created by this manager
1135  changes, and the rangeChanged() signal which is emitted whenever
1136  such a property changes its range of valid values.
1137 
1138  \sa QtAbstractPropertyManager, QtDoubleSpinBoxFactory
1139 */
1140 
1141 /*!
1142  \fn void QtDoublePropertyManager::valueChanged(QtProperty *property, double value)
1143 
1144  This signal is emitted whenever a property created by this manager
1145  changes its value, passing a pointer to the \a property and the new
1146  \a value as parameters.
1147 
1148  \sa setValue()
1149 */
1150 
1151 /*!
1152  \fn void QtDoublePropertyManager::rangeChanged(QtProperty *property, double minimum, double maximum)
1153 
1154  This signal is emitted whenever a property created by this manager
1155  changes its range of valid values, passing a pointer to the
1156  \a property and the new \a minimum and \a maximum values
1157 
1158  \sa setRange()
1159 */
1160 
1161 /*!
1162  \fn void QtDoublePropertyManager::decimalsChanged(QtProperty *property, int prec)
1163 
1164  This signal is emitted whenever a property created by this manager
1165  changes its precision of value, passing a pointer to the
1166  \a property and the new \a prec value
1167 
1168  \sa setDecimals()
1169 */
1170 
1171 /*!
1172  \fn void QtDoublePropertyManager::singleStepChanged(QtProperty *property, double step)
1173 
1174  This signal is emitted whenever a property created by this manager
1175  changes its single step property, passing a pointer to the
1176  \a property and the new \a step value
1177 
1178  \sa setSingleStep()
1179 */
1180 
1181 /*!
1182  Creates a manager with the given \a parent.
1183 */
1185  : QtAbstractPropertyManager(parent)
1186 {
1187  d_ptr = new QtDoublePropertyManagerPrivate;
1188  d_ptr->q_ptr = this;
1189 }
1190 
1191 /*!
1192  Destroys this manager, and all the properties it has created.
1193 */
1195 {
1196  clear();
1197  delete d_ptr;
1198 }
1199 
1200 /*!
1201  Returns the given \a property's value.
1202 
1203  If the given property is not managed by this manager, this
1204  function returns 0.
1205 
1206  \sa setValue()
1207 */
1208 double QtDoublePropertyManager::value(const QtProperty* property) const
1209 {
1210  return getValue<double>(d_ptr->m_values, property, 0.0);
1211 }
1212 
1213 /*!
1214  Returns the given \a property's minimum value.
1215 
1216  \sa maximum(), setRange()
1217 */
1218 double QtDoublePropertyManager::minimum(const QtProperty* property) const
1219 {
1220  return getMinimum<double>(d_ptr->m_values, property, 0.0);
1221 }
1222 
1223 /*!
1224  Returns the given \a property's maximum value.
1225 
1226  \sa minimum(), setRange()
1227 */
1228 double QtDoublePropertyManager::maximum(const QtProperty* property) const
1229 {
1230  return getMaximum<double>(d_ptr->m_values, property, 0.0);
1231 }
1232 
1233 /*!
1234  Returns the given \a property's step value.
1235 
1236  The step is typically used to increment or decrement a property value while pressing an arrow key.
1237 
1238  \sa setSingleStep()
1239 */
1241 {
1242  return getData<double>(d_ptr->m_values, &QtDoublePropertyManagerPrivate::Data::singleStep, property, 0);
1243 }
1244 
1245 /*!
1246  Returns the given \a property's precision, in decimals.
1247 
1248  \sa setDecimals()
1249 */
1251 {
1252  return getData<int>(d_ptr->m_values, &QtDoublePropertyManagerPrivate::Data::decimals, property, 0);
1253 }
1254 
1255 /*!
1256  Returns read-only status of the property.
1257 
1258  When property is read-only it's value can be selected and copied from editor but not modified.
1259 
1260  \sa QtDoublePropertyManager::setReadOnly
1261 */
1263 {
1264  return getData<bool>(d_ptr->m_values, &QtDoublePropertyManagerPrivate::Data::readOnly, property, false);
1265 }
1266 
1267 /*!
1268  \reimp
1269 */
1270 QString QtDoublePropertyManager::valueText(const QtProperty* property) const
1271 {
1272  const QtDoublePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
1273 
1274  if (it == d_ptr->m_values.constEnd())
1275  {
1276  return QString();
1277  }
1278 
1279  return QLocale::system().toString(it.value().val, 'f', it.value().decimals);
1280 }
1281 
1282 /*!
1283  \fn void QtDoublePropertyManager::setValue(QtProperty *property, double value)
1284 
1285  Sets the value of the given \a property to \a value.
1286 
1287  If the specified \a value is not valid according to the given
1288  \a property's range, the \a value is adjusted to the nearest valid value
1289  within the range.
1290 
1291  \sa value(), setRange(), valueChanged()
1292 */
1294 {
1295  void (QtDoublePropertyManagerPrivate::*setSubPropertyValue)(QtProperty*, double) = 0;
1296  setValueInRange<double, QtDoublePropertyManagerPrivate, QtDoublePropertyManager, double>(this, d_ptr,
1299  property, val, setSubPropertyValue);
1300 }
1301 
1302 /*!
1303  Sets the step value for the given \a property to \a step.
1304 
1305  The step is typically used to increment or decrement a property value while pressing an arrow key.
1306 
1307  \sa singleStep()
1308 */
1310 {
1311  const QtDoublePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
1312 
1313  if (it == d_ptr->m_values.end())
1314  {
1315  return;
1316  }
1317 
1319 
1320  if (step < 0)
1321  {
1322  step = 0;
1323  }
1324 
1325  if (data.singleStep == step)
1326  {
1327  return;
1328  }
1329 
1330  data.singleStep = step;
1331 
1332  it.value() = data;
1333 
1334  emit singleStepChanged(property, data.singleStep);
1335 }
1336 
1337 /*!
1338  Sets read-only status of the property.
1339 
1340  \sa QtDoublePropertyManager::setReadOnly
1341 */
1342 void QtDoublePropertyManager::setReadOnly(QtProperty* property, bool readOnly)
1343 {
1344  const QtDoublePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
1345 
1346  if (it == d_ptr->m_values.end())
1347  {
1348  return;
1349  }
1350 
1352 
1353  if (data.readOnly == readOnly)
1354  {
1355  return;
1356  }
1357 
1358  data.readOnly = readOnly;
1359  it.value() = data;
1360 
1361  emit propertyChanged(property);
1362  emit readOnlyChanged(property, data.readOnly);
1363 }
1364 
1365 /*!
1366  \fn void QtDoublePropertyManager::setDecimals(QtProperty *property, int prec)
1367 
1368  Sets the precision of the given \a property to \a prec.
1369 
1370  The valid decimal range is 0-13. The default is 2.
1371 
1372  \sa decimals()
1373 */
1375 {
1376  const QtDoublePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
1377 
1378  if (it == d_ptr->m_values.end())
1379  {
1380  return;
1381  }
1382 
1384 
1385  if (prec > 13)
1386  {
1387  prec = 13;
1388  }
1389  else if (prec < 0)
1390  {
1391  prec = 0;
1392  }
1393 
1394  if (data.decimals == prec)
1395  {
1396  return;
1397  }
1398 
1399  data.decimals = prec;
1400 
1401  it.value() = data;
1402 
1403  emit decimalsChanged(property, data.decimals);
1404 }
1405 
1406 /*!
1407  Sets the minimum value for the given \a property to \a minVal.
1408 
1409  When setting the minimum value, the maximum and current values are
1410  adjusted if necessary (ensuring that the range remains valid and
1411  that the current value is within in the range).
1412 
1413  \sa minimum(), setRange(), rangeChanged()
1414 */
1415 void QtDoublePropertyManager::setMinimum(QtProperty* property, double minVal)
1416 {
1417  setMinimumValue<double, QtDoublePropertyManagerPrivate, QtDoublePropertyManager, double, QtDoublePropertyManagerPrivate::Data>(this, d_ptr,
1421  property, minVal);
1422 }
1423 
1424 /*!
1425  Sets the maximum value for the given \a property to \a maxVal.
1426 
1427  When setting the maximum value, the minimum and current values are
1428  adjusted if necessary (ensuring that the range remains valid and
1429  that the current value is within in the range).
1430 
1431  \sa maximum(), setRange(), rangeChanged()
1432 */
1433 void QtDoublePropertyManager::setMaximum(QtProperty* property, double maxVal)
1434 {
1435  setMaximumValue<double, QtDoublePropertyManagerPrivate, QtDoublePropertyManager, double, QtDoublePropertyManagerPrivate::Data>(this, d_ptr,
1439  property, maxVal);
1440 }
1441 
1442 /*!
1443  \fn void QtDoublePropertyManager::setRange(QtProperty *property, double minimum, double maximum)
1444 
1445  Sets the range of valid values.
1446 
1447  This is a convenience function defining the range of valid values
1448  in one go; setting the \a minimum and \a maximum values for the
1449  given \a property with a single function call.
1450 
1451  When setting a new range, the current value is adjusted if
1452  necessary (ensuring that the value remains within range).
1453 
1454  \sa setMinimum(), setMaximum(), rangeChanged()
1455 */
1456 void QtDoublePropertyManager::setRange(QtProperty* property, double minVal, double maxVal)
1457 {
1458  void (QtDoublePropertyManagerPrivate::*setSubPropertyRange)(QtProperty*, double, double, double) = 0;
1459  setBorderValues<double, QtDoublePropertyManagerPrivate, QtDoublePropertyManager, double>(this, d_ptr,
1463  property, minVal, maxVal, setSubPropertyRange);
1464 }
1465 
1466 /*!
1467  \reimp
1468 */
1470 {
1471  d_ptr->m_values[property] = QtDoublePropertyManagerPrivate::Data();
1472 }
1473 
1474 /*!
1475  \reimp
1476 */
1478 {
1479  d_ptr->m_values.remove(property);
1480 }
1481 
1482 // QtStringPropertyManager
1483 
1485 {
1486  QtStringPropertyManager* q_ptr;
1487  Q_DECLARE_PUBLIC(QtStringPropertyManager)
1488 public:
1489 
1490  struct Data
1491  {
1492  Data() : regExp(QString(QLatin1Char('*')), Qt::CaseSensitive, QRegExp::Wildcard),
1493  echoMode(QLineEdit::Normal), readOnly(false)
1494  {
1495  }
1496  QString val;
1497  QRegExp regExp;
1499  bool readOnly;
1500  };
1501 
1502  using PropertyValueMap = QMap<const QtProperty*, Data>;
1503  QMap<const QtProperty*, Data> m_values;
1504 };
1505 
1506 /*!
1507  \class QtStringPropertyManager
1508 
1509  \brief The QtStringPropertyManager provides and manages QString properties.
1510 
1511  A string property's value can be retrieved using the value()
1512  function, and set using the setValue() slot.
1513 
1514  The current value can be checked against a regular expression. To
1515  set the regular expression use the setRegExp() slot, use the
1516  regExp() function to retrieve the currently set expression.
1517 
1518  In addition, QtStringPropertyManager provides the valueChanged() signal
1519  which is emitted whenever a property created by this manager
1520  changes, and the regExpChanged() signal which is emitted whenever
1521  such a property changes its currently set regular expression.
1522 
1523  \sa QtAbstractPropertyManager, QtLineEditFactory
1524 */
1525 
1526 /*!
1527  \fn void QtStringPropertyManager::valueChanged(QtProperty *property, const QString &value)
1528 
1529  This signal is emitted whenever a property created by this manager
1530  changes its value, passing a pointer to the \a property and the
1531  new \a value as parameters.
1532 
1533  \sa setValue()
1534 */
1535 
1536 /*!
1537  \fn void QtStringPropertyManager::regExpChanged(QtProperty *property, const QRegExp &regExp)
1538 
1539  This signal is emitted whenever a property created by this manager
1540  changes its currenlty set regular expression, passing a pointer to
1541  the \a property and the new \a regExp as parameters.
1542 
1543  \sa setRegExp()
1544 */
1545 
1546 /*!
1547  Creates a manager with the given \a parent.
1548 */
1550  : QtAbstractPropertyManager(parent)
1551 {
1552  d_ptr = new QtStringPropertyManagerPrivate;
1553  d_ptr->q_ptr = this;
1554 }
1555 
1556 /*!
1557  Destroys this manager, and all the properties it has created.
1558 */
1560 {
1561  clear();
1562  delete d_ptr;
1563 }
1564 
1565 /*!
1566  Returns the given \a property's value.
1567 
1568  If the given property is not managed by this manager, this
1569  function returns an empty string.
1570 
1571  \sa setValue()
1572 */
1573 QString QtStringPropertyManager::value(const QtProperty* property) const
1574 {
1575  return getValue<QString>(d_ptr->m_values, property);
1576 }
1577 
1578 /*!
1579  Returns the given \a property's currently set regular expression.
1580 
1581  If the given \a property is not managed by this manager, this
1582  function returns an empty expression.
1583 
1584  \sa setRegExp()
1585 */
1586 QRegExp QtStringPropertyManager::regExp(const QtProperty* property) const
1587 {
1588  return getData<QRegExp>(d_ptr->m_values, &QtStringPropertyManagerPrivate::Data::regExp, property, QRegExp());
1589 }
1590 
1591 /*!
1592  \reimp
1593 */
1595 {
1596  return (EchoMode)getData<int>(d_ptr->m_values, &QtStringPropertyManagerPrivate::Data::echoMode, property, 0);
1597 }
1598 
1599 /*!
1600  Returns read-only status of the property.
1601 
1602  When property is read-only it's value can be selected and copied from editor but not modified.
1603 
1604  \sa QtStringPropertyManager::setReadOnly
1605 */
1607 {
1608  return getData<bool>(d_ptr->m_values, &QtStringPropertyManagerPrivate::Data::readOnly, property, false);
1609 }
1610 
1611 /*!
1612  \reimp
1613 */
1614 QString QtStringPropertyManager::valueText(const QtProperty* property) const
1615 {
1616  const QtStringPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
1617 
1618  if (it == d_ptr->m_values.constEnd())
1619  {
1620  return QString();
1621  }
1622 
1623  return it.value().val;
1624 }
1625 
1626 /*!
1627  \reimp
1628 */
1629 QString QtStringPropertyManager::displayText(const QtProperty* property) const
1630 {
1631  const QtStringPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
1632 
1633  if (it == d_ptr->m_values.constEnd())
1634  {
1635  return QString();
1636  }
1637 
1638  QLineEdit edit;
1639  edit.setEchoMode((EchoMode)it.value().echoMode);
1640  edit.setText(it.value().val);
1641  return edit.displayText();
1642 }
1643 
1644 /*!
1645  \fn void QtStringPropertyManager::setValue(QtProperty *property, const QString &value)
1646 
1647  Sets the value of the given \a property to \a value.
1648 
1649  If the specified \a value doesn't match the given \a property's
1650  regular expression, this function does nothing.
1651 
1652  \sa value(), setRegExp(), valueChanged()
1653 */
1654 void QtStringPropertyManager::setValue(QtProperty* property, const QString& val)
1655 {
1656  const QtStringPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
1657 
1658  if (it == d_ptr->m_values.end())
1659  {
1660  return;
1661  }
1662 
1664 
1665  if (data.val == val)
1666  {
1667  return;
1668  }
1669 
1670  if (data.regExp.isValid() && !data.regExp.exactMatch(val))
1671  {
1672  return;
1673  }
1674 
1675  data.val = val;
1676 
1677  it.value() = data;
1678 
1679  emit propertyChanged(property);
1680  emit valueChanged(property, data.val);
1681 }
1682 
1683 /*!
1684  Sets the regular expression of the given \a property to \a regExp.
1685 
1686  \sa regExp(), setValue(), regExpChanged()
1687 */
1688 void QtStringPropertyManager::setRegExp(QtProperty* property, const QRegExp& regExp)
1689 {
1690  const QtStringPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
1691 
1692  if (it == d_ptr->m_values.end())
1693  {
1694  return;
1695  }
1696 
1698 
1699  if (data.regExp == regExp)
1700  {
1701  return;
1702  }
1703 
1704  data.regExp = regExp;
1705 
1706  it.value() = data;
1707 
1708  emit regExpChanged(property, data.regExp);
1709 }
1710 
1711 
1713 {
1714  const QtStringPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
1715 
1716  if (it == d_ptr->m_values.end())
1717  {
1718  return;
1719  }
1720 
1722 
1723  if (data.echoMode == echoMode)
1724  {
1725  return;
1726  }
1727 
1728  data.echoMode = echoMode;
1729  it.value() = data;
1730 
1731  emit propertyChanged(property);
1732  emit echoModeChanged(property, data.echoMode);
1733 }
1734 
1735 /*!
1736  Sets read-only status of the property.
1737 
1738  \sa QtStringPropertyManager::setReadOnly
1739 */
1740 void QtStringPropertyManager::setReadOnly(QtProperty* property, bool readOnly)
1741 {
1742  const QtStringPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
1743 
1744  if (it == d_ptr->m_values.end())
1745  {
1746  return;
1747  }
1748 
1750 
1751  if (data.readOnly == readOnly)
1752  {
1753  return;
1754  }
1755 
1756  data.readOnly = readOnly;
1757  it.value() = data;
1758 
1759  emit propertyChanged(property);
1760  emit readOnlyChanged(property, data.readOnly);
1761 }
1762 
1763 /*!
1764  \reimp
1765 */
1767 {
1768  d_ptr->m_values[property] = QtStringPropertyManagerPrivate::Data();
1769 }
1770 
1771 /*!
1772  \reimp
1773 */
1775 {
1776  d_ptr->m_values.remove(property);
1777 }
1778 
1779 // QtBoolPropertyManager
1780 // Return an icon containing a check box indicator
1781 static QIcon drawCheckBox(bool value)
1782 {
1783  QStyleOptionButton opt;
1784  opt.state |= value ? QStyle::State_On : QStyle::State_Off;
1785  opt.state |= QStyle::State_Enabled;
1786  const QStyle* style = QApplication::style();
1787  // Figure out size of an indicator and make sure it is not scaled down in a list view item
1788  // by making the pixmap as big as a list view icon and centering the indicator in it.
1789  // (if it is smaller, it can't be helped)
1790  const int indicatorWidth = style->pixelMetric(QStyle::PM_IndicatorWidth, &opt);
1791  const int indicatorHeight = style->pixelMetric(QStyle::PM_IndicatorHeight, &opt);
1792  const int listViewIconSize = indicatorWidth;
1793  const int pixmapWidth = indicatorWidth;
1794  const int pixmapHeight = qMax(indicatorHeight, listViewIconSize);
1795 
1796  opt.rect = QRect(0, 0, indicatorWidth, indicatorHeight);
1797  QPixmap pixmap = QPixmap(pixmapWidth, pixmapHeight);
1798  pixmap.fill(Qt::transparent);
1799  {
1800  // Center?
1801  const int xoff = (pixmapWidth > indicatorWidth) ? (pixmapWidth - indicatorWidth) / 2 : 0;
1802  const int yoff = (pixmapHeight > indicatorHeight) ? (pixmapHeight - indicatorHeight) / 2 : 0;
1803  QPainter painter(&pixmap);
1804  painter.translate(xoff, yoff);
1805  style->drawPrimitive(QStyle::PE_IndicatorCheckBox, &opt, &painter);
1806  }
1807  return QIcon(pixmap);
1808 }
1809 
1811 {
1812  QtBoolPropertyManager* q_ptr;
1813  Q_DECLARE_PUBLIC(QtBoolPropertyManager)
1814 public:
1816 
1817  struct Data
1818  {
1819  Data() : val(false), textVisible(true) {}
1820  bool val;
1822  };
1823 
1824  using PropertyValueMap = QMap<const QtProperty*, Data>;
1826 
1827  const QIcon m_checkedIcon;
1828  const QIcon m_uncheckedIcon;
1829 };
1830 
1832  m_checkedIcon(drawCheckBox(true)),
1833  m_uncheckedIcon(drawCheckBox(false))
1834 {
1835 }
1836 
1837 /*!
1838  \class QtBoolPropertyManager
1839 
1840  \brief The QtBoolPropertyManager class provides and manages boolean properties.
1841 
1842  The property's value can be retrieved using the value() function,
1843  and set using the setValue() slot.
1844 
1845  In addition, QtBoolPropertyManager provides the valueChanged() signal
1846  which is emitted whenever a property created by this manager
1847  changes.
1848 
1849  \sa QtAbstractPropertyManager, QtCheckBoxFactory
1850 */
1851 
1852 /*!
1853  \fn void QtBoolPropertyManager::valueChanged(QtProperty *property, bool value)
1854 
1855  This signal is emitted whenever a property created by this manager
1856  changes its value, passing a pointer to the \a property and the
1857  new \a value as parameters.
1858 */
1859 
1860 /*!
1861  Creates a manager with the given \a parent.
1862 */
1864  : QtAbstractPropertyManager(parent)
1865 {
1866  d_ptr = new QtBoolPropertyManagerPrivate;
1867  d_ptr->q_ptr = this;
1868 }
1869 
1870 /*!
1871  Destroys this manager, and all the properties it has created.
1872 */
1874 {
1875  clear();
1876  delete d_ptr;
1877 }
1878 
1879 /*!
1880  Returns the given \a property's value.
1881 
1882  If the given \a property is not managed by \e this manager, this
1883  function returns false.
1884 
1885  \sa setValue()
1886 */
1887 bool QtBoolPropertyManager::value(const QtProperty* property) const
1888 {
1889  return getValue<bool>(d_ptr->m_values, property, false);
1890 }
1891 
1893 {
1894  return getData<bool>(d_ptr->m_values, &QtBoolPropertyManagerPrivate::Data::textVisible, property, false);
1895 }
1896 
1897 /*!
1898  \reimp
1899 */
1900 QString QtBoolPropertyManager::valueText(const QtProperty* property) const
1901 {
1902  const QtBoolPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
1903 
1904  if (it == d_ptr->m_values.constEnd())
1905  {
1906  return QString();
1907  }
1908 
1909  const QtBoolPropertyManagerPrivate::Data& data = it.value();
1910 
1911  if (!data.textVisible)
1912  {
1913  return QString();
1914  }
1915 
1916  static const QString trueText = tr("True");
1917  static const QString falseText = tr("False");
1918  return data.val ? trueText : falseText;
1919 }
1920 
1921 /*!
1922  \reimp
1923 */
1924 QIcon QtBoolPropertyManager::valueIcon(const QtProperty* property) const
1925 {
1926  const QtBoolPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
1927 
1928  if (it == d_ptr->m_values.constEnd())
1929  {
1930  return QIcon();
1931  }
1932 
1933  return it.value().val ? d_ptr->m_checkedIcon : d_ptr->m_uncheckedIcon;
1934 }
1935 
1936 /*!
1937  \fn void QtBoolPropertyManager::setValue(QtProperty *property, bool value)
1938 
1939  Sets the value of the given \a property to \a value.
1940 
1941  \sa value()
1942 */
1944 {
1945  const QtBoolPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
1946 
1947  if (it == d_ptr->m_values.end())
1948  {
1949  return;
1950  }
1951 
1953 
1954  if (data.val == val)
1955  {
1956  return;
1957  }
1958 
1959  data.val = val;
1960  it.value() = data;
1961 
1962  emit propertyChanged(property);
1963  emit valueChanged(property, data.val);
1964 }
1965 
1966 void QtBoolPropertyManager::setTextVisible(QtProperty* property, bool textVisible)
1967 {
1968  const QtBoolPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
1969 
1970  if (it == d_ptr->m_values.end())
1971  {
1972  return;
1973  }
1974 
1976 
1977  if (data.textVisible == textVisible)
1978  {
1979  return;
1980  }
1981 
1982  data.textVisible = textVisible;
1983  it.value() = data;
1984 
1985  emit propertyChanged(property);
1986  emit textVisibleChanged(property, data.textVisible);
1987 }
1988 
1989 /*!
1990  \reimp
1991 */
1993 {
1994  d_ptr->m_values[property] = QtBoolPropertyManagerPrivate::Data();
1995 }
1996 
1997 /*!
1998  \reimp
1999 */
2001 {
2002  d_ptr->m_values.remove(property);
2003 }
2004 
2005 // QtDatePropertyManager
2006 
2008 {
2009  QtDatePropertyManager* q_ptr;
2010  Q_DECLARE_PUBLIC(QtDatePropertyManager)
2011 public:
2012 
2013  struct Data
2014  {
2015  Data() : val(QDate::currentDate()), minVal(QDate(1752, 9, 14)),
2016  maxVal(QDate(7999, 12, 31)) {}
2017  QDate val;
2018  QDate minVal;
2019  QDate maxVal;
2020  QDate minimumValue() const
2021  {
2022  return minVal;
2023  }
2024  QDate maximumValue() const
2025  {
2026  return maxVal;
2027  }
2028  void setMinimumValue(const QDate& newMinVal)
2029  {
2030  setSimpleMinimumData(this, newMinVal);
2031  }
2032  void setMaximumValue(const QDate& newMaxVal)
2033  {
2034  setSimpleMaximumData(this, newMaxVal);
2035  }
2036  };
2037 
2038  QString m_format;
2039 
2040  using PropertyValueMap = QMap<const QtProperty*, Data>;
2041  QMap<const QtProperty*, Data> m_values;
2042 };
2043 
2044 /*!
2045  \class QtDatePropertyManager
2046 
2047  \brief The QtDatePropertyManager provides and manages QDate properties.
2048 
2049  A date property has a current value, and a range specifying the
2050  valid dates. The range is defined by a minimum and a maximum
2051  value.
2052 
2053  The property's values can be retrieved using the minimum(),
2054  maximum() and value() functions, and can be set using the
2055  setMinimum(), setMaximum() and setValue() slots. Alternatively,
2056  the range can be defined in one go using the setRange() slot.
2057 
2058  In addition, QtDatePropertyManager provides the valueChanged() signal
2059  which is emitted whenever a property created by this manager
2060  changes, and the rangeChanged() signal which is emitted whenever
2061  such a property changes its range of valid dates.
2062 
2063  \sa QtAbstractPropertyManager, QtDateEditFactory, QtDateTimePropertyManager
2064 */
2065 
2066 /*!
2067  \fn void QtDatePropertyManager::valueChanged(QtProperty *property, const QDate &value)
2068 
2069  This signal is emitted whenever a property created by this manager
2070  changes its value, passing a pointer to the \a property and the new
2071  \a value as parameters.
2072 
2073  \sa setValue()
2074 */
2075 
2076 /*!
2077  \fn void QtDatePropertyManager::rangeChanged(QtProperty *property, const QDate &minimum, const QDate &maximum)
2078 
2079  This signal is emitted whenever a property created by this manager
2080  changes its range of valid dates, passing a pointer to the \a
2081  property and the new \a minimum and \a maximum dates.
2082 
2083  \sa setRange()
2084 */
2085 
2086 /*!
2087  Creates a manager with the given \a parent.
2088 */
2090  : QtAbstractPropertyManager(parent)
2091 {
2092  d_ptr = new QtDatePropertyManagerPrivate;
2093  d_ptr->q_ptr = this;
2094 
2095  QLocale loc;
2096  d_ptr->m_format = loc.dateFormat(QLocale::ShortFormat);
2097 }
2098 
2099 /*!
2100  Destroys this manager, and all the properties it has created.
2101 */
2103 {
2104  clear();
2105  delete d_ptr;
2106 }
2107 
2108 /*!
2109  Returns the given \a property's value.
2110 
2111  If the given \a property is not managed by \e this manager, this
2112  function returns an invalid date.
2113 
2114  \sa setValue()
2115 */
2116 QDate QtDatePropertyManager::value(const QtProperty* property) const
2117 {
2118  return getValue<QDate>(d_ptr->m_values, property);
2119 }
2120 
2121 /*!
2122  Returns the given \a property's minimum date.
2123 
2124  \sa maximum(), setRange()
2125 */
2126 QDate QtDatePropertyManager::minimum(const QtProperty* property) const
2127 {
2128  return getMinimum<QDate>(d_ptr->m_values, property);
2129 }
2130 
2131 /*!
2132  Returns the given \a property's maximum date.
2133 
2134  \sa minimum(), setRange()
2135 */
2136 QDate QtDatePropertyManager::maximum(const QtProperty* property) const
2137 {
2138  return getMaximum<QDate>(d_ptr->m_values, property);
2139 }
2140 
2141 /*!
2142  \reimp
2143 */
2144 QString QtDatePropertyManager::valueText(const QtProperty* property) const
2145 {
2146  const QtDatePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
2147 
2148  if (it == d_ptr->m_values.constEnd())
2149  {
2150  return QString();
2151  }
2152 
2153  return it.value().val.toString(d_ptr->m_format);
2154 }
2155 
2156 /*!
2157  \fn void QtDatePropertyManager::setValue(QtProperty *property, const QDate &value)
2158 
2159  Sets the value of the given \a property to \a value.
2160 
2161  If the specified \a value is not a valid date according to the
2162  given \a property's range, the value is adjusted to the nearest
2163  valid value within the range.
2164 
2165  \sa value(), setRange(), valueChanged()
2166 */
2167 void QtDatePropertyManager::setValue(QtProperty* property, const QDate& val)
2168 {
2169  void (QtDatePropertyManagerPrivate::*setSubPropertyValue)(QtProperty*, const QDate&) = 0;
2170  setValueInRange<const QDate&, QtDatePropertyManagerPrivate, QtDatePropertyManager, const QDate>(this, d_ptr,
2173  property, val, setSubPropertyValue);
2174 }
2175 
2176 /*!
2177  Sets the minimum value for the given \a property to \a minVal.
2178 
2179  When setting the minimum value, the maximum and current values are
2180  adjusted if necessary (ensuring that the range remains valid and
2181  that the current value is within in the range).
2182 
2183  \sa minimum(), setRange()
2184 */
2185 void QtDatePropertyManager::setMinimum(QtProperty* property, const QDate& minVal)
2186 {
2187  setMinimumValue<const QDate&, QtDatePropertyManagerPrivate, QtDatePropertyManager, QDate, QtDatePropertyManagerPrivate::Data>(this, d_ptr,
2191  property, minVal);
2192 }
2193 
2194 /*!
2195  Sets the maximum value for the given \a property to \a maxVal.
2196 
2197  When setting the maximum value, the minimum and current
2198  values are adjusted if necessary (ensuring that the range remains
2199  valid and that the current value is within in the range).
2200 
2201  \sa maximum(), setRange()
2202 */
2203 void QtDatePropertyManager::setMaximum(QtProperty* property, const QDate& maxVal)
2204 {
2205  setMaximumValue<const QDate&, QtDatePropertyManagerPrivate, QtDatePropertyManager, QDate, QtDatePropertyManagerPrivate::Data>(this, d_ptr,
2209  property, maxVal);
2210 }
2211 
2212 /*!
2213  \fn void QtDatePropertyManager::setRange(QtProperty *property, const QDate &minimum, const QDate &maximum)
2214 
2215  Sets the range of valid dates.
2216 
2217  This is a convenience function defining the range of valid dates
2218  in one go; setting the \a minimum and \a maximum values for the
2219  given \a property with a single function call.
2220 
2221  When setting a new date range, the current value is adjusted if
2222  necessary (ensuring that the value remains in date range).
2223 
2224  \sa setMinimum(), setMaximum(), rangeChanged()
2225 */
2226 void QtDatePropertyManager::setRange(QtProperty* property, const QDate& minVal, const QDate& maxVal)
2227 {
2228  void (QtDatePropertyManagerPrivate::*setSubPropertyRange)(QtProperty*, const QDate&,
2229  const QDate&, const QDate&) = 0;
2230  setBorderValues<const QDate&, QtDatePropertyManagerPrivate, QtDatePropertyManager, QDate>(this, d_ptr,
2234  property, minVal, maxVal, setSubPropertyRange);
2235 }
2236 
2237 /*!
2238  \reimp
2239 */
2241 {
2242  d_ptr->m_values[property] = QtDatePropertyManagerPrivate::Data();
2243 }
2244 
2245 /*!
2246  \reimp
2247 */
2249 {
2250  d_ptr->m_values.remove(property);
2251 }
2252 
2253 // QtTimePropertyManager
2254 
2256 {
2257  QtTimePropertyManager* q_ptr;
2258  Q_DECLARE_PUBLIC(QtTimePropertyManager)
2259 public:
2260 
2261  QString m_format;
2262 
2263  using PropertyValueMap = QMap<const QtProperty*, QTime>;
2265 };
2266 
2267 /*!
2268  \class QtTimePropertyManager
2269 
2270  \brief The QtTimePropertyManager provides and manages QTime properties.
2271 
2272  A time property's value can be retrieved using the value()
2273  function, and set using the setValue() slot.
2274 
2275  In addition, QtTimePropertyManager provides the valueChanged() signal
2276  which is emitted whenever a property created by this manager
2277  changes.
2278 
2279  \sa QtAbstractPropertyManager, QtTimeEditFactory
2280 */
2281 
2282 /*!
2283  \fn void QtTimePropertyManager::valueChanged(QtProperty *property, const QTime &value)
2284 
2285  This signal is emitted whenever a property created by this manager
2286  changes its value, passing a pointer to the \a property and the
2287  new \a value as parameters.
2288 
2289  \sa setValue()
2290 */
2291 
2292 /*!
2293  Creates a manager with the given \a parent.
2294 */
2296  : QtAbstractPropertyManager(parent)
2297 {
2298  d_ptr = new QtTimePropertyManagerPrivate;
2299  d_ptr->q_ptr = this;
2300 
2301  QLocale loc;
2302  d_ptr->m_format = loc.timeFormat(QLocale::ShortFormat);
2303 }
2304 
2305 /*!
2306  Destroys this manager, and all the properties it has created.
2307 */
2309 {
2310  clear();
2311  delete d_ptr;
2312 }
2313 
2314 /*!
2315  Returns the given \a property's value.
2316 
2317  If the given property is not managed by this manager, this
2318  function returns an invalid time object.
2319 
2320  \sa setValue()
2321 */
2322 QTime QtTimePropertyManager::value(const QtProperty* property) const
2323 {
2324  return d_ptr->m_values.value(property, QTime());
2325 }
2326 
2327 /*!
2328  \reimp
2329 */
2330 QString QtTimePropertyManager::valueText(const QtProperty* property) const
2331 {
2332  const QtTimePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
2333 
2334  if (it == d_ptr->m_values.constEnd())
2335  {
2336  return QString();
2337  }
2338 
2339  return it.value().toString(d_ptr->m_format);
2340 }
2341 
2342 /*!
2343  \fn void QtTimePropertyManager::setValue(QtProperty *property, const QTime &value)
2344 
2345  Sets the value of the given \a property to \a value.
2346 
2347  \sa value(), valueChanged()
2348 */
2349 void QtTimePropertyManager::setValue(QtProperty* property, const QTime& val)
2350 {
2351  setSimpleValue<const QTime&, QTime, QtTimePropertyManager>(d_ptr->m_values, this,
2354  property, val);
2355 }
2356 
2357 /*!
2358  \reimp
2359 */
2361 {
2362  d_ptr->m_values[property] = QTime::currentTime();
2363 }
2364 
2365 /*!
2366  \reimp
2367 */
2369 {
2370  d_ptr->m_values.remove(property);
2371 }
2372 
2373 // QtDateTimePropertyManager
2374 
2376 {
2378  Q_DECLARE_PUBLIC(QtDateTimePropertyManager)
2379 public:
2380 
2381  QString m_format;
2382 
2383  using PropertyValueMap = QMap<const QtProperty*, QDateTime>;
2385 };
2386 
2387 /*! \class QtDateTimePropertyManager
2388 
2389  \brief The QtDateTimePropertyManager provides and manages QDateTime properties.
2390 
2391  A date and time property has a current value which can be
2392  retrieved using the value() function, and set using the setValue()
2393  slot. In addition, QtDateTimePropertyManager provides the
2394  valueChanged() signal which is emitted whenever a property created
2395  by this manager changes.
2396 
2397  \sa QtAbstractPropertyManager, QtDateTimeEditFactory, QtDatePropertyManager
2398 */
2399 
2400 /*!
2401  \fn void QtDateTimePropertyManager::valueChanged(QtProperty *property, const QDateTime &value)
2402 
2403  This signal is emitted whenever a property created by this manager
2404  changes its value, passing a pointer to the \a property and the new
2405  \a value as parameters.
2406 */
2407 
2408 /*!
2409  Creates a manager with the given \a parent.
2410 */
2412  : QtAbstractPropertyManager(parent)
2413 {
2415  d_ptr->q_ptr = this;
2416 
2417  QLocale loc;
2418  d_ptr->m_format = loc.dateFormat(QLocale::ShortFormat);
2419  d_ptr->m_format += QLatin1Char(' ');
2420  d_ptr->m_format += loc.timeFormat(QLocale::ShortFormat);
2421 }
2422 
2423 /*!
2424  Destroys this manager, and all the properties it has created.
2425 */
2427 {
2428  clear();
2429  delete d_ptr;
2430 }
2431 
2432 /*!
2433  Returns the given \a property's value.
2434 
2435  If the given \a property is not managed by this manager, this
2436  function returns an invalid QDateTime object.
2437 
2438  \sa setValue()
2439 */
2440 QDateTime QtDateTimePropertyManager::value(const QtProperty* property) const
2441 {
2442  return d_ptr->m_values.value(property, QDateTime());
2443 }
2444 
2445 /*!
2446  \reimp
2447 */
2448 QString QtDateTimePropertyManager::valueText(const QtProperty* property) const
2449 {
2450  const QtDateTimePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
2451 
2452  if (it == d_ptr->m_values.constEnd())
2453  {
2454  return QString();
2455  }
2456 
2457  return it.value().toString(d_ptr->m_format);
2458 }
2459 
2460 /*!
2461  \fn void QtDateTimePropertyManager::setValue(QtProperty *property, const QDateTime &value)
2462 
2463  Sets the value of the given \a property to \a value.
2464 
2465  \sa value(), valueChanged()
2466 */
2467 void QtDateTimePropertyManager::setValue(QtProperty* property, const QDateTime& val)
2468 {
2469  setSimpleValue<const QDateTime&, QDateTime, QtDateTimePropertyManager>(d_ptr->m_values, this,
2472  property, val);
2473 }
2474 
2475 /*!
2476  \reimp
2477 */
2479 {
2480  d_ptr->m_values[property] = QDateTime::currentDateTime();
2481 }
2482 
2483 /*!
2484  \reimp
2485 */
2487 {
2488  d_ptr->m_values.remove(property);
2489 }
2490 
2491 // QtKeySequencePropertyManager
2492 
2494 {
2496  Q_DECLARE_PUBLIC(QtKeySequencePropertyManager)
2497 public:
2498 
2499  QString m_format;
2500 
2501  using PropertyValueMap = QMap<const QtProperty*, QKeySequence>;
2503 };
2504 
2505 /*! \class QtKeySequencePropertyManager
2506 
2507  \brief The QtKeySequencePropertyManager provides and manages QKeySequence properties.
2508 
2509  A key sequence's value can be retrieved using the value()
2510  function, and set using the setValue() slot.
2511 
2512  In addition, QtKeySequencePropertyManager provides the valueChanged() signal
2513  which is emitted whenever a property created by this manager
2514  changes.
2515 
2516  \sa QtAbstractPropertyManager
2517 */
2518 
2519 /*!
2520  \fn void QtKeySequencePropertyManager::valueChanged(QtProperty *property, const QKeySequence &value)
2521 
2522  This signal is emitted whenever a property created by this manager
2523  changes its value, passing a pointer to the \a property and the new
2524  \a value as parameters.
2525 */
2526 
2527 /*!
2528  Creates a manager with the given \a parent.
2529 */
2531  : QtAbstractPropertyManager(parent)
2532 {
2534  d_ptr->q_ptr = this;
2535 }
2536 
2537 /*!
2538  Destroys this manager, and all the properties it has created.
2539 */
2541 {
2542  clear();
2543  delete d_ptr;
2544 }
2545 
2546 /*!
2547  Returns the given \a property's value.
2548 
2549  If the given \a property is not managed by this manager, this
2550  function returns an empty QKeySequence object.
2551 
2552  \sa setValue()
2553 */
2554 QKeySequence QtKeySequencePropertyManager::value(const QtProperty* property) const
2555 {
2556  return d_ptr->m_values.value(property, QKeySequence());
2557 }
2558 
2559 /*!
2560  \reimp
2561 */
2563 {
2564  const QtKeySequencePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
2565 
2566  if (it == d_ptr->m_values.constEnd())
2567  {
2568  return QString();
2569  }
2570 
2571  return it.value().toString(QKeySequence::NativeText);
2572 }
2573 
2574 /*!
2575  \fn void QtKeySequencePropertyManager::setValue(QtProperty *property, const QKeySequence &value)
2576 
2577  Sets the value of the given \a property to \a value.
2578 
2579  \sa value(), valueChanged()
2580 */
2581 void QtKeySequencePropertyManager::setValue(QtProperty* property, const QKeySequence& val)
2582 {
2583  setSimpleValue<const QKeySequence&, QKeySequence, QtKeySequencePropertyManager>(d_ptr->m_values, this,
2586  property, val);
2587 }
2588 
2589 /*!
2590  \reimp
2591 */
2593 {
2594  d_ptr->m_values[property] = QKeySequence();
2595 }
2596 
2597 /*!
2598  \reimp
2599 */
2601 {
2602  d_ptr->m_values.remove(property);
2603 }
2604 
2605 // QtCharPropertyManager
2606 
2608 {
2609  QtCharPropertyManager* q_ptr;
2610  Q_DECLARE_PUBLIC(QtCharPropertyManager)
2611 public:
2612 
2613  using PropertyValueMap = QMap<const QtProperty*, QChar>;
2615 };
2616 
2617 /*! \class QtCharPropertyManager
2618 
2619  \brief The QtCharPropertyManager provides and manages QChar properties.
2620 
2621  A char's value can be retrieved using the value()
2622  function, and set using the setValue() slot.
2623 
2624  In addition, QtCharPropertyManager provides the valueChanged() signal
2625  which is emitted whenever a property created by this manager
2626  changes.
2627 
2628  \sa QtAbstractPropertyManager
2629 */
2630 
2631 /*!
2632  \fn void QtCharPropertyManager::valueChanged(QtProperty *property, const QChar &value)
2633 
2634  This signal is emitted whenever a property created by this manager
2635  changes its value, passing a pointer to the \a property and the new
2636  \a value as parameters.
2637 */
2638 
2639 /*!
2640  Creates a manager with the given \a parent.
2641 */
2643  : QtAbstractPropertyManager(parent)
2644 {
2645  d_ptr = new QtCharPropertyManagerPrivate;
2646  d_ptr->q_ptr = this;
2647 }
2648 
2649 /*!
2650  Destroys this manager, and all the properties it has created.
2651 */
2653 {
2654  clear();
2655  delete d_ptr;
2656 }
2657 
2658 /*!
2659  Returns the given \a property's value.
2660 
2661  If the given \a property is not managed by this manager, this
2662  function returns an null QChar object.
2663 
2664  \sa setValue()
2665 */
2666 QChar QtCharPropertyManager::value(const QtProperty* property) const
2667 {
2668  return d_ptr->m_values.value(property, QChar());
2669 }
2670 
2671 /*!
2672  \reimp
2673 */
2674 QString QtCharPropertyManager::valueText(const QtProperty* property) const
2675 {
2676  const QtCharPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
2677 
2678  if (it == d_ptr->m_values.constEnd())
2679  {
2680  return QString();
2681  }
2682 
2683  const QChar c = it.value();
2684  return c.isNull() ? QString() : QString(c);
2685 }
2686 
2687 /*!
2688  \fn void QtCharPropertyManager::setValue(QtProperty *property, const QChar &value)
2689 
2690  Sets the value of the given \a property to \a value.
2691 
2692  \sa value(), valueChanged()
2693 */
2694 void QtCharPropertyManager::setValue(QtProperty* property, const QChar& val)
2695 {
2696  setSimpleValue<const QChar&, QChar, QtCharPropertyManager>(d_ptr->m_values, this,
2699  property, val);
2700 }
2701 
2702 /*!
2703  \reimp
2704 */
2706 {
2707  d_ptr->m_values[property] = QChar();
2708 }
2709 
2710 /*!
2711  \reimp
2712 */
2714 {
2715  d_ptr->m_values.remove(property);
2716 }
2717 
2718 // QtLocalePropertyManager
2719 
2721 {
2722  QtLocalePropertyManager* q_ptr;
2723  Q_DECLARE_PUBLIC(QtLocalePropertyManager)
2724 public:
2725 
2727 
2728  void slotEnumChanged(QtProperty* property, int value);
2729  void slotPropertyDestroyed(QtProperty* property);
2730 
2731  using PropertyValueMap = QMap<const QtProperty*, QLocale>;
2733 
2735 
2736  QMap<const QtProperty*, QtProperty*> m_propertyToLanguage;
2737  QMap<const QtProperty*, QtProperty*> m_propertyToCountry;
2738 
2739  QMap<const QtProperty*, QtProperty*> m_languageToProperty;
2740  QMap<const QtProperty*, QtProperty*> m_countryToProperty;
2741 };
2742 
2744 {
2745 }
2746 
2748 {
2749  if (QtProperty* prop = m_languageToProperty.value(property, 0))
2750  {
2751  const QLocale loc = m_values[prop];
2752  QLocale::Language newLanguage = loc.language();
2753  QLocale::Country newCountry = loc.country();
2754  metaEnumProvider()->indexToLocale(value, 0, &newLanguage, 0);
2755  QLocale newLoc(newLanguage, newCountry);
2756  q_ptr->setValue(prop, newLoc);
2757  }
2758  else if (QtProperty* prop = m_countryToProperty.value(property, 0))
2759  {
2760  const QLocale loc = m_values[prop];
2761  QLocale::Language newLanguage = loc.language();
2762  QLocale::Country newCountry = loc.country();
2763  metaEnumProvider()->indexToLocale(m_enumPropertyManager->value(m_propertyToLanguage.value(prop)), value, &newLanguage, &newCountry);
2764  QLocale newLoc(newLanguage, newCountry);
2765  q_ptr->setValue(prop, newLoc);
2766  }
2767 }
2768 
2770 {
2771  if (QtProperty* subProp = m_languageToProperty.value(property, 0))
2772  {
2773  m_propertyToLanguage[subProp] = 0;
2774  m_languageToProperty.remove(property);
2775  }
2776  else if (QtProperty* subProp = m_countryToProperty.value(property, 0))
2777  {
2778  m_propertyToCountry[subProp] = 0;
2779  m_countryToProperty.remove(property);
2780  }
2781 }
2782 
2783 /*!
2784  \class QtLocalePropertyManager
2785 
2786  \brief The QtLocalePropertyManager provides and manages QLocale properties.
2787 
2788  A locale property has nested \e language and \e country
2789  subproperties. The top-level property's value can be retrieved
2790  using the value() function, and set using the setValue() slot.
2791 
2792  The subproperties are created by QtEnumPropertyManager object.
2793  These submanager can be retrieved using the subEnumPropertyManager()
2794  function. In order to provide editing widgets for the subproperties
2795  in a property browser widget, this manager must be associated with editor factory.
2796 
2797  In addition, QtLocalePropertyManager provides the valueChanged()
2798  signal which is emitted whenever a property created by this
2799  manager changes.
2800 
2801  \sa QtAbstractPropertyManager, QtEnumPropertyManager
2802 */
2803 
2804 /*!
2805  \fn void QtLocalePropertyManager::valueChanged(QtProperty *property, const QLocale &value)
2806 
2807  This signal is emitted whenever a property created by this manager
2808  changes its value, passing a pointer to the \a property and the
2809  new \a value as parameters.
2810 
2811  \sa setValue()
2812 */
2813 
2814 /*!
2815  Creates a manager with the given \a parent.
2816 */
2818  : QtAbstractPropertyManager(parent)
2819 {
2820  d_ptr = new QtLocalePropertyManagerPrivate;
2821  d_ptr->q_ptr = this;
2822 
2823  d_ptr->m_enumPropertyManager = new QtEnumPropertyManager(this);
2824  connect(d_ptr->m_enumPropertyManager, SIGNAL(valueChanged(QtProperty*, int)),
2825  this, SLOT(slotEnumChanged(QtProperty*, int)));
2826 
2827  connect(d_ptr->m_enumPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
2828  this, SLOT(slotPropertyDestroyed(QtProperty*)));
2829 }
2830 
2831 /*!
2832  Destroys this manager, and all the properties it has created.
2833 */
2835 {
2836  clear();
2837  delete d_ptr;
2838 }
2839 
2840 /*!
2841  Returns the manager that creates the nested \e language
2842  and \e country subproperties.
2843 
2844  In order to provide editing widgets for the mentioned subproperties
2845  in a property browser widget, this manager must be associated with
2846  an editor factory.
2847 
2848  \sa QtAbstractPropertyBrowser::setFactoryForManager()
2849 */
2851 {
2852  return d_ptr->m_enumPropertyManager;
2853 }
2854 
2855 /*!
2856  Returns the given \a property's value.
2857 
2858  If the given property is not managed by this manager, this
2859  function returns the default locale.
2860 
2861  \sa setValue()
2862 */
2863 QLocale QtLocalePropertyManager::value(const QtProperty* property) const
2864 {
2865  return d_ptr->m_values.value(property, QLocale());
2866 }
2867 
2868 /*!
2869  \reimp
2870 */
2871 QString QtLocalePropertyManager::valueText(const QtProperty* property) const
2872 {
2873  const QtLocalePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
2874 
2875  if (it == d_ptr->m_values.constEnd())
2876  {
2877  return QString();
2878  }
2879 
2880  QLocale loc = it.value();
2881 
2882  int langIdx = 0;
2883  int countryIdx = 0;
2884  metaEnumProvider()->localeToIndex(loc.language(), loc.country(), &langIdx, &countryIdx);
2885  QString str = tr("%1, %2")
2886  .arg(metaEnumProvider()->languageEnumNames().at(langIdx))
2887  .arg(metaEnumProvider()->countryEnumNames(loc.language()).at(countryIdx));
2888  return str;
2889 }
2890 
2891 /*!
2892  \fn void QtLocalePropertyManager::setValue(QtProperty *property, const QLocale &value)
2893 
2894  Sets the value of the given \a property to \a value. Nested
2895  properties are updated automatically.
2896 
2897  \sa value(), valueChanged()
2898 */
2899 void QtLocalePropertyManager::setValue(QtProperty* property, const QLocale& val)
2900 {
2901  const QtLocalePropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
2902 
2903  if (it == d_ptr->m_values.end())
2904  {
2905  return;
2906  }
2907 
2908  const QLocale loc = it.value();
2909 
2910  if (loc == val)
2911  {
2912  return;
2913  }
2914 
2915  it.value() = val;
2916 
2917  int langIdx = 0;
2918  int countryIdx = 0;
2919  metaEnumProvider()->localeToIndex(val.language(), val.country(), &langIdx, &countryIdx);
2920 
2921  if (loc.language() != val.language())
2922  {
2923  d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToLanguage.value(property), langIdx);
2924  d_ptr->m_enumPropertyManager->setEnumNames(d_ptr->m_propertyToCountry.value(property),
2925  metaEnumProvider()->countryEnumNames(val.language()));
2926  }
2927 
2928  d_ptr->m_enumPropertyManager->setValue(d_ptr->m_propertyToCountry.value(property), countryIdx);
2929 
2930  emit propertyChanged(property);
2931  emit valueChanged(property, val);
2932 }
2933 
2934 /*!
2935  \reimp
2936 */
2938 {
2939  QLocale val;
2940  d_ptr->m_values[property] = val;
2941 
2942  int langIdx = 0;
2943  int countryIdx = 0;
2944  metaEnumProvider()->localeToIndex(val.language(), val.country(), &langIdx, &countryIdx);
2945 
2946  QtProperty* languageProp = d_ptr->m_enumPropertyManager->addProperty();
2947  languageProp->setPropertyName(tr("Language"));
2948  d_ptr->m_enumPropertyManager->setEnumNames(languageProp, metaEnumProvider()->languageEnumNames());
2949  d_ptr->m_enumPropertyManager->setValue(languageProp, langIdx);
2950  d_ptr->m_propertyToLanguage[property] = languageProp;
2951  d_ptr->m_languageToProperty[languageProp] = property;
2952  property->addSubProperty(languageProp);
2953 
2954  QtProperty* countryProp = d_ptr->m_enumPropertyManager->addProperty();
2955  countryProp->setPropertyName(tr("Country"));
2956  d_ptr->m_enumPropertyManager->setEnumNames(countryProp, metaEnumProvider()->countryEnumNames(val.language()));
2957  d_ptr->m_enumPropertyManager->setValue(countryProp, countryIdx);
2958  d_ptr->m_propertyToCountry[property] = countryProp;
2959  d_ptr->m_countryToProperty[countryProp] = property;
2960  property->addSubProperty(countryProp);
2961 }
2962 
2963 /*!
2964  \reimp
2965 */
2967 {
2968  QtProperty* languageProp = d_ptr->m_propertyToLanguage[property];
2969 
2970  if (languageProp)
2971  {
2972  d_ptr->m_languageToProperty.remove(languageProp);
2973  delete languageProp;
2974  }
2975 
2976  d_ptr->m_propertyToLanguage.remove(property);
2977 
2978  QtProperty* countryProp = d_ptr->m_propertyToCountry[property];
2979 
2980  if (countryProp)
2981  {
2982  d_ptr->m_countryToProperty.remove(countryProp);
2983  delete countryProp;
2984  }
2985 
2986  d_ptr->m_propertyToCountry.remove(property);
2987 
2988  d_ptr->m_values.remove(property);
2989 }
2990 
2991 // QtPointPropertyManager
2992 
2994 {
2995  QtPointPropertyManager* q_ptr;
2996  Q_DECLARE_PUBLIC(QtPointPropertyManager)
2997 public:
2998 
2999  void slotIntChanged(QtProperty* property, int value);
3000  void slotPropertyDestroyed(QtProperty* property);
3001 
3002  using PropertyValueMap = QMap<const QtProperty*, QPoint>;
3004 
3006 
3007  QMap<const QtProperty*, QtProperty*> m_propertyToX;
3008  QMap<const QtProperty*, QtProperty*> m_propertyToY;
3009 
3010  QMap<const QtProperty*, QtProperty*> m_xToProperty;
3011  QMap<const QtProperty*, QtProperty*> m_yToProperty;
3012 };
3013 
3015 {
3016  if (QtProperty* xprop = m_xToProperty.value(property, 0))
3017  {
3018  QPoint p = m_values[xprop];
3019  p.setX(value);
3020  q_ptr->setValue(xprop, p);
3021  }
3022  else if (QtProperty* yprop = m_yToProperty.value(property, 0))
3023  {
3024  QPoint p = m_values[yprop];
3025  p.setY(value);
3026  q_ptr->setValue(yprop, p);
3027  }
3028 }
3029 
3031 {
3032  if (QtProperty* pointProp = m_xToProperty.value(property, 0))
3033  {
3034  m_propertyToX[pointProp] = 0;
3035  m_xToProperty.remove(property);
3036  }
3037  else if (QtProperty* pointProp = m_yToProperty.value(property, 0))
3038  {
3039  m_propertyToY[pointProp] = 0;
3040  m_yToProperty.remove(property);
3041  }
3042 }
3043 
3044 /*! \class QtPointPropertyManager
3045 
3046  \brief The QtPointPropertyManager provides and manages QPoint properties.
3047 
3048  A point property has nested \e x and \e y subproperties. The
3049  top-level property's value can be retrieved using the value()
3050  function, and set using the setValue() slot.
3051 
3052  The subproperties are created by a QtIntPropertyManager object. This
3053  manager can be retrieved using the subIntPropertyManager() function. In
3054  order to provide editing widgets for the subproperties in a
3055  property browser widget, this manager must be associated with an
3056  editor factory.
3057 
3058  In addition, QtPointPropertyManager provides the valueChanged() signal which
3059  is emitted whenever a property created by this manager changes.
3060 
3061  \sa QtAbstractPropertyManager, QtIntPropertyManager, QtPointFPropertyManager
3062 */
3063 
3064 /*!
3065  \fn void QtPointPropertyManager::valueChanged(QtProperty *property, const QPoint &value)
3066 
3067  This signal is emitted whenever a property created by this manager
3068  changes its value, passing a pointer to the \a property and the
3069  new \a value as parameters.
3070 
3071  \sa setValue()
3072 */
3073 
3074 /*!
3075  Creates a manager with the given \a parent.
3076 */
3078  : QtAbstractPropertyManager(parent)
3079 {
3080  d_ptr = new QtPointPropertyManagerPrivate;
3081  d_ptr->q_ptr = this;
3082 
3083  d_ptr->m_intPropertyManager = new QtIntPropertyManager(this);
3084  connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*, int)),
3085  this, SLOT(slotIntChanged(QtProperty*, int)));
3086  connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
3087  this, SLOT(slotPropertyDestroyed(QtProperty*)));
3088 }
3089 
3090 /*!
3091  Destroys this manager, and all the properties it has created.
3092 */
3094 {
3095  clear();
3096  delete d_ptr;
3097 }
3098 
3099 /*!
3100  Returns the manager that creates the nested \e x and \e y
3101  subproperties.
3102 
3103  In order to provide editing widgets for the subproperties in a
3104  property browser widget, this manager must be associated with an
3105  editor factory.
3106 
3107  \sa QtAbstractPropertyBrowser::setFactoryForManager()
3108 */
3110 {
3111  return d_ptr->m_intPropertyManager;
3112 }
3113 
3114 /*!
3115  Returns the given \a property's value.
3116 
3117  If the given \a property is not managed by this manager, this
3118  function returns a point with coordinates (0, 0).
3119 
3120  \sa setValue()
3121 */
3122 QPoint QtPointPropertyManager::value(const QtProperty* property) const
3123 {
3124  return d_ptr->m_values.value(property, QPoint());
3125 }
3126 
3127 /*!
3128  \reimp
3129 */
3130 QString QtPointPropertyManager::valueText(const QtProperty* property) const
3131 {
3132  const QtPointPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
3133 
3134  if (it == d_ptr->m_values.constEnd())
3135  {
3136  return QString();
3137  }
3138 
3139  const QPoint v = it.value();
3140  return QString(tr("(%1, %2)").arg(QString::number(v.x()))
3141  .arg(QString::number(v.y())));
3142 }
3143 
3144 /*!
3145  \fn void QtPointPropertyManager::setValue(QtProperty *property, const QPoint &value)
3146 
3147  Sets the value of the given \a property to \a value. Nested
3148  properties are updated automatically.
3149 
3150  \sa value(), valueChanged()
3151 */
3152 void QtPointPropertyManager::setValue(QtProperty* property, const QPoint& val)
3153 {
3154  const QtPointPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
3155 
3156  if (it == d_ptr->m_values.end())
3157  {
3158  return;
3159  }
3160 
3161  if (it.value() == val)
3162  {
3163  return;
3164  }
3165 
3166  it.value() = val;
3167  d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToX[property], val.x());
3168  d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToY[property], val.y());
3169 
3170  emit propertyChanged(property);
3171  emit valueChanged(property, val);
3172 }
3173 
3174 /*!
3175  \reimp
3176 */
3178 {
3179  d_ptr->m_values[property] = QPoint(0, 0);
3180 
3181  QtProperty* xProp = d_ptr->m_intPropertyManager->addProperty();
3182  xProp->setPropertyName(tr("X"));
3183  d_ptr->m_intPropertyManager->setValue(xProp, 0);
3184  d_ptr->m_propertyToX[property] = xProp;
3185  d_ptr->m_xToProperty[xProp] = property;
3186  property->addSubProperty(xProp);
3187 
3188  QtProperty* yProp = d_ptr->m_intPropertyManager->addProperty();
3189  yProp->setPropertyName(tr("Y"));
3190  d_ptr->m_intPropertyManager->setValue(yProp, 0);
3191  d_ptr->m_propertyToY[property] = yProp;
3192  d_ptr->m_yToProperty[yProp] = property;
3193  property->addSubProperty(yProp);
3194 }
3195 
3196 /*!
3197  \reimp
3198 */
3200 {
3201  QtProperty* xProp = d_ptr->m_propertyToX[property];
3202 
3203  if (xProp)
3204  {
3205  d_ptr->m_xToProperty.remove(xProp);
3206  delete xProp;
3207  }
3208 
3209  d_ptr->m_propertyToX.remove(property);
3210 
3211  QtProperty* yProp = d_ptr->m_propertyToY[property];
3212 
3213  if (yProp)
3214  {
3215  d_ptr->m_yToProperty.remove(yProp);
3216  delete yProp;
3217  }
3218 
3219  d_ptr->m_propertyToY.remove(property);
3220 
3221  d_ptr->m_values.remove(property);
3222 }
3223 
3224 // QtPointFPropertyManager
3225 
3227 {
3228  QtPointFPropertyManager* q_ptr;
3229  Q_DECLARE_PUBLIC(QtPointFPropertyManager)
3230 public:
3231 
3232  struct Data
3233  {
3234  Data() : decimals(2) {}
3235  QPointF val;
3237  };
3238 
3239  void slotDoubleChanged(QtProperty* property, double value);
3240  void slotPropertyDestroyed(QtProperty* property);
3241 
3242  using PropertyValueMap = QMap<const QtProperty*, Data>;
3244 
3246 
3247  QMap<const QtProperty*, QtProperty*> m_propertyToX;
3248  QMap<const QtProperty*, QtProperty*> m_propertyToY;
3249 
3250  QMap<const QtProperty*, QtProperty*> m_xToProperty;
3251  QMap<const QtProperty*, QtProperty*> m_yToProperty;
3252 };
3253 
3255 {
3256  if (QtProperty* prop = m_xToProperty.value(property, 0))
3257  {
3258  QPointF p = m_values[prop].val;
3259  p.setX(value);
3260  q_ptr->setValue(prop, p);
3261  }
3262  else if (QtProperty* prop = m_yToProperty.value(property, 0))
3263  {
3264  QPointF p = m_values[prop].val;
3265  p.setY(value);
3266  q_ptr->setValue(prop, p);
3267  }
3268 }
3269 
3271 {
3272  if (QtProperty* pointProp = m_xToProperty.value(property, 0))
3273  {
3274  m_propertyToX[pointProp] = 0;
3275  m_xToProperty.remove(property);
3276  }
3277  else if (QtProperty* pointProp = m_yToProperty.value(property, 0))
3278  {
3279  m_propertyToY[pointProp] = 0;
3280  m_yToProperty.remove(property);
3281  }
3282 }
3283 
3284 /*! \class QtPointFPropertyManager
3285 
3286  \brief The QtPointFPropertyManager provides and manages QPointF properties.
3287 
3288  A point property has nested \e x and \e y subproperties. The
3289  top-level property's value can be retrieved using the value()
3290  function, and set using the setValue() slot.
3291 
3292  The subproperties are created by a QtDoublePropertyManager object. This
3293  manager can be retrieved using the subDoublePropertyManager() function. In
3294  order to provide editing widgets for the subproperties in a
3295  property browser widget, this manager must be associated with an
3296  editor factory.
3297 
3298  In addition, QtPointFPropertyManager provides the valueChanged() signal which
3299  is emitted whenever a property created by this manager changes.
3300 
3301  \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtPointPropertyManager
3302 */
3303 
3304 /*!
3305  \fn void QtPointFPropertyManager::valueChanged(QtProperty *property, const QPointF &value)
3306 
3307  This signal is emitted whenever a property created by this manager
3308  changes its value, passing a pointer to the \a property and the
3309  new \a value as parameters.
3310 
3311  \sa setValue()
3312 */
3313 
3314 /*!
3315  \fn void QtPointFPropertyManager::decimalsChanged(QtProperty *property, int prec)
3316 
3317  This signal is emitted whenever a property created by this manager
3318  changes its precision of value, passing a pointer to the
3319  \a property and the new \a prec value
3320 
3321  \sa setDecimals()
3322 */
3323 
3324 /*!
3325  Creates a manager with the given \a parent.
3326 */
3328  : QtAbstractPropertyManager(parent)
3329 {
3330  d_ptr = new QtPointFPropertyManagerPrivate;
3331  d_ptr->q_ptr = this;
3332 
3334  connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty*, double)),
3335  this, SLOT(slotDoubleChanged(QtProperty*, double)));
3336  connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
3337  this, SLOT(slotPropertyDestroyed(QtProperty*)));
3338 }
3339 
3340 /*!
3341  Destroys this manager, and all the properties it has created.
3342 */
3344 {
3345  clear();
3346  delete d_ptr;
3347 }
3348 
3349 /*!
3350  Returns the manager that creates the nested \e x and \e y
3351  subproperties.
3352 
3353  In order to provide editing widgets for the subproperties in a
3354  property browser widget, this manager must be associated with an
3355  editor factory.
3356 
3357  \sa QtAbstractPropertyBrowser::setFactoryForManager()
3358 */
3360 {
3361  return d_ptr->m_doublePropertyManager;
3362 }
3363 
3364 /*!
3365  Returns the given \a property's value.
3366 
3367  If the given \a property is not managed by this manager, this
3368  function returns a point with coordinates (0, 0).
3369 
3370  \sa setValue()
3371 */
3372 QPointF QtPointFPropertyManager::value(const QtProperty* property) const
3373 {
3374  return getValue<QPointF>(d_ptr->m_values, property);
3375 }
3376 
3377 /*!
3378  Returns the given \a property's precision, in decimals.
3379 
3380  \sa setDecimals()
3381 */
3383 {
3384  return getData<int>(d_ptr->m_values, &QtPointFPropertyManagerPrivate::Data::decimals, property, 0);
3385 }
3386 
3387 /*!
3388  \reimp
3389 */
3390 QString QtPointFPropertyManager::valueText(const QtProperty* property) const
3391 {
3392  const QtPointFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
3393 
3394  if (it == d_ptr->m_values.constEnd())
3395  {
3396  return QString();
3397  }
3398 
3399  const QPointF v = it.value().val;
3400  const int dec = it.value().decimals;
3401  return QString(tr("(%1, %2)").arg(QString::number(v.x(), 'f', dec))
3402  .arg(QString::number(v.y(), 'f', dec)));
3403 }
3404 
3405 /*!
3406  \fn void QtPointFPropertyManager::setValue(QtProperty *property, const QPointF &value)
3407 
3408  Sets the value of the given \a property to \a value. Nested
3409  properties are updated automatically.
3410 
3411  \sa value(), valueChanged()
3412 */
3413 void QtPointFPropertyManager::setValue(QtProperty* property, const QPointF& val)
3414 {
3415  const QtPointFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
3416 
3417  if (it == d_ptr->m_values.end())
3418  {
3419  return;
3420  }
3421 
3422  if (it.value().val == val)
3423  {
3424  return;
3425  }
3426 
3427  it.value().val = val;
3428  d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToX[property], val.x());
3429  d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToY[property], val.y());
3430 
3431  emit propertyChanged(property);
3432  emit valueChanged(property, val);
3433 }
3434 
3435 /*!
3436  \fn void QtPointFPropertyManager::setDecimals(QtProperty *property, int prec)
3437 
3438  Sets the precision of the given \a property to \a prec.
3439 
3440  The valid decimal range is 0-13. The default is 2.
3441 
3442  \sa decimals()
3443 */
3445 {
3446  const QtPointFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
3447 
3448  if (it == d_ptr->m_values.end())
3449  {
3450  return;
3451  }
3452 
3454 
3455  if (prec > 13)
3456  {
3457  prec = 13;
3458  }
3459  else if (prec < 0)
3460  {
3461  prec = 0;
3462  }
3463 
3464  if (data.decimals == prec)
3465  {
3466  return;
3467  }
3468 
3469  data.decimals = prec;
3470  d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToX[property], prec);
3471  d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToY[property], prec);
3472 
3473  it.value() = data;
3474 
3475  emit decimalsChanged(property, data.decimals);
3476 }
3477 
3478 /*!
3479  \reimp
3480 */
3482 {
3483  d_ptr->m_values[property] = QtPointFPropertyManagerPrivate::Data();
3484 
3485  QtProperty* xProp = d_ptr->m_doublePropertyManager->addProperty();
3486  xProp->setPropertyName(tr("X"));
3487  d_ptr->m_doublePropertyManager->setDecimals(xProp, decimals(property));
3488  d_ptr->m_doublePropertyManager->setValue(xProp, 0);
3489  d_ptr->m_propertyToX[property] = xProp;
3490  d_ptr->m_xToProperty[xProp] = property;
3491  property->addSubProperty(xProp);
3492 
3493  QtProperty* yProp = d_ptr->m_doublePropertyManager->addProperty();
3494  yProp->setPropertyName(tr("Y"));
3495  d_ptr->m_doublePropertyManager->setDecimals(yProp, decimals(property));
3496  d_ptr->m_doublePropertyManager->setValue(yProp, 0);
3497  d_ptr->m_propertyToY[property] = yProp;
3498  d_ptr->m_yToProperty[yProp] = property;
3499  property->addSubProperty(yProp);
3500 }
3501 
3502 /*!
3503  \reimp
3504 */
3506 {
3507  QtProperty* xProp = d_ptr->m_propertyToX[property];
3508 
3509  if (xProp)
3510  {
3511  d_ptr->m_xToProperty.remove(xProp);
3512  delete xProp;
3513  }
3514 
3515  d_ptr->m_propertyToX.remove(property);
3516 
3517  QtProperty* yProp = d_ptr->m_propertyToY[property];
3518 
3519  if (yProp)
3520  {
3521  d_ptr->m_yToProperty.remove(yProp);
3522  delete yProp;
3523  }
3524 
3525  d_ptr->m_propertyToY.remove(property);
3526 
3527  d_ptr->m_values.remove(property);
3528 }
3529 
3530 // QtSizePropertyManager
3531 
3533 {
3534  QtSizePropertyManager* q_ptr;
3535  Q_DECLARE_PUBLIC(QtSizePropertyManager)
3536 public:
3537 
3538  void slotIntChanged(QtProperty* property, int value);
3539  void slotPropertyDestroyed(QtProperty* property);
3540  void setValue(QtProperty* property, const QSize& val);
3541  void setRange(QtProperty* property,
3542  const QSize& minVal, const QSize& maxVal, const QSize& val);
3543 
3544  struct Data
3545  {
3546  Data() : val(QSize(0, 0)), minVal(QSize(0, 0)), maxVal(QSize(INT_MAX, INT_MAX)) {}
3547  QSize val;
3548  QSize minVal;
3549  QSize maxVal;
3550  QSize minimumValue() const
3551  {
3552  return minVal;
3553  }
3554  QSize maximumValue() const
3555  {
3556  return maxVal;
3557  }
3558  void setMinimumValue(const QSize& newMinVal)
3559  {
3560  setSizeMinimumData(this, newMinVal);
3561  }
3562  void setMaximumValue(const QSize& newMaxVal)
3563  {
3564  setSizeMaximumData(this, newMaxVal);
3565  }
3566  };
3567 
3568  using PropertyValueMap = QMap<const QtProperty*, Data>;
3570 
3572 
3573  QMap<const QtProperty*, QtProperty*> m_propertyToW;
3574  QMap<const QtProperty*, QtProperty*> m_propertyToH;
3575 
3576  QMap<const QtProperty*, QtProperty*> m_wToProperty;
3577  QMap<const QtProperty*, QtProperty*> m_hToProperty;
3578 };
3579 
3581 {
3582  if (QtProperty* prop = m_wToProperty.value(property, 0))
3583  {
3584  QSize s = m_values[prop].val;
3585  s.setWidth(value);
3586  q_ptr->setValue(prop, s);
3587  }
3588  else if (QtProperty* prop = m_hToProperty.value(property, 0))
3589  {
3590  QSize s = m_values[prop].val;
3591  s.setHeight(value);
3592  q_ptr->setValue(prop, s);
3593  }
3594 }
3595 
3597 {
3598  if (QtProperty* pointProp = m_wToProperty.value(property, 0))
3599  {
3600  m_propertyToW[pointProp] = 0;
3601  m_wToProperty.remove(property);
3602  }
3603  else if (QtProperty* pointProp = m_hToProperty.value(property, 0))
3604  {
3605  m_propertyToH[pointProp] = 0;
3606  m_hToProperty.remove(property);
3607  }
3608 }
3609 
3610 void QtSizePropertyManagerPrivate::setValue(QtProperty* property, const QSize& val)
3611 {
3612  m_intPropertyManager->setValue(m_propertyToW.value(property), val.width());
3613  m_intPropertyManager->setValue(m_propertyToH.value(property), val.height());
3614 }
3615 
3617  const QSize& minVal, const QSize& maxVal, const QSize& val)
3618 {
3619  QtProperty* wProperty = m_propertyToW.value(property);
3620  QtProperty* hProperty = m_propertyToH.value(property);
3621  m_intPropertyManager->setRange(wProperty, minVal.width(), maxVal.width());
3622  m_intPropertyManager->setValue(wProperty, val.width());
3623  m_intPropertyManager->setRange(hProperty, minVal.height(), maxVal.height());
3624  m_intPropertyManager->setValue(hProperty, val.height());
3625 }
3626 
3627 /*!
3628  \class QtSizePropertyManager
3629 
3630  \brief The QtSizePropertyManager provides and manages QSize properties.
3631 
3632  A size property has nested \e width and \e height
3633  subproperties. The top-level property's value can be retrieved
3634  using the value() function, and set using the setValue() slot.
3635 
3636  The subproperties are created by a QtIntPropertyManager object. This
3637  manager can be retrieved using the subIntPropertyManager() function. In
3638  order to provide editing widgets for the subproperties in a
3639  property browser widget, this manager must be associated with an
3640  editor factory.
3641 
3642  A size property also has a range of valid values defined by a
3643  minimum size and a maximum size. These sizes can be retrieved
3644  using the minimum() and the maximum() functions, and set using the
3645  setMinimum() and setMaximum() slots. Alternatively, the range can
3646  be defined in one go using the setRange() slot.
3647 
3648  In addition, QtSizePropertyManager provides the valueChanged() signal
3649  which is emitted whenever a property created by this manager
3650  changes, and the rangeChanged() signal which is emitted whenever
3651  such a property changes its range of valid sizes.
3652 
3653  \sa QtAbstractPropertyManager, QtIntPropertyManager, QtSizeFPropertyManager
3654 */
3655 
3656 /*!
3657  \fn void QtSizePropertyManager::valueChanged(QtProperty *property, const QSize &value)
3658 
3659  This signal is emitted whenever a property created by this manager
3660  changes its value, passing a pointer to the \a property and the new
3661  \a value as parameters.
3662 
3663  \sa setValue()
3664 */
3665 
3666 /*!
3667  \fn void QtSizePropertyManager::rangeChanged(QtProperty *property, const QSize &minimum, const QSize &maximum)
3668 
3669  This signal is emitted whenever a property created by this manager
3670  changes its range of valid sizes, passing a pointer to the \a
3671  property and the new \a minimum and \a maximum sizes.
3672 
3673  \sa setRange()
3674 */
3675 
3676 /*!
3677  Creates a manager with the given \a parent.
3678 */
3680  : QtAbstractPropertyManager(parent)
3681 {
3682  d_ptr = new QtSizePropertyManagerPrivate;
3683  d_ptr->q_ptr = this;
3684 
3685  d_ptr->m_intPropertyManager = new QtIntPropertyManager(this);
3686  connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*, int)),
3687  this, SLOT(slotIntChanged(QtProperty*, int)));
3688  connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
3689  this, SLOT(slotPropertyDestroyed(QtProperty*)));
3690 }
3691 
3692 /*!
3693  Destroys this manager, and all the properties it has created.
3694 */
3696 {
3697  clear();
3698  delete d_ptr;
3699 }
3700 
3701 /*!
3702  Returns the manager that creates the nested \e width and \e height
3703  subproperties.
3704 
3705  In order to provide editing widgets for the \e width and \e height
3706  properties in a property browser widget, this manager must be
3707  associated with an editor factory.
3708 
3709  \sa QtAbstractPropertyBrowser::setFactoryForManager()
3710 */
3712 {
3713  return d_ptr->m_intPropertyManager;
3714 }
3715 
3716 /*!
3717  Returns the given \a property's value.
3718 
3719  If the given \a property is not managed by this manager, this
3720  function returns an invalid size
3721 
3722  \sa setValue()
3723 */
3724 QSize QtSizePropertyManager::value(const QtProperty* property) const
3725 {
3726  return getValue<QSize>(d_ptr->m_values, property);
3727 }
3728 
3729 /*!
3730  Returns the given \a property's minimum size value.
3731 
3732  \sa setMinimum(), maximum(), setRange()
3733 */
3734 QSize QtSizePropertyManager::minimum(const QtProperty* property) const
3735 {
3736  return getMinimum<QSize>(d_ptr->m_values, property);
3737 }
3738 
3739 /*!
3740  Returns the given \a property's maximum size value.
3741 
3742  \sa setMaximum(), minimum(), setRange()
3743 */
3744 QSize QtSizePropertyManager::maximum(const QtProperty* property) const
3745 {
3746  return getMaximum<QSize>(d_ptr->m_values, property);
3747 }
3748 
3749 /*!
3750  \reimp
3751 */
3752 QString QtSizePropertyManager::valueText(const QtProperty* property) const
3753 {
3754  const QtSizePropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
3755 
3756  if (it == d_ptr->m_values.constEnd())
3757  {
3758  return QString();
3759  }
3760 
3761  const QSize v = it.value().val;
3762  return QString(tr("%1 x %2").arg(QString::number(v.width()))
3763  .arg(QString::number(v.height())));
3764 }
3765 
3766 /*!
3767  \fn void QtSizePropertyManager::setValue(QtProperty *property, const QSize &value)
3768 
3769  Sets the value of the given \a property to \a value.
3770 
3771  If the specified \a value is not valid according to the given \a
3772  property's size range, the \a value is adjusted to the nearest
3773  valid value within the size range.
3774 
3775  \sa value(), setRange(), valueChanged()
3776 */
3777 void QtSizePropertyManager::setValue(QtProperty* property, const QSize& val)
3778 {
3779  setValueInRange<const QSize&, QtSizePropertyManagerPrivate, QtSizePropertyManager, const QSize>(this, d_ptr,
3782  property, val, &QtSizePropertyManagerPrivate::setValue);
3783 }
3784 
3785 /*!
3786  Sets the minimum size value for the given \a property to \a minVal.
3787 
3788  When setting the minimum size value, the maximum and current
3789  values are adjusted if necessary (ensuring that the size range
3790  remains valid and that the current value is within the range).
3791 
3792  \sa minimum(), setRange(), rangeChanged()
3793 */
3794 void QtSizePropertyManager::setMinimum(QtProperty* property, const QSize& minVal)
3795 {
3796  setBorderValue<const QSize&, QtSizePropertyManagerPrivate, QtSizePropertyManager, QSize, QtSizePropertyManagerPrivate::Data>(this, d_ptr,
3800  property,
3804 }
3805 
3806 /*!
3807  Sets the maximum size value for the given \a property to \a maxVal.
3808 
3809  When setting the maximum size value, the minimum and current
3810  values are adjusted if necessary (ensuring that the size range
3811  remains valid and that the current value is within the range).
3812 
3813  \sa maximum(), setRange(), rangeChanged()
3814 */
3815 void QtSizePropertyManager::setMaximum(QtProperty* property, const QSize& maxVal)
3816 {
3817  setBorderValue<const QSize&, QtSizePropertyManagerPrivate, QtSizePropertyManager, QSize, QtSizePropertyManagerPrivate::Data>(this, d_ptr,
3821  property,
3825 }
3826 
3827 /*!
3828  \fn void QtSizePropertyManager::setRange(QtProperty *property, const QSize &minimum, const QSize &maximum)
3829 
3830  Sets the range of valid values.
3831 
3832  This is a convenience function defining the range of valid values
3833  in one go; setting the \a minimum and \a maximum values for the
3834  given \a property with a single function call.
3835 
3836  When setting a new range, the current value is adjusted if
3837  necessary (ensuring that the value remains within the range).
3838 
3839  \sa setMinimum(), setMaximum(), rangeChanged()
3840 */
3841 void QtSizePropertyManager::setRange(QtProperty* property, const QSize& minVal, const QSize& maxVal)
3842 {
3843  setBorderValues<const QSize&, QtSizePropertyManagerPrivate, QtSizePropertyManager, QSize>(this, d_ptr,
3847  property, minVal, maxVal, &QtSizePropertyManagerPrivate::setRange);
3848 }
3849 
3850 /*!
3851  \reimp
3852 */
3854 {
3855  d_ptr->m_values[property] = QtSizePropertyManagerPrivate::Data();
3856 
3857  QtProperty* wProp = d_ptr->m_intPropertyManager->addProperty();
3858  wProp->setPropertyName(tr("Width"));
3859  d_ptr->m_intPropertyManager->setValue(wProp, 0);
3860  d_ptr->m_intPropertyManager->setMinimum(wProp, 0);
3861  d_ptr->m_propertyToW[property] = wProp;
3862  d_ptr->m_wToProperty[wProp] = property;
3863  property->addSubProperty(wProp);
3864 
3865  QtProperty* hProp = d_ptr->m_intPropertyManager->addProperty();
3866  hProp->setPropertyName(tr("Height"));
3867  d_ptr->m_intPropertyManager->setValue(hProp, 0);
3868  d_ptr->m_intPropertyManager->setMinimum(hProp, 0);
3869  d_ptr->m_propertyToH[property] = hProp;
3870  d_ptr->m_hToProperty[hProp] = property;
3871  property->addSubProperty(hProp);
3872 }
3873 
3874 /*!
3875  \reimp
3876 */
3878 {
3879  QtProperty* wProp = d_ptr->m_propertyToW[property];
3880 
3881  if (wProp)
3882  {
3883  d_ptr->m_wToProperty.remove(wProp);
3884  delete wProp;
3885  }
3886 
3887  d_ptr->m_propertyToW.remove(property);
3888 
3889  QtProperty* hProp = d_ptr->m_propertyToH[property];
3890 
3891  if (hProp)
3892  {
3893  d_ptr->m_hToProperty.remove(hProp);
3894  delete hProp;
3895  }
3896 
3897  d_ptr->m_propertyToH.remove(property);
3898 
3899  d_ptr->m_values.remove(property);
3900 }
3901 
3902 // QtSizeFPropertyManager
3903 
3905 {
3906  QtSizeFPropertyManager* q_ptr;
3907  Q_DECLARE_PUBLIC(QtSizeFPropertyManager)
3908 public:
3909 
3910  void slotDoubleChanged(QtProperty* property, double value);
3911  void slotPropertyDestroyed(QtProperty* property);
3912  void setValue(QtProperty* property, const QSizeF& val);
3913  void setRange(QtProperty* property,
3914  const QSizeF& minVal, const QSizeF& maxVal, const QSizeF& val);
3915 
3916  struct Data
3917  {
3918  Data() : val(QSizeF(0, 0)), minVal(QSizeF(0, 0)), maxVal(QSizeF(INT_MAX, INT_MAX)), decimals(2) {}
3919  QSizeF val;
3920  QSizeF minVal;
3921  QSizeF maxVal;
3923  QSizeF minimumValue() const
3924  {
3925  return minVal;
3926  }
3927  QSizeF maximumValue() const
3928  {
3929  return maxVal;
3930  }
3931  void setMinimumValue(const QSizeF& newMinVal)
3932  {
3933  setSizeMinimumData(this, newMinVal);
3934  }
3935  void setMaximumValue(const QSizeF& newMaxVal)
3936  {
3937  setSizeMaximumData(this, newMaxVal);
3938  }
3939  };
3940 
3941  using PropertyValueMap = QMap<const QtProperty*, Data>;
3943 
3945 
3946  QMap<const QtProperty*, QtProperty*> m_propertyToW;
3947  QMap<const QtProperty*, QtProperty*> m_propertyToH;
3948 
3949  QMap<const QtProperty*, QtProperty*> m_wToProperty;
3950  QMap<const QtProperty*, QtProperty*> m_hToProperty;
3951 };
3952 
3954 {
3955  if (QtProperty* prop = m_wToProperty.value(property, 0))
3956  {
3957  QSizeF s = m_values[prop].val;
3958  s.setWidth(value);
3959  q_ptr->setValue(prop, s);
3960  }
3961  else if (QtProperty* prop = m_hToProperty.value(property, 0))
3962  {
3963  QSizeF s = m_values[prop].val;
3964  s.setHeight(value);
3965  q_ptr->setValue(prop, s);
3966  }
3967 }
3968 
3970 {
3971  if (QtProperty* pointProp = m_wToProperty.value(property, 0))
3972  {
3973  m_propertyToW[pointProp] = 0;
3974  m_wToProperty.remove(property);
3975  }
3976  else if (QtProperty* pointProp = m_hToProperty.value(property, 0))
3977  {
3978  m_propertyToH[pointProp] = 0;
3979  m_hToProperty.remove(property);
3980  }
3981 }
3982 
3983 void QtSizeFPropertyManagerPrivate::setValue(QtProperty* property, const QSizeF& val)
3984 {
3985  m_doublePropertyManager->setValue(m_propertyToW.value(property), val.width());
3986  m_doublePropertyManager->setValue(m_propertyToH.value(property), val.height());
3987 }
3988 
3990  const QSizeF& minVal, const QSizeF& maxVal, const QSizeF& val)
3991 {
3992  m_doublePropertyManager->setRange(m_propertyToW[property], minVal.width(), maxVal.width());
3993  m_doublePropertyManager->setValue(m_propertyToW[property], val.width());
3994  m_doublePropertyManager->setRange(m_propertyToH[property], minVal.height(), maxVal.height());
3995  m_doublePropertyManager->setValue(m_propertyToH[property], val.height());
3996 }
3997 
3998 /*!
3999  \class QtSizeFPropertyManager
4000 
4001  \brief The QtSizeFPropertyManager provides and manages QSizeF properties.
4002 
4003  A size property has nested \e width and \e height
4004  subproperties. The top-level property's value can be retrieved
4005  using the value() function, and set using the setValue() slot.
4006 
4007  The subproperties are created by a QtDoublePropertyManager object. This
4008  manager can be retrieved using the subDoublePropertyManager() function. In
4009  order to provide editing widgets for the subproperties in a
4010  property browser widget, this manager must be associated with an
4011  editor factory.
4012 
4013  A size property also has a range of valid values defined by a
4014  minimum size and a maximum size. These sizes can be retrieved
4015  using the minimum() and the maximum() functions, and set using the
4016  setMinimum() and setMaximum() slots. Alternatively, the range can
4017  be defined in one go using the setRange() slot.
4018 
4019  In addition, QtSizeFPropertyManager provides the valueChanged() signal
4020  which is emitted whenever a property created by this manager
4021  changes, and the rangeChanged() signal which is emitted whenever
4022  such a property changes its range of valid sizes.
4023 
4024  \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtSizePropertyManager
4025 */
4026 
4027 /*!
4028  \fn void QtSizeFPropertyManager::valueChanged(QtProperty *property, const QSizeF &value)
4029 
4030  This signal is emitted whenever a property created by this manager
4031  changes its value, passing a pointer to the \a property and the new
4032  \a value as parameters.
4033 
4034  \sa setValue()
4035 */
4036 
4037 /*!
4038  \fn void QtSizeFPropertyManager::rangeChanged(QtProperty *property, const QSizeF &minimum, const QSizeF &maximum)
4039 
4040  This signal is emitted whenever a property created by this manager
4041  changes its range of valid sizes, passing a pointer to the \a
4042  property and the new \a minimum and \a maximum sizes.
4043 
4044  \sa setRange()
4045 */
4046 
4047 /*!
4048  \fn void QtSizeFPropertyManager::decimalsChanged(QtProperty *property, int prec)
4049 
4050  This signal is emitted whenever a property created by this manager
4051  changes its precision of value, passing a pointer to the
4052  \a property and the new \a prec value
4053 
4054  \sa setDecimals()
4055 */
4056 
4057 /*!
4058  Creates a manager with the given \a parent.
4059 */
4061  : QtAbstractPropertyManager(parent)
4062 {
4063  d_ptr = new QtSizeFPropertyManagerPrivate;
4064  d_ptr->q_ptr = this;
4065 
4067  connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty*, double)),
4068  this, SLOT(slotDoubleChanged(QtProperty*, double)));
4069  connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
4070  this, SLOT(slotPropertyDestroyed(QtProperty*)));
4071 }
4072 
4073 /*!
4074  Destroys this manager, and all the properties it has created.
4075 */
4077 {
4078  clear();
4079  delete d_ptr;
4080 }
4081 
4082 /*!
4083  Returns the manager that creates the nested \e width and \e height
4084  subproperties.
4085 
4086  In order to provide editing widgets for the \e width and \e height
4087  properties in a property browser widget, this manager must be
4088  associated with an editor factory.
4089 
4090  \sa QtAbstractPropertyBrowser::setFactoryForManager()
4091 */
4093 {
4094  return d_ptr->m_doublePropertyManager;
4095 }
4096 
4097 /*!
4098  Returns the given \a property's value.
4099 
4100  If the given \a property is not managed by this manager, this
4101  function returns an invalid size
4102 
4103  \sa setValue()
4104 */
4105 QSizeF QtSizeFPropertyManager::value(const QtProperty* property) const
4106 {
4107  return getValue<QSizeF>(d_ptr->m_values, property);
4108 }
4109 
4110 /*!
4111  Returns the given \a property's precision, in decimals.
4112 
4113  \sa setDecimals()
4114 */
4116 {
4117  return getData<int>(d_ptr->m_values, &QtSizeFPropertyManagerPrivate::Data::decimals, property, 0);
4118 }
4119 
4120 /*!
4121  Returns the given \a property's minimum size value.
4122 
4123  \sa setMinimum(), maximum(), setRange()
4124 */
4125 QSizeF QtSizeFPropertyManager::minimum(const QtProperty* property) const
4126 {
4127  return getMinimum<QSizeF>(d_ptr->m_values, property);
4128 }
4129 
4130 /*!
4131  Returns the given \a property's maximum size value.
4132 
4133  \sa setMaximum(), minimum(), setRange()
4134 */
4135 QSizeF QtSizeFPropertyManager::maximum(const QtProperty* property) const
4136 {
4137  return getMaximum<QSizeF>(d_ptr->m_values, property);
4138 }
4139 
4140 /*!
4141  \reimp
4142 */
4143 QString QtSizeFPropertyManager::valueText(const QtProperty* property) const
4144 {
4145  const QtSizeFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
4146 
4147  if (it == d_ptr->m_values.constEnd())
4148  {
4149  return QString();
4150  }
4151 
4152  const QSizeF v = it.value().val;
4153  const int dec = it.value().decimals;
4154  return QString(tr("%1 x %2").arg(QString::number(v.width(), 'f', dec))
4155  .arg(QString::number(v.height(), 'f', dec)));
4156 }
4157 
4158 /*!
4159  \fn void QtSizeFPropertyManager::setValue(QtProperty *property, const QSizeF &value)
4160 
4161  Sets the value of the given \a property to \a value.
4162 
4163  If the specified \a value is not valid according to the given \a
4164  property's size range, the \a value is adjusted to the nearest
4165  valid value within the size range.
4166 
4167  \sa value(), setRange(), valueChanged()
4168 */
4169 void QtSizeFPropertyManager::setValue(QtProperty* property, const QSizeF& val)
4170 {
4171  setValueInRange<const QSizeF&, QtSizeFPropertyManagerPrivate, QtSizeFPropertyManager, QSizeF>(this, d_ptr,
4174  property, val, &QtSizeFPropertyManagerPrivate::setValue);
4175 }
4176 
4177 /*!
4178  \fn void QtSizeFPropertyManager::setDecimals(QtProperty *property, int prec)
4179 
4180  Sets the precision of the given \a property to \a prec.
4181 
4182  The valid decimal range is 0-13. The default is 2.
4183 
4184  \sa decimals()
4185 */
4187 {
4188  const QtSizeFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
4189 
4190  if (it == d_ptr->m_values.end())
4191  {
4192  return;
4193  }
4194 
4196 
4197  if (prec > 13)
4198  {
4199  prec = 13;
4200  }
4201  else if (prec < 0)
4202  {
4203  prec = 0;
4204  }
4205 
4206  if (data.decimals == prec)
4207  {
4208  return;
4209  }
4210 
4211  data.decimals = prec;
4212  d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToW[property], prec);
4213  d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToH[property], prec);
4214 
4215  it.value() = data;
4216 
4217  emit decimalsChanged(property, data.decimals);
4218 }
4219 
4220 /*!
4221  Sets the minimum size value for the given \a property to \a minVal.
4222 
4223  When setting the minimum size value, the maximum and current
4224  values are adjusted if necessary (ensuring that the size range
4225  remains valid and that the current value is within the range).
4226 
4227  \sa minimum(), setRange(), rangeChanged()
4228 */
4229 void QtSizeFPropertyManager::setMinimum(QtProperty* property, const QSizeF& minVal)
4230 {
4231  setBorderValue<const QSizeF&, QtSizeFPropertyManagerPrivate, QtSizeFPropertyManager, QSizeF, QtSizeFPropertyManagerPrivate::Data>(this, d_ptr,
4235  property,
4239 }
4240 
4241 /*!
4242  Sets the maximum size value for the given \a property to \a maxVal.
4243 
4244  When setting the maximum size value, the minimum and current
4245  values are adjusted if necessary (ensuring that the size range
4246  remains valid and that the current value is within the range).
4247 
4248  \sa maximum(), setRange(), rangeChanged()
4249 */
4250 void QtSizeFPropertyManager::setMaximum(QtProperty* property, const QSizeF& maxVal)
4251 {
4252  setBorderValue<const QSizeF&, QtSizeFPropertyManagerPrivate, QtSizeFPropertyManager, QSizeF, QtSizeFPropertyManagerPrivate::Data>(this, d_ptr,
4256  property,
4260 }
4261 
4262 /*!
4263  \fn void QtSizeFPropertyManager::setRange(QtProperty *property, const QSizeF &minimum, const QSizeF &maximum)
4264 
4265  Sets the range of valid values.
4266 
4267  This is a convenience function defining the range of valid values
4268  in one go; setting the \a minimum and \a maximum values for the
4269  given \a property with a single function call.
4270 
4271  When setting a new range, the current value is adjusted if
4272  necessary (ensuring that the value remains within the range).
4273 
4274  \sa setMinimum(), setMaximum(), rangeChanged()
4275 */
4276 void QtSizeFPropertyManager::setRange(QtProperty* property, const QSizeF& minVal, const QSizeF& maxVal)
4277 {
4278  setBorderValues<const QSizeF&, QtSizeFPropertyManagerPrivate, QtSizeFPropertyManager, QSizeF>(this, d_ptr,
4282  property, minVal, maxVal, &QtSizeFPropertyManagerPrivate::setRange);
4283 }
4284 
4285 /*!
4286  \reimp
4287 */
4289 {
4290  d_ptr->m_values[property] = QtSizeFPropertyManagerPrivate::Data();
4291 
4292  QtProperty* wProp = d_ptr->m_doublePropertyManager->addProperty();
4293  wProp->setPropertyName(tr("Width"));
4294  d_ptr->m_doublePropertyManager->setDecimals(wProp, decimals(property));
4295  d_ptr->m_doublePropertyManager->setValue(wProp, 0);
4296  d_ptr->m_doublePropertyManager->setMinimum(wProp, 0);
4297  d_ptr->m_propertyToW[property] = wProp;
4298  d_ptr->m_wToProperty[wProp] = property;
4299  property->addSubProperty(wProp);
4300 
4301  QtProperty* hProp = d_ptr->m_doublePropertyManager->addProperty();
4302  hProp->setPropertyName(tr("Height"));
4303  d_ptr->m_doublePropertyManager->setDecimals(hProp, decimals(property));
4304  d_ptr->m_doublePropertyManager->setValue(hProp, 0);
4305  d_ptr->m_doublePropertyManager->setMinimum(hProp, 0);
4306  d_ptr->m_propertyToH[property] = hProp;
4307  d_ptr->m_hToProperty[hProp] = property;
4308  property->addSubProperty(hProp);
4309 }
4310 
4311 /*!
4312  \reimp
4313 */
4315 {
4316  QtProperty* wProp = d_ptr->m_propertyToW[property];
4317 
4318  if (wProp)
4319  {
4320  d_ptr->m_wToProperty.remove(wProp);
4321  delete wProp;
4322  }
4323 
4324  d_ptr->m_propertyToW.remove(property);
4325 
4326  QtProperty* hProp = d_ptr->m_propertyToH[property];
4327 
4328  if (hProp)
4329  {
4330  d_ptr->m_hToProperty.remove(hProp);
4331  delete hProp;
4332  }
4333 
4334  d_ptr->m_propertyToH.remove(property);
4335 
4336  d_ptr->m_values.remove(property);
4337 }
4338 
4339 // QtRectPropertyManager
4340 
4342 {
4343  QtRectPropertyManager* q_ptr;
4344  Q_DECLARE_PUBLIC(QtRectPropertyManager)
4345 public:
4346 
4347  void slotIntChanged(QtProperty* property, int value);
4348  void slotPropertyDestroyed(QtProperty* property);
4349  void setConstraint(QtProperty* property, const QRect& constraint, const QRect& val);
4350 
4351  struct Data
4352  {
4353  Data() : val(0, 0, 0, 0) {}
4354  QRect val;
4355  QRect constraint;
4356  };
4357 
4358  using PropertyValueMap = QMap<const QtProperty*, Data>;
4360 
4362 
4363  QMap<const QtProperty*, QtProperty*> m_propertyToX;
4364  QMap<const QtProperty*, QtProperty*> m_propertyToY;
4365  QMap<const QtProperty*, QtProperty*> m_propertyToW;
4366  QMap<const QtProperty*, QtProperty*> m_propertyToH;
4367 
4368  QMap<const QtProperty*, QtProperty*> m_xToProperty;
4369  QMap<const QtProperty*, QtProperty*> m_yToProperty;
4370  QMap<const QtProperty*, QtProperty*> m_wToProperty;
4371  QMap<const QtProperty*, QtProperty*> m_hToProperty;
4372 };
4373 
4375 {
4376  if (QtProperty* prop = m_xToProperty.value(property, 0))
4377  {
4378  QRect r = m_values[prop].val;
4379  r.moveLeft(value);
4380  q_ptr->setValue(prop, r);
4381  }
4382  else if (QtProperty* prop = m_yToProperty.value(property))
4383  {
4384  QRect r = m_values[prop].val;
4385  r.moveTop(value);
4386  q_ptr->setValue(prop, r);
4387  }
4388  else if (QtProperty* prop = m_wToProperty.value(property, 0))
4389  {
4390  Data data = m_values[prop];
4391  QRect r = data.val;
4392  r.setWidth(value);
4393 
4394  if (!data.constraint.isNull() && data.constraint.x() + data.constraint.width() < r.x() + r.width())
4395  {
4396  r.moveLeft(data.constraint.left() + data.constraint.width() - r.width());
4397  }
4398 
4399  q_ptr->setValue(prop, r);
4400  }
4401  else if (QtProperty* prop = m_hToProperty.value(property, 0))
4402  {
4403  Data data = m_values[prop];
4404  QRect r = data.val;
4405  r.setHeight(value);
4406 
4407  if (!data.constraint.isNull() && data.constraint.y() + data.constraint.height() < r.y() + r.height())
4408  {
4409  r.moveTop(data.constraint.top() + data.constraint.height() - r.height());
4410  }
4411 
4412  q_ptr->setValue(prop, r);
4413  }
4414 }
4415 
4417 {
4418  if (QtProperty* pointProp = m_xToProperty.value(property, 0))
4419  {
4420  m_propertyToX[pointProp] = 0;
4421  m_xToProperty.remove(property);
4422  }
4423  else if (QtProperty* pointProp = m_yToProperty.value(property, 0))
4424  {
4425  m_propertyToY[pointProp] = 0;
4426  m_yToProperty.remove(property);
4427  }
4428  else if (QtProperty* pointProp = m_wToProperty.value(property, 0))
4429  {
4430  m_propertyToW[pointProp] = 0;
4431  m_wToProperty.remove(property);
4432  }
4433  else if (QtProperty* pointProp = m_hToProperty.value(property, 0))
4434  {
4435  m_propertyToH[pointProp] = 0;
4436  m_hToProperty.remove(property);
4437  }
4438 }
4439 
4441  const QRect& constraint, const QRect& val)
4442 {
4443  const bool isNull = constraint.isNull();
4444  const int left = isNull ? INT_MIN : constraint.left();
4445  const int right = isNull ? INT_MAX : constraint.left() + constraint.width();
4446  const int top = isNull ? INT_MIN : constraint.top();
4447  const int bottom = isNull ? INT_MAX : constraint.top() + constraint.height();
4448  const int width = isNull ? INT_MAX : constraint.width();
4449  const int height = isNull ? INT_MAX : constraint.height();
4450 
4451  m_intPropertyManager->setRange(m_propertyToX[property], left, right);
4452  m_intPropertyManager->setRange(m_propertyToY[property], top, bottom);
4453  m_intPropertyManager->setRange(m_propertyToW[property], 0, width);
4454  m_intPropertyManager->setRange(m_propertyToH[property], 0, height);
4455 
4456  m_intPropertyManager->setValue(m_propertyToX[property], val.x());
4457  m_intPropertyManager->setValue(m_propertyToY[property], val.y());
4458  m_intPropertyManager->setValue(m_propertyToW[property], val.width());
4459  m_intPropertyManager->setValue(m_propertyToH[property], val.height());
4460 }
4461 
4462 /*!
4463  \class QtRectPropertyManager
4464 
4465  \brief The QtRectPropertyManager provides and manages QRect properties.
4466 
4467  A rectangle property has nested \e x, \e y, \e width and \e height
4468  subproperties. The top-level property's value can be retrieved
4469  using the value() function, and set using the setValue() slot.
4470 
4471  The subproperties are created by a QtIntPropertyManager object. This
4472  manager can be retrieved using the subIntPropertyManager() function. In
4473  order to provide editing widgets for the subproperties in a
4474  property browser widget, this manager must be associated with an
4475  editor factory.
4476 
4477  A rectangle property also has a constraint rectangle which can be
4478  retrieved using the constraint() function, and set using the
4479  setConstraint() slot.
4480 
4481  In addition, QtRectPropertyManager provides the valueChanged() signal
4482  which is emitted whenever a property created by this manager
4483  changes, and the constraintChanged() signal which is emitted
4484  whenever such a property changes its constraint rectangle.
4485 
4486  \sa QtAbstractPropertyManager, QtIntPropertyManager, QtRectFPropertyManager
4487 */
4488 
4489 /*!
4490  \fn void QtRectPropertyManager::valueChanged(QtProperty *property, const QRect &value)
4491 
4492  This signal is emitted whenever a property created by this manager
4493  changes its value, passing a pointer to the \a property and the new
4494  \a value as parameters.
4495 
4496  \sa setValue()
4497 */
4498 
4499 /*!
4500  \fn void QtRectPropertyManager::constraintChanged(QtProperty *property, const QRect &constraint)
4501 
4502  This signal is emitted whenever property changes its constraint
4503  rectangle, passing a pointer to the \a property and the new \a
4504  constraint rectangle as parameters.
4505 
4506  \sa setConstraint()
4507 */
4508 
4509 /*!
4510  Creates a manager with the given \a parent.
4511 */
4513  : QtAbstractPropertyManager(parent)
4514 {
4515  d_ptr = new QtRectPropertyManagerPrivate;
4516  d_ptr->q_ptr = this;
4517 
4518  d_ptr->m_intPropertyManager = new QtIntPropertyManager(this);
4519  connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty*, int)),
4520  this, SLOT(slotIntChanged(QtProperty*, int)));
4521  connect(d_ptr->m_intPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
4522  this, SLOT(slotPropertyDestroyed(QtProperty*)));
4523 }
4524 
4525 /*!
4526  Destroys this manager, and all the properties it has created.
4527 */
4529 {
4530  clear();
4531  delete d_ptr;
4532 }
4533 
4534 /*!
4535  Returns the manager that creates the nested \e x, \e y, \e width
4536  and \e height subproperties.
4537 
4538  In order to provide editing widgets for the mentioned
4539  subproperties in a property browser widget, this manager must be
4540  associated with an editor factory.
4541 
4542  \sa QtAbstractPropertyBrowser::setFactoryForManager()
4543 */
4545 {
4546  return d_ptr->m_intPropertyManager;
4547 }
4548 
4549 /*!
4550  Returns the given \a property's value.
4551 
4552  If the given \a property is not managed by this manager, this
4553  function returns an invalid rectangle.
4554 
4555  \sa setValue(), constraint()
4556 */
4557 QRect QtRectPropertyManager::value(const QtProperty* property) const
4558 {
4559  return getValue<QRect>(d_ptr->m_values, property);
4560 }
4561 
4562 /*!
4563  Returns the given \a property's constraining rectangle. If returned value is null QRect it means there is no constraint applied.
4564 
4565  \sa value(), setConstraint()
4566 */
4567 QRect QtRectPropertyManager::constraint(const QtProperty* property) const
4568 {
4569  return getData<QRect>(d_ptr->m_values, &QtRectPropertyManagerPrivate::Data::constraint, property, QRect());
4570 }
4571 
4572 /*!
4573  \reimp
4574 */
4575 QString QtRectPropertyManager::valueText(const QtProperty* property) const
4576 {
4577  const QtRectPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
4578 
4579  if (it == d_ptr->m_values.constEnd())
4580  {
4581  return QString();
4582  }
4583 
4584  const QRect v = it.value().val;
4585  return QString(tr("[(%1, %2), %3 x %4]").arg(QString::number(v.x()))
4586  .arg(QString::number(v.y()))
4587  .arg(QString::number(v.width()))
4588  .arg(QString::number(v.height())));
4589 }
4590 
4591 /*!
4592  \fn void QtRectPropertyManager::setValue(QtProperty *property, const QRect &value)
4593 
4594  Sets the value of the given \a property to \a value. Nested
4595  properties are updated automatically.
4596 
4597  If the specified \a value is not inside the given \a property's
4598  constraining rectangle, the value is adjusted accordingly to fit
4599  within the constraint.
4600 
4601  \sa value(), setConstraint(), valueChanged()
4602 */
4603 void QtRectPropertyManager::setValue(QtProperty* property, const QRect& val)
4604 {
4605  const QtRectPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
4606 
4607  if (it == d_ptr->m_values.end())
4608  {
4609  return;
4610  }
4611 
4613 
4614  QRect newRect = val.normalized();
4615 
4616  if (!data.constraint.isNull() && !data.constraint.contains(newRect))
4617  {
4618  const QRect r1 = data.constraint;
4619  const QRect r2 = newRect;
4620  newRect.setLeft(qMax(r1.left(), r2.left()));
4621  newRect.setRight(qMin(r1.right(), r2.right()));
4622  newRect.setTop(qMax(r1.top(), r2.top()));
4623  newRect.setBottom(qMin(r1.bottom(), r2.bottom()));
4624 
4625  if (newRect.width() < 0 || newRect.height() < 0)
4626  {
4627  return;
4628  }
4629  }
4630 
4631  if (data.val == newRect)
4632  {
4633  return;
4634  }
4635 
4636  data.val = newRect;
4637 
4638  it.value() = data;
4639  d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToX[property], newRect.x());
4640  d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToY[property], newRect.y());
4641  d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToW[property], newRect.width());
4642  d_ptr->m_intPropertyManager->setValue(d_ptr->m_propertyToH[property], newRect.height());
4643 
4644  emit propertyChanged(property);
4645  emit valueChanged(property, data.val);
4646 }
4647 
4648 /*!
4649  Sets the given \a property's constraining rectangle to \a
4650  constraint.
4651 
4652  When setting the constraint, the current value is adjusted if
4653  necessary (ensuring that the current rectangle value is inside the
4654  constraint). In order to reset the constraint pass a null QRect value.
4655 
4656  \sa setValue(), constraint(), constraintChanged()
4657 */
4658 void QtRectPropertyManager::setConstraint(QtProperty* property, const QRect& constraint)
4659 {
4660  const QtRectPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
4661 
4662  if (it == d_ptr->m_values.end())
4663  {
4664  return;
4665  }
4666 
4668 
4669  QRect newConstraint = constraint.normalized();
4670 
4671  if (data.constraint == newConstraint)
4672  {
4673  return;
4674  }
4675 
4676  const QRect oldVal = data.val;
4677 
4678  data.constraint = newConstraint;
4679 
4680  if (!data.constraint.isNull() && !data.constraint.contains(oldVal))
4681  {
4682  QRect r1 = data.constraint;
4683  QRect r2 = data.val;
4684 
4685  if (r2.width() > r1.width())
4686  {
4687  r2.setWidth(r1.width());
4688  }
4689 
4690  if (r2.height() > r1.height())
4691  {
4692  r2.setHeight(r1.height());
4693  }
4694 
4695  if (r2.left() < r1.left())
4696  {
4697  r2.moveLeft(r1.left());
4698  }
4699  else if (r2.right() > r1.right())
4700  {
4701  r2.moveRight(r1.right());
4702  }
4703 
4704  if (r2.top() < r1.top())
4705  {
4706  r2.moveTop(r1.top());
4707  }
4708  else if (r2.bottom() > r1.bottom())
4709  {
4710  r2.moveBottom(r1.bottom());
4711  }
4712 
4713  data.val = r2;
4714  }
4715 
4716  it.value() = data;
4717 
4718  emit constraintChanged(property, data.constraint);
4719 
4720  d_ptr->setConstraint(property, data.constraint, data.val);
4721 
4722  if (data.val == oldVal)
4723  {
4724  return;
4725  }
4726 
4727  emit propertyChanged(property);
4728  emit valueChanged(property, data.val);
4729 }
4730 
4731 /*!
4732  \reimp
4733 */
4735 {
4736  d_ptr->m_values[property] = QtRectPropertyManagerPrivate::Data();
4737 
4738  QtProperty* xProp = d_ptr->m_intPropertyManager->addProperty();
4739  xProp->setPropertyName(tr("X"));
4740  d_ptr->m_intPropertyManager->setValue(xProp, 0);
4741  d_ptr->m_propertyToX[property] = xProp;
4742  d_ptr->m_xToProperty[xProp] = property;
4743  property->addSubProperty(xProp);
4744 
4745  QtProperty* yProp = d_ptr->m_intPropertyManager->addProperty();
4746  yProp->setPropertyName(tr("Y"));
4747  d_ptr->m_intPropertyManager->setValue(yProp, 0);
4748  d_ptr->m_propertyToY[property] = yProp;
4749  d_ptr->m_yToProperty[yProp] = property;
4750  property->addSubProperty(yProp);
4751 
4752  QtProperty* wProp = d_ptr->m_intPropertyManager->addProperty();
4753  wProp->setPropertyName(tr("Width"));
4754  d_ptr->m_intPropertyManager->setValue(wProp, 0);
4755  d_ptr->m_intPropertyManager->setMinimum(wProp, 0);
4756  d_ptr->m_propertyToW[property] = wProp;
4757  d_ptr->m_wToProperty[wProp] = property;
4758  property->addSubProperty(wProp);
4759 
4760  QtProperty* hProp = d_ptr->m_intPropertyManager->addProperty();
4761  hProp->setPropertyName(tr("Height"));
4762  d_ptr->m_intPropertyManager->setValue(hProp, 0);
4763  d_ptr->m_intPropertyManager->setMinimum(hProp, 0);
4764  d_ptr->m_propertyToH[property] = hProp;
4765  d_ptr->m_hToProperty[hProp] = property;
4766  property->addSubProperty(hProp);
4767 }
4768 
4769 /*!
4770  \reimp
4771 */
4773 {
4774  QtProperty* xProp = d_ptr->m_propertyToX[property];
4775 
4776  if (xProp)
4777  {
4778  d_ptr->m_xToProperty.remove(xProp);
4779  delete xProp;
4780  }
4781 
4782  d_ptr->m_propertyToX.remove(property);
4783 
4784  QtProperty* yProp = d_ptr->m_propertyToY[property];
4785 
4786  if (yProp)
4787  {
4788  d_ptr->m_yToProperty.remove(yProp);
4789  delete yProp;
4790  }
4791 
4792  d_ptr->m_propertyToY.remove(property);
4793 
4794  QtProperty* wProp = d_ptr->m_propertyToW[property];
4795 
4796  if (wProp)
4797  {
4798  d_ptr->m_wToProperty.remove(wProp);
4799  delete wProp;
4800  }
4801 
4802  d_ptr->m_propertyToW.remove(property);
4803 
4804  QtProperty* hProp = d_ptr->m_propertyToH[property];
4805 
4806  if (hProp)
4807  {
4808  d_ptr->m_hToProperty.remove(hProp);
4809  delete hProp;
4810  }
4811 
4812  d_ptr->m_propertyToH.remove(property);
4813 
4814  d_ptr->m_values.remove(property);
4815 }
4816 
4817 // QtRectFPropertyManager
4818 
4820 {
4821  QtRectFPropertyManager* q_ptr;
4822  Q_DECLARE_PUBLIC(QtRectFPropertyManager)
4823 public:
4824 
4825  void slotDoubleChanged(QtProperty* property, double value);
4826  void slotPropertyDestroyed(QtProperty* property);
4827  void setConstraint(QtProperty* property, const QRectF& constraint, const QRectF& val);
4828 
4829  struct Data
4830  {
4831  Data() : val(0, 0, 0, 0), decimals(2) {}
4832  QRectF val;
4833  QRectF constraint;
4835  };
4836 
4837  using PropertyValueMap = QMap<const QtProperty*, Data>;
4839 
4841 
4842  QMap<const QtProperty*, QtProperty*> m_propertyToX;
4843  QMap<const QtProperty*, QtProperty*> m_propertyToY;
4844  QMap<const QtProperty*, QtProperty*> m_propertyToW;
4845  QMap<const QtProperty*, QtProperty*> m_propertyToH;
4846 
4847  QMap<const QtProperty*, QtProperty*> m_xToProperty;
4848  QMap<const QtProperty*, QtProperty*> m_yToProperty;
4849  QMap<const QtProperty*, QtProperty*> m_wToProperty;
4850  QMap<const QtProperty*, QtProperty*> m_hToProperty;
4851 };
4852 
4854 {
4855  if (QtProperty* prop = m_xToProperty.value(property, 0))
4856  {
4857  QRectF r = m_values[prop].val;
4858  r.moveLeft(value);
4859  q_ptr->setValue(prop, r);
4860  }
4861  else if (QtProperty* prop = m_yToProperty.value(property, 0))
4862  {
4863  QRectF r = m_values[prop].val;
4864  r.moveTop(value);
4865  q_ptr->setValue(prop, r);
4866  }
4867  else if (QtProperty* prop = m_wToProperty.value(property, 0))
4868  {
4869  Data data = m_values[prop];
4870  QRectF r = data.val;
4871  r.setWidth(value);
4872 
4873  if (!data.constraint.isNull() && data.constraint.x() + data.constraint.width() < r.x() + r.width())
4874  {
4875  r.moveLeft(data.constraint.left() + data.constraint.width() - r.width());
4876  }
4877 
4878  q_ptr->setValue(prop, r);
4879  }
4880  else if (QtProperty* prop = m_hToProperty.value(property, 0))
4881  {
4882  Data data = m_values[prop];
4883  QRectF r = data.val;
4884  r.setHeight(value);
4885 
4886  if (!data.constraint.isNull() && data.constraint.y() + data.constraint.height() < r.y() + r.height())
4887  {
4888  r.moveTop(data.constraint.top() + data.constraint.height() - r.height());
4889  }
4890 
4891  q_ptr->setValue(prop, r);
4892  }
4893 }
4894 
4896 {
4897  if (QtProperty* pointProp = m_xToProperty.value(property, 0))
4898  {
4899  m_propertyToX[pointProp] = 0;
4900  m_xToProperty.remove(property);
4901  }
4902  else if (QtProperty* pointProp = m_yToProperty.value(property, 0))
4903  {
4904  m_propertyToY[pointProp] = 0;
4905  m_yToProperty.remove(property);
4906  }
4907  else if (QtProperty* pointProp = m_wToProperty.value(property, 0))
4908  {
4909  m_propertyToW[pointProp] = 0;
4910  m_wToProperty.remove(property);
4911  }
4912  else if (QtProperty* pointProp = m_hToProperty.value(property, 0))
4913  {
4914  m_propertyToH[pointProp] = 0;
4915  m_hToProperty.remove(property);
4916  }
4917 }
4918 
4920  const QRectF& constraint, const QRectF& val)
4921 {
4922  const bool isNull = constraint.isNull();
4923  const float left = isNull ? FLT_MIN : constraint.left();
4924  const float right = isNull ? FLT_MAX : constraint.left() + constraint.width();
4925  const float top = isNull ? FLT_MIN : constraint.top();
4926  const float bottom = isNull ? FLT_MAX : constraint.top() + constraint.height();
4927  const float width = isNull ? FLT_MAX : constraint.width();
4928  const float height = isNull ? FLT_MAX : constraint.height();
4929 
4930  m_doublePropertyManager->setRange(m_propertyToX[property], left, right);
4931  m_doublePropertyManager->setRange(m_propertyToY[property], top, bottom);
4932  m_doublePropertyManager->setRange(m_propertyToW[property], 0, width);
4933  m_doublePropertyManager->setRange(m_propertyToH[property], 0, height);
4934 
4935  m_doublePropertyManager->setValue(m_propertyToX[property], val.x());
4936  m_doublePropertyManager->setValue(m_propertyToY[property], val.y());
4937  m_doublePropertyManager->setValue(m_propertyToW[property], val.width());
4938  m_doublePropertyManager->setValue(m_propertyToH[property], val.height());
4939 }
4940 
4941 /*!
4942  \class QtRectFPropertyManager
4943 
4944  \brief The QtRectFPropertyManager provides and manages QRectF properties.
4945 
4946  A rectangle property has nested \e x, \e y, \e width and \e height
4947  subproperties. The top-level property's value can be retrieved
4948  using the value() function, and set using the setValue() slot.
4949 
4950  The subproperties are created by a QtDoublePropertyManager object. This
4951  manager can be retrieved using the subDoublePropertyManager() function. In
4952  order to provide editing widgets for the subproperties in a
4953  property browser widget, this manager must be associated with an
4954  editor factory.
4955 
4956  A rectangle property also has a constraint rectangle which can be
4957  retrieved using the constraint() function, and set using the
4958  setConstraint() slot.
4959 
4960  In addition, QtRectFPropertyManager provides the valueChanged() signal
4961  which is emitted whenever a property created by this manager
4962  changes, and the constraintChanged() signal which is emitted
4963  whenever such a property changes its constraint rectangle.
4964 
4965  \sa QtAbstractPropertyManager, QtDoublePropertyManager, QtRectPropertyManager
4966 */
4967 
4968 /*!
4969  \fn void QtRectFPropertyManager::valueChanged(QtProperty *property, const QRectF &value)
4970 
4971  This signal is emitted whenever a property created by this manager
4972  changes its value, passing a pointer to the \a property and the new
4973  \a value as parameters.
4974 
4975  \sa setValue()
4976 */
4977 
4978 /*!
4979  \fn void QtRectFPropertyManager::constraintChanged(QtProperty *property, const QRectF &constraint)
4980 
4981  This signal is emitted whenever property changes its constraint
4982  rectangle, passing a pointer to the \a property and the new \a
4983  constraint rectangle as parameters.
4984 
4985  \sa setConstraint()
4986 */
4987 
4988 /*!
4989  \fn void QtRectFPropertyManager::decimalsChanged(QtProperty *property, int prec)
4990 
4991  This signal is emitted whenever a property created by this manager
4992  changes its precision of value, passing a pointer to the
4993  \a property and the new \a prec value
4994 
4995  \sa setDecimals()
4996 */
4997 
4998 /*!
4999  Creates a manager with the given \a parent.
5000 */
5002  : QtAbstractPropertyManager(parent)
5003 {
5004  d_ptr = new QtRectFPropertyManagerPrivate;
5005  d_ptr->q_ptr = this;
5006 
5008  connect(d_ptr->m_doublePropertyManager, SIGNAL(valueChanged(QtProperty*, double)),
5009  this, SLOT(slotDoubleChanged(QtProperty*, double)));
5010  connect(d_ptr->m_doublePropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
5011  this, SLOT(slotPropertyDestroyed(QtProperty*)));
5012 }
5013 
5014 /*!
5015  Destroys this manager, and all the properties it has created.
5016 */
5018 {
5019  clear();
5020  delete d_ptr;
5021 }
5022 
5023 /*!
5024  Returns the manager that creates the nested \e x, \e y, \e width
5025  and \e height subproperties.
5026 
5027  In order to provide editing widgets for the mentioned
5028  subproperties in a property browser widget, this manager must be
5029  associated with an editor factory.
5030 
5031  \sa QtAbstractPropertyBrowser::setFactoryForManager()
5032 */
5034 {
5035  return d_ptr->m_doublePropertyManager;
5036 }
5037 
5038 /*!
5039  Returns the given \a property's value.
5040 
5041  If the given \a property is not managed by this manager, this
5042  function returns an invalid rectangle.
5043 
5044  \sa setValue(), constraint()
5045 */
5046 QRectF QtRectFPropertyManager::value(const QtProperty* property) const
5047 {
5048  return getValue<QRectF>(d_ptr->m_values, property);
5049 }
5050 
5051 /*!
5052  Returns the given \a property's precision, in decimals.
5053 
5054  \sa setDecimals()
5055 */
5057 {
5058  return getData<int>(d_ptr->m_values, &QtRectFPropertyManagerPrivate::Data::decimals, property, 0);
5059 }
5060 
5061 /*!
5062  Returns the given \a property's constraining rectangle. If returned value is null QRectF it means there is no constraint applied.
5063 
5064  \sa value(), setConstraint()
5065 */
5066 QRectF QtRectFPropertyManager::constraint(const QtProperty* property) const
5067 {
5068  return getData<QRectF>(d_ptr->m_values, &QtRectFPropertyManagerPrivate::Data::constraint, property, QRect());
5069 }
5070 
5071 /*!
5072  \reimp
5073 */
5074 QString QtRectFPropertyManager::valueText(const QtProperty* property) const
5075 {
5076  const QtRectFPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
5077 
5078  if (it == d_ptr->m_values.constEnd())
5079  {
5080  return QString();
5081  }
5082 
5083  const QRectF v = it.value().val;
5084  const int dec = it.value().decimals;
5085  return QString(tr("[(%1, %2), %3 x %4]").arg(QString::number(v.x(), 'f', dec))
5086  .arg(QString::number(v.y(), 'f', dec))
5087  .arg(QString::number(v.width(), 'f', dec))
5088  .arg(QString::number(v.height(), 'f', dec)));
5089 }
5090 
5091 /*!
5092  \fn void QtRectFPropertyManager::setValue(QtProperty *property, const QRectF &value)
5093 
5094  Sets the value of the given \a property to \a value. Nested
5095  properties are updated automatically.
5096 
5097  If the specified \a value is not inside the given \a property's
5098  constraining rectangle, the value is adjusted accordingly to fit
5099  within the constraint.
5100 
5101  \sa value(), setConstraint(), valueChanged()
5102 */
5103 void QtRectFPropertyManager::setValue(QtProperty* property, const QRectF& val)
5104 {
5105  const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
5106 
5107  if (it == d_ptr->m_values.end())
5108  {
5109  return;
5110  }
5111 
5113 
5114  QRectF newRect = val.normalized();
5115 
5116  if (!data.constraint.isNull() && !data.constraint.contains(newRect))
5117  {
5118  const QRectF r1 = data.constraint;
5119  const QRectF r2 = newRect;
5120  newRect.setLeft(qMax(r1.left(), r2.left()));
5121  newRect.setRight(qMin(r1.right(), r2.right()));
5122  newRect.setTop(qMax(r1.top(), r2.top()));
5123  newRect.setBottom(qMin(r1.bottom(), r2.bottom()));
5124 
5125  if (newRect.width() < 0 || newRect.height() < 0)
5126  {
5127  return;
5128  }
5129  }
5130 
5131  if (data.val == newRect)
5132  {
5133  return;
5134  }
5135 
5136  data.val = newRect;
5137 
5138  it.value() = data;
5139  d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToX[property], newRect.x());
5140  d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToY[property], newRect.y());
5141  d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToW[property], newRect.width());
5142  d_ptr->m_doublePropertyManager->setValue(d_ptr->m_propertyToH[property], newRect.height());
5143 
5144  emit propertyChanged(property);
5145  emit valueChanged(property, data.val);
5146 }
5147 
5148 /*!
5149  Sets the given \a property's constraining rectangle to \a
5150  constraint.
5151 
5152  When setting the constraint, the current value is adjusted if
5153  necessary (ensuring that the current rectangle value is inside the
5154  constraint). In order to reset the constraint pass a null QRectF value.
5155 
5156  \sa setValue(), constraint(), constraintChanged()
5157 */
5158 void QtRectFPropertyManager::setConstraint(QtProperty* property, const QRectF& constraint)
5159 {
5160  const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
5161 
5162  if (it == d_ptr->m_values.end())
5163  {
5164  return;
5165  }
5166 
5168 
5169  QRectF newConstraint = constraint.normalized();
5170 
5171  if (data.constraint == newConstraint)
5172  {
5173  return;
5174  }
5175 
5176  const QRectF oldVal = data.val;
5177 
5178  data.constraint = newConstraint;
5179 
5180  if (!data.constraint.isNull() && !data.constraint.contains(oldVal))
5181  {
5182  QRectF r1 = data.constraint;
5183  QRectF r2 = data.val;
5184 
5185  if (r2.width() > r1.width())
5186  {
5187  r2.setWidth(r1.width());
5188  }
5189 
5190  if (r2.height() > r1.height())
5191  {
5192  r2.setHeight(r1.height());
5193  }
5194 
5195  if (r2.left() < r1.left())
5196  {
5197  r2.moveLeft(r1.left());
5198  }
5199  else if (r2.right() > r1.right())
5200  {
5201  r2.moveRight(r1.right());
5202  }
5203 
5204  if (r2.top() < r1.top())
5205  {
5206  r2.moveTop(r1.top());
5207  }
5208  else if (r2.bottom() > r1.bottom())
5209  {
5210  r2.moveBottom(r1.bottom());
5211  }
5212 
5213  data.val = r2;
5214  }
5215 
5216  it.value() = data;
5217 
5218  emit constraintChanged(property, data.constraint);
5219 
5220  d_ptr->setConstraint(property, data.constraint, data.val);
5221 
5222  if (data.val == oldVal)
5223  {
5224  return;
5225  }
5226 
5227  emit propertyChanged(property);
5228  emit valueChanged(property, data.val);
5229 }
5230 
5231 /*!
5232  \fn void QtRectFPropertyManager::setDecimals(QtProperty *property, int prec)
5233 
5234  Sets the precision of the given \a property to \a prec.
5235 
5236  The valid decimal range is 0-13. The default is 2.
5237 
5238  \sa decimals()
5239 */
5241 {
5242  const QtRectFPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
5243 
5244  if (it == d_ptr->m_values.end())
5245  {
5246  return;
5247  }
5248 
5250 
5251  if (prec > 13)
5252  {
5253  prec = 13;
5254  }
5255  else if (prec < 0)
5256  {
5257  prec = 0;
5258  }
5259 
5260  if (data.decimals == prec)
5261  {
5262  return;
5263  }
5264 
5265  data.decimals = prec;
5266  d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToX[property], prec);
5267  d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToY[property], prec);
5268  d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToW[property], prec);
5269  d_ptr->m_doublePropertyManager->setDecimals(d_ptr->m_propertyToH[property], prec);
5270 
5271  it.value() = data;
5272 
5273  emit decimalsChanged(property, data.decimals);
5274 }
5275 
5276 /*!
5277  \reimp
5278 */
5280 {
5281  d_ptr->m_values[property] = QtRectFPropertyManagerPrivate::Data();
5282 
5283  QtProperty* xProp = d_ptr->m_doublePropertyManager->addProperty();
5284  xProp->setPropertyName(tr("X"));
5285  d_ptr->m_doublePropertyManager->setDecimals(xProp, decimals(property));
5286  d_ptr->m_doublePropertyManager->setValue(xProp, 0);
5287  d_ptr->m_propertyToX[property] = xProp;
5288  d_ptr->m_xToProperty[xProp] = property;
5289  property->addSubProperty(xProp);
5290 
5291  QtProperty* yProp = d_ptr->m_doublePropertyManager->addProperty();
5292  yProp->setPropertyName(tr("Y"));
5293  d_ptr->m_doublePropertyManager->setDecimals(yProp, decimals(property));
5294  d_ptr->m_doublePropertyManager->setValue(yProp, 0);
5295  d_ptr->m_propertyToY[property] = yProp;
5296  d_ptr->m_yToProperty[yProp] = property;
5297  property->addSubProperty(yProp);
5298 
5299  QtProperty* wProp = d_ptr->m_doublePropertyManager->addProperty();
5300  wProp->setPropertyName(tr("Width"));
5301  d_ptr->m_doublePropertyManager->setDecimals(wProp, decimals(property));
5302  d_ptr->m_doublePropertyManager->setValue(wProp, 0);
5303  d_ptr->m_doublePropertyManager->setMinimum(wProp, 0);
5304  d_ptr->m_propertyToW[property] = wProp;
5305  d_ptr->m_wToProperty[wProp] = property;
5306  property->addSubProperty(wProp);
5307 
5308  QtProperty* hProp = d_ptr->m_doublePropertyManager->addProperty();
5309  hProp->setPropertyName(tr("Height"));
5310  d_ptr->m_doublePropertyManager->setDecimals(hProp, decimals(property));
5311  d_ptr->m_doublePropertyManager->setValue(hProp, 0);
5312  d_ptr->m_doublePropertyManager->setMinimum(hProp, 0);
5313  d_ptr->m_propertyToH[property] = hProp;
5314  d_ptr->m_hToProperty[hProp] = property;
5315  property->addSubProperty(hProp);
5316 }
5317 
5318 /*!
5319  \reimp
5320 */
5322 {
5323  QtProperty* xProp = d_ptr->m_propertyToX[property];
5324 
5325  if (xProp)
5326  {
5327  d_ptr->m_xToProperty.remove(xProp);
5328  delete xProp;
5329  }
5330 
5331  d_ptr->m_propertyToX.remove(property);
5332 
5333  QtProperty* yProp = d_ptr->m_propertyToY[property];
5334 
5335  if (yProp)
5336  {
5337  d_ptr->m_yToProperty.remove(yProp);
5338  delete yProp;
5339  }
5340 
5341  d_ptr->m_propertyToY.remove(property);
5342 
5343  QtProperty* wProp = d_ptr->m_propertyToW[property];
5344 
5345  if (wProp)
5346  {
5347  d_ptr->m_wToProperty.remove(wProp);
5348  delete wProp;
5349  }
5350 
5351  d_ptr->m_propertyToW.remove(property);
5352 
5353  QtProperty* hProp = d_ptr->m_propertyToH[property];
5354 
5355  if (hProp)
5356  {
5357  d_ptr->m_hToProperty.remove(hProp);
5358  delete hProp;
5359  }
5360 
5361  d_ptr->m_propertyToH.remove(property);
5362 
5363  d_ptr->m_values.remove(property);
5364 }
5365 
5366 // QtEnumPropertyManager
5367 
5369 {
5370  QtEnumPropertyManager* q_ptr;
5371  Q_DECLARE_PUBLIC(QtEnumPropertyManager)
5372 public:
5373 
5374  struct Data
5375  {
5376  Data() : val(-1) {}
5377  int val;
5378  QStringList enumNames;
5379  QMap<int, QIcon> enumIcons;
5380  };
5381 
5382  using PropertyValueMap = QMap<const QtProperty*, Data>;
5384 };
5385 
5386 /*!
5387  \class QtEnumPropertyManager
5388 
5389  \brief The QtEnumPropertyManager provides and manages enum properties.
5390 
5391  Each enum property has an associated list of enum names which can
5392  be retrieved using the enumNames() function, and set using the
5393  corresponding setEnumNames() function. An enum property's value is
5394  represented by an index in this list, and can be retrieved and set
5395  using the value() and setValue() slots respectively.
5396 
5397  Each enum value can also have an associated icon. The mapping from
5398  values to icons can be set using the setEnumIcons() function and
5399  queried with the enumIcons() function.
5400 
5401  In addition, QtEnumPropertyManager provides the valueChanged() signal
5402  which is emitted whenever a property created by this manager
5403  changes. The enumNamesChanged() or enumIconsChanged() signal is emitted
5404  whenever the list of enum names or icons is altered.
5405 
5406  \sa QtAbstractPropertyManager, QtEnumEditorFactory
5407 */
5408 
5409 /*!
5410  \fn void QtEnumPropertyManager::valueChanged(QtProperty *property, int value)
5411 
5412  This signal is emitted whenever a property created by this manager
5413  changes its value, passing a pointer to the \a property and the new
5414  \a value as parameters.
5415 
5416  \sa setValue()
5417 */
5418 
5419 /*!
5420  \fn void QtEnumPropertyManager::enumNamesChanged(QtProperty *property, const QStringList &names)
5421 
5422  This signal is emitted whenever a property created by this manager
5423  changes its enum names, passing a pointer to the \a property and
5424  the new \a names as parameters.
5425 
5426  \sa setEnumNames()
5427 */
5428 
5429 /*!
5430  \fn void QtEnumPropertyManager::enumIconsChanged(QtProperty *property, const QMap<int, QIcon> &icons)
5431 
5432  This signal is emitted whenever a property created by this manager
5433  changes its enum icons, passing a pointer to the \a property and
5434  the new mapping of values to \a icons as parameters.
5435 
5436  \sa setEnumIcons()
5437 */
5438 
5439 /*!
5440  Creates a manager with the given \a parent.
5441 */
5443  : QtAbstractPropertyManager(parent)
5444 {
5445  d_ptr = new QtEnumPropertyManagerPrivate;
5446  d_ptr->q_ptr = this;
5447 }
5448 
5449 /*!
5450  Destroys this manager, and all the properties it has created.
5451 */
5453 {
5454  clear();
5455  delete d_ptr;
5456 }
5457 
5458 /*!
5459  Returns the given \a property's value which is an index in the
5460  list returned by enumNames()
5461 
5462  If the given property is not managed by this manager, this
5463  function returns -1.
5464 
5465  \sa enumNames(), setValue()
5466 */
5467 int QtEnumPropertyManager::value(const QtProperty* property) const
5468 {
5469  return getValue<int>(d_ptr->m_values, property, -1);
5470 }
5471 
5472 /*!
5473  Returns the given \a property's list of enum names.
5474 
5475  \sa value(), setEnumNames()
5476 */
5477 QStringList QtEnumPropertyManager::enumNames(const QtProperty* property) const
5478 {
5479  return getData<QStringList>(d_ptr->m_values, &QtEnumPropertyManagerPrivate::Data::enumNames, property, QStringList());
5480 }
5481 
5482 /*!
5483  Returns the given \a property's map of enum values to their icons.
5484 
5485  \sa value(), setEnumIcons()
5486 */
5487 QMap<int, QIcon> QtEnumPropertyManager::enumIcons(const QtProperty* property) const
5488 {
5489  return getData<QMap<int, QIcon> >(d_ptr->m_values, &QtEnumPropertyManagerPrivate::Data::enumIcons, property, QMap<int, QIcon>());
5490 }
5491 
5492 /*!
5493  \reimp
5494 */
5495 QString QtEnumPropertyManager::valueText(const QtProperty* property) const
5496 {
5497  const QtEnumPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
5498 
5499  if (it == d_ptr->m_values.constEnd())
5500  {
5501  return QString();
5502  }
5503 
5504  const QtEnumPropertyManagerPrivate::Data& data = it.value();
5505 
5506  const int v = data.val;
5507 
5508  if (v >= 0 && v < data.enumNames.count())
5509  {
5510  return data.enumNames.at(v);
5511  }
5512 
5513  return QString();
5514 }
5515 
5516 /*!
5517  \reimp
5518 */
5519 QIcon QtEnumPropertyManager::valueIcon(const QtProperty* property) const
5520 {
5521  const QtEnumPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
5522 
5523  if (it == d_ptr->m_values.constEnd())
5524  {
5525  return QIcon();
5526  }
5527 
5528  const QtEnumPropertyManagerPrivate::Data& data = it.value();
5529 
5530  const int v = data.val;
5531  return data.enumIcons.value(v);
5532 }
5533 
5534 /*!
5535  \fn void QtEnumPropertyManager::setValue(QtProperty *property, int value)
5536 
5537  Sets the value of the given \a property to \a value.
5538 
5539  The specified \a value must be less than the size of the given \a
5540  property's enumNames() list, and larger than (or equal to) 0.
5541 
5542  \sa value(), valueChanged()
5543 */
5545 {
5546  const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
5547 
5548  if (it == d_ptr->m_values.end())
5549  {
5550  return;
5551  }
5552 
5554 
5555  if (val >= data.enumNames.count())
5556  {
5557  return;
5558  }
5559 
5560  if (val < 0 && data.enumNames.count() > 0)
5561  {
5562  return;
5563  }
5564 
5565  if (val < 0)
5566  {
5567  val = -1;
5568  }
5569 
5570  if (data.val == val)
5571  {
5572  return;
5573  }
5574 
5575  data.val = val;
5576 
5577  it.value() = data;
5578 
5579  emit propertyChanged(property);
5580  emit valueChanged(property, data.val);
5581 }
5582 
5583 /*!
5584  Sets the given \a property's list of enum names to \a
5585  enumNames. The \a property's current value is reset to 0
5586  indicating the first item of the list.
5587 
5588  If the specified \a enumNames list is empty, the \a property's
5589  current value is set to -1.
5590 
5591  \sa enumNames(), enumNamesChanged()
5592 */
5593 void QtEnumPropertyManager::setEnumNames(QtProperty* property, const QStringList& enumNames)
5594 {
5595  const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
5596 
5597  if (it == d_ptr->m_values.end())
5598  {
5599  return;
5600  }
5601 
5603 
5604  if (data.enumNames == enumNames)
5605  {
5606  return;
5607  }
5608 
5609  data.enumNames = enumNames;
5610 
5611  data.val = -1;
5612 
5613  if (enumNames.count() > 0)
5614  {
5615  data.val = 0;
5616  }
5617 
5618  it.value() = data;
5619 
5620  emit enumNamesChanged(property, data.enumNames);
5621 
5622  emit propertyChanged(property);
5623  emit valueChanged(property, data.val);
5624 }
5625 
5626 /*!
5627  Sets the given \a property's map of enum values to their icons to \a
5628  enumIcons.
5629 
5630  Each enum value can have associated icon. This association is represented with passed \a enumIcons map.
5631 
5632  \sa enumNames(), enumNamesChanged()
5633 */
5634 void QtEnumPropertyManager::setEnumIcons(QtProperty* property, const QMap<int, QIcon>& enumIcons)
5635 {
5636  const QtEnumPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
5637 
5638  if (it == d_ptr->m_values.end())
5639  {
5640  return;
5641  }
5642 
5643  it.value().enumIcons = enumIcons;
5644 
5645  emit enumIconsChanged(property, it.value().enumIcons);
5646 
5647  emit propertyChanged(property);
5648 }
5649 
5650 /*!
5651  \reimp
5652 */
5654 {
5655  d_ptr->m_values[property] = QtEnumPropertyManagerPrivate::Data();
5656 }
5657 
5658 /*!
5659  \reimp
5660 */
5662 {
5663  d_ptr->m_values.remove(property);
5664 }
5665 
5666 // QtFlagPropertyManager
5667 
5669 {
5670  QtFlagPropertyManager* q_ptr;
5671  Q_DECLARE_PUBLIC(QtFlagPropertyManager)
5672 public:
5673 
5674  void slotBoolChanged(QtProperty* property, bool value);
5675  void slotPropertyDestroyed(QtProperty* property);
5676 
5677  struct Data
5678  {
5679  Data() : val(-1) {}
5680  int val;
5681  QStringList flagNames;
5682  };
5683 
5684  using PropertyValueMap = QMap<const QtProperty*, Data>;
5686 
5688 
5689  QMap<const QtProperty*, QList<QtProperty*> > m_propertyToFlags;
5690 
5691  QMap<const QtProperty*, QtProperty*> m_flagToProperty;
5692 };
5693 
5695 {
5696  QtProperty* prop = m_flagToProperty.value(property, 0);
5697 
5698  if (prop == 0)
5699  {
5700  return;
5701  }
5702 
5703  QListIterator<QtProperty*> itProp(m_propertyToFlags[prop]);
5704  int level = 0;
5705 
5706  while (itProp.hasNext())
5707  {
5708  QtProperty* p = itProp.next();
5709 
5710  if (p == property)
5711  {
5712  int v = m_values[prop].val;
5713 
5714  if (value)
5715  {
5716  v |= (1 << level);
5717  }
5718  else
5719  {
5720  v &= ~(1 << level);
5721  }
5722 
5723  q_ptr->setValue(prop, v);
5724  return;
5725  }
5726 
5727  level++;
5728  }
5729 }
5730 
5732 {
5733  QtProperty* flagProperty = m_flagToProperty.value(property, 0);
5734 
5735  if (flagProperty == 0)
5736  {
5737  return;
5738  }
5739 
5740  m_propertyToFlags[flagProperty].replace(m_propertyToFlags[flagProperty].indexOf(property), 0);
5741  m_flagToProperty.remove(property);
5742 }
5743 
5744 /*!
5745  \class QtFlagPropertyManager
5746 
5747  \brief The QtFlagPropertyManager provides and manages flag properties.
5748 
5749  Each flag property has an associated list of flag names which can
5750  be retrieved using the flagNames() function, and set using the
5751  corresponding setFlagNames() function.
5752 
5753  The flag manager provides properties with nested boolean
5754  subproperties representing each flag, i.e. a flag property's value
5755  is the binary combination of the subproperties' values. A
5756  property's value can be retrieved and set using the value() and
5757  setValue() slots respectively. The combination of flags is represented
5758  by single int value - that's why it's possible to store up to
5759  32 independent flags in one flag property.
5760 
5761  The subproperties are created by a QtBoolPropertyManager object. This
5762  manager can be retrieved using the subBoolPropertyManager() function. In
5763  order to provide editing widgets for the subproperties in a
5764  property browser widget, this manager must be associated with an
5765  editor factory.
5766 
5767  In addition, QtFlagPropertyManager provides the valueChanged() signal
5768  which is emitted whenever a property created by this manager
5769  changes, and the flagNamesChanged() signal which is emitted
5770  whenever the list of flag names is altered.
5771 
5772  \sa QtAbstractPropertyManager, QtBoolPropertyManager
5773 */
5774 
5775 /*!
5776  \fn void QtFlagPropertyManager::valueChanged(QtProperty *property, int value)
5777 
5778  This signal is emitted whenever a property created by this manager
5779  changes its value, passing a pointer to the \a property and the new
5780  \a value as parameters.
5781 
5782  \sa setValue()
5783 */
5784 
5785 /*!
5786  \fn void QtFlagPropertyManager::flagNamesChanged(QtProperty *property, const QStringList &names)
5787 
5788  This signal is emitted whenever a property created by this manager
5789  changes its flag names, passing a pointer to the \a property and the
5790  new \a names as parameters.
5791 
5792  \sa setFlagNames()
5793 */
5794 
5795 /*!
5796  Creates a manager with the given \a parent.
5797 */
5799  : QtAbstractPropertyManager(parent)
5800 {
5801  d_ptr = new QtFlagPropertyManagerPrivate;
5802  d_ptr->q_ptr = this;
5803 
5804  d_ptr->m_boolPropertyManager = new QtBoolPropertyManager(this);
5805  connect(d_ptr->m_boolPropertyManager, SIGNAL(valueChanged(QtProperty*, bool)),
5806  this, SLOT(slotBoolChanged(QtProperty*, bool)));
5807  connect(d_ptr->m_boolPropertyManager, SIGNAL(propertyDestroyed(QtProperty*)),
5808  this, SLOT(slotPropertyDestroyed(QtProperty*)));
5809 }
5810 
5811 /*!
5812  Destroys this manager, and all the properties it has created.
5813 */
5815 {
5816  clear();
5817  delete d_ptr;
5818 }
5819 
5820 /*!
5821  Returns the manager that produces the nested boolean subproperties
5822  representing each flag.
5823 
5824  In order to provide editing widgets for the subproperties in a
5825  property browser widget, this manager must be associated with an
5826  editor factory.
5827 
5828  \sa QtAbstractPropertyBrowser::setFactoryForManager()
5829 */
5831 {
5832  return d_ptr->m_boolPropertyManager;
5833 }
5834 
5835 /*!
5836  Returns the given \a property's value.
5837 
5838  If the given property is not managed by this manager, this
5839  function returns 0.
5840 
5841  \sa flagNames(), setValue()
5842 */
5843 int QtFlagPropertyManager::value(const QtProperty* property) const
5844 {
5845  return getValue<int>(d_ptr->m_values, property, 0);
5846 }
5847 
5848 /*!
5849  Returns the given \a property's list of flag names.
5850 
5851  \sa value(), setFlagNames()
5852 */
5853 QStringList QtFlagPropertyManager::flagNames(const QtProperty* property) const
5854 {
5855  return getData<QStringList>(d_ptr->m_values, &QtFlagPropertyManagerPrivate::Data::flagNames, property, QStringList());
5856 }
5857 
5858 /*!
5859  \reimp
5860 */
5861 QString QtFlagPropertyManager::valueText(const QtProperty* property) const
5862 {
5863  const QtFlagPropertyManagerPrivate::PropertyValueMap::const_iterator it = d_ptr->m_values.constFind(property);
5864 
5865  if (it == d_ptr->m_values.constEnd())
5866  {
5867  return QString();
5868  }
5869 
5870  const QtFlagPropertyManagerPrivate::Data& data = it.value();
5871 
5872  QString str;
5873  int level = 0;
5874  const QChar bar = QLatin1Char('|');
5875  const QStringList::const_iterator fncend = data.flagNames.constEnd();
5876 
5877  for (QStringList::const_iterator it = data.flagNames.constBegin(); it != fncend; ++it)
5878  {
5879  if (data.val & (1 << level))
5880  {
5881  if (!str.isEmpty())
5882  {
5883  str += bar;
5884  }
5885 
5886  str += *it;
5887  }
5888 
5889  level++;
5890  }
5891 
5892  return str;
5893 }
5894 
5895 /*!
5896  \fn void QtFlagPropertyManager::setValue(QtProperty *property, int value)
5897 
5898  Sets the value of the given \a property to \a value. Nested
5899  properties are updated automatically.
5900 
5901  The specified \a value must be less than the binary combination of
5902  the property's flagNames() list size (i.e. less than 2\sup n,
5903  where \c n is the size of the list) and larger than (or equal to)
5904  0.
5905 
5906  \sa value(), valueChanged()
5907 */
5909 {
5910  const QtFlagPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
5911 
5912  if (it == d_ptr->m_values.end())
5913  {
5914  return;
5915  }
5916 
5918 
5919  if (data.val == val)
5920  {
5921  return;
5922  }
5923 
5924  if (val > (1 << data.flagNames.count()) - 1)
5925  {
5926  return;
5927  }
5928 
5929  if (val < 0)
5930  {
5931  return;
5932  }
5933 
5934  data.val = val;
5935 
5936  it.value() = data;
5937 
5938  QListIterator<QtProperty*> itProp(d_ptr->m_propertyToFlags[property]);
5939  int level = 0;
5940 
5941  while (itProp.hasNext())
5942  {
5943  QtProperty* prop = itProp.next();
5944 
5945  if (prop)
5946  {
5947  d_ptr->m_boolPropertyManager->setValue(prop, val & (1 << level));
5948  }
5949 
5950  level++;
5951  }
5952 
5953  emit propertyChanged(property);
5954  emit valueChanged(property, data.val);
5955 }
5956 
5957 /*!
5958  Sets the given \a property's list of flag names to \a flagNames. The
5959  property's current value is reset to 0 indicating the first item
5960  of the list.
5961 
5962  \sa flagNames(), flagNamesChanged()
5963 */
5964 void QtFlagPropertyManager::setFlagNames(QtProperty* property, const QStringList& flagNames)
5965 {
5966  const QtFlagPropertyManagerPrivate::PropertyValueMap::iterator it = d_ptr->m_values.find(property);
5967 
5968  if (it == d_ptr->m_values.end())
5969  {
5970  return;
5971  }
5972 
5974 
5975  if (data.flagNames == flagNames)
5976  {
5977  return;
5978  }
5979 
5980  data.flagNames = flagNames;
5981  data.val = 0;
5982 
5983  it.value() = data;
5984 
5985  QListIterator<QtProperty*> itProp(d_ptr->m_propertyToFlags[property]);
5986 
5987  while (itProp.hasNext())
5988  {
5989  QtProperty* prop = itProp.next();
5990 
5991  if (prop)
5992  {
5993  delete prop;
5994  d_ptr->m_flagToProperty.remove(prop);
5995  }
5996  }
5997 
5998  d_ptr->m_propertyToFlags[property].clear();
5999 
6000  QStringListIterator itFlag(flagNames);
6001 
6002  while (itFlag.hasNext())
6003  {
6004  const QString flagName = itFlag.next();
6005  QtProperty* prop = d_ptr->m_boolPropertyManager->addProperty();
6006  prop->setPropertyName(flagName);
6007  property->addSubProperty(prop);
6008  d_ptr->m_propertyToFlags[property].append(prop);
6009