17#include "moc_qgsstyle.cpp"
41#include <QDomDocument>
44#include <QDomNodeList>
53#define STYLE_CURRENT_VERSION "2"
78QgsStyle *QgsStyle::sDefaultStyle =
nullptr;
83 std::unique_ptr< QgsSimpleMarkerSymbolLayer > simpleMarker = std::make_unique< QgsSimpleMarkerSymbolLayer >(
Qgis::MarkerShape::Circle,
85 simpleMarker->setStrokeWidth( 0.4 );
86 mPatchMarkerSymbol = std::make_unique< QgsMarkerSymbol >(
QgsSymbolLayerList() << simpleMarker.release() );
88 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 84, 176, 74 ), 0.6 );
89 mPatchLineSymbol = std::make_unique< QgsLineSymbol >(
QgsSymbolLayerList() << simpleLine.release() );
91 std::unique_ptr< QgsGradientFillSymbolLayer > gradientFill = std::make_unique< QgsGradientFillSymbolLayer >( QColor( 66, 150, 63 ), QColor( 84, 176, 74 ) );
92 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleOutline = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 56, 128, 54 ), 0.26 );
93 mPatchFillSymbol = std::make_unique< QgsFillSymbol >(
QgsSymbolLayerList() << gradientFill.release() << simpleOutline.release() );
114 switch ( entity->
type() )
148 static QString sStyleFilename;
149 if ( !sDefaultStyle )
155 if ( !QFile::exists( sStyleFilename ) )
163 sDefaultStyle->createStyleMetadataTableIfNeeded();
170 sDefaultStyle->mInitialized =
false;
173 sDefaultStyle->initializeDefaultStyle( sStyleFilename );
176 sDefaultStyle->
setName( QObject::tr(
"Default" ) );
178 else if ( initialize && !sDefaultStyle->mInitialized )
181 sDefaultStyle->initializeDefaultStyle( sStyleFilename );
183 return sDefaultStyle;
186void QgsStyle::initializeDefaultStyle(
const QString &filename )
188 Q_ASSERT(
this == sDefaultStyle );
189 if (
this != sDefaultStyle )
205 delete sDefaultStyle;
206 sDefaultStyle =
nullptr;
211 qDeleteAll( mSymbols );
212 qDeleteAll( mColorRamps );
213 qDeleteAll( m3dSymbols );
217 mTextFormats.clear();
221 mCachedFavorites.clear();
230 if ( mSymbols.contains(
name ) )
233 delete mSymbols.value(
name );
251 QDomDocument doc( QStringLiteral(
"dummy" ) );
253 if ( symEl.isNull() )
255 QgsDebugError( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
260 QTextStream stream( &xmlArray );
261#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
262 stream.setCodec(
"UTF-8" );
264 symEl.save( stream, 4 );
266 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
268 if ( !runEmptyQuery( query ) )
270 QgsDebugError( QStringLiteral(
"Couldn't insert symbol into the database!" ) );
332 return mSymbols.value(
name );
337 return mSymbols.count();
342 return mSymbols.keys();
352 if ( mColorRamps.contains(
name ) )
355 delete mColorRamps.value(
name );
373 if ( mTextFormats.contains(
name ) )
376 mTextFormats.remove(
name );
377 mTextFormats.insert(
name, format );
383 mTextFormats.insert(
name, format );
394 if ( mLabelSettings.contains(
name ) )
397 mLabelSettings.remove(
name );
398 mLabelSettings.insert(
name, settings );
404 mLabelSettings.insert(
name, settings );
415 if ( mLegendPatchShapes.contains(
name ) )
418 mLegendPatchShapes.remove(
name );
419 mLegendPatchShapes.insert(
name, shape );
425 mLegendPatchShapes.insert(
name, shape );
436 if ( m3dSymbols.contains(
name ) )
439 delete m3dSymbols.take(
name );
457 QDomDocument doc( QStringLiteral(
"dummy" ) );
460 if ( rampEl.isNull() )
462 QgsDebugError( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
467 QTextStream stream( &xmlArray );
468#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
469 stream.setCodec(
"UTF-8" );
471 rampEl.save( stream, 4 );
472 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO colorramp VALUES (NULL, '%q', '%q', %d);",
473 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
474 if ( !runEmptyQuery( query ) )
476 QgsDebugError( QStringLiteral(
"Couldn't insert colorramp into the database!" ) );
498 return ramp ? ramp->
clone() :
nullptr;
503 return mColorRamps.value(
name );
508 return mColorRamps.count();
513 return mColorRamps.keys();
516void QgsStyle::handleDeferred3DSymbolCreation()
518 for (
auto it = mDeferred3DsymbolElements.constBegin(); it != mDeferred3DsymbolElements.constEnd(); ++it )
520 const QString symbolType = it.value().attribute( QStringLiteral(
"type" ) );
534 mDeferred3DsymbolElements.clear();
537bool QgsStyle::openDatabase(
const QString &filename )
539 int rc = mCurrentDB.
open( filename );
542 mErrorString = QStringLiteral(
"Couldn't open the style database: %1" ).arg( mCurrentDB.
errorMessage() );
551 mErrorString.clear();
552 if ( !openDatabase( filename ) )
554 mErrorString = QStringLiteral(
"Unable to create database" );
566 mErrorString.clear();
567 if ( !openDatabase( QStringLiteral(
":memory:" ) ) )
569 mErrorString = QStringLiteral(
"Unable to create temporary memory database" );
582 "id INTEGER PRIMARY KEY,"\
585 "favorite INTEGER);"\
586 "CREATE TABLE colorramp("\
587 "id INTEGER PRIMARY KEY,"\
590 "favorite INTEGER);"\
591 "CREATE TABLE textformat("\
592 "id INTEGER PRIMARY KEY,"\
595 "favorite INTEGER);"\
596 "CREATE TABLE labelsettings("\
597 "id INTEGER PRIMARY KEY,"\
600 "favorite INTEGER);"\
601 "CREATE TABLE legendpatchshapes("\
602 "id INTEGER PRIMARY KEY,"\
605 "favorite INTEGER);"\
606 "CREATE TABLE symbol3d("\
607 "id INTEGER PRIMARY KEY,"\
610 "favorite INTEGER);"\
612 "id INTEGER PRIMARY KEY,"\
614 "CREATE TABLE tagmap("\
615 "tag_id INTEGER NOT NULL,"\
616 "symbol_id INTEGER);"\
617 "CREATE TABLE ctagmap("\
618 "tag_id INTEGER NOT NULL,"\
619 "colorramp_id INTEGER);"\
620 "CREATE TABLE tftagmap("\
621 "tag_id INTEGER NOT NULL,"\
622 "textformat_id INTEGER);"\
623 "CREATE TABLE lstagmap("\
624 "tag_id INTEGER NOT NULL,"\
625 "labelsettings_id INTEGER);"\
626 "CREATE TABLE lpstagmap("\
627 "tag_id INTEGER NOT NULL,"\
628 "legendpatchshape_id INTEGER);"\
629 "CREATE TABLE symbol3dtagmap("\
630 "tag_id INTEGER NOT NULL,"\
631 "symbol3d_id INTEGER);"\
632 "CREATE TABLE smartgroup("\
633 "id INTEGER PRIMARY KEY,"\
636 runEmptyQuery( query );
641 mErrorString.clear();
644 if ( !openDatabase( filename ) )
646 mErrorString = QStringLiteral(
"Unable to open database file specified" );
652 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='textformat'" );
655 statement = mCurrentDB.
prepare( query, rc );
656 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
659 "id INTEGER PRIMARY KEY,"\
662 "favorite INTEGER);"\
663 "CREATE TABLE tftagmap("\
664 "tag_id INTEGER NOT NULL,"\
665 "textformat_id INTEGER);" );
666 runEmptyQuery( query );
669 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='labelsettings'" );
670 statement = mCurrentDB.
prepare( query, rc );
671 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
674 "id INTEGER PRIMARY KEY,"\
677 "favorite INTEGER);"\
678 "CREATE TABLE lstagmap("\
679 "tag_id INTEGER NOT NULL,"\
680 "labelsettings_id INTEGER);" );
681 runEmptyQuery( query );
684 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='legendpatchshapes'" );
685 statement = mCurrentDB.
prepare( query, rc );
686 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
689 "id INTEGER PRIMARY KEY,"\
692 "favorite INTEGER);"\
693 "CREATE TABLE lpstagmap("\
694 "tag_id INTEGER NOT NULL,"\
695 "legendpatchshape_id INTEGER);" );
696 runEmptyQuery( query );
700 statement = mCurrentDB.
prepare( query, rc );
701 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
704 "id INTEGER PRIMARY KEY,"\
707 "favorite INTEGER);"\
708 "CREATE TABLE symbol3dtagmap("\
709 "tag_id INTEGER NOT NULL,"\
710 "symbol3d_id INTEGER);" );
711 runEmptyQuery( query );
716 "UPDATE colorramp SET favorite=0 WHERE favorite IS NULL;"
717 "UPDATE textformat SET favorite=0 WHERE favorite IS NULL;"
718 "UPDATE labelsettings SET favorite=0 WHERE favorite IS NULL;"
719 "UPDATE legendpatchshapes SET favorite=0 WHERE favorite IS NULL;"
720 "UPDATE symbol3d SET favorite=0 WHERE favorite IS NULL;"
722 runEmptyQuery( query );
728 statement = mCurrentDB.
prepare( query, rc );
730 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
736 if ( !doc.setContent( xmlstring ) )
742 QDomElement symElement = doc.documentElement();
745 mSymbols.insert( symbolName,
symbol );
752 statement = mCurrentDB.
prepare( query, rc );
753 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
759 if ( !doc.setContent( xmlstring ) )
764 QDomElement rampElement = doc.documentElement();
767 mColorRamps.insert( rampName, ramp );
774 statement = mCurrentDB.
prepare( query, rc );
775 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
781 if ( !doc.setContent( xmlstring ) )
786 QDomElement formatElement = doc.documentElement();
789 mTextFormats.insert( formatName, format );
796 statement = mCurrentDB.
prepare( query, rc );
797 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
803 if ( !doc.setContent( xmlstring ) )
805 QgsDebugError(
"Cannot open label settings " + settingsName );
808 QDomElement settingsElement = doc.documentElement();
811 mLabelSettings.insert( settingsName, settings );
818 statement = mCurrentDB.
prepare( query, rc );
819 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
825 if ( !doc.setContent( xmlstring ) )
827 QgsDebugError(
"Cannot open legend patch shape " + settingsName );
830 QDomElement settingsElement = doc.documentElement();
833 mLegendPatchShapes.insert( settingsName, shape );
840 statement = mCurrentDB.
prepare( query, rc );
844 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
850 if ( !doc.setContent( xmlstring ) )
855 QDomElement settingsElement = doc.documentElement();
857 if ( !registry3dPopulated )
859 mDeferred3DsymbolElements.insert( settingsName, settingsElement );
863 const QString symbolType = settingsElement.attribute( QStringLiteral(
"type" ) );
868 m3dSymbols.insert( settingsName,
symbol.release() );
879 mFileName = filename;
880 createStyleMetadataTableIfNeeded();
886 mErrorString.clear();
888 if ( !filename.isEmpty() )
889 mFileName = filename;
896 mFileName = filename;
901 if ( mSymbols.contains( newName ) )
903 QgsDebugError( QStringLiteral(
"Symbol of new name already exists" ) );
911 mSymbols.insert( newName,
symbol );
915 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database to tag." ) );
922 QgsDebugError( QStringLiteral(
"No such symbol for tagging in database: " ) + oldName );
941 if ( mColorRamps.contains( newName ) )
943 QgsDebugError( QStringLiteral(
"Color ramp of new name already exists." ) );
951 mColorRamps.insert( newName, ramp );
957 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM colorramp WHERE name='%q'", oldName.toUtf8().constData() );
959 statement = mCurrentDB.
prepare( query, nErr );
960 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
962 rampid = sqlite3_column_int( statement.get(), 0 );
977 QDomDocument doc( QStringLiteral(
"dummy" ) );
980 if ( formatElem.isNull() )
982 QgsDebugError( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
987 QTextStream stream( &xmlArray );
988#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
989 stream.setCodec(
"UTF-8" );
991 formatElem.save( stream, 4 );
992 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO textformat VALUES (NULL, '%q', '%q', %d);",
993 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
994 if ( !runEmptyQuery( query ) )
996 QgsDebugError( QStringLiteral(
"Couldn't insert text format into the database!" ) );
1017 if ( mTextFormats.contains( newName ) )
1019 QgsDebugError( QStringLiteral(
"Text format of new name already exists." ) );
1023 if ( !mTextFormats.contains( oldName ) )
1027 mTextFormats.insert( newName, format );
1033 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM textformat WHERE name='%q'", oldName.toUtf8().constData() );
1035 statement = mCurrentDB.
prepare( query, nErr );
1036 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1038 textFormatId = sqlite3_column_int( statement.get(), 0 );
1053 QDomDocument doc( QStringLiteral(
"dummy" ) );
1056 if ( settingsElem.isNull() )
1058 QgsDebugError( QStringLiteral(
"Couldn't convert label settings to valid XML!" ) );
1062 QByteArray xmlArray;
1063 QTextStream stream( &xmlArray );
1064#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1065 stream.setCodec(
"UTF-8" );
1067 settingsElem.save( stream, 4 );
1068 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO labelsettings VALUES (NULL, '%q', '%q', %d);",
1069 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1070 if ( !runEmptyQuery( query ) )
1072 QgsDebugError( QStringLiteral(
"Couldn't insert label settings into the database!" ) );
1093 if ( mLabelSettings.contains( newName ) )
1095 QgsDebugError( QStringLiteral(
"Label settings of new name already exists." ) );
1099 if ( !mLabelSettings.contains( oldName ) )
1103 mLabelSettings.insert( newName, settings );
1109 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM labelsettings WHERE name='%q'", oldName.toUtf8().constData() );
1111 statement = mCurrentDB.
prepare( query, nErr );
1112 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1129 QDomDocument doc( QStringLiteral(
"dummy" ) );
1130 QDomElement shapeElem = doc.createElement( QStringLiteral(
"shape" ) );
1133 QByteArray xmlArray;
1134 QTextStream stream( &xmlArray );
1135#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1136 stream.setCodec(
"UTF-8" );
1138 shapeElem.save( stream, 4 );
1139 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO legendpatchshapes VALUES (NULL, '%q', '%q', %d);",
1140 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1141 if ( !runEmptyQuery( query ) )
1143 QgsDebugError( QStringLiteral(
"Couldn't insert legend patch shape into the database!" ) );
1158 if ( mLegendPatchShapes.contains( newName ) )
1160 QgsDebugError( QStringLiteral(
"Legend patch shape of new name already exists." ) );
1164 if ( !mLegendPatchShapes.contains( oldName ) )
1168 mLegendPatchShapes.insert( newName, shape );
1174 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM legendpatchshapes WHERE name='%q'", oldName.toUtf8().constData() );
1176 statement = mCurrentDB.
prepare( query, nErr );
1177 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1195 if ( mDefaultPatchCache[
static_cast< int >( type ) ].contains( size ) )
1196 return mDefaultPatchCache[
static_cast< int >( type ) ].value( size );
1202 geom =
QgsGeometry( std::make_unique< QgsPoint >(
static_cast< int >( size.width() ) / 2,
static_cast< int >( size.height() ) / 2 ) );
1209 double y =
static_cast< int >( size.height() ) / 2 + 0.5;
1210 geom =
QgsGeometry( std::make_unique< QgsLineString >( ( QVector< double >() << 0 << size.width() ),
1211 ( QVector< double >() << y << y ) ) );
1217 geom =
QgsGeometry( std::make_unique< QgsPolygon >(
1218 new QgsLineString( QVector< double >() << 0 <<
static_cast< int >( size.width() ) <<
static_cast< int >( size.width() ) << 0 << 0,
1219 QVector< double >() <<
static_cast< int >( size.height() ) <<
static_cast< int >( size.height() ) << 0 << 0 <<
static_cast< int >( size.height() ) ) ) );
1228 mDefaultPatchCache[
static_cast< int >( type ) ][size ] = res;
1235 return QList<QList<QPolygonF> >();
1237 if ( mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ].contains( size ) )
1238 return mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ].value( size );
1241 mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ][size ] = res;
1247 return textFormat( QStringLiteral(
"Default" ) );
1267 QDomDocument doc( QStringLiteral(
"dummy" ) );
1268 QDomElement elem = doc.createElement( QStringLiteral(
"symbol" ) );
1269 elem.setAttribute( QStringLiteral(
"type" ),
symbol->
type() );
1272 QByteArray xmlArray;
1273 QTextStream stream( &xmlArray );
1274#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1275 stream.setCodec(
"UTF-8" );
1277 elem.save( stream, 4 );
1278 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO symbol3d VALUES (NULL, '%q', '%q', %d);",
1279 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1280 if ( !runEmptyQuery( query ) )
1282 QgsDebugError( QStringLiteral(
"Couldn't insert 3d symbol into the database!" ) );
1297 if ( m3dSymbols.contains( newName ) )
1299 QgsDebugError( QStringLiteral(
"3d symbol of new name already exists." ) );
1303 if ( !m3dSymbols.contains( oldName ) )
1307 m3dSymbols.insert( newName,
symbol );
1313 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM symbol3d WHERE name='%q'", oldName.toUtf8().constData() );
1315 statement = mCurrentDB.
prepare( query, nErr );
1316 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1331 return m3dSymbols.keys();
1338 QgsDebugError( QStringLiteral(
"Cannot Open database for getting favorite symbols" ) );
1339 return QStringList();
1348 return QStringList();
1351 query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT name FROM %1 WHERE favorite=1" ).arg( entityTableName( type ) ).toLocal8Bit().data() );
1357 statement = mCurrentDB.
prepare( query, nErr );
1359 QStringList symbols;
1360 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1372 QgsDebugError( QStringLiteral(
"Cannot open database to get symbols of tagid %1" ).arg( tagid ) );
1373 return QStringList();
1382 return QStringList();
1385 subquery =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT %1 FROM %2 WHERE tag_id=%d" ).arg( tagmapEntityIdFieldName( type ),
1386 tagmapTableName( type ) ).toLocal8Bit().data(), tagid );
1392 statement = mCurrentDB.
prepare( subquery, nErr );
1395 QStringList symbols;
1396 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1398 int id = sqlite3_column_int( statement.get(), 0 );
1400 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT name FROM %1 WHERE id=%d" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
id );
1404 statement2 = mCurrentDB.
prepare( query, rc );
1405 while ( rc == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1420 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO tag VALUES (NULL, '%q')", tagname.toUtf8().constData() );
1422 statement = mCurrentDB.
prepare( query, nErr );
1423 if ( nErr == SQLITE_OK )
1424 ( void )sqlite3_step( statement.get() );
1427 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1431 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
1437 return QStringList();
1443 statement = mCurrentDB.
prepare( query, nError );
1445 QStringList tagList;
1446 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1456 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET name='%q' WHERE id=%d" ).arg( entityTableName( type ) ).toLocal8Bit().data(), newName.toUtf8().constData(),
id );
1458 const bool result = runEmptyQuery( query );
1461 mErrorString = QStringLiteral(
"Could not rename!" );
1465 mCachedTags.clear();
1466 mCachedFavorites.clear();
1491 bool groupRemoved =
false;
1496 query =
qgs_sqlite3_mprintf(
"DELETE FROM tag WHERE id=%d; DELETE FROM tagmap WHERE tag_id=%d",
id,
id );
1497 groupRemoved =
true;
1501 groupRemoved =
true;
1505 query =
qgs_sqlite3_mprintf( QStringLiteral(
"DELETE FROM %1 WHERE id=%d; DELETE FROM %2 WHERE %3=%d" ).arg(
1506 entityTableName( type ),
1507 tagmapTableName( type ),
1508 tagmapEntityIdFieldName( type )
1509 ).toLocal8Bit().data(),
id,
id );
1513 bool result =
false;
1514 if ( !runEmptyQuery( query ) )
1516 QgsDebugError( QStringLiteral(
"Could not delete entity!" ) );
1520 mCachedTags.clear();
1521 mCachedFavorites.clear();
1526 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1545 std::unique_ptr< QgsSymbol >
symbol( mSymbols.take(
name ) );
1554 std::unique_ptr< QgsAbstract3DSymbol >
symbol( m3dSymbols.take(
name ) );
1563 std::unique_ptr< QgsColorRamp > ramp( mColorRamps.take(
name ) );
1571 if ( !mTextFormats.contains(
name ) )
1574 mTextFormats.remove(
name );
1580 if ( !mLabelSettings.contains(
name ) )
1583 mLabelSettings.remove(
name );
1589 if ( !mLegendPatchShapes.contains(
name ) )
1592 mLegendPatchShapes.remove(
name );
1599 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database to modify." ) );
1609 const bool result =
remove( type,
id );
1612 mCachedTags[ type ].remove(
name );
1613 mCachedFavorites[ type ].remove(
name );
1642bool QgsStyle::runEmptyQuery(
const QString &query )
1647 char *zErr =
nullptr;
1648 int nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1650 if ( nErr != SQLITE_OK )
1653 sqlite3_free( zErr );
1656 return nErr == SQLITE_OK;
1667 QgsDebugError( QStringLiteral(
"Wrong entity value. cannot apply group" ) );
1671 query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET favorite=1 WHERE name='%q'" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
1672 name.toUtf8().constData() );
1676 const bool res = runEmptyQuery( query );
1686 mCachedFavorites[ type ].insert(
name,
true );
1703 QgsDebugError( QStringLiteral(
"Wrong entity value. cannot apply group" ) );
1707 query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET favorite=0 WHERE name='%q'" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
name.toUtf8().constData() );
1711 const bool res = runEmptyQuery( query );
1714 mCachedFavorites[ type ].insert(
name,
false );
1725 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database to search" ) );
1726 return QStringList();
1735 return QStringList();
1738 item = entityTableName( type );
1743 item.toUtf8().constData(), qword.toUtf8().constData() );
1746 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1748 QSet< QString > symbols;
1749 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1755 query =
qgs_sqlite3_mprintf(
"SELECT id FROM tag WHERE name LIKE '%%%q%%'", qword.toUtf8().constData() );
1756 statement = mCurrentDB.
prepare( query, nErr );
1759 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1764 QString dummy = tagids.join( QLatin1String(
", " ) );
1765 query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT %1 FROM %2 WHERE tag_id IN (%q)" ).arg( tagmapEntityIdFieldName( type ),
1766 tagmapTableName( type ) ).toLocal8Bit().data(), dummy.toUtf8().constData() );
1768 statement = mCurrentDB.
prepare( query, nErr );
1770 QStringList symbolids;
1771 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1776 dummy = symbolids.join( QLatin1String(
", " ) );
1778 item.toUtf8().constData(), dummy.toUtf8().constData() );
1779 statement = mCurrentDB.
prepare( query, nErr );
1780 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1785 return QStringList( symbols.constBegin(), symbols.constEnd() );
1792 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database to tag." ) );
1815 const auto constTags =
tags;
1816 for (
const QString &t : constTags )
1819 if ( !
tag.isEmpty() )
1831 QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"INSERT INTO %1 VALUES (%d,%d)" ).arg( tagmapTableName( type ) ).toLocal8Bit().data(), tagid, symbolid );
1833 char *zErr =
nullptr;
1835 nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1839 sqlite3_free( zErr );
1845 clearCachedTags( type,
symbol );
1855 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database for detagging." ) );
1870 if ( symbolid == 0 )
1875 const auto constTags =
tags;
1876 for (
const QString &
tag : constTags )
1881 statement2 = mCurrentDB.
prepare( query, nErr );
1884 if ( nErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1886 tagid = sqlite3_column_int( statement2.get(), 0 );
1892 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"DELETE FROM %1 WHERE tag_id=%d AND %2=%d" ).arg( tagmapTableName( type ), tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), tagid, symbolid );
1893 runEmptyQuery( query );
1897 clearCachedTags( type,
symbol );
1910 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database for detagging." ) );
1925 if ( symbolid == 0 )
1931 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"DELETE FROM %1 WHERE %2=%d" ).arg( tagmapTableName( type ),
1932 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1933 runEmptyQuery( query );
1935 clearCachedTags( type,
symbol );
1950 return QStringList();
1953 if ( mCachedTags[ type ].contains(
symbol ) )
1954 return mCachedTags[ type ].value(
symbol );
1960 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
1961 return QStringList();
1966 return QStringList();
1969 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT tag_id FROM %1 WHERE %2=%d" ).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( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
2010 if ( mCachedFavorites[ type ].contains(
name ) )
2011 return mCachedFavorites[ type ].value(
name );
2015 const QStringList names =
allNames( type );
2016 if ( !names.contains(
name ) )
2022 for (
const QString &n : names )
2024 const bool isFav = favorites.contains( n );
2028 mCachedFavorites[ type ].insert( n, isFav );
2037 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
2064 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT tag_id FROM %1 WHERE tag_id=%d AND %2=%d" ).arg( tagmapTableName( type ),
2065 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), tagid, symbolid );
2068 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2070 return ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW );
2082 statement = mCurrentDB.
prepare( query, nError );
2085 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2093int QgsStyle::getId(
const QString &table,
const QString &name )
2095 QString lowerName(
name.toLower() );
2096 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE LOWER(name)='%q'", table.toUtf8().constData(), lowerName.toUtf8().constData() );
2099 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2102 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2104 id = sqlite3_column_int( statement.get(), 0 );
2109 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE name='%q'", table.toUtf8().constData(),
name.toUtf8().constData() );
2112 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2113 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2115 id = sqlite3_column_int( statement.get(), 0 );
2122QString QgsStyle::getName(
const QString &table,
int id )
const
2124 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM %q WHERE id='%q'", table.toUtf8().constData(), QString::number(
id ).toUtf8().constData() );
2127 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2130 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2140 return getId( QStringLiteral(
"symbol" ),
name );
2145 return getId( entityTableName( type ),
name );
2150 return getId( QStringLiteral(
"colorramp" ),
name );
2155 return mTextFormats.value(
name );
2160 return mTextFormats.count();
2165 return mTextFormats.keys();
2170 return getId( QStringLiteral(
"textformat" ),
name );
2175 return mLabelSettings.value(
name );
2180 return mLegendPatchShapes.value(
name );
2185 return mLegendPatchShapes.count();
2190 if ( !mLegendPatchShapes.contains(
name ) )
2193 return mLegendPatchShapes.value(
name ).symbolType();
2198 return m3dSymbols.contains(
name ) ? m3dSymbols.value(
name )->clone() :
nullptr;
2203 return m3dSymbols.count();
2208 if ( !m3dSymbols.contains(
name ) )
2209 return QList<Qgis::GeometryType>();
2211 return m3dSymbols.value(
name )->compatibleGeometryTypes();
2216 if ( !mLabelSettings.contains(
name ) )
2219 return mLabelSettings.value(
name ).layerType;
2224 return mLabelSettings.count();
2229 return mLabelSettings.keys();
2234 return getId( QStringLiteral(
"labelsettings" ),
name );
2239 return mLegendPatchShapes.keys();
2247 return mPatchMarkerSymbol.get();
2250 return mPatchLineSymbol.get();
2253 return mPatchFillSymbol.get();
2263 return getId( QStringLiteral(
"tag" ),
name );
2268 return getId( QStringLiteral(
"smartgroup" ),
name );
2299 return QStringList();
2305 conditions.values( QStringLiteral(
"!tag" ) ),
2306 conditions.values( QStringLiteral(
"name" ) ),
2307 conditions.values( QStringLiteral(
"!name" ) ) );
2310int QgsStyle::addSmartgroup(
const QString &name,
const QString &op,
const QStringList &matchTag,
const QStringList &noMatchTag,
const QStringList &matchName,
const QStringList &noMatchName )
2312 QDomDocument doc( QStringLiteral(
"dummy" ) );
2313 QDomElement smartEl = doc.createElement( QStringLiteral(
"smartgroup" ) );
2314 smartEl.setAttribute( QStringLiteral(
"name" ),
name );
2315 smartEl.setAttribute( QStringLiteral(
"operator" ), op );
2317 auto addCondition = [&doc, &smartEl](
const QString & constraint,
const QStringList & parameters )
2319 for (
const QString ¶m : parameters )
2321 QDomElement condEl = doc.createElement( QStringLiteral(
"condition" ) );
2322 condEl.setAttribute( QStringLiteral(
"constraint" ), constraint );
2323 condEl.setAttribute( QStringLiteral(
"param" ), param );
2324 smartEl.appendChild( condEl );
2327 addCondition( QStringLiteral(
"tag" ), matchTag );
2328 addCondition( QStringLiteral(
"!tag" ), noMatchTag );
2329 addCondition( QStringLiteral(
"name" ), matchName );
2330 addCondition( QStringLiteral(
"!name" ), noMatchName );
2332 QByteArray xmlArray;
2333 QTextStream stream( &xmlArray );
2334#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2335 stream.setCodec(
"UTF-8" );
2337 smartEl.save( stream, 4 );
2339 name.toUtf8().constData(), xmlArray.constData() );
2341 if ( runEmptyQuery( query ) )
2344 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
2347 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
2351 QgsDebugError( QStringLiteral(
"Couldn't add the smart group into the database!" ) );
2360 QgsDebugError( QStringLiteral(
"Cannot open database for listing groups" ) );
2369 statement = mCurrentDB.
prepare( query, nError );
2372 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2385 QgsDebugError( QStringLiteral(
"Cannot open database for listing groups" ) );
2386 return QStringList();
2394 statement = mCurrentDB.
prepare( query, nError );
2397 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2407 QStringList symbols;
2412 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2413 if ( !( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW ) )
2415 return QStringList();
2421 if ( !doc.setContent( xmlstr ) )
2423 QgsDebugError( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2425 QDomElement smartEl = doc.documentElement();
2426 QString op = smartEl.attribute( QStringLiteral(
"operator" ) );
2427 QDomNodeList conditionNodes = smartEl.childNodes();
2429 bool firstSet =
true;
2430 for (
int i = 0; i < conditionNodes.count(); i++ )
2432 QDomElement condEl = conditionNodes.at( i ).toElement();
2433 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2434 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2436 QStringList resultNames;
2438 if ( constraint == QLatin1String(
"tag" ) )
2442 else if ( constraint == QLatin1String(
"name" ) )
2444 resultNames =
allNames( type ).filter( param, Qt::CaseInsensitive );
2446 else if ( constraint == QLatin1String(
"!tag" ) )
2450 for (
const QString &
name : unwanted )
2452 resultNames.removeAll(
name );
2455 else if ( constraint == QLatin1String(
"!name" ) )
2457 const QStringList all =
allNames( type );
2458 for (
const QString &str : all )
2460 if ( !str.contains( param, Qt::CaseInsensitive ) )
2468 symbols = resultNames;
2473 if ( op == QLatin1String(
"OR" ) )
2475 symbols << resultNames;
2477 else if ( op == QLatin1String(
"AND" ) )
2479 QStringList dummy = symbols;
2481 for (
const QString &result : std::as_const( resultNames ) )
2483 if ( dummy.contains( result ) )
2492 const QSet< QString > uniqueSet( symbols.constBegin(), symbols.constEnd() );
2493 QStringList unique( uniqueSet.begin(), uniqueSet.end() );
2494 std::sort( unique.begin(), unique.end() );
2502 QgsDebugError( QStringLiteral(
"Cannot open database for listing groups" ) );
2512 statement = mCurrentDB.
prepare( query, nError );
2513 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2517 if ( !doc.setContent( xmlstr ) )
2519 QgsDebugError( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2522 QDomElement smartEl = doc.documentElement();
2523 QDomNodeList conditionNodes = smartEl.childNodes();
2525 for (
int i = 0; i < conditionNodes.count(); i++ )
2527 QDomElement condEl = conditionNodes.at( i ).toElement();
2528 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2529 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2531 condition.insert( constraint, param );
2542 QgsDebugError( QStringLiteral(
"Cannot open database for listing groups" ) );
2552 statement = mCurrentDB.
prepare( query, nError );
2553 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2557 if ( !doc.setContent( xmlstr ) )
2559 QgsDebugError( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2561 QDomElement smartEl = doc.documentElement();
2562 op = smartEl.attribute( QStringLiteral(
"operator" ) );
2570 if ( filename.isEmpty() )
2572 QgsDebugError( QStringLiteral(
"Invalid filename for style export." ) );
2576 QDomDocument doc( QStringLiteral(
"qgis_style" ) );
2577 QDomElement root = doc.createElement( QStringLiteral(
"qgis_style" ) );
2579 doc.appendChild( root );
2589 QDomNodeList symbolsList = symbolsElem.elementsByTagName( QStringLiteral(
"symbol" ) );
2590 int nbSymbols = symbolsList.count();
2591 for (
int i = 0; i < nbSymbols; ++i )
2593 QDomElement
symbol = symbolsList.at( i ).toElement();
2594 QString
name =
symbol.attribute( QStringLiteral(
"name" ) );
2596 if (
tags.count() > 0 )
2598 symbol.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2600 if ( favoriteSymbols.contains(
name ) )
2602 symbol.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2607 QDomElement rampsElem = doc.createElement( QStringLiteral(
"colorramps" ) );
2608 for ( QMap<QString, QgsColorRamp *>::const_iterator itr = mColorRamps.constBegin(); itr != mColorRamps.constEnd(); ++itr )
2612 if (
tags.count() > 0 )
2614 rampEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2616 if ( favoriteColorramps.contains( itr.key() ) )
2618 rampEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2620 rampsElem.appendChild( rampEl );
2624 QDomElement textFormatsElem = doc.createElement( QStringLiteral(
"textformats" ) );
2625 for (
auto it = mTextFormats.constBegin(); it != mTextFormats.constEnd(); ++it )
2627 QDomElement textFormatEl = doc.createElement( QStringLiteral(
"textformat" ) );
2628 textFormatEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2630 textFormatEl.appendChild( textStyleEl );
2632 if (
tags.count() > 0 )
2634 textFormatEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2636 if ( favoriteTextFormats.contains( it.key() ) )
2638 textFormatEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2640 textFormatsElem.appendChild( textFormatEl );
2644 QDomElement labelSettingsElem = doc.createElement( QStringLiteral(
"labelsettings" ) );
2645 for (
auto it = mLabelSettings.constBegin(); it != mLabelSettings.constEnd(); ++it )
2647 QDomElement labelSettingsEl = doc.createElement( QStringLiteral(
"labelsetting" ) );
2648 labelSettingsEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2650 labelSettingsEl.appendChild( defEl );
2652 if (
tags.count() > 0 )
2654 labelSettingsEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2656 if ( favoriteTextFormats.contains( it.key() ) )
2658 labelSettingsEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2660 labelSettingsElem.appendChild( labelSettingsEl );
2664 QDomElement legendPatchShapesElem = doc.createElement( QStringLiteral(
"legendpatchshapes" ) );
2665 for (
auto it = mLegendPatchShapes.constBegin(); it != mLegendPatchShapes.constEnd(); ++it )
2667 QDomElement legendPatchShapeEl = doc.createElement( QStringLiteral(
"legendpatchshape" ) );
2668 legendPatchShapeEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2669 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2671 legendPatchShapeEl.appendChild( defEl );
2673 if (
tags.count() > 0 )
2675 legendPatchShapeEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2677 if ( favoriteLegendShapes.contains( it.key() ) )
2679 legendPatchShapeEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2681 legendPatchShapesElem.appendChild( legendPatchShapeEl );
2685 QDomElement symbols3DElem = doc.createElement( QStringLiteral(
"symbols3d" ) );
2686 for (
auto it = m3dSymbols.constBegin(); it != m3dSymbols.constEnd(); ++it )
2688 QDomElement symbolEl = doc.createElement( QStringLiteral(
"symbol3d" ) );
2689 symbolEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2690 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2691 defEl.setAttribute( QStringLiteral(
"type" ), it.value()->type() );
2693 symbolEl.appendChild( defEl );
2695 if (
tags.count() > 0 )
2697 symbolEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2699 if ( favorite3DSymbols.contains( it.key() ) )
2701 symbolEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2703 symbols3DElem.appendChild( symbolEl );
2706 root.appendChild( symbolsElem );
2707 root.appendChild( rampsElem );
2708 root.appendChild( textFormatsElem );
2709 root.appendChild( labelSettingsElem );
2710 root.appendChild( legendPatchShapesElem );
2711 root.appendChild( symbols3DElem );
2714 QFile f( filename );
2715 if ( !f.open( QFile::WriteOnly | QIODevice::Truncate ) )
2717 mErrorString =
"Couldn't open file for writing: " + filename;
2721 QTextStream ts( &f );
2722#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2723 ts.setCodec(
"UTF-8" );
2738 mErrorString = QString();
2739 QDomDocument doc( QStringLiteral(
"style" ) );
2740 QFile f( filename );
2741 if ( !f.open( QFile::ReadOnly ) )
2743 mErrorString = QStringLiteral(
"Unable to open the specified file" );
2744 QgsDebugError( QStringLiteral(
"Error opening the style XML file." ) );
2748 if ( !doc.setContent( &f ) )
2750 mErrorString = QStringLiteral(
"Unable to understand the style file: %1" ).arg( filename );
2757 QDomElement docEl = doc.documentElement();
2758 if ( docEl.tagName() != QLatin1String(
"qgis_style" ) )
2760 mErrorString =
"Incorrect root tag in style: " + docEl.tagName();
2764 const QString version = docEl.attribute( QStringLiteral(
"version" ) );
2765 if ( version != QLatin1String(
STYLE_CURRENT_VERSION ) && version != QLatin1String(
"0" ) && version != QLatin1String(
"1" ) )
2767 mErrorString =
"Unknown style file version: " + version;
2773 QDomElement symbolsElement = docEl.firstChildElement( QStringLiteral(
"symbols" ) );
2774 QDomElement e = symbolsElement.firstChildElement();
2778 runEmptyQuery( query );
2783 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2785 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2786 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2792 if ( e.tagName() == QLatin1String(
"symbol" ) )
2794 QString
name = e.attribute( QStringLiteral(
"name" ) );
2796 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2798 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2800 bool favorite =
false;
2801 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2828 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
2835 QDomElement rampsElement = docEl.firstChildElement( QStringLiteral(
"colorramps" ) );
2836 e = rampsElement.firstChildElement();
2837 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2839 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2840 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2846 if ( e.tagName() == QLatin1String(
"colorramp" ) )
2848 QString
name = e.attribute( QStringLiteral(
"name" ) );
2850 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2852 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2854 bool favorite =
false;
2855 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2879 if ( qobject_cast< QGuiApplication * >( QCoreApplication::instance() ) )
2883 const QDomElement textFormatElement = docEl.firstChildElement( QStringLiteral(
"textformats" ) );
2884 e = textFormatElement.firstChildElement();
2885 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2887 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2888 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2894 if ( e.tagName() == QLatin1String(
"textformat" ) )
2896 QString
name = e.attribute( QStringLiteral(
"name" ) );
2898 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2900 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2902 bool favorite =
false;
2903 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2909 const QDomElement styleElem = e.firstChildElement();
2927 const QDomElement labelSettingsElement = docEl.firstChildElement( QStringLiteral(
"labelsettings" ) );
2928 e = labelSettingsElement.firstChildElement();
2929 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2931 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2932 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2938 if ( e.tagName() == QLatin1String(
"labelsetting" ) )
2940 QString
name = e.attribute( QStringLiteral(
"name" ) );
2942 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2944 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2946 bool favorite =
false;
2947 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2953 const QDomElement styleElem = e.firstChildElement();
2972 const QDomElement legendPatchShapesElement = docEl.firstChildElement( QStringLiteral(
"legendpatchshapes" ) );
2973 e = legendPatchShapesElement.firstChildElement();
2974 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2976 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2977 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2983 if ( e.tagName() == QLatin1String(
"legendpatchshape" ) )
2985 QString
name = e.attribute( QStringLiteral(
"name" ) );
2987 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2989 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2991 bool favorite =
false;
2992 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2998 const QDomElement shapeElem = e.firstChildElement();
3016 const QDomElement symbols3DElement = docEl.firstChildElement( QStringLiteral(
"symbols3d" ) );
3017 e = symbols3DElement.firstChildElement();
3018 for ( ; !e.isNull(); e = e.nextSiblingElement() )
3020 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
3021 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
3027 if ( e.tagName() == QLatin1String(
"symbol3d" ) )
3029 QString
name = e.attribute( QStringLiteral(
"name" ) );
3031 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
3033 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
3035 bool favorite =
false;
3036 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
3041 const QDomElement symbolElem = e.firstChildElement();
3042 const QString type = symbolElem.attribute( QStringLiteral(
"type" ) );
3063 runEmptyQuery( query );
3070 QFileInfo fileInfo( path );
3072 if ( fileInfo.suffix().compare( QLatin1String(
"xml" ), Qt::CaseInsensitive ) != 0 )
3076 if ( !QFile::exists( path ) )
3079 QFile inputFile( path );
3080 if ( !inputFile.open( QIODevice::ReadOnly ) )
3083 QTextStream stream( &inputFile );
3084 const QString line = stream.readLine();
3085 return line == QLatin1String(
"<!DOCTYPE qgis_style>" );
3100 mReadOnly = readOnly;
3103bool QgsStyle::updateSymbol( StyleEntity type,
const QString &name )
3105 QDomDocument doc( QStringLiteral(
"dummy" ) );
3107 QByteArray xmlArray;
3108 QTextStream stream( &xmlArray );
3109#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
3110 stream.setCodec(
"UTF-8" );
3120 auto it = mSymbols.constFind(
name );
3121 if ( it == mSymbols.constEnd() || !it.value() )
3123 QgsDebugError( QStringLiteral(
"Update request received for unavailable symbol" ) );
3128 if ( symEl.isNull() )
3130 QgsDebugError( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
3133 symEl.save( stream, 4 );
3135 xmlArray.constData(),
name.toUtf8().constData() );
3142 auto it = m3dSymbols.constFind(
name );
3143 if ( it == m3dSymbols.constEnd() || !it.value() )
3145 QgsDebugError( QStringLiteral(
"Update request received for unavailable symbol" ) );
3149 symEl = doc.createElement( QStringLiteral(
"symbol" ) );
3150 symEl.setAttribute( QStringLiteral(
"type" ), it.value()->type() );
3152 if ( symEl.isNull() )
3154 QgsDebugError( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
3157 symEl.save( stream, 4 );
3159 xmlArray.constData(),
name.toUtf8().constData() );
3165 auto it = mColorRamps.constFind(
name );
3166 if ( it == mColorRamps.constEnd() || !it.value() )
3168 QgsDebugError( QStringLiteral(
"Update requested for unavailable color ramp." ) );
3173 if ( symEl.isNull() )
3175 QgsDebugError( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
3178 symEl.save( stream, 4 );
3180 xmlArray.constData(),
name.toUtf8().constData() );
3186 auto it = mTextFormats.constFind(
name );
3187 if ( it == mTextFormats.constEnd() )
3189 QgsDebugError( QStringLiteral(
"Update requested for unavailable text format." ) );
3194 if ( symEl.isNull() )
3196 QgsDebugError( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
3199 symEl.save( stream, 4 );
3201 xmlArray.constData(),
name.toUtf8().constData() );
3207 auto it = mLabelSettings.constFind(
name );
3208 if ( it == mLabelSettings.constEnd() )
3210 QgsDebugError( QStringLiteral(
"Update requested for unavailable label settings." ) );
3215 if ( symEl.isNull() )
3217 QgsDebugError( QStringLiteral(
"Couldn't convert label settings to valid XML!" ) );
3220 symEl.save( stream, 4 );
3222 xmlArray.constData(),
name.toUtf8().constData() );
3228 auto it = mLegendPatchShapes.constFind(
name );
3229 if ( it == mLegendPatchShapes.constEnd() )
3231 QgsDebugError( QStringLiteral(
"Update requested for unavailable legend patch shape." ) );
3235 symEl = doc.createElement( QStringLiteral(
"shape" ) );
3237 symEl.save( stream, 4 );
3239 xmlArray.constData(),
name.toUtf8().constData() );
3246 QgsDebugError( QStringLiteral(
"Updating the unsupported StyleEntity" ) );
3252 if ( !runEmptyQuery( query ) )
3254 QgsDebugError( QStringLiteral(
"Couldn't update symbol into the database!" ) );
3290 mCachedTags[ type ].remove(
name );
3293bool QgsStyle::createStyleMetadataTableIfNeeded()
3296 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='stylemetadata'" );
3299 statement = mCurrentDB.
prepare( query, rc );
3301 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
3305 "id INTEGER PRIMARY KEY,"\
3308 runEmptyQuery( query );
3310 runEmptyQuery( query );
3319void QgsStyle::upgradeIfRequired()
3323 if ( !createStyleMetadataTableIfNeeded() )
3325 const QString query =
qgs_sqlite3_mprintf(
"SELECT value FROM stylemetadata WHERE key='version'" );
3328 if ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
3340 runEmptyQuery( query );
3350 return QStringLiteral(
"symbol" );
3353 return QStringLiteral(
"colorramp" );
3356 return QStringLiteral(
"textformat" );
3359 return QStringLiteral(
"labelsettings" );
3362 return QStringLiteral(
"legendpatchshapes" );
3365 return QStringLiteral(
"symbol3d" );
3368 return QStringLiteral(
"tag" );
3371 return QStringLiteral(
"smartgroup" );
3381 return QStringLiteral(
"tagmap" );
3384 return QStringLiteral(
"ctagmap" );
3387 return QStringLiteral(
"tftagmap" );
3390 return QStringLiteral(
"lstagmap" );
3393 return QStringLiteral(
"lpstagmap" );
3396 return QStringLiteral(
"symbol3dtagmap" );
3410 return QStringLiteral(
"symbol_id" );
3413 return QStringLiteral(
"colorramp_id" );
3416 return QStringLiteral(
"textformat_id" );
3419 return QStringLiteral(
"labelsettings_id" );
3422 return QStringLiteral(
"legendpatchshape_id" );
3425 return QStringLiteral(
"symbol3d_id" );
@ 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.
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 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...
The class is used as a container of context for various read/write operations on other objects.
Scoped object for logging of the runtime for a single operation or group of operations.
This class is a composition of two QSettings instances:
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.
bool addEntity(const QString &name, const QgsStyleEntityInterface *entity, bool update=false)
Adds an entity to the style, with the specified name.
bool saveColorRamp(const QString &name, QgsColorRamp *ramp, bool favorite, const QStringList &tags)
Adds the colorramp to the database.
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.
void symbolSaved(const QString &name, QgsSymbol *symbol)
Emitted every time a new symbol has been added to the database.
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 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.
bool saveSymbol(const QString &name, QgsSymbol *symbol, bool favorite, const QStringList &tags)
Adds the symbol to the database with tags.
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.
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.
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 QgsColorRamp * loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
static QDomElement saveColorRamp(const QString &name, QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
static 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 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.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
Qgis::SymbolType type() const
Returns the symbol's type.
Container for all settings relating to text rendering.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
bool isValid() const
Returns true if the format is valid.
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.
int open(const QString &path)
Opens the database at the specified file path.
QString errorMessage() const
Returns the most recent error message encountered by the database.
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