Skip to content

Commit 899c2f8

Browse files
committed
[composer] Prevent hang on trying to export compositions and atlases to files which can't be overwritten, and warn user instead (fix #9283) (fix #10016). Fix mouse cursor getting stuck after failed atlas exports.
1 parent d039863 commit 899c2f8

File tree

4 files changed

+119
-27
lines changed

4 files changed

+119
-27
lines changed

python/core/composer/qgscomposition.sip

+8-4
Original file line numberDiff line numberDiff line change
@@ -364,11 +364,15 @@ class QgsComposition : QGraphicsScene
364364
/** Print on a preconfigured printer */
365365
void doPrint( QPrinter& printer, QPainter& painter );
366366

367-
/** Convenience function that prepares the printer and prints */
368-
void print( QPrinter &printer );
367+
/**Convenience function that prepares the printer and prints
368+
* @returns true if print was successful
369+
*/
370+
bool print( QPrinter &printer );
369371

370-
/** Convenience function that prepares the printer for printing in PDF and prints */
371-
void exportAsPDF( const QString& file );
372+
/**Convenience function that prepares the printer for printing in PDF and prints
373+
* @returns true if export was successful
374+
*/
375+
bool exportAsPDF( const QString& file );
372376

373377
//! print composer page to image
374378
//! If the image does not fit into memory, a null image is returned

src/app/composer/qgscomposer.cpp

+91-15
Original file line numberDiff line numberDiff line change
@@ -1406,7 +1406,16 @@ void QgsComposer::exportCompositionAsPDF( QgsComposer::OutputMode mode )
14061406
mComposition->beginPrintAsPDF( printer, outputFileName );
14071407
// set the correct resolution
14081408
mComposition->beginPrint( printer );
1409-
painter.begin( &printer );
1409+
bool printReady = painter.begin( &printer );
1410+
if ( !printReady )
1411+
{
1412+
QMessageBox::warning( this, tr( "Atlas processing error" ),
1413+
QString( tr( "Error creating %1." ) ).arg( outputFileName ),
1414+
QMessageBox::Ok,
1415+
QMessageBox::Ok );
1416+
mView->setPaintingEnabled( true );
1417+
return;
1418+
}
14101419
}
14111420

14121421
QProgressDialog progress( tr( "Rendering maps..." ), tr( "Abort" ), 0, atlasMap->numFeatures(), this );
@@ -1429,6 +1438,7 @@ void QgsComposer::exportCompositionAsPDF( QgsComposer::OutputMode mode )
14291438
QMessageBox::Ok,
14301439
QMessageBox::Ok );
14311440
mView->setPaintingEnabled( true );
1441+
QApplication::restoreOverrideCursor();
14321442
return;
14331443
}
14341444
if ( !atlasOnASingleFile )
@@ -1441,7 +1451,17 @@ void QgsComposer::exportCompositionAsPDF( QgsComposer::OutputMode mode )
14411451
mComposition->beginPrintAsPDF( multiFilePrinter, outputFileName );
14421452
// set the correct resolution
14431453
mComposition->beginPrint( multiFilePrinter );
1444-
painter.begin( &multiFilePrinter );
1454+
bool printReady = painter.begin( &multiFilePrinter );
1455+
if ( !printReady )
1456+
{
1457+
QMessageBox::warning( this, tr( "Atlas processing error" ),
1458+
QString( tr( "Error creating %1." ) ).arg( outputFileName ),
1459+
QMessageBox::Ok,
1460+
QMessageBox::Ok );
1461+
mView->setPaintingEnabled( true );
1462+
QApplication::restoreOverrideCursor();
1463+
return;
1464+
}
14451465
mComposition->doPrint( multiFilePrinter, painter );
14461466
painter.end();
14471467
}
@@ -1462,7 +1482,17 @@ void QgsComposer::exportCompositionAsPDF( QgsComposer::OutputMode mode )
14621482
}
14631483
else
14641484
{
1465-
mComposition->exportAsPDF( outputFileName );
1485+
bool exportOk = mComposition->exportAsPDF( outputFileName );
1486+
if ( !exportOk )
1487+
{
1488+
QMessageBox::warning( this, tr( "Atlas processing error" ),
1489+
QString( tr( "Error creating %1." ) ).arg( outputFileName ),
1490+
QMessageBox::Ok,
1491+
QMessageBox::Ok );
1492+
mView->setPaintingEnabled( true );
1493+
QApplication::restoreOverrideCursor();
1494+
return;
1495+
}
14661496
}
14671497

14681498
if ( ! mComposition->useAdvancedEffects() )
@@ -1547,6 +1577,7 @@ void QgsComposer::printComposition( QgsComposer::OutputMode mode )
15471577
QMessageBox::Ok,
15481578
QMessageBox::Ok );
15491579
mView->setPaintingEnabled( true );
1580+
QApplication::restoreOverrideCursor();
15501581
return;
15511582
}
15521583
QProgressDialog progress( tr( "Rendering maps..." ), tr( "Abort" ), 0, atlasMap->numFeatures(), this );
@@ -1569,6 +1600,7 @@ void QgsComposer::printComposition( QgsComposer::OutputMode mode )
15691600
QMessageBox::Ok,
15701601
QMessageBox::Ok );
15711602
mView->setPaintingEnabled( true );
1603+
QApplication::restoreOverrideCursor();
15721604
return;
15731605
}
15741606

@@ -1681,15 +1713,25 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
16811713
mView->setPaintingEnabled( true );
16821714
return;
16831715
}
1716+
bool saveOk;
16841717
if ( i == 0 )
16851718
{
1686-
image.save( fileNExt.first, fileNExt.second.toLocal8Bit().constData() );
1719+
saveOk = image.save( fileNExt.first, fileNExt.second.toLocal8Bit().constData() );
16871720
}
16881721
else
16891722
{
16901723
QFileInfo fi( fileNExt.first );
16911724
QString outputFilePath = fi.absolutePath() + "/" + fi.baseName() + "_" + QString::number( i + 1 ) + "." + fi.suffix();
1692-
image.save( outputFilePath, fileNExt.second.toLocal8Bit().constData() );
1725+
saveOk = image.save( outputFilePath, fileNExt.second.toLocal8Bit().constData() );
1726+
}
1727+
if ( !saveOk )
1728+
{
1729+
QMessageBox::warning( this, tr( "Image export error" ),
1730+
QString( tr( "Error creating %1." ) ).arg( fileNExt.first ),
1731+
QMessageBox::Ok,
1732+
QMessageBox::Ok );
1733+
mView->setPaintingEnabled( true );
1734+
return;
16931735
}
16941736
}
16951737

@@ -1800,6 +1842,7 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
18001842
QMessageBox::Ok,
18011843
QMessageBox::Ok );
18021844
mView->setPaintingEnabled( true );
1845+
QApplication::restoreOverrideCursor();
18031846
return;
18041847
}
18051848

@@ -1823,6 +1866,7 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
18231866
QMessageBox::Ok,
18241867
QMessageBox::Ok );
18251868
mView->setPaintingEnabled( true );
1869+
QApplication::restoreOverrideCursor();
18261870
return;
18271871
}
18281872

@@ -1831,16 +1875,25 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
18311875
for ( int i = 0; i < mComposition->numPages(); ++i )
18321876
{
18331877
QImage image = mComposition->printPageAsRaster( i );
1878+
QString imageFilename = filename;
18341879

1835-
if ( i == 0 )
1880+
if ( i != 0 )
18361881
{
1837-
image.save( filename, format.toLocal8Bit().constData() );
1882+
//append page number
1883+
QFileInfo fi( filename );
1884+
imageFilename = fi.absolutePath() + "/" + fi.baseName() + "_" + QString::number( i + 1 ) + "." + fi.suffix();
18381885
}
1839-
else
1886+
1887+
bool saveOk = image.save( imageFilename, format.toLocal8Bit().constData() );
1888+
if ( !saveOk )
18401889
{
1841-
QFileInfo fi( filename );
1842-
QString outputFilePath = fi.absolutePath() + "/" + fi.baseName() + "_" + QString::number( i + 1 ) + "." + fi.suffix();
1843-
image.save( outputFilePath, format.toLocal8Bit().constData() );
1890+
QMessageBox::warning( this, tr( "Atlas processing error" ),
1891+
QString( tr( "Error creating %1." ) ).arg( imageFilename ),
1892+
QMessageBox::Ok,
1893+
QMessageBox::Ok );
1894+
mView->setPaintingEnabled( true );
1895+
QApplication::restoreOverrideCursor();
1896+
return;
18441897
}
18451898
}
18461899

@@ -2098,14 +2151,16 @@ void QgsComposer::exportCompositionAsSVG( QgsComposer::OutputMode mode )
20982151
{
20992152
QSvgGenerator generator;
21002153
generator.setTitle( QgsProject::instance()->title() );
2154+
QString currentFileName = outputFileName;
21012155
if ( i == 0 )
21022156
{
21032157
generator.setFileName( outputFileName );
21042158
}
21052159
else
21062160
{
21072161
QFileInfo fi( outputFileName );
2108-
generator.setFileName( fi.absolutePath() + "/" + fi.baseName() + "_" + QString::number( i + 1 ) + "." + fi.suffix() );
2162+
currentFileName = fi.absolutePath() + "/" + fi.baseName() + "_" + QString::number( i + 1 ) + "." + fi.suffix();
2163+
generator.setFileName( currentFileName );
21092164
}
21102165

21112166
//width in pixel
@@ -2116,7 +2171,17 @@ void QgsComposer::exportCompositionAsSVG( QgsComposer::OutputMode mode )
21162171
generator.setViewBox( QRect( 0, 0, width, height ) );
21172172
generator.setResolution( mComposition->printResolution() ); //because the rendering is done in mm, convert the dpi
21182173

2119-
QPainter p( &generator );
2174+
QPainter p;
2175+
bool createOk = p.begin( &generator );
2176+
if ( !createOk )
2177+
{
2178+
QMessageBox::warning( this, tr( "SVG export error" ),
2179+
QString( tr( "Error creating %1." ) ).arg( currentFileName ),
2180+
QMessageBox::Ok,
2181+
QMessageBox::Ok );
2182+
mView->setPaintingEnabled( true );
2183+
return;
2184+
}
21202185

21212186
mComposition->renderPage( &p, i );
21222187
p.end();
@@ -2224,8 +2289,19 @@ void QgsComposer::exportCompositionAsSVG( QgsComposer::OutputMode mode )
22242289
}
22252290
}
22262291
QFileInfo fi( outputFileName );
2227-
QFile out( i == 0 ? outputFileName : fi.absolutePath() + "/" + fi.baseName() + "_" + QString::number( i + 1 ) + "." + fi.suffix() );
2228-
out.open( QIODevice::WriteOnly | QIODevice::Text );
2292+
QString currentFileName = i == 0 ? outputFileName : fi.absolutePath() + "/" + fi.baseName() + "_" + QString::number( i + 1 ) + "." + fi.suffix();
2293+
QFile out( currentFileName );
2294+
bool openOk = out.open( QIODevice::WriteOnly | QIODevice::Text );
2295+
if ( !openOk )
2296+
{
2297+
QMessageBox::warning( this, tr( "SVG export error" ),
2298+
QString( tr( "Error creating %1." ) ).arg( currentFileName ),
2299+
QMessageBox::Ok,
2300+
QMessageBox::Ok );
2301+
mView->setPaintingEnabled( true );
2302+
return;
2303+
}
2304+
22292305
out.write( svg.toByteArray() );
22302306
}
22312307
}

src/core/composer/qgscomposition.cpp

+12-4
Original file line numberDiff line numberDiff line change
@@ -2445,11 +2445,11 @@ void QgsComposition::beginPrintAsPDF( QPrinter& printer, const QString& file )
24452445
QgsPaintEngineHack::fixEngineFlags( printer.paintEngine() );
24462446
}
24472447

2448-
void QgsComposition::exportAsPDF( const QString& file )
2448+
bool QgsComposition::exportAsPDF( const QString& file )
24492449
{
24502450
QPrinter printer;
24512451
beginPrintAsPDF( printer, file );
2452-
print( printer );
2452+
return print( printer );
24532453
}
24542454

24552455
void QgsComposition::doPrint( QPrinter& printer, QPainter& p )
@@ -2499,11 +2499,19 @@ void QgsComposition::beginPrint( QPrinter &printer )
24992499
printer.setResolution( printResolution() );
25002500
}
25012501

2502-
void QgsComposition::print( QPrinter &printer )
2502+
bool QgsComposition::print( QPrinter &printer )
25032503
{
25042504
beginPrint( printer );
2505-
QPainter p( &printer );
2505+
QPainter p;
2506+
bool ready = p.begin( &printer );
2507+
if ( !ready )
2508+
{
2509+
//error beginning print
2510+
return false;
2511+
}
25062512
doPrint( printer, p );
2513+
p.end();
2514+
return true;
25072515
}
25082516

25092517
QImage QgsComposition::printPageAsRaster( int page )

src/core/composer/qgscomposition.h

+8-4
Original file line numberDiff line numberDiff line change
@@ -424,11 +424,15 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
424424
/** Print on a preconfigured printer */
425425
void doPrint( QPrinter& printer, QPainter& painter );
426426

427-
/** Convenience function that prepares the printer and prints */
428-
void print( QPrinter &printer );
427+
/**Convenience function that prepares the printer and prints
428+
* @returns true if print was successful
429+
*/
430+
bool print( QPrinter &printer );
429431

430-
/** Convenience function that prepares the printer for printing in PDF and prints */
431-
void exportAsPDF( const QString& file );
432+
/**Convenience function that prepares the printer for printing in PDF and prints
433+
* @returns true if export was successful
434+
*/
435+
bool exportAsPDF( const QString& file );
432436

433437
//! print composer page to image
434438
//! If the image does not fit into memory, a null image is returned

0 commit comments

Comments
 (0)