mirror of
https://github.com/qgis/QGIS.git
synced 2025-06-18 00:04:02 -04:00
Fix searching for symbols by tag (fix #14445), add tests
This commit is contained in:
parent
e404a1c0a3
commit
6be8d06dc6
@ -59,6 +59,12 @@ class QgsStyleV2 : QObject
|
||||
*/
|
||||
int addTag( const QString& tagName );
|
||||
|
||||
/** Returns a list of all tags in the style database
|
||||
* @note added in QGIS 2.16
|
||||
* @see addTag()
|
||||
*/
|
||||
QStringList tags() const;
|
||||
|
||||
//! return a map of groupid and names for the given parent group
|
||||
QMap<int, QString> childGroupNames( const QString& parent = "" );
|
||||
|
||||
|
@ -104,9 +104,7 @@ bool QgsStyleV2::addSymbol( const QString& name, QgsSymbolV2* symbol, bool updat
|
||||
|
||||
bool QgsStyleV2::saveSymbol( const QString& name, QgsSymbolV2* symbol, int groupid, const QStringList& tags )
|
||||
{
|
||||
// TODO add support for tags and groups
|
||||
Q_UNUSED( tags );
|
||||
|
||||
// TODO add support for groups
|
||||
QDomDocument doc( "dummy" );
|
||||
QDomElement symEl = QgsSymbolLayerV2Utils::saveSymbol( name, symbol, doc );
|
||||
if ( symEl.isNull() )
|
||||
@ -128,6 +126,8 @@ bool QgsStyleV2::saveSymbol( const QString& name, QgsSymbolV2* symbol, int group
|
||||
return false;
|
||||
}
|
||||
|
||||
tagSymbol( SymbolEntity, name, tags );
|
||||
|
||||
emit symbolSaved( name, symbol );
|
||||
|
||||
return true;
|
||||
@ -209,9 +209,6 @@ bool QgsStyleV2::addColorRamp( const QString& name, QgsVectorColorRampV2* colorR
|
||||
|
||||
bool QgsStyleV2::saveColorRamp( const QString& name, QgsVectorColorRampV2* ramp, int groupid, const QStringList& tags )
|
||||
{
|
||||
// TODO add support for groups and tags
|
||||
Q_UNUSED( tags );
|
||||
|
||||
// insert it into the database
|
||||
QDomDocument doc( "dummy" );
|
||||
QDomElement rampEl = QgsSymbolLayerV2Utils::saveColorRamp( name, ramp, doc );
|
||||
@ -234,6 +231,8 @@ bool QgsStyleV2::saveColorRamp( const QString& name, QgsVectorColorRampV2* ramp,
|
||||
return false;
|
||||
}
|
||||
|
||||
tagSymbol( ColorrampEntity, name, tags );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -654,6 +653,27 @@ int QgsStyleV2::addTag( const QString& tagname )
|
||||
return static_cast< int >( sqlite3_last_insert_rowid( mCurrentDB ) );
|
||||
}
|
||||
|
||||
QStringList QgsStyleV2::tags() const
|
||||
{
|
||||
if ( !mCurrentDB )
|
||||
return QStringList();
|
||||
|
||||
sqlite3_stmt *ppStmt;
|
||||
|
||||
char *query = sqlite3_mprintf( "SELECT name FROM tag" );
|
||||
int nError = sqlite3_prepare_v2( mCurrentDB, query, -1, &ppStmt, nullptr );
|
||||
|
||||
QStringList tagList;
|
||||
while ( nError == SQLITE_OK && sqlite3_step( ppStmt ) == SQLITE_ROW )
|
||||
{
|
||||
tagList << QString::fromUtf8( reinterpret_cast< const char * >( sqlite3_column_text( ppStmt, 0 ) ) );
|
||||
}
|
||||
|
||||
sqlite3_finalize( ppStmt );
|
||||
|
||||
return tagList;
|
||||
}
|
||||
|
||||
void QgsStyleV2::rename( StyleEntity type, int id, const QString& newName )
|
||||
{
|
||||
char *query;
|
||||
@ -781,6 +801,7 @@ QStringList QgsStyleV2::findSymbols( StyleEntity type, const QString& qword )
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
// first find symbols with matching name
|
||||
QString item = ( type == SymbolEntity ) ? "symbol" : "colorramp";
|
||||
char *query = sqlite3_mprintf( "SELECT name FROM %q WHERE name LIKE '%%%q%%'",
|
||||
item.toUtf8().constData(), qword.toUtf8().constData() );
|
||||
@ -788,7 +809,7 @@ QStringList QgsStyleV2::findSymbols( StyleEntity type, const QString& qword )
|
||||
sqlite3_stmt *ppStmt;
|
||||
int nErr = sqlite3_prepare_v2( mCurrentDB, query, -1, &ppStmt, nullptr );
|
||||
|
||||
QStringList symbols;
|
||||
QSet< QString > symbols;
|
||||
while ( nErr == SQLITE_OK && sqlite3_step( ppStmt ) == SQLITE_ROW )
|
||||
{
|
||||
symbols << QString::fromUtf8( reinterpret_cast< const char * >( sqlite3_column_text( ppStmt, 0 ) ) );
|
||||
@ -796,7 +817,54 @@ QStringList QgsStyleV2::findSymbols( StyleEntity type, const QString& qword )
|
||||
|
||||
sqlite3_finalize( ppStmt );
|
||||
|
||||
return symbols;
|
||||
// next add symbols with matching tags
|
||||
query = sqlite3_mprintf( "SELECT id FROM tag WHERE name LIKE '%%%q%%'", qword.toUtf8().constData() );
|
||||
nErr = sqlite3_prepare_v2( mCurrentDB, query, -1, &ppStmt, NULL );
|
||||
|
||||
QStringList tagids;
|
||||
while ( nErr == SQLITE_OK && sqlite3_step( ppStmt ) == SQLITE_ROW )
|
||||
{
|
||||
tagids << QString::fromUtf8(( const char * ) sqlite3_column_text( ppStmt, 0 ) );
|
||||
}
|
||||
|
||||
sqlite3_finalize( ppStmt );
|
||||
|
||||
|
||||
QString dummy = tagids.join( ", " );
|
||||
|
||||
if ( type == SymbolEntity )
|
||||
{
|
||||
query = sqlite3_mprintf( "SELECT symbol_id FROM tagmap WHERE tag_id IN (%q)",
|
||||
dummy.toUtf8().constData() );
|
||||
}
|
||||
else
|
||||
{
|
||||
query = sqlite3_mprintf( "SELECT colorramp_id FROM ctagmap WHERE tag_id IN (%q)",
|
||||
dummy.toUtf8().constData() );
|
||||
}
|
||||
nErr = sqlite3_prepare_v2( mCurrentDB, query, -1, &ppStmt, NULL );
|
||||
|
||||
QStringList symbolids;
|
||||
while ( nErr == SQLITE_OK && sqlite3_step( ppStmt ) == SQLITE_ROW )
|
||||
{
|
||||
symbolids << QString::fromUtf8(( const char * ) sqlite3_column_text( ppStmt, 0 ) );
|
||||
}
|
||||
|
||||
sqlite3_finalize( ppStmt );
|
||||
|
||||
|
||||
dummy = symbolids.join( ", " );
|
||||
query = sqlite3_mprintf( "SELECT name FROM %q WHERE id IN (%q)",
|
||||
item.toUtf8().constData(), dummy.toUtf8().constData() );
|
||||
nErr = sqlite3_prepare_v2( mCurrentDB, query, -1, &ppStmt, NULL );
|
||||
while ( nErr == SQLITE_OK && sqlite3_step( ppStmt ) == SQLITE_ROW )
|
||||
{
|
||||
symbols << QString::fromUtf8(( const char * ) sqlite3_column_text( ppStmt, 0 ) );
|
||||
}
|
||||
|
||||
sqlite3_finalize( ppStmt );
|
||||
|
||||
return symbols.toList();
|
||||
}
|
||||
|
||||
bool QgsStyleV2::tagSymbol( StyleEntity type, const QString& symbol, const QStringList& tags )
|
||||
@ -870,6 +938,11 @@ bool QgsStyleV2::detagSymbol( StyleEntity type, const QString& symbol, const QSt
|
||||
{
|
||||
symbolid = sqlite3_column_int( ppStmt, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
sqlite3_finalize( ppStmt );
|
||||
return false;
|
||||
}
|
||||
|
||||
sqlite3_finalize( ppStmt );
|
||||
|
||||
|
@ -122,6 +122,12 @@ class CORE_EXPORT QgsStyleV2 : public QObject
|
||||
*/
|
||||
int addTag( const QString& tagName );
|
||||
|
||||
/** Returns a list of all tags in the style database
|
||||
* @note added in QGIS 2.16
|
||||
* @see addTag()
|
||||
*/
|
||||
QStringList tags() const;
|
||||
|
||||
//! return a map of groupid and names for the given parent group
|
||||
QgsSymbolGroupMap childGroupNames( const QString& parent = "" );
|
||||
|
||||
|
@ -65,6 +65,7 @@ class TestStyleV2 : public QObject
|
||||
void testCreateColorRamps();
|
||||
void testLoadColorRamps();
|
||||
void testSaveLoad();
|
||||
void testTags();
|
||||
|
||||
};
|
||||
|
||||
@ -255,5 +256,114 @@ void TestStyleV2::testSaveLoad()
|
||||
testLoadColorRamps();
|
||||
}
|
||||
|
||||
void TestStyleV2::testTags()
|
||||
{
|
||||
mStyle->clear();
|
||||
//add some tags
|
||||
int id = mStyle->addTag( "red" );
|
||||
QCOMPARE( id, mStyle->tagId( "red" ) );
|
||||
id = mStyle->addTag( "starry" );
|
||||
QCOMPARE( id, mStyle->tagId( "starry" ) );
|
||||
id = mStyle->addTag( "circle" );
|
||||
QCOMPARE( id, mStyle->tagId( "circle" ) );
|
||||
id = mStyle->addTag( "blue" );
|
||||
QCOMPARE( id, mStyle->tagId( "blue" ) );
|
||||
id = mStyle->addTag( "purple" );
|
||||
QCOMPARE( id, mStyle->tagId( "purple" ) );
|
||||
|
||||
QStringList tags = mStyle->tags();
|
||||
QCOMPARE( tags.count(), 5 );
|
||||
QVERIFY( tags.contains( "red" ) );
|
||||
QVERIFY( tags.contains( "starry" ) );
|
||||
QVERIFY( tags.contains( "circle" ) );
|
||||
QVERIFY( tags.contains( "blue" ) );
|
||||
QVERIFY( tags.contains( "purple" ) );
|
||||
|
||||
//remove tag
|
||||
mStyle->remove( QgsStyleV2::TagEntity, mStyle->tagId( "purple" ) );
|
||||
mStyle->remove( QgsStyleV2::TagEntity, -999 ); //bad id
|
||||
tags = mStyle->tags();
|
||||
QCOMPARE( tags.count(), 4 );
|
||||
QVERIFY( !tags.contains( "purple" ) );
|
||||
|
||||
//add some symbols
|
||||
QVERIFY( mStyle->saveSymbol( "symbol1", QgsMarkerSymbolV2::createSimple( QgsStringMap() ), 0, QStringList() << "red" << "starry" ) );
|
||||
mStyle->addSymbol( "blue starry", QgsMarkerSymbolV2::createSimple( QgsStringMap() ), true );
|
||||
mStyle->addSymbol( "red circle", QgsMarkerSymbolV2::createSimple( QgsStringMap() ), true );
|
||||
|
||||
//tag them
|
||||
QVERIFY( mStyle->tagSymbol( QgsStyleV2::SymbolEntity, "blue starry", QStringList() << "blue" << "starry" ) );
|
||||
QVERIFY( mStyle->tagSymbol( QgsStyleV2::SymbolEntity, "red circle", QStringList() << "red" << "circle" ) );
|
||||
//bad symbol name
|
||||
QVERIFY( !mStyle->tagSymbol( QgsStyleV2::SymbolEntity, "no symbol", QStringList() << "red" << "circle" ) );
|
||||
//tag which hasn't been added yet
|
||||
QVERIFY( mStyle->tagSymbol( QgsStyleV2::SymbolEntity, "red circle", QStringList() << "round" ) );
|
||||
tags = mStyle->tags();
|
||||
QVERIFY( tags.contains( "round" ) );
|
||||
|
||||
//check that tags have been applied
|
||||
tags = mStyle->tagsOfSymbol( QgsStyleV2::SymbolEntity, "blue starry" );
|
||||
QCOMPARE( tags.count(), 2 );
|
||||
QVERIFY( tags.contains( "blue" ) );
|
||||
QVERIFY( tags.contains( "starry" ) );
|
||||
tags = mStyle->tagsOfSymbol( QgsStyleV2::SymbolEntity, "red circle" );
|
||||
QCOMPARE( tags.count(), 3 );
|
||||
QVERIFY( tags.contains( "red" ) );
|
||||
QVERIFY( tags.contains( "circle" ) );
|
||||
QVERIFY( tags.contains( "round" ) );
|
||||
tags = mStyle->tagsOfSymbol( QgsStyleV2::SymbolEntity, "symbol1" );
|
||||
QCOMPARE( tags.count(), 2 );
|
||||
QVERIFY( tags.contains( "red" ) );
|
||||
QVERIFY( tags.contains( "starry" ) );
|
||||
|
||||
//remove a tag, including a non-present tag
|
||||
QVERIFY( mStyle->detagSymbol( QgsStyleV2::SymbolEntity, "blue starry", QStringList() << "bad" << "blue" ) );
|
||||
tags = mStyle->tagsOfSymbol( QgsStyleV2::SymbolEntity, "blue starry" );
|
||||
QCOMPARE( tags.count(), 1 );
|
||||
QVERIFY( tags.contains( "starry" ) );
|
||||
|
||||
//try to remove tag from non-existing symbol
|
||||
QVERIFY( !mStyle->detagSymbol( QgsStyleV2::SymbolEntity, "no symbol!", QStringList() << "bad" << "blue" ) );
|
||||
|
||||
//check symbols with tag
|
||||
QStringList symbols = mStyle->symbolsWithTag( QgsStyleV2::SymbolEntity, mStyle->tagId( "red" ) );
|
||||
QCOMPARE( symbols.count(), 2 );
|
||||
QVERIFY( symbols.contains( "symbol1" ) );
|
||||
QVERIFY( symbols.contains( "red circle" ) );
|
||||
symbols = mStyle->symbolsWithTag( QgsStyleV2::SymbolEntity, mStyle->tagId( "starry" ) );
|
||||
QCOMPARE( symbols.count(), 2 );
|
||||
QVERIFY( symbols.contains( "symbol1" ) );
|
||||
QVERIFY( symbols.contains( "blue starry" ) );
|
||||
symbols = mStyle->symbolsWithTag( QgsStyleV2::SymbolEntity, mStyle->tagId( "circle" ) );
|
||||
QCOMPARE( symbols.count(), 1 );
|
||||
QVERIFY( symbols.contains( "red circle" ) );
|
||||
symbols = mStyle->symbolsWithTag( QgsStyleV2::SymbolEntity, mStyle->tagId( "round" ) );
|
||||
QCOMPARE( symbols.count(), 1 );
|
||||
QVERIFY( symbols.contains( "red circle" ) );
|
||||
symbols = mStyle->symbolsWithTag( QgsStyleV2::SymbolEntity, mStyle->tagId( "blue" ) );
|
||||
QVERIFY( symbols.isEmpty() );
|
||||
symbols = mStyle->symbolsWithTag( QgsStyleV2::SymbolEntity, mStyle->tagId( "no tag" ) );
|
||||
QVERIFY( symbols.isEmpty() );
|
||||
|
||||
//searching returns symbols with matching tags
|
||||
symbols = mStyle->findSymbols( QgsStyleV2::SymbolEntity, "red" );
|
||||
QCOMPARE( symbols.count(), 2 );
|
||||
QVERIFY( symbols.contains( "symbol1" ) );
|
||||
QVERIFY( symbols.contains( "red circle" ) );
|
||||
symbols = mStyle->findSymbols( QgsStyleV2::SymbolEntity, "symbol1" );
|
||||
QCOMPARE( symbols.count(), 1 );
|
||||
QVERIFY( symbols.contains( "symbol1" ) );
|
||||
symbols = mStyle->findSymbols( QgsStyleV2::SymbolEntity, "starry" );
|
||||
QCOMPARE( symbols.count(), 2 );
|
||||
QVERIFY( symbols.contains( "symbol1" ) );
|
||||
QVERIFY( symbols.contains( "blue starry" ) );
|
||||
symbols = mStyle->findSymbols( QgsStyleV2::SymbolEntity, "blue" );
|
||||
QCOMPARE( symbols.count(), 1 );
|
||||
QVERIFY( symbols.contains( "blue starry" ) );
|
||||
symbols = mStyle->findSymbols( QgsStyleV2::SymbolEntity, "round" );
|
||||
QCOMPARE( symbols.count(), 1 );
|
||||
QVERIFY( symbols.contains( "red circle" ) );
|
||||
}
|
||||
|
||||
QTEST_MAIN( TestStyleV2 )
|
||||
#include "testqgsstylev2.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user