44#include <QDomDocument>
47#include <QDomNodeList>
53#include "moc_qgsstyle.cpp"
55using namespace Qt::StringLiterals;
57#define STYLE_CURRENT_VERSION "2"
82QgsStyle *QgsStyle::sDefaultStyle =
nullptr;
88 simpleMarker->setStrokeWidth( 0.4 );
89 mPatchMarkerSymbol = std::make_unique< QgsMarkerSymbol >(
QgsSymbolLayerList() << simpleMarker.release() );
91 auto simpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 84, 176, 74 ), 0.6 );
92 mPatchLineSymbol = std::make_unique< QgsLineSymbol >(
QgsSymbolLayerList() << simpleLine.release() );
94 auto gradientFill = std::make_unique< QgsGradientFillSymbolLayer >( QColor( 66, 150, 63 ), QColor( 84, 176, 74 ) );
95 auto simpleOutline = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 56, 128, 54 ), 0.26 );
96 mPatchFillSymbol = std::make_unique< QgsFillSymbol >(
QgsSymbolLayerList() << gradientFill.release() << simpleOutline.release() );
117 switch ( entity->
type() )
150 static QString sStyleFilename;
151 if ( !sDefaultStyle )
157 if ( !QFile::exists( sStyleFilename ) )
160 sDefaultStyle->createDatabase( sStyleFilename );
165 sDefaultStyle->createStyleMetadataTableIfNeeded();
172 sDefaultStyle->mInitialized =
false;
175 sDefaultStyle->initializeDefaultStyle( sStyleFilename );
178 sDefaultStyle->setName( QObject::tr(
"Default" ) );
180 else if ( initialize && !sDefaultStyle->mInitialized )
183 sDefaultStyle->initializeDefaultStyle( sStyleFilename );
185 return sDefaultStyle;
188void QgsStyle::initializeDefaultStyle(
const QString &filename )
190 Q_ASSERT(
this == sDefaultStyle );
191 if (
this != sDefaultStyle )
207 delete sDefaultStyle;
208 sDefaultStyle =
nullptr;
213 qDeleteAll( mSymbols );
214 qDeleteAll( mColorRamps );
215 qDeleteAll( m3dSymbols );
219 mTextFormats.clear();
223 mCachedFavorites.clear();
232 auto it = mSymbols.constFind(
name );
233 if ( it != mSymbols.constEnd() )
254 QDomDocument doc( u
"dummy"_s );
256 if ( symEl.isNull() )
263 QTextStream stream( &xmlArray );
264 symEl.save( stream, 4 );
265 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO symbol VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
267 if ( !runEmptyQuery( query ) )
269 QgsDebugError( u
"Couldn't insert symbol into the database!"_s );
331 return mSymbols.value(
name );
336 return mSymbols.count();
341 return mSymbols.keys();
351 auto it = mColorRamps.constFind(
name );
352 if ( it != mColorRamps.constEnd() )
373 auto it = mTextFormats.find(
name );
374 if ( it != mTextFormats.end() )
377 mTextFormats.erase( it );
378 mTextFormats.insert(
name, format );
384 mTextFormats.insert(
name, format );
395 auto it = mLabelSettings.find(
name );
396 if ( it != mLabelSettings.end() )
399 mLabelSettings.erase( it );
400 mLabelSettings.insert(
name, settings );
406 mLabelSettings.insert(
name, settings );
417 auto it = mLegendPatchShapes.find(
name );
418 if ( it != mLegendPatchShapes.end() )
421 mLegendPatchShapes.erase( it );
422 mLegendPatchShapes.insert(
name, shape );
428 mLegendPatchShapes.insert(
name, shape );
439 auto it = m3dSymbols.constFind(
name );
440 if ( it != m3dSymbols.constEnd() )
461 QDomDocument doc( u
"dummy"_s );
464 if ( rampEl.isNull() )
466 QgsDebugError( u
"Couldn't convert color ramp to valid XML!"_s );
471 QTextStream stream( &xmlArray );
472 rampEl.save( stream, 4 );
473 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO colorramp VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
474 if ( !runEmptyQuery( query ) )
476 QgsDebugError( u
"Couldn't insert colorramp into the database!"_s );
498 return ramp ? ramp->
clone() :
nullptr;
508 return mColorRamps.count();
513 return mColorRamps.keys();
516void QgsStyle::handleDeferred3DSymbolCreation()
518 for (
auto it = mDeferred3DsymbolElements.constBegin(); it != mDeferred3DsymbolElements.constEnd(); ++it )
520 const QString symbolType = it.value().attribute( u
"type"_s );
534 mDeferred3DsymbolElements.clear();
537bool QgsStyle::openDatabase(
const QString &filename )
539 int rc = mCurrentDB.open( filename );
542 mErrorString = u
"Couldn't open the style database: %1"_s.arg( mCurrentDB.errorMessage() );
551 mErrorString.clear();
552 if ( !openDatabase( filename ) )
554 mErrorString = u
"Unable to create database"_s;
566 mErrorString.clear();
567 if ( !openDatabase( u
":memory:"_s ) )
569 mErrorString = u
"Unable to create temporary memory database"_s;
582 "CREATE TABLE symbol("
583 "id INTEGER PRIMARY KEY,"
587 "CREATE TABLE colorramp("
588 "id INTEGER PRIMARY KEY,"
592 "CREATE TABLE textformat("
593 "id INTEGER PRIMARY KEY,"
597 "CREATE TABLE labelsettings("
598 "id INTEGER PRIMARY KEY,"
602 "CREATE TABLE legendpatchshapes("
603 "id INTEGER PRIMARY KEY,"
607 "CREATE TABLE symbol3d("
608 "id INTEGER PRIMARY KEY,"
613 "id INTEGER PRIMARY KEY,"
615 "CREATE TABLE tagmap("
616 "tag_id INTEGER NOT NULL,"
617 "symbol_id INTEGER);"
618 "CREATE TABLE ctagmap("
619 "tag_id INTEGER NOT NULL,"
620 "colorramp_id INTEGER);"
621 "CREATE TABLE tftagmap("
622 "tag_id INTEGER NOT NULL,"
623 "textformat_id INTEGER);"
624 "CREATE TABLE lstagmap("
625 "tag_id INTEGER NOT NULL,"
626 "labelsettings_id INTEGER);"
627 "CREATE TABLE lpstagmap("
628 "tag_id INTEGER NOT NULL,"
629 "legendpatchshape_id INTEGER);"
630 "CREATE TABLE symbol3dtagmap("
631 "tag_id INTEGER NOT NULL,"
632 "symbol3d_id INTEGER);"
633 "CREATE TABLE smartgroup("
634 "id INTEGER PRIMARY KEY,"
638 runEmptyQuery( query );
643 mErrorString.clear();
646 if ( !openDatabase( filename ) )
648 mErrorString = u
"Unable to open database file specified"_s;
654 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='textformat'" );
657 statement = mCurrentDB.prepare( query, rc );
658 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
661 "CREATE TABLE textformat("
662 "id INTEGER PRIMARY KEY,"
666 "CREATE TABLE tftagmap("
667 "tag_id INTEGER NOT NULL,"
668 "textformat_id INTEGER);"
670 runEmptyQuery( query );
673 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='labelsettings'" );
674 statement = mCurrentDB.prepare( query, rc );
675 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
678 "CREATE TABLE labelsettings("
679 "id INTEGER PRIMARY KEY,"
683 "CREATE TABLE lstagmap("
684 "tag_id INTEGER NOT NULL,"
685 "labelsettings_id INTEGER);"
687 runEmptyQuery( query );
690 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='legendpatchshapes'" );
691 statement = mCurrentDB.prepare( query, rc );
692 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
695 "CREATE TABLE legendpatchshapes("
696 "id INTEGER PRIMARY KEY,"
700 "CREATE TABLE lpstagmap("
701 "tag_id INTEGER NOT NULL,"
702 "legendpatchshape_id INTEGER);"
704 runEmptyQuery( query );
708 statement = mCurrentDB.prepare( query, rc );
709 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
712 "CREATE TABLE symbol3d("
713 "id INTEGER PRIMARY KEY,"
717 "CREATE TABLE symbol3dtagmap("
718 "tag_id INTEGER NOT NULL,"
719 "symbol3d_id INTEGER);"
721 runEmptyQuery( query );
726 "UPDATE symbol SET favorite=0 WHERE favorite IS NULL;"
727 "UPDATE colorramp SET favorite=0 WHERE favorite IS NULL;"
728 "UPDATE textformat SET favorite=0 WHERE favorite IS NULL;"
729 "UPDATE labelsettings SET favorite=0 WHERE favorite IS NULL;"
730 "UPDATE legendpatchshapes SET favorite=0 WHERE favorite IS NULL;"
731 "UPDATE symbol3d SET favorite=0 WHERE favorite IS NULL;"
733 runEmptyQuery( query );
739 statement = mCurrentDB.prepare( query, rc );
741 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
747 if ( !doc.setContent( xmlstring ) )
753 QDomElement symElement = doc.documentElement();
756 mSymbols.insert( symbolName,
symbol.release() );
763 statement = mCurrentDB.prepare( query, rc );
764 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
770 if ( !doc.setContent( xmlstring ) )
775 QDomElement rampElement = doc.documentElement();
778 mColorRamps.insert( rampName, ramp.release() );
785 statement = mCurrentDB.prepare( query, rc );
786 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
792 if ( !doc.setContent( xmlstring ) )
797 QDomElement formatElement = doc.documentElement();
800 mTextFormats.insert( formatName, format );
807 statement = mCurrentDB.prepare( query, rc );
808 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
814 if ( !doc.setContent( xmlstring ) )
816 QgsDebugError(
"Cannot open label settings " + settingsName );
819 QDomElement settingsElement = doc.documentElement();
822 mLabelSettings.insert( settingsName, settings );
829 statement = mCurrentDB.prepare( query, rc );
830 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
836 if ( !doc.setContent( xmlstring ) )
838 QgsDebugError(
"Cannot open legend patch shape " + settingsName );
841 QDomElement settingsElement = doc.documentElement();
844 mLegendPatchShapes.insert( settingsName, shape );
851 statement = mCurrentDB.prepare( query, rc );
855 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
861 if ( !doc.setContent( xmlstring ) )
866 QDomElement settingsElement = doc.documentElement();
868 if ( !registry3dPopulated )
870 mDeferred3DsymbolElements.insert( settingsName, settingsElement );
874 const QString symbolType = settingsElement.attribute( u
"type"_s );
879 m3dSymbols.insert( settingsName,
symbol.release() );
890 mFileName = filename;
891 createStyleMetadataTableIfNeeded();
897 mErrorString.clear();
899 if ( !filename.isEmpty() )
900 mFileName = filename;
907 mFileName = filename;
912 if ( mSymbols.contains( newName ) )
922 mSymbols.insert( newName,
symbol );
933 QgsDebugError( u
"No such symbol for tagging in database: "_s + oldName );
952 if ( mColorRamps.contains( newName ) )
954 QgsDebugError( u
"Color ramp of new name already exists."_s );
962 mColorRamps.insert( newName, ramp );
968 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM colorramp WHERE name='%q'", oldName.toUtf8().constData() );
970 statement = mCurrentDB.prepare( query, nErr );
971 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
973 rampid = sqlite3_column_int( statement.get(), 0 );
988 QDomDocument doc( u
"dummy"_s );
991 if ( formatElem.isNull() )
993 QgsDebugError( u
"Couldn't convert text format to valid XML!"_s );
998 QTextStream stream( &xmlArray );
999 formatElem.save( stream, 4 );
1000 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO textformat VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1001 if ( !runEmptyQuery( query ) )
1003 QgsDebugError( u
"Couldn't insert text format into the database!"_s );
1024 if ( mTextFormats.contains( newName ) )
1026 QgsDebugError( u
"Text format of new name already exists."_s );
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( u
"dummy"_s );
1063 if ( settingsElem.isNull() )
1065 QgsDebugError( u
"Couldn't convert label settings to valid XML!"_s );
1069 QByteArray xmlArray;
1070 QTextStream stream( &xmlArray );
1071 settingsElem.save( stream, 4 );
1072 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO labelsettings VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1073 if ( !runEmptyQuery( query ) )
1075 QgsDebugError( u
"Couldn't insert label settings into the database!"_s );
1096 if ( mLabelSettings.contains( newName ) )
1098 QgsDebugError( u
"Label settings of new name already exists."_s );
1102 if ( !mLabelSettings.contains( oldName ) )
1106 mLabelSettings.insert( newName, settings );
1112 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM labelsettings WHERE name='%q'", oldName.toUtf8().constData() );
1114 statement = mCurrentDB.prepare( query, nErr );
1115 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1132 QDomDocument doc( u
"dummy"_s );
1133 QDomElement shapeElem = doc.createElement( u
"shape"_s );
1136 QByteArray xmlArray;
1137 QTextStream stream( &xmlArray );
1138 shapeElem.save( stream, 4 );
1139 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO legendpatchshapes VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1140 if ( !runEmptyQuery( query ) )
1142 QgsDebugError( u
"Couldn't insert legend patch shape into the database!"_s );
1157 if ( mLegendPatchShapes.contains( newName ) )
1159 QgsDebugError( u
"Legend patch shape of new name already exists."_s );
1163 if ( !mLegendPatchShapes.contains( oldName ) )
1167 mLegendPatchShapes.insert( newName, shape );
1173 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM legendpatchshapes WHERE name='%q'", oldName.toUtf8().constData() );
1175 statement = mCurrentDB.prepare( query, nErr );
1176 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1194 auto it = mDefaultPatchCache[
static_cast< int >( type )].constFind( size );
1195 if ( it != mDefaultPatchCache[
static_cast< int >( type )].constEnd() )
1202 geom =
QgsGeometry( std::make_unique< QgsPoint >(
static_cast< int >( size.width() ) / 2,
static_cast< int >( size.height() ) / 2 ) );
1209 double y =
static_cast< int >( size.height() ) / 2 + 0.5;
1210 geom =
QgsGeometry( std::make_unique< QgsLineString >( ( QVector< double >() << 0 << size.width() ), ( QVector< double >() << y << y ) ) );
1218 QVector< double >() << 0 <<
static_cast< int >( size.width() ) <<
static_cast< int >( size.width() ) << 0 << 0,
1219 QVector< double >() <<
static_cast< int >( size.height() ) <<
static_cast< int >( size.height() ) << 0 << 0 <<
static_cast< int >( size.height() )
1230 mDefaultPatchCache[
static_cast< int >( type )][size] = res;
1237 return QList<QList<QPolygonF> >();
1239 auto it = mDefaultPatchQPolygonFCache[
static_cast< int >( type )].constFind( size );
1240 if ( it != mDefaultPatchQPolygonFCache[
static_cast< int >( type )].constEnd() )
1244 mDefaultPatchQPolygonFCache[
static_cast< int >( type )][size] = res;
1270 QDomDocument doc( u
"dummy"_s );
1271 QDomElement elem = doc.createElement( u
"symbol"_s );
1272 elem.setAttribute( u
"type"_s,
symbol->type() );
1275 QByteArray xmlArray;
1276 QTextStream stream( &xmlArray );
1277 elem.save( stream, 4 );
1278 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO symbol3d VALUES (NULL, '%q', '%q', %d);",
name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1279 if ( !runEmptyQuery( query ) )
1281 QgsDebugError( u
"Couldn't insert 3d symbol into the database!"_s );
1296 if ( m3dSymbols.contains( newName ) )
1298 QgsDebugError( u
"3d symbol of new name already exists."_s );
1302 if ( !m3dSymbols.contains( oldName ) )
1306 m3dSymbols.insert( newName,
symbol );
1312 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM symbol3d WHERE name='%q'", oldName.toUtf8().constData() );
1314 statement = mCurrentDB.prepare( query, nErr );
1315 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1330 return m3dSymbols.keys();
1337 QgsDebugError( u
"Cannot Open database for getting favorite symbols"_s );
1338 return QStringList();
1347 return QStringList();
1350 query =
qgs_sqlite3_mprintf( u
"SELECT name FROM %1 WHERE favorite=1"_s.arg( entityTableName( type ) ).toLocal8Bit().data() );
1356 statement = mCurrentDB.prepare( query, nErr );
1358 QStringList symbols;
1359 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1371 QgsDebugError( u
"Cannot open database to get symbols of tagid %1"_s.arg( tagid ) );
1372 return QStringList();
1381 return QStringList();
1384 subquery =
qgs_sqlite3_mprintf( u
"SELECT %1 FROM %2 WHERE tag_id=%d"_s.arg( tagmapEntityIdFieldName( type ), tagmapTableName( type ) ).toLocal8Bit().data(), tagid );
1390 statement = mCurrentDB.prepare( subquery, nErr );
1393 QStringList symbols;
1394 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1396 int id = sqlite3_column_int( statement.get(), 0 );
1398 const QString query =
qgs_sqlite3_mprintf( u
"SELECT name FROM %1 WHERE id=%d"_s.arg( entityTableName( type ) ).toLocal8Bit().data(),
id );
1402 statement2 = mCurrentDB.prepare( query, rc );
1403 while ( rc == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1418 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO tag VALUES (NULL, '%q')", tagname.toUtf8().constData() );
1420 statement = mCurrentDB.prepare( query, nErr );
1421 if ( nErr == SQLITE_OK )
1422 ( void ) sqlite3_step( statement.get() );
1425 settings.
setValue( u
"qgis/symbolsListGroupsIndex"_s, 0 );
1429 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
1435 return QStringList();
1441 statement = mCurrentDB.prepare( query, nError );
1443 QStringList tagList;
1444 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1454 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 );
1456 const bool result = runEmptyQuery( query );
1459 mErrorString = u
"Could not rename!"_s;
1463 mCachedTags.clear();
1464 mCachedFavorites.clear();
1489 bool groupRemoved =
false;
1494 query =
qgs_sqlite3_mprintf(
"DELETE FROM tag WHERE id=%d; DELETE FROM tagmap WHERE tag_id=%d",
id,
id );
1495 groupRemoved =
true;
1499 groupRemoved =
true;
1504 =
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 );
1508 bool result =
false;
1509 if ( !runEmptyQuery( query ) )
1515 mCachedTags.clear();
1516 mCachedFavorites.clear();
1521 settings.
setValue( u
"qgis/symbolsListGroupsIndex"_s, 0 );
1540 std::unique_ptr< QgsSymbol >
symbol( mSymbols.take(
name ) );
1549 std::unique_ptr< QgsAbstract3DSymbol >
symbol( m3dSymbols.take(
name ) );
1558 std::unique_ptr< QgsColorRamp > ramp( mColorRamps.take(
name ) );
1566 auto it = mTextFormats.find(
name );
1567 if ( it == mTextFormats.end() )
1570 mTextFormats.erase( it );
1576 auto it = mLabelSettings.find(
name );
1577 if ( it == mLabelSettings.end() )
1580 mLabelSettings.erase( it );
1586 auto it = mLegendPatchShapes.find(
name );
1587 if ( it == mLegendPatchShapes.end() )
1590 mLegendPatchShapes.erase( it );
1597 QgsDebugError( u
"Sorry! Cannot open database to modify."_s );
1607 const bool result =
remove( type,
id );
1610 mCachedTags[type].remove(
name );
1611 mCachedFavorites[type].remove(
name );
1640bool QgsStyle::runEmptyQuery(
const QString &query )
1645 char *zErr =
nullptr;
1646 int nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1648 if ( nErr != SQLITE_OK )
1651 sqlite3_free( zErr );
1654 return nErr == SQLITE_OK;
1665 QgsDebugError( u
"Wrong entity value. cannot apply group"_s );
1669 query =
qgs_sqlite3_mprintf( u
"UPDATE %1 SET favorite=1 WHERE name='%q'"_s.arg( entityTableName( type ) ).toLocal8Bit().data(),
name.toUtf8().constData() );
1673 const bool res = runEmptyQuery( query );
1683 mCachedFavorites[type].insert(
name,
true );
1700 QgsDebugError( u
"Wrong entity value. cannot apply group"_s );
1704 query =
qgs_sqlite3_mprintf( u
"UPDATE %1 SET favorite=0 WHERE name='%q'"_s.arg( entityTableName( type ) ).toLocal8Bit().data(),
name.toUtf8().constData() );
1708 const bool res = runEmptyQuery( query );
1711 mCachedFavorites[type].insert(
name,
false );
1722 QgsDebugError( u
"Sorry! Cannot open database to search"_s );
1723 return QStringList();
1732 return QStringList();
1735 item = entityTableName( type );
1739 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM %q WHERE name LIKE '%%%q%%'", item.toUtf8().constData(), qword.toUtf8().constData() );
1743 statement = mCurrentDB.prepare( query, nErr );
1745 QSet< QString > symbols;
1746 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1752 query =
qgs_sqlite3_mprintf(
"SELECT id FROM tag WHERE name LIKE '%%%q%%'", qword.toUtf8().constData() );
1753 statement = mCurrentDB.prepare( query, nErr );
1756 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1761 QString dummy = tagids.join(
", "_L1 );
1762 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() );
1764 statement = mCurrentDB.prepare( query, nErr );
1766 QStringList symbolids;
1767 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1772 dummy = symbolids.join(
", "_L1 );
1773 query =
qgs_sqlite3_mprintf(
"SELECT name FROM %q WHERE id IN (%q)", item.toUtf8().constData(), dummy.toUtf8().constData() );
1774 statement = mCurrentDB.prepare( query, nErr );
1775 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1780 return QStringList( symbols.constBegin(), symbols.constEnd() );
1810 const auto constTags =
tags;
1811 for (
const QString &t : constTags )
1814 if ( !
tag.isEmpty() )
1826 QString query =
qgs_sqlite3_mprintf( u
"INSERT INTO %1 VALUES (%d,%d)"_s.arg( tagmapTableName( type ) ).toLocal8Bit().data(), tagid, symbolid );
1828 char *zErr =
nullptr;
1830 nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1834 sqlite3_free( zErr );
1840 clearCachedTags( type,
symbol );
1850 QgsDebugError( u
"Sorry! Cannot open database for detagging."_s );
1865 if ( symbolid == 0 )
1870 const auto constTags =
tags;
1871 for (
const QString &
tag : constTags )
1876 statement2 = mCurrentDB.prepare( query, nErr );
1879 if ( nErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1881 tagid = sqlite3_column_int( statement2.get(), 0 );
1887 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 );
1888 runEmptyQuery( query );
1892 clearCachedTags( type,
symbol );
1905 QgsDebugError( u
"Sorry! Cannot open database for detagging."_s );
1920 if ( symbolid == 0 )
1926 const QString query =
qgs_sqlite3_mprintf( u
"DELETE FROM %1 WHERE %2=%d"_s.arg( tagmapTableName( type ), tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1927 runEmptyQuery( query );
1929 clearCachedTags( type,
symbol );
1944 return QStringList();
1948 auto it = mCachedTags[type].constFind(
symbol );
1949 if ( it != mCachedTags[type].constEnd() )
1957 QgsDebugError( u
"Sorry! Cannot open database for getting the tags."_s );
1958 return QStringList();
1963 return QStringList();
1966 const QString query =
qgs_sqlite3_mprintf( u
"SELECT tag_id FROM %1 WHERE %2=%d"_s.arg( tagmapTableName( type ), tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1970 statement = mCurrentDB.prepare( query, nErr );
1972 QStringList tagList;
1973 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1975 QString subquery =
qgs_sqlite3_mprintf(
"SELECT name FROM tag WHERE id=%d", sqlite3_column_int( statement.get(), 0 ) );
1979 statement2 = mCurrentDB.prepare( subquery, pErr );
1980 if ( pErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1987 mCachedTags[type].insert(
symbol, tagList );
1996 QgsDebugError( u
"Sorry! Cannot open database for getting the tags."_s );
2008 auto it = mCachedFavorites[type].constFind(
name );
2009 if ( it != mCachedFavorites[type].constEnd() )
2015 const QStringList names =
allNames( type );
2016 if ( !names.contains(
name ) )
2022 for (
const QString &n : names )
2024 const bool isFav = favorites.contains( n );
2028 mCachedFavorites[type].insert( n, isFav );
2037 QgsDebugError( u
"Sorry! Cannot open database for getting the tags."_s );
2064 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 );
2068 statement = mCurrentDB.prepare( query, nErr );
2070 return ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW );
2082 statement = mCurrentDB.prepare( query, nError );
2085 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2093int QgsStyle::getId(
const QString &table,
const QString &name )
2095 QString lowerName(
name.toLower() );
2096 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE LOWER(name)='%q'", table.toUtf8().constData(), lowerName.toUtf8().constData() );
2100 statement = mCurrentDB.
prepare( query, nErr );
2103 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2105 id = sqlite3_column_int( statement.get(), 0 );
2110 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE name='%q'", table.toUtf8().constData(),
name.toUtf8().constData() );
2112 sqlite3_statement_unique_ptr statement;
2114 statement = mCurrentDB.prepare( query, nErr );
2115 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2117 id = sqlite3_column_int( statement.get(), 0 );
2124QString QgsStyle::getName(
const QString &table,
int id )
const
2126 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM %q WHERE id='%q'", table.toUtf8().constData(), QString::number(
id ).toUtf8().constData() );
2128 sqlite3_statement_unique_ptr statement;
2130 statement = mCurrentDB.prepare( query, nErr );
2133 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2143 return getId( u
"symbol"_s,
name );
2148 return getId( entityTableName( type ),
name );
2153 return getId( u
"colorramp"_s,
name );
2158 return mTextFormats.value(
name );
2163 return mTextFormats.count();
2168 return mTextFormats.keys();
2173 return getId( u
"textformat"_s,
name );
2178 return mLabelSettings.value(
name );
2183 return mLegendPatchShapes.value(
name );
2188 return mLegendPatchShapes.count();
2193 auto it = mLegendPatchShapes.constFind(
name );
2194 if ( it == mLegendPatchShapes.constEnd() )
2197 return it.value().symbolType();
2202 auto it = m3dSymbols.constFind(
name );
2203 if ( it != m3dSymbols.constEnd() )
2204 return it.value()->
clone();
2210 return m3dSymbols.count();
2215 auto it = m3dSymbols.constFind(
name );
2216 if ( it == m3dSymbols.constEnd() )
2217 return QList<Qgis::GeometryType>();
2219 return it.value()->compatibleGeometryTypes();
2224 auto it = mLabelSettings.constFind(
name );
2225 if ( it == mLabelSettings.constEnd() )
2228 return it.value().layerType;
2233 return mLabelSettings.count();
2238 return mLabelSettings.keys();
2243 return getId( u
"labelsettings"_s,
name );
2248 return mLegendPatchShapes.keys();
2256 return mPatchMarkerSymbol.get();
2259 return mPatchLineSymbol.get();
2262 return mPatchFillSymbol.get();
2272 return getId( u
"tag"_s,
name );
2277 return getId( u
"smartgroup"_s,
name );
2308 return QStringList();
2313 return addSmartgroup(
name, op, conditions.values( u
"tag"_s ), conditions.values( u
"!tag"_s ), conditions.values( u
"name"_s ), conditions.values( u
"!name"_s ) );
2316int QgsStyle::addSmartgroup(
const QString &
name,
const QString &op,
const QStringList &matchTag,
const QStringList &noMatchTag,
const QStringList &matchName,
const QStringList &noMatchName )
2318 QDomDocument doc( u
"dummy"_s );
2319 QDomElement smartEl = doc.createElement( u
"smartgroup"_s );
2320 smartEl.setAttribute( u
"name"_s,
name );
2321 smartEl.setAttribute( u
"operator"_s, op );
2323 auto addCondition = [&doc, &smartEl](
const QString &constraint,
const QStringList ¶meters ) {
2324 for (
const QString ¶m : parameters )
2326 QDomElement condEl = doc.createElement( u
"condition"_s );
2327 condEl.setAttribute( u
"constraint"_s, constraint );
2328 condEl.setAttribute( u
"param"_s, param );
2329 smartEl.appendChild( condEl );
2332 addCondition( u
"tag"_s, matchTag );
2333 addCondition( u
"!tag"_s, noMatchTag );
2334 addCondition( u
"name"_s, matchName );
2335 addCondition( u
"!name"_s, noMatchName );
2337 QByteArray xmlArray;
2338 QTextStream stream( &xmlArray );
2339 smartEl.save( stream, 4 );
2340 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO smartgroup VALUES (NULL, '%q', '%q')",
name.toUtf8().constData(), xmlArray.constData() );
2342 if ( runEmptyQuery( query ) )
2345 settings.
setValue( u
"qgis/symbolsListGroupsIndex"_s, 0 );
2348 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
2352 QgsDebugError( u
"Couldn't add the smart group into the database!"_s );
2361 QgsDebugError( u
"Cannot open database for listing groups"_s );
2370 statement = mCurrentDB.prepare( query, nError );
2373 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2386 QgsDebugError( u
"Cannot open database for listing groups"_s );
2387 return QStringList();
2395 statement = mCurrentDB.prepare( query, nError );
2398 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2408 QStringList symbols;
2414 statement = mCurrentDB.prepare( query, nErr );
2415 if ( !( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW ) )
2417 return QStringList();
2423 if ( !doc.setContent( xmlstr ) )
2425 QgsDebugError( u
"Cannot open smartgroup id: %1"_s.arg(
id ) );
2427 QDomElement smartEl = doc.documentElement();
2428 QString op = smartEl.attribute( u
"operator"_s );
2429 QDomNodeList conditionNodes = smartEl.childNodes();
2431 bool firstSet =
true;
2432 for (
int i = 0; i < conditionNodes.count(); i++ )
2434 QDomElement condEl = conditionNodes.at( i ).toElement();
2435 QString constraint = condEl.attribute( u
"constraint"_s );
2436 QString param = condEl.attribute( u
"param"_s );
2438 QStringList resultNames;
2440 if ( constraint ==
"tag"_L1 )
2444 else if ( constraint ==
"name"_L1 )
2446 resultNames =
allNames( type ).filter( param, Qt::CaseInsensitive );
2448 else if ( constraint ==
"!tag"_L1 )
2452 for (
const QString &
name : unwanted )
2454 resultNames.removeAll(
name );
2457 else if ( constraint ==
"!name"_L1 )
2459 const QStringList all =
allNames( type );
2460 for (
const QString &str : all )
2462 if ( !str.contains( param, Qt::CaseInsensitive ) )
2470 symbols = resultNames;
2475 if ( op ==
"OR"_L1 )
2477 symbols << resultNames;
2479 else if ( op ==
"AND"_L1 )
2481 QStringList dummy = symbols;
2483 for (
const QString &result : std::as_const( resultNames ) )
2485 if ( dummy.contains( result ) )
2494 const QSet< QString > uniqueSet( symbols.constBegin(), symbols.constEnd() );
2495 QStringList unique( uniqueSet.begin(), uniqueSet.end() );
2496 std::sort( unique.begin(), unique.end() );
2504 QgsDebugError( u
"Cannot open database for listing groups"_s );
2514 statement = mCurrentDB.prepare( query, nError );
2515 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2519 if ( !doc.setContent( xmlstr ) )
2521 QgsDebugError( u
"Cannot open smartgroup id: %1"_s.arg(
id ) );
2524 QDomElement smartEl = doc.documentElement();
2525 QDomNodeList conditionNodes = smartEl.childNodes();
2527 for (
int i = 0; i < conditionNodes.count(); i++ )
2529 QDomElement condEl = conditionNodes.at( i ).toElement();
2530 QString constraint = condEl.attribute( u
"constraint"_s );
2531 QString param = condEl.attribute( u
"param"_s );
2533 condition.insert( constraint, param );
2544 QgsDebugError( u
"Cannot open database for listing groups"_s );
2554 statement = mCurrentDB.prepare( query, nError );
2555 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2559 if ( !doc.setContent( xmlstr ) )
2561 QgsDebugError( u
"Cannot open smartgroup id: %1"_s.arg(
id ) );
2563 QDomElement smartEl = doc.documentElement();
2564 op = smartEl.attribute( u
"operator"_s );
2572 if ( filename.isEmpty() )
2578 QDomDocument doc( u
"qgis_style"_s );
2579 QDomElement root = doc.createElement( u
"qgis_style"_s );
2581 doc.appendChild( root );
2591 QDomNodeList symbolsList = symbolsElem.elementsByTagName( u
"symbol"_s );
2592 int nbSymbols = symbolsList.count();
2593 for (
int i = 0; i < nbSymbols; ++i )
2595 QDomElement
symbol = symbolsList.at( i ).toElement();
2596 QString
name =
symbol.attribute( u
"name"_s );
2598 if (
tags.count() > 0 )
2600 symbol.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2602 if ( favoriteSymbols.contains(
name ) )
2604 symbol.setAttribute( u
"favorite"_s, u
"1"_s );
2609 QDomElement rampsElem = doc.createElement( u
"colorramps"_s );
2610 for ( QMap<QString, QgsColorRamp *>::const_iterator itr = mColorRamps.constBegin(); itr != mColorRamps.constEnd(); ++itr )
2614 if (
tags.count() > 0 )
2616 rampEl.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2618 if ( favoriteColorramps.contains( itr.key() ) )
2620 rampEl.setAttribute( u
"favorite"_s, u
"1"_s );
2622 rampsElem.appendChild( rampEl );
2626 QDomElement textFormatsElem = doc.createElement( u
"textformats"_s );
2627 for (
auto it = mTextFormats.constBegin(); it != mTextFormats.constEnd(); ++it )
2629 QDomElement textFormatEl = doc.createElement( u
"textformat"_s );
2630 textFormatEl.setAttribute( u
"name"_s, it.key() );
2632 textFormatEl.appendChild( textStyleEl );
2634 if (
tags.count() > 0 )
2636 textFormatEl.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2638 if ( favoriteTextFormats.contains( it.key() ) )
2640 textFormatEl.setAttribute( u
"favorite"_s, u
"1"_s );
2642 textFormatsElem.appendChild( textFormatEl );
2646 QDomElement labelSettingsElem = doc.createElement( u
"labelsettings"_s );
2647 for (
auto it = mLabelSettings.constBegin(); it != mLabelSettings.constEnd(); ++it )
2649 QDomElement labelSettingsEl = doc.createElement( u
"labelsetting"_s );
2650 labelSettingsEl.setAttribute( u
"name"_s, it.key() );
2652 labelSettingsEl.appendChild( defEl );
2654 if (
tags.count() > 0 )
2656 labelSettingsEl.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2658 if ( favoriteTextFormats.contains( it.key() ) )
2660 labelSettingsEl.setAttribute( u
"favorite"_s, u
"1"_s );
2662 labelSettingsElem.appendChild( labelSettingsEl );
2666 QDomElement legendPatchShapesElem = doc.createElement( u
"legendpatchshapes"_s );
2667 for (
auto it = mLegendPatchShapes.constBegin(); it != mLegendPatchShapes.constEnd(); ++it )
2669 QDomElement legendPatchShapeEl = doc.createElement( u
"legendpatchshape"_s );
2670 legendPatchShapeEl.setAttribute( u
"name"_s, it.key() );
2671 QDomElement defEl = doc.createElement( u
"definition"_s );
2673 legendPatchShapeEl.appendChild( defEl );
2675 if (
tags.count() > 0 )
2677 legendPatchShapeEl.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2679 if ( favoriteLegendShapes.contains( it.key() ) )
2681 legendPatchShapeEl.setAttribute( u
"favorite"_s, u
"1"_s );
2683 legendPatchShapesElem.appendChild( legendPatchShapeEl );
2687 QDomElement symbols3DElem = doc.createElement( u
"symbols3d"_s );
2688 for (
auto it = m3dSymbols.constBegin(); it != m3dSymbols.constEnd(); ++it )
2690 QDomElement symbolEl = doc.createElement( u
"symbol3d"_s );
2691 symbolEl.setAttribute( u
"name"_s, it.key() );
2692 QDomElement defEl = doc.createElement( u
"definition"_s );
2693 defEl.setAttribute( u
"type"_s, it.value()->type() );
2695 symbolEl.appendChild( defEl );
2697 if (
tags.count() > 0 )
2699 symbolEl.setAttribute( u
"tags"_s,
tags.join(
',' ) );
2701 if ( favorite3DSymbols.contains( it.key() ) )
2703 symbolEl.setAttribute( u
"favorite"_s, u
"1"_s );
2705 symbols3DElem.appendChild( symbolEl );
2708 root.appendChild( symbolsElem );
2709 root.appendChild( rampsElem );
2710 root.appendChild( textFormatsElem );
2711 root.appendChild( labelSettingsElem );
2712 root.appendChild( legendPatchShapesElem );
2713 root.appendChild( symbols3DElem );
2716 QFile f( filename );
2717 if ( !f.open( QFile::WriteOnly | QIODevice::Truncate ) )
2719 mErrorString =
"Couldn't open file for writing: " + filename;
2723 QTextStream ts( &f );
2737 mErrorString = QString();
2738 QDomDocument doc( u
"style"_s );
2739 QFile f( filename );
2740 if ( !f.open( QFile::ReadOnly ) )
2742 mErrorString = u
"Unable to open the specified file"_s;
2747 if ( !doc.setContent( &f ) )
2749 mErrorString = u
"Unable to understand the style file: %1"_s.arg( filename );
2756 QDomElement docEl = doc.documentElement();
2757 if ( docEl.tagName() !=
"qgis_style"_L1 )
2759 mErrorString =
"Incorrect root tag in style: " + docEl.tagName();
2763 const QString version = docEl.attribute( u
"version"_s );
2766 mErrorString =
"Unknown style file version: " + version;
2772 QDomElement symbolsElement = docEl.firstChildElement( u
"symbols"_s );
2773 QDomElement e = symbolsElement.firstChildElement();
2777 runEmptyQuery( query );
2782 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2784 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
2785 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2791 if ( e.tagName() ==
"symbol"_L1 )
2793 QString
name = e.attribute( u
"name"_s );
2795 if ( e.hasAttribute( u
"tags"_s ) )
2797 tags = e.attribute( u
"tags"_s ).split(
',' );
2799 bool favorite =
false;
2800 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
2808 QgsSymbol *symbolPtr =
symbol.get();
2828 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
2835 QDomElement rampsElement = docEl.firstChildElement( u
"colorramps"_s );
2836 e = rampsElement.firstChildElement();
2837 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2839 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
2840 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2846 if ( e.tagName() ==
"colorramp"_L1 )
2848 QString
name = e.attribute( u
"name"_s );
2850 if ( e.hasAttribute( u
"tags"_s ) )
2852 tags = e.attribute( u
"tags"_s ).split(
',' );
2854 bool favorite =
false;
2855 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
2863 QgsColorRamp *rampPtr = ramp.get();
2880 if ( qobject_cast< QGuiApplication * >( QCoreApplication::instance() ) )
2884 const QDomElement textFormatElement = docEl.firstChildElement( u
"textformats"_s );
2885 e = textFormatElement.firstChildElement();
2886 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2888 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
2889 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2895 if ( e.tagName() ==
"textformat"_L1 )
2897 QString
name = e.attribute( u
"name"_s );
2899 if ( e.hasAttribute( u
"tags"_s ) )
2901 tags = e.attribute( u
"tags"_s ).split(
',' );
2903 bool favorite =
false;
2904 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
2909 QgsTextFormat format;
2910 const QDomElement styleElem = e.firstChildElement();
2911 format.
readXml( styleElem, QgsReadWriteContext() );
2928 const QDomElement labelSettingsElement = docEl.firstChildElement( u
"labelsettings"_s );
2929 e = labelSettingsElement.firstChildElement();
2930 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2932 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
2933 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2939 if ( e.tagName() ==
"labelsetting"_L1 )
2941 QString
name = e.attribute( u
"name"_s );
2943 if ( e.hasAttribute( u
"tags"_s ) )
2945 tags = e.attribute( u
"tags"_s ).split(
',' );
2947 bool favorite =
false;
2948 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
2953 QgsPalLayerSettings settings;
2954 const QDomElement styleElem = e.firstChildElement();
2955 settings.
readXml( styleElem, QgsReadWriteContext() );
2973 const QDomElement legendPatchShapesElement = docEl.firstChildElement( u
"legendpatchshapes"_s );
2974 e = legendPatchShapesElement.firstChildElement();
2975 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2977 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
2978 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2984 if ( e.tagName() ==
"legendpatchshape"_L1 )
2986 QString
name = e.attribute( u
"name"_s );
2988 if ( e.hasAttribute( u
"tags"_s ) )
2990 tags = e.attribute( u
"tags"_s ).split(
',' );
2992 bool favorite =
false;
2993 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
2998 QgsLegendPatchShape shape;
2999 const QDomElement shapeElem = e.firstChildElement();
3000 shape.
readXml( shapeElem, QgsReadWriteContext() );
3017 const QDomElement symbols3DElement = docEl.firstChildElement( u
"symbols3d"_s );
3018 e = symbols3DElement.firstChildElement();
3019 for ( ; !e.isNull(); e = e.nextSiblingElement() )
3021 const int entityAddedVersion = e.attribute( u
"addedVersion"_s ).toInt();
3022 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
3028 if ( e.tagName() ==
"symbol3d"_L1 )
3030 QString
name = e.attribute( u
"name"_s );
3032 if ( e.hasAttribute( u
"tags"_s ) )
3034 tags = e.attribute( u
"tags"_s ).split(
',' );
3036 bool favorite =
false;
3037 if ( e.hasAttribute( u
"favorite"_s ) && e.attribute( u
"favorite"_s ) ==
"1"_L1 )
3042 const QDomElement symbolElem = e.firstChildElement();
3043 const QString type = symbolElem.attribute( u
"type"_s );
3047 sym->readXml( symbolElem, QgsReadWriteContext() );
3048 QgsAbstract3DSymbol *newSym = sym.get();
3064 runEmptyQuery( query );
3071 QFileInfo fileInfo( path );
3073 if ( fileInfo.suffix().compare(
"xml"_L1, Qt::CaseInsensitive ) != 0 )
3077 if ( !QFile::exists( path ) )
3080 QFile inputFile( path );
3081 if ( !inputFile.open( QIODevice::ReadOnly ) )
3084 QTextStream stream( &inputFile );
3085 const QString line = stream.readLine();
3086 return line ==
"<!DOCTYPE qgis_style>"_L1;
3101 mReadOnly = readOnly;
3104bool QgsStyle::updateSymbol( StyleEntity type,
const QString &name )
3106 QDomDocument doc( u
"dummy"_s );
3108 QByteArray xmlArray;
3109 QTextStream stream( &xmlArray );
3118 auto it = mSymbols.constFind(
name );
3119 if ( it == mSymbols.constEnd() || !it.value() )
3121 QgsDebugError( u
"Update request received for unavailable symbol"_s );
3126 if ( symEl.isNull() )
3128 QgsDebugError( u
"Couldn't convert symbol to valid XML!"_s );
3131 symEl.save( stream, 4 );
3132 query =
qgs_sqlite3_mprintf(
"UPDATE symbol SET xml='%q' WHERE name='%q';", xmlArray.constData(),
name.toUtf8().constData() );
3139 auto it = m3dSymbols.constFind(
name );
3140 if ( it == m3dSymbols.constEnd() || !it.value() )
3142 QgsDebugError( u
"Update request received for unavailable symbol"_s );
3146 symEl = doc.createElement( u
"symbol"_s );
3147 symEl.setAttribute( u
"type"_s, it.value()->type() );
3148 it.value()->writeXml( symEl, QgsReadWriteContext() );
3149 if ( symEl.isNull() )
3151 QgsDebugError( u
"Couldn't convert symbol to valid XML!"_s );
3154 symEl.save( stream, 4 );
3155 query =
qgs_sqlite3_mprintf(
"UPDATE symbol3d SET xml='%q' WHERE name='%q';", xmlArray.constData(),
name.toUtf8().constData() );
3161 auto it = mColorRamps.constFind(
name );
3162 if ( it == mColorRamps.constEnd() || !it.value() )
3164 QgsDebugError( u
"Update requested for unavailable color ramp."_s );
3169 if ( symEl.isNull() )
3171 QgsDebugError( u
"Couldn't convert color ramp to valid XML!"_s );
3174 symEl.save( stream, 4 );
3175 query =
qgs_sqlite3_mprintf(
"UPDATE colorramp SET xml='%q' WHERE name='%q';", xmlArray.constData(),
name.toUtf8().constData() );
3181 auto it = mTextFormats.constFind(
name );
3182 if ( it == mTextFormats.constEnd() )
3184 QgsDebugError( u
"Update requested for unavailable text format."_s );
3188 symEl = it.value().writeXml( doc, QgsReadWriteContext() );
3189 if ( symEl.isNull() )
3191 QgsDebugError( u
"Couldn't convert text format to valid XML!"_s );
3194 symEl.save( stream, 4 );
3195 query =
qgs_sqlite3_mprintf(
"UPDATE textformat SET xml='%q' WHERE name='%q';", xmlArray.constData(),
name.toUtf8().constData() );
3201 auto it = mLabelSettings.constFind(
name );
3202 if ( it == mLabelSettings.constEnd() )
3204 QgsDebugError( u
"Update requested for unavailable label settings."_s );
3208 symEl = it.value().writeXml( doc, QgsReadWriteContext() );
3209 if ( symEl.isNull() )
3211 QgsDebugError( u
"Couldn't convert label settings to valid XML!"_s );
3214 symEl.save( stream, 4 );
3215 query =
qgs_sqlite3_mprintf(
"UPDATE labelsettings SET xml='%q' WHERE name='%q';", xmlArray.constData(),
name.toUtf8().constData() );
3221 auto it = mLegendPatchShapes.constFind(
name );
3222 if ( it == mLegendPatchShapes.constEnd() )
3224 QgsDebugError( u
"Update requested for unavailable legend patch shape."_s );
3228 symEl = doc.createElement( u
"shape"_s );
3229 it.value().writeXml( symEl, doc, QgsReadWriteContext() );
3230 symEl.save( stream, 4 );
3231 query =
qgs_sqlite3_mprintf(
"UPDATE legendpatchshapes SET xml='%q' WHERE name='%q';", xmlArray.constData(),
name.toUtf8().constData() );
3244 if ( !runEmptyQuery( query ) )
3246 QgsDebugError( u
"Couldn't update symbol into the database!"_s );
3282 mCachedTags[type].remove(
name );
3285bool QgsStyle::createStyleMetadataTableIfNeeded()
3288 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='stylemetadata'" );
3289 sqlite3_statement_unique_ptr statement;
3291 statement = mCurrentDB.prepare( query, rc );
3293 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
3297 "CREATE TABLE stylemetadata("
3298 "id INTEGER PRIMARY KEY,"
3302 runEmptyQuery( query );
3304 runEmptyQuery( query );
3313void QgsStyle::upgradeIfRequired()
3317 if ( !createStyleMetadataTableIfNeeded() )
3319 const QString query =
qgs_sqlite3_mprintf(
"SELECT value FROM stylemetadata WHERE key='version'" );
3321 sqlite3_statement_unique_ptr statement = mCurrentDB.prepare( query, rc );
3322 if ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
3334 runEmptyQuery( query );
3347 return u
"colorramp"_s;
3350 return u
"textformat"_s;
3353 return u
"labelsettings"_s;
3356 return u
"legendpatchshapes"_s;
3359 return u
"symbol3d"_s;
3365 return u
"smartgroup"_s;
3378 return u
"ctagmap"_s;
3381 return u
"tftagmap"_s;
3384 return u
"lstagmap"_s;
3387 return u
"lpstagmap"_s;
3390 return u
"symbol3dtagmap"_s;
3404 return u
"symbol_id"_s;
3407 return u
"colorramp_id"_s;
3410 return u
"textformat_id"_s;
3413 return u
"labelsettings_id"_s;
3416 return u
"legendpatchshape_id"_s;
3419 return u
"symbol3d_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.
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