diff --git a/python/gui/editorwidgets/core/qgssearchwidgetwrapper.sip b/python/gui/editorwidgets/core/qgssearchwidgetwrapper.sip index 1351c58b5a1..648629b6094 100644 --- a/python/gui/editorwidgets/core/qgssearchwidgetwrapper.sip +++ b/python/gui/editorwidgets/core/qgssearchwidgetwrapper.sip @@ -90,6 +90,8 @@ class QgsSearchWidgetWrapper : QgsWidgetWrapper IsNull, IsNotBetween, IsNotNull, + StartsWith, + EndsWith, }; typedef QFlags FilterFlags; diff --git a/src/gui/editorwidgets/core/qgssearchwidgetwrapper.cpp b/src/gui/editorwidgets/core/qgssearchwidgetwrapper.cpp index 8dc5361ec25..450e9ff6d99 100644 --- a/src/gui/editorwidgets/core/qgssearchwidgetwrapper.cpp +++ b/src/gui/editorwidgets/core/qgssearchwidgetwrapper.cpp @@ -34,7 +34,9 @@ QList QgsSearchWidgetWrapper::exclusiveFilte << Contains << DoesNotContain << IsNull - << IsNotNull; + << IsNotNull + << StartsWith + << EndsWith; } QList QgsSearchWidgetWrapper::nonExclusiveFilterFlags() @@ -73,7 +75,10 @@ QString QgsSearchWidgetWrapper::toString( QgsSearchWidgetWrapper::FilterFlag fla return QObject::tr( "Is missing (null)" ); case IsNotNull: return QObject::tr( "Is not missing (not null)" ); - + case StartsWith: + return QObject::tr( "Starts with" ); + case EndsWith: + return QObject::tr( "Ends with" ); } return QString(); } diff --git a/src/gui/editorwidgets/core/qgssearchwidgetwrapper.h b/src/gui/editorwidgets/core/qgssearchwidgetwrapper.h index 4b19d2e6bc6..ce304c71cdc 100644 --- a/src/gui/editorwidgets/core/qgssearchwidgetwrapper.h +++ b/src/gui/editorwidgets/core/qgssearchwidgetwrapper.h @@ -109,6 +109,8 @@ class GUI_EXPORT QgsSearchWidgetWrapper : public QgsWidgetWrapper IsNull = 1 << 11, //!< Supports searching for null values IsNotBetween = 1 << 12, //!< Supports searching for values outside of a set range IsNotNull = 1 << 13, //!< Supports searching for non-null values + StartsWith = 1 << 14, //!< Supports searching for strings that start with + EndsWith = 1 << 15, //!< Supports searching for strings that end with }; Q_DECLARE_FLAGS( FilterFlags, FilterFlag ) diff --git a/src/gui/editorwidgets/qgsdefaultsearchwidgetwrapper.cpp b/src/gui/editorwidgets/qgsdefaultsearchwidgetwrapper.cpp index 569fa8eea1b..abcd6d2c1d8 100644 --- a/src/gui/editorwidgets/qgsdefaultsearchwidgetwrapper.cpp +++ b/src/gui/editorwidgets/qgsdefaultsearchwidgetwrapper.cpp @@ -109,7 +109,7 @@ QgsSearchWidgetWrapper::FilterFlags QgsDefaultSearchWidgetWrapper::supportedFlag break; case QVariant::String: - flags |= Contains | DoesNotContain; + flags |= Contains | DoesNotContain | StartsWith | EndsWith; break; default: @@ -213,15 +213,21 @@ QString QgsDefaultSearchWidgetWrapper::createExpression( QgsSearchWidgetWrapper: + ( flags & EqualTo ? "=" : "<>" ) + QStringLiteral( "lower(%1)" ).arg( QgsExpression::quotedString( mLineEdit->text() ) ); } - else if ( flags & Contains || flags & DoesNotContain ) + else if ( flags & Contains || flags & DoesNotContain || flags & StartsWith || flags & EndsWith ) { QString exp = fieldName + ( mCheckbox && mCheckbox->isChecked() ? " LIKE " : " ILIKE " ); QString value = QgsExpression::quotedString( mLineEdit->text() ); value.chop( 1 ); value = value.remove( 0, 1 ); - exp += "'%" + value + "%'"; + exp += '\''; + if ( !flags.testFlag( StartsWith ) ) + exp += '%'; + exp += value; + if ( !flags.testFlag( EndsWith ) ) + exp += '%'; + exp += '\''; if ( flags & DoesNotContain ) - exp.prepend( "NOT (" ).append( ")" ); + exp.prepend( "NOT (" ).append( ')' ); return exp; } diff --git a/tests/src/python/test_qgssearchwidgetwrapper.py b/tests/src/python/test_qgssearchwidgetwrapper.py index ccbd555b01e..c5c5e54cd6f 100644 --- a/tests/src/python/test_qgssearchwidgetwrapper.py +++ b/tests/src/python/test_qgssearchwidgetwrapper.py @@ -87,9 +87,13 @@ class PyQgsDefaultSearchWidgetWrapper(unittest.TestCase): case_sensitive.setChecked(False) self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.Contains), '"fldtxt" ILIKE \'%test%\'') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.DoesNotContain), 'NOT ("fldtxt" ILIKE \'%test%\')') + self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.StartsWith), '"fldtxt" ILIKE \'test%\'') + self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EndsWith), '"fldtxt" ILIKE \'%test\'') case_sensitive.setChecked(True) self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.Contains), '"fldtxt" LIKE \'%test%\'') self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.DoesNotContain), 'NOT ("fldtxt" LIKE \'%test%\')') + self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.StartsWith), '"fldtxt" LIKE \'test%\'') + self.assertEqual(w.createExpression(QgsSearchWidgetWrapper.EndsWith), '"fldtxt" LIKE \'%test\'') case_sensitive.setChecked(False) # numeric field