QGIS API Documentation  2.99.0-Master (19b062c)
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 {
33 }
34 
35 
37 {
38  QVariant v;
39 
40  if ( mComboBox )
41  {
42  int cbxIdx = mComboBox->currentIndex();
43  if ( cbxIdx > -1 )
44  {
45  v = mComboBox->currentData();
46  }
47  }
48 
49  if ( mListWidget )
50  {
51  QStringList selection;
52  for ( int i = 0; i < mListWidget->count(); ++i )
53  {
54  QListWidgetItem *item = mListWidget->item( i );
55  if ( item->checkState() == Qt::Checked )
56  selection << item->data( Qt::UserRole ).toString();
57  }
58 
59  v = selection.join( QStringLiteral( "," ) ).prepend( '{' ).append( '}' );
60  }
61 
62  if ( mLineEdit )
63  {
64  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem &item, mCache )
65  {
66  if ( item.value == mLineEdit->text() )
67  {
68  v = item.key;
69  break;
70  }
71  }
72  }
73 
74  return v;
75 }
76 
78 {
79  if ( config( QStringLiteral( "AllowMulti" ) ).toBool() )
80  {
81  return new QListWidget( parent );
82  }
83  else if ( config( QStringLiteral( "UseCompleter" ) ).toBool() )
84  {
85  return new QgsFilterLineEdit( parent );
86  }
87  {
88  return new QComboBox( parent );
89  }
90 }
91 
93 {
95 
96  mComboBox = qobject_cast<QComboBox *>( editor );
97  mListWidget = qobject_cast<QListWidget *>( editor );
98  mLineEdit = qobject_cast<QLineEdit *>( editor );
99 
100  if ( mComboBox )
101  {
102  if ( config( QStringLiteral( "AllowNull" ) ).toBool() )
103  {
104  mComboBox->addItem( tr( "(no selection)" ), QVariant( field().type() ) );
105  }
106 
107  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem &element, mCache )
108  {
109  mComboBox->addItem( element.value, element.key );
110  }
111 
112  connect( mComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ),
113  this, static_cast<void ( QgsEditorWidgetWrapper::* )()>( &QgsEditorWidgetWrapper::valueChanged ) );
114  }
115  else if ( mListWidget )
116  {
117  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem &element, mCache )
118  {
119  QListWidgetItem *item = nullptr;
120  item = new QListWidgetItem( element.value );
121  item->setData( Qt::UserRole, element.key );
122 
123  mListWidget->addItem( item );
124  }
125  connect( mListWidget, &QListWidget::itemChanged, this, static_cast<void ( QgsEditorWidgetWrapper::* )()>( &QgsEditorWidgetWrapper::valueChanged ) );
126  }
127  else if ( mLineEdit )
128  {
129  QStringList values;
130  values.reserve( mCache.size() );
131  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem &i, mCache )
132  {
133  values << i.value;
134  }
135 
136  QStringListModel *m = new QStringListModel( values, mLineEdit );
137  QCompleter *completer = new QCompleter( m, mLineEdit );
138  completer->setCaseSensitivity( Qt::CaseInsensitive );
139  mLineEdit->setCompleter( completer );
140  }
141 }
142 
144 {
145  return mListWidget || mLineEdit || mComboBox;
146 }
147 
149 {
150  if ( mListWidget )
151  {
152  QStringList checkList;
153  if ( value.type() == QVariant::StringList )
154  checkList = value.toStringList();
155  else if ( value.type() == QVariant::String )
156  checkList = value.toString().remove( QChar( '{' ) ).remove( QChar( '}' ) ).split( ',' );
157 
158  for ( int i = 0; i < mListWidget->count(); ++i )
159  {
160  QListWidgetItem *item = mListWidget->item( i );
161  item->setCheckState( checkList.contains( item->data( Qt::UserRole ).toString() ) ? Qt::Checked : Qt::Unchecked );
162  }
163  }
164  else if ( mComboBox )
165  {
166  mComboBox->setCurrentIndex( mComboBox->findData( value ) );
167  }
168  else if ( mLineEdit )
169  {
171  {
172  if ( i.key == value )
173  {
174  mLineEdit->setText( i.value );
175  break;
176  }
177  }
178  }
179 }
180 
182 {
183  if ( mListWidget )
184  {
185  mListWidget->blockSignals( true );
186  for ( int i = 0; i < mListWidget->count(); ++i )
187  {
188  mListWidget->item( i )->setCheckState( Qt::PartiallyChecked );
189  }
190  mListWidget->blockSignals( false );
191  }
192  else if ( mComboBox )
193  {
194  whileBlocking( mComboBox )->setCurrentIndex( -1 );
195  }
196  else if ( mLineEdit )
197  {
198  whileBlocking( mLineEdit )->clear();
199  }
200 }
201 
203 {
204  if ( mEnabled == enabled )
205  return;
206 
207  mEnabled = enabled;
208 
209  if ( mListWidget )
210  {
211  for ( int i = 0; i < mListWidget->count(); ++i )
212  {
213  QListWidgetItem *item = mListWidget->item( i );
214 
215  if ( enabled )
216  item->setFlags( item->flags() | Qt::ItemIsEnabled );
217  else
218  item->setFlags( item->flags() & ~Qt::ItemIsEnabled );
219  }
220  }
221  else
223 }
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)