26 #include <QDomDocument> 27 #include <QDomElement> 29 #include <QDomNodeList> 31 #include <QTextStream> 37 #define STYLE_CURRENT_VERSION "1" 53 if ( !QFile::exists( styleFilename ) )
83 if ( !symbol || name.isEmpty() )
99 saveSymbol( name, symbol,
false, QStringList() );
108 QDomDocument doc( QStringLiteral(
"dummy" ) );
110 if ( symEl.isNull() )
112 QgsDebugMsg(
"Couldn't convert symbol to valid XML!" );
117 QTextStream stream( &xmlArray );
118 stream.setCodec(
"UTF-8" );
119 symEl.save( stream, 4 );
120 char *query = sqlite3_mprintf(
"INSERT INTO symbol VALUES (NULL, '%q', '%q', %d);",
121 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
125 QgsDebugMsg(
"Couldn't insert symbol into the database!" );
149 QgsDebugMsg(
"Sorry! Cannot open database to tag." );
156 QgsDebugMsg(
"No such symbol for deleting in database: " + name +
". Cheers." );
167 return symbol ? symbol->
clone() :
nullptr;
188 if ( !colorRamp || name.isEmpty() )
213 QDomDocument doc( QStringLiteral(
"dummy" ) );
216 if ( rampEl.isNull() )
218 QgsDebugMsg(
"Couldn't convert color ramp to valid XML!" );
223 QTextStream stream( &xmlArray );
224 stream.setCodec(
"UTF-8" );
225 rampEl.save( stream, 4 );
226 char *query = sqlite3_mprintf(
"INSERT INTO colorramp VALUES (NULL, '%q', '%q', %d);",
227 name.toUtf8().constData(), xmlArray.constData(), ( favorite ? 1 : 0 ) );
230 QgsDebugMsg(
"Couldn't insert colorramp into the database!" );
245 char *query = sqlite3_mprintf(
"DELETE FROM colorramp WHERE name='%q'", name.toUtf8().constData() );
248 QgsDebugMsg(
"Couldn't remove color ramp from the database." );
260 return ramp ? ramp->
clone() :
nullptr;
295 mErrorString = QStringLiteral(
"Unable to create database" );
310 mErrorString = QStringLiteral(
"Unable to create temporary memory database" );
322 char *query = sqlite3_mprintf(
"CREATE TABLE symbol("\
323 "id INTEGER PRIMARY KEY,"\
326 "favorite INTEGER);"\
327 "CREATE TABLE colorramp("\
328 "id INTEGER PRIMARY KEY,"\
331 "favorite INTEGER);"\
333 "id INTEGER PRIMARY KEY,"\
335 "CREATE TABLE tagmap("\
336 "tag_id INTEGER NOT NULL,"\
337 "symbol_id INTEGER);"\
338 "CREATE TABLE ctagmap("\
339 "tag_id INTEGER NOT NULL,"\
340 "colorramp_id INTEGER);"\
341 "CREATE TABLE smartgroup("\
342 "id INTEGER PRIMARY KEY,"\
355 mErrorString = QStringLiteral(
"Unable to open database file specified" );
361 char *query = sqlite3_mprintf(
"UPDATE symbol SET favorite=0 WHERE favorite IS NULL;" 362 "UPDATE colorramp SET favorite=0 WHERE favorite IS NULL;" 367 query = sqlite3_mprintf(
"SELECT * FROM symbol" );
373 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
378 if ( !doc.setContent( xmlstring ) )
380 QgsDebugMsg(
"Cannot open symbol " + symbol_name );
384 QDomElement symElement = doc.documentElement();
387 mSymbols.insert( symbol_name, symbol );
390 query = sqlite3_mprintf(
"SELECT * FROM colorramp" );
392 while ( rc == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
397 if ( !doc.setContent( xmlstring ) )
402 QDomElement rampElement = doc.documentElement();
418 if ( filename.isEmpty() )
424 QDomDocument doc(
"qgis_style" );
425 QDomElement root = doc.createElement(
"qgis_style" );
427 doc.appendChild( root );
431 QDomElement rampsElem = doc.createElement(
"colorramps" );
434 for ( QMap<QString, QgsColorRamp *>::iterator itr =
mColorRamps.begin(); itr !=
mColorRamps.end(); ++itr )
437 rampsElem.appendChild( rampEl );
440 root.appendChild( symbolsElem );
441 root.appendChild( rampsElem );
445 if ( !f.open( QFile::WriteOnly ) )
447 mErrorString =
"Couldn't open file for writing: " + filename;
450 QTextStream ts( &f );
451 ts.setCodec(
"UTF-8" );
464 QgsDebugMsg(
"Symbol of new name already exists" );
476 QgsDebugMsg(
"Sorry! Cannot open database to tag." );
483 QgsDebugMsg(
"No such symbol for tagging in database: " + oldName );
496 QgsDebugMsg(
"Color ramp of new name already exists." );
508 char *query = sqlite3_mprintf(
"SELECT id FROM colorramp WHERE name='%q'", oldName.toUtf8().constData() );
511 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
513 rampid = sqlite3_column_int( statement.get(), 0 );
524 QgsDebugMsg( QString(
"Cannot Open database for getting favorite symbols" ) );
525 return QStringList();
528 char *query =
nullptr;
531 query = sqlite3_mprintf(
"SELECT name FROM symbol WHERE favorite=1" );
535 query = sqlite3_mprintf(
"SELECT name FROM colorramp WHERE favorite=1" );
540 return QStringList();
548 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
560 QgsDebugMsg( QString(
"Cannot open database to get symbols of tagid %1" ).arg( tagid ) );
561 return QStringList();
564 char *subquery =
nullptr;
567 subquery = sqlite3_mprintf(
"SELECT symbol_id FROM tagmap WHERE tag_id=%d", tagid );
571 subquery = sqlite3_mprintf(
"SELECT colorramp_id FROM ctagmap WHERE tag_id=%d", tagid );
576 return QStringList();
585 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
587 int id = sqlite3_column_int( statement.get(), 0 );
590 ? sqlite3_mprintf(
"SELECT name FROM symbol WHERE id=%d",
id )
591 : sqlite3_mprintf(
"SELECT name FROM colorramp WHERE id=%d",
id );
596 while ( rc == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
598 symbols << QString::fromUtf8( reinterpret_cast< const char * >( sqlite3_column_text( statement2.get(), 0 ) ) );
611 char *query = sqlite3_mprintf(
"INSERT INTO tag VALUES (NULL, '%q')", tagname.toUtf8().constData() );
614 if ( nErr == SQLITE_OK )
615 ( void )sqlite3_step( statement.get() );
618 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
622 return static_cast< int >( sqlite3_last_insert_rowid(
mCurrentDB.get() ) );
628 return QStringList();
632 char *query = sqlite3_mprintf(
"SELECT name FROM tag" );
637 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
647 bool groupRenamed =
false;
648 char *query =
nullptr;
652 query = sqlite3_mprintf(
"UPDATE symbol SET name='%q' WHERE id=%d", newName.toUtf8().constData(), id );
655 query = sqlite3_mprintf(
"UPDATE colorramp SET name='%q' WHERE id=%d", newName.toUtf8().constData(), id );
658 query = sqlite3_mprintf(
"UPDATE tag SET name='%q' WHERE id=%d", newName.toUtf8().constData(), id );
662 query = sqlite3_mprintf(
"UPDATE smartgroup SET name='%q' WHERE id=%d", newName.toUtf8().constData(), id );
684 bool groupRemoved =
false;
685 char *query =
nullptr;
689 query = sqlite3_mprintf(
"DELETE FROM symbol WHERE id=%d; DELETE FROM tagmap WHERE symbol_id=%d",
id,
id );
692 query = sqlite3_mprintf(
"DELETE FROM colorramp WHERE id=%d",
id );
695 query = sqlite3_mprintf(
"DELETE FROM tag WHERE id=%d; DELETE FROM tagmap WHERE tag_id=%d",
id,
id );
699 query = sqlite3_mprintf(
"DELETE FROM smartgroup WHERE id=%d",
id );
716 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
728 char *zErr =
nullptr;
729 int nErr = sqlite3_exec(
mCurrentDB.get(), query,
nullptr,
nullptr, &zErr );
733 sqlite3_free( query );
736 if ( nErr != SQLITE_OK )
739 sqlite3_free( zErr );
742 return zErr == SQLITE_OK;
747 char *query =
nullptr;
752 query = sqlite3_mprintf(
"UPDATE symbol SET favorite=1 WHERE name='%q'", name.toUtf8().constData() );
755 query = sqlite3_mprintf(
"UPDATE colorramp SET favorite=1 WHERE name='%q'", name.toUtf8().constData() );
759 QgsDebugMsg(
"Wrong entity value. cannot apply group" );
768 char *query =
nullptr;
773 query = sqlite3_mprintf(
"UPDATE symbol SET favorite=0 WHERE name='%q'", name.toUtf8().constData() );
776 query = sqlite3_mprintf(
"UPDATE colorramp SET favorite=0 WHERE name='%q'", name.toUtf8().constData() );
780 QgsDebugMsg(
"Wrong entity value. cannot apply group" );
791 QgsDebugMsg(
"Sorry! Cannot open database to search" );
792 return QStringList();
796 QString item = ( type ==
SymbolEntity ) ? QStringLiteral(
"symbol" ) : QStringLiteral(
"colorramp" );
797 char *query = sqlite3_mprintf(
"SELECT name FROM %q WHERE name LIKE '%%%q%%'",
798 item.toUtf8().constData(), qword.toUtf8().constData() );
803 QSet< QString > symbols;
804 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
810 query = sqlite3_mprintf(
"SELECT id FROM tag WHERE name LIKE '%%%q%%'", qword.toUtf8().constData() );
814 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
816 tagids << QString::fromUtf8( (
const char * ) sqlite3_column_text( statement.get(), 0 ) );
819 QString dummy = tagids.join( QStringLiteral(
", " ) );
823 query = sqlite3_mprintf(
"SELECT symbol_id FROM tagmap WHERE tag_id IN (%q)",
824 dummy.toUtf8().constData() );
828 query = sqlite3_mprintf(
"SELECT colorramp_id FROM ctagmap WHERE tag_id IN (%q)",
829 dummy.toUtf8().constData() );
833 QStringList symbolids;
834 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
836 symbolids << QString::fromUtf8( (
const char * ) sqlite3_column_text( statement.get(), 0 ) );
839 dummy = symbolids.join( QStringLiteral(
", " ) );
840 query = sqlite3_mprintf(
"SELECT name FROM %q WHERE id IN (%q)",
841 item.toUtf8().constData(), dummy.toUtf8().constData() );
843 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
845 symbols << QString::fromUtf8( (
const char * ) sqlite3_column_text( statement.get(), 0 ) );
848 return symbols.toList();
855 QgsDebugMsg(
"Sorry! Cannot open database to tag." );
862 QgsDebugMsg(
"No such symbol for tagging in database: " + symbol );
867 Q_FOREACH (
const QString &t, tags )
870 if ( !tag.isEmpty() )
873 char *query = sqlite3_mprintf(
"SELECT id FROM tag WHERE LOWER(name)='%q'", tag.toUtf8().toLower().constData() );
879 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
881 tagid = sqlite3_column_int( statement.get(), 0 );
892 ? sqlite3_mprintf(
"INSERT INTO tagmap VALUES (%d,%d)", tagid, symbolid )
893 : sqlite3_mprintf(
"INSERT INTO ctagmap VALUES (%d,%d)", tagid, symbolid );
895 char *zErr =
nullptr;
896 nErr = sqlite3_exec(
mCurrentDB.get(), query,
nullptr,
nullptr, &zErr );
912 QgsDebugMsg(
"Sorry! Cannot open database for detgging." );
917 ? sqlite3_mprintf(
"SELECT id FROM symbol WHERE name='%q'", symbol.toUtf8().constData() )
918 : sqlite3_mprintf(
"SELECT id FROM colorramp WHERE name='%q'", symbol.toUtf8().constData() );
923 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
925 symbolid = sqlite3_column_int( statement.get(), 0 );
932 Q_FOREACH (
const QString &
tag, tags )
934 query = sqlite3_mprintf(
"SELECT id FROM tag WHERE name='%q'", tag.toUtf8().constData() );
940 if ( nErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
942 tagid = sqlite3_column_int( statement2.get(), 0 );
949 ? sqlite3_mprintf(
"DELETE FROM tagmap WHERE tag_id=%d AND symbol_id=%d", tagid, symbolid )
950 : sqlite3_mprintf(
"DELETE FROM ctagmap WHERE tag_id=%d AND colorramp_id=%d", tagid, symbolid );
965 QgsDebugMsg(
"Sorry! Cannot open database for detgging." );
970 ? sqlite3_mprintf(
"SELECT id FROM symbol WHERE name='%q'", symbol.toUtf8().constData() )
971 : sqlite3_mprintf(
"SELECT id FROM colorramp WHERE name='%q'", symbol.toUtf8().constData() );
977 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
979 symbolid = sqlite3_column_int( statement.get(), 0 );
988 ? sqlite3_mprintf(
"DELETE FROM tagmap WHERE symbol_id=%d", symbolid )
989 : sqlite3_mprintf(
"DELETE FROM ctagmap WHERE colorramp_id=%d", symbolid );
1002 QgsDebugMsg(
"Sorry! Cannot open database for getting the tags." );
1003 return QStringList();
1008 return QStringList();
1012 ? sqlite3_mprintf(
"SELECT tag_id FROM tagmap WHERE symbol_id=%d", symbolid )
1013 : sqlite3_mprintf(
"SELECT tag_id FROM ctagmap WHERE colorramp_id=%d", symbolid );
1018 QStringList tagList;
1019 while ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1021 char *subquery = sqlite3_mprintf(
"SELECT name FROM tag WHERE id=%d", sqlite3_column_int( statement.get(), 0 ) );
1026 if ( pErr == SQLITE_OK && sqlite3_step( statement2.get() ) == SQLITE_ROW )
1028 tagList << QString::fromUtf8( reinterpret_cast< const char * >( sqlite3_column_text( statement2.get(), 0 ) ) );
1039 QgsDebugMsg(
"Sorry! Cannot open database for getting the tags." );
1048 int tagid =
tagId( tag );
1056 ? sqlite3_mprintf(
"SELECT tag_id FROM tagmap WHERE tag_id=%d AND symbol_id=%d", tagid, symbolid )
1057 : sqlite3_mprintf(
"SELECT tag_id FROM ctagmap WHERE tag_id=%d AND colorramp_id=%d", tagid, symbolid );
1062 return ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW );
1072 char *query = sqlite3_mprintf(
"SELECT name FROM tag WHERE id=%d",
id );
1077 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1087 char *query = sqlite3_mprintf(
"SELECT id FROM %q WHERE LOWER(name)='%q'", table.toUtf8().constData(), name.toUtf8().toLower().constData() );
1093 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1095 id = sqlite3_column_int( statement.get(), 0 );
1103 char *query = sqlite3_mprintf(
"SELECT name FROM %q WHERE id='%q'", table.toUtf8().constData(), QString::number(
id ).toUtf8().constData() );
1109 if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1119 return getId( QStringLiteral(
"symbol" ), name );
1124 return getId( QStringLiteral(
"colorramp" ), name );
1129 return getId( QStringLiteral(
"tag" ), name );
1134 return getId( QStringLiteral(
"smartgroup" ), name );
1139 QDomDocument doc( QStringLiteral(
"dummy" ) );
1140 QDomElement smartEl = doc.createElement( QStringLiteral(
"smartgroup" ) );
1141 smartEl.setAttribute( QStringLiteral(
"name" ), name );
1142 smartEl.setAttribute( QStringLiteral(
"operator" ), op );
1144 QStringList constraints;
1145 constraints << QStringLiteral(
"tag" ) << QStringLiteral(
"group" ) << QStringLiteral(
"name" ) << QStringLiteral(
"!tag" ) << QStringLiteral(
"!group" ) << QStringLiteral(
"!name" );
1147 Q_FOREACH (
const QString &constraint, constraints )
1149 QStringList parameters = conditions.values( constraint );
1150 Q_FOREACH (
const QString ¶m, parameters )
1152 QDomElement condEl = doc.createElement( QStringLiteral(
"condition" ) );
1153 condEl.setAttribute( QStringLiteral(
"constraint" ), constraint );
1154 condEl.setAttribute( QStringLiteral(
"param" ), param );
1155 smartEl.appendChild( condEl );
1159 QByteArray xmlArray;
1160 QTextStream stream( &xmlArray );
1161 stream.setCodec(
"UTF-8" );
1162 smartEl.save( stream, 4 );
1163 char *query = sqlite3_mprintf(
"INSERT INTO smartgroup VALUES (NULL, '%q', '%q')",
1164 name.toUtf8().constData(), xmlArray.constData() );
1169 settings.
setValue( QStringLiteral(
"qgis/symbolsListGroupsIndex" ), 0 );
1172 return static_cast< int >( sqlite3_last_insert_rowid(
mCurrentDB.get() ) );
1176 QgsDebugMsg(
"Couldn't insert symbol into the database!" );
1185 QgsDebugMsg(
"Cannot open database for listing groups" );
1189 char *query = sqlite3_mprintf(
"SELECT * FROM smartgroup" );
1197 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1200 groupNames.insert( sqlite3_column_int( statement.get(),
SmartgroupId ), group );
1210 QgsDebugMsg(
"Cannot open database for listing groups" );
1211 return QStringList();
1214 char *query = sqlite3_mprintf(
"SELECT name FROM smartgroup" );
1222 while ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1232 QStringList symbols;
1234 char *query = sqlite3_mprintf(
"SELECT xml FROM smartgroup WHERE id=%d",
id );
1238 if ( !( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW ) )
1240 return QStringList();
1246 if ( !doc.setContent( xmlstr ) )
1248 QgsDebugMsg( QString(
"Cannot open smartgroup id: %1" ).arg(
id ) );
1250 QDomElement smartEl = doc.documentElement();
1251 QString op = smartEl.attribute( QStringLiteral(
"operator" ) );
1252 QDomNodeList conditionNodes = smartEl.childNodes();
1254 bool firstSet =
true;
1255 for (
int i = 0; i < conditionNodes.count(); i++ )
1257 QDomElement condEl = conditionNodes.at( i ).toElement();
1258 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
1259 QString param = condEl.attribute( QStringLiteral(
"param" ) );
1261 QStringList resultNames;
1263 if ( constraint == QLatin1String(
"tag" ) )
1267 else if ( constraint == QLatin1String(
"name" ) )
1271 resultNames =
symbolNames().filter( param, Qt::CaseInsensitive );
1275 resultNames =
colorRampNames().filter( param, Qt::CaseInsensitive );
1278 else if ( constraint == QLatin1String(
"!tag" ) )
1282 Q_FOREACH (
const QString &name, unwanted )
1284 resultNames.removeAll( name );
1287 else if ( constraint == QLatin1String(
"!name" ) )
1290 Q_FOREACH (
const QString &str, all )
1292 if ( !str.contains( param, Qt::CaseInsensitive ) )
1300 symbols = resultNames;
1305 if ( op == QLatin1String(
"OR" ) )
1307 symbols << resultNames;
1309 else if ( op == QLatin1String(
"AND" ) )
1311 QStringList dummy = symbols;
1313 Q_FOREACH (
const QString &result, resultNames )
1315 if ( dummy.contains( result ) )
1330 QgsDebugMsg(
"Cannot open database for listing groups" );
1336 char *query = sqlite3_mprintf(
"SELECT xml FROM smartgroup WHERE id=%d",
id );
1341 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1345 if ( !doc.setContent( xmlstr ) )
1347 QgsDebugMsg( QString(
"Cannot open smartgroup id: %1" ).arg(
id ) );
1350 QDomElement smartEl = doc.documentElement();
1351 QDomNodeList conditionNodes = smartEl.childNodes();
1353 for (
int i = 0; i < conditionNodes.count(); i++ )
1355 QDomElement condEl = conditionNodes.at( i ).toElement();
1356 QString constraint = condEl.attribute( QStringLiteral(
"constraint" ) );
1357 QString param = condEl.attribute( QStringLiteral(
"param" ) );
1359 condition.insert( constraint, param );
1370 QgsDebugMsg(
"Cannot open database for listing groups" );
1376 char *query = sqlite3_mprintf(
"SELECT xml FROM smartgroup WHERE id=%d",
id );
1381 if ( nError == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1385 if ( !doc.setContent( xmlstr ) )
1387 QgsDebugMsg( QString(
"Cannot open smartgroup id: %1" ).arg(
id ) );
1389 QDomElement smartEl = doc.documentElement();
1390 op = smartEl.attribute( QStringLiteral(
"operator" ) );
1398 if ( filename.isEmpty() )
1400 QgsDebugMsg(
"Invalid filename for style export." );
1404 QDomDocument doc( QStringLiteral(
"qgis_style" ) );
1405 QDomElement root = doc.createElement( QStringLiteral(
"qgis_style" ) );
1407 doc.appendChild( root );
1414 QDomNodeList symbolsList = symbolsElem.elementsByTagName( QStringLiteral(
"symbol" ) );
1415 int nbSymbols = symbolsList.count();
1416 for (
int i = 0; i < nbSymbols; ++i )
1418 QDomElement
symbol = symbolsList.at( i ).toElement();
1419 QString name = symbol.attribute( QStringLiteral(
"name" ) );
1421 if ( tags.count() > 0 )
1423 symbol.setAttribute( QStringLiteral(
"tags" ), tags.join(
',' ) );
1425 if ( favoriteSymbols.contains( name ) )
1427 symbol.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
1432 QDomElement rampsElem = doc.createElement( QStringLiteral(
"colorramps" ) );
1433 for ( QMap<QString, QgsColorRamp *>::const_iterator itr =
mColorRamps.constBegin(); itr !=
mColorRamps.constEnd(); ++itr )
1437 if ( tags.count() > 0 )
1439 rampEl.setAttribute( QStringLiteral(
"tags" ), tags.join(
',' ) );
1441 if ( favoriteColorramps.contains( itr.key() ) )
1443 rampEl.setAttribute( QStringLiteral(
"favorite" ), QStringLiteral(
"1" ) );
1445 rampsElem.appendChild( rampEl );
1448 root.appendChild( symbolsElem );
1449 root.appendChild( rampsElem );
1452 QFile
f( filename );
1453 if ( !f.open( QFile::WriteOnly | QIODevice::Truncate ) )
1455 mErrorString =
"Couldn't open file for writing: " + filename;
1459 QTextStream ts( &f );
1460 ts.setCodec(
"UTF-8" );
1471 QDomDocument doc( QStringLiteral(
"style" ) );
1472 QFile
f( filename );
1473 if ( !f.open( QFile::ReadOnly ) )
1475 mErrorString = QStringLiteral(
"Unable to open the specified file" );
1476 QgsDebugMsg(
"Error opening the style XML file." );
1480 if ( !doc.setContent( &f ) )
1482 mErrorString = QStringLiteral(
"Unable to understand the style file: %1" ).arg( filename );
1489 QDomElement docEl = doc.documentElement();
1490 if ( docEl.tagName() != QLatin1String(
"qgis_style" ) )
1492 mErrorString =
"Incorrect root tag in style: " + docEl.tagName();
1496 QString version = docEl.attribute( QStringLiteral(
"version" ) );
1499 mErrorString =
"Unknown style file version: " + version;
1505 QDomElement symbolsElement = docEl.firstChildElement( QStringLiteral(
"symbols" ) );
1506 QDomElement e = symbolsElement.firstChildElement();
1509 char *query =
nullptr;
1510 query = sqlite3_mprintf(
"BEGIN TRANSACTION;" );
1516 while ( !e.isNull() )
1518 if ( e.tagName() == QLatin1String(
"symbol" ) )
1520 QString name = e.attribute( QStringLiteral(
"name" ) );
1522 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
1524 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
1526 bool favorite =
false;
1527 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QStringLiteral(
"1" ) )
1546 e = e.nextSiblingElement();
1555 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
1562 QDomElement rampsElement = docEl.firstChildElement( QStringLiteral(
"colorramps" ) );
1563 e = rampsElement.firstChildElement();
1564 while ( !e.isNull() )
1566 if ( e.tagName() == QLatin1String(
"colorramp" ) )
1568 QString name = e.attribute( QStringLiteral(
"name" ) );
1570 if ( e.hasAttribute( QStringLiteral(
"tags" ) ) )
1572 tags = e.attribute( QStringLiteral(
"tags" ) ).split(
',' );
1574 bool favorite =
false;
1575 if ( e.hasAttribute( QStringLiteral(
"favorite" ) ) && e.attribute( QStringLiteral(
"favorite" ) ) == QStringLiteral(
"1" ) )
1594 e = e.nextSiblingElement();
1597 query = sqlite3_mprintf(
"COMMIT TRANSACTION;" );
1606 QDomDocument doc( QStringLiteral(
"dummy" ) );
1608 QByteArray xmlArray;
1609 QTextStream stream( &xmlArray );
1610 stream.setCodec(
"UTF-8" );
1612 char *query =
nullptr;
1619 QgsDebugMsg(
"Update request received for unavailable symbol" );
1624 if ( symEl.isNull() )
1626 QgsDebugMsg(
"Couldn't convert symbol to valid XML!" );
1629 symEl.save( stream, 4 );
1630 query = sqlite3_mprintf(
"UPDATE symbol SET xml='%q' WHERE name='%q';",
1631 xmlArray.constData(), name.toUtf8().constData() );
1637 QgsDebugMsg(
"Update requested for unavailable color ramp." );
1641 std::unique_ptr< QgsColorRamp > ramp(
colorRamp( name ) );
1643 if ( symEl.isNull() )
1645 QgsDebugMsg(
"Couldn't convert color ramp to valid XML!" );
1648 symEl.save( stream, 4 );
1649 query = sqlite3_mprintf(
"UPDATE colorramp SET xml='%q' WHERE name='%q';",
1650 xmlArray.constData(), name.toUtf8().constData() );
1654 QgsDebugMsg(
"Updating the unsupported StyleEntity" );
1661 QgsDebugMsg(
"Couldn't insert symbol into the database!" );
int getId(const QString &table, const QString &name)
Gets the id from the table for the given name from the database, 0 if not found.
bool exportXml(const QString &filename)
Exports the style as a XML file.
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 addColorRamp(const QString &name, QgsColorRamp *colorRamp, bool update=false)
Adds a color ramp to the style.
void symbolSaved(const QString &name, QgsSymbol *symbol)
Is emitted every time a new symbol has been added to the database.
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)
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.
Unique pointer for sqlite3 prepared statements, which automatically finalizes the statement when the ...
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.
void remove(StyleEntity type, int id)
Removes the specified entity from the db.
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 DB.
bool updateSymbol(StyleEntity type, const QString &name)
Updates the properties of an existing symbol/colorramp.
static QDomElement saveColorRamp(const QString &name, QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
bool tagSymbol(StyleEntity type, const QString &symbol, const QStringList &tags)
Tags the symbol with the tags in the list.
static QgsSymbol * loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
QgsColorRamp * colorRamp(const QString &name) const
Returns a new copy of the specified color ramp.
bool removeColorRamp(const QString &name)
Removes color ramp from style (and delete it)
#define STYLE_CURRENT_VERSION
static QgsStyle * defaultStyle()
Returns default application-wide style.
StyleEntity
Enum for Entities involved in a style.
static QString defaultStylePath()
Returns the path to default style (works as a starting point).
QString errorMessage() const
Returns the most recent error message encountered by the database.
int symbolCount()
Returns count of symbols in style.
void setValue(const QString &key, const QVariant &value, const QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
bool renameSymbol(const QString &oldName, const QString &newName)
Changessymbol's name.
QString tag(int id) const
Returns the tag name for the given id.
QString getName(const QString &table, int id) const
Gets the name from the table for the given id from the database, empty if not found.
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)
QStringList symbolNames()
Returns a list of names of symbols.
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.
bool removeFavorite(StyleEntity type, const QString &name)
Removes the specified symbol from favorites.
static QgsStyle * sDefaultStyle
QStringList findSymbols(StyleEntity type, const QString &qword)
Returns the names of the symbols which have a matching 'substring' in its definition.
void groupsModified()
Is emitted every time a tag or smartgroup has been added, removed, or renamed.
QgsStyle()=default
Constructor for QgsStyle.
int addTag(const QString &tagName)
Adds a new tag and returns the tag's id.
bool runEmptyQuery(char *query, bool freeQuery=true)
Convenience function that would run queries which don't generate return values.
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.
bool createMemoryDatabase()
Creates a temporary memory database.
QString smartgroupOperator(int id)
Returns the operator for the smartgroup clumsy implementation TODO create a class for smartgroups...
sqlite3_statement_unique_ptr prepare(const QString &sql, int &resultCode) const
Prepares a sql statement, returning the result.
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 ...
QgsVectorColorRampMap mColorRamps
int open(const QString &path)
Opens the database at the specified file path.
void rename(StyleEntity type, int id, const QString &newName)
Renames the given entity with the specified id.
QgsSmartConditionMap smartgroup(int id)
Returns the QgsSmartConditionMap for the given id.
QStringList colorRampNames()
Returns a list of names of color ramps.
QStringList symbolsOfSmartgroup(StyleEntity type, int id)
Returns the symbols for the smartgroup.
int smartgroupId(const QString &smartgroup)
Returns the DB id for the given smartgroup name.
QStringList smartgroupNames()
Returns the smart groups list.
int tagId(const QString &tag)
Returns the DB id for the given tag name.
bool addSymbol(const QString &name, QgsSymbol *symbol, bool update=false)
Adds a symbol to style and takes symbol's ownership.
QStringList tags() const
Returns a list of all tags in the style database.
int addSmartgroup(const QString &name, const QString &op, const QgsSmartConditionMap &conditions)
Adds a new smartgroup to the database and returns the id.
bool openDatabase(const QString &filename)
Convenience function to open the DB and return a sqlite3 object.
bool createDatabase(const QString &filename)
Creates an on-disk database.
virtual QgsSymbol * clone() const =0
Get a deep copy of this symbol.
int colorrampId(const QString &name)
Returns the id in the style database for the given colorramp name returns 0 if not found...
int symbolId(const QString &name)
Returns the id in the style database for the given symbol name returns 0 if not found.
sqlite3_database_unique_ptr mCurrentDB
QMap< QString, QgsSymbol *> QgsSymbolMap
static QDomElement saveSymbol(const QString &symbolName, QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
bool renameColorRamp(const QString &oldName, const QString &newName)
Changes ramp's name.
int colorRampCount()
Returns count of color ramps.
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 DB with the tags.
bool removeSymbol(const QString &name)
Removes symbol from style (and delete it)
bool addFavorite(StyleEntity type, const QString &name)
Adds the specified symbol to favorites.
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.
QMultiMap< QString, QString > QgsSmartConditionMap
A multimap to hold the smart group conditions as constraint and parameter pairs.
QgsSymbolGroupMap smartgroupsListMap()
Returns the smart groups map with id as key and name as value.