QGIS API Documentation  3.6.0-Noosa (5873452)
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 #include "qgsapplication.h"
25 
26 #include <QStringListModel>
27 #include <QCompleter>
28 
30  : QgsSearchWidgetWrapper( vl, fieldIdx, parent )
31 
32 {
33 }
34 
36 {
37  return !mLineEdit;
38 }
39 
41 {
42  return mExpression;
43 }
44 
46 {
47  QVariant v;
48 
49  if ( mComboBox )
50  {
51  int cbxIdx = mComboBox->currentIndex();
52  if ( cbxIdx > -1 )
53  {
54  v = mComboBox->currentData();
55  }
56  }
57 
58  if ( mLineEdit )
59  {
60  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem &i, mCache )
61  {
62  if ( i.value == mLineEdit->text() )
63  {
64  v = i.key;
65  break;
66  }
67  }
68  }
69 
70  return v;
71 }
72 
73 QgsSearchWidgetWrapper::FilterFlags QgsValueRelationSearchWidgetWrapper::supportedFlags() const
74 {
75  return EqualTo | NotEqualTo | IsNull | IsNotNull;
76 }
77 
78 QgsSearchWidgetWrapper::FilterFlags QgsValueRelationSearchWidgetWrapper::defaultFlags() const
79 {
80  return EqualTo;
81 }
82 
83 QString QgsValueRelationSearchWidgetWrapper::createExpression( QgsSearchWidgetWrapper::FilterFlags flags ) const
84 {
85  QString fieldName = createFieldIdentifier();
86 
87  //clear any unsupported flags
88  flags &= supportedFlags();
89  if ( flags & IsNull )
90  return fieldName + " IS NULL";
91  if ( flags & IsNotNull )
92  return fieldName + " IS NOT NULL";
93 
94  QVariant v = value();
95  if ( !v.isValid() )
96  return QString();
97 
98  switch ( v.type() )
99  {
100  case QVariant::Int:
101  case QVariant::UInt:
102  case QVariant::Double:
103  case QVariant::LongLong:
104  case QVariant::ULongLong:
105  {
106  if ( flags & EqualTo )
107  return fieldName + '=' + v.toString();
108  else if ( flags & NotEqualTo )
109  return fieldName + "<>" + v.toString();
110  break;
111  }
112 
113  default:
114  {
115  if ( flags & EqualTo )
116  return fieldName + "='" + v.toString() + '\'';
117  else if ( flags & NotEqualTo )
118  return fieldName + "<>'" + v.toString() + '\'';
119  break;
120  }
121  }
122 
123  return QString();
124 }
125 
127 {
128  if ( mComboBox )
129  {
130  mComboBox->setCurrentIndex( 0 );
131  }
132  if ( mLineEdit )
133  {
134  mLineEdit->setText( QString() );
135  }
136 }
137 
139 {
140  if ( mComboBox )
141  {
142  mComboBox->setEnabled( enabled );
143  }
144  if ( mLineEdit )
145  {
146  mLineEdit->setEnabled( enabled );
147  }
148 }
149 
151 {
152  return true;
153 }
154 
156 {
157  QVariant vl = value();
158  if ( !vl.isValid() )
159  {
160  clearExpression();
161  emit valueCleared();
162  }
163  else
164  {
165  setExpression( vl.isNull() ? QgsApplication::nullRepresentation() : vl.toString() );
166  emit valueChanged();
167  }
169 }
170 
172 {
173  QString exp = expression;
174  QString nullValue = QgsApplication::nullRepresentation();
175  QString fieldName = layer()->fields().at( mFieldIdx ).name();
176 
177  QString str;
178  if ( exp == nullValue )
179  {
180  str = QStringLiteral( "%1 IS NULL" ).arg( QgsExpression::quotedColumnRef( fieldName ) );
181  }
182  else
183  {
184  str = QStringLiteral( "%1 = '%3'" )
185  .arg( QgsExpression::quotedColumnRef( fieldName ),
186  exp.replace( '\'', QLatin1String( "''" ) )
187  );
188  }
189  mExpression = str;
190 }
191 
193 {
194  if ( config( QStringLiteral( "AllowMulti" ) ).toBool() )
195  {
196  return new QgsFilterLineEdit( parent );
197  }
198  else if ( config( QStringLiteral( "UseCompleter" ) ).toBool() )
199  {
200  return new QgsFilterLineEdit( parent );
201  }
202  else
203  {
204  return new QComboBox( parent );
205  }
206 }
207 
209 {
211 
212  mComboBox = qobject_cast<QComboBox *>( editor );
213  mLineEdit = qobject_cast<QLineEdit *>( editor );
214 
215  if ( mComboBox )
216  {
217  mComboBox->addItem( tr( "Please select" ), QVariant() ); // creates an invalid to allow selecting all features
218  if ( config( QStringLiteral( "AllowNull" ) ).toBool() )
219  {
220  mComboBox->addItem( tr( "(no selection)" ), QVariant( layer()->fields().at( mFieldIdx ).type() ) );
221  }
222 
223  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem &element, mCache )
224  {
225  mComboBox->addItem( element.value, element.key );
226  }
227 
228  connect( mComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsValueRelationSearchWidgetWrapper::onValueChanged );
229  }
230  else if ( mLineEdit )
231  {
232  QStringList values;
233  values.reserve( mCache.size() );
234  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem &i, mCache )
235  {
236  values << i.value;
237  }
238 
239  QStringListModel *m = new QStringListModel( values, mLineEdit );
240  QCompleter *completer = new QCompleter( m, mLineEdit );
241  completer->setCaseSensitivity( Qt::CaseInsensitive );
242  mLineEdit->setCompleter( completer );
243  connect( mLineEdit, &QLineEdit::textChanged, this, &QgsValueRelationSearchWidgetWrapper::onValueChanged );
244  }
245 }
246 
247 
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:58
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:163
Supports searching for null values.
QgsFields fields() const FINAL
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.