@@ -849,7 +849,7 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::exportToSvg( const QString &f
849
849
}
850
850
}
851
851
852
- ExportResult result = renderToLayeredSvg ( settings, width, height, i, bounds, fileName, svgLayerId, layerName, svg, svgDocRoot );
852
+ ExportResult result = renderToLayeredSvg ( settings, width, height, i, bounds, fileName, svgLayerId, layerName, svg, svgDocRoot, settings. exportMetadata );
853
853
if ( result != Success )
854
854
return result;
855
855
@@ -861,6 +861,9 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::exportToSvg( const QString &f
861
861
}
862
862
}
863
863
864
+ if ( settings.exportMetadata )
865
+ appendMetadataToSvg ( svg );
866
+
864
867
QFile out ( fileName );
865
868
bool openOk = out.open ( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate );
866
869
if ( !openOk )
@@ -873,27 +876,59 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::exportToSvg( const QString &f
873
876
}
874
877
else
875
878
{
876
- QSvgGenerator generator;
877
- generator.setTitle ( mLayout ->project ()->title () );
878
- generator.setFileName ( fileName );
879
- generator.setSize ( QSize ( width, height ) );
880
- generator.setViewBox ( QRect ( 0 , 0 , width, height ) );
881
- generator.setResolution ( settings.dpi );
882
-
883
- QPainter p;
884
- bool createOk = p.begin ( &generator );
885
- if ( !createOk )
879
+ QBuffer svgBuffer;
886
880
{
887
- mErrorFileName = fileName;
888
- return FileError;
881
+ QSvgGenerator generator;
882
+ if ( settings.exportMetadata )
883
+ {
884
+ generator.setTitle ( mLayout ->project ()->metadata ().title () );
885
+ generator.setDescription ( mLayout ->project ()->metadata ().abstract () );
886
+ }
887
+ generator.setOutputDevice ( &svgBuffer );
888
+ generator.setSize ( QSize ( width, height ) );
889
+ generator.setViewBox ( QRect ( 0 , 0 , width, height ) );
890
+ generator.setResolution ( settings.dpi );
891
+
892
+ QPainter p;
893
+ bool createOk = p.begin ( &generator );
894
+ if ( !createOk )
895
+ {
896
+ mErrorFileName = fileName;
897
+ return FileError;
898
+ }
899
+
900
+ if ( settings.cropToContents )
901
+ renderRegion ( &p, bounds );
902
+ else
903
+ renderPage ( &p, i );
904
+
905
+ p.end ();
889
906
}
907
+ {
908
+ svgBuffer.close ();
909
+ svgBuffer.open ( QIODevice::ReadOnly );
910
+ QDomDocument svg;
911
+ QString errorMsg;
912
+ int errorLine;
913
+ if ( ! svg.setContent ( &svgBuffer, false , &errorMsg, &errorLine ) )
914
+ {
915
+ mErrorFileName = fileName;
916
+ return SvgLayerError;
917
+ }
890
918
891
- if ( settings.cropToContents )
892
- renderRegion ( &p, bounds );
893
- else
894
- renderPage ( &p, i );
919
+ if ( settings.exportMetadata )
920
+ appendMetadataToSvg ( svg );
921
+
922
+ QFile out ( fileName );
923
+ bool openOk = out.open ( QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate );
924
+ if ( !openOk )
925
+ {
926
+ mErrorFileName = fileName;
927
+ return FileError;
928
+ }
895
929
896
- p.end ();
930
+ out.write ( svg.toByteArray () );
931
+ }
897
932
}
898
933
}
899
934
@@ -1067,15 +1102,18 @@ void QgsLayoutExporter::updatePrinterPageSize( QgsLayout *layout, QPrinter &prin
1067
1102
printer.setPaperSize ( pageSizeMM.toQSizeF (), QPrinter::Millimeter );
1068
1103
}
1069
1104
1070
- QgsLayoutExporter::ExportResult QgsLayoutExporter::renderToLayeredSvg ( const SvgExportSettings &settings, double width, double height, int page, QRectF bounds, const QString &filename, int svgLayerId, const QString &layerName, QDomDocument &svg, QDomNode &svgDocRoot ) const
1105
+ QgsLayoutExporter::ExportResult QgsLayoutExporter::renderToLayeredSvg ( const SvgExportSettings &settings, double width, double height, int page, QRectF bounds, const QString &filename, int svgLayerId, const QString &layerName, QDomDocument &svg, QDomNode &svgDocRoot, bool includeMetadata ) const
1071
1106
{
1072
1107
QBuffer svgBuffer;
1073
1108
{
1074
1109
QSvgGenerator generator;
1075
- if ( const QgsMasterLayoutInterface *l = dynamic_cast < const QgsMasterLayoutInterface * >( mLayout .data () ) )
1076
- generator.setTitle ( l->name () );
1077
- else if ( mLayout ->project () )
1078
- generator.setTitle ( mLayout ->project ()->title () );
1110
+ if ( includeMetadata )
1111
+ {
1112
+ if ( const QgsMasterLayoutInterface *l = dynamic_cast < const QgsMasterLayoutInterface * >( mLayout .data () ) )
1113
+ generator.setTitle ( l->name () );
1114
+ else if ( mLayout ->project () )
1115
+ generator.setTitle ( mLayout ->project ()->title () );
1116
+ }
1079
1117
1080
1118
generator.setOutputDevice ( &svgBuffer );
1081
1119
generator.setSize ( QSize ( width, height ) );
@@ -1122,6 +1160,68 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::renderToLayeredSvg( const Svg
1122
1160
return Success;
1123
1161
}
1124
1162
1163
+ void QgsLayoutExporter::appendMetadataToSvg ( QDomDocument &svg ) const
1164
+ {
1165
+ const QgsProjectMetadata &metadata = mLayout ->project ()->metadata ();
1166
+ QDomElement metadataElement = svg.createElement ( QStringLiteral ( " metadata" ) );
1167
+ metadataElement.setAttribute ( QStringLiteral ( " id" ), QStringLiteral ( " qgismetadata" ) );
1168
+ QDomElement rdfElement = svg.createElement ( QStringLiteral ( " rdf:RDF" ) );
1169
+ QDomElement workElement = svg.createElement ( QStringLiteral ( " cc:Work" ) );
1170
+
1171
+ auto addTextNode = [&workElement, &svg]( const QString & tag, const QString & value )
1172
+ {
1173
+ QDomElement element = svg.createElement ( tag );
1174
+ QDomText t = svg.createTextNode ( value );
1175
+ element.appendChild ( t );
1176
+ workElement.appendChild ( element );
1177
+ };
1178
+
1179
+ addTextNode ( QStringLiteral ( " dc:format" ), QStringLiteral ( " image/svg+xml" ) );
1180
+ addTextNode ( QStringLiteral ( " dc:title" ), metadata.title () );
1181
+ addTextNode ( QStringLiteral ( " dc:date" ), metadata.creationDateTime ().toString ( Qt::ISODate ) );
1182
+ addTextNode ( QStringLiteral ( " dc:identifier" ), metadata.identifier () );
1183
+ addTextNode ( QStringLiteral ( " dc:description" ), metadata.abstract () );
1184
+
1185
+ auto addAgentNode = [&workElement, &svg]( const QString & tag, const QString & value )
1186
+ {
1187
+ QDomElement element = svg.createElement ( tag );
1188
+ QDomElement agentElement = svg.createElement ( QStringLiteral ( " cc:Agent" ) );
1189
+ QDomElement titleElement = svg.createElement ( QStringLiteral ( " dc:title" ) );
1190
+ QDomText t = svg.createTextNode ( value );
1191
+ titleElement.appendChild ( t );
1192
+ agentElement.appendChild ( titleElement );
1193
+ element.appendChild ( agentElement );
1194
+ workElement.appendChild ( element );
1195
+ };
1196
+
1197
+ addAgentNode ( QStringLiteral ( " dc:creator" ), metadata.author () );
1198
+ addAgentNode ( QStringLiteral ( " dc:publisher" ), QStringLiteral ( " QGIS %1" ).arg ( Qgis::QGIS_VERSION ) );
1199
+
1200
+ // keywords
1201
+ {
1202
+ QDomElement element = svg.createElement ( QStringLiteral ( " dc:subject" ) );
1203
+ QDomElement bagElement = svg.createElement ( QStringLiteral ( " rdf:Bag" ) );
1204
+ QgsAbstractMetadataBase::KeywordMap keywords = metadata.keywords ();
1205
+ for ( auto it = keywords.constBegin (); it != keywords.constEnd (); ++it )
1206
+ {
1207
+ const QStringList words = it.value ();
1208
+ for ( const QString &keyword : words )
1209
+ {
1210
+ QDomElement liElement = svg.createElement ( QStringLiteral ( " rdf:li" ) );
1211
+ QDomText t = svg.createTextNode ( keyword );
1212
+ liElement.appendChild ( t );
1213
+ bagElement.appendChild ( liElement );
1214
+ }
1215
+ }
1216
+ element.appendChild ( bagElement );
1217
+ workElement.appendChild ( element );
1218
+ }
1219
+
1220
+ rdfElement.appendChild ( workElement );
1221
+ metadataElement.appendChild ( rdfElement );
1222
+ svg.documentElement ().appendChild ( metadataElement );
1223
+ }
1224
+
1125
1225
std::unique_ptr<double []> QgsLayoutExporter::computeGeoTransform ( const QgsLayoutItemMap *map, const QRectF ®ion, double dpi ) const
1126
1226
{
1127
1227
if ( !map )
0 commit comments