QGIS API Documentation  3.2.0-Bonn (bc43194)
qgsvaluerelationsearchwidgetwrapper.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvaluerelationsearchwidgetwrapper.cpp
3  --------------------------------------
4  Date : 5.1.2014
5  Copyright : (C) 2014 Matthias Kuhn
6  Email : matthias at opengis dot ch
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"
20 #include "qgsvectorlayer.h"
21 #include "qgsfilterlineedit.h"
23 #include "qgssettings.h"
24 
25 #include <QStringListModel>
26 #include <QCompleter>
27 
29  : QgsSearchWidgetWrapper( vl, fieldIdx, parent )
30 
31 {
32 }
33 
35 {
36  return !mLineEdit;
37 }
38 
40 {
41  return mExpression;
42 }
43 
45 {
46  QVariant v;
47 
48  if ( mComboBox )
49  {
50  int cbxIdx = mComboBox->currentIndex();
51  if ( cbxIdx > -1 )
52  {
53  v = mComboBox->currentData();
54  }
55  }
56 
57  if ( mLineEdit )
58  {
59  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem &i, mCache )
60  {
61  if ( i.value == mLineEdit->text() )
62  {
63  v = i.key;
64  break;
65  }
66  }
67  }
68 
69  return v;
70 }
71 
72 QgsSearchWidgetWrapper::FilterFlags QgsValueRelationSearchWidgetWrapper::supportedFlags() const
73 {
74  return EqualTo | NotEqualTo | IsNull | IsNotNull;
75 }
76 
77 QgsSearchWidgetWrapper::FilterFlags QgsValueRelationSearchWidgetWrapper::defaultFlags() const
78 {
79  return EqualTo;
80 }
81 
82 QString QgsValueRelationSearchWidgetWrapper::createExpression( QgsSearchWidgetWrapper::FilterFlags flags ) const
83 {
84  QString fieldName = createFieldIdentifier();
85 
86  //clear any unsupported flags
87  flags &= supportedFlags();
88  if ( flags & IsNull )
89  return fieldName + " IS NULL";
90  if ( flags & IsNotNull )
91  return fieldName + " IS NOT NULL";
92 
93  QVariant v = value();
94  if ( !v.isValid() )
95  return QString();
96 
97  switch ( v.type() )
98  {
99  case QVariant::Int:
100  case QVariant::UInt:
101  case QVariant::Double:
102  case QVariant::LongLong:
103  case QVariant::ULongLong:
104  {
105  if ( flags & EqualTo )
106  return fieldName + '=' + v.toString();
107  else if ( flags & NotEqualTo )
108  return fieldName + "<>" + v.toString();
109  break;
110  }
111 
112  default:
113  {
114  if ( flags & EqualTo )
115  return fieldName + "='" + v.toString() + '\'';
116  else if ( flags & NotEqualTo )
117  return fieldName + "<>'" + v.toString() + '\'';
118  break;
119  }
120  }
121 
122  return QString();
123 }
124 
126 {
127  if ( mComboBox )
128  {
129  mComboBox->setCurrentIndex( 0 );
130  }
131  if ( mLineEdit )
132  {
133  mLineEdit->setText( QString() );
134  }
135 }
136 
138 {
139  if ( mComboBox )
140  {
141  mComboBox->setEnabled( enabled );
142  }
143  if ( mLineEdit )
144  {
145  mLineEdit->setEnabled( enabled );
146  }
147 }
148 
150 {
151  return true;
152 }
153 
155 {
156  QVariant vl = value();
157  if ( !vl.isValid() )
158  {
159  clearExpression();
160  emit valueCleared();
161  }
162  else
163  {
164  setExpression( vl.isNull() ? QgsApplication::nullRepresentation() : vl.toString() );
165  emit valueChanged();
166  }
168 }
169 
171 {
172  QString exp = expression;
173  QString nullValue = QgsApplication::nullRepresentation();
174  QString fieldName = layer()->fields().at( mFieldIdx ).name();
175 
176  QString str;
177  if ( exp == nullValue )
178  {
179  str = QStringLiteral( "%1 IS NULL" ).arg( QgsExpression::quotedColumnRef( fieldName ) );
180  }
181  else
182  {
183  str = QStringLiteral( "%1 = '%3'" )
184  .arg( QgsExpression::quotedColumnRef( fieldName ),
185  exp.replace( '\'', QLatin1String( "''" ) )
186  );
187  }
188  mExpression = str;
189 }
190 
192 {
193  if ( config( QStringLiteral( "AllowMulti" ) ).toBool() )
194  {
195  return new QgsFilterLineEdit( parent );
196  }
197  else if ( config( QStringLiteral( "UseCompleter" ) ).toBool() )
198  {
199  return new QgsFilterLineEdit( parent );
200  }
201  else
202  {
203  return new QComboBox( parent );
204  }
205 }
206 
208 {
210 
211  mComboBox = qobject_cast<QComboBox *>( editor );
212  mLineEdit = qobject_cast<QLineEdit *>( editor );
213 
214  if ( mComboBox )
215  {
216  mComboBox->addItem( tr( "Please select" ), QVariant() ); // creates an invalid to allow selecting all features
217  if ( config( QStringLiteral( "AllowNull" ) ).toBool() )
218  {
219  mComboBox->addItem( tr( "(no selection)" ), QVariant( layer()->fields().at( mFieldIdx ).type() ) );
220  }
221 
222  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem &element, mCache )
223  {
224  mComboBox->addItem( element.value, element.key );
225  }
226 
227  connect( mComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsValueRelationSearchWidgetWrapper::onValueChanged );
228  }
229  else if ( mLineEdit )
230  {
231  QStringList values;
232  values.reserve( mCache.size() );
233  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem &i, mCache )
234  {
235  values << i.value;
236  }
237 
238  QStringListModel *m = new QStringListModel( values, mLineEdit );
239  QCompleter *completer = new QCompleter( m, mLineEdit );
240  completer->setCaseSensitivity( Qt::CaseInsensitive );
241  mLineEdit->setCompleter( completer );
242  connect( mLineEdit, &QLineEdit::textChanged, this, &QgsValueRelationSearchWidgetWrapper::onValueChanged );
243  }
244 }
245 
246 
QgsValueRelationSearchWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QWidget *parent=nullptr)
Constructor for QgsValueRelationSearchWidgetWrapper.
Shows a search widget on a filter form.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
QString name
Definition: qgsfield.h:57
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
bool valid() const override
Returns true if the widget has been properly initialized.
Supports searching for non-null values.
QString createExpression(QgsSearchWidgetWrapper::FilterFlags flags) const override
void clearExpression()
clears the expression to search for all features
QVariantMap config() const
Returns the whole config.
QString createFieldIdentifier() const
Gets a field name or expression to use as field comparison.
QWidget * createWidget(QWidget *parent) override
This method should create a new widget with the provided parent.
bool applyDirectly() override
If this is true, then this search widget should take effect directly when its expression changes...
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
Definition: qgsfields.cpp:145
Supports searching for null values.
QgsFields fields() const override
Returns the list of fields of this layer.
void valueChanged()
Emitted when a user changes the value of the search widget.
void onValueChanged()
Called when current value of search widget changes.
QLineEdit subclass with built in support for clearing the widget&#39;s value and handling custom null val...
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
void expressionChanged(const QString &exp)
Emitted whenever the expression changes.
QVariant createCache(QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config) const override
Create a cache for a given field.
QgsSearchWidgetWrapper::FilterFlags defaultFlags() const override
Returns the filter flags which should be set by default for the search widget.
void valueCleared()
Emitted when a user changes the value of the search widget back to an empty, default state...
QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.
Represents a vector layer which manages a vector based data sets.
QgsSearchWidgetWrapper::FilterFlags supportedFlags() const override
Returns filter flags supported by the search widget.
QString expression() const override
Will be used to access the widget&#39;s value.