QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgssymbollayerreference.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgssymbollayerreference.cpp
3 ---------------------
4 begin : July 2019
5 copyright : (C) 2019 by Hugo Mercier / Oslandia
6 email : infos at oslandia dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17#include "qgis.h"
18#include <QRegularExpression>
19
21{
22 QStringList slst;
23 slst.reserve( lst.size() );
24 for ( const QgsSymbolLayerReference &ref : lst )
25 {
26 QStringList indexPathStr;
27 const QVector<int> indexPath = ref.symbolLayerId().symbolLayerIndexPath();
28 indexPathStr.reserve( indexPath.size() );
29 for ( const int index : indexPath )
30 {
31 indexPathStr.append( QString::number( index ) );
32 }
33 // this is BAD BAD BAD -- it assumes that the component parts eg the symbolKey has no commas!
34 // a more unique string should have been used as a concatenator here, but it's too late to fix that without breaking projects...
35 slst.append( QStringLiteral( "%1,%2,%3" ).arg( ref.layerId(), ref.symbolLayerId().symbolKey(), indexPathStr.join( ',' ) ) );
36 }
37 return slst.join( ';' );
38}
39
41{
43 if ( str.isEmpty() )
44 return lst;
45
46 // when saving we used ; as a concatenator... but that was silly, cos maybe the symbol keys contain this string!
47 // try to handle this gracefully via regex...
48 const thread_local QRegularExpression partsRx( QStringLiteral( "((?:.*?),(?:.*?),(?:(?:\\d+,)+)?(?:\\d+);)" ) );
49 QRegularExpressionMatchIterator partsIt = partsRx.globalMatch( str + ';' );
50
51 while ( partsIt.hasNext() )
52 {
53 const QRegularExpressionMatch partMatch = partsIt.next();
54 const QString tuple = partMatch.captured( 1 );
55
56 // We should have "layer_id,symbol_key,symbol_layer_index0,symbol_layer_index1,..."
57 // EXCEPT that the symbol_key CAN have commas, so this whole logic is extremely broken.
58 // Let's see if a messy regex can save the day!
59 const thread_local QRegularExpression rx( QStringLiteral( "(.*?),(.*?),((?:\\d+,)+)?(\\d+)" ) );
60
61 const QRegularExpressionMatch match = rx.match( tuple );
62 if ( !match.hasMatch() )
63 continue;
64
65 const QString layerId = match.captured( 1 );
66 const QString symbolKey = match.captured( 2 );
67 const QStringList indices = QString( match.captured( 3 ) + match.captured( 4 ) ).split( ',' );
68
69 QVector<int> indexPath;
70 indexPath.reserve( indices.size() );
71 for ( const QString &index : indices )
72 {
73 indexPath.append( index.toInt() );
74 }
75 lst.append( QgsSymbolLayerReference( layerId, QgsSymbolLayerId( symbolKey, indexPath ) ) );
76 }
77 return lst;
78}
We may need stable references to symbol layers, when pointers to symbol layers is not usable (when a ...
Type used to refer to a specific symbol layer in a symbol of a layer.
#define str(x)
Definition: qgis.cpp:37
QString symbolLayerReferenceListToString(const QgsSymbolLayerReferenceList &lst)
Utilitary function to turn a QgsSymbolLayerReferenceList into a string.
QgsSymbolLayerReferenceList stringToSymbolLayerReferenceList(const QString &str)
Utilitary function to parse a string originated from symbolLayerReferenceListToString into a QgsSymbo...
QList< QgsSymbolLayerReference > QgsSymbolLayerReferenceList