QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
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#include "moc_qgsdefaultsearchwidgetwrapper.cpp"
18
19#include "qgsfields.h"
20#include "qgsfieldvalidator.h"
21#include "qgsexpression.h"
23#include "qgssettings.h"
24#include "qgsapplication.h"
25
26#include <QHBoxLayout>
27
29 : QgsSearchWidgetWrapper( vl, fieldIdx, parent )
30 , mCaseString( QStringLiteral( "LIKE" ) )
31{
32}
33
35{
36 return mExpression;
37}
38
39void QgsDefaultSearchWidgetWrapper::setCaseString( int caseSensitiveCheckState )
40{
41 if ( caseSensitiveCheckState == Qt::Checked )
42 {
43 mCaseString = QStringLiteral( "LIKE" );
44 }
45 else
46 {
47 mCaseString = QStringLiteral( "ILIKE" );
48 }
49 // need to update also the line edit
50 setExpression( mLineEdit->text() );
51
52 if ( applyDirectly() )
54}
55
56void QgsDefaultSearchWidgetWrapper::setExpression( const QString &expression )
57{
58 const QMetaType::Type fldType = layer()->fields().at( mFieldIdx ).type();
59 const bool numeric = ( fldType == QMetaType::Type::Int || fldType == QMetaType::Type::Double || fldType == QMetaType::Type::LongLong );
60
61 QString exp = expression;
62 const QString nullValue = QgsApplication::nullRepresentation();
63 const QString fieldName = layer()->fields().at( mFieldIdx ).name();
64 QString str;
65 if ( exp == nullValue )
66 {
67 str = QStringLiteral( "%1 IS NULL" ).arg( QgsExpression::quotedColumnRef( fieldName ) );
68 }
69 else
70 {
71 str = QStringLiteral( "%1 %2 '%3'" )
72 .arg( QgsExpression::quotedColumnRef( fieldName ), numeric ? QStringLiteral( "=" ) : mCaseString, numeric ? exp.replace( '\'', QLatin1String( "''" ) ) : '%' + exp.replace( '\'', QLatin1String( "''" ) ) + '%' ); // escape quotes
73 }
74 mExpression = str;
75}
76
78{
79 return new QWidget( parent );
80}
81
83{
84 return false;
85}
86
88{
90
91 const QMetaType::Type fldType = layer()->fields().at( mFieldIdx ).type();
92 switch ( fldType )
93 {
94 case QMetaType::Type::Int:
95 case QMetaType::Type::UInt:
96 case QMetaType::Type::Double:
97 case QMetaType::Type::LongLong:
98 case QMetaType::Type::ULongLong:
99 case QMetaType::Type::QDate:
100 case QMetaType::Type::QDateTime:
101 case QMetaType::Type::QTime:
103 break;
104
105 case QMetaType::Type::QString:
107 break;
108
109 default:
110 break;
111 }
112 return flags;
113}
114
116{
117 const QMetaType::Type fldType = layer()->fields().at( mFieldIdx ).type();
118 switch ( fldType )
119 {
120 //numeric
121 case QMetaType::Type::Int:
122 case QMetaType::Type::UInt:
123 case QMetaType::Type::Double:
124 case QMetaType::Type::LongLong:
125 case QMetaType::Type::ULongLong:
126
127 // date
128 case QMetaType::Type::QDate:
129 case QMetaType::Type::QDateTime:
130 case QMetaType::Type::QTime:
131 return EqualTo;
132
133 case QMetaType::Type::QString:
134 return Contains;
135
136 default:
137 break;
138 }
139 return EqualTo;
140}
141
143{
144 //clear any unsupported flags
145 flags &= supportedFlags();
146
147 const QMetaType::Type fldType = layer()->fields().at( mFieldIdx ).type();
148 const QString fieldName = createFieldIdentifier();
149
150 if ( flags & IsNull )
151 return fieldName + " IS NULL";
152 if ( flags & IsNotNull )
153 return fieldName + " IS NOT NULL";
154
155 switch ( fldType )
156 {
157 case QMetaType::Type::Int:
158 case QMetaType::Type::UInt:
159 case QMetaType::Type::Double:
160 case QMetaType::Type::LongLong:
161 case QMetaType::Type::ULongLong:
162 {
163 if ( flags & EqualTo )
164 return fieldName + '=' + mLineEdit->text();
165 else if ( flags & NotEqualTo )
166 return fieldName + "<>" + mLineEdit->text();
167 else if ( flags & GreaterThan )
168 return fieldName + '>' + mLineEdit->text();
169 else if ( flags & LessThan )
170 return fieldName + '<' + mLineEdit->text();
171 else if ( flags & GreaterThanOrEqualTo )
172 return fieldName + ">=" + mLineEdit->text();
173 else if ( flags & LessThanOrEqualTo )
174 return fieldName + "<=" + mLineEdit->text();
175 break;
176 }
177
178 case QMetaType::Type::QDate:
179 case QMetaType::Type::QDateTime:
180 case QMetaType::Type::QTime:
181 {
182 if ( flags & EqualTo )
183 return fieldName + "='" + mLineEdit->text() + '\'';
184 else if ( flags & NotEqualTo )
185 return fieldName + "<>'" + mLineEdit->text() + '\'';
186 else if ( flags & GreaterThan )
187 return fieldName + ">'" + mLineEdit->text() + '\'';
188 else if ( flags & LessThan )
189 return fieldName + "<'" + mLineEdit->text() + '\'';
190 else if ( flags & GreaterThanOrEqualTo )
191 return fieldName + ">='" + mLineEdit->text() + '\'';
192 else if ( flags & LessThanOrEqualTo )
193 return fieldName + "<='" + mLineEdit->text() + '\'';
194 break;
195 }
196
197 case QMetaType::Type::QString:
198 {
199 // case insensitive!
200 if ( flags & EqualTo || flags & NotEqualTo )
201 {
202 if ( mCheckbox && mCheckbox->isChecked() )
203 return fieldName + ( ( flags & EqualTo ) ? "=" : "<>" )
204 + QgsExpression::quotedString( mLineEdit->text() );
205 else
206 return QStringLiteral( "lower(%1)" ).arg( fieldName )
207 + ( ( flags & EqualTo ) ? "=" : "<>" ) + QStringLiteral( "lower(%1)" ).arg( QgsExpression::quotedString( mLineEdit->text() ) );
208 }
209 else if ( flags & Contains || flags & DoesNotContain || flags & StartsWith || flags & EndsWith )
210 {
211 QString exp = fieldName + ( mCheckbox && mCheckbox->isChecked() ? " LIKE " : " ILIKE " );
212 QString value = QgsExpression::quotedString( mLineEdit->text() );
213 value.chop( 1 );
214 value = value.remove( 0, 1 );
215 exp += '\'';
216 if ( !flags.testFlag( StartsWith ) )
217 exp += '%';
218 exp += value;
219 if ( !flags.testFlag( EndsWith ) )
220 exp += '%';
221 exp += '\'';
222 if ( flags & DoesNotContain )
223 exp.prepend( "NOT (" ).append( ')' );
224 return exp;
225 }
226
227 break;
228 }
229
230 default:
231 break;
232 }
233
234 return QString();
235}
236
238{
239 mLineEdit->setText( QString() );
240}
241
243{
244 mLineEdit->setEnabled( enabled );
245 if ( mCheckbox )
246 mCheckbox->setEnabled( enabled );
247}
248
250{
251 mContainer = widget;
252 mContainer->setLayout( new QHBoxLayout() );
253 mContainer->layout()->setContentsMargins( 0, 0, 0, 0 );
254 const QMetaType::Type fldType = layer()->fields().at( mFieldIdx ).type();
255
256 if ( fldType == QMetaType::Type::QString )
257 {
258 mLineEdit = new QgsFieldValuesLineEdit();
259 static_cast<QgsFieldValuesLineEdit *>( mLineEdit )->setLayer( layer() );
260 static_cast<QgsFieldValuesLineEdit *>( mLineEdit )->setAttributeIndex( mFieldIdx );
261 }
262 else
263 {
264 mLineEdit = new QgsFilterLineEdit();
265 }
266 mContainer->layout()->addWidget( mLineEdit );
267 mContainer->setFocusProxy( mLineEdit );
268
269 if ( fldType == QMetaType::Type::QString )
270 {
271 mCheckbox = new QCheckBox( QStringLiteral( "Case sensitive" ) );
272 mContainer->layout()->addWidget( mCheckbox );
273 connect( mCheckbox, &QCheckBox::stateChanged, this, &QgsDefaultSearchWidgetWrapper::setCaseString );
274 mCheckbox->setChecked( Qt::Unchecked );
275 }
276
277 connect( mLineEdit, &QLineEdit::textChanged, this, &QgsDefaultSearchWidgetWrapper::textChanged );
278 connect( mLineEdit, &QLineEdit::returnPressed, this, &QgsDefaultSearchWidgetWrapper::filterChanged );
279 connect( mLineEdit, &QLineEdit::textEdited, this, &QgsSearchWidgetWrapper::valueChanged );
280
281 mCaseString = QStringLiteral( "ILIKE" );
282}
283
285{
286 return true;
287}
288
293
295{
296 return mCheckbox;
297}
298
299void QgsDefaultSearchWidgetWrapper::filterChanged()
300{
302}
303
304void QgsDefaultSearchWidgetWrapper::textChanged( const QString &text )
305{
306 if ( text.isEmpty() )
307 emit valueCleared();
308
309 setExpression( text );
310}
static QString nullRepresentation()
Returns the string used to represent the value NULL throughout QGIS.
QString createExpression(QgsSearchWidgetWrapper::FilterFlags flags) const override
Creates a filter expression based on the current state of the search widget and the specified filter ...
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.
QMetaType::Type type
Definition qgsfield.h:60
QString name
Definition qgsfield.h:62
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
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.
@ 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.
QFlags< FilterFlag > FilterFlags
Represents a vector layer which manages a vector based data sets.
QWidget * widget()
Access the widget managed by this wrapper.
QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.