33 #include <QDomDocument>
34 #include <QDomElement>
36 #include <QDomNodeList>
38 #include <QTextStream>
44 #define STYLE_CURRENT_VERSION "2"
58 QgsStyle *QgsStyle::sDefaultStyle =
nullptr;
64 simpleMarker->setStrokeWidth( 0.4 );
65 mPatchMarkerSymbol = qgis::make_unique< QgsMarkerSymbol >(
QgsSymbolLayerList() << simpleMarker.release() );
67 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleLine = qgis::make_unique< QgsSimpleLineSymbolLayer >( QColor( 84, 176, 74 ), 0.6 );
68 mPatchLineSymbol = qgis::make_unique< QgsLineSymbol >(
QgsSymbolLayerList() << simpleLine.release() );
70 std::unique_ptr< QgsGradientFillSymbolLayer > gradientFill = qgis::make_unique< QgsGradientFillSymbolLayer >( QColor( 66, 150, 63 ), QColor( 84, 176, 74 ) );
71 std::unique_ptr< QgsSimpleLineSymbolLayer > simpleOutline = qgis::make_unique< QgsSimpleLineSymbolLayer >( QColor( 56, 128, 54 ), 0.26 );
72 mPatchFillSymbol = qgis::make_unique< QgsFillSymbol >(
QgsSymbolLayerList() << gradientFill.release() << simpleOutline.release() );
82 switch ( entity->
type() )
113 if ( !sDefaultStyle )
119 if ( !QFile::exists( styleFilename ) )
131 if ( sDefaultStyle->
load( styleFilename ) )
133 sDefaultStyle->upgradeIfRequired();
137 return sDefaultStyle;
142 delete sDefaultStyle;
143 sDefaultStyle =
nullptr;
148 qDeleteAll( mSymbols );
149 qDeleteAll( mColorRamps );
153 mTextFormats.clear();
156 mCachedFavorites.clear();
161 if ( !
symbol || name.isEmpty() )
165 if ( mSymbols.contains( name ) )
168 delete mSymbols.value( name );
169 mSymbols.insert( name,
symbol );
175 mSymbols.insert( name,
symbol );
186 QDomDocument doc( QStringLiteral(
"dummy" ) );
188 if ( symEl.isNull() )
190 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
195 QTextStream stream( &xmlArray );
196 stream.setCodec(
"UTF-8" );
197 symEl.save( stream, 4 );
198 auto query =
QgsSqlite3Mprintf(
"INSERT INTO symbol VALUES (NULL, '%q', '%q', %d);",
199 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
201 if ( !runEmptyQuery( query ) )
203 QgsDebugMsg( QStringLiteral(
"Couldn't insert symbol into the database!" ) );
207 mCachedFavorites[
SymbolEntity ].insert( name, favorite );
256 return mSymbols.value( name );
261 return mSymbols.count();
266 return mSymbols.keys();
276 if ( mColorRamps.contains( name ) )
279 delete mColorRamps.value( name );
297 if ( mTextFormats.contains( name ) )
300 mTextFormats.remove( name );
301 mTextFormats.insert( name, format );
307 mTextFormats.insert( name, format );
318 if ( mLabelSettings.contains( name ) )
321 mLabelSettings.remove( name );
322 mLabelSettings.insert( name, settings );
328 mLabelSettings.insert( name, settings );
339 if ( mLegendPatchShapes.contains( name ) )
342 mLegendPatchShapes.remove( name );
343 mLegendPatchShapes.insert( name, shape );
349 mLegendPatchShapes.insert( name, shape );
360 QDomDocument doc( QStringLiteral(
"dummy" ) );
363 if ( rampEl.isNull() )
365 QgsDebugMsg( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
370 QTextStream stream( &xmlArray );
371 stream.setCodec(
"UTF-8" );
372 rampEl.save( stream, 4 );
373 auto query =
QgsSqlite3Mprintf(
"INSERT INTO colorramp VALUES (NULL, '%q', '%q', %d);",
374 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
375 if ( !runEmptyQuery( query ) )
377 QgsDebugMsg( QStringLiteral(
"Couldn't insert colorramp into the database!" ) );
399 return ramp ? ramp->
clone() :
nullptr;
404 return mColorRamps.value( name );
409 return mColorRamps.count();
414 return mColorRamps.keys();
417 bool QgsStyle::openDatabase(
const QString &filename )
419 int rc = mCurrentDB.
open( filename );
422 mErrorString = QStringLiteral(
"Couldn't open the style database: %1" ).arg( mCurrentDB.
errorMessage() );
431 mErrorString.clear();
432 if ( !openDatabase( filename ) )
434 mErrorString = QStringLiteral(
"Unable to create database" );
446 mErrorString.clear();
447 if ( !openDatabase( QStringLiteral(
":memory:" ) ) )
449 mErrorString = QStringLiteral(
"Unable to create temporary memory database" );
462 "id INTEGER PRIMARY KEY,"\
465 "favorite INTEGER);"\
466 "CREATE TABLE colorramp("\
467 "id INTEGER PRIMARY KEY,"\
470 "favorite INTEGER);"\
471 "CREATE TABLE textformat("\
472 "id INTEGER PRIMARY KEY,"\
475 "favorite INTEGER);"\
476 "CREATE TABLE labelsettings("\
477 "id INTEGER PRIMARY KEY,"\
480 "favorite INTEGER);"\
481 "CREATE TABLE legendpatchshapes("\
482 "id INTEGER PRIMARY KEY,"\
485 "favorite INTEGER);"\
487 "id INTEGER PRIMARY KEY,"\
489 "CREATE TABLE tagmap("\
490 "tag_id INTEGER NOT NULL,"\
491 "symbol_id INTEGER);"\
492 "CREATE TABLE ctagmap("\
493 "tag_id INTEGER NOT NULL,"\
494 "colorramp_id INTEGER);"\
495 "CREATE TABLE tftagmap("\
496 "tag_id INTEGER NOT NULL,"\
497 "textformat_id INTEGER);"\
498 "CREATE TABLE lstagmap("\
499 "tag_id INTEGER NOT NULL,"\
500 "labelsettings_id INTEGER);"\
501 "CREATE TABLE lpstagmap("\
502 "tag_id INTEGER NOT NULL,"\
503 "legendpatchshape_id INTEGER);"\
504 "CREATE TABLE smartgroup("\
505 "id INTEGER PRIMARY KEY,"\
508 runEmptyQuery( query );
513 mErrorString.clear();
516 if ( !openDatabase( filename ) )
518 mErrorString = QStringLiteral(
"Unable to open database file specified" );
524 auto query =
QgsSqlite3Mprintf(
"SELECT name FROM sqlite_master WHERE name='textformat'" );
527 statement = mCurrentDB.
prepare( query, rc );
528 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
531 "id INTEGER PRIMARY KEY,"\
534 "favorite INTEGER);"\
535 "CREATE TABLE tftagmap("\
536 "tag_id INTEGER NOT NULL,"\
537 "textformat_id INTEGER);" );
538 runEmptyQuery( query );
541 query =
QgsSqlite3Mprintf(
"SELECT name FROM sqlite_master WHERE name='labelsettings'" );
542 statement = mCurrentDB.
prepare( query, rc );
543 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
546 "id INTEGER PRIMARY KEY,"\
549 "favorite INTEGER);"\
550 "CREATE TABLE lstagmap("\
551 "tag_id INTEGER NOT NULL,"\
552 "labelsettings_id INTEGER);" );
553 runEmptyQuery( query );
556 query =
QgsSqlite3Mprintf(
"SELECT name FROM sqlite_master WHERE name='legendpatchshapes'" );
557 statement = mCurrentDB.
prepare( query, rc );
558 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
561 "id INTEGER PRIMARY KEY,"\
564 "favorite INTEGER);"\
565 "CREATE TABLE lpstagmap("\
566 "tag_id INTEGER NOT NULL,"\
567 "legendpatchshape_id INTEGER);" );
568 runEmptyQuery( query );
572 query =
QgsSqlite3Mprintf(
"UPDATE symbol SET favorite=0 WHERE favorite IS NULL;"
573 "UPDATE colorramp SET favorite=0 WHERE favorite IS NULL;"
574 "UPDATE textformat SET favorite=0 WHERE favorite IS NULL;"
575 "UPDATE labelsettings SET favorite=0 WHERE favorite IS NULL;"
576 "UPDATE legendpatchshapes SET favorite=0 WHERE favorite IS NULL;"
578 runEmptyQuery( query );
584 statement = mCurrentDB.
prepare( query, rc );
586 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
592 if ( !doc.setContent( xmlstring ) )
598 QDomElement symElement = doc.documentElement();
601 mSymbols.insert( symbolName,
symbol );
608 statement = mCurrentDB.
prepare( query, rc );
609 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
615 if ( !doc.setContent( xmlstring ) )
620 QDomElement rampElement = doc.documentElement();
623 mColorRamps.insert( rampName, ramp );
630 statement = mCurrentDB.
prepare( query, rc );
631 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
637 if ( !doc.setContent( xmlstring ) )
639 QgsDebugMsg(
"Cannot open text format " + formatName );
642 QDomElement formatElement = doc.documentElement();
645 mTextFormats.insert( formatName, format );
652 statement = mCurrentDB.
prepare( query, rc );
653 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
659 if ( !doc.setContent( xmlstring ) )
661 QgsDebugMsg(
"Cannot open label settings " + settingsName );
664 QDomElement settingsElement = doc.documentElement();
667 mLabelSettings.insert( settingsName, settings );
674 statement = mCurrentDB.
prepare( query, rc );
675 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
681 if ( !doc.setContent( xmlstring ) )
683 QgsDebugMsg(
"Cannot open legend patch shape " + settingsName );
686 QDomElement settingsElement = doc.documentElement();
689 mLegendPatchShapes.insert( settingsName, shape );
693 mFileName = filename;
701 mErrorString.clear();
703 if ( filename.isEmpty() )
704 filename = mFileName;
709 QDomDocument doc(
"qgis_style" );
710 QDomElement root = doc.createElement(
"qgis_style" );
712 doc.appendChild( root );
716 QDomElement rampsElem = doc.createElement(
"colorramps" );
719 for ( QMap<QString, QgsColorRamp *>::iterator itr = mColorRamps.begin(); itr != mColorRamps.end(); ++itr )
722 rampsElem.appendChild( rampEl );
725 root.appendChild( symbolsElem );
726 root.appendChild( rampsElem );
730 if ( !f.open( QFile::WriteOnly ) )
732 mErrorString =
"Couldn't open file for writing: " + filename;
735 QTextStream ts( &f );
736 ts.setCodec(
"UTF-8" );
741 mFileName = filename;
747 if ( mSymbols.contains( newName ) )
749 QgsDebugMsg( QStringLiteral(
"Symbol of new name already exists" ) );
757 mSymbols.insert( newName,
symbol );
761 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to tag." ) );
768 QgsDebugMsg( QStringLiteral(
"No such symbol for tagging in database: " ) + oldName );
787 if ( mColorRamps.contains( newName ) )
789 QgsDebugMsg( QStringLiteral(
"Color ramp of new name already exists." ) );
797 mColorRamps.insert( newName, ramp );
803 auto query =
QgsSqlite3Mprintf(
"SELECT id FROM colorramp WHERE name='%q'", oldName.toUtf8().constData() );
805 statement = mCurrentDB.
prepare( query, nErr );
806 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
808 rampid = sqlite3_column_int( statement.get(), 0 );
823 QDomDocument doc( QStringLiteral(
"dummy" ) );
826 if ( formatElem.isNull() )
828 QgsDebugMsg( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
833 QTextStream stream( &xmlArray );
834 stream.setCodec(
"UTF-8" );
835 formatElem.save( stream, 4 );
836 auto query =
QgsSqlite3Mprintf(
"INSERT INTO textformat VALUES (NULL, '%q', '%q', %d);",
837 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
838 if ( !runEmptyQuery( query ) )
840 QgsDebugMsg( QStringLiteral(
"Couldn't insert text format into the database!" ) );
861 if ( mTextFormats.contains( newName ) )
863 QgsDebugMsg( QStringLiteral(
"Text format of new name already exists." ) );
867 if ( !mTextFormats.contains( oldName ) )
871 mTextFormats.insert( newName, format );
877 auto query =
QgsSqlite3Mprintf(
"SELECT id FROM textformat WHERE name='%q'", oldName.toUtf8().constData() );
879 statement = mCurrentDB.
prepare( query, nErr );
880 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
882 textFormatId = sqlite3_column_int( statement.get(), 0 );
897 QDomDocument doc( QStringLiteral(
"dummy" ) );
900 if ( settingsElem.isNull() )
902 QgsDebugMsg( QStringLiteral(
"Couldn't convert label settings to valid XML!" ) );
907 QTextStream stream( &xmlArray );
908 stream.setCodec(
"UTF-8" );
909 settingsElem.save( stream, 4 );
910 auto query =
QgsSqlite3Mprintf(
"INSERT INTO labelsettings VALUES (NULL, '%q', '%q', %d);",
911 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
912 if ( !runEmptyQuery( query ) )
914 QgsDebugMsg( QStringLiteral(
"Couldn't insert label settings into the database!" ) );
935 if ( mLabelSettings.contains( newName ) )
937 QgsDebugMsg( QStringLiteral(
"Label settings of new name already exists." ) );
941 if ( !mLabelSettings.contains( oldName ) )
945 mLabelSettings.insert( newName, settings );
951 auto query =
QgsSqlite3Mprintf(
"SELECT id FROM labelsettings WHERE name='%q'", oldName.toUtf8().constData() );
953 statement = mCurrentDB.
prepare( query, nErr );
954 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
971 QDomDocument doc( QStringLiteral(
"dummy" ) );
972 QDomElement shapeElem = doc.createElement( QStringLiteral(
"shape" ) );
976 QTextStream stream( &xmlArray );
977 stream.setCodec(
"UTF-8" );
978 shapeElem.save( stream, 4 );
979 auto query =
QgsSqlite3Mprintf(
"INSERT INTO legendpatchshapes VALUES (NULL, '%q', '%q', %d);",
980 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
981 if ( !runEmptyQuery( query ) )
983 QgsDebugMsg( QStringLiteral(
"Couldn't insert legend patch shape into the database!" ) );
998 if ( mLegendPatchShapes.contains( newName ) )
1000 QgsDebugMsg( QStringLiteral(
"Legend patch shape of new name already exists." ) );
1004 if ( !mLegendPatchShapes.contains( oldName ) )
1008 mLegendPatchShapes.insert( newName, shape );
1014 auto query =
QgsSqlite3Mprintf(
"SELECT id FROM legendpatchshapes WHERE name='%q'", oldName.toUtf8().constData() );
1016 statement = mCurrentDB.
prepare( query, nErr );
1017 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1035 if ( mDefaultPatchCache[ type ].contains( size ) )
1036 return mDefaultPatchCache[ type ].value( size );
1042 geom =
QgsGeometry( qgis::make_unique< QgsPoint >(
static_cast< int >( size.width() ) / 2,
static_cast< int >( size.height() ) / 2 ) );
1049 double y =
static_cast< int >( size.height() ) / 2 + 0.5;
1050 geom =
QgsGeometry( qgis::make_unique< QgsLineString >( ( QVector< double >() << 0 << size.width() ),
1051 ( QVector< double >() << y << y ) ) );
1057 geom =
QgsGeometry( qgis::make_unique< QgsPolygon >(
1058 new QgsLineString( QVector< double >() << 0 <<
static_cast< int >( size.width() ) <<
static_cast< int >( size.width() ) << 0 << 0,
1059 QVector< double >() <<
static_cast< int >( size.height() ) <<
static_cast< int >( size.height() ) << 0 << 0 <<
static_cast< int >( size.height() ) ) ) );
1068 mDefaultPatchCache[ type ][size ] = res;
1075 return QList<QList<QPolygonF> >();
1077 if ( mDefaultPatchQPolygonFCache[ type ].contains( size ) )
1078 return mDefaultPatchQPolygonFCache[ type ].value( size );
1081 mDefaultPatchQPolygonFCache[ type ][size ] = res;
1089 QgsDebugMsg( QStringLiteral(
"Cannot Open database for getting favorite symbols" ) );
1090 return QStringList();
1098 QgsDebugMsg( QStringLiteral(
"No such style entity" ) );
1099 return QStringList();
1102 query =
QgsSqlite3Mprintf( QStringLiteral(
"SELECT name FROM %1 WHERE favorite=1" ).arg( entityTableName( type ) ).toLocal8Bit().data() );
1108 statement = mCurrentDB.
prepare( query, nErr );
1110 QStringList symbols;
1111 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1123 QgsDebugMsg( QStringLiteral(
"Cannot open database to get symbols of tagid %1" ).arg( tagid ) );
1124 return QStringList();
1132 QgsDebugMsg( QStringLiteral(
"Unknown Entity" ) );
1133 return QStringList();
1136 subquery =
QgsSqlite3Mprintf( QStringLiteral(
"SELECT %1 FROM %2 WHERE tag_id=%d" ).arg( tagmapEntityIdFieldName( type ),
1137 tagmapTableName( type ) ).toLocal8Bit().data(), tagid );
1143 statement = mCurrentDB.
prepare( subquery, nErr );
1146 QStringList symbols;
1147 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1149 int id = sqlite3_column_int( statement.get(), 0 );
1151 const QString query =
QgsSqlite3Mprintf( QStringLiteral(
"SELECT name FROM %1 WHERE id=%d" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
id );
1155 statement2 = mCurrentDB.
prepare( query, rc );
1156 while ( rc == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1171 auto query =
QgsSqlite3Mprintf(
"INSERT INTO tag VALUES (NULL, '%q')", tagname.toUtf8().constData() );
1173 statement = mCurrentDB.
prepare( query, nErr );
1174 if ( nErr == SQLITE_OK )
1175 ( void )sqlite3_step( statement.get() );
1178 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1182 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
1188 return QStringList();
1194 statement = mCurrentDB.
prepare( query, nError );
1196 QStringList tagList;
1197 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1207 const QString query =
QgsSqlite3Mprintf( QStringLiteral(
"UPDATE %1 SET name='%q' WHERE id=%d" ).arg( entityTableName( type ) ).toLocal8Bit().data(), newName.toUtf8().constData(),
id );
1209 const bool result = runEmptyQuery( query );
1212 mErrorString = QStringLiteral(
"Could not rename!" );
1216 mCachedTags.clear();
1217 mCachedFavorites.clear();
1242 bool groupRemoved =
false;
1247 query =
QgsSqlite3Mprintf(
"DELETE FROM tag WHERE id=%d; DELETE FROM tagmap WHERE tag_id=%d",
id,
id );
1248 groupRemoved =
true;
1252 groupRemoved =
true;
1256 query =
QgsSqlite3Mprintf( QStringLiteral(
"DELETE FROM %1 WHERE id=%d; DELETE FROM %2 WHERE %3=%d" ).arg(
1257 entityTableName( type ),
1258 tagmapTableName( type ),
1259 tagmapEntityIdFieldName( type )
1260 ).toLocal8Bit().data(),
id,
id );
1264 bool result =
false;
1265 if ( !runEmptyQuery( query ) )
1267 QgsDebugMsg( QStringLiteral(
"Could not delete entity!" ) );
1271 mCachedTags.clear();
1272 mCachedFavorites.clear();
1277 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1296 std::unique_ptr< QgsSymbol >
symbol( mSymbols.take( name ) );
1305 std::unique_ptr< QgsColorRamp > ramp( mColorRamps.take( name ) );
1313 if ( !mTextFormats.contains( name ) )
1316 mTextFormats.remove( name );
1322 if ( !mLabelSettings.contains( name ) )
1325 mLabelSettings.remove( name );
1331 if ( !mLegendPatchShapes.contains( name ) )
1334 mLegendPatchShapes.remove( name );
1341 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to modify." ) );
1345 const int id =
entityId( type, name );
1348 QgsDebugMsg(
"No matching entity for deleting in database: " + name );
1351 const bool result =
remove( type,
id );
1354 mCachedTags[ type ].remove( name );
1355 mCachedFavorites[ type ].remove( name );
1384 bool QgsStyle::runEmptyQuery(
const QString &query )
1389 char *zErr =
nullptr;
1390 int nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1392 if ( nErr != SQLITE_OK )
1395 sqlite3_free( zErr );
1398 return nErr == SQLITE_OK;
1409 QgsDebugMsg( QStringLiteral(
"Wrong entity value. cannot apply group" ) );
1413 query =
QgsSqlite3Mprintf( QStringLiteral(
"UPDATE %1 SET favorite=1 WHERE name='%q'" ).arg( entityTableName( type ) ).toLocal8Bit().data(),
1414 name.toUtf8().constData() );
1418 const bool res = runEmptyQuery( query );
1428 mCachedFavorites[ type ].insert( name,
true );
1445 QgsDebugMsg( QStringLiteral(
"Wrong entity value. cannot apply group" ) );
1449 query =
QgsSqlite3Mprintf( QStringLiteral(
"UPDATE %1 SET favorite=0 WHERE name='%q'" ).arg( entityTableName( type ) ).toLocal8Bit().data(), name.toUtf8().constData() );
1453 const bool res = runEmptyQuery( query );
1456 mCachedFavorites[ type ].insert( name,
false );
1467 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to search" ) );
1468 return QStringList();
1477 return QStringList();
1480 item = entityTableName( type );
1485 item.toUtf8().constData(), qword.toUtf8().constData() );
1488 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1490 QSet< QString > symbols;
1491 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1497 query =
QgsSqlite3Mprintf(
"SELECT id FROM tag WHERE name LIKE '%%%q%%'", qword.toUtf8().constData() );
1498 statement = mCurrentDB.
prepare( query, nErr );
1501 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1506 QString dummy = tagids.join( QStringLiteral(
", " ) );
1507 query =
QgsSqlite3Mprintf( QStringLiteral(
"SELECT %1 FROM %2 WHERE tag_id IN (%q)" ).arg( tagmapEntityIdFieldName( type ),
1508 tagmapTableName( type ) ).toLocal8Bit().data(), dummy.toUtf8().constData() );
1510 statement = mCurrentDB.
prepare( query, nErr );
1512 QStringList symbolids;
1513 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1518 dummy = symbolids.join( QStringLiteral(
", " ) );
1520 item.toUtf8().constData(), dummy.toUtf8().constData() );
1521 statement = mCurrentDB.
prepare( query, nErr );
1522 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1527 return qgis::setToList( symbols );
1534 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database to tag." ) );
1552 QgsDebugMsg( QStringLiteral(
"No such symbol for tagging in database: " ) +
symbol );
1557 const auto constTags =
tags;
1558 for (
const QString &t : constTags )
1561 if ( !
tag.isEmpty() )
1573 QString query =
QgsSqlite3Mprintf( QStringLiteral(
"INSERT INTO %1 VALUES (%d,%d)" ).arg( tagmapTableName( type ) ).toLocal8Bit().data(), tagid, symbolid );
1575 char *zErr =
nullptr;
1577 nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(),
nullptr,
nullptr, &zErr );
1581 sqlite3_free( zErr );
1587 clearCachedTags( type,
symbol );
1597 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for detagging." ) );
1612 if ( symbolid == 0 )
1617 const auto constTags =
tags;
1618 for (
const QString &
tag : constTags )
1623 statement2 = mCurrentDB.
prepare( query, nErr );
1626 if ( nErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1628 tagid = sqlite3_column_int( statement2.get(), 0 );
1634 const QString query =
QgsSqlite3Mprintf( QStringLiteral(
"DELETE FROM %1 WHERE tag_id=%d AND %2=%d" ).arg( tagmapTableName( type ), tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), tagid, symbolid );
1635 runEmptyQuery( query );
1639 clearCachedTags( type,
symbol );
1652 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for detagging." ) );
1667 if ( symbolid == 0 )
1673 const QString query =
QgsSqlite3Mprintf( QStringLiteral(
"DELETE FROM %1 WHERE %2=%d" ).arg( tagmapTableName( type ),
1674 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1675 runEmptyQuery( query );
1677 clearCachedTags( type,
symbol );
1692 return QStringList();
1695 if ( mCachedTags[ type ].contains(
symbol ) )
1696 return mCachedTags[ type ].value(
symbol );
1702 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
1703 return QStringList();
1708 return QStringList();
1711 const QString query =
QgsSqlite3Mprintf( QStringLiteral(
"SELECT tag_id FROM %1 WHERE %2=%d" ).arg( tagmapTableName( type ),
1712 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), symbolid );
1715 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1717 QStringList tagList;
1718 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1720 auto subquery =
QgsSqlite3Mprintf(
"SELECT name FROM tag WHERE id=%d", sqlite3_column_int( statement.get(), 0 ) );
1724 statement2 = mCurrentDB.
prepare( subquery, pErr );
1725 if ( pErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1732 mCachedTags[ type ].insert(
symbol, tagList );
1741 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
1752 if ( mCachedFavorites[ type ].contains( name ) )
1753 return mCachedFavorites[ type ].value( name );
1757 const QStringList names =
allNames( type );
1758 if ( !names.contains( name ) )
1764 for (
const QString &n : names )
1766 const bool isFav = favorites.contains( n );
1770 mCachedFavorites[ type ].insert( n, isFav );
1779 QgsDebugMsg( QStringLiteral(
"Sorry! Cannot open database for getting the tags." ) );
1806 const QString query =
QgsSqlite3Mprintf( QStringLiteral(
"SELECT tag_id FROM %1 WHERE tag_id=%d AND %2=%d" ).arg( tagmapTableName( type ),
1807 tagmapEntityIdFieldName( type ) ).toLocal8Bit().data(), tagid, symbolid );
1810 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1812 return ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW );
1824 statement = mCurrentDB.
prepare( query, nError );
1827 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1835 int QgsStyle::getId(
const QString &table,
const QString &name )
1837 QString lowerName( name.toLower() );
1838 auto query =
QgsSqlite3Mprintf(
"SELECT id FROM %q WHERE LOWER(name)='%q'", table.toUtf8().constData(), lowerName.toUtf8().constData() );
1841 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1844 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1846 id = sqlite3_column_int( statement.get(), 0 );
1851 auto query =
QgsSqlite3Mprintf(
"SELECT id FROM %q WHERE name='%q'", table.toUtf8().constData(), name.toUtf8().constData() );
1854 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1855 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1857 id = sqlite3_column_int( statement.get(), 0 );
1864 QString QgsStyle::getName(
const QString &table,
int id )
const
1866 auto query =
QgsSqlite3Mprintf(
"SELECT name FROM %q WHERE id='%q'", table.toUtf8().constData(), QString::number(
id ).toUtf8().constData() );
1869 int nErr; statement = mCurrentDB.
prepare( query, nErr );
1872 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1882 return getId( QStringLiteral(
"symbol" ), name );
1887 return getId( entityTableName( type ), name );
1892 return getId( QStringLiteral(
"colorramp" ), name );
1897 return mTextFormats.value( name );
1902 return mTextFormats.count();
1907 return mTextFormats.keys();
1912 return getId( QStringLiteral(
"textformat" ), name );
1917 return mLabelSettings.value( name );
1922 return mLegendPatchShapes.value( name );
1927 return mLegendPatchShapes.count();
1932 if ( !mLegendPatchShapes.contains( name ) )
1935 return mLegendPatchShapes.value( name ).symbolType();
1940 if ( !mLabelSettings.contains( name ) )
1943 return mLabelSettings.value( name ).layerType;
1948 return mLabelSettings.count();
1953 return mLabelSettings.keys();
1958 return getId( QStringLiteral(
"labelsettings" ), name );
1963 return mLegendPatchShapes.keys();
1971 return mPatchMarkerSymbol.get();
1974 return mPatchLineSymbol.get();
1977 return mPatchFillSymbol.get();
1987 return getId( QStringLiteral(
"tag" ), name );
1992 return getId( QStringLiteral(
"smartgroup" ), name );
2020 return QStringList();
2025 return addSmartgroup( name, op, conditions.values( QStringLiteral(
"tag" ) ),
2026 conditions.values( QStringLiteral(
"!tag" ) ),
2027 conditions.values( QStringLiteral(
"name" ) ),
2028 conditions.values( QStringLiteral(
"!name" ) ) );
2031 int QgsStyle::addSmartgroup(
const QString &name,
const QString &op,
const QStringList &matchTag,
const QStringList &noMatchTag,
const QStringList &matchName,
const QStringList &noMatchName )
2033 QDomDocument doc( QStringLiteral(
"dummy" ) );
2034 QDomElement smartEl = doc.createElement( QStringLiteral(
"smartgroup" ) );
2035 smartEl.setAttribute( QStringLiteral(
"name" ), name );
2036 smartEl.setAttribute( QStringLiteral(
"operator" ), op );
2038 auto addCondition = [&doc, &smartEl](
const QString & constraint,
const QStringList & parameters )
2040 for (
const QString ¶m : parameters )
2042 QDomElement condEl = doc.createElement( QStringLiteral(
"condition" ) );
2043 condEl.setAttribute( QStringLiteral(
"constraint" ), constraint );
2044 condEl.setAttribute( QStringLiteral(
"param" ), param );
2045 smartEl.appendChild( condEl );
2048 addCondition( QStringLiteral(
"tag" ), matchTag );
2049 addCondition( QStringLiteral(
"!tag" ), noMatchTag );
2050 addCondition( QStringLiteral(
"name" ), matchName );
2051 addCondition( QStringLiteral(
"!name" ), noMatchName );
2053 QByteArray xmlArray;
2054 QTextStream stream( &xmlArray );
2055 stream.setCodec(
"UTF-8" );
2056 smartEl.save( stream, 4 );
2057 auto query =
QgsSqlite3Mprintf(
"INSERT INTO smartgroup VALUES (NULL, '%q', '%q')",
2058 name.toUtf8().constData(), xmlArray.constData() );
2060 if ( runEmptyQuery( query ) )
2063 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
2066 return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB.get() ) );
2070 QgsDebugMsg( QStringLiteral(
"Couldn't insert symbol into the database!" ) );
2079 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2088 statement = mCurrentDB.
prepare( query, nError );
2091 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2094 groupNames.insert( sqlite3_column_int( statement.get(),
SmartgroupId ), group );
2104 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2105 return QStringList();
2113 statement = mCurrentDB.
prepare( query, nError );
2116 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2126 QStringList symbols;
2131 int nErr; statement = mCurrentDB.
prepare( query, nErr );
2132 if ( !( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW ) )
2134 return QStringList();
2140 if ( !doc.setContent( xmlstr ) )
2142 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2144 QDomElement smartEl = doc.documentElement();
2145 QString op = smartEl.attribute( QStringLiteral(
"operator" ) );
2146 QDomNodeList conditionNodes = smartEl.childNodes();
2148 bool firstSet =
true;
2149 for (
int i = 0; i < conditionNodes.count(); i++ )
2151 QDomElement condEl = conditionNodes.at( i ).toElement();
2152 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2153 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2155 QStringList resultNames;
2157 if ( constraint == QLatin1String(
"tag" ) )
2161 else if ( constraint == QLatin1String(
"name" ) )
2163 resultNames =
allNames( type ).filter( param, Qt::CaseInsensitive );
2165 else if ( constraint == QLatin1String(
"!tag" ) )
2169 for (
const QString &name : unwanted )
2171 resultNames.removeAll( name );
2174 else if ( constraint == QLatin1String(
"!name" ) )
2176 const QStringList all =
allNames( type );
2177 for (
const QString &str : all )
2179 if ( !str.contains( param, Qt::CaseInsensitive ) )
2187 symbols = resultNames;
2192 if ( op == QLatin1String(
"OR" ) )
2194 symbols << resultNames;
2196 else if ( op == QLatin1String(
"AND" ) )
2198 QStringList dummy = symbols;
2200 for (
const QString &result : qgis::as_const( resultNames ) )
2202 if ( dummy.contains( result ) )
2211 QStringList unique = qgis::setToList( qgis::listToSet( symbols ) );
2212 std::sort( unique.begin(), unique.end() );
2220 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2230 statement = mCurrentDB.
prepare( query, nError );
2231 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2235 if ( !doc.setContent( xmlstr ) )
2237 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2240 QDomElement smartEl = doc.documentElement();
2241 QDomNodeList conditionNodes = smartEl.childNodes();
2243 for (
int i = 0; i < conditionNodes.count(); i++ )
2245 QDomElement condEl = conditionNodes.at( i ).toElement();
2246 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
2247 QString param = condEl.attribute( QStringLiteral(
"param" ) );
2249 condition.insert( constraint, param );
2260 QgsDebugMsg( QStringLiteral(
"Cannot open database for listing groups" ) );
2270 statement = mCurrentDB.
prepare( query, nError );
2271 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2275 if ( !doc.setContent( xmlstr ) )
2277 QgsDebugMsg( QStringLiteral(
"Cannot open smartgroup id: %1" ).arg(
id ) );
2279 QDomElement smartEl = doc.documentElement();
2280 op = smartEl.attribute( QStringLiteral(
"operator" ) );
2288 if ( filename.isEmpty() )
2290 QgsDebugMsg( QStringLiteral(
"Invalid filename for style export." ) );
2294 QDomDocument doc( QStringLiteral(
"qgis_style" ) );
2295 QDomElement root = doc.createElement( QStringLiteral(
"qgis_style" ) );
2297 doc.appendChild( root );
2305 QDomNodeList symbolsList = symbolsElem.elementsByTagName( QStringLiteral(
"symbol" ) );
2306 int nbSymbols = symbolsList.count();
2307 for (
int i = 0; i < nbSymbols; ++i )
2309 QDomElement
symbol = symbolsList.at( i ).toElement();
2310 QString name =
symbol.attribute( QStringLiteral(
"name" ) );
2312 if (
tags.count() > 0 )
2314 symbol.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2316 if ( favoriteSymbols.contains( name ) )
2318 symbol.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2323 QDomElement rampsElem = doc.createElement( QStringLiteral(
"colorramps" ) );
2324 for ( QMap<QString, QgsColorRamp *>::const_iterator itr = mColorRamps.constBegin(); itr != mColorRamps.constEnd(); ++itr )
2328 if (
tags.count() > 0 )
2330 rampEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2332 if ( favoriteColorramps.contains( itr.key() ) )
2334 rampEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2336 rampsElem.appendChild( rampEl );
2340 QDomElement textFormatsElem = doc.createElement( QStringLiteral(
"textformats" ) );
2341 for (
auto it = mTextFormats.constBegin(); it != mTextFormats.constEnd(); ++it )
2343 QDomElement textFormatEl = doc.createElement( QStringLiteral(
"textformat" ) );
2344 textFormatEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2346 textFormatEl.appendChild( textStyleEl );
2348 if (
tags.count() > 0 )
2350 textFormatEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2352 if ( favoriteTextFormats.contains( it.key() ) )
2354 textFormatEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2356 textFormatsElem.appendChild( textFormatEl );
2360 QDomElement labelSettingsElem = doc.createElement( QStringLiteral(
"labelsettings" ) );
2361 for (
auto it = mLabelSettings.constBegin(); it != mLabelSettings.constEnd(); ++it )
2363 QDomElement labelSettingsEl = doc.createElement( QStringLiteral(
"labelsetting" ) );
2364 labelSettingsEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2366 labelSettingsEl.appendChild( defEl );
2368 if (
tags.count() > 0 )
2370 labelSettingsEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2372 if ( favoriteTextFormats.contains( it.key() ) )
2374 labelSettingsEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2376 labelSettingsElem.appendChild( labelSettingsEl );
2380 QDomElement legendPatchShapesElem = doc.createElement( QStringLiteral(
"legendpatchshapes" ) );
2381 for (
auto it = mLegendPatchShapes.constBegin(); it != mLegendPatchShapes.constEnd(); ++it )
2383 QDomElement legendPatchShapeEl = doc.createElement( QStringLiteral(
"legendpatchshape" ) );
2384 legendPatchShapeEl.setAttribute( QStringLiteral(
"name" ), it.key() );
2385 QDomElement defEl = doc.createElement( QStringLiteral(
"definition" ) );
2387 legendPatchShapeEl.appendChild( defEl );
2389 if (
tags.count() > 0 )
2391 legendPatchShapeEl.setAttribute( QStringLiteral(
"tags" ),
tags.join(
',' ) );
2393 if ( favoriteTextFormats.contains( it.key() ) )
2395 legendPatchShapeEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
2397 legendPatchShapesElem.appendChild( legendPatchShapeEl );
2400 root.appendChild( symbolsElem );
2401 root.appendChild( rampsElem );
2402 root.appendChild( textFormatsElem );
2403 root.appendChild( labelSettingsElem );
2404 root.appendChild( legendPatchShapesElem );
2407 QFile f( filename );
2408 if ( !f.open( QFile::WriteOnly | QIODevice::Truncate ) )
2410 mErrorString =
"Couldn't open file for writing: " + filename;
2414 QTextStream ts( &f );
2415 ts.setCodec(
"UTF-8" );
2419 mFileName = filename;
2430 mErrorString = QString();
2431 QDomDocument doc( QStringLiteral(
"style" ) );
2432 QFile f( filename );
2433 if ( !f.open( QFile::ReadOnly ) )
2435 mErrorString = QStringLiteral(
"Unable to open the specified file" );
2436 QgsDebugMsg( QStringLiteral(
"Error opening the style XML file." ) );
2440 if ( !doc.setContent( &f ) )
2442 mErrorString = QStringLiteral(
"Unable to understand the style file: %1" ).arg( filename );
2443 QgsDebugMsg( QStringLiteral(
"XML Parsing error" ) );
2449 QDomElement docEl = doc.documentElement();
2450 if ( docEl.tagName() != QLatin1String(
"qgis_style" ) )
2452 mErrorString =
"Incorrect root tag in style: " + docEl.tagName();
2456 const QString version = docEl.attribute( QStringLiteral(
"version" ) );
2457 if ( version != QLatin1String(
STYLE_CURRENT_VERSION ) && version != QLatin1String(
"0" ) && version != QLatin1String(
"1" ) )
2459 mErrorString =
"Unknown style file version: " + version;
2465 QDomElement symbolsElement = docEl.firstChildElement( QStringLiteral(
"symbols" ) );
2466 QDomElement e = symbolsElement.firstChildElement();
2470 runEmptyQuery( query );
2475 while ( !e.isNull() )
2477 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2478 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2484 if ( e.tagName() == QLatin1String(
"symbol" ) )
2486 QString name = e.attribute( QStringLiteral(
"name" ) );
2488 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2490 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2492 bool favorite =
false;
2493 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QStringLiteral(
"1" ) )
2512 e = e.nextSiblingElement();
2521 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
2528 QDomElement rampsElement = docEl.firstChildElement( QStringLiteral(
"colorramps" ) );
2529 e = rampsElement.firstChildElement();
2530 while ( !e.isNull() )
2532 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2533 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2539 if ( e.tagName() == QLatin1String(
"colorramp" ) )
2541 QString name = e.attribute( QStringLiteral(
"name" ) );
2543 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2545 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2547 bool favorite =
false;
2548 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QStringLiteral(
"1" ) )
2567 e = e.nextSiblingElement();
2573 const QDomElement textFormatElement = docEl.firstChildElement( QStringLiteral(
"textformats" ) );
2574 e = textFormatElement.firstChildElement();
2575 while ( !e.isNull() )
2577 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2578 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2584 if ( e.tagName() == QLatin1String(
"textformat" ) )
2586 QString name = e.attribute( QStringLiteral(
"name" ) );
2588 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2590 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2592 bool favorite =
false;
2593 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QStringLiteral(
"1" ) )
2599 const QDomElement styleElem = e.firstChildElement();
2611 e = e.nextSiblingElement();
2618 const QDomElement labelSettingsElement = docEl.firstChildElement( QStringLiteral(
"labelsettings" ) );
2619 e = labelSettingsElement.firstChildElement();
2620 while ( !e.isNull() )
2622 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2623 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2629 if ( e.tagName() == QLatin1String(
"labelsetting" ) )
2631 QString name = e.attribute( QStringLiteral(
"name" ) );
2633 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2635 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2637 bool favorite =
false;
2638 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QStringLiteral(
"1" ) )
2644 const QDomElement styleElem = e.firstChildElement();
2656 e = e.nextSiblingElement();
2663 const QDomElement legendPatchShapesElement = docEl.firstChildElement( QStringLiteral(
"legendpatchshapes" ) );
2664 e = legendPatchShapesElement.firstChildElement();
2665 while ( !e.isNull() )
2667 const int entityAddedVersion = e.attribute( QStringLiteral(
"addedVersion" ) ).toInt();
2668 if ( entityAddedVersion != 0 && sinceVersion != -1 && entityAddedVersion <= sinceVersion )
2674 if ( e.tagName() == QLatin1String(
"legendpatchshape" ) )
2676 QString name = e.attribute( QStringLiteral(
"name" ) );
2678 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
2680 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
2682 bool favorite =
false;
2683 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QStringLiteral(
"1" ) )
2689 const QDomElement shapeElem = e.firstChildElement();
2701 e = e.nextSiblingElement();
2706 runEmptyQuery( query );
2708 mFileName = filename;
2714 QFileInfo fileInfo( path );
2716 if ( fileInfo.suffix().compare( QLatin1String(
"xml" ), Qt::CaseInsensitive ) != 0 )
2720 if ( !QFile::exists( path ) )
2723 QFile inputFile( path );
2724 if ( !inputFile.open( QIODevice::ReadOnly ) )
2727 QTextStream stream( &inputFile );
2728 const QString line = stream.readLine();
2729 return line == QLatin1String(
"<!DOCTYPE qgis_style>" );
2732 bool QgsStyle::updateSymbol( StyleEntity type,
const QString &name )
2734 QDomDocument doc( QStringLiteral(
"dummy" ) );
2736 QByteArray xmlArray;
2737 QTextStream stream( &xmlArray );
2738 stream.setCodec(
"UTF-8" );
2749 QgsDebugMsg( QStringLiteral(
"Update request received for unavailable symbol" ) );
2754 if ( symEl.isNull() )
2756 QgsDebugMsg( QStringLiteral(
"Couldn't convert symbol to valid XML!" ) );
2759 symEl.save( stream, 4 );
2761 xmlArray.constData(), name.toUtf8().constData() );
2769 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable color ramp." ) );
2773 std::unique_ptr< QgsColorRamp > ramp(
colorRamp( name ) );
2775 if ( symEl.isNull() )
2777 QgsDebugMsg( QStringLiteral(
"Couldn't convert color ramp to valid XML!" ) );
2780 symEl.save( stream, 4 );
2782 xmlArray.constData(), name.toUtf8().constData() );
2790 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable text format." ) );
2796 if ( symEl.isNull() )
2798 QgsDebugMsg( QStringLiteral(
"Couldn't convert text format to valid XML!" ) );
2801 symEl.save( stream, 4 );
2803 xmlArray.constData(), name.toUtf8().constData() );
2811 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable label settings." ) );
2817 if ( symEl.isNull() )
2819 QgsDebugMsg( QStringLiteral(
"Couldn't convert label settings to valid XML!" ) );
2822 symEl.save( stream, 4 );
2823 query =
QgsSqlite3Mprintf(
"UPDATE labelsettings SET xml='%q' WHERE name='%q';",
2824 xmlArray.constData(), name.toUtf8().constData() );
2832 QgsDebugMsg( QStringLiteral(
"Update requested for unavailable legend patch shape." ) );
2837 symEl = doc.createElement( QStringLiteral(
"shape" ) );
2839 symEl.save( stream, 4 );
2840 query =
QgsSqlite3Mprintf(
"UPDATE legendpatchshapes SET xml='%q' WHERE name='%q';",
2841 xmlArray.constData(), name.toUtf8().constData() );
2848 QgsDebugMsg( QStringLiteral(
"Updating the unsupported StyleEntity" ) );
2854 if ( !runEmptyQuery( query ) )
2856 QgsDebugMsg( QStringLiteral(
"Couldn't insert symbol into the database!" ) );
2891 mCachedTags[ type ].remove( name );
2894 void QgsStyle::upgradeIfRequired()
2897 auto query =
QgsSqlite3Mprintf(
"SELECT name FROM sqlite_master WHERE name='stylemetadata'" );
2901 statement = mCurrentDB.
prepare( query, rc );
2903 if ( rc != SQLITE_OK || sqlite3_step( statement.get() ) != SQLITE_ROW )
2907 "id INTEGER PRIMARY KEY,"\
2910 runEmptyQuery( query );
2911 query =
QgsSqlite3Mprintf(
"INSERT INTO stylemetadata VALUES (NULL, '%q', '%q')",
"version",
"31200" );
2912 runEmptyQuery( query );
2918 query =
QgsSqlite3Mprintf(
"SELECT value FROM stylemetadata WHERE key='version'" );
2919 statement = mCurrentDB.
prepare( query, rc );
2920 if ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
2932 runEmptyQuery( query );
2942 return QStringLiteral(
"symbol" );
2945 return QStringLiteral(
"colorramp" );
2948 return QStringLiteral(
"textformat" );
2951 return QStringLiteral(
"labelsettings" );
2954 return QStringLiteral(
"legendpatchshapes" );
2957 return QStringLiteral(
"tag" );
2960 return QStringLiteral(
"smartgroup" );
2970 return QStringLiteral(
"tagmap" );
2973 return QStringLiteral(
"ctagmap" );
2976 return QStringLiteral(
"tftagmap" );
2979 return QStringLiteral(
"lstagmap" );
2982 return QStringLiteral(
"lpstagmap" );
2996 return QStringLiteral(
"symbol_id" );
2999 return QStringLiteral(
"colorramp_id" );
3002 return QStringLiteral(
"textformat_id" );
3005 return QStringLiteral(
"labelsettings_id" );
3008 return QStringLiteral(
"legendpatchshape_id" );