38 #include <QDomDocument>
39 #include <QDomElement>
41 #include <QDomNodeList>
43 #include <QTextStream>
50 #define STYLE_CURRENT_VERSION "2"
75 QgsStyle *QgsStyle::sDefaultStyle =
nullptr;
79 std::unique_ptr< QgsSimpleMarkerSymbolLayer > simpleMarker = std::make_unique< QgsSimpleMarkerSymbolLayer >(
Qgis::MarkerShape::Circle,
81 simpleMarker->setStrokeWidth( 0.4 );
82 mPatchMarkerSymbol = std::make_unique< QgsMarkerSymbol >(
QgsSymbolLayerList() << simpleMarker.release() );
84 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 84, 176, 74 ), 0.6 );
85 mPatchLineSymbol = std::make_unique< QgsLineSymbol >(
QgsSymbolLayerList() << simpleLine.release() );
87 std::unique_ptr< QgsGradientFillSymbolLayer > gradientFill = std::make_unique< QgsGradientFillSymbolLayer >( QColor( 66, 150, 63 ), QColor( 84, 176, 74 ) );
88 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleOutline = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 56, 128, 54 ), 0.26 );
89 mPatchFillSymbol = std::make_unique< QgsFillSymbol >(
QgsSymbolLayerList() << gradientFill.release() << simpleOutline.release() );
99 switch ( entity->
type() )
133 if ( !sDefaultStyle )
139 if ( !QFile::exists( styleFilename ) )
147 sDefaultStyle->createStyleMetadataTableIfNeeded();
154 if ( sDefaultStyle->
load( styleFilename ) )
156 sDefaultStyle->upgradeIfRequired();
160 return sDefaultStyle;
165 delete sDefaultStyle;
166 sDefaultStyle =
nullptr;
171 qDeleteAll( mSymbols );
172 qDeleteAll( mColorRamps );
173 qDeleteAll( m3dSymbols );
177 mTextFormats.clear();
181 mCachedFavorites.clear();
186 if ( !
symbol || name.isEmpty() )
190 if ( mSymbols.contains( name ) )
193 delete mSymbols.value( name );
194 mSymbols.insert( name,
symbol );
200 mSymbols.insert( name,
symbol );
211 QDomDocument doc( QStringLiteral(
"dummy" ) );
213 if ( symEl.isNull() )
215 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
220 QTextStream stream( &xmlArray );
221 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
222 stream.setCodec(
"UTF-8" );
224 symEl.save( stream, 4 );
226 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
228 if ( !runEmptyQuery( query ) )
230 QgsDebugMsg( QStringLiteral(
"Couldn't insert symbol into the database!" ) );
234 mCachedFavorites[
SymbolEntity ].insert( name, favorite );
286 return mSymbols.value( name );
291 return mSymbols.count();
296 return mSymbols.keys();
306 if ( mColorRamps.contains( name ) )
309 delete mColorRamps.value( name );
327 if ( mTextFormats.contains( name ) )
330 mTextFormats.remove( name );
331 mTextFormats.insert( name, format );
337 mTextFormats.insert( name, format );
348 if ( mLabelSettings.contains( name ) )
351 mLabelSettings.remove( name );
352 mLabelSettings.insert( name, settings );
358 mLabelSettings.insert( name, settings );
369 if ( mLegendPatchShapes.contains( name ) )
372 mLegendPatchShapes.remove( name );
373 mLegendPatchShapes.insert( name, shape );
379 mLegendPatchShapes.insert( name, shape );
390 if ( m3dSymbols.contains( name ) )
393 delete m3dSymbols.take( name );
394 m3dSymbols.insert( name,
symbol );
400 m3dSymbols.insert( name,
symbol );
411 QDomDocument doc( QStringLiteral(
"dummy" ) );
414 if ( rampEl.isNull() )
416 QgsDebugMsg( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
421 QTextStream stream( &xmlArray );
422 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
423 stream.setCodec(
"UTF-8" );
425 rampEl.save( stream, 4 );
426 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO colorramp VALUES (NULL, '%q', '%q', %d);",
427 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
428 if ( !runEmptyQuery( query ) )
430 QgsDebugMsg( QStringLiteral(
"Couldn't insert colorramp into the database!" ) );
452 return ramp ? ramp->
clone() :
nullptr;
457 return mColorRamps.value( name );
462 return mColorRamps.count();
467 return mColorRamps.keys();
470 void QgsStyle::handleDeferred3DSymbolCreation()
472 for (
auto it = mDeferred3DsymbolElements.constBegin(); it != mDeferred3DsymbolElements.constEnd(); ++it )
474 const QString symbolType = it.value().attribute( QStringLiteral(
"type" ) );
484 QgsDebugMsg(
"Cannot open 3d symbol " + it.key() );
488 mDeferred3DsymbolElements.clear();
491 bool QgsStyle::openDatabase(
const QString &filename )
493 int rc = mCurrentDB.
open( filename );
496 mErrorString = QStringLiteral(
"Couldn't open the style database: %1" ).arg( mCurrentDB.
errorMessage() );
505 mErrorString.clear();
506 if ( !openDatabase( filename ) )
508 mErrorString = QStringLiteral(
"Unable to create database" );
520 mErrorString.clear();
521 if ( !openDatabase( QStringLiteral(
":memory:" ) ) )
523 mErrorString = QStringLiteral(
"Unable to create temporary memory database" );
536 "id INTEGER PRIMARY KEY,"\
539 "favorite INTEGER);"\
540 "CREATE TABLE colorramp("\
541 "id INTEGER PRIMARY KEY,"\
544 "favorite INTEGER);"\
545 "CREATE TABLE textformat("\
546 "id INTEGER PRIMARY KEY,"\
549 "favorite INTEGER);"\
550 "CREATE TABLE labelsettings("\
551 "id INTEGER PRIMARY KEY,"\
554 "favorite INTEGER);"\
555 "CREATE TABLE legendpatchshapes("\
556 "id INTEGER PRIMARY KEY,"\
559 "favorite INTEGER);"\
560 "CREATE TABLE symbol3d("\
561 "id INTEGER PRIMARY KEY,"\
564 "favorite INTEGER);"\
566 "id INTEGER PRIMARY KEY,"\
568 "CREATE TABLE tagmap("\
569 "tag_id INTEGER NOT NULL,"\
570 "symbol_id INTEGER);"\
571 "CREATE TABLE ctagmap("\
572 "tag_id INTEGER NOT NULL,"\
573 "colorramp_id INTEGER);"\
574 "CREATE TABLE tftagmap("\
575 "tag_id INTEGER NOT NULL,"\
576 "textformat_id INTEGER);"\
577 "CREATE TABLE lstagmap("\
578 "tag_id INTEGER NOT NULL,"\
579 "labelsettings_id INTEGER);"\
580 "CREATE TABLE lpstagmap("\
581 "tag_id INTEGER NOT NULL,"\
582 "legendpatchshape_id INTEGER);"\
583 "CREATE TABLE symbol3dtagmap("\
584 "tag_id INTEGER NOT NULL,"\
585 "symbol3d_id INTEGER);"\
586 "CREATE TABLE smartgroup("\
587 "id INTEGER PRIMARY KEY,"\
590 runEmptyQuery( query );
595 mErrorString.clear();
598 if ( !openDatabase( filename ) )
600 mErrorString = QStringLiteral(
"Unable to open database file specified" );
606 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='textformat'" );
609 statement = mCurrentDB.
prepare( query, rc );
610 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
613 "id INTEGER PRIMARY KEY,"\
616 "favorite INTEGER);"\
617 "CREATE TABLE tftagmap("\
618 "tag_id INTEGER NOT NULL,"\
619 "textformat_id INTEGER);" );
620 runEmptyQuery( query );
623 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='labelsettings'" );
624 statement = mCurrentDB.
prepare( query, rc );
625 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
628 "id INTEGER PRIMARY KEY,"\
631 "favorite INTEGER);"\
632 "CREATE TABLE lstagmap("\
633 "tag_id INTEGER NOT NULL,"\
634 "labelsettings_id INTEGER);" );
635 runEmptyQuery( query );
638 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='legendpatchshapes'" );
639 statement = mCurrentDB.
prepare( query, rc );
640 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
643 "id INTEGER PRIMARY KEY,"\
646 "favorite INTEGER);"\
647 "CREATE TABLE lpstagmap("\
648 "tag_id INTEGER NOT NULL,"\
649 "legendpatchshape_id INTEGER);" );
650 runEmptyQuery( query );
654 statement = mCurrentDB.
prepare( query, rc );
655 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
658 "id INTEGER PRIMARY KEY,"\
661 "favorite INTEGER);"\
662 "CREATE TABLE symbol3dtagmap("\
663 "tag_id INTEGER NOT NULL,"\
664 "symbol3d_id INTEGER);" );
665 runEmptyQuery( query );
670 "UPDATE colorramp SET favorite=0 WHERE favorite IS NULL;"
671 "UPDATE textformat SET favorite=0 WHERE favorite IS NULL;"
672 "UPDATE labelsettings SET favorite=0 WHERE favorite IS NULL;"
673 "UPDATE legendpatchshapes SET favorite=0 WHERE favorite IS NULL;"
674 "UPDATE symbol3d SET favorite=0 WHERE favorite IS NULL;"
676 runEmptyQuery( query );
682 statement = mCurrentDB.
prepare( query, rc );
684 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
690 if ( !doc.setContent( xmlstring ) )
696 QDomElement symElement = doc.documentElement();
699 mSymbols.insert( symbolName,
symbol );
706 statement = mCurrentDB.
prepare( query, rc );
707 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
713 if ( !doc.setContent( xmlstring ) )
718 QDomElement rampElement = doc.documentElement();
721 mColorRamps.insert( rampName, ramp );
728 statement = mCurrentDB.
prepare( query, rc );
729 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
735 if ( !doc.setContent( xmlstring ) )
737 QgsDebugMsg(
"Cannot open text format " + formatName );
740 QDomElement formatElement = doc.documentElement();
743 mTextFormats.insert( formatName, format );
750 statement = mCurrentDB.
prepare( query, rc );
751 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
757 if ( !doc.setContent( xmlstring ) )
759 QgsDebugMsg(
"Cannot open label settings " + settingsName );
762 QDomElement settingsElement = doc.documentElement();
765 mLabelSettings.insert( settingsName, settings );
772 statement = mCurrentDB.
prepare( query, rc );
773 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
779 if ( !doc.setContent( xmlstring ) )
781 QgsDebugMsg(
"Cannot open legend patch shape " + settingsName );
784 QDomElement settingsElement = doc.documentElement();
787 mLegendPatchShapes.insert( settingsName, shape );
794 statement = mCurrentDB.
prepare( query, rc );
798 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
804 if ( !doc.setContent( xmlstring ) )
806 QgsDebugMsg(
"Cannot open 3d symbol " + settingsName );
809 QDomElement settingsElement = doc.documentElement();
811 if ( !registry3dPopulated )
813 mDeferred3DsymbolElements.insert( settingsName, settingsElement );
817 const QString symbolType = settingsElement.attribute( QStringLiteral(
"type" ) );
822 m3dSymbols.insert( settingsName,
symbol.release() );
826 QgsDebugMsg(
"Cannot open 3d symbol " + settingsName );
833 mFileName = filename;
841 mErrorString.clear();
843 if ( filename.isEmpty() )
844 filename = mFileName;
849 QDomDocument doc(
"qgis_style" );
850 QDomElement root = doc.createElement(
"qgis_style" );
852 doc.appendChild( root );
856 QDomElement rampsElem = doc.createElement(
"colorramps" );
859 for ( QMap<QString, QgsColorRamp *>::iterator itr = mColorRamps.begin(); itr != mColorRamps.end(); ++itr )
862 rampsElem.appendChild( rampEl );
865 root.appendChild( symbolsElem );
866 root.appendChild( rampsElem );
870 if ( !f.open( QFile::WriteOnly ) )
872 mErrorString =
"Couldn't open file for writing: " + filename;
875 QTextStream ts( &f );
876 ts.setCodec(
"UTF-8" );
881 mFileName = filename;
887 if ( mSymbols.contains( newName ) )
889 QgsDebugMsg( QStringLiteral(
"Symbol of new name already exists" ) );
897 mSymbols.insert( newName,
symbol );
901 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to tag." ) );
908 QgsDebugMsg( QStringLiteral(
"No such symbol for tagging in database: " ) + oldName );
927 if ( mColorRamps.contains( newName ) )
929 QgsDebugMsg( QStringLiteral(
"Color ramp of new name already exists." ) );
937 mColorRamps.insert( newName, ramp );
943 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM colorramp WHERE name='%q'", oldName.toUtf8().constData() );
945 statement = mCurrentDB.
prepare( query, nErr );
946 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
948 rampid = sqlite3_column_int( statement.get(), 0 );
963 QDomDocument doc( QStringLiteral(
"dummy" ) );
966 if ( formatElem.isNull() )
968 QgsDebugMsg( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
973 QTextStream stream( &xmlArray );
974 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
975 stream.setCodec(
"UTF-8" );
977 formatElem.save( stream, 4 );
978 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO textformat VALUES (NULL, '%q', '%q', %d);",
979 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
980 if ( !runEmptyQuery( query ) )
982 QgsDebugMsg( QStringLiteral(
"Couldn't insert text format into the database!" ) );
1003 if ( mTextFormats.contains( newName ) )
1005 QgsDebugMsg( QStringLiteral(
"Text format of new name already exists." ) );
1009 if ( !mTextFormats.contains( oldName ) )
1013 mTextFormats.insert( newName, format );
1019 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM textformat WHERE name='%q'", oldName.toUtf8().constData() );
1021 statement = mCurrentDB.
prepare( query, nErr );
1022 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1024 textFormatId = sqlite3_column_int( statement.get(), 0 );
1039 QDomDocument doc( QStringLiteral(
"dummy" ) );
1042 if ( settingsElem.isNull() )
1044 QgsDebugMsg( QStringLiteral(
"Couldn't convert label settings to valid XML!" ) );
1048 QByteArray xmlArray;
1049 QTextStream stream( &xmlArray );
1050 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1051 stream.setCodec(
"UTF-8" );
1053 settingsElem.save( stream, 4 );
1054 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO labelsettings VALUES (NULL, '%q', '%q', %d);",
1055 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1056 if ( !runEmptyQuery( query ) )
1058 QgsDebugMsg( QStringLiteral(
"Couldn't insert label settings into the database!" ) );
1079 if ( mLabelSettings.contains( newName ) )
1081 QgsDebugMsg( QStringLiteral(
"Label settings of new name already exists." ) );
1085 if ( !mLabelSettings.contains( oldName ) )
1089 mLabelSettings.insert( newName, settings );
1095 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM labelsettings WHERE name='%q'", oldName.toUtf8().constData() );
1097 statement = mCurrentDB.
prepare( query, nErr );
1098 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1115 QDomDocument doc( QStringLiteral(
"dummy" ) );
1116 QDomElement shapeElem = doc.createElement( QStringLiteral(
"shape" ) );
1119 QByteArray xmlArray;
1120 QTextStream stream( &xmlArray );
1121 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1122 stream.setCodec(
"UTF-8" );
1124 shapeElem.save( stream, 4 );
1125 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO legendpatchshapes VALUES (NULL, '%q', '%q', %d);",
1126 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1127 if ( !runEmptyQuery( query ) )
1129 QgsDebugMsg( QStringLiteral(
"Couldn't insert legend patch shape into the database!" ) );
1144 if ( mLegendPatchShapes.contains( newName ) )
1146 QgsDebugMsg( QStringLiteral(
"Legend patch shape of new name already exists." ) );
1150 if ( !mLegendPatchShapes.contains( oldName ) )
1154 mLegendPatchShapes.insert( newName, shape );
1160 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM legendpatchshapes WHERE name='%q'", oldName.toUtf8().constData() );
1162 statement = mCurrentDB.
prepare( query, nErr );
1163 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1181 if ( mDefaultPatchCache[
static_cast< int >( type ) ].contains( size ) )
1182 return mDefaultPatchCache[
static_cast< int >( type ) ].value( size );
1188 geom =
QgsGeometry( std::make_unique< QgsPoint >(
static_cast< int >( size.width() ) / 2,
static_cast< int >( size.height() ) / 2 ) );
1195 double y =
static_cast< int >( size.height() ) / 2 + 0.5;
1196 geom =
QgsGeometry( std::make_unique< QgsLineString >( ( QVector< double >() << 0 << size.width() ),
1197 ( QVector< double >() << y << y ) ) );
1203 geom =
QgsGeometry( std::make_unique< QgsPolygon >(
1204 new QgsLineString( QVector< double >() << 0 <<
static_cast< int >( size.width() ) <<
static_cast< int >( size.width() ) << 0 << 0,
1205 QVector< double >() <<
static_cast< int >( size.height() ) <<
static_cast< int >( size.height() ) << 0 << 0 <<
static_cast< int >( size.height() ) ) ) );
1214 mDefaultPatchCache[
static_cast< int >( type ) ][size ] = res;
1221 return QList<QList<QPolygonF> >();
1223 if ( mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ].contains( size ) )
1224 return mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ].value( size );
1227 mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ][size ] = res;
1233 return textFormat( QStringLiteral(
"Default" ) );
1239 QDomDocument doc( QStringLiteral(
"dummy" ) );
1240 QDomElement elem = doc.createElement( QStringLiteral(
"symbol" ) );
1241 elem.setAttribute( QStringLiteral(
"type" ),
symbol->
type() );
1244 QByteArray xmlArray;
1245 QTextStream stream( &xmlArray );
1246 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1247 stream.setCodec(
"UTF-8" );
1249 elem.save( stream, 4 );
1250 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO symbol3d VALUES (NULL, '%q', '%q', %d);",
1251 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1252 if ( !runEmptyQuery( query ) )
1254 QgsDebugMsg( QStringLiteral(
"Couldn't insert 3d symbol into the database!" ) );
1269 if ( m3dSymbols.contains( newName ) )
1271 QgsDebugMsg( QStringLiteral(
"3d symbol of new name already exists." ) );
1275 if ( !m3dSymbols.contains( oldName ) )
1279 m3dSymbols.insert( newName,
symbol );
1285 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM symbol3d WHERE name='%q'", oldName.toUtf8().constData() );
1287 statement = mCurrentDB.
prepare( query, nErr );
1288 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1303 return m3dSymbols.keys();
1310 QgsDebugMsg( QStringLiteral(
"Cannot Open database for getting favorite symbols" ) );
1311 return QStringList();
1319 QgsDebugMsg( QStringLiteral(
"No such style entity" ) );
1320 return QStringList();
1323 query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT name FROM %1 WHERE favorite=1" ).arg( entityTableName( type ) ).toLocal8Bit().data() );
1329 statement = mCurrentDB.
prepare( query, nErr );
1331 QStringList symbols;
1332 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1344 QgsDebugMsg( QStringLiteral(
"Cannot open database to get symbols of tagid %1" ).arg( tagid ) );
1345 return QStringList();
1353 QgsDebugMsg( QStringLiteral(
"Unknown Entity" ) );
1354 return QStringList();
1357 subquery =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT %1 FROM %2 WHERE tag_id=%d" ).arg( tagmapEntityIdFieldName( type ),
1358 tagmapTableName( type ) ).toLocal8Bit().data(), tagid );
1364 statement = mCurrentDB.
prepare( subquery, nErr );
1367 QStringList symbols;
1368 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1370 int id = sqlite3_column_int( statement.get(), 0 );
1372 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT name FROM %1 WHERE id=%d" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
id );
1376 statement2 = mCurrentDB.
prepare( query, rc );
1377 while ( rc == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1392 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO tag VALUES (NULL, '%q')", tagname.toUtf8().constData() );
1394 statement = mCurrentDB.
prepare( query, nErr );
1395 if ( nErr == SQLITE_OK )
1396 ( void )sqlite3_step( statement.get() );
1399 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1403 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
1409 return QStringList();
1415 statement = mCurrentDB.
prepare( query, nError );
1417 QStringList tagList;
1418 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1428 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET name='%q' WHERE id=%d" ).arg( entityTableName( type ) ).toLocal8Bit().data(), newName.toUtf8().constData(),
id );
1430 const bool result = runEmptyQuery( query );
1433 mErrorString = QStringLiteral(
"Could not rename!" );
1437 mCachedTags.clear();
1438 mCachedFavorites.clear();
1463 bool groupRemoved =
false;
1468 query =
qgs_sqlite3_mprintf(
"DELETE FROM tag WHERE id=%d; DELETE FROM tagmap WHERE tag_id=%d",
id,
id );
1469 groupRemoved =
true;
1473 groupRemoved =
true;
1477 query =
qgs_sqlite3_mprintf( QStringLiteral(
"DELETE FROM %1 WHERE id=%d; DELETE FROM %2 WHERE %3=%d" ).arg(
1478 entityTableName( type ),
1479 tagmapTableName( type ),
1480 tagmapEntityIdFieldName( type )
1481 ).toLocal8Bit().data(),
id,
id );
1485 bool result =
false;
1486 if ( !runEmptyQuery( query ) )
1488 QgsDebugMsg( QStringLiteral(
"Could not delete entity!" ) );
1492 mCachedTags.clear();
1493 mCachedFavorites.clear();
1498 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1517 std::unique_ptr< QgsSymbol >
symbol( mSymbols.take( name ) );
1526 std::unique_ptr< QgsAbstract3DSymbol >
symbol( m3dSymbols.take( name ) );
1535 std::unique_ptr< QgsColorRamp > ramp( mColorRamps.take( name ) );
1543 if ( !mTextFormats.contains( name ) )
1546 mTextFormats.remove( name );
1552 if ( !mLabelSettings.contains( name ) )
1555 mLabelSettings.remove( name );
1561 if ( !mLegendPatchShapes.contains( name ) )
1564 mLegendPatchShapes.remove( name );
1571 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to modify." ) );
1575 const int id =
entityId( type, name );
1578 QgsDebugMsg(
"No matching entity for deleting in database: " + name );
1581 const bool result =
remove( type,
id );
1584 mCachedTags[ type ].remove( name );
1585 mCachedFavorites[ type ].remove( name );
1614 bool QgsStyle::runEmptyQuery(
const QString &query )
1619 char *zErr =
nullptr;
1620 int nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1622 if ( nErr != SQLITE_OK )
1625 sqlite3_free( zErr );
1628 return nErr == SQLITE_OK;
1639 QgsDebugMsg( QStringLiteral(
"Wrong entity value. cannot apply group" ) );
1643 query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET favorite=1 WHERE name='%q'" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
1644 name.toUtf8().constData() );
1648 const bool res = runEmptyQuery( query );
1658 mCachedFavorites[ type ].insert( name,
true );
1675 QgsDebugMsg( QStringLiteral(
"Wrong entity value. cannot apply group" ) );
1679 query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET favorite=0 WHERE name='%q'" ).arg( entityTableName( type ) ).toLocal8Bit().data(), name.toUtf8().constData() );
1683 const bool res = runEmptyQuery( query );
1686 mCachedFavorites[ type ].insert( name,
false );
1697 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to search" ) );
1698 return QStringList();
1707 return QStringList();
1710 item = entityTableName( type );
1715 item.toUtf8().constData(), qword.toUtf8().constData() );
1718 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1720 QSet< QString > symbols;
1721 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1727 query =
qgs_sqlite3_mprintf(
"SELECT id FROM tag WHERE name LIKE '%%%q%%'", qword.toUtf8().constData() );
1728 statement = mCurrentDB.
prepare( query, nErr );
1731 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1736 QString dummy = tagids.join( QLatin1String(
", " ) );
1737 query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT %1 FROM %2 WHERE tag_id IN (%q)" ).arg( tagmapEntityIdFieldName( type ),
1738 tagmapTableName( type ) ).toLocal8Bit().data(), dummy.toUtf8().constData() );
1740 statement = mCurrentDB.
prepare( query, nErr );
1742 QStringList symbolids;
1743 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1748 dummy = symbolids.join( QLatin1String(
", " ) );
1750 item.toUtf8().constData(), dummy.toUtf8().constData() );
1751 statement = mCurrentDB.
prepare( query, nErr );
1752 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1757 return qgis::setToList( symbols );
1764 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to tag." ) );
1782 QgsDebugMsg( QStringLiteral(
"No such symbol for tagging in database: " ) +
symbol );
1787 const auto constTags =
tags;
1788 for (
const QString &t : constTags )
1791 if ( !
tag.isEmpty() )
1803 QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"INSERT INTO %1 VALUES (%d,%d)" ).arg( tagmapTableName( type ) ).toLocal8Bit().data(), tagid, symbolid );
1805 char *zErr =
nullptr;
1807 nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1811 sqlite3_free( zErr );
1817 clearCachedTags( type,
symbol );
1827 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for detagging." ) );
1842 if ( symbolid == 0 )
1847 const auto constTags =
tags;
1848 for (
const QString &
tag : constTags )
1853 statement2 = mCurrentDB.
prepare( query, nErr );
1856 if ( nErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1858 tagid = sqlite3_column_int( statement2.get(), 0 );
1864 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 );
1865 runEmptyQuery( query );
1869 clearCachedTags( type,
symbol );
1882 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for detagging." ) );
1897 if ( symbolid == 0 )
1903 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"DELETE FROM %1 WHERE %2=%d" ).arg( tagmapTableName( type ),
1904 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1905 runEmptyQuery( query );
1907 clearCachedTags( type,
symbol );
1922 return QStringList();
1925 if ( mCachedTags[ type ].contains(
symbol ) )
1926 return mCachedTags[ type ].value(
symbol );
1932 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
1933 return QStringList();
1938 return QStringList();
1941 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT tag_id FROM %1 WHERE %2=%d" ).arg( tagmapTableName( type ),
1942 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1945 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1947 QStringList tagList;
1948 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1950 QString subquery =
qgs_sqlite3_mprintf(
"SELECT name FROM tag WHERE id=%d", sqlite3_column_int( statement.get(), 0 ) );
1954 statement2 = mCurrentDB.
prepare( subquery, pErr );
1955 if ( pErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1962 mCachedTags[ type ].insert(
symbol, tagList );
1971 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
1982 if ( mCachedFavorites[ type ].contains( name ) )
1983 return mCachedFavorites[ type ].value( name );
1987 const QStringList names =
allNames( type );
1988 if ( !names.contains( name ) )
1994 for (
const QString &n : names )
1996 const bool isFav = favorites.contains( n );
2000 mCachedFavorites[ type ].insert( n, isFav );
2009 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
2036 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT tag_id FROM %1 WHERE tag_id=%d AND %2=%d" ).arg( tagmapTableName( type ),
2037 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), tagid, symbolid );
2040 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2042 return ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW );
2054 statement = mCurrentDB.
prepare( query, nError );
2057 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2065 int QgsStyle::getId(
const QString &table,
const QString &name )
2067 QString lowerName( name.toLower() );
2068 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE LOWER(name)='%q'", table.toUtf8().constData(), lowerName.toUtf8().constData() );
2071 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2074 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2076 id = sqlite3_column_int( statement.get(), 0 );
2081 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE name='%q'", table.toUtf8().constData(), name.toUtf8().constData() );
2084 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2085 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2087 id = sqlite3_column_int( statement.get(), 0 );
2094 QString QgsStyle::getName(
const QString &table,
int id )
const
2096 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM %q WHERE id='%q'", table.toUtf8().constData(), QString::number(
id ).toUtf8().constData() );
2099 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2102 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2112 return getId( QStringLiteral(
"symbol" ), name );
2117 return getId( entityTableName( type ), name );
2122 return getId( QStringLiteral(
"colorramp" ), name );
2127 return mTextFormats.value( name );
2132 return mTextFormats.count();
2137 return mTextFormats.keys();
2142 return getId( QStringLiteral(
"textformat" ), name );
2147 return mLabelSettings.value( name );
2152 return mLegendPatchShapes.value( name );
2157 return mLegendPatchShapes.count();
2162 if ( !mLegendPatchShapes.contains( name ) )
2165 return mLegendPatchShapes.value( name ).symbolType();
2170 return m3dSymbols.contains( name ) ? m3dSymbols.value( name )->clone() :
nullptr;
2175 return m3dSymbols.count();
2180 if ( !m3dSymbols.contains( name ) )
2181 return QList<QgsWkbTypes::GeometryType>();
2183 return m3dSymbols.value( name )->compatibleGeometryTypes();
2188 if ( !mLabelSettings.contains( name ) )
2191 return mLabelSettings.value( name ).layerType;
2196 return mLabelSettings.count();
2201 return mLabelSettings.keys();
2206 return getId( QStringLiteral(
"labelsettings" ), name );
2211 return mLegendPatchShapes.keys();
2219 return mPatchMarkerSymbol.get();
2222 return mPatchLineSymbol.get();
2225 return mPatchFillSymbol.get();
2235 return getId( QStringLiteral(
"tag" ), name );
2240 return getId( QStringLiteral(
"smartgroup" ), name );
2271 return QStringList();
2276 return addSmartgroup( name, op, conditions.values( QStringLiteral(
"tag" ) ),
2277 conditions.values( QStringLiteral(
"!tag" ) ),
2278 conditions.values( QStringLiteral(
"name" ) ),
2279 conditions.values( QStringLiteral(
"!name" ) ) );
2282 int QgsStyle::addSmartgroup(
const QString &name,
const QString &op,
const QStringList &matchTag,
const QStringList &noMatchTag,
const QStringList &matchName,
const QStringList &noMatchName )
2284 QDomDocument doc( QStringLiteral(
"dummy" ) );
2285 QDomElement smartEl = doc.createElement( QStringLiteral(
"smartgroup" ) );
2286 smartEl.setAttribute( QStringLiteral(
"name" ), name );
2287 smartEl.setAttribute( QStringLiteral(
"operator" ), op );
2289 auto addCondition = [&doc, &smartEl](
const QString & constraint,
const QStringList & parameters )
2291 for (
const QString ¶m : parameters )
2293 QDomElement condEl = doc.createElement( QStringLiteral(
"condition" ) );
2294 condEl.setAttribute( QStringLiteral(
"constraint" ), constraint );
2295 condEl.setAttribute( QStringLiteral(
"param" ), param );
2296 smartEl.appendChild( condEl );
2299 addCondition( QStringLiteral(
"tag" ), matchTag );
2300 addCondition( QStringLiteral(
"!tag" ), noMatchTag );
2301 addCondition( QStringLiteral(
"name" ), matchName );
2302 addCondition( QStringLiteral(
"!name" ), noMatchName );
2304 QByteArray xmlArray;
2305 QTextStream stream( &xmlArray );
2306 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2307 stream.setCodec(
"UTF-8" );
2309 smartEl.save( stream, 4 );
2311 name.toUtf8().constData(), xmlArray.constData() );
2313 if ( runEmptyQuery( query ) )
2316 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
2319 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
2323 QgsDebugMsg( QStringLiteral(
"Couldn't add the smart group into the database!" ) );
2332 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2341 statement = mCurrentDB.
prepare( query, nError );
2344 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2347 groupNames.insert( sqlite3_column_int( statement.get(),
SmartgroupId ), group );
2357 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2358 return QStringList();
2366 statement = mCurrentDB.
prepare( query, nError );
2369 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2379 QStringList symbols;
2384 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2385 if ( !( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW ) )
2387 return QStringList();
2393 if ( !doc.setContent( xmlstr ) )
2395 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2397 QDomElement smartEl = doc.documentElement();
2398 QString op = smartEl.attribute( QStringLiteral(
"operator" ) );
2399 QDomNodeList conditionNodes = smartEl.childNodes();
2401 bool firstSet =
true;
2402 for (
int i = 0; i < conditionNodes.count(); i++ )
2404 QDomElement condEl = conditionNodes.at( i ).toElement();
2405 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2406 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2408 QStringList resultNames;
2410 if ( constraint == QLatin1String(
"tag" ) )
2414 else if ( constraint == QLatin1String(
"name" ) )
2416 resultNames =
allNames( type ).filter( param, Qt::CaseInsensitive );
2418 else if ( constraint == QLatin1String(
"!tag" ) )
2422 for (
const QString &name : unwanted )
2424 resultNames.removeAll( name );
2427 else if ( constraint == QLatin1String(
"!name" ) )
2429 const QStringList all =
allNames( type );
2430 for (
const QString &
str : all )
2432 if ( !
str.contains( param, Qt::CaseInsensitive ) )
2440 symbols = resultNames;
2445 if ( op == QLatin1String(
"OR" ) )
2447 symbols << resultNames;
2449 else if ( op == QLatin1String(
"AND" ) )
2451 QStringList dummy = symbols;
2453 for (
const QString &result : std::as_const( resultNames ) )
2455 if ( dummy.contains( result ) )
2464 QStringList unique = qgis::setToList( qgis::listToSet( symbols ) );
2465 std::sort( unique.begin(), unique.end() );
2473 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2483 statement = mCurrentDB.
prepare( query, nError );
2484 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2488 if ( !doc.setContent( xmlstr ) )
2490 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2493 QDomElement smartEl = doc.documentElement();
2494 QDomNodeList conditionNodes = smartEl.childNodes();
2496 for (
int i = 0; i < conditionNodes.count(); i++ )
2498 QDomElement condEl = conditionNodes.at( i ).toElement();
2499 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2500 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2502 condition.insert( constraint, param );
2513 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2523 statement = mCurrentDB.
prepare( query, nError );
2524 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2528 if ( !doc.setContent( xmlstr ) )
2530 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2532 QDomElement smartEl = doc.documentElement();
2533 op = smartEl.attribute( QStringLiteral(
"operator" ) );
2541 if ( filename.isEmpty() )
2543 QgsDebugMsg( QStringLiteral(
"Invalid filename for style export." ) );
2547 QDomDocument doc( QStringLiteral(
"qgis_style" ) );
2548 QDomElement root = doc.createElement( QStringLiteral(
"qgis_style" ) );
2550 doc.appendChild( root );
2560 QDomNodeList symbolsList = symbolsElem.elementsByTagName( QStringLiteral(
"symbol" ) );
2561 int nbSymbols = symbolsList.count();
2562 for (
int i = 0; i < nbSymbols; ++i )
2564 QDomElement
symbol = symbolsList.at( i ).toElement();
2565 QString name =
symbol.attribute( QStringLiteral(
"name" ) );
2567 if (
tags.count() > 0 )
2569 symbol.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2571 if ( favoriteSymbols.contains( name ) )
2573 symbol.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2578 QDomElement rampsElem = doc.createElement( QStringLiteral(
"colorramps" ) );
2579 for ( QMap<QString, QgsColorRamp *>::const_iterator itr = mColorRamps.constBegin(); itr != mColorRamps.constEnd(); ++itr )
2583 if (
tags.count() > 0 )
2585 rampEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2587 if ( favoriteColorramps.contains( itr.key() ) )
2589 rampEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2591 rampsElem.appendChild( rampEl );
2595 QDomElement textFormatsElem = doc.createElement( QStringLiteral(
"textformats" ) );
2596 for (
auto it = mTextFormats.constBegin(); it != mTextFormats.constEnd(); ++it )
2598 QDomElement textFormatEl = doc.createElement( QStringLiteral(
"textformat" ) );
2599 textFormatEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2601 textFormatEl.appendChild( textStyleEl );
2603 if (
tags.count() > 0 )
2605 textFormatEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2607 if ( favoriteTextFormats.contains( it.key() ) )
2609 textFormatEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2611 textFormatsElem.appendChild( textFormatEl );
2615 QDomElement labelSettingsElem = doc.createElement( QStringLiteral(
"labelsettings" ) );
2616 for (
auto it = mLabelSettings.constBegin(); it != mLabelSettings.constEnd(); ++it )
2618 QDomElement labelSettingsEl = doc.createElement( QStringLiteral(
"labelsetting" ) );
2619 labelSettingsEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2621 labelSettingsEl.appendChild( defEl );
2623 if (
tags.count() > 0 )
2625 labelSettingsEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2627 if ( favoriteTextFormats.contains( it.key() ) )
2629 labelSettingsEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2631 labelSettingsElem.appendChild( labelSettingsEl );
2635 QDomElement legendPatchShapesElem = doc.createElement( QStringLiteral(
"legendpatchshapes" ) );
2636 for (
auto it = mLegendPatchShapes.constBegin(); it != mLegendPatchShapes.constEnd(); ++it )
2638 QDomElement legendPatchShapeEl = doc.createElement( QStringLiteral(
"legendpatchshape" ) );
2639 legendPatchShapeEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2640 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2642 legendPatchShapeEl.appendChild( defEl );
2644 if (
tags.count() > 0 )
2646 legendPatchShapeEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2648 if ( favoriteLegendShapes.contains( it.key() ) )
2650 legendPatchShapeEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2652 legendPatchShapesElem.appendChild( legendPatchShapeEl );
2656 QDomElement symbols3DElem = doc.createElement( QStringLiteral(
"symbols3d" ) );
2657 for (
auto it = m3dSymbols.constBegin(); it != m3dSymbols.constEnd(); ++it )
2659 QDomElement symbolEl = doc.createElement( QStringLiteral(
"symbol3d" ) );
2660 symbolEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2661 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2662 defEl.setAttribute( QStringLiteral(
"type" ), it.value()->type() );
2664 symbolEl.appendChild( defEl );
2666 if (
tags.count() > 0 )
2668 symbolEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2670 if ( favorite3DSymbols.contains( it.key() ) )
2672 symbolEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2674 symbols3DElem.appendChild( symbolEl );
2677 root.appendChild( symbolsElem );
2678 root.appendChild( rampsElem );
2679 root.appendChild( textFormatsElem );
2680 root.appendChild( labelSettingsElem );
2681 root.appendChild( legendPatchShapesElem );
2682 root.appendChild( symbols3DElem );
2685 QFile f( filename );
2686 if ( !f.open( QFile::WriteOnly | QIODevice::Truncate ) )
2688 mErrorString =
"Couldn't open file for writing: " + filename;
2692 QTextStream ts( &f );
2693 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2694 ts.setCodec(
"UTF-8" );
2699 mFileName = filename;
2710 mErrorString = QString();
2711 QDomDocument doc( QStringLiteral(
"style" ) );
2712 QFile f( filename );
2713 if ( !f.open( QFile::ReadOnly ) )
2715 mErrorString = QStringLiteral(
"Unable to open the specified file" );
2716 QgsDebugMsg( QStringLiteral(
"Error opening the style XML file." ) );
2720 if ( !doc.setContent( &f ) )
2722 mErrorString = QStringLiteral(
"Unable to understand the style file: %1" ).arg( filename );
2723 QgsDebugMsg( QStringLiteral(
"XML Parsing error" ) );
2729 QDomElement docEl = doc.documentElement();
2730 if ( docEl.tagName() != QLatin1String(
"qgis_style" ) )
2732 mErrorString =
"Incorrect root tag in style: " + docEl.tagName();
2736 const QString version = docEl.attribute( QStringLiteral(
"version" ) );
2737 if ( version != QLatin1String(
STYLE_CURRENT_VERSION ) && version != QLatin1String(
"0" ) && version != QLatin1String(
"1" ) )
2739 mErrorString =
"Unknown style file version: " + version;
2745 QDomElement symbolsElement = docEl.firstChildElement( QStringLiteral(
"symbols" ) );
2746 QDomElement e = symbolsElement.firstChildElement();
2750 runEmptyQuery( query );
2755 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2757 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2758 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2764 if ( e.tagName() == QLatin1String(
"symbol" ) )
2766 QString name = e.attribute( QStringLiteral(
"name" ) );
2768 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2770 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2772 bool favorite =
false;
2773 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2800 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
2807 QDomElement rampsElement = docEl.firstChildElement( QStringLiteral(
"colorramps" ) );
2808 e = rampsElement.firstChildElement();
2809 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2811 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2812 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2818 if ( e.tagName() == QLatin1String(
"colorramp" ) )
2820 QString name = e.attribute( QStringLiteral(
"name" ) );
2822 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2824 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2826 bool favorite =
false;
2827 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2851 if ( qobject_cast< QGuiApplication * >( QCoreApplication::instance() ) )
2855 const QDomElement textFormatElement = docEl.firstChildElement( QStringLiteral(
"textformats" ) );
2856 e = textFormatElement.firstChildElement();
2857 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2859 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2860 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2866 if ( e.tagName() == QLatin1String(
"textformat" ) )
2868 QString name = e.attribute( QStringLiteral(
"name" ) );
2870 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2872 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2874 bool favorite =
false;
2875 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2881 const QDomElement styleElem = e.firstChildElement();
2899 const QDomElement labelSettingsElement = docEl.firstChildElement( QStringLiteral(
"labelsettings" ) );
2900 e = labelSettingsElement.firstChildElement();
2901 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2903 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2904 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2910 if ( e.tagName() == QLatin1String(
"labelsetting" ) )
2912 QString name = e.attribute( QStringLiteral(
"name" ) );
2914 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2916 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2918 bool favorite =
false;
2919 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2925 const QDomElement styleElem = e.firstChildElement();
2944 const QDomElement legendPatchShapesElement = docEl.firstChildElement( QStringLiteral(
"legendpatchshapes" ) );
2945 e = legendPatchShapesElement.firstChildElement();
2946 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2948 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2949 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2955 if ( e.tagName() == QLatin1String(
"legendpatchshape" ) )
2957 QString name = e.attribute( QStringLiteral(
"name" ) );
2959 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2961 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2963 bool favorite =
false;
2964 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2970 const QDomElement shapeElem = e.firstChildElement();
2988 const QDomElement symbols3DElement = docEl.firstChildElement( QStringLiteral(
"symbols3d" ) );
2989 e = symbols3DElement.firstChildElement();
2990 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2992 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2993 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2999 if ( e.tagName() == QLatin1String(
"symbol3d" ) )
3001 QString name = e.attribute( QStringLiteral(
"name" ) );
3003 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
3005 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
3007 bool favorite =
false;
3008 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
3013 const QDomElement symbolElem = e.firstChildElement();
3014 const QString type = symbolElem.attribute( QStringLiteral(
"type" ) );
3035 runEmptyQuery( query );
3037 mFileName = filename;
3043 QFileInfo fileInfo( path );
3045 if ( fileInfo.suffix().compare( QLatin1String(
"xml" ), Qt::CaseInsensitive ) != 0 )
3049 if ( !QFile::exists( path ) )
3052 QFile inputFile( path );
3053 if ( !inputFile.open( QIODevice::ReadOnly ) )
3056 QTextStream stream( &inputFile );
3057 const QString line = stream.readLine();
3058 return line == QLatin1String(
"<!DOCTYPE qgis_style>" );
3061 bool QgsStyle::updateSymbol( StyleEntity type,
const QString &name )
3063 QDomDocument doc( QStringLiteral(
"dummy" ) );
3065 QByteArray xmlArray;
3066 QTextStream stream( &xmlArray );
3067 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
3068 stream.setCodec(
"UTF-8" );
3080 QgsDebugMsg( QStringLiteral(
"Update request received for unavailable symbol" ) );
3085 if ( symEl.isNull() )
3087 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
3090 symEl.save( stream, 4 );
3092 xmlArray.constData(), name.toUtf8().constData() );
3101 QgsDebugMsg( QStringLiteral(
"Update request received for unavailable symbol" ) );
3105 symEl = doc.createElement( QStringLiteral(
"symbol" ) );
3106 symEl.setAttribute( QStringLiteral(
"type" ), m3dSymbols.value( name )->type() );
3108 if ( symEl.isNull() )
3110 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
3113 symEl.save( stream, 4 );
3115 xmlArray.constData(), name.toUtf8().constData() );
3123 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable color ramp." ) );
3127 std::unique_ptr< QgsColorRamp > ramp(
colorRamp( name ) );
3129 if ( symEl.isNull() )
3131 QgsDebugMsg( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
3134 symEl.save( stream, 4 );
3136 xmlArray.constData(), name.toUtf8().constData() );
3144 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable text format." ) );
3150 if ( symEl.isNull() )
3152 QgsDebugMsg( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
3155 symEl.save( stream, 4 );
3157 xmlArray.constData(), name.toUtf8().constData() );
3165 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable label settings." ) );
3171 if ( symEl.isNull() )
3173 QgsDebugMsg( QStringLiteral(
"Couldn't convert label settings to valid XML!" ) );
3176 symEl.save( stream, 4 );
3178 xmlArray.constData(), name.toUtf8().constData() );
3186 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable legend patch shape." ) );
3191 symEl = doc.createElement( QStringLiteral(
"shape" ) );
3193 symEl.save( stream, 4 );
3195 xmlArray.constData(), name.toUtf8().constData() );
3202 QgsDebugMsg( QStringLiteral(
"Updating the unsupported StyleEntity" ) );
3208 if ( !runEmptyQuery( query ) )
3210 QgsDebugMsg( QStringLiteral(
"Couldn't update symbol into the database!" ) );
3246 mCachedTags[ type ].remove( name );
3249 bool QgsStyle::createStyleMetadataTableIfNeeded()
3252 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='stylemetadata'" );
3255 statement = mCurrentDB.
prepare( query, rc );
3257 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
3261 "id INTEGER PRIMARY KEY,"\
3264 runEmptyQuery( query );
3266 runEmptyQuery( query );
3275 void QgsStyle::upgradeIfRequired()
3279 if ( !createStyleMetadataTableIfNeeded() )
3281 const QString query =
qgs_sqlite3_mprintf(
"SELECT value FROM stylemetadata WHERE key='version'" );
3284 if ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
3296 runEmptyQuery( query );
3306 return QStringLiteral(
"symbol" );
3309 return QStringLiteral(
"colorramp" );
3312 return QStringLiteral(
"textformat" );
3315 return QStringLiteral(
"labelsettings" );
3318 return QStringLiteral(
"legendpatchshapes" );
3321 return QStringLiteral(
"symbol3d" );
3324 return QStringLiteral(
"tag" );
3327 return QStringLiteral(
"smartgroup" );
3337 return QStringLiteral(
"tagmap" );
3340 return QStringLiteral(
"ctagmap" );
3343 return QStringLiteral(
"tftagmap" );
3346 return QStringLiteral(
"lstagmap" );
3349 return QStringLiteral(
"lpstagmap" );
3352 return QStringLiteral(
"symbol3dtagmap" );
3366 return QStringLiteral(
"symbol_id" );
3369 return QStringLiteral(
"colorramp_id" );
3372 return QStringLiteral(
"textformat_id" );
3375 return QStringLiteral(
"labelsettings_id" );
3378 return QStringLiteral(
"legendpatchshape_id" );
3381 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.
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 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.
bool saveLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool favorite, const QStringList &tags)
Adds label settings to the database.
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.
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()
QgsStyle()
Constructor for QgsStyle.
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.
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 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.
bool save(QString filename=QString())
Saves style into a file (will use current filename if empty string is passed)
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.
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.
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...
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.
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