QGIS API Documentation  2.14.11-Essen
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 "qgsfield.h"
19 #include "qgsmaplayerregistry.h"
21 #include "qgsvectorlayer.h"
22 #include "qgsfilterlineedit.h"
23 
24 #include <QSettings>
25 #include <QStringListModel>
26 #include <QCompleter>
27 
29  : QgsSearchWidgetWrapper( vl, fieldIdx, parent )
30  , mComboBox( nullptr )
31  , mListWidget( nullptr )
32  , mLineEdit( nullptr )
33  , mLayer( nullptr )
34 {
35 }
36 
38 {
39  if ( mLineEdit )
40  {
41  return false;
42  }
43  return true;
44 }
45 
47 {
48  return mExpression;
49 }
50 
52 {
53  QVariant v;
54 
55  if ( mComboBox )
56  {
57  int cbxIdx = mComboBox->currentIndex();
58  if ( cbxIdx > -1 )
59  {
60  v = mComboBox->itemData( mComboBox->currentIndex() );
61  }
62  }
63 
64  if ( mListWidget )
65  {
66  QStringList selection;
67  for ( int i = 0; i < mListWidget->count(); ++i )
68  {
69  QListWidgetItem* item = mListWidget->item( i );
70  if ( item->checkState() == Qt::Checked )
71  selection << item->data( Qt::UserRole ).toString();
72  }
73 
74  v = selection.join( "," ).prepend( '{' ).append( '}' );
75  }
76 
77  if ( mLineEdit )
78  {
79  Q_FOREACH ( const ValueRelationItem& i , mCache )
80  {
81  if ( i.second == mLineEdit->text() )
82  {
83  v = i.first;
84  break;
85  }
86  }
87  }
88 
89  return v;
90 }
91 
93 {
94  return true;
95 }
96 
98 {
99  QVariant vl = value();
100  if ( !vl.isValid() )
101  {
102  clearExpression();
103  }
104  else
105  {
106  QSettings settings;
107  setExpression( vl.isNull() ? settings.value( "qgis/nullValue", "NULL" ).toString() : vl.toString() );
108  }
110 }
111 
113 {
114  QSettings settings;
115  QString nullValue = settings.value( "qgis/nullValue", "NULL" ).toString();
116  QString fieldName = layer()->fields().at( mFieldIdx ).name();
117 
118  QString str;
119  if ( exp == nullValue )
120  {
121  str = QString( "%1 IS NULL" ).arg( QgsExpression::quotedColumnRef( fieldName ) );
122  }
123  else
124  {
125  str = QString( "%1 = '%3'" )
126  .arg( QgsExpression::quotedColumnRef( fieldName ),
127  exp.replace( '\'', "''" )
128  );
129  }
130  mExpression = str;
131 }
132 
134 {
135  if ( config( "AllowMulti" ).toBool() )
136  {
137  return new QgsFilterLineEdit( parent );
138  }
139  else if ( config( "UseCompleter" ).toBool() )
140  {
141  return new QgsFilterLineEdit( parent );
142  }
143  else
144  {
145  return new QComboBox( parent );
146  }
147 }
148 
150 {
152 
153  mComboBox = qobject_cast<QComboBox*>( editor );
154  mListWidget = qobject_cast<QListWidget*>( editor );
155  mLineEdit = qobject_cast<QLineEdit*>( editor );
156 
157  if ( mComboBox )
158  {
159  mComboBox->addItem( tr( "Please select" ), QVariant() ); // creates an invalid to allow selecting all features
160  if ( config( "AllowNull" ).toBool() )
161  {
162  mComboBox->addItem( tr( "(no selection)" ), QVariant( layer()->fields().at( mFieldIdx ).type() ) );
163  }
164 
165  Q_FOREACH ( const ValueRelationItem& element, mCache )
166  {
167  mComboBox->addItem( element.second, element.first );
168  }
169 
170  connect( mComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( valueChanged() ) );
171  }
172  else if ( mListWidget )
173  {
174  Q_FOREACH ( const ValueRelationItem& element, mCache )
175  {
176  QListWidgetItem *item;
177  item = new QListWidgetItem( element.second );
178  item->setData( Qt::UserRole, element.first );
179 
180  mListWidget->addItem( item );
181  }
182  connect( mListWidget, SIGNAL( itemChanged( QListWidgetItem* ) ), this, SLOT( valueChanged() ) );
183  }
184  else if ( mLineEdit )
185  {
186  QStringList values;
187  Q_FOREACH ( const ValueRelationItem& i, mCache )
188  {
189  values << i.second;
190  }
191 
192  QStringListModel* m = new QStringListModel( values, mLineEdit );
193  QCompleter* completer = new QCompleter( m, mLineEdit );
194  completer->setCaseSensitivity( Qt::CaseInsensitive );
195  mLineEdit->setCompleter( completer );
196  connect( mLineEdit, SIGNAL( textChanged( QListWidgetItem* ) ), this, SLOT( valueChanged() ) );
197  }
198 }
199 
200 
void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity)
QgsValueRelationSearchWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QWidget *parent=nullptr)
Manages an editor widget Widget and wrapper share the same parent.
QString & append(QChar ch)
Qt::CheckState checkState() const
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
QString & prepend(QChar ch)
bool valid() const override
Return true if the widget has been properly initialized.
void clearExpression()
clears the expression to search for all features
QString join(const QString &separator) const
QString tr(const char *sourceText, const char *disambiguation, int n)
QString name() const
Gets the name of the field.
Definition: qgsfield.cpp:84
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:385
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...
QgsFields fields() const
Returns the list of fields of this layer.
void addItem(const QString &text, const QVariant &userData)
bool isNull() const
virtual QVariant data(int role) const
QString expression() override
Will be used to access the widget&#39;s value.
Lineedit with builtin clear button.
void expressionChanged(const QString &exp)
Emitted whenever the expression changes.
QListWidgetItem * item(int row) const
QVariant itemData(int index, int role) const
virtual void setData(int role, const QVariant &value)
static ValueRelationCache createCache(const QgsEditorWidgetConfig &config)
QString & replace(int position, int n, QChar after)
QVariant value(const QString &key, const QVariant &defaultValue) const
bool isValid() const
QgsEditorWidgetConfig config() const
Returns the whole config.
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.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QString toString() const