47#include <QDomDocument>
50#include <QDomNodeList>
56#include "moc_qgsstyle.cpp"
58using namespace Qt::StringLiterals;
60#define STYLE_CURRENT_VERSION "2"
95QgsStyle *QgsStyle::sDefaultStyle =
nullptr;
101 simpleMarker->setStrokeWidth( 0.4 );
102 mPatchMarkerSymbol = std::make_unique< QgsMarkerSymbol >(
QgsSymbolLayerList() << simpleMarker.release() );
104 auto simpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 84, 176, 74 ), 0.6 );
105 mPatchLineSymbol = std::make_unique< QgsLineSymbol >(
QgsSymbolLayerList() << simpleLine.release() );
107 auto gradientFill = std::make_unique< QgsGradientFillSymbolLayer >( QColor( 66, 150, 63 ), QColor( 84, 176, 74 ) );
108 auto simpleOutline = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 56, 128, 54 ), 0.26 );
109 mPatchFillSymbol = std::make_unique< QgsFillSymbol >(
QgsSymbolLayerList() << gradientFill.release() << simpleOutline.release() );
130 switch ( entity->
type() )
166 static QString sStyleFilename;
167 if ( !sDefaultStyle )
173 if ( !QFile::exists( sStyleFilename ) )
176 sDefaultStyle->createDatabase( sStyleFilename );
181 sDefaultStyle->createStyleMetadataTableIfNeeded();
188 sDefaultStyle->mInitialized =
false;
191 sDefaultStyle->initializeDefaultStyle( sStyleFilename );
194 sDefaultStyle->setName( QObject::tr(
"Default" ) );
196 else if ( initialize && !sDefaultStyle->mInitialized )
199 sDefaultStyle->initializeDefaultStyle( sStyleFilename );
201 return sDefaultStyle;
204void QgsStyle::initializeDefaultStyle(
const QString &filename )
206 Q_ASSERT(
this == sDefaultStyle );
207 if (
this != sDefaultStyle )
223 delete sDefaultStyle;
224 sDefaultStyle =
nullptr;
229 qDeleteAll( mSymbols );
230 qDeleteAll( mColorRamps );
231 qDeleteAll( m3dSymbols );
235 mTextFormats.clear();
239 mCachedFavorites.clear();
248 auto it = mSymbols.constFind(
name );
249 if ( it != mSymbols.constEnd() )
270 QDomDocument doc( u
"dummy"_s );
272 if ( symEl.isNull() )
279 QTextStream stream( &xmlArray );
280 symEl.save( stream, 4 );
281 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO symbol VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
283 if ( !runEmptyQuery( query ) )
285 QgsDebugError( u
"Couldn't insert symbol into the database!"_s );
350 return mSymbols.value(
name );
355 return static_cast< int >( mSymbols.count() );
360 return mSymbols.keys();
369 auto it = mColorRamps.constFind(
name );
370 if ( it != mColorRamps.constEnd() )
391 auto it = mTextFormats.find(
name );
392 if ( it != mTextFormats.end() )
395 mTextFormats.erase( it );
396 mTextFormats.insert(
name, format );
402 mTextFormats.insert(
name, format );
413 auto it = mLabelSettings.find(
name );
414 if ( it != mLabelSettings.end() )
417 mLabelSettings.erase( it );
418 mLabelSettings.insert(
name, settings );
424 mLabelSettings.insert(
name, settings );
435 auto it = mLegendPatchShapes.find(
name );
436 if ( it != mLegendPatchShapes.end() )
439 mLegendPatchShapes.erase( it );
440 mLegendPatchShapes.insert(
name, shape );
446 mLegendPatchShapes.insert(
name, shape );
457 auto it = m3dSymbols.constFind(
name );
458 if ( it != m3dSymbols.constEnd() )
479 auto it = mMaterialSettings.constFind(
name );
480 if ( it != mMaterialSettings.constEnd() )
484 mMaterialSettings.insert(
name, settings );
490 mMaterialSettings.insert(
name, settings );
501 QDomDocument doc( u
"dummy"_s );
504 if ( rampEl.isNull() )
506 QgsDebugError( u
"Couldn't convert color ramp to valid XML!"_s );
511 QTextStream stream( &xmlArray );
512 rampEl.save( stream, 4 );
513 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO colorramp VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
514 if ( !runEmptyQuery( query ) )
516 QgsDebugError( u
"Couldn't insert colorramp into the database!"_s );
538 return ramp ? ramp->
clone() :
nullptr;
548 return static_cast< int >( mColorRamps.count() );
553 return mColorRamps.keys();
556void QgsStyle::handleDeferred3DSymbolCreation()
558 for (
auto it = mDeferred3DsymbolElements.constBegin(); it != mDeferred3DsymbolElements.constEnd(); ++it )
560 const QString symbolType = it.value().attribute( u
"type"_s );
574 mDeferred3DsymbolElements.clear();
577bool QgsStyle::openDatabase(
const QString &filename )
579 int rc = mCurrentDB.open( filename );
582 mErrorString = u
"Couldn't open the style database: %1"_s.arg( mCurrentDB.errorMessage() );
591 mErrorString.clear();
592 if ( !openDatabase( filename ) )
594 mErrorString = u
"Unable to create database"_s;
606 mErrorString.clear();
607 if ( !openDatabase( u
":memory:"_s ) )
609 mErrorString = u
"Unable to create temporary memory database"_s;
622 "CREATE TABLE symbol("
623 "id INTEGER PRIMARY KEY,"
627 "CREATE TABLE colorramp("
628 "id INTEGER PRIMARY KEY,"
632 "CREATE TABLE textformat("
633 "id INTEGER PRIMARY KEY,"
637 "CREATE TABLE labelsettings("
638 "id INTEGER PRIMARY KEY,"
642 "CREATE TABLE legendpatchshapes("
643 "id INTEGER PRIMARY KEY,"
647 "CREATE TABLE symbol3d("
648 "id INTEGER PRIMARY KEY,"
652 "CREATE TABLE materialsettings("
653 "id INTEGER PRIMARY KEY,"
658 "id INTEGER PRIMARY KEY,"
660 "CREATE TABLE tagmap("
661 "tag_id INTEGER NOT NULL,"
662 "symbol_id INTEGER);"
663 "CREATE TABLE ctagmap("
664 "tag_id INTEGER NOT NULL,"
665 "colorramp_id INTEGER);"
666 "CREATE TABLE tftagmap("
667 "tag_id INTEGER NOT NULL,"
668 "textformat_id INTEGER);"
669 "CREATE TABLE lstagmap("
670 "tag_id INTEGER NOT NULL,"
671 "labelsettings_id INTEGER);"
672 "CREATE TABLE lpstagmap("
673 "tag_id INTEGER NOT NULL,"
674 "legendpatchshape_id INTEGER);"
675 "CREATE TABLE symbol3dtagmap("
676 "tag_id INTEGER NOT NULL,"
677 "symbol3d_id INTEGER);"
678 "CREATE TABLE materialsettingstagmap("
679 "tag_id INTEGER NOT NULL,"
680 "materialsettings_id INTEGER);"
681 "CREATE TABLE smartgroup("
682 "id INTEGER PRIMARY KEY,"
686 runEmptyQuery( query );
691 mErrorString.clear();
694 if ( !openDatabase( filename ) )
696 mErrorString = u
"Unable to open database file specified"_s;
702 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='textformat'" );
705 statement = mCurrentDB.prepare( query, rc );
706 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
709 "CREATE TABLE textformat("
710 "id INTEGER PRIMARY KEY,"
714 "CREATE TABLE tftagmap("
715 "tag_id INTEGER NOT NULL,"
716 "textformat_id INTEGER);"
718 runEmptyQuery( query );
721 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='labelsettings'" );
722 statement = mCurrentDB.prepare( query, rc );
723 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
726 "CREATE TABLE labelsettings("
727 "id INTEGER PRIMARY KEY,"
731 "CREATE TABLE lstagmap("
732 "tag_id INTEGER NOT NULL,"
733 "labelsettings_id INTEGER);"
735 runEmptyQuery( query );
738 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='legendpatchshapes'" );
739 statement = mCurrentDB.prepare( query, rc );
740 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
743 "CREATE TABLE legendpatchshapes("
744 "id INTEGER PRIMARY KEY,"
748 "CREATE TABLE lpstagmap("
749 "tag_id INTEGER NOT NULL,"
750 "legendpatchshape_id INTEGER);"
752 runEmptyQuery( query );
756 statement = mCurrentDB.prepare( query, rc );
757 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
760 "CREATE TABLE symbol3d("
761 "id INTEGER PRIMARY KEY,"
765 "CREATE TABLE symbol3dtagmap("
766 "tag_id INTEGER NOT NULL,"
767 "symbol3d_id INTEGER);"
769 runEmptyQuery( query );
773 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='materialsettings'" );
774 statement = mCurrentDB.prepare( query, rc );
775 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
778 "CREATE TABLE materialsettings("
779 "id INTEGER PRIMARY KEY,"
783 "CREATE TABLE materialsettingstagmap("
784 "tag_id INTEGER NOT NULL,"
785 "materialsettings_id INTEGER);"
787 runEmptyQuery( query );
792 "UPDATE symbol SET favorite=0 WHERE favorite IS NULL;"
793 "UPDATE colorramp SET favorite=0 WHERE favorite IS NULL;"
794 "UPDATE textformat SET favorite=0 WHERE favorite IS NULL;"
795 "UPDATE labelsettings SET favorite=0 WHERE favorite IS NULL;"
796 "UPDATE legendpatchshapes SET favorite=0 WHERE favorite IS NULL;"
797 "UPDATE symbol3d SET favorite=0 WHERE favorite IS NULL;"
798 "UPDATE materialsettings SET favorite=0 WHERE favorite IS NULL;"
800 runEmptyQuery( query );
806 statement = mCurrentDB.prepare( query, rc );
808 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
814 if ( !doc.setContent( xmlstring ) )
820 QDomElement symElement = doc.documentElement();
823 mSymbols.insert( symbolName,
symbol.release() );
830 statement = mCurrentDB.prepare( query, rc );
831 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
837 if ( !doc.setContent( xmlstring ) )
842 QDomElement rampElement = doc.documentElement();
845 mColorRamps.insert( rampName, ramp.release() );
852 statement = mCurrentDB.prepare( query, rc );
853 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
859 if ( !doc.setContent( xmlstring ) )
864 QDomElement formatElement = doc.documentElement();
867 mTextFormats.insert( formatName, format );
874 statement = mCurrentDB.prepare( query, rc );
875 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
881 if ( !doc.setContent( xmlstring ) )
883 QgsDebugError(
"Cannot open label settings " + settingsName );
886 QDomElement settingsElement = doc.documentElement();
889 mLabelSettings.insert( settingsName, settings );
896 statement = mCurrentDB.prepare( query, rc );
897 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
903 if ( !doc.setContent( xmlstring ) )
905 QgsDebugError(
"Cannot open legend patch shape " + settingsName );
908 QDomElement settingsElement = doc.documentElement();
911 mLegendPatchShapes.insert( settingsName, shape );
918 statement = mCurrentDB.prepare( query, rc );
922 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
928 if ( !doc.setContent( xmlstring ) )
933 QDomElement settingsElement = doc.documentElement();
935 if ( !registry3dPopulated )
937 mDeferred3DsymbolElements.insert( settingsName, settingsElement );
941 const QString symbolType = settingsElement.attribute( u
"type"_s );
946 m3dSymbols.insert( settingsName,
symbol.release() );
960 statement = mCurrentDB.prepare( query, rc );
962 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
968 if ( !doc.setContent( xmlstring ) )
970 QgsDebugError(
"Cannot open material settings " + settingsName );
973 QDomElement settingsElement = doc.documentElement();
975 const QString materialType = settingsElement.attribute( u
"type"_s );
980 mMaterialSettings.insert( settingsName, settings.release() );
984 QgsDebugError(
"Cannot open material settings " + settingsName );
990 mFileName = filename;
991 createStyleMetadataTableIfNeeded();
997 mErrorString.clear();
999 if ( !filename.isEmpty() )
1000 mFileName = filename;
1007 mFileName = filename;
1012 if ( mSymbols.contains( newName ) )
1022 mSymbols.insert( newName,
symbol );
1030 int symbolid =
symbolId( oldName );
1033 QgsDebugError( u
"No such symbol for tagging in database: "_s + oldName );
1052 if ( mColorRamps.contains( newName ) )
1054 QgsDebugError( u
"Color ramp of new name already exists."_s );
1062 mColorRamps.insert( newName, ramp );
1068 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM colorramp WHERE name='%q'", oldName.toUtf8().constData() );
1070 statement = mCurrentDB.prepare( query, nErr );
1071 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1073 rampid = sqlite3_column_int( statement.get(), 0 );
1088 QDomDocument doc( u
"dummy"_s );
1091 if ( formatElem.isNull() )
1093 QgsDebugError( u
"Couldn't convert text format to valid XML!"_s );
1097 QByteArray xmlArray;
1098 QTextStream stream( &xmlArray );
1099 formatElem.save( stream, 4 );
1100 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO textformat VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1101 if ( !runEmptyQuery( query ) )
1103 QgsDebugError( u
"Couldn't insert text format into the database!"_s );
1124 if ( mTextFormats.contains( newName ) )
1126 QgsDebugError( u
"Text format of new name already exists."_s );
1130 if ( !mTextFormats.contains( oldName ) )
1134 mTextFormats.insert( newName, format );
1140 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM textformat WHERE name='%q'", oldName.toUtf8().constData() );
1142 statement = mCurrentDB.prepare( query, nErr );
1143 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1145 textFormatId = sqlite3_column_int( statement.get(), 0 );
1160 QDomDocument doc( u
"dummy"_s );
1163 if ( settingsElem.isNull() )
1165 QgsDebugError( u
"Couldn't convert label settings to valid XML!"_s );
1169 QByteArray xmlArray;
1170 QTextStream stream( &xmlArray );
1171 settingsElem.save( stream, 4 );
1172 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO labelsettings VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1173 if ( !runEmptyQuery( query ) )
1175 QgsDebugError( u
"Couldn't insert label settings into the database!"_s );
1196 if ( mLabelSettings.contains( newName ) )
1198 QgsDebugError( u
"Label settings of new name already exists."_s );
1202 if ( !mLabelSettings.contains( oldName ) )
1206 mLabelSettings.insert( newName, settings );
1212 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM labelsettings WHERE name='%q'", oldName.toUtf8().constData() );
1214 statement = mCurrentDB.prepare( query, nErr );
1215 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1232 QDomDocument doc( u
"dummy"_s );
1233 QDomElement shapeElem = doc.createElement( u
"shape"_s );
1236 QByteArray xmlArray;
1237 QTextStream stream( &xmlArray );
1238 shapeElem.save( stream, 4 );
1239 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO legendpatchshapes VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1240 if ( !runEmptyQuery( query ) )
1242 QgsDebugError( u
"Couldn't insert legend patch shape into the database!"_s );
1257 if ( mLegendPatchShapes.contains( newName ) )
1259 QgsDebugError( u
"Legend patch shape of new name already exists."_s );
1263 if ( !mLegendPatchShapes.contains( oldName ) )
1267 mLegendPatchShapes.insert( newName, shape );
1273 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM legendpatchshapes WHERE name='%q'", oldName.toUtf8().constData() );
1275 statement = mCurrentDB.prepare( query, nErr );
1276 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1294 auto it = mDefaultPatchCache[
static_cast< int >( type )].constFind( size );
1295 if ( it != mDefaultPatchCache[
static_cast< int >( type )].constEnd() )
1302 geom =
QgsGeometry( std::make_unique< QgsPoint >(
static_cast< int >( size.width() ) / 2,
static_cast< int >( size.height() ) / 2 ) );
1309 double y =
static_cast< int >( size.height() ) / 2 + 0.5;
1310 geom =
QgsGeometry( std::make_unique< QgsLineString >( ( QVector< double >() << 0 << size.width() ), ( QVector< double >() << y << y ) ) );
1318 QVector< double >() << 0 <<
static_cast< int >( size.width() ) <<
static_cast< int >( size.width() ) << 0 << 0,
1319 QVector< double >() <<
static_cast< int >( size.height() ) <<
static_cast< int >( size.height() ) << 0 << 0 <<
static_cast< int >( size.height() )
1330 mDefaultPatchCache[
static_cast< int >( type )][size] = res;
1337 return QList<QList<QPolygonF> >();
1339 auto it = mDefaultPatchQPolygonFCache[
static_cast< int >( type )].constFind( size );
1340 if ( it != mDefaultPatchQPolygonFCache[
static_cast< int >( type )].constEnd() )
1344 mDefaultPatchQPolygonFCache[
static_cast< int >( type )][size] = res;
1370 QDomDocument doc( u
"dummy"_s );
1371 QDomElement elem = doc.createElement( u
"symbol"_s );
1372 elem.setAttribute( u
"type"_s,
symbol->type() );
1375 QByteArray xmlArray;
1376 QTextStream stream( &xmlArray );
1377 elem.save( stream, 4 );
1378 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO symbol3d VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1379 if ( !runEmptyQuery( query ) )
1381 QgsDebugError( u
"Couldn't insert 3d symbol into the database!"_s );
1396 if ( m3dSymbols.contains( newName ) )
1398 QgsDebugError( u
"3d symbol of new name already exists."_s );
1402 if ( !m3dSymbols.contains( oldName ) )
1406 m3dSymbols.insert( newName,
symbol );
1412 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM symbol3d WHERE name='%q'", oldName.toUtf8().constData() );
1414 statement = mCurrentDB.prepare( query, nErr );
1415 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1430 return m3dSymbols.keys();
1436 QDomDocument doc( u
"dummy"_s );
1437 QDomElement elem = doc.createElement( u
"settings"_s );
1438 elem.setAttribute( u
"type"_s, settings->
type() );
1441 QByteArray xmlArray;
1442 QTextStream stream( &xmlArray );
1443 elem.save( stream, 4 );
1444 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO materialsettings VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1445 if ( !runEmptyQuery( query ) )
1447 QgsDebugError( u
"Couldn't insert material settings into the database!"_s );
1462 if ( mMaterialSettings.contains( newName ) )
1464 QgsDebugError( u
"material settings of new name already exists."_s );
1468 if ( !mMaterialSettings.contains( oldName ) )
1470 std::unique_ptr< QgsAbstractMaterialSettings > settings( mMaterialSettings.take( oldName ) );
1472 mMaterialSettings.insert( newName, settings.release() );
1476 int materialSettingsId = 0;
1478 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM materialsettings WHERE name='%q'", oldName.toUtf8().constData() );
1480 statement = mCurrentDB.prepare( query, nErr );
1481 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1483 materialSettingsId = sqlite3_column_int( statement.get(), 0 );
1496 return mMaterialSettings.keys();
1501 return static_cast< int >( mMaterialSettings.size() );
1506 auto it = mMaterialSettings.constFind(
name );
1507 if ( it != mMaterialSettings.constEnd() )
1508 return std::unique_ptr< QgsAbstractMaterialSettings >( it.value()->clone() );
1516 QgsDebugError( u
"Cannot Open database for getting favorite symbols"_s );
1517 return QStringList();
1526 return QStringList();
1529 query =
qgs_sqlite3_mprintf( u
"SELECT name FROM %1 WHERE favorite=1"_s.arg( entityTableName( type ) ).toLocal8Bit().data() );
1535 statement = mCurrentDB.prepare( query, nErr );
1537 QStringList symbols;
1538 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1550 QgsDebugError( u
"Cannot open database to get symbols of tagid %1"_s.arg( tagid ) );
1551 return QStringList();
1560 return QStringList();
1563 subquery =
qgs_sqlite3_mprintf( u
"SELECT %1 FROM %2 WHERE tag_id=%d"_s.arg( tagmapEntityIdFieldName( type ), tagmapTableName( type ) ).toLocal8Bit().data(), tagid );
1569 statement = mCurrentDB.prepare( subquery, nErr );
1572 QStringList symbols;
1573 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1575 int id = sqlite3_column_int( statement.get(), 0 );
1577 const QString query =
qgs_sqlite3_mprintf( u
"SELECT name FROM %1 WHERE id=%d"_s.arg( entityTableName( type ) ).toLocal8Bit().data(),
id );
1581 statement2 = mCurrentDB.prepare( query, rc );
1582 while ( rc == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1597 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO tag VALUES (NULL, '%q')", tagname.toUtf8().constData() );
1599 statement = mCurrentDB.prepare( query, nErr );
1600 if ( nErr == SQLITE_OK )
1601 ( void ) sqlite3_step( statement.get() );
1607 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
1613 return QStringList();
1619 statement = mCurrentDB.prepare( query, nError );
1621 QStringList tagList;
1622 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1632 const QString query =
qgs_sqlite3_mprintf( u
"UPDATE %1 SET name='%q' WHERE id=%d"_s.arg( entityTableName( type ) ).toLocal8Bit().data(), newName.toUtf8().constData(),
id );
1634 const bool result = runEmptyQuery( query );
1637 mErrorString = u
"Could not rename!"_s;
1641 mCachedTags.clear();
1642 mCachedFavorites.clear();
1667 bool groupRemoved =
false;
1672 query =
qgs_sqlite3_mprintf(
"DELETE FROM tag WHERE id=%d; DELETE FROM tagmap WHERE tag_id=%d",
id,
id );
1673 groupRemoved =
true;
1677 groupRemoved =
true;
1682 =
qgs_sqlite3_mprintf( u
"DELETE FROM %1 WHERE id=%d; DELETE FROM %2 WHERE %3=%d"_s.arg( entityTableName( type ), tagmapTableName( type ), tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(),
id,
id );
1686 bool result =
false;
1687 if ( !runEmptyQuery( query ) )
1693 mCachedTags.clear();
1694 mCachedFavorites.clear();
1717 std::unique_ptr< QgsSymbol >
symbol( mSymbols.take(
name ) );
1726 std::unique_ptr< QgsAbstract3DSymbol >
symbol( m3dSymbols.take(
name ) );
1735 std::unique_ptr< QgsAbstractMaterialSettings > settings( mMaterialSettings.take(
name ) );
1744 std::unique_ptr< QgsColorRamp > ramp( mColorRamps.take(
name ) );
1752 auto it = mTextFormats.find(
name );
1753 if ( it == mTextFormats.end() )
1756 mTextFormats.erase( it );
1762 auto it = mLabelSettings.find(
name );
1763 if ( it == mLabelSettings.end() )
1766 mLabelSettings.erase( it );
1772 auto it = mLegendPatchShapes.find(
name );
1773 if ( it == mLegendPatchShapes.end() )
1776 mLegendPatchShapes.erase( it );
1783 QgsDebugError( u
"Sorry! Cannot open database to modify."_s );
1793 const bool result =
remove( type,
id );
1796 mCachedTags[type].remove(
name );
1797 mCachedFavorites[type].remove(
name );
1826bool QgsStyle::runEmptyQuery(
const QString &query )
1831 char *zErr =
nullptr;
1832 int nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1834 if ( nErr != SQLITE_OK )
1837 sqlite3_free( zErr );
1840 return nErr == SQLITE_OK;
1851 QgsDebugError( u
"Wrong entity value. cannot apply group"_s );
1855 query =
qgs_sqlite3_mprintf( u
"UPDATE %1 SET favorite=1 WHERE name='%q'"_s.arg( entityTableName( type ) ).toLocal8Bit().data(),
name.toUtf8().constData() );
1859 const bool res = runEmptyQuery( query );
1869 mCachedFavorites[type].insert(
name,
true );
1886 QgsDebugError( u
"Wrong entity value. cannot apply group"_s );
1890 query =
qgs_sqlite3_mprintf( u
"UPDATE %1 SET favorite=0 WHERE name='%q'"_s.arg( entityTableName( type ) ).toLocal8Bit().data(),
name.toUtf8().constData() );
1894 const bool res = runEmptyQuery( query );
1897 mCachedFavorites[type].insert(
name,
false );
1908 QgsDebugError( u
"Sorry! Cannot open database to search"_s );
1909 return QStringList();
1918 return QStringList();
1921 item = entityTableName( type );
1925 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM %q WHERE name LIKE '%%%q%%'", item.toUtf8().constData(), qword.toUtf8().constData() );
1929 statement = mCurrentDB.prepare( query, nErr );
1931 QSet< QString > symbols;
1932 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1938 query =
qgs_sqlite3_mprintf(
"SELECT id FROM tag WHERE name LIKE '%%%q%%'", qword.toUtf8().constData() );
1939 statement = mCurrentDB.prepare( query, nErr );
1942 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1947 QString dummy = tagids.join(
", "_L1 );
1948 query =
qgs_sqlite3_mprintf( u
"SELECT %1 FROM %2 WHERE tag_id IN (%q)"_s.arg( tagmapEntityIdFieldName( type ), tagmapTableName( type ) ).toLocal8Bit().data(), dummy.toUtf8().constData() );
1950 statement = mCurrentDB.prepare( query, nErr );
1952 QStringList symbolids;
1953 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1958 dummy = symbolids.join(
", "_L1 );
1959 query =
qgs_sqlite3_mprintf(
"SELECT name FROM %q WHERE id IN (%q)", item.toUtf8().constData(), dummy.toUtf8().constData() );
1960 statement = mCurrentDB.prepare( query, nErr );
1961 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1966 return QStringList( symbols.constBegin(), symbols.constEnd() );
1996 const auto constTags =
tags;
1997 for (
const QString &t : constTags )
2000 if ( !
tag.isEmpty() )
2012 QString query =
qgs_sqlite3_mprintf( u
"INSERT INTO %1 VALUES (%d,%d)"_s.arg( tagmapTableName( type ) ).toLocal8Bit().data(), tagid, symbolid );
2014 char *zErr =
nullptr;
2016 nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
2020 sqlite3_free( zErr );
2026 clearCachedTags( type,
symbol );
2036 QgsDebugError( u
"Sorry! Cannot open database for detagging."_s );
2051 if ( symbolid == 0 )
2056 const auto constTags =
tags;
2057 for (
const QString &
tag : constTags )
2062 statement2 = mCurrentDB.prepare( query, nErr );
2065 if ( nErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
2067 tagid = sqlite3_column_int( statement2.get(), 0 );
2073 const QString query =
qgs_sqlite3_mprintf( u
"DELETE FROM %1 WHERE tag_id=%d AND %2=%d"_s.arg( tagmapTableName( type ), tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), tagid, symbolid );
2074 runEmptyQuery( query );
2078 clearCachedTags( type,
symbol );
2091 QgsDebugError( u
"Sorry! Cannot open database for detagging."_s );
2106 if ( symbolid == 0 )
2112 const QString query =
qgs_sqlite3_mprintf( u
"DELETE FROM %1 WHERE %2=%d"_s.arg( tagmapTableName( type ), tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
2113 runEmptyQuery( query );
2115 clearCachedTags( type,
symbol );
2130 return QStringList();
2134 auto it = mCachedTags[type].constFind(
symbol );
2135 if ( it != mCachedTags[type].constEnd() )
2143 QgsDebugError( u
"Sorry! Cannot open database for getting the tags."_s );
2144 return QStringList();
2149 return QStringList();
2152 const QString query =
qgs_sqlite3_mprintf( u
"SELECT tag_id FROM %1 WHERE %2=%d"_s.arg( tagmapTableName( type ), tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
2156 statement = mCurrentDB.prepare( query, nErr );
2158 QStringList tagList;
2159 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2161 QString subquery =
qgs_sqlite3_mprintf(
"SELECT name FROM tag WHERE id=%d", sqlite3_column_int( statement.get(), 0 ) );
2165 statement2 = mCurrentDB.prepare( subquery, pErr );
2166 if ( pErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
2173 mCachedTags[type].insert(
symbol, tagList );
2182 QgsDebugError( u
"Sorry! Cannot open database for getting the tags."_s );
2194 auto it = mCachedFavorites[type].constFind(
name );
2195 if ( it != mCachedFavorites[type].constEnd() )
2201 const QStringList names =
allNames( type );
2202 if ( !names.contains(
name ) )
2208 for (
const QString &n : names )
2210 const bool isFav = favorites.contains( n );
2214 mCachedFavorites[type].insert( n, isFav );
2223 QgsDebugError( u
"Sorry! Cannot open database for getting the tags."_s );
2250 const QString query =
qgs_sqlite3_mprintf( u
"SELECT tag_id FROM %1 WHERE tag_id=%d AND %2=%d"_s.arg( tagmapTableName( type ), tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), tagid, symbolid );
2254 statement = mCurrentDB.prepare( query, nErr );
2256 return ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW );
2268 statement = mCurrentDB.prepare( query, nError );
2271 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2279int QgsStyle::getId(
const QString &table,
const QString &name )
2281 QString lowerName(
name.toLower() );
2282 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE LOWER(name)='%q'", table.toUtf8().constData(), lowerName.toUtf8().constData() );
2286 statement = mCurrentDB.
prepare( query, nErr );
2289 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2291 id = sqlite3_column_int( statement.get(), 0 );
2296 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE name='%q'", table.toUtf8().constData(),
name.toUtf8().constData() );
2298 sqlite3_statement_unique_ptr statement;
2300 statement = mCurrentDB.prepare( query, nErr );
2301 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2303 id = sqlite3_column_int( statement.get(), 0 );
2310QString QgsStyle::getName(
const QString &table,
int id )
const
2312 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM %q WHERE id='%q'", table.toUtf8().constData(), QString::number(
id ).toUtf8().constData() );
2314 sqlite3_statement_unique_ptr statement;
2316 statement = mCurrentDB.prepare( query, nErr );
2319 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2329 return getId( u
"symbol"_s,
name );
2334 return getId( entityTableName( type ),
name );
2339 return getId( u
"colorramp"_s,
name );
2344 return mTextFormats.value(
name );
2349 return static_cast< int >( mTextFormats.count() );
2354 return mTextFormats.keys();
2359 return getId( u
"textformat"_s,
name );
2364 return mLabelSettings.value(
name );
2369 return mLegendPatchShapes.value(
name );
2374 return static_cast< int >( mLegendPatchShapes.count() );
2379 auto it = mLegendPatchShapes.constFind(
name );
2380 if ( it == mLegendPatchShapes.constEnd() )
2383 return it.value().symbolType();
2388 auto it = m3dSymbols.constFind(
name );
2389 if ( it != m3dSymbols.constEnd() )
2390 return it.value()->
clone();
2396 return static_cast< int >( m3dSymbols.count() );
2401 auto it = m3dSymbols.constFind(
name );
2402 if ( it == m3dSymbols.constEnd() )
2403 return QList<Qgis::GeometryType>();
2405 return it.value()->compatibleGeometryTypes();
2410 auto it = mLabelSettings.constFind(
name );
2411 if ( it == mLabelSettings.constEnd() )
2414 return it.value().layerType;
2419 return static_cast< int >( mLabelSettings.count() );
2424 return mLabelSettings.keys();
2429 return getId( u
"labelsettings"_s,
name );
2434 return mLegendPatchShapes.keys();
2442 return mPatchMarkerSymbol.get();
2445 return mPatchLineSymbol.get();
2448 return mPatchFillSymbol.get();
2458 return getId( u
"tag"_s,
name );
2463 return getId( u
"smartgroup"_s,
name );
2497 return QStringList();
2502 return addSmartgroup(
name, op, conditions.values( u
"tag"_s ), conditions.values( u
"!tag"_s ), conditions.values( u
"name"_s ), conditions.values( u
"!name"_s ) );
2505int QgsStyle::addSmartgroup(
const QString &
name,
const QString &op,
const QStringList &matchTag,
const QStringList &noMatchTag,
const QStringList &matchName,
const QStringList &noMatchName )
2507 QDomDocument doc( u
"dummy"_s );
2508 QDomElement smartEl = doc.createElement( u
"smartgroup"_s );
2509 smartEl.setAttribute( u
"name"_s,
name );
2510 smartEl.setAttribute( u
"operator"_s, op );
2512 auto addCondition = [&doc, &smartEl](
const QString &constraint,
const QStringList ¶meters ) {
2513 for (
const QString ¶m : parameters )
2515 QDomElement condEl = doc.createElement( u
"condition"_s );
2516 condEl.setAttribute( u
"constraint"_s, constraint );
2517 condEl.setAttribute( u
"param"_s, param );
2518 smartEl.appendChild( condEl );
2521 addCondition( u
"tag"_s, matchTag );
2522 addCondition( u
"!tag"_s, noMatchTag );
2523 addCondition( u
"name"_s, matchName );
2524 addCondition( u
"!name"_s, noMatchName );
2526 QByteArray xmlArray;
2527 QTextStream stream( &xmlArray );
2528 smartEl.save( stream, 4 );
2529 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO smartgroup VALUES (NULL, '%q', '%q')",
name.toUtf8().constData(), xmlArray.constData() );
2531 if ( runEmptyQuery( query ) )
2536 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
2540 QgsDebugError( u
"Couldn't add the smart group into the database!"_s );
2549 QgsDebugError( u
"Cannot open database for listing groups"_s );
2558 statement = mCurrentDB.prepare( query, nError );
2561 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2574 QgsDebugError( u
"Cannot open database for listing groups"_s );
2575 return QStringList();
2583 statement = mCurrentDB.prepare( query, nError );
2586 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2596 QStringList symbols;
2602 statement = mCurrentDB.prepare( query, nErr );
2603 if ( !( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW ) )
2605 return QStringList();
2611 if ( !doc.setContent( xmlstr ) )
2613 QgsDebugError( u
"Cannot open smartgroup id: %1"_s.arg(
id ) );
2615 QDomElement smartEl = doc.documentElement();
2616 QString op = smartEl.attribute( u
"operator"_s );
2617 QDomNodeList conditionNodes = smartEl.childNodes();
2619 bool firstSet =
true;
2620 for (
int i = 0; i < conditionNodes.count(); i++ )
2622 QDomElement condEl = conditionNodes.at( i ).toElement();
2623 QString constraint = condEl.attribute( u
"constraint"_s );
2624 QString param = condEl.attribute( u
"param"_s );
2626 QStringList resultNames;
2628 if ( constraint ==
"tag"_L1 )
2632 else if ( constraint ==
"name"_L1 )
2634 resultNames =
allNames( type ).filter( param, Qt::CaseInsensitive );
2636 else if ( constraint ==
"!tag"_L1 )
2640 for (
const QString &
name : unwanted )
2642 resultNames.removeAll(
name );
2645 else if ( constraint ==
"!name"_L1 )
2647 const QStringList all =
allNames( type );
2648 for (
const QString &str : all )
2650 if ( !str.contains( param, Qt::CaseInsensitive ) )
2658 symbols = resultNames;
2663 if ( op ==
"OR"_L1 )
2665 symbols << resultNames;
2667 else if ( op ==
"AND"_L1 )
2669 QStringList dummy = symbols;
2671 for (
const QString &result : std::as_const( resultNames ) )
2673 if ( dummy.contains( result ) )
2682 const QSet< QString > uniqueSet( symbols.constBegin(), symbols.constEnd() );
2683 QStringList unique( uniqueSet.begin(), uniqueSet.end() );
2684 std::sort( unique.begin(), unique.end() );
2692 QgsDebugError( u
"Cannot open database for listing groups"_s );
2702 statement = mCurrentDB.prepare( query, nError );
2703 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2707 if ( !doc.setContent( xmlstr ) )
2709 QgsDebugError( u
"Cannot open smartgroup id: %1"_s.arg(
id ) );
2712 QDomElement smartEl = doc.documentElement();
2713 QDomNodeList conditionNodes = smartEl.childNodes();
2715 for (
int i = 0; i < conditionNodes.count(); i++ )
2717 QDomElement condEl = conditionNodes.at( i ).toElement();
2718 QString constraint = condEl.attribute( u
"constraint"_s );
2719 QString param = condEl.attribute( u
"param"_s );
2721 condition.insert( constraint, param );
2732 QgsDebugError( u
"Cannot open database for listing groups"_s );
2742 statement = mCurrentDB.prepare( query, nError );
2743 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2747 if ( !doc.setContent( xmlstr ) )
2749 QgsDebugError( u
"Cannot open smartgroup id: %1"_s.arg(
id ) );
2751 QDomElement smartEl = doc.documentElement();
2752 op = smartEl.attribute( u
"operator"_s );
2760 if ( filename.isEmpty() )
2766 QDomDocument doc( u
"qgis_style"_s );
2767 QDomElement root = doc.createElement( u
"qgis_style"_s );
2769 doc.appendChild( root );
2780 QDomNodeList symbolsList = symbolsElem.elementsByTagName( u
"symbol"_s );
2781 int nbSymbols = symbolsList.count();
2782 for (
int i = 0; i < nbSymbols; ++i )
2784 QDomElement
symbol = symbolsList.at( i ).toElement();
2785 QString
name =
symbol.attribute( u
"name"_s );
2787 if (
tags.count() > 0 )
2789 symbol.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2791 if ( favoriteSymbols.contains(
name ) )
2793 symbol.setAttribute( u
"favorite"_s, u
"1"_s );
2798 QDomElement rampsElem = doc.createElement( u
"colorramps"_s );
2799 for ( QMap<QString, QgsColorRamp *>::const_iterator itr = mColorRamps.constBegin(); itr != mColorRamps.constEnd(); ++itr )
2803 if (
tags.count() > 0 )
2805 rampEl.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2807 if ( favoriteColorramps.contains( itr.key() ) )
2809 rampEl.setAttribute( u
"favorite"_s, u
"1"_s );
2811 rampsElem.appendChild( rampEl );
2815 QDomElement textFormatsElem = doc.createElement( u
"textformats"_s );
2816 for (
auto it = mTextFormats.constBegin(); it != mTextFormats.constEnd(); ++it )
2818 QDomElement textFormatEl = doc.createElement( u
"textformat"_s );
2819 textFormatEl.setAttribute( u
"name"_s, it.key() );
2821 textFormatEl.appendChild( textStyleEl );
2823 if (
tags.count() > 0 )
2825 textFormatEl.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2827 if ( favoriteTextFormats.contains( it.key() ) )
2829 textFormatEl.setAttribute( u
"favorite"_s, u
"1"_s );
2831 textFormatsElem.appendChild( textFormatEl );
2835 QDomElement labelSettingsElem = doc.createElement( u
"labelsettings"_s );
2836 for (
auto it = mLabelSettings.constBegin(); it != mLabelSettings.constEnd(); ++it )
2838 QDomElement labelSettingsEl = doc.createElement( u
"labelsetting"_s );
2839 labelSettingsEl.setAttribute( u
"name"_s, it.key() );
2841 labelSettingsEl.appendChild( defEl );
2843 if (
tags.count() > 0 )
2845 labelSettingsEl.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2847 if ( favoriteTextFormats.contains( it.key() ) )
2849 labelSettingsEl.setAttribute( u
"favorite"_s, u
"1"_s );
2851 labelSettingsElem.appendChild( labelSettingsEl );
2855 QDomElement legendPatchShapesElem = doc.createElement( u
"legendpatchshapes"_s );
2856 for (
auto it = mLegendPatchShapes.constBegin(); it != mLegendPatchShapes.constEnd(); ++it )
2858 QDomElement legendPatchShapeEl = doc.createElement( u
"legendpatchshape"_s );
2859 legendPatchShapeEl.setAttribute( u
"name"_s, it.key() );
2860 QDomElement defEl = doc.createElement( u
"definition"_s );
2862 legendPatchShapeEl.appendChild( defEl );
2864 if (
tags.count() > 0 )
2866 legendPatchShapeEl.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2868 if ( favoriteLegendShapes.contains( it.key() ) )
2870 legendPatchShapeEl.setAttribute( u
"favorite"_s, u
"1"_s );
2872 legendPatchShapesElem.appendChild( legendPatchShapeEl );
2876 QDomElement symbols3DElem = doc.createElement( u
"symbols3d"_s );
2877 for (
auto it = m3dSymbols.constBegin(); it != m3dSymbols.constEnd(); ++it )
2879 QDomElement symbolEl = doc.createElement( u
"symbol3d"_s );
2880 symbolEl.setAttribute( u
"name"_s, it.key() );
2881 QDomElement defEl = doc.createElement( u
"definition"_s );
2882 defEl.setAttribute( u
"type"_s, it.value()->type() );
2884 symbolEl.appendChild( defEl );
2886 if (
tags.count() > 0 )
2888 symbolEl.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2890 if ( favorite3DSymbols.contains( it.key() ) )
2892 symbolEl.setAttribute( u
"favorite"_s, u
"1"_s );
2894 symbols3DElem.appendChild( symbolEl );
2898 QDomElement materialSettingsElem = doc.createElement( u
"materialsettings"_s );
2899 for (
auto it = mMaterialSettings.constBegin(); it != mMaterialSettings.constEnd(); ++it )
2901 QDomElement materialSettingEl = doc.createElement( u
"material"_s );
2902 materialSettingEl.setAttribute( u
"name"_s, it.key() );
2903 QDomElement defEl = doc.createElement( u
"definition"_s );
2905 materialSettingEl.appendChild( defEl );
2907 if (
tags.count() > 0 )
2909 materialSettingEl.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2911 if ( favoriteMaterialSettings.contains( it.key() ) )
2913 materialSettingEl.setAttribute( u
"favorite"_s, u
"1"_s );
2915 materialSettingsElem.appendChild( materialSettingEl );
2917 root.appendChild( symbolsElem );
2918 root.appendChild( rampsElem );
2919 root.appendChild( textFormatsElem );
2920 root.appendChild( labelSettingsElem );
2921 root.appendChild( legendPatchShapesElem );
2922 root.appendChild( symbols3DElem );
2923 root.appendChild( materialSettingsElem );
2926 QFile f( filename );
2927 if ( !f.open( QFile::WriteOnly | QIODevice::Truncate ) )
2929 mErrorString =
"Couldn't open file for writing: " + filename;
2933 QTextStream ts( &f );
2947 mErrorString = QString();
2948 QDomDocument doc( u
"style"_s );
2949 QFile f( filename );
2950 if ( !f.open( QFile::ReadOnly ) )
2952 mErrorString = u
"Unable to open the specified file"_s;
2957 if ( !doc.setContent( &f ) )
2959 mErrorString = u
"Unable to understand the style file: %1"_s.arg( filename );
2966 QDomElement docEl = doc.documentElement();
2967 if ( docEl.tagName() !=
"qgis_style"_L1 )
2969 mErrorString =
"Incorrect root tag in style: " + docEl.tagName();
2973 const QString version = docEl.attribute( u
"version"_s );
2976 mErrorString =
"Unknown style file version: " + version;
2982 QDomElement symbolsElement = docEl.firstChildElement( u
"symbols"_s );
2983 QDomElement e = symbolsElement.firstChildElement();
2987 runEmptyQuery( query );
2992 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2994 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
2995 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
3001 if ( e.tagName() ==
"symbol"_L1 )
3003 QString
name = e.attribute( u
"name"_s );
3005 if ( e.hasAttribute( u
"tags"_s ) )
3007 tags = e.attribute( u
"tags"_s ).split(
',' );
3009 bool favorite =
false;
3010 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
3018 QgsSymbol *symbolPtr =
symbol.get();
3038 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
3045 QDomElement rampsElement = docEl.firstChildElement( u
"colorramps"_s );
3046 e = rampsElement.firstChildElement();
3047 for ( ; !e.isNull(); e = e.nextSiblingElement() )
3049 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
3050 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
3056 if ( e.tagName() ==
"colorramp"_L1 )
3058 QString
name = e.attribute( u
"name"_s );
3060 if ( e.hasAttribute( u
"tags"_s ) )
3062 tags = e.attribute( u
"tags"_s ).split(
',' );
3064 bool favorite =
false;
3065 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
3073 QgsColorRamp *rampPtr = ramp.get();
3090 if ( qobject_cast< QGuiApplication * >( QCoreApplication::instance() ) )
3094 const QDomElement textFormatElement = docEl.firstChildElement( u
"textformats"_s );
3095 e = textFormatElement.firstChildElement();
3096 for ( ; !e.isNull(); e = e.nextSiblingElement() )
3098 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
3099 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
3105 if ( e.tagName() ==
"textformat"_L1 )
3107 QString
name = e.attribute( u
"name"_s );
3109 if ( e.hasAttribute( u
"tags"_s ) )
3111 tags = e.attribute( u
"tags"_s ).split(
',' );
3113 bool favorite =
false;
3114 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
3119 QgsTextFormat format;
3120 const QDomElement styleElem = e.firstChildElement();
3121 format.
readXml( styleElem, QgsReadWriteContext() );
3138 const QDomElement labelSettingsElement = docEl.firstChildElement( u
"labelsettings"_s );
3139 e = labelSettingsElement.firstChildElement();
3140 for ( ; !e.isNull(); e = e.nextSiblingElement() )
3142 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
3143 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
3149 if ( e.tagName() ==
"labelsetting"_L1 )
3151 QString
name = e.attribute( u
"name"_s );
3153 if ( e.hasAttribute( u
"tags"_s ) )
3155 tags = e.attribute( u
"tags"_s ).split(
',' );
3157 bool favorite =
false;
3158 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
3163 QgsPalLayerSettings settings;
3164 const QDomElement styleElem = e.firstChildElement();
3165 settings.
readXml( styleElem, QgsReadWriteContext() );
3183 const QDomElement legendPatchShapesElement = docEl.firstChildElement( u
"legendpatchshapes"_s );
3184 e = legendPatchShapesElement.firstChildElement();
3185 for ( ; !e.isNull(); e = e.nextSiblingElement() )
3187 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
3188 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
3194 if ( e.tagName() ==
"legendpatchshape"_L1 )
3196 QString
name = e.attribute( u
"name"_s );
3198 if ( e.hasAttribute( u
"tags"_s ) )
3200 tags = e.attribute( u
"tags"_s ).split(
',' );
3202 bool favorite =
false;
3203 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
3208 QgsLegendPatchShape shape;
3209 const QDomElement shapeElem = e.firstChildElement();
3210 shape.
readXml( shapeElem, QgsReadWriteContext() );
3227 const QDomElement symbols3DElement = docEl.firstChildElement( u
"symbols3d"_s );
3228 e = symbols3DElement.firstChildElement();
3229 for ( ; !e.isNull(); e = e.nextSiblingElement() )
3231 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
3232 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
3238 if ( e.tagName() ==
"symbol3d"_L1 )
3240 QString
name = e.attribute( u
"name"_s );
3242 if ( e.hasAttribute( u
"tags"_s ) )
3244 tags = e.attribute( u
"tags"_s ).split(
',' );
3246 bool favorite =
false;
3247 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
3252 const QDomElement symbolElem = e.firstChildElement();
3253 const QString type = symbolElem.attribute( u
"type"_s );
3257 sym->readXml( symbolElem, QgsReadWriteContext() );
3258 QgsAbstract3DSymbol *newSym = sym.get();
3276 const QDomElement materialSettingsElement = docEl.firstChildElement( u
"materialsettings"_s );
3277 e = materialSettingsElement.firstChildElement();
3278 for ( ; !e.isNull(); e = e.nextSiblingElement() )
3280 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
3281 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
3287 if ( e.tagName() ==
"material"_L1 )
3289 QString
name = e.attribute( u
"name"_s );
3291 if ( e.hasAttribute( u
"tags"_s ) )
3293 tags = e.attribute( u
"tags"_s ).split(
',' );
3295 bool favorite =
false;
3296 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
3301 const QDomElement materialElem = e.firstChildElement();
3302 const QString type = materialElem.attribute( u
"type"_s );
3306 settings->
readXml( materialElem, QgsReadWriteContext() );
3307 QgsAbstractMaterialSettings *newMaterial = settings.get();
3323 runEmptyQuery( query );
3330 QFileInfo fileInfo( path );
3332 if ( fileInfo.suffix().compare(
"xml"_L1, Qt::CaseInsensitive ) != 0 )
3336 if ( !QFile::exists( path ) )
3339 QFile inputFile( path );
3340 if ( !inputFile.open( QIODevice::ReadOnly ) )
3343 QTextStream stream( &inputFile );
3344 const QString line = stream.readLine();
3345 return line ==
"<!DOCTYPE qgis_style>"_L1;
3360 mReadOnly = readOnly;
3363bool QgsStyle::updateSymbol( StyleEntity type,
const QString &name )
3365 QDomDocument doc( u
"dummy"_s );
3367 QByteArray xmlArray;
3368 QTextStream stream( &xmlArray );
3377 auto it = mSymbols.constFind(
name );
3378 if ( it == mSymbols.constEnd() || !it.value() )
3380 QgsDebugError( u
"Update request received for unavailable symbol"_s );
3385 if ( symEl.isNull() )
3387 QgsDebugError( u
"Couldn't convert symbol to valid XML!"_s );
3390 symEl.save( stream, 4 );
3391 query =
qgs_sqlite3_mprintf(
"UPDATE symbol SET xml='%q' WHERE name='%q';", xmlArray.constData(),
name.toUtf8().constData() );
3398 auto it = m3dSymbols.constFind(
name );
3399 if ( it == m3dSymbols.constEnd() || !it.value() )
3401 QgsDebugError( u
"Update request received for unavailable symbol"_s );
3405 symEl = doc.createElement( u
"symbol"_s );
3406 symEl.setAttribute( u
"type"_s, it.value()->type() );
3407 it.value()->writeXml( symEl, QgsReadWriteContext() );
3408 if ( symEl.isNull() )
3410 QgsDebugError( u
"Couldn't convert symbol to valid XML!"_s );
3413 symEl.save( stream, 4 );
3414 query =
qgs_sqlite3_mprintf(
"UPDATE symbol3d SET xml='%q' WHERE name='%q';", xmlArray.constData(),
name.toUtf8().constData() );
3421 auto it = mMaterialSettings.constFind(
name );
3422 if ( it == mMaterialSettings.constEnd() || !it.value() )
3424 QgsDebugError( u
"Update request received for unavailable material"_s );
3428 symEl = doc.createElement( u
"material"_s );
3429 it.value()->writeXml( symEl, QgsReadWriteContext() );
3430 if ( symEl.isNull() )
3432 QgsDebugError( u
"Couldn't convert material settings to valid XML!"_s );
3435 symEl.save( stream, 4 );
3436 query =
qgs_sqlite3_mprintf(
"UPDATE materialsettings SET xml='%q' WHERE name='%q';", xmlArray.constData(),
name.toUtf8().constData() );
3442 auto it = mColorRamps.constFind(
name );
3443 if ( it == mColorRamps.constEnd() || !it.value() )
3445 QgsDebugError( u
"Update requested for unavailable color ramp."_s );
3450 if ( symEl.isNull() )
3452 QgsDebugError( u
"Couldn't convert color ramp to valid XML!"_s );
3455 symEl.save( stream, 4 );
3456 query =
qgs_sqlite3_mprintf(
"UPDATE colorramp SET xml='%q' WHERE name='%q';", xmlArray.constData(),
name.toUtf8().constData() );
3462 auto it = mTextFormats.constFind(
name );
3463 if ( it == mTextFormats.constEnd() )
3465 QgsDebugError( u
"Update requested for unavailable text format."_s );
3469 symEl = it.value().writeXml( doc, QgsReadWriteContext() );
3470 if ( symEl.isNull() )
3472 QgsDebugError( u
"Couldn't convert text format to valid XML!"_s );
3475 symEl.save( stream, 4 );
3476 query =
qgs_sqlite3_mprintf(
"UPDATE textformat SET xml='%q' WHERE name='%q';", xmlArray.constData(),
name.toUtf8().constData() );
3482 auto it = mLabelSettings.constFind(
name );
3483 if ( it == mLabelSettings.constEnd() )
3485 QgsDebugError( u
"Update requested for unavailable label settings."_s );
3489 symEl = it.value().writeXml( doc, QgsReadWriteContext() );
3490 if ( symEl.isNull() )
3492 QgsDebugError( u
"Couldn't convert label settings to valid XML!"_s );
3495 symEl.save( stream, 4 );
3496 query =
qgs_sqlite3_mprintf(
"UPDATE labelsettings SET xml='%q' WHERE name='%q';", xmlArray.constData(),
name.toUtf8().constData() );
3502 auto it = mLegendPatchShapes.constFind(
name );
3503 if ( it == mLegendPatchShapes.constEnd() )
3505 QgsDebugError( u
"Update requested for unavailable legend patch shape."_s );
3509 symEl = doc.createElement( u
"shape"_s );
3510 it.value().writeXml( symEl, doc, QgsReadWriteContext() );
3511 symEl.save( stream, 4 );
3512 query =
qgs_sqlite3_mprintf(
"UPDATE legendpatchshapes SET xml='%q' WHERE name='%q';", xmlArray.constData(),
name.toUtf8().constData() );
3525 if ( !runEmptyQuery( query ) )
3527 QgsDebugError( u
"Couldn't update symbol into the database!"_s );
3564 mCachedTags[type].remove(
name );
3567bool QgsStyle::createStyleMetadataTableIfNeeded()
3570 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='stylemetadata'" );
3571 sqlite3_statement_unique_ptr statement;
3573 statement = mCurrentDB.prepare( query, rc );
3575 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
3579 "CREATE TABLE stylemetadata("
3580 "id INTEGER PRIMARY KEY,"
3584 runEmptyQuery( query );
3586 runEmptyQuery( query );
3595void QgsStyle::upgradeIfRequired()
3599 if ( !createStyleMetadataTableIfNeeded() )
3601 const QString query =
qgs_sqlite3_mprintf(
"SELECT value FROM stylemetadata WHERE key='version'" );
3603 sqlite3_statement_unique_ptr statement = mCurrentDB.prepare( query, rc );
3604 if ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
3616 runEmptyQuery( query );
3629 return u
"colorramp"_s;
3632 return u
"textformat"_s;
3635 return u
"labelsettings"_s;
3638 return u
"legendpatchshapes"_s;
3641 return u
"symbol3d"_s;
3644 return u
"materialsettings"_s;
3650 return u
"smartgroup"_s;
3663 return u
"ctagmap"_s;
3666 return u
"tftagmap"_s;
3669 return u
"lstagmap"_s;
3672 return u
"lpstagmap"_s;
3675 return u
"symbol3dtagmap"_s;
3678 return u
"materialsettingstagmap"_s;
3692 return u
"symbol_id"_s;
3695 return u
"colorramp_id"_s;
3698 return u
"textformat_id"_s;
3701 return u
"labelsettings_id"_s;
3704 return u
"legendpatchshape_id"_s;
3707 return u
"symbol3d_id"_s;
3710 return u
"materialsettings_id"_s;
@ 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.
Abstract base class for material settings.
virtual void writeXml(QDomElement &element, const QgsReadWriteContext &) const
Writes settings to a DOM element.
virtual QString type() const =0
Returns the unique type name for the material.
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 QgsMaterialRegistry * materialRegistry()
Returns registry of available 3D materials.
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.
std::unique_ptr< QgsAbstractMaterialSettings > createMaterialSettings(const QString &type) const
Creates a new instance of the material settings of the specified type.
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.
static const QgsSettingsEntryInteger * settingsSymbolsListGroupsIndex
Settings entry for symbols list groups index.
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 material settings 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.
@ MaterialSettingsEntity
Material settings.
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.
bool saveMaterialSettings(const QString &name, QgsAbstractMaterialSettings *settings, bool favorite, const QStringList &tags)
Adds 3D material settings to the database.
QStringList colorRampNames() const
Returns a list of names of color ramps.
std::unique_ptr< QgsAbstractMaterialSettings > materialSettings(const QString &name) const
Returns a new copy of the 3D material settings with the specified name.
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 addMaterialSettings(const QString &name, QgsAbstractMaterialSettings *settings, bool update=false)
Adds a 3D material settings with the specified name to the 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.
QStringList materialSettingsNames() const
Returns a list of names of 3D material settings in the style.
bool renameMaterialSettings(const QString &oldName, const QString &newName)
Changes a 3D material settings's name.
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.
int materialSettingsCount() const
Returns count of 3D material settings in 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
MaterialSettingsTable
Columns available in the 3D material settings table.
@ MaterialSettingsTableId
3d material settings ID
@ MaterialSettingsTableName
3d material settings name
@ MaterialSettingsTableFavoriteId
3d material settings is favorite flag
@ MaterialSettingsTableXML
3d material settings definition (as XML)
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