1f12dc5a7e10c243b9e77110a4bec045e905fd50
[profile/ivi/qtdeclarative.git] / src / quick / items / qquickimagebase.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: http://www.qt-project.org/
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qquickimagebase_p.h"
43 #include "qquickimagebase_p_p.h"
44
45 #include <QtDeclarative/qdeclarativeinfo.h>
46
47 QT_BEGIN_NAMESPACE
48
49 QQuickImageBase::QQuickImageBase(QQuickItem *parent)
50 : QQuickImplicitSizeItem(*(new QQuickImageBasePrivate), parent)
51 {
52     setFlag(ItemHasContents);
53 }
54
55 QQuickImageBase::QQuickImageBase(QQuickImageBasePrivate &dd, QQuickItem *parent)
56 : QQuickImplicitSizeItem(dd, parent)
57 {
58     setFlag(ItemHasContents);
59 }
60
61 QQuickImageBase::~QQuickImageBase()
62 {
63 }
64
65 QQuickImageBase::Status QQuickImageBase::status() const
66 {
67     Q_D(const QQuickImageBase);
68     return d->status;
69 }
70
71
72 qreal QQuickImageBase::progress() const
73 {
74     Q_D(const QQuickImageBase);
75     return d->progress;
76 }
77
78
79 bool QQuickImageBase::asynchronous() const
80 {
81     Q_D(const QQuickImageBase);
82     return d->async;
83 }
84
85 void QQuickImageBase::setAsynchronous(bool async)
86 {
87     Q_D(QQuickImageBase);
88     if (d->async != async) {
89         d->async = async;
90         emit asynchronousChanged();
91     }
92 }
93
94 QUrl QQuickImageBase::source() const
95 {
96     Q_D(const QQuickImageBase);
97     return d->url;
98 }
99
100 void QQuickImageBase::setSource(const QUrl &url)
101 {
102     Q_D(QQuickImageBase);
103     //equality is fairly expensive, so we bypass for simple, common case
104     if ((d->url.isEmpty() == url.isEmpty()) && url == d->url)
105         return;
106
107     d->url = url;
108     emit sourceChanged(d->url);
109
110     if (isComponentComplete())
111         load();
112 }
113
114 void QQuickImageBase::setSourceSize(const QSize& size)
115 {
116     Q_D(QQuickImageBase);
117     if (d->sourcesize == size)
118         return;
119
120     d->sourcesize = size;
121     d->explicitSourceSize = true;
122     emit sourceSizeChanged();
123     if (isComponentComplete())
124         load();
125 }
126
127 QSize QQuickImageBase::sourceSize() const
128 {
129     Q_D(const QQuickImageBase);
130
131     int width = d->sourcesize.width();
132     int height = d->sourcesize.height();
133     return QSize(width != -1 ? width : d->pix.width(), height != -1 ? height : d->pix.height());
134 }
135
136 void QQuickImageBase::resetSourceSize()
137 {
138     Q_D(QQuickImageBase);
139     if (!d->explicitSourceSize)
140         return;
141     d->explicitSourceSize = false;
142     d->sourcesize = QSize();
143     emit sourceSizeChanged();
144     if (isComponentComplete())
145         load();
146 }
147
148 bool QQuickImageBase::cache() const
149 {
150     Q_D(const QQuickImageBase);
151     return d->cache;
152 }
153
154 void QQuickImageBase::setCache(bool cache)
155 {
156     Q_D(QQuickImageBase);
157     if (d->cache == cache)
158         return;
159
160     d->cache = cache;
161     emit cacheChanged();
162     if (isComponentComplete())
163         load();
164 }
165
166 QImage QQuickImageBase::image() const
167 {
168     Q_D(const QQuickImageBase);
169     return d->pix.image();
170 }
171
172 void QQuickImageBase::setMirror(bool mirror)
173 {
174     Q_D(QQuickImageBase);
175     if (mirror == d->mirror)
176         return;
177
178     d->mirror = mirror;
179
180     if (isComponentComplete())
181         update();
182
183     emit mirrorChanged();
184 }
185
186 bool QQuickImageBase::mirror() const
187 {
188     Q_D(const QQuickImageBase);
189     return d->mirror;
190 }
191
192 void QQuickImageBase::load()
193 {
194     Q_D(QQuickImageBase);
195
196     if (d->url.isEmpty()) {
197         d->pix.clear(this);
198         d->status = Null;
199         d->progress = 0.0;
200         pixmapChange();
201         emit progressChanged(d->progress);
202         emit statusChanged(d->status);
203         update();
204     } else {
205         QDeclarativePixmap::Options options;
206         if (d->async)
207             options |= QDeclarativePixmap::Asynchronous;
208         if (d->cache)
209             options |= QDeclarativePixmap::Cache;
210         d->pix.clear(this);
211         pixmapChange();
212         d->pix.load(qmlEngine(this), d->url, d->explicitSourceSize ? sourceSize() : QSize(), options);
213
214         if (d->pix.isLoading()) {
215             d->progress = 0.0;
216             d->status = Loading;
217             emit progressChanged(d->progress);
218             emit statusChanged(d->status);
219
220             static int thisRequestProgress = -1;
221             static int thisRequestFinished = -1;
222             if (thisRequestProgress == -1) {
223                 thisRequestProgress =
224                     QQuickImageBase::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
225                 thisRequestFinished =
226                     QQuickImageBase::staticMetaObject.indexOfSlot("requestFinished()");
227             }
228
229             d->pix.connectFinished(this, thisRequestFinished);
230             d->pix.connectDownloadProgress(this, thisRequestProgress);
231
232         } else {
233             requestFinished();
234         }
235     }
236 }
237
238 void QQuickImageBase::requestFinished()
239 {
240     Q_D(QQuickImageBase);
241
242     QQuickImageBase::Status oldStatus = d->status;
243     qreal oldProgress = d->progress;
244
245     if (d->pix.isError()) {
246         d->status = Error;
247         qmlInfo(this) << d->pix.error();
248     } else {
249         d->status = Ready;
250     }
251
252     d->progress = 1.0;
253
254     pixmapChange();
255
256     if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height())
257         emit sourceSizeChanged();
258
259     if (d->status != oldStatus)
260         emit statusChanged(d->status);
261     if (d->progress != oldProgress)
262         emit progressChanged(d->progress);
263
264     update();
265 }
266
267 void QQuickImageBase::requestProgress(qint64 received, qint64 total)
268 {
269     Q_D(QQuickImageBase);
270     if (d->status == Loading && total > 0) {
271         d->progress = qreal(received)/total;
272         emit progressChanged(d->progress);
273     }
274 }
275
276 void QQuickImageBase::componentComplete()
277 {
278     Q_D(QQuickImageBase);
279     QQuickItem::componentComplete();
280     if (d->url.isValid())
281         load();
282 }
283
284 void QQuickImageBase::pixmapChange()
285 {
286     Q_D(QQuickImageBase);
287     setImplicitSize(d->pix.width(), d->pix.height());
288 }
289
290 QT_END_NAMESPACE