mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
Add python safe addSmartgroup method, unit tests for smart groups
This commit is contained in:
parent
c41af120a0
commit
95d65ae861
@ -86,6 +86,21 @@ Adds a new tag and returns the tag's id
|
||||
%End
|
||||
|
||||
|
||||
int addSmartgroup( const QString &name, const QString &op, const QStringList &matchTag, const QStringList &noMatchTag,
|
||||
const QStringList &matchName, const QStringList &noMatchName );
|
||||
%Docstring
|
||||
Adds a new smartgroup to the database and returns the id.
|
||||
|
||||
:param name: is the name of the new Smart Group to be added
|
||||
:param op: is the operator between the conditions; AND/OR as QString
|
||||
:param matchTag: list of strings to match within tags
|
||||
:param noMatchTag: list of strings to exclude matches from tags
|
||||
:param matchName: list of string to match within names
|
||||
:param noMatchName: list of strings to exclude matches from names
|
||||
|
||||
.. versionadded:: 3.4
|
||||
%End
|
||||
|
||||
QStringList tags() const;
|
||||
%Docstring
|
||||
Returns a list of all tags in the style database
|
||||
|
@ -1169,26 +1169,34 @@ int QgsStyle::smartgroupId( const QString &name )
|
||||
}
|
||||
|
||||
int QgsStyle::addSmartgroup( const QString &name, const QString &op, const QgsSmartConditionMap &conditions )
|
||||
{
|
||||
return addSmartgroup( name, op, conditions.values( QStringLiteral( "tag" ) ),
|
||||
conditions.values( QStringLiteral( "!tag" ) ),
|
||||
conditions.values( QStringLiteral( "name" ) ),
|
||||
conditions.values( QStringLiteral( "!name" ) ) );
|
||||
}
|
||||
|
||||
int QgsStyle::addSmartgroup( const QString &name, const QString &op, const QStringList &matchTag, const QStringList &noMatchTag, const QStringList &matchName, const QStringList &noMatchName )
|
||||
{
|
||||
QDomDocument doc( QStringLiteral( "dummy" ) );
|
||||
QDomElement smartEl = doc.createElement( QStringLiteral( "smartgroup" ) );
|
||||
smartEl.setAttribute( QStringLiteral( "name" ), name );
|
||||
smartEl.setAttribute( QStringLiteral( "operator" ), op );
|
||||
|
||||
QStringList constraints;
|
||||
constraints << QStringLiteral( "tag" ) << QStringLiteral( "group" ) << QStringLiteral( "name" ) << QStringLiteral( "!tag" ) << QStringLiteral( "!group" ) << QStringLiteral( "!name" );
|
||||
|
||||
Q_FOREACH ( const QString &constraint, constraints )
|
||||
auto addCondition = [&doc, &smartEl]( const QString & constraint, const QStringList & parameters )
|
||||
{
|
||||
QStringList parameters = conditions.values( constraint );
|
||||
Q_FOREACH ( const QString ¶m, parameters )
|
||||
for ( const QString ¶m : parameters )
|
||||
{
|
||||
QDomElement condEl = doc.createElement( QStringLiteral( "condition" ) );
|
||||
condEl.setAttribute( QStringLiteral( "constraint" ), constraint );
|
||||
condEl.setAttribute( QStringLiteral( "param" ), param );
|
||||
smartEl.appendChild( condEl );
|
||||
}
|
||||
}
|
||||
};
|
||||
addCondition( QStringLiteral( "tag" ), matchTag );
|
||||
addCondition( QStringLiteral( "!tag" ), noMatchTag );
|
||||
addCondition( QStringLiteral( "name" ), matchName );
|
||||
addCondition( QStringLiteral( "!name" ), noMatchName );
|
||||
|
||||
QByteArray xmlArray;
|
||||
QTextStream stream( &xmlArray );
|
||||
@ -1312,16 +1320,16 @@ QStringList QgsStyle::symbolsOfSmartgroup( StyleEntity type, int id )
|
||||
else if ( constraint == QLatin1String( "!tag" ) )
|
||||
{
|
||||
resultNames = type == SymbolEntity ? symbolNames() : colorRampNames();
|
||||
QStringList unwanted = symbolsWithTag( type, tagId( param ) );
|
||||
Q_FOREACH ( const QString &name, unwanted )
|
||||
const QStringList unwanted = symbolsWithTag( type, tagId( param ) );
|
||||
for ( const QString &name : unwanted )
|
||||
{
|
||||
resultNames.removeAll( name );
|
||||
}
|
||||
}
|
||||
else if ( constraint == QLatin1String( "!name" ) )
|
||||
{
|
||||
QStringList all = type == SymbolEntity ? symbolNames() : colorRampNames();
|
||||
Q_FOREACH ( const QString &str, all )
|
||||
const QStringList all = type == SymbolEntity ? symbolNames() : colorRampNames();
|
||||
for ( const QString &str : all )
|
||||
{
|
||||
if ( !str.contains( param, Qt::CaseInsensitive ) )
|
||||
resultNames << str;
|
||||
@ -1344,7 +1352,7 @@ QStringList QgsStyle::symbolsOfSmartgroup( StyleEntity type, int id )
|
||||
{
|
||||
QStringList dummy = symbols;
|
||||
symbols.clear();
|
||||
Q_FOREACH ( const QString &result, resultNames )
|
||||
for ( const QString &result : qgis::as_const( resultNames ) )
|
||||
{
|
||||
if ( dummy.contains( result ) )
|
||||
symbols << result;
|
||||
@ -1354,7 +1362,10 @@ QStringList QgsStyle::symbolsOfSmartgroup( StyleEntity type, int id )
|
||||
} // DOM loop ends here
|
||||
}
|
||||
|
||||
return symbols;
|
||||
// return sorted, unique list
|
||||
QStringList unique = symbols.toSet().toList();
|
||||
std::sort( unique.begin(), unique.end() );
|
||||
return unique;
|
||||
}
|
||||
|
||||
QgsSmartConditionMap QgsStyle::smartgroup( int id )
|
||||
@ -1437,7 +1448,7 @@ bool QgsStyle::exportXml( const QString &filename )
|
||||
|
||||
QDomDocument doc( QStringLiteral( "qgis_style" ) );
|
||||
QDomElement root = doc.createElement( QStringLiteral( "qgis_style" ) );
|
||||
root.setAttribute( QStringLiteral( "version" ), STYLE_CURRENT_VERSION );
|
||||
root.setAttribute( QStringLiteral( "version" ), QStringLiteral( STYLE_CURRENT_VERSION ) );
|
||||
doc.appendChild( root );
|
||||
|
||||
QStringList favoriteSymbols = symbolsOfFavorite( SymbolEntity );
|
||||
@ -1528,7 +1539,7 @@ bool QgsStyle::importXml( const QString &filename )
|
||||
}
|
||||
|
||||
QString version = docEl.attribute( QStringLiteral( "version" ) );
|
||||
if ( version != STYLE_CURRENT_VERSION && version != QLatin1String( "0" ) )
|
||||
if ( version != QLatin1String( STYLE_CURRENT_VERSION ) && version != QLatin1String( "0" ) )
|
||||
{
|
||||
mErrorString = "Unknown style file version: " + version;
|
||||
return false;
|
||||
@ -1543,7 +1554,7 @@ bool QgsStyle::importXml( const QString &filename )
|
||||
auto query = QgsSqlite3Mprintf( "BEGIN TRANSACTION;" );
|
||||
runEmptyQuery( query );
|
||||
|
||||
if ( version == STYLE_CURRENT_VERSION )
|
||||
if ( version == QLatin1String( STYLE_CURRENT_VERSION ) )
|
||||
{
|
||||
// For the new style, load symbols individually
|
||||
while ( !e.isNull() )
|
||||
|
@ -140,6 +140,21 @@ class CORE_EXPORT QgsStyle : public QObject
|
||||
*/
|
||||
int addSmartgroup( const QString &name, const QString &op, const QgsSmartConditionMap &conditions ) SIP_SKIP;
|
||||
|
||||
/**
|
||||
* Adds a new smartgroup to the database and returns the id.
|
||||
*
|
||||
* \param name is the name of the new Smart Group to be added
|
||||
* \param op is the operator between the conditions; AND/OR as QString
|
||||
* \param matchTag list of strings to match within tags
|
||||
* \param noMatchTag list of strings to exclude matches from tags
|
||||
* \param matchName list of string to match within names
|
||||
* \param noMatchName list of strings to exclude matches from names
|
||||
*
|
||||
* \since QGIS 3.4
|
||||
*/
|
||||
int addSmartgroup( const QString &name, const QString &op, const QStringList &matchTag, const QStringList &noMatchTag,
|
||||
const QStringList &matchName, const QStringList &noMatchName );
|
||||
|
||||
/**
|
||||
* Returns a list of all tags in the style database
|
||||
*
|
||||
|
@ -67,6 +67,7 @@ class TestStyle : public QObject
|
||||
void testSaveLoad();
|
||||
void testFavorites();
|
||||
void testTags();
|
||||
void testSmartGroup();
|
||||
|
||||
};
|
||||
|
||||
@ -551,5 +552,88 @@ void TestStyle::testTags()
|
||||
QCOMPARE( tagsChangedSpy.at( 13 ).at( 2 ).toStringList(), QStringList() );
|
||||
}
|
||||
|
||||
void TestStyle::testSmartGroup()
|
||||
{
|
||||
QgsStyle style;
|
||||
style.createMemoryDatabase();
|
||||
|
||||
QSignalSpy groupModifiedSpy( &style, &QgsStyle::groupsModified );
|
||||
|
||||
std::unique_ptr< QgsMarkerSymbol > sym1( QgsMarkerSymbol::createSimple( QgsStringMap() ) );
|
||||
std::unique_ptr< QgsMarkerSymbol > sym2( QgsMarkerSymbol::createSimple( QgsStringMap() ) );
|
||||
std::unique_ptr< QgsMarkerSymbol > sym3( QgsMarkerSymbol::createSimple( QgsStringMap() ) );
|
||||
style.addSymbol( QStringLiteral( "symbolA" ), sym1->clone(), true );
|
||||
style.addSymbol( QStringLiteral( "symbolB" ), sym2->clone(), true );
|
||||
style.addSymbol( QStringLiteral( "symbolC" ), sym3->clone(), true );
|
||||
QgsLimitedRandomColorRamp *randomRamp = new QgsLimitedRandomColorRamp();
|
||||
QVERIFY( style.addColorRamp( "ramp a", randomRamp, true ) );
|
||||
randomRamp = new QgsLimitedRandomColorRamp();
|
||||
QVERIFY( style.addColorRamp( "different bbb", randomRamp, true ) );
|
||||
|
||||
QVERIFY( style.smartgroupNames().empty() );
|
||||
QVERIFY( style.smartgroup( 5 ).isEmpty() );
|
||||
QCOMPARE( style.smartgroupId( QStringLiteral( "no exist" ) ), 0 );
|
||||
|
||||
int res = style.addSmartgroup( QStringLiteral( "mine" ), QStringLiteral( "AND" ), QStringList(), QStringList(), QStringList() << QStringLiteral( "a" ), QStringList() );
|
||||
QCOMPARE( res, 1 );
|
||||
QCOMPARE( style.smartgroupNames(), QStringList() << QStringLiteral( "mine" ) );
|
||||
QCOMPARE( style.smartgroup( 1 ).values( QStringLiteral( "name" ) ), QStringList() << QStringLiteral( "a" ) );
|
||||
QCOMPARE( style.smartgroupId( QStringLiteral( "mine" ) ), 1 );
|
||||
QCOMPARE( groupModifiedSpy.count(), 1 );
|
||||
|
||||
QCOMPARE( style.symbolsOfSmartgroup( QgsStyle::SymbolEntity, 1 ), QStringList() << QStringLiteral( "symbolA" ) );
|
||||
QCOMPARE( style.symbolsOfSmartgroup( QgsStyle::ColorrampEntity, 1 ), QStringList() << QStringLiteral( "ramp a" ) );
|
||||
|
||||
res = style.addSmartgroup( QStringLiteral( "tag" ), QStringLiteral( "OR" ), QStringList(), QStringList(), QStringList() << "c", QStringList() << "a" );
|
||||
QCOMPARE( res, 2 );
|
||||
QCOMPARE( style.smartgroupNames(), QStringList() << QStringLiteral( "mine" ) << QStringLiteral( "tag" ) );
|
||||
QCOMPARE( style.smartgroup( 2 ).values( QStringLiteral( "name" ) ), QStringList() << QStringLiteral( "c" ) );
|
||||
QCOMPARE( style.smartgroup( 2 ).values( QStringLiteral( "!name" ) ), QStringList() << QStringLiteral( "a" ) );
|
||||
QCOMPARE( style.smartgroupId( QStringLiteral( "tag" ) ), 2 );
|
||||
QCOMPARE( groupModifiedSpy.count(), 2 );
|
||||
|
||||
QCOMPARE( style.symbolsOfSmartgroup( QgsStyle::SymbolEntity, 2 ), QStringList() << QStringLiteral( "symbolB" ) << QStringLiteral( "symbolC" ) );
|
||||
QCOMPARE( style.symbolsOfSmartgroup( QgsStyle::ColorrampEntity, 2 ), QStringList() << QStringLiteral( "different bbb" ) );
|
||||
|
||||
// tag some symbols
|
||||
style.tagSymbol( QgsStyle::SymbolEntity, "symbolA", QStringList() << "red" << "blue" );
|
||||
style.tagSymbol( QgsStyle::SymbolEntity, "symbolB", QStringList() << "blue" );
|
||||
style.tagSymbol( QgsStyle::ColorrampEntity, "ramp a", QStringList() << "blue" );
|
||||
style.tagSymbol( QgsStyle::ColorrampEntity, "different bbb", QStringList() << "blue" << "red" );
|
||||
|
||||
// adding tags modifies groups!
|
||||
QCOMPARE( groupModifiedSpy.count(), 4 );
|
||||
|
||||
res = style.addSmartgroup( QStringLiteral( "tags" ), QStringLiteral( "AND" ), QStringList() << "blue", QStringList() << "red", QStringList(), QStringList() );
|
||||
QCOMPARE( res, 3 );
|
||||
QCOMPARE( style.smartgroupNames(), QStringList() << QStringLiteral( "mine" ) << QStringLiteral( "tag" ) << QStringLiteral( "tags" ) );
|
||||
QCOMPARE( style.smartgroup( 3 ).values( QStringLiteral( "tag" ) ), QStringList() << QStringLiteral( "blue" ) );
|
||||
QCOMPARE( style.smartgroup( 3 ).values( QStringLiteral( "!tag" ) ), QStringList() << QStringLiteral( "red" ) );
|
||||
QCOMPARE( style.smartgroupId( QStringLiteral( "tags" ) ), 3 );
|
||||
QCOMPARE( groupModifiedSpy.count(), 5 );
|
||||
|
||||
QCOMPARE( style.symbolsOfSmartgroup( QgsStyle::SymbolEntity, 3 ), QStringList() << QStringLiteral( "symbolB" ) );
|
||||
QCOMPARE( style.symbolsOfSmartgroup( QgsStyle::ColorrampEntity, 3 ), QStringList() << QStringLiteral( "ramp a" ) );
|
||||
|
||||
res = style.addSmartgroup( QStringLiteral( "combined" ), QStringLiteral( "AND" ), QStringList() << "blue", QStringList(), QStringList(), QStringList() << "a" );
|
||||
QCOMPARE( res, 4 );
|
||||
QCOMPARE( style.smartgroupNames(), QStringList() << QStringLiteral( "mine" ) << QStringLiteral( "tag" ) << QStringLiteral( "tags" ) << QStringLiteral( "combined" ) );
|
||||
QCOMPARE( style.smartgroup( 4 ).values( QStringLiteral( "tag" ) ), QStringList() << QStringLiteral( "blue" ) );
|
||||
QCOMPARE( style.smartgroup( 4 ).values( QStringLiteral( "!name" ) ), QStringList() << QStringLiteral( "a" ) );
|
||||
QCOMPARE( style.smartgroupId( QStringLiteral( "combined" ) ), 4 );
|
||||
QCOMPARE( groupModifiedSpy.count(), 6 );
|
||||
|
||||
QCOMPARE( style.symbolsOfSmartgroup( QgsStyle::SymbolEntity, 4 ), QStringList() << QStringLiteral( "symbolB" ) );
|
||||
QCOMPARE( style.symbolsOfSmartgroup( QgsStyle::ColorrampEntity, 4 ), QStringList() << QStringLiteral( "different bbb" ) );
|
||||
|
||||
style.remove( QgsStyle::SmartgroupEntity, 1 );
|
||||
QCOMPARE( style.smartgroupNames(), QStringList() << QStringLiteral( "tag" ) << QStringLiteral( "tags" ) << QStringLiteral( "combined" ) );
|
||||
QCOMPARE( groupModifiedSpy.count(), 7 );
|
||||
|
||||
style.remove( QgsStyle::SmartgroupEntity, 4 );
|
||||
QCOMPARE( style.smartgroupNames(), QStringList() << QStringLiteral( "tag" ) << QStringLiteral( "tags" ) );
|
||||
QCOMPARE( groupModifiedSpy.count(), 8 );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestStyle )
|
||||
#include "testqgsstyle.moc"
|
||||
|
Loading…
x
Reference in New Issue
Block a user