src/declarative/graphicsitems/qdeclarativeborderimage.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
    92 QDeclarativeBorderImage::~QDeclarativeBorderImage()
    92 QDeclarativeBorderImage::~QDeclarativeBorderImage()
    93 {
    93 {
    94     Q_D(QDeclarativeBorderImage);
    94     Q_D(QDeclarativeBorderImage);
    95     if (d->sciReply)
    95     if (d->sciReply)
    96         d->sciReply->deleteLater();
    96         d->sciReply->deleteLater();
    97     if (d->sciPendingPixmapCache)
       
    98         QDeclarativePixmapCache::cancel(d->sciurl, this);
       
    99 }
    97 }
   100 /*!
    98 /*!
   101     \qmlproperty enumeration BorderImage::status
    99     \qmlproperty enumeration BorderImage::status
   102 
   100 
   103     This property holds the status of image loading.  It can be one of:
   101     This property holds the status of image loading.  It can be one of:
   136 /*!
   134 /*!
   137     \qmlproperty url BorderImage::source
   135     \qmlproperty url BorderImage::source
   138 
   136 
   139     BorderImage can handle any image format supported by Qt, loaded from any URL scheme supported by Qt.
   137     BorderImage can handle any image format supported by Qt, loaded from any URL scheme supported by Qt.
   140 
   138 
   141     It can also handle .sci files, which are a Qml-specific format. A .sci file uses a simple text-based format that specifies
   139     It can also handle .sci files, which are a QML-specific format. A .sci file uses a simple text-based format that specifies
   142     the borders, the image file and the tile rules.
   140     the borders, the image file and the tile rules.
   143 
   141 
   144     The following .sci file sets the borders to 10 on each side for the image \c picture.png:
   142     The following .sci file sets the borders to 10 on each side for the image \c picture.png:
   145     \qml
   143     \qml
   146     border.left: 10
   144     border.left: 10
   149     border.right: 10
   147     border.right: 10
   150     source: picture.png
   148     source: picture.png
   151     \endqml
   149     \endqml
   152 
   150 
   153     The URL may be absolute, or relative to the URL of the component.
   151     The URL may be absolute, or relative to the URL of the component.
       
   152 
       
   153     \sa QDeclarativeImageProvider
   154 */
   154 */
   155 void QDeclarativeBorderImage::setSource(const QUrl &url)
   155 void QDeclarativeBorderImage::setSource(const QUrl &url)
   156 {
   156 {
   157     Q_D(QDeclarativeBorderImage);
   157     Q_D(QDeclarativeBorderImage);
   158     //equality is fairly expensive, so we bypass for simple, common case
   158     //equality is fairly expensive, so we bypass for simple, common case
   162     if (d->sciReply) {
   162     if (d->sciReply) {
   163         d->sciReply->deleteLater();
   163         d->sciReply->deleteLater();
   164         d->sciReply = 0;
   164         d->sciReply = 0;
   165     }
   165     }
   166 
   166 
   167     if (d->pendingPixmapCache) {
       
   168         QDeclarativePixmapCache::cancel(d->url, this);
       
   169         d->pendingPixmapCache = false;
       
   170     }
       
   171     if (d->sciPendingPixmapCache) {
       
   172         QDeclarativePixmapCache::cancel(d->sciurl, this);
       
   173         d->sciPendingPixmapCache = false;
       
   174     }
       
   175 
       
   176     d->url = url;
   167     d->url = url;
   177     d->sciurl = QUrl();
   168     d->sciurl = QUrl();
   178     emit sourceChanged(d->url);
   169     emit sourceChanged(d->url);
   179 
   170 
   180     if (isComponentComplete())
   171     if (isComponentComplete())
   188         d->progress = 0.0;
   179         d->progress = 0.0;
   189         emit progressChanged(d->progress);
   180         emit progressChanged(d->progress);
   190     }
   181     }
   191 
   182 
   192     if (d->url.isEmpty()) {
   183     if (d->url.isEmpty()) {
   193         d->pix = QPixmap();
   184         d->pix.clear();
   194         d->status = Null;
   185         d->status = Null;
   195         setImplicitWidth(0);
   186         setImplicitWidth(0);
   196         setImplicitHeight(0);
   187         setImplicitHeight(0);
   197         emit statusChanged(d->status);
   188         emit statusChanged(d->status);
   198         update();
   189         update();
   222 
   213 
   223                 QMetaObject::connect(d->sciReply, sciReplyFinished, this,
   214                 QMetaObject::connect(d->sciReply, sciReplyFinished, this,
   224                                      thisSciRequestFinished, Qt::DirectConnection);
   215                                      thisSciRequestFinished, Qt::DirectConnection);
   225             }
   216             }
   226         } else {
   217         } else {
   227             QSize impsize;
   218 
   228             QString errorString;
   219             d->pix.load(qmlEngine(this), d->url, d->async);
   229             QDeclarativePixmapReply::Status status = QDeclarativePixmapCache::get(d->url, &d->pix, &errorString, &impsize, d->async);
   220 
   230             if (status != QDeclarativePixmapReply::Ready && status != QDeclarativePixmapReply::Error) {
   221             if (d->pix.isLoading()) {
   231                 QDeclarativePixmapReply *reply = QDeclarativePixmapCache::request(qmlEngine(this), d->url);
   222                 d->pix.connectFinished(this, SLOT(requestFinished()));
   232                 d->pendingPixmapCache = true;
   223                 d->pix.connectDownloadProgress(this, SLOT(requestProgress(qint64,qint64)));
   233                 connect(reply, SIGNAL(finished()), this, SLOT(requestFinished()));
       
   234                 connect(reply, SIGNAL(downloadProgress(qint64,qint64)),
       
   235                         this, SLOT(requestProgress(qint64,qint64)));
       
   236             } else {
   224             } else {
   237                 //### should be unified with requestFinished
   225                 QSize impsize = d->pix.implicitSize();
   238                 setImplicitWidth(impsize.width());
   226                 setImplicitWidth(impsize.width());
   239                 setImplicitHeight(impsize.height());
   227                 setImplicitHeight(impsize.height());
   240 
   228 
   241                 if (d->pix.isNull()) {
   229                 if (d->pix.isReady()) {
       
   230                     d->status = Ready;
       
   231                 } else {
   242                     d->status = Error;
   232                     d->status = Error;
   243                     qmlInfo(this) << errorString;
   233                     qmlInfo(this) << d->pix.error();
   244                 }
   234                 }
   245                 if (d->status == Loading)
   235 
   246                     d->status = Ready;
       
   247                 d->progress = 1.0;
   236                 d->progress = 1.0;
   248                 emit statusChanged(d->status);
   237                 emit statusChanged(d->status);
   249                 emit progressChanged(d->progress);
   238                 emit progressChanged(d->progress);
   250                 update();
   239                 update();
   251             }
   240             }
   341         sg->setRight(sci.gridRight());
   330         sg->setRight(sci.gridRight());
   342         d->horizontalTileMode = sci.horizontalTileRule();
   331         d->horizontalTileMode = sci.horizontalTileRule();
   343         d->verticalTileMode = sci.verticalTileRule();
   332         d->verticalTileMode = sci.verticalTileRule();
   344 
   333 
   345         d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl()));
   334         d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl()));
   346         QSize impsize;
   335 
   347         QString errorString;
   336         d->pix.load(qmlEngine(this), d->sciurl, d->async);
   348         QDeclarativePixmapReply::Status status = QDeclarativePixmapCache::get(d->sciurl, &d->pix, &errorString, &impsize, d->async);
   337 
   349         if (status != QDeclarativePixmapReply::Ready && status != QDeclarativePixmapReply::Error) {
   338         if (d->pix.isLoading()) {
   350             QDeclarativePixmapReply *reply = QDeclarativePixmapCache::request(qmlEngine(this), d->sciurl);
       
   351             d->sciPendingPixmapCache = true;
       
   352 
       
   353             static int replyDownloadProgress = -1;
       
   354             static int replyFinished = -1;
       
   355             static int thisRequestProgress = -1;
   339             static int thisRequestProgress = -1;
   356             static int thisRequestFinished = -1;
   340             static int thisRequestFinished = -1;
   357             if (replyDownloadProgress == -1) {
   341             if (thisRequestProgress == -1) {
   358                 replyDownloadProgress =
       
   359                     QDeclarativePixmapReply::staticMetaObject.indexOfSignal("downloadProgress(qint64,qint64)");
       
   360                 replyFinished =
       
   361                     QDeclarativePixmapReply::staticMetaObject.indexOfSignal("finished()");
       
   362                 thisRequestProgress =
   342                 thisRequestProgress =
   363                     QDeclarativeBorderImage::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
   343                     QDeclarativeBorderImage::staticMetaObject.indexOfSlot("requestProgress(qint64,qint64)");
   364                 thisRequestFinished =
   344                 thisRequestFinished =
   365                     QDeclarativeBorderImage::staticMetaObject.indexOfSlot("requestFinished()");
   345                     QDeclarativeBorderImage::staticMetaObject.indexOfSlot("requestFinished()");
   366             }
   346             }
   367 
   347 
   368             QMetaObject::connect(reply, replyFinished, this,
   348             d->pix.connectFinished(this, thisRequestFinished);
   369                                  thisRequestFinished, Qt::DirectConnection);
   349             d->pix.connectDownloadProgress(this, thisRequestProgress);
   370             QMetaObject::connect(reply, replyDownloadProgress, this,
   350 
   371                                  thisRequestProgress, Qt::DirectConnection);
       
   372         } else {
   351         } else {
   373             //### should be unified with requestFinished
   352 
       
   353             QSize impsize = d->pix.implicitSize();
   374             setImplicitWidth(impsize.width());
   354             setImplicitWidth(impsize.width());
   375             setImplicitHeight(impsize.height());
   355             setImplicitHeight(impsize.height());
   376 
   356 
   377             if (d->pix.isNull()) {
   357             if (d->pix.isReady()) {
       
   358                 d->status = Ready;
       
   359             } else {
   378                 d->status = Error;
   360                 d->status = Error;
   379                 qmlInfo(this) << errorString;
   361                 qmlInfo(this) << d->pix.error();
   380             }
   362             }
   381             if (d->status == Loading)
   363 
   382                 d->status = Ready;
       
   383             d->progress = 1.0;
   364             d->progress = 1.0;
   384             emit statusChanged(d->status);
   365             emit statusChanged(d->status);
   385             emit progressChanged(1.0);
   366             emit progressChanged(1.0);
   386             update();
   367             update();
       
   368 
   387         }
   369         }
   388     }
   370     }
   389 }
   371 }
   390 
   372 
   391 void QDeclarativeBorderImage::requestFinished()
   373 void QDeclarativeBorderImage::requestFinished()
   392 {
   374 {
   393     Q_D(QDeclarativeBorderImage);
   375     Q_D(QDeclarativeBorderImage);
   394 
   376 
   395     QSize impsize;
   377     QSize impsize = d->pix.implicitSize();
   396     if (d->url.path().endsWith(QLatin1String(".sci"))) {
   378     if (d->pix.isError()) {
   397         d->sciPendingPixmapCache = false;
   379         d->status = Error;
   398         QString errorString;
   380         qmlInfo(this) << d->pix.error();
   399         if (QDeclarativePixmapCache::get(d->sciurl, &d->pix, &errorString, &impsize, d->async) != QDeclarativePixmapReply::Ready) {
       
   400             d->status = Error;
       
   401             qmlInfo(this) << errorString;
       
   402         }
       
   403     } else {
   381     } else {
   404         d->pendingPixmapCache = false;
   382         d->status = Ready;
   405         QString errorString;
   383     }
   406         if (QDeclarativePixmapCache::get(d->url, &d->pix, &errorString, &impsize, d->async) != QDeclarativePixmapReply::Ready) {
   384 
   407             d->status = Error;
       
   408             qmlInfo(this) << errorString;
       
   409         }
       
   410     }
       
   411     setImplicitWidth(impsize.width());
   385     setImplicitWidth(impsize.width());
   412     setImplicitHeight(impsize.height());
   386     setImplicitHeight(impsize.height());
   413 
   387 
   414     if (d->status == Loading)
       
   415         d->status = Ready;
       
   416     d->progress = 1.0;
   388     d->progress = 1.0;
   417     emit statusChanged(d->status);
   389     emit statusChanged(d->status);
   418     emit progressChanged(1.0);
   390     emit progressChanged(1.0);
   419     update();
   391     update();
   420 }
   392 }
   447         d->sciReply = 0;
   419         d->sciReply = 0;
   448         setGridScaledImage(sci);
   420         setGridScaledImage(sci);
   449     }
   421     }
   450 }
   422 }
   451 
   423 
       
   424 void QDeclarativeBorderImage::doUpdate()
       
   425 {
       
   426     update();
       
   427 }
       
   428 
   452 void QDeclarativeBorderImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
   429 void QDeclarativeBorderImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
   453 {
   430 {
   454     Q_D(QDeclarativeBorderImage);
   431     Q_D(QDeclarativeBorderImage);
   455     if (d->pix.isNull())
   432     if (d->pix.isNull())
   456         return;
   433         return;