Skip to content

Commit b3c31d3

Browse files
committedJun 13, 2018
[bugfix] Fix symbol tags with cyrillic names
... and other non-ascii as well Fixes #18282 - Style Manager - Impossible to work with non-Latin characters (tag or symbol names)
1 parent 3f938e4 commit b3c31d3

File tree

2 files changed

+49
-19
lines changed

2 files changed

+49
-19
lines changed
 

‎src/core/symbology/qgsstyle.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -870,29 +870,21 @@ bool QgsStyle::tagSymbol( StyleEntity type, const QString &symbol, const QString
870870
if ( !tag.isEmpty() )
871871
{
872872
// sql: gets the id of the tag if present or insert the tag and get the id of the tag
873-
auto query = QgsSqlite3Mprintf( "SELECT id FROM tag WHERE LOWER(name)='%q'", tag.toUtf8().toLower().constData() );
874-
875-
sqlite3_statement_unique_ptr statement;
876-
int nErr; statement = mCurrentDB.prepare( query, nErr );
877-
878-
int tagid;
879-
if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
880-
{
881-
tagid = sqlite3_column_int( statement.get(), 0 );
882-
}
883-
else
873+
int tagid( tagId( tag ) );
874+
if ( ! tagid )
884875
{
885876
tagid = addTag( tag );
886877
}
887878

888879
// Now map the tag to the symbol if it's not already tagged
889880
if ( !symbolHasTag( type, symbol, tag ) )
890881
{
891-
query = type == SymbolEntity
892-
? QgsSqlite3Mprintf( "INSERT INTO tagmap VALUES (%d,%d)", tagid, symbolid )
893-
: QgsSqlite3Mprintf( "INSERT INTO ctagmap VALUES (%d,%d)", tagid, symbolid );
882+
auto query = type == SymbolEntity
883+
? QgsSqlite3Mprintf( "INSERT INTO tagmap VALUES (%d,%d)", tagid, symbolid )
884+
: QgsSqlite3Mprintf( "INSERT INTO ctagmap VALUES (%d,%d)", tagid, symbolid );
894885

895886
char *zErr = nullptr;
887+
int nErr;
896888
nErr = sqlite3_exec( mCurrentDB.get(), query.toUtf8().constData(), nullptr, nullptr, &zErr );
897889
if ( nErr )
898890
{
@@ -963,7 +955,7 @@ bool QgsStyle::detagSymbol( StyleEntity type, const QString &symbol )
963955
{
964956
if ( !mCurrentDB )
965957
{
966-
QgsDebugMsg( "Sorry! Cannot open database for detgging." );
958+
QgsDebugMsg( "Sorry! Cannot open database for detagging." );
967959
return false;
968960
}
969961

@@ -1085,7 +1077,8 @@ QString QgsStyle::tag( int id ) const
10851077

10861078
int QgsStyle::getId( const QString &table, const QString &name )
10871079
{
1088-
auto query = QgsSqlite3Mprintf( "SELECT id FROM %q WHERE LOWER(name)='%q'", table.toUtf8().constData(), name.toUtf8().toLower().constData() );
1080+
QString lowerName( name.toLower() );
1081+
auto query = QgsSqlite3Mprintf( "SELECT id FROM %q WHERE LOWER(name)='%q'", table.toUtf8().constData(), lowerName.toUtf8().constData() );
10891082

10901083
sqlite3_statement_unique_ptr statement;
10911084
int nErr; statement = mCurrentDB.prepare( query, nErr );
@@ -1095,6 +1088,18 @@ int QgsStyle::getId( const QString &table, const QString &name )
10951088
{
10961089
id = sqlite3_column_int( statement.get(), 0 );
10971090
}
1091+
else
1092+
{
1093+
// Try the name without lowercase conversion
1094+
auto query = QgsSqlite3Mprintf( "SELECT id FROM %q WHERE name='%q'", table.toUtf8().constData(), name.toUtf8().constData() );
1095+
1096+
sqlite3_statement_unique_ptr statement;
1097+
int nErr; statement = mCurrentDB.prepare( query, nErr );
1098+
if ( nErr == SQLITE_OK && sqlite3_step( statement.get() ) == SQLITE_ROW )
1099+
{
1100+
id = sqlite3_column_int( statement.get(), 0 );
1101+
}
1102+
}
10981103

10991104
return id;
11001105
}

‎tests/src/core/testqgsstyle.cpp

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,28 +291,35 @@ void TestStyle::testTags()
291291
QCOMPARE( id, mStyle->tagId( "purple" ) );
292292
QCOMPARE( QStringLiteral( "purple" ), mStyle->tag( id ) );
293293

294+
// Cyrillic
295+
id = mStyle->addTag( QStringLiteral( "МЕТЕОР" ) );
296+
QCOMPARE( id, mStyle->tagId( "МЕТЕОР" ) );
297+
294298
QStringList tags = mStyle->tags();
295-
QCOMPARE( tags.count(), 5 );
299+
QCOMPARE( tags.count(), 6 );
296300
QVERIFY( tags.contains( "red" ) );
297301
QVERIFY( tags.contains( "starry" ) );
298302
QVERIFY( tags.contains( "circle" ) );
299303
QVERIFY( tags.contains( "blue" ) );
300304
QVERIFY( tags.contains( "purple" ) );
305+
QVERIFY( tags.contains( "МЕТЕОР" ) );
301306

302307
//remove tag
303308
mStyle->remove( QgsStyle::TagEntity, mStyle->tagId( QStringLiteral( "purple" ) ) );
304309
mStyle->remove( QgsStyle::TagEntity, -999 ); //bad id
305310
tags = mStyle->tags();
306-
QCOMPARE( tags.count(), 4 );
311+
QCOMPARE( tags.count(), 5 );
307312
QVERIFY( !tags.contains( "purple" ) );
308313

309314
//add some symbols
310315
std::unique_ptr< QgsMarkerSymbol> sym1( QgsMarkerSymbol::createSimple( QgsStringMap() ) );
311316
std::unique_ptr< QgsMarkerSymbol> sym2( QgsMarkerSymbol::createSimple( QgsStringMap() ) );
312317
std::unique_ptr< QgsMarkerSymbol> sym3( QgsMarkerSymbol::createSimple( QgsStringMap() ) );
318+
std::unique_ptr< QgsMarkerSymbol> sym4( QgsMarkerSymbol::createSimple( QgsStringMap() ) );
313319
QVERIFY( mStyle->saveSymbol( "symbol1", sym1.get(), false, QStringList() << "red" << "starry" ) );
314320
mStyle->addSymbol( QStringLiteral( "blue starry" ), sym2.release(), true );
315321
mStyle->addSymbol( QStringLiteral( "red circle" ), sym3.release(), true );
322+
mStyle->addSymbol( QStringLiteral( "МЕТЕОР" ), sym4.release(), true );
316323

317324
//tag them
318325
QVERIFY( mStyle->tagSymbol( QgsStyle::SymbolEntity, "blue starry", QStringList() << "blue" << "starry" ) );
@@ -324,6 +331,13 @@ void TestStyle::testTags()
324331
tags = mStyle->tags();
325332
QVERIFY( tags.contains( "round" ) );
326333

334+
// Cyrillic
335+
// Add twice (see issue #18281)
336+
QVERIFY( mStyle->tagSymbol( QgsStyle::SymbolEntity, "МЕТЕОР", QStringList() << "МЕТЕОР" ) );
337+
tags = mStyle->tags();
338+
QVERIFY( tags.contains( "МЕТЕОР" ) );
339+
QCOMPARE( tags.filter( "МЕТЕОР" ).count(), 1 );
340+
327341
//check that tags have been applied
328342
tags = mStyle->tagsOfSymbol( QgsStyle::SymbolEntity, QStringLiteral( "blue starry" ) );
329343
QCOMPARE( tags.count(), 2 );
@@ -339,8 +353,13 @@ void TestStyle::testTags()
339353
QVERIFY( tags.contains( "red" ) );
340354
QVERIFY( tags.contains( "starry" ) );
341355

356+
tags = mStyle->tagsOfSymbol( QgsStyle::SymbolEntity, QStringLiteral( "МЕТЕОР" ) );
357+
QCOMPARE( tags.count(), 1 );
358+
QVERIFY( tags.contains( "МЕТЕОР" ) );
359+
342360
//check that a given tag is attached to a symbol
343361
QVERIFY( mStyle->symbolHasTag( QgsStyle::SymbolEntity, QStringLiteral( "blue starry" ), QStringLiteral( "blue" ) ) );
362+
QVERIFY( mStyle->symbolHasTag( QgsStyle::SymbolEntity, QStringLiteral( "МЕТЕОР" ), QStringLiteral( "МЕТЕОР" ) ) );
344363

345364
//check that a given tag is not attached to a symbol
346365
QCOMPARE( false, mStyle->symbolHasTag( QgsStyle::SymbolEntity, QStringLiteral( "blue starry" ), QStringLiteral( "notblue" ) ) );
@@ -368,7 +387,9 @@ void TestStyle::testTags()
368387
QVERIFY( symbols.contains( "red circle" ) );
369388
symbols = mStyle->symbolsWithTag( QgsStyle::SymbolEntity, mStyle->tagId( QStringLiteral( "round" ) ) );
370389
QCOMPARE( symbols.count(), 1 );
371-
QVERIFY( symbols.contains( "red circle" ) );
390+
symbols = mStyle->symbolsWithTag( QgsStyle::SymbolEntity, mStyle->tagId( QStringLiteral( "МЕТЕОР" ) ) );
391+
QCOMPARE( symbols.count(), 1 );
392+
QVERIFY( symbols.contains( "МЕТЕОР" ) );
372393
symbols = mStyle->symbolsWithTag( QgsStyle::SymbolEntity, mStyle->tagId( QStringLiteral( "blue" ) ) );
373394
QVERIFY( symbols.isEmpty() );
374395
symbols = mStyle->symbolsWithTag( QgsStyle::SymbolEntity, mStyle->tagId( QStringLiteral( "no tag" ) ) );
@@ -392,6 +413,10 @@ void TestStyle::testTags()
392413
symbols = mStyle->findSymbols( QgsStyle::SymbolEntity, QStringLiteral( "round" ) );
393414
QCOMPARE( symbols.count(), 1 );
394415
QVERIFY( symbols.contains( "red circle" ) );
416+
symbols = mStyle->findSymbols( QgsStyle::SymbolEntity, QStringLiteral( "МЕТЕОР" ) );
417+
QCOMPARE( symbols.count(), 1 );
418+
QVERIFY( symbols.contains( "МЕТЕОР" ) );
419+
395420
}
396421

397422
QGSTEST_MAIN( TestStyle )

0 commit comments

Comments
 (0)
Please sign in to comment.