Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion app/filter/uniquevaluesfiltermodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ UniqueValuesFilterModel::UniqueValuesFilterModel( QObject *parent ) : QAbstractL
connect( &mResultWatcher, &QFutureWatcher<QVariantList>::finished, this, &UniqueValuesFilterModel::onLoadingFinished );
}

QHash<int, QByteArray> UniqueValuesFilterModel::roleNames() const
{
QHash<int, QByteArray> roleMap = QAbstractListModel::roleNames();
roleMap.insert( ValueRole, QStringLiteral( "value" ).toLatin1() );
return roleMap;
}

int UniqueValuesFilterModel::rowCount( const QModelIndex &parent ) const
{
Q_UNUSED( parent )
Expand All @@ -34,6 +41,9 @@ QVariant UniqueValuesFilterModel::data( const QModelIndex &index, int role ) con
switch ( role )
{
case Qt::DisplayRole:
// for NULL values, which are gotten as empty strings, we want to return some meaningful text for users
return mItems.at( index.row() ).toString().isEmpty() ? QVariant( tr( "No value" ) ) : mItems.at( index.row() );
case ValueRole:
return mItems.at( index.row() );
default:
return {};
Expand Down Expand Up @@ -105,7 +115,16 @@ QVariantList UniqueValuesFilterModel::loadUniqueValues( QgsVectorLayer *layer, i
{
std::unique_ptr<QgsVectorLayer> l( layer );

const QSet<QVariant> uniqueValues = l->uniqueValues( fieldIndex, 1000000 );
QSet<QVariant> uniqueValues = l->uniqueValues( fieldIndex, 1000000 );

uniqueValues << QVariant( QString() );

// both empty string and null value show up in the same way, let's remove one to have only one "No value" option in UI
const QVariant nullValidQVariant = QVariant( QMetaType( QMetaType::QString ) );
if ( uniqueValues.contains( QVariant( "" ) ) && uniqueValues.contains( nullValidQVariant ) )
{
uniqueValues.remove( QVariant( "" ) );
}

QVariantList results;

Expand Down
7 changes: 7 additions & 0 deletions app/filter/uniquevaluesfiltermodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,16 @@ class UniqueValuesFilterModel : public QAbstractListModel
Q_PROPERTY( int count READ rowCount NOTIFY countChanged )

public:
enum Roles
{
ValueRole = Qt::UserRole + 1, // DisplayRole is used for description
};
Q_ENUM( Roles )

explicit UniqueValuesFilterModel( QObject *parent = nullptr );
~UniqueValuesFilterModel() override = default;

QHash<int, QByteArray> roleNames() const override;
int rowCount( const QModelIndex &parent = QModelIndex() ) const override;
QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override;

Expand Down
44 changes: 37 additions & 7 deletions app/filtercontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,31 @@ QString FilterController::buildFieldExpression( const FieldFilter &filter ) cons
break;
}
case FieldFilter::CheckboxFilter:
case FieldFilter::SingleSelectFilter:
{
expressionCopy.replace( QStringLiteral( "@@value@@" ), QgsExpression::quotedValue( filter.value.toList().at( 0 ) ) );
break;
}
case FieldFilter::SingleSelectFilter:
{
// check if the value is NULL and if it is search for both NULL and empty string
if ( QgsVariantUtils::isNull( filter.value.toList().at( 0 ) ) )
{
QStringList expressions;
QString expressionTemplate( expressionCopy );
expressionTemplate.replace( QStringLiteral( "@@value@@" ), QStringLiteral( "NULL" ) );
expressions << QStringLiteral( "(%1)" ).arg( expressionTemplate );
expressionTemplate = QString( expressionCopy );
expressionTemplate.replace( QStringLiteral( "@@value@@" ), QStringLiteral( "''" ) );
expressions << QStringLiteral( "(%1)" ).arg( expressionTemplate );

expressionCopy = expressions.join( QStringLiteral( " OR " ) );
}
else
{
expressionCopy.replace( QStringLiteral( "@@value@@" ), QgsExpression::quotedValue( filter.value.toList().at( 0 ) ) );
}
break;
}
case FieldFilter::NumberFilter:
{
const QVariant &variantFrom = filter.value.toList().at( 0 );
Expand Down Expand Up @@ -225,12 +245,25 @@ QString FilterController::buildFieldExpression( const FieldFilter &filter ) cons
break;
}

QStringList quotedValues;
QStringList expressions;
for ( const QVariant &v : values )
{
quotedValues << QgsExpression::quotedValue( v );
QString expressionTemplate( expressionCopy );
if ( QgsVariantUtils::isNull( v ) )
{
expressionTemplate.replace( QStringLiteral( "@@value@@" ), QStringLiteral( "NULL" ) );
expressions << QStringLiteral( "(%1)" ).arg( expressionTemplate );
expressionTemplate = QString( expressionCopy );
expressionTemplate.replace( QStringLiteral( "@@value@@" ), QStringLiteral( "''" ) );
expressions << QStringLiteral( "(%1)" ).arg( expressionTemplate );
}
else
{
expressionTemplate.replace( QStringLiteral( "@@value@@" ), QgsExpression::quotedValue( v ) );
expressions << QStringLiteral( "(%1)" ).arg( expressionTemplate );
}
}
expressionCopy.replace( QStringLiteral( "@@values@@" ), quotedValues.join( QStringLiteral( ", " ) ) );
expressionCopy = expressions.join( QStringLiteral( " OR " ) );
break;
}
}
Expand Down Expand Up @@ -455,9 +488,6 @@ QVariantMap FilterController::getDropdownConfiguration( const QString &filterId
QVariantMap map;

const QgsProject *project = QgsProject::instance();

if ( !project ) return {};

const QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( project->mapLayers().value( fieldFilter.layerId ) );

if ( !layer ) return {};
Expand Down
3 changes: 1 addition & 2 deletions app/qml/filters/MMFiltersPanel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,7 @@ MMComponents.MMDrawer {
{
// TODO: might be worth moving this logic to C++

const isMulti = filterType === FieldFilter.MultiSelectFilter
props['isMultiSelect'] = isMulti
props['isMultiSelect'] = filterType === FieldFilter.MultiSelectFilter

const dropdownConfig = __activeProject.filterController.getDropdownConfiguration( modelData.filterId )

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Column {

textRole: "display"
secondaryTextRole: ""
valueRole: "display"
valueRole: "value"

onSelectionFinished: function( selectedItems ) {
root.currentValue = selectedItems
Expand Down
Loading