Commit ed424628 authored by Marco Bubke's avatar Marco Bubke

QmlDesigner.Instances: Move instances out of process

The complete qml emulation layer (instances) is moved
into another external process (qmlpuppet).

Summary of architectural changes:

- Asynchronous messaging
    Handling commands and data transfer asynchronously reduces the
    amount of context switches between processes.

- Proxy classes for client process
    This classes abstract the inter process communication

- QVariant based command parsing and serialization
    Using LocalSocket in bidirectional manner for communications
    of commands and data transfer.

- Integer based identifier instead of ModelNode in client process
    The qml emulation layer (instances) has no more depencies to our
    internal data model.

- Timer based rendering
    Rendering in instances is controlled by a timer. Only dirty items
    are updated.
parent f123af08
......@@ -78,6 +78,8 @@ bin/*.dll
bin/qtcreator
bin/qtcreator_process_stub*
bin/qtcreator.exe
bin/qmlpuppet
bin/qmlpuppet.exe
share/doc/qtcreator/qtcreator.qch
src/tools/gen-cpp-ast/generate-ast
src/tools/mkvisitor/cplusplus0
......
......@@ -34,7 +34,8 @@
#include <modelnode.h>
#include <nodemetainfo.h>
#include <widgetqueryview.h>
#include <qmlanchors.h>
#include <QGraphicsSceneMouseEvent>
#include <QDebug>
......@@ -72,10 +73,7 @@ void FormEditorItem::setup()
{
if (qmlItemNode().hasInstanceParent()) {
setParentItem(scene()->itemForQmlItemNode(qmlItemNode().instanceParent().toQmlItemNode()));
setVisible(true);
setOpacity(qmlItemNode().instanceValue("opacity").toDouble());
} else if (!qmlItemNode().isRootNode()){
setVisible(false);
}
setFlag(QGraphicsItem::ItemClipsChildrenToShape, qmlItemNode().instanceValue("clip").toBool());
......
......@@ -144,7 +144,6 @@ void FormEditorScene::synchronizeTransformation(const QmlItemNode &qmlItemNode)
{
FormEditorItem *item = itemForQmlItemNode(qmlItemNode);
item->updateGeometry();
item->update();
if (qmlItemNode.isRootNode()) {
QRectF sceneRect(qmlItemNode.instanceBoundingRect());
......@@ -175,8 +174,6 @@ void FormEditorScene::synchronizeOtherProperty(const QmlItemNode &qmlItemNode, c
if (propertyName == "visible")
item->setContentVisible(qmlItemNode.instanceValue("visible").toBool());
if (item)
item->update();
}
}
......@@ -344,13 +341,6 @@ void FormEditorScene::reparentItem(const QmlItemNode &node, const QmlItemNode &n
if (item->parentItem() != parentItem) {
item->setParentItem(parentItem);
if (parentItem) {
item->setVisible(true);
} else {
item->setVisible(false);
}
item->update();
}
}
......@@ -380,7 +370,6 @@ void FormEditorScene::clearFormEditorItems()
foreach (QGraphicsItem *item, itemList) {
if (qgraphicsitem_cast<FormEditorItem* >(item)) {
item->setParentItem(0);
item->setVisible(false);
}
}
......
......@@ -40,7 +40,6 @@
#include "formeditorscene.h"
#include <rewritertransaction.h>
#include <modelnode.h>
#include <modelutilities.h>
#include <itemlibraryinfo.h>
#include <metainfo.h>
#include <model.h>
......@@ -451,6 +450,33 @@ void FormEditorView::customNotification(const AbstractView *view, const QString
m_formEditorWidget->setFeedbackNode(QmlItemNode());
}
if (identifier == "__instance information changed__") {
QList<FormEditorItem*> itemNodeList;
foreach (const ModelNode &node, nodeList) {
QmlItemNode qmlItemNode(node);
if (qmlItemNode.isValid() && scene()->hasItemForQmlItemNode(qmlItemNode)) {
scene()->synchronizeParent(qmlItemNode);
scene()->synchronizeTransformation(qmlItemNode);
itemNodeList.append(scene()->itemForQmlItemNode(qmlItemNode));
}
}
m_currentTool->formEditorItemsChanged(itemNodeList);
}
if (identifier == "__instance render pixmap changed__") {
QList<FormEditorItem*> itemNodeList;
foreach (const ModelNode &node, nodeList) {
QmlItemNode qmlItemNode(node);
if (qmlItemNode.isValid() && scene()->hasItemForQmlItemNode(qmlItemNode)) {
scene()->itemForQmlItemNode(qmlItemNode)->update();
}
}
}
QmlModelView::customNotification(view, identifier, nodeList, data);
}
......@@ -509,26 +535,6 @@ QmlItemNode findRecursiveQmlItemNode(const QmlObjectNode &firstQmlObjectNode)
return QmlItemNode();
}
void FormEditorView::transformChanged(const QmlObjectNode &qmlObjectNode, const QString &/*propertyName*/)
{
QmlItemNode itemNode = qmlObjectNode.toQmlItemNode();
if (itemNode.isValid() && scene()->hasItemForQmlItemNode(itemNode)) {
m_scene->synchronizeTransformation(itemNode);
m_currentTool->formEditorItemsChanged(QList<FormEditorItem*>() << m_scene->itemForQmlItemNode(itemNode));
}
scene()->update();
}
void FormEditorView::parentChanged(const QmlObjectNode &qmlObjectNode)
{
QmlItemNode itemNode = qmlObjectNode.toQmlItemNode();
if (itemNode.isValid() && scene()->hasItemForQmlItemNode(itemNode)) {
scene()->synchronizeParent(itemNode);
m_currentTool->formEditorItemsChanged(QList<FormEditorItem*>() << m_scene->itemForQmlItemNode(itemNode));
}
}
void FormEditorView::otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName)
{
Q_ASSERT(qmlObjectNode.isValid());
......@@ -556,7 +562,6 @@ void FormEditorView::stateChanged(const QmlModelState &newQmlModelState, const Q
{
QmlModelView::stateChanged(newQmlModelState, oldQmlModelState);
m_formEditorWidget->anchorToolAction()->setEnabled(newQmlModelState.isBaseState());
if (!newQmlModelState.isBaseState() && currentTool() == m_anchorTool) {
......
......@@ -112,8 +112,6 @@ signals:
void ItemCreatorDeActivated();
protected:
void transformChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName);
void parentChanged(const QmlObjectNode &qmlObjectNode);
void otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName);
void stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState);
......
......@@ -81,12 +81,8 @@ void StatesEditorView::setCurrentStateSilent(int index)
return;
}
nodeInstanceView()->setBlockStatePropertyChanges(true);
QmlModelView::activateState(state);
nodeInstanceView()->setBlockStatePropertyChanges(false);
m_settingSilentState = false;
}
......@@ -478,45 +474,47 @@ void StatesEditorView::selectedNodesChanged(const QList<ModelNode> &/*selectedNo
QPixmap StatesEditorView::renderState(int i)
{
if (debug)
qDebug() << __FUNCTION__ << i;
return QPixmap();
// if (debug)
// qDebug() << __FUNCTION__ << i;
if (!m_attachedToModel)
return QPixmap();
// if (!m_attachedToModel)
// return QPixmap();
Q_ASSERT(i >= 0 && i < m_modelStates.size());
QmlModelState oldState = currentState();
setCurrentStateSilent(i);
// Q_ASSERT(i >= 0 && i < m_modelStates.size());
// QmlModelState oldState = currentState();
// setCurrentStateSilent(i);
Q_ASSERT(nodeInstanceView());
// Q_ASSERT(nodeInstanceView());
const int checkerbordSize= 10;
QPixmap tilePixmap(checkerbordSize * 2, checkerbordSize * 2);
tilePixmap.fill(Qt::white);
QPainter tilePainter(&tilePixmap);
QColor color(220, 220, 220);
tilePainter.fillRect(0, 0, checkerbordSize, checkerbordSize, color);
tilePainter.fillRect(checkerbordSize, checkerbordSize, checkerbordSize, checkerbordSize, color);
tilePainter.end();
// const int checkerbordSize= 10;
// QPixmap tilePixmap(checkerbordSize * 2, checkerbordSize * 2);
// tilePixmap.fill(Qt::white);
// QPainter tilePainter(&tilePixmap);
// QColor color(220, 220, 220);
// tilePainter.fillRect(0, 0, checkerbordSize, checkerbordSize, color);
// tilePainter.fillRect(checkerbordSize, checkerbordSize, checkerbordSize, checkerbordSize, color);
// tilePainter.end();
QSizeF pixmapSize(nodeInstanceView()->sceneRect().size());
if (pixmapSize.width() > 100 || pixmapSize.height() > 100) // sensible maximum size
pixmapSize.scale(QSize(100, 100), Qt::KeepAspectRatio);
QSize cutSize(floor(pixmapSize.width()),floor(pixmapSize.height()));
pixmapSize.setWidth(ceil(pixmapSize.width()));
pixmapSize.setHeight(ceil(pixmapSize.height()));
QPixmap pixmap(pixmapSize.toSize());
// QSizeF pixmapSize(nodeInstanceView()->sceneRect().size());
// if (pixmapSize.width() > 100 || pixmapSize.height() > 100) // sensible maximum size
// pixmapSize.scale(QSize(100, 100), Qt::KeepAspectRatio);
// QSize cutSize(floor(pixmapSize.width()),floor(pixmapSize.height()));
// pixmapSize.setWidth(ceil(pixmapSize.width()));
// pixmapSize.setHeight(ceil(pixmapSize.height()));
// QPixmap pixmap(pixmapSize.toSize());
QPainter painter(&pixmap);
painter.drawTiledPixmap(pixmap.rect(), tilePixmap);
nodeInstanceView()->render(&painter, pixmap.rect(), nodeInstanceView()->sceneRect());
// QPainter painter(&pixmap);
// painter.drawTiledPixmap(pixmap.rect(), tilePixmap);
// nodeInstanceView()->render(&painter, pixmap.rect(), nodeInstanceView()->sceneRect());
setCurrentStateSilent(m_modelStates.indexOf(oldState));
// setCurrentStateSilent(m_modelStates.indexOf(oldState));
Q_ASSERT(oldState == currentState());
// Q_ASSERT(oldState == currentState());
return pixmap.copy(0,0,cutSize.width(),cutSize.height());
// return pixmap.copy(0,0,cutSize.width(),cutSize.height());
}
void StatesEditorView::sceneChanged()
......
......@@ -2,7 +2,7 @@ include($$PWD/filemanager/filemanager.pri)
include (../config.pri)
QT += script \
declarative
network
DEFINES += TEST_EXPORTS
INCLUDEPATH += $$PWD \
......@@ -27,15 +27,9 @@ SOURCES += $$PWD/model/abstractview.cpp \
$$PWD/model/propertycontainer.cpp \
$$PWD/pluginmanager/widgetpluginmanager.cpp \
$$PWD/pluginmanager/widgetpluginpath.cpp \
$$PWD/instances/nodeinstance.cpp \
$$PWD/instances/servernodeinstance.cpp \
$$PWD/instances/objectnodeinstance.cpp \
$$PWD/instances/widgetnodeinstance.cpp \
$$PWD/instances/graphicswidgetnodeinstance.cpp \
$$PWD/instances/qmlgraphicsitemnodeinstance.cpp \
$$PWD/instances/graphicsscenenodeinstance.cpp \
$$PWD/instances/graphicsviewnodeinstance.cpp \
$$PWD/instances/proxywidgetnodeinstance.cpp \
$$PWD/instances/qmlviewnodeinstance.cpp \
$$PWD/instances/dummynodeinstance.cpp \
$$PWD/instances/qmlpropertychangesnodeinstance.cpp \
$$PWD/instances/qmlstatenodeinstance.cpp \
......@@ -95,8 +89,35 @@ SOURCES += $$PWD/model/abstractview.cpp \
$$PWD/instances/nodeinstancemetaobject.cpp \
$$PWD/instances/behaviornodeinstance.cpp \
$$PWD/instances/nodeinstancesignalspy.cpp \
$$PWD/instances/positionernodeinstance.cpp
$$PWD/instances/positionernodeinstance.cpp \
$$PWD/instances/nodeinstanceserver.cpp \
$$PWD/instances/declarativedesignercommunicationinterface.cpp \
$$PWD/instances/createinstancescommand.cpp \
$$PWD/instances/nodeinstanceserverinterface.cpp \
$$PWD/instances/nodeinstance.cpp \
$$PWD/instances/propertyvaluecontainer.cpp \
$$PWD/instances/childrenchangeeventfilter.cpp \
$$PWD/instances/propertybindingcontainer.cpp \
$$PWD/instances/propertyabstractcontainer.cpp \
$$PWD/instances/createscenecommand.cpp \
$$PWD/instances/instancecontainer.cpp \
$$PWD/instances/changefileurlcommand.cpp \
$$PWD/instances/clearscenecommand.cpp \
$$PWD/instances/reparentcontainer.cpp \
$$PWD/instances/reparentinstancescommand.cpp \
$$PWD/instances/changevaluescommand.cpp \
$$PWD/instances/changebindingscommand.cpp \
$$PWD/instances/changeidscommand.cpp \
$$PWD/instances/idcontainer.cpp \
$$PWD/instances/removeinstancescommand.cpp \
$$PWD/instances/removepropertiescommand.cpp \
$$PWD/instances/valueschangedcommand.cpp \
$$PWD/instances/pixmapchangedcommand.cpp \
$$PWD/instances/informationchangedcommand.cpp \
$$PWD/instances/informationcontainer.cpp \
$$PWD/instances/changestatecommand.cpp \
$$PWD/instances/nodeinstanceserverproxy.cpp \
$$PWD/instances/nodeinstanceclientproxy.cpp
HEADERS += $$PWD/include/corelib_global.h \
$$PWD/include/abstractview.h \
$$PWD/include/nodeinstanceview.h \
......@@ -111,7 +132,6 @@ HEADERS += $$PWD/include/corelib_global.h \
$$PWD/include/modelnode.h \
$$PWD/include/model.h \
$$PWD/include/nodeproperty.h \
$$PWD/include/widgetqueryview.h \
$$PWD/include/subcomponentmanager.h \
$$PWD/include/propertycontainer.h \
$$PWD/model/internalnode_p.h \
......@@ -120,15 +140,9 @@ HEADERS += $$PWD/include/corelib_global.h \
$$PWD/model/propertyparser.h \
$$PWD/pluginmanager/widgetpluginmanager.h \
$$PWD/pluginmanager/widgetpluginpath.h \
$$PWD/include/nodeinstance.h \
$$PWD/instances/servernodeinstance.h \
$$PWD/instances/objectnodeinstance.h \
$$PWD/instances/widgetnodeinstance.h \
$$PWD/instances/graphicswidgetnodeinstance.h \
$$PWD/instances/qmlgraphicsitemnodeinstance.h \
$$PWD/instances/graphicsscenenodeinstance.h \
$$PWD/instances/graphicsviewnodeinstance.h \
$$PWD/instances/proxywidgetnodeinstance.h \
$$PWD/instances/qmlviewnodeinstance.h \
$$PWD/instances/dummynodeinstance.h \
$$PWD/instances/qmlpropertychangesnodeinstance.h \
$$PWD/instances/qmlstatenodeinstance.h \
......@@ -189,12 +203,40 @@ HEADERS += $$PWD/include/corelib_global.h \
$$PWD/instances/nodeinstancemetaobject.h \
$$PWD/instances/behaviornodeinstance.h \
$$PWD/instances/nodeinstancesignalspy.h \
$$PWD/instances/positionernodeinstance.h
$$PWD/instances/positionernodeinstance.h \
$$PWD/instances/nodeinstanceserver.h \
$$PWD/instances/declarativedesignercommunicationinterface.h \
$$PWD/instances/createinstancescommand.h \
$$PWD/include/nodeinstanceserverinterface.h \
$$PWD/include/nodeinstance.h \
$$PWD/include/propertyvaluecontainer.h \
$$PWD/instances/childrenchangeeventfilter.h \
$$PWD/include/propertybindingcontainer.h \
$$PWD/include/propertyabstractcontainer.h \
$$PWD/instances/createscenecommand.h \
$$PWD/instances/instancecontainer.h \
$$PWD/instances/changefileurlcommand.h \
$$PWD/instances/clearscenecommand.h \
$$PWD/instances/reparentcontainer.h \
$$PWD/instances/reparentinstancescommand.h \
$$PWD/instances/changevaluescommand.h \
$$PWD/instances/changebindingscommand.h \
$$PWD/instances/changeidscommand.h \
$$PWD/instances/idcontainer.h \
$$PWD/instances/removeinstancescommand.h \
$$PWD/instances/removepropertiescommand.h \
$$PWD/include/nodeinstanceclientinterface.h \
$$PWD/instances/valueschangedcommand.h \
$$PWD/instances/pixmapchangedcommand.h \
$$PWD/instances/informationchangedcommand.h \
$$PWD/instances/informationcontainer.h \
$$PWD/include/commondefines.h \
$$PWD/instances/changestatecommand.h \
$$PWD/instances/nodeinstanceserverproxy.h \
$$PWD/instances/nodeinstanceclientproxy.h
contains(CONFIG, plugin) {
# If core.pri has been included in the qmldesigner plugin
SOURCES += $$PWD/model/basetexteditmodifier.cpp
HEADERS += $$PWD/include/basetexteditmodifier.h
}
SOURCES += $$PWD/exception.cpp
SOURCES += $$PWD/invalidnodeinstanceexception.cpp
#ifndef COMMONDEFINES_H
#define COMMONDEFINES_H
#include <QMetaType>
namespace QmlDesigner {
enum InformationName
{
NoName,
Size,
BoundingRect,
Transform,
HasAnchor,
Anchor,
InstanceTypeForProperty,
PenWidth,
Position,
IsInPositioner,
SceneTransform,
IsResizable,
IsMovable,
IsAnchoredByChildren,
IsAnchoredBySibling,
HasContent,
HasBindingForProperty,
Parent
};
}
#endif // COMMONDEFINES_H
......@@ -61,7 +61,6 @@ class AbstractView;
class NodeListProperty;
class NodeProperty;
class NodeAbstractProperty;
class NodeInstance;
class ModelNode;
CORESHARED_EXPORT QList<Internal::InternalNodePointer> toInternalNodeList(const QList<ModelNode> &nodeList);
......
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef PROXYNODEINSTANCE_H
#define PROXYNODEINSTANCE_H
#ifndef NODEINSTANCE_H
#define NODEINSTANCE_H
#include "corelib_global.h"
#include <QSharedPointer>
#include <QHash>
#include <QRectF>
#include <propertymetainfo.h>
#include <qmlanchors.h>
#include <QTransform>
#include <QPointF>
#include <QSizeF>
#include <QPair>
QT_BEGIN_NAMESPACE
class QPainter;
class QStyleOptionGraphicsItem;
class QDeclarativeContext;
class QGraphicsItem;
class QGraphicsTransform;
QT_END_NAMESPACE
#include "commondefines.h"
namespace QmlDesigner {
class ModelNode;
class NodeInstanceView;
class Preview;
class NodeMetaInfo;
class NodeState;
class WidgetQueryView;
namespace Internal {
class ObjectNodeInstance;
class QmlGraphicsItemNodeInstance;
class QmlPropertyChangesNodeInstance;
class GraphicsObjectNodeInstance;
class QmlStateNodeInstance;
}
class ProxyNodeInstanceData;
class CORESHARED_EXPORT NodeInstance
class NodeInstance
{
friend class CORESHARED_EXPORT QmlDesigner::WidgetQueryView;
friend CORESHARED_EXPORT class Preview;
friend CORESHARED_EXPORT class NodeInstanceView;
friend class QHash<ModelNode, NodeInstance>;
friend CORESHARED_EXPORT uint qHash(const NodeInstance &instance);
friend CORESHARED_EXPORT bool operator==(const NodeInstance &first, const NodeInstance &second);
friend CORESHARED_EXPORT class NodeMetaInfo;
friend class QmlDesigner::Internal::QmlGraphicsItemNodeInstance;
friend class QmlDesigner::Internal::GraphicsObjectNodeInstance;
friend class QmlDesigner::Internal::ObjectNodeInstance;
friend class QmlDesigner::Internal::QmlPropertyChangesNodeInstance;
friend class QmlDesigner::Internal::QmlStateNodeInstance;
friend class NodeInstanceView;
public:
static NodeInstance create(const ModelNode &node, qint32 instanceId);
NodeInstance();
~NodeInstance();
NodeInstance(const NodeInstance &other);
NodeInstance& operator=(const NodeInstance &other);
void paint(QPainter *painter);
NodeInstance parent() const;
bool hasParent() const;
ModelNode modelNode() const;
bool isTopLevel() const;
bool isQmlGraphicsItem() const;
bool isGraphicsScene() const;
bool isGraphicsView() const;
bool isGraphicsWidget() const;
bool isProxyWidget() const;
bool isWidget() const;
bool isQDeclarativeView() const;
bool isGraphicsObject() const;
bool isTransition() const;
bool isPositioner() const;
bool equalGraphicsItem(QGraphicsItem *item) const;
QRectF boundingRect() const;
QPointF position() const;
QSizeF size() const;
QTransform transform() const;
QTransform customTransform() const;
QTransform sceneTransform() const;
double rotation() const;
double scale() const;
QList<QGraphicsTransform *> transformations() const;
QPointF transformOriginPoint() const;
double zValue() const;
double opacity() const;
QVariant property(const QString &name) const;
QVariant defaultValue(const QString &name) const;
QString instanceType(const QString &name) const;
bool hasBindingForProperty(const QString &name) const;
bool isValid() const;
void makeInvalid();
void renderPixmapNextPaint();
QRectF boundingRect() const;
bool hasContent() const;
bool isResizable() const;
bool isMovable() const;
bool isInPositioner() const;
bool isWrappingThisObject(QObject *object) const;
QVariant resetVariant(const QString &name) const;
bool hasAnchor(const QString &name) const;
bool isAnchoredBySibling() const;
bool isAnchoredByChildren() const;