From d9a73e5b8e344d6bf89dd602c21cbbbd17b7836f Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 7 May 2009 09:08:44 +1000 Subject: Doc. --- src/declarative/util/qmllistmodel.cpp | 68 +++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/src/declarative/util/qmllistmodel.cpp b/src/declarative/util/qmllistmodel.cpp index 1cd2f69..8184bda 100644 --- a/src/declarative/util/qmllistmodel.cpp +++ b/src/declarative/util/qmllistmodel.cpp @@ -93,8 +93,7 @@ Q_DECLARE_METATYPE(QListModelInterface *); } \endcode - Elements beginning with a capital are items. Elements beginning - with lower-case are the data roles. The above example defines a + Item roles (properties) must begin with a lower-case letter. The above example defines a ListModel containing three items, with the roles "name" and "cost". The defined model can be used in views such as ListView: @@ -102,15 +101,9 @@ Q_DECLARE_METATYPE(QListModelInterface *); Component { id: FruitDelegate Item { - width: 200 - height: 50 - Text { - text: name - } - Text { - text: '$'+cost - anchors.right: parent.right - } + width: 200; height: 50 + Text { text: name } + Text { text: '$'+cost; anchors.right: parent.right } } } @@ -120,6 +113,59 @@ Q_DECLARE_METATYPE(QListModelInterface *); anchors.fill: parent } \endcode + + It is possible for roles to contain list data. In the example below we create a list of fruit attributes: + + \code + ListModel { + id: FruitModel + ListElement { + name: "Apple" + cost: 2.45 + attributes: [ + ListElement { description: "Core" }, + ListElement { description: "Deciduous" } + ] + } + ListElement { + name: "Orange" + cost: 3.25 + attributes: [ + ListElement { description: "Citrus" } + ] + } + ListElement { + name: "Banana" + cost: 1.95 + attributes: [ + ListElement { description: "Tropical" } + ListElement { description: "Seedless" } + ] + } + } + \endcode + + The delegate below will list all the fruit attributes: + \code + Component { + id: FruitDelegate + Item { + width: 200; height: 50 + Text { id: Name; text: name } + Text { text: '$'+cost; anchors.right: parent.right } + HorizontalLayout { + anchors.top: Name.bottom + spacing: 5 + Text { text: "Attributes:" } + Repeater { + dataSource: attributes + Component { Text { text: description } } + } + } + } + } + \endcode + */ struct ModelNode; -- cgit v0.12 From 7825c0e89fffc1a41d71e5e7a791b10d3c182e32 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 7 May 2009 10:42:43 +1000 Subject: Use correct 'from' value for repeating animations. Each loop, we need to check whether the user has set a from value, and if not get the current value. --- doc/src/declarative/animation.qdoc | 17 ++++++----------- src/declarative/util/qmlanimation.cpp | 3 +++ src/declarative/util/qmlanimation_p.h | 14 +++++++++++--- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/doc/src/declarative/animation.qdoc b/doc/src/declarative/animation.qdoc index f7e03ee..f17f5c9 100644 --- a/doc/src/declarative/animation.qdoc +++ b/doc/src/declarative/animation.qdoc @@ -25,7 +25,7 @@ Other Features: \o Animation synchronization \endlist -The simplest form of animation is using \c NumericAnimation +The simplest form of animation is using \l NumericAnimation The following example creates a bouncing effect: \code @@ -34,20 +34,15 @@ Rect { width: 120; height: 200; color: "white" Image { id: img - source: "pics/qtlogo.png" + source: "qt-logo.png" x: 60-img.width/2 - y: 200-img.height + y: 0 y: SequentialAnimation { running: true repeat: true - NumericAnimation { - to: 200-img.height - easing: "easeOutBounce(amplitude:100)" - duration: 2000 - } - PauseAnimation { - duration: 1000 - } + NumericAnimation { to: 200-img.height; easing: "easeOutBounce"; duration: 2000 } + PauseAnimation { duration: 1000 } + NumericAnimation { to: 0; easing: "easeOutQuad"; duration: 1000 } } } } diff --git a/src/declarative/util/qmlanimation.cpp b/src/declarative/util/qmlanimation.cpp index 08a7a28..dd4e1eb 100644 --- a/src/declarative/util/qmlanimation.cpp +++ b/src/declarative/util/qmlanimation.cpp @@ -791,6 +791,7 @@ void QmlColorAnimation::prepare(QmlMetaProperty &p) d->fromSourced = false; d->value.QmlTimeLineValue::setValue(0.); d->ca->setAnimValue(&d->value, QAbstractAnimation::KeepWhenStopped); + d->ca->setFromSourcedValue(&d->fromSourced); } QAbstractAnimation *QmlColorAnimation::qtAnimation() @@ -1595,6 +1596,7 @@ void QmlNumericAnimation::prepare(QmlMetaProperty &p) d->fromSourced = false; d->value.QmlTimeLineValue::setValue(0.); d->na->setAnimValue(&d->value, QAbstractAnimation::KeepWhenStopped); + d->na->setFromSourcedValue(&d->fromSourced); } QAbstractAnimation *QmlNumericAnimation::qtAnimation() @@ -2152,6 +2154,7 @@ void QmlVariantAnimation::prepare(QmlMetaProperty &p) d->fromSourced = false; d->value.QmlTimeLineValue::setValue(0.); d->va->setAnimValue(&d->value, QAbstractAnimation::KeepWhenStopped); + d->va->setFromSourcedValue(&d->fromSourced); } void QmlVariantAnimation::transition(QmlStateActions &actions, diff --git a/src/declarative/util/qmlanimation_p.h b/src/declarative/util/qmlanimation_p.h index 06b7c08..00937a6 100644 --- a/src/declarative/util/qmlanimation_p.h +++ b/src/declarative/util/qmlanimation_p.h @@ -116,8 +116,7 @@ private: class QmlTimeLineValueAnimator : public QVariantAnimation { public: - QmlTimeLineValueAnimator(QObject *parent = 0) : QVariantAnimation(parent), animValue(0), policy(KeepWhenStopped) {} - QmlTimeLineValueAnimator(QmlTimeLineValue *value, QObject *parent = 0) : QVariantAnimation(parent), animValue(value), policy(KeepWhenStopped) {} + QmlTimeLineValueAnimator(QObject *parent = 0) : QVariantAnimation(parent), animValue(0), fromSourced(0), policy(KeepWhenStopped) {} void setAnimValue(QmlTimeLineValue *value, DeletionPolicy p) { if (state() == Running) @@ -125,6 +124,10 @@ public: animValue = value; policy = p; } + void setFromSourcedValue(bool *value) + { + fromSourced = value; + } protected: virtual void updateCurrentValue(const QVariant &value) { @@ -134,7 +137,11 @@ protected: virtual void updateState(State oldState, State newState) { QVariantAnimation::updateState(oldState, newState); - if (newState == Stopped && policy == DeleteWhenStopped) { + if (newState == Running) { + //check for new from every loop + if (fromSourced) + *fromSourced = false; + } else if (newState == Stopped && policy == DeleteWhenStopped) { delete animValue; animValue = 0; } @@ -142,6 +149,7 @@ protected: private: QmlTimeLineValue *animValue; + bool *fromSourced; DeletionPolicy policy; }; -- cgit v0.12 From 44972c661c6cad9942cc8c8e42f02085b3bff0d5 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 7 May 2009 10:59:29 +1000 Subject: Add progress reporting to Image and use it in the flickr demo. --- demos/declarative/flickr/content/ImageDetails.qml | 8 ++- src/declarative/fx/qfximage.cpp | 69 ++++++++++++++++++++++- src/declarative/fx/qfximage.h | 5 ++ src/declarative/fx/qfximage_p.h | 11 ++-- src/declarative/fx/qfxpixmap.cpp | 8 ++- src/declarative/fx/qfxpixmap.h | 3 +- 6 files changed, 93 insertions(+), 11 deletions(-) diff --git a/demos/declarative/flickr/content/ImageDetails.qml b/demos/declarative/flickr/content/ImageDetails.qml index 7b16831..45e191a 100644 --- a/demos/declarative/flickr/content/ImageDetails.qml +++ b/demos/declarative/flickr/content/ImageDetails.qml @@ -68,7 +68,8 @@ Flipable { Rect { anchors.fill: parent; color: "black"; opacity: 0.4; pen.color: "white"; pen.width: 2 } - Loading { anchors.centeredIn: parent; visible: BigImage.status } +// Loading { anchors.centeredIn: parent; visible: BigImage.status } + Progress { anchors.centeredIn: parent; width: 200; height: 18; progress: BigImage.progress; visible: BigImage.status } Flickable { id: Flick; width: Container.width - 10; height: Container.height - 10 x: 5; y: 5; clip: true; viewportWidth: (BigImage.width * BigImage.scale) + BigImage.x; @@ -84,6 +85,11 @@ Flipable { MediaButton { id: BackButton2; x: 630; y: 370; text: "Back"; onClicked: { Container.state = '' } } + Text { + text: "Image Unavailable" + visible: BigImage.status == 'Error' + anchors.centeredIn: parent; color: "white"; font.bold: true + } Slider { id: Slider; x: 25; y: 374; imageWidth: Container.photoWidth; imageHeight: Container.photoHeight } } diff --git a/src/declarative/fx/qfximage.cpp b/src/declarative/fx/qfximage.cpp index 106d551..835a4ff 100644 --- a/src/declarative/fx/qfximage.cpp +++ b/src/declarative/fx/qfximage.cpp @@ -783,6 +783,19 @@ QString QFxImage::propertyInfo() const return d->url.toString(); } +/*! + \qmlproperty enum Image::status + + This property holds the status of image loading. It can be one of: + \list + \o Idle - no image has been set, or the image has been loaded + \o Loading - the images is currently being loaded + \o Error - an error occurred while loading the image + \endlist + + \sa progress +*/ + QFxImage::Status QFxImage::status() const { Q_D(const QFxImage); @@ -790,6 +803,21 @@ QFxImage::Status QFxImage::status() const } /*! + \qmlproperty real Image::progress + + This property holds the progress of image loading, from 0.0 (nothing loaded) + to 1.0 (finished). + + \sa status +*/ + +qreal QFxImage::progress() const +{ + Q_D(const QFxImage); + return d->progress; +} + +/*! \qmlproperty string Image::source Image can handle any image format supported by Qt, loaded from any URL scheme supported by Qt. @@ -844,6 +872,10 @@ void QFxImage::setSource(const QString &url) d->source = url; d->url = qmlContext(this)->resolvedUrl(url); d->sciurl = QUrl(); + if (d->progress != 0.0) { + d->progress = 0.0; + emit progressChanged(d->progress); + } if (url.isEmpty()) { setPixmap(QPixmap()); @@ -866,7 +898,14 @@ void QFxImage::setSource(const QString &url) this, SLOT(sciRequestFinished())); } } else { - QFxPixmap::get(qmlEngine(this), d->url, this, SLOT(requestFinished())); + d->reply = QFxPixmap::get(qmlEngine(this), d->url, this, SLOT(requestFinished())); + if (d->reply) { + connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), + this, SLOT(requestProgress(qint64,qint64))); + } else { + d->progress = 1.0; + emit progressChanged(d->progress); + } } } @@ -879,6 +918,12 @@ void QFxImage::requestFinished() if (d->url.path().endsWith(QLatin1String(".sci"))) { d->_pix = QFxPixmap(d->sciurl); } else { + if (d->reply) { + disconnect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), + this, SLOT(requestProgress(qint64,qint64))); + if (d->reply->error() != QNetworkReply::NoError) + d->status = Error; + } d->_pix = QFxPixmap(d->url); d->_pix.setOpaque(d->_opaque); setOptions(QFxImage::SimpleItem, true); @@ -886,13 +931,16 @@ void QFxImage::requestFinished() setImplicitWidth(d->_pix.width()); setImplicitHeight(d->_pix.height()); - d->status = Idle; + if (d->status == Loading) + d->status = Idle; + d->progress = 1.0; #if defined(QFX_RENDER_OPENGL) d->_texDirty = true; d->_tex.clear(); #endif emit statusChanged(d->status); emit sourceChanged(d->source); + emit progressChanged(1.0); update(); } @@ -912,6 +960,14 @@ void QFxImage::sciRequestFinished() } } +void QFxImage::requestProgress(qint64 received, qint64 total) +{ + Q_D(QFxImage); + if (d->status == Loading && total > 0) { + d->progress = qreal(received)/total; + emit progressChanged(d->progress); + } +} void QFxImage::setGridScaledImage(const QFxGridScaledImage& sci) { @@ -921,7 +977,14 @@ void QFxImage::setGridScaledImage(const QFxGridScaledImage& sci) emit statusChanged(d->status); } else { d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl())); - QFxPixmap::get(qmlEngine(this), d->sciurl, this, SLOT(requestFinished())); + d->reply = QFxPixmap::get(qmlEngine(this), d->sciurl, this, SLOT(requestFinished())); + if (d->reply) { + connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), + this, SLOT(requestProgress(qint64,qint64))); + } else { + d->progress = 1.0; + emit progressChanged(d->progress); + } QFxScaleGrid *sg = scaleGrid(); sg->setTop(sci.gridTop()); sg->setBottom(sci.gridBottom()); diff --git a/src/declarative/fx/qfximage.h b/src/declarative/fx/qfximage.h index 37fe5be..dc13a97 100644 --- a/src/declarative/fx/qfximage.h +++ b/src/declarative/fx/qfximage.h @@ -43,6 +43,7 @@ #define QFXIMAGE_H #include +#include QT_BEGIN_HEADER @@ -58,6 +59,7 @@ class Q_DECLARATIVE_EXPORT QFxImage : public QFxItem Q_PROPERTY(Status status READ status NOTIFY statusChanged) Q_PROPERTY(QString source READ source WRITE setSource NOTIFY sourceChanged) + Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) Q_PROPERTY(QFxScaleGrid *scaleGrid READ scaleGrid) Q_PROPERTY(bool tile READ isTiled WRITE setTiled) @@ -84,6 +86,7 @@ public: enum Status { Idle, Loading, Error }; Status status() const; + qreal progress() const; QString source() const; virtual void setSource(const QString &url); @@ -101,6 +104,7 @@ public: Q_SIGNALS: void sourceChanged(const QString &); void statusChanged(Status); + void progressChanged(qreal progress); protected: QFxImage(QFxImagePrivate &dd, QFxItem *parent); @@ -109,6 +113,7 @@ protected: private Q_SLOTS: void requestFinished(); void sciRequestFinished(); + void requestProgress(qint64,qint64); private: Q_DISABLE_COPY(QFxImage) diff --git a/src/declarative/fx/qfximage_p.h b/src/declarative/fx/qfximage_p.h index fbb4c44..43942fe 100644 --- a/src/declarative/fx/qfximage_p.h +++ b/src/declarative/fx/qfximage_p.h @@ -76,7 +76,7 @@ public: #if defined(QFX_RENDER_OPENGL) _texDirty(true), #endif - status(QFxImage::Idle), reply(0) + status(QFxImage::Idle), reply(0), progress(0.0) { } @@ -95,10 +95,10 @@ public: } QFxScaleGrid *_scaleGrid; - bool _tiled; QFxPixmap _pix; - bool _smooth; - bool _opaque; + bool _tiled : 1; + bool _smooth : 1; + bool _opaque : 1; #if defined(QFX_RENDER_OPENGL) void checkDirty(); bool _texDirty; @@ -109,7 +109,8 @@ public: QString source; QUrl url; QUrl sciurl; - QNetworkReply *reply; + QPointer reply; + qreal progress; }; QT_END_NAMESPACE diff --git a/src/declarative/fx/qfxpixmap.cpp b/src/declarative/fx/qfxpixmap.cpp index 0d456c6..3fdd8e5 100644 --- a/src/declarative/fx/qfxpixmap.cpp +++ b/src/declarative/fx/qfxpixmap.cpp @@ -233,8 +233,11 @@ QFxPixmap::operator const QSimpleCanvasConfig::Image &() const Starts a network request to load \a url. When the URL is loaded, the given slot is invoked. Note that if the image is already cached, the slot may be invoked immediately. + + Returns a QNetworkReply if the image is not immediately available, otherwise + returns 0. The QNetworkReply must not be stored - it may be destroyed at any time. */ -void QFxPixmap::get(QmlEngine *engine, const QUrl& url, QObject* obj, const char* slot) +QNetworkReply *QFxPixmap::get(QmlEngine *engine, const QUrl& url, QObject* obj, const char* slot) { QString key = url.toString(); QFxPixmapCache::Iterator iter = qfxPixmapCache.find(key); @@ -259,11 +262,14 @@ void QFxPixmap::get(QmlEngine *engine, const QUrl& url, QObject* obj, const char if ((*iter)->reply) { // still loading QObject::connect((*iter)->reply, SIGNAL(finished()), obj, slot); + return (*iter)->reply; } else { // already loaded QObject dummy; QObject::connect(&dummy, SIGNAL(destroyed()), obj, slot); } + + return 0; } /*! diff --git a/src/declarative/fx/qfxpixmap.h b/src/declarative/fx/qfxpixmap.h index 9a3ba4e..748991e 100644 --- a/src/declarative/fx/qfxpixmap.h +++ b/src/declarative/fx/qfxpixmap.h @@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) class QmlEngine; +class QNetworkReply; class QFxPixmapPrivate; class Q_DECLARATIVE_EXPORT QFxPixmap { @@ -65,7 +66,7 @@ public: QFxPixmap &operator=(const QFxPixmap &); - static void get(QmlEngine *, const QUrl& url, QObject*, const char* slot); + static QNetworkReply *get(QmlEngine *, const QUrl& url, QObject*, const char* slot); static void cancelGet(const QUrl& url, QObject* obj, const char* slot); bool isNull() const; -- cgit v0.12 From d2dbe01664c1adb8d1848b566621dbe4470f184b Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Thu, 7 May 2009 13:40:12 +1000 Subject: Use VisualModel --- demos/declarative/flickr/flickr2.qml | 274 +++++++++++++++++++++++++++++++++++ 1 file changed, 274 insertions(+) create mode 100644 demos/declarative/flickr/flickr2.qml diff --git a/demos/declarative/flickr/flickr2.qml b/demos/declarative/flickr/flickr2.qml new file mode 100644 index 0000000..4875fa4 --- /dev/null +++ b/demos/declarative/flickr/flickr2.qml @@ -0,0 +1,274 @@ +import "content" + +Item { + id: MainWindow; width: 800; height: 450 + + property bool showPathView : false + + VisualModel { + id: MyVisualModel + model: + XmlListModel { + id: FeedModel + property string tags : "" + source: "http://api.flickr.com/services/feeds/photos_public.gne?"+(tags ? "tags="+tags+"&" : "")+"format=rss2" + query: "doc($src)/rss/channel/item" + namespaceDeclarations: "declare namespace media=\"http://search.yahoo.com/mrss/\";" + + Role { name: "title"; query: "title/string()" } + Role { name: "imagePath"; query: "media:thumbnail/@url/string()" } + Role { name: "url"; query: "media:content/@url/string()" } + Role { name: "description"; query: "description/string()"; isCData: true } + Role { name: "tags"; query: "media:category/string()" } + Role { name: "photoWidth"; query: "media:content/@width/string()" } + Role { name: "photoHeight"; query: "media:content/@height/string()" } + Role { name: "photoType"; query: "media:content/@type/string()" } + Role { name: "photoAuthor"; query: "author/string()" } + Role { name: "photoDate"; query: "pubDate/string()" } + } + + delegate: Package { + Item { + id: Wrapper; width: 85; height: 85 + scale: Wrapper.PathView.scale; z: Wrapper.PathView.z + + transform: [ + Rotation3D { id: Rotation; axis.startX: 30; axis.endX: 30; axis.endY: 60; angle: Wrapper.PathView.angle } + ] + + Connection { + sender: ImageDetails; signal: "closed()" + script: { if (Wrapper.state == 'Details') Wrapper.state = '' } + } + + Script { + function photoClicked() { + ImageDetails.photoTitle = title; + ImageDetails.flickableArea.yPosition = 0; + ImageDetails.fullScreenArea.source = ""; + ImageDetails.photoDescription = description; + ImageDetails.photoTags = tags; + ImageDetails.photoWidth = photoWidth; + ImageDetails.photoHeight = photoHeight; + ImageDetails.photoType = photoType; + ImageDetails.photoAuthor = photoAuthor; + ImageDetails.photoDate = photoDate; + ImageDetails.photoUrl = url; + ImageDetails.rating = 0; + Wrapper.state = "Details"; + } + } + + Rect { + id: WhiteRect; anchors.fill: parent; color: "white"; radius: 5 + + Loading { x: 26; y: 26; visible: Thumb.status } + Image { id: Thumb; source: imagePath; x: 5; y: 5 } + + Item { + id: Shadows + Image { source: "content/pics/shadow-right.png"; x: WhiteRect.width; height: WhiteRect.height } + Image { source: "content/pics/shadow-bottom.png"; y: WhiteRect.height; width: WhiteRect.width } + Image { id: Corner; source: "content/pics/shadow-corner.png"; x: WhiteRect.width; y: WhiteRect.height } + } + } + + MouseRegion { anchors.fill: Wrapper; onClicked: { photoClicked() } } + + states: [ + State { + name: "Details" + SetProperties { target: ImageDetails; z: 2 } + ParentChange { target: Wrapper; parent: ImageDetails.frontContainer } + SetProperties { target: Wrapper; x: 45; y: 35; scale: 1; z: 1000 } + SetProperties { target: Rotation; angle: 0 } + SetProperties { target: Shadows; opacity: 0 } + SetProperties { target: ImageDetails; y: 20 } + SetProperties { target: PhotoGridView; y: "-480" } + SetProperties { target: PhotoPathView; y: "-480" } + SetProperties { target: CloseButton; opacity: 0 } + SetProperties { target: FetchButton; opacity: 0 } + SetProperties { target: CategoryText; y: "-50" } + } + ] + + transitions: [ + Transition { + fromState: "*"; toState: "Details" + ParentChangeAction { } + NumericAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing: "easeInOutQuad" } + }, + Transition { + fromState: "Details"; toState: "*" + SequentialAnimation { + ParentChangeAction { } + NumericAnimation { properties: "x,y,scale,opacity,angle"; duration: 500; easing: "easeInOutQuad" } + SetPropertyAction { filter: Wrapper; properties: "z" } + } + } + ] + } + + Item { + Package.name: "rightBox" + id: RightBox; x: 200; width: 85; height: 85 + } + + Item { + Package.name: "leftBox" + id: LeftBox; width: 85; height: 85 + } + + Item { + id: MyItem + states: [ + State { + name: "left" + when: MainWindow.showPathView == true + SetProperty { + target: Wrapper + property: "moveToParent" + value: LeftBox + } + }, + State { + name: "right" + when: MainWindow.showPathView == false + SetProperty { + target: Wrapper + property: "moveToParent" + value: RightBox + } + } + ] + transitions: [ + Transition { + fromState: "*" + toState: "*" + SequentialAnimation { + SetPropertyAction { + target: Wrapper + property: "moveToParent" + value: Bounce + } + ParallelAnimation { + NumericAnimation { + target: Wrapper + properties: "x" + to: 0 + duration: 250 + } + NumericAnimation { + target: Wrapper + properties: "y" + to: 0 + easing: "easeInQuad" + duration: 250 + } + } + SetPropertyAction { + target: Wrapper + property: "moveToParent" + } + ParallelAnimation { + NumericAnimation { + target: Wrapper + properties: "x" + to: 0 + duration: 250 + } + NumericAnimation { + target: Wrapper + properties: "y" + to: 0 + easing: "easeOutQuad" + duration: 250 + } + } + } + } + ] + state: "right" + } + + } + } + + + Item { + id: Background + + Image { source: "content/pics/background.png"; opaque: true } + + GridView { + id: PhotoGridView; model: MyVisualModel.parts.leftBox + cellWidth: 105; cellHeight: 105; x:32; y: 80; width: 800; height: 330; z: 1 + } + + PathView { + id: PhotoPathView; model: MyVisualModel.parts.rightBox + y: 80; width: 800; height: 330; z: 1 + path: Path { + startX: -50; startY: 40; + + PathAttribute { name: "scale"; value: 1 } + PathAttribute { name: "angle"; value: -45 } + + PathCubic { + x: 400; y: 220 + control1X: 140; control1Y: 40 + control2X: 210; control2Y: 220 + } + + PathAttribute { name: "scale"; value: 1.2 } + PathAttribute { name: "z"; value: 1 } + PathAttribute { name: "angle"; value: 0 } + + PathCubic { + x: 850; y: 40 + control2X: 660; control2Y: 40 + control1X: 590; control1Y: 220 + } + + PathAttribute { name: "scale"; value: 1 } + PathAttribute { name: "angle"; value: -45 } + } + + } + + ImageDetails { id: ImageDetails; width: 750; x: 25; y: 500; height: 410 } + + MediaButton { + id: CloseButton; x: 680; y: 410; text: "View Mode" + onClicked: { if (MainWindow.showPathView == true) MainWindow.showPathView = false; else MainWindow.showPathView = true } + } + + MediaButton { + id: FetchButton + text: "Update" + anchors.right: CloseButton.left; anchors.rightMargin: 5 + anchors.top: CloseButton.top + onClicked: { FeedModel.reload(); } + } + + states: [ + State { + name: "PathView" + } + ] + + transitions: [ + Transition { + fromState: "*"; toState: "*" + NumericAnimation { properties: "y"; duration: 650; easing: "easeOutBounce(amplitude:0.1)" } + } + ] + } + + Text { + id: CategoryText; anchors.horizontalCenter: parent.horizontalCenter; y: 15; + text: "Flickr - " + + (FeedModel.tags=="" ? "Uploads from everyone" : "Recent Uploads tagged " + FeedModel.tags) + font.size: 16; font.bold: true; color: "white"; style: "Raised"; styleColor: "black" + } +} -- cgit v0.12 From 1d1acbdf3161bc5d79ddd73704687f1c604c766a Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 7 May 2009 13:44:36 +1000 Subject: Viewing the same image twice showed no image the second time. --- demos/declarative/flickr/content/ImageDetails.qml | 1 - demos/declarative/flickr/flickr.qml | 8 ++++++-- src/declarative/fx/qfximage.cpp | 11 +++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/demos/declarative/flickr/content/ImageDetails.qml b/demos/declarative/flickr/content/ImageDetails.qml index 45e191a..8ed61ec 100644 --- a/demos/declarative/flickr/content/ImageDetails.qml +++ b/demos/declarative/flickr/content/ImageDetails.qml @@ -3,7 +3,6 @@ Flipable { property var frontContainer: ContainerFront property var flickableArea: Flickable - property var fullScreenArea: BigImage property string photoTitle: "" property string photoDescription: "" property int photoWidth diff --git a/demos/declarative/flickr/flickr.qml b/demos/declarative/flickr/flickr.qml index 5caffb9..95c808c 100644 --- a/demos/declarative/flickr/flickr.qml +++ b/demos/declarative/flickr/flickr.qml @@ -35,14 +35,18 @@ Item { Connection { sender: ImageDetails; signal: "closed()" - script: { if (Wrapper.state == 'Details') Wrapper.state = '' } + script: { + if (Wrapper.state == 'Details') { + Wrapper.state = ''; + ImageDetails.photoUrl = ""; + } + } } Script { function photoClicked() { ImageDetails.photoTitle = title; ImageDetails.flickableArea.yPosition = 0; - ImageDetails.fullScreenArea.source = ""; ImageDetails.photoDescription = description; ImageDetails.photoWidth = photoWidth; ImageDetails.photoHeight = photoHeight; diff --git a/src/declarative/fx/qfximage.cpp b/src/declarative/fx/qfximage.cpp index 835a4ff..657e9a5 100644 --- a/src/declarative/fx/qfximage.cpp +++ b/src/declarative/fx/qfximage.cpp @@ -880,6 +880,17 @@ void QFxImage::setSource(const QString &url) if (url.isEmpty()) { setPixmap(QPixmap()); d->status = Idle; + d->progress = 1.0; + setImplicitWidth(0); + setImplicitHeight(0); +#if defined(QFX_RENDER_OPENGL) + d->_texDirty = true; + d->_tex.clear(); +#endif + emit statusChanged(d->status); + emit sourceChanged(d->source); + emit progressChanged(1.0); + update(); } else { d->status = Loading; if (d->url.path().endsWith(QLatin1String(".sci"))) { -- cgit v0.12 From 78dd666b4f9dd2acc987926eff9513217fff490a Mon Sep 17 00:00:00 2001 From: Yann Bodson Date: Thu, 7 May 2009 13:55:24 +1000 Subject: Add missing 'Quit' menu item. --- tools/qmlviewer/qmlviewer.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/qmlviewer/qmlviewer.cpp b/tools/qmlviewer/qmlviewer.cpp index dbbe233..7962ed1 100644 --- a/tools/qmlviewer/qmlviewer.cpp +++ b/tools/qmlviewer/qmlviewer.cpp @@ -79,6 +79,12 @@ void QmlViewer::createMenuBar() connect(reloadAction, SIGNAL(triggered()), this, SLOT(reload())); fileMenu->addAction(reloadAction); + QAction *quitAction = new QAction(tr("&Quit"), this); + quitAction->setShortcut(QKeySequence("Ctrl+Q")); + connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); + fileMenu->addSeparator(); + fileMenu->addAction(quitAction); + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); QAction *aboutAction = new QAction(tr("&About Qt..."), this); connect(aboutAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); -- cgit v0.12 From 9e9ee6ac63038c050ef02b102c23ebb899c45374 Mon Sep 17 00:00:00 2001 From: Michael Brasser Date: Thu, 7 May 2009 14:11:05 +1000 Subject: Tweaks to viewer. --- tools/qmlviewer/main.cpp | 1 - tools/qmlviewer/qmlviewer.cpp | 36 +++++++++++++++++++++++++++++++----- tools/qmlviewer/qmlviewer.h | 3 +++ 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/tools/qmlviewer/main.cpp b/tools/qmlviewer/main.cpp index b588111..3f74ef6 100644 --- a/tools/qmlviewer/main.cpp +++ b/tools/qmlviewer/main.cpp @@ -60,7 +60,6 @@ int main(int argc, char ** argv) char raster[] = "raster"; newargv[argc+1] = raster; - QApplication app(newargc, newargv); app.setApplicationName("viewer"); diff --git a/tools/qmlviewer/qmlviewer.cpp b/tools/qmlviewer/qmlviewer.cpp index 7962ed1..04054ec 100644 --- a/tools/qmlviewer/qmlviewer.cpp +++ b/tools/qmlviewer/qmlviewer.cpp @@ -53,7 +53,8 @@ QmlViewer::QmlViewer(QFxTestEngine::TestMode testMode, const QString &testDir, Q setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_NoSystemBackground); - createMenuBar(); + if (!(flags & Qt::FramelessWindowHint)) + createMenuBar(); canvas = new QFxView(this); if(testMode != QFxTestEngine::NoTest) @@ -85,12 +86,38 @@ void QmlViewer::createMenuBar() fileMenu->addSeparator(); fileMenu->addAction(quitAction); + /*QMenu *recordMenu = menuBar()->addMenu(tr("&Recording")); + + QAction *snapshotAction = new QAction(tr("&Take Snapsot"), 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);*/ + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); QAction *aboutAction = new QAction(tr("&About Qt..."), this); connect(aboutAction, SIGNAL(triggered()), qApp, SLOT(aboutQt())); helpMenu->addAction(aboutAction); } +void QmlViewer::takeSnapShot() +{ + static int snapshotcount = 1; + QString snapFileName = QString(QLatin1String("snapshot%1.png")).arg(snapshotcount); + canvas->asImage().save(snapFileName); + qDebug() << "Wrote" << snapFileName; + ++snapshotcount; +} + +void QmlViewer::toggleRecording() +{ + bool recording = recordTimer.isActive(); + //recordAction->setText(recording ? tr("&Start Recording Video") : tr("&End Recording Video")); + setRecording(!recording); +} + void QmlViewer::reload() { openQml(currentFileName); @@ -303,10 +330,9 @@ void QmlViewer::keyPressEvent(QKeyEvent *event) << "device keys: 0=quit, 1..8=F1..F8" ; } else if (event->key() == Qt::Key_F2 || (event->key() == Qt::Key_2 && devicemode)) { - setRecording(!recordTimer.isActive()); + toggleRecording(); } else if (event->key() == Qt::Key_F3 || (event->key() == Qt::Key_3 && devicemode)) { - canvas->asImage().save("snapshot.png"); - qDebug() << "Wrote snapshot.png"; + takeSnapShot(); } else if (event->key() == Qt::Key_F4 || (event->key() == Qt::Key_4 && devicemode)) { canvas->dumpItems(); canvas->checkState(); @@ -404,7 +430,7 @@ void QmlViewer::setRecording(bool on) args << "-delay" << QString::number(record_period/10); args << inputs; args << record_file; - qDebug() << "Converting..." << 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 diff --git a/tools/qmlviewer/qmlviewer.h b/tools/qmlviewer/qmlviewer.h index b4117a2..405e8d9 100644 --- a/tools/qmlviewer/qmlviewer.h +++ b/tools/qmlviewer/qmlviewer.h @@ -48,6 +48,8 @@ public slots: void openQml(const QString& fileName); void open(); void reload(); + void takeSnapShot(); + void toggleRecording(); protected: virtual void keyPressEvent(QKeyEvent *); @@ -70,6 +72,7 @@ private: int record_period; int record_autotime; bool devicemode; + QAction *recordAction; QFxTestEngine *testEngine; }; -- cgit v0.12 From 7032e0d9c08fcea67bb4d96be241b6b5803843ee Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 7 May 2009 14:12:37 +1000 Subject: Add "watchers" to debugger --- src/declarative/debugger/qmldebugger.cpp | 153 ++++++++++++++++++++++++------- src/declarative/debugger/qmldebugger.h | 12 ++- src/declarative/qml/qmlengine.cpp | 36 ++++++-- src/declarative/qml/qmlengine_p.h | 11 +++ src/declarative/qml/qmlmetaproperty.cpp | 12 +++ src/declarative/qml/qmlmetaproperty.h | 1 + 6 files changed, 185 insertions(+), 40 deletions(-) diff --git a/src/declarative/debugger/qmldebugger.cpp b/src/declarative/debugger/qmldebugger.cpp index 033a15f..9b84b9e 100644 --- a/src/declarative/debugger/qmldebugger.cpp +++ b/src/declarative/debugger/qmldebugger.cpp @@ -43,6 +43,8 @@ #include #include #include +#include +#include #include #include #include @@ -52,10 +54,11 @@ #include #include #include +#include #include QmlDebugger::QmlDebugger(QWidget *parent) -: QWidget(parent), m_tree(0) +: QWidget(parent), m_tree(0), m_warnings(0), m_watchers(0), m_text(0) { QHBoxLayout *layout = new QHBoxLayout; setLayout(layout); @@ -69,18 +72,33 @@ QmlDebugger::QmlDebugger(QWidget *parent) splitter->addWidget(treeWid); m_tree = new QTreeWidget(treeWid); + m_tree->setSelectionMode(QTreeWidget::NoSelection); m_tree->setHeaderHidden(true); - QObject::connect(m_tree, SIGNAL(itemPressed(QTreeWidgetItem *, int)), this, SLOT(itemPressed(QTreeWidgetItem *))); + QObject::connect(m_tree, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(itemClicked(QTreeWidgetItem *))); + QObject::connect(m_tree, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(itemDoubleClicked(QTreeWidgetItem *))); vlayout->addWidget(m_tree); QPushButton *pb = new QPushButton("Refresh", treeWid); QObject::connect(pb, SIGNAL(clicked()), this, SLOT(refresh())); vlayout->addWidget(pb); + QTabWidget *tabs = new QTabWidget(this); + m_text = new QPlainTextEdit(this); m_text->setReadOnly(true); - splitter->addWidget(m_text); + tabs->addTab(m_text, "File"); + + m_warnings = new QTreeWidget(this); + m_warnings->setHeaderHidden(true); + tabs->addTab(m_warnings, "Warnings"); + + m_watchers = new QTableWidget(this); + tabs->addTab(m_watchers, "Watchers"); + + splitter->addWidget(tabs); splitter->setStretchFactor(1, 2); + + setGeometry(0, 100, 800, 600); } class QmlDebuggerItem : public QTreeWidgetItem @@ -103,31 +121,29 @@ public: QPointer bindableValue; }; -void QmlDebugger::itemPressed(QTreeWidgetItem *i) +void QmlDebugger::itemDoubleClicked(QTreeWidgetItem *i) { QmlDebuggerItem *item = static_cast(i); if(item->bindableValue) { - QString str; - QmlExpressionPrivate *p = item->bindableValue->d; - if(p->log) { - QString str; - QDebug d(&str); - for(int ii = 0; ii < p->log->count(); ++ii) { - d << p->log->at(ii).result() << "\n"; - QStringList warnings = p->log->at(ii).warnings(); - foreach(const QString &warning, warnings) - d << " " << warning << "\n"; - } - m_text->setPlainText(str); + if(m_watchedIds.contains(p->id)) { + m_watchedIds.remove(p->id); + item->setForeground(0, Qt::green); } else { - m_text->setPlainText("No history"); + m_watchedIds.insert(p->id); + item->setForeground(0, QColor("purple")); } - } else if(item->url.scheme() == QLatin1String("file")) { + } +} + +void QmlDebugger::itemClicked(QTreeWidgetItem *i) +{ + QmlDebuggerItem *item = static_cast(i); + if(item->url.scheme() == QLatin1String("file")) { QString f = item->url.toLocalFile(); QFile file(f); file.open(QIODevice::ReadOnly); @@ -141,17 +157,11 @@ void QmlDebugger::itemPressed(QTreeWidgetItem *i) QTextDocument *document = m_text->document(); QTextCharFormat format; format.setForeground(Qt::lightGray); - { - QTextCursor cursor(document); - cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); - cursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor, item->startLine - 1); - cursor.setCharFormat(format); - } { QTextCursor cursor(document); cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); - cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, item->endLine); + cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, item->endLine); cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); cursor.setCharFormat(format); } @@ -159,31 +169,87 @@ void QmlDebugger::itemPressed(QTreeWidgetItem *i) { QTextCursor cursor(document); cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); - cursor.setCharFormat(QTextCharFormat()); + cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, item->startLine - 1); + cursor.setCharFormat(format); } { QTextCursor cursor(document); cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); - cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, item->startLine - 1); + cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, item->startLine - 1); m_text->setTextCursor(cursor); m_text->centerCursor(); } + + } } } -static bool makeItem(QObject *obj, QmlDebuggerItem *item) +bool QmlDebugger::makeItem(QObject *obj, QmlDebuggerItem *item) { bool rv = true; QString text; if(QmlBindableValue *bv = qobject_cast(obj)) { + QmlExpressionPrivate *p = bv->d; + text = bv->property().name() + ": " + bv->expression(); - item->setForeground(0, Qt::green); + bool watched = m_watchedIds.contains(p->id); + if(watched) + item->setForeground(0, QColor("purple")); + else + item->setForeground(0, Qt::green); item->bindableValue = bv; + + if(p->log) { + QTreeWidgetItem *warningItem = 0; + + int column = m_watchers->columnCount(); + + if(watched) { + m_watchers->insertColumn(column); + QTableWidgetItem *tableheader = new QTableWidgetItem; + tableheader->setText(bv->expression()); + tableheader->setToolTip(bv->expression()); + m_watchers->setHorizontalHeaderItem(column, tableheader); + } + + for(int ii = 0; ii < p->log->count(); ++ii) { + const QmlExpressionLog &log = p->log->at(ii); + + QString variant; QDebug d(&variant); d << log.result(); + if(watched) { + QString str = log.result().toString(); + if(str.isEmpty()) + str = variant; + m_expressions << qMakePair(log.time(), qMakePair(column, str)); + } + + if(!log.warnings().isEmpty()) { + + if(!warningItem) { + warningItem = new QTreeWidgetItem(m_warnings); + warningItem->setText(0, bv->expression()); + } + + QTreeWidgetItem *entry = new QTreeWidgetItem(warningItem); + entry->setExpanded(true); + + entry->setText(0, variant); + + foreach(const QString &warning, log.warnings()) { + QTreeWidgetItem *w = new QTreeWidgetItem(entry); + w->setText(0, warning); + } + } + + } + + } + } else if(QmlBoundSignal *bs = qobject_cast(obj)) { QMetaMethod method = obj->parent()->metaObject()->method(bs->index()); QByteArray sig = method.signature(); @@ -237,7 +303,7 @@ static bool makeItem(QObject *obj, QmlDebuggerItem *item) return rv; } -static void buildTree(QObject *obj, QmlDebuggerItem *parent) +void QmlDebugger::buildTree(QObject *obj, QmlDebuggerItem *parent) { QObjectList children = obj->children(); @@ -253,9 +319,20 @@ void QmlDebugger::refresh() setDebugObject(m_object); } +bool operator<(const QPair > &lhs, + const QPair > &rhs) +{ + return lhs.first < rhs.first; +} + void QmlDebugger::setDebugObject(QObject *obj) { m_tree->clear(); + m_warnings->clear(); + m_watchers->clear(); + m_watchers->setColumnCount(0); + m_watchers->setRowCount(0); + m_expressions.clear(); m_object = obj; if(!obj) @@ -265,6 +342,20 @@ void QmlDebugger::setDebugObject(QObject *obj) makeItem(obj, item); buildTree(obj, item); item->setExpanded(true); - setGeometry(0, 100, 800, 600); + + m_watchers->setRowCount(m_expressions.count()); + + qSort(m_expressions.begin(), m_expressions.end()); + + for(int ii = 0; ii < m_expressions.count(); ++ii) { + + const QPair > &expr = m_expressions.at(ii); + QTableWidgetItem *item = new QTableWidgetItem; + item->setText(expr.second.second); + m_watchers->setItem(ii, expr.second.first, item); + + } + + } diff --git a/src/declarative/debugger/qmldebugger.h b/src/declarative/debugger/qmldebugger.h index 943abef..e04eb2e 100644 --- a/src/declarative/debugger/qmldebugger.h +++ b/src/declarative/debugger/qmldebugger.h @@ -43,6 +43,7 @@ #define QMLDEBUGGER_H #include +#include #include QT_BEGIN_HEADER @@ -54,6 +55,8 @@ QT_MODULE(Declarative) class QTreeWidget; class QTreeWidgetItem; class QPlainTextEdit; +class QmlDebuggerItem; +class QTableWidget; class QmlDebugger : public QWidget { Q_OBJECT @@ -66,12 +69,19 @@ public slots: void refresh(); private slots: - void itemPressed(QTreeWidgetItem *); + void itemClicked(QTreeWidgetItem *); + void itemDoubleClicked(QTreeWidgetItem *); private: + void buildTree(QObject *obj, QmlDebuggerItem *parent); + bool makeItem(QObject *obj, QmlDebuggerItem *item); QTreeWidget *m_tree; + QTreeWidget *m_warnings; + QTableWidget *m_watchers; QPlainTextEdit *m_text; QPointer m_object; + QList > > m_expressions; + QSet m_watchedIds; }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index be5226e..15b5879 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -139,7 +139,7 @@ QStack *QmlEngineStack::engines() QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e) : rootContext(0), currentBindContext(0), currentExpression(0), q(e), - rootComponent(0), networkAccessManager(0), typeManager(e) + rootComponent(0), networkAccessManager(0), typeManager(e), uniqueId(1) { QScriptValue proto = scriptEngine.newObject(); proto.setProperty(QLatin1String("emit"), @@ -720,17 +720,17 @@ QmlEngine *QmlEngine::activeEngine() QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b) -: q(b), ctxt(0), sseData(0), proxy(0), me(0), trackChange(false), log(0) +: q(b), ctxt(0), sseData(0), proxy(0), me(0), trackChange(false), id(0), log(0) { } QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b, void *expr, QmlRefCount *rc) -: q(b), ctxt(0), sse((const char *)expr, rc), sseData(0), proxy(0), me(0), trackChange(true), log(0) +: q(b), ctxt(0), sse((const char *)expr, rc), sseData(0), proxy(0), me(0), trackChange(true), id(0), log(0) { } QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b, const QString &expr, bool ssecompile) -: q(b), ctxt(0), expression(expr), sseData(0), proxy(0), me(0), trackChange(true), log(0) +: q(b), ctxt(0), expression(expr), sseData(0), proxy(0), me(0), trackChange(true), id(0), log(0) { if (ssecompile) { #ifdef Q_ENABLE_PERFORMANCE_LOG @@ -765,6 +765,8 @@ QmlExpression::QmlExpression(QmlContext *ctxt, void *expr, : d(new QmlExpressionPrivate(this, expr, rc)) { d->ctxt = ctxt; + if(ctxt && ctxt->engine()) + d->id = ctxt->engine()->d_func()->getUniqueId(); d->me = me; } @@ -774,6 +776,8 @@ QmlExpression::QmlExpression(QmlContext *ctxt, const QString &expr, : d(new QmlExpressionPrivate(this, expr, ssecompile)) { d->ctxt = ctxt; + if(ctxt && ctxt->engine()) + d->id = ctxt->engine()->d_func()->getUniqueId(); d->me = me; } @@ -789,6 +793,8 @@ QmlExpression::QmlExpression(QmlContext *ctxt, const QString &expression, : d(new QmlExpressionPrivate(this, expression, true)) { d->ctxt = ctxt; + if(ctxt && ctxt->engine()) + d->id = ctxt->engine()->d_func()->getUniqueId(); d->me = scope; } @@ -810,7 +816,7 @@ QmlEngine *QmlExpression::engine() const } /*! - Returns teh QmlContext this expression is associated with, or 0 if there + Returns the QmlContext this expression is associated with, or 0 if there is no association or the QmlContext has been destroyed. */ QmlContext *QmlExpression::context() const @@ -988,6 +994,7 @@ QVariant QmlExpression::value() if(qmlDebugger()) { QmlExpressionLog log; + log.setTime(engine()->d_func()->getUniqueId()); log.setExpression(expression()); log.setResult(rv); @@ -997,8 +1004,8 @@ QVariant QmlExpression::value() if (prop.hasChangedNotifier()) { prop.connectNotifier(d->proxy, changedIndex); - } else { - QString warn = QLatin1String("Expression depends on property without a NOTIFY signal: ") + QLatin1String(prop.object()->metaObject()->className()) + QLatin1String(".") + prop.name(); + } else if (prop.needsChangedNotifier()) { + QString warn = QLatin1String("Expression depends on property without a NOTIFY signal: [") + QLatin1String(prop.object()->metaObject()->className()) + QLatin1String("].") + prop.name(); log.addWarning(warn); } } @@ -1015,6 +1022,7 @@ QVariant QmlExpression::value() } } else { QmlExpressionLog log; + log.setTime(engine()->d_func()->getUniqueId()); log.setExpression(expression()); log.setResult(rv); d->addLog(log); @@ -1023,6 +1031,7 @@ QVariant QmlExpression::value() } else { if(qmlDebugger()) { QmlExpressionLog log; + log.setTime(engine()->d_func()->getUniqueId()); log.setExpression(expression()); log.setResult(rv); d->addLog(log); @@ -1421,7 +1430,8 @@ QmlExpressionLog::QmlExpressionLog() } QmlExpressionLog::QmlExpressionLog(const QmlExpressionLog &o) -: m_expression(o.m_expression), +: m_time(o.m_time), + m_expression(o.m_expression), m_result(o.m_result), m_warnings(o.m_warnings) { @@ -1433,12 +1443,22 @@ QmlExpressionLog::~QmlExpressionLog() QmlExpressionLog &QmlExpressionLog::operator=(const QmlExpressionLog &o) { + m_time = o.m_time; m_expression = o.m_expression; m_result = o.m_result; m_warnings = o.m_warnings; return *this; } +void QmlExpressionLog::setTime(quint32 time) +{ + m_time = time; +} + +quint32 QmlExpressionLog::time() const +{ + return m_time; +} QString QmlExpressionLog::expression() const { diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index 7d5176e..63df0ba 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -114,6 +114,11 @@ public: QmlCompositeTypeManager typeManager; QMap nameSpacePaths; + + mutable quint32 uniqueId; + quint32 getUniqueId() const { + return uniqueId++; + } }; @@ -201,6 +206,9 @@ public: QmlExpressionLog &operator=(const QmlExpressionLog &); + void setTime(quint32); + quint32 time() const; + QString expression() const; void setExpression(const QString &); @@ -211,6 +219,7 @@ public: void setResult(const QVariant &); private: + quint32 m_time; QString m_expression; QVariant m_result; QStringList m_warnings; @@ -233,6 +242,8 @@ public: QObject *me; bool trackChange; + quint32 id; + void addLog(const QmlExpressionLog &); QList *log; }; diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp index 40c9b0e..59d6b38 100644 --- a/src/declarative/qml/qmlmetaproperty.cpp +++ b/src/declarative/qml/qmlmetaproperty.cpp @@ -988,6 +988,18 @@ bool QmlMetaProperty::hasChangedNotifier() const } /*! + Returns true if the property needs a change notifier signal for bindings + to remain upto date, false otherwise. + + Some properties, such as attached properties or those whose value never + changes, do not require a change notifier. +*/ +bool QmlMetaProperty::needsChangedNotifier() const +{ + return type() & Property && !(type() & Attached); +} + +/*! Connects the property's change notifier signal to the specified \a method of the \a dest object and returns true. Returns false if this metaproperty does not diff --git a/src/declarative/qml/qmlmetaproperty.h b/src/declarative/qml/qmlmetaproperty.h index 4836038..68b06e5 100644 --- a/src/declarative/qml/qmlmetaproperty.h +++ b/src/declarative/qml/qmlmetaproperty.h @@ -89,6 +89,7 @@ public: void emitSignal(); bool hasChangedNotifier() const; + bool needsChangedNotifier() const; bool connectNotifier(QObject *dest, const char *slot) const; bool connectNotifier(QObject *dest, int method) const; -- cgit v0.12 From 572f00d8c2684f6e396d17638ae08bfac57b410e Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 7 May 2009 14:23:51 +1000 Subject: Don't crash --- src/declarative/fx/qfximage.cpp | 26 +++++++++++++------------- src/declarative/fx/qfximage_p.h | 3 ++- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/declarative/fx/qfximage.cpp b/src/declarative/fx/qfximage.cpp index 657e9a5..d66846d 100644 --- a/src/declarative/fx/qfximage.cpp +++ b/src/declarative/fx/qfximage.cpp @@ -125,8 +125,8 @@ QFxImage::QFxImage(QFxImagePrivate &dd, QFxItem *parent) QFxImage::~QFxImage() { Q_D(const QFxImage); - if (d->reply) - d->reply->deleteLater(); + if (d->sciReply) + d->sciReply->deleteLater(); } /*! @@ -859,9 +859,9 @@ void QFxImage::setSource(const QString &url) if (url == d->source) return; - if (d->reply) { - d->reply->deleteLater(); - d->reply = 0; + if (d->sciReply) { + d->sciReply->deleteLater(); + d->sciReply = 0; } if (!d->url.isEmpty()) @@ -904,8 +904,8 @@ void QFxImage::setSource(const QString &url) { QNetworkRequest req(d->url); req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); - d->reply = qmlEngine(this)->networkAccessManager()->get(req); - QObject::connect(d->reply, SIGNAL(finished()), + d->sciReply = qmlEngine(this)->networkAccessManager()->get(req); + QObject::connect(d->sciReply, SIGNAL(finished()), this, SLOT(sciRequestFinished())); } } else { @@ -958,15 +958,15 @@ void QFxImage::requestFinished() void QFxImage::sciRequestFinished() { Q_D(QFxImage); - if (d->reply->error() != QNetworkReply::NoError) { + if (d->sciReply->error() != QNetworkReply::NoError) { d->status = Error; - d->reply->deleteLater(); - d->reply = 0; + d->sciReply->deleteLater(); + d->sciReply = 0; emit statusChanged(d->status); } else { - QFxGridScaledImage sci(d->reply); - d->reply->deleteLater(); - d->reply = 0; + QFxGridScaledImage sci(d->sciReply); + d->sciReply->deleteLater(); + d->sciReply = 0; setGridScaledImage(sci); } } diff --git a/src/declarative/fx/qfximage_p.h b/src/declarative/fx/qfximage_p.h index 43942fe..8227ce4 100644 --- a/src/declarative/fx/qfximage_p.h +++ b/src/declarative/fx/qfximage_p.h @@ -76,7 +76,7 @@ public: #if defined(QFX_RENDER_OPENGL) _texDirty(true), #endif - status(QFxImage::Idle), reply(0), progress(0.0) + status(QFxImage::Idle), sciReply(0), progress(0.0) { } @@ -109,6 +109,7 @@ public: QString source; QUrl url; QUrl sciurl; + QNetworkReply *sciReply; QPointer reply; qreal progress; }; -- cgit v0.12 From 072f3e64042dc8379d09f3661525879cc4b6a5db Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Thu, 7 May 2009 14:37:25 +1000 Subject: Disable watcher table selection --- src/declarative/debugger/qmldebugger.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/declarative/debugger/qmldebugger.cpp b/src/declarative/debugger/qmldebugger.cpp index 9b84b9e..a1956f9 100644 --- a/src/declarative/debugger/qmldebugger.cpp +++ b/src/declarative/debugger/qmldebugger.cpp @@ -93,6 +93,7 @@ QmlDebugger::QmlDebugger(QWidget *parent) tabs->addTab(m_warnings, "Warnings"); m_watchers = new QTableWidget(this); + m_watchers->setSelectionMode(QTableWidget::NoSelection); tabs->addTab(m_watchers, "Watchers"); splitter->addWidget(tabs); -- cgit v0.12 From 6f665b568b5234d07e8ea709026f4b11bf0c09f0 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 7 May 2009 14:42:35 +1000 Subject: Forgot progress bar. --- demos/declarative/flickr/content/Progress.qml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 demos/declarative/flickr/content/Progress.qml diff --git a/demos/declarative/flickr/content/Progress.qml b/demos/declarative/flickr/content/Progress.qml new file mode 100644 index 0000000..92a232e --- /dev/null +++ b/demos/declarative/flickr/content/Progress.qml @@ -0,0 +1,25 @@ +Item { + id: Progress; + + property var progress: 0 + + Rect { + id: Container; anchors.fill: parent; gradientColor: "#66000000"; + pen.color: "white"; pen.width: 1; color: "#66343434"; radius: height/2 - 2 + } + + Rect { + id: Fill + y: 2; height: parent.height-4; + x: 2; width: Math.max(parent.width * progress - 4, 0); + opacity: width < 1 ? 0 : 1 + color: "lightsteelblue"; gradientColor: "steelblue"; radius: height/2 - 2 + } + + Text { + text: Math.round(progress * 100) + "%" + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + color: "white"; font.bold: true + } +} -- cgit v0.12