Qt 4.8
qdeclarativeborderimage.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
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, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "private/qdeclarativeborderimage_p.h"
43 #include "private/qdeclarativeborderimage_p_p.h"
44 
45 #include <qdeclarativeinfo.h>
46 #include <private/qdeclarativeengine_p.h>
47 
48 #include <QNetworkRequest>
49 #include <QNetworkReply>
50 #include <QFile>
51 
53 
174 {
175 }
176 
178 {
180  if (d->sciReply)
181  d->sciReply->deleteLater();
182 }
300 {
302  //equality is fairly expensive, so we bypass for simple, common case
303  if ((d->url.isEmpty() == url.isEmpty()) && url == d->url)
304  return;
305 
306  if (d->sciReply) {
307  d->sciReply->deleteLater();
308  d->sciReply = 0;
309  }
310 
311  d->url = url;
312  d->sciurl = QUrl();
313  emit sourceChanged(d->url);
314 
315  if (isComponentComplete())
316  load();
317 }
318 
320 {
321  Q_UNUSED(size);
322  qmlInfo(this) << "Setting sourceSize for borderImage not supported";
323 }
324 
326 {
328  if (d->progress != 0.0) {
329  d->progress = 0.0;
330  emit progressChanged(d->progress);
331  }
332 
333  if (d->url.isEmpty()) {
334  d->pix.clear(this);
335  d->status = Null;
336  setImplicitWidth(0);
338  emit statusChanged(d->status);
339  update();
340  } else {
341  d->status = Loading;
342  if (d->url.path().endsWith(QLatin1String("sci"))) {
343 #ifndef QT_NO_LOCALFILE_OPTIMIZED_QML
345  if (!lf.isEmpty()) {
346  QFile file(lf);
349  } else
350 #endif
351  {
352  QNetworkRequest req(d->url);
353  d->sciReply = qmlEngine(this)->networkAccessManager()->get(req);
354 
355  static int sciReplyFinished = -1;
356  static int thisSciRequestFinished = -1;
357  if (sciReplyFinished == -1) {
358  sciReplyFinished =
360  thisSciRequestFinished =
362  }
363 
364  QMetaObject::connect(d->sciReply, sciReplyFinished, this,
365  thisSciRequestFinished, Qt::DirectConnection);
366  }
367  } else {
368 
369  QDeclarativePixmap::Options options;
370  if (d->async)
372  if (d->cache)
373  options |= QDeclarativePixmap::Cache;
374  d->pix.clear(this);
375  d->pix.load(qmlEngine(this), d->url, options);
376 
377  if (d->pix.isLoading()) {
378  d->pix.connectFinished(this, SLOT(requestFinished()));
379  d->pix.connectDownloadProgress(this, SLOT(requestProgress(qint64,qint64)));
380  } else {
381  QSize impsize = d->pix.implicitSize();
382  setImplicitWidth(impsize.width());
383  setImplicitHeight(impsize.height());
384 
385  if (d->pix.isReady()) {
386  d->status = Ready;
387  } else {
388  d->status = Error;
389  qmlInfo(this) << d->pix.error();
390  }
391 
392  d->progress = 1.0;
393  emit statusChanged(d->status);
394  emit progressChanged(d->progress);
395  requestFinished();
396  update();
397  }
398  }
399  }
400 
401  emit statusChanged(d->status);
402 }
403 
437 {
439  return d->getScaleGrid();
440 }
441 
460 {
462  return d->horizontalTileMode;
463 }
464 
466 {
468  if (t != d->horizontalTileMode) {
469  d->horizontalTileMode = t;
471  update();
472  }
473 }
474 
476 {
478  return d->verticalTileMode;
479 }
480 
482 {
484  if (t != d->verticalTileMode) {
485  d->verticalTileMode = t;
487  update();
488  }
489 }
490 
492 {
494  if (!sci.isValid()) {
495  d->status = Error;
496  emit statusChanged(d->status);
497  } else {
499  sg->setTop(sci.gridTop());
500  sg->setBottom(sci.gridBottom());
501  sg->setLeft(sci.gridLeft());
502  sg->setRight(sci.gridRight());
503  d->horizontalTileMode = sci.horizontalTileRule();
504  d->verticalTileMode = sci.verticalTileRule();
505 
506  d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl()));
507 
508  QDeclarativePixmap::Options options;
509  if (d->async)
511  if (d->cache)
512  options |= QDeclarativePixmap::Cache;
513  d->pix.clear(this);
514  d->pix.load(qmlEngine(this), d->sciurl, options);
515 
516  if (d->pix.isLoading()) {
517  static int thisRequestProgress = -1;
518  static int thisRequestFinished = -1;
519  if (thisRequestProgress == -1) {
520  thisRequestProgress =
521  QDeclarativeBorderImage::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
522  thisRequestFinished =
524  }
525 
526  d->pix.connectFinished(this, thisRequestFinished);
527  d->pix.connectDownloadProgress(this, thisRequestProgress);
528 
529  } else {
530 
531  QSize impsize = d->pix.implicitSize();
532  setImplicitWidth(impsize.width());
533  setImplicitHeight(impsize.height());
534 
535  if (d->pix.isReady()) {
536  d->status = Ready;
537  } else {
538  d->status = Error;
539  qmlInfo(this) << d->pix.error();
540  }
541 
542  d->progress = 1.0;
543  emit statusChanged(d->status);
544  emit progressChanged(1.0);
545  update();
546 
547  }
548  }
549 }
550 
552 {
554 
555  QSize impsize = d->pix.implicitSize();
556  if (d->pix.isError()) {
557  d->status = Error;
558  qmlInfo(this) << d->pix.error();
559  } else {
560  d->status = Ready;
561  }
562 
563  setImplicitWidth(impsize.width());
564  setImplicitHeight(impsize.height());
565 
566  if (d->sourcesize.width() != d->pix.width() || d->sourcesize.height() != d->pix.height())
568 
569  d->progress = 1.0;
570  emit statusChanged(d->status);
571  emit progressChanged(1.0);
572  update();
573 }
574 
575 #define BORDERIMAGE_MAX_REDIRECT 16
576 
578 {
580 
581  d->redirectCount++;
582  if (d->redirectCount < BORDERIMAGE_MAX_REDIRECT) {
583  QVariant redirect = d->sciReply->attribute(QNetworkRequest::RedirectionTargetAttribute);
584  if (redirect.isValid()) {
585  QUrl url = d->sciReply->url().resolved(redirect.toUrl());
586  setSource(url);
587  return;
588  }
589  }
590  d->redirectCount=0;
591 
592  if (d->sciReply->error() != QNetworkReply::NoError) {
593  d->status = Error;
594  d->sciReply->deleteLater();
595  d->sciReply = 0;
596  emit statusChanged(d->status);
597  } else {
598  QDeclarativeGridScaledImage sci(d->sciReply);
599  d->sciReply->deleteLater();
600  d->sciReply = 0;
601  setGridScaledImage(sci);
602  }
603 }
604 
606 {
607  update();
608 }
609 
611 {
613  if (d->pix.isNull() || d->width() <= 0.0 || d->height() <= 0.0)
614  return;
615 
616  bool oldAA = p->testRenderHint(QPainter::Antialiasing);
617  bool oldSmooth = p->testRenderHint(QPainter::SmoothPixmapTransform);
618  QTransform oldTransform;
619  if (d->smooth)
621  if (d->mirror) {
622  oldTransform = p->transform();
624  mirror.translate(d->width(), 0).scale(-1, 1.0);
625  p->setWorldTransform(mirror * oldTransform);
626  }
627 
628  const QDeclarativeScaleGrid *border = d->getScaleGrid();
629  int left = border->left();
630  int right = border->right();
631  qreal borderWidth = left + right;
632  if (borderWidth > 0.0 && d->width() < borderWidth) {
633  qreal diff = borderWidth - d->width() - 1;
634  left -= qRound(diff * qreal(left) / borderWidth);
635  right -= qRound(diff * qreal(right) / borderWidth);
636  }
637  int top = border->top();
638  int bottom = border->bottom();
639  qreal borderHeight = top + bottom;
640  if (borderHeight > 0.0 && d->height() < borderHeight) {
641  qreal diff = borderHeight - d->height() - 1;
642  top -= qRound(diff * qreal(top) / borderHeight);
643  bottom -= qRound(diff * qreal(bottom) / borderHeight);
644  }
645  QMargins margins(left, top, right, bottom);
646  QTileRules rules((Qt::TileRule)d->horizontalTileMode, (Qt::TileRule)d->verticalTileMode);
647  qDrawBorderPixmap(p, QRect(0, 0, (int)d->width(), (int)d->height()), margins, d->pix, d->pix.rect(), margins, rules);
648  if (d->smooth) {
651  }
652  if (d->mirror)
653  p->setWorldTransform(oldTransform);
654 }
655 
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
static QString urlToLocalFileOrQrc(const QUrl &url)
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
QDeclarativeBorderImage::TileMode horizontalTileRule() const
QDeclarativeBorderImage(QDeclarativeItem *parent=0)
double qreal
Definition: qglobal.h:1193
static bool connect(const QObject *sender, int signal_index, const QObject *receiver, int method_index, int type=0, int *types=0)
Definition: qobject.cpp:3194
const QTransform & transform() const
Returns the world transformation matrix.
Definition: qpainter.cpp:9558
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QDeclarativeParserStatus ** d
TileRule
Definition: qnamespace.h:198
bool open(OpenMode flags)
Opens the file using OpenMode mode, returning true if successful; otherwise false.
Definition: qfile.cpp:1064
bool isComponentComplete() const
Returns true if construction of the QML component is complete; otherwise returns false.
bool isEmpty() const
Returns true if the URL has no data; otherwise returns false.
Definition: qurl.cpp:4317
#define SLOT(a)
Definition: qobjectdefs.h:226
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
TileMode horizontalTileMode() const
static const QMetaObject staticMetaObject
This variable stores the meta-object for the class.
Definition: qobject.h:128
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
QTransform & translate(qreal dx, qreal dy)
Moves the coordinate system dx along the x axis and dy along the y axis, and returns a reference to t...
Definition: qtransform.cpp:417
bool testRenderHint(RenderHint hint) const
Returns true if hint is set; otherwise returns false.
Definition: qpainter.h:457
The QUrl class provides a convenient interface for working with URLs.
Definition: qurl.h:61
The QString class provides a Unicode character string.
Definition: qstring.h:83
QDeclarativeScaleGrid * border()
void update(const QRectF &rect=QRectF())
Schedules a redraw of the area covered by rect in this item.
#define Q_D(Class)
Definition: qglobal.h:2482
Q_CORE_EXPORT QTextStream & right(QTextStream &s)
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *)
qreal scale() const
Returns the scale factor of the item.
void statusChanged(QDeclarativeImageBase::Status)
int width() const
Returns the width.
Definition: qsize.h:126
void setRenderHint(RenderHint hint, bool on=true)
Sets the given render hint on the painter if on is true; otherwise clears the render hint...
Definition: qpainter.cpp:7620
TileMode verticalTileMode() const
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
The QDeclarativeItem class provides the most basic of all visual items in QML.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
#define emit
Definition: qobjectdefs.h:76
void sourceChanged(const QUrl &)
static Bigint * diff(Bigint *a, Bigint *b)
int indexOfSlot(const char *slot) const
Finds slot and returns its index; otherwise returns -1.
int indexOfSignal(const char *signal) const
Finds signal and returns its index; otherwise returns -1.
__int64 qint64
Definition: qglobal.h:942
void setImplicitWidth(qreal)
Sets the implied width of the item to w.
QNetworkReply * get(const QNetworkRequest &request)
Posts a request to obtain the contents of the target request and returns a new QNetworkReply object o...
QUrl toUrl() const
Returns the variant as a QUrl if the variant has type() Url ; otherwise returns an invalid QUrl...
Definition: qvariant.cpp:2528
void qDrawBorderPixmap(QPainter *painter, const QRect &targetRect, const QMargins &targetMargins, const QPixmap &pixmap, const QRect &sourceRect, const QMargins &sourceMargins, const QTileRules &rules, QDrawBorderPixmap::DrawingHints hints)
Draws the indicated sourceRect rectangle from the given pixmap into the given targetRect rectangle...
Definition: qdrawutil.cpp:1106
The QDeclarativeScaleGrid class allows you to specify a 3x3 grid to use in scaling an image...
void setRenderHints(RenderHints hints, bool on=true)
Sets the given render hints on the painter if on is true; otherwise clears the render hints...
Definition: qpainter.cpp:7649
The QFile class provides an interface for reading from and writing to files.
Definition: qfile.h:65
void progressChanged(qreal progress)
Q_DECLARATIVE_EXPORT QDeclarativeEngine * qmlEngine(const QObject *)
Holds the rules used to draw a pixmap or image split into nine segments, similar to [CSS3 border-imag...
Definition: qdrawutil.h:136
QDeclarativeBorderImage::TileMode verticalTileRule() const
int height() const
Returns the height.
Definition: qsize.h:129
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
void setWorldTransform(const QTransform &matrix, bool combine=false)
Sets the world transformation matrix.
Definition: qpainter.cpp:9630
The QNetworkRequest class holds a request to be sent with QNetworkAccessManager.
void setGridScaledImage(const QDeclarativeGridScaledImage &sci)
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
The QMargins class defines the four margins of a rectangle.
Definition: qmargins.h:53
QDeclarativeInfo qmlInfo(const QObject *me)
void setImplicitHeight(qreal)
Sets the implied height of the item to h.
QNetworkAccessManager * networkAccessManager() const
Returns a common QNetworkAccessManager which can be used by any QML element instantiated by this engi...
bool isValid() const
Returns true if the storage type of this variant is not QVariant::Invalid; otherwise returns false...
Definition: qvariant.h:485
Q_CORE_EXPORT QTextStream & left(QTextStream &s)
The QStyleOptionGraphicsItem class is used to describe the parameters needed to draw a QGraphicsItem...
Definition: qstyleoption.h:867
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
#define BORDERIMAGE_MAX_REDIRECT
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
void requestProgress(qint64, qint64)
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:65