PageRenderTime 27ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 0ms

/src/plugins/qmldesigner/designercore/model/model.cpp

https://bitbucket.org/kpozn/qtcreator
C++ | 1984 lines | 1441 code | 373 blank | 170 comment | 212 complexity | c5aa68b63152c8bb180120bb8ee9db16 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-3.0
  1. /**************************************************************************
  2. **
  3. ** This file is part of Qt Creator
  4. **
  5. ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
  6. **
  7. ** Contact: Nokia Corporation (info@qt.nokia.com)
  8. **
  9. **
  10. ** GNU Lesser General Public License Usage
  11. **
  12. ** This file may be used under the terms of the GNU Lesser General Public
  13. ** License version 2.1 as published by the Free Software Foundation and
  14. ** appearing in the file LICENSE.LGPL included in the packaging of this file.
  15. ** Please review the following information to ensure the GNU Lesser General
  16. ** Public License version 2.1 requirements will be met:
  17. ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  18. **
  19. ** In addition, as a special exception, Nokia gives you certain additional
  20. ** rights. These rights are described in the Nokia Qt LGPL Exception
  21. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  22. **
  23. ** Other Usage
  24. **
  25. ** Alternatively, this file may be used in accordance with the terms and
  26. ** conditions contained in a signed written agreement between you and Nokia.
  27. **
  28. ** If you have questions regarding the use of this file, please contact
  29. ** Nokia at info@qt.nokia.com.
  30. **
  31. **************************************************************************/
  32. #include <model.h>
  33. #include <modelnode.h>
  34. #include "internalnode_p.h"
  35. #include "invalidpropertyexception.h"
  36. #include "invalidargumentexception.h"
  37. #include <QtCore/QFile>
  38. #include <QtCore/QByteArray>
  39. #include <QWeakPointer>
  40. #include <QtCore/QFileInfo>
  41. #include <QtGui/QUndoStack>
  42. #include <QtXml/QXmlStreamReader>
  43. #include <QtCore/QDebug>
  44. #include <QPlainTextEdit>
  45. #include <QHashIterator>
  46. #include "abstractview.h"
  47. #include "nodeinstanceview.h"
  48. #include "metainfo.h"
  49. #include "nodemetainfo.h"
  50. #include "model_p.h"
  51. #include "subcomponentmanager.h"
  52. #include "variantparser.h"
  53. #include "internalproperty.h"
  54. #include "internalnodelistproperty.h"
  55. #include "internalnodeabstractproperty.h"
  56. #include "invalidmodelnodeexception.h"
  57. #include "invalidmodelstateexception.h"
  58. #include "invalidslideindexexception.h"
  59. #include "abstractproperty.h"
  60. #include "variantproperty.h"
  61. #include "bindingproperty.h"
  62. #include "nodeabstractproperty.h"
  63. #include "nodelistproperty.h"
  64. #include "rewritertransaction.h"
  65. #include "rewriterview.h"
  66. #include "rewritingexception.h"
  67. #include "invalididexception.h"
  68. /*!
  69. \defgroup CoreModel
  70. */
  71. /*!
  72. \class QmlDesigner::Model
  73. \ingroup CoreModel
  74. \brief This is the facade for the abstract model data.
  75. All write access is running through this interface
  76. The Model is the central place to access a qml files data (see e.g. rootNode() ) and meta data (see metaInfo() ).
  77. Components that want to be informed about changes in the model can register a subclass of AbstractView via attachView().
  78. \see QmlDesigner::ModelNode, QmlDesigner::AbstractProperty, QmlDesigner::AbstractView
  79. */
  80. namespace QmlDesigner {
  81. namespace Internal {
  82. ModelPrivate::ModelPrivate(Model *model) :
  83. m_q(model),
  84. m_writeLock(false),
  85. m_internalIdCounter(1)
  86. {
  87. m_rootInternalNode = createNode("QtQuick/Item", 1, 0, PropertyListType(), PropertyListType(), QString(), ModelNode::NodeWithoutSource,true);
  88. m_acutalStateNode = m_rootInternalNode;
  89. }
  90. ModelPrivate::~ModelPrivate()
  91. {
  92. detachAllViews();
  93. }
  94. void ModelPrivate::detachAllViews()
  95. {
  96. foreach (const QWeakPointer<AbstractView> &view, m_viewList)
  97. detachView(view.data(), true);
  98. m_viewList.clear();
  99. if (m_rewriterView) {
  100. m_rewriterView->modelAboutToBeDetached(m_q);
  101. m_rewriterView.clear();
  102. }
  103. if (m_nodeInstanceView) {
  104. m_nodeInstanceView->modelAboutToBeDetached(m_q);
  105. m_nodeInstanceView.clear();
  106. }
  107. }
  108. Model *ModelPrivate::create(QString type, int major, int minor, Model *metaInfoPropxyModel)
  109. {
  110. Model *model = new Model;
  111. model->d->m_metaInfoProxyModel = metaInfoPropxyModel;
  112. model->d->rootNode()->setType(type);
  113. model->d->rootNode()->setMajorVersion(major);
  114. model->d->rootNode()->setMinorVersion(minor);
  115. return model;
  116. }
  117. void ModelPrivate::changeImports(const QList<Import> &toBeAddedImportList, const QList<Import> &toBeRemovedImportList)
  118. {
  119. QList<Import> removedImportList;
  120. foreach (const Import &import, toBeRemovedImportList) {
  121. if (m_imports.contains(import)) {
  122. removedImportList.append(import);
  123. m_imports.removeOne(import);
  124. }
  125. }
  126. QList<Import> addedImportList;
  127. foreach (const Import &import, toBeAddedImportList) {
  128. if (!m_imports.contains(import)) {
  129. addedImportList.append(import);
  130. m_imports.append(import);
  131. }
  132. }
  133. if (!removedImportList.isEmpty() || !addedImportList.isEmpty())
  134. notifyImportsChanged(addedImportList, removedImportList);
  135. }
  136. void ModelPrivate::notifyImportsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports)
  137. {
  138. bool resetModel = false;
  139. QString description;
  140. try {
  141. if (rewriterView()) {
  142. rewriterView()->importsChanged(addedImports, removedImports);
  143. }
  144. } catch (RewritingException &e) {
  145. description = e.description();
  146. resetModel = true;
  147. }
  148. NodeMetaInfo::clearCache();
  149. if (nodeInstanceView())
  150. nodeInstanceView()->importsChanged(addedImports, removedImports);
  151. foreach (const QWeakPointer<AbstractView> &view, m_viewList)
  152. view->importsChanged(addedImports, removedImports);
  153. if (resetModel) {
  154. resetModelByRewriter(description);
  155. }
  156. }
  157. QUrl ModelPrivate::fileUrl() const
  158. {
  159. return m_fileUrl;
  160. }
  161. void ModelPrivate::setFileUrl(const QUrl &fileUrl)
  162. {
  163. QUrl oldPath = m_fileUrl;
  164. if (oldPath != fileUrl) {
  165. m_fileUrl = fileUrl;
  166. foreach (const QWeakPointer<AbstractView> &view, m_viewList)
  167. view->fileUrlChanged(oldPath, fileUrl);
  168. }
  169. }
  170. InternalNode::Pointer ModelPrivate::createNode(const QString &typeString,
  171. int majorVersion,
  172. int minorVersion,
  173. const QList<QPair<QString, QVariant> > &propertyList,
  174. const QList<QPair<QString, QVariant> > &auxPropertyList,
  175. const QString &nodeSource,
  176. ModelNode::NodeSourceType nodeSourceType,
  177. bool isRootNode)
  178. {
  179. if (typeString.isEmpty())
  180. throw InvalidArgumentException(__LINE__, __FUNCTION__, __FILE__, tr("invalid type"));
  181. qint32 internalId = 0;
  182. if (!isRootNode)
  183. internalId = m_internalIdCounter++;
  184. InternalNode::Pointer newInternalNodePointer = InternalNode::create(typeString, majorVersion, minorVersion, internalId);
  185. newInternalNodePointer->setNodeSourceType(nodeSourceType);
  186. typedef QPair<QString, QVariant> PropertyPair;
  187. foreach (const PropertyPair &propertyPair, propertyList) {
  188. newInternalNodePointer->addVariantProperty(propertyPair.first);
  189. newInternalNodePointer->variantProperty(propertyPair.first)->setValue(propertyPair.second);
  190. }
  191. foreach (const PropertyPair &propertyPair, auxPropertyList) {
  192. newInternalNodePointer->setAuxiliaryData(propertyPair.first, propertyPair.second);
  193. }
  194. m_nodeSet.insert(newInternalNodePointer);
  195. m_internalIdNodeHash.insert(newInternalNodePointer->internalId(), newInternalNodePointer);
  196. if (!nodeSource.isNull())
  197. newInternalNodePointer->setNodeSource(nodeSource);
  198. notifyNodeCreated(newInternalNodePointer);
  199. return newInternalNodePointer;
  200. }
  201. void ModelPrivate::removeNodeFromModel(const InternalNodePointer &node)
  202. {
  203. Q_ASSERT(!node.isNull());
  204. node->resetParentProperty();
  205. if (!node->id().isEmpty())
  206. m_idNodeHash.remove(node->id());
  207. node->setValid(false);
  208. m_nodeSet.remove(node);
  209. m_internalIdNodeHash.remove(node->internalId());
  210. }
  211. void ModelPrivate::removeAllSubNodes(const InternalNode::Pointer &node)
  212. {
  213. foreach (const InternalNodePointer &subNode, node->allSubNodes()) {
  214. removeNodeFromModel(subNode);
  215. }
  216. }
  217. void ModelPrivate::removeNode(const InternalNode::Pointer &node)
  218. {
  219. Q_ASSERT(!node.isNull());
  220. AbstractView::PropertyChangeFlags propertyChangeFlags = AbstractView::NoAdditionalChanges;
  221. notifyNodeAboutToBeRemoved(node);
  222. InternalNodeAbstractProperty::Pointer oldParentProperty(node->parentProperty());
  223. removeAllSubNodes(node);
  224. removeNodeFromModel(node);
  225. InternalNode::Pointer parentNode;
  226. QString parentPropertyName;
  227. if (oldParentProperty) {
  228. parentNode = oldParentProperty->propertyOwner();
  229. parentPropertyName = oldParentProperty->name();
  230. }
  231. if (oldParentProperty && oldParentProperty->isEmpty()) {
  232. removePropertyWithoutNotification(oldParentProperty);
  233. propertyChangeFlags |= AbstractView::EmptyPropertiesRemoved;
  234. }
  235. notifyNodeRemoved(node, parentNode, parentPropertyName, propertyChangeFlags);
  236. }
  237. InternalNode::Pointer ModelPrivate::rootNode() const
  238. {
  239. return m_rootInternalNode;
  240. }
  241. MetaInfo ModelPrivate::metaInfo() const
  242. {
  243. return m_metaInfo;
  244. }
  245. void ModelPrivate::setMetaInfo(const MetaInfo &metaInfo)
  246. {
  247. m_metaInfo = metaInfo;
  248. }
  249. void ModelPrivate::changeNodeId(const InternalNode::Pointer& internalNodePointer, const QString &id)
  250. {
  251. const QString oldId = internalNodePointer->id();
  252. internalNodePointer->setId(id);
  253. if (!oldId.isEmpty())
  254. m_idNodeHash.remove(oldId);
  255. if (!id.isEmpty())
  256. m_idNodeHash.insert(id, internalNodePointer);
  257. try {
  258. notifyNodeIdChanged(internalNodePointer, id, oldId);
  259. } catch (RewritingException &e) {
  260. throw InvalidIdException(__LINE__, __FUNCTION__, __FILE__, id, e.description());
  261. }
  262. }
  263. void ModelPrivate::checkPropertyName(const QString &propertyName)
  264. {
  265. if (propertyName.isEmpty()) {
  266. Q_ASSERT_X(propertyName.isEmpty(), Q_FUNC_INFO, "empty property name");
  267. throw InvalidPropertyException(__LINE__, __FUNCTION__, __FILE__, "<empty property name>");
  268. }
  269. if (propertyName == "id") {
  270. Q_ASSERT_X(propertyName != "id", Q_FUNC_INFO, "cannot add property id");
  271. throw InvalidPropertyException(__LINE__, __FUNCTION__, __FILE__, propertyName);
  272. }
  273. }
  274. void ModelPrivate::notifyAuxiliaryDataChanged(const InternalNodePointer &internalNode, const QString &name, const QVariant &data)
  275. {
  276. bool resetModel = false;
  277. QString description;
  278. try {
  279. if (rewriterView()) {
  280. ModelNode node(internalNode, model(), rewriterView());
  281. rewriterView()->auxiliaryDataChanged(node, name, data);
  282. }
  283. } catch (RewritingException &e) {
  284. description = e.description();
  285. resetModel = true;
  286. }
  287. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  288. Q_ASSERT(view != 0);
  289. ModelNode node(internalNode, model(), view.data());
  290. view->auxiliaryDataChanged(node, name, data);
  291. }
  292. if (nodeInstanceView()) {
  293. ModelNode node(internalNode, model(), nodeInstanceView());
  294. nodeInstanceView()->auxiliaryDataChanged(node, name, data);
  295. }
  296. if (resetModel) {
  297. resetModelByRewriter(description);
  298. }
  299. }
  300. void ModelPrivate::notifyNodeSourceChanged(const InternalNodePointer &internalNode, const QString &newNodeSource)
  301. {
  302. bool resetModel = false;
  303. QString description;
  304. try {
  305. if (rewriterView()) {
  306. ModelNode node(internalNode, model(), rewriterView());
  307. rewriterView()->nodeSourceChanged(node, newNodeSource);
  308. }
  309. } catch (RewritingException &e) {
  310. description = e.description();
  311. resetModel = true;
  312. }
  313. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  314. Q_ASSERT(view != 0);
  315. ModelNode node(internalNode, model(), view.data());
  316. view->nodeSourceChanged(node, newNodeSource);
  317. }
  318. if (nodeInstanceView()) {
  319. ModelNode node(internalNode, model(), nodeInstanceView());
  320. nodeInstanceView()->nodeSourceChanged(node, newNodeSource);
  321. }
  322. if (resetModel) {
  323. resetModelByRewriter(description);
  324. }
  325. }
  326. void ModelPrivate::notifyRootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion)
  327. {
  328. bool resetModel = false;
  329. QString description;
  330. try {
  331. if (rewriterView())
  332. rewriterView()->rootNodeTypeChanged(type, majorVersion, minorVersion);
  333. } catch (RewritingException &e) {
  334. description = e.description();
  335. resetModel = true;
  336. }
  337. if (nodeInstanceView())
  338. nodeInstanceView()->rootNodeTypeChanged(type, majorVersion, minorVersion);
  339. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  340. Q_ASSERT(view != 0);
  341. view->rootNodeTypeChanged(type, majorVersion, minorVersion);
  342. }
  343. if (resetModel) {
  344. resetModelByRewriter(description);
  345. }
  346. }
  347. void ModelPrivate::notifyInstancePropertyChange(const QList<QPair<ModelNode, QString> > &propertyPairList)
  348. {
  349. // no need to notify the rewriter or the instance view
  350. typedef QPair<ModelNode, QString> ModelNodePropertyPair;
  351. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  352. Q_ASSERT(view != 0);
  353. QList<QPair<ModelNode, QString> > adaptedPropertyList;
  354. foreach (const ModelNodePropertyPair &propertyPair, propertyPairList) {
  355. ModelNodePropertyPair newPair(ModelNode(propertyPair.first.internalNode(), model(), view.data()), propertyPair.second);
  356. adaptedPropertyList.append(newPair);
  357. }
  358. view->instancePropertyChange(adaptedPropertyList);
  359. }
  360. }
  361. void ModelPrivate::notifyInstancesCompleted(const QVector<ModelNode> &nodeVector)
  362. {
  363. bool resetModel = false;
  364. QString description;
  365. QVector<Internal::InternalNode::Pointer> internalVector(toInternalNodeVector(nodeVector));
  366. try {
  367. if (rewriterView())
  368. rewriterView()->instancesCompleted(toModelNodeVector(internalVector, rewriterView()));
  369. } catch (RewritingException &e) {
  370. description = e.description();
  371. resetModel = true;
  372. }
  373. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  374. Q_ASSERT(view != 0);
  375. view->instancesCompleted(toModelNodeVector(internalVector, view.data()));
  376. }
  377. if (nodeInstanceView()) {
  378. nodeInstanceView()->instancesCompleted(toModelNodeVector(internalVector, nodeInstanceView()));
  379. }
  380. if (resetModel) {
  381. resetModelByRewriter(description);
  382. }
  383. }
  384. QMultiHash<ModelNode, InformationName> convertModelNodeInformationHash(const QMultiHash<ModelNode, InformationName> &informationChangeHash, AbstractView *view)
  385. {
  386. QMultiHash<ModelNode, InformationName> convertedModelNodeInformationHash;
  387. QHashIterator<ModelNode, InformationName> hashIterator(informationChangeHash);
  388. while (hashIterator.hasNext()) {
  389. hashIterator.next();
  390. convertedModelNodeInformationHash.insert(ModelNode(hashIterator.key(), view), hashIterator.value());
  391. }
  392. return convertedModelNodeInformationHash;
  393. }
  394. void ModelPrivate::notifyInstancesInformationsChange(const QMultiHash<ModelNode, InformationName> &informationChangeHash)
  395. {
  396. bool resetModel = false;
  397. QString description;
  398. try {
  399. if (rewriterView())
  400. rewriterView()->instanceInformationsChange(convertModelNodeInformationHash(informationChangeHash, rewriterView()));
  401. } catch (RewritingException &e) {
  402. description = e.description();
  403. resetModel = true;
  404. }
  405. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  406. Q_ASSERT(view != 0);
  407. view->instanceInformationsChange(convertModelNodeInformationHash(informationChangeHash, view.data()));
  408. }
  409. if (nodeInstanceView()) {
  410. nodeInstanceView()->instanceInformationsChange(convertModelNodeInformationHash(informationChangeHash, nodeInstanceView()));
  411. }
  412. if (resetModel) {
  413. resetModelByRewriter(description);
  414. }
  415. }
  416. void ModelPrivate::notifyInstancesRenderImageChanged(const QVector<ModelNode> &nodeVector)
  417. {
  418. bool resetModel = false;
  419. QString description;
  420. QVector<Internal::InternalNode::Pointer> internalVector(toInternalNodeVector(nodeVector));
  421. try {
  422. if (rewriterView())
  423. rewriterView()->instancesRenderImageChanged(toModelNodeVector(internalVector, rewriterView()));
  424. } catch (RewritingException &e) {
  425. description = e.description();
  426. resetModel = true;
  427. }
  428. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  429. Q_ASSERT(view != 0);
  430. view->instancesRenderImageChanged(toModelNodeVector(internalVector, view.data()));
  431. }
  432. if (nodeInstanceView()) {
  433. nodeInstanceView()->instancesRenderImageChanged(toModelNodeVector(internalVector, nodeInstanceView()));
  434. }
  435. if (resetModel) {
  436. resetModelByRewriter(description);
  437. }
  438. }
  439. void ModelPrivate::notifyInstancesPreviewImageChanged(const QVector<ModelNode> &nodeVector)
  440. {
  441. bool resetModel = false;
  442. QString description;
  443. QVector<Internal::InternalNode::Pointer> internalVector(toInternalNodeVector(nodeVector));
  444. try {
  445. if (rewriterView())
  446. rewriterView()->instancesPreviewImageChanged(toModelNodeVector(internalVector, rewriterView()));
  447. } catch (RewritingException &e) {
  448. description = e.description();
  449. resetModel = true;
  450. }
  451. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  452. Q_ASSERT(view != 0);
  453. view->instancesPreviewImageChanged(toModelNodeVector(internalVector, view.data()));
  454. }
  455. if (nodeInstanceView()) {
  456. nodeInstanceView()->instancesPreviewImageChanged(toModelNodeVector(internalVector, nodeInstanceView()));
  457. }
  458. if (resetModel) {
  459. resetModelByRewriter(description);
  460. }
  461. }
  462. void ModelPrivate::notifyInstancesChildrenChanged(const QVector<ModelNode> &nodeVector)
  463. {
  464. bool resetModel = false;
  465. QString description;
  466. QVector<Internal::InternalNode::Pointer> internalVector(toInternalNodeVector(nodeVector));
  467. try {
  468. if (rewriterView())
  469. rewriterView()->instancesChildrenChanged(toModelNodeVector(internalVector, rewriterView()));
  470. } catch (RewritingException &e) {
  471. description = e.description();
  472. resetModel = true;
  473. }
  474. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  475. Q_ASSERT(view != 0);
  476. view->instancesChildrenChanged(toModelNodeVector(internalVector, view.data()));
  477. }
  478. if (nodeInstanceView()) {
  479. nodeInstanceView()->instancesChildrenChanged(toModelNodeVector(internalVector, nodeInstanceView()));
  480. }
  481. if (resetModel) {
  482. resetModelByRewriter(description);
  483. }
  484. }
  485. void ModelPrivate::notifyActualStateChanged(const ModelNode &node)
  486. {
  487. bool resetModel = false;
  488. QString description;
  489. m_acutalStateNode = node.internalNode();
  490. try {
  491. if (rewriterView())
  492. rewriterView()->actualStateChanged(ModelNode(node.internalNode(), model(), rewriterView()));
  493. } catch (RewritingException &e) {
  494. description = e.description();
  495. resetModel = true;
  496. }
  497. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  498. Q_ASSERT(view != 0);
  499. view->actualStateChanged(ModelNode(node.internalNode(), model(), view.data()));
  500. }
  501. if (nodeInstanceView()) {
  502. nodeInstanceView()->actualStateChanged(ModelNode(node.internalNode(), model(), nodeInstanceView()));
  503. }
  504. if (resetModel) {
  505. resetModelByRewriter(description);
  506. }
  507. }
  508. void ModelPrivate::notifyRewriterBeginTransaction()
  509. {
  510. bool resetModel = false;
  511. QString description;
  512. try {
  513. if (rewriterView())
  514. rewriterView()->rewriterBeginTransaction();
  515. } catch (RewritingException &e) {
  516. description = e.description();
  517. resetModel = true;
  518. }
  519. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  520. Q_ASSERT(view != 0);
  521. view->rewriterBeginTransaction();
  522. }
  523. if (nodeInstanceView()) {
  524. nodeInstanceView()->rewriterBeginTransaction();
  525. }
  526. if (resetModel) {
  527. resetModelByRewriter(description);
  528. }
  529. }
  530. void ModelPrivate::notifyRewriterEndTransaction()
  531. {
  532. bool resetModel = false;
  533. QString description;
  534. try {
  535. if (rewriterView())
  536. rewriterView()->rewriterEndTransaction();
  537. } catch (RewritingException &e) {
  538. description = e.description();
  539. resetModel = true;
  540. }
  541. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  542. Q_ASSERT(view != 0);
  543. view->rewriterEndTransaction();
  544. }
  545. if (nodeInstanceView()) {
  546. nodeInstanceView()->rewriterEndTransaction();
  547. }
  548. if (resetModel) {
  549. resetModelByRewriter(description);
  550. }
  551. }
  552. void ModelPrivate::notifyInstanceToken(const QString &token, int number, const QVector<ModelNode> &nodeVector)
  553. {
  554. bool resetModel = false;
  555. QString description;
  556. QVector<Internal::InternalNode::Pointer> internalVector(toInternalNodeVector(nodeVector));
  557. try {
  558. if (rewriterView())
  559. rewriterView()->instancesToken(token, number, toModelNodeVector(internalVector, rewriterView()));
  560. } catch (RewritingException &e) {
  561. description = e.description();
  562. resetModel = true;
  563. }
  564. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  565. Q_ASSERT(view != 0);
  566. view->instancesToken(token, number, toModelNodeVector(internalVector, view.data()));
  567. }
  568. if (nodeInstanceView()) {
  569. nodeInstanceView()->instancesToken(token, number, toModelNodeVector(internalVector, nodeInstanceView()));
  570. }
  571. if (resetModel) {
  572. resetModelByRewriter(description);
  573. }
  574. }
  575. void ModelPrivate::notifyCustomNotification(const AbstractView *senderView, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data)
  576. {
  577. bool resetModel = false;
  578. QString description;
  579. QList<Internal::InternalNode::Pointer> internalList(toInternalNodeList(nodeList));
  580. try {
  581. if (rewriterView())
  582. rewriterView()->customNotification(senderView, identifier, toModelNodeList(internalList, rewriterView()), data);
  583. } catch (RewritingException &e) {
  584. description = e.description();
  585. resetModel = true;
  586. }
  587. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  588. Q_ASSERT(view != 0);
  589. view->customNotification(senderView, identifier, toModelNodeList(internalList, view.data()), data);
  590. }
  591. if (nodeInstanceView()) {
  592. nodeInstanceView()->customNotification(senderView, identifier, toModelNodeList(internalList, nodeInstanceView()), data);
  593. }
  594. if (resetModel) {
  595. resetModelByRewriter(description);
  596. }
  597. }
  598. void ModelPrivate::notifyPropertiesRemoved(const QList<PropertyPair> &propertyPairList)
  599. {
  600. bool resetModel = false;
  601. QString description;
  602. try {
  603. if (rewriterView()) {
  604. QList<AbstractProperty> propertyList;
  605. foreach (const PropertyPair &propertyPair, propertyPairList) {
  606. AbstractProperty newProperty(propertyPair.second, propertyPair.first, model(), rewriterView());
  607. propertyList.append(newProperty);
  608. }
  609. rewriterView()->propertiesRemoved(propertyList);
  610. }
  611. } catch (RewritingException &e) {
  612. description = e.description();
  613. resetModel = true;
  614. }
  615. if (nodeInstanceView()) {
  616. QList<AbstractProperty> propertyList;
  617. foreach (const PropertyPair &propertyPair, propertyPairList) {
  618. AbstractProperty newProperty(propertyPair.second, propertyPair.first, model(), nodeInstanceView());
  619. propertyList.append(newProperty);
  620. }
  621. nodeInstanceView()->propertiesRemoved(propertyList);
  622. }
  623. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  624. QList<AbstractProperty> propertyList;
  625. Q_ASSERT(view != 0);
  626. foreach (const PropertyPair &propertyPair, propertyPairList) {
  627. AbstractProperty newProperty(propertyPair.second, propertyPair.first, model(), view.data());
  628. propertyList.append(newProperty);
  629. }
  630. view->propertiesRemoved(propertyList);
  631. }
  632. if (resetModel) {
  633. resetModelByRewriter(description);
  634. }
  635. }
  636. void ModelPrivate::notifyPropertiesAboutToBeRemoved(const QList<InternalProperty::Pointer> &internalPropertyList)
  637. {
  638. bool resetModel = false;
  639. QString description;
  640. try {
  641. if (rewriterView()) {
  642. QList<AbstractProperty> propertyList;
  643. foreach (const InternalProperty::Pointer &property, internalPropertyList) {
  644. AbstractProperty newProperty(property->name(), property->propertyOwner(), model(), rewriterView());
  645. propertyList.append(newProperty);
  646. }
  647. rewriterView()->propertiesAboutToBeRemoved(propertyList);
  648. }
  649. } catch (RewritingException &e) {
  650. description = e.description();
  651. resetModel = true;
  652. }
  653. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  654. QList<AbstractProperty> propertyList;
  655. Q_ASSERT(view != 0);
  656. foreach (const InternalProperty::Pointer &property, internalPropertyList) {
  657. AbstractProperty newProperty(property->name(), property->propertyOwner(), model(), view.data());
  658. propertyList.append(newProperty);
  659. }
  660. try {
  661. view->propertiesAboutToBeRemoved(propertyList);
  662. } catch (RewritingException &e) {
  663. description = e.description();
  664. resetModel = true;
  665. }
  666. }
  667. if (nodeInstanceView()) {
  668. QList<AbstractProperty> propertyList;
  669. foreach (const InternalProperty::Pointer &property, internalPropertyList) {
  670. AbstractProperty newProperty(property->name(), property->propertyOwner(), model(), nodeInstanceView());
  671. propertyList.append(newProperty);
  672. }
  673. nodeInstanceView()->propertiesAboutToBeRemoved(propertyList);
  674. }
  675. if (resetModel) {
  676. resetModelByRewriter(description);
  677. }
  678. }
  679. void ModelPrivate::setAuxiliaryData(const InternalNode::Pointer& node, const QString &name, const QVariant &data)
  680. {
  681. node->setAuxiliaryData(name, data);
  682. notifyAuxiliaryDataChanged(node, name,data);
  683. }
  684. void ModelPrivate::resetModelByRewriter(const QString &description)
  685. {
  686. if (rewriterView()) {
  687. rewriterView()->resetToLastCorrectQml();
  688. }
  689. throw RewritingException(__LINE__, __FUNCTION__, __FILE__, description, rewriterView()->textModifierContent());
  690. }
  691. void ModelPrivate::attachView(AbstractView *view)
  692. {
  693. if (m_viewList.contains(view))
  694. return;
  695. m_viewList.append(view);
  696. view->modelAttached(m_q);
  697. }
  698. void ModelPrivate::detachView(AbstractView *view, bool notifyView)
  699. {
  700. if (notifyView)
  701. view->modelAboutToBeDetached(m_q);
  702. m_viewList.removeOne(view);
  703. }
  704. void ModelPrivate::notifyNodeCreated(const InternalNode::Pointer &newInternalNodePointer)
  705. {
  706. Q_ASSERT(newInternalNodePointer->isValid());
  707. bool resetModel = false;
  708. QString description;
  709. try {
  710. if (rewriterView()) {
  711. ModelNode createdNode(newInternalNodePointer, model(), rewriterView());
  712. rewriterView()->nodeCreated(createdNode);
  713. }
  714. } catch (RewritingException &e) {
  715. description = e.description();
  716. resetModel = true;
  717. }
  718. if (nodeInstanceView()) {
  719. ModelNode createdNode(newInternalNodePointer, model(), nodeInstanceView());
  720. nodeInstanceView()->nodeCreated(createdNode);
  721. }
  722. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  723. Q_ASSERT(view != 0);
  724. ModelNode createdNode(newInternalNodePointer, model(), view.data());
  725. view->nodeCreated(createdNode);
  726. }
  727. if (resetModel) {
  728. resetModelByRewriter(description);
  729. }
  730. }
  731. void ModelPrivate::notifyNodeAboutToBeRemoved(const InternalNode::Pointer &nodePointer)
  732. {
  733. bool resetModel = false;
  734. QString description;
  735. try {
  736. if (rewriterView()) {
  737. ModelNode node(nodePointer, model(), rewriterView());
  738. rewriterView()->nodeAboutToBeRemoved(node);
  739. }
  740. } catch (RewritingException &e) {
  741. description = e.description();
  742. resetModel = true;
  743. }
  744. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  745. Q_ASSERT(view != 0);
  746. ModelNode node(nodePointer, model(), view.data());
  747. view->nodeAboutToBeRemoved(node);
  748. }
  749. if (nodeInstanceView()) {
  750. ModelNode node(nodePointer, model(), nodeInstanceView());
  751. nodeInstanceView()->nodeAboutToBeRemoved(node);
  752. }
  753. if (resetModel) {
  754. resetModelByRewriter(description);
  755. }
  756. }
  757. void ModelPrivate::notifyNodeRemoved(const InternalNodePointer &nodePointer, const InternalNodePointer &parentNodePointer, const QString &parentPropertyName, AbstractView::PropertyChangeFlags propertyChange)
  758. {
  759. bool resetModel = false;
  760. QString description;
  761. try {
  762. if (rewriterView()) {
  763. ModelNode node(nodePointer, model(), rewriterView());
  764. NodeAbstractProperty parentProperty(parentPropertyName, parentNodePointer, model(), rewriterView());
  765. rewriterView()->nodeRemoved(node, parentProperty, propertyChange);
  766. }
  767. } catch (RewritingException &e) {
  768. description = e.description();
  769. resetModel = true;
  770. }
  771. if (nodeInstanceView()) {
  772. ModelNode node(nodePointer, model(), nodeInstanceView());
  773. NodeAbstractProperty parentProperty(parentPropertyName, parentNodePointer, model(), nodeInstanceView());
  774. nodeInstanceView()->nodeRemoved(node, parentProperty, propertyChange);
  775. }
  776. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  777. Q_ASSERT(view != 0);
  778. ModelNode node(nodePointer, model(), view.data());
  779. NodeAbstractProperty parentProperty(parentPropertyName, parentNodePointer, model(), view.data());
  780. view->nodeRemoved(node, parentProperty, propertyChange);
  781. }
  782. if (resetModel) {
  783. resetModelByRewriter(description);
  784. }
  785. }
  786. void ModelPrivate::notifyNodeIdChanged(const InternalNode::Pointer& nodePointer, const QString& newId, const QString& oldId)
  787. {
  788. bool resetModel = false;
  789. QString description;
  790. try {
  791. if (rewriterView()) {
  792. ModelNode node(nodePointer, model(), rewriterView());
  793. rewriterView()->nodeIdChanged(node, newId, oldId);
  794. }
  795. } catch (RewritingException &e) {
  796. description = e.description();
  797. resetModel = true;
  798. }
  799. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  800. Q_ASSERT(view != 0);
  801. ModelNode node(nodePointer, model(), view.data());
  802. view->nodeIdChanged(node, newId, oldId);
  803. }
  804. if (nodeInstanceView()) {
  805. ModelNode node(nodePointer, model(), nodeInstanceView());
  806. nodeInstanceView()->nodeIdChanged(node, newId, oldId);
  807. }
  808. if (resetModel) {
  809. resetModelByRewriter(description);
  810. }
  811. }
  812. void ModelPrivate::notifyBindingPropertiesChanged(const QList<InternalBindingPropertyPointer> &internalBropertyList, AbstractView::PropertyChangeFlags propertyChange)
  813. {
  814. bool resetModel = false;
  815. QString description;
  816. try {
  817. if (rewriterView()) {
  818. QList<BindingProperty> propertyList;
  819. foreach (const InternalBindingPropertyPointer &bindingProperty, internalBropertyList) {
  820. propertyList.append(BindingProperty(bindingProperty->name(), bindingProperty->propertyOwner(), model(), rewriterView()));
  821. }
  822. rewriterView()->bindingPropertiesChanged(propertyList, propertyChange);
  823. }
  824. } catch (RewritingException &e) {
  825. description = e.description();
  826. resetModel = true;
  827. }
  828. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  829. Q_ASSERT(view != 0);
  830. QList<BindingProperty> propertyList;
  831. foreach (const InternalBindingPropertyPointer &bindingProperty, internalBropertyList) {
  832. propertyList.append(BindingProperty(bindingProperty->name(), bindingProperty->propertyOwner(), model(), view.data()));
  833. }
  834. view->bindingPropertiesChanged(propertyList, propertyChange);
  835. }
  836. if (nodeInstanceView()) {
  837. QList<BindingProperty> propertyList;
  838. foreach (const InternalBindingPropertyPointer &bindingProperty, internalBropertyList) {
  839. propertyList.append(BindingProperty(bindingProperty->name(), bindingProperty->propertyOwner(), model(), nodeInstanceView()));
  840. }
  841. nodeInstanceView()->bindingPropertiesChanged(propertyList, propertyChange);
  842. }
  843. if (resetModel) {
  844. resetModelByRewriter(description);
  845. }
  846. }
  847. void ModelPrivate::notifyScriptFunctionsChanged(const InternalNodePointer &internalNodePointer, const QStringList &scriptFunctionList)
  848. {
  849. bool resetModel = false;
  850. QString description;
  851. try {
  852. if (rewriterView()) {
  853. ModelNode node(internalNodePointer, model(), rewriterView());
  854. rewriterView()->scriptFunctionsChanged(node, scriptFunctionList);
  855. }
  856. } catch (RewritingException &e) {
  857. description = e.description();
  858. resetModel = true;
  859. }
  860. if (nodeInstanceView()) {
  861. ModelNode node(internalNodePointer, model(), nodeInstanceView());
  862. nodeInstanceView()->scriptFunctionsChanged(node, scriptFunctionList);
  863. }
  864. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  865. Q_ASSERT(view != 0);
  866. ModelNode node(internalNodePointer, model(), view.data());
  867. view->scriptFunctionsChanged(node, scriptFunctionList);
  868. }
  869. if (resetModel) {
  870. resetModelByRewriter(description);
  871. }
  872. }
  873. void ModelPrivate::notifyVariantPropertiesChanged(const InternalNodePointer &internalNodePointer, const QStringList& propertyNameList, AbstractView::PropertyChangeFlags propertyChange)
  874. {
  875. bool resetModel = false;
  876. QString description;
  877. try {
  878. if (rewriterView()) {
  879. QList<VariantProperty> propertyList;
  880. foreach (const QString &propertyName, propertyNameList) {
  881. Q_ASSERT(internalNodePointer->hasProperty(propertyName));
  882. Q_ASSERT(internalNodePointer->property(propertyName)->isVariantProperty());
  883. VariantProperty property(propertyName, internalNodePointer, model(), rewriterView());
  884. propertyList.append(property);
  885. }
  886. ModelNode node(internalNodePointer, model(), rewriterView());
  887. rewriterView()->variantPropertiesChanged(propertyList, propertyChange);
  888. }
  889. } catch (RewritingException &e) {
  890. description = e.description();
  891. resetModel = true;
  892. }
  893. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  894. QList<VariantProperty> propertyList;
  895. Q_ASSERT(view != 0);
  896. foreach (const QString &propertyName, propertyNameList) {
  897. Q_ASSERT(internalNodePointer->hasProperty(propertyName));
  898. Q_ASSERT(internalNodePointer->property(propertyName)->isVariantProperty());
  899. VariantProperty property(propertyName, internalNodePointer, model(), view.data());
  900. propertyList.append(property);
  901. }
  902. ModelNode node(internalNodePointer, model(), view.data());
  903. view->variantPropertiesChanged(propertyList, propertyChange);
  904. }
  905. if (nodeInstanceView()) {
  906. QList<VariantProperty> propertyList;
  907. foreach (const QString &propertyName, propertyNameList) {
  908. Q_ASSERT(internalNodePointer->hasProperty(propertyName));
  909. Q_ASSERT(internalNodePointer->property(propertyName)->isVariantProperty());
  910. VariantProperty property(propertyName, internalNodePointer, model(), nodeInstanceView());
  911. propertyList.append(property);
  912. }
  913. ModelNode node(internalNodePointer, model(), nodeInstanceView());
  914. nodeInstanceView()->variantPropertiesChanged(propertyList, propertyChange);
  915. }
  916. if (resetModel) {
  917. resetModelByRewriter(description);
  918. }
  919. }
  920. void ModelPrivate::notifyNodeAboutToBeReparent(const InternalNodePointer &internalNodePointer, const InternalNodeAbstractPropertyPointer &newPropertyParent, const InternalNodePointer &oldParent, const QString &oldPropertyName, AbstractView::PropertyChangeFlags propertyChange)
  921. {
  922. bool resetModel = false;
  923. QString description;
  924. try {
  925. if (rewriterView()) {
  926. NodeAbstractProperty newProperty;
  927. NodeAbstractProperty oldProperty;
  928. if (!oldPropertyName.isEmpty() && oldParent->isValid())
  929. oldProperty = NodeAbstractProperty(oldPropertyName, oldParent, model(), rewriterView());
  930. if (!newPropertyParent.isNull())
  931. newProperty = NodeAbstractProperty(newPropertyParent, model(), rewriterView());
  932. ModelNode node(internalNodePointer, model(), rewriterView());
  933. rewriterView()->nodeAboutToBeReparented(node, newProperty, oldProperty, propertyChange);
  934. }
  935. } catch (RewritingException &e) {
  936. description = e.description();
  937. resetModel = true;
  938. }
  939. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  940. NodeAbstractProperty newProperty;
  941. NodeAbstractProperty oldProperty;
  942. Q_ASSERT(!view.isNull());
  943. if (!oldPropertyName.isEmpty() && oldParent->isValid())
  944. oldProperty = NodeAbstractProperty(oldPropertyName, oldParent, model(), view.data());
  945. if (!newPropertyParent.isNull())
  946. newProperty = NodeAbstractProperty(newPropertyParent, model(), view.data());
  947. ModelNode node(internalNodePointer, model(), view.data());
  948. view->nodeAboutToBeReparented(node, newProperty, oldProperty, propertyChange);
  949. }
  950. if (nodeInstanceView()) {
  951. NodeAbstractProperty newProperty;
  952. NodeAbstractProperty oldProperty;
  953. if (!oldPropertyName.isEmpty() && oldParent->isValid())
  954. oldProperty = NodeAbstractProperty(oldPropertyName, oldParent, model(), nodeInstanceView());
  955. if (!newPropertyParent.isNull())
  956. newProperty = NodeAbstractProperty(newPropertyParent, model(), nodeInstanceView());
  957. ModelNode node(internalNodePointer, model(), nodeInstanceView());
  958. nodeInstanceView()->nodeAboutToBeReparented(node, newProperty, oldProperty, propertyChange);
  959. }
  960. if (resetModel) {
  961. resetModelByRewriter(description);
  962. }
  963. }
  964. void ModelPrivate::notifyNodeReparent(const InternalNode::Pointer &internalNodePointer, const InternalNodeAbstractProperty::Pointer &newPropertyParent, const InternalNodePointer &oldParent, const QString &oldPropertyName, AbstractView::PropertyChangeFlags propertyChange)
  965. {
  966. bool resetModel = false;
  967. QString description;
  968. try {
  969. if (rewriterView()) {
  970. NodeAbstractProperty newProperty;
  971. NodeAbstractProperty oldProperty;
  972. if (!oldPropertyName.isEmpty() && oldParent->isValid())
  973. oldProperty = NodeAbstractProperty(oldPropertyName, oldParent, model(), rewriterView());
  974. if (!newPropertyParent.isNull())
  975. newProperty = NodeAbstractProperty(newPropertyParent, model(), rewriterView());
  976. ModelNode node(internalNodePointer, model(), rewriterView());
  977. rewriterView()->nodeReparented(node, newProperty, oldProperty, propertyChange);
  978. }
  979. } catch (RewritingException &e) {
  980. description = e.description();
  981. resetModel = true;
  982. }
  983. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  984. NodeAbstractProperty newProperty;
  985. NodeAbstractProperty oldProperty;
  986. Q_ASSERT(!view.isNull());
  987. if (!oldPropertyName.isEmpty() && oldParent->isValid())
  988. oldProperty = NodeAbstractProperty(oldPropertyName, oldParent, model(), view.data());
  989. if (!newPropertyParent.isNull())
  990. newProperty = NodeAbstractProperty(newPropertyParent, model(), view.data());
  991. ModelNode node(internalNodePointer, model(), view.data());
  992. view->nodeReparented(node, newProperty, oldProperty, propertyChange);
  993. }
  994. if (nodeInstanceView()) {
  995. NodeAbstractProperty newProperty;
  996. NodeAbstractProperty oldProperty;
  997. if (!oldPropertyName.isEmpty() && oldParent->isValid())
  998. oldProperty = NodeAbstractProperty(oldPropertyName, oldParent, model(), nodeInstanceView());
  999. if (!newPropertyParent.isNull())
  1000. newProperty = NodeAbstractProperty(newPropertyParent, model(), nodeInstanceView());
  1001. ModelNode node(internalNodePointer, model(), nodeInstanceView());
  1002. nodeInstanceView()->nodeReparented(node, newProperty, oldProperty, propertyChange);
  1003. }
  1004. if (resetModel) {
  1005. resetModelByRewriter(description);
  1006. }
  1007. }
  1008. void ModelPrivate::notifyNodeOrderChanged(const InternalNodeListPropertyPointer &internalListPropertyPointer,
  1009. const InternalNode::Pointer &internalNodePointer,
  1010. int oldIndex)
  1011. {
  1012. bool resetModel = false;
  1013. QString description;
  1014. try {
  1015. if (rewriterView())
  1016. rewriterView()->nodeOrderChanged(NodeListProperty(internalListPropertyPointer, model(), rewriterView()),
  1017. ModelNode(internalNodePointer, model(), rewriterView()),
  1018. oldIndex);
  1019. } catch (RewritingException &e) {
  1020. description = e.description();
  1021. resetModel = true;
  1022. }
  1023. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  1024. Q_ASSERT(!view.isNull());
  1025. view->nodeOrderChanged(NodeListProperty(internalListPropertyPointer, model(), view.data()),
  1026. ModelNode(internalNodePointer, model(), view.data()),
  1027. oldIndex);
  1028. }
  1029. if (nodeInstanceView())
  1030. nodeInstanceView()->nodeOrderChanged(NodeListProperty(internalListPropertyPointer, model(), nodeInstanceView()),
  1031. ModelNode(internalNodePointer, model(), nodeInstanceView()),
  1032. oldIndex);
  1033. if (resetModel) {
  1034. resetModelByRewriter(description);
  1035. }
  1036. }
  1037. void ModelPrivate::setSelectedNodes(const QList<InternalNode::Pointer> &selectedNodeList)
  1038. {
  1039. QList<InternalNode::Pointer> sortedSelectedList(selectedNodeList);
  1040. QMutableListIterator<InternalNode::Pointer> iterator(sortedSelectedList);
  1041. while (iterator.hasNext()) {
  1042. InternalNode::Pointer node(iterator.next());
  1043. if (!node->isValid())
  1044. iterator.remove();
  1045. }
  1046. sortedSelectedList = sortedSelectedList.toSet().toList();
  1047. qSort(sortedSelectedList);
  1048. if (sortedSelectedList == m_selectedNodeList)
  1049. return;
  1050. const QList<InternalNode::Pointer> lastSelectedNodeList = m_selectedNodeList;
  1051. m_selectedNodeList = sortedSelectedList;
  1052. changeSelectedNodes(sortedSelectedList, lastSelectedNodeList);
  1053. }
  1054. void ModelPrivate::clearSelectedNodes()
  1055. {
  1056. const QList<InternalNode::Pointer> lastSelectedNodeList = m_selectedNodeList;
  1057. m_selectedNodeList.clear();
  1058. changeSelectedNodes(m_selectedNodeList, lastSelectedNodeList);
  1059. }
  1060. QList<ModelNode> ModelPrivate::toModelNodeList(const QList<InternalNode::Pointer> &nodeList, AbstractView *view) const
  1061. {
  1062. QList<ModelNode> newNodeList;
  1063. foreach (const Internal::InternalNode::Pointer &node, nodeList)
  1064. newNodeList.append(ModelNode(node, model(), view));
  1065. return newNodeList;
  1066. }
  1067. QVector<ModelNode> ModelPrivate::toModelNodeVector(const QVector<InternalNode::Pointer> &nodeVector, AbstractView *view) const
  1068. {
  1069. QVector<ModelNode> newNodeVector;
  1070. foreach (const Internal::InternalNode::Pointer &node, nodeVector)
  1071. newNodeVector.append(ModelNode(node, model(), view));
  1072. return newNodeVector;
  1073. }
  1074. QList<Internal::InternalNode::Pointer> ModelPrivate::toInternalNodeList(const QList<ModelNode> &nodeList) const
  1075. {
  1076. QList<Internal::InternalNode::Pointer> newNodeList;
  1077. foreach (const ModelNode &node, nodeList)
  1078. newNodeList.append(node.internalNode());
  1079. return newNodeList;
  1080. }
  1081. QVector<Internal::InternalNode::Pointer> ModelPrivate::toInternalNodeVector(const QVector<ModelNode> &nodeVector) const
  1082. {
  1083. QVector<Internal::InternalNode::Pointer> newNodeVector;
  1084. foreach (const ModelNode &node, nodeVector)
  1085. newNodeVector.append(node.internalNode());
  1086. return newNodeVector;
  1087. }
  1088. void ModelPrivate::changeSelectedNodes(const QList<InternalNode::Pointer> &newSelectedNodeList,
  1089. const QList<InternalNode::Pointer> &oldSelectedNodeList)
  1090. {
  1091. foreach (const QWeakPointer<AbstractView> &view, m_viewList) {
  1092. Q_ASSERT(view != 0);
  1093. view->selectedNodesChanged(toModelNodeList(newSelectedNodeList, view.data()), toModelNodeList(oldSelectedNodeList, view.data()));
  1094. }
  1095. }
  1096. QList<InternalNode::Pointer> ModelPrivate::selectedNodes() const
  1097. {
  1098. foreach (const InternalNode::Pointer &node, m_selectedNodeList) {
  1099. if (!node->isValid())
  1100. throw new InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
  1101. }
  1102. return m_selectedNodeList;
  1103. }
  1104. void ModelPrivate::selectNode(const InternalNode::Pointer &node)
  1105. {
  1106. if (selectedNodes().contains(node))
  1107. return;
  1108. QList<InternalNode::Pointer> selectedNodeList(selectedNodes());
  1109. selectedNodeList += node;
  1110. setSelectedNodes(selectedNodeList);
  1111. }
  1112. void ModelPrivate::deselectNode(const InternalNode::Pointer &node)
  1113. {
  1114. QList<InternalNode::Pointer> selectedNodeList(selectedNodes());
  1115. bool isRemoved = selectedNodeList.removeOne(node);
  1116. if (!isRemoved)
  1117. return;
  1118. setSelectedNodes(selectedNodeList);
  1119. }
  1120. void ModelPrivate::removePropertyWithoutNotification(const InternalPropertyPointer &property)
  1121. {
  1122. if (property->isNodeAbstractProperty()) {
  1123. foreach (const InternalNode::Pointer & internalNode, property->toNodeAbstractProperty()->allSubNodes())
  1124. removeNodeFromModel(internalNode);
  1125. }
  1126. property->remove();
  1127. }
  1128. static QList<PropertyPair> toPropertyPairList(const QList<InternalProperty::Pointer> &propertyList)
  1129. {
  1130. QList<PropertyPair> propertyPairList;
  1131. foreach (const InternalProperty::Pointer &property, propertyList)
  1132. propertyPairList.append(qMakePair(property->propertyOwner(), property->name()));
  1133. return propertyPairList;
  1134. }
  1135. void ModelPrivate::removeProperty(const InternalProperty::Pointer &property)
  1136. {
  1137. notifyPropertiesAboutToBeRemoved(QList<InternalProperty::Pointer>() << property);
  1138. QList<PropertyPair> propertyPairList = toPropertyPairList(QList<InternalProperty::Pointer>() << property);
  1139. removePropertyWithoutNotification(property);
  1140. notifyPropertiesRemoved(propertyPairList);
  1141. }
  1142. void ModelPrivate::setBindingProperty(const InternalNode::Pointer &internalNode, const QString &name, const QString &expression)
  1143. {
  1144. AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges;
  1145. if (!internalNode->hasProperty(name)) {
  1146. internalNode->addBindingProperty(name);
  1147. propertyChange = AbstractView::PropertiesAdded;
  1148. }
  1149. InternalBindingProperty::Pointer bindingProperty = internalNode->bindingProperty(name);
  1150. bindingProperty->setExpression(expression);
  1151. notifyBindingPropertiesChanged(QList<InternalBindingPropertyPointer>() << bindingProperty, propertyChange);
  1152. }
  1153. void ModelPrivate::setVariantProperty(const InternalNode::Pointer &internalNode, const QString &name, const QVariant &value)
  1154. {
  1155. AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges;
  1156. if (!internalNode->hasProperty(name)) {
  1157. internalNode->addVariantProperty(name);
  1158. propertyChange = AbstractView::PropertiesAdded;
  1159. }
  1160. internalNode->variantProperty(name)->setValue(value);
  1161. internalNode->variantProperty(name)->resetDynamicTypeName();
  1162. notifyVariantPropertiesChanged(internalNode, QStringList() << name, propertyChange);
  1163. }
  1164. void ModelPrivate::setDynamicVariantProperty(const InternalNodePointer &internalNode, const QString &name, const QString &dynamicPropertyType, const QVariant &value)
  1165. {
  1166. AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges;
  1167. if (!internalNode->hasProperty(name)) {
  1168. internalNode->addVariantProperty(name);
  1169. propertyChange = AbstractView::PropertiesAdded;
  1170. }
  1171. internalNode->variantProperty(name)->setDynamicValue(dynamicPropertyType, value);
  1172. notifyVariantPropertiesChanged(internalNode, QStringList() << name, propertyChange);
  1173. }
  1174. void ModelPrivate::setDynamicBindingProperty(const InternalNodePointer &internalNode, const QString &name, const QString &dynamicPropertyType, const QString &expression)
  1175. {
  1176. AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges;
  1177. if (!internalNode->hasProperty(name)) {
  1178. internalNode->addBindingProperty(name);
  1179. propertyChange = AbstractView::PropertiesAdded;
  1180. }
  1181. InternalBindingProperty::Pointer bindingProperty = internalNode->bindingProperty(name);
  1182. bindingProperty->setDynamicExpression(dynamicPropertyType, expression);
  1183. notifyBindingPropertiesChanged(QList<InternalBindingPropertyPointer>() << bindingProperty, propertyChange);
  1184. }
  1185. void ModelPrivate::reparentNode(const InternalNode::Pointer &newParentNode, const QString &name, const InternalNode::Pointer &node, bool list)
  1186. {
  1187. AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges;
  1188. if (!newParentNode->hasProperty(name)) {
  1189. if (list)
  1190. newParentNode->addNodeListProperty(name);
  1191. else
  1192. newParentNode->addNodeProperty(name);
  1193. propertyChange |= AbstractView::PropertiesAdded;
  1194. }
  1195. InternalNodeAbstractProperty::Pointer oldParentProperty(node->parentProperty());
  1196. InternalNode::Pointer oldParentNode;
  1197. QString oldParentPropertyName;
  1198. if (oldParentProperty && oldParentProperty->isValid()) {
  1199. oldParentNode = node->parentProperty()->propertyOwner();
  1200. oldParentPropertyName = node->parentProperty()->name();
  1201. }
  1202. InternalNodeAbstractProperty::Pointer newParentProperty(newParentNode->nodeAbstractProperty(name));
  1203. Q_ASSERT(!newParentProperty.isNull());
  1204. notifyNodeAboutToBeReparent(node, newParentProperty, oldParentNode, oldParentPropertyName, propertyChange);
  1205. if (newParentProperty)
  1206. node->setParentProperty(newParentProperty);
  1207. if (oldParentProperty && oldParentProperty->isValid() && oldParentProperty->isEmpty()) {
  1208. removePropertyWithoutNotification(oldParentProperty);
  1209. propertyChange |= AbstractView::EmptyPropertiesRemoved;
  1210. }
  1211. notifyNodeReparent(node, newParentProperty, oldParentNode, oldParentPropertyName, propertyChange);
  1212. }
  1213. void ModelPrivate::clearParent(const InternalNodePointer &node)
  1214. {
  1215. InternalNodeAbstractProperty::Pointer oldParentProperty(node->parentProperty());
  1216. InternalNode::Pointer oldParentNode;
  1217. QString oldParentPropertyName;
  1218. if (oldParentProperty->isValid()) {
  1219. oldParentNode = node->parentProperty()->propertyOwner();
  1220. oldParentPropertyName = node->parentProperty()->name();
  1221. }
  1222. node->resetParentProperty();
  1223. notifyNodeReparent(node, InternalNodeAbstractProperty::Pointer(), oldParentNode, oldParentPropertyName, AbstractView::NoAdditionalChanges);
  1224. }
  1225. void ModelPrivate::changeRootNodeType(const QString &type, int majorVersion, int minorVersion)
  1226. {
  1227. Q_ASSERT(!rootNode().isNull());
  1228. rootNode()->setType(type);
  1229. rootNode()->setMajorVersion(majorVersion);
  1230. rootNode()->setMinorVersion(minorVersion);
  1231. notifyRootNodeTypeChanged(type, majorVersion, minorVersion);
  1232. }
  1233. void ModelPrivate::setScriptFunctions(const InternalNode::Pointer &internalNode, const QStringList &scriptFunctionList)
  1234. {
  1235. internalNode->setScriptFunctions(scriptFunctionList);
  1236. notifyScriptFunctionsChanged(internalNode, scriptFunctionList);
  1237. }
  1238. void ModelPrivate::setNodeSource(const InternalNodePointer &internalNode, const QString &nodeSource)
  1239. {
  1240. internalNode->setNodeSource(nodeSource);
  1241. notifyNodeSourceChanged(internalNode, nodeSource);
  1242. }
  1243. void ModelPrivate::changeNodeOrder(const InternalNode::Pointer &internalParentNode, const QString &listPropertyName, int from, int to)
  1244. {
  1245. InternalNodeListProperty::Pointer nodeList(internalParentNode->nodeListProperty(listPropertyName));
  1246. Q_ASSERT(!nodeList.isNull());
  1247. nodeList->slide(from, to);
  1248. const InternalNodePointer internalNode = nodeList->nodeList().at(to);
  1249. notifyNodeOrderChanged(nodeList, internalNode, from);
  1250. }
  1251. void ModelPrivate::setRewriterView(RewriterView *rewriterView)
  1252. {
  1253. if (rewriterView == m_rewriterView.data())
  1254. return;
  1255. Q_ASSERT(!(rewriterView && m_rewriterView));
  1256. m_rewriterView = rewriterView;
  1257. if (rewriterView)
  1258. rewriterView->modelAttached(model());
  1259. else if (m_rewriterView)
  1260. m_rewriterView->modelAboutToBeDetached(model());
  1261. }
  1262. RewriterView *ModelPrivate::rewriterView() const
  1263. {
  1264. return m_rewriterView.data();
  1265. }
  1266. void ModelPrivate::setNodeInstanceView(NodeInstanceView *nodeInstanceView)
  1267. {
  1268. if (nodeInstanceView == m_nodeInstanceView.data())
  1269. return;
  1270. if (m_nodeInstanceView)
  1271. m_nodeInstanceView->modelAboutToBeDetached(m_q);
  1272. m_nodeInstanceView = nodeInstanceView;
  1273. if (nodeInstanceView)
  1274. nodeInstanceView->modelAttached(m_q);
  1275. }
  1276. NodeInstanceView *ModelPrivate::nodeInstanceView() const
  1277. {
  1278. return m_nodeInstanceView.data();
  1279. }
  1280. InternalNodePointer ModelPrivate::nodeForId(const QString &id) const
  1281. {
  1282. return m_idNodeHash.value(id);
  1283. }
  1284. bool ModelPrivate::hasId(const QString &id) const
  1285. {
  1286. return m_idNodeHash.contains(id);
  1287. }
  1288. InternalNodePointer ModelPrivate::nodeForInternalId(qint32 internalId) const
  1289. {
  1290. return m_internalIdNodeHash.value(internalId);
  1291. }
  1292. bool ModelPrivate::hasNodeForInternalId(qint32 internalId) const
  1293. {
  1294. return m_internalIdNodeHash.contains(internalId);
  1295. }
  1296. QList<InternalNodePointer> ModelPrivate::allNodes() const
  1297. {
  1298. // the item must be ordered!
  1299. QList<InternalNodePointer> nodeList;
  1300. if (m_rootInternalNode.isNull() || !m_rootInternalNode->isValid())
  1301. return nodeList;
  1302. nodeList.append(m_rootInternalNode);
  1303. nodeList.append(m_rootInternalNode->allSubNodes());
  1304. nodeList.append((m_nodeSet - nodeList.toSet()).toList());
  1305. return nodeList;
  1306. }
  1307. bool ModelPrivate::isWriteLocked() const
  1308. {
  1309. return m_writeLock;
  1310. }
  1311. InternalNode::Pointer ModelPrivate::actualStateNode() const
  1312. {
  1313. return m_acutalStateNode;
  1314. }
  1315. WriteLocker::WriteLocker(ModelPrivate *model)
  1316. : m_model(model)
  1317. {
  1318. Q_ASSERT(model);
  1319. if (m_model->m_writeLock)
  1320. qWarning() << "QmlDesigner: Misbehaving view calls back to model!!!";
  1321. // FIXME: Enable it again
  1322. Q_ASSERT(!m_model->m_writeLock);
  1323. model->m_writeLock = true;
  1324. }
  1325. WriteLocker::WriteLocker(Model *model)
  1326. : m_model(model->d)
  1327. {
  1328. Q_ASSERT(model->d);
  1329. if (m_model->m_writeLock)
  1330. qWarning() << "QmlDesigner: Misbehaving view calls back to model!!!";
  1331. // FIXME: Enable it again
  1332. Q_ASSERT(!m_model->m_writeLock);
  1333. m_model->m_writeLock = true;
  1334. }
  1335. WriteLocker::~WriteLocker()
  1336. {
  1337. if (!m_model->m_writeLock)
  1338. qWarning() << "QmlDesigner: Misbehaving view calls back to model!!!";
  1339. // FIXME: Enable it again
  1340. Q_ASSERT(m_model->m_writeLock);
  1341. m_model->m_writeLock = false;
  1342. }
  1343. //static QString anchorLinePropertyValue(const InternalNode::Pointer &sourceNode, const InternalNode::Pointer &targetNode, const AnchorLine::Type &targetType)
  1344. //{
  1345. // if (targetNode.isNull() || !targetNode->isValid())
  1346. // return QString();
  1347. //
  1348. // if (sourceNode.isNull() || !sourceNode->isValid())
  1349. // return QString();
  1350. //
  1351. // if (targetNode == sourceNode)
  1352. // return QString();
  1353. //
  1354. // QString anchorLineType = InternalNodeAnchors::lineTypeToString(targetType);
  1355. //
  1356. // // handle "parent" and "parent.something"
  1357. // if (targetNode == sourceNode->parentNode()) {
  1358. // if (anchorLineType.isNull())
  1359. // return QLatin1String("parent");
  1360. // else
  1361. // return QString("parent.%1").arg(anchorLineType);
  1362. // }
  1363. //
  1364. // if (anchorLineType.isNull())
  1365. // return QString(); // for sibling reference, the type cannot be empty anymore.
  1366. //
  1367. // foreach (const InternalNode::Pointer &sibling, sourceNode->parentNode()->childNodes()) {
  1368. // if (sibling == targetNode) {
  1369. // return QString("%1.%2").arg(sibling->id(), anchorLineType);
  1370. // }
  1371. // }
  1372. //
  1373. // return QString();
  1374. //}
  1375. }
  1376. Model::Model() :
  1377. QObject(),
  1378. d(new Internal::ModelPrivate(this))
  1379. {
  1380. }
  1381. Model::~Model()
  1382. {
  1383. delete d;
  1384. }
  1385. Model *Model::create(QString type, int major, int minor, Model *metaInfoPropxyModel)
  1386. {
  1387. return Internal::ModelPrivate::create(type, major, minor, metaInfoPropxyModel);
  1388. }
  1389. /*!
  1390. \brief Creates a model for a component definition
  1391. Creates a model containing the content of a component node. The component node itself is
  1392. not part of the newly created model; it's the first item defined after "Component {"
  1393. that is the root node.
  1394. \arg componentNode must be valid & of type "Qt/Component"
  1395. \return the newly created model. The caller takes ownership of the object life time.
  1396. */
  1397. //Model *Model::createComponentModel(const ModelNode &componentNode)
  1398. //{
  1399. //
  1400. // if (!componentNode.isValid() || componentNode.type() != "Qt/Component") {
  1401. // throw new InvalidArgumentException(__LINE__, __FUNCTION__, __FILE__, QString("componentNode"));
  1402. // }
  1403. //
  1404. // // the data property does not include the Component element itself
  1405. // const TextLocation componentRootLocation
  1406. // = componentNode.baseNodeState().m_internalNodeState->propertyLocation("data");
  1407. //
  1408. // TextModifier *textModifier
  1409. // = new Internal::ComponentTextModifier(d->m_rewriter->textModifier(),
  1410. // componentRootLocation,
  1411. // d->m_rootInternalNode->baseNodeState()->location());
  1412. //
  1413. // QList<QDeclarativeError> errors;
  1414. // Model *subModel = create(textModifier, d->m_fileUrl, &errors);
  1415. //
  1416. // Q_ASSERT(subModel);
  1417. // Q_ASSERT(errors.size() == 0); // should never happen, after all it was already compiled!
  1418. //
  1419. // textModifier->setParent(subModel);
  1420. //
  1421. // return subModel;
  1422. //}
  1423. QList<Import> Model::imports() const
  1424. {
  1425. return d->imports();
  1426. }
  1427. void Model::changeImports(const QList<Import> &importsToBeAdded, const QList<Import> &importsToBeRemoved)
  1428. {
  1429. d->changeImports(importsToBeAdded, importsToBeRemoved);
  1430. }
  1431. static bool compareVersions(const QString &version1, const QString &version2, bool allowHigherVersion)
  1432. {
  1433. if (version1 == version2)
  1434. return true;
  1435. if (!allowHigherVersion)
  1436. return false;
  1437. QStringList version1List = version1.split('.');
  1438. QStringList version2List = version2.split('.');
  1439. if (version1List.count() == 2 && version2List.count() == 2) {
  1440. bool ok;
  1441. int major1 = version1List.first().toInt(&ok);
  1442. if (!ok)
  1443. return false;
  1444. int major2 = version2List.first().toInt(&ok);
  1445. if (!ok)
  1446. return false;
  1447. if (major1 >= major2) {
  1448. int minor1 = version1List.last().toInt(&ok);
  1449. if (!ok)
  1450. return false;
  1451. int minor2 = version2List.last().toInt(&ok);
  1452. if (!ok)
  1453. return false;
  1454. if (minor1 >= minor2)
  1455. return true;
  1456. }
  1457. }
  1458. return false;
  1459. }
  1460. bool Model::hasImport(const Import &import, bool ignoreAlias, bool allowHigherVersion)
  1461. {
  1462. if (imports().contains(import))
  1463. return true;
  1464. if (!ignoreAlias)
  1465. return false;
  1466. foreach (const Import &existingImport, imports()) {
  1467. if (existingImport.isFileImport() && import.isFileImport())
  1468. if (existingImport.file() == import.file() && compareVersions(existingImport.version(), import.version(), allowHigherVersion))
  1469. return true;
  1470. if (existingImport.isLibraryImport() && import.isLibraryImport())
  1471. if (existingImport.url() == import.url() && compareVersions(existingImport.version(), import.version(), allowHigherVersion))
  1472. return true;
  1473. }
  1474. return false;
  1475. }
  1476. RewriterView *Model::rewriterView() const
  1477. {
  1478. return d->rewriterView();
  1479. }
  1480. /*!
  1481. \brief Returns the model that is used for metainfo
  1482. \return Return itself if not other metaInfoProxyModel does exist
  1483. */
  1484. Model *Model::metaInfoProxyModel()
  1485. {
  1486. if (d->m_metaInfoProxyModel)
  1487. return d->m_metaInfoProxyModel->metaInfoProxyModel();
  1488. else
  1489. return this;
  1490. }
  1491. #if 0
  1492. /*!
  1493. \brief Creates a new empty model
  1494. \param uiFilePath path to the ui file
  1495. \param[out] errorMessage returns a error message
  1496. \return new created model
  1497. */
  1498. Model *Model::create(const QString &rootType)
  1499. {
  1500. return Internal::ModelPrivate::create(rootType);
  1501. }
  1502. #endif
  1503. Model *Model::masterModel() const
  1504. {
  1505. return d->m_masterModel.data();
  1506. }
  1507. void Model::setMasterModel(Model *model)
  1508. {
  1509. d->m_masterModel = model;
  1510. }
  1511. /*!
  1512. \brief Returns the URL against which relative URLs within the model should be resolved.
  1513. \return The base URL.
  1514. */
  1515. QUrl Model::fileUrl() const
  1516. {
  1517. return d->fileUrl();
  1518. }
  1519. /*!
  1520. \brief Sets the URL against which relative URLs within the model should be resolved.
  1521. \param url the base URL, i.e. the qml file path.
  1522. */
  1523. void Model::setFileUrl(const QUrl &url)
  1524. {
  1525. Internal::WriteLocker locker(d);
  1526. d->setFileUrl(url);
  1527. }
  1528. /*!
  1529. \brief Returns list of QML types available within the model.
  1530. */
  1531. const MetaInfo Model::metaInfo() const
  1532. {
  1533. return d->metaInfo();
  1534. }
  1535. bool Model::hasNodeMetaInfo(const QString &typeName, int majorVersion, int minorVersion)
  1536. {
  1537. return NodeMetaInfo(metaInfoProxyModel(), typeName, majorVersion, minorVersion).isValid();
  1538. }
  1539. NodeMetaInfo Model::metaInfo(const QString &typeName, int majorVersion, int minorVersion)
  1540. {
  1541. return NodeMetaInfo(metaInfoProxyModel(), typeName, majorVersion, minorVersion);
  1542. }
  1543. /*!
  1544. \brief Returns list of QML types available within the model.
  1545. */
  1546. MetaInfo Model::metaInfo()
  1547. {
  1548. return d->metaInfo();
  1549. }
  1550. /*! \name Undo Redo Interface
  1551. here you can find a facade to the internal undo redo framework
  1552. */
  1553. /*! \name View related functions
  1554. */
  1555. //\{
  1556. /*!
  1557. \brief Attaches a view to the model
  1558. Registers a "view" that from then on will be informed about changes to the model. Different views
  1559. will always be informed in the order in which they registered to the model.
  1560. The view is informed that it has been registered within the model by a call to AbstractView::modelAttached .
  1561. \param view The view object to register. Must be not null.
  1562. \see detachView
  1563. */
  1564. void Model::attachView(AbstractView *view)
  1565. {
  1566. // Internal::WriteLocker locker(d);
  1567. RewriterView *rewriterView = qobject_cast<RewriterView*>(view);
  1568. if (rewriterView) {
  1569. d->setRewriterView(rewriterView);
  1570. return;
  1571. }
  1572. NodeInstanceView *nodeInstanceView = qobject_cast<NodeInstanceView*>(view);
  1573. if (nodeInstanceView) {
  1574. d->setNodeInstanceView(nodeInstanceView);
  1575. return;
  1576. }
  1577. d->attachView(view);
  1578. }
  1579. /*!
  1580. \brief Detaches a view to the model
  1581. \param view The view to unregister. Must be not null.
  1582. \param emitDetachNotify If set to NotifyView (the default), AbstractView::modelAboutToBeDetached() will be called
  1583. \see attachView
  1584. */
  1585. void Model::detachView(AbstractView *view, ViewNotification emitDetachNotify)
  1586. {
  1587. // Internal::WriteLocker locker(d);
  1588. bool emitNotify = (emitDetachNotify == NotifyView);
  1589. RewriterView *rewriterView = qobject_cast<RewriterView*>(view);
  1590. if (rewriterView) {
  1591. d->setRewriterView(0);
  1592. return;
  1593. }
  1594. NodeInstanceView *nodeInstanceView = qobject_cast<NodeInstanceView*>(view);
  1595. if (nodeInstanceView) {
  1596. d->setNodeInstanceView(0);
  1597. return;
  1598. }
  1599. d->detachView(view, emitNotify);
  1600. }
  1601. }