44#include <QDomDocument>
47#include <QDomNodeList>
53#include "moc_qgsstyle.cpp"
55using namespace Qt::StringLiterals;
57#define STYLE_CURRENT_VERSION "2"
82QgsStyle *QgsStyle::sDefaultStyle =
nullptr;
89 simpleMarker->setStrokeWidth( 0.4 );
90 mPatchMarkerSymbol = std::make_unique< QgsMarkerSymbol >(
QgsSymbolLayerList() << simpleMarker.release() );
92 auto simpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 84, 176, 74 ), 0.6 );
93 mPatchLineSymbol = std::make_unique< QgsLineSymbol >(
QgsSymbolLayerList() << simpleLine.release() );
95 auto gradientFill = std::make_unique< QgsGradientFillSymbolLayer >( QColor( 66, 150, 63 ), QColor( 84, 176, 74 ) );
96 auto simpleOutline = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 56, 128, 54 ), 0.26 );
97 mPatchFillSymbol = std::make_unique< QgsFillSymbol >(
QgsSymbolLayerList() << gradientFill.release() << simpleOutline.release() );
118 switch ( entity->
type() )
152 static QString sStyleFilename;
153 if ( !sDefaultStyle )
159 if ( !QFile::exists( sStyleFilename ) )
162 sDefaultStyle->createDatabase( sStyleFilename );
167 sDefaultStyle->createStyleMetadataTableIfNeeded();
174 sDefaultStyle->mInitialized =
false;
177 sDefaultStyle->initializeDefaultStyle( sStyleFilename );
180 sDefaultStyle->setName( QObject::tr(
"Default" ) );
182 else if ( initialize && !sDefaultStyle->mInitialized )
185 sDefaultStyle->initializeDefaultStyle( sStyleFilename );
187 return sDefaultStyle;
190void QgsStyle::initializeDefaultStyle(
const QString &filename )
192 Q_ASSERT(
this == sDefaultStyle );
193 if (
this != sDefaultStyle )
209 delete sDefaultStyle;
210 sDefaultStyle =
nullptr;
215 qDeleteAll( mSymbols );
216 qDeleteAll( mColorRamps );
217 qDeleteAll( m3dSymbols );
221 mTextFormats.clear();
225 mCachedFavorites.clear();
234 auto it = mSymbols.constFind(
name );
235 if ( it != mSymbols.constEnd() )
256 QDomDocument doc( u
"dummy"_s );
258 if ( symEl.isNull() )
265 QTextStream stream( &xmlArray );
266 symEl.save( stream, 4 );
268 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
270 if ( !runEmptyQuery( query ) )
272 QgsDebugError( u
"Couldn't insert symbol into the database!"_s );
334 return mSymbols.value(
name );
339 return mSymbols.count();
344 return mSymbols.keys();
354 auto it = mColorRamps.constFind(
name );
355 if ( it != mColorRamps.constEnd() )
376 auto it = mTextFormats.find(
name );
377 if ( it != mTextFormats.end() )
380 mTextFormats.erase( it );
381 mTextFormats.insert(
name, format );
387 mTextFormats.insert(
name, format );
398 auto it = mLabelSettings.find(
name );
399 if ( it != mLabelSettings.end() )
402 mLabelSettings.erase( it );
403 mLabelSettings.insert(
name, settings );
409 mLabelSettings.insert(
name, settings );
420 auto it = mLegendPatchShapes.find(
name );
421 if ( it != mLegendPatchShapes.end() )
424 mLegendPatchShapes.erase( it );
425 mLegendPatchShapes.insert(
name, shape );
431 mLegendPatchShapes.insert(
name, shape );
442 auto it = m3dSymbols.constFind(
name );
443 if ( it != m3dSymbols.constEnd() )
464 QDomDocument doc( u
"dummy"_s );
467 if ( rampEl.isNull() )
469 QgsDebugError( u
"Couldn't convert color ramp to valid XML!"_s );
474 QTextStream stream( &xmlArray );
475 rampEl.save( stream, 4 );
476 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO colorramp VALUES (NULL, '%q', '%q', %d);",
477 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
478 if ( !runEmptyQuery( query ) )
480 QgsDebugError( u
"Couldn't insert colorramp into the database!"_s );
502 return ramp ? ramp->
clone() :
nullptr;
512 return mColorRamps.count();
517 return mColorRamps.keys();
520void QgsStyle::handleDeferred3DSymbolCreation()
522 for (
auto it = mDeferred3DsymbolElements.constBegin(); it != mDeferred3DsymbolElements.constEnd(); ++it )
524 const QString symbolType = it.value().attribute( u
"type"_s );
538 mDeferred3DsymbolElements.clear();
541bool QgsStyle::openDatabase(
const QString &filename )
543 int rc = mCurrentDB.open( filename );
546 mErrorString = u
"Couldn't open the style database: %1"_s.arg( mCurrentDB.errorMessage() );
555 mErrorString.clear();
556 if ( !openDatabase( filename ) )
558 mErrorString = u
"Unable to create database"_s;
570 mErrorString.clear();
571 if ( !openDatabase( u
":memory:"_s ) )
573 mErrorString = u
"Unable to create temporary memory database"_s;
586 "id INTEGER PRIMARY KEY,"\
589 "favorite INTEGER);"\
590 "CREATE TABLE colorramp("\
591 "id INTEGER PRIMARY KEY,"\
594 "favorite INTEGER);"\
595 "CREATE TABLE textformat("\
596 "id INTEGER PRIMARY KEY,"\
599 "favorite INTEGER);"\
600 "CREATE TABLE labelsettings("\
601 "id INTEGER PRIMARY KEY,"\
604 "favorite INTEGER);"\
605 "CREATE TABLE legendpatchshapes("\
606 "id INTEGER PRIMARY KEY,"\
609 "favorite INTEGER);"\
610 "CREATE TABLE symbol3d("\
611 "id INTEGER PRIMARY KEY,"\
614 "favorite INTEGER);"\
616 "id INTEGER PRIMARY KEY,"\
618 "CREATE TABLE tagmap("\
619 "tag_id INTEGER NOT NULL,"\
620 "symbol_id INTEGER);"\
621 "CREATE TABLE ctagmap("\
622 "tag_id INTEGER NOT NULL,"\
623 "colorramp_id INTEGER);"\
624 "CREATE TABLE tftagmap("\
625 "tag_id INTEGER NOT NULL,"\
626 "textformat_id INTEGER);"\
627 "CREATE TABLE lstagmap("\
628 "tag_id INTEGER NOT NULL,"\
629 "labelsettings_id INTEGER);"\
630 "CREATE TABLE lpstagmap("\
631 "tag_id INTEGER NOT NULL,"\
632 "legendpatchshape_id INTEGER);"\
633 "CREATE TABLE symbol3dtagmap("\
634 "tag_id INTEGER NOT NULL,"\
635 "symbol3d_id INTEGER);"\
636 "CREATE TABLE smartgroup("\
637 "id INTEGER PRIMARY KEY,"\
640 runEmptyQuery( query );
645 mErrorString.clear();
648 if ( !openDatabase( filename ) )
650 mErrorString = u
"Unable to open database file specified"_s;
656 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='textformat'" );
659 statement = mCurrentDB.prepare( query, rc );
660 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
663 "id INTEGER PRIMARY KEY,"\
666 "favorite INTEGER);"\
667 "CREATE TABLE tftagmap("\
668 "tag_id INTEGER NOT NULL,"\
669 "textformat_id INTEGER);" );
670 runEmptyQuery( query );
673 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='labelsettings'" );
674 statement = mCurrentDB.prepare( query, rc );
675 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
678 "id INTEGER PRIMARY KEY,"\
681 "favorite INTEGER);"\
682 "CREATE TABLE lstagmap("\
683 "tag_id INTEGER NOT NULL,"\
684 "labelsettings_id INTEGER);" );
685 runEmptyQuery( query );
688 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='legendpatchshapes'" );
689 statement = mCurrentDB.prepare( query, rc );
690 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
693 "id INTEGER PRIMARY KEY,"\
696 "favorite INTEGER);"\
697 "CREATE TABLE lpstagmap("\
698 "tag_id INTEGER NOT NULL,"\
699 "legendpatchshape_id INTEGER);" );
700 runEmptyQuery( query );
704 statement = mCurrentDB.prepare( query, rc );
705 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
708 "id INTEGER PRIMARY KEY,"\
711 "favorite INTEGER);"\
712 "CREATE TABLE symbol3dtagmap("\
713 "tag_id INTEGER NOT NULL,"\
714 "symbol3d_id INTEGER);" );
715 runEmptyQuery( query );
720 "UPDATE colorramp SET favorite=0 WHERE favorite IS NULL;"
721 "UPDATE textformat SET favorite=0 WHERE favorite IS NULL;"
722 "UPDATE labelsettings SET favorite=0 WHERE favorite IS NULL;"
723 "UPDATE legendpatchshapes SET favorite=0 WHERE favorite IS NULL;"
724 "UPDATE symbol3d SET favorite=0 WHERE favorite IS NULL;"
726 runEmptyQuery( query );
732 statement = mCurrentDB.prepare( query, rc );
734 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
740 if ( !doc.setContent( xmlstring ) )
746 QDomElement symElement = doc.documentElement();
749 mSymbols.insert( symbolName,
symbol.release() );
756 statement = mCurrentDB.prepare( query, rc );
757 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
763 if ( !doc.setContent( xmlstring ) )
768 QDomElement rampElement = doc.documentElement();
771 mColorRamps.insert( rampName, ramp.release() );
778 statement = mCurrentDB.prepare( query, rc );
779 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
785 if ( !doc.setContent( xmlstring ) )
790 QDomElement formatElement = doc.documentElement();
793 mTextFormats.insert( formatName, format );
800 statement = mCurrentDB.prepare( query, rc );
801 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
807 if ( !doc.setContent( xmlstring ) )
809 QgsDebugError(
"Cannot open label settings " + settingsName );
812 QDomElement settingsElement = doc.documentElement();
815 mLabelSettings.insert( settingsName, settings );
822 statement = mCurrentDB.prepare( query, rc );
823 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
829 if ( !doc.setContent( xmlstring ) )
831 QgsDebugError(
"Cannot open legend patch shape " + settingsName );
834 QDomElement settingsElement = doc.documentElement();
837 mLegendPatchShapes.insert( settingsName, shape );
844 statement = mCurrentDB.prepare( query, rc );
848 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
854 if ( !doc.setContent( xmlstring ) )
859 QDomElement settingsElement = doc.documentElement();
861 if ( !registry3dPopulated )
863 mDeferred3DsymbolElements.insert( settingsName, settingsElement );
867 const QString symbolType = settingsElement.attribute( u
"type"_s );
872 m3dSymbols.insert( settingsName,
symbol.release() );
883 mFileName = filename;
884 createStyleMetadataTableIfNeeded();
890 mErrorString.clear();
892 if ( !filename.isEmpty() )
893 mFileName = filename;
900 mFileName = filename;
905 if ( mSymbols.contains( newName ) )
915 mSymbols.insert( newName,
symbol );
926 QgsDebugError( u
"No such symbol for tagging in database: "_s + oldName );
945 if ( mColorRamps.contains( newName ) )
947 QgsDebugError( u
"Color ramp of new name already exists."_s );
955 mColorRamps.insert( newName, ramp );
961 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM colorramp WHERE name='%q'", oldName.toUtf8().constData() );
963 statement = mCurrentDB.prepare( query, nErr );
964 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
966 rampid = sqlite3_column_int( statement.get(), 0 );
981 QDomDocument doc( u
"dummy"_s );
984 if ( formatElem.isNull() )
986 QgsDebugError( u
"Couldn't convert text format to valid XML!"_s );
991 QTextStream stream( &xmlArray );
992 formatElem.save( stream, 4 );
993 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO textformat VALUES (NULL, '%q', '%q', %d);",
994 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
995 if ( !runEmptyQuery( query ) )
997 QgsDebugError( u
"Couldn't insert text format into the database!"_s );
1018 if ( mTextFormats.contains( newName ) )
1020 QgsDebugError( u
"Text format of new name already exists."_s );
1024 if ( !mTextFormats.contains( oldName ) )
1028 mTextFormats.insert( newName, format );
1034 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM textformat WHERE name='%q'", oldName.toUtf8().constData() );
1036 statement = mCurrentDB.prepare( query, nErr );
1037 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1039 textFormatId = sqlite3_column_int( statement.get(), 0 );
1054 QDomDocument doc( u
"dummy"_s );
1057 if ( settingsElem.isNull() )
1059 QgsDebugError( u
"Couldn't convert label settings to valid XML!"_s );
1063 QByteArray xmlArray;
1064 QTextStream stream( &xmlArray );
1065 settingsElem.save( stream, 4 );
1066 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO labelsettings VALUES (NULL, '%q', '%q', %d);",
1067 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1068 if ( !runEmptyQuery( query ) )
1070 QgsDebugError( u
"Couldn't insert label settings into the database!"_s );
1091 if ( mLabelSettings.contains( newName ) )
1093 QgsDebugError( u
"Label settings of new name already exists."_s );
1097 if ( !mLabelSettings.contains( oldName ) )
1101 mLabelSettings.insert( newName, settings );
1107 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM labelsettings WHERE name='%q'", oldName.toUtf8().constData() );
1109 statement = mCurrentDB.prepare( query, nErr );
1110 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1127 QDomDocument doc( u
"dummy"_s );
1128 QDomElement shapeElem = doc.createElement( u
"shape"_s );
1131 QByteArray xmlArray;
1132 QTextStream stream( &xmlArray );
1133 shapeElem.save( stream, 4 );
1134 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO legendpatchshapes VALUES (NULL, '%q', '%q', %d);",
1135 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1136 if ( !runEmptyQuery( query ) )
1138 QgsDebugError( u
"Couldn't insert legend patch shape into the database!"_s );
1153 if ( mLegendPatchShapes.contains( newName ) )
1155 QgsDebugError( u
"Legend patch shape of new name already exists."_s );
1159 if ( !mLegendPatchShapes.contains( oldName ) )
1163 mLegendPatchShapes.insert( newName, shape );
1169 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM legendpatchshapes WHERE name='%q'", oldName.toUtf8().constData() );
1171 statement = mCurrentDB.prepare( query, nErr );
1172 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1190 auto it = mDefaultPatchCache[
static_cast< int >( type ) ].constFind( size );
1191 if ( it != mDefaultPatchCache[
static_cast< int >( type ) ].constEnd() )
1198 geom =
QgsGeometry( std::make_unique< QgsPoint >(
static_cast< int >( size.width() ) / 2,
static_cast< int >( size.height() ) / 2 ) );
1205 double y =
static_cast< int >( size.height() ) / 2 + 0.5;
1206 geom =
QgsGeometry( std::make_unique< QgsLineString >( ( QVector< double >() << 0 << size.width() ),
1207 ( QVector< double >() << y << y ) ) );
1213 geom =
QgsGeometry( std::make_unique< QgsPolygon >(
1214 new QgsLineString( QVector< double >() << 0 <<
static_cast< int >( size.width() ) <<
static_cast< int >( size.width() ) << 0 << 0,
1215 QVector< double >() <<
static_cast< int >( size.height() ) <<
static_cast< int >( size.height() ) << 0 << 0 <<
static_cast< int >( size.height() ) ) ) );
1224 mDefaultPatchCache[
static_cast< int >( type ) ][size ] = res;
1231 return QList<QList<QPolygonF> >();
1233 auto it = mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ].constFind( size );
1234 if ( it != mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ].constEnd() )
1238 mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ][size ] = res;
1264 QDomDocument doc( u
"dummy"_s );
1265 QDomElement elem = doc.createElement( u
"symbol"_s );
1266 elem.setAttribute( u
"type"_s,
symbol->type() );
1269 QByteArray xmlArray;
1270 QTextStream stream( &xmlArray );
1271 elem.save( stream, 4 );
1272 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO symbol3d VALUES (NULL, '%q', '%q', %d);",
1273 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1274 if ( !runEmptyQuery( query ) )
1276 QgsDebugError( u
"Couldn't insert 3d symbol into the database!"_s );
1291 if ( m3dSymbols.contains( newName ) )
1293 QgsDebugError( u
"3d symbol of new name already exists."_s );
1297 if ( !m3dSymbols.contains( oldName ) )
1301 m3dSymbols.insert( newName,
symbol );
1307 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM symbol3d WHERE name='%q'", oldName.toUtf8().constData() );
1309 statement = mCurrentDB.prepare( query, nErr );
1310 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1325 return m3dSymbols.keys();
1332 QgsDebugError( u
"Cannot Open database for getting favorite symbols"_s );
1333 return QStringList();
1342 return QStringList();
1345 query =
qgs_sqlite3_mprintf( u
"SELECT name FROM %1 WHERE favorite=1"_s.arg( entityTableName( type ) ).toLocal8Bit().data() );
1351 statement = mCurrentDB.prepare( query, nErr );
1353 QStringList symbols;
1354 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1366 QgsDebugError( u
"Cannot open database to get symbols of tagid %1"_s.arg( tagid ) );
1367 return QStringList();
1376 return QStringList();
1379 subquery =
qgs_sqlite3_mprintf( u
"SELECT %1 FROM %2 WHERE tag_id=%d"_s.arg( tagmapEntityIdFieldName( type ),
1380 tagmapTableName( type ) ).toLocal8Bit().data(), tagid );
1386 statement = mCurrentDB.prepare( subquery, nErr );
1389 QStringList symbols;
1390 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1392 int id = sqlite3_column_int( statement.get(), 0 );
1394 const QString query =
qgs_sqlite3_mprintf( u
"SELECT name FROM %1 WHERE id=%d"_s.arg( entityTableName( type ) ).toLocal8Bit().data(),
id );
1398 statement2 = mCurrentDB.prepare( query, rc );
1399 while ( rc == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1414 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO tag VALUES (NULL, '%q')", tagname.toUtf8().constData() );
1416 statement = mCurrentDB.prepare( query, nErr );
1417 if ( nErr == SQLITE_OK )
1418 ( void )sqlite3_step( statement.get() );
1421 settings.
setValue( u
"qgis/symbolsListGroupsIndex"_s, 0 );
1425 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
1431 return QStringList();
1437 statement = mCurrentDB.prepare( query, nError );
1439 QStringList tagList;
1440 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1450 const QString query =
qgs_sqlite3_mprintf( u
"UPDATE %1 SET name='%q' WHERE id=%d"_s.arg( entityTableName( type ) ).toLocal8Bit().data(), newName.toUtf8().constData(),
id );
1452 const bool result = runEmptyQuery( query );
1455 mErrorString = u
"Could not rename!"_s;
1459 mCachedTags.clear();
1460 mCachedFavorites.clear();
1485 bool groupRemoved =
false;
1490 query =
qgs_sqlite3_mprintf(
"DELETE FROM tag WHERE id=%d; DELETE FROM tagmap WHERE tag_id=%d",
id,
id );
1491 groupRemoved =
true;
1495 groupRemoved =
true;
1499 query =
qgs_sqlite3_mprintf( u
"DELETE FROM %1 WHERE id=%d; DELETE FROM %2 WHERE %3=%d"_s.arg(
1500 entityTableName( type ),
1501 tagmapTableName( type ),
1502 tagmapEntityIdFieldName( type )
1503 ).toLocal8Bit().data(),
id,
id );
1507 bool result =
false;
1508 if ( !runEmptyQuery( query ) )
1514 mCachedTags.clear();
1515 mCachedFavorites.clear();
1520 settings.
setValue( u
"qgis/symbolsListGroupsIndex"_s, 0 );
1539 std::unique_ptr< QgsSymbol >
symbol( mSymbols.take(
name ) );
1548 std::unique_ptr< QgsAbstract3DSymbol >
symbol( m3dSymbols.take(
name ) );
1557 std::unique_ptr< QgsColorRamp > ramp( mColorRamps.take(
name ) );
1565 auto it = mTextFormats.find(
name );
1566 if ( it == mTextFormats.end() )
1569 mTextFormats.erase( it );
1575 auto it = mLabelSettings.find(
name );
1576 if ( it == mLabelSettings.end() )
1579 mLabelSettings.erase( it );
1585 auto it = mLegendPatchShapes.find(
name );
1586 if ( it == mLegendPatchShapes.end() )
1589 mLegendPatchShapes.erase( it );
1596 QgsDebugError( u
"Sorry! Cannot open database to modify."_s );
1606 const bool result =
remove( type,
id );
1609 mCachedTags[ type ].remove(
name );
1610 mCachedFavorites[ type ].remove(
name );
1639bool QgsStyle::runEmptyQuery(
const QString &query )
1644 char *zErr =
nullptr;
1645 int nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1647 if ( nErr != SQLITE_OK )
1650 sqlite3_free( zErr );
1653 return nErr == SQLITE_OK;
1664 QgsDebugError( u
"Wrong entity value. cannot apply group"_s );
1668 query =
qgs_sqlite3_mprintf( u
"UPDATE %1 SET favorite=1 WHERE name='%q'"_s.arg( entityTableName( type ) ).toLocal8Bit().data(),
1669 name.toUtf8().constData() );
1673 const bool res = runEmptyQuery( query );
1683 mCachedFavorites[ type ].insert(
name,
true );
1700 QgsDebugError( u
"Wrong entity value. cannot apply group"_s );
1704 query =
qgs_sqlite3_mprintf( u
"UPDATE %1 SET favorite=0 WHERE name='%q'"_s.arg( entityTableName( type ) ).toLocal8Bit().data(),
name.toUtf8().constData() );
1708 const bool res = runEmptyQuery( query );
1711 mCachedFavorites[ type ].insert(
name,
false );
1722 QgsDebugError( u
"Sorry! Cannot open database to search"_s );
1723 return QStringList();
1732 return QStringList();
1735 item = entityTableName( type );
1740 item.toUtf8().constData(), qword.toUtf8().constData() );
1743 int nErr; statement = mCurrentDB.prepare( query, nErr );
1745 QSet< QString > symbols;
1746 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1752 query =
qgs_sqlite3_mprintf(
"SELECT id FROM tag WHERE name LIKE '%%%q%%'", qword.toUtf8().constData() );
1753 statement = mCurrentDB.prepare( query, nErr );
1756 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1761 QString dummy = tagids.join(
", "_L1 );
1762 query =
qgs_sqlite3_mprintf( u
"SELECT %1 FROM %2 WHERE tag_id IN (%q)"_s.arg( tagmapEntityIdFieldName( type ),
1763 tagmapTableName( type ) ).toLocal8Bit().data(), dummy.toUtf8().constData() );
1765 statement = mCurrentDB.prepare( query, nErr );
1767 QStringList symbolids;
1768 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1773 dummy = symbolids.join(
", "_L1 );
1775 item.toUtf8().constData(), dummy.toUtf8().constData() );
1776 statement = mCurrentDB.prepare( query, nErr );
1777 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1782 return QStringList( symbols.constBegin(), symbols.constEnd() );
1812 const auto constTags =
tags;
1813 for (
const QString &t : constTags )
1816 if ( !
tag.isEmpty() )
1828 QString query =
qgs_sqlite3_mprintf( u
"INSERT INTO %1 VALUES (%d,%d)"_s.arg( tagmapTableName( type ) ).toLocal8Bit().data(), tagid, symbolid );
1830 char *zErr =
nullptr;
1832 nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1836 sqlite3_free( zErr );
1842 clearCachedTags( type,
symbol );
1852 QgsDebugError( u
"Sorry! Cannot open database for detagging."_s );
1867 if ( symbolid == 0 )
1872 const auto constTags =
tags;
1873 for (
const QString &
tag : constTags )
1878 statement2 = mCurrentDB.prepare( query, nErr );
1881 if ( nErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1883 tagid = sqlite3_column_int( statement2.get(), 0 );
1889 const QString query =
qgs_sqlite3_mprintf( u
"DELETE FROM %1 WHERE tag_id=%d AND %2=%d"_s.arg( tagmapTableName( type ), tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), tagid, symbolid );
1890 runEmptyQuery( query );
1894 clearCachedTags( type,
symbol );
1907 QgsDebugError( u
"Sorry! Cannot open database for detagging."_s );
1922 if ( symbolid == 0 )
1928 const QString query =
qgs_sqlite3_mprintf( u
"DELETE FROM %1 WHERE %2=%d"_s.arg( tagmapTableName( type ),
1929 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1930 runEmptyQuery( query );
1932 clearCachedTags( type,
symbol );
1947 return QStringList();
1951 auto it = mCachedTags[ type ].constFind(
symbol );
1952 if ( it != mCachedTags[ type ].constEnd() )
1960 QgsDebugError( u
"Sorry! Cannot open database for getting the tags."_s );
1961 return QStringList();
1966 return QStringList();
1969 const QString query =
qgs_sqlite3_mprintf( u
"SELECT tag_id FROM %1 WHERE %2=%d"_s.arg( tagmapTableName( type ),
1970 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1973 int nErr; statement = mCurrentDB.prepare( query, nErr );
1975 QStringList tagList;
1976 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1978 QString subquery =
qgs_sqlite3_mprintf(
"SELECT name FROM tag WHERE id=%d", sqlite3_column_int( statement.get(), 0 ) );
1982 statement2 = mCurrentDB.prepare( subquery, pErr );
1983 if ( pErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1990 mCachedTags[ type ].insert(
symbol, tagList );
1999 QgsDebugError( u
"Sorry! Cannot open database for getting the tags."_s );
2011 auto it = mCachedFavorites[ type ].constFind(
name );
2012 if ( it != mCachedFavorites[ type ].constEnd() )
2018 const QStringList names =
allNames( type );
2019 if ( !names.contains(
name ) )
2025 for (
const QString &n : names )
2027 const bool isFav = favorites.contains( n );
2031 mCachedFavorites[ type ].insert( n, isFav );
2040 QgsDebugError( u
"Sorry! Cannot open database for getting the tags."_s );
2067 const QString query =
qgs_sqlite3_mprintf( u
"SELECT tag_id FROM %1 WHERE tag_id=%d AND %2=%d"_s.arg( tagmapTableName( type ),
2068 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), tagid, symbolid );
2071 int nErr; statement = mCurrentDB.prepare( query, nErr );
2073 return ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW );
2085 statement = mCurrentDB.prepare( query, nError );
2088 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2096int QgsStyle::getId(
const QString &table,
const QString &name )
2098 QString lowerName(
name.toLower() );
2099 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE LOWER(name)='%q'", table.toUtf8().constData(), lowerName.toUtf8().constData() );
2102 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2105 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2107 id = sqlite3_column_int( statement.get(), 0 );
2112 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE name='%q'", table.toUtf8().constData(),
name.toUtf8().constData() );
2114 sqlite3_statement_unique_ptr statement;
2115 int nErr; statement = mCurrentDB.prepare( query, nErr );
2116 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2118 id = sqlite3_column_int( statement.get(), 0 );
2125QString QgsStyle::getName(
const QString &table,
int id )
const
2127 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM %q WHERE id='%q'", table.toUtf8().constData(), QString::number(
id ).toUtf8().constData() );
2129 sqlite3_statement_unique_ptr statement;
2130 int nErr; statement = mCurrentDB.prepare( query, nErr );
2133 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2143 return getId( u
"symbol"_s,
name );
2148 return getId( entityTableName( type ),
name );
2153 return getId( u
"colorramp"_s,
name );
2158 return mTextFormats.value(
name );
2163 return mTextFormats.count();
2168 return mTextFormats.keys();
2173 return getId( u
"textformat"_s,
name );
2178 return mLabelSettings.value(
name );
2183 return mLegendPatchShapes.value(
name );
2188 return mLegendPatchShapes.count();
2193 auto it = mLegendPatchShapes.constFind(
name );
2194 if ( it == mLegendPatchShapes.constEnd() )
2197 return it.value().symbolType();
2202 auto it = m3dSymbols.constFind(
name );
2203 if ( it != m3dSymbols.constEnd( ) )
2204 return it.value()->
clone();
2210 return m3dSymbols.count();
2215 auto it = m3dSymbols.constFind(
name );
2216 if ( it == m3dSymbols.constEnd() )
2217 return QList<Qgis::GeometryType>();
2219 return it.value()->compatibleGeometryTypes();
2224 auto it = mLabelSettings.constFind(
name );
2225 if ( it == mLabelSettings.constEnd() )
2228 return it.value().layerType;
2233 return mLabelSettings.count();
2238 return mLabelSettings.keys();
2243 return getId( u
"labelsettings"_s,
name );
2248 return mLegendPatchShapes.keys();
2256 return mPatchMarkerSymbol.get();
2259 return mPatchLineSymbol.get();
2262 return mPatchFillSymbol.get();
2272 return getId( u
"tag"_s,
name );
2277 return getId( u
"smartgroup"_s,
name );
2308 return QStringList();
2314 conditions.values( u
"!tag"_s ),
2315 conditions.values( u
"name"_s ),
2316 conditions.values( u
"!name"_s ) );
2319int QgsStyle::addSmartgroup(
const QString &
name,
const QString &op,
const QStringList &matchTag,
const QStringList &noMatchTag,
const QStringList &matchName,
const QStringList &noMatchName )
2321 QDomDocument doc( u
"dummy"_s );
2322 QDomElement smartEl = doc.createElement( u
"smartgroup"_s );
2323 smartEl.setAttribute( u
"name"_s,
name );
2324 smartEl.setAttribute( u
"operator"_s, op );
2326 auto addCondition = [&doc, &smartEl](
const QString & constraint,
const QStringList & parameters )
2328 for (
const QString ¶m : parameters )
2330 QDomElement condEl = doc.createElement( u
"condition"_s );
2331 condEl.setAttribute( u
"constraint"_s, constraint );
2332 condEl.setAttribute( u
"param"_s, param );
2333 smartEl.appendChild( condEl );
2336 addCondition( u
"tag"_s, matchTag );
2337 addCondition( u
"!tag"_s, noMatchTag );
2338 addCondition( u
"name"_s, matchName );
2339 addCondition( u
"!name"_s, noMatchName );
2341 QByteArray xmlArray;
2342 QTextStream stream( &xmlArray );
2343 smartEl.save( stream, 4 );
2345 name.toUtf8().constData(), xmlArray.constData() );
2347 if ( runEmptyQuery( query ) )
2350 settings.
setValue( u
"qgis/symbolsListGroupsIndex"_s, 0 );
2353 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
2357 QgsDebugError( u
"Couldn't add the smart group into the database!"_s );
2366 QgsDebugError( u
"Cannot open database for listing groups"_s );
2375 statement = mCurrentDB.prepare( query, nError );
2378 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2391 QgsDebugError( u
"Cannot open database for listing groups"_s );
2392 return QStringList();
2400 statement = mCurrentDB.prepare( query, nError );
2403 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2413 QStringList symbols;
2418 int nErr; statement = mCurrentDB.prepare( query, nErr );
2419 if ( !( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW ) )
2421 return QStringList();
2427 if ( !doc.setContent( xmlstr ) )
2429 QgsDebugError( u
"Cannot open smartgroup id: %1"_s.arg(
id ) );
2431 QDomElement smartEl = doc.documentElement();
2432 QString op = smartEl.attribute( u
"operator"_s );
2433 QDomNodeList conditionNodes = smartEl.childNodes();
2435 bool firstSet =
true;
2436 for (
int i = 0; i < conditionNodes.count(); i++ )
2438 QDomElement condEl = conditionNodes.at( i ).toElement();
2439 QString constraint = condEl.attribute( u
"constraint"_s );
2440 QString param = condEl.attribute( u
"param"_s );
2442 QStringList resultNames;
2444 if ( constraint ==
"tag"_L1 )
2448 else if ( constraint ==
"name"_L1 )
2450 resultNames =
allNames( type ).filter( param, Qt::CaseInsensitive );
2452 else if ( constraint ==
"!tag"_L1 )
2456 for (
const QString &
name : unwanted )
2458 resultNames.removeAll(
name );
2461 else if ( constraint ==
"!name"_L1 )
2463 const QStringList all =
allNames( type );
2464 for (
const QString &str : all )
2466 if ( !str.contains( param, Qt::CaseInsensitive ) )
2474 symbols = resultNames;
2479 if ( op ==
"OR"_L1 )
2481 symbols << resultNames;
2483 else if ( op ==
"AND"_L1 )
2485 QStringList dummy = symbols;
2487 for (
const QString &result : std::as_const( resultNames ) )
2489 if ( dummy.contains( result ) )
2498 const QSet< QString > uniqueSet( symbols.constBegin(), symbols.constEnd() );
2499 QStringList unique( uniqueSet.begin(), uniqueSet.end() );
2500 std::sort( unique.begin(), unique.end() );
2508 QgsDebugError( u
"Cannot open database for listing groups"_s );
2518 statement = mCurrentDB.prepare( query, nError );
2519 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2523 if ( !doc.setContent( xmlstr ) )
2525 QgsDebugError( u
"Cannot open smartgroup id: %1"_s.arg(
id ) );
2528 QDomElement smartEl = doc.documentElement();
2529 QDomNodeList conditionNodes = smartEl.childNodes();
2531 for (
int i = 0; i < conditionNodes.count(); i++ )
2533 QDomElement condEl = conditionNodes.at( i ).toElement();
2534 QString constraint = condEl.attribute( u
"constraint"_s );
2535 QString param = condEl.attribute( u
"param"_s );
2537 condition.insert( constraint, param );
2548 QgsDebugError( u
"Cannot open database for listing groups"_s );
2558 statement = mCurrentDB.prepare( query, nError );
2559 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2563 if ( !doc.setContent( xmlstr ) )
2565 QgsDebugError( u
"Cannot open smartgroup id: %1"_s.arg(
id ) );
2567 QDomElement smartEl = doc.documentElement();
2568 op = smartEl.attribute( u
"operator"_s );
2576 if ( filename.isEmpty() )
2582 QDomDocument doc( u
"qgis_style"_s );
2583 QDomElement root = doc.createElement( u
"qgis_style"_s );
2585 doc.appendChild( root );
2595 QDomNodeList symbolsList = symbolsElem.elementsByTagName( u
"symbol"_s );
2596 int nbSymbols = symbolsList.count();
2597 for (
int i = 0; i < nbSymbols; ++i )
2599 QDomElement
symbol = symbolsList.at( i ).toElement();
2600 QString
name =
symbol.attribute( u
"name"_s );
2602 if (
tags.count() > 0 )
2604 symbol.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2606 if ( favoriteSymbols.contains(
name ) )
2608 symbol.setAttribute( u
"favorite"_s, u
"1"_s );
2613 QDomElement rampsElem = doc.createElement( u
"colorramps"_s );
2614 for ( QMap<QString, QgsColorRamp *>::const_iterator itr = mColorRamps.constBegin(); itr != mColorRamps.constEnd(); ++itr )
2618 if (
tags.count() > 0 )
2620 rampEl.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2622 if ( favoriteColorramps.contains( itr.key() ) )
2624 rampEl.setAttribute( u
"favorite"_s, u
"1"_s );
2626 rampsElem.appendChild( rampEl );
2630 QDomElement textFormatsElem = doc.createElement( u
"textformats"_s );
2631 for (
auto it = mTextFormats.constBegin(); it != mTextFormats.constEnd(); ++it )
2633 QDomElement textFormatEl = doc.createElement( u
"textformat"_s );
2634 textFormatEl.setAttribute( u
"name"_s, it.key() );
2636 textFormatEl.appendChild( textStyleEl );
2638 if (
tags.count() > 0 )
2640 textFormatEl.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2642 if ( favoriteTextFormats.contains( it.key() ) )
2644 textFormatEl.setAttribute( u
"favorite"_s, u
"1"_s );
2646 textFormatsElem.appendChild( textFormatEl );
2650 QDomElement labelSettingsElem = doc.createElement( u
"labelsettings"_s );
2651 for (
auto it = mLabelSettings.constBegin(); it != mLabelSettings.constEnd(); ++it )
2653 QDomElement labelSettingsEl = doc.createElement( u
"labelsetting"_s );
2654 labelSettingsEl.setAttribute( u
"name"_s, it.key() );
2656 labelSettingsEl.appendChild( defEl );
2658 if (
tags.count() > 0 )
2660 labelSettingsEl.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2662 if ( favoriteTextFormats.contains( it.key() ) )
2664 labelSettingsEl.setAttribute( u
"favorite"_s, u
"1"_s );
2666 labelSettingsElem.appendChild( labelSettingsEl );
2670 QDomElement legendPatchShapesElem = doc.createElement( u
"legendpatchshapes"_s );
2671 for (
auto it = mLegendPatchShapes.constBegin(); it != mLegendPatchShapes.constEnd(); ++it )
2673 QDomElement legendPatchShapeEl = doc.createElement( u
"legendpatchshape"_s );
2674 legendPatchShapeEl.setAttribute( u
"name"_s, it.key() );
2675 QDomElement defEl = doc.createElement( u
"definition"_s );
2677 legendPatchShapeEl.appendChild( defEl );
2679 if (
tags.count() > 0 )
2681 legendPatchShapeEl.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2683 if ( favoriteLegendShapes.contains( it.key() ) )
2685 legendPatchShapeEl.setAttribute( u
"favorite"_s, u
"1"_s );
2687 legendPatchShapesElem.appendChild( legendPatchShapeEl );
2691 QDomElement symbols3DElem = doc.createElement( u
"symbols3d"_s );
2692 for (
auto it = m3dSymbols.constBegin(); it != m3dSymbols.constEnd(); ++it )
2694 QDomElement symbolEl = doc.createElement( u
"symbol3d"_s );
2695 symbolEl.setAttribute( u
"name"_s, it.key() );
2696 QDomElement defEl = doc.createElement( u
"definition"_s );
2697 defEl.setAttribute( u
"type"_s, it.value()->type() );
2699 symbolEl.appendChild( defEl );
2701 if (
tags.count() > 0 )
2703 symbolEl.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2705 if ( favorite3DSymbols.contains( it.key() ) )
2707 symbolEl.setAttribute( u
"favorite"_s, u
"1"_s );
2709 symbols3DElem.appendChild( symbolEl );
2712 root.appendChild( symbolsElem );
2713 root.appendChild( rampsElem );
2714 root.appendChild( textFormatsElem );
2715 root.appendChild( labelSettingsElem );
2716 root.appendChild( legendPatchShapesElem );
2717 root.appendChild( symbols3DElem );
2720 QFile f( filename );
2721 if ( !f.open( QFile::WriteOnly | QIODevice::Truncate ) )
2723 mErrorString =
"Couldn't open file for writing: " + filename;
2727 QTextStream ts( &f );
2741 mErrorString = QString();
2742 QDomDocument doc( u
"style"_s );
2743 QFile f( filename );
2744 if ( !f.open( QFile::ReadOnly ) )
2746 mErrorString = u
"Unable to open the specified file"_s;
2751 if ( !doc.setContent( &f ) )
2753 mErrorString = u
"Unable to understand the style file: %1"_s.arg( filename );
2760 QDomElement docEl = doc.documentElement();
2761 if ( docEl.tagName() !=
"qgis_style"_L1 )
2763 mErrorString =
"Incorrect root tag in style: " + docEl.tagName();
2767 const QString version = docEl.attribute( u
"version"_s );
2770 mErrorString =
"Unknown style file version: " + version;
2776 QDomElement symbolsElement = docEl.firstChildElement( u
"symbols"_s );
2777 QDomElement e = symbolsElement.firstChildElement();
2781 runEmptyQuery( query );
2786 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2788 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
2789 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2795 if ( e.tagName() ==
"symbol"_L1 )
2797 QString
name = e.attribute( u
"name"_s );
2799 if ( e.hasAttribute( u
"tags"_s ) )
2801 tags = e.attribute( u
"tags"_s ).split(
',' );
2803 bool favorite =
false;
2804 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
2812 QgsSymbol *symbolPtr =
symbol.get();
2832 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
2839 QDomElement rampsElement = docEl.firstChildElement( u
"colorramps"_s );
2840 e = rampsElement.firstChildElement();
2841 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2843 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
2844 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2850 if ( e.tagName() ==
"colorramp"_L1 )
2852 QString
name = e.attribute( u
"name"_s );
2854 if ( e.hasAttribute( u
"tags"_s ) )
2856 tags = e.attribute( u
"tags"_s ).split(
',' );
2858 bool favorite =
false;
2859 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
2867 QgsColorRamp *rampPtr = ramp.get();
2884 if ( qobject_cast< QGuiApplication * >( QCoreApplication::instance() ) )
2888 const QDomElement textFormatElement = docEl.firstChildElement( u
"textformats"_s );
2889 e = textFormatElement.firstChildElement();
2890 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2892 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
2893 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2899 if ( e.tagName() ==
"textformat"_L1 )
2901 QString
name = e.attribute( u
"name"_s );
2903 if ( e.hasAttribute( u
"tags"_s ) )
2905 tags = e.attribute( u
"tags"_s ).split(
',' );
2907 bool favorite =
false;
2908 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
2913 QgsTextFormat format;
2914 const QDomElement styleElem = e.firstChildElement();
2915 format.
readXml( styleElem, QgsReadWriteContext() );
2932 const QDomElement labelSettingsElement = docEl.firstChildElement( u
"labelsettings"_s );
2933 e = labelSettingsElement.firstChildElement();
2934 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2936 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
2937 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2943 if ( e.tagName() ==
"labelsetting"_L1 )
2945 QString
name = e.attribute( u
"name"_s );
2947 if ( e.hasAttribute( u
"tags"_s ) )
2949 tags = e.attribute( u
"tags"_s ).split(
',' );
2951 bool favorite =
false;
2952 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
2957 QgsPalLayerSettings settings;
2958 const QDomElement styleElem = e.firstChildElement();
2959 settings.
readXml( styleElem, QgsReadWriteContext() );
2977 const QDomElement legendPatchShapesElement = docEl.firstChildElement( u
"legendpatchshapes"_s );
2978 e = legendPatchShapesElement.firstChildElement();
2979 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2981 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
2982 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2988 if ( e.tagName() ==
"legendpatchshape"_L1 )
2990 QString
name = e.attribute( u
"name"_s );
2992 if ( e.hasAttribute( u
"tags"_s ) )
2994 tags = e.attribute( u
"tags"_s ).split(
',' );
2996 bool favorite =
false;
2997 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
3002 QgsLegendPatchShape shape;
3003 const QDomElement shapeElem = e.firstChildElement();
3004 shape.
readXml( shapeElem, QgsReadWriteContext() );
3021 const QDomElement symbols3DElement = docEl.firstChildElement( u
"symbols3d"_s );
3022 e = symbols3DElement.firstChildElement();
3023 for ( ; !e.isNull(); e = e.nextSiblingElement() )
3025 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
3026 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
3032 if ( e.tagName() ==
"symbol3d"_L1 )
3034 QString
name = e.attribute( u
"name"_s );
3036 if ( e.hasAttribute( u
"tags"_s ) )
3038 tags = e.attribute( u
"tags"_s ).split(
',' );
3040 bool favorite =
false;
3041 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
3046 const QDomElement symbolElem = e.firstChildElement();
3047 const QString type = symbolElem.attribute( u
"type"_s );
3051 sym->readXml( symbolElem, QgsReadWriteContext() );
3052 QgsAbstract3DSymbol *newSym = sym.get();
3068 runEmptyQuery( query );
3075 QFileInfo fileInfo( path );
3077 if ( fileInfo.suffix().compare(
"xml"_L1, Qt::CaseInsensitive ) != 0 )
3081 if ( !QFile::exists( path ) )
3084 QFile inputFile( path );
3085 if ( !inputFile.open( QIODevice::ReadOnly ) )
3088 QTextStream stream( &inputFile );
3089 const QString line = stream.readLine();
3090 return line ==
"<!DOCTYPE qgis_style>"_L1;
3105 mReadOnly = readOnly;
3108bool QgsStyle::updateSymbol( StyleEntity type,
const QString &name )
3110 QDomDocument doc( u
"dummy"_s );
3112 QByteArray xmlArray;
3113 QTextStream stream( &xmlArray );
3122 auto it = mSymbols.constFind(
name );
3123 if ( it == mSymbols.constEnd() || !it.value() )
3125 QgsDebugError( u
"Update request received for unavailable symbol"_s );
3130 if ( symEl.isNull() )
3132 QgsDebugError( u
"Couldn't convert symbol to valid XML!"_s );
3135 symEl.save( stream, 4 );
3137 xmlArray.constData(),
name.toUtf8().constData() );
3144 auto it = m3dSymbols.constFind(
name );
3145 if ( it == m3dSymbols.constEnd() || !it.value() )
3147 QgsDebugError( u
"Update request received for unavailable symbol"_s );
3151 symEl = doc.createElement( u
"symbol"_s );
3152 symEl.setAttribute( u
"type"_s, it.value()->type() );
3153 it.value()->writeXml( symEl, QgsReadWriteContext() );
3154 if ( symEl.isNull() )
3156 QgsDebugError( u
"Couldn't convert symbol to valid XML!"_s );
3159 symEl.save( stream, 4 );
3161 xmlArray.constData(),
name.toUtf8().constData() );
3167 auto it = mColorRamps.constFind(
name );
3168 if ( it == mColorRamps.constEnd() || !it.value() )
3170 QgsDebugError( u
"Update requested for unavailable color ramp."_s );
3175 if ( symEl.isNull() )
3177 QgsDebugError( u
"Couldn't convert color ramp to valid XML!"_s );
3180 symEl.save( stream, 4 );
3182 xmlArray.constData(),
name.toUtf8().constData() );
3188 auto it = mTextFormats.constFind(
name );
3189 if ( it == mTextFormats.constEnd() )
3191 QgsDebugError( u
"Update requested for unavailable text format."_s );
3195 symEl = it.value().writeXml( doc, QgsReadWriteContext() );
3196 if ( symEl.isNull() )
3198 QgsDebugError( u
"Couldn't convert text format to valid XML!"_s );
3201 symEl.save( stream, 4 );
3203 xmlArray.constData(),
name.toUtf8().constData() );
3209 auto it = mLabelSettings.constFind(
name );
3210 if ( it == mLabelSettings.constEnd() )
3212 QgsDebugError( u
"Update requested for unavailable label settings."_s );
3216 symEl = it.value().writeXml( doc, QgsReadWriteContext() );
3217 if ( symEl.isNull() )
3219 QgsDebugError( u
"Couldn't convert label settings to valid XML!"_s );
3222 symEl.save( stream, 4 );
3224 xmlArray.constData(),
name.toUtf8().constData() );
3230 auto it = mLegendPatchShapes.constFind(
name );
3231 if ( it == mLegendPatchShapes.constEnd() )
3233 QgsDebugError( u
"Update requested for unavailable legend patch shape."_s );
3237 symEl = doc.createElement( u
"shape"_s );
3238 it.value().writeXml( symEl, doc, QgsReadWriteContext() );
3239 symEl.save( stream, 4 );
3241 xmlArray.constData(),
name.toUtf8().constData() );
3254 if ( !runEmptyQuery( query ) )
3256 QgsDebugError( u
"Couldn't update symbol into the database!"_s );
3292 mCachedTags[ type ].remove(
name );
3295bool QgsStyle::createStyleMetadataTableIfNeeded()
3298 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='stylemetadata'" );
3299 sqlite3_statement_unique_ptr statement;
3301 statement = mCurrentDB.prepare( query, rc );
3303 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
3307 "id INTEGER PRIMARY KEY,"\
3310 runEmptyQuery( query );
3312 runEmptyQuery( query );
3321void QgsStyle::upgradeIfRequired()
3325 if ( !createStyleMetadataTableIfNeeded() )
3327 const QString query =
qgs_sqlite3_mprintf(
"SELECT value FROM stylemetadata WHERE key='version'" );
3329 sqlite3_statement_unique_ptr statement = mCurrentDB.prepare( query, rc );
3330 if ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
3342 runEmptyQuery( query );
3355 return u
"colorramp"_s;
3358 return u
"textformat"_s;
3361 return u
"labelsettings"_s;
3364 return u
"legendpatchshapes"_s;
3367 return u
"symbol3d"_s;
3373 return u
"smartgroup"_s;
3386 return u
"ctagmap"_s;
3389 return u
"tftagmap"_s;
3392 return u
"lstagmap"_s;
3395 return u
"lpstagmap"_s;
3398 return u
"symbol3dtagmap"_s;
3412 return u
"symbol_id"_s;
3415 return u
"colorramp_id"_s;
3418 return u
"textformat_id"_s;
3421 return u
"labelsettings_id"_s;
3424 return u
"legendpatchshape_id"_s;
3427 return u
"symbol3d_id"_s;
@ ScaleArea
Calculate scale by the area.
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
static int versionInt()
Version number used for comparing versions using the "Check QGIS Version" function.
QStringList symbolTypes() const
Returns a list of all available symbol types.
Abstract base class for 3D symbols that are used by VectorLayer3DRenderer objects.
virtual QgsAbstract3DSymbol * clone() const =0
Returns a new instance of the symbol with the same settings.
static QString userStylePath()
Returns the path to user's style.
static QString defaultStylePath()
Returns the path to default style (works as a starting point).
static Qgs3DSymbolRegistry * symbol3DRegistry()
Returns registry of available 3D symbols.
Abstract base class for color ramps.
virtual double value(int index) const =0
Returns relative value between [0,1] of color at specified index.
virtual QgsColorRamp * clone() const =0
Creates a clone of the color ramp.
A geometry is the spatial representation of a feature.
Represents a patch shape for use in map legends.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Read settings from a DOM element.
QList< QList< QPolygonF > > toQPolygonF(Qgis::SymbolType type, QSizeF size) const
Converts the patch shape to a set of QPolygonF objects representing how the patch should be drawn for...
void writeXml(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
Qgis::SymbolType symbolType() const
Returns the symbol type associated with this patch.
Line string geometry type, with support for z-dimension and m-values.
Contains settings for how a map layer will be labeled.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
QgsTextFormat defaultTextFormat() const
Returns the project default text format.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
const QgsProjectStyleSettings * styleSettings() const
Returns the project's style settings, which contains settings and properties relating to how a QgsPro...
A container for the context for various read/write operations on objects.
Scoped object for logging of the runtime for a single operation or group of operations.
Stores settings for use within QGIS.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
A color ramp entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
An interface for entities which can be placed in a QgsStyle database.
virtual QgsStyle::StyleEntity type() const =0
Returns the type of style entity.
A label settings entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A legend patch shape entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A 3d symbol entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A symbol entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A text format entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A database of saved style entities, including symbols, color ramps, text formats and others.
bool addEntity(const QString &name, const QgsStyleEntityInterface *entity, bool update=false)
Adds an entity to the style, with the specified name.
void setFileName(const QString &filename)
Sets the current file name of the style database.
void labelSettingsChanged(const QString &name)
Emitted whenever a label setting's definition is changed.
int colorRampCount()
Returns count of color ramps.
bool detagSymbol(StyleEntity type, const QString &symbol, const QStringList &tags)
Detags the symbol with the given list.
QgsTextFormat textFormat(const QString &name) const
Returns the text format with the specified name.
QStringList allNames(StyleEntity type) const
Returns a list of the names of all existing entities of the specified type.
QgsLegendPatchShape defaultPatch(Qgis::SymbolType type, QSizeF size) const
Returns the default legend patch shape for the given symbol type.
bool remove(StyleEntity type, int id)
Removes the specified entity from the database.
bool removeSymbol(const QString &name)
Removes symbol from style (and delete it).
void entityChanged(QgsStyle::StyleEntity entity, const QString &name)
Emitted whenever an entity's definition is changed.
bool removeLabelSettings(const QString &name)
Removes label settings from the style.
void labelSettingsAdded(const QString &name)
Emitted whenever label settings have been added to the style and the database has been updated as a r...
QStringList tags() const
Returns a list of all tags in the style database.
QString tag(int id) const
Returns the tag name for the given id.
QgsSmartConditionMap smartgroup(int id)
Returns the QgsSmartConditionMap for the given id.
bool renameColorRamp(const QString &oldName, const QString &newName)
Changes ramp's name.
void rampAdded(const QString &name)
Emitted whenever a color ramp has been added to the style and the database has been updated as a resu...
QStringList symbol3DNames() const
Returns a list of names of 3d symbols in the style.
bool tagSymbol(StyleEntity type, const QString &symbol, const QStringList &tags)
Tags the symbol with the tags in the list.
int entityId(StyleEntity type, const QString &name)
Returns the id in the style database for the given name of the specified entity type.
void rebuildIconPreviews()
Emitted whenever icon previews for entities in the style must be rebuilt.
bool saveLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool favorite, const QStringList &tags)
Adds label settings to the database.
Q_DECL_DEPRECATED bool save(const QString &filename=QString())
Saves style into a file.
bool symbolHasTag(StyleEntity type, const QString &symbol, const QString &tag)
Returns whether a given tag is associated with the symbol.
void aboutToBeDestroyed()
Emitted just before the style object is destroyed.
QgsTextFormat defaultTextFormat(QgsStyle::TextFormatContext context=QgsStyle::TextFormatContext::Labeling) const
Returns the default text format to use for new text based objects in the specified context.
@ XML
Label settings definition (as XML).
@ Name
Label settings name.
bool createDatabase(const QString &filename)
Creates an on-disk database.
QStringList textFormatNames() const
Returns a list of names of text formats in the style.
const QgsColorRamp * colorRampRef(const QString &name) const
Returns a const pointer to a symbol (doesn't create new instance).
QStringList symbolsWithTag(StyleEntity type, int tagid) const
Returns the symbol names with which have the given tag.
bool addColorRamp(const QString &name, QgsColorRamp *colorRamp, bool update=false)
Adds a color ramp to the style.
bool removeTextFormat(const QString &name)
Removes a text format from the style.
QgsSymbol * symbol(const QString &name)
Returns a NEW copy of symbol.
void labelSettingsRemoved(const QString &name)
Emitted whenever label settings have been removed from the style and the database has been updated as...
QStringList symbolsOfSmartgroup(StyleEntity type, int id)
Returns the symbols for the smartgroup.
int labelSettingsCount() const
Returns count of label settings in the style.
StyleEntity
Enum for Entities involved in a style.
@ LabelSettingsEntity
Label settings.
@ TextFormatEntity
Text formats.
@ SmartgroupEntity
Smart groups.
@ Symbol3DEntity
3D symbol entity
@ ColorrampEntity
Color ramps.
@ LegendPatchShapeEntity
Legend patch shape.
QStringList tagsOfSymbol(StyleEntity type, const QString &symbol)
Returns the tags associated with the symbol.
void symbolRenamed(const QString &oldName, const QString &newName)
Emitted whenever a symbol has been renamed from oldName to newName.
QList< Qgis::GeometryType > symbol3DCompatibleGeometryTypes(const QString &name) const
Returns the list of the vector layer geometry types which are compatible with the 3D symbol with the ...
@ XML
Color ramp definition (as XML).
void groupsModified()
Emitted every time a tag or smartgroup has been added, removed, or renamed.
void clear()
Removes all contents of the style.
int smartgroupId(const QString &smartgroup)
Returns the database id for the given smartgroup name.
void rampRemoved(const QString &name)
Emitted whenever a color ramp has been removed from the style and the database has been updated as a ...
void entityRenamed(QgsStyle::StyleEntity entity, const QString &oldName, const QString &newName)
Emitted whenever a entity of the specified type has been renamed from oldName to newName.
const QgsSymbol * symbolRef(const QString &name) const
Returns a const pointer to a symbol (doesn't create new instance).
int addSmartgroup(const QString &name, const QString &op, const QgsSmartConditionMap &conditions)
Adds a new smartgroup to the database and returns the id.
QStringList colorRampNames() const
Returns a list of names of color ramps.
void textFormatChanged(const QString &name)
Emitted whenever a text format's definition is changed.
bool addSymbol3D(const QString &name, QgsAbstract3DSymbol *symbol, bool update=false)
Adds a 3d symbol with the specified name to the style.
QStringList legendPatchShapeNames() const
Returns a list of names of legend patch shapes in the style.
bool renameLegendPatchShape(const QString &oldName, const QString &newName)
Changes a legend patch shape's name.
static void cleanDefaultStyle()
Deletes the default style. Only to be used by QgsApplication::exitQgis().
void symbolSaved(const QString &name, const QgsSymbol *symbol)
Emitted every time a new symbol has been added to the database.
void textFormatRenamed(const QString &oldName, const QString &newName)
Emitted whenever a text format has been renamed from oldName to newName.
void triggerIconRebuild()
Triggers emission of the rebuildIconPreviews() signal.
void setName(const QString &name)
Sets the name of the style.
bool removeEntityByName(StyleEntity type, const QString &name)
Removes the entry of the specified type with matching name from the database.
void labelSettingsRenamed(const QString &oldName, const QString &newName)
Emitted whenever label settings have been renamed from oldName to newName.
void initialized()
Emitted when the style database has been fully initialized.
@ XML
Text format definition (as XML).
int textFormatCount() const
Returns count of text formats in the style.
QStringList findSymbols(StyleEntity type, const QString &qword)
Returns the names of the symbols which have a matching 'substring' in its definition.
int tagId(const QString &tag)
Returns the database id for the given tag name.
void rampRenamed(const QString &oldName, const QString &newName)
Emitted whenever a color ramp has been renamed from oldName to newName.
bool exportXml(const QString &filename)
Exports the style as a XML file.
void createTables()
Creates tables structure for new database.
bool isReadOnly() const
Returns true if the style is considered a read-only library.
bool addLegendPatchShape(const QString &name, const QgsLegendPatchShape &shape, bool update=false)
Adds a legend patch shape with the specified name to the style.
int textFormatId(const QString &name)
Returns the ID in the style database for the given text format by name.
QgsColorRamp * colorRamp(const QString &name) const
Returns a new copy of the specified color ramp.
int symbolCount()
Returns count of symbols in style.
bool renameEntity(StyleEntity type, const QString &oldName, const QString &newName)
Renames an entity of the specified type from oldName to newName.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
static bool isXmlStyleFile(const QString &path)
Tests if the file at path is a QGIS style XML file.
int symbol3DCount() const
Returns count of 3D symbols in the style.
bool createMemoryDatabase()
Creates a temporary memory database.
int colorrampId(const QString &name)
Returns the id in the style database for the given colorramp name returns 0 if not found.
bool saveSymbol(const QString &name, const QgsSymbol *symbol, bool favorite, const QStringList &tags)
Adds the symbol to the database with tags.
QStringList labelSettingsNames() const
Returns a list of names of label settings in the style.
bool load(const QString &filename)
Loads a file into the style.
QStringList smartgroupNames() const
Returns the smart groups list.
bool rename(StyleEntity type, int id, const QString &newName)
Renames the given entity with the specified id.
bool renameTextFormat(const QString &oldName, const QString &newName)
Changes a text format's name.
void textFormatAdded(const QString &name)
Emitted whenever a text format has been added to the style and the database has been updated as a res...
bool removeFavorite(StyleEntity type, const QString &name)
Removes the specified symbol from favorites.
static QgsTextFormat defaultTextFormatForProject(QgsProject *project, QgsStyle::TextFormatContext context=QgsStyle::TextFormatContext::Labeling)
Returns the default text format to use for new text based objects for the specified project,...
int legendPatchShapesCount() const
Returns count of legend patch shapes in the style.
QgsSymbolGroupMap smartgroupsListMap()
Returns the smart groups map with id as key and name as value.
bool isFavorite(StyleEntity type, const QString &name)
Returns true if the symbol with matching type and name is marked as a favorite.
int symbolId(const QString &name)
Returns the id in the style database for the given symbol name returns 0 if not found.
bool saveLegendPatchShape(const QString &name, const QgsLegendPatchShape &shape, bool favorite, const QStringList &tags)
Adds a legend patch shape to the database.
QString name() const
Returns the name of the style.
QgsStyle(QObject *parent=nullptr)
Constructor for QgsStyle, with the specified parent object.
Qgis::GeometryType labelSettingsLayerType(const QString &name) const
Returns the layer geometry type corresponding to the label settings with the specified name,...
@ XML
Symbol definition (as XML).
bool renameLabelSettings(const QString &oldName, const QString &newName)
Changes a label setting's name.
bool renameSymbol3D(const QString &oldName, const QString &newName)
Changes a 3d symbol's name.
bool addTextFormat(const QString &name, const QgsTextFormat &format, bool update=false)
Adds a text format with the specified name to the style.
bool saveColorRamp(const QString &name, const QgsColorRamp *ramp, bool favorite, const QStringList &tags)
Adds the colorramp to the database.
void rampChanged(const QString &name)
Emitted whenever a color ramp's definition is changed.
QStringList symbolsOfFavorite(StyleEntity type) const
Returns the symbol names which are flagged as favorite.
void entityTagsChanged(QgsStyle::StyleEntity entity, const QString &name, const QStringList &newTags)
Emitted whenever an entity's tags are changed.
bool renameSymbol(const QString &oldName, const QString &newName)
Renames a symbol from oldName to newName.
bool removeColorRamp(const QString &name)
Removes color ramp from style (and delete it).
bool saveSymbol3D(const QString &name, QgsAbstract3DSymbol *symbol, bool favorite, const QStringList &tags)
Adds a 3d symbol to the database.
void favoritedChanged(QgsStyle::StyleEntity entity, const QString &name, bool isFavorite)
Emitted whenever an entity is either favorited or un-favorited.
QgsPalLayerSettings labelSettings(const QString &name) const
Returns the label settings with the specified name.
void entityRemoved(QgsStyle::StyleEntity entity, const QString &name)
Emitted whenever an entity of the specified type is removed from the style and the database has been ...
int labelSettingsId(const QString &name)
Returns the ID in the style database for the given label settings by name.
Qgis::SymbolType legendPatchShapeSymbolType(const QString &name) const
Returns the symbol type corresponding to the legend patch shape with the specified name,...
QgsAbstract3DSymbol * symbol3D(const QString &name) const
Returns a new copy of the 3D symbol with the specified name.
int addTag(const QString &tagName)
Adds a new tag and returns the tag's id.
const QgsSymbol * previewSymbolForPatchShape(const QgsLegendPatchShape &shape) const
Returns a symbol to use for rendering preview icons for a patch shape.
bool addSymbol(const QString &name, QgsSymbol *symbol, bool update=false)
Adds a symbol to style and takes symbol's ownership.
QgsLegendPatchShape legendPatchShape(const QString &name) const
Returns the legend patch shape with the specified name.
void entityAdded(QgsStyle::StyleEntity entity, const QString &name)
Emitted every time a new entity has been added to the database.
QStringList symbolNames() const
Returns a list of names of symbols.
TextFormatContext
Text format context.
void symbolRemoved(const QString &name)
Emitted whenever a symbol has been removed from the style and the database has been updated as a resu...
void symbolChanged(const QString &name)
Emitted whenever a symbol's definition is changed.
bool addFavorite(StyleEntity type, const QString &name)
Adds the specified symbol to favorites.
QString smartgroupOperator(int id)
Returns the operator for the smartgroup.
bool saveTextFormat(const QString &name, const QgsTextFormat &format, bool favorite, const QStringList &tags)
Adds a text format to the database.
QList< QList< QPolygonF > > defaultPatchAsQPolygonF(Qgis::SymbolType type, QSizeF size) const
Returns the default patch geometry for the given symbol type and size as a set of QPolygonF objects (...
void textFormatRemoved(const QString &name)
Emitted whenever a text format has been removed from the style and the database has been updated as a...
void setReadOnly(bool readOnly)
Sets whether the style is considered a read-only library.
bool importXml(const QString &filename)
Imports the symbols and colorramps into the default style database from the given XML file.
bool addLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool update=false)
Adds label settings with the specified name to the style.
static std::unique_ptr< QgsColorRamp > loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
static std::unique_ptr< QgsSymbol > loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
static QDomElement saveColorRamp(const QString &name, const QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
static void resetSymbolLayerIds(QgsSymbol *symbol)
Regenerate recursively unique id from all symbol symbol layers.
static QgsSymbolMap loadSymbols(QDomElement &element, const QgsReadWriteContext &context)
Reads a collection of symbols from XML and returns them in a map. Caller is responsible for deleting ...
static QDomElement saveSymbols(QgsSymbolMap &symbols, const QString &tagName, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a collection of symbols to XML with specified tagName for the top-level element.
Abstract base class for all rendered symbols.
Container for all settings relating to text rendering.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
sqlite3_statement_unique_ptr prepare(const QString &sql, int &resultCode) const
Prepares a sql statement, returning the result.
Unique pointer for sqlite3 prepared statements, which automatically finalizes the statement when the ...
QString columnAsText(int column) const
Returns the column value from the current statement row as a string.
QMultiMap< QString, QString > QgsSmartConditionMap
A multimap to hold the smart group conditions as constraint and parameter pairs.
#define QgsDebugError(str)
QMap< QString, QgsSymbol * > QgsSymbolMap
QString qgs_sqlite3_mprintf(const char *format,...)
Wraps sqlite3_mprintf() by automatically freeing the memory.
LegendPatchTable
Columns available in the legend patch table.
@ LegendPatchTableId
Legend patch ID.
@ LegendPatchTableName
Legend patch name.
@ LegendPatchTableFavoriteId
Legend patch is favorite flag.
@ LegendPatchTableXML
Legend patch definition (as XML).
#define STYLE_CURRENT_VERSION
Symbol3DTable
Columns available in the 3d symbol table.
@ Symbol3DTableXML
3d symbol definition (as XML)
@ Symbol3DTableName
3d symbol name
@ Symbol3DTableFavoriteId
3d symbol is favorite flag
@ Symbol3DTableId
3d symbol ID
QMap< int, QString > QgsSymbolGroupMap
QList< QgsSymbolLayer * > QgsSymbolLayerList