diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-05-08 00:48:55 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-05-08 00:48:55 (GMT) |
commit | bc20e3e0325f0f3395a6a2012cd263a724576ba1 (patch) | |
tree | af0d92073e2bff55c202c66dab08fb2f052b8e58 | |
parent | 93b289cb9d2ff48e5b894a0b91fa5372df399004 (diff) | |
parent | 3223c155b5fe6439a123350de5c25337b7d3af13 (diff) | |
download | Qt-bc20e3e0325f0f3395a6a2012cd263a724576ba1.zip Qt-bc20e3e0325f0f3395a6a2012cd263a724576ba1.tar.gz Qt-bc20e3e0325f0f3395a6a2012cd263a724576ba1.tar.bz2 |
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
26 files changed, 252 insertions, 97 deletions
diff --git a/demos/declarative/contacts/Contact.qml b/demos/declarative/contacts/Contact.qml index 342c356..7297fa6 100644 --- a/demos/declarative/contacts/Contact.qml +++ b/demos/declarative/contacts/Contact.qml @@ -52,6 +52,11 @@ Item { } ] + function refresh() { + labelField.value = label; + emailField.value = email; + phoneField.value = phone; + } function update() { updateContactQuery.exec(); } diff --git a/demos/declarative/contacts/ContactField.qml b/demos/declarative/contacts/ContactField.qml index 3ce2c1a..cb319ae 100644 --- a/demos/declarative/contacts/ContactField.qml +++ b/demos/declarative/contacts/ContactField.qml @@ -5,7 +5,7 @@ Item { property var label: "Name" property var icon: "pics/phone.png" property var value: "" - onValueChanged: { fieldText.text=field.value } + onValueChanged: { fieldText.text = contactField.value } RemoveButton { id: removeButton anchors.right: parent.right diff --git a/demos/declarative/contacts/contacts.qml b/demos/declarative/contacts/contacts.qml index ce5a2b5..4582bd1 100644 --- a/demos/declarative/contacts/contacts.qml +++ b/demos/declarative/contacts/contacts.qml @@ -39,9 +39,11 @@ Rect { children: [ MouseRegion { anchors.fill: parent - onClicked: { Details.qml = 'Contact.qml'; + onClicked: { + Details.qml = 'Contact.qml'; wrapper.state='opened'; - contacts.mode = 'edit'; } + contacts.mode = 'edit'; + } } ] } @@ -142,7 +144,7 @@ Rect { anchors.right: parent.right anchors.rightMargin: 5 icon: "pics/new.png" - onClicked: { print("open new contact edit"); newContactItem.label = ''; newContactItem.phone = ''; newContactItem.email = ''; contacts.mode = 'new' } + onClicked: { newContactItem.refresh(); contacts.mode = 'new' } opacity: contacts.mode == 'list' ? 1 : 0 } Button { @@ -174,10 +176,15 @@ Rect { delegate: contactDelegate focus: false } - Contact { - id: newContactItem + FocusRealm { + id: newContactWrapper anchors.fill: contactListView opacity: 0 + focus: contacts.mode == 'new' + Contact { + id: newContactItem + anchors.fill: parent + } } Connection { sender: confirmEditButton @@ -234,7 +241,7 @@ Rect { ] } KeyProxy { - focus: true + focus: contacts.mode != 'new' targets: { contacts.mode == "list" ? [searchBarWrapper, contactListView] : [contactListView]} } states: [ @@ -247,7 +254,7 @@ Rect { value: 0 } SetProperty { - target: newContactItem + target: newContactWrapper property: "opacity" value: 1 } diff --git a/demos/declarative/flickr/content/ImageDetails.qml b/demos/declarative/flickr/content/ImageDetails.qml index 955f85d..8677efc 100644 --- a/demos/declarative/flickr/content/ImageDetails.qml +++ b/demos/declarative/flickr/content/ImageDetails.qml @@ -3,6 +3,7 @@ Flipable { property var frontContainer: ContainerFront property var flickableArea: Flickable + property var slider: Slider property string photoTitle: "" property string photoDescription: "" property string photoTags: "" @@ -42,7 +43,7 @@ Flipable { LikeOMeter { x: 40; y: 250; rating: Container.rating } - Flickable { id: Flickable; x: 220; width: 480; height: 230; y: 120; clip: true + Flickable { id: Flickable; x: 220; width: 480; height: 210; y: 130; clip: true viewportWidth: 480; viewportHeight: DescriptionText.height WebView { id: DescriptionText; width: parent.width @@ -60,8 +61,9 @@ Flipable { text: "<b>Published:</b> " + Container.photoDate } Text { id: TagsLabel; color: "white"; x: 220; anchors.top: Date.bottom; text: Container.photoTags == "" ? "" : "<b>Tags:</b> " } - Text { id: Tags; color: "white"; width: parent.width-x-20; anchors.left: TagsLabel.right; anchors.top: Date.bottom; elide: "ElideRight" - text: Container.photoTags == "" ? "" : Container.photoTags } + Text { id: Tags; color: "white"; width: parent.width-x-20; + anchors.left: TagsLabel.right; anchors.top: Date.bottom; + elide: "ElideRight"; text: Container.photoTags } ScrollBar { id: ScrollBar; x: 720; y: Flickable.y; width: 7; height: Flickable.height; opacity: 0; flickableArea: Flickable; clip: true } @@ -95,7 +97,7 @@ Flipable { anchors.centeredIn: parent; color: "white"; font.bold: true } - Slider { id: Slider; x: 25; y: 374; imageWidth: Container.photoWidth; imageHeight: Container.photoHeight } + Slider { id: Slider; x: 25; y: 374; visible: BigImage.status == 0; imageWidth: Container.photoWidth; imageHeight: Container.photoHeight } } states: [ diff --git a/demos/declarative/flickr/content/Slider.qml b/demos/declarative/flickr/content/Slider.qml index ba9d842..c6a3e5e 100644 --- a/demos/declarative/flickr/content/Slider.qml +++ b/demos/declarative/flickr/content/Slider.qml @@ -3,6 +3,7 @@ Item { property var value: Handle.x / Slider.xMax property int xMax: Slider.width - Handle.width - 2 + property var handle: Handle property int imageWidth property int imageHeight diff --git a/demos/declarative/flickr/flickr.qml b/demos/declarative/flickr/flickr.qml index 85af8e3..dc150cb 100644 --- a/demos/declarative/flickr/flickr.qml +++ b/demos/declarative/flickr/flickr.qml @@ -58,6 +58,7 @@ Item { ImageDetails.photoDate = photoDate; ImageDetails.photoUrl = url; ImageDetails.rating = 0; + ImageDetails.slider.handle.x = ImageDetails.slider.xMax; Wrapper.state = "Details"; } } @@ -121,7 +122,7 @@ Item { Image { source: "content/pics/background.png"; opaque: true } GridView { - id: PhotoGridView; model: FeedModel; delegate: PhotoDelegate + id: PhotoGridView; model: FeedModel; delegate: PhotoDelegate; cacheBuffer: 100 cellWidth: 105; cellHeight: 105; x:32; y: 80; width: 800; height: 330; z: 1 } diff --git a/demos/declarative/flickr/flickr2.qml b/demos/declarative/flickr/flickr2.qml index 4875fa4..3b1208c 100644 --- a/demos/declarative/flickr/flickr2.qml +++ b/demos/declarative/flickr/flickr2.qml @@ -143,29 +143,31 @@ Item { ] transitions: [ Transition { - fromState: "*" - toState: "*" + fromState: "left" + toState: "right" SequentialAnimation { SetPropertyAction { target: Wrapper property: "moveToParent" - value: Bounce } ParallelAnimation { NumericAnimation { target: Wrapper - properties: "x" + properties: "x,y" to: 0 - duration: 250 - } - NumericAnimation { - target: Wrapper - properties: "y" - to: 0 - easing: "easeInQuad" - duration: 250 + easing: "easeOutQuad" + duration: 350 } } + } + }, + Transition { + fromState: "right" + toState: "left" + SequentialAnimation { + PauseAnimation { + duration: Math.floor(index/7)*100 + } SetPropertyAction { target: Wrapper property: "moveToParent" @@ -173,13 +175,7 @@ Item { ParallelAnimation { NumericAnimation { target: Wrapper - properties: "x" - to: 0 - duration: 250 - } - NumericAnimation { - target: Wrapper - properties: "y" + properties: "x,y" to: 0 easing: "easeOutQuad" duration: 250 @@ -203,14 +199,20 @@ Item { GridView { id: PhotoGridView; model: MyVisualModel.parts.leftBox cellWidth: 105; cellHeight: 105; x:32; y: 80; width: 800; height: 330; z: 1 + cacheBuffer: 100 } PathView { id: PhotoPathView; model: MyVisualModel.parts.rightBox y: 80; width: 800; height: 330; z: 1 + pathItemCount: 10; snapPosition: 0.001 path: Path { - startX: -50; startY: 40; + startX: -150; startY: 40; + PathPercent { value: 0 } + PathLine { x: -50; y: 40 } + + PathPercent { value: 0.001 } PathAttribute { name: "scale"; value: 1 } PathAttribute { name: "angle"; value: -45 } @@ -232,6 +234,10 @@ Item { PathAttribute { name: "scale"; value: 1 } PathAttribute { name: "angle"; value: -45 } + + PathPercent { value: 0.999 } + PathLine { x: 950; y: 40 } + PathPercent { value: 1.0 } } } diff --git a/src/declarative/canvas/qsimplecanvas_graphicsview.cpp b/src/declarative/canvas/qsimplecanvas_graphicsview.cpp index dd4012b..5c6f2f5 100644 --- a/src/declarative/canvas/qsimplecanvas_graphicsview.cpp +++ b/src/declarative/canvas/qsimplecanvas_graphicsview.cpp @@ -110,7 +110,6 @@ void QSimpleGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) p = p->parent(); } owner->mouseReleaseEvent(event); - ungrabMouse(); } void QSimpleGraphicsItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) diff --git a/src/declarative/fx/qfxblendedimage.cpp b/src/declarative/fx/qfxblendedimage.cpp index 3326ea8..79b8e41 100644 --- a/src/declarative/fx/qfxblendedimage.cpp +++ b/src/declarative/fx/qfxblendedimage.cpp @@ -101,7 +101,7 @@ void QFxBlendedImage::setPrimaryUrl(const QString &url) if (primSrc == url) return; if (!primSrc.isEmpty()) - QFxPixmap::cancelGet(primUrl,this,SLOT(primaryLoaded())); + QFxPixmap::cancelGet(primUrl,this); primSrc = url; primUrl = qmlContext(this)->resolvedUrl(url); if (!primSrc.isEmpty()) @@ -129,7 +129,7 @@ void QFxBlendedImage::setSecondaryUrl(const QString &url) if (secSrc == url) return; if (!secSrc.isEmpty()) - QFxPixmap::cancelGet(secUrl,this,SLOT(secondaryLoaded())); + QFxPixmap::cancelGet(secUrl,this); secSrc = url; secUrl = qmlContext(this)->resolvedUrl(url); if (!secSrc.isEmpty()) diff --git a/src/declarative/fx/qfxhighlightfilter.cpp b/src/declarative/fx/qfxhighlightfilter.cpp index 862a698..a22ad98 100644 --- a/src/declarative/fx/qfxhighlightfilter.cpp +++ b/src/declarative/fx/qfxhighlightfilter.cpp @@ -149,7 +149,7 @@ void QFxHighlightFilter::setSource(const QString &f) if (d->source == f) return; if (!d->source.isEmpty()) - QFxPixmap::cancelGet(d->url, this, SLOT(imageLoaded())); + QFxPixmap::cancelGet(d->url, this); d->source = f; d->url = qmlContext(this)->resolvedUrl(f); #if defined(QFX_RENDER_OPENGL2) diff --git a/src/declarative/fx/qfximage.cpp b/src/declarative/fx/qfximage.cpp index d66846d..e1ac2c7 100644 --- a/src/declarative/fx/qfximage.cpp +++ b/src/declarative/fx/qfximage.cpp @@ -865,9 +865,9 @@ void QFxImage::setSource(const QString &url) } if (!d->url.isEmpty()) - QFxPixmap::cancelGet(d->url, this, SLOT(requestFinished())); + QFxPixmap::cancelGet(d->url, this); if (!d->sciurl.isEmpty()) - QFxPixmap::cancelGet(d->sciurl, this, SLOT(requestFinished())); + QFxPixmap::cancelGet(d->sciurl, this); d->source = url; d->url = qmlContext(this)->resolvedUrl(url); diff --git a/src/declarative/fx/qfxparticles.cpp b/src/declarative/fx/qfxparticles.cpp index 8535a73..1aaf256 100644 --- a/src/declarative/fx/qfxparticles.cpp +++ b/src/declarative/fx/qfxparticles.cpp @@ -635,7 +635,7 @@ void QFxParticles::setSource(const QString &name) return; if (!d->source.isEmpty()) - QFxPixmap::cancelGet(d->url, this, SLOT(imageLoaded())); + QFxPixmap::cancelGet(d->url, this); if (name.isEmpty()) { d->source = name; d->url = QUrl(); diff --git a/src/declarative/fx/qfxpathview.cpp b/src/declarative/fx/qfxpathview.cpp index 715ae5a..2b39d6e 100644 --- a/src/declarative/fx/qfxpathview.cpp +++ b/src/declarative/fx/qfxpathview.cpp @@ -145,7 +145,7 @@ QFxPathView::~QFxPathView() QVariant QFxPathView::model() const { Q_D(const QFxPathView); - return d->model ? d->model->model() : QVariant(); + return d->modelVariant; } void QFxPathView::setModel(const QVariant &model) @@ -154,13 +154,24 @@ void QFxPathView::setModel(const QVariant &model) if (d->model) { disconnect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int))); disconnect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int))); + disconnect(d->model, SIGNAL(itemCreated(int, QFxItem*)), this, SLOT(itemCreated(int,QFxItem*))); + for (int i=0; i<d->items.count(); i++){ + QFxItem *p = d->items[i]; + attachedProperties.remove(p); + d->model->release(p); + } + d->items.clear(); } - if (QFxVisualItemModel *m = qvariant_cast<QFxVisualItemModel*>(model)) { + + d->modelVariant = model; + QObject *object = qvariant_cast<QObject*>(model); + QFxVisualItemModel *vim = 0; + if (object && (vim = qobject_cast<QFxVisualItemModel *>(object))) { if (d->ownModel) { delete d->model; d->ownModel = false; } - d->model = m; + d->model = vim; } else { if (!d->ownModel) { d->model = new QFxVisualItemModel(qmlContext(this)); @@ -171,6 +182,7 @@ void QFxPathView::setModel(const QVariant &model) if (d->model) { connect(d->model, SIGNAL(itemsInserted(int,int)), this, SLOT(itemsInserted(int,int))); connect(d->model, SIGNAL(itemsRemoved(int,int)), this, SLOT(itemsRemoved(int,int))); + connect(d->model, SIGNAL(itemCreated(int, QFxItem*)), this, SLOT(itemCreated(int,QFxItem*))); } d->firstIndex = 0; d->pathOffset = 0; @@ -550,7 +562,7 @@ void QFxPathViewPrivate::regenerate() } items.clear(); - if (!model || model->count() <= 0 || !model->delegate() || !path) + if (!isValid()) return; if (firstIndex >= model->count()) @@ -560,14 +572,14 @@ void QFxPathViewPrivate::regenerate() int numItems = pathItems >= 0 ? pathItems : model->count(); for (int i=0; i < numItems && i < model->count(); ++i){ - QFxItem *item = model->item((i + firstIndex) % model->count()); - if (!item) + QFxItem *item = getItem((i + firstIndex) % model->count()); + if (!item) { + qWarning() << "PathView: Cannot create item, index" << (i + firstIndex) % model->count(); return; + } items.append(item); item->setZ(i); - item->setParent(q); } - q->refill(); } @@ -577,7 +589,6 @@ void QFxPathViewPrivate::updateItem(QFxItem *item, qreal percent) foreach(const QString &attr, path->attributes()) static_cast<QFxPathViewAttached *>(obj)->setValue(attr.toLatin1(), path->attributeAt(attr, percent)); } - QPointF pf = path->pointAt(percent); item->setX(pf.x() - item->width()*item->scale()/2); item->setY(pf.y() - item->height()*item->scale()/2); @@ -586,7 +597,7 @@ void QFxPathViewPrivate::updateItem(QFxItem *item, qreal percent) void QFxPathView::refill() { Q_D(QFxPathView); - if (!d->model || d->model->count() <= 0) + if (!d->isValid()) return; QList<qreal> positions; @@ -619,28 +630,28 @@ void QFxPathView::refill() if (wrapIndex < d->items.count()/2){ while(wrapIndex-- >= 0){ QFxItem* p = d->items.takeFirst(); + d->updateItem(p, 0.0); attachedProperties.remove(p); d->model->release(p); d->firstIndex++; d->firstIndex %= d->model->count(); int index = (d->firstIndex + d->items.count())%d->model->count(); - d->items << d->model->item(index); + d->items << d->getItem(index); d->items.last()->setZ(wrapIndex); - d->items.last()->setParent(this); d->pathOffset++; d->pathOffset=d->pathOffset % d->items.count(); } } else { while(wrapIndex++ < d->items.count()-1){ QFxItem* p = d->items.takeLast(); + d->updateItem(p, 1.0); attachedProperties.remove(p); d->model->release(p); d->firstIndex--; if (d->firstIndex < 0) d->firstIndex = d->model->count() - 1; - d->items.prepend(d->model->item(d->firstIndex)); + d->items.prepend(d->getItem(d->firstIndex)); d->items.first()->setZ(d->firstIndex); - d->items.first()->setParent(this); d->pathOffset--; if (d->pathOffset < 0) d->pathOffset = d->items.count() - 1; @@ -658,11 +669,12 @@ void QFxPathView::itemsInserted(int modelIndex, int count) { //XXX support animated insertion Q_D(QFxPathView); + if (!d->isValid()) + return; if (d->pathItems == -1) { for (int i = 0; i < count; ++i) { - QFxItem *item = d->model->item(modelIndex + i); + QFxItem *item = d->getItem(modelIndex + i); item->setZ(modelIndex + i); - item->setParent(this); d->items.insert(modelIndex + i, item); } refill(); @@ -687,6 +699,8 @@ void QFxPathView::itemsRemoved(int modelIndex, int count) { //XXX support animated removal Q_D(QFxPathView); + if (!d->isValid()) + return; if (d->pathItems == -1) { for (int i = 0; i < count; ++i) { QFxItem* p = d->items.takeAt(modelIndex); @@ -719,6 +733,19 @@ void QFxPathView::itemsRemoved(int modelIndex, int count) d->moveOffset.setValue(targetOffset); } +void QFxPathView::itemCreated(int index, QFxItem *item) +{ + Q_D(QFxPathView); + if (d->requestedIndex != index) { + item->setItemParent(this); + d->updateItem(item, index < d->firstIndex ? 0.0 : 1.0); + } +} + +void QFxPathView::destroyingItem(QFxItem *item) +{ +} + void QFxPathView::ticked() { Q_D(QFxPathView); diff --git a/src/declarative/fx/qfxpathview.h b/src/declarative/fx/qfxpathview.h index 23f2f07..0e1ac6f 100644 --- a/src/declarative/fx/qfxpathview.h +++ b/src/declarative/fx/qfxpathview.h @@ -115,6 +115,8 @@ private Q_SLOTS: void ticked(); void itemsInserted(int index, int count); void itemsRemoved(int index, int count); + void itemCreated(int index, QFxItem *item); + void destroyingItem(QFxItem *item); protected: QFxPathView(QFxPathViewPrivate &dd, QFxItem *parent); diff --git a/src/declarative/fx/qfxpathview_p.h b/src/declarative/fx/qfxpathview_p.h index a19d778..358daf6 100644 --- a/src/declarative/fx/qfxpathview_p.h +++ b/src/declarative/fx/qfxpathview_p.h @@ -77,7 +77,7 @@ public: : path(0), currentIndex(0), startPc(0), lastDist(0) , lastElapsed(0), stealMouse(false), ownModel(false), activeItem(0) , snapPos(0), dragMargin(0), moveOffset(this, &QFxPathViewPrivate::setOffset) - , firstIndex(0), pathItems(-1), pathOffset(0), model(0) + , firstIndex(0), pathItems(-1), pathOffset(0), requestedIndex(-1), model(0) , moveReason(Other) { fixupOffsetEvent = QmlTimeLineEvent::timeLineEvent<QFxPathViewPrivate, &QFxPathViewPrivate::fixOffset>(&moveOffset, this); @@ -92,6 +92,20 @@ public: q->connect(&tl, SIGNAL(updated()), q, SLOT(ticked())); } + QFxItem *getItem(int modelIndex) { + Q_Q(QFxPathView); + requestedIndex = modelIndex; + QFxItem *item = model->item(modelIndex); + if (item) + item->setItemParent(q); + requestedIndex = -1; + return item; + } + + bool isValid() const { + return model && model->count() > 0 && model->delegate() && path; + } + int calcCurrentIndex(); void updateCurrent(); void fixOffset(); @@ -108,8 +122,8 @@ public: qreal lastDist; int lastElapsed; qreal _offset; - int stealMouse : 1; - int ownModel : 1; + bool stealMouse : 1; + bool ownModel : 1; QTime lastPosTime; QPointF lastPos; QFxItem *activeItem; @@ -121,6 +135,7 @@ public: int firstIndex; int pathItems; int pathOffset; + int requestedIndex; QList<QFxItem *> items; QFxVisualItemModel *model; QVariant modelVariant; diff --git a/src/declarative/fx/qfxpixmap.cpp b/src/declarative/fx/qfxpixmap.cpp index 3fdd8e5..0e5a10f 100644 --- a/src/declarative/fx/qfxpixmap.cpp +++ b/src/declarative/fx/qfxpixmap.cpp @@ -275,15 +275,18 @@ QNetworkReply *QFxPixmap::get(QmlEngine *engine, const QUrl& url, QObject* obj, /*! Stops the given slot being invoked if the given url finishes loading. May also cancel loading (eg. if no other pending request). + + Any connections to the QNetworkReply returned by get() will be + disconnected. */ -void QFxPixmap::cancelGet(const QUrl& url, QObject* obj, const char* slot) +void QFxPixmap::cancelGet(const QUrl& url, QObject* obj) { QString key = url.toString(); QFxPixmapCache::Iterator iter = qfxPixmapCache.find(key); if (iter == qfxPixmapCache.end()) return; if ((*iter)->reply) - QObject::disconnect((*iter)->reply, SIGNAL(finished()), obj, slot); + QObject::disconnect((*iter)->reply, 0, obj, 0); // XXX - loading not cancelled. Need to revisit caching } diff --git a/src/declarative/fx/qfxpixmap.h b/src/declarative/fx/qfxpixmap.h index 748991e..297dba7 100644 --- a/src/declarative/fx/qfxpixmap.h +++ b/src/declarative/fx/qfxpixmap.h @@ -67,7 +67,7 @@ public: QFxPixmap &operator=(const QFxPixmap &); static QNetworkReply *get(QmlEngine *, const QUrl& url, QObject*, const char* slot); - static void cancelGet(const QUrl& url, QObject* obj, const char* slot); + static void cancelGet(const QUrl& url, QObject* obj); bool isNull() const; diff --git a/src/declarative/fx/qfxvisualitemmodel.cpp b/src/declarative/fx/qfxvisualitemmodel.cpp index 7d0d7a5..9428281 100644 --- a/src/declarative/fx/qfxvisualitemmodel.cpp +++ b/src/declarative/fx/qfxvisualitemmodel.cpp @@ -336,6 +336,10 @@ void QFxVisualItemModel::setModel(const QVariant &model) this, SIGNAL(itemsRemoved(int,int))); QObject::disconnect(d->m_visualItemModel, SIGNAL(itemsMoved(int,int,int)), this, SIGNAL(itemsMoved(int,int,int))); + QObject::disconnect(d->m_visualItemModel, SIGNAL(packageCreated(int,QmlPackage*)), + this, SLOT(_q_packageCreated(int,QmlPackage*))); + QObject::disconnect(d->m_visualItemModel, SIGNAL(destroyingPackage(QmlPackage*)), + this, SLOT(_q_destroyingPackage(QmlPackage*))); d->m_visualItemModel = 0; } @@ -385,6 +389,10 @@ void QFxVisualItemModel::setModel(const QVariant &model) this, SIGNAL(itemsRemoved(int,int))); QObject::connect(d->m_visualItemModel, SIGNAL(itemsMoved(int,int,int)), this, SIGNAL(itemsMoved(int,int,int))); + QObject::connect(d->m_visualItemModel, SIGNAL(packageCreated(int,QmlPackage*)), + this, SLOT(_q_packageCreated(int,QmlPackage*))); + QObject::connect(d->m_visualItemModel, SIGNAL(destroyingPackage(QmlPackage*)), + this, SLOT(_q_destroyingPackage(QmlPackage*))); return; } if (!d->m_modelList) @@ -397,6 +405,8 @@ void QFxVisualItemModel::setModel(const QVariant &model) QmlComponent *QFxVisualItemModel::delegate() const { Q_D(const QFxVisualItemModel); + if (d->m_visualItemModel) + return d->m_visualItemModel->delegate(); return d->m_delegate; } @@ -404,7 +414,6 @@ void QFxVisualItemModel::setDelegate(QmlComponent *delegate) { Q_D(QFxVisualItemModel); d->m_delegate = delegate; - if (d->modelCount()) emit itemsInserted(0, d->modelCount()); } @@ -445,6 +454,7 @@ void QFxVisualItemModel::release(QFxItem *item) item->setItemParent(0); QObject *obj = item; + bool inPackage = false; if (QmlPackage *package = d->m_packaged.value(item)) { static_cast<QObject*>(item)->setParent(package); d->m_packaged.remove(item); @@ -454,6 +464,7 @@ void QFxVisualItemModel::release(QFxItem *item) if (*iter == package) return; } + inPackage = true; obj = package; // fall through and delete } @@ -461,6 +472,8 @@ void QFxVisualItemModel::release(QFxItem *item) for (QHash<int, QObject *>::Iterator iter = d->m_cache.begin(); iter != d->m_cache.end(); ++iter) { if (*iter == obj) { + if (inPackage) + emit destroyingPackage(qobject_cast<QmlPackage*>(obj)); delete obj; d->m_cache.erase(iter); return; @@ -511,6 +524,7 @@ QFxItem *QFxVisualItemModel::item(int index, const QByteArray &viewId, bool comp QObject *o = package->part(QLatin1String(viewId)); item = qobject_cast<QFxItem *>(o); d->m_packaged[o] = package; + emit packageCreated(index, package); } } @@ -688,6 +702,18 @@ void QFxVisualItemModel::_q_dataChanged(const QModelIndex &begin, const QModelIn _q_itemsChanged(begin.row(), end.row() - begin.row() + 1, d->m_roles); } +void QFxVisualItemModel::_q_packageCreated(int index, QmlPackage *package) +{ + Q_D(QFxVisualItemModel); + emit itemCreated(index, qobject_cast<QFxItem*>(package->part(d->m_part))); +} + +void QFxVisualItemModel::_q_destroyingPackage(QmlPackage *package) +{ + Q_D(QFxVisualItemModel); + emit destroyingItem(qobject_cast<QFxItem*>(package->part(d->m_part))); +} + QML_DEFINE_TYPE(QFxVisualItemModel,VisualModel); QT_END_NAMESPACE diff --git a/src/declarative/fx/qfxvisualitemmodel.h b/src/declarative/fx/qfxvisualitemmodel.h index 5ec42e9..33017e2 100644 --- a/src/declarative/fx/qfxvisualitemmodel.h +++ b/src/declarative/fx/qfxvisualitemmodel.h @@ -60,6 +60,7 @@ QT_MODULE(Declarative) class QFxItem; class QmlComponent; +class QmlPackage; class QFxVisualItemModelPrivate; class QFxVisualItemModel : public QObject { @@ -98,6 +99,10 @@ Q_SIGNALS: void itemsInserted(int index, int count); void itemsRemoved(int index, int count); void itemsMoved(int from, int to, int count); + void itemCreated(int index, QFxItem *item); + void packageCreated(int index, QmlPackage *package); + void destroyingItem(QFxItem *item); + void destroyingPackage(QmlPackage *package); private Q_SLOTS: void _q_itemsChanged(int, int, const QList<int> &); @@ -107,6 +112,8 @@ private Q_SLOTS: void _q_rowsInserted(const QModelIndex &,int,int); void _q_rowsRemoved(const QModelIndex &,int,int); void _q_dataChanged(const QModelIndex&,const QModelIndex&); + void _q_packageCreated(int index, QmlPackage *package); + void _q_destroyingPackage(QmlPackage *package); private: Q_DISABLE_COPY(QFxVisualItemModel) diff --git a/src/declarative/qml/qmldom.cpp b/src/declarative/qml/qmldom.cpp index 689446b..a31be81 100644 --- a/src/declarative/qml/qmldom.cpp +++ b/src/declarative/qml/qmldom.cpp @@ -149,16 +149,15 @@ int QmlDomDocument::version() const \sa QmlDomDocument::save() QmlDomDocument::loadError() */ -bool QmlDomDocument::load(QmlEngine *engine, const QByteArray &data) +bool QmlDomDocument::load(QmlEngine *engine, const QByteArray &data, const QUrl &url) { Q_UNUSED(engine); - d->errors.clear(); QmlCompiledComponent component; QmlCompiler compiler; - QmlCompositeTypeData *td = ((QmlEnginePrivate *)QmlEnginePrivate::get(engine))->typeManager.getImmediate(data, QUrl());; + QmlCompositeTypeData *td = ((QmlEnginePrivate *)QmlEnginePrivate::get(engine))->typeManager.getImmediate(data, url);; if(td->status == QmlCompositeTypeData::Error) { d->errors = td->errors; diff --git a/src/declarative/qml/qmldom.h b/src/declarative/qml/qmldom.h index daca888..f90fb08 100644 --- a/src/declarative/qml/qmldom.h +++ b/src/declarative/qml/qmldom.h @@ -73,7 +73,7 @@ public: int version() const; QList<QmlError> errors() const; - bool load(QmlEngine *, const QByteArray &); + bool load(QmlEngine *, const QByteArray &, const QUrl & = QUrl()); QByteArray save() const; QmlDomObject rootObject() const; diff --git a/tests/auto/declarative/qmldom/qmldom.pro b/tests/auto/declarative/qmldom/qmldom.pro index 5294cb4..d566354 100644 --- a/tests/auto/declarative/qmldom/qmldom.pro +++ b/tests/auto/declarative/qmldom/qmldom.pro @@ -1,3 +1,5 @@ load(qttest_p4) contains(QT_CONFIG,declarative): QT += declarative SOURCES += tst_qmldom.cpp + +DEFINES += SRCDIR=\\\"$$PWD\\\" diff --git a/tests/auto/declarative/qmldom/tst_qmldom.cpp b/tests/auto/declarative/qmldom/tst_qmldom.cpp index 36d37f6..ca8929d 100644 --- a/tests/auto/declarative/qmldom/tst_qmldom.cpp +++ b/tests/auto/declarative/qmldom/tst_qmldom.cpp @@ -4,6 +4,7 @@ #include <QtDeclarative/qmldom.h> #include <QtCore/QDebug> +#include <QtCore/QFile> class tst_qmldom : public QObject { @@ -15,6 +16,7 @@ private slots: void loadSimple(); void loadProperties(); void loadChildObject(); + void loadComposite(); void testValueSource(); @@ -30,7 +32,7 @@ void tst_qmldom::loadSimple() QmlDomDocument document; QVERIFY(document.load(&engine, qml)); - QVERIFY(document.loadError().isEmpty()); + QVERIFY(document.errors().isEmpty()); QmlDomObject rootObject = document.rootObject(); QVERIFY(rootObject.isValid()); @@ -87,6 +89,27 @@ void tst_qmldom::loadChildObject() QVERIFY(childItem.objectType() == "Item"); } +void tst_qmldom::loadComposite() +{ + QFile file(SRCDIR "/top.qml"); + QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); + + QmlDomDocument document; + QVERIFY(document.load(&engine, file.readAll(), QUrl::fromLocalFile(file.fileName()))); + QVERIFY(document.errors().isEmpty()); + + QmlDomObject rootItem = document.rootObject(); + QVERIFY(rootItem.isValid()); + QCOMPARE(rootItem.objectType(), QByteArray("MyComponent")); + QCOMPARE(rootItem.properties().size(), 2); + + QmlDomProperty widthProperty = rootItem.property("width"); + QVERIFY(widthProperty.value().isLiteral()); + + QmlDomProperty heightProperty = rootItem.property("height"); + QVERIFY(heightProperty.value().isLiteral()); +} + void tst_qmldom::testValueSource() { QByteArray qml = "Rect { height: Follow { spring: 1.4; damping: .15; source: Math.min(Math.max(-130, value*2.2 - 130), 133); }}"; diff --git a/tools/qmlviewer/main.cpp b/tools/qmlviewer/main.cpp index 3f74ef6..379fda9 100644 --- a/tools/qmlviewer/main.cpp +++ b/tools/qmlviewer/main.cpp @@ -26,7 +26,7 @@ void usage() qWarning(" -v, -version ............................. display version"); qWarning(" -frameless ............................... run with no window frame"); qWarning(" -skin <qvfbskindir> ...................... run with a skin window frame"); - qWarning(" -recordfile <output> ..................... set output file"); + qWarning(" -recordfile <output> ..................... set video recording file"); qWarning(" - ImageMagick 'convert' for GIF)"); qWarning(" - png file for raw frames"); qWarning(" - 'ffmpeg' for other formats"); @@ -69,7 +69,7 @@ int main(int argc, char ** argv) int autorecord_from = 0; int autorecord_to = 0; QString dither = "none"; - QString recordfile = "animation.gif"; + QString recordfile; QString skin; bool devkeys = false; bool cache = false; diff --git a/tools/qmlviewer/qmlviewer.cpp b/tools/qmlviewer/qmlviewer.cpp index 04054ec..8457972 100644 --- a/tools/qmlviewer/qmlviewer.cpp +++ b/tools/qmlviewer/qmlviewer.cpp @@ -31,6 +31,7 @@ #include <QFile> #include <QFileInfo> #include <QVBoxLayout> +#include <QProgressDialog> #include <QProcess> #include <QMenuBar> #include <QMenu> @@ -86,15 +87,15 @@ void QmlViewer::createMenuBar() fileMenu->addSeparator(); fileMenu->addAction(quitAction); - /*QMenu *recordMenu = menuBar()->addMenu(tr("&Recording")); + QMenu *recordMenu = menuBar()->addMenu(tr("&Recording")); - QAction *snapshotAction = new QAction(tr("&Take Snapsot"), this); + QAction *snapshotAction = new QAction(tr("&Take Snapsot\tF3"), this); connect(snapshotAction, SIGNAL(triggered()), this, SLOT(takeSnapShot())); recordMenu->addAction(snapshotAction); - recordAction = new QAction(tr("&Start Recording Video"), this); - connect(recordAction, SIGNAL(triggered()), this, SLOT(toggleRecording())); - recordMenu->addAction(recordAction);*/ + recordAction = new QAction(tr("Start Recording &Video\tF2"), this); + connect(recordAction, SIGNAL(triggered()), this, SLOT(toggleRecordingWithSelection())); + recordMenu->addAction(recordAction); QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); QAction *aboutAction = new QAction(tr("&About Qt..."), this); @@ -111,13 +112,31 @@ void QmlViewer::takeSnapShot() ++snapshotcount; } +void QmlViewer::toggleRecordingWithSelection() +{ + if (!recordTimer.isActive()) { + QString fileName = QFileDialog::getSaveFileName(this, tr("Save Video File"), "", tr("Common Video files (*.avi *.mpeg *.mov);; GIF Animation (*.gif);; Individual PNG frames (*.png);; All ffmpeg formats (*.*)")); + if (fileName.isEmpty()) + return; + if (!fileName.contains(QRegExp(".[^\\/]*$"))) + fileName += ".avi"; + setRecordFile(fileName); + } + toggleRecording(); +} + void QmlViewer::toggleRecording() { - bool recording = recordTimer.isActive(); - //recordAction->setText(recording ? tr("&Start Recording Video") : tr("&End Recording Video")); - setRecording(!recording); + if (record_file.isEmpty()) { + toggleRecordingWithSelection(); + return; + } + bool recording = !recordTimer.isActive(); + recordAction->setText(recording ? tr("&Stop Recording Video\tF2") : tr("&Start Recording Video\tF2")); + setRecording(recording); } + void QmlViewer::reload() { openQml(currentFileName); @@ -389,6 +408,9 @@ void QmlViewer::setRecording(bool on) frame_stream->close(); qDebug() << "Wrote" << record_file; } else { + QProgressDialog progress(tr("Saving frames..."), tr("Cancel"), 0, frames.count()+10, this); + progress.setWindowModality(Qt::WindowModal); + int frame=0; QStringList inputs; qDebug() << "Saving frames..."; @@ -406,6 +428,9 @@ void QmlViewer::setRecording(bool on) png_output = false; } foreach (QImage* img, frames) { + progress.setValue(progress.value()+1); + if (progress.wasCanceled()) + break; QString name; name.sprintf(framename.toLocal8Bit(),frame++); if (record_dither=="ordered") @@ -420,31 +445,35 @@ void QmlViewer::setRecording(bool on) delete img; } - if (png_output) { - framename.replace(QRegExp("%\\d*."),"*"); - qDebug() << "Wrote frames" << framename; - inputs.clear(); // don't remove them - } else { - // ImageMagick and gifsicle for GIF encoding - QStringList args; - args << "-delay" << QString::number(record_period/10); - args << inputs; - args << record_file; - qDebug() << "Converting..." << record_file << "(this may take a while)"; - if (0!=QProcess::execute("convert", args)) { - qWarning() << "Cannot run ImageMagick 'convert' - recorded frames not converted"; + if (!progress.wasCanceled()) { + if (png_output) { + framename.replace(QRegExp("%\\d*."),"*"); + qDebug() << "Wrote frames" << framename; inputs.clear(); // don't remove them - qDebug() << "Wrote frames tmp-frame*.png"; } else { - if (record_file.right(4).toLower() == ".gif") { - qDebug() << "Compressing..." << record_file; - if (0!=QProcess::execute("gifsicle", QStringList() << "-O2" << "-o" << record_file << record_file)) - qWarning() << "Cannot run 'gifsicle' - not compressed"; + // ImageMagick and gifsicle for GIF encoding + progress.setLabelText(tr("Converting frames to GIF file...")); + QStringList args; + args << "-delay" << QString::number(record_period/10); + args << inputs; + args << record_file; + qDebug() << "Converting..." << record_file << "(this may take a while)"; + if (0!=QProcess::execute("convert", args)) { + qWarning() << "Cannot run ImageMagick 'convert' - recorded frames not converted"; + inputs.clear(); // don't remove them + qDebug() << "Wrote frames tmp-frame*.png"; + } else { + if (record_file.right(4).toLower() == ".gif") { + qDebug() << "Compressing..." << record_file; + if (0!=QProcess::execute("gifsicle", QStringList() << "-O2" << "-o" << record_file << record_file)) + qWarning() << "Cannot run 'gifsicle' - not compressed"; + } + qDebug() << "Wrote" << record_file; } - qDebug() << "Wrote" << record_file; } } + progress.setValue(progress.maximum()-1); foreach (QString name, inputs) QFile::remove(name); diff --git a/tools/qmlviewer/qmlviewer.h b/tools/qmlviewer/qmlviewer.h index 405e8d9..fc8a427 100644 --- a/tools/qmlviewer/qmlviewer.h +++ b/tools/qmlviewer/qmlviewer.h @@ -50,6 +50,7 @@ public slots: void reload(); void takeSnapShot(); void toggleRecording(); + void toggleRecordingWithSelection(); protected: virtual void keyPressEvent(QKeyEvent *); |