QGIS API Documentation  2.99.0-Master (ae4d26a)
qgsvaluerelationwidgetwrapper.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvaluerelationwidgetwrapper.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 "qgis.h"
19 #include "qgsfields.h"
20 #include "qgsproject.h"
22 #include "qgsvectorlayer.h"
23 #include "qgsfilterlineedit.h"
24 #include "qgsfeatureiterator.h"
26 
27 #include <QStringListModel>
28 #include <QCompleter>
29 
30 QgsValueRelationWidgetWrapper::QgsValueRelationWidgetWrapper( QgsVectorLayer *vl, int fieldIdx, QWidget *editor, QWidget *parent )
31  : QgsEditorWidgetWrapper( vl, fieldIdx, editor, parent )
32  , mUpdating( false )
33 {
34 }
35 
36 
38 {
39  QVariant v;
40 
41  if ( mComboBox )
42  {
43  int cbxIdx = mComboBox->currentIndex();
44  if ( cbxIdx > -1 )
45  {
46  v = mComboBox->currentData();
47  }
48  }
49 
50  if ( mListWidget )
51  {
52  QStringList selection;
53  for ( int i = 0; i < mListWidget->count(); ++i )
54  {
55  QListWidgetItem *item = mListWidget->item( i );
56  if ( item->checkState() == Qt::Checked )
57  selection << item->data( Qt::UserRole ).toString();
58  }
59 
60  v = selection.join( QStringLiteral( "," ) ).prepend( '{' ).append( '}' );
61  }
62 
63  if ( mLineEdit )
64  {
65  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem &item, mCache )
66  {
67  if ( item.value == mLineEdit->text() )
68  {
69  v = item.value;
70  break;
71  }
72  }
73  }
74 
75  return v;
76 }
77 
79 {
80  if ( config( QStringLiteral( "AllowMulti" ) ).toBool() )
81  {
82  return new QListWidget( parent );
83  }
84  else if ( config( QStringLiteral( "UseCompleter" ) ).toBool() )
85  {
86  return new QgsFilterLineEdit( parent );
87  }
88  {
89  return new QComboBox( parent );
90  }
91 }
92 
94 {
96 
97  mComboBox = qobject_cast<QComboBox *>( editor );
98  mListWidget = qobject_cast<QListWidget *>( editor );
99  mLineEdit = qobject_cast<QLineEdit *>( editor );
100 
101  if ( mComboBox )
102  {
103  if ( config( QStringLiteral( "AllowNull" ) ).toBool() )
104  {
105  mComboBox->addItem( tr( "(no selection)" ), QVariant( field().type() ) );
106  }
107 
108  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem &element, mCache )
109  {
110  mComboBox->addItem( element.value, element.key );
111  }
112 
113  connect( mComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ),
114  this, static_cast<void ( QgsEditorWidgetWrapper::* )()>( &QgsEditorWidgetWrapper::valueChanged ) );
115  }
116  else if ( mListWidget )
117  {
118  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem &element, mCache )
119  {
120  QListWidgetItem *item = nullptr;
121  item = new QListWidgetItem( element.value );
122  item->setData( Qt::UserRole, element.key );
123 
124  mListWidget->addItem( item );
125  }
126  connect( mListWidget, &QListWidget::itemChanged, this, static_cast<void ( QgsEditorWidgetWrapper::* )()>( &QgsEditorWidgetWrapper::valueChanged ) );
127  }
128  else if ( mLineEdit )
129  {
130  QStringList values;
131  values.reserve( mCache.size() );
132  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem &i, mCache )
133  {
134  values << i.value;
135  }
136 
137  QStringListModel *m = new QStringListModel( values, mLineEdit );
138  QCompleter *completer = new QCompleter( m, mLineEdit );
139  completer->setCaseSensitivity( Qt::CaseInsensitive );
140  mLineEdit->setCompleter( completer );
141  }
142 }
143 
145 {
146  return mListWidget || mLineEdit || mComboBox;
147 }
148 
150 {
151  if ( mListWidget )
152  {
153  QStringList checkList = value.toString().remove( QChar( '{' ) ).remove( QChar( '}' ) ).split( ',' );
154 
155  for ( int i = 0; i < mListWidget->count(); ++i )
156  {
157  QListWidgetItem *item = mListWidget->item( i );
158  item->setCheckState( checkList.contains( item->data( Qt::UserRole ).toString() ) ? Qt::Checked : Qt::Unchecked );
159  }
160  }
161  else if ( mComboBox )
162  {
163  mComboBox->setCurrentIndex( mComboBox->findData( value ) );
164  }
165  else if ( mLineEdit )
166  {
168  {
169  if ( i.key == value )
170  {
171  mLineEdit->setText( i.value );
172  break;
173  }
174  }
175  }
176 }
177 
179 {
180  if ( mListWidget )
181  {
182  mListWidget->blockSignals( true );
183  for ( int i = 0; i < mListWidget->count(); ++i )
184  {
185  mListWidget->item( i )->setCheckState( Qt::PartiallyChecked );
186  }
187  mListWidget->blockSignals( false );
188  }
189  else if ( mComboBox )
190  {
191  whileBlocking( mComboBox )->setCurrentIndex( -1 );
192  }
193  else if ( mLineEdit )
194  {
195  whileBlocking( mLineEdit )->clear();
196  }
197 }
198 
200 {
201  if ( mUpdating )
202  return;
203 
204  if ( mListWidget )
205  {
206  mUpdating = true;
207  for ( int i = 0; i < mListWidget->count(); ++i )
208  {
209  QListWidgetItem *item = mListWidget->item( i );
210 
211  if ( enabled )
212  item->setFlags( item->flags() | Qt::ItemIsEnabled );
213  else
214  item->setFlags( item->flags() & ~Qt::ItemIsEnabled );
215  }
216  mUpdating = false;
217  }
218  else
220 }
void valueChanged()
Will call the value() method to determine the emitted value.
QgsField field() const
Access the field.
void showIndeterminateState() override
Sets the widget to display in an indeterminate "mixed value" state.
Manages an editor widget Widget and wrapper share the same parent.
void setValue(const QVariant &value) override
virtual void setEnabled(bool enabled) override
Is used to enable or disable the edit functionality of the managed widget.
QVariantMap config() const
Returns the whole config.
bool valid() const override
Return true if the widget has been properly initialized.
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
QLineEdit subclass with built in support for clearing the widget&#39;s value and handling custom null val...
QVariant createCache(QgsVectorLayer *layer, int fieldIndex, const QVariantMap &config) const override
Create a cache for a given field.
void setEnabled(bool enabled) override
Is used to enable or disable the edit functionality of the managed widget.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:200
QWidget * createWidget(QWidget *parent) override
This method should create a new widget with the provided parent.
Represents a vector layer which manages a vector based data sets.
QVariant value() const override
Will be used to access the widget&#39;s value.
QgsValueRelationWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QWidget *editor=nullptr, QWidget *parent=nullptr)