35 #include <QDomDocument> 36 #include <QDomElement> 38 #include <QDomNodeList> 40 #include <QTextStream> 46 #define STYLE_CURRENT_VERSION "2" 71 QgsStyle *QgsStyle::sDefaultStyle =
nullptr;
77 simpleMarker->setStrokeWidth( 0.4 );
78 mPatchMarkerSymbol = qgis::make_unique< QgsMarkerSymbol >(
QgsSymbolLayerList() << simpleMarker.release() );
80 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine = qgis::make_unique< QgsSimpleLineSymbolLayer >( QColor( 84, 176, 74 ), 0.6 );
81 mPatchLineSymbol = qgis::make_unique< QgsLineSymbol >(
QgsSymbolLayerList() << simpleLine.release() );
83 std::unique_ptr< QgsGradientFillSymbolLayer > gradientFill = qgis::make_unique< QgsGradientFillSymbolLayer >( QColor( 66, 150, 63 ), QColor( 84, 176, 74 ) );
84 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleOutline = qgis::make_unique< QgsSimpleLineSymbolLayer >( QColor( 56, 128, 54 ), 0.26 );
85 mPatchFillSymbol = qgis::make_unique< QgsFillSymbol >(
QgsSymbolLayerList() << gradientFill.release() << simpleOutline.release() );
95 switch ( entity->
type() )
98 if ( !static_cast< const QgsStyleSymbolEntity * >( entity )->symbol() )
100 return addSymbol( name, static_cast< const QgsStyleSymbolEntity * >( entity )->
symbol()->clone(), update );
103 if ( !static_cast< const QgsStyleColorRampEntity * >( entity )->ramp() )
105 return addColorRamp( name, static_cast< const QgsStyleColorRampEntity * >( entity )->ramp()->clone(), update );
108 return addTextFormat( name, static_cast< const QgsStyleTextFormatEntity * >( entity )->format(), update );
111 return addLabelSettings( name, static_cast< const QgsStyleLabelSettingsEntity * >( entity )->settings(), update );
114 return addLegendPatchShape( name, static_cast< const QgsStyleLegendPatchShapeEntity * >( entity )->shape(), update );
117 return addSymbol3D( name, static_cast< const QgsStyleSymbol3DEntity * >( entity )->
symbol()->clone(), update );
129 if ( !sDefaultStyle )
135 if ( !QFile::exists( styleFilename ) )
147 if ( sDefaultStyle->
load( styleFilename ) )
149 sDefaultStyle->upgradeIfRequired();
153 return sDefaultStyle;
158 delete sDefaultStyle;
159 sDefaultStyle =
nullptr;
164 qDeleteAll( mSymbols );
165 qDeleteAll( mColorRamps );
166 qDeleteAll( m3dSymbols );
170 mTextFormats.clear();
174 mCachedFavorites.clear();
179 if ( !symbol || name.isEmpty() )
183 if ( mSymbols.contains( name ) )
186 delete mSymbols.value( name );
187 mSymbols.insert( name, symbol );
193 mSymbols.insert( name, symbol );
195 saveSymbol( name, symbol,
false, QStringList() );
204 QDomDocument doc( QStringLiteral(
"dummy" ) );
206 if ( symEl.isNull() )
208 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
213 QTextStream stream( &xmlArray );
214 stream.setCodec(
"UTF-8" );
215 symEl.save( stream, 4 );
217 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
219 if ( !runEmptyQuery( query ) )
221 QgsDebugMsg( QStringLiteral(
"Couldn't insert symbol into the database!" ) );
225 mCachedFavorites[
SymbolEntity ].insert( name, favorite );
272 return symbol ? symbol->
clone() :
nullptr;
277 return mSymbols.value( name );
282 return mSymbols.count();
287 return mSymbols.keys();
293 if ( !colorRamp || name.isEmpty() )
297 if ( mColorRamps.contains( name ) )
300 delete mColorRamps.value( name );
301 mColorRamps.insert( name, colorRamp );
307 mColorRamps.insert( name, colorRamp );
318 if ( mTextFormats.contains( name ) )
321 mTextFormats.remove( name );
322 mTextFormats.insert( name, format );
328 mTextFormats.insert( name, format );
339 if ( mLabelSettings.contains( name ) )
342 mLabelSettings.remove( name );
343 mLabelSettings.insert( name, settings );
349 mLabelSettings.insert( name, settings );
360 if ( mLegendPatchShapes.contains( name ) )
363 mLegendPatchShapes.remove( name );
364 mLegendPatchShapes.insert( name, shape );
370 mLegendPatchShapes.insert( name, shape );
381 if ( m3dSymbols.contains( name ) )
384 delete m3dSymbols.take( name );
385 m3dSymbols.insert( name, symbol );
391 m3dSymbols.insert( name, symbol );
402 QDomDocument doc( QStringLiteral(
"dummy" ) );
405 if ( rampEl.isNull() )
407 QgsDebugMsg( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
412 QTextStream stream( &xmlArray );
413 stream.setCodec(
"UTF-8" );
414 rampEl.save( stream, 4 );
415 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO colorramp VALUES (NULL, '%q', '%q', %d);",
416 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
417 if ( !runEmptyQuery( query ) )
419 QgsDebugMsg( QStringLiteral(
"Couldn't insert colorramp into the database!" ) );
441 return ramp ? ramp->
clone() :
nullptr;
446 return mColorRamps.value( name );
451 return mColorRamps.count();
456 return mColorRamps.keys();
459 void QgsStyle::handleDeferred3DSymbolCreation()
461 for (
auto it = mDeferred3DsymbolElements.constBegin(); it != mDeferred3DsymbolElements.constEnd(); ++it )
463 const QString symbolType = it.value().attribute( QStringLiteral(
"type" ) );
473 QgsDebugMsg(
"Cannot open 3d symbol " + it.key() );
477 mDeferred3DsymbolElements.clear();
480 bool QgsStyle::openDatabase(
const QString &filename )
482 int rc = mCurrentDB.
open( filename );
485 mErrorString = QStringLiteral(
"Couldn't open the style database: %1" ).arg( mCurrentDB.
errorMessage() );
494 mErrorString.clear();
495 if ( !openDatabase( filename ) )
497 mErrorString = QStringLiteral(
"Unable to create database" );
509 mErrorString.clear();
510 if ( !openDatabase( QStringLiteral(
":memory:" ) ) )
512 mErrorString = QStringLiteral(
"Unable to create temporary memory database" );
525 "id INTEGER PRIMARY KEY,"\
528 "favorite INTEGER);"\
529 "CREATE TABLE colorramp("\
530 "id INTEGER PRIMARY KEY,"\
533 "favorite INTEGER);"\
534 "CREATE TABLE textformat("\
535 "id INTEGER PRIMARY KEY,"\
538 "favorite INTEGER);"\
539 "CREATE TABLE labelsettings("\
540 "id INTEGER PRIMARY KEY,"\
543 "favorite INTEGER);"\
544 "CREATE TABLE legendpatchshapes("\
545 "id INTEGER PRIMARY KEY,"\
548 "favorite INTEGER);"\
549 "CREATE TABLE symbol3d("\
550 "id INTEGER PRIMARY KEY,"\
553 "favorite INTEGER);"\
555 "id INTEGER PRIMARY KEY,"\
557 "CREATE TABLE tagmap("\
558 "tag_id INTEGER NOT NULL,"\
559 "symbol_id INTEGER);"\
560 "CREATE TABLE ctagmap("\
561 "tag_id INTEGER NOT NULL,"\
562 "colorramp_id INTEGER);"\
563 "CREATE TABLE tftagmap("\
564 "tag_id INTEGER NOT NULL,"\
565 "textformat_id INTEGER);"\
566 "CREATE TABLE lstagmap("\
567 "tag_id INTEGER NOT NULL,"\
568 "labelsettings_id INTEGER);"\
569 "CREATE TABLE lpstagmap("\
570 "tag_id INTEGER NOT NULL,"\
571 "legendpatchshape_id INTEGER);"\
572 "CREATE TABLE symbol3dtagmap("\
573 "tag_id INTEGER NOT NULL,"\
574 "symbol3d_id INTEGER);"\
575 "CREATE TABLE smartgroup("\
576 "id INTEGER PRIMARY KEY,"\
579 runEmptyQuery( query );
584 mErrorString.clear();
587 if ( !openDatabase( filename ) )
589 mErrorString = QStringLiteral(
"Unable to open database file specified" );
595 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='textformat'" );
598 statement = mCurrentDB.
prepare( query, rc );
599 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
602 "id INTEGER PRIMARY KEY,"\
605 "favorite INTEGER);"\
606 "CREATE TABLE tftagmap("\
607 "tag_id INTEGER NOT NULL,"\
608 "textformat_id INTEGER);" );
609 runEmptyQuery( query );
612 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='labelsettings'" );
613 statement = mCurrentDB.
prepare( query, rc );
614 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
617 "id INTEGER PRIMARY KEY,"\
620 "favorite INTEGER);"\
621 "CREATE TABLE lstagmap("\
622 "tag_id INTEGER NOT NULL,"\
623 "labelsettings_id INTEGER);" );
624 runEmptyQuery( query );
627 query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='legendpatchshapes'" );
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 lpstagmap("\
637 "tag_id INTEGER NOT NULL,"\
638 "legendpatchshape_id INTEGER);" );
639 runEmptyQuery( query );
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 symbol3dtagmap("\
652 "tag_id INTEGER NOT NULL,"\
653 "symbol3d_id INTEGER);" );
654 runEmptyQuery( query );
659 "UPDATE colorramp SET favorite=0 WHERE favorite IS NULL;" 660 "UPDATE textformat SET favorite=0 WHERE favorite IS NULL;" 661 "UPDATE labelsettings SET favorite=0 WHERE favorite IS NULL;" 662 "UPDATE legendpatchshapes SET favorite=0 WHERE favorite IS NULL;" 663 "UPDATE symbol3d SET favorite=0 WHERE favorite IS NULL;" 665 runEmptyQuery( query );
671 statement = mCurrentDB.
prepare( query, rc );
673 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
679 if ( !doc.setContent( xmlstring ) )
685 QDomElement symElement = doc.documentElement();
688 mSymbols.insert( symbolName, symbol );
695 statement = mCurrentDB.
prepare( query, rc );
696 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
702 if ( !doc.setContent( xmlstring ) )
707 QDomElement rampElement = doc.documentElement();
710 mColorRamps.insert( rampName, ramp );
717 statement = mCurrentDB.
prepare( query, rc );
718 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
724 if ( !doc.setContent( xmlstring ) )
726 QgsDebugMsg(
"Cannot open text format " + formatName );
729 QDomElement formatElement = doc.documentElement();
732 mTextFormats.insert( formatName, format );
739 statement = mCurrentDB.
prepare( query, rc );
740 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
746 if ( !doc.setContent( xmlstring ) )
748 QgsDebugMsg(
"Cannot open label settings " + settingsName );
751 QDomElement settingsElement = doc.documentElement();
754 mLabelSettings.insert( settingsName, settings );
761 statement = mCurrentDB.
prepare( query, rc );
762 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
768 if ( !doc.setContent( xmlstring ) )
770 QgsDebugMsg(
"Cannot open legend patch shape " + settingsName );
773 QDomElement settingsElement = doc.documentElement();
776 mLegendPatchShapes.insert( settingsName, shape );
783 statement = mCurrentDB.
prepare( query, rc );
787 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
793 if ( !doc.setContent( xmlstring ) )
795 QgsDebugMsg(
"Cannot open 3d symbol " + settingsName );
798 QDomElement settingsElement = doc.documentElement();
800 if ( !registry3dPopulated )
802 mDeferred3DsymbolElements.insert( settingsName, settingsElement );
806 const QString symbolType = settingsElement.attribute( QStringLiteral(
"type" ) );
811 m3dSymbols.insert( settingsName, symbol.release() );
815 QgsDebugMsg(
"Cannot open 3d symbol " + settingsName );
822 mFileName = filename;
830 mErrorString.clear();
832 if ( filename.isEmpty() )
833 filename = mFileName;
838 QDomDocument doc(
"qgis_style" );
839 QDomElement root = doc.createElement(
"qgis_style" );
841 doc.appendChild( root );
845 QDomElement rampsElem = doc.createElement(
"colorramps" );
848 for ( QMap<QString, QgsColorRamp *>::iterator itr = mColorRamps.begin(); itr != mColorRamps.end(); ++itr )
851 rampsElem.appendChild( rampEl );
854 root.appendChild( symbolsElem );
855 root.appendChild( rampsElem );
859 if ( !f.open( QFile::WriteOnly ) )
861 mErrorString =
"Couldn't open file for writing: " + filename;
864 QTextStream ts( &f );
865 ts.setCodec(
"UTF-8" );
870 mFileName = filename;
876 if ( mSymbols.contains( newName ) )
878 QgsDebugMsg( QStringLiteral(
"Symbol of new name already exists" ) );
886 mSymbols.insert( newName, symbol );
890 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to tag." ) );
897 QgsDebugMsg( QStringLiteral(
"No such symbol for tagging in database: " ) + oldName );
916 if ( mColorRamps.contains( newName ) )
918 QgsDebugMsg( QStringLiteral(
"Color ramp of new name already exists." ) );
926 mColorRamps.insert( newName, ramp );
932 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM colorramp WHERE name='%q'", oldName.toUtf8().constData() );
934 statement = mCurrentDB.
prepare( query, nErr );
935 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
937 rampid = sqlite3_column_int( statement.get(), 0 );
952 QDomDocument doc( QStringLiteral(
"dummy" ) );
955 if ( formatElem.isNull() )
957 QgsDebugMsg( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
962 QTextStream stream( &xmlArray );
963 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 stream.setCodec(
"UTF-8" );
1038 settingsElem.save( stream, 4 );
1039 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO labelsettings VALUES (NULL, '%q', '%q', %d);",
1040 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1041 if ( !runEmptyQuery( query ) )
1043 QgsDebugMsg( QStringLiteral(
"Couldn't insert label settings into the database!" ) );
1064 if ( mLabelSettings.contains( newName ) )
1066 QgsDebugMsg( QStringLiteral(
"Label settings of new name already exists." ) );
1070 if ( !mLabelSettings.contains( oldName ) )
1074 mLabelSettings.insert( newName, settings );
1080 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM labelsettings WHERE name='%q'", oldName.toUtf8().constData() );
1082 statement = mCurrentDB.
prepare( query, nErr );
1083 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1085 labelSettingsId = sqlite3_column_int( statement.get(), 0 );
1100 QDomDocument doc( QStringLiteral(
"dummy" ) );
1101 QDomElement shapeElem = doc.createElement( QStringLiteral(
"shape" ) );
1104 QByteArray xmlArray;
1105 QTextStream stream( &xmlArray );
1106 stream.setCodec(
"UTF-8" );
1107 shapeElem.save( stream, 4 );
1108 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO legendpatchshapes VALUES (NULL, '%q', '%q', %d);",
1109 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1110 if ( !runEmptyQuery( query ) )
1112 QgsDebugMsg( QStringLiteral(
"Couldn't insert legend patch shape into the database!" ) );
1127 if ( mLegendPatchShapes.contains( newName ) )
1129 QgsDebugMsg( QStringLiteral(
"Legend patch shape of new name already exists." ) );
1133 if ( !mLegendPatchShapes.contains( oldName ) )
1137 mLegendPatchShapes.insert( newName, shape );
1143 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM legendpatchshapes WHERE name='%q'", oldName.toUtf8().constData() );
1145 statement = mCurrentDB.
prepare( query, nErr );
1146 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1148 labelSettingsId = sqlite3_column_int( statement.get(), 0 );
1164 if ( mDefaultPatchCache[ type ].contains( size ) )
1165 return mDefaultPatchCache[ type ].value( size );
1171 geom =
QgsGeometry( qgis::make_unique< QgsPoint >( static_cast< int >( size.width() ) / 2, static_cast< int >( size.height() ) / 2 ) );
1178 double y =
static_cast< int >( size.height() ) / 2 + 0.5;
1179 geom =
QgsGeometry( qgis::make_unique< QgsLineString >( ( QVector< double >() << 0 << size.width() ),
1180 ( QVector< double >() << y << y ) ) );
1186 geom =
QgsGeometry( qgis::make_unique< QgsPolygon >(
1187 new QgsLineString( QVector< double >() << 0 << static_cast< int >( size.width() ) << static_cast< int >( size.width() ) << 0 << 0,
1188 QVector< double >() <<
static_cast< int >( size.height() ) << static_cast< int >( size.height() ) << 0 << 0 << static_cast< int >( size.height() ) ) ) );
1197 mDefaultPatchCache[ type ][size ] = res;
1204 return QList<QList<QPolygonF> >();
1206 if ( mDefaultPatchQPolygonFCache[ type ].contains( size ) )
1207 return mDefaultPatchQPolygonFCache[ type ].value( size );
1210 mDefaultPatchQPolygonFCache[ type ][size ] = res;
1217 QDomDocument doc( QStringLiteral(
"dummy" ) );
1218 QDomElement elem = doc.createElement( QStringLiteral(
"symbol" ) );
1219 elem.setAttribute( QStringLiteral(
"type" ), symbol->
type() );
1222 QByteArray xmlArray;
1223 QTextStream stream( &xmlArray );
1224 stream.setCodec(
"UTF-8" );
1225 elem.save( stream, 4 );
1226 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO symbol3d VALUES (NULL, '%q', '%q', %d);",
1227 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
1228 if ( !runEmptyQuery( query ) )
1230 QgsDebugMsg( QStringLiteral(
"Couldn't insert 3d symbol into the database!" ) );
1245 if ( m3dSymbols.contains( newName ) )
1247 QgsDebugMsg( QStringLiteral(
"3d symbol of new name already exists." ) );
1251 if ( !m3dSymbols.contains( oldName ) )
1255 m3dSymbols.insert( newName, symbol );
1261 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM symbol3d WHERE name='%q'", oldName.toUtf8().constData() );
1263 statement = mCurrentDB.
prepare( query, nErr );
1264 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1266 labelSettingsId = sqlite3_column_int( statement.get(), 0 );
1279 return m3dSymbols.keys();
1286 QgsDebugMsg( QStringLiteral(
"Cannot Open database for getting favorite symbols" ) );
1287 return QStringList();
1295 QgsDebugMsg( QStringLiteral(
"No such style entity" ) );
1296 return QStringList();
1299 query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT name FROM %1 WHERE favorite=1" ).arg( entityTableName( type ) ).toLocal8Bit().data() );
1305 statement = mCurrentDB.
prepare( query, nErr );
1307 QStringList symbols;
1308 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1320 QgsDebugMsg( QStringLiteral(
"Cannot open database to get symbols of tagid %1" ).arg( tagid ) );
1321 return QStringList();
1329 QgsDebugMsg( QStringLiteral(
"Unknown Entity" ) );
1330 return QStringList();
1333 subquery =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT %1 FROM %2 WHERE tag_id=%d" ).arg( tagmapEntityIdFieldName( type ),
1334 tagmapTableName( type ) ).toLocal8Bit().data(), tagid );
1340 statement = mCurrentDB.
prepare( subquery, nErr );
1343 QStringList symbols;
1344 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1346 int id = sqlite3_column_int( statement.get(), 0 );
1348 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT name FROM %1 WHERE id=%d" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
id );
1352 statement2 = mCurrentDB.
prepare( query, rc );
1353 while ( rc == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1368 QString query =
qgs_sqlite3_mprintf(
"INSERT INTO tag VALUES (NULL, '%q')", tagname.toUtf8().constData() );
1370 statement = mCurrentDB.
prepare( query, nErr );
1371 if ( nErr == SQLITE_OK )
1372 ( void )sqlite3_step( statement.get() );
1375 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1379 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
1385 return QStringList();
1391 statement = mCurrentDB.
prepare( query, nError );
1393 QStringList tagList;
1394 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1404 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET name='%q' WHERE id=%d" ).arg( entityTableName( type ) ).toLocal8Bit().data(), newName.toUtf8().constData(), id );
1406 const bool result = runEmptyQuery( query );
1409 mErrorString = QStringLiteral(
"Could not rename!" );
1413 mCachedTags.clear();
1414 mCachedFavorites.clear();
1439 bool groupRemoved =
false;
1444 query =
qgs_sqlite3_mprintf(
"DELETE FROM tag WHERE id=%d; DELETE FROM tagmap WHERE tag_id=%d",
id,
id );
1445 groupRemoved =
true;
1449 groupRemoved =
true;
1453 query =
qgs_sqlite3_mprintf( QStringLiteral(
"DELETE FROM %1 WHERE id=%d; DELETE FROM %2 WHERE %3=%d" ).arg(
1454 entityTableName( type ),
1455 tagmapTableName( type ),
1456 tagmapEntityIdFieldName( type )
1457 ).toLocal8Bit().data(),
id,
id );
1461 bool result =
false;
1462 if ( !runEmptyQuery( query ) )
1464 QgsDebugMsg( QStringLiteral(
"Could not delete entity!" ) );
1468 mCachedTags.clear();
1469 mCachedFavorites.clear();
1474 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1493 std::unique_ptr< QgsSymbol >
symbol( mSymbols.take( name ) );
1502 std::unique_ptr< QgsAbstract3DSymbol >
symbol( m3dSymbols.take( name ) );
1511 std::unique_ptr< QgsColorRamp > ramp( mColorRamps.take( name ) );
1519 if ( !mTextFormats.contains( name ) )
1522 mTextFormats.remove( name );
1528 if ( !mLabelSettings.contains( name ) )
1531 mLabelSettings.remove( name );
1537 if ( !mLegendPatchShapes.contains( name ) )
1540 mLegendPatchShapes.remove( name );
1547 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to modify." ) );
1551 const int id =
entityId( type, name );
1554 QgsDebugMsg(
"No matching entity for deleting in database: " + name );
1557 const bool result =
remove( type, id );
1560 mCachedTags[ type ].remove( name );
1561 mCachedFavorites[ type ].remove( name );
1590 bool QgsStyle::runEmptyQuery(
const QString &query )
1595 char *zErr =
nullptr;
1596 int nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1598 if ( nErr != SQLITE_OK )
1601 sqlite3_free( zErr );
1604 return nErr == SQLITE_OK;
1615 QgsDebugMsg( QStringLiteral(
"Wrong entity value. cannot apply group" ) );
1619 query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET favorite=1 WHERE name='%q'" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
1620 name.toUtf8().constData() );
1624 const bool res = runEmptyQuery( query );
1634 mCachedFavorites[ type ].insert( name,
true );
1651 QgsDebugMsg( QStringLiteral(
"Wrong entity value. cannot apply group" ) );
1655 query =
qgs_sqlite3_mprintf( QStringLiteral(
"UPDATE %1 SET favorite=0 WHERE name='%q'" ).arg( entityTableName( type ) ).toLocal8Bit().data(), name.toUtf8().constData() );
1659 const bool res = runEmptyQuery( query );
1662 mCachedFavorites[ type ].insert( name,
false );
1673 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to search" ) );
1674 return QStringList();
1683 return QStringList();
1686 item = entityTableName( type );
1691 item.toUtf8().constData(), qword.toUtf8().constData() );
1694 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1696 QSet< QString > symbols;
1697 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1703 query =
qgs_sqlite3_mprintf(
"SELECT id FROM tag WHERE name LIKE '%%%q%%'", qword.toUtf8().constData() );
1704 statement = mCurrentDB.
prepare( query, nErr );
1707 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1712 QString dummy = tagids.join( QLatin1String(
", " ) );
1713 query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT %1 FROM %2 WHERE tag_id IN (%q)" ).arg( tagmapEntityIdFieldName( type ),
1714 tagmapTableName( type ) ).toLocal8Bit().data(), dummy.toUtf8().constData() );
1716 statement = mCurrentDB.
prepare( query, nErr );
1718 QStringList symbolids;
1719 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1724 dummy = symbolids.join( QLatin1String(
", " ) );
1726 item.toUtf8().constData(), dummy.toUtf8().constData() );
1727 statement = mCurrentDB.
prepare( query, nErr );
1728 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1733 return qgis::setToList( symbols );
1740 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to tag." ) );
1752 symbolid =
entityId( type, symbol );
1758 QgsDebugMsg( QStringLiteral(
"No such symbol for tagging in database: " ) + symbol );
1763 const auto constTags =
tags;
1764 for (
const QString &t : constTags )
1767 if ( !tag.isEmpty() )
1770 int tagid(
tagId( tag ) );
1779 QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"INSERT INTO %1 VALUES (%d,%d)" ).arg( tagmapTableName( type ) ).toLocal8Bit().data(), tagid, symbolid );
1781 char *zErr =
nullptr;
1783 nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1787 sqlite3_free( zErr );
1793 clearCachedTags( type, symbol );
1803 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for detagging." ) );
1817 const int symbolid =
entityId( type, symbol );
1818 if ( symbolid == 0 )
1823 const auto constTags =
tags;
1824 for (
const QString &
tag : constTags )
1829 statement2 = mCurrentDB.
prepare( query, nErr );
1832 if ( nErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1834 tagid = sqlite3_column_int( statement2.get(), 0 );
1840 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 );
1841 runEmptyQuery( query );
1845 clearCachedTags( type, symbol );
1858 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for detagging." ) );
1872 const int symbolid =
entityId( type, symbol );
1873 if ( symbolid == 0 )
1879 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"DELETE FROM %1 WHERE %2=%d" ).arg( tagmapTableName( type ),
1880 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1881 runEmptyQuery( query );
1883 clearCachedTags( type, symbol );
1898 return QStringList();
1901 if ( mCachedTags[ type ].contains( symbol ) )
1902 return mCachedTags[ type ].value( symbol );
1908 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
1909 return QStringList();
1912 int symbolid =
entityId( type, symbol );
1914 return QStringList();
1917 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT tag_id FROM %1 WHERE %2=%d" ).arg( tagmapTableName( type ),
1918 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1921 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1923 QStringList tagList;
1924 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1926 QString subquery =
qgs_sqlite3_mprintf(
"SELECT name FROM tag WHERE id=%d", sqlite3_column_int( statement.get(), 0 ) );
1930 statement2 = mCurrentDB.
prepare( subquery, pErr );
1931 if ( pErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1938 mCachedTags[ type ].insert( symbol, tagList );
1947 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
1958 if ( mCachedFavorites[ type ].contains( name ) )
1959 return mCachedFavorites[ type ].value( name );
1963 const QStringList names =
allNames( type );
1964 if ( !names.contains( name ) )
1970 for (
const QString &n : names )
1972 const bool isFav = favorites.contains( n );
1976 mCachedFavorites[ type ].insert( n, isFav );
1985 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
1997 symbolid =
entityId( type, symbol );
2005 int tagid =
tagId( tag );
2012 const QString query =
qgs_sqlite3_mprintf( QStringLiteral(
"SELECT tag_id FROM %1 WHERE tag_id=%d AND %2=%d" ).arg( tagmapTableName( type ),
2013 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), tagid, symbolid );
2016 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2018 return ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW );
2030 statement = mCurrentDB.
prepare( query, nError );
2033 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2041 int QgsStyle::getId(
const QString &table,
const QString &name )
2043 QString lowerName( name.toLower() );
2044 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE LOWER(name)='%q'", table.toUtf8().constData(), lowerName.toUtf8().constData() );
2047 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2050 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2052 id = sqlite3_column_int( statement.get(), 0 );
2057 QString query =
qgs_sqlite3_mprintf(
"SELECT id FROM %q WHERE name='%q'", table.toUtf8().constData(), name.toUtf8().constData() );
2060 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2061 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2063 id = sqlite3_column_int( statement.get(), 0 );
2070 QString QgsStyle::getName(
const QString &table,
int id )
const 2072 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM %q WHERE id='%q'", table.toUtf8().constData(), QString::number(
id ).toUtf8().constData() );
2075 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2078 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2088 return getId( QStringLiteral(
"symbol" ), name );
2093 return getId( entityTableName( type ), name );
2098 return getId( QStringLiteral(
"colorramp" ), name );
2103 return mTextFormats.value( name );
2108 return mTextFormats.count();
2113 return mTextFormats.keys();
2118 return getId( QStringLiteral(
"textformat" ), name );
2123 return mLabelSettings.value( name );
2128 return mLegendPatchShapes.value( name );
2133 return mLegendPatchShapes.count();
2138 if ( !mLegendPatchShapes.contains( name ) )
2141 return mLegendPatchShapes.value( name ).symbolType();
2146 return m3dSymbols.contains( name ) ? m3dSymbols.value( name )->clone() :
nullptr;
2151 return m3dSymbols.count();
2156 if ( !m3dSymbols.contains( name ) )
2157 return QList<QgsWkbTypes::GeometryType>();
2159 return m3dSymbols.value( name )->compatibleGeometryTypes();
2164 if ( !mLabelSettings.contains( name ) )
2167 return mLabelSettings.value( name ).layerType;
2172 return mLabelSettings.count();
2177 return mLabelSettings.keys();
2182 return getId( QStringLiteral(
"labelsettings" ), name );
2187 return mLegendPatchShapes.keys();
2195 return mPatchMarkerSymbol.get();
2198 return mPatchLineSymbol.get();
2201 return mPatchFillSymbol.get();
2211 return getId( QStringLiteral(
"tag" ), name );
2216 return getId( QStringLiteral(
"smartgroup" ), name );
2247 return QStringList();
2252 return addSmartgroup( name, op, conditions.values( QStringLiteral(
"tag" ) ),
2253 conditions.values( QStringLiteral(
"!tag" ) ),
2254 conditions.values( QStringLiteral(
"name" ) ),
2255 conditions.values( QStringLiteral(
"!name" ) ) );
2258 int QgsStyle::addSmartgroup(
const QString &name,
const QString &op,
const QStringList &matchTag,
const QStringList &noMatchTag,
const QStringList &matchName,
const QStringList &noMatchName )
2260 QDomDocument doc( QStringLiteral(
"dummy" ) );
2261 QDomElement smartEl = doc.createElement( QStringLiteral(
"smartgroup" ) );
2262 smartEl.setAttribute( QStringLiteral(
"name" ), name );
2263 smartEl.setAttribute( QStringLiteral(
"operator" ), op );
2265 auto addCondition = [&doc, &smartEl](
const QString & constraint,
const QStringList & parameters )
2267 for (
const QString ¶m : parameters )
2269 QDomElement condEl = doc.createElement( QStringLiteral(
"condition" ) );
2270 condEl.setAttribute( QStringLiteral(
"constraint" ), constraint );
2271 condEl.setAttribute( QStringLiteral(
"param" ), param );
2272 smartEl.appendChild( condEl );
2275 addCondition( QStringLiteral(
"tag" ), matchTag );
2276 addCondition( QStringLiteral(
"!tag" ), noMatchTag );
2277 addCondition( QStringLiteral(
"name" ), matchName );
2278 addCondition( QStringLiteral(
"!name" ), noMatchName );
2280 QByteArray xmlArray;
2281 QTextStream stream( &xmlArray );
2282 stream.setCodec(
"UTF-8" );
2283 smartEl.save( stream, 4 );
2285 name.toUtf8().constData(), xmlArray.constData() );
2287 if ( runEmptyQuery( query ) )
2290 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
2293 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
2297 QgsDebugMsg( QStringLiteral(
"Couldn't insert symbol into the database!" ) );
2306 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2315 statement = mCurrentDB.
prepare( query, nError );
2318 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2321 groupNames.insert( sqlite3_column_int( statement.get(),
SmartgroupId ), group );
2331 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2332 return QStringList();
2340 statement = mCurrentDB.
prepare( query, nError );
2343 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2353 QStringList symbols;
2358 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2359 if ( !( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW ) )
2361 return QStringList();
2367 if ( !doc.setContent( xmlstr ) )
2369 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2371 QDomElement smartEl = doc.documentElement();
2372 QString op = smartEl.attribute( QStringLiteral(
"operator" ) );
2373 QDomNodeList conditionNodes = smartEl.childNodes();
2375 bool firstSet =
true;
2376 for (
int i = 0; i < conditionNodes.count(); i++ )
2378 QDomElement condEl = conditionNodes.at( i ).toElement();
2379 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2380 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2382 QStringList resultNames;
2384 if ( constraint == QLatin1String(
"tag" ) )
2388 else if ( constraint == QLatin1String(
"name" ) )
2390 resultNames =
allNames( type ).filter( param, Qt::CaseInsensitive );
2392 else if ( constraint == QLatin1String(
"!tag" ) )
2396 for (
const QString &name : unwanted )
2398 resultNames.removeAll( name );
2401 else if ( constraint == QLatin1String(
"!name" ) )
2403 const QStringList all =
allNames( type );
2404 for (
const QString &str : all )
2406 if ( !str.contains( param, Qt::CaseInsensitive ) )
2414 symbols = resultNames;
2419 if ( op == QLatin1String(
"OR" ) )
2421 symbols << resultNames;
2423 else if ( op == QLatin1String(
"AND" ) )
2425 QStringList dummy = symbols;
2427 for (
const QString &result : qgis::as_const( resultNames ) )
2429 if ( dummy.contains( result ) )
2438 QStringList unique = qgis::setToList( qgis::listToSet( symbols ) );
2439 std::sort( unique.begin(), unique.end() );
2447 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2457 statement = mCurrentDB.
prepare( query, nError );
2458 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2462 if ( !doc.setContent( xmlstr ) )
2464 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2467 QDomElement smartEl = doc.documentElement();
2468 QDomNodeList conditionNodes = smartEl.childNodes();
2470 for (
int i = 0; i < conditionNodes.count(); i++ )
2472 QDomElement condEl = conditionNodes.at( i ).toElement();
2473 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2474 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2476 condition.insert( constraint, param );
2487 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2497 statement = mCurrentDB.
prepare( query, nError );
2498 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2502 if ( !doc.setContent( xmlstr ) )
2504 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2506 QDomElement smartEl = doc.documentElement();
2507 op = smartEl.attribute( QStringLiteral(
"operator" ) );
2515 if ( filename.isEmpty() )
2517 QgsDebugMsg( QStringLiteral(
"Invalid filename for style export." ) );
2521 QDomDocument doc( QStringLiteral(
"qgis_style" ) );
2522 QDomElement root = doc.createElement( QStringLiteral(
"qgis_style" ) );
2524 doc.appendChild( root );
2534 QDomNodeList symbolsList = symbolsElem.elementsByTagName( QStringLiteral(
"symbol" ) );
2535 int nbSymbols = symbolsList.count();
2536 for (
int i = 0; i < nbSymbols; ++i )
2538 QDomElement
symbol = symbolsList.at( i ).toElement();
2539 QString name = symbol.attribute( QStringLiteral(
"name" ) );
2541 if ( tags.count() > 0 )
2543 symbol.setAttribute( QStringLiteral(
"tags" ), tags.join(
',' ) );
2545 if ( favoriteSymbols.contains( name ) )
2547 symbol.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2552 QDomElement rampsElem = doc.createElement( QStringLiteral(
"colorramps" ) );
2553 for ( QMap<QString, QgsColorRamp *>::const_iterator itr = mColorRamps.constBegin(); itr != mColorRamps.constEnd(); ++itr )
2557 if ( tags.count() > 0 )
2559 rampEl.setAttribute( QStringLiteral(
"tags" ), tags.join(
',' ) );
2561 if ( favoriteColorramps.contains( itr.key() ) )
2563 rampEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2565 rampsElem.appendChild( rampEl );
2569 QDomElement textFormatsElem = doc.createElement( QStringLiteral(
"textformats" ) );
2570 for (
auto it = mTextFormats.constBegin(); it != mTextFormats.constEnd(); ++it )
2572 QDomElement textFormatEl = doc.createElement( QStringLiteral(
"textformat" ) );
2573 textFormatEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2575 textFormatEl.appendChild( textStyleEl );
2577 if ( tags.count() > 0 )
2579 textFormatEl.setAttribute( QStringLiteral(
"tags" ), tags.join(
',' ) );
2581 if ( favoriteTextFormats.contains( it.key() ) )
2583 textFormatEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2585 textFormatsElem.appendChild( textFormatEl );
2589 QDomElement labelSettingsElem = doc.createElement( QStringLiteral(
"labelsettings" ) );
2590 for (
auto it = mLabelSettings.constBegin(); it != mLabelSettings.constEnd(); ++it )
2592 QDomElement labelSettingsEl = doc.createElement( QStringLiteral(
"labelsetting" ) );
2593 labelSettingsEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2595 labelSettingsEl.appendChild( defEl );
2597 if ( tags.count() > 0 )
2599 labelSettingsEl.setAttribute( QStringLiteral(
"tags" ), tags.join(
',' ) );
2601 if ( favoriteTextFormats.contains( it.key() ) )
2603 labelSettingsEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2605 labelSettingsElem.appendChild( labelSettingsEl );
2609 QDomElement legendPatchShapesElem = doc.createElement( QStringLiteral(
"legendpatchshapes" ) );
2610 for (
auto it = mLegendPatchShapes.constBegin(); it != mLegendPatchShapes.constEnd(); ++it )
2612 QDomElement legendPatchShapeEl = doc.createElement( QStringLiteral(
"legendpatchshape" ) );
2613 legendPatchShapeEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2614 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2616 legendPatchShapeEl.appendChild( defEl );
2618 if ( tags.count() > 0 )
2620 legendPatchShapeEl.setAttribute( QStringLiteral(
"tags" ), tags.join(
',' ) );
2622 if ( favoriteLegendShapes.contains( it.key() ) )
2624 legendPatchShapeEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2626 legendPatchShapesElem.appendChild( legendPatchShapeEl );
2630 QDomElement symbols3DElem = doc.createElement( QStringLiteral(
"symbols3d" ) );
2631 for (
auto it = m3dSymbols.constBegin(); it != m3dSymbols.constEnd(); ++it )
2633 QDomElement symbolEl = doc.createElement( QStringLiteral(
"symbol3d" ) );
2634 symbolEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2635 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2636 defEl.setAttribute( QStringLiteral(
"type" ), it.value()->type() );
2638 symbolEl.appendChild( defEl );
2640 if ( tags.count() > 0 )
2642 symbolEl.setAttribute( QStringLiteral(
"tags" ), tags.join(
',' ) );
2644 if ( favorite3DSymbols.contains( it.key() ) )
2646 symbolEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2648 symbols3DElem.appendChild( symbolEl );
2651 root.appendChild( symbolsElem );
2652 root.appendChild( rampsElem );
2653 root.appendChild( textFormatsElem );
2654 root.appendChild( labelSettingsElem );
2655 root.appendChild( legendPatchShapesElem );
2656 root.appendChild( symbols3DElem );
2659 QFile f( filename );
2660 if ( !f.open( QFile::WriteOnly | QIODevice::Truncate ) )
2662 mErrorString =
"Couldn't open file for writing: " + filename;
2666 QTextStream ts( &f );
2667 ts.setCodec(
"UTF-8" );
2671 mFileName = filename;
2682 mErrorString = QString();
2683 QDomDocument doc( QStringLiteral(
"style" ) );
2684 QFile f( filename );
2685 if ( !f.open( QFile::ReadOnly ) )
2687 mErrorString = QStringLiteral(
"Unable to open the specified file" );
2688 QgsDebugMsg( QStringLiteral(
"Error opening the style XML file." ) );
2692 if ( !doc.setContent( &f ) )
2694 mErrorString = QStringLiteral(
"Unable to understand the style file: %1" ).arg( filename );
2695 QgsDebugMsg( QStringLiteral(
"XML Parsing error" ) );
2701 QDomElement docEl = doc.documentElement();
2702 if ( docEl.tagName() != QLatin1String(
"qgis_style" ) )
2704 mErrorString =
"Incorrect root tag in style: " + docEl.tagName();
2708 const QString version = docEl.attribute( QStringLiteral(
"version" ) );
2709 if ( version != QLatin1String(
STYLE_CURRENT_VERSION ) && version != QLatin1String(
"0" ) && version != QLatin1String(
"1" ) )
2711 mErrorString =
"Unknown style file version: " + version;
2717 QDomElement symbolsElement = docEl.firstChildElement( QStringLiteral(
"symbols" ) );
2718 QDomElement e = symbolsElement.firstChildElement();
2722 runEmptyQuery( query );
2727 while ( !e.isNull() )
2729 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2730 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2736 if ( e.tagName() == QLatin1String(
"symbol" ) )
2738 QString name = e.attribute( QStringLiteral(
"name" ) );
2740 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2742 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2744 bool favorite =
false;
2745 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2764 e = e.nextSiblingElement();
2773 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
2780 QDomElement rampsElement = docEl.firstChildElement( QStringLiteral(
"colorramps" ) );
2781 e = rampsElement.firstChildElement();
2782 while ( !e.isNull() )
2784 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2785 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2791 if ( e.tagName() == QLatin1String(
"colorramp" ) )
2793 QString name = e.attribute( QStringLiteral(
"name" ) );
2795 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2797 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2799 bool favorite =
false;
2800 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2819 e = e.nextSiblingElement();
2825 const QDomElement textFormatElement = docEl.firstChildElement( QStringLiteral(
"textformats" ) );
2826 e = textFormatElement.firstChildElement();
2827 while ( !e.isNull() )
2829 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2830 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2836 if ( e.tagName() == QLatin1String(
"textformat" ) )
2838 QString name = e.attribute( QStringLiteral(
"name" ) );
2840 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2842 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2844 bool favorite =
false;
2845 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2851 const QDomElement styleElem = e.firstChildElement();
2863 e = e.nextSiblingElement();
2870 const QDomElement labelSettingsElement = docEl.firstChildElement( QStringLiteral(
"labelsettings" ) );
2871 e = labelSettingsElement.firstChildElement();
2872 while ( !e.isNull() )
2874 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2875 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2881 if ( e.tagName() == QLatin1String(
"labelsetting" ) )
2883 QString name = e.attribute( QStringLiteral(
"name" ) );
2885 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2887 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2889 bool favorite =
false;
2890 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2896 const QDomElement styleElem = e.firstChildElement();
2908 e = e.nextSiblingElement();
2915 const QDomElement legendPatchShapesElement = docEl.firstChildElement( QStringLiteral(
"legendpatchshapes" ) );
2916 e = legendPatchShapesElement.firstChildElement();
2917 while ( !e.isNull() )
2919 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2920 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2926 if ( e.tagName() == QLatin1String(
"legendpatchshape" ) )
2928 QString name = e.attribute( QStringLiteral(
"name" ) );
2930 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2932 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2934 bool favorite =
false;
2935 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2941 const QDomElement shapeElem = e.firstChildElement();
2953 e = e.nextSiblingElement();
2960 const QDomElement symbols3DElement = docEl.firstChildElement( QStringLiteral(
"symbols3d" ) );
2961 e = symbols3DElement.firstChildElement();
2962 while ( !e.isNull() )
2964 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2965 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2971 if ( e.tagName() == QLatin1String(
"symbol3d" ) )
2973 QString name = e.attribute( QStringLiteral(
"name" ) );
2975 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2977 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2979 bool favorite =
false;
2980 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QLatin1String(
"1" ) )
2985 const QDomElement symbolElem = e.firstChildElement();
2986 const QString type = symbolElem.attribute( QStringLiteral(
"type" ) );
3003 e = e.nextSiblingElement();
3008 runEmptyQuery( query );
3010 mFileName = filename;
3016 QFileInfo fileInfo( path );
3018 if ( fileInfo.suffix().compare( QLatin1String(
"xml" ), Qt::CaseInsensitive ) != 0 )
3022 if ( !QFile::exists( path ) )
3025 QFile inputFile( path );
3026 if ( !inputFile.open( QIODevice::ReadOnly ) )
3029 QTextStream stream( &inputFile );
3030 const QString line = stream.readLine();
3031 return line == QLatin1String(
"<!DOCTYPE qgis_style>" );
3034 bool QgsStyle::updateSymbol(
StyleEntity type,
const QString &name )
3036 QDomDocument doc( QStringLiteral(
"dummy" ) );
3038 QByteArray xmlArray;
3039 QTextStream stream( &xmlArray );
3040 stream.setCodec(
"UTF-8" );
3051 QgsDebugMsg( QStringLiteral(
"Update request received for unavailable symbol" ) );
3056 if ( symEl.isNull() )
3058 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
3061 symEl.save( stream, 4 );
3063 xmlArray.constData(), name.toUtf8().constData() );
3072 QgsDebugMsg( QStringLiteral(
"Update request received for unavailable symbol" ) );
3076 symEl = doc.createElement( QStringLiteral(
"symbol" ) );
3077 symEl.setAttribute( QStringLiteral(
"type" ), m3dSymbols.value( name )->type() );
3079 if ( symEl.isNull() )
3081 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
3084 symEl.save( stream, 4 );
3086 xmlArray.constData(), name.toUtf8().constData() );
3094 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable color ramp." ) );
3098 std::unique_ptr< QgsColorRamp > ramp(
colorRamp( name ) );
3100 if ( symEl.isNull() )
3102 QgsDebugMsg( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
3105 symEl.save( stream, 4 );
3107 xmlArray.constData(), name.toUtf8().constData() );
3115 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable text format." ) );
3121 if ( symEl.isNull() )
3123 QgsDebugMsg( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
3126 symEl.save( stream, 4 );
3128 xmlArray.constData(), name.toUtf8().constData() );
3136 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable label settings." ) );
3142 if ( symEl.isNull() )
3144 QgsDebugMsg( QStringLiteral(
"Couldn't convert label settings to valid XML!" ) );
3147 symEl.save( stream, 4 );
3149 xmlArray.constData(), name.toUtf8().constData() );
3157 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable legend patch shape." ) );
3162 symEl = doc.createElement( QStringLiteral(
"shape" ) );
3164 symEl.save( stream, 4 );
3166 xmlArray.constData(), name.toUtf8().constData() );
3173 QgsDebugMsg( QStringLiteral(
"Updating the unsupported StyleEntity" ) );
3179 if ( !runEmptyQuery( query ) )
3181 QgsDebugMsg( QStringLiteral(
"Couldn't insert symbol into the database!" ) );
3217 mCachedTags[ type ].remove( name );
3220 void QgsStyle::upgradeIfRequired()
3223 QString query =
qgs_sqlite3_mprintf(
"SELECT name FROM sqlite_master WHERE name='stylemetadata'" );
3227 statement = mCurrentDB.
prepare( query, rc );
3229 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
3233 "id INTEGER PRIMARY KEY,"\
3236 runEmptyQuery( query );
3237 query =
qgs_sqlite3_mprintf(
"INSERT INTO stylemetadata VALUES (NULL, '%q', '%q')",
"version",
"31200" );
3238 runEmptyQuery( query );
3245 statement = mCurrentDB.
prepare( query, rc );
3246 if ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
3258 runEmptyQuery( query );
3268 return QStringLiteral(
"symbol" );
3271 return QStringLiteral(
"colorramp" );
3274 return QStringLiteral(
"textformat" );
3277 return QStringLiteral(
"labelsettings" );
3280 return QStringLiteral(
"legendpatchshapes" );
3283 return QStringLiteral(
"symbol3d" );
3286 return QStringLiteral(
"tag" );
3289 return QStringLiteral(
"smartgroup" );
3299 return QStringLiteral(
"tagmap" );
3302 return QStringLiteral(
"ctagmap" );
3305 return QStringLiteral(
"tftagmap" );
3308 return QStringLiteral(
"lstagmap" );
3311 return QStringLiteral(
"lpstagmap" );
3314 return QStringLiteral(
"symbol3dtagmap" );
3328 return QStringLiteral(
"symbol_id" );
3331 return QStringLiteral(
"colorramp_id" );
3334 return QStringLiteral(
"textformat_id" );
3337 return QStringLiteral(
"labelsettings_id" );
3340 return QStringLiteral(
"legendpatchshape_id" );
3343 return QStringLiteral(
"symbol3d_id" );
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Read settings from a DOM element.
bool exportXml(const QString &filename)
Exports the style as a XML file.
QStringList allNames(StyleEntity type) const
Returns a list of the names of all existing entities of the specified type.
The class is used as a container of context for various read/write operations on other objects...
void clear()
Removes all contents of the style.
const QgsColorRamp * colorRampRef(const QString &name) const
Returns a const pointer to a symbol (doesn't create new instance)
bool addEntity(const QString &name, const QgsStyleEntityInterface *entity, bool update=false)
Adds an entity to the style, with the specified name.
bool addTextFormat(const QString &name, const QgsTextFormat &format, bool update=false)
Adds a text format with the specified name to the style.
bool addColorRamp(const QString &name, QgsColorRamp *colorRamp, bool update=false)
Adds a color ramp to the style.
void symbolSaved(const QString &name, QgsSymbol *symbol)
Emitted every time a new symbol has been added to the database.
Scoped object for logging of the runtime for a single operation or group of operations.
static QString userStylePath()
Returns the path to user's style.
bool symbolHasTag(StyleEntity type, const QString &symbol, const QString &tag)
Returns whether a given tag is associated with the symbol.
bool save(QString filename=QString())
Saves style into a file (will use current filename if empty string is passed)
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...
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
Abstract base class for all rendered symbols.
An interface for entities which can be placed in a QgsStyle database.
void entityAdded(QgsStyle::StyleEntity entity, const QString &name)
Emitted every time a new entity has been added to the database.
This class is a composition of two QSettings instances:
QStringList symbolsWithTag(StyleEntity type, int tagid) const
Returns the symbol names with which have the given tag.
void entityTagsChanged(QgsStyle::StyleEntity entity, const QString &name, const QStringList &newTags)
Emitted whenever an entity's tags are changed.
Unique pointer for sqlite3 prepared statements, which automatically finalizes the statement when the ...
QgsLegendPatchShape defaultPatch(QgsSymbol::SymbolType type, QSizeF size) const
Returns the default legend patch shape for the given symbol type.
int legendPatchShapesCount() const
Returns count of legend patch shapes in the style.
void createTables()
Creates tables structure for new database.
bool load(const QString &filename)
Loads a file into the style.
virtual QgsColorRamp * clone() const =0
Creates a clone of the color ramp.
bool addLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool update=false)
Adds label settings with the specified name to the style.
QStringList tagsOfSymbol(StyleEntity type, const QString &symbol)
Returns the tags associated with the symbol.
Abstract base class for color ramps.
QMap< int, QString > QgsSymbolGroupMap
bool saveColorRamp(const QString &name, QgsColorRamp *ramp, bool favorite, const QStringList &tags)
Adds the colorramp to the database.
static QDomElement saveColorRamp(const QString &name, QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
int textFormatCount() const
Returns count of text formats in the style.
bool tagSymbol(StyleEntity type, const QString &symbol, const QStringList &tags)
Tags the symbol with the tags in the list.
QList< QList< QPolygonF > > defaultPatchAsQPolygonF(QgsSymbol::SymbolType type, QSizeF size) const
Returns the default patch geometry for the given symbol type and size as a set of QPolygonF objects (...
A geometry is the spatial representation of a feature.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
bool addLegendPatchShape(const QString &name, const QgsLegendPatchShape &shape, bool update=false)
Adds a legend patch shape with the specified name to the style.
Symbol definition (as XML)
int entityId(StyleEntity type, const QString &name)
Returns the id in the style database for the given name of the specified entity type.
void textFormatRemoved(const QString &name)
Emitted whenever a text format has been removed from the style and the database has been updated as a...
int labelSettingsId(const QString &name)
Returns the ID in the style database for the given label settings by name.
static QgsSymbol * loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
void rampChanged(const QString &name)
Emitted whenever a color ramp's definition is changed.
QgsColorRamp * colorRamp(const QString &name) const
Returns a new copy of the specified color ramp.
QgsAbstract3DSymbol * symbol3D(const QString &name) const
Returns a new copy of the 3D symbol with the specified name.
bool removeColorRamp(const QString &name)
Removes color ramp from style (and delete it)
bool rename(StyleEntity type, int id, const QString &newName)
Renames the given entity with the specified id.
Represents a patch shape for use in map legends.
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...
virtual void writeXml(QDomElement &elem, const QgsReadWriteContext &context) const =0
Writes symbol configuration to the given DOM element.
3 Abstract base class for 3D symbols that are used by VectorLayer3DRenderer objects.
#define STYLE_CURRENT_VERSION
static QgsStyle * defaultStyle()
Returns default application-wide style.
StyleEntity
Enum for Entities involved in a style.
int labelSettingsCount() const
Returns count of label settings in the style.
static QString defaultStylePath()
Returns the path to default style (works as a starting point).
bool isFavorite(StyleEntity type, const QString &name)
Returns true if the symbol with matching type and name is marked as a favorite.
QString errorMessage() const
Returns the most recent error message encountered by the database.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
SymbolType
Type of the symbol.
3d symbol definition (as XML)
int symbolCount()
Returns count of symbols in style.
static int versionInt()
Version number used for comparing versions using the "Check QGIS Version" function.
bool renameSymbol(const QString &oldName, const QString &newName)
Renames a symbol from oldName to newName.
QStringList textFormatNames() const
Returns a list of names of text formats in the style.
QgsPalLayerSettings labelSettings(const QString &name) const
Returns the label settings with the specified name.
LegendPatchTable
Columns available in the legend patch table.
void rampRemoved(const QString &name)
Emitted whenever a color ramp has been removed from the style and the database has been updated as a ...
QList< QList< QPolygonF > > toQPolygonF(QgsSymbol::SymbolType type, QSizeF size) const
Converts the patch shape to a set of QPolygonF objects representing how the patch should be drawn for...
QString tag(int id) const
Returns the tag name for the given id.
void labelSettingsRemoved(const QString &name)
Emitted whenever label settings have been removed from the style and the database has been updated as...
bool importXml(const QString &filename)
Imports the symbols and colorramps into the default style database from the given XML file...
const QgsSymbol * symbolRef(const QString &name) const
Returns a const pointer to a symbol (doesn't create new instance)
const QgsSymbol * previewSymbolForPatchShape(const QgsLegendPatchShape &shape) const
Returns a symbol to use for rendering preview icons for a patch shape.
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.
QStringList labelSettingsNames() const
Returns a list of names of label settings in the style.
bool removeFavorite(StyleEntity type, const QString &name)
Removes the specified symbol from favorites.
Calculate scale by the area.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
QgsStyle()
Constructor for QgsStyle.
int textFormatId(const QString &name)
Returns the ID in the style database for the given text format by name.
bool remove(StyleEntity type, int id)
Removes the specified entity from the database.
QStringList findSymbols(StyleEntity type, const QString &qword)
Returns the names of the symbols which have a matching 'substring' in its definition.
void groupsModified()
Emitted every time a tag or smartgroup has been added, removed, or renamed.
int addTag(const QString &tagName)
Adds a new tag and returns the tag's id.
bool removeEntityByName(StyleEntity type, const QString &name)
Removes the entry of the specified type with matching name from the database.
static void cleanDefaultStyle()
Deletes the default style. Only to be used by QgsApplication::exitQgis()
QStringList legendPatchShapeNames() const
Returns a list of names of legend patch shapes in the style.
QList< QgsSymbolLayer * > QgsSymbolLayerList
QString columnAsText(int column) const
Returns the column value from the current statement row as a string.
static QgsColorRamp * loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
Legend patch shape (since QGIS 3.14)
bool createMemoryDatabase()
Creates a temporary memory database.
QString smartgroupOperator(int id)
Returns the operator for the smartgroup.
static bool isXmlStyleFile(const QString &path)
Tests if the file at path is a QGIS style XML file.
virtual QString type() const =0
Returns identifier of symbol type. Each 3D symbol implementation should return a different type...
sqlite3_statement_unique_ptr prepare(const QString &sql, int &resultCode) const
Prepares a sql statement, returning the result.
void symbolRenamed(const QString &oldName, const QString &newName)
Emitted whenever a symbol has been renamed from oldName to newName.
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 ...
int open(const QString &path)
Opens the database at the specified file path.
void labelSettingsChanged(const QString &name)
Emitted whenever a label setting's definition is changed.
QgsTextFormat textFormat(const QString &name) const
Returns the text format with the specified name.
void textFormatRenamed(const QString &oldName, const QString &newName)
Emitted whenever a text format has been renamed from oldName to newName.
3d symbol is favorite flag
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
void favoritedChanged(QgsStyle::StyleEntity entity, const QString &name, bool isFavorite)
Emitted whenever an entity is either favorited or un-favorited.
QgsLegendPatchShape legendPatchShape(const QString &name) const
Returns the legend patch shape with the specified name.
static Qgs3DSymbolRegistry * symbol3DRegistry()
Returns registry of available 3D symbols.
QgsSmartConditionMap smartgroup(int id)
Returns the QgsSmartConditionMap for the given id.
void symbolRemoved(const QString &name)
Emitted whenever a symbol has been removed from the style and the database has been updated as a resu...
QStringList symbolsOfSmartgroup(StyleEntity type, int id)
Returns the symbols for the smartgroup.
int smartgroupId(const QString &smartgroup)
Returns the database id for the given smartgroup name.
bool renameEntity(StyleEntity type, const QString &oldName, const QString &newName)
Renames an entity of the specified type from oldName to newName.
int tagId(const QString &tag)
Returns the database id for the given tag name.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
bool saveTextFormat(const QString &name, const QgsTextFormat &format, bool favorite, const QStringList &tags)
Adds a text format to the database.
bool addSymbol(const QString &name, QgsSymbol *symbol, bool update=false)
Adds a symbol to style and takes symbol's ownership.
bool removeTextFormat(const QString &name)
Removes a text format from the style.
QStringList tags() const
Returns a list of all tags in the style database.
void rampRenamed(const QString &oldName, const QString &newName)
Emitted whenever a color ramp has been renamed from oldName to newName.
bool renameSymbol3D(const QString &oldName, const QString &newName)
Changes a 3d symbol's name.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
virtual QgsStyle::StyleEntity type() const =0
Returns the type of style entity.
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.
void textFormatChanged(const QString &name)
Emitted whenever a text format's definition is changed.
int addSmartgroup(const QString &name, const QString &op, const QgsSmartConditionMap &conditions)
Adds a new smartgroup to the database and returns the id.
Text format definition (as XML)
void symbolChanged(const QString &name)
Emitted whenever a symbol's definition is changed.
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 ...
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
bool createDatabase(const QString &filename)
Creates an on-disk database.
QString qgs_sqlite3_mprintf(const char *format,...)
Wraps sqlite3_mprintf() by automatically freeing the memory.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
void writeXml(QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
int colorrampId(const QString &name)
Returns the id in the style database for the given colorramp name returns 0 if not found...
Line string geometry type, with support for z-dimension and m-values.
int symbolId(const QString &name)
Returns the id in the style database for the given symbol name returns 0 if not found.
void entityChanged(QgsStyle::StyleEntity entity, const QString &name)
Emitted whenever an entity's definition is changed.
Symbol3DTable
Columns available in the 3d symbol table.
QStringList colorRampNames() const
Returns a list of names of color ramps.
Legend patch definition (as XML)
QMap< QString, QgsSymbol *> QgsSymbolMap
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
bool addSymbol3D(const QString &name, QgsAbstract3DSymbol *symbol, bool update=false)
Adds a 3d symbol with the specified name to the style.
int symbol3DCount() const
Returns count of 3D symbols in the style.
3D symbol entity (since QGIS 3.14)
bool renameLabelSettings(const QString &oldName, const QString &newName)
Changes a label setting's name.
bool renameColorRamp(const QString &oldName, const QString &newName)
Changes ramp's name.
QgsWkbTypes::GeometryType labelSettingsLayerType(const QString &name) const
Returns the layer geometry type corresponding to the label settings with the specified name...
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 ...
int colorRampCount()
Returns count of color ramps.
QgsSymbol::SymbolType symbolType() const
Returns the symbol type associated with this patch.
void labelSettingsRenamed(const QString &oldName, const QString &newName)
Emitted whenever label settings have been renamed from oldName to newName.
bool renameLegendPatchShape(const QString &oldName, const QString &newName)
Changes a legend patch shape's name.
bool saveSymbol3D(const QString &name, QgsAbstract3DSymbol *symbol, bool favorite, const QStringList &tags)
Adds a 3d symbol to the database.
QStringList symbol3DNames() const
Returns a list of names of 3d symbols in 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...
QgsSymbol * symbol(const QString &name)
Returns a NEW copy of symbol.
bool saveSymbol(const QString &name, QgsSymbol *symbol, bool favorite, const QStringList &tags)
Adds the symbol to the database with tags.
bool saveLegendPatchShape(const QString &name, const QgsLegendPatchShape &shape, bool favorite, const QStringList &tags)
Adds a legend patch shape to the database.
bool removeSymbol(const QString &name)
Removes symbol from style (and delete it)
Container for all settings relating to text rendering.
bool saveLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool favorite, const QStringList &tags)
Adds label settings to the database.
bool addFavorite(StyleEntity type, const QString &name)
Adds the specified symbol to favorites.
Label settings definition (as XML)
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
bool removeLabelSettings(const QString &name)
Removes label settings from the style.
Legend patch is favorite flag.
bool renameTextFormat(const QString &oldName, const QString &newName)
Changes a text format's name.
bool detagSymbol(StyleEntity type, const QString &symbol, const QStringList &tags)
Detags the symbol with the given list.
QStringList symbolsOfFavorite(StyleEntity type) const
Returns the symbol names which are flagged as favorite.
Color ramp definition (as XML)
QMultiMap< QString, QString > QgsSmartConditionMap
A multimap to hold the smart group conditions as constraint and parameter pairs.
QgsStyle::StyleEntity type() const override
Returns the type of style entity.
QgsSymbol::SymbolType legendPatchShapeSymbolType(const QString &name) const
Returns the symbol type corresponding to the legend patch shape with the specified name...
QStringList symbolTypes() const
Returns a list of all available symbol types.
QgsSymbolGroupMap smartgroupsListMap()
Returns the smart groups map with id as key and name as value.
QStringList smartgroupNames() const
Returns the smart groups list.
QStringList symbolNames() const
Returns a list of names of symbols.