Skip to content

Commit

Permalink
[composer] Fetch html using QgsNetworkAccessManager so that reply can…
Browse files Browse the repository at this point in the history
… be manipulated prior to rendering. Sponsored by City of Uster, Switzerland.
  • Loading branch information
nyalldawson committed Jul 16, 2014
1 parent 256999d commit 3f90dbb
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 6 deletions.
67 changes: 62 additions & 5 deletions src/core/composer/qgscomposerhtml.cpp
Expand Up @@ -18,12 +18,14 @@
#include "qgscomposition.h"
#include "qgsaddremovemultiframecommand.h"
#include "qgsnetworkaccessmanager.h"
#include "qgsmessagelog.h"

#include <QCoreApplication>
#include <QPainter>
#include <QWebFrame>
#include <QWebPage>
#include <QImage>
#include <QNetworkReply>

QgsComposerHtml::QgsComposerHtml( QgsComposition* c, bool createUndoCommands ): QgsComposerMultiFrame( c, createUndoCommands ),
mContentMode( QgsComposerHtml::Url ),
Expand Down Expand Up @@ -78,26 +80,81 @@ void QgsComposerHtml::setHtml( const QString html )
mHtml = html;
}

QString QgsComposerHtml::fetchHtml( QUrl url )
{
QUrl nextUrlToFetch = url;
QNetworkReply* reply = 0;

//loop until fetched valid html
while ( 1 )
{
//set contents
QNetworkRequest request( nextUrlToFetch );
reply = QgsNetworkAccessManager::instance()->get( request );
connect( reply, SIGNAL( finished() ), this, SLOT( frameLoaded() ) );
//pause until HTML fetch
mLoaded = false;
while ( !mLoaded )
{
qApp->processEvents();
}

if ( reply->error() != QNetworkReply::NoError )
{
QgsMessageLog::logMessage( tr( "HTML fetch %1 failed with error %2" ).arg( reply->url().toString() ).arg( reply->errorString() ) );
reply->deleteLater();
return QString();
}

QVariant redirect = reply->attribute( QNetworkRequest::RedirectionTargetAttribute );
if ( redirect.isNull() )
{
//no error or redirect, got target
break;
}

//redirect, so fetch redirect target
nextUrlToFetch = redirect.toUrl();
reply->deleteLater();
}

QVariant status = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute );
if ( !status.isNull() && status.toInt() >= 400 )
{
QgsMessageLog::logMessage( tr( "HTML fetch %1 failed with error %2" ).arg( reply->url().toString() ).arg( status.toString() ) );
reply->deleteLater();
return QString();
}

QByteArray array = reply->readAll();
reply->deleteLater();
return QString( array );
}

void QgsComposerHtml::loadHtml()
{
if ( !mWebPage || ( mContentMode == QgsComposerHtml::Url && mUrl.isEmpty() ) )
{
return;
}

mLoaded = false;
//set contents
QString loadedHtml;
switch ( mContentMode )
{
case QgsComposerHtml::Url:
mWebPage->mainFrame()->load( mUrl );
{
loadedHtml = fetchHtml( mUrl );
break;
}
case QgsComposerHtml::ManualHtml:
mWebPage->mainFrame()->setHtml( mHtml );
loadedHtml = mHtml;
break;
}

//pause until HTML loaded
mLoaded = false;
//set html, using the specified url as base if in Url mode
mWebPage->mainFrame()->setHtml( loadedHtml, mContentMode == QgsComposerHtml::Url ? QUrl( mUrl ) : QUrl() );

while ( !mLoaded )
{
qApp->processEvents();
Expand Down
5 changes: 4 additions & 1 deletion src/core/composer/qgscomposerhtml.h
Expand Up @@ -155,7 +155,7 @@ class CORE_EXPORT QgsComposerHtml: public QgsComposerMultiFrame
void loadHtml();

private slots:
void frameLoaded( bool ok );
void frameLoaded( bool ok = true );

private:
ContentMode mContentMode;
Expand All @@ -173,6 +173,9 @@ class CORE_EXPORT QgsComposerHtml: public QgsComposerMultiFrame

//renders a snapshot of the page to a cached image
void renderCachedImage();

//fetches html content from a url and returns it as a string
QString fetchHtml( QUrl url );
};

#endif // QGSCOMPOSERHTML_H

0 comments on commit 3f90dbb

Please sign in to comment.