QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgsdefaultsearchwidgetwrapper.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsdefaultsearchwidgettwrapper.cpp
3 --------------------------------------
4 Date : 31.5.2015
5 Copyright : (C) 2015 Karolina Alexiou (carolinux)
6 Email : carolinegr at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
17
18#include "qgsfields.h"
19#include "qgsfieldvalidator.h"
20#include "qgsexpression.h"
22#include "qgssettings.h"
23#include "qgsapplication.h"
24
25#include <QHBoxLayout>
26
28 : QgsSearchWidgetWrapper( vl, fieldIdx, parent )
29 , mCaseString( QStringLiteral( "LIKE" ) )
30{
31}
32
34{
35 return mExpression;
36}
37
38void QgsDefaultSearchWidgetWrapper::setCaseString( int caseSensitiveCheckState )
39{
40 if ( caseSensitiveCheckState == Qt::Checked )
41 {
42 mCaseString = QStringLiteral( "LIKE" );
43 }
44 else
45 {
46 mCaseString = QStringLiteral( "ILIKE" );
47 }
48 // need to update also the line edit
49 setExpression( mLineEdit->text() );
50
51 if ( applyDirectly() )
53}
54
55void QgsDefaultSearchWidgetWrapper::setExpression( const QString &expression )
56{
57 const QVariant::Type fldType = layer()->fields().at( mFieldIdx ).type();
58 const bool numeric = ( fldType == QVariant::Int || fldType == QVariant::Double || fldType == QVariant::LongLong );
59
60 QString exp = expression;
61 const QString nullValue = QgsApplication::nullRepresentation();
62 const QString fieldName = layer()->fields().at( mFieldIdx ).name();
63 QString str;
64 if ( exp == nullValue )
65 {
66 str = QStringLiteral( "%1 IS NULL" ).arg( QgsExpression::quotedColumnRef( fieldName ) );
67 }
68 else
69 {
70 str = QStringLiteral( "%1 %2 '%3'" )
71 .arg( QgsExpression::quotedColumnRef( fieldName ),
72 numeric ? QStringLiteral( "=" ) : mCaseString,
73 numeric ?
74 exp.replace( '\'', QLatin1String( "''" ) )
75 :
76 '%' + exp.replace( '\'', QLatin1String( "''" ) ) + '%' ); // escape quotes
77 }
79}
80
82{
83 return new QWidget( parent );
84}
85
87{
88 return false;
89}
90
91QgsSearchWidgetWrapper::FilterFlags QgsDefaultSearchWidgetWrapper::supportedFlags() const
92{
93 FilterFlags flags = EqualTo | NotEqualTo | IsNull | IsNotNull;
94
95 const QVariant::Type fldType = layer()->fields().at( mFieldIdx ).type();
96 switch ( fldType )
97 {
98 case QVariant::Int:
99 case QVariant::UInt:
100 case QVariant::Double:
101 case QVariant::LongLong:
102 case QVariant::ULongLong:
103 case QVariant::Date:
104 case QVariant::DateTime:
105 case QVariant::Time:
107 break;
108
109 case QVariant::String:
111 break;
112
113 default:
114 break;
115 }
116 return flags;
117}
118
119QgsSearchWidgetWrapper::FilterFlags QgsDefaultSearchWidgetWrapper::defaultFlags() const
120{
121 const QVariant::Type fldType = layer()->fields().at( mFieldIdx ).type();
122 switch ( fldType )
123 {
124 case QVariant::Int:
125 case QVariant::UInt:
126 case QVariant::Double:
127 case QVariant::LongLong:
128 case QVariant::ULongLong:
129 //numeric
130 return EqualTo;
131
132 case QVariant::Date:
133 case QVariant::DateTime:
134 case QVariant::Time:
135 return EqualTo;
136
137 case QVariant::String:
138 return Contains;
139
140 default:
141 break;
142 }
143 return EqualTo;
144}
145
146QString QgsDefaultSearchWidgetWrapper::createExpression( QgsSearchWidgetWrapper::FilterFlags flags ) const
147{
148 //clear any unsupported flags
149 flags &= supportedFlags();
150
151 const QVariant::Type fldType = layer()->fields().at( mFieldIdx ).type();
152 const QString fieldName = createFieldIdentifier();
153
154 if ( flags & IsNull )
155 return fieldName + " IS NULL";
156 if ( flags & IsNotNull )
157 return fieldName + " IS NOT NULL";
158
159 switch ( fldType )
160 {
161 case QVariant::Int:
162 case QVariant::UInt:
163 case QVariant::Double:
164 case QVariant::LongLong:
165 case QVariant::ULongLong:
166 {
167 if ( flags & EqualTo )
168 return fieldName + '=' + mLineEdit->text();
169 else if ( flags & NotEqualTo )
170 return fieldName + "<>" + mLineEdit->text();
171 else if ( flags & GreaterThan )
172 return fieldName + '>' + mLineEdit->text();
173 else if ( flags & LessThan )
174 return fieldName + '<' + mLineEdit->text();
175 else if ( flags & GreaterThanOrEqualTo )
176 return fieldName + ">=" + mLineEdit->text();
177 else if ( flags & LessThanOrEqualTo )
178 return fieldName + "<=" + mLineEdit->text();
179 break;
180 }
181
182 case QVariant::Date:
183 case QVariant::DateTime:
184 case QVariant::Time:
185 {
186 if ( flags & EqualTo )
187 return fieldName + "='" + mLineEdit->text() + '\'';
188 else if ( flags & NotEqualTo )
189 return fieldName + "<>'" + mLineEdit->text() + '\'';
190 else if ( flags & GreaterThan )
191 return fieldName + ">'" + mLineEdit->text() + '\'';
192 else if ( flags & LessThan )
193 return fieldName + "<'" + mLineEdit->text() + '\'';
194 else if ( flags & GreaterThanOrEqualTo )
195 return fieldName + ">='" + mLineEdit->text() + '\'';
196 else if ( flags & LessThanOrEqualTo )
197 return fieldName + "<='" + mLineEdit->text() + '\'';
198 break;
199 }
200
201 case QVariant::String:
202 {
203 // case insensitive!
204 if ( flags & EqualTo || flags & NotEqualTo )
205 {
206 if ( mCheckbox && mCheckbox->isChecked() )
207 return fieldName + ( ( flags & EqualTo ) ? "=" : "<>" )
208 + QgsExpression::quotedString( mLineEdit->text() );
209 else
210 return QStringLiteral( "lower(%1)" ).arg( fieldName )
211 + ( ( flags & EqualTo ) ? "=" : "<>" ) +
212 QStringLiteral( "lower(%1)" ).arg( QgsExpression::quotedString( mLineEdit->text() ) );
213 }
214 else if ( flags & Contains || flags & DoesNotContain || flags & StartsWith || flags & EndsWith )
215 {
216 QString exp = fieldName + ( mCheckbox && mCheckbox->isChecked() ? " LIKE " : " ILIKE " );
217 QString value = QgsExpression::quotedString( mLineEdit->text() );
218 value.chop( 1 );
219 value = value.remove( 0, 1 );
220 exp += '\'';
221 if ( !flags.testFlag( StartsWith ) )
222 exp += '%';
223 exp += value;
224 if ( !flags.testFlag( EndsWith ) )
225 exp += '%';
226 exp += '\'';
227 if ( flags & DoesNotContain )
228 exp.prepend( "NOT (" ).append( ')' );
229 return exp;
230 }
231
232 break;
233 }
234
235 default:
236 break;
237 }
238
239 return QString();
240}
241
243{
244 mLineEdit->setText( QString() );
245}
246
248{
249 mLineEdit->setEnabled( enabled );
250 if ( mCheckbox )
251 mCheckbox->setEnabled( enabled );
252}
253
255{
256 mContainer = widget;
257 mContainer->setLayout( new QHBoxLayout() );
258 mContainer->layout()->setContentsMargins( 0, 0, 0, 0 );
259 const QVariant::Type fldType = layer()->fields().at( mFieldIdx ).type();
260
261 if ( fldType == QVariant::String )
262 {
263 mLineEdit = new QgsFieldValuesLineEdit();
264 static_cast< QgsFieldValuesLineEdit * >( mLineEdit )->setLayer( layer() );
265 static_cast< QgsFieldValuesLineEdit * >( mLineEdit )->setAttributeIndex( mFieldIdx );
266 }
267 else
268 {
269 mLineEdit = new QgsFilterLineEdit();
270 }
271 mContainer->layout()->addWidget( mLineEdit );
272 mContainer->setFocusProxy( mLineEdit );
273
274 if ( fldType == QVariant::String )
275 {
276 mCheckbox = new QCheckBox( QStringLiteral( "Case sensitive" ) );
277 mContainer->layout()->addWidget( mCheckbox );
278 connect( mCheckbox, &QCheckBox::stateChanged, this, &QgsDefaultSearchWidgetWrapper::setCaseString );
279 mCheckbox->setChecked( Qt::Unchecked );
280 }
281
282 connect( mLineEdit, &QLineEdit::textChanged, this, &QgsDefaultSearchWidgetWrapper::textChanged );
283 connect( mLineEdit, &QLineEdit::returnPressed, this, &QgsDefaultSearchWidgetWrapper::filterChanged );
284 connect( mLineEdit, &QLineEdit::textEdited, this, &QgsSearchWidgetWrapper::valueChanged );
285
286 mCaseString = QStringLiteral( "ILIKE" );
287}
288
290{
291 return true;
292}
293
295{
296 return mLineEdit;
297}
298
300{
301 return mCheckbox;
302}
303
304void QgsDefaultSearchWidgetWrapper::filterChanged()
305{
307}
308
309void QgsDefaultSearchWidgetWrapper::textChanged( const QString &text )
310{
311 if ( text.isEmpty() )
312 emit valueCleared();
313
314 setExpression( text );
315}
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
QString createExpression(QgsSearchWidgetWrapper::FilterFlags flags) const override
void setExpression(const QString &exp) override
QWidget * createWidget(QWidget *parent) override
This method should create a new widget with the provided parent.
QString expression() const override
Will be used to access the widget's value.
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
QgsSearchWidgetWrapper::FilterFlags supportedFlags() const override
Returns filter flags supported by the search widget.
QCheckBox * caseSensitiveCheckBox()
Returns a pointer to the case sensitivity checkbox in the widget.
QgsFilterLineEdit * lineEdit()
Returns a pointer to the line edit part of the widget.
QgsDefaultSearchWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QWidget *parent=nullptr)
Constructor for QgsDefaultSearchWidgetWrapper.
bool applyDirectly() override
If this is true, then this search widget should take effect directly when its expression changes.
QgsSearchWidgetWrapper::FilterFlags defaultFlags() const override
Returns the filter flags which should be set by default for the search widget.
bool valid() const override
Returns true if the widget has been properly initialized.
static QString quotedString(QString text)
Returns a quoted version of a string (in single quotes)
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
A line edit with an autocompleter which takes unique values from a vector layer's fields.
QString name
Definition: qgsfield.h:60
QVariant::Type type
Definition: qgsfield.h:58
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Definition: qgsfields.cpp:163
QLineEdit subclass with built in support for clearing the widget's value and handling custom null val...
Shows a search widget on a filter form.
@ Contains
Supports value "contains" searching.
@ IsNotBetween
Supports searching for values outside of a set range.
@ StartsWith
Supports searching for strings that start with.
@ LessThan
Supports less than.
@ IsNull
Supports searching for null values.
@ EndsWith
Supports searching for strings that end with.
@ GreaterThan
Supports greater than.
@ IsNotNull
Supports searching for non-null values.
@ EqualTo
Supports equal to.
@ DoesNotContain
Supports value does not contain searching.
@ Between
Supports searches between two values.
@ NotEqualTo
Supports not equal to.
void valueChanged()
Emitted when a user changes the value of the search widget.
void valueCleared()
Emitted when a user changes the value of the search widget back to an empty, default state.
void expressionChanged(const QString &exp)
Emitted whenever the expression changes.
QString createFieldIdentifier() const
Gets a field name or expression to use as field comparison.
Represents a vector layer which manages a vector based data sets.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QWidget * widget()
Access the widget managed by this wrapper.
QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.
#define str(x)
Definition: qgis.cpp:37