24 #include "qgssettings.h"
38 #include <QDomDocument>
39 #include <QDomElement>
41 #include <QDomNodeList>
43 #include <QTextStream>
50 #define STYLE_CURRENT_VERSION "2"
75 QgsStyle *QgsStyle::sDefaultStyle =
nullptr;
81 simpleMarker->setStrokeWidth( 0.4 );
82 mPatchMarkerSymbol = std::make_unique< QgsMarkerSymbol >(
QgsSymbolLayerList() << simpleMarker.release() );
84 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 84, 176, 74 ), 0.6 );
85 mPatchLineSymbol = std::make_unique< QgsLineSymbol >(
QgsSymbolLayerList() << simpleLine.release() );
87 std::unique_ptr< QgsGradientFillSymbolLayer > gradientFill = std::make_unique< QgsGradientFillSymbolLayer >( QColor( 66, 150, 63 ), QColor( 84, 176, 74 ) );
88 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleOutline = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 56, 128, 54 ), 0.26 );
89 mPatchFillSymbol = std::make_unique< QgsFillSymbol >(
QgsSymbolLayerList() << gradientFill.release() << simpleOutline.release() );
99 switch ( entity->
type() )
133 if ( !sDefaultStyle )
139 if ( !QFile::exists( styleFilename ) )
151 if ( sDefaultStyle->
load( styleFilename ) )
153 sDefaultStyle->upgradeIfRequired();
157 return sDefaultStyle;
162 delete sDefaultStyle;
163 sDefaultStyle =
nullptr;
168 qDeleteAll( mSymbols );
169 qDeleteAll( mColorRamps );
170 qDeleteAll( m3dSymbols );
174 mTextFormats.clear();
178 mCachedFavorites.clear();
183 if ( !
symbol || name.isEmpty() )
187 if ( mSymbols.contains( name ) )
190 delete mSymbols.value( name );
191 mSymbols.insert( name,
symbol );
197 mSymbols.insert( name,
symbol );
208 QDomDocument doc( QStringLiteral(
"dummy" ) );
210 if ( symEl.isNull() )
212 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
217 QTextStream stream( &xmlArray );
218 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
219 stream.setCodec(
"UTF-8" );
221 symEl.save( stream, 4 );
223 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
225 if ( !runEmptyQuery( query ) )
227 QgsDebugMsg( QStringLiteral(
"Couldn't insert symbol into the database!" ) );
231 mCachedFavorites[
SymbolEntity ].insert( name, favorite );
283 return mSymbols.value( name );
288 return mSymbols.count();
293 return mSymbols.keys();
303 if ( mColorRamps.contains( name ) )
306 delete mColorRamps.value( name );
324 if ( mTextFormats.contains( name ) )
327 mTextFormats.remove( name );
328 mTextFormats.insert( name, format );
334 mTextFormats.insert( name, format );
345 if ( mLabelSettings.contains( name ) )
348 mLabelSettings.remove( name );
349 mLabelSettings.insert( name, settings );
355 mLabelSettings.insert( name, settings );
366 if ( mLegendPatchShapes.contains( name ) )
369 mLegendPatchShapes.remove( name );
370 mLegendPatchShapes.insert( name, shape );
376 mLegendPatchShapes.insert( name, shape );
387 if ( m3dSymbols.contains( name ) )
390 delete m3dSymbols.take( name );
391 m3dSymbols.insert( name,
symbol );
397 m3dSymbols.insert( name,
symbol );
408 QDomDocument doc( QStringLiteral(
"dummy" ) );
411 if ( rampEl.isNull() )
413 QgsDebugMsg( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
418 QTextStream stream( &xmlArray );
419 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
420 stream.setCodec(
"UTF-8" );
422 rampEl.save( stream, 4 );
423 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO colorramp VALUES (NULL, '%q', '%q', %d);",
424 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
425 if ( !runEmptyQuery( query ) )
427 QgsDebugMsg( QStringLiteral(
"Couldn't insert colorramp into the database!" ) );
449 return ramp ? ramp->
clone() :
nullptr;
454 return mColorRamps.value( name );
459 return mColorRamps.count();
464 return mColorRamps.keys();
467 void QgsStyle::handleDeferred3DSymbolCreation()
469 for (
auto it = mDeferred3DsymbolElements.constBegin(); it != mDeferred3DsymbolElements.constEnd(); ++it )
471 const QString symbolType = it.value().attribute( QStringLiteral(
"type" ) );
481 QgsDebugMsg(
"Cannot open 3d symbol " + it.key() );
485 mDeferred3DsymbolElements.clear();
488 bool QgsStyle::openDatabase(
const QString &filename )
490 int rc = mCurrentDB.
open( filename );
493 mErrorString = QStringLiteral(
"Couldn't open the style database: %1" ).arg( mCurrentDB.
errorMessage() );
502 mErrorString.clear();
503 if ( !openDatabase( filename ) )
505 mErrorString = QStringLiteral(
"Unable to create database" );
517 mErrorString.clear();
518 if ( !openDatabase( QStringLiteral(
":memory:" ) ) )
520 mErrorString = QStringLiteral(
"Unable to create temporary memory database" );
533 "id INTEGER PRIMARY KEY,"\
536 "favorite INTEGER);"\
537 "CREATE TABLE colorramp("\
538 "id INTEGER PRIMARY KEY,"\
541 "favorite INTEGER);"\
542 "CREATE TABLE textformat("\
543 "id INTEGER PRIMARY KEY,"\
546 "favorite INTEGER);"\
547 "CREATE TABLE labelsettings("\
548 "id INTEGER PRIMARY KEY,"\
551 "favorite INTEGER);"\
552 "CREATE TABLE legendpatchshapes("\
553 "id INTEGER PRIMARY KEY,"\
556 "favorite INTEGER);"\
557 "CREATE TABLE symbol3d("\
558 "id INTEGER PRIMARY KEY,"\
561 "favorite INTEGER);"\
563 "id INTEGER PRIMARY KEY,"\
565 "CREATE TABLE tagmap("\
566 "tag_id INTEGER NOT NULL,"\
567 "symbol_id INTEGER);"\
568 "CREATE TABLE ctagmap("\
569 "tag_id INTEGER NOT NULL,"\
570 "colorramp_id INTEGER);"\
571 "CREATE TABLE tftagmap("\
572 "tag_id INTEGER NOT NULL,"\
573 "textformat_id INTEGER);"\
574 "CREATE TABLE lstagmap("\
575 "tag_id INTEGER NOT NULL,"\
576 "labelsettings_id INTEGER);"\
577 "CREATE TABLE lpstagmap("\
578 "tag_id INTEGER NOT NULL,"\
579 "legendpatchshape_id INTEGER);"\
580 "CREATE TABLE symbol3dtagmap("\
581 "tag_id INTEGER NOT NULL,"\
582 "symbol3d_id INTEGER);"\
583 "CREATE TABLE smartgroup("\
584 "id INTEGER PRIMARY KEY,"\
587 runEmptyQuery( query );
592 mErrorString.clear();
595 if ( !openDatabase( filename ) )
597 mErrorString = QStringLiteral(
"Unable to open database file specified" );
603 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='textformat'" );
606 statement = mCurrentDB.
prepare( query, rc );
607 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
610 "id INTEGER PRIMARY KEY,"\
613 "favorite INTEGER);"\
614 "CREATE TABLE tftagmap("\
615 "tag_id INTEGER NOT NULL,"\
616 "textformat_id INTEGER);" );
617 runEmptyQuery( query );
620 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='labelsettings'" );
621 statement = mCurrentDB.
prepare( query, rc );
622 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
625 "id INTEGER PRIMARY KEY,"\
628 "favorite INTEGER);"\
629 "CREATE TABLE lstagmap("\
630 "tag_id INTEGER NOT NULL,"\
631 "labelsettings_id INTEGER);" );
632 runEmptyQuery( query );
635 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='legendpatchshapes'" );
636 statement = mCurrentDB.
prepare( query, rc );
637 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
640 "id INTEGER PRIMARY KEY,"\
643 "favorite INTEGER);"\
644 "CREATE TABLE lpstagmap("\
645 "tag_id INTEGER NOT NULL,"\
646 "legendpatchshape_id INTEGER);" );
647 runEmptyQuery( query );
651 statement = mCurrentDB.
prepare( query, rc );
652 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
655 "id INTEGER PRIMARY KEY,"\
658 "favorite INTEGER);"\
659 "CREATE TABLE symbol3dtagmap("\
660 "tag_id INTEGER NOT NULL,"\
661 "symbol3d_id INTEGER);" );
662 runEmptyQuery( query );
667 "UPDATE colorramp SET favorite=0 WHERE favorite IS NULL;"
668 "UPDATE textformat SET favorite=0 WHERE favorite IS NULL;"
669 "UPDATE labelsettings SET favorite=0 WHERE favorite IS NULL;"
670 "UPDATE legendpatchshapes SET favorite=0 WHERE favorite IS NULL;"
671 "UPDATE symbol3d SET favorite=0 WHERE favorite IS NULL;"
673 runEmptyQuery( query );
679 statement = mCurrentDB.
prepare( query, rc );
681 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
687 if ( !doc.setContent( xmlstring ) )
693 QDomElement symElement = doc.documentElement();
696 mSymbols.insert( symbolName,
symbol );
703 statement = mCurrentDB.
prepare( query, rc );
704 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
710 if ( !doc.setContent( xmlstring ) )
715 QDomElement rampElement = doc.documentElement();
718 mColorRamps.insert( rampName, ramp );
725 statement = mCurrentDB.
prepare( query, rc );
726 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
732 if ( !doc.setContent( xmlstring ) )
734 QgsDebugMsg(
"Cannot open text format " + formatName );
737 QDomElement formatElement = doc.documentElement();
740 mTextFormats.insert( formatName, format );
747 statement = mCurrentDB.
prepare( query, rc );
748 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
754 if ( !doc.setContent( xmlstring ) )
756 QgsDebugMsg(
"Cannot open label settings " + settingsName );
759 QDomElement settingsElement = doc.documentElement();
762 mLabelSettings.insert( settingsName, settings );
769 statement = mCurrentDB.
prepare( query, rc );
770 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
776 if ( !doc.setContent( xmlstring ) )
778 QgsDebugMsg(
"Cannot open legend patch shape " + settingsName );
781 QDomElement settingsElement = doc.documentElement();
784 mLegendPatchShapes.insert( settingsName, shape );
791 statement = mCurrentDB.
prepare( query, rc );
795 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
801 if ( !doc.setContent( xmlstring ) )
803 QgsDebugMsg(
"Cannot open 3d symbol " + settingsName );
806 QDomElement settingsElement = doc.documentElement();
808 if ( !registry3dPopulated )
810 mDeferred3DsymbolElements.insert( settingsName, settingsElement );
814 const QString symbolType = settingsElement.attribute( QStringLiteral(
"type" ) );
819 m3dSymbols.insert( settingsName,
symbol.release() );
823 QgsDebugMsg(
"Cannot open 3d symbol " + settingsName );
830 mFileName = filename;
838 mErrorString.clear();
840 if ( filename.isEmpty() )
841 filename = mFileName;
846 QDomDocument doc(
"qgis_style" );
847 QDomElement root = doc.createElement(
"qgis_style" );
849 doc.appendChild( root );
853 QDomElement rampsElem = doc.createElement(
"colorramps" );
856 for ( QMap<QString, QgsColorRamp *>::iterator itr = mColorRamps.begin(); itr != mColorRamps.end(); ++itr )
859 rampsElem.appendChild( rampEl );
862 root.appendChild( symbolsElem );
863 root.appendChild( rampsElem );
867 if ( !f.open( QFile::WriteOnly ) )
869 mErrorString =
"Couldn't open file for writing: " + filename;
872 QTextStream ts( &f );
873 ts.setCodec(
"UTF-8" );
878 mFileName = filename;
884 if ( mSymbols.contains( newName ) )
886 QgsDebugMsg( QStringLiteral(
"Symbol of new name already exists" ) );
894 mSymbols.insert( newName,
symbol );
898 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to tag." ) );
905 QgsDebugMsg( QStringLiteral(
"No such symbol for tagging in database: " ) + oldName );
924 if ( mColorRamps.contains( newName ) )
926 QgsDebugMsg( QStringLiteral(
"Color ramp of new name already exists." ) );
934 mColorRamps.insert( newName, ramp );
940 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM colorramp WHERE name='%q'", oldName.toUtf8().constData() );
942 statement = mCurrentDB.
prepare( query, nErr );
943 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
945 rampid = sqlite3_column_int( statement.get(), 0 );
960 QDomDocument doc( QStringLiteral(
"dummy" ) );
963 if ( formatElem.isNull() )
965 QgsDebugMsg( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
970 QTextStream stream( &xmlArray );
971 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
972 stream.setCodec(
"UTF-8" );
974 formatElem.save( stream, 4 );
975 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO textformat VALUES (NULL, '%q', '%q', %d);",
976 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
977 if ( !runEmptyQuery( query ) )
979 QgsDebugMsg( QStringLiteral(
"Couldn't insert text format into the database!" ) );
1000 if ( mTextFormats.contains( newName ) )
1002 QgsDebugMsg( QStringLiteral(
"Text format of new name already exists." ) );
1006 if ( !mTextFormats.contains( oldName ) )
1010 mTextFormats.insert( newName, format );
1016 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM textformat WHERE name='%q'", oldName.toUtf8().constData() );
1018 statement = mCurrentDB.
prepare( query, nErr );
1019 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1021 textFormatId = sqlite3_column_int( statement.get(), 0 );
1036 QDomDocument doc( QStringLiteral(
"dummy" ) );
1039 if ( settingsElem.isNull() )
1041 QgsDebugMsg( QStringLiteral(
"Couldn't convert label settings to valid XML!" ) );
1045 QByteArray xmlArray;
1046 QTextStream stream( &xmlArray );
1047 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1048 stream.setCodec(
"UTF-8" );
1050 settingsElem.save( stream, 4 );
1051 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO labelsettings VALUES (NULL, '%q', '%q', %d);",
1052 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1053 if ( !runEmptyQuery( query ) )
1055 QgsDebugMsg( QStringLiteral(
"Couldn't insert label settings into the database!" ) );
1076 if ( mLabelSettings.contains( newName ) )
1078 QgsDebugMsg( QStringLiteral(
"Label settings of new name already exists." ) );
1082 if ( !mLabelSettings.contains( oldName ) )
1086 mLabelSettings.insert( newName, settings );
1092 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM labelsettings WHERE name='%q'", oldName.toUtf8().constData() );
1094 statement = mCurrentDB.
prepare( query, nErr );
1095 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1112 QDomDocument doc( QStringLiteral(
"dummy" ) );
1113 QDomElement shapeElem = doc.createElement( QStringLiteral(
"shape" ) );
1116 QByteArray xmlArray;
1117 QTextStream stream( &xmlArray );
1118 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1119 stream.setCodec(
"UTF-8" );
1121 shapeElem.save( stream, 4 );
1122 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO legendpatchshapes VALUES (NULL, '%q', '%q', %d);",
1123 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1124 if ( !runEmptyQuery( query ) )
1126 QgsDebugMsg( QStringLiteral(
"Couldn't insert legend patch shape into the database!" ) );
1141 if ( mLegendPatchShapes.contains( newName ) )
1143 QgsDebugMsg( QStringLiteral(
"Legend patch shape of new name already exists." ) );
1147 if ( !mLegendPatchShapes.contains( oldName ) )
1151 mLegendPatchShapes.insert( newName, shape );
1157 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM legendpatchshapes WHERE name='%q'", oldName.toUtf8().constData() );
1159 statement = mCurrentDB.
prepare( query, nErr );
1160 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1178 if ( mDefaultPatchCache[
static_cast< int >( type ) ].contains( size ) )
1179 return mDefaultPatchCache[
static_cast< int >( type ) ].value( size );
1185 geom =
QgsGeometry( std::make_unique< QgsPoint >(
static_cast< int >( size.width() ) / 2,
static_cast< int >( size.height() ) / 2 ) );
1192 double y =
static_cast< int >( size.height() ) / 2 + 0.5;
1193 geom =
QgsGeometry( std::make_unique< QgsLineString >( ( QVector< double >() << 0 << size.width() ),
1194 ( QVector< double >() << y << y ) ) );
1200 geom =
QgsGeometry( std::make_unique< QgsPolygon >(
1201 new QgsLineString( QVector< double >() << 0 <<
static_cast< int >( size.width() ) <<
static_cast< int >( size.width() ) << 0 << 0,
1202 QVector< double >() <<
static_cast< int >( size.height() ) <<
static_cast< int >( size.height() ) << 0 << 0 <<
static_cast< int >( size.height() ) ) ) );
1211 mDefaultPatchCache[
static_cast< int >( type ) ][size ] = res;
1218 return QList<QList<QPolygonF> >();
1220 if ( mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ].contains( size ) )
1221 return mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ].value( size );
1224 mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ][size ] = res;
1230 return textFormat( QStringLiteral(
"Default" ) );
1236 QDomDocument doc( QStringLiteral(
"dummy" ) );
1237 QDomElement elem = doc.createElement( QStringLiteral(
"symbol" ) );
1238 elem.setAttribute( QStringLiteral(
"type" ),
symbol->
type() );
1241 QByteArray xmlArray;
1242 QTextStream stream( &xmlArray );
1243 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1244 stream.setCodec(
"UTF-8" );
1246 elem.save( stream, 4 );
1247 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO symbol3d VALUES (NULL, '%q', '%q', %d);",
1248 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1249 if ( !runEmptyQuery( query ) )
1251 QgsDebugMsg( QStringLiteral(
"Couldn't insert 3d symbol into the database!" ) );
1266 if ( m3dSymbols.contains( newName ) )
1268 QgsDebugMsg( QStringLiteral(
"3d symbol of new name already exists." ) );
1272 if ( !m3dSymbols.contains( oldName ) )
1276 m3dSymbols.insert( newName,
symbol );
1282 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM symbol3d WHERE name='%q'", oldName.toUtf8().constData() );
1284 statement = mCurrentDB.
prepare( query, nErr );
1285 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1300 return m3dSymbols.keys();
1307 QgsDebugMsg( QStringLiteral(
"Cannot Open database for getting favorite symbols" ) );
1308 return QStringList();
1316 QgsDebugMsg( QStringLiteral(
"No such style entity" ) );
1317 return QStringList();
1320 query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT name FROM %1 WHERE favorite=1" ).arg( entityTableName( type ) ).toLocal8Bit().data() );
1326 statement = mCurrentDB.
prepare( query, nErr );
1328 QStringList symbols;
1329 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1341 QgsDebugMsg( QStringLiteral(
"Cannot open database to get symbols of tagid %1" ).arg( tagid ) );
1342 return QStringList();
1350 QgsDebugMsg( QStringLiteral(
"Unknown Entity" ) );
1351 return QStringList();
1354 subquery =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT %1 FROM %2 WHERE tag_id=%d" ).arg( tagmapEntityIdFieldName( type ),
1355 tagmapTableName( type ) ).toLocal8Bit().data(), tagid );
1361 statement = mCurrentDB.
prepare( subquery, nErr );
1364 QStringList symbols;
1365 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1367 int id = sqlite3_column_int( statement.get(), 0 );
1369 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT name FROM %1 WHERE id=%d" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
id );
1373 statement2 = mCurrentDB.
prepare( query, rc );
1374 while ( rc == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1389 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO tag VALUES (NULL, '%q')", tagname.toUtf8().constData() );
1391 statement = mCurrentDB.
prepare( query, nErr );
1392 if ( nErr == SQLITE_OK )
1393 ( void )sqlite3_step( statement.get() );
1395 QgsSettings settings;
1396 settings.setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1400 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
1406 return QStringList();
1412 statement = mCurrentDB.
prepare( query, nError );
1414 QStringList tagList;
1415 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1425 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET name='%q' WHERE id=%d" ).arg( entityTableName( type ) ).toLocal8Bit().data(), newName.toUtf8().constData(),
id );
1427 const bool result = runEmptyQuery( query );
1430 mErrorString = QStringLiteral(
"Could not rename!" );
1434 mCachedTags.clear();
1435 mCachedFavorites.clear();
1460 bool groupRemoved =
false;
1465 query =
qgs_sqlite3_mprintf(
"DELETE FROM tag WHERE id=%d; DELETE FROM tagmap WHERE tag_id=%d",
id,
id );
1466 groupRemoved =
true;
1470 groupRemoved =
true;
1474 query =
qgs_sqlite3_mprintf( QStringLiteral(
"DELETE FROM %1 WHERE id=%d; DELETE FROM %2 WHERE %3=%d" ).arg(
1475 entityTableName( type ),
1476 tagmapTableName( type ),
1477 tagmapEntityIdFieldName( type )
1478 ).toLocal8Bit().data(),
id,
id );
1482 bool result =
false;
1483 if ( !runEmptyQuery( query ) )
1485 QgsDebugMsg( QStringLiteral(
"Could not delete entity!" ) );
1489 mCachedTags.clear();
1490 mCachedFavorites.clear();
1494 QgsSettings settings;
1495 settings.setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1514 std::unique_ptr< QgsSymbol >
symbol( mSymbols.take( name ) );
1523 std::unique_ptr< QgsAbstract3DSymbol >
symbol( m3dSymbols.take( name ) );
1532 std::unique_ptr< QgsColorRamp > ramp( mColorRamps.take( name ) );
1540 if ( !mTextFormats.contains( name ) )
1543 mTextFormats.remove( name );
1549 if ( !mLabelSettings.contains( name ) )
1552 mLabelSettings.remove( name );
1558 if ( !mLegendPatchShapes.contains( name ) )
1561 mLegendPatchShapes.remove( name );
1568 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to modify." ) );
1572 const int id =
entityId( type, name );
1575 QgsDebugMsg(
"No matching entity for deleting in database: " + name );
1578 const bool result =
remove( type,
id );
1581 mCachedTags[ type ].remove( name );
1582 mCachedFavorites[ type ].remove( name );
1611 bool QgsStyle::runEmptyQuery(
const QString &query )
1616 char *zErr =
nullptr;
1617 int nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1619 if ( nErr != SQLITE_OK )
1622 sqlite3_free( zErr );
1625 return nErr == SQLITE_OK;
1636 QgsDebugMsg( QStringLiteral(
"Wrong entity value. cannot apply group" ) );
1640 query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET favorite=1 WHERE name='%q'" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
1641 name.toUtf8().constData() );
1645 const bool res = runEmptyQuery( query );
1655 mCachedFavorites[ type ].insert( name,
true );
1672 QgsDebugMsg( QStringLiteral(
"Wrong entity value. cannot apply group" ) );
1676 query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET favorite=0 WHERE name='%q'" ).arg( entityTableName( type ) ).toLocal8Bit().data(), name.toUtf8().constData() );
1680 const bool res = runEmptyQuery( query );
1683 mCachedFavorites[ type ].insert( name,
false );
1694 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to search" ) );
1695 return QStringList();
1704 return QStringList();
1707 item = entityTableName( type );
1712 item.toUtf8().constData(), qword.toUtf8().constData() );
1715 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1717 QSet< QString > symbols;
1718 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1724 query =
qgs_sqlite3_mprintf(
"SELECT id FROM tag WHERE name LIKE '%%%q%%'", qword.toUtf8().constData() );
1725 statement = mCurrentDB.
prepare( query, nErr );
1728 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1733 QString dummy = tagids.join( QLatin1String(
", " ) );
1734 query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT %1 FROM %2 WHERE tag_id IN (%q)" ).arg( tagmapEntityIdFieldName( type ),
1735 tagmapTableName( type ) ).toLocal8Bit().data(), dummy.toUtf8().constData() );
1737 statement = mCurrentDB.
prepare( query, nErr );
1739 QStringList symbolids;
1740 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1745 dummy = symbolids.join( QLatin1String(
", " ) );
1747 item.toUtf8().constData(), dummy.toUtf8().constData() );
1748 statement = mCurrentDB.
prepare( query, nErr );
1749 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1754 return qgis::setToList( symbols );
1761 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to tag." ) );
1779 QgsDebugMsg( QStringLiteral(
"No such symbol for tagging in database: " ) +
symbol );
1784 const auto constTags =
tags;
1785 for (
const QString &t : constTags )
1788 if ( !
tag.isEmpty() )
1800 QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"INSERT INTO %1 VALUES (%d,%d)" ).arg( tagmapTableName( type ) ).toLocal8Bit().data(), tagid, symbolid );
1802 char *zErr =
nullptr;
1804 nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1808 sqlite3_free( zErr );
1814 clearCachedTags( type,
symbol );
1824 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for detagging." ) );
1839 if ( symbolid == 0 )
1844 const auto constTags =
tags;
1845 for (
const QString &
tag : constTags )
1850 statement2 = mCurrentDB.
prepare( query, nErr );
1853 if ( nErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1855 tagid = sqlite3_column_int( statement2.get(), 0 );
1861 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"DELETE FROM %1 WHERE tag_id=%d AND %2=%d" ).arg( tagmapTableName( type ), tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), tagid, symbolid );
1862 runEmptyQuery( query );
1866 clearCachedTags( type,
symbol );
1879 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for detagging." ) );
1894 if ( symbolid == 0 )
1900 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"DELETE FROM %1 WHERE %2=%d" ).arg( tagmapTableName( type ),
1901 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1902 runEmptyQuery( query );
1904 clearCachedTags( type,
symbol );
1919 return QStringList();
1922 if ( mCachedTags[ type ].contains(
symbol ) )
1923 return mCachedTags[ type ].value(
symbol );
1929 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
1930 return QStringList();
1935 return QStringList();
1938 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT tag_id FROM %1 WHERE %2=%d" ).arg( tagmapTableName( type ),
1939 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1942 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1944 QStringList tagList;
1945 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1947 QString subquery =
qgs_sqlite3_mprintf(
"SELECT name FROM tag WHERE id=%d", sqlite3_column_int( statement.get(), 0 ) );
1951 statement2 = mCurrentDB.
prepare( subquery, pErr );
1952 if ( pErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1959 mCachedTags[ type ].insert(
symbol, tagList );
1968 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
1979 if ( mCachedFavorites[ type ].contains( name ) )
1980 return mCachedFavorites[ type ].value( name );
1984 const QStringList names =
allNames( type );
1985 if ( !names.contains( name ) )
1991 for (
const QString &n : names )
1993 const bool isFav = favorites.contains( n );
1997 mCachedFavorites[ type ].insert( n, isFav );
2006 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
2033 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT tag_id FROM %1 WHERE tag_id=%d AND %2=%d" ).arg( tagmapTableName( type ),
2034 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), tagid, symbolid );
2037 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2039 return ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW );
2051 statement = mCurrentDB.
prepare( query, nError );
2054 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2062 int QgsStyle::getId(
const QString &table,
const QString &name )
2064 QString lowerName( name.toLower() );
2065 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE LOWER(name)='%q'", table.toUtf8().constData(), lowerName.toUtf8().constData() );
2068 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2071 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2073 id = sqlite3_column_int( statement.get(), 0 );
2078 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE name='%q'", table.toUtf8().constData(), name.toUtf8().constData() );
2081 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2082 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2084 id = sqlite3_column_int( statement.get(), 0 );
2091 QString QgsStyle::getName(
const QString &table,
int id )
const
2093 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM %q WHERE id='%q'", table.toUtf8().constData(), QString::number(
id ).toUtf8().constData() );
2096 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2099 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2109 return getId( QStringLiteral(
"symbol" ), name );
2114 return getId( entityTableName( type ), name );
2119 return getId( QStringLiteral(
"colorramp" ), name );
2124 return mTextFormats.value( name );
2129 return mTextFormats.count();
2134 return mTextFormats.keys();
2139 return getId( QStringLiteral(
"textformat" ), name );
2144 return mLabelSettings.value( name );
2149 return mLegendPatchShapes.value( name );
2154 return mLegendPatchShapes.count();
2159 if ( !mLegendPatchShapes.contains( name ) )
2162 return mLegendPatchShapes.value( name ).symbolType();
2167 return m3dSymbols.contains( name ) ? m3dSymbols.value( name )->clone() :
nullptr;
2172 return m3dSymbols.count();
2177 if ( !m3dSymbols.contains( name ) )
2178 return QList<QgsWkbTypes::GeometryType>();
2180 return m3dSymbols.value( name )->compatibleGeometryTypes();
2185 if ( !mLabelSettings.contains( name ) )
2188 return mLabelSettings.value( name ).layerType;
2193 return mLabelSettings.count();
2198 return mLabelSettings.keys();
2203 return getId( QStringLiteral(
"labelsettings" ), name );
2208 return mLegendPatchShapes.keys();
2216 return mPatchMarkerSymbol.get();
2219 return mPatchLineSymbol.get();
2222 return mPatchFillSymbol.get();
2232 return getId( QStringLiteral(
"tag" ), name );
2237 return getId( QStringLiteral(
"smartgroup" ), name );
2268 return QStringList();
2273 return addSmartgroup( name, op, conditions.values( QStringLiteral(
"tag" ) ),
2274 conditions.values( QStringLiteral(
"!tag" ) ),
2275 conditions.values( QStringLiteral(
"name" ) ),
2276 conditions.values( QStringLiteral(
"!name" ) ) );
2279 int QgsStyle::addSmartgroup(
const QString &name,
const QString &op,
const QStringList &matchTag,
const QStringList &noMatchTag,
const QStringList &matchName,
const QStringList &noMatchName )
2281 QDomDocument doc( QStringLiteral(
"dummy" ) );
2282 QDomElement smartEl = doc.createElement( QStringLiteral(
"smartgroup" ) );
2283 smartEl.setAttribute( QStringLiteral(
"name" ), name );
2284 smartEl.setAttribute( QStringLiteral(
"operator" ), op );
2286 auto addCondition = [&doc, &smartEl](
const QString & constraint,
const QStringList & parameters )
2288 for (
const QString ¶m : parameters )
2290 QDomElement condEl = doc.createElement( QStringLiteral(
"condition" ) );
2291 condEl.setAttribute( QStringLiteral(
"constraint" ), constraint );
2292 condEl.setAttribute( QStringLiteral(
"param" ), param );
2293 smartEl.appendChild( condEl );
2296 addCondition( QStringLiteral(
"tag" ), matchTag );
2297 addCondition( QStringLiteral(
"!tag" ), noMatchTag );
2298 addCondition( QStringLiteral(
"name" ), matchName );
2299 addCondition( QStringLiteral(
"!name" ), noMatchName );
2301 QByteArray xmlArray;
2302 QTextStream stream( &xmlArray );
2303 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2304 stream.setCodec(
"UTF-8" );
2306 smartEl.save( stream, 4 );
2308 name.toUtf8().constData(), xmlArray.constData() );
2310 if ( runEmptyQuery( query ) )
2312 QgsSettings settings;
2313 settings.setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
2316 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
2320 QgsDebugMsg( QStringLiteral(
"Couldn't insert symbol into the database!" ) );
2329 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2338 statement = mCurrentDB.
prepare( query, nError );
2341 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2344 groupNames.insert( sqlite3_column_int( statement.get(),
SmartgroupId ), group );
2354 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2355 return QStringList();
2363 statement = mCurrentDB.
prepare( query, nError );
2366 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2376 QStringList symbols;
2381 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2382 if ( !( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW ) )
2384 return QStringList();
2390 if ( !doc.setContent( xmlstr ) )
2392 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2394 QDomElement smartEl = doc.documentElement();
2395 QString op = smartEl.attribute( QStringLiteral(
"operator" ) );
2396 QDomNodeList conditionNodes = smartEl.childNodes();
2398 bool firstSet =
true;
2399 for (
int i = 0; i < conditionNodes.count(); i++ )
2401 QDomElement condEl = conditionNodes.at( i ).toElement();
2402 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2403 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2405 QStringList resultNames;
2407 if ( constraint == QLatin1String(
"tag" ) )
2411 else if ( constraint == QLatin1String(
"name" ) )
2413 resultNames =
allNames( type ).filter( param, Qt::CaseInsensitive );
2415 else if ( constraint == QLatin1String(
"!tag" ) )
2419 for (
const QString &name : unwanted )
2421 resultNames.removeAll( name );
2424 else if ( constraint == QLatin1String(
"!name" ) )
2426 const QStringList all =
allNames( type );
2427 for (
const QString &
str : all )
2429 if ( !
str.contains( param, Qt::CaseInsensitive ) )
2437 symbols = resultNames;
2442 if ( op == QLatin1String(
"OR" ) )
2444 symbols << resultNames;
2446 else if ( op == QLatin1String(
"AND" ) )
2448 QStringList dummy = symbols;
2450 for (
const QString &result : std::as_const( resultNames ) )
2452 if ( dummy.contains( result ) )
2461 QStringList unique = qgis::setToList( qgis::listToSet( symbols ) );
2462 std::sort( unique.begin(), unique.end() );
2470 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2480 statement = mCurrentDB.
prepare( query, nError );
2481 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2485 if ( !doc.setContent( xmlstr ) )
2487 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2490 QDomElement smartEl = doc.documentElement();
2491 QDomNodeList conditionNodes = smartEl.childNodes();
2493 for (
int i = 0; i < conditionNodes.count(); i++ )
2495 QDomElement condEl = conditionNodes.at( i ).toElement();
2496 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2497 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2499 condition.insert( constraint, param );
2510 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2520 statement = mCurrentDB.
prepare( query, nError );
2521 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2525 if ( !doc.setContent( xmlstr ) )
2527 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2529 QDomElement smartEl = doc.documentElement();
2530 op = smartEl.attribute( QStringLiteral(
"operator" ) );
2538 if ( filename.isEmpty() )
2540 QgsDebugMsg( QStringLiteral(
"Invalid filename for style export." ) );
2544 QDomDocument doc( QStringLiteral(
"qgis_style" ) );
2545 QDomElement root = doc.createElement( QStringLiteral(
"qgis_style" ) );
2547 doc.appendChild( root );
2557 QDomNodeList symbolsList = symbolsElem.elementsByTagName( QStringLiteral(
"symbol" ) );
2558 int nbSymbols = symbolsList.count();
2559 for (
int i = 0; i < nbSymbols; ++i )
2561 QDomElement
symbol = symbolsList.at( i ).toElement();
2562 QString name =
symbol.attribute( QStringLiteral(
"name" ) );
2564 if (
tags.count() > 0 )
2566 symbol.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2568 if ( favoriteSymbols.contains( name ) )
2570 symbol.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2575 QDomElement rampsElem = doc.createElement( QStringLiteral(
"colorramps" ) );
2576 for ( QMap<QString, QgsColorRamp *>::const_iterator itr = mColorRamps.constBegin(); itr != mColorRamps.constEnd(); ++itr )
2580 if (
tags.count() > 0 )
2582 rampEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2584 if ( favoriteColorramps.contains( itr.key() ) )
2586 rampEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2588 rampsElem.appendChild( rampEl );
2592 QDomElement textFormatsElem = doc.createElement( QStringLiteral(
"textformats" ) );
2593 for (
auto it = mTextFormats.constBegin(); it != mTextFormats.constEnd(); ++it )
2595 QDomElement textFormatEl = doc.createElement( QStringLiteral(
"textformat" ) );
2596 textFormatEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2598 textFormatEl.appendChild( textStyleEl );
2600 if (
tags.count() > 0 )
2602 textFormatEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2604 if ( favoriteTextFormats.contains( it.key() ) )
2606 textFormatEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2608 textFormatsElem.appendChild( textFormatEl );
2612 QDomElement labelSettingsElem = doc.createElement( QStringLiteral(
"labelsettings" ) );
2613 for (
auto it = mLabelSettings.constBegin(); it != mLabelSettings.constEnd(); ++it )
2615 QDomElement labelSettingsEl = doc.createElement( QStringLiteral(
"labelsetting" ) );
2616 labelSettingsEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2618 labelSettingsEl.appendChild( defEl );
2620 if (
tags.count() > 0 )
2622 labelSettingsEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2624 if ( favoriteTextFormats.contains( it.key() ) )
2626 labelSettingsEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2628 labelSettingsElem.appendChild( labelSettingsEl );
2632 QDomElement legendPatchShapesElem = doc.createElement( QStringLiteral(
"legendpatchshapes" ) );
2633 for (
auto it = mLegendPatchShapes.constBegin(); it != mLegendPatchShapes.constEnd(); ++it )
2635 QDomElement legendPatchShapeEl = doc.createElement( QStringLiteral(
"legendpatchshape" ) );
2636 legendPatchShapeEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2637 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2639 legendPatchShapeEl.appendChild( defEl );
2641 if (
tags.count() > 0 )
2643 legendPatchShapeEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2645 if ( favoriteLegendShapes.contains( it.key() ) )
2647 legendPatchShapeEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2649 legendPatchShapesElem.appendChild( legendPatchShapeEl );
2653 QDomElement symbols3DElem = doc.createElement( QStringLiteral(
"symbols3d" ) );
2654 for (
auto it = m3dSymbols.constBegin(); it != m3dSymbols.constEnd(); ++it )
2656 QDomElement symbolEl = doc.createElement( QStringLiteral(
"symbol3d" ) );
2657 symbolEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2658 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2659 defEl.setAttribute( QStringLiteral(
"type" ), it.value()->type() );
2661 symbolEl.appendChild( defEl );
2663 if (
tags.count() > 0 )
2665 symbolEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2667 if ( favorite3DSymbols.contains( it.key() ) )
2669 symbolEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2671 symbols3DElem.appendChild( symbolEl );
2674 root.appendChild( symbolsElem );
2675 root.appendChild( rampsElem );
2676 root.appendChild( textFormatsElem );
2677 root.appendChild( labelSettingsElem );
2678 root.appendChild( legendPatchShapesElem );
2679 root.appendChild( symbols3DElem );
2682 QFile f( filename );
2683 if ( !f.open( QFile::WriteOnly | QIODevice::Truncate ) )
2685 mErrorString =
"Couldn't open file for writing: " + filename;
2689 QTextStream ts( &f );
2690 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2691 ts.setCodec(
"UTF-8" );
2696 mFileName = filename;
2707 mErrorString = QString();
2708 QDomDocument doc( QStringLiteral(
"style" ) );
2709 QFile f( filename );
2710 if ( !f.open( QFile::ReadOnly ) )
2712 mErrorString = QStringLiteral(
"Unable to open the specified file" );
2713 QgsDebugMsg( QStringLiteral(
"Error opening the style XML file." ) );
2717 if ( !doc.setContent( &f ) )
2719 mErrorString = QStringLiteral(
"Unable to understand the style file: %1" ).arg( filename );
2720 QgsDebugMsg( QStringLiteral(
"XML Parsing error" ) );
2726 QDomElement docEl = doc.documentElement();
2727 if ( docEl.tagName() != QLatin1String(
"qgis_style" ) )
2729 mErrorString =
"Incorrect root tag in style: " + docEl.tagName();
2733 const QString version = docEl.attribute( QStringLiteral(
"version" ) );
2734 if ( version != QLatin1String(
STYLE_CURRENT_VERSION ) && version != QLatin1String(
"0" ) && version != QLatin1String(
"1" ) )
2736 mErrorString =
"Unknown style file version: " + version;
2742 QDomElement symbolsElement = docEl.firstChildElement( QStringLiteral(
"symbols" ) );
2743 QDomElement e = symbolsElement.firstChildElement();
2747 runEmptyQuery( query );
2752 while ( !e.isNull() )
2754 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2755 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2761 if ( e.tagName() == QLatin1String(
"symbol" ) )
2763 QString name = e.attribute( QStringLiteral(
"name" ) );
2765 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2767 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2769 bool favorite =
false;
2770 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2789 e = e.nextSiblingElement();
2798 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
2805 QDomElement rampsElement = docEl.firstChildElement( QStringLiteral(
"colorramps" ) );
2806 e = rampsElement.firstChildElement();
2807 while ( !e.isNull() )
2809 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2810 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2816 if ( e.tagName() == QLatin1String(
"colorramp" ) )
2818 QString name = e.attribute( QStringLiteral(
"name" ) );
2820 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2822 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2824 bool favorite =
false;
2825 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2844 e = e.nextSiblingElement();
2850 if ( qobject_cast< QGuiApplication * >( QCoreApplication::instance() ) )
2854 const QDomElement textFormatElement = docEl.firstChildElement( QStringLiteral(
"textformats" ) );
2855 e = textFormatElement.firstChildElement();
2856 while ( !e.isNull() )
2858 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2859 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2865 if ( e.tagName() == QLatin1String(
"textformat" ) )
2867 QString name = e.attribute( QStringLiteral(
"name" ) );
2869 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2871 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2873 bool favorite =
false;
2874 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2880 const QDomElement styleElem = e.firstChildElement();
2892 e = e.nextSiblingElement();
2899 const QDomElement labelSettingsElement = docEl.firstChildElement( QStringLiteral(
"labelsettings" ) );
2900 e = labelSettingsElement.firstChildElement();
2901 while ( !e.isNull() )
2903 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2904 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2910 if ( e.tagName() == QLatin1String(
"labelsetting" ) )
2912 QString name = e.attribute( QStringLiteral(
"name" ) );
2914 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2916 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2918 bool favorite =
false;
2919 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2925 const QDomElement styleElem = e.firstChildElement();
2937 e = e.nextSiblingElement();
2945 const QDomElement legendPatchShapesElement = docEl.firstChildElement( QStringLiteral(
"legendpatchshapes" ) );
2946 e = legendPatchShapesElement.firstChildElement();
2947 while ( !e.isNull() )
2949 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2950 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2956 if ( e.tagName() == QLatin1String(
"legendpatchshape" ) )
2958 QString name = e.attribute( QStringLiteral(
"name" ) );
2960 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2962 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2964 bool favorite =
false;
2965 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2971 const QDomElement shapeElem = e.firstChildElement();
2983 e = e.nextSiblingElement();
2990 const QDomElement symbols3DElement = docEl.firstChildElement( QStringLiteral(
"symbols3d" ) );
2991 e = symbols3DElement.firstChildElement();
2992 while ( !e.isNull() )
2994 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2995 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
3001 if ( e.tagName() == QLatin1String(
"symbol3d" ) )
3003 QString name = e.attribute( QStringLiteral(
"name" ) );
3005 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
3007 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
3009 bool favorite =
false;
3010 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
3015 const QDomElement symbolElem = e.firstChildElement();
3016 const QString type = symbolElem.attribute( QStringLiteral(
"type" ) );
3033 e = e.nextSiblingElement();
3038 runEmptyQuery( query );
3040 mFileName = filename;
3046 QFileInfo fileInfo( path );
3048 if ( fileInfo.suffix().compare( QLatin1String(
"xml" ), Qt::CaseInsensitive ) != 0 )
3052 if ( !QFile::exists( path ) )
3055 QFile inputFile( path );
3056 if ( !inputFile.open( QIODevice::ReadOnly ) )
3059 QTextStream stream( &inputFile );
3060 const QString line = stream.readLine();
3061 return line == QLatin1String(
"<!DOCTYPE qgis_style>" );
3064 bool QgsStyle::updateSymbol( StyleEntity type,
const QString &name )
3066 QDomDocument doc( QStringLiteral(
"dummy" ) );
3068 QByteArray xmlArray;
3069 QTextStream stream( &xmlArray );
3070 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
3071 stream.setCodec(
"UTF-8" );
3083 QgsDebugMsg( QStringLiteral(
"Update request received for unavailable symbol" ) );
3088 if ( symEl.isNull() )
3090 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
3093 symEl.save( stream, 4 );
3095 xmlArray.constData(), name.toUtf8().constData() );
3104 QgsDebugMsg( QStringLiteral(
"Update request received for unavailable symbol" ) );
3108 symEl = doc.createElement( QStringLiteral(
"symbol" ) );
3109 symEl.setAttribute( QStringLiteral(
"type" ), m3dSymbols.value( name )->type() );
3111 if ( symEl.isNull() )
3113 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
3116 symEl.save( stream, 4 );
3118 xmlArray.constData(), name.toUtf8().constData() );
3126 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable color ramp." ) );
3130 std::unique_ptr< QgsColorRamp > ramp(
colorRamp( name ) );
3132 if ( symEl.isNull() )
3134 QgsDebugMsg( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
3137 symEl.save( stream, 4 );
3139 xmlArray.constData(), name.toUtf8().constData() );
3147 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable text format." ) );
3153 if ( symEl.isNull() )
3155 QgsDebugMsg( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
3158 symEl.save( stream, 4 );
3160 xmlArray.constData(), name.toUtf8().constData() );
3168 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable label settings." ) );
3174 if ( symEl.isNull() )
3176 QgsDebugMsg( QStringLiteral(
"Couldn't convert label settings to valid XML!" ) );
3179 symEl.save( stream, 4 );
3181 xmlArray.constData(), name.toUtf8().constData() );
3189 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable legend patch shape." ) );
3194 symEl = doc.createElement( QStringLiteral(
"shape" ) );
3196 symEl.save( stream, 4 );
3198 xmlArray.constData(), name.toUtf8().constData() );
3205 QgsDebugMsg( QStringLiteral(
"Updating the unsupported StyleEntity" ) );
3211 if ( !runEmptyQuery( query ) )
3213 QgsDebugMsg( QStringLiteral(
"Couldn't insert symbol into the database!" ) );
3249 mCachedTags[ type ].remove( name );
3252 void QgsStyle::upgradeIfRequired()
3255 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='stylemetadata'" );
3259 statement = mCurrentDB.
prepare( query, rc );
3261 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
3265 "id INTEGER PRIMARY KEY,"\
3268 runEmptyQuery( query );
3269 query =
qgs_sqlite3_mprintf(
"INSERT INTO stylemetadata VALUES (NULL, '%q', '%q')",
"version",
"31200" );
3270 runEmptyQuery( query );
3277 statement = mCurrentDB.
prepare( query, rc );
3278 if ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
3290 runEmptyQuery( query );
3300 return QStringLiteral(
"symbol" );
3303 return QStringLiteral(
"colorramp" );
3306 return QStringLiteral(
"textformat" );
3309 return QStringLiteral(
"labelsettings" );
3312 return QStringLiteral(
"legendpatchshapes" );
3315 return QStringLiteral(
"symbol3d" );
3318 return QStringLiteral(
"tag" );
3321 return QStringLiteral(
"smartgroup" );
3331 return QStringLiteral(
"tagmap" );
3334 return QStringLiteral(
"ctagmap" );
3337 return QStringLiteral(
"tftagmap" );
3340 return QStringLiteral(
"lstagmap" );
3343 return QStringLiteral(
"lpstagmap" );
3346 return QStringLiteral(
"symbol3dtagmap" );
3360 return QStringLiteral(
"symbol_id" );
3363 return QStringLiteral(
"colorramp_id" );
3366 return QStringLiteral(
"textformat_id" );
3369 return QStringLiteral(
"labelsettings_id" );
3372 return QStringLiteral(
"legendpatchshape_id" );
3375 return QStringLiteral(
"symbol3d_id" );
@ ScaleArea
Calculate scale by the area.
static int versionInt()
Version number used for comparing versions using the "Check QGIS Version" function.
QStringList symbolTypes() const
Returns a list of all available symbol types.
static QString userStylePath()
Returns the path to user's style.
static QString defaultStylePath()
Returns the path to default style (works as a starting point).
static Qgs3DSymbolRegistry * symbol3DRegistry()
Returns registry of available 3D symbols.
Abstract base class for color ramps.
virtual QgsColorRamp * clone() const =0
Creates a clone of the color ramp.
A geometry is the spatial representation of a feature.
Represents a patch shape for use in map legends.
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Read settings from a DOM element.
QList< QList< QPolygonF > > toQPolygonF(Qgis::SymbolType type, QSizeF size) const
Converts the patch shape to a set of QPolygonF objects representing how the patch should be drawn for...
void writeXml(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
Qgis::SymbolType symbolType() const
Returns the symbol type associated with this patch.
Line string geometry type, with support for z-dimension and m-values.
Contains settings for how a map layer will be labeled.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
The class is used as a container of context for various read/write operations on other objects.
Scoped object for logging of the runtime for a single operation or group of operations.
A color ramp entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
An interface for entities which can be placed in a QgsStyle database.
virtual QgsStyle::StyleEntity type() const =0
Returns the type of style entity.
A label settings entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A legend patch shape entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A 3d symbol entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A symbol entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A text format entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
bool addEntity(const QString &name, const QgsStyleEntityInterface *entity, bool update=false)
Adds an entity to the style, with the specified name.
bool saveColorRamp(const QString &name, QgsColorRamp *ramp, bool favorite, const QStringList &tags)
Adds the colorramp to the database.
void labelSettingsChanged(const QString &name)
Emitted whenever a label setting's definition is changed.
int colorRampCount()
Returns count of color ramps.
bool detagSymbol(StyleEntity type, const QString &symbol, const QStringList &tags)
Detags the symbol with the given list.
QgsTextFormat textFormat(const QString &name) const
Returns the text format with the specified name.
QStringList allNames(StyleEntity type) const
Returns a list of the names of all existing entities of the specified type.
QgsLegendPatchShape defaultPatch(Qgis::SymbolType type, QSizeF size) const
Returns the default legend patch shape for the given symbol type.
bool remove(StyleEntity type, int id)
Removes the specified entity from the database.
bool removeSymbol(const QString &name)
Removes symbol from style (and delete it)
void entityChanged(QgsStyle::StyleEntity entity, const QString &name)
Emitted whenever an entity's definition is changed.
bool removeLabelSettings(const QString &name)
Removes label settings from the style.
void labelSettingsAdded(const QString &name)
Emitted whenever label settings have been added to the style and the database has been updated as a r...
QStringList tags() const
Returns a list of all tags in the style database.
QString tag(int id) const
Returns the tag name for the given id.
QgsSmartConditionMap smartgroup(int id)
Returns the QgsSmartConditionMap for the given id.
bool renameColorRamp(const QString &oldName, const QString &newName)
Changes ramp's name.
void rampAdded(const QString &name)
Emitted whenever a color ramp has been added to the style and the database has been updated as a resu...
QStringList symbol3DNames() const
Returns a list of names of 3d symbols in the style.
bool tagSymbol(StyleEntity type, const QString &symbol, const QStringList &tags)
Tags the symbol with the tags in the list.
int entityId(StyleEntity type, const QString &name)
Returns the id in the style database for the given name of the specified entity type.
bool saveLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool favorite, const QStringList &tags)
Adds label settings to the database.
void symbolSaved(const QString &name, QgsSymbol *symbol)
Emitted every time a new symbol has been added to the database.
bool symbolHasTag(StyleEntity type, const QString &symbol, const QString &tag)
Returns whether a given tag is associated with the symbol.
QgsTextFormat defaultTextFormat(QgsStyle::TextFormatContext context=QgsStyle::TextFormatContext::Labeling) const
Returns the default text format to use for new text based objects in the specified context.
bool createDatabase(const QString &filename)
Creates an on-disk database.
QStringList textFormatNames() const
Returns a list of names of text formats in the style.
const QgsColorRamp * colorRampRef(const QString &name) const
Returns a const pointer to a symbol (doesn't create new instance)
QStringList symbolsWithTag(StyleEntity type, int tagid) const
Returns the symbol names with which have the given tag.
QList< QgsWkbTypes::GeometryType > symbol3DCompatibleGeometryTypes(const QString &name) const
Returns the list of the vector layer geometry types which are compatible with the 3D symbol with the ...
bool addColorRamp(const QString &name, QgsColorRamp *colorRamp, bool update=false)
Adds a color ramp to the style.
bool removeTextFormat(const QString &name)
Removes a text format from the style.
QgsSymbol * symbol(const QString &name)
Returns a NEW copy of symbol.
void labelSettingsRemoved(const QString &name)
Emitted whenever label settings have been removed from the style and the database has been updated as...
QStringList symbolsOfSmartgroup(StyleEntity type, int id)
Returns the symbols for the smartgroup.
int labelSettingsCount() const
Returns count of label settings in the style.
StyleEntity
Enum for Entities involved in a style.
@ LabelSettingsEntity
Label settings.
@ TextFormatEntity
Text formats.
@ SmartgroupEntity
Smart groups.
@ Symbol3DEntity
3D symbol entity (since QGIS 3.14)
@ ColorrampEntity
Color ramps.
@ LegendPatchShapeEntity
Legend patch shape (since QGIS 3.14)
QStringList tagsOfSymbol(StyleEntity type, const QString &symbol)
Returns the tags associated with the symbol.
void symbolRenamed(const QString &oldName, const QString &newName)
Emitted whenever a symbol has been renamed from oldName to newName.
void groupsModified()
Emitted every time a tag or smartgroup has been added, removed, or renamed.
void clear()
Removes all contents of the style.
int smartgroupId(const QString &smartgroup)
Returns the database id for the given smartgroup name.
void rampRemoved(const QString &name)
Emitted whenever a color ramp has been removed from the style and the database has been updated as a ...
void entityRenamed(QgsStyle::StyleEntity entity, const QString &oldName, const QString &newName)
Emitted whenever a entity of the specified type has been renamed from oldName to newName.
const QgsSymbol * symbolRef(const QString &name) const
Returns a const pointer to a symbol (doesn't create new instance)
int addSmartgroup(const QString &name, const QString &op, const QgsSmartConditionMap &conditions)
Adds a new smartgroup to the database and returns the id.
QStringList colorRampNames() const
Returns a list of names of color ramps.
void textFormatChanged(const QString &name)
Emitted whenever a text format's definition is changed.
bool addSymbol3D(const QString &name, QgsAbstract3DSymbol *symbol, bool update=false)
Adds a 3d symbol with the specified name to the style.
QStringList legendPatchShapeNames() const
Returns a list of names of legend patch shapes in the style.
bool renameLegendPatchShape(const QString &oldName, const QString &newName)
Changes a legend patch shape's name.
static void cleanDefaultStyle()
Deletes the default style. Only to be used by QgsApplication::exitQgis()
QgsStyle()
Constructor for QgsStyle.
static QgsStyle * defaultStyle()
Returns default application-wide style.
void textFormatRenamed(const QString &oldName, const QString &newName)
Emitted whenever a text format has been renamed from oldName to newName.
bool removeEntityByName(StyleEntity type, const QString &name)
Removes the entry of the specified type with matching name from the database.
void labelSettingsRenamed(const QString &oldName, const QString &newName)
Emitted whenever label settings have been renamed from oldName to newName.
int textFormatCount() const
Returns count of text formats in the style.
QStringList findSymbols(StyleEntity type, const QString &qword)
Returns the names of the symbols which have a matching 'substring' in its definition.
int tagId(const QString &tag)
Returns the database id for the given tag name.
void rampRenamed(const QString &oldName, const QString &newName)
Emitted whenever a color ramp has been renamed from oldName to newName.
bool exportXml(const QString &filename)
Exports the style as a XML file.
QgsWkbTypes::GeometryType labelSettingsLayerType(const QString &name) const
Returns the layer geometry type corresponding to the label settings with the specified name,...
void createTables()
Creates tables structure for new database.
bool addLegendPatchShape(const QString &name, const QgsLegendPatchShape &shape, bool update=false)
Adds a legend patch shape with the specified name to the style.
bool saveSymbol(const QString &name, QgsSymbol *symbol, bool favorite, const QStringList &tags)
Adds the symbol to the database with tags.
int textFormatId(const QString &name)
Returns the ID in the style database for the given text format by name.
QgsColorRamp * colorRamp(const QString &name) const
Returns a new copy of the specified color ramp.
int symbolCount()
Returns count of symbols in style.
bool renameEntity(StyleEntity type, const QString &oldName, const QString &newName)
Renames an entity of the specified type from oldName to newName.
static bool isXmlStyleFile(const QString &path)
Tests if the file at path is a QGIS style XML file.
int symbol3DCount() const
Returns count of 3D symbols in the style.
bool createMemoryDatabase()
Creates a temporary memory database.
int colorrampId(const QString &name)
Returns the id in the style database for the given colorramp name returns 0 if not found.
QStringList labelSettingsNames() const
Returns a list of names of label settings in the style.
bool load(const QString &filename)
Loads a file into the style.
bool save(QString filename=QString())
Saves style into a file (will use current filename if empty string is passed)
QStringList smartgroupNames() const
Returns the smart groups list.
bool rename(StyleEntity type, int id, const QString &newName)
Renames the given entity with the specified id.
bool renameTextFormat(const QString &oldName, const QString &newName)
Changes a text format's name.
void textFormatAdded(const QString &name)
Emitted whenever a text format has been added to the style and the database has been updated as a res...
bool removeFavorite(StyleEntity type, const QString &name)
Removes the specified symbol from favorites.
int legendPatchShapesCount() const
Returns count of legend patch shapes in the style.
QgsSymbolGroupMap smartgroupsListMap()
Returns the smart groups map with id as key and name as value.
bool isFavorite(StyleEntity type, const QString &name)
Returns true if the symbol with matching type and name is marked as a favorite.
int symbolId(const QString &name)
Returns the id in the style database for the given symbol name returns 0 if not found.
bool saveLegendPatchShape(const QString &name, const QgsLegendPatchShape &shape, bool favorite, const QStringList &tags)
Adds a legend patch shape to the database.
bool renameLabelSettings(const QString &oldName, const QString &newName)
Changes a label setting's name.
bool renameSymbol3D(const QString &oldName, const QString &newName)
Changes a 3d symbol's name.
bool addTextFormat(const QString &name, const QgsTextFormat &format, bool update=false)
Adds a text format with the specified name to the style.
void rampChanged(const QString &name)
Emitted whenever a color ramp's definition is changed.
QStringList symbolsOfFavorite(StyleEntity type) const
Returns the symbol names which are flagged as favorite.
void entityTagsChanged(QgsStyle::StyleEntity entity, const QString &name, const QStringList &newTags)
Emitted whenever an entity's tags are changed.
bool renameSymbol(const QString &oldName, const QString &newName)
Renames a symbol from oldName to newName.
bool removeColorRamp(const QString &name)
Removes color ramp from style (and delete it)
bool saveSymbol3D(const QString &name, QgsAbstract3DSymbol *symbol, bool favorite, const QStringList &tags)
Adds a 3d symbol to the database.
void favoritedChanged(QgsStyle::StyleEntity entity, const QString &name, bool isFavorite)
Emitted whenever an entity is either favorited or un-favorited.
QgsPalLayerSettings labelSettings(const QString &name) const
Returns the label settings with the specified name.
void entityRemoved(QgsStyle::StyleEntity entity, const QString &name)
Emitted whenever an entity of the specified type is removed from the style and the database has been ...
int labelSettingsId(const QString &name)
Returns the ID in the style database for the given label settings by name.
Qgis::SymbolType legendPatchShapeSymbolType(const QString &name) const
Returns the symbol type corresponding to the legend patch shape with the specified name,...
QgsAbstract3DSymbol * symbol3D(const QString &name) const
Returns a new copy of the 3D symbol with the specified name.
int addTag(const QString &tagName)
Adds a new tag and returns the tag's id.
const QgsSymbol * previewSymbolForPatchShape(const QgsLegendPatchShape &shape) const
Returns a symbol to use for rendering preview icons for a patch shape.
bool addSymbol(const QString &name, QgsSymbol *symbol, bool update=false)
Adds a symbol to style and takes symbol's ownership.
QgsLegendPatchShape legendPatchShape(const QString &name) const
Returns the legend patch shape with the specified name.
void entityAdded(QgsStyle::StyleEntity entity, const QString &name)
Emitted every time a new entity has been added to the database.
QStringList symbolNames() const
Returns a list of names of symbols.
TextFormatContext
Text format context.
void symbolRemoved(const QString &name)
Emitted whenever a symbol has been removed from the style and the database has been updated as a resu...
void symbolChanged(const QString &name)
Emitted whenever a symbol's definition is changed.
bool addFavorite(StyleEntity type, const QString &name)
Adds the specified symbol to favorites.
QString smartgroupOperator(int id)
Returns the operator for the smartgroup.
bool saveTextFormat(const QString &name, const QgsTextFormat &format, bool favorite, const QStringList &tags)
Adds a text format to the database.
QList< QList< QPolygonF > > defaultPatchAsQPolygonF(Qgis::SymbolType type, QSizeF size) const
Returns the default patch geometry for the given symbol type and size as a set of QPolygonF objects (...
void textFormatRemoved(const QString &name)
Emitted whenever a text format has been removed from the style and the database has been updated as a...
bool importXml(const QString &filename)
Imports the symbols and colorramps into the default style database from the given XML file.
bool addLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool update=false)
Adds label settings with the specified name to the style.
static QgsColorRamp * loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
static QDomElement saveColorRamp(const QString &name, QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
static QgsSymbol * loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
static QgsSymbolMap loadSymbols(QDomElement &element, const QgsReadWriteContext &context)
Reads a collection of symbols from XML and returns them in a map. Caller is responsible for deleting ...
static QDomElement saveSymbols(QgsSymbolMap &symbols, const QString &tagName, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a collection of symbols to XML with specified tagName for the top-level element.
Abstract base class for all rendered symbols.
Qgis::SymbolType type() const
Returns the symbol's type.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
Container for all settings relating to text rendering.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
sqlite3_statement_unique_ptr prepare(const QString &sql, int &resultCode) const
Prepares a sql statement, returning the result.
int open(const QString &path)
Opens the database at the specified file path.
QString errorMessage() const
Returns the most recent error message encountered by the database.
Unique pointer for sqlite3 prepared statements, which automatically finalizes the statement when the ...
QString columnAsText(int column) const
Returns the column value from the current statement row as a string.
QMultiMap< QString, QString > QgsSmartConditionMap
A multimap to hold the smart group conditions as constraint and parameter pairs.
QMap< QString, QgsSymbol * > QgsSymbolMap
QString qgs_sqlite3_mprintf(const char *format,...)
Wraps sqlite3_mprintf() by automatically freeing the memory.
LegendPatchTable
Columns available in the legend patch table.
@ LegendPatchTableId
Legend patch ID.
@ LegendPatchTableName
Legend patch name.
@ LegendPatchTableFavoriteId
Legend patch is favorite flag.
@ LegendPatchTableXML
Legend patch definition (as XML)
#define STYLE_CURRENT_VERSION
Symbol3DTable
Columns available in the 3d symbol table.
@ Symbol3DTableXML
3d symbol definition (as XML)
@ Symbol3DTableName
3d symbol name
@ Symbol3DTableFavoriteId
3d symbol is favorite flag
@ Symbol3DTableId
3d symbol ID
@ TextFormatName
Text format name.
@ TextFormatXML
Text format definition (as XML)
@ SymbolXML
Symbol definition (as XML)
@ SmartgroupName
Smart group name.
@ SmartgroupId
Smart group ID.
QMap< int, QString > QgsSymbolGroupMap
@ LabelSettingsName
Label settings name.
@ LabelSettingsXML
Label settings definition (as XML)
@ ColorrampName
Color ramp name.
@ ColorrampXML
Color ramp definition (as XML)
QList< QgsSymbolLayer * > QgsSymbolLayerList