QGIS API Documentation  3.21.0-Master (5b68dc587e)
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