40#include <QDomDocument>
43#include <QDomNodeList>
52#define STYLE_CURRENT_VERSION "2"
77QgsStyle *QgsStyle::sDefaultStyle =
nullptr;
82 std::unique_ptr< QgsSimpleMarkerSymbolLayer > simpleMarker = std::make_unique< QgsSimpleMarkerSymbolLayer >(
Qgis::MarkerShape::Circle,
84 simpleMarker->setStrokeWidth( 0.4 );
85 mPatchMarkerSymbol = std::make_unique< QgsMarkerSymbol >(
QgsSymbolLayerList() << simpleMarker.release() );
87 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 84, 176, 74 ), 0.6 );
88 mPatchLineSymbol = std::make_unique< QgsLineSymbol >(
QgsSymbolLayerList() << simpleLine.release() );
90 std::unique_ptr< QgsGradientFillSymbolLayer > gradientFill = std::make_unique< QgsGradientFillSymbolLayer >( QColor( 66, 150, 63 ), QColor( 84, 176, 74 ) );
91 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleOutline = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 56, 128, 54 ), 0.26 );
92 mPatchFillSymbol = std::make_unique< QgsFillSymbol >(
QgsSymbolLayerList() << gradientFill.release() << simpleOutline.release() );
113 switch ( entity->
type() )
147 if ( !sDefaultStyle )
153 if ( !QFile::exists( styleFilename ) )
161 sDefaultStyle->createStyleMetadataTableIfNeeded();
168 sDefaultStyle->
load( styleFilename );
169 sDefaultStyle->upgradeIfRequired();
171 sDefaultStyle->
setName( QObject::tr(
"Default" ) );
173 return sDefaultStyle;
178 delete sDefaultStyle;
179 sDefaultStyle =
nullptr;
184 qDeleteAll( mSymbols );
185 qDeleteAll( mColorRamps );
186 qDeleteAll( m3dSymbols );
190 mTextFormats.clear();
194 mCachedFavorites.clear();
203 if ( mSymbols.contains(
name ) )
206 delete mSymbols.value(
name );
224 QDomDocument doc( QStringLiteral(
"dummy" ) );
226 if ( symEl.isNull() )
228 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
233 QTextStream stream( &xmlArray );
234#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
235 stream.setCodec(
"UTF-8" );
237 symEl.save( stream, 4 );
239 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
241 if ( !runEmptyQuery( query ) )
243 QgsDebugMsg( QStringLiteral(
"Couldn't insert symbol into the database!" ) );
299 return mSymbols.value(
name );
304 return mSymbols.count();
309 return mSymbols.keys();
319 if ( mColorRamps.contains(
name ) )
322 delete mColorRamps.value(
name );
340 if ( mTextFormats.contains(
name ) )
343 mTextFormats.remove(
name );
344 mTextFormats.insert(
name, format );
350 mTextFormats.insert(
name, format );
361 if ( mLabelSettings.contains(
name ) )
364 mLabelSettings.remove(
name );
365 mLabelSettings.insert(
name, settings );
371 mLabelSettings.insert(
name, settings );
382 if ( mLegendPatchShapes.contains(
name ) )
385 mLegendPatchShapes.remove(
name );
386 mLegendPatchShapes.insert(
name, shape );
392 mLegendPatchShapes.insert(
name, shape );
403 if ( m3dSymbols.contains(
name ) )
406 delete m3dSymbols.take(
name );
424 QDomDocument doc( QStringLiteral(
"dummy" ) );
427 if ( rampEl.isNull() )
429 QgsDebugMsg( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
434 QTextStream stream( &xmlArray );
435#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
436 stream.setCodec(
"UTF-8" );
438 rampEl.save( stream, 4 );
439 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO colorramp VALUES (NULL, '%q', '%q', %d);",
440 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
441 if ( !runEmptyQuery( query ) )
443 QgsDebugMsg( QStringLiteral(
"Couldn't insert colorramp into the database!" ) );
465 return ramp ? ramp->
clone() :
nullptr;
470 return mColorRamps.value(
name );
475 return mColorRamps.count();
480 return mColorRamps.keys();
483void QgsStyle::handleDeferred3DSymbolCreation()
485 for (
auto it = mDeferred3DsymbolElements.constBegin(); it != mDeferred3DsymbolElements.constEnd(); ++it )
487 const QString symbolType = it.value().attribute( QStringLiteral(
"type" ) );
497 QgsDebugMsg(
"Cannot open 3d symbol " + it.key() );
501 mDeferred3DsymbolElements.clear();
504bool QgsStyle::openDatabase(
const QString &filename )
506 int rc = mCurrentDB.
open( filename );
509 mErrorString = QStringLiteral(
"Couldn't open the style database: %1" ).arg( mCurrentDB.
errorMessage() );
518 mErrorString.clear();
519 if ( !openDatabase( filename ) )
521 mErrorString = QStringLiteral(
"Unable to create database" );
533 mErrorString.clear();
534 if ( !openDatabase( QStringLiteral(
":memory:" ) ) )
536 mErrorString = QStringLiteral(
"Unable to create temporary memory database" );
549 "id INTEGER PRIMARY KEY,"\
552 "favorite INTEGER);"\
553 "CREATE TABLE colorramp("\
554 "id INTEGER PRIMARY KEY,"\
557 "favorite INTEGER);"\
558 "CREATE TABLE textformat("\
559 "id INTEGER PRIMARY KEY,"\
562 "favorite INTEGER);"\
563 "CREATE TABLE labelsettings("\
564 "id INTEGER PRIMARY KEY,"\
567 "favorite INTEGER);"\
568 "CREATE TABLE legendpatchshapes("\
569 "id INTEGER PRIMARY KEY,"\
572 "favorite INTEGER);"\
573 "CREATE TABLE symbol3d("\
574 "id INTEGER PRIMARY KEY,"\
577 "favorite INTEGER);"\
579 "id INTEGER PRIMARY KEY,"\
581 "CREATE TABLE tagmap("\
582 "tag_id INTEGER NOT NULL,"\
583 "symbol_id INTEGER);"\
584 "CREATE TABLE ctagmap("\
585 "tag_id INTEGER NOT NULL,"\
586 "colorramp_id INTEGER);"\
587 "CREATE TABLE tftagmap("\
588 "tag_id INTEGER NOT NULL,"\
589 "textformat_id INTEGER);"\
590 "CREATE TABLE lstagmap("\
591 "tag_id INTEGER NOT NULL,"\
592 "labelsettings_id INTEGER);"\
593 "CREATE TABLE lpstagmap("\
594 "tag_id INTEGER NOT NULL,"\
595 "legendpatchshape_id INTEGER);"\
596 "CREATE TABLE symbol3dtagmap("\
597 "tag_id INTEGER NOT NULL,"\
598 "symbol3d_id INTEGER);"\
599 "CREATE TABLE smartgroup("\
600 "id INTEGER PRIMARY KEY,"\
603 runEmptyQuery( query );
608 mErrorString.clear();
611 if ( !openDatabase( filename ) )
613 mErrorString = QStringLiteral(
"Unable to open database file specified" );
619 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='textformat'" );
622 statement = mCurrentDB.
prepare( query, rc );
623 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
626 "id INTEGER PRIMARY KEY,"\
629 "favorite INTEGER);"\
630 "CREATE TABLE tftagmap("\
631 "tag_id INTEGER NOT NULL,"\
632 "textformat_id INTEGER);" );
633 runEmptyQuery( query );
636 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='labelsettings'" );
637 statement = mCurrentDB.
prepare( query, rc );
638 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
641 "id INTEGER PRIMARY KEY,"\
644 "favorite INTEGER);"\
645 "CREATE TABLE lstagmap("\
646 "tag_id INTEGER NOT NULL,"\
647 "labelsettings_id INTEGER);" );
648 runEmptyQuery( query );
651 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='legendpatchshapes'" );
652 statement = mCurrentDB.
prepare( query, rc );
653 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
656 "id INTEGER PRIMARY KEY,"\
659 "favorite INTEGER);"\
660 "CREATE TABLE lpstagmap("\
661 "tag_id INTEGER NOT NULL,"\
662 "legendpatchshape_id INTEGER);" );
663 runEmptyQuery( query );
667 statement = mCurrentDB.
prepare( query, rc );
668 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
671 "id INTEGER PRIMARY KEY,"\
674 "favorite INTEGER);"\
675 "CREATE TABLE symbol3dtagmap("\
676 "tag_id INTEGER NOT NULL,"\
677 "symbol3d_id INTEGER);" );
678 runEmptyQuery( query );
683 "UPDATE colorramp SET favorite=0 WHERE favorite IS NULL;"
684 "UPDATE textformat SET favorite=0 WHERE favorite IS NULL;"
685 "UPDATE labelsettings SET favorite=0 WHERE favorite IS NULL;"
686 "UPDATE legendpatchshapes SET favorite=0 WHERE favorite IS NULL;"
687 "UPDATE symbol3d SET favorite=0 WHERE favorite IS NULL;"
689 runEmptyQuery( query );
695 statement = mCurrentDB.
prepare( query, rc );
697 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
703 if ( !doc.setContent( xmlstring ) )
709 QDomElement symElement = doc.documentElement();
712 mSymbols.insert( symbolName,
symbol );
719 statement = mCurrentDB.
prepare( query, rc );
720 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
726 if ( !doc.setContent( xmlstring ) )
731 QDomElement rampElement = doc.documentElement();
734 mColorRamps.insert( rampName, ramp );
741 statement = mCurrentDB.
prepare( query, rc );
742 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
748 if ( !doc.setContent( xmlstring ) )
750 QgsDebugMsg(
"Cannot open text format " + formatName );
753 QDomElement formatElement = doc.documentElement();
756 mTextFormats.insert( formatName, format );
763 statement = mCurrentDB.
prepare( query, rc );
764 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
770 if ( !doc.setContent( xmlstring ) )
772 QgsDebugMsg(
"Cannot open label settings " + settingsName );
775 QDomElement settingsElement = doc.documentElement();
778 mLabelSettings.insert( settingsName, settings );
785 statement = mCurrentDB.
prepare( query, rc );
786 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
792 if ( !doc.setContent( xmlstring ) )
794 QgsDebugMsg(
"Cannot open legend patch shape " + settingsName );
797 QDomElement settingsElement = doc.documentElement();
800 mLegendPatchShapes.insert( settingsName, shape );
807 statement = mCurrentDB.
prepare( query, rc );
811 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
817 if ( !doc.setContent( xmlstring ) )
819 QgsDebugMsg(
"Cannot open 3d symbol " + settingsName );
822 QDomElement settingsElement = doc.documentElement();
824 if ( !registry3dPopulated )
826 mDeferred3DsymbolElements.insert( settingsName, settingsElement );
830 const QString symbolType = settingsElement.attribute( QStringLiteral(
"type" ) );
835 m3dSymbols.insert( settingsName,
symbol.release() );
839 QgsDebugMsg(
"Cannot open 3d symbol " + settingsName );
846 mFileName = filename;
847 createStyleMetadataTableIfNeeded();
853 mErrorString.clear();
855 if ( !filename.isEmpty() )
856 mFileName = filename;
863 mFileName = filename;
868 if ( mSymbols.contains( newName ) )
870 QgsDebugMsg( QStringLiteral(
"Symbol of new name already exists" ) );
878 mSymbols.insert( newName,
symbol );
882 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to tag." ) );
889 QgsDebugMsg( QStringLiteral(
"No such symbol for tagging in database: " ) + oldName );
908 if ( mColorRamps.contains( newName ) )
910 QgsDebugMsg( QStringLiteral(
"Color ramp of new name already exists." ) );
918 mColorRamps.insert( newName, ramp );
924 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM colorramp WHERE name='%q'", oldName.toUtf8().constData() );
926 statement = mCurrentDB.
prepare( query, nErr );
927 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
929 rampid = sqlite3_column_int( statement.get(), 0 );
944 QDomDocument doc( QStringLiteral(
"dummy" ) );
947 if ( formatElem.isNull() )
949 QgsDebugMsg( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
954 QTextStream stream( &xmlArray );
955#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
956 stream.setCodec(
"UTF-8" );
958 formatElem.save( stream, 4 );
959 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO textformat VALUES (NULL, '%q', '%q', %d);",
960 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
961 if ( !runEmptyQuery( query ) )
963 QgsDebugMsg( QStringLiteral(
"Couldn't insert text format into the database!" ) );
984 if ( mTextFormats.contains( newName ) )
986 QgsDebugMsg( QStringLiteral(
"Text format of new name already exists." ) );
990 if ( !mTextFormats.contains( oldName ) )
994 mTextFormats.insert( newName, format );
1000 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM textformat WHERE name='%q'", oldName.toUtf8().constData() );
1002 statement = mCurrentDB.
prepare( query, nErr );
1003 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1005 textFormatId = sqlite3_column_int( statement.get(), 0 );
1020 QDomDocument doc( QStringLiteral(
"dummy" ) );
1023 if ( settingsElem.isNull() )
1025 QgsDebugMsg( QStringLiteral(
"Couldn't convert label settings to valid XML!" ) );
1029 QByteArray xmlArray;
1030 QTextStream stream( &xmlArray );
1031#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1032 stream.setCodec(
"UTF-8" );
1034 settingsElem.save( stream, 4 );
1035 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO labelsettings VALUES (NULL, '%q', '%q', %d);",
1036 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1037 if ( !runEmptyQuery( query ) )
1039 QgsDebugMsg( QStringLiteral(
"Couldn't insert label settings into the database!" ) );
1060 if ( mLabelSettings.contains( newName ) )
1062 QgsDebugMsg( QStringLiteral(
"Label settings of new name already exists." ) );
1066 if ( !mLabelSettings.contains( oldName ) )
1070 mLabelSettings.insert( newName, settings );
1076 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM labelsettings WHERE name='%q'", oldName.toUtf8().constData() );
1078 statement = mCurrentDB.
prepare( query, nErr );
1079 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1096 QDomDocument doc( QStringLiteral(
"dummy" ) );
1097 QDomElement shapeElem = doc.createElement( QStringLiteral(
"shape" ) );
1100 QByteArray xmlArray;
1101 QTextStream stream( &xmlArray );
1102#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1103 stream.setCodec(
"UTF-8" );
1105 shapeElem.save( stream, 4 );
1106 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO legendpatchshapes VALUES (NULL, '%q', '%q', %d);",
1107 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1108 if ( !runEmptyQuery( query ) )
1110 QgsDebugMsg( QStringLiteral(
"Couldn't insert legend patch shape into the database!" ) );
1125 if ( mLegendPatchShapes.contains( newName ) )
1127 QgsDebugMsg( QStringLiteral(
"Legend patch shape of new name already exists." ) );
1131 if ( !mLegendPatchShapes.contains( oldName ) )
1135 mLegendPatchShapes.insert( newName, shape );
1141 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM legendpatchshapes WHERE name='%q'", oldName.toUtf8().constData() );
1143 statement = mCurrentDB.
prepare( query, nErr );
1144 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1162 if ( mDefaultPatchCache[
static_cast< int >( type ) ].contains( size ) )
1163 return mDefaultPatchCache[
static_cast< int >( type ) ].value( size );
1169 geom =
QgsGeometry( std::make_unique< QgsPoint >(
static_cast< int >( size.width() ) / 2,
static_cast< int >( size.height() ) / 2 ) );
1176 double y =
static_cast< int >( size.height() ) / 2 + 0.5;
1177 geom =
QgsGeometry( std::make_unique< QgsLineString >( ( QVector< double >() << 0 << size.width() ),
1178 ( QVector< double >() << y << y ) ) );
1184 geom =
QgsGeometry( std::make_unique< QgsPolygon >(
1185 new QgsLineString( QVector< double >() << 0 <<
static_cast< int >( size.width() ) <<
static_cast< int >( size.width() ) << 0 << 0,
1186 QVector< double >() <<
static_cast< int >( size.height() ) <<
static_cast< int >( size.height() ) << 0 << 0 <<
static_cast< int >( size.height() ) ) ) );
1195 mDefaultPatchCache[
static_cast< int >( type ) ][size ] = res;
1202 return QList<QList<QPolygonF> >();
1204 if ( mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ].contains( size ) )
1205 return mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ].value( size );
1208 mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ][size ] = res;
1214 return textFormat( QStringLiteral(
"Default" ) );
1234 QDomDocument doc( QStringLiteral(
"dummy" ) );
1235 QDomElement elem = doc.createElement( QStringLiteral(
"symbol" ) );
1236 elem.setAttribute( QStringLiteral(
"type" ),
symbol->
type() );
1239 QByteArray xmlArray;
1240 QTextStream stream( &xmlArray );
1241#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1242 stream.setCodec(
"UTF-8" );
1244 elem.save( stream, 4 );
1245 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO symbol3d VALUES (NULL, '%q', '%q', %d);",
1246 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1247 if ( !runEmptyQuery( query ) )
1249 QgsDebugMsg( QStringLiteral(
"Couldn't insert 3d symbol into the database!" ) );
1264 if ( m3dSymbols.contains( newName ) )
1266 QgsDebugMsg( QStringLiteral(
"3d symbol of new name already exists." ) );
1270 if ( !m3dSymbols.contains( oldName ) )
1274 m3dSymbols.insert( newName,
symbol );
1280 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM symbol3d WHERE name='%q'", oldName.toUtf8().constData() );
1282 statement = mCurrentDB.
prepare( query, nErr );
1283 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1298 return m3dSymbols.keys();
1305 QgsDebugMsg( QStringLiteral(
"Cannot Open database for getting favorite symbols" ) );
1306 return QStringList();
1314 QgsDebugMsg( QStringLiteral(
"No such style entity" ) );
1315 return QStringList();
1318 query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT name FROM %1 WHERE favorite=1" ).arg( entityTableName( type ) ).toLocal8Bit().data() );
1324 statement = mCurrentDB.
prepare( query, nErr );
1326 QStringList symbols;
1327 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1339 QgsDebugMsg( QStringLiteral(
"Cannot open database to get symbols of tagid %1" ).arg( tagid ) );
1340 return QStringList();
1348 QgsDebugMsg( QStringLiteral(
"Unknown Entity" ) );
1349 return QStringList();
1352 subquery =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT %1 FROM %2 WHERE tag_id=%d" ).arg( tagmapEntityIdFieldName( type ),
1353 tagmapTableName( type ) ).toLocal8Bit().data(), tagid );
1359 statement = mCurrentDB.
prepare( subquery, nErr );
1362 QStringList symbols;
1363 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1365 int id = sqlite3_column_int( statement.get(), 0 );
1367 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT name FROM %1 WHERE id=%d" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
id );
1371 statement2 = mCurrentDB.
prepare( query, rc );
1372 while ( rc == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1387 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO tag VALUES (NULL, '%q')", tagname.toUtf8().constData() );
1389 statement = mCurrentDB.
prepare( query, nErr );
1390 if ( nErr == SQLITE_OK )
1391 ( void )sqlite3_step( statement.get() );
1394 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1398 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
1404 return QStringList();
1410 statement = mCurrentDB.
prepare( query, nError );
1412 QStringList tagList;
1413 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1423 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET name='%q' WHERE id=%d" ).arg( entityTableName( type ) ).toLocal8Bit().data(), newName.toUtf8().constData(),
id );
1425 const bool result = runEmptyQuery( query );
1428 mErrorString = QStringLiteral(
"Could not rename!" );
1432 mCachedTags.clear();
1433 mCachedFavorites.clear();
1458 bool groupRemoved =
false;
1463 query =
qgs_sqlite3_mprintf(
"DELETE FROM tag WHERE id=%d; DELETE FROM tagmap WHERE tag_id=%d",
id,
id );
1464 groupRemoved =
true;
1468 groupRemoved =
true;
1472 query =
qgs_sqlite3_mprintf( QStringLiteral(
"DELETE FROM %1 WHERE id=%d; DELETE FROM %2 WHERE %3=%d" ).arg(
1473 entityTableName( type ),
1474 tagmapTableName( type ),
1475 tagmapEntityIdFieldName( type )
1476 ).toLocal8Bit().data(),
id,
id );
1480 bool result =
false;
1481 if ( !runEmptyQuery( query ) )
1483 QgsDebugMsg( QStringLiteral(
"Could not delete entity!" ) );
1487 mCachedTags.clear();
1488 mCachedFavorites.clear();
1493 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1512 std::unique_ptr< QgsSymbol >
symbol( mSymbols.take(
name ) );
1521 std::unique_ptr< QgsAbstract3DSymbol >
symbol( m3dSymbols.take(
name ) );
1530 std::unique_ptr< QgsColorRamp > ramp( mColorRamps.take(
name ) );
1538 if ( !mTextFormats.contains(
name ) )
1541 mTextFormats.remove(
name );
1547 if ( !mLabelSettings.contains(
name ) )
1550 mLabelSettings.remove(
name );
1556 if ( !mLegendPatchShapes.contains(
name ) )
1559 mLegendPatchShapes.remove(
name );
1566 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to modify." ) );
1573 QgsDebugMsg(
"No matching entity for deleting in database: " +
name );
1576 const bool result =
remove( type,
id );
1579 mCachedTags[ type ].remove(
name );
1580 mCachedFavorites[ type ].remove(
name );
1609bool QgsStyle::runEmptyQuery(
const QString &query )
1614 char *zErr =
nullptr;
1615 int nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1617 if ( nErr != SQLITE_OK )
1620 sqlite3_free( zErr );
1623 return nErr == SQLITE_OK;
1634 QgsDebugMsg( QStringLiteral(
"Wrong entity value. cannot apply group" ) );
1638 query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET favorite=1 WHERE name='%q'" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
1639 name.toUtf8().constData() );
1643 const bool res = runEmptyQuery( query );
1653 mCachedFavorites[ type ].insert(
name,
true );
1670 QgsDebugMsg( QStringLiteral(
"Wrong entity value. cannot apply group" ) );
1674 query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET favorite=0 WHERE name='%q'" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
name.toUtf8().constData() );
1678 const bool res = runEmptyQuery( query );
1681 mCachedFavorites[ type ].insert(
name,
false );
1692 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to search" ) );
1693 return QStringList();
1702 return QStringList();
1705 item = entityTableName( type );
1710 item.toUtf8().constData(), qword.toUtf8().constData() );
1713 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1715 QSet< QString > symbols;
1716 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1722 query =
qgs_sqlite3_mprintf(
"SELECT id FROM tag WHERE name LIKE '%%%q%%'", qword.toUtf8().constData() );
1723 statement = mCurrentDB.
prepare( query, nErr );
1726 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1731 QString dummy = tagids.join( QLatin1String(
", " ) );
1732 query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT %1 FROM %2 WHERE tag_id IN (%q)" ).arg( tagmapEntityIdFieldName( type ),
1733 tagmapTableName( type ) ).toLocal8Bit().data(), dummy.toUtf8().constData() );
1735 statement = mCurrentDB.
prepare( query, nErr );
1737 QStringList symbolids;
1738 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1743 dummy = symbolids.join( QLatin1String(
", " ) );
1745 item.toUtf8().constData(), dummy.toUtf8().constData() );
1746 statement = mCurrentDB.
prepare( query, nErr );
1747 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1752 return QStringList( symbols.constBegin(), symbols.constEnd() );
1759 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to tag." ) );
1777 QgsDebugMsg( QStringLiteral(
"No such symbol for tagging in database: " ) +
symbol );
1782 const auto constTags =
tags;
1783 for (
const QString &t : constTags )
1786 if ( !
tag.isEmpty() )
1798 QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"INSERT INTO %1 VALUES (%d,%d)" ).arg( tagmapTableName( type ) ).toLocal8Bit().data(), tagid, symbolid );
1800 char *zErr =
nullptr;
1802 nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1806 sqlite3_free( zErr );
1812 clearCachedTags( type,
symbol );
1822 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for detagging." ) );
1837 if ( symbolid == 0 )
1842 const auto constTags =
tags;
1843 for (
const QString &
tag : constTags )
1848 statement2 = mCurrentDB.
prepare( query, nErr );
1851 if ( nErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1853 tagid = sqlite3_column_int( statement2.get(), 0 );
1859 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 );
1860 runEmptyQuery( query );
1864 clearCachedTags( type,
symbol );
1877 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for detagging." ) );
1892 if ( symbolid == 0 )
1898 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"DELETE FROM %1 WHERE %2=%d" ).arg( tagmapTableName( type ),
1899 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1900 runEmptyQuery( query );
1902 clearCachedTags( type,
symbol );
1917 return QStringList();
1920 if ( mCachedTags[ type ].contains(
symbol ) )
1921 return mCachedTags[ type ].value(
symbol );
1927 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
1928 return QStringList();
1933 return QStringList();
1936 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT tag_id FROM %1 WHERE %2=%d" ).arg( tagmapTableName( type ),
1937 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1940 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1942 QStringList tagList;
1943 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1945 QString subquery =
qgs_sqlite3_mprintf(
"SELECT name FROM tag WHERE id=%d", sqlite3_column_int( statement.get(), 0 ) );
1949 statement2 = mCurrentDB.
prepare( subquery, pErr );
1950 if ( pErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1957 mCachedTags[ type ].insert(
symbol, tagList );
1966 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
1977 if ( mCachedFavorites[ type ].contains(
name ) )
1978 return mCachedFavorites[ type ].value(
name );
1982 const QStringList names =
allNames( type );
1983 if ( !names.contains(
name ) )
1989 for (
const QString &n : names )
1991 const bool isFav = favorites.contains( n );
1995 mCachedFavorites[ type ].insert( n, isFav );
2004 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
2031 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT tag_id FROM %1 WHERE tag_id=%d AND %2=%d" ).arg( tagmapTableName( type ),
2032 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), tagid, symbolid );
2035 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2037 return ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW );
2049 statement = mCurrentDB.
prepare( query, nError );
2052 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2060int QgsStyle::getId(
const QString &table,
const QString &name )
2062 QString lowerName(
name.toLower() );
2063 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE LOWER(name)='%q'", table.toUtf8().constData(), lowerName.toUtf8().constData() );
2066 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2069 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2071 id = sqlite3_column_int( statement.get(), 0 );
2076 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE name='%q'", table.toUtf8().constData(),
name.toUtf8().constData() );
2079 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2080 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2082 id = sqlite3_column_int( statement.get(), 0 );
2089QString QgsStyle::getName(
const QString &table,
int id )
const
2091 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM %q WHERE id='%q'", table.toUtf8().constData(), QString::number(
id ).toUtf8().constData() );
2094 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2097 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2107 return getId( QStringLiteral(
"symbol" ),
name );
2112 return getId( entityTableName( type ),
name );
2117 return getId( QStringLiteral(
"colorramp" ),
name );
2122 return mTextFormats.value(
name );
2127 return mTextFormats.count();
2132 return mTextFormats.keys();
2137 return getId( QStringLiteral(
"textformat" ),
name );
2142 return mLabelSettings.value(
name );
2147 return mLegendPatchShapes.value(
name );
2152 return mLegendPatchShapes.count();
2157 if ( !mLegendPatchShapes.contains(
name ) )
2160 return mLegendPatchShapes.value(
name ).symbolType();
2165 return m3dSymbols.contains(
name ) ? m3dSymbols.value(
name )->clone() :
nullptr;
2170 return m3dSymbols.count();
2175 if ( !m3dSymbols.contains(
name ) )
2176 return QList<QgsWkbTypes::GeometryType>();
2178 return m3dSymbols.value(
name )->compatibleGeometryTypes();
2183 if ( !mLabelSettings.contains(
name ) )
2186 return mLabelSettings.value(
name ).layerType;
2191 return mLabelSettings.count();
2196 return mLabelSettings.keys();
2201 return getId( QStringLiteral(
"labelsettings" ),
name );
2206 return mLegendPatchShapes.keys();
2214 return mPatchMarkerSymbol.get();
2217 return mPatchLineSymbol.get();
2220 return mPatchFillSymbol.get();
2230 return getId( QStringLiteral(
"tag" ),
name );
2235 return getId( QStringLiteral(
"smartgroup" ),
name );
2266 return QStringList();
2272 conditions.values( QStringLiteral(
"!tag" ) ),
2273 conditions.values( QStringLiteral(
"name" ) ),
2274 conditions.values( QStringLiteral(
"!name" ) ) );
2277int QgsStyle::addSmartgroup(
const QString &name,
const QString &op,
const QStringList &matchTag,
const QStringList &noMatchTag,
const QStringList &matchName,
const QStringList &noMatchName )
2279 QDomDocument doc( QStringLiteral(
"dummy" ) );
2280 QDomElement smartEl = doc.createElement( QStringLiteral(
"smartgroup" ) );
2281 smartEl.setAttribute( QStringLiteral(
"name" ),
name );
2282 smartEl.setAttribute( QStringLiteral(
"operator" ), op );
2284 auto addCondition = [&doc, &smartEl](
const QString & constraint,
const QStringList & parameters )
2286 for (
const QString ¶m : parameters )
2288 QDomElement condEl = doc.createElement( QStringLiteral(
"condition" ) );
2289 condEl.setAttribute( QStringLiteral(
"constraint" ), constraint );
2290 condEl.setAttribute( QStringLiteral(
"param" ), param );
2291 smartEl.appendChild( condEl );
2294 addCondition( QStringLiteral(
"tag" ), matchTag );
2295 addCondition( QStringLiteral(
"!tag" ), noMatchTag );
2296 addCondition( QStringLiteral(
"name" ), matchName );
2297 addCondition( QStringLiteral(
"!name" ), noMatchName );
2299 QByteArray xmlArray;
2300 QTextStream stream( &xmlArray );
2301#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2302 stream.setCodec(
"UTF-8" );
2304 smartEl.save( stream, 4 );
2306 name.toUtf8().constData(), xmlArray.constData() );
2308 if ( runEmptyQuery( query ) )
2311 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
2314 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
2318 QgsDebugMsg( QStringLiteral(
"Couldn't add the smart group into the database!" ) );
2327 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2336 statement = mCurrentDB.
prepare( query, nError );
2339 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2342 groupNames.insert( sqlite3_column_int( statement.get(),
SmartgroupId ), group );
2352 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2353 return QStringList();
2361 statement = mCurrentDB.
prepare( query, nError );
2364 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2374 QStringList symbols;
2379 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2380 if ( !( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW ) )
2382 return QStringList();
2388 if ( !doc.setContent( xmlstr ) )
2390 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2392 QDomElement smartEl = doc.documentElement();
2393 QString op = smartEl.attribute( QStringLiteral(
"operator" ) );
2394 QDomNodeList conditionNodes = smartEl.childNodes();
2396 bool firstSet =
true;
2397 for (
int i = 0; i < conditionNodes.count(); i++ )
2399 QDomElement condEl = conditionNodes.at( i ).toElement();
2400 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2401 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2403 QStringList resultNames;
2405 if ( constraint == QLatin1String(
"tag" ) )
2409 else if ( constraint == QLatin1String(
"name" ) )
2411 resultNames =
allNames( type ).filter( param, Qt::CaseInsensitive );
2413 else if ( constraint == QLatin1String(
"!tag" ) )
2417 for (
const QString &
name : unwanted )
2419 resultNames.removeAll(
name );
2422 else if ( constraint == QLatin1String(
"!name" ) )
2424 const QStringList all =
allNames( type );
2425 for (
const QString &
str : all )
2427 if ( !
str.contains( param, Qt::CaseInsensitive ) )
2435 symbols = resultNames;
2440 if ( op == QLatin1String(
"OR" ) )
2442 symbols << resultNames;
2444 else if ( op == QLatin1String(
"AND" ) )
2446 QStringList dummy = symbols;
2448 for (
const QString &result : std::as_const( resultNames ) )
2450 if ( dummy.contains( result ) )
2459 const QSet< QString > uniqueSet( symbols.constBegin(), symbols.constEnd() );
2460 QStringList unique( uniqueSet.begin(), uniqueSet.end() );
2461 std::sort( unique.begin(), unique.end() );
2469 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2479 statement = mCurrentDB.
prepare( query, nError );
2480 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2484 if ( !doc.setContent( xmlstr ) )
2486 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2489 QDomElement smartEl = doc.documentElement();
2490 QDomNodeList conditionNodes = smartEl.childNodes();
2492 for (
int i = 0; i < conditionNodes.count(); i++ )
2494 QDomElement condEl = conditionNodes.at( i ).toElement();
2495 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2496 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2498 condition.insert( constraint, param );
2509 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2519 statement = mCurrentDB.
prepare( query, nError );
2520 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2524 if ( !doc.setContent( xmlstr ) )
2526 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2528 QDomElement smartEl = doc.documentElement();
2529 op = smartEl.attribute( QStringLiteral(
"operator" ) );
2537 if ( filename.isEmpty() )
2539 QgsDebugMsg( QStringLiteral(
"Invalid filename for style export." ) );
2543 QDomDocument doc( QStringLiteral(
"qgis_style" ) );
2544 QDomElement root = doc.createElement( QStringLiteral(
"qgis_style" ) );
2546 doc.appendChild( root );
2556 QDomNodeList symbolsList = symbolsElem.elementsByTagName( QStringLiteral(
"symbol" ) );
2557 int nbSymbols = symbolsList.count();
2558 for (
int i = 0; i < nbSymbols; ++i )
2560 QDomElement
symbol = symbolsList.at( i ).toElement();
2561 QString
name =
symbol.attribute( QStringLiteral(
"name" ) );
2563 if (
tags.count() > 0 )
2565 symbol.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2567 if ( favoriteSymbols.contains(
name ) )
2569 symbol.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2574 QDomElement rampsElem = doc.createElement( QStringLiteral(
"colorramps" ) );
2575 for ( QMap<QString, QgsColorRamp *>::const_iterator itr = mColorRamps.constBegin(); itr != mColorRamps.constEnd(); ++itr )
2579 if (
tags.count() > 0 )
2581 rampEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2583 if ( favoriteColorramps.contains( itr.key() ) )
2585 rampEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2587 rampsElem.appendChild( rampEl );
2591 QDomElement textFormatsElem = doc.createElement( QStringLiteral(
"textformats" ) );
2592 for (
auto it = mTextFormats.constBegin(); it != mTextFormats.constEnd(); ++it )
2594 QDomElement textFormatEl = doc.createElement( QStringLiteral(
"textformat" ) );
2595 textFormatEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2597 textFormatEl.appendChild( textStyleEl );
2599 if (
tags.count() > 0 )
2601 textFormatEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2603 if ( favoriteTextFormats.contains( it.key() ) )
2605 textFormatEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2607 textFormatsElem.appendChild( textFormatEl );
2611 QDomElement labelSettingsElem = doc.createElement( QStringLiteral(
"labelsettings" ) );
2612 for (
auto it = mLabelSettings.constBegin(); it != mLabelSettings.constEnd(); ++it )
2614 QDomElement labelSettingsEl = doc.createElement( QStringLiteral(
"labelsetting" ) );
2615 labelSettingsEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2617 labelSettingsEl.appendChild( defEl );
2619 if (
tags.count() > 0 )
2621 labelSettingsEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2623 if ( favoriteTextFormats.contains( it.key() ) )
2625 labelSettingsEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2627 labelSettingsElem.appendChild( labelSettingsEl );
2631 QDomElement legendPatchShapesElem = doc.createElement( QStringLiteral(
"legendpatchshapes" ) );
2632 for (
auto it = mLegendPatchShapes.constBegin(); it != mLegendPatchShapes.constEnd(); ++it )
2634 QDomElement legendPatchShapeEl = doc.createElement( QStringLiteral(
"legendpatchshape" ) );
2635 legendPatchShapeEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2636 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2638 legendPatchShapeEl.appendChild( defEl );
2640 if (
tags.count() > 0 )
2642 legendPatchShapeEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2644 if ( favoriteLegendShapes.contains( it.key() ) )
2646 legendPatchShapeEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2648 legendPatchShapesElem.appendChild( legendPatchShapeEl );
2652 QDomElement symbols3DElem = doc.createElement( QStringLiteral(
"symbols3d" ) );
2653 for (
auto it = m3dSymbols.constBegin(); it != m3dSymbols.constEnd(); ++it )
2655 QDomElement symbolEl = doc.createElement( QStringLiteral(
"symbol3d" ) );
2656 symbolEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2657 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2658 defEl.setAttribute( QStringLiteral(
"type" ), it.value()->type() );
2660 symbolEl.appendChild( defEl );
2662 if (
tags.count() > 0 )
2664 symbolEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2666 if ( favorite3DSymbols.contains( it.key() ) )
2668 symbolEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2670 symbols3DElem.appendChild( symbolEl );
2673 root.appendChild( symbolsElem );
2674 root.appendChild( rampsElem );
2675 root.appendChild( textFormatsElem );
2676 root.appendChild( labelSettingsElem );
2677 root.appendChild( legendPatchShapesElem );
2678 root.appendChild( symbols3DElem );
2681 QFile f( filename );
2682 if ( !f.open( QFile::WriteOnly | QIODevice::Truncate ) )
2684 mErrorString =
"Couldn't open file for writing: " + filename;
2688 QTextStream ts( &f );
2689#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2690 ts.setCodec(
"UTF-8" );
2705 mErrorString = QString();
2706 QDomDocument doc( QStringLiteral(
"style" ) );
2707 QFile f( filename );
2708 if ( !f.open( QFile::ReadOnly ) )
2710 mErrorString = QStringLiteral(
"Unable to open the specified file" );
2711 QgsDebugMsg( QStringLiteral(
"Error opening the style XML file." ) );
2715 if ( !doc.setContent( &f ) )
2717 mErrorString = QStringLiteral(
"Unable to understand the style file: %1" ).arg( filename );
2718 QgsDebugMsg( QStringLiteral(
"XML Parsing error" ) );
2724 QDomElement docEl = doc.documentElement();
2725 if ( docEl.tagName() != QLatin1String(
"qgis_style" ) )
2727 mErrorString =
"Incorrect root tag in style: " + docEl.tagName();
2731 const QString version = docEl.attribute( QStringLiteral(
"version" ) );
2732 if ( version != QLatin1String(
STYLE_CURRENT_VERSION ) && version != QLatin1String(
"0" ) && version != QLatin1String(
"1" ) )
2734 mErrorString =
"Unknown style file version: " + version;
2740 QDomElement symbolsElement = docEl.firstChildElement( QStringLiteral(
"symbols" ) );
2741 QDomElement e = symbolsElement.firstChildElement();
2745 runEmptyQuery( query );
2750 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2752 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2753 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2759 if ( e.tagName() == QLatin1String(
"symbol" ) )
2761 QString
name = e.attribute( QStringLiteral(
"name" ) );
2763 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2765 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2767 bool favorite =
false;
2768 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2795 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
2802 QDomElement rampsElement = docEl.firstChildElement( QStringLiteral(
"colorramps" ) );
2803 e = rampsElement.firstChildElement();
2804 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2806 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2807 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2813 if ( e.tagName() == QLatin1String(
"colorramp" ) )
2815 QString
name = e.attribute( QStringLiteral(
"name" ) );
2817 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2819 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2821 bool favorite =
false;
2822 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2846 if ( qobject_cast< QGuiApplication * >( QCoreApplication::instance() ) )
2850 const QDomElement textFormatElement = docEl.firstChildElement( QStringLiteral(
"textformats" ) );
2851 e = textFormatElement.firstChildElement();
2852 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2854 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2855 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2861 if ( e.tagName() == QLatin1String(
"textformat" ) )
2863 QString
name = e.attribute( QStringLiteral(
"name" ) );
2865 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2867 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2869 bool favorite =
false;
2870 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2876 const QDomElement styleElem = e.firstChildElement();
2894 const QDomElement labelSettingsElement = docEl.firstChildElement( QStringLiteral(
"labelsettings" ) );
2895 e = labelSettingsElement.firstChildElement();
2896 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2898 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2899 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2905 if ( e.tagName() == QLatin1String(
"labelsetting" ) )
2907 QString
name = e.attribute( QStringLiteral(
"name" ) );
2909 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2911 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2913 bool favorite =
false;
2914 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2920 const QDomElement styleElem = e.firstChildElement();
2939 const QDomElement legendPatchShapesElement = docEl.firstChildElement( QStringLiteral(
"legendpatchshapes" ) );
2940 e = legendPatchShapesElement.firstChildElement();
2941 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2943 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2944 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2950 if ( e.tagName() == QLatin1String(
"legendpatchshape" ) )
2952 QString
name = e.attribute( QStringLiteral(
"name" ) );
2954 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2956 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2958 bool favorite =
false;
2959 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2965 const QDomElement shapeElem = e.firstChildElement();
2983 const QDomElement symbols3DElement = docEl.firstChildElement( QStringLiteral(
"symbols3d" ) );
2984 e = symbols3DElement.firstChildElement();
2985 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2987 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2988 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2994 if ( e.tagName() == QLatin1String(
"symbol3d" ) )
2996 QString
name = e.attribute( QStringLiteral(
"name" ) );
2998 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
3000 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
3002 bool favorite =
false;
3003 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
3008 const QDomElement symbolElem = e.firstChildElement();
3009 const QString type = symbolElem.attribute( QStringLiteral(
"type" ) );
3030 runEmptyQuery( query );
3037 QFileInfo fileInfo( path );
3039 if ( fileInfo.suffix().compare( QLatin1String(
"xml" ), Qt::CaseInsensitive ) != 0 )
3043 if ( !QFile::exists( path ) )
3046 QFile inputFile( path );
3047 if ( !inputFile.open( QIODevice::ReadOnly ) )
3050 QTextStream stream( &inputFile );
3051 const QString line = stream.readLine();
3052 return line == QLatin1String(
"<!DOCTYPE qgis_style>" );
3067 mReadOnly = readOnly;
3070bool QgsStyle::updateSymbol( StyleEntity type,
const QString &name )
3072 QDomDocument doc( QStringLiteral(
"dummy" ) );
3074 QByteArray xmlArray;
3075 QTextStream stream( &xmlArray );
3076#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
3077 stream.setCodec(
"UTF-8" );
3089 QgsDebugMsg( QStringLiteral(
"Update request received for unavailable symbol" ) );
3094 if ( symEl.isNull() )
3096 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
3099 symEl.save( stream, 4 );
3101 xmlArray.constData(),
name.toUtf8().constData() );
3110 QgsDebugMsg( QStringLiteral(
"Update request received for unavailable symbol" ) );
3114 symEl = doc.createElement( QStringLiteral(
"symbol" ) );
3115 symEl.setAttribute( QStringLiteral(
"type" ), m3dSymbols.value(
name )->type() );
3117 if ( symEl.isNull() )
3119 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
3122 symEl.save( stream, 4 );
3124 xmlArray.constData(),
name.toUtf8().constData() );
3132 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable color ramp." ) );
3138 if ( symEl.isNull() )
3140 QgsDebugMsg( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
3143 symEl.save( stream, 4 );
3145 xmlArray.constData(),
name.toUtf8().constData() );
3153 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable text format." ) );
3159 if ( symEl.isNull() )
3161 QgsDebugMsg( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
3164 symEl.save( stream, 4 );
3166 xmlArray.constData(),
name.toUtf8().constData() );
3174 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable label settings." ) );
3180 if ( symEl.isNull() )
3182 QgsDebugMsg( QStringLiteral(
"Couldn't convert label settings to valid XML!" ) );
3185 symEl.save( stream, 4 );
3187 xmlArray.constData(),
name.toUtf8().constData() );
3195 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable legend patch shape." ) );
3200 symEl = doc.createElement( QStringLiteral(
"shape" ) );
3202 symEl.save( stream, 4 );
3204 xmlArray.constData(),
name.toUtf8().constData() );
3211 QgsDebugMsg( QStringLiteral(
"Updating the unsupported StyleEntity" ) );
3217 if ( !runEmptyQuery( query ) )
3219 QgsDebugMsg( QStringLiteral(
"Couldn't update symbol into the database!" ) );
3255 mCachedTags[ type ].remove(
name );
3258bool QgsStyle::createStyleMetadataTableIfNeeded()
3261 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='stylemetadata'" );
3264 statement = mCurrentDB.
prepare( query, rc );
3266 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
3270 "id INTEGER PRIMARY KEY,"\
3273 runEmptyQuery( query );
3275 runEmptyQuery( query );
3284void QgsStyle::upgradeIfRequired()
3288 if ( !createStyleMetadataTableIfNeeded() )
3290 const QString query =
qgs_sqlite3_mprintf(
"SELECT value FROM stylemetadata WHERE key='version'" );
3293 if ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
3305 runEmptyQuery( query );
3315 return QStringLiteral(
"symbol" );
3318 return QStringLiteral(
"colorramp" );
3321 return QStringLiteral(
"textformat" );
3324 return QStringLiteral(
"labelsettings" );
3327 return QStringLiteral(
"legendpatchshapes" );
3330 return QStringLiteral(
"symbol3d" );
3333 return QStringLiteral(
"tag" );
3336 return QStringLiteral(
"smartgroup" );
3346 return QStringLiteral(
"tagmap" );
3349 return QStringLiteral(
"ctagmap" );
3352 return QStringLiteral(
"tftagmap" );
3355 return QStringLiteral(
"lstagmap" );
3358 return QStringLiteral(
"lpstagmap" );
3361 return QStringLiteral(
"symbol3dtagmap" );
3375 return QStringLiteral(
"symbol_id" );
3378 return QStringLiteral(
"colorramp_id" );
3381 return QStringLiteral(
"textformat_id" );
3384 return QStringLiteral(
"labelsettings_id" );
3387 return QStringLiteral(
"legendpatchshape_id" );
3390 return QStringLiteral(
"symbol3d_id" );
@ ScaleArea
Calculate scale by the area.
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.
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.
QList< QgsWkbTypes::GeometryType > symbol3DCompatibleGeometryTypes(const QString &name) const
Returns the list of the vector layer geometry types which are compatible with the 3D symbol with the ...
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 (since QGIS 3.14)
@ ColorrampEntity
Color ramps.
@ LegendPatchShapeEntity
Legend patch shape (since QGIS 3.14)
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.
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()
static QgsStyle * defaultStyle()
Returns default application-wide style.
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.
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.
QgsWkbTypes::GeometryType labelSettingsLayerType(const QString &name) const
Returns the layer geometry type corresponding to the label settings with the specified name,...
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 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.
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 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.
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
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.
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
@ TextFormatName
Text format name.
@ TextFormatXML
Text format definition (as XML)
@ SymbolXML
Symbol definition (as XML)
@ SmartgroupName
Smart group name.
@ SmartgroupId
Smart group ID.
QMap< int, QString > QgsSymbolGroupMap
@ LabelSettingsName
Label settings name.
@ LabelSettingsXML
Label settings definition (as XML)
@ ColorrampName
Color ramp name.
@ ColorrampXML
Color ramp definition (as XML)
QList< QgsSymbolLayer * > QgsSymbolLayerList