OSDN Git Service

Update license.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / qmldesigner / designercore / instances / nodeinstanceserver.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2009 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 qt-info@nokia.com.
30 **
31 **************************************************************************/
32
33 #include "nodeinstanceserver.h"
34
35 #include <QGraphicsItem>
36 #include <private/qgraphicsitem_p.h>
37 #include <private/qgraphicsscene_p.h>
38 #include <QDeclarativeEngine>
39 #include <QDeclarativeView>
40 #include <QFileSystemWatcher>
41 #include <QUrl>
42 #include <QSet>
43 #include <QDir>
44 #include <QVariant>
45 #include <QMetaType>
46 #include <QDeclarativeComponent>
47 #include <QDeclarativeContext>
48 #include <private/qlistmodelinterface_p.h>
49 #include <QAbstractAnimation>
50 #include <private/qabstractanimation_p.h>
51
52 #include "servernodeinstance.h"
53 #include "childrenchangeeventfilter.h"
54 #include "propertyabstractcontainer.h"
55 #include "propertybindingcontainer.h"
56 #include "propertyvaluecontainer.h"
57 #include "instancecontainer.h"
58 #include "createinstancescommand.h"
59 #include "changefileurlcommand.h"
60 #include "clearscenecommand.h"
61 #include "reparentinstancescommand.h"
62 #include "changevaluescommand.h"
63 #include "changebindingscommand.h"
64 #include "changeidscommand.h"
65 #include "removeinstancescommand.h"
66 #include "nodeinstanceclientinterface.h"
67 #include "removepropertiescommand.h"
68 #include "valueschangedcommand.h"
69 #include "informationchangedcommand.h"
70 #include "pixmapchangedcommand.h"
71 #include "commondefines.h"
72 #include "childrenchangeeventfilter.h"
73 #include "changestatecommand.h"
74 #include "addimportcommand.h"
75 #include "childrenchangedcommand.h"
76 #include "completecomponentcommand.h"
77 #include "componentcompletedcommand.h"
78 #include "createscenecommand.h"
79
80 #include "dummycontextobject.h"
81
82 #include <iostream>
83 #include <stdio.h>
84
85
86 namespace QmlDesigner {
87
88 NodeInstanceServer::NodeInstanceServer(NodeInstanceClientInterface *nodeInstanceClient) :
89     NodeInstanceServerInterface(),
90     m_childrenChangeEventFilter(new Internal::ChildrenChangeEventFilter(this)),
91     m_nodeInstanceClient(nodeInstanceClient),
92     m_timer(0),
93     m_renderTimerInterval(16),
94     m_slowRenderTimer(false),
95     m_slowRenderTimerInterval(200)
96 {
97     qmlRegisterType<DummyContextObject>("QmlDesigner", 1, 0, "DummyContextObject");
98
99     m_importList.append("import Qt 4.7\n");
100     connect(m_childrenChangeEventFilter.data(), SIGNAL(childrenChanged(QObject*)), this, SLOT(emitParentChanged(QObject*)));
101 }
102
103 NodeInstanceServer::~NodeInstanceServer()
104 {
105     delete m_declarativeView.data();
106 }
107
108 QList<ServerNodeInstance>  NodeInstanceServer::createInstances(const QVector<InstanceContainer> &containerVector)
109 {
110     Q_ASSERT(m_declarativeView);
111     QList<ServerNodeInstance> instanceList;
112     foreach(const InstanceContainer &instanceContainer, containerVector) {
113         ServerNodeInstance instance = ServerNodeInstance::create(this, instanceContainer);
114         insertInstanceRelationship(instance);
115         instanceList.append(instance);
116         instance.internalObject()->installEventFilter(childrenChangeEventFilter());
117         if (instanceContainer.instanceId() == 0) {
118             m_rootNodeInstance = instance;
119             QGraphicsObject *rootGraphicsObject = qobject_cast<QGraphicsObject*>(instance.internalObject());
120             if (rootGraphicsObject) {
121                 m_declarativeView->scene()->addItem(rootGraphicsObject);
122                 m_declarativeView->setSceneRect(rootGraphicsObject->boundingRect());
123             }
124
125         }
126
127         foreach (QDeclarativeContext* context, allSubContextsForObject(instance.internalObject()))
128             setupDummysForContext(context);
129     }
130
131     return instanceList;
132 }
133
134 void NodeInstanceServer::createInstances(const CreateInstancesCommand &command)
135 {
136     createInstances(command.instances());
137     refreshBindings();
138     startRenderTimer();
139 }
140
141 ServerNodeInstance NodeInstanceServer::instanceForId(qint32 id) const
142 {
143     if (id < 0)
144         return ServerNodeInstance();
145
146     Q_ASSERT(m_idInstanceHash.contains(id));
147     return m_idInstanceHash.value(id);
148 }
149
150 bool NodeInstanceServer::hasInstanceForId(qint32 id) const
151 {
152     if (id < 0)
153         return false;
154
155     return m_idInstanceHash.contains(id);
156 }
157
158 ServerNodeInstance NodeInstanceServer::instanceForObject(QObject *object) const
159 {
160     Q_ASSERT(m_objectInstanceHash.contains(object));
161     return m_objectInstanceHash.value(object);
162 }
163
164 bool NodeInstanceServer::hasInstanceForObject(QObject *object) const
165 {
166     if (object == 0)
167         return false;
168
169     return m_objectInstanceHash.contains(object);
170 }
171
172 void NodeInstanceServer::setRenderTimerInterval(int timerInterval)
173 {
174     m_renderTimerInterval = timerInterval;
175 }
176
177 void NodeInstanceServer::setSlowRenderTimerInterval(int timerInterval)
178 {
179     m_slowRenderTimerInterval = timerInterval;
180 }
181
182 void NodeInstanceServer::setTimerId(int timerId)
183 {
184     m_timer = timerId;
185 }
186
187 int NodeInstanceServer::timerId() const
188 {
189     return m_timer;
190 }
191
192 int NodeInstanceServer::renderTimerInterval() const
193 {
194     return m_renderTimerInterval;
195 }
196
197 void NodeInstanceServer::startRenderTimer()
198 {
199     if (m_slowRenderTimer)
200         stopRenderTimer();
201
202     if (m_timer == 0)
203         m_timer = startTimer(m_renderTimerInterval);
204
205     m_slowRenderTimer = false;
206 }
207
208 void NodeInstanceServer::slowDownRenderTimer()
209 {
210     if (!m_slowRenderTimer)
211         stopRenderTimer();
212
213     if (m_timer != 0) {
214         killTimer(m_timer);
215         m_timer = 0;
216     }
217
218     if (m_timer == 0)
219         m_timer = startTimer(m_slowRenderTimerInterval);
220
221     m_slowRenderTimer = true;
222 }
223
224 void NodeInstanceServer::stopRenderTimer()
225 {
226     if (m_timer) {
227         killTimer(m_timer);
228         m_timer = 0;
229     }
230 }
231
232 void NodeInstanceServer::createScene(const CreateSceneCommand &command)
233 {
234     initializeDeclarativeView();
235     QList<ServerNodeInstance> instanceList = setupScene(command);
236
237     refreshBindings();
238
239     nodeInstanceClient()->informationChanged(createAllInformationChangedCommand(instanceList, true));
240     nodeInstanceClient()->valuesChanged(createValuesChangedCommand(instanceList));
241     sendChildrenChangedCommand(instanceList);
242     nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand(instanceList));
243     nodeInstanceClient()->componentCompleted(createComponentCompletedCommand(instanceList));
244
245     startRenderTimer();
246 }
247
248 void NodeInstanceServer::clearScene(const ClearSceneCommand &/*command*/)
249 {
250     stopRenderTimer();
251
252     removeAllInstanceRelationships();
253     m_fileSystemWatcherHash.clear();
254     m_rootNodeInstance.makeInvalid();
255     m_changedPropertyList.clear();
256     m_fileUrl.clear();
257
258     delete m_declarativeView.data();
259 }
260
261 void NodeInstanceServer::removeInstances(const RemoveInstancesCommand &command)
262 {
263     ServerNodeInstance oldState = activeStateInstance();
264     if (activeStateInstance().isValid())
265         activeStateInstance().deactivateState();
266
267     foreach(qint32 instanceId, command.instanceIds()) {
268         removeInstanceRelationsip(instanceId);
269     }
270
271     if (oldState.isValid())
272         oldState.activateState();
273
274     refreshBindings();
275     startRenderTimer();
276 }
277
278 void NodeInstanceServer::removeProperties(const RemovePropertiesCommand &command)
279 {
280     bool hasDynamicProperties = false;
281     foreach(const PropertyAbstractContainer &container, command.properties()) {
282         hasDynamicProperties |= container.isDynamic();
283         resetInstanceProperty(container);
284     }
285
286     if (hasDynamicProperties)
287         refreshBindings();
288
289     startRenderTimer();
290 }
291
292 void NodeInstanceServer::reparentInstances(const QVector<ReparentContainer> &containerVector)
293 {
294     foreach(const ReparentContainer &container, containerVector) {
295         ServerNodeInstance instance = instanceForId(container.instanceId());
296         if (instance.isValid()) {
297             instance.reparent(instanceForId(container.oldParentInstanceId()), container.oldParentProperty(), instanceForId(container.newParentInstanceId()), container.newParentProperty());
298         }
299     }
300
301 }
302
303 void NodeInstanceServer::reparentInstances(const ReparentInstancesCommand &command)
304 {
305     reparentInstances(command.reparentInstances());
306     refreshBindings();
307     startRenderTimer();
308 }
309
310 void NodeInstanceServer::changeState(const ChangeStateCommand &command)
311 {
312     if (hasInstanceForId(command.stateInstanceId())) {
313         if (activeStateInstance().isValid())
314             activeStateInstance().deactivateState();
315         ServerNodeInstance instance = instanceForId(command.stateInstanceId());
316         instance.activateState();
317     } else {
318         if (activeStateInstance().isValid())
319             activeStateInstance().deactivateState();
320     }
321
322     startRenderTimer();
323 }
324
325 void NodeInstanceServer::completeComponent(const CompleteComponentCommand &command)
326 {
327     QList<ServerNodeInstance> instanceList;
328
329     foreach(qint32 instanceId, command.instances()) {
330         if (hasInstanceForId(instanceId)) {
331             ServerNodeInstance instance = instanceForId(instanceId);
332             instance.doComponentComplete();
333             instanceList.append(instance);
334         }
335     }
336
337     m_completedComponentList.append(instanceList);
338     refreshBindings();
339
340     nodeInstanceClient()->valuesChanged(createValuesChangedCommand(instanceList));
341     nodeInstanceClient()->informationChanged(createAllInformationChangedCommand(instanceList, true));
342     nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand(instanceList));
343
344     startRenderTimer();
345 }
346
347 void NodeInstanceServer::addImports(const QVector<AddImportContainer> &containerVector)
348 {
349     foreach (const AddImportContainer &container, containerVector) {
350         QString importStatement = QString("import ");
351
352         if (!container.fileName().isEmpty())
353             importStatement += '"' + container.fileName() + '"';
354         else if (!container.url().isEmpty())
355             importStatement += container.url().toString();
356
357         if (!container.version().isEmpty())
358             importStatement += ' ' + container.version();
359
360         if (!container.alias().isEmpty())
361             importStatement += " as " + container.alias();
362
363         importStatement.append('\n');
364
365         if (!m_importList.contains(importStatement))
366             m_importList.append(importStatement);
367     }
368
369     delete m_importComponent.data();
370     delete m_importComponentObject.data();
371
372     m_importComponent = new QDeclarativeComponent(engine(), 0);
373     QString componentString;
374     foreach(const QString &importStatement, m_importList)
375         componentString += QString("%1").arg(importStatement);
376
377     componentString += QString("Item {}\n");
378
379     m_importComponent->setData(componentString.toUtf8(), fileUrl());
380     m_importComponentObject = m_importComponent->create();
381
382     if (!m_importComponent->errorString().isEmpty())
383         qDebug() << "QmlDesigner.NodeInstances: import wrong: " << m_importComponent->errorString();
384 }
385
386 void NodeInstanceServer::addImport(const AddImportCommand &command)
387 {
388     addImports(QVector<AddImportContainer>() << command.import());
389 }
390
391 void NodeInstanceServer::changeFileUrl(const ChangeFileUrlCommand &command)
392 {
393     m_fileUrl = command.fileUrl();
394
395     if (engine())
396         engine()->setBaseUrl(m_fileUrl);
397
398     refreshBindings();
399     startRenderTimer();
400 }
401
402 void NodeInstanceServer::changePropertyValues(const ChangeValuesCommand &command)
403 {
404     bool hasDynamicProperties = false;
405     foreach(const PropertyValueContainer &container, command.valueChanges()) {
406         hasDynamicProperties |= container.isDynamic();
407         setInstancePropertyVariant(container);
408     }
409
410     if (hasDynamicProperties)
411         refreshBindings();
412
413     startRenderTimer();
414 }
415
416
417 void NodeInstanceServer::changePropertyBindings(const ChangeBindingsCommand &command)
418 {
419     bool hasDynamicProperties = false;
420     foreach(const PropertyBindingContainer &container, command.bindingChanges()) {
421         hasDynamicProperties |= container.isDynamic();
422         setInstancePropertyBinding(container);
423     }
424
425     if (hasDynamicProperties)
426         refreshBindings();
427
428     startRenderTimer();
429 }
430
431 void NodeInstanceServer::changeIds(const ChangeIdsCommand &command)
432 {
433     foreach(const IdContainer &container, command.ids()) {
434         if (hasInstanceForId(container.instanceId()))
435             instanceForId(container.instanceId()).setId(container.id());
436     }
437
438     refreshBindings();
439     startRenderTimer();
440 }
441
442 QDeclarativeEngine *NodeInstanceServer::engine() const
443 {
444     if (m_declarativeView)
445         return m_declarativeView->engine();
446
447     return 0;
448 }
449
450 QDeclarativeContext *NodeInstanceServer::context() const
451 {
452     if (m_importComponentObject) {
453         QDeclarativeContext *importComponentContext = QDeclarativeEngine::contextForObject(m_importComponentObject.data());
454         if (importComponentContext) // this should be the default
455             return importComponentContext;
456     }
457
458     if (engine())
459         return engine()->rootContext();
460
461     return 0;
462 }
463
464 QDeclarativeView *NodeInstanceServer::delcarativeView() const
465 {
466     return m_declarativeView.data();
467 }
468
469 const QVector<NodeInstanceServer::InstancePropertyPair> NodeInstanceServer::changedPropertyList() const
470 {
471     return m_changedPropertyList;
472 }
473
474 void NodeInstanceServer::clearChangedPropertyList()
475 {
476     m_changedPropertyList.clear();
477 }
478
479 void NodeInstanceServer::setupDummysForContext(QDeclarativeContext *context)
480 {
481     foreach (const DummyPair& dummyPair, m_dummyObjectList) {
482         if (dummyPair.second) {
483             context->setContextProperty(dummyPair.first, dummyPair.second.data());
484         }
485     }
486 }
487
488
489 QList<QDeclarativeContext*> NodeInstanceServer::allSubContextsForObject(QObject *object)
490 {
491     QList<QDeclarativeContext*> contextList;
492
493     if (object) {
494         foreach (QObject *subObject, allSubObjectsForObject(object)) {
495             QDeclarativeContext *contextOfObject = QDeclarativeEngine::contextForObject(subObject);
496             if (contextOfObject) {
497                 if (contextOfObject != context() && !contextList.contains(contextOfObject))
498                     contextList.append(contextOfObject);
499             }
500         }
501     }
502
503     return contextList;
504 }
505
506 QList<QObject*> NodeInstanceServer::allSubObjectsForObject(QObject *object)
507 {
508     QList<QObject*> subChildren;
509     if (object) {
510         subChildren = object->findChildren<QObject*>();
511     }
512
513     return subChildren;
514 }
515
516 void NodeInstanceServer::refreshBindings()
517 {
518     static int counter = 0;
519     engine()->rootContext()->setContextProperty(QString("__%1").arg(counter++), 0); // refreshing bindings
520 }
521
522 void NodeInstanceServer::removeAllInstanceRelationships()
523 {
524     // prevent destroyed() signals calling back
525
526     foreach (ServerNodeInstance instance, m_objectInstanceHash.values()) {
527         if (instance.isValid())
528             instance.setId(QString());
529     }
530
531     //first  the root object
532     if (rootNodeInstance().internalObject())
533         rootNodeInstance().internalObject()->disconnect();
534
535     rootNodeInstance().makeInvalid();
536
537
538     foreach (ServerNodeInstance instance, m_objectInstanceHash.values()) {
539         if (instance.internalObject())
540             instance.internalObject()->disconnect();
541         instance.makeInvalid();
542     }
543
544     m_idInstanceHash.clear();
545     m_objectInstanceHash.clear();
546 }
547
548 QFileSystemWatcher *NodeInstanceServer::dummydataFileSystemWatcher()
549 {
550     if (m_dummdataFileSystemWatcher.isNull()) {
551         m_dummdataFileSystemWatcher = new QFileSystemWatcher(this);
552         connect(m_dummdataFileSystemWatcher.data(), SIGNAL(fileChanged(QString)), this, SLOT(refreshDummyData(QString)));
553     }
554
555     return m_dummdataFileSystemWatcher.data();
556 }
557
558 QFileSystemWatcher *NodeInstanceServer::fileSystemWatcher()
559 {
560     if (m_fileSystemWatcher.isNull()) {
561         m_fileSystemWatcher = new QFileSystemWatcher(this);
562         connect(m_fileSystemWatcher.data(), SIGNAL(fileChanged(QString)), this, SLOT(refreshLocalFileProperty(QString)));
563     }
564
565     return m_fileSystemWatcher.data();
566 }
567
568 Internal::ChildrenChangeEventFilter *NodeInstanceServer::childrenChangeEventFilter() const
569 {
570     return m_childrenChangeEventFilter.data();
571 }
572
573 void NodeInstanceServer::addFilePropertyToFileSystemWatcher(QObject *object, const QString &propertyName, const QString &path)
574 {
575     if (!m_fileSystemWatcherHash.contains(path)) {
576         m_fileSystemWatcherHash.insert(path, ObjectPropertyPair(object, propertyName));
577         fileSystemWatcher()->addPath(path);
578     }
579 }
580
581 void NodeInstanceServer::removeFilePropertyFromFileSystemWatcher(QObject *object, const QString &propertyName, const QString &path)
582 {
583     if (m_fileSystemWatcherHash.contains(path)) {
584         fileSystemWatcher()->removePath(path);
585         m_fileSystemWatcherHash.remove(path, ObjectPropertyPair(object, propertyName));
586     }
587 }
588
589 void NodeInstanceServer::refreshLocalFileProperty(const QString &path)
590 {
591     if (m_fileSystemWatcherHash.contains(path)) {
592         QList<ObjectPropertyPair> objectPropertyPairList = m_fileSystemWatcherHash.values();
593         foreach(const ObjectPropertyPair &objectPropertyPair, objectPropertyPairList) {
594             QObject *object = objectPropertyPair.first.data();
595             QString propertyName = objectPropertyPair.second;
596
597             if (hasInstanceForObject(object)) {
598                 instanceForObject(object).refreshProperty(propertyName);
599             }
600         }
601     }
602 }
603
604 void NodeInstanceServer::refreshDummyData(const QString &path)
605 {
606     engine()->clearComponentCache();
607     QFileInfo filePath(path);
608     if (filePath.completeBaseName().contains("_dummycontext")) {
609         loadDummyContextObjectFile(filePath);
610     } else {
611         loadDummyDataFile(filePath);
612     }
613
614     refreshBindings();
615     startRenderTimer();
616 }
617
618 void NodeInstanceServer::addChangedProperty(const InstancePropertyPair &property)
619 {
620     if (!m_changedPropertyList.contains(property))
621         m_changedPropertyList.append(property);
622 }
623
624 void NodeInstanceServer::emitParentChanged(QObject *child)
625 {
626     if (hasInstanceForObject(child)) {
627         addChangedProperty(InstancePropertyPair(instanceForObject(child), "parent"));
628     }
629 }
630
631 Internal::ChildrenChangeEventFilter *NodeInstanceServer::childrenChangeEventFilter()
632 {
633     if (m_childrenChangeEventFilter.isNull()) {
634         m_childrenChangeEventFilter = new Internal::ChildrenChangeEventFilter(this);
635         connect(m_childrenChangeEventFilter.data(), SIGNAL(childrenChanged(QObject*)), this, SLOT(emitParentChanged(QObject*)));
636     }
637
638     return m_childrenChangeEventFilter.data();
639 }
640
641 void NodeInstanceServer::resetInstanceProperty(const PropertyAbstractContainer &propertyContainer)
642 {
643     if (hasInstanceForId(propertyContainer.instanceId())) { // TODO ugly workaround
644         ServerNodeInstance instance = instanceForId(propertyContainer.instanceId());
645         Q_ASSERT(instance.isValid());
646
647         const QString name = propertyContainer.name();
648
649         if (activeStateInstance().isValid() && !instance.isSubclassOf("QtQuick/PropertyChanges")) {
650             bool statePropertyWasReseted = activeStateInstance().resetStateProperty(instance, name, instance.resetVariant(name));
651             if (!statePropertyWasReseted)
652                 instance.resetProperty(name);
653         } else {
654             instance.resetProperty(name);
655         }
656     }
657 }
658
659
660 void NodeInstanceServer::setInstancePropertyBinding(const PropertyBindingContainer &bindingContainer)
661 {
662     if (hasInstanceForId(bindingContainer.instanceId())) {
663         ServerNodeInstance instance = instanceForId(bindingContainer.instanceId());
664
665         const QString name = bindingContainer.name();
666         const QString expression = bindingContainer.expression();
667
668
669         if (activeStateInstance().isValid() && !instance.isSubclassOf("QtQuick/PropertyChanges")) {
670             bool stateBindingWasUpdated = activeStateInstance().updateStateBinding(instance, name, expression);
671             if (!stateBindingWasUpdated) {
672                 if (bindingContainer.isDynamic())
673                     instance.setPropertyDynamicBinding(name, bindingContainer.dynamicTypeName(), expression);
674                 else
675                     instance.setPropertyBinding(name, expression);
676             }
677         } else {
678             if (bindingContainer.isDynamic())
679                 instance.setPropertyDynamicBinding(name, bindingContainer.dynamicTypeName(), expression);
680             else
681                 instance.setPropertyBinding(name, expression);
682         }
683     }
684 }
685
686
687 void NodeInstanceServer::removeProperties(const QList<PropertyAbstractContainer> &propertyList)
688 {
689     foreach (const PropertyAbstractContainer &property, propertyList)
690         resetInstanceProperty(property);
691 }
692
693 void NodeInstanceServer::setInstancePropertyVariant(const PropertyValueContainer &valueContainer)
694 {
695     if (hasInstanceForId(valueContainer.instanceId())) {
696         ServerNodeInstance instance = instanceForId(valueContainer.instanceId());
697
698
699         const QString name = valueContainer.name();
700         const QVariant value = valueContainer.value();
701
702
703         if (activeStateInstance().isValid() && !instance.isSubclassOf("QtQuick/PropertyChanges")) {
704             bool stateValueWasUpdated = activeStateInstance().updateStateVariant(instance, name, value);
705             if (!stateValueWasUpdated) {
706                 if (valueContainer.isDynamic())
707                     instance.setPropertyDynamicVariant(name, valueContainer.dynamicTypeName(), value);
708                 else
709                     instance.setPropertyVariant(name, value);
710             }
711         } else { //base state
712             if (valueContainer.isDynamic())
713                 instance.setPropertyDynamicVariant(name, valueContainer.dynamicTypeName(), value);
714             else
715                 instance.setPropertyVariant(name, value);
716         }
717
718 //        instance.paintUpdate();
719     }
720 }
721
722
723 QUrl NodeInstanceServer::fileUrl() const
724 {
725     return m_fileUrl;
726 }
727
728 ServerNodeInstance NodeInstanceServer::activeStateInstance() const
729 {
730     return m_activeStateInstance;
731 }
732
733 ServerNodeInstance NodeInstanceServer::rootNodeInstance() const
734 {
735     return m_rootNodeInstance;
736 }
737
738 void NodeInstanceServer::setStateInstance(const ServerNodeInstance &stateInstance)
739 {
740     m_activeStateInstance = stateInstance;
741 }
742
743 void NodeInstanceServer::clearStateInstance()
744 {
745     m_activeStateInstance = ServerNodeInstance();
746 }
747
748 void NodeInstanceServer::timerEvent(QTimerEvent *event)
749 {
750     if (event->timerId() == m_timer) {
751         findItemChangesAndSendChangeCommands();
752     }
753
754     NodeInstanceServerInterface::timerEvent(event);
755 }
756
757 NodeInstanceClientInterface *NodeInstanceServer::nodeInstanceClient() const
758 {
759     return m_nodeInstanceClient;
760 }
761
762 void NodeInstanceServer::sendChildrenChangedCommand(const QList<ServerNodeInstance> childList)
763 {
764     QSet<ServerNodeInstance> parentSet;
765     QList<ServerNodeInstance> noParentList;
766
767     foreach (const ServerNodeInstance &child, childList) {
768         if (!child.hasParent())
769             noParentList.append(child);
770         else
771             parentSet.insert(child.parent());
772     }
773
774
775     foreach (const ServerNodeInstance &parent, parentSet)
776         nodeInstanceClient()->childrenChanged(createChildrenChangedCommand(parent, parent.childItems()));
777
778     if (!noParentList.isEmpty())
779         nodeInstanceClient()->childrenChanged(createChildrenChangedCommand(ServerNodeInstance(), noParentList));
780
781 }
782
783 ChildrenChangedCommand NodeInstanceServer::createChildrenChangedCommand(const ServerNodeInstance &parentInstance, const QList<ServerNodeInstance> &instanceList) const
784 {
785     QVector<qint32> instanceVector;
786
787     foreach(const ServerNodeInstance &instance, instanceList)
788         instanceVector.append(instance.instanceId());
789
790     return ChildrenChangedCommand(parentInstance.instanceId(), instanceVector);
791 }
792
793 InformationChangedCommand NodeInstanceServer::createAllInformationChangedCommand(const QList<ServerNodeInstance> &instanceList, bool initial) const
794 {
795     QVector<InformationContainer> informationVector;
796
797     foreach(const ServerNodeInstance &instance, instanceList) {
798         informationVector.append(InformationContainer(instance.instanceId(), Position, instance.position()));
799         informationVector.append(InformationContainer(instance.instanceId(), Transform, instance.transform()));
800         informationVector.append(InformationContainer(instance.instanceId(), SceneTransform, instance.sceneTransform()));
801         informationVector.append(InformationContainer(instance.instanceId(), Size, instance.size()));
802         informationVector.append(InformationContainer(instance.instanceId(), BoundingRect, instance.boundingRect()));
803         informationVector.append(InformationContainer(instance.instanceId(), Transform, instance.transform()));
804         informationVector.append(InformationContainer(instance.instanceId(), HasContent, instance.hasContent()));
805         informationVector.append(InformationContainer(instance.instanceId(), IsMovable, instance.isMovable()));
806         informationVector.append(InformationContainer(instance.instanceId(), IsResizable, instance.isResizable()));
807         informationVector.append(InformationContainer(instance.instanceId(), IsInPositioner, instance.isInPositioner()));
808         informationVector.append(InformationContainer(instance.instanceId(), PenWidth, instance.penWidth()));
809         informationVector.append(InformationContainer(instance.instanceId(), IsAnchoredByChildren, instance.isAnchoredByChildren()));
810         informationVector.append(InformationContainer(instance.instanceId(), IsAnchoredBySibling, instance.isAnchoredBySibling()));
811
812         informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.fill"), instance.hasAnchor("anchors.fill")));
813         informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.centerIn"), instance.hasAnchor("anchors.centerIn")));
814         informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.right"), instance.hasAnchor("anchors.right")));
815         informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.top"), instance.hasAnchor("anchors.top")));
816         informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.left"), instance.hasAnchor("anchors.left")));
817         informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.bottom"), instance.hasAnchor("anchors.bottom")));
818         informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.horizontalCenter"), instance.hasAnchor("anchors.horizontalCenter")));
819         informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.verticalCenter"), instance.hasAnchor("anchors.verticalCenter")));
820         informationVector.append(InformationContainer(instance.instanceId(), HasAnchor, QString("anchors.baseline"), instance.hasAnchor("anchors.baseline")));
821
822         QPair<QString, ServerNodeInstance> anchorPair = instance.anchor("anchors.fill");
823         informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.fill"), anchorPair.first, anchorPair.second.instanceId()));
824
825         anchorPair = instance.anchor("anchors.centerIn");
826         informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.centerIn"), anchorPair.first, anchorPair.second.instanceId()));
827
828         anchorPair = instance.anchor("anchors.right");
829         informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.right"), anchorPair.first, anchorPair.second.instanceId()));
830
831         anchorPair = instance.anchor("anchors.top");
832         informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.top"), anchorPair.first, anchorPair.second.instanceId()));
833
834         anchorPair = instance.anchor("anchors.left");
835         informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.left"), anchorPair.first, anchorPair.second.instanceId()));
836
837         anchorPair = instance.anchor("anchors.bottom");
838         informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.bottom"), anchorPair.first, anchorPair.second.instanceId()));
839
840         anchorPair = instance.anchor("anchors.horizontalCenter");
841         informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.horizontalCenter"), anchorPair.first, anchorPair.second.instanceId()));
842
843         anchorPair = instance.anchor("anchors.verticalCenter");
844         informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.verticalCenter"), anchorPair.first, anchorPair.second.instanceId()));
845
846         anchorPair = instance.anchor("anchors.baseline");
847         informationVector.append(InformationContainer(instance.instanceId(), Anchor, QString("anchors.baseline"), anchorPair.first, anchorPair.second.instanceId()));
848
849         QStringList propertyNames = instance.propertyNames();
850
851         if (initial) {
852             foreach (const QString &propertyName,propertyNames)
853                 informationVector.append(InformationContainer(instance.instanceId(), InstanceTypeForProperty, propertyName, instance.instanceType(propertyName)));
854         }
855
856         foreach (const QString &propertyName,instance.propertyNames()) {
857             bool hasChanged = false;
858             bool hasBinding = instance.hasBindingForProperty(propertyName, &hasChanged);
859             if (hasChanged)
860                 informationVector.append(InformationContainer(instance.instanceId(), HasBindingForProperty, propertyName, hasBinding));
861         }
862
863     }
864
865     return InformationChangedCommand(informationVector);
866 }
867
868 ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QList<ServerNodeInstance> &instanceList) const
869 {
870     QVector<PropertyValueContainer> valueVector;
871
872     foreach(const ServerNodeInstance &instance, instanceList) {
873         foreach(const QString &propertyName, instance.propertyNames()) {
874             QVariant propertyValue = instance.property(propertyName);
875             if (propertyValue.type() < QVariant::UserType)
876                 valueVector.append(PropertyValueContainer(instance.instanceId(), propertyName, propertyValue, QString()));
877         }
878     }
879
880     return ValuesChangedCommand(valueVector);
881 }
882
883 ComponentCompletedCommand NodeInstanceServer::createComponentCompletedCommand(const QList<ServerNodeInstance> &instanceList)
884 {
885     QVector<qint32> idVector;
886     foreach (const ServerNodeInstance &instance, instanceList) {
887         if (instance.instanceId() >= 0)
888             idVector.append(instance.instanceId());
889     }
890
891     return ComponentCompletedCommand(idVector);
892 }
893
894 ValuesChangedCommand NodeInstanceServer::createValuesChangedCommand(const QVector<InstancePropertyPair> &propertyList) const
895 {
896     QVector<PropertyValueContainer> valueVector;
897
898     foreach (const InstancePropertyPair &property, propertyList) {
899         const QString propertyName = property.second;
900         const ServerNodeInstance instance = property.first;
901
902         if( instance.isValid()) {
903             QVariant propertyValue = instance.property(propertyName);
904             if (propertyValue.type() < QVariant::UserType)
905                 valueVector.append(PropertyValueContainer(instance.instanceId(), propertyName, propertyValue, QString()));
906         }
907     }
908
909     return ValuesChangedCommand(valueVector);
910 }
911
912 QStringList NodeInstanceServer::imports() const
913 {
914     return m_importList;
915 }
916
917 QObject *NodeInstanceServer::dummyContextObject() const
918 {
919     return m_dummyContextObject.data();
920 }
921
922 void NodeInstanceServer::notifyPropertyChange(qint32 instanceid, const QString &propertyName)
923 {
924     if (hasInstanceForId(instanceid))
925         addChangedProperty(InstancePropertyPair(instanceForId(instanceid), propertyName));
926 }
927
928 void NodeInstanceServer::insertInstanceRelationship(const ServerNodeInstance &instance)
929 {
930     Q_ASSERT(instance.isValid());
931     Q_ASSERT(!m_idInstanceHash.contains(instance.instanceId()));
932     Q_ASSERT(!m_objectInstanceHash.contains(instance.internalObject()));
933     m_objectInstanceHash.insert(instance.internalObject(), instance);
934     m_idInstanceHash.insert(instance.instanceId(), instance);
935 }
936
937 void NodeInstanceServer::removeInstanceRelationsip(qint32 instanceId)
938 {
939     if (hasInstanceForId(instanceId)) {
940         ServerNodeInstance instance = instanceForId(instanceId);
941         if (instance.isValid())
942             instance.setId(QString());
943         m_idInstanceHash.remove(instanceId);
944         m_objectInstanceHash.remove(instance.internalObject());
945         instance.makeInvalid();
946     }
947 }
948
949 PixmapChangedCommand NodeInstanceServer::createPixmapChangedCommand(const QList<ServerNodeInstance> &instanceList) const
950 {
951     QVector<ImageContainer> imageVector;
952
953     foreach (const ServerNodeInstance &instance, instanceList) {
954         if (instance.isValid())
955             imageVector.append(ImageContainer(instance.instanceId(), instance.renderImage()));
956     }
957
958     return PixmapChangedCommand(imageVector);
959 }
960
961 bool NodeInstanceServer::nonInstanceChildIsDirty(QGraphicsObject *graphicsObject) const
962 {
963     QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(graphicsObject);
964     if (d->dirtyChildren) {
965         foreach(QGraphicsItem *child, graphicsObject->childItems()) {
966             QGraphicsObject *childGraphicsObject = child->toGraphicsObject();
967             if (hasInstanceForObject(childGraphicsObject))
968                 continue;
969
970             QGraphicsItemPrivate *childPrivate = QGraphicsItemPrivate::get(child);
971             if (childPrivate->dirty || nonInstanceChildIsDirty(childGraphicsObject))
972                 return true;
973         }
974     }
975
976     return false;
977 }
978
979 void NodeInstanceServer::resetAllItems()
980 {
981 //     m_declarativeView->scene()->update();
982 //    m_declarativeView->viewport()->repaint();
983     static_cast<QGraphicsScenePrivate*>(QObjectPrivate::get(m_declarativeView->scene()))->processDirtyItemsEmitted = true;
984
985     foreach (QGraphicsItem *item, m_declarativeView->items())
986          static_cast<QGraphicsScenePrivate*>(QObjectPrivate::get(m_declarativeView->scene()))->resetDirtyItem(item);
987 }
988
989 void NodeInstanceServer::initializeDeclarativeView()
990 {
991     Q_ASSERT(!m_declarativeView.data());
992
993     m_declarativeView = new QDeclarativeView;
994 #ifndef Q_WS_MAC
995     m_declarativeView->setAttribute(Qt::WA_DontShowOnScreen, true);
996 #endif
997     m_declarativeView->setViewportUpdateMode(QGraphicsView::NoViewportUpdate);
998     m_declarativeView->show();
999 #ifdef Q_WS_MAC
1000     m_declarativeView->setAttribute(Qt::WA_DontShowOnScreen, true);
1001 #endif
1002     QUnifiedTimer::instance()->setSlowdownFactor(0.00001);
1003     QUnifiedTimer::instance()->setSlowModeEnabled(true);
1004 }
1005
1006 QImage NodeInstanceServer::renderPreviewImage()
1007 {
1008     QSize size = rootNodeInstance().boundingRect().size().toSize();
1009     size.scale(100, 100, Qt::KeepAspectRatio);
1010
1011     QImage image(size, QImage::Format_ARGB32);
1012     image.fill(0xFFFFFFFF);
1013
1014     if (m_declarativeView) {
1015         QPainter painter(&image);
1016         painter.setRenderHint(QPainter::Antialiasing, true);
1017         painter.setRenderHint(QPainter::TextAntialiasing, true);
1018         painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
1019         painter.setRenderHint(QPainter::HighQualityAntialiasing, true);
1020         painter.setRenderHint(QPainter::NonCosmeticDefaultPen, true);
1021
1022         m_declarativeView->scene()->render(&painter, image.rect(), rootNodeInstance().boundingRect().toRect(), Qt::IgnoreAspectRatio);
1023     }
1024
1025     return image;
1026 }
1027
1028 void NodeInstanceServer::loadDummyDataFile(const QFileInfo& qmlFileInfo)
1029 {
1030     QDeclarativeComponent component(engine(), qmlFileInfo.filePath());
1031     QObject *dummyData = component.create();
1032     if(component.isError()) {
1033         QList<QDeclarativeError> errors = component.errors();
1034         foreach (const QDeclarativeError &error, errors) {
1035             qWarning() << error;
1036         }
1037     }
1038
1039     QVariant oldDummyDataObject = m_declarativeView->rootContext()->contextProperty(qmlFileInfo.completeBaseName());
1040
1041     if (dummyData) {
1042         qWarning() << "Loaded dummy data:" << qmlFileInfo.filePath();
1043         m_declarativeView->rootContext()->setContextProperty(qmlFileInfo.completeBaseName(), dummyData);
1044         dummyData->setParent(this);
1045         m_dummyObjectList.append(DummyPair(qmlFileInfo.completeBaseName(), dummyData));
1046     }
1047
1048     if (!oldDummyDataObject.isNull())
1049         delete oldDummyDataObject.value<QObject*>();
1050
1051     if (!dummydataFileSystemWatcher()->files().contains(qmlFileInfo.filePath()))
1052         dummydataFileSystemWatcher()->addPath(qmlFileInfo.filePath());
1053
1054     if (rootNodeInstance().isValid() && rootNodeInstance().internalObject()) {
1055         foreach (QDeclarativeContext *context, allSubContextsForObject(rootNodeInstance().internalObject()))
1056             setupDummysForContext(context);
1057     }
1058 }
1059
1060 void NodeInstanceServer::loadDummyContextObjectFile(const QFileInfo& qmlFileInfo)
1061 {
1062     delete m_dummyContextObject.data();
1063
1064     QDeclarativeComponent component(engine(), qmlFileInfo.filePath());
1065     m_dummyContextObject = component.create();
1066
1067     if(component.isError()) {
1068         QList<QDeclarativeError> errors = component.errors();
1069         foreach (const QDeclarativeError &error, errors) {
1070             qWarning() << error;
1071         }
1072     }
1073
1074     if (m_dummyContextObject) {
1075         qWarning() << "Loaded dummy context object:" << qmlFileInfo.filePath();
1076         m_dummyContextObject->setParent(this);
1077     }
1078
1079     if (!dummydataFileSystemWatcher()->files().contains(qmlFileInfo.filePath()))
1080         dummydataFileSystemWatcher()->addPath(qmlFileInfo.filePath());
1081
1082     refreshBindings();
1083 }
1084
1085 void NodeInstanceServer::loadDummyDataFiles(const QString& directory)
1086 {
1087     QDir dir(directory, "*.qml");
1088     QList<QFileInfo> filePathList = dir.entryInfoList();
1089     QString baseName = QFileInfo(fileUrl().toLocalFile()).completeBaseName();
1090     foreach (const QFileInfo &qmlFileInfo, filePathList) {
1091         if (!qmlFileInfo.completeBaseName().contains("_dummycontext")) {
1092             loadDummyDataFile(qmlFileInfo);
1093         } else if (qmlFileInfo.completeBaseName() == baseName+"_dummycontext") {
1094             loadDummyContextObjectFile(qmlFileInfo);
1095         }
1096     }
1097 }
1098
1099 QStringList dummyDataDirectories(const QString& directoryPath)
1100 {
1101     QStringList dummyDataDirectoryList;
1102     QDir directory(directoryPath);
1103     while(true) {
1104         if (directory.isRoot() || !directory.exists())
1105             return dummyDataDirectoryList;
1106
1107         if (directory.exists("dummydata"))
1108             dummyDataDirectoryList.prepend(directory.absoluteFilePath("dummydata"));
1109
1110         directory.cdUp();
1111     }
1112 }
1113
1114 QList<ServerNodeInstance> NodeInstanceServer::setupScene(const CreateSceneCommand &command)
1115 {
1116     if (!command.fileUrl().isEmpty()) {
1117         engine()->setBaseUrl(command.fileUrl());
1118         m_fileUrl = command.fileUrl();
1119     }
1120
1121     addImports(command.imports());
1122
1123     if (!command.fileUrl().isEmpty()) {
1124         QStringList dummyDataDirectoryList = dummyDataDirectories(QFileInfo(command.fileUrl().toLocalFile()).path());
1125         foreach(const QString &dummyDataDirectory, dummyDataDirectoryList)
1126             loadDummyDataFiles(dummyDataDirectory);
1127     }
1128
1129     static_cast<QGraphicsScenePrivate*>(QObjectPrivate::get(m_declarativeView->scene()))->processDirtyItemsEmitted = true;
1130
1131     QList<ServerNodeInstance> instanceList = createInstances(command.instances());
1132     reparentInstances(command.reparentInstances());
1133
1134     foreach(const IdContainer &container, command.ids()) {
1135         if (hasInstanceForId(container.instanceId()))
1136             instanceForId(container.instanceId()).setId(container.id());
1137     }
1138
1139     foreach(const PropertyValueContainer &container, command.valueChanges()) {
1140         if (container.isDynamic())
1141             setInstancePropertyVariant(container);
1142     }
1143
1144     foreach(const PropertyValueContainer &container, command.valueChanges()) {
1145         if (!container.isDynamic())
1146             setInstancePropertyVariant(container);
1147     }
1148
1149     foreach(const PropertyBindingContainer &container, command.bindingChanges()) {
1150         if (container.isDynamic())
1151             setInstancePropertyBinding(container);
1152     }
1153
1154     foreach(const PropertyBindingContainer &container, command.bindingChanges()) {
1155         if (!container.isDynamic())
1156             setInstancePropertyBinding(container);
1157     }
1158
1159     foreach(ServerNodeInstance instance, instanceList)
1160         instance.doComponentComplete();
1161
1162     m_declarativeView->scene()->setSceneRect(rootNodeInstance().boundingRect());
1163
1164     return instanceList;
1165 }
1166
1167 void NodeInstanceServer::findItemChangesAndSendChangeCommands()
1168 {
1169     static bool inFunction = false;
1170     if (!inFunction) {
1171         inFunction = true;
1172
1173         QSet<ServerNodeInstance> informationChangedInstanceSet;
1174         QVector<InstancePropertyPair> propertyChangedList;
1175         QSet<ServerNodeInstance> parentChangedSet;
1176         bool adjustSceneRect = false;
1177
1178         if (m_declarativeView) {
1179             foreach (QGraphicsItem *item, m_declarativeView->items()) {
1180                 QGraphicsObject *graphicsObject = item->toGraphicsObject();
1181                 if (graphicsObject && hasInstanceForObject(graphicsObject)) {
1182                     ServerNodeInstance instance = instanceForObject(graphicsObject);
1183                     QGraphicsItemPrivate *d = QGraphicsItemPrivate::get(item);
1184
1185                     if (d->dirtySceneTransform || d->geometryChanged || d->dirty)
1186                         informationChangedInstanceSet.insert(instance);
1187
1188                     if (d->geometryChanged) {
1189                         if (instance.isRootNodeInstance())
1190                             m_declarativeView->scene()->setSceneRect(item->boundingRect());
1191                     }
1192
1193                 }
1194             }
1195
1196             foreach (const InstancePropertyPair& property, m_changedPropertyList) {
1197                 const ServerNodeInstance instance = property.first;
1198                 const QString propertyName = property.second;
1199
1200                 if (instance.isValid()) {
1201                     if (instance.isRootNodeInstance() && (propertyName == "width" || propertyName == "height"))
1202                         adjustSceneRect = true;
1203
1204                     if (propertyName.contains("anchors"))
1205                         informationChangedInstanceSet.insert(instance);
1206
1207                     if (propertyName == "parent") {
1208                         informationChangedInstanceSet.insert(instance);
1209                         parentChangedSet.insert(instance);
1210                     }
1211
1212                     propertyChangedList.append(property);
1213                 }
1214             }
1215
1216             m_changedPropertyList.clear();
1217             resetAllItems();
1218
1219             if (!informationChangedInstanceSet.isEmpty())
1220                 nodeInstanceClient()->informationChanged(createAllInformationChangedCommand(informationChangedInstanceSet.toList()));
1221
1222             if (!propertyChangedList.isEmpty())
1223                 nodeInstanceClient()->valuesChanged(createValuesChangedCommand(propertyChangedList));
1224
1225             if (!parentChangedSet.isEmpty())
1226                 sendChildrenChangedCommand(parentChangedSet.toList());
1227
1228             if (adjustSceneRect) {
1229                 QRectF boundingRect = m_rootNodeInstance.boundingRect();
1230                 if (boundingRect.isValid()) {
1231                     m_declarativeView->setSceneRect(boundingRect);
1232                 }
1233             }
1234
1235             if (!m_completedComponentList.isEmpty()) {
1236                 nodeInstanceClient()->componentCompleted(createComponentCompletedCommand(m_completedComponentList));
1237                 m_completedComponentList.clear();
1238             }
1239
1240             slowDownRenderTimer();
1241             nodeInstanceClient()->flush();
1242             nodeInstanceClient()->synchronizeWithClientProcess();
1243         }
1244
1245         inFunction = false;
1246     }
1247
1248 }
1249 }
1250
1251
1252