40#include <QDomDocument>
43#include <QDomNodeList>
52#define STYLE_CURRENT_VERSION "2"
77QgsStyle *QgsStyle::sDefaultStyle =
nullptr;
82 std::unique_ptr< QgsSimpleMarkerSymbolLayer > simpleMarker = std::make_unique< QgsSimpleMarkerSymbolLayer >(
Qgis::MarkerShape::Circle,
84 simpleMarker->setStrokeWidth( 0.4 );
85 mPatchMarkerSymbol = std::make_unique< QgsMarkerSymbol >(
QgsSymbolLayerList() << simpleMarker.release() );
87 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 84, 176, 74 ), 0.6 );
88 mPatchLineSymbol = std::make_unique< QgsLineSymbol >(
QgsSymbolLayerList() << simpleLine.release() );
90 std::unique_ptr< QgsGradientFillSymbolLayer > gradientFill = std::make_unique< QgsGradientFillSymbolLayer >( QColor( 66, 150, 63 ), QColor( 84, 176, 74 ) );
91 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleOutline = std::make_unique< QgsSimpleLineSymbolLayer >( QColor( 56, 128, 54 ), 0.26 );
92 mPatchFillSymbol = std::make_unique< QgsFillSymbol >(
QgsSymbolLayerList() << gradientFill.release() << simpleOutline.release() );
113 switch ( entity->
type() )
147 if ( !sDefaultStyle )
153 if ( !QFile::exists( styleFilename ) )
161 sDefaultStyle->createStyleMetadataTableIfNeeded();
168 sDefaultStyle->
load( styleFilename );
169 sDefaultStyle->upgradeIfRequired();
171 sDefaultStyle->
setName( QObject::tr(
"Default" ) );
173 return sDefaultStyle;
178 delete sDefaultStyle;
179 sDefaultStyle =
nullptr;
184 qDeleteAll( mSymbols );
185 qDeleteAll( mColorRamps );
186 qDeleteAll( m3dSymbols );
190 mTextFormats.clear();
194 mCachedFavorites.clear();
203 if ( mSymbols.contains(
name ) )
206 delete mSymbols.value(
name );
224 QDomDocument doc( QStringLiteral(
"dummy" ) );
226 if ( symEl.isNull() )
228 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
233 QTextStream stream( &xmlArray );
234#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
235 stream.setCodec(
"UTF-8" );
237 symEl.save( stream, 4 );
239 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
241 if ( !runEmptyQuery( query ) )
243 QgsDebugMsg( QStringLiteral(
"Couldn't insert symbol into the database!" ) );
305 return mSymbols.value(
name );
310 return mSymbols.count();
315 return mSymbols.keys();
325 if ( mColorRamps.contains(
name ) )
328 delete mColorRamps.value(
name );
346 if ( mTextFormats.contains(
name ) )
349 mTextFormats.remove(
name );
350 mTextFormats.insert(
name, format );
356 mTextFormats.insert(
name, format );
367 if ( mLabelSettings.contains(
name ) )
370 mLabelSettings.remove(
name );
371 mLabelSettings.insert(
name, settings );
377 mLabelSettings.insert(
name, settings );
388 if ( mLegendPatchShapes.contains(
name ) )
391 mLegendPatchShapes.remove(
name );
392 mLegendPatchShapes.insert(
name, shape );
398 mLegendPatchShapes.insert(
name, shape );
409 if ( m3dSymbols.contains(
name ) )
412 delete m3dSymbols.take(
name );
430 QDomDocument doc( QStringLiteral(
"dummy" ) );
433 if ( rampEl.isNull() )
435 QgsDebugMsg( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
440 QTextStream stream( &xmlArray );
441#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
442 stream.setCodec(
"UTF-8" );
444 rampEl.save( stream, 4 );
445 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO colorramp VALUES (NULL, '%q', '%q', %d);",
446 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
447 if ( !runEmptyQuery( query ) )
449 QgsDebugMsg( QStringLiteral(
"Couldn't insert colorramp into the database!" ) );
471 return ramp ? ramp->
clone() :
nullptr;
476 return mColorRamps.value(
name );
481 return mColorRamps.count();
486 return mColorRamps.keys();
489void QgsStyle::handleDeferred3DSymbolCreation()
491 for (
auto it = mDeferred3DsymbolElements.constBegin(); it != mDeferred3DsymbolElements.constEnd(); ++it )
493 const QString symbolType = it.value().attribute( QStringLiteral(
"type" ) );
503 QgsDebugMsg(
"Cannot open 3d symbol " + it.key() );
507 mDeferred3DsymbolElements.clear();
510bool QgsStyle::openDatabase(
const QString &filename )
512 int rc = mCurrentDB.
open( filename );
515 mErrorString = QStringLiteral(
"Couldn't open the style database: %1" ).arg( mCurrentDB.
errorMessage() );
524 mErrorString.clear();
525 if ( !openDatabase( filename ) )
527 mErrorString = QStringLiteral(
"Unable to create database" );
539 mErrorString.clear();
540 if ( !openDatabase( QStringLiteral(
":memory:" ) ) )
542 mErrorString = QStringLiteral(
"Unable to create temporary memory database" );
555 "id INTEGER PRIMARY KEY,"\
558 "favorite INTEGER);"\
559 "CREATE TABLE colorramp("\
560 "id INTEGER PRIMARY KEY,"\
563 "favorite INTEGER);"\
564 "CREATE TABLE textformat("\
565 "id INTEGER PRIMARY KEY,"\
568 "favorite INTEGER);"\
569 "CREATE TABLE labelsettings("\
570 "id INTEGER PRIMARY KEY,"\
573 "favorite INTEGER);"\
574 "CREATE TABLE legendpatchshapes("\
575 "id INTEGER PRIMARY KEY,"\
578 "favorite INTEGER);"\
579 "CREATE TABLE symbol3d("\
580 "id INTEGER PRIMARY KEY,"\
583 "favorite INTEGER);"\
585 "id INTEGER PRIMARY KEY,"\
587 "CREATE TABLE tagmap("\
588 "tag_id INTEGER NOT NULL,"\
589 "symbol_id INTEGER);"\
590 "CREATE TABLE ctagmap("\
591 "tag_id INTEGER NOT NULL,"\
592 "colorramp_id INTEGER);"\
593 "CREATE TABLE tftagmap("\
594 "tag_id INTEGER NOT NULL,"\
595 "textformat_id INTEGER);"\
596 "CREATE TABLE lstagmap("\
597 "tag_id INTEGER NOT NULL,"\
598 "labelsettings_id INTEGER);"\
599 "CREATE TABLE lpstagmap("\
600 "tag_id INTEGER NOT NULL,"\
601 "legendpatchshape_id INTEGER);"\
602 "CREATE TABLE symbol3dtagmap("\
603 "tag_id INTEGER NOT NULL,"\
604 "symbol3d_id INTEGER);"\
605 "CREATE TABLE smartgroup("\
606 "id INTEGER PRIMARY KEY,"\
609 runEmptyQuery( query );
614 mErrorString.clear();
617 if ( !openDatabase( filename ) )
619 mErrorString = QStringLiteral(
"Unable to open database file specified" );
625 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='textformat'" );
628 statement = mCurrentDB.
prepare( query, rc );
629 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
632 "id INTEGER PRIMARY KEY,"\
635 "favorite INTEGER);"\
636 "CREATE TABLE tftagmap("\
637 "tag_id INTEGER NOT NULL,"\
638 "textformat_id INTEGER);" );
639 runEmptyQuery( query );
642 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='labelsettings'" );
643 statement = mCurrentDB.
prepare( query, rc );
644 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
647 "id INTEGER PRIMARY KEY,"\
650 "favorite INTEGER);"\
651 "CREATE TABLE lstagmap("\
652 "tag_id INTEGER NOT NULL,"\
653 "labelsettings_id INTEGER);" );
654 runEmptyQuery( query );
657 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='legendpatchshapes'" );
658 statement = mCurrentDB.
prepare( query, rc );
659 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
662 "id INTEGER PRIMARY KEY,"\
665 "favorite INTEGER);"\
666 "CREATE TABLE lpstagmap("\
667 "tag_id INTEGER NOT NULL,"\
668 "legendpatchshape_id INTEGER);" );
669 runEmptyQuery( query );
673 statement = mCurrentDB.
prepare( query, rc );
674 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
677 "id INTEGER PRIMARY KEY,"\
680 "favorite INTEGER);"\
681 "CREATE TABLE symbol3dtagmap("\
682 "tag_id INTEGER NOT NULL,"\
683 "symbol3d_id INTEGER);" );
684 runEmptyQuery( query );
689 "UPDATE colorramp SET favorite=0 WHERE favorite IS NULL;"
690 "UPDATE textformat SET favorite=0 WHERE favorite IS NULL;"
691 "UPDATE labelsettings SET favorite=0 WHERE favorite IS NULL;"
692 "UPDATE legendpatchshapes SET favorite=0 WHERE favorite IS NULL;"
693 "UPDATE symbol3d SET favorite=0 WHERE favorite IS NULL;"
695 runEmptyQuery( query );
701 statement = mCurrentDB.
prepare( query, rc );
703 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
709 if ( !doc.setContent( xmlstring ) )
715 QDomElement symElement = doc.documentElement();
718 mSymbols.insert( symbolName,
symbol );
725 statement = mCurrentDB.
prepare( query, rc );
726 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
732 if ( !doc.setContent( xmlstring ) )
737 QDomElement rampElement = doc.documentElement();
740 mColorRamps.insert( rampName, ramp );
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 text format " + formatName );
759 QDomElement formatElement = doc.documentElement();
762 mTextFormats.insert( formatName, format );
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 label settings " + settingsName );
781 QDomElement settingsElement = doc.documentElement();
784 mLabelSettings.insert( settingsName, settings );
791 statement = mCurrentDB.
prepare( query, rc );
792 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
798 if ( !doc.setContent( xmlstring ) )
800 QgsDebugMsg(
"Cannot open legend patch shape " + settingsName );
803 QDomElement settingsElement = doc.documentElement();
806 mLegendPatchShapes.insert( settingsName, shape );
813 statement = mCurrentDB.
prepare( query, rc );
817 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
823 if ( !doc.setContent( xmlstring ) )
825 QgsDebugMsg(
"Cannot open 3d symbol " + settingsName );
828 QDomElement settingsElement = doc.documentElement();
830 if ( !registry3dPopulated )
832 mDeferred3DsymbolElements.insert( settingsName, settingsElement );
836 const QString symbolType = settingsElement.attribute( QStringLiteral(
"type" ) );
841 m3dSymbols.insert( settingsName,
symbol.release() );
845 QgsDebugMsg(
"Cannot open 3d symbol " + settingsName );
852 mFileName = filename;
853 createStyleMetadataTableIfNeeded();
859 mErrorString.clear();
861 if ( !filename.isEmpty() )
862 mFileName = filename;
869 mFileName = filename;
874 if ( mSymbols.contains( newName ) )
876 QgsDebugMsg( QStringLiteral(
"Symbol of new name already exists" ) );
884 mSymbols.insert( newName,
symbol );
888 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to tag." ) );
895 QgsDebugMsg( QStringLiteral(
"No such symbol for tagging in database: " ) + oldName );
914 if ( mColorRamps.contains( newName ) )
916 QgsDebugMsg( QStringLiteral(
"Color ramp of new name already exists." ) );
924 mColorRamps.insert( newName, ramp );
930 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM colorramp WHERE name='%q'", oldName.toUtf8().constData() );
932 statement = mCurrentDB.
prepare( query, nErr );
933 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
935 rampid = sqlite3_column_int( statement.get(), 0 );
950 QDomDocument doc( QStringLiteral(
"dummy" ) );
953 if ( formatElem.isNull() )
955 QgsDebugMsg( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
960 QTextStream stream( &xmlArray );
961#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
962 stream.setCodec(
"UTF-8" );
964 formatElem.save( stream, 4 );
965 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO textformat VALUES (NULL, '%q', '%q', %d);",
966 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
967 if ( !runEmptyQuery( query ) )
969 QgsDebugMsg( QStringLiteral(
"Couldn't insert text format into the database!" ) );
990 if ( mTextFormats.contains( newName ) )
992 QgsDebugMsg( QStringLiteral(
"Text format of new name already exists." ) );
996 if ( !mTextFormats.contains( oldName ) )
1000 mTextFormats.insert( newName, format );
1006 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM textformat WHERE name='%q'", oldName.toUtf8().constData() );
1008 statement = mCurrentDB.
prepare( query, nErr );
1009 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1011 textFormatId = sqlite3_column_int( statement.get(), 0 );
1026 QDomDocument doc( QStringLiteral(
"dummy" ) );
1029 if ( settingsElem.isNull() )
1031 QgsDebugMsg( QStringLiteral(
"Couldn't convert label settings to valid XML!" ) );
1035 QByteArray xmlArray;
1036 QTextStream stream( &xmlArray );
1037#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1038 stream.setCodec(
"UTF-8" );
1040 settingsElem.save( stream, 4 );
1041 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO labelsettings VALUES (NULL, '%q', '%q', %d);",
1042 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1043 if ( !runEmptyQuery( query ) )
1045 QgsDebugMsg( QStringLiteral(
"Couldn't insert label settings into the database!" ) );
1066 if ( mLabelSettings.contains( newName ) )
1068 QgsDebugMsg( QStringLiteral(
"Label settings of new name already exists." ) );
1072 if ( !mLabelSettings.contains( oldName ) )
1076 mLabelSettings.insert( newName, settings );
1082 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM labelsettings WHERE name='%q'", oldName.toUtf8().constData() );
1084 statement = mCurrentDB.
prepare( query, nErr );
1085 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1102 QDomDocument doc( QStringLiteral(
"dummy" ) );
1103 QDomElement shapeElem = doc.createElement( QStringLiteral(
"shape" ) );
1106 QByteArray xmlArray;
1107 QTextStream stream( &xmlArray );
1108#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1109 stream.setCodec(
"UTF-8" );
1111 shapeElem.save( stream, 4 );
1112 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO legendpatchshapes VALUES (NULL, '%q', '%q', %d);",
1113 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1114 if ( !runEmptyQuery( query ) )
1116 QgsDebugMsg( QStringLiteral(
"Couldn't insert legend patch shape into the database!" ) );
1131 if ( mLegendPatchShapes.contains( newName ) )
1133 QgsDebugMsg( QStringLiteral(
"Legend patch shape of new name already exists." ) );
1137 if ( !mLegendPatchShapes.contains( oldName ) )
1141 mLegendPatchShapes.insert( newName, shape );
1147 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM legendpatchshapes WHERE name='%q'", oldName.toUtf8().constData() );
1149 statement = mCurrentDB.
prepare( query, nErr );
1150 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1168 if ( mDefaultPatchCache[
static_cast< int >( type ) ].contains( size ) )
1169 return mDefaultPatchCache[
static_cast< int >( type ) ].value( size );
1175 geom =
QgsGeometry( std::make_unique< QgsPoint >(
static_cast< int >( size.width() ) / 2,
static_cast< int >( size.height() ) / 2 ) );
1182 double y =
static_cast< int >( size.height() ) / 2 + 0.5;
1183 geom =
QgsGeometry( std::make_unique< QgsLineString >( ( QVector< double >() << 0 << size.width() ),
1184 ( QVector< double >() << y << y ) ) );
1190 geom =
QgsGeometry( std::make_unique< QgsPolygon >(
1191 new QgsLineString( QVector< double >() << 0 <<
static_cast< int >( size.width() ) <<
static_cast< int >( size.width() ) << 0 << 0,
1192 QVector< double >() <<
static_cast< int >( size.height() ) <<
static_cast< int >( size.height() ) << 0 << 0 <<
static_cast< int >( size.height() ) ) ) );
1201 mDefaultPatchCache[
static_cast< int >( type ) ][size ] = res;
1208 return QList<QList<QPolygonF> >();
1210 if ( mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ].contains( size ) )
1211 return mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ].value( size );
1214 mDefaultPatchQPolygonFCache[
static_cast< int >( type ) ][size ] = res;
1220 return textFormat( QStringLiteral(
"Default" ) );
1240 QDomDocument doc( QStringLiteral(
"dummy" ) );
1241 QDomElement elem = doc.createElement( QStringLiteral(
"symbol" ) );
1242 elem.setAttribute( QStringLiteral(
"type" ),
symbol->
type() );
1245 QByteArray xmlArray;
1246 QTextStream stream( &xmlArray );
1247#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1248 stream.setCodec(
"UTF-8" );
1250 elem.save( stream, 4 );
1251 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO symbol3d VALUES (NULL, '%q', '%q', %d);",
1252 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1253 if ( !runEmptyQuery( query ) )
1255 QgsDebugMsg( QStringLiteral(
"Couldn't insert 3d symbol into the database!" ) );
1270 if ( m3dSymbols.contains( newName ) )
1272 QgsDebugMsg( QStringLiteral(
"3d symbol of new name already exists." ) );
1276 if ( !m3dSymbols.contains( oldName ) )
1280 m3dSymbols.insert( newName,
symbol );
1286 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM symbol3d WHERE name='%q'", oldName.toUtf8().constData() );
1288 statement = mCurrentDB.
prepare( query, nErr );
1289 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1304 return m3dSymbols.keys();
1311 QgsDebugMsg( QStringLiteral(
"Cannot Open database for getting favorite symbols" ) );
1312 return QStringList();
1320 QgsDebugMsg( QStringLiteral(
"No such style entity" ) );
1321 return QStringList();
1324 query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT name FROM %1 WHERE favorite=1" ).arg( entityTableName( type ) ).toLocal8Bit().data() );
1330 statement = mCurrentDB.
prepare( query, nErr );
1332 QStringList symbols;
1333 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1345 QgsDebugMsg( QStringLiteral(
"Cannot open database to get symbols of tagid %1" ).arg( tagid ) );
1346 return QStringList();
1354 QgsDebugMsg( QStringLiteral(
"Unknown Entity" ) );
1355 return QStringList();
1358 subquery =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT %1 FROM %2 WHERE tag_id=%d" ).arg( tagmapEntityIdFieldName( type ),
1359 tagmapTableName( type ) ).toLocal8Bit().data(), tagid );
1365 statement = mCurrentDB.
prepare( subquery, nErr );
1368 QStringList symbols;
1369 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1371 int id = sqlite3_column_int( statement.get(), 0 );
1373 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT name FROM %1 WHERE id=%d" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
id );
1377 statement2 = mCurrentDB.
prepare( query, rc );
1378 while ( rc == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1393 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO tag VALUES (NULL, '%q')", tagname.toUtf8().constData() );
1395 statement = mCurrentDB.
prepare( query, nErr );
1396 if ( nErr == SQLITE_OK )
1397 ( void )sqlite3_step( statement.get() );
1400 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1404 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
1410 return QStringList();
1416 statement = mCurrentDB.
prepare( query, nError );
1418 QStringList tagList;
1419 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1429 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET name='%q' WHERE id=%d" ).arg( entityTableName( type ) ).toLocal8Bit().data(), newName.toUtf8().constData(),
id );
1431 const bool result = runEmptyQuery( query );
1434 mErrorString = QStringLiteral(
"Could not rename!" );
1438 mCachedTags.clear();
1439 mCachedFavorites.clear();
1464 bool groupRemoved =
false;
1469 query =
qgs_sqlite3_mprintf(
"DELETE FROM tag WHERE id=%d; DELETE FROM tagmap WHERE tag_id=%d",
id,
id );
1470 groupRemoved =
true;
1474 groupRemoved =
true;
1478 query =
qgs_sqlite3_mprintf( QStringLiteral(
"DELETE FROM %1 WHERE id=%d; DELETE FROM %2 WHERE %3=%d" ).arg(
1479 entityTableName( type ),
1480 tagmapTableName( type ),
1481 tagmapEntityIdFieldName( type )
1482 ).toLocal8Bit().data(),
id,
id );
1486 bool result =
false;
1487 if ( !runEmptyQuery( query ) )
1489 QgsDebugMsg( QStringLiteral(
"Could not delete entity!" ) );
1493 mCachedTags.clear();
1494 mCachedFavorites.clear();
1499 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1518 std::unique_ptr< QgsSymbol >
symbol( mSymbols.take(
name ) );
1527 std::unique_ptr< QgsAbstract3DSymbol >
symbol( m3dSymbols.take(
name ) );
1536 std::unique_ptr< QgsColorRamp > ramp( mColorRamps.take(
name ) );
1544 if ( !mTextFormats.contains(
name ) )
1547 mTextFormats.remove(
name );
1553 if ( !mLabelSettings.contains(
name ) )
1556 mLabelSettings.remove(
name );
1562 if ( !mLegendPatchShapes.contains(
name ) )
1565 mLegendPatchShapes.remove(
name );
1572 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to modify." ) );
1579 QgsDebugMsg(
"No matching entity for deleting in database: " +
name );
1582 const bool result =
remove( type,
id );
1585 mCachedTags[ type ].remove(
name );
1586 mCachedFavorites[ type ].remove(
name );
1615bool QgsStyle::runEmptyQuery(
const QString &query )
1620 char *zErr =
nullptr;
1621 int nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1623 if ( nErr != SQLITE_OK )
1626 sqlite3_free( zErr );
1629 return nErr == SQLITE_OK;
1640 QgsDebugMsg( QStringLiteral(
"Wrong entity value. cannot apply group" ) );
1644 query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET favorite=1 WHERE name='%q'" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
1645 name.toUtf8().constData() );
1649 const bool res = runEmptyQuery( query );
1659 mCachedFavorites[ type ].insert(
name,
true );
1676 QgsDebugMsg( QStringLiteral(
"Wrong entity value. cannot apply group" ) );
1680 query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET favorite=0 WHERE name='%q'" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
name.toUtf8().constData() );
1684 const bool res = runEmptyQuery( query );
1687 mCachedFavorites[ type ].insert(
name,
false );
1698 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to search" ) );
1699 return QStringList();
1708 return QStringList();
1711 item = entityTableName( type );
1716 item.toUtf8().constData(), qword.toUtf8().constData() );
1719 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1721 QSet< QString > symbols;
1722 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1728 query =
qgs_sqlite3_mprintf(
"SELECT id FROM tag WHERE name LIKE '%%%q%%'", qword.toUtf8().constData() );
1729 statement = mCurrentDB.
prepare( query, nErr );
1732 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1737 QString dummy = tagids.join( QLatin1String(
", " ) );
1738 query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT %1 FROM %2 WHERE tag_id IN (%q)" ).arg( tagmapEntityIdFieldName( type ),
1739 tagmapTableName( type ) ).toLocal8Bit().data(), dummy.toUtf8().constData() );
1741 statement = mCurrentDB.
prepare( query, nErr );
1743 QStringList symbolids;
1744 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1749 dummy = symbolids.join( QLatin1String(
", " ) );
1751 item.toUtf8().constData(), dummy.toUtf8().constData() );
1752 statement = mCurrentDB.
prepare( query, nErr );
1753 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1758 return QStringList( symbols.constBegin(), symbols.constEnd() );
1765 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to tag." ) );
1783 QgsDebugMsg( QStringLiteral(
"No such symbol for tagging in database: " ) +
symbol );
1788 const auto constTags =
tags;
1789 for (
const QString &t : constTags )
1792 if ( !
tag.isEmpty() )
1804 QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"INSERT INTO %1 VALUES (%d,%d)" ).arg( tagmapTableName( type ) ).toLocal8Bit().data(), tagid, symbolid );
1806 char *zErr =
nullptr;
1808 nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1812 sqlite3_free( zErr );
1818 clearCachedTags( type,
symbol );
1828 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for detagging." ) );
1843 if ( symbolid == 0 )
1848 const auto constTags =
tags;
1849 for (
const QString &
tag : constTags )
1854 statement2 = mCurrentDB.
prepare( query, nErr );
1857 if ( nErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1859 tagid = sqlite3_column_int( statement2.get(), 0 );
1865 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 );
1866 runEmptyQuery( query );
1870 clearCachedTags( type,
symbol );
1883 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for detagging." ) );
1898 if ( symbolid == 0 )
1904 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"DELETE FROM %1 WHERE %2=%d" ).arg( tagmapTableName( type ),
1905 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1906 runEmptyQuery( query );
1908 clearCachedTags( type,
symbol );
1923 return QStringList();
1926 if ( mCachedTags[ type ].contains(
symbol ) )
1927 return mCachedTags[ type ].value(
symbol );
1933 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
1934 return QStringList();
1939 return QStringList();
1942 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT tag_id FROM %1 WHERE %2=%d" ).arg( tagmapTableName( type ),
1943 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1946 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1948 QStringList tagList;
1949 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1951 QString subquery =
qgs_sqlite3_mprintf(
"SELECT name FROM tag WHERE id=%d", sqlite3_column_int( statement.get(), 0 ) );
1955 statement2 = mCurrentDB.
prepare( subquery, pErr );
1956 if ( pErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1963 mCachedTags[ type ].insert(
symbol, tagList );
1972 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
1983 if ( mCachedFavorites[ type ].contains(
name ) )
1984 return mCachedFavorites[ type ].value(
name );
1988 const QStringList names =
allNames( type );
1989 if ( !names.contains(
name ) )
1995 for (
const QString &n : names )
1997 const bool isFav = favorites.contains( n );
2001 mCachedFavorites[ type ].insert( n, isFav );
2010 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
2037 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT tag_id FROM %1 WHERE tag_id=%d AND %2=%d" ).arg( tagmapTableName( type ),
2038 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), tagid, symbolid );
2041 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2043 return ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW );
2055 statement = mCurrentDB.
prepare( query, nError );
2058 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2066int QgsStyle::getId(
const QString &table,
const QString &name )
2068 QString lowerName(
name.toLower() );
2069 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE LOWER(name)='%q'", table.toUtf8().constData(), lowerName.toUtf8().constData() );
2072 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2075 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2077 id = sqlite3_column_int( statement.get(), 0 );
2082 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE name='%q'", table.toUtf8().constData(),
name.toUtf8().constData() );
2085 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2086 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2088 id = sqlite3_column_int( statement.get(), 0 );
2095QString QgsStyle::getName(
const QString &table,
int id )
const
2097 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM %q WHERE id='%q'", table.toUtf8().constData(), QString::number(
id ).toUtf8().constData() );
2100 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2103 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2113 return getId( QStringLiteral(
"symbol" ),
name );
2118 return getId( entityTableName( type ),
name );
2123 return getId( QStringLiteral(
"colorramp" ),
name );
2128 return mTextFormats.value(
name );
2133 return mTextFormats.count();
2138 return mTextFormats.keys();
2143 return getId( QStringLiteral(
"textformat" ),
name );
2148 return mLabelSettings.value(
name );
2153 return mLegendPatchShapes.value(
name );
2158 return mLegendPatchShapes.count();
2163 if ( !mLegendPatchShapes.contains(
name ) )
2166 return mLegendPatchShapes.value(
name ).symbolType();
2171 return m3dSymbols.contains(
name ) ? m3dSymbols.value(
name )->clone() :
nullptr;
2176 return m3dSymbols.count();
2181 if ( !m3dSymbols.contains(
name ) )
2182 return QList<Qgis::GeometryType>();
2184 return m3dSymbols.value(
name )->compatibleGeometryTypes();
2189 if ( !mLabelSettings.contains(
name ) )
2190 return Qgis::GeometryType::Unknown;
2192 return mLabelSettings.value(
name ).layerType;
2197 return mLabelSettings.count();
2202 return mLabelSettings.keys();
2207 return getId( QStringLiteral(
"labelsettings" ),
name );
2212 return mLegendPatchShapes.keys();
2220 return mPatchMarkerSymbol.get();
2223 return mPatchLineSymbol.get();
2226 return mPatchFillSymbol.get();
2236 return getId( QStringLiteral(
"tag" ),
name );
2241 return getId( QStringLiteral(
"smartgroup" ),
name );
2272 return QStringList();
2278 conditions.values( QStringLiteral(
"!tag" ) ),
2279 conditions.values( QStringLiteral(
"name" ) ),
2280 conditions.values( QStringLiteral(
"!name" ) ) );
2283int QgsStyle::addSmartgroup(
const QString &name,
const QString &op,
const QStringList &matchTag,
const QStringList &noMatchTag,
const QStringList &matchName,
const QStringList &noMatchName )
2285 QDomDocument doc( QStringLiteral(
"dummy" ) );
2286 QDomElement smartEl = doc.createElement( QStringLiteral(
"smartgroup" ) );
2287 smartEl.setAttribute( QStringLiteral(
"name" ),
name );
2288 smartEl.setAttribute( QStringLiteral(
"operator" ), op );
2290 auto addCondition = [&doc, &smartEl](
const QString & constraint,
const QStringList & parameters )
2292 for (
const QString ¶m : parameters )
2294 QDomElement condEl = doc.createElement( QStringLiteral(
"condition" ) );
2295 condEl.setAttribute( QStringLiteral(
"constraint" ), constraint );
2296 condEl.setAttribute( QStringLiteral(
"param" ), param );
2297 smartEl.appendChild( condEl );
2300 addCondition( QStringLiteral(
"tag" ), matchTag );
2301 addCondition( QStringLiteral(
"!tag" ), noMatchTag );
2302 addCondition( QStringLiteral(
"name" ), matchName );
2303 addCondition( QStringLiteral(
"!name" ), noMatchName );
2305 QByteArray xmlArray;
2306 QTextStream stream( &xmlArray );
2307#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2308 stream.setCodec(
"UTF-8" );
2310 smartEl.save( stream, 4 );
2312 name.toUtf8().constData(), xmlArray.constData() );
2314 if ( runEmptyQuery( query ) )
2317 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
2320 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
2324 QgsDebugMsg( QStringLiteral(
"Couldn't add the smart group into the database!" ) );
2333 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2342 statement = mCurrentDB.
prepare( query, nError );
2345 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2348 groupNames.insert( sqlite3_column_int( statement.get(),
SmartgroupId ), group );
2358 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2359 return QStringList();
2367 statement = mCurrentDB.
prepare( query, nError );
2370 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2380 QStringList symbols;
2385 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2386 if ( !( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW ) )
2388 return QStringList();
2394 if ( !doc.setContent( xmlstr ) )
2396 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2398 QDomElement smartEl = doc.documentElement();
2399 QString op = smartEl.attribute( QStringLiteral(
"operator" ) );
2400 QDomNodeList conditionNodes = smartEl.childNodes();
2402 bool firstSet =
true;
2403 for (
int i = 0; i < conditionNodes.count(); i++ )
2405 QDomElement condEl = conditionNodes.at( i ).toElement();
2406 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2407 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2409 QStringList resultNames;
2411 if ( constraint == QLatin1String(
"tag" ) )
2415 else if ( constraint == QLatin1String(
"name" ) )
2417 resultNames =
allNames( type ).filter( param, Qt::CaseInsensitive );
2419 else if ( constraint == QLatin1String(
"!tag" ) )
2423 for (
const QString &
name : unwanted )
2425 resultNames.removeAll(
name );
2428 else if ( constraint == QLatin1String(
"!name" ) )
2430 const QStringList all =
allNames( type );
2431 for (
const QString &
str : all )
2433 if ( !
str.contains( param, Qt::CaseInsensitive ) )
2441 symbols = resultNames;
2446 if ( op == QLatin1String(
"OR" ) )
2448 symbols << resultNames;
2450 else if ( op == QLatin1String(
"AND" ) )
2452 QStringList dummy = symbols;
2454 for (
const QString &result : std::as_const( resultNames ) )
2456 if ( dummy.contains( result ) )
2465 const QSet< QString > uniqueSet( symbols.constBegin(), symbols.constEnd() );
2466 QStringList unique( uniqueSet.begin(), uniqueSet.end() );
2467 std::sort( unique.begin(), unique.end() );
2475 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2485 statement = mCurrentDB.
prepare( query, nError );
2486 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2490 if ( !doc.setContent( xmlstr ) )
2492 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2495 QDomElement smartEl = doc.documentElement();
2496 QDomNodeList conditionNodes = smartEl.childNodes();
2498 for (
int i = 0; i < conditionNodes.count(); i++ )
2500 QDomElement condEl = conditionNodes.at( i ).toElement();
2501 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2502 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2504 condition.insert( constraint, param );
2515 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2525 statement = mCurrentDB.
prepare( query, nError );
2526 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2530 if ( !doc.setContent( xmlstr ) )
2532 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2534 QDomElement smartEl = doc.documentElement();
2535 op = smartEl.attribute( QStringLiteral(
"operator" ) );
2543 if ( filename.isEmpty() )
2545 QgsDebugMsg( QStringLiteral(
"Invalid filename for style export." ) );
2549 QDomDocument doc( QStringLiteral(
"qgis_style" ) );
2550 QDomElement root = doc.createElement( QStringLiteral(
"qgis_style" ) );
2552 doc.appendChild( root );
2562 QDomNodeList symbolsList = symbolsElem.elementsByTagName( QStringLiteral(
"symbol" ) );
2563 int nbSymbols = symbolsList.count();
2564 for (
int i = 0; i < nbSymbols; ++i )
2566 QDomElement
symbol = symbolsList.at( i ).toElement();
2567 QString
name =
symbol.attribute( QStringLiteral(
"name" ) );
2569 if (
tags.count() > 0 )
2571 symbol.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2573 if ( favoriteSymbols.contains(
name ) )
2575 symbol.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2580 QDomElement rampsElem = doc.createElement( QStringLiteral(
"colorramps" ) );
2581 for ( QMap<QString, QgsColorRamp *>::const_iterator itr = mColorRamps.constBegin(); itr != mColorRamps.constEnd(); ++itr )
2585 if (
tags.count() > 0 )
2587 rampEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2589 if ( favoriteColorramps.contains( itr.key() ) )
2591 rampEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2593 rampsElem.appendChild( rampEl );
2597 QDomElement textFormatsElem = doc.createElement( QStringLiteral(
"textformats" ) );
2598 for (
auto it = mTextFormats.constBegin(); it != mTextFormats.constEnd(); ++it )
2600 QDomElement textFormatEl = doc.createElement( QStringLiteral(
"textformat" ) );
2601 textFormatEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2603 textFormatEl.appendChild( textStyleEl );
2605 if (
tags.count() > 0 )
2607 textFormatEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2609 if ( favoriteTextFormats.contains( it.key() ) )
2611 textFormatEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2613 textFormatsElem.appendChild( textFormatEl );
2617 QDomElement labelSettingsElem = doc.createElement( QStringLiteral(
"labelsettings" ) );
2618 for (
auto it = mLabelSettings.constBegin(); it != mLabelSettings.constEnd(); ++it )
2620 QDomElement labelSettingsEl = doc.createElement( QStringLiteral(
"labelsetting" ) );
2621 labelSettingsEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2623 labelSettingsEl.appendChild( defEl );
2625 if (
tags.count() > 0 )
2627 labelSettingsEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2629 if ( favoriteTextFormats.contains( it.key() ) )
2631 labelSettingsEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2633 labelSettingsElem.appendChild( labelSettingsEl );
2637 QDomElement legendPatchShapesElem = doc.createElement( QStringLiteral(
"legendpatchshapes" ) );
2638 for (
auto it = mLegendPatchShapes.constBegin(); it != mLegendPatchShapes.constEnd(); ++it )
2640 QDomElement legendPatchShapeEl = doc.createElement( QStringLiteral(
"legendpatchshape" ) );
2641 legendPatchShapeEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2642 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2644 legendPatchShapeEl.appendChild( defEl );
2646 if (
tags.count() > 0 )
2648 legendPatchShapeEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2650 if ( favoriteLegendShapes.contains( it.key() ) )
2652 legendPatchShapeEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2654 legendPatchShapesElem.appendChild( legendPatchShapeEl );
2658 QDomElement symbols3DElem = doc.createElement( QStringLiteral(
"symbols3d" ) );
2659 for (
auto it = m3dSymbols.constBegin(); it != m3dSymbols.constEnd(); ++it )
2661 QDomElement symbolEl = doc.createElement( QStringLiteral(
"symbol3d" ) );
2662 symbolEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2663 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2664 defEl.setAttribute( QStringLiteral(
"type" ), it.value()->type() );
2666 symbolEl.appendChild( defEl );
2668 if (
tags.count() > 0 )
2670 symbolEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2672 if ( favorite3DSymbols.contains( it.key() ) )
2674 symbolEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2676 symbols3DElem.appendChild( symbolEl );
2679 root.appendChild( symbolsElem );
2680 root.appendChild( rampsElem );
2681 root.appendChild( textFormatsElem );
2682 root.appendChild( labelSettingsElem );
2683 root.appendChild( legendPatchShapesElem );
2684 root.appendChild( symbols3DElem );
2687 QFile f( filename );
2688 if ( !f.open( QFile::WriteOnly | QIODevice::Truncate ) )
2690 mErrorString =
"Couldn't open file for writing: " + filename;
2694 QTextStream ts( &f );
2695#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
2696 ts.setCodec(
"UTF-8" );
2711 mErrorString = QString();
2712 QDomDocument doc( QStringLiteral(
"style" ) );
2713 QFile f( filename );
2714 if ( !f.open( QFile::ReadOnly ) )
2716 mErrorString = QStringLiteral(
"Unable to open the specified file" );
2717 QgsDebugMsg( QStringLiteral(
"Error opening the style XML file." ) );
2721 if ( !doc.setContent( &f ) )
2723 mErrorString = QStringLiteral(
"Unable to understand the style file: %1" ).arg( filename );
2724 QgsDebugMsg( QStringLiteral(
"XML Parsing error" ) );
2730 QDomElement docEl = doc.documentElement();
2731 if ( docEl.tagName() != QLatin1String(
"qgis_style" ) )
2733 mErrorString =
"Incorrect root tag in style: " + docEl.tagName();
2737 const QString version = docEl.attribute( QStringLiteral(
"version" ) );
2738 if ( version != QLatin1String(
STYLE_CURRENT_VERSION ) && version != QLatin1String(
"0" ) && version != QLatin1String(
"1" ) )
2740 mErrorString =
"Unknown style file version: " + version;
2746 QDomElement symbolsElement = docEl.firstChildElement( QStringLiteral(
"symbols" ) );
2747 QDomElement e = symbolsElement.firstChildElement();
2751 runEmptyQuery( query );
2756 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2758 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2759 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2765 if ( e.tagName() == QLatin1String(
"symbol" ) )
2767 QString
name = e.attribute( QStringLiteral(
"name" ) );
2769 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2771 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2773 bool favorite =
false;
2774 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2801 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
2808 QDomElement rampsElement = docEl.firstChildElement( QStringLiteral(
"colorramps" ) );
2809 e = rampsElement.firstChildElement();
2810 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2812 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2813 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2819 if ( e.tagName() == QLatin1String(
"colorramp" ) )
2821 QString
name = e.attribute( QStringLiteral(
"name" ) );
2823 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2825 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2827 bool favorite =
false;
2828 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2852 if ( qobject_cast< QGuiApplication * >( QCoreApplication::instance() ) )
2856 const QDomElement textFormatElement = docEl.firstChildElement( QStringLiteral(
"textformats" ) );
2857 e = textFormatElement.firstChildElement();
2858 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2860 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2861 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2867 if ( e.tagName() == QLatin1String(
"textformat" ) )
2869 QString
name = e.attribute( QStringLiteral(
"name" ) );
2871 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2873 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2875 bool favorite =
false;
2876 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2882 const QDomElement styleElem = e.firstChildElement();
2900 const QDomElement labelSettingsElement = docEl.firstChildElement( QStringLiteral(
"labelsettings" ) );
2901 e = labelSettingsElement.firstChildElement();
2902 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2904 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2905 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2911 if ( e.tagName() == QLatin1String(
"labelsetting" ) )
2913 QString
name = e.attribute( QStringLiteral(
"name" ) );
2915 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2917 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2919 bool favorite =
false;
2920 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2926 const QDomElement styleElem = e.firstChildElement();
2945 const QDomElement legendPatchShapesElement = docEl.firstChildElement( QStringLiteral(
"legendpatchshapes" ) );
2946 e = legendPatchShapesElement.firstChildElement();
2947 for ( ; !e.isNull(); e = e.nextSiblingElement() )
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();
2989 const QDomElement symbols3DElement = docEl.firstChildElement( QStringLiteral(
"symbols3d" ) );
2990 e = symbols3DElement.firstChildElement();
2991 for ( ; !e.isNull(); e = e.nextSiblingElement() )
2993 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2994 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
3000 if ( e.tagName() == QLatin1String(
"symbol3d" ) )
3002 QString
name = e.attribute( QStringLiteral(
"name" ) );
3004 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
3006 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
3008 bool favorite =
false;
3009 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
3014 const QDomElement symbolElem = e.firstChildElement();
3015 const QString type = symbolElem.attribute( QStringLiteral(
"type" ) );
3036 runEmptyQuery( query );
3043 QFileInfo fileInfo( path );
3045 if ( fileInfo.suffix().compare( QLatin1String(
"xml" ), Qt::CaseInsensitive ) != 0 )
3049 if ( !QFile::exists( path ) )
3052 QFile inputFile( path );
3053 if ( !inputFile.open( QIODevice::ReadOnly ) )
3056 QTextStream stream( &inputFile );
3057 const QString line = stream.readLine();
3058 return line == QLatin1String(
"<!DOCTYPE qgis_style>" );
3073 mReadOnly = readOnly;
3076bool QgsStyle::updateSymbol( StyleEntity type,
const QString &name )
3078 QDomDocument doc( QStringLiteral(
"dummy" ) );
3080 QByteArray xmlArray;
3081 QTextStream stream( &xmlArray );
3082#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
3083 stream.setCodec(
"UTF-8" );
3095 QgsDebugMsg( QStringLiteral(
"Update request received for unavailable symbol" ) );
3100 if ( symEl.isNull() )
3102 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
3105 symEl.save( stream, 4 );
3107 xmlArray.constData(),
name.toUtf8().constData() );
3116 QgsDebugMsg( QStringLiteral(
"Update request received for unavailable symbol" ) );
3120 symEl = doc.createElement( QStringLiteral(
"symbol" ) );
3121 symEl.setAttribute( QStringLiteral(
"type" ), m3dSymbols.value(
name )->type() );
3123 if ( symEl.isNull() )
3125 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
3128 symEl.save( stream, 4 );
3130 xmlArray.constData(),
name.toUtf8().constData() );
3138 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable color ramp." ) );
3144 if ( symEl.isNull() )
3146 QgsDebugMsg( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
3149 symEl.save( stream, 4 );
3151 xmlArray.constData(),
name.toUtf8().constData() );
3159 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable text format." ) );
3165 if ( symEl.isNull() )
3167 QgsDebugMsg( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
3170 symEl.save( stream, 4 );
3172 xmlArray.constData(),
name.toUtf8().constData() );
3180 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable label settings." ) );
3186 if ( symEl.isNull() )
3188 QgsDebugMsg( QStringLiteral(
"Couldn't convert label settings to valid XML!" ) );
3191 symEl.save( stream, 4 );
3193 xmlArray.constData(),
name.toUtf8().constData() );
3201 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable legend patch shape." ) );
3206 symEl = doc.createElement( QStringLiteral(
"shape" ) );
3208 symEl.save( stream, 4 );
3210 xmlArray.constData(),
name.toUtf8().constData() );
3217 QgsDebugMsg( QStringLiteral(
"Updating the unsupported StyleEntity" ) );
3223 if ( !runEmptyQuery( query ) )
3225 QgsDebugMsg( QStringLiteral(
"Couldn't update symbol into the database!" ) );
3261 mCachedTags[ type ].remove(
name );
3264bool QgsStyle::createStyleMetadataTableIfNeeded()
3267 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='stylemetadata'" );
3270 statement = mCurrentDB.
prepare( query, rc );
3272 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
3276 "id INTEGER PRIMARY KEY,"\
3279 runEmptyQuery( query );
3281 runEmptyQuery( query );
3290void QgsStyle::upgradeIfRequired()
3294 if ( !createStyleMetadataTableIfNeeded() )
3296 const QString query =
qgs_sqlite3_mprintf(
"SELECT value FROM stylemetadata WHERE key='version'" );
3299 if ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
3311 runEmptyQuery( query );
3321 return QStringLiteral(
"symbol" );
3324 return QStringLiteral(
"colorramp" );
3327 return QStringLiteral(
"textformat" );
3330 return QStringLiteral(
"labelsettings" );
3333 return QStringLiteral(
"legendpatchshapes" );
3336 return QStringLiteral(
"symbol3d" );
3339 return QStringLiteral(
"tag" );
3342 return QStringLiteral(
"smartgroup" );
3352 return QStringLiteral(
"tagmap" );
3355 return QStringLiteral(
"ctagmap" );
3358 return QStringLiteral(
"tftagmap" );
3361 return QStringLiteral(
"lstagmap" );
3364 return QStringLiteral(
"lpstagmap" );
3367 return QStringLiteral(
"symbol3dtagmap" );
3381 return QStringLiteral(
"symbol_id" );
3384 return QStringLiteral(
"colorramp_id" );
3387 return QStringLiteral(
"textformat_id" );
3390 return QStringLiteral(
"labelsettings_id" );
3393 return QStringLiteral(
"legendpatchshape_id" );
3396 return QStringLiteral(
"symbol3d_id" );
@ ScaleArea
Calculate scale by the area.
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
static int versionInt()
Version number used for comparing versions using the "Check QGIS Version" function.
QStringList symbolTypes() const
Returns a list of all available symbol types.
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.
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...
The class is used as a container of context for various read/write operations on other objects.
Scoped object for logging of the runtime for a single operation or group of operations.
This class is a composition of two QSettings instances:
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
A color ramp entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
An interface for entities which can be placed in a QgsStyle database.
virtual QgsStyle::StyleEntity type() const =0
Returns the type of style entity.
A label settings entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A legend patch shape entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A 3d symbol entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A symbol entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
A text format entity for QgsStyle databases.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
bool addEntity(const QString &name, const QgsStyleEntityInterface *entity, bool update=false)
Adds an entity to the style, with the specified name.
bool saveColorRamp(const QString &name, QgsColorRamp *ramp, bool favorite, const QStringList &tags)
Adds the colorramp to the database.
void 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.
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.
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.
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 (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.
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 ...
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()
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.
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.
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.
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.
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,...
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...
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 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 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.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
Qgis::SymbolType type() const
Returns the symbol's type.
Container for all settings relating to text rendering.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
bool isValid() const
Returns true if the format is valid.
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.
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