44#include <QDomDocument>
47#include <QDomNodeList>
52#include "moc_qgsstyle.cpp"
54#define STYLE_CURRENT_VERSION "2"
79QgsStyle *QgsStyle::sDefaultStyle =
nullptr;
86 simpleMarker->setStrokeWidth( 0.4 );
87 mPatchMarkerSymbol = std::make_unique< QgsMarkerSymbol >(
QgsSymbolLayerList() << simpleMarker.release() );
89 auto simpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 84, 176, 74 ), 0.6 );
90 mPatchLineSymbol = std::make_unique< QgsLineSymbol >(
QgsSymbolLayerList() << simpleLine.release() );
92 auto gradientFill = std::make_unique< QgsGradientFillSymbolLayer >( QColor( 66, 150, 63 ), QColor( 84, 176, 74 ) );
93 auto simpleOutline = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 56, 128, 54 ), 0.26 );
94 mPatchFillSymbol = std::make_unique< QgsFillSymbol >(
QgsSymbolLayerList() << gradientFill.release() << simpleOutline.release() );
115 switch ( entity->
type() )
149 static QString sStyleFilename;
150 if ( !sDefaultStyle )
156 if ( !QFile::exists( sStyleFilename ) )
159 sDefaultStyle->createDatabase( sStyleFilename );
164 sDefaultStyle->createStyleMetadataTableIfNeeded();
171 sDefaultStyle->mInitialized =
false;
174 sDefaultStyle->initializeDefaultStyle( sStyleFilename );
177 sDefaultStyle->setName( QObject::tr(
"Default" ) );
179 else if ( initialize && !sDefaultStyle->mInitialized )
182 sDefaultStyle->initializeDefaultStyle( sStyleFilename );
184 return sDefaultStyle;
187void QgsStyle::initializeDefaultStyle(
const QString &filename )
189 Q_ASSERT(
this == sDefaultStyle );
190 if (
this != sDefaultStyle )
206 delete sDefaultStyle;
207 sDefaultStyle =
nullptr;
212 qDeleteAll( mSymbols );
213 qDeleteAll( mColorRamps );
214 qDeleteAll( m3dSymbols );
218 mTextFormats.clear();
222 mCachedFavorites.clear();
231 auto it = mSymbols.constFind(
name );
232 if ( it != mSymbols.constEnd() )
253 QDomDocument doc( QStringLiteral(
"dummy" ) );
255 if ( symEl.isNull() )
257 QgsDebugError( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
262 QTextStream stream( &xmlArray );
263#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
264 stream.setCodec(
"UTF-8" );
266 symEl.save( stream, 4 );
268 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
270 if ( !runEmptyQuery( query ) )
272 QgsDebugError( QStringLiteral(
"Couldn't insert symbol into the database!" ) );
334 return mSymbols.value(
name );
339 return mSymbols.count();
344 return mSymbols.keys();
354 auto it = mColorRamps.constFind(
name );
355 if ( it != mColorRamps.constEnd() )
376 auto it = mTextFormats.find(
name );
377 if ( it != mTextFormats.end() )
380 mTextFormats.erase( it );
381 mTextFormats.insert(
name, format );
387 mTextFormats.insert(
name, format );
398 auto it = mLabelSettings.find(
name );
399 if ( it != mLabelSettings.end() )
402 mLabelSettings.erase( it );
403 mLabelSettings.insert(
name, settings );
409 mLabelSettings.insert(
name, settings );
420 auto it = mLegendPatchShapes.find(
name );
421 if ( it != mLegendPatchShapes.end() )
424 mLegendPatchShapes.erase( it );
425 mLegendPatchShapes.insert(
name, shape );
431 mLegendPatchShapes.insert(
name, shape );
442 auto it = m3dSymbols.constFind(
name );
443 if ( it != m3dSymbols.constEnd() )
464 QDomDocument doc( QStringLiteral(
"dummy" ) );
467 if ( rampEl.isNull() )
469 QgsDebugError( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
474 QTextStream stream( &xmlArray );
475#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
476 stream.setCodec(
"UTF-8" );
478 rampEl.save( stream, 4 );
479 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO colorramp VALUES (NULL, '%q', '%q', %d);",
480 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
481 if ( !runEmptyQuery( query ) )
483 QgsDebugError( QStringLiteral(
"Couldn't insert colorramp into the database!" ) );
505 return ramp ? ramp->
clone() :
nullptr;
515 return mColorRamps.count();
520 return mColorRamps.keys();
523void QgsStyle::handleDeferred3DSymbolCreation()
525 for (
auto it = mDeferred3DsymbolElements.constBegin(); it != mDeferred3DsymbolElements.constEnd(); ++it )
527 const QString symbolType = it.value().attribute( QStringLiteral(
"type" ) );
541 mDeferred3DsymbolElements.clear();
544bool QgsStyle::openDatabase(
const QString &filename )
546 int rc = mCurrentDB.open( filename );
549 mErrorString = QStringLiteral(
"Couldn't open the style database: %1" ).arg( mCurrentDB.errorMessage() );
558 mErrorString.clear();
559 if ( !openDatabase( filename ) )
561 mErrorString = QStringLiteral(
"Unable to create database" );
573 mErrorString.clear();
574 if ( !openDatabase( QStringLiteral(
":memory:" ) ) )
576 mErrorString = QStringLiteral(
"Unable to create temporary memory database" );
589 "id INTEGER PRIMARY KEY,"\
592 "favorite INTEGER);"\
593 "CREATE TABLE colorramp("\
594 "id INTEGER PRIMARY KEY,"\
597 "favorite INTEGER);"\
598 "CREATE TABLE textformat("\
599 "id INTEGER PRIMARY KEY,"\
602 "favorite INTEGER);"\
603 "CREATE TABLE labelsettings("\
604 "id INTEGER PRIMARY KEY,"\
607 "favorite INTEGER);"\
608 "CREATE TABLE legendpatchshapes("\
609 "id INTEGER PRIMARY KEY,"\
612 "favorite INTEGER);"\
613 "CREATE TABLE symbol3d("\
614 "id INTEGER PRIMARY KEY,"\
617 "favorite INTEGER);"\
619 "id INTEGER PRIMARY KEY,"\
621 "CREATE TABLE tagmap("\
622 "tag_id INTEGER NOT NULL,"\
623 "symbol_id INTEGER);"\
624 "CREATE TABLE ctagmap("\
625 "tag_id INTEGER NOT NULL,"\
626 "colorramp_id INTEGER);"\
627 "CREATE TABLE tftagmap("\
628 "tag_id INTEGER NOT NULL,"\
629 "textformat_id INTEGER);"\
630 "CREATE TABLE lstagmap("\
631 "tag_id INTEGER NOT NULL,"\
632 "labelsettings_id INTEGER);"\
633 "CREATE TABLE lpstagmap("\
634 "tag_id INTEGER NOT NULL,"\
635 "legendpatchshape_id INTEGER);"\
636 "CREATE TABLE symbol3dtagmap("\
637 "tag_id INTEGER NOT NULL,"\
638 "symbol3d_id INTEGER);"\
639 "CREATE TABLE smartgroup("\
640 "id INTEGER PRIMARY KEY,"\
643 runEmptyQuery( query );
648 mErrorString.clear();
651 if ( !openDatabase( filename ) )
653 mErrorString = QStringLiteral(
"Unable to open database file specified" );
659 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='textformat'" );
662 statement = mCurrentDB.prepare( query, rc );
663 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
666 "id INTEGER PRIMARY KEY,"\
669 "favorite INTEGER);"\
670 "CREATE TABLE tftagmap("\
671 "tag_id INTEGER NOT NULL,"\
672 "textformat_id INTEGER);" );
673 runEmptyQuery( query );
676 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='labelsettings'" );
677 statement = mCurrentDB.prepare( query, rc );
678 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
681 "id INTEGER PRIMARY KEY,"\
684 "favorite INTEGER);"\
685 "CREATE TABLE lstagmap("\
686 "tag_id INTEGER NOT NULL,"\
687 "labelsettings_id INTEGER);" );
688 runEmptyQuery( query );
691 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='legendpatchshapes'" );
692 statement = mCurrentDB.prepare( query, rc );
693 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
696 "id INTEGER PRIMARY KEY,"\
699 "favorite INTEGER);"\
700 "CREATE TABLE lpstagmap("\
701 "tag_id INTEGER NOT NULL,"\
702 "legendpatchshape_id INTEGER);" );
703 runEmptyQuery( query );
707 statement = mCurrentDB.prepare( query, rc );
708 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
711 "id INTEGER PRIMARY KEY,"\
714 "favorite INTEGER);"\
715 "CREATE TABLE symbol3dtagmap("\
716 "tag_id INTEGER NOT NULL,"\
717 "symbol3d_id INTEGER);" );
718 runEmptyQuery( query );
723 "UPDATE colorramp SET favorite=0 WHERE favorite IS NULL;"
724 "UPDATE textformat SET favorite=0 WHERE favorite IS NULL;"
725 "UPDATE labelsettings SET favorite=0 WHERE favorite IS NULL;"
726 "UPDATE legendpatchshapes SET favorite=0 WHERE favorite IS NULL;"
727 "UPDATE symbol3d SET favorite=0 WHERE favorite IS NULL;"
729 runEmptyQuery( query );
735 statement = mCurrentDB.prepare( query, rc );
737 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
743 if ( !doc.setContent( xmlstring ) )
749 QDomElement symElement = doc.documentElement();
752 mSymbols.insert( symbolName,
symbol.release() );
759 statement = mCurrentDB.prepare( query, rc );
760 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
766 if ( !doc.setContent( xmlstring ) )
771 QDomElement rampElement = doc.documentElement();
774 mColorRamps.insert( rampName, ramp.release() );
781 statement = mCurrentDB.prepare( query, rc );
782 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
788 if ( !doc.setContent( xmlstring ) )
793 QDomElement formatElement = doc.documentElement();
796 mTextFormats.insert( formatName, format );
803 statement = mCurrentDB.prepare( query, rc );
804 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
810 if ( !doc.setContent( xmlstring ) )
812 QgsDebugError(
"Cannot open label settings " + settingsName );
815 QDomElement settingsElement = doc.documentElement();
818 mLabelSettings.insert( settingsName, settings );
825 statement = mCurrentDB.prepare( query, rc );
826 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
832 if ( !doc.setContent( xmlstring ) )
834 QgsDebugError(
"Cannot open legend patch shape " + settingsName );
837 QDomElement settingsElement = doc.documentElement();
840 mLegendPatchShapes.insert( settingsName, shape );
847 statement = mCurrentDB.prepare( query, rc );
851 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
857 if ( !doc.setContent( xmlstring ) )
862 QDomElement settingsElement = doc.documentElement();
864 if ( !registry3dPopulated )
866 mDeferred3DsymbolElements.insert( settingsName, settingsElement );
870 const QString symbolType = settingsElement.attribute( QStringLiteral(
"type" ) );
875 m3dSymbols.insert( settingsName,
symbol.release() );
886 mFileName = filename;
887 createStyleMetadataTableIfNeeded();
893 mErrorString.clear();
895 if ( !filename.isEmpty() )
896 mFileName = filename;
903 mFileName = filename;
908 if ( mSymbols.contains( newName ) )
910 QgsDebugError( QStringLiteral(
"Symbol of new name already exists" ) );
918 mSymbols.insert( newName,
symbol );
922 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database to tag." ) );
929 QgsDebugError( QStringLiteral(
"No such symbol for tagging in database: " ) + oldName );
948 if ( mColorRamps.contains( newName ) )
950 QgsDebugError( QStringLiteral(
"Color ramp of new name already exists." ) );
958 mColorRamps.insert( newName, ramp );
964 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM colorramp WHERE name='%q'", oldName.toUtf8().constData() );
966 statement = mCurrentDB.prepare( query, nErr );
967 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
969 rampid = sqlite3_column_int( statement.get(), 0 );
984 QDomDocument doc( QStringLiteral(
"dummy" ) );
987 if ( formatElem.isNull() )
989 QgsDebugError( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
994 QTextStream stream( &xmlArray );
995#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
996 stream.setCodec(
"UTF-8" );
998 formatElem.save( stream, 4 );
999 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO textformat VALUES (NULL, '%q', '%q', %d);",
1000 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1001 if ( !runEmptyQuery( query ) )
1003 QgsDebugError( QStringLiteral(
"Couldn't insert text format into the database!" ) );
1024 if ( mTextFormats.contains( newName ) )
1026 QgsDebugError( QStringLiteral(
"Text format of new name already exists." ) );
1030 if ( !mTextFormats.contains( oldName ) )
1034 mTextFormats.insert( newName, format );
1040 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM textformat WHERE name='%q'", oldName.toUtf8().constData() );
1042 statement = mCurrentDB.prepare( query, nErr );
1043 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1045 textFormatId = sqlite3_column_int( statement.get(), 0 );
1060 QDomDocument doc( QStringLiteral(
"dummy" ) );
1063 if ( settingsElem.isNull() )
1065 QgsDebugError( QStringLiteral(
"Couldn't convert label settings to valid XML!" ) );
1069 QByteArray xmlArray;
1070 QTextStream stream( &xmlArray );
1071#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1072 stream.setCodec(
"UTF-8" );
1074 settingsElem.save( stream, 4 );
1075 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO labelsettings VALUES (NULL, '%q', '%q', %d);",
1076 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1077 if ( !runEmptyQuery( query ) )
1079 QgsDebugError( QStringLiteral(
"Couldn't insert label settings into the database!" ) );
1100 if ( mLabelSettings.contains( newName ) )
1102 QgsDebugError( QStringLiteral(
"Label settings of new name already exists." ) );
1106 if ( !mLabelSettings.contains( oldName ) )
1110 mLabelSettings.insert( newName, settings );
1116 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM labelsettings WHERE name='%q'", oldName.toUtf8().constData() );
1118 statement = mCurrentDB.prepare( query, nErr );
1119 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1136 QDomDocument doc( QStringLiteral(
"dummy" ) );
1137 QDomElement shapeElem = doc.createElement( QStringLiteral(
"shape" ) );
1140 QByteArray xmlArray;
1141 QTextStream stream( &xmlArray );
1142#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1143 stream.setCodec(
"UTF-8" );
1145 shapeElem.save( stream, 4 );
1146 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO legendpatchshapes VALUES (NULL, '%q', '%q', %d);",
1147 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1148 if ( !runEmptyQuery( query ) )
1150 QgsDebugError( QStringLiteral(
"Couldn't insert legend patch shape into the database!" ) );
1165 if ( mLegendPatchShapes.contains( newName ) )
1167 QgsDebugError( QStringLiteral(
"Legend patch shape of new name already exists." ) );
1171 if ( !mLegendPatchShapes.contains( oldName ) )
1175 mLegendPatchShapes.insert( newName, shape );
1181 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM legendpatchshapes WHERE name='%q'", oldName.toUtf8().constData() );
1183 statement = mCurrentDB.prepare( query, nErr );
1184 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1202 auto it = mDefaultPatchCache[
static_cast< int >( type ) ].constFind( size );
1203 if ( it != mDefaultPatchCache[
static_cast< int >( type ) ].constEnd() )
1210 geom =
QgsGeometry( std::make_unique< QgsPoint >(
static_cast< int >( size.width() ) / 2,
static_cast< int >( size.height() ) / 2 ) );
1217 double y =
static_cast< int >( size.height() ) / 2 + 0.5;
1218 geom =
QgsGeometry( std::make_unique< QgsLineString >( ( QVector< double >() << 0 << size.width() ),
1219 ( QVector< double >() << y << y ) ) );
1225 geom =
QgsGeometry( std::make_unique< QgsPolygon >(
1226 new QgsLineString( QVector< double >() << 0 <<
static_cast< int >( size.width() ) <<
static_cast< int >( size.width() ) << 0 << 0,
1227 QVector< double >() <<
static_cast< int >( size.height() ) <<
static_cast< int >( size.height() ) << 0 << 0 <<
static_cast< int >( size.height() ) ) ) );
1236 mDefaultPatchCache[
static_cast< int >( type ) ][size ] = res;
1243 return QList<QList<QPolygonF> >();
1245 auto it = mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ].constFind( size );
1246 if ( it != mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ].constEnd() )
1250 mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ][size ] = res;
1256 return textFormat( QStringLiteral(
"Default" ) );
1276 QDomDocument doc( QStringLiteral(
"dummy" ) );
1277 QDomElement elem = doc.createElement( QStringLiteral(
"symbol" ) );
1278 elem.setAttribute( QStringLiteral(
"type" ),
symbol->type() );
1281 QByteArray xmlArray;
1282 QTextStream stream( &xmlArray );
1283#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1284 stream.setCodec(
"UTF-8" );
1286 elem.save( stream, 4 );
1287 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO symbol3d VALUES (NULL, '%q', '%q', %d);",
1288 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1289 if ( !runEmptyQuery( query ) )
1291 QgsDebugError( QStringLiteral(
"Couldn't insert 3d symbol into the database!" ) );
1306 if ( m3dSymbols.contains( newName ) )
1308 QgsDebugError( QStringLiteral(
"3d symbol of new name already exists." ) );
1312 if ( !m3dSymbols.contains( oldName ) )
1316 m3dSymbols.insert( newName,
symbol );
1322 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM symbol3d WHERE name='%q'", oldName.toUtf8().constData() );
1324 statement = mCurrentDB.prepare( query, nErr );
1325 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1340 return m3dSymbols.keys();
1347 QgsDebugError( QStringLiteral(
"Cannot Open database for getting favorite symbols" ) );
1348 return QStringList();
1357 return QStringList();
1360 query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT name FROM %1 WHERE favorite=1" ).arg( entityTableName( type ) ).toLocal8Bit().data() );
1366 statement = mCurrentDB.prepare( query, nErr );
1368 QStringList symbols;
1369 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1381 QgsDebugError( QStringLiteral(
"Cannot open database to get symbols of tagid %1" ).arg( tagid ) );
1382 return QStringList();
1391 return QStringList();
1394 subquery =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT %1 FROM %2 WHERE tag_id=%d" ).arg( tagmapEntityIdFieldName( type ),
1395 tagmapTableName( type ) ).toLocal8Bit().data(), tagid );
1401 statement = mCurrentDB.prepare( subquery, nErr );
1404 QStringList symbols;
1405 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1407 int id = sqlite3_column_int( statement.get(), 0 );
1409 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT name FROM %1 WHERE id=%d" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
id );
1413 statement2 = mCurrentDB.prepare( query, rc );
1414 while ( rc == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1429 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO tag VALUES (NULL, '%q')", tagname.toUtf8().constData() );
1431 statement = mCurrentDB.prepare( query, nErr );
1432 if ( nErr == SQLITE_OK )
1433 ( void )sqlite3_step( statement.get() );
1436 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1440 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
1446 return QStringList();
1452 statement = mCurrentDB.prepare( query, nError );
1454 QStringList tagList;
1455 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1465 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET name='%q' WHERE id=%d" ).arg( entityTableName( type ) ).toLocal8Bit().data(), newName.toUtf8().constData(),
id );
1467 const bool result = runEmptyQuery( query );
1470 mErrorString = QStringLiteral(
"Could not rename!" );
1474 mCachedTags.clear();
1475 mCachedFavorites.clear();
1500 bool groupRemoved =
false;
1505 query =
qgs_sqlite3_mprintf(
"DELETE FROM tag WHERE id=%d; DELETE FROM tagmap WHERE tag_id=%d",
id,
id );
1506 groupRemoved =
true;
1510 groupRemoved =
true;
1514 query =
qgs_sqlite3_mprintf( QStringLiteral(
"DELETE FROM %1 WHERE id=%d; DELETE FROM %2 WHERE %3=%d" ).arg(
1515 entityTableName( type ),
1516 tagmapTableName( type ),
1517 tagmapEntityIdFieldName( type )
1518 ).toLocal8Bit().data(),
id,
id );
1522 bool result =
false;
1523 if ( !runEmptyQuery( query ) )
1525 QgsDebugError( QStringLiteral(
"Could not delete entity!" ) );
1529 mCachedTags.clear();
1530 mCachedFavorites.clear();
1535 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1554 std::unique_ptr< QgsSymbol >
symbol( mSymbols.take(
name ) );
1563 std::unique_ptr< QgsAbstract3DSymbol >
symbol( m3dSymbols.take(
name ) );
1572 std::unique_ptr< QgsColorRamp > ramp( mColorRamps.take(
name ) );
1580 auto it = mTextFormats.find(
name );
1581 if ( it == mTextFormats.end() )
1584 mTextFormats.erase( it );
1590 auto it = mLabelSettings.find(
name );
1591 if ( it == mLabelSettings.end() )
1594 mLabelSettings.erase( it );
1600 auto it = mLegendPatchShapes.find(
name );
1601 if ( it == mLegendPatchShapes.end() )
1604 mLegendPatchShapes.erase( it );
1611 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database to modify." ) );
1621 const bool result =
remove( type,
id );
1624 mCachedTags[ type ].remove(
name );
1625 mCachedFavorites[ type ].remove(
name );
1654bool QgsStyle::runEmptyQuery(
const QString &query )
1659 char *zErr =
nullptr;
1660 int nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1662 if ( nErr != SQLITE_OK )
1665 sqlite3_free( zErr );
1668 return nErr == SQLITE_OK;
1679 QgsDebugError( QStringLiteral(
"Wrong entity value. cannot apply group" ) );
1683 query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET favorite=1 WHERE name='%q'" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
1684 name.toUtf8().constData() );
1688 const bool res = runEmptyQuery( query );
1698 mCachedFavorites[ type ].insert(
name,
true );
1715 QgsDebugError( QStringLiteral(
"Wrong entity value. cannot apply group" ) );
1719 query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET favorite=0 WHERE name='%q'" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
name.toUtf8().constData() );
1723 const bool res = runEmptyQuery( query );
1726 mCachedFavorites[ type ].insert(
name,
false );
1737 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database to search" ) );
1738 return QStringList();
1747 return QStringList();
1750 item = entityTableName( type );
1755 item.toUtf8().constData(), qword.toUtf8().constData() );
1758 int nErr; statement = mCurrentDB.prepare( query, nErr );
1760 QSet< QString > symbols;
1761 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1767 query =
qgs_sqlite3_mprintf(
"SELECT id FROM tag WHERE name LIKE '%%%q%%'", qword.toUtf8().constData() );
1768 statement = mCurrentDB.prepare( query, nErr );
1771 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1776 QString dummy = tagids.join( QLatin1String(
", " ) );
1777 query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT %1 FROM %2 WHERE tag_id IN (%q)" ).arg( tagmapEntityIdFieldName( type ),
1778 tagmapTableName( type ) ).toLocal8Bit().data(), dummy.toUtf8().constData() );
1780 statement = mCurrentDB.prepare( query, nErr );
1782 QStringList symbolids;
1783 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1788 dummy = symbolids.join( QLatin1String(
", " ) );
1790 item.toUtf8().constData(), dummy.toUtf8().constData() );
1791 statement = mCurrentDB.prepare( query, nErr );
1792 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1797 return QStringList( symbols.constBegin(), symbols.constEnd() );
1804 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database to tag." ) );
1827 const auto constTags =
tags;
1828 for (
const QString &t : constTags )
1831 if ( !
tag.isEmpty() )
1843 QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"INSERT INTO %1 VALUES (%d,%d)" ).arg( tagmapTableName( type ) ).toLocal8Bit().data(), tagid, symbolid );
1845 char *zErr =
nullptr;
1847 nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1851 sqlite3_free( zErr );
1857 clearCachedTags( type,
symbol );
1867 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database for detagging." ) );
1882 if ( symbolid == 0 )
1887 const auto constTags =
tags;
1888 for (
const QString &
tag : constTags )
1893 statement2 = mCurrentDB.prepare( query, nErr );
1896 if ( nErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1898 tagid = sqlite3_column_int( statement2.get(), 0 );
1904 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 );
1905 runEmptyQuery( query );
1909 clearCachedTags( type,
symbol );
1922 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database for detagging." ) );
1937 if ( symbolid == 0 )
1943 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"DELETE FROM %1 WHERE %2=%d" ).arg( tagmapTableName( type ),
1944 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1945 runEmptyQuery( query );
1947 clearCachedTags( type,
symbol );
1962 return QStringList();
1966 auto it = mCachedTags[ type ].constFind(
symbol );
1967 if ( it != mCachedTags[ type ].constEnd() )
1975 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
1976 return QStringList();
1981 return QStringList();
1984 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT tag_id FROM %1 WHERE %2=%d" ).arg( tagmapTableName( type ),
1985 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1988 int nErr; statement = mCurrentDB.prepare( query, nErr );
1990 QStringList tagList;
1991 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1993 QString subquery =
qgs_sqlite3_mprintf(
"SELECT name FROM tag WHERE id=%d", sqlite3_column_int( statement.get(), 0 ) );
1997 statement2 = mCurrentDB.prepare( subquery, pErr );
1998 if ( pErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
2005 mCachedTags[ type ].insert(
symbol, tagList );
2014 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
2026 auto it = mCachedFavorites[ type ].constFind(
name );
2027 if ( it != mCachedFavorites[ type ].constEnd() )
2033 const QStringList names =
allNames( type );
2034 if ( !names.contains(
name ) )
2040 for (
const QString &n : names )
2042 const bool isFav = favorites.contains( n );
2046 mCachedFavorites[ type ].insert( n, isFav );
2055 QgsDebugError( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
2082 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT tag_id FROM %1 WHERE tag_id=%d AND %2=%d" ).arg( tagmapTableName( type ),
2083 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), tagid, symbolid );
2086 int nErr; statement = mCurrentDB.prepare( query, nErr );
2088 return ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW );
2100 statement = mCurrentDB.prepare( query, nError );
2103 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2111int QgsStyle::getId(
const QString &table,
const QString &name )
2113 QString lowerName(
name.toLower() );
2114 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE LOWER(name)='%q'", table.toUtf8().constData(), lowerName.toUtf8().constData() );
2117 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2120 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2122 id = sqlite3_column_int( statement.get(), 0 );
2127 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE name='%q'", table.toUtf8().constData(),
name.toUtf8().constData() );
2129 sqlite3_statement_unique_ptr statement;
2130 int nErr; statement = mCurrentDB.prepare( query, nErr );
2131 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2133 id = sqlite3_column_int( statement.get(), 0 );
2140QString QgsStyle::getName(
const QString &table,
int id )
const
2142 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM %q WHERE id='%q'", table.toUtf8().constData(), QString::number(
id ).toUtf8().constData() );
2144 sqlite3_statement_unique_ptr statement;
2145 int nErr; statement = mCurrentDB.prepare( query, nErr );
2148 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2158 return getId( QStringLiteral(
"symbol" ),
name );
2163 return getId( entityTableName( type ),
name );
2168 return getId( QStringLiteral(
"colorramp" ),
name );
2173 return mTextFormats.value(
name );
2178 return mTextFormats.count();
2183 return mTextFormats.keys();
2188 return getId( QStringLiteral(
"textformat" ),
name );
2193 return mLabelSettings.value(
name );
2198 return mLegendPatchShapes.value(
name );
2203 return mLegendPatchShapes.count();
2208 auto it = mLegendPatchShapes.constFind(
name );
2209 if ( it == mLegendPatchShapes.constEnd() )
2212 return it.value().symbolType();
2217 auto it = m3dSymbols.constFind(
name );
2218 if ( it != m3dSymbols.constEnd( ) )
2219 return it.value()->
clone();
2225 return m3dSymbols.count();
2230 auto it = m3dSymbols.constFind(
name );
2231 if ( it == m3dSymbols.constEnd() )
2232 return QList<Qgis::GeometryType>();
2234 return it.value()->compatibleGeometryTypes();
2239 auto it = mLabelSettings.constFind(
name );
2240 if ( it == mLabelSettings.constEnd() )
2243 return it.value().layerType;
2248 return mLabelSettings.count();
2253 return mLabelSettings.keys();
2258 return getId( QStringLiteral(
"labelsettings" ),
name );
2263 return mLegendPatchShapes.keys();
2271 return mPatchMarkerSymbol.get();
2274 return mPatchLineSymbol.get();
2277 return mPatchFillSymbol.get();
2287 return getId( QStringLiteral(
"tag" ),
name );
2292 return getId( QStringLiteral(
"smartgroup" ),
name );
2323 return QStringList();
2329 conditions.values( QStringLiteral(
"!tag" ) ),
2330 conditions.values( QStringLiteral(
"name" ) ),
2331 conditions.values( QStringLiteral(
"!name" ) ) );
2334int QgsStyle::addSmartgroup(
const QString &
name,
const QString &op,
const QStringList &matchTag,
const QStringList &noMatchTag,
const QStringList &matchName,
const QStringList &noMatchName )
2336 QDomDocument doc( QStringLiteral(
"dummy" ) );
2337 QDomElement smartEl = doc.createElement( QStringLiteral(
"smartgroup" ) );
2338 smartEl.setAttribute( QStringLiteral(
"name" ),
name );
2339 smartEl.setAttribute( QStringLiteral(
"operator" ), op );
2341 auto addCondition = [&doc, &smartEl](
const QString & constraint,
const QStringList & parameters )
2343 for (
const QString ¶m : parameters )
2345 QDomElement condEl = doc.createElement( QStringLiteral(
"condition" ) );
2346 condEl.setAttribute( QStringLiteral(
"constraint" ), constraint );
2347 condEl.setAttribute( QStringLiteral(
"param" ), param );
2348 smartEl.appendChild( condEl );
2351 addCondition( QStringLiteral(
"tag" ), matchTag );
2352 addCondition( QStringLiteral(
"!tag" ), noMatchTag );
2353 addCondition( QStringLiteral(
"name" ), matchName );
2354 addCondition( QStringLiteral(
"!name" ), noMatchName );
2356 QByteArray xmlArray;
2357 QTextStream stream( &xmlArray );
2358#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2359 stream.setCodec(
"UTF-8" );
2361 smartEl.save( stream, 4 );
2363 name.toUtf8().constData(), xmlArray.constData() );
2365 if ( runEmptyQuery( query ) )
2368 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
2371 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
2375 QgsDebugError( QStringLiteral(
"Couldn't add the smart group into the database!" ) );
2384 QgsDebugError( QStringLiteral(
"Cannot open database for listing groups" ) );
2393 statement = mCurrentDB.prepare( query, nError );
2396 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2409 QgsDebugError( QStringLiteral(
"Cannot open database for listing groups" ) );
2410 return QStringList();
2418 statement = mCurrentDB.prepare( query, nError );
2421 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2431 QStringList symbols;
2436 int nErr; statement = mCurrentDB.prepare( query, nErr );
2437 if ( !( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW ) )
2439 return QStringList();
2445 if ( !doc.setContent( xmlstr ) )
2447 QgsDebugError( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2449 QDomElement smartEl = doc.documentElement();
2450 QString op = smartEl.attribute( QStringLiteral(
"operator" ) );
2451 QDomNodeList conditionNodes = smartEl.childNodes();
2453 bool firstSet =
true;
2454 for (
int i = 0; i < conditionNodes.count(); i++ )
2456 QDomElement condEl = conditionNodes.at( i ).toElement();
2457 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2458 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2460 QStringList resultNames;
2462 if ( constraint == QLatin1String(
"tag" ) )
2466 else if ( constraint == QLatin1String(
"name" ) )
2468 resultNames =
allNames( type ).filter( param, Qt::CaseInsensitive );
2470 else if ( constraint == QLatin1String(
"!tag" ) )
2474 for (
const QString &
name : unwanted )
2476 resultNames.removeAll(
name );
2479 else if ( constraint == QLatin1String(
"!name" ) )
2481 const QStringList all =
allNames( type );
2482 for (
const QString &str : all )
2484 if ( !str.contains( param, Qt::CaseInsensitive ) )
2492 symbols = resultNames;
2497 if ( op == QLatin1String(
"OR" ) )
2499 symbols << resultNames;
2501 else if ( op == QLatin1String(
"AND" ) )
2503 QStringList dummy = symbols;
2505 for (
const QString &result : std::as_const( resultNames ) )
2507 if ( dummy.contains( result ) )
2516 const QSet< QString > uniqueSet( symbols.constBegin(), symbols.constEnd() );
2517 QStringList unique( uniqueSet.begin(), uniqueSet.end() );
2518 std::sort( unique.begin(), unique.end() );
2526 QgsDebugError( QStringLiteral(
"Cannot open database for listing groups" ) );
2536 statement = mCurrentDB.prepare( query, nError );
2537 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2541 if ( !doc.setContent( xmlstr ) )
2543 QgsDebugError( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2546 QDomElement smartEl = doc.documentElement();
2547 QDomNodeList conditionNodes = smartEl.childNodes();
2549 for (
int i = 0; i < conditionNodes.count(); i++ )
2551 QDomElement condEl = conditionNodes.at( i ).toElement();
2552 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2553 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2555 condition.insert( constraint, param );
2566 QgsDebugError( QStringLiteral(
"Cannot open database for listing groups" ) );
2576 statement = mCurrentDB.prepare( query, nError );
2577 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2581 if ( !doc.setContent( xmlstr ) )
2583 QgsDebugError( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2585 QDomElement smartEl = doc.documentElement();
2586 op = smartEl.attribute( QStringLiteral(
"operator" ) );
2594 if ( filename.isEmpty() )
2596 QgsDebugError( QStringLiteral(
"Invalid filename for style export." ) );
2600 QDomDocument doc( QStringLiteral(
"qgis_style" ) );
2601 QDomElement root = doc.createElement( QStringLiteral(
"qgis_style" ) );
2603 doc.appendChild( root );
2613 QDomNodeList symbolsList = symbolsElem.elementsByTagName( QStringLiteral(
"symbol" ) );
2614 int nbSymbols = symbolsList.count();
2615 for (
int i = 0; i < nbSymbols; ++i )
2617 QDomElement
symbol = symbolsList.at( i ).toElement();
2618 QString
name =
symbol.attribute( QStringLiteral(
"name" ) );
2620 if (
tags.count() > 0 )
2622 symbol.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2624 if ( favoriteSymbols.contains(
name ) )
2626 symbol.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2631 QDomElement rampsElem = doc.createElement( QStringLiteral(
"colorramps" ) );
2632 for ( QMap<QString, QgsColorRamp *>::const_iterator itr = mColorRamps.constBegin(); itr != mColorRamps.constEnd(); ++itr )
2636 if (
tags.count() > 0 )
2638 rampEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2640 if ( favoriteColorramps.contains( itr.key() ) )
2642 rampEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2644 rampsElem.appendChild( rampEl );
2648 QDomElement textFormatsElem = doc.createElement( QStringLiteral(
"textformats" ) );
2649 for (
auto it = mTextFormats.constBegin(); it != mTextFormats.constEnd(); ++it )
2651 QDomElement textFormatEl = doc.createElement( QStringLiteral(
"textformat" ) );
2652 textFormatEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2654 textFormatEl.appendChild( textStyleEl );
2656 if (
tags.count() > 0 )
2658 textFormatEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2660 if ( favoriteTextFormats.contains( it.key() ) )
2662 textFormatEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2664 textFormatsElem.appendChild( textFormatEl );
2668 QDomElement labelSettingsElem = doc.createElement( QStringLiteral(
"labelsettings" ) );
2669 for (
auto it = mLabelSettings.constBegin(); it != mLabelSettings.constEnd(); ++it )
2671 QDomElement labelSettingsEl = doc.createElement( QStringLiteral(
"labelsetting" ) );
2672 labelSettingsEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2674 labelSettingsEl.appendChild( defEl );
2676 if (
tags.count() > 0 )
2678 labelSettingsEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2680 if ( favoriteTextFormats.contains( it.key() ) )
2682 labelSettingsEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2684 labelSettingsElem.appendChild( labelSettingsEl );
2688 QDomElement legendPatchShapesElem = doc.createElement( QStringLiteral(
"legendpatchshapes" ) );
2689 for (
auto it = mLegendPatchShapes.constBegin(); it != mLegendPatchShapes.constEnd(); ++it )
2691 QDomElement legendPatchShapeEl = doc.createElement( QStringLiteral(
"legendpatchshape" ) );
2692 legendPatchShapeEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2693 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2695 legendPatchShapeEl.appendChild( defEl );
2697 if (
tags.count() > 0 )
2699 legendPatchShapeEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2701 if ( favoriteLegendShapes.contains( it.key() ) )
2703 legendPatchShapeEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2705 legendPatchShapesElem.appendChild( legendPatchShapeEl );
2709 QDomElement symbols3DElem = doc.createElement( QStringLiteral(
"symbols3d" ) );
2710 for (
auto it = m3dSymbols.constBegin(); it != m3dSymbols.constEnd(); ++it )
2712 QDomElement symbolEl = doc.createElement( QStringLiteral(
"symbol3d" ) );
2713 symbolEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2714 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2715 defEl.setAttribute( QStringLiteral(
"type" ), it.value()->type() );
2717 symbolEl.appendChild( defEl );
2719 if (
tags.count() > 0 )
2721 symbolEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2723 if ( favorite3DSymbols.contains( it.key() ) )
2725 symbolEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2727 symbols3DElem.appendChild( symbolEl );
2730 root.appendChild( symbolsElem );
2731 root.appendChild( rampsElem );
2732 root.appendChild( textFormatsElem );
2733 root.appendChild( labelSettingsElem );
2734 root.appendChild( legendPatchShapesElem );
2735 root.appendChild( symbols3DElem );
2738 QFile f( filename );
2739 if ( !f.open( QFile::WriteOnly | QIODevice::Truncate ) )
2741 mErrorString =
"Couldn't open file for writing: " + filename;
2745 QTextStream ts( &f );
2746#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2747 ts.setCodec(
"UTF-8" );
2762 mErrorString = QString();
2763 QDomDocument doc( QStringLiteral(
"style" ) );
2764 QFile f( filename );
2765 if ( !f.open( QFile::ReadOnly ) )
2767 mErrorString = QStringLiteral(
"Unable to open the specified file" );
2768 QgsDebugError( QStringLiteral(
"Error opening the style XML file." ) );
2772 if ( !doc.setContent( &f ) )
2774 mErrorString = QStringLiteral(
"Unable to understand the style file: %1" ).arg( filename );
2781 QDomElement docEl = doc.documentElement();
2782 if ( docEl.tagName() != QLatin1String(
"qgis_style" ) )
2784 mErrorString =
"Incorrect root tag in style: " + docEl.tagName();
2788 const QString version = docEl.attribute( QStringLiteral(
"version" ) );
2789 if ( version != QLatin1String(
STYLE_CURRENT_VERSION ) && version != QLatin1String(
"0" ) && version != QLatin1String(
"1" ) )
2791 mErrorString =
"Unknown style file version: " + version;
2797 QDomElement symbolsElement = docEl.firstChildElement( QStringLiteral(
"symbols" ) );
2798 QDomElement e = symbolsElement.firstChildElement();
2802 runEmptyQuery( query );
2807 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2809 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2810 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2816 if ( e.tagName() == QLatin1String(
"symbol" ) )
2818 QString
name = e.attribute( QStringLiteral(
"name" ) );
2820 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2822 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2824 bool favorite =
false;
2825 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2833 QgsSymbol *symbolPtr =
symbol.get();
2853 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
2860 QDomElement rampsElement = docEl.firstChildElement( QStringLiteral(
"colorramps" ) );
2861 e = rampsElement.firstChildElement();
2862 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2864 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2865 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2871 if ( e.tagName() == QLatin1String(
"colorramp" ) )
2873 QString
name = e.attribute( QStringLiteral(
"name" ) );
2875 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2877 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2879 bool favorite =
false;
2880 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2888 QgsColorRamp *rampPtr = ramp.get();
2905 if ( qobject_cast< QGuiApplication * >( QCoreApplication::instance() ) )
2909 const QDomElement textFormatElement = docEl.firstChildElement( QStringLiteral(
"textformats" ) );
2910 e = textFormatElement.firstChildElement();
2911 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2913 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2914 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2920 if ( e.tagName() == QLatin1String(
"textformat" ) )
2922 QString
name = e.attribute( QStringLiteral(
"name" ) );
2924 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2926 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2928 bool favorite =
false;
2929 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2934 QgsTextFormat format;
2935 const QDomElement styleElem = e.firstChildElement();
2936 format.
readXml( styleElem, QgsReadWriteContext() );
2953 const QDomElement labelSettingsElement = docEl.firstChildElement( QStringLiteral(
"labelsettings" ) );
2954 e = labelSettingsElement.firstChildElement();
2955 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2957 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2958 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2964 if ( e.tagName() == QLatin1String(
"labelsetting" ) )
2966 QString
name = e.attribute( QStringLiteral(
"name" ) );
2968 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2970 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2972 bool favorite =
false;
2973 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2978 QgsPalLayerSettings settings;
2979 const QDomElement styleElem = e.firstChildElement();
2980 settings.
readXml( styleElem, QgsReadWriteContext() );
2998 const QDomElement legendPatchShapesElement = docEl.firstChildElement( QStringLiteral(
"legendpatchshapes" ) );
2999 e = legendPatchShapesElement.firstChildElement();
3000 for ( ; !e.isNull(); e = e.nextSiblingElement() )
3002 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
3003 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
3009 if ( e.tagName() == QLatin1String(
"legendpatchshape" ) )
3011 QString
name = e.attribute( QStringLiteral(
"name" ) );
3013 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
3015 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
3017 bool favorite =
false;
3018 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
3023 QgsLegendPatchShape shape;
3024 const QDomElement shapeElem = e.firstChildElement();
3025 shape.
readXml( shapeElem, QgsReadWriteContext() );
3042 const QDomElement symbols3DElement = docEl.firstChildElement( QStringLiteral(
"symbols3d" ) );
3043 e = symbols3DElement.firstChildElement();
3044 for ( ; !e.isNull(); e = e.nextSiblingElement() )
3046 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
3047 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
3053 if ( e.tagName() == QLatin1String(
"symbol3d" ) )
3055 QString
name = e.attribute( QStringLiteral(
"name" ) );
3057 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
3059 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
3061 bool favorite =
false;
3062 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
3067 const QDomElement symbolElem = e.firstChildElement();
3068 const QString type = symbolElem.attribute( QStringLiteral(
"type" ) );
3072 sym->readXml( symbolElem, QgsReadWriteContext() );
3073 QgsAbstract3DSymbol *newSym = sym.get();
3089 runEmptyQuery( query );
3096 QFileInfo fileInfo( path );
3098 if ( fileInfo.suffix().compare( QLatin1String(
"xml" ), Qt::CaseInsensitive ) != 0 )
3102 if ( !QFile::exists( path ) )
3105 QFile inputFile( path );
3106 if ( !inputFile.open( QIODevice::ReadOnly ) )
3109 QTextStream stream( &inputFile );
3110 const QString line = stream.readLine();
3111 return line == QLatin1String(
"<!DOCTYPE qgis_style>" );
3126 mReadOnly = readOnly;
3129bool QgsStyle::updateSymbol( StyleEntity type,
const QString &name )
3131 QDomDocument doc( QStringLiteral(
"dummy" ) );
3133 QByteArray xmlArray;
3134 QTextStream stream( &xmlArray );
3135#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
3136 stream.setCodec(
"UTF-8" );
3146 auto it = mSymbols.constFind(
name );
3147 if ( it == mSymbols.constEnd() || !it.value() )
3149 QgsDebugError( QStringLiteral(
"Update request received for unavailable symbol" ) );
3154 if ( symEl.isNull() )
3156 QgsDebugError( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
3159 symEl.save( stream, 4 );
3161 xmlArray.constData(),
name.toUtf8().constData() );
3168 auto it = m3dSymbols.constFind(
name );
3169 if ( it == m3dSymbols.constEnd() || !it.value() )
3171 QgsDebugError( QStringLiteral(
"Update request received for unavailable symbol" ) );
3175 symEl = doc.createElement( QStringLiteral(
"symbol" ) );
3176 symEl.setAttribute( QStringLiteral(
"type" ), it.value()->type() );
3177 it.value()->writeXml( symEl, QgsReadWriteContext() );
3178 if ( symEl.isNull() )
3180 QgsDebugError( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
3183 symEl.save( stream, 4 );
3185 xmlArray.constData(),
name.toUtf8().constData() );
3191 auto it = mColorRamps.constFind(
name );
3192 if ( it == mColorRamps.constEnd() || !it.value() )
3194 QgsDebugError( QStringLiteral(
"Update requested for unavailable color ramp." ) );
3199 if ( symEl.isNull() )
3201 QgsDebugError( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
3204 symEl.save( stream, 4 );
3206 xmlArray.constData(),
name.toUtf8().constData() );
3212 auto it = mTextFormats.constFind(
name );
3213 if ( it == mTextFormats.constEnd() )
3215 QgsDebugError( QStringLiteral(
"Update requested for unavailable text format." ) );
3219 symEl = it.value().writeXml( doc, QgsReadWriteContext() );
3220 if ( symEl.isNull() )
3222 QgsDebugError( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
3225 symEl.save( stream, 4 );
3227 xmlArray.constData(),
name.toUtf8().constData() );
3233 auto it = mLabelSettings.constFind(
name );
3234 if ( it == mLabelSettings.constEnd() )
3236 QgsDebugError( QStringLiteral(
"Update requested for unavailable label settings." ) );
3240 symEl = it.value().writeXml( doc, QgsReadWriteContext() );
3241 if ( symEl.isNull() )
3243 QgsDebugError( QStringLiteral(
"Couldn't convert label settings to valid XML!" ) );
3246 symEl.save( stream, 4 );
3248 xmlArray.constData(),
name.toUtf8().constData() );
3254 auto it = mLegendPatchShapes.constFind(
name );
3255 if ( it == mLegendPatchShapes.constEnd() )
3257 QgsDebugError( QStringLiteral(
"Update requested for unavailable legend patch shape." ) );
3261 symEl = doc.createElement( QStringLiteral(
"shape" ) );
3262 it.value().writeXml( symEl, doc, QgsReadWriteContext() );
3263 symEl.save( stream, 4 );
3265 xmlArray.constData(),
name.toUtf8().constData() );
3272 QgsDebugError( QStringLiteral(
"Updating the unsupported StyleEntity" ) );
3278 if ( !runEmptyQuery( query ) )
3280 QgsDebugError( QStringLiteral(
"Couldn't update symbol into the database!" ) );
3316 mCachedTags[ type ].remove(
name );
3319bool QgsStyle::createStyleMetadataTableIfNeeded()
3322 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='stylemetadata'" );
3323 sqlite3_statement_unique_ptr statement;
3325 statement = mCurrentDB.prepare( query, rc );
3327 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
3331 "id INTEGER PRIMARY KEY,"\
3334 runEmptyQuery( query );
3336 runEmptyQuery( query );
3345void QgsStyle::upgradeIfRequired()
3349 if ( !createStyleMetadataTableIfNeeded() )
3351 const QString query =
qgs_sqlite3_mprintf(
"SELECT value FROM stylemetadata WHERE key='version'" );
3353 sqlite3_statement_unique_ptr statement = mCurrentDB.prepare( query, rc );
3354 if ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
3366 runEmptyQuery( query );
3376 return QStringLiteral(
"symbol" );
3379 return QStringLiteral(
"colorramp" );
3382 return QStringLiteral(
"textformat" );
3385 return QStringLiteral(
"labelsettings" );
3388 return QStringLiteral(
"legendpatchshapes" );
3391 return QStringLiteral(
"symbol3d" );
3394 return QStringLiteral(
"tag" );
3397 return QStringLiteral(
"smartgroup" );
3407 return QStringLiteral(
"tagmap" );
3410 return QStringLiteral(
"ctagmap" );
3413 return QStringLiteral(
"tftagmap" );
3416 return QStringLiteral(
"lstagmap" );
3419 return QStringLiteral(
"lpstagmap" );
3422 return QStringLiteral(
"symbol3dtagmap" );
3436 return QStringLiteral(
"symbol_id" );
3439 return QStringLiteral(
"colorramp_id" );
3442 return QStringLiteral(
"textformat_id" );
3445 return QStringLiteral(
"labelsettings_id" );
3448 return QStringLiteral(
"legendpatchshape_id" );
3451 return QStringLiteral(
"symbol3d_id" );
@ ScaleArea
Calculate scale by the area.
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
static int versionInt()
Version number used for comparing versions using the "Check QGIS Version" function.
QStringList symbolTypes() const
Returns a list of all available symbol types.
Abstract base class for 3D symbols that are used by VectorLayer3DRenderer objects.
virtual QgsAbstract3DSymbol * clone() const =0
Returns a new instance of the symbol with the same settings.
static QString userStylePath()
Returns the path to user's style.
static QString defaultStylePath()
Returns the path to default style (works as a starting point).
static Qgs3DSymbolRegistry * symbol3DRegistry()
Returns registry of available 3D symbols.
Abstract base class for color ramps.
virtual double value(int index) const =0
Returns relative value between [0,1] of color at specified index.
virtual QgsColorRamp * clone() const =0
Creates a clone of the color ramp.
A geometry is the spatial representation of a feature.
Represents a patch shape for use in map legends.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Read settings from a DOM element.
QList< QList< QPolygonF > > toQPolygonF(Qgis::SymbolType type, QSizeF size) const
Converts the patch shape to a set of QPolygonF objects representing how the patch should be drawn for...
void writeXml(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
Qgis::SymbolType symbolType() const
Returns the symbol type associated with this patch.
Line string geometry type, with support for z-dimension and m-values.
Contains settings for how a map layer will be labeled.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
QgsTextFormat defaultTextFormat() const
Returns the project default text format.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
const QgsProjectStyleSettings * styleSettings() const
Returns the project's style settings, which contains settings and properties relating to how a QgsPro...
A container for the context for various read/write operations on objects.
Scoped object for logging of the runtime for a single operation or group of operations.
Stores settings for use within QGIS.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
A color ramp entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
An interface for entities which can be placed in a QgsStyle database.
virtual QgsStyle::StyleEntity type() const =0
Returns the type of style entity.
A label settings entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A legend patch shape entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A 3d symbol entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A symbol entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A text format entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A database of saved style entities, including symbols, color ramps, text formats and others.
bool addEntity(const QString &name, const QgsStyleEntityInterface *entity, bool update=false)
Adds an entity to the style, with the specified name.
void setFileName(const QString &filename)
Sets the current file name of the style database.
void labelSettingsChanged(const QString &name)
Emitted whenever a label setting's definition is changed.
int colorRampCount()
Returns count of color ramps.
bool detagSymbol(StyleEntity type, const QString &symbol, const QStringList &tags)
Detags the symbol with the given list.
QgsTextFormat textFormat(const QString &name) const
Returns the text format with the specified name.
QStringList allNames(StyleEntity type) const
Returns a list of the names of all existing entities of the specified type.
QgsLegendPatchShape defaultPatch(Qgis::SymbolType type, QSizeF size) const
Returns the default legend patch shape for the given symbol type.
bool remove(StyleEntity type, int id)
Removes the specified entity from the database.
bool removeSymbol(const QString &name)
Removes symbol from style (and delete it).
void entityChanged(QgsStyle::StyleEntity entity, const QString &name)
Emitted whenever an entity's definition is changed.
bool removeLabelSettings(const QString &name)
Removes label settings from the style.
void labelSettingsAdded(const QString &name)
Emitted whenever label settings have been added to the style and the database has been updated as a r...
QStringList tags() const
Returns a list of all tags in the style database.
QString tag(int id) const
Returns the tag name for the given id.
QgsSmartConditionMap smartgroup(int id)
Returns the QgsSmartConditionMap for the given id.
bool renameColorRamp(const QString &oldName, const QString &newName)
Changes ramp's name.
void rampAdded(const QString &name)
Emitted whenever a color ramp has been added to the style and the database has been updated as a resu...
QStringList symbol3DNames() const
Returns a list of names of 3d symbols in the style.
bool tagSymbol(StyleEntity type, const QString &symbol, const QStringList &tags)
Tags the symbol with the tags in the list.
int entityId(StyleEntity type, const QString &name)
Returns the id in the style database for the given name of the specified entity type.
void rebuildIconPreviews()
Emitted whenever icon previews for entities in the style must be rebuilt.
bool saveLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool favorite, const QStringList &tags)
Adds label settings to the database.
Q_DECL_DEPRECATED bool save(const QString &filename=QString())
Saves style into a file.
bool symbolHasTag(StyleEntity type, const QString &symbol, const QString &tag)
Returns whether a given tag is associated with the symbol.
void aboutToBeDestroyed()
Emitted just before the style object is destroyed.
QgsTextFormat defaultTextFormat(QgsStyle::TextFormatContext context=QgsStyle::TextFormatContext::Labeling) const
Returns the default text format to use for new text based objects in the specified context.
@ XML
Label settings definition (as XML).
@ Name
Label settings name.
bool createDatabase(const QString &filename)
Creates an on-disk database.
QStringList textFormatNames() const
Returns a list of names of text formats in the style.
const QgsColorRamp * colorRampRef(const QString &name) const
Returns a const pointer to a symbol (doesn't create new instance).
QStringList symbolsWithTag(StyleEntity type, int tagid) const
Returns the symbol names with which have the given tag.
bool addColorRamp(const QString &name, QgsColorRamp *colorRamp, bool update=false)
Adds a color ramp to the style.
bool removeTextFormat(const QString &name)
Removes a text format from the style.
QgsSymbol * symbol(const QString &name)
Returns a NEW copy of symbol.
void labelSettingsRemoved(const QString &name)
Emitted whenever label settings have been removed from the style and the database has been updated as...
QStringList symbolsOfSmartgroup(StyleEntity type, int id)
Returns the symbols for the smartgroup.
int labelSettingsCount() const
Returns count of label settings in the style.
StyleEntity
Enum for Entities involved in a style.
@ LabelSettingsEntity
Label settings.
@ TextFormatEntity
Text formats.
@ SmartgroupEntity
Smart groups.
@ Symbol3DEntity
3D symbol entity
@ ColorrampEntity
Color ramps.
@ LegendPatchShapeEntity
Legend patch shape.
QStringList tagsOfSymbol(StyleEntity type, const QString &symbol)
Returns the tags associated with the symbol.
void symbolRenamed(const QString &oldName, const QString &newName)
Emitted whenever a symbol has been renamed from oldName to newName.
QList< Qgis::GeometryType > symbol3DCompatibleGeometryTypes(const QString &name) const
Returns the list of the vector layer geometry types which are compatible with the 3D symbol with the ...
@ XML
Color ramp definition (as XML).
void groupsModified()
Emitted every time a tag or smartgroup has been added, removed, or renamed.
void clear()
Removes all contents of the style.
int smartgroupId(const QString &smartgroup)
Returns the database id for the given smartgroup name.
void rampRemoved(const QString &name)
Emitted whenever a color ramp has been removed from the style and the database has been updated as a ...
void entityRenamed(QgsStyle::StyleEntity entity, const QString &oldName, const QString &newName)
Emitted whenever a entity of the specified type has been renamed from oldName to newName.
const QgsSymbol * symbolRef(const QString &name) const
Returns a const pointer to a symbol (doesn't create new instance).
int addSmartgroup(const QString &name, const QString &op, const QgsSmartConditionMap &conditions)
Adds a new smartgroup to the database and returns the id.
QStringList colorRampNames() const
Returns a list of names of color ramps.
void textFormatChanged(const QString &name)
Emitted whenever a text format's definition is changed.
bool addSymbol3D(const QString &name, QgsAbstract3DSymbol *symbol, bool update=false)
Adds a 3d symbol with the specified name to the style.
QStringList legendPatchShapeNames() const
Returns a list of names of legend patch shapes in the style.
bool renameLegendPatchShape(const QString &oldName, const QString &newName)
Changes a legend patch shape's name.
static void cleanDefaultStyle()
Deletes the default style. Only to be used by QgsApplication::exitQgis().
void symbolSaved(const QString &name, const QgsSymbol *symbol)
Emitted every time a new symbol has been added to the database.
void textFormatRenamed(const QString &oldName, const QString &newName)
Emitted whenever a text format has been renamed from oldName to newName.
void triggerIconRebuild()
Triggers emission of the rebuildIconPreviews() signal.
void setName(const QString &name)
Sets the name of the style.
bool removeEntityByName(StyleEntity type, const QString &name)
Removes the entry of the specified type with matching name from the database.
void labelSettingsRenamed(const QString &oldName, const QString &newName)
Emitted whenever label settings have been renamed from oldName to newName.
void initialized()
Emitted when the style database has been fully initialized.
@ XML
Text format definition (as XML).
int textFormatCount() const
Returns count of text formats in the style.
QStringList findSymbols(StyleEntity type, const QString &qword)
Returns the names of the symbols which have a matching 'substring' in its definition.
int tagId(const QString &tag)
Returns the database id for the given tag name.
void rampRenamed(const QString &oldName, const QString &newName)
Emitted whenever a color ramp has been renamed from oldName to newName.
bool exportXml(const QString &filename)
Exports the style as a XML file.
void createTables()
Creates tables structure for new database.
bool isReadOnly() const
Returns true if the style is considered a read-only library.
bool addLegendPatchShape(const QString &name, const QgsLegendPatchShape &shape, bool update=false)
Adds a legend patch shape with the specified name to the style.
int textFormatId(const QString &name)
Returns the ID in the style database for the given text format by name.
QgsColorRamp * colorRamp(const QString &name) const
Returns a new copy of the specified color ramp.
int symbolCount()
Returns count of symbols in style.
bool renameEntity(StyleEntity type, const QString &oldName, const QString &newName)
Renames an entity of the specified type from oldName to newName.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
static bool isXmlStyleFile(const QString &path)
Tests if the file at path is a QGIS style XML file.
int symbol3DCount() const
Returns count of 3D symbols in the style.
bool createMemoryDatabase()
Creates a temporary memory database.
int colorrampId(const QString &name)
Returns the id in the style database for the given colorramp name returns 0 if not found.
bool saveSymbol(const QString &name, const QgsSymbol *symbol, bool favorite, const QStringList &tags)
Adds the symbol to the database with tags.
QStringList labelSettingsNames() const
Returns a list of names of label settings in the style.
bool load(const QString &filename)
Loads a file into the style.
QStringList smartgroupNames() const
Returns the smart groups list.
bool rename(StyleEntity type, int id, const QString &newName)
Renames the given entity with the specified id.
bool renameTextFormat(const QString &oldName, const QString &newName)
Changes a text format's name.
void textFormatAdded(const QString &name)
Emitted whenever a text format has been added to the style and the database has been updated as a res...
bool removeFavorite(StyleEntity type, const QString &name)
Removes the specified symbol from favorites.
static QgsTextFormat defaultTextFormatForProject(QgsProject *project, QgsStyle::TextFormatContext context=QgsStyle::TextFormatContext::Labeling)
Returns the default text format to use for new text based objects for the specified project,...
int legendPatchShapesCount() const
Returns count of legend patch shapes in the style.
QgsSymbolGroupMap smartgroupsListMap()
Returns the smart groups map with id as key and name as value.
bool isFavorite(StyleEntity type, const QString &name)
Returns true if the symbol with matching type and name is marked as a favorite.
int symbolId(const QString &name)
Returns the id in the style database for the given symbol name returns 0 if not found.
bool saveLegendPatchShape(const QString &name, const QgsLegendPatchShape &shape, bool favorite, const QStringList &tags)
Adds a legend patch shape to the database.
QString name() const
Returns the name of the style.
QgsStyle(QObject *parent=nullptr)
Constructor for QgsStyle, with the specified parent object.
Qgis::GeometryType labelSettingsLayerType(const QString &name) const
Returns the layer geometry type corresponding to the label settings with the specified name,...
@ XML
Symbol definition (as XML).
bool renameLabelSettings(const QString &oldName, const QString &newName)
Changes a label setting's name.
bool renameSymbol3D(const QString &oldName, const QString &newName)
Changes a 3d symbol's name.
bool addTextFormat(const QString &name, const QgsTextFormat &format, bool update=false)
Adds a text format with the specified name to the style.
bool saveColorRamp(const QString &name, const QgsColorRamp *ramp, bool favorite, const QStringList &tags)
Adds the colorramp to the database.
void rampChanged(const QString &name)
Emitted whenever a color ramp's definition is changed.
QStringList symbolsOfFavorite(StyleEntity type) const
Returns the symbol names which are flagged as favorite.
void entityTagsChanged(QgsStyle::StyleEntity entity, const QString &name, const QStringList &newTags)
Emitted whenever an entity's tags are changed.
bool renameSymbol(const QString &oldName, const QString &newName)
Renames a symbol from oldName to newName.
bool removeColorRamp(const QString &name)
Removes color ramp from style (and delete it).
bool saveSymbol3D(const QString &name, QgsAbstract3DSymbol *symbol, bool favorite, const QStringList &tags)
Adds a 3d symbol to the database.
void favoritedChanged(QgsStyle::StyleEntity entity, const QString &name, bool isFavorite)
Emitted whenever an entity is either favorited or un-favorited.
QgsPalLayerSettings labelSettings(const QString &name) const
Returns the label settings with the specified name.
void entityRemoved(QgsStyle::StyleEntity entity, const QString &name)
Emitted whenever an entity of the specified type is removed from the style and the database has been ...
int labelSettingsId(const QString &name)
Returns the ID in the style database for the given label settings by name.
Qgis::SymbolType legendPatchShapeSymbolType(const QString &name) const
Returns the symbol type corresponding to the legend patch shape with the specified name,...
QgsAbstract3DSymbol * symbol3D(const QString &name) const
Returns a new copy of the 3D symbol with the specified name.
int addTag(const QString &tagName)
Adds a new tag and returns the tag's id.
const QgsSymbol * previewSymbolForPatchShape(const QgsLegendPatchShape &shape) const
Returns a symbol to use for rendering preview icons for a patch shape.
bool addSymbol(const QString &name, QgsSymbol *symbol, bool update=false)
Adds a symbol to style and takes symbol's ownership.
QgsLegendPatchShape legendPatchShape(const QString &name) const
Returns the legend patch shape with the specified name.
void entityAdded(QgsStyle::StyleEntity entity, const QString &name)
Emitted every time a new entity has been added to the database.
QStringList symbolNames() const
Returns a list of names of symbols.
TextFormatContext
Text format context.
void symbolRemoved(const QString &name)
Emitted whenever a symbol has been removed from the style and the database has been updated as a resu...
void symbolChanged(const QString &name)
Emitted whenever a symbol's definition is changed.
bool addFavorite(StyleEntity type, const QString &name)
Adds the specified symbol to favorites.
QString smartgroupOperator(int id)
Returns the operator for the smartgroup.
bool saveTextFormat(const QString &name, const QgsTextFormat &format, bool favorite, const QStringList &tags)
Adds a text format to the database.
QList< QList< QPolygonF > > defaultPatchAsQPolygonF(Qgis::SymbolType type, QSizeF size) const
Returns the default patch geometry for the given symbol type and size as a set of QPolygonF objects (...
void textFormatRemoved(const QString &name)
Emitted whenever a text format has been removed from the style and the database has been updated as a...
void setReadOnly(bool readOnly)
Sets whether the style is considered a read-only library.
bool importXml(const QString &filename)
Imports the symbols and colorramps into the default style database from the given XML file.
bool addLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool update=false)
Adds label settings with the specified name to the style.
static std::unique_ptr< QgsColorRamp > loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
static std::unique_ptr< QgsSymbol > loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
static QDomElement saveColorRamp(const QString &name, const QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
static void resetSymbolLayerIds(QgsSymbol *symbol)
Regenerate recursively unique id from all symbol symbol layers.
static QgsSymbolMap loadSymbols(QDomElement &element, const QgsReadWriteContext &context)
Reads a collection of symbols from XML and returns them in a map. Caller is responsible for deleting ...
static QDomElement saveSymbols(QgsSymbolMap &symbols, const QString &tagName, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a collection of symbols to XML with specified tagName for the top-level element.
Abstract base class for all rendered symbols.
Container for all settings relating to text rendering.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
sqlite3_statement_unique_ptr prepare(const QString &sql, int &resultCode) const
Prepares a sql statement, returning the result.
Unique pointer for sqlite3 prepared statements, which automatically finalizes the statement when the ...
QString columnAsText(int column) const
Returns the column value from the current statement row as a string.
QMultiMap< QString, QString > QgsSmartConditionMap
A multimap to hold the smart group conditions as constraint and parameter pairs.
#define QgsDebugError(str)
QMap< QString, QgsSymbol * > QgsSymbolMap
QString qgs_sqlite3_mprintf(const char *format,...)
Wraps sqlite3_mprintf() by automatically freeing the memory.
LegendPatchTable
Columns available in the legend patch table.
@ LegendPatchTableId
Legend patch ID.
@ LegendPatchTableName
Legend patch name.
@ LegendPatchTableFavoriteId
Legend patch is favorite flag.
@ LegendPatchTableXML
Legend patch definition (as XML).
#define STYLE_CURRENT_VERSION
Symbol3DTable
Columns available in the 3d symbol table.
@ Symbol3DTableXML
3d symbol definition (as XML)
@ Symbol3DTableName
3d symbol name
@ Symbol3DTableFavoriteId
3d symbol is favorite flag
@ Symbol3DTableId
3d symbol ID
QMap< int, QString > QgsSymbolGroupMap
QList< QgsSymbolLayer * > QgsSymbolLayerList