QGIS API Documentation 3.40.0-Bratislava (b56115d8743)
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
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 QMetaType::Type fldType = layer()->fields().at( mFieldIdx ).type();
58 const bool numeric = ( fldType == QMetaType::Type::Int || fldType == QMetaType::Type::Double || fldType == QMetaType::Type::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
92{
94
95 const QMetaType::Type fldType = layer()->fields().at( mFieldIdx ).type();
96 switch ( fldType )
97 {
98 case QMetaType::Type::Int:
99 case QMetaType::Type::UInt:
100 case QMetaType::Type::Double:
101 case QMetaType::Type::LongLong:
102 case QMetaType::Type::ULongLong:
103 case QMetaType::Type::QDate:
104 case QMetaType::Type::QDateTime:
105 case QMetaType::Type::QTime:
107 break;
108
109 case QMetaType::Type::QString:
111 break;
112
113 default:
114 break;
115 }
116 return flags;
117}
118
120{
121 const QMetaType::Type fldType = layer()->fields().at( mFieldIdx ).type();
122 switch ( fldType )
123 {
124 //numeric
125 case QMetaType::Type::Int:
126 case QMetaType::Type::UInt:
127 case QMetaType::Type::Double:
128 case QMetaType::Type::LongLong:
129 case QMetaType::Type::ULongLong:
130
131 // date
132 case QMetaType::Type::QDate:
133 case QMetaType::Type::QDateTime:
134 case QMetaType::Type::QTime:
135 return EqualTo;
136
137 case QMetaType::Type::QString:
138 return Contains;
139
140 default:
141 break;
142 }
143 return EqualTo;
144}
145
147{
148 //clear any unsupported flags
149 flags &= supportedFlags();
150
151 const QMetaType::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 QMetaType::Type::Int:
162 case QMetaType::Type::UInt:
163 case QMetaType::Type::Double:
164 case QMetaType::Type::LongLong:
165 case QMetaType::Type::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 QMetaType::Type::QDate:
183 case QMetaType::Type::QDateTime:
184 case QMetaType::Type::QTime:
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 QMetaType::Type::QString:
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 QMetaType::Type fldType = layer()->fields().at( mFieldIdx ).type();
260
261 if ( fldType == QMetaType::Type::QString )
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 == QMetaType::Type::QString )
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
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()
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.
#define str(x)
Definition qgis.cpp:38