diff options
author | Yann Bodson <yann.bodson@nokia.com> | 2009-08-07 06:54:32 (GMT) |
---|---|---|
committer | Yann Bodson <yann.bodson@nokia.com> | 2009-08-07 07:01:57 (GMT) |
commit | 7105e534a980554277fbe1da2698fca6a5bc49aa (patch) | |
tree | 1dcc1c8dc1aec1f25d2f43fac327fdacb4091149 /src/declarative/fx/qfximagebase.cpp | |
parent | d93e8b21fafb546c9f8fefbb170bbb2d66fe6e93 (diff) | |
download | Qt-7105e534a980554277fbe1da2698fca6a5bc49aa.zip Qt-7105e534a980554277fbe1da2698fca6a5bc49aa.tar.gz Qt-7105e534a980554277fbe1da2698fca6a5bc49aa.tar.bz2 |
Start moving code from QFxImage to QFxImageBase
Diffstat (limited to 'src/declarative/fx/qfximagebase.cpp')
-rw-r--r-- | src/declarative/fx/qfximagebase.cpp | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/src/declarative/fx/qfximagebase.cpp b/src/declarative/fx/qfximagebase.cpp index e0b72c2..39c43d3 100644 --- a/src/declarative/fx/qfximagebase.cpp +++ b/src/declarative/fx/qfximagebase.cpp @@ -41,17 +41,263 @@ #include "qfximagebase.h" #include "qfximagebase_p.h" +#include <QNetworkRequest> +#include <QNetworkReply> +#include <QFile> +#include <QtDeclarative/qmlengine.h> QT_BEGIN_NAMESPACE QFxImageBase::QFxImageBase(QFxItem *parent) : QFxItem(*(new QFxImageBasePrivate), parent) { + setFlag(QGraphicsItem::ItemHasNoContents, true); } QFxImageBase::QFxImageBase(QFxImageBasePrivate &dd, QFxItem *parent) : QFxItem(dd, parent) { + setFlag(QGraphicsItem::ItemHasNoContents, true); +} + +QFxImageBase::~QFxImageBase() +{ + Q_D(QFxImageBase); + if (d->sciReply) + d->sciReply->deleteLater(); + if (!d->url.isEmpty()) + QFxPixmap::cancelGet(d->url, this); + if (!d->sciurl.isEmpty()) + QFxPixmap::cancelGet(d->sciurl, this); +} + +/*! + \qmlproperty int Image::scaleGrid.left + \qmlproperty int Image::scaleGrid.right + \qmlproperty int Image::scaleGrid.top + \qmlproperty int Image::scaleGrid.bottom + + \target ImagexmlpropertiesscaleGrid + + A scale grid uses 4 grid lines (2 horizontal and 2 vertical) to break an image into 9 sections, as shown below: + + \image declarative-scalegrid.png + + When the image is scaled: + \list + \i the corners (sections 1, 3, 7, and 9) are not scaled at all + \i the middle (section 5) is scaled both horizontally and vertically + \i sections 2 and 8 are scaled horizontally + \i sections 4 and 6 are scaled vertically + \endlist + + Each scale grid property (left, right, top, and bottom) specifies an offset from the respective side. For example, \c scaleGrid.bottom="10" sets the bottom scale grid line 10 pixels up from the bottom of the image. + + A scale grid can also be specified using a + \l {Image::source}{.sci file}. +*/ +QFxScaleGrid *QFxImageBase::scaleGrid() +{ + Q_D(QFxImageBase); + return d->getScaleGrid(); +} + +void QFxImageBase::componentComplete() +{ + QFxItem::componentComplete(); +} + + +QFxImageBase::Status QFxImageBase::status() const +{ + Q_D(const QFxImageBase); + return d->status; +} + + +qreal QFxImageBase::progress() const +{ + Q_D(const QFxImageBase); + return d->progress; +} + + +/*! + \property QFxImage::source + \brief the url of the image to be displayed in this item. + + The content specified can be of any image type loadable by QImage. Alternatively, + you can specify an sci format file, which specifies both an image and it's scale grid. +*/ +QUrl QFxImageBase::source() const +{ + Q_D(const QFxImageBase); + return d->url; +} + +void QFxImageBase::setSource(const QUrl &url) +{ + Q_D(QFxImageBase); + //equality is fairly expensive, so we bypass for simple, common case + if ((d->url.isEmpty() == url.isEmpty()) && url == d->url) + return; + + if (d->sciReply) { + d->sciReply->deleteLater(); + d->sciReply = 0; + } + + if (!d->url.isEmpty()) + QFxPixmap::cancelGet(d->url, this); + if (!d->sciurl.isEmpty()) + QFxPixmap::cancelGet(d->sciurl, this); + + d->url = url; + d->sciurl = QUrl(); + if (d->progress != 0.0) { + d->progress = 0.0; + emit progressChanged(d->progress); + } + + if (url.isEmpty()) { + d->pix = QPixmap(); + d->status = Null; + d->progress = 1.0; + setImplicitWidth(0); + setImplicitHeight(0); + emit statusChanged(d->status); + emit sourceChanged(d->url); + emit progressChanged(1.0); + update(); + } else { + d->status = Loading; + if (d->url.path().endsWith(QLatin1String(".sci"))) { +#ifndef QT_NO_LOCALFILE_OPTIMIZED_QML + if (d->url.scheme() == QLatin1String("file")) { + QFile file(d->url.toLocalFile()); + file.open(QIODevice::ReadOnly); + setGridScaledImage(QFxGridScaledImage(&file)); + } else +#endif + { + QNetworkRequest req(d->url); + req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); + d->sciReply = qmlEngine(this)->networkAccessManager()->get(req); + QObject::connect(d->sciReply, SIGNAL(finished()), + this, SLOT(sciRequestFinished())); + } + } else { + d->reply = QFxPixmap::get(qmlEngine(this), d->url, &d->pix); + if (d->reply) { + connect(d->reply, SIGNAL(finished()), this, SLOT(requestFinished())); + connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), + this, SLOT(requestProgress(qint64,qint64))); + } else { + //### should be unified with requestFinished + setImplicitWidth(d->pix.width()); + setImplicitHeight(d->pix.height()); + + if (d->status == Loading) + d->status = Ready; + d->progress = 1.0; + emit statusChanged(d->status); + emit sourceChanged(d->url); + emit progressChanged(1.0); + update(); + } + } + } + + emit statusChanged(d->status); +} + +void QFxImageBase::requestFinished() +{ + Q_D(QFxImageBase); + if (d->url.path().endsWith(QLatin1String(".sci"))) { + QFxPixmap::find(d->sciurl, &d->pix); + } else { + if (d->reply) { + //###disconnect really needed? + disconnect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), + this, SLOT(requestProgress(qint64,qint64))); + if (d->reply->error() != QNetworkReply::NoError) + d->status = Error; + } + QFxPixmap::find(d->url, &d->pix); + } + setImplicitWidth(d->pix.width()); + setImplicitHeight(d->pix.height()); + + if (d->status == Loading) + d->status = Ready; + d->progress = 1.0; + emit statusChanged(d->status); + emit sourceChanged(d->url); + emit progressChanged(1.0); + update(); +} + +void QFxImageBase::sciRequestFinished() +{ + Q_D(QFxImageBase); + if (d->sciReply->error() != QNetworkReply::NoError) { + d->status = Error; + d->sciReply->deleteLater(); + d->sciReply = 0; + emit statusChanged(d->status); + } else { + QFxGridScaledImage sci(d->sciReply); + d->sciReply->deleteLater(); + d->sciReply = 0; + setGridScaledImage(sci); + } +} + +void QFxImageBase::requestProgress(qint64 received, qint64 total) +{ + Q_D(QFxImageBase); + if (d->status == Loading && total > 0) { + d->progress = qreal(received)/total; + emit progressChanged(d->progress); + } +} + +void QFxImageBase::setGridScaledImage(const QFxGridScaledImage& sci) +{ + Q_D(QFxImageBase); + if (!sci.isValid()) { + d->status = Error; + emit statusChanged(d->status); + } else { + QFxScaleGrid *sg = scaleGrid(); + sg->setTop(sci.gridTop()); + sg->setBottom(sci.gridBottom()); + sg->setLeft(sci.gridLeft()); + sg->setRight(sci.gridRight()); + sg->setHorizontalTileRule(sci.horizontalTileRule()); + sg->setVerticalTileRule(sci.verticalTileRule()); + + d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl())); + d->reply = QFxPixmap::get(qmlEngine(this), d->sciurl, &d->pix); + if (d->reply) { + connect(d->reply, SIGNAL(finished()), this, SLOT(requestFinished())); + connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), + this, SLOT(requestProgress(qint64,qint64))); + } else { + //### should be unified with requestFinished + setImplicitWidth(d->pix.width()); + setImplicitHeight(d->pix.height()); + + if (d->status == Loading) + d->status = Ready; + d->progress = 1.0; + emit statusChanged(d->status); + emit sourceChanged(d->url); + emit progressChanged(1.0); + update(); + } + } } QT_END_NAMESPACE |