QGIS API Documentation  2.14.0-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.
QgsFields fields() const
Returns the list of fields of this layer.
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)
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...
void addItem(const QString &text, const QVariant &userData)
bool isNull() const
QString name() const
Gets the name of the field.
Definition: qgsfield.cpp:84
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
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:385
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
QgsVectorLayer * layer() const
Access the QgsVectorLayer, you are working on.
QgsEditorWidgetConfig config() const
Returns the whole config.
bool isValid() const
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