Make QgsLayoutExporter::generateFileName virtual, so exporter

subclasses can be made which customise the generated file names
This commit is contained in:
Nyall Dawson 2017-12-11 18:50:28 +10:00
parent 48b6e02c8f
commit 8b1e057d2c
4 changed files with 102 additions and 11 deletions

View File

@ -21,11 +21,42 @@ class QgsLayoutExporter
%End
public:
struct PageExportDetails
{
QString directory;
%Docstring
Target folder
%End
QString baseName;
%Docstring
Base part of filename (i.e. file name without extension or '.')
%End
QString extension;
%Docstring
File suffix/extension (without the leading '.')
%End
int page;
%Docstring
Page number, where 0 = first page.
%End
};
QgsLayoutExporter( QgsLayout *layout );
%Docstring
Constructor for QgsLayoutExporter, for the specified ``layout``.
%End
virtual ~QgsLayoutExporter();
QgsLayout *layout() const;
%Docstring
Returns the layout linked to this exporter.
:rtype: QgsLayout
%End
void renderPage( QPainter *painter, int page ) const;
%Docstring
Renders a full page to a destination ``painter``.
@ -207,6 +238,15 @@ Resolution to export layout at
The ``dpi`` argument can be set to the actual DPI of exported file, or left as -1 to use the layout's default DPI.
%End
protected:
virtual QString generateFileName( const PageExportDetails &details ) const;
%Docstring
Generates the file name for a page during export.
Subclasses can override this method to customise page file naming.
:rtype: str
%End
};

View File

@ -31,6 +31,11 @@ QgsLayoutExporter::QgsLayoutExporter( QgsLayout *layout )
}
QgsLayout *QgsLayoutExporter::layout() const
{
return mLayout;
}
void QgsLayoutExporter::renderPage( QPainter *painter, int page ) const
{
if ( !mLayout )
@ -169,9 +174,11 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::exportToImage( const QString
}
QFileInfo fi( filePath );
QString path = fi.path();
QString baseName = fi.baseName();
QString extension = fi.completeSuffix();
PageExportDetails pageDetails;
pageDetails.directory = fi.path();
pageDetails.baseName = fi.baseName();
pageDetails.extension = fi.completeSuffix();
LayoutContextSettingsRestorer dpiRestorer( mLayout );
( void )dpiRestorer;
@ -207,7 +214,8 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::exportToImage( const QString
if ( skip )
continue; // should skip this page, e.g. null size
QString outputFilePath = generateFileName( path, baseName, extension, page );
pageDetails.page = page;
QString outputFilePath = generateFileName( pageDetails );
if ( image.isNull() )
{
@ -215,7 +223,7 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::exportToImage( const QString
return MemoryError;
}
if ( !saveImage( image, outputFilePath, extension ) )
if ( !saveImage( image, outputFilePath, pageDetails.extension ) )
{
mErrorFileName = outputFilePath;
return FileError;
@ -509,15 +517,15 @@ QImage QgsLayoutExporter::createImage( const QgsLayoutExporter::ImageExportSetti
}
}
QString QgsLayoutExporter::generateFileName( const QString &path, const QString &baseName, const QString &suffix, int page ) const
QString QgsLayoutExporter::generateFileName( const PageExportDetails &details ) const
{
if ( page == 0 )
if ( details.page == 0 )
{
return path + '/' + baseName + '.' + suffix;
return details.directory + '/' + details.baseName + '.' + details.extension;
}
else
{
return path + '/' + baseName + '_' + QString::number( page + 1 ) + '.' + suffix;
return details.directory + '/' + details.baseName + '_' + QString::number( details.page + 1 ) + '.' + details.extension;
}
}

View File

@ -38,11 +38,34 @@ class CORE_EXPORT QgsLayoutExporter
public:
//! Contains details of a page being exported by the class
struct PageExportDetails
{
//! Target folder
QString directory;
//! Base part of filename (i.e. file name without extension or '.')
QString baseName;
//! File suffix/extension (without the leading '.')
QString extension;
//! Page number, where 0 = first page.
int page = 0;
};
/**
* Constructor for QgsLayoutExporter, for the specified \a layout.
*/
QgsLayoutExporter( QgsLayout *layout );
virtual ~QgsLayoutExporter() = default;
/**
* Returns the layout linked to this exporter.
*/
QgsLayout *layout() const;
/**
* Renders a full page to a destination \a painter.
*
@ -219,6 +242,14 @@ class CORE_EXPORT QgsLayoutExporter
*/
void computeWorldFileParameters( const QRectF &region, double &a, double &b, double &c, double &d, double &e, double &f, double dpi = -1 ) const;
protected:
/**
* Generates the file name for a page during export.
*
* Subclasses can override this method to customise page file naming.
*/
virtual QString generateFileName( const PageExportDetails &details ) const;
private:
@ -228,8 +259,6 @@ class CORE_EXPORT QgsLayoutExporter
QImage createImage( const ImageExportSettings &settings, int page, QRectF &bounds, bool &skipPage ) const;
QString generateFileName( const QString &path, const QString &baseName, const QString &suffix, int page ) const;
/**
* Saves an image to a file, possibly using format specific options (e.g. LZW compression for tiff)
*/

View File

@ -317,6 +317,20 @@ class TestQgsLayoutExporter(unittest.TestCase):
self.assertAlmostEqual(values[4], 1925.000000000000, 2)
self.assertAlmostEqual(values[5], 3050.000000000000, 2)
def testPageFileName(self):
l = QgsLayout(QgsProject.instance())
exporter = QgsLayoutExporter(l)
details = QgsLayoutExporter.PageExportDetails()
details.directory = '/tmp/output'
details.baseName = 'my_maps'
details.extension = 'png'
details.page = 0
self.assertEqual(exporter.generateFileName(details), '/tmp/output/my_maps.png')
details.page = 1
self.assertEqual(exporter.generateFileName(details), '/tmp/output/my_maps_2.png')
details.page = 2
self.assertEqual(exporter.generateFileName(details), '/tmp/output/my_maps_3.png')
if __name__ == '__main__':
unittest.main()