qtpropertybrowser.cpp 64 KB

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