Skip to content
Open
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
19 changes: 19 additions & 0 deletions app/filtercontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@ FilterController::FilterController( QObject *parent )
{
}

bool FilterController::filtersEnabled() const
{
return mFiltersEnabled;
}

void FilterController::setFiltersEnabled( bool enabled )
{
if ( mFiltersEnabled == enabled )
return;
mFiltersEnabled = enabled;
emit filtersEnabledChanged();
}

bool FilterController::hasActiveFilters() const
{
for ( auto it = mAppliedFilters.constBegin(); it != mAppliedFilters.constEnd(); ++it )
Expand Down Expand Up @@ -463,6 +476,12 @@ void FilterController::applyFiltersToAllLayers()
{
emit hasActiveFiltersChanged();
}

if ( !mFiltersEnabled )
{
mFiltersEnabled = true;
emit filtersEnabledChanged();
}
}

void FilterController::discardPendingChanges()
Expand Down
12 changes: 12 additions & 0 deletions app/filtercontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,22 @@ class FilterController : public QObject
*/
Q_PROPERTY( QStringList filteredLayerIds READ filteredLayerIds NOTIFY filtersChanged )

/**
* Whether filters are currently enabled (applied to the map).
* When false, filters are defined but not applied.
*/
Q_PROPERTY( bool filtersEnabled READ filtersEnabled WRITE setFiltersEnabled NOTIFY filtersEnabledChanged )

public:
explicit FilterController( QObject *parent = nullptr );
~FilterController() override = default;

bool hasActiveFilters() const;
QStringList filteredLayerIds() const;

bool filtersEnabled() const;
void setFiltersEnabled( bool enabled );

/**
* @brief Sets a filter for a specific field on a layer
* @param layerId The layer ID
Expand Down Expand Up @@ -211,6 +220,7 @@ class FilterController : public QObject
void filtersChanged();
void hasActiveFiltersChanged();
void layerFilterChanged( const QString &layerId );
void filtersEnabledChanged();

private:
QString buildFieldExpression( const FieldFilter &filter ) const;
Expand All @@ -224,6 +234,8 @@ class FilterController : public QObject

// Applied state, updated only when the user confirms via "Show results"
QMap<QString, QMap<QString, FieldFilter>> mAppliedFilters;

bool mFiltersEnabled = true;
};

#endif // FILTERCONTROLLER_H
2 changes: 1 addition & 1 deletion app/icons/Filter.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 0 additions & 3 deletions app/icons/FilterFilled.svg

This file was deleted.

1 change: 0 additions & 1 deletion app/icons/icons.qrc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
<file>Features.svg</file>
<file>FeaturesFilled.svg</file>
<file>Filter.svg</file>
<file>FilterFilled.svg</file>
<file>GPSAntennaHeight.svg</file>
<file>GPSIcon.svg</file>
<file>GPSSatellite.svg</file>
Expand Down
2 changes: 0 additions & 2 deletions app/mmstyle.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ class MMStyle: public QObject
Q_PROPERTY( QUrl facebookIcon READ facebookIcon CONSTANT )
Q_PROPERTY( QUrl featuresIcon READ featuresIcon CONSTANT )
Q_PROPERTY( QUrl filterIcon READ filterIcon CONSTANT )
Q_PROPERTY( QUrl filterFilledIcon READ filterFilledIcon CONSTANT )
Q_PROPERTY( QUrl globeIcon READ globeIcon CONSTANT )
Q_PROPERTY( QUrl globalIcon READ globalIcon CONSTANT )
Q_PROPERTY( QUrl gpsIcon READ gpsIcon CONSTANT )
Expand Down Expand Up @@ -433,7 +432,6 @@ class MMStyle: public QObject
QUrl deleteIcon() const {return QUrl( "qrc:/Delete.svg" );}
QUrl featuresIcon() const {return QUrl( "qrc:/Features.svg" );}
QUrl filterIcon() const {return QUrl( "qrc:/Filter.svg" );}
QUrl filterFilledIcon() const {return QUrl( "qrc:/FilterFilled.svg" );}
QUrl downloadIcon() const {return QUrl( "qrc:/Download.svg" );}
QUrl uploadIcon() const {return QUrl( "qrc:/Upload.svg" );}
QUrl editIcon() const {return QUrl( "qrc:/Edit.svg" );}
Expand Down
96 changes: 48 additions & 48 deletions app/qml/filters/MMFilterLayerSection.qml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Column {

property var fieldInfo: modelData
property string fieldName: fieldInfo ? fieldInfo.name : ""
property string fieldDisplayName: fieldInfo ? (fieldInfo.displayName || fieldInfo.name) : ""
property string fieldDisplayName: fieldInfo ? ( fieldInfo.displayName || fieldInfo.name ) : ""
property string filterType: fieldInfo ? fieldInfo.filterType : "text"
property var currentValue: fieldInfo ? fieldInfo.currentValue : null
property var currentValueTo: fieldInfo ? fieldInfo.currentValueTo : null
Expand Down Expand Up @@ -82,17 +82,17 @@ Column {
spacing: __style.margin12

property bool rangeInvalid: {
let fromVal = parseFloat(fromNumberInput.text)
let toVal = parseFloat(toNumberInput.text)
return !isNaN(fromVal) && !isNaN(toVal) && fromVal > toVal
let fromVal = parseFloat( fromNumberInput.text )
let toVal = parseFloat( toNumberInput.text )
return !isNaN( fromVal ) && !isNaN( toVal ) && fromVal > toVal
}

MMTextInput {
id: fromNumberInput
width: (parent.width - __style.margin12) / 2
placeholderText: qsTr("From")
text: fieldDelegate.currentValue !== null && fieldDelegate.currentValue !== undefined ? String(fieldDelegate.currentValue) : ""
errorMsg: parent.rangeInvalid ? qsTr("\"From\" must be less than \"To\"") : ""
width: ( parent.width - __style.margin12 ) / 2
placeholderText: qsTr( "From" )
text: fieldDelegate.currentValue !== null && fieldDelegate.currentValue !== undefined ? String( fieldDelegate.currentValue ) : ""
errorMsg: parent.rangeInvalid ? qsTr( "\"From\" must be less than \"To\"" ) : ""

property bool initialized: false
Component.onCompleted: initialized = true
Expand All @@ -105,9 +105,9 @@ Column {

MMTextInput {
id: toNumberInput
width: (parent.width - __style.margin12) / 2
placeholderText: qsTr("To")
text: fieldDelegate.currentValueTo !== null && fieldDelegate.currentValueTo !== undefined ? String(fieldDelegate.currentValueTo) : ""
width: ( parent.width - __style.margin12 ) / 2
placeholderText: qsTr( "To" )
text: fieldDelegate.currentValueTo !== null && fieldDelegate.currentValueTo !== undefined ? String( fieldDelegate.currentValueTo ) : ""

property bool initialized: false
Component.onCompleted: initialized = true
Expand Down Expand Up @@ -138,12 +138,12 @@ Column {
spacing: __style.margin12

property bool rangeInvalid: {
if (!fromDateInput.selectedDate || !toDateInput.selectedDate) return false
if ( !fromDateInput.selectedDate || !toDateInput.selectedDate ) return false
return fromDateInput.selectedDate > toDateInput.selectedDate
}

Item {
width: (parent.width - __style.margin12) / 2
width: ( parent.width - __style.margin12 ) / 2
height: fromDateInput.height

MMPrivateComponents.MMBaseSingleLineInput {
Expand All @@ -154,20 +154,20 @@ Column {

Component.onCompleted: {
let val = fieldDelegate.currentValue
if (val !== null && val !== undefined) {
let d = new Date(val)
if (!isNaN(d.getTime())) selectedDate = d
if ( val !== null && val !== undefined ) {
let d = new Date( val )
if ( !isNaN( d.getTime() ) ) selectedDate = d
}
}

placeholderText: qsTr("From")
placeholderText: qsTr( "From" )
text: {
if (!selectedDate) return ""
if (fieldDelegate.hasTime) return Qt.formatDateTime(selectedDate, Qt.DefaultLocaleShortDate)
return Qt.formatDate(selectedDate, Qt.DefaultLocaleShortDate)
if ( !selectedDate ) return ""
if ( fieldDelegate.hasTime ) return Qt.formatDateTime( selectedDate, Qt.DefaultLocaleShortDate )
return Qt.formatDate( selectedDate, Qt.DefaultLocaleShortDate )
}
textField.readOnly: true
errorMsg: dateRangeRow.rangeInvalid ? qsTr("\"From\" must be less than \"To\"") : ""
errorMsg: dateRangeRow.rangeInvalid ? qsTr( "\"From\" must be less than \"To\"" ) : ""

rightContent: MMIcon {
size: __style.icon24
Expand All @@ -177,7 +177,7 @@ Column {

onTextClicked: fromCalendarLoader.active = true
onRightContentClicked: {
if (fromDateInput.selectedDate) {
if ( fromDateInput.selectedDate ) {
fromDateInput.selectedDate = null
let toDate = toDateInput.selectedDate ? toDateInput.selectedDate : null
__activeProject.filterController.setDateFilter(root.layerId, fieldDelegate.fieldName, null, toDate, fieldDelegate.hasTime)
Expand Down Expand Up @@ -216,7 +216,7 @@ Column {
}

Item {
width: (parent.width - __style.margin12) / 2
width: ( parent.width - __style.margin12 ) / 2
height: toDateInput.height

MMPrivateComponents.MMBaseSingleLineInput {
Expand All @@ -227,17 +227,17 @@ Column {

Component.onCompleted: {
let val = fieldDelegate.currentValueTo
if (val !== null && val !== undefined) {
let d = new Date(val)
if (!isNaN(d.getTime())) selectedDate = d
if ( val !== null && val !== undefined ) {
let d = new Date( val )
if ( !isNaN( d.getTime() ) ) selectedDate = d
}
}

placeholderText: qsTr("To")
placeholderText: qsTr( "To" )
text: {
if (!selectedDate) return ""
if (fieldDelegate.hasTime) return Qt.formatDateTime(selectedDate, Qt.DefaultLocaleShortDate)
return Qt.formatDate(selectedDate, Qt.DefaultLocaleShortDate)
if ( !selectedDate ) return ""
if ( fieldDelegate.hasTime ) return Qt.formatDateTime( selectedDate, Qt.DefaultLocaleShortDate )
return Qt.formatDate( selectedDate, Qt.DefaultLocaleShortDate )
}
textField.readOnly: true

Expand All @@ -249,7 +249,7 @@ Column {

onTextClicked: toCalendarLoader.active = true
onRightContentClicked: {
if (toDateInput.selectedDate) {
if ( toDateInput.selectedDate ) {
toDateInput.selectedDate = null
let fromDate = fromDateInput.selectedDate ? fromDateInput.selectedDate : null
__activeProject.filterController.setDateFilter(root.layerId, fieldDelegate.fieldName, fromDate, null, fieldDelegate.hasTime)
Expand Down Expand Up @@ -295,13 +295,13 @@ Column {
width: parent.width
visible: fieldDelegate.filterType === "text"
title: fieldDelegate.fieldDisplayName
placeholderText: qsTr("Type to filter...")
placeholderText: qsTr( "Type to filter..." )

// Explicitly handle undefined/null values
text: {
let val = fieldDelegate.currentValue
if (val !== null && val !== undefined && val !== "") {
return String(val)
if ( val !== null && val !== undefined && val !== "" ) {
return String( val )
}
return ""
}
Expand All @@ -311,7 +311,7 @@ Column {
Component.onCompleted: initialized = true

onTextChanged: {
if (!initialized) return
if ( !initialized ) return
// Pass raw text to C++ - validation happens there
__activeProject.filterController.setTextFilter(root.layerId, fieldDelegate.fieldName, text)
}
Expand All @@ -338,14 +338,14 @@ Column {
width: parent.width
textField.readOnly: true

placeholderText: qsTr("Select...")
placeholderText: qsTr( "Select..." )
text: {
let texts = fieldDelegate.currentValueTexts
if (!texts || texts.length === 0) return ""
if (fieldDelegate.multiSelect && texts.length > 1) {
return qsTr("%1 selected").arg(texts.length)
if ( !texts || texts.length === 0 ) return ""
if ( fieldDelegate.multiSelect && texts.length > 1 ) {
return qsTr( "%1 selected" ).arg( texts.length )
}
return texts.join(", ")
return texts.join( ", " )
}

rightContent: MMIcon {
Expand Down Expand Up @@ -386,7 +386,7 @@ Column {

list.model: ListModel { id: dropdownListModel }

onSearchTextChanged: function(searchText) {
onSearchTextChanged: function( searchText ) {
internal.pendingSearchText = searchText
searchDebounceTimer.restart()
}
Expand All @@ -410,30 +410,30 @@ Column {
interval: 300
repeat: false
onTriggered: {
populateOptions(internal.pendingSearchText)
populateOptions( internal.pendingSearchText )
}
}

function populateOptions(searchText) {
let options = __activeProject.filterController.getDropdownOptions(root.vectorLayer, fieldDelegate.fieldName, searchText, 100)
dropdownListModel.clear()
for (let i = 0; i < options.length; i++) {
dropdownListModel.append(options[i])
for ( let i = 0; i < options.length; i++ ) {
dropdownListModel.append( options[i] )
}
}

Component.onCompleted: {
// Set selected imperatively — QStringList from C++ needs
// conversion to a plain JS array for includes() to work
let val = fieldDelegate.currentValue
if (val && val.length > 0) {
if ( val && val.length > 0 ) {
let arr = []
for (let i = 0; i < val.length; i++) {
arr.push(String(val[i]))
for ( let i = 0; i < val.length; i++ ) {
arr.push( String( val[i] ) )
}
selected = arr
}
populateOptions("")
populateOptions( "" )
open()
}
}
Expand Down
4 changes: 2 additions & 2 deletions app/qml/filters/MMFiltersPanel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ MMComponents.MMDrawer {

drawerContent: Item {
width: parent.width
height: root.maxHeightHit ? root.drawerContentAvailableHeight : (contentColumn.implicitHeight + __style.margin12 + showResultsButton.height)
height: root.maxHeightHit ? root.drawerContentAvailableHeight : ( contentColumn.implicitHeight + __style.margin12 + showResultsButton.height )

MMComponents.MMScrollView {
id: scrollView
Expand Down Expand Up @@ -169,7 +169,7 @@ MMComponents.MMDrawer {
Connections {
target: __activeProject

function onProjectReloaded(qgsProject) {
function onProjectReloaded( qgsProject ) {
internal.refreshLayers()
}
}
Expand Down
Loading
Loading