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
43 changes: 41 additions & 2 deletions app/filtercontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,13 @@ QString FilterController::buildFieldExpression( const FieldFilter &filter ) cons

if ( filter.filterType == QLatin1String( "bool" ) )
{
bool boolValue = filter.value.toBool();
return QStringLiteral( "%1 = %2" ).arg( quotedField, boolValue ? QStringLiteral( "TRUE" ) : QStringLiteral( "FALSE" ) );
// for custom checkboxes the values can also be string or integers
if ( filter.value.typeId() == QMetaType::Bool )
{
bool boolValue = filter.value.toBool();
return QStringLiteral( "%1 = %2" ).arg( quotedField, boolValue ? QStringLiteral( "TRUE" ) : QStringLiteral( "FALSE" ) );
}
return QStringLiteral( "%1 = %2" ).arg( quotedField, QgsExpression::quotedValue( filter.value ) );
}
else if ( filter.filterType == QLatin1String( "text" ) )
{
Expand Down Expand Up @@ -502,13 +507,47 @@ QVariantList FilterController::getFilterableFields( QgsVectorLayer *layer ) cons
filterType = QStringLiteral( "dropdown" );
multiSelect = widgetSetup.config().value( QStringLiteral( "AllowMulti" ) ).toBool();
}
else if ( widgetType == QLatin1String( "CheckBox" ) )
{
filterType = QStringLiteral( "bool" );
QVariantMap config = widgetSetup.config();
QString checkedStateStr = config.value( QStringLiteral( "CheckedState" ) ).toString();
QString uncheckedStateStr = config.value( QStringLiteral( "UncheckedState" ) ).toString();

if ( !checkedStateStr.isEmpty() )
fieldInfo[QStringLiteral( "boolTrueLabel" )] = checkedStateStr;
if ( !uncheckedStateStr.isEmpty() )
fieldInfo[QStringLiteral( "boolFalseLabel" )] = uncheckedStateStr;

// Emit typed checked/unchecked values matching the field's actual storage type
QMetaType::Type fieldType = static_cast<QMetaType::Type>( field.type() );
bool isIntField = ( fieldType == QMetaType::Int || fieldType == QMetaType::UInt ||
fieldType == QMetaType::LongLong || fieldType == QMetaType::ULongLong );

if ( !checkedStateStr.isEmpty() )
{
bool ok = false;
int intVal = checkedStateStr.toInt( &ok );
fieldInfo[QStringLiteral( "boolCheckedValue" )] = ( isIntField && ok ) ? QVariant( intVal ) : QVariant( checkedStateStr );
}
if ( !uncheckedStateStr.isEmpty() )
{
bool ok = false;
int intVal = uncheckedStateStr.toInt( &ok );
fieldInfo[QStringLiteral( "boolUncheckedValue" )] = ( isIntField && ok ) ? QVariant( intVal ) : QVariant( uncheckedStateStr );
}
}
else
{
// Determine filter type based on field data type
QMetaType::Type fieldType = static_cast<QMetaType::Type>( field.type() );

switch ( fieldType )
{
case QMetaType::Bool:
filterType = QStringLiteral( "bool" );
break;

case QMetaType::Int:
case QMetaType::UInt:
case QMetaType::LongLong:
Expand Down
13 changes: 11 additions & 2 deletions app/qml/filters/MMFiltersPanel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ MMComponents.MMDrawer {
currentValueTo: f.currentValueTo !== undefined ? f.currentValueTo : null,
hasTime: !!f.hasTime,
multiSelect: !!f.multiSelect,
currentValueTexts: f.currentValueTexts || []
currentValueTexts: f.currentValueTexts || [],
boolTrueLabel: f.boolTrueLabel || "",
boolFalseLabel: f.boolFalseLabel || "",
boolCheckedValue: f.boolCheckedValue !== undefined ? f.boolCheckedValue : null,
boolUncheckedValue: f.boolUncheckedValue !== undefined ? f.boolUncheckedValue : null
})
}
}
Expand Down Expand Up @@ -172,7 +176,12 @@ MMComponents.MMDrawer {
}))
break
case "bool":
setSource( "components/MMFilterBoolInput.qml", base )
setSource( "components/MMFilterBoolInput.qml", Object.assign( {}, base, {
boolTrueLabel: modelData.boolTrueLabel,
boolFalseLabel: modelData.boolFalseLabel,
boolCheckedValue: modelData.boolCheckedValue,
boolUncheckedValue: modelData.boolUncheckedValue
}))
break
case "dropdown":
setSource( "components/MMFilterDropdownEditor.qml", Object.assign( {}, base, {
Expand Down
17 changes: 14 additions & 3 deletions app/qml/filters/components/MMFilterBoolInput.qml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ Column {
required property string fieldLayerId
required property string fieldName

property string boolTrueLabel: ""
property string boolFalseLabel: ""
property var boolCheckedValue: null
property var boolUncheckedValue: null

property bool _initialized: false
Component.onCompleted: _initialized = true

Expand All @@ -39,10 +44,14 @@ Column {
width: parent.width
backgroundColor: __style.lightGreenColor

trueText: root.boolTrueLabel !== "" ? root.boolTrueLabel : qsTr( "True" )
falseText: root.boolFalseLabel !== "" ? root.boolFalseLabel : qsTr( "False" )

selectedIndex: {
let val = root.currentValue
if ( val === null || val === undefined ) return MMSegmentControl.Options.All
return ( val === true || val === 1 ) ? MMSegmentControl.Options.True : MMSegmentControl.Options.False
let checkedVal = root.boolCheckedValue !== null ? root.boolCheckedValue : true
return ( val == checkedVal ) ? MMSegmentControl.Options.True : MMSegmentControl.Options.False
}

onSelectedIndexChanged: {
Expand All @@ -52,10 +61,12 @@ Column {
__activeProject.filterController.removeFieldFilter( root.fieldLayerId, root.fieldName )
break
case MMSegmentControl.Options.True:
__activeProject.filterController.setFieldFilter( root.fieldLayerId, root.fieldName, "bool", true )
__activeProject.filterController.setFieldFilter( root.fieldLayerId, root.fieldName, "bool",
root.boolCheckedValue !== null ? root.boolCheckedValue : true )
break
case MMSegmentControl.Options.False:
__activeProject.filterController.setFieldFilter( root.fieldLayerId, root.fieldName, "bool", false )
__activeProject.filterController.setFieldFilter( root.fieldLayerId, root.fieldName, "bool",
root.boolUncheckedValue !== null ? root.boolUncheckedValue : false )
break
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/qml/form/editors/MMFormSwitchEditor.qml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ MMSwitchInput {
text: _fieldHasMixedValues ? "" : checked ? internal.checkedStateValue : internal.uncheckedStateValue
placeholderText: _fieldHasMixedValues ? _fieldValue : ""

checked: _fieldHasMixedValues ? internal.uncheckedStateValue : _fieldValue === internal.checkedStateValue
checked: !_fieldHasMixedValues && internal.checkedStateValue !== "" && _fieldValue == internal.checkedStateValue

onToggled: {
let newVal = checked ? internal.checkedStateValue : internal.uncheckedStateValue
Expand Down
Loading