Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsmaprenderersequentialjob.cpp 3 : : -------------------------------------- 4 : : Date : December 2013 5 : : Copyright : (C) 2013 by Martin Dobias 6 : : Email : wonder dot sk at gmail dot com 7 : : *************************************************************************** 8 : : * * 9 : : * This program is free software; you can redistribute it and/or modify * 10 : : * it under the terms of the GNU General Public License as published by * 11 : : * the Free Software Foundation; either version 2 of the License, or * 12 : : * (at your option) any later version. * 13 : : * * 14 : : ***************************************************************************/ 15 : : 16 : : #include "qgsmaprenderersequentialjob.h" 17 : : 18 : : #include "qgslogger.h" 19 : : #include "qgsmaprenderercustompainterjob.h" 20 : : #include "qgspallabeling.h" 21 : : #include "qgslabelingresults.h" 22 : : 23 : 0 : QgsMapRendererSequentialJob::QgsMapRendererSequentialJob( const QgsMapSettings &settings ) 24 : 0 : : QgsMapRendererQImageJob( settings ) 25 : : 26 : 0 : { 27 : 0 : QgsDebugMsgLevel( QStringLiteral( "SEQUENTIAL construct" ), 5 ); 28 : : 29 : 0 : mImage = QImage( mSettings.deviceOutputSize(), mSettings.outputImageFormat() ); 30 : 0 : mImage.setDevicePixelRatio( mSettings.devicePixelRatio() ); 31 : 0 : mImage.setDotsPerMeterX( mSettings.devicePixelRatio() * 1000 * settings.outputDpi() / 25.4 ); 32 : 0 : mImage.setDotsPerMeterY( mSettings.devicePixelRatio() * 1000 * settings.outputDpi() / 25.4 ); 33 : 0 : mImage.fill( Qt::transparent ); 34 : 0 : } 35 : : 36 : 0 : QgsMapRendererSequentialJob::~QgsMapRendererSequentialJob() 37 : 0 : { 38 : 0 : QgsDebugMsgLevel( QStringLiteral( "SEQUENTIAL destruct" ), 5 ); 39 : 0 : if ( isActive() ) 40 : : { 41 : : // still running! 42 : 0 : QgsDebugMsgLevel( QStringLiteral( "SEQUENTIAL destruct -- still running! (canceling)" ), 5 ); 43 : 0 : cancel(); 44 : 0 : } 45 : : 46 : : Q_ASSERT( !mInternalJob && !mPainter ); 47 : 0 : } 48 : : 49 : : 50 : 0 : void QgsMapRendererSequentialJob::start() 51 : : { 52 : 0 : if ( isActive() ) 53 : 0 : return; // do nothing if we are already running 54 : : 55 : 0 : mLabelingResults.reset(); 56 : : 57 : 0 : mRenderingStart.start(); 58 : 0 : 59 : 0 : mErrors.clear(); 60 : 0 : 61 : 0 : QgsDebugMsgLevel( QStringLiteral( "SEQUENTIAL START" ), 5 ); 62 : 0 : 63 : : Q_ASSERT( !mInternalJob && !mPainter ); 64 : : 65 : 0 : mPainter = new QPainter( &mImage ); 66 : : 67 : 0 : mInternalJob = new QgsMapRendererCustomPainterJob( mSettings, mPainter ); 68 : 0 : mInternalJob->setCache( mCache ); 69 : : 70 : 0 : connect( mInternalJob, &QgsMapRendererJob::finished, this, &QgsMapRendererSequentialJob::internalFinished ); 71 : : 72 : 0 : mInternalJob->start(); 73 : 0 : } 74 : : 75 : : 76 : 0 : void QgsMapRendererSequentialJob::cancel() 77 : : { 78 : 0 : if ( !isActive() ) 79 : 0 : return; 80 : : 81 : 0 : QgsDebugMsgLevel( QStringLiteral( "sequential - cancel internal" ), 5 ); 82 : 0 : mInternalJob->cancel(); 83 : : 84 : : Q_ASSERT( !mInternalJob && !mPainter ); 85 : 0 : } 86 : : 87 : 0 : void QgsMapRendererSequentialJob::cancelWithoutBlocking() 88 : : { 89 : 0 : if ( !isActive() ) 90 : 0 : return; 91 : : 92 : 0 : QgsDebugMsgLevel( QStringLiteral( "sequential - cancel internal" ), 5 ); 93 : 0 : mInternalJob->cancelWithoutBlocking(); 94 : 0 : } 95 : : 96 : 0 : void QgsMapRendererSequentialJob::waitForFinished() 97 : : { 98 : 0 : if ( !isActive() ) 99 : 0 : return; 100 : : 101 : 0 : mInternalJob->waitForFinished(); 102 : 0 : } 103 : : 104 : 0 : bool QgsMapRendererSequentialJob::isActive() const 105 : : { 106 : 0 : return nullptr != mInternalJob; 107 : : } 108 : : 109 : 0 : bool QgsMapRendererSequentialJob::usedCachedLabels() const 110 : : { 111 : 0 : return mUsedCachedLabels; 112 : : } 113 : : 114 : 0 : QgsLabelingResults *QgsMapRendererSequentialJob::takeLabelingResults() 115 : : { 116 : 0 : return mLabelingResults.release(); 117 : : } 118 : : 119 : : 120 : 0 : QImage QgsMapRendererSequentialJob::renderedImage() 121 : : { 122 : 0 : if ( isActive() && mCache ) 123 : : // this will allow immediate display of cached layers and at the same time updates of the layer being rendered 124 : 0 : return composeImage( mSettings, mInternalJob->jobs(), LabelRenderJob() ); 125 : : else 126 : 0 : return mImage; 127 : 0 : } 128 : : 129 : : 130 : 0 : void QgsMapRendererSequentialJob::internalFinished() 131 : : { 132 : 0 : QgsDebugMsgLevel( QStringLiteral( "SEQUENTIAL finished" ), 5 ); 133 : : 134 : 0 : mPainter->end(); 135 : 0 : delete mPainter; 136 : 0 : mPainter = nullptr; 137 : : 138 : 0 : mLabelingResults.reset( mInternalJob->takeLabelingResults() ); 139 : 0 : mUsedCachedLabels = mInternalJob->usedCachedLabels(); 140 : : 141 : 0 : mErrors = mInternalJob->errors(); 142 : : 143 : : // now we are in a slot called from mInternalJob - do not delete it immediately 144 : : // so the class is still valid when the execution returns to the class 145 : 0 : mInternalJob->deleteLater(); 146 : 0 : mInternalJob = nullptr; 147 : : 148 : 0 : mRenderingTime = mRenderingStart.elapsed(); 149 : : 150 : 0 : emit finished(); 151 : 0 : }