Live preview: Creating objects dynamically

This commit is contained in:
Lasse Holmstedt
2010-07-16 09:41:56 +02:00
parent c77e560f65
commit a457d2eec3
10 changed files with 112 additions and 2 deletions

View File

@@ -408,6 +408,13 @@ void ClientProxy::changeToSelectMarqueeTool()
m_designClient->changeToSelectMarqueeTool(); m_designClient->changeToSelectMarqueeTool();
} }
void ClientProxy::createQmlObject(const QString &qmlText, const QDeclarativeDebugObjectReference &parentRef,
const QStringList &imports, const QString &filename)
{
if (isDesignClientConnected())
m_designClient->createQmlObject(qmlText, parentRef, imports, filename);
}
bool ClientProxy::isDesignClientConnected() const bool ClientProxy::isDesignClientConnected() const
{ {
return (m_designClient && m_conn->isConnected()); return (m_designClient && m_conn->isConnected());

View File

@@ -102,6 +102,8 @@ public slots:
void changeToZoomTool(); void changeToZoomTool();
void changeToSelectTool(); void changeToSelectTool();
void changeToSelectMarqueeTool(); void changeToSelectMarqueeTool();
void createQmlObject(const QString &qmlText, const QDeclarativeDebugObjectReference &parent,
const QStringList &imports, const QString &filename = QString());
private slots: private slots:
void contextChanged(); void contextChanged();

View File

@@ -98,6 +98,7 @@ static QString label(UiObjectMember *member, Document::Ptr doc)
} else if(UiArrayBinding *foo = cast<UiArrayBinding *>(member)) { } else if(UiArrayBinding *foo = cast<UiArrayBinding *>(member)) {
str = label(foo->qualifiedId) + QLatin1String("[]"); str = label(foo->qualifiedId) + QLatin1String("[]");
} else if(UiScriptBinding *foo = cast<UiScriptBinding *>(member)) { } else if(UiScriptBinding *foo = cast<UiScriptBinding *>(member)) {
Q_UNUSED(foo)
} else { } else {
quint32 start = member->firstSourceLocation().begin(); quint32 start = member->firstSourceLocation().begin();
quint32 end = member->lastSourceLocation().end(); quint32 end = member->lastSourceLocation().end();
@@ -277,6 +278,34 @@ static QString _methodName(UiSourceElement *source)
} }
void Delta::insert(UiObjectMember *member, UiObjectMember *parentMember, const QList<QDeclarativeDebugObjectReference > &debugReferences, const Document::Ptr &doc)
{
if (!member || !parentMember)
return;
// create new objects
if (UiObjectDefinition* uiObjectDef = cast<UiObjectDefinition *>(member)) {
unsigned begin = uiObjectDef->firstSourceLocation().begin();
unsigned end = uiObjectDef->lastSourceLocation().end();
QString qmlText = doc->source().mid(begin, end - begin);
QStringList importList;
for (UiImportList *it = doc->qmlProgram()->imports; it; it = it->next) {
if (!it->import)
continue;
unsigned importBegin = it->import->firstSourceLocation().begin();
unsigned importEnd = it->import->lastSourceLocation().end();
importList << doc->source().mid(importBegin, importEnd - importBegin);
}
foreach(const QDeclarativeDebugObjectReference &ref, debugReferences) {
if (ref.debugId() != -1) {
ClientProxy::instance()->createQmlObject(qmlText, ref, importList, doc->fileName());
}
}
}
}
Delta::DebugIdMap Delta::operator()(const Document::Ptr &doc1, const Document::Ptr &doc2, const DebugIdMap &debugIds) Delta::DebugIdMap Delta::operator()(const Document::Ptr &doc1, const Document::Ptr &doc2, const DebugIdMap &debugIds)
{ {
Q_ASSERT(doc1->qmlProgram()); Q_ASSERT(doc1->qmlProgram());
@@ -297,13 +326,14 @@ Delta::DebugIdMap Delta::operator()(const Document::Ptr &doc1, const Document::P
while(!todo.isEmpty()) { while(!todo.isEmpty()) {
UiObjectMember *y = todo.takeFirst(); UiObjectMember *y = todo.takeFirst();
todo += children(y); todo += children(y);
if (!M.way2.contains(y)) { if (!M.way2.contains(y)) {
insert(y, parents2.parent.value(y), newDebuggIds.value(parents2.parent.value(y)), doc2);
qDebug () << "insert " << label(y, doc2) << " to " << label(parents2.parent.value(y), doc2); qDebug () << "insert " << label(y, doc2) << " to " << label(parents2.parent.value(y), doc2);
continue; continue;
} }
UiObjectMember *x = M.way2[y]; UiObjectMember *x = M.way2[y];
//--8<--------------------------------------------------------------------------------------- //--8<---------------------------------------------------------------------------------------
if (debugIds.contains(x)) { if (debugIds.contains(x)) {
newDebuggIds[y] = debugIds[x]; newDebuggIds[y] = debugIds[x];

View File

@@ -77,6 +77,10 @@ public:
static bool compare(QmlJS::AST::UiQualifiedId *id, QmlJS::AST::UiQualifiedId *other); static bool compare(QmlJS::AST::UiQualifiedId *id, QmlJS::AST::UiQualifiedId *other);
static QmlJS::AST::UiObjectMemberList *objectMembers(QmlJS::AST::UiObjectMember *object); static QmlJS::AST::UiObjectMemberList *objectMembers(QmlJS::AST::UiObjectMember *object);
private:
void insert(UiObjectMember *member, UiObjectMember *parentMember,
const QList<QDeclarativeDebugObjectReference> &debugReferences, const Document::Ptr &doc);
private: private:
QmlJS::Document::Ptr _doc; QmlJS::Document::Ptr _doc;
QmlJS::Document::Ptr _previousDoc; QmlJS::Document::Ptr _previousDoc;

View File

@@ -213,6 +213,24 @@ void QmlJSDesignDebugClient::changeToZoomTool()
sendMessage(message); sendMessage(message);
} }
void QmlJSDesignDebugClient::createQmlObject(const QString &qmlText, const QDeclarativeDebugObjectReference &parentRef,
const QStringList &imports, const QString &filename)
{
if (!m_connection || !m_connection->isConnected())
return;
QByteArray message;
QDataStream ds(&message, QIODevice::WriteOnly);
ds << QByteArray("CREATE_OBJECT")
<< qmlText
<< parentRef.debugId()
<< imports
<< filename;
sendMessage(message);
}
void QmlJSDesignDebugClient::applyChangesToQmlFile() void QmlJSDesignDebugClient::applyChangesToQmlFile()
{ {
if (!m_connection || !m_connection->isConnected()) if (!m_connection || !m_connection->isConnected())

View File

@@ -64,6 +64,9 @@ public:
void changeToSelectMarqueeTool(); void changeToSelectMarqueeTool();
void changeToZoomTool(); void changeToZoomTool();
void createQmlObject(const QString &qmlText, const QDeclarativeDebugObjectReference &parentRef,
const QStringList &imports, const QString &filename);
void applyChangesToQmlFile(); void applyChangesToQmlFile();
void applyChangesFromQmlFile(); void applyChangesFromQmlFile();

View File

@@ -1,4 +1,5 @@
#include "qdeclarativedesigndebugserver.h" #include "qdeclarativedesigndebugserver.h"
#include <QStringList>
#include <QDebug> #include <QDebug>
@@ -52,6 +53,13 @@ void QDeclarativeDesignDebugServer::messageReceived(const QByteArray &message)
bool inDesignMode; bool inDesignMode;
ds >> inDesignMode; ds >> inDesignMode;
emit designModeBehaviorChanged(inDesignMode); emit designModeBehaviorChanged(inDesignMode);
} else if (type == "CREATE_OBJECT") {
QString qml;
int parentId;
QString filename;
QStringList imports;
ds >> qml >> parentId >> imports >> filename;
emit objectCreationRequested(qml, objectForId(parentId), imports, filename);
} }
} }

View File

@@ -72,6 +72,9 @@ Q_SIGNALS:
void zoomToolRequested(); void zoomToolRequested();
void colorPickerToolRequested(); void colorPickerToolRequested();
void objectCreationRequested(const QString &qml, QObject *parent,
const QStringList &imports, const QString &filename = QString());
// 1 = normal speed, // 1 = normal speed,
// 0 = paused, // 0 = paused,
// 1 < x < 16 = slowdown by some factor // 1 < x < 16 = slowdown by some factor

View File

@@ -8,9 +8,12 @@
#include "subcomponenteditortool.h" #include "subcomponenteditortool.h"
#include "qmltoolbar.h" #include "qmltoolbar.h"
#include <QMouseEvent>
#include <QDeclarativeItem> #include <QDeclarativeItem>
#include <QDeclarativeEngine>
#include <QDeclarativeContext>
#include <QDeclarativeExpression>
#include <QWidget> #include <QWidget>
#include <QMouseEvent>
#include <QGraphicsObject> #include <QGraphicsObject>
#include <QApplication> #include <QApplication>
@@ -48,6 +51,9 @@ QDeclarativeDesignView::QDeclarativeDesignView(QWidget *parent) :
connect(qmlDesignDebugServer(), SIGNAL(selectMarqueeToolRequested()), SLOT(changeToMarqueeSelectTool())); connect(qmlDesignDebugServer(), SIGNAL(selectMarqueeToolRequested()), SLOT(changeToMarqueeSelectTool()));
connect(qmlDesignDebugServer(), SIGNAL(selectToolRequested()), SLOT(changeToSingleSelectTool())); connect(qmlDesignDebugServer(), SIGNAL(selectToolRequested()), SLOT(changeToSingleSelectTool()));
connect(qmlDesignDebugServer(), SIGNAL(zoomToolRequested()), SLOT(changeToZoomTool())); connect(qmlDesignDebugServer(), SIGNAL(zoomToolRequested()), SLOT(changeToZoomTool()));
connect(qmlDesignDebugServer(),
SIGNAL(objectCreationRequested(QString,QObject*,QStringList,QString)),
SLOT(createQmlObject(QString,QObject*,QStringList,QString)));
connect(this, SIGNAL(statusChanged(QDeclarativeView::Status)), SLOT(onStatusChanged(QDeclarativeView::Status))); connect(this, SIGNAL(statusChanged(QDeclarativeView::Status)), SLOT(onStatusChanged(QDeclarativeView::Status)));
@@ -178,6 +184,32 @@ void QDeclarativeDesignView::keyReleaseEvent(QKeyEvent *event)
m_currentTool->keyReleaseEvent(event); m_currentTool->keyReleaseEvent(event);
} }
void QDeclarativeDesignView::createQmlObject(const QString &qml, QObject *parent, const QStringList &importList, const QString &filename)
{
if (!parent)
return;
QString imports;
foreach(const QString &s, importList) {
imports += s + "\n";
}
QDeclarativeContext *parentContext = engine()->contextForObject(parent);
QDeclarativeComponent component(engine(), this);
QByteArray constructedQml = QString(imports + qml).toLatin1();
component.setData(constructedQml, filename);
QObject *newObject = component.create(parentContext);
if (newObject) {
newObject->setParent(parent);
QDeclarativeItem *parentItem = dynamic_cast<QDeclarativeItem*>(parent);
QDeclarativeItem *newItem = dynamic_cast<QDeclarativeItem*>(newObject);
if (parentItem && newItem) {
newItem->setParentItem(parentItem);
}
}
}
QGraphicsItem *QDeclarativeDesignView::currentRootItem() const QGraphicsItem *QDeclarativeDesignView::currentRootItem() const
{ {
return m_subcomponentEditorTool->currentRootItem(); return m_subcomponentEditorTool->currentRootItem();

View File

@@ -93,6 +93,8 @@ private Q_SLOTS:
void onStatusChanged(QDeclarativeView::Status status); void onStatusChanged(QDeclarativeView::Status status);
void onCurrentObjectsChanged(QList<QObject*> objects); void onCurrentObjectsChanged(QList<QObject*> objects);
void applyChangesFromClient(); void applyChangesFromClient();
void createQmlObject(const QString &qml, QObject *parent,
const QStringList &imports, const QString &filename = QString());
private: private:
void clearEditorItems(); void clearEditorItems();
@@ -101,6 +103,7 @@ private:
QList<QGraphicsItem*> filterForCurrentContext(QList<QGraphicsItem*> &itemlist) const; QList<QGraphicsItem*> filterForCurrentContext(QList<QGraphicsItem*> &itemlist) const;
QList<QGraphicsItem*> filterForSelection(QList<QGraphicsItem*> &itemlist) const; QList<QGraphicsItem*> filterForSelection(QList<QGraphicsItem*> &itemlist) const;
private: private:
QPointF m_cursorPos; QPointF m_cursorPos;
QList<QWeakPointer<QGraphicsObject> > m_currentSelection; QList<QWeakPointer<QGraphicsObject> > m_currentSelection;