1919 ***************************************************************************/
2020"""
2121
22+ import shutil
2223import sys
2324import tempfile
2425from enum import Enum
5354from .project import ProjectConfiguration , ProjectProperties
5455from .utils .file_utils import (
5556 copy_attachments ,
56- copy_multifile ,
5757 set_relative_embed_layer_symbols_on_project ,
5858)
5959from .utils .logger import logger
@@ -200,6 +200,10 @@ def _convert(self, project: QgsProject) -> None:
200200 xml_elements_to_preserve
201201 )
202202
203+ # Additional project files, such as image decoration, to be copied to the converted project
204+ project_path = Path (project .fileName ()).parent
205+ additional_project_files = []
206+
203207 # Create a new temporary `QgsProject` instance just to make sure that `theMapCanvas`
204208 # XML object is properly set within the XML document. Using a new `QgsProject`
205209 # instead of the singleton `QgsProject.instance()` allows using the read flags.
@@ -208,6 +212,25 @@ def _convert(self, project: QgsProject) -> None:
208212 tmp_project .read (tmp_project_filename , read_flags )
209213 tmp_project .readProject .disconnect (on_original_project_read )
210214
215+ # Insure the image decoration asset is copied if present and relative to the project path
216+ image_decoration_path , _ = tmp_project .readEntry ("Image" , "/ImagePath" , "" )
217+ if image_decoration_path :
218+ image_decoration_path = Path (image_decoration_path )
219+ if not image_decoration_path .is_absolute ():
220+ image_decoration_path = project_path .joinpath (
221+ image_decoration_path
222+ ).resolve ()
223+
224+ if image_decoration_path .is_file () and image_decoration_path .is_relative_to (
225+ project_path
226+ ):
227+ additional_project_files .append (str (image_decoration_path ))
228+
229+ # copy project plugin if present
230+ plugin_file = Path ("{}.qml" .format (str (self .original_filename )[:- 4 ]))
231+ if plugin_file .exists ():
232+ additional_project_files .append (str (plugin_file ))
233+
211234 # NOTE force delete the `QgsProject`, otherwise the `QgsApplication` might be deleted by the time the project is garbage collected
212235 del tmp_project
213236
@@ -315,6 +338,16 @@ def _convert(self, project: QgsProject) -> None:
315338
316339 self ._check_canceled ()
317340
341+ # copy additional project files (e.g. layout images, symbology images, etc)
342+ for additional_project_file in additional_project_files :
343+ additional_project_file_path = Path (additional_project_file )
344+ relative_path = additional_project_file_path .relative_to (project_path )
345+ destination_file = self ._export_filename .parent .joinpath (
346+ relative_path
347+ ).resolve ()
348+ destination_file .parent .mkdir (parents = True , exist_ok = True )
349+ shutil .copy (additional_project_file , str (destination_file ))
350+
318351 # save the offline project twice so that the offline plugin can "know" that it's a relative path
319352 QgsProject .instance ().write (str (export_project_filename ))
320353
@@ -337,15 +370,6 @@ def _convert(self, project: QgsProject) -> None:
337370 Path (source_dir ),
338371 )
339372
340- # copy project plugin if present
341- plugin_file = Path ("{}.qml" .format (str (self .original_filename )[:- 4 ]))
342- if plugin_file .exists ():
343- self ._check_canceled ()
344-
345- copy_multifile (
346- plugin_file , export_project_filename .parent .joinpath (plugin_file .name )
347- )
348-
349373 if offline_layers :
350374 bbox = None
351375 if self .project_configuration .offline_copy_only_aoi :
0 commit comments