QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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 "qgsfield.h"
19 #include "qgsfieldvalidator.h"
20 #include "qgsexpression.h"
21 #include <QSettings>
22 #include <QHBoxLayout>
23 
25  : QgsSearchWidgetWrapper( vl, fieldIdx, parent )
26  , mLineEdit( nullptr )
27  , mCheckbox( nullptr )
28  , mContainer( nullptr )
29  , mCaseString( QString( "LIKE" ) )
30 {
31 }
32 
34 {
35  return mExpression;
36 }
37 
38 void QgsDefaultSearchWidgetWrapper::setCaseString( int caseSensitiveCheckState )
39 {
40  if ( caseSensitiveCheckState == Qt::Checked )
41  {
42  mCaseString = "LIKE";
43  }
44  else
45  {
46  mCaseString = "ILIKE";
47  }
48  // need to update also the line edit
49  setExpression( mLineEdit->text() );
50 
51  if ( applyDirectly() )
53 }
54 
56 {
57  QVariant::Type fldType = layer()->fields().at( mFieldIdx ).type();
58  bool numeric = ( fldType == QVariant::Int || fldType == QVariant::Double || fldType == QVariant::LongLong );
59 
60  QSettings settings;
61  QString nullValue = settings.value( "qgis/nullValue", "NULL" ).toString();
62  QString fieldName = layer()->fields().at( mFieldIdx ).name();
63  QString str;
64  if ( exp == nullValue )
65  {
66  str = QString( "%1 IS NULL" ).arg( QgsExpression::quotedColumnRef( fieldName ) );
67  }
68  else
69  {
70  str = QString( "%1 %2 '%3'" )
71  .arg( QgsExpression::quotedColumnRef( fieldName ),
72  numeric ? "=" : mCaseString,
73  numeric ?
74  exp.replace( '\'', "''" )
75  :
76  '%' + exp.replace( '\'', "''" ) + '%' ); // escape quotes
77  }
78  mExpression = str;
79 }
80 
82 {
83  return new QWidget( parent );
84 }
85 
87 {
88  return false;
89 }
90 
91 QgsSearchWidgetWrapper::FilterFlags QgsDefaultSearchWidgetWrapper::supportedFlags() const
92 {
93  FilterFlags flags = EqualTo | NotEqualTo | IsNull | IsNotNull;
94 
95  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:
110  flags |= Contains | DoesNotContain;
111  break;
112 
113  default:
114  break;
115  }
116  return flags;
117 }
118 
119 QgsSearchWidgetWrapper::FilterFlags QgsDefaultSearchWidgetWrapper::defaultFlags() const
120 {
121  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 
146 QString QgsDefaultSearchWidgetWrapper::createExpression( QgsSearchWidgetWrapper::FilterFlags flags ) const
147 {
148  //clear any unsupported flags
149  flags &= supportedFlags();
150 
151  QVariant::Type fldType = layer()->fields().at( mFieldIdx ).type();
152  QString fieldName = QgsExpression::quotedColumnRef( layer()->fields().at( mFieldIdx ).name() );
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 QString( "lower(%1)" ).arg( fieldName )
211  + ( flags & EqualTo ? "=" : "<>" ) +
212  QString( "lower(%1)" ).arg( QgsExpression::quotedString( mLineEdit->text() ) );
213  }
214  else if ( flags & Contains || flags & DoesNotContain )
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 += "'%" + value + "%'";
221  if ( flags & DoesNotContain )
222  exp.prepend( "NOT (" ).append( ")" );
223  return exp;
224  }
225 
226  break;
227  }
228 
229  default:
230  break;
231  }
232 
233  return QString();
234 }
235 
237 {
238  mLineEdit->setText( QString() );
239 }
240 
242 {
243  mLineEdit->setEnabled( enabled );
244  if ( mCheckbox )
245  mCheckbox->setEnabled( enabled );
246 }
247 
249 {
250  mContainer = widget;
251  mContainer->setLayout( new QHBoxLayout() );
252  mContainer->layout()->setMargin( 0 );
253  mContainer->layout()->setContentsMargins( 0, 0, 0, 0 );
254  mLineEdit = new QgsFilterLineEdit();
255  mContainer->layout()->addWidget( mLineEdit );
256 
257  QVariant::Type fldType = layer()->fields().at( mFieldIdx ).type();
258  if ( fldType == QVariant::String )
259  {
260  mCheckbox = new QCheckBox( "Case sensitive" );
261  mContainer->layout()->addWidget( mCheckbox );
262  connect( mCheckbox, SIGNAL( stateChanged( int ) ), this, SLOT( setCaseString( int ) ) );
263  mCheckbox->setChecked( Qt::Unchecked );
264  }
265 
266  connect( mLineEdit, SIGNAL( textChanged( QString ) ), this, SLOT( textChanged( QString ) ) );
267  connect( mLineEdit, SIGNAL( returnPressed() ), this, SLOT( filterChanged() ) );
268  connect( mLineEdit, SIGNAL( textEdited( QString ) ), this, SIGNAL( valueChanged() ) );
269 
270  mCaseString = "ILIKE";
271 }
272 
274 {
275  return true;
276 }
277 
279 {
280  return mLineEdit;
281 }
282 
284 {
285  return mCheckbox;
286 }
287 
288 void QgsDefaultSearchWidgetWrapper::filterChanged()
289 {
291 }
292 
293 void QgsDefaultSearchWidgetWrapper::textChanged( const QString& text )
294 {
295  if ( text.isEmpty() )
296  emit valueCleared();
297 
298  setExpression( text );
299 }
QLayout * layout() const
Manages an editor widget Widget and wrapper share the same parent.
QString & append(QChar ch)
void setContentsMargins(int left, int top, int right, int bottom)
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
QString name
Definition: qgsfield.h:52
QString & prepend(QChar ch)
virtual void setEnabled(bool enabled) override
QWidget * createWidget(QWidget *parent) override
This method should create a new widget with the provided parent.
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
QCheckBox * caseSensitiveCheckBox()
Returns a pointer to the case sensitivity check box in the widget.
void chop(int n)
QgsFilterLineEdit * lineEdit()
Returns a pointer to the line edit part of the widget.
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:422
QgsFields fields() const
Returns the list of fields of this layer.
const char * name() const
void setEnabled(bool)
void setLayout(QLayout *layout)
void valueChanged()
Emitted when a user changes the value of the search widget.
FilterFlags defaultFlags() const override
Returns the filter flags which should be set by default for the search widget.
bool isEmpty() const
QString expression() override
Will be used to access the widget&#39;s value.
QLineEdit subclass with built in support for clearing the widget&#39;s value and handling custom null val...
void expressionChanged(const QString &exp)
Emitted whenever the expression changes.
void setMargin(int margin)
void addWidget(QWidget *w)
bool valid() const override
Return true if the widget has been properly initialized.
bool isChecked() const
QString & replace(int position, int n, QChar after)
QVariant value(const QString &key, const QVariant &defaultValue) const
bool applyDirectly() override
If this is true, then this search widget should take effect directly when its expression changes...
void valueCleared()
Emitted when a user changes the value of the search widget back to an empty, default state...
QgsDefaultSearchWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QWidget *parent=nullptr)
static QString quotedString(QString text)
Returns a quoted version of a string (in single quotes)
virtual QString createExpression(FilterFlags flags) const override
Creates a filter expression based on the current state of the search widget and the specified filter ...
QWidget * widget()
Access the widget managed by this wrapper.
QgsVectorLayer * layer() const
Access the QgsVectorLayer, you are working on.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const
Represents a vector layer which manages a vector based data sets.
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
Definition: qgsfield.cpp:97
FilterFlags supportedFlags() const override
Returns filter flags supported by the search widget.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QString toString() const