@@ -228,6 +228,37 @@ def is_valid_filepath(path: str) -> bool:
228228 return True
229229
230230
231+ def update_symbols_path_assets (symbol , new_path : Path ) -> None :
232+ """
233+ Updates the path of a symbol layer.
234+ Args:
235+ symbol: The QGIS symbol (from a renderer).
236+ new_path: The base path to which asset paths should be made relative to.
237+ """
238+ if symbol is None :
239+ return
240+
241+ destination_dir = new_path / "assets"
242+ destination_dir .mkdir (parents = True , exist_ok = True )
243+
244+ for symbol_layer in symbol .symbolLayers ():
245+ if isinstance (
246+ symbol_layer , (QgsSvgMarkerSymbolLayer , QgsRasterMarkerSymbolLayer )
247+ ):
248+ source_path = Path (symbol_layer .path ())
249+
250+ if not source_path .is_relative_to (new_path ):
251+ if source_path .exists ():
252+ destination_path_file = destination_dir / source_path .name
253+
254+ if not destination_path_file .exists ():
255+ shutil .copy2 (source_path , destination_path_file )
256+
257+ symbol_layer .setPath (
258+ str (destination_path_file .relative_to (new_path ))
259+ )
260+
261+
231262def update_symbols_to_project_assets (
232263 layer : QgsVectorLayer , new_path : Optional [Path ] = None
233264) -> None :
@@ -258,50 +289,17 @@ def update_symbols_to_project_assets(
258289 project_home = project .homePath ()
259290 new_path = Path (project_home )
260291
261- destination_dir = new_path / "assets"
262- destination_dir .mkdir (parents = True , exist_ok = True )
263-
264- def update_symbols_path_assets (symbol ):
265- """Updates the path of a symbol layer."""
266- if symbol is None :
267- return
268-
269- for symbol_layer in symbol .symbolLayers ():
270- if isinstance (
271- symbol_layer , (QgsSvgMarkerSymbolLayer , QgsRasterMarkerSymbolLayer )
272- ):
273- source_path = Path (symbol_layer .path ())
274-
275- try :
276- source_path .relative_to (new_path )
277- continue
278- except ValueError :
279- # Proceed with copying
280- pass
281-
282- if source_path .exists ():
283- destination_path_file = destination_dir / source_path .name
284-
285- if not destination_path_file .exists ():
286- shutil .copy2 (source_path , destination_path_file )
287-
288- symbol_layer .setPath (
289- str (destination_path_file .relative_to (new_path ))
290- )
291-
292- elif hasattr (symbol_layer , "subSymbol" ):
293- # Recursively for nested symbology
294- update_symbols_path_assets (symbol_layer .subSymbol ())
295-
296292 if isinstance (renderer , QgsSingleSymbolRenderer ):
297293 symbol = renderer .symbol ()
298294 if symbol :
299- update_symbols_path_assets (symbol )
295+ update_symbols_path_assets (symbol , new_path )
300296
301297 elif isinstance (renderer , QgsRuleBasedRenderer ):
302298 for rule in renderer .rootRule ().children ():
303- if rule .symbol ():
304- update_symbols_path_assets (rule .symbol ())
299+ symbols = rule .symbols ()
300+ if symbols :
301+ for symbol in symbols :
302+ update_symbols_path_assets (symbol , new_path )
305303
306304 elif isinstance (renderer , QgsCategorizedSymbolRenderer ):
307305 categories = renderer .categories ()
@@ -311,7 +309,7 @@ def update_symbols_path_assets(symbol):
311309 # if not the new symbol path is not updated.
312310 category = renderer .categories ()[index ]
313311 symbol = category .symbol ().clone ()
314- update_symbols_path_assets (symbol )
312+ update_symbols_path_assets (symbol , new_path )
315313 renderer .updateCategorySymbol (index , symbol )
316314
317315 layer .setRenderer (renderer )
0 commit comments