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