40 #include <QDomDocument>
41 #include <QDomElement>
43 #include <QDomNodeList>
45 #include <QTextStream>
52 #define STYLE_CURRENT_VERSION "2"
77 QgsStyle *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();
483 void 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();
504 bool 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 );
1609 bool 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 qgis::setToList( symbols );
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 )
2060 int 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 );
2089 QString 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" ) ) );
2277 int 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 QStringList unique = qgis::setToList( qgis::listToSet( symbols ) );
2460 std::sort( unique.begin(), unique.end() );
2468 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2478 statement = mCurrentDB.
prepare( query, nError );
2479 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2483 if ( !doc.setContent( xmlstr ) )
2485 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2488 QDomElement smartEl = doc.documentElement();
2489 QDomNodeList conditionNodes = smartEl.childNodes();
2491 for (
int i = 0; i < conditionNodes.count(); i++ )
2493 QDomElement condEl = conditionNodes.at( i ).toElement();
2494 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2495 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2497 condition.insert( constraint, param );
2508 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2518 statement = mCurrentDB.
prepare( query, nError );
2519 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2523 if ( !doc.setContent( xmlstr ) )
2525 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2527 QDomElement smartEl = doc.documentElement();
2528 op = smartEl.attribute( QStringLiteral(
"operator" ) );
2536 if ( filename.isEmpty() )
2538 QgsDebugMsg( QStringLiteral(
"Invalid filename for style export." ) );
2542 QDomDocument doc( QStringLiteral(
"qgis_style" ) );
2543 QDomElement root = doc.createElement( QStringLiteral(
"qgis_style" ) );
2545 doc.appendChild( root );
2555 QDomNodeList symbolsList = symbolsElem.elementsByTagName( QStringLiteral(
"symbol" ) );
2556 int nbSymbols = symbolsList.count();
2557 for (
int i = 0; i < nbSymbols; ++i )
2559 QDomElement
symbol = symbolsList.at( i ).toElement();
2560 QString
name =
symbol.attribute( QStringLiteral(
"name" ) );
2562 if (
tags.count() > 0 )
2564 symbol.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2566 if ( favoriteSymbols.contains(
name ) )
2568 symbol.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2573 QDomElement rampsElem = doc.createElement( QStringLiteral(
"colorramps" ) );
2574 for ( QMap<QString, QgsColorRamp *>::const_iterator itr = mColorRamps.constBegin(); itr != mColorRamps.constEnd(); ++itr )
2578 if (
tags.count() > 0 )
2580 rampEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2582 if ( favoriteColorramps.contains( itr.key() ) )
2584 rampEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2586 rampsElem.appendChild( rampEl );
2590 QDomElement textFormatsElem = doc.createElement( QStringLiteral(
"textformats" ) );
2591 for (
auto it = mTextFormats.constBegin(); it != mTextFormats.constEnd(); ++it )
2593 QDomElement textFormatEl = doc.createElement( QStringLiteral(
"textformat" ) );
2594 textFormatEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2596 textFormatEl.appendChild( textStyleEl );
2598 if (
tags.count() > 0 )
2600 textFormatEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2602 if ( favoriteTextFormats.contains( it.key() ) )
2604 textFormatEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2606 textFormatsElem.appendChild( textFormatEl );
2610 QDomElement labelSettingsElem = doc.createElement( QStringLiteral(
"labelsettings" ) );
2611 for (
auto it = mLabelSettings.constBegin(); it != mLabelSettings.constEnd(); ++it )
2613 QDomElement labelSettingsEl = doc.createElement( QStringLiteral(
"labelsetting" ) );
2614 labelSettingsEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2616 labelSettingsEl.appendChild( defEl );
2618 if (
tags.count() > 0 )
2620 labelSettingsEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2622 if ( favoriteTextFormats.contains( it.key() ) )
2624 labelSettingsEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2626 labelSettingsElem.appendChild( labelSettingsEl );
2630 QDomElement legendPatchShapesElem = doc.createElement( QStringLiteral(
"legendpatchshapes" ) );
2631 for (
auto it = mLegendPatchShapes.constBegin(); it != mLegendPatchShapes.constEnd(); ++it )
2633 QDomElement legendPatchShapeEl = doc.createElement( QStringLiteral(
"legendpatchshape" ) );
2634 legendPatchShapeEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2635 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2637 legendPatchShapeEl.appendChild( defEl );
2639 if (
tags.count() > 0 )
2641 legendPatchShapeEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2643 if ( favoriteLegendShapes.contains( it.key() ) )
2645 legendPatchShapeEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2647 legendPatchShapesElem.appendChild( legendPatchShapeEl );
2651 QDomElement symbols3DElem = doc.createElement( QStringLiteral(
"symbols3d" ) );
2652 for (
auto it = m3dSymbols.constBegin(); it != m3dSymbols.constEnd(); ++it )
2654 QDomElement symbolEl = doc.createElement( QStringLiteral(
"symbol3d" ) );
2655 symbolEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2656 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2657 defEl.setAttribute( QStringLiteral(
"type" ), it.value()->type() );
2659 symbolEl.appendChild( defEl );
2661 if (
tags.count() > 0 )
2663 symbolEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2665 if ( favorite3DSymbols.contains( it.key() ) )
2667 symbolEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2669 symbols3DElem.appendChild( symbolEl );
2672 root.appendChild( symbolsElem );
2673 root.appendChild( rampsElem );
2674 root.appendChild( textFormatsElem );
2675 root.appendChild( labelSettingsElem );
2676 root.appendChild( legendPatchShapesElem );
2677 root.appendChild( symbols3DElem );
2680 QFile f( filename );
2681 if ( !f.open( QFile::WriteOnly | QIODevice::Truncate ) )
2683 mErrorString =
"Couldn't open file for writing: " + filename;
2687 QTextStream ts( &f );
2688 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2689 ts.setCodec(
"UTF-8" );
2704 mErrorString = QString();
2705 QDomDocument doc( QStringLiteral(
"style" ) );
2706 QFile f( filename );
2707 if ( !f.open( QFile::ReadOnly ) )
2709 mErrorString = QStringLiteral(
"Unable to open the specified file" );
2710 QgsDebugMsg( QStringLiteral(
"Error opening the style XML file." ) );
2714 if ( !doc.setContent( &f ) )
2716 mErrorString = QStringLiteral(
"Unable to understand the style file: %1" ).arg( filename );
2717 QgsDebugMsg( QStringLiteral(
"XML Parsing error" ) );
2723 QDomElement docEl = doc.documentElement();
2724 if ( docEl.tagName() != QLatin1String(
"qgis_style" ) )
2726 mErrorString =
"Incorrect root tag in style: " + docEl.tagName();
2730 const QString version = docEl.attribute( QStringLiteral(
"version" ) );
2731 if ( version != QLatin1String(
STYLE_CURRENT_VERSION ) && version != QLatin1String(
"0" ) && version != QLatin1String(
"1" ) )
2733 mErrorString =
"Unknown style file version: " + version;
2739 QDomElement symbolsElement = docEl.firstChildElement( QStringLiteral(
"symbols" ) );
2740 QDomElement e = symbolsElement.firstChildElement();
2744 runEmptyQuery( query );
2749 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2751 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2752 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2758 if ( e.tagName() == QLatin1String(
"symbol" ) )
2760 QString
name = e.attribute( QStringLiteral(
"name" ) );
2762 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2764 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2766 bool favorite =
false;
2767 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2794 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
2801 QDomElement rampsElement = docEl.firstChildElement( QStringLiteral(
"colorramps" ) );
2802 e = rampsElement.firstChildElement();
2803 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2805 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2806 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2812 if ( e.tagName() == QLatin1String(
"colorramp" ) )
2814 QString
name = e.attribute( QStringLiteral(
"name" ) );
2816 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2818 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2820 bool favorite =
false;
2821 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2845 if ( qobject_cast< QGuiApplication * >( QCoreApplication::instance() ) )
2849 const QDomElement textFormatElement = docEl.firstChildElement( QStringLiteral(
"textformats" ) );
2850 e = textFormatElement.firstChildElement();
2851 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2853 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2854 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2860 if ( e.tagName() == QLatin1String(
"textformat" ) )
2862 QString
name = e.attribute( QStringLiteral(
"name" ) );
2864 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2866 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2868 bool favorite =
false;
2869 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2875 const QDomElement styleElem = e.firstChildElement();
2893 const QDomElement labelSettingsElement = docEl.firstChildElement( QStringLiteral(
"labelsettings" ) );
2894 e = labelSettingsElement.firstChildElement();
2895 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2897 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2898 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2904 if ( e.tagName() == QLatin1String(
"labelsetting" ) )
2906 QString
name = e.attribute( QStringLiteral(
"name" ) );
2908 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2910 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2912 bool favorite =
false;
2913 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2919 const QDomElement styleElem = e.firstChildElement();
2938 const QDomElement legendPatchShapesElement = docEl.firstChildElement( QStringLiteral(
"legendpatchshapes" ) );
2939 e = legendPatchShapesElement.firstChildElement();
2940 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2942 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2943 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2949 if ( e.tagName() == QLatin1String(
"legendpatchshape" ) )
2951 QString
name = e.attribute( QStringLiteral(
"name" ) );
2953 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2955 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2957 bool favorite =
false;
2958 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2964 const QDomElement shapeElem = e.firstChildElement();
2982 const QDomElement symbols3DElement = docEl.firstChildElement( QStringLiteral(
"symbols3d" ) );
2983 e = symbols3DElement.firstChildElement();
2984 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2986 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2987 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2993 if ( e.tagName() == QLatin1String(
"symbol3d" ) )
2995 QString
name = e.attribute( QStringLiteral(
"name" ) );
2997 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2999 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
3001 bool favorite =
false;
3002 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
3007 const QDomElement symbolElem = e.firstChildElement();
3008 const QString type = symbolElem.attribute( QStringLiteral(
"type" ) );
3029 runEmptyQuery( query );
3036 QFileInfo fileInfo( path );
3038 if ( fileInfo.suffix().compare( QLatin1String(
"xml" ), Qt::CaseInsensitive ) != 0 )
3042 if ( !QFile::exists( path ) )
3045 QFile inputFile( path );
3046 if ( !inputFile.open( QIODevice::ReadOnly ) )
3049 QTextStream stream( &inputFile );
3050 const QString line = stream.readLine();
3051 return line == QLatin1String(
"<!DOCTYPE qgis_style>" );
3066 mReadOnly = readOnly;
3069 bool QgsStyle::updateSymbol( StyleEntity type,
const QString &name )
3071 QDomDocument doc( QStringLiteral(
"dummy" ) );
3073 QByteArray xmlArray;
3074 QTextStream stream( &xmlArray );
3075 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
3076 stream.setCodec(
"UTF-8" );
3088 QgsDebugMsg( QStringLiteral(
"Update request received for unavailable symbol" ) );
3093 if ( symEl.isNull() )
3095 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
3098 symEl.save( stream, 4 );
3100 xmlArray.constData(),
name.toUtf8().constData() );
3109 QgsDebugMsg( QStringLiteral(
"Update request received for unavailable symbol" ) );
3113 symEl = doc.createElement( QStringLiteral(
"symbol" ) );
3114 symEl.setAttribute( QStringLiteral(
"type" ), m3dSymbols.value(
name )->type() );
3116 if ( symEl.isNull() )
3118 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
3121 symEl.save( stream, 4 );
3123 xmlArray.constData(),
name.toUtf8().constData() );
3131 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable color ramp." ) );
3137 if ( symEl.isNull() )
3139 QgsDebugMsg( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
3142 symEl.save( stream, 4 );
3144 xmlArray.constData(),
name.toUtf8().constData() );
3152 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable text format." ) );
3158 if ( symEl.isNull() )
3160 QgsDebugMsg( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
3163 symEl.save( stream, 4 );
3165 xmlArray.constData(),
name.toUtf8().constData() );
3173 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable label settings." ) );
3179 if ( symEl.isNull() )
3181 QgsDebugMsg( QStringLiteral(
"Couldn't convert label settings to valid XML!" ) );
3184 symEl.save( stream, 4 );
3186 xmlArray.constData(),
name.toUtf8().constData() );
3194 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable legend patch shape." ) );
3199 symEl = doc.createElement( QStringLiteral(
"shape" ) );
3201 symEl.save( stream, 4 );
3203 xmlArray.constData(),
name.toUtf8().constData() );
3210 QgsDebugMsg( QStringLiteral(
"Updating the unsupported StyleEntity" ) );
3216 if ( !runEmptyQuery( query ) )
3218 QgsDebugMsg( QStringLiteral(
"Couldn't update symbol into the database!" ) );
3254 mCachedTags[ type ].remove(
name );
3257 bool QgsStyle::createStyleMetadataTableIfNeeded()
3260 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='stylemetadata'" );
3263 statement = mCurrentDB.
prepare( query, rc );
3265 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
3269 "id INTEGER PRIMARY KEY,"\
3272 runEmptyQuery( query );
3274 runEmptyQuery( query );
3283 void QgsStyle::upgradeIfRequired()
3287 if ( !createStyleMetadataTableIfNeeded() )
3289 const QString query =
qgs_sqlite3_mprintf(
"SELECT value FROM stylemetadata WHERE key='version'" );
3292 if ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
3304 runEmptyQuery( query );
3314 return QStringLiteral(
"symbol" );
3317 return QStringLiteral(
"colorramp" );
3320 return QStringLiteral(
"textformat" );
3323 return QStringLiteral(
"labelsettings" );
3326 return QStringLiteral(
"legendpatchshapes" );
3329 return QStringLiteral(
"symbol3d" );
3332 return QStringLiteral(
"tag" );
3335 return QStringLiteral(
"smartgroup" );
3345 return QStringLiteral(
"tagmap" );
3348 return QStringLiteral(
"ctagmap" );
3351 return QStringLiteral(
"tftagmap" );
3354 return QStringLiteral(
"lstagmap" );
3357 return QStringLiteral(
"lpstagmap" );
3360 return QStringLiteral(
"symbol3dtagmap" );
3374 return QStringLiteral(
"symbol_id" );
3377 return QStringLiteral(
"colorramp_id" );
3380 return QStringLiteral(
"textformat_id" );
3383 return QStringLiteral(
"labelsettings_id" );
3386 return QStringLiteral(
"legendpatchshape_id" );
3389 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.
Qgis::SymbolType type() const
Returns the symbol's type.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
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