QGIS API Documentation  3.20.0-Odense (decaadbb31)
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 ( 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 
44  // when saving we used ; as a concatenator... but that was silly, cos maybe the symbol keys contain this string!
45  // try to handle this gracefully via regex...
46  const QRegularExpression partsRx( QStringLiteral( "((?:.*?),(?:.*?),(?:(?:\\d+,)+)?(?:\\d+);)" ) );
47  QRegularExpressionMatchIterator partsIt = partsRx.globalMatch( str + ';' );
48 
49  while ( partsIt.hasNext() )
50  {
51  QRegularExpressionMatch partMatch = partsIt.next();
52  const QString tuple = partMatch.captured( 1 );
53 
54  // We should have "layer_id,symbol_key,symbol_layer_index0,symbol_layer_index1,..."
55  // EXCEPT that the symbol_key CAN have commas, so this whole logic is extremely broken.
56  // Let's see if a messy regex can save the day!
57  const QRegularExpression rx( QStringLiteral( "(.*?),(.*?),((?:\\d+,)+)?(\\d+)" ) );
58 
59  const QRegularExpressionMatch match = rx.match( tuple );
60  if ( !match.hasMatch() )
61  continue;
62 
63  const QString layerId = match.captured( 1 );
64  const QString symbolKey = match.captured( 2 );
65  const QStringList indices = QString( match.captured( 3 ) + match.captured( 4 ) ).split( ',' );
66 
67  QVector<int> indexPath;
68  indexPath.reserve( indices.size() );
69  for ( const QString &index : indices )
70  {
71  indexPath.append( index.toInt() );
72  }
73  lst.append( QgsSymbolLayerReference( layerId, QgsSymbolLayerId( symbolKey, indexPath ) ) );
74  }
75  return lst;
76 }
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