QGIS API Documentation  2.99.0-Master (0a63d1f)
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  , mComboBox( nullptr )
33  , mListWidget( nullptr )
34  , mLineEdit( nullptr )
35  , mLayer( nullptr )
36 {
37 }
38 
39 
41 {
42  QVariant v;
43 
44  if ( mComboBox )
45  {
46  int cbxIdx = mComboBox->currentIndex();
47  if ( cbxIdx > -1 )
48  {
49  v = mComboBox->currentData();
50  }
51  }
52 
53  if ( mListWidget )
54  {
55  QStringList selection;
56  for ( int i = 0; i < mListWidget->count(); ++i )
57  {
58  QListWidgetItem* item = mListWidget->item( i );
59  if ( item->checkState() == Qt::Checked )
60  selection << item->data( Qt::UserRole ).toString();
61  }
62 
63  v = selection.join( QStringLiteral( "," ) ).prepend( '{' ).append( '}' );
64  }
65 
66  if ( mLineEdit )
67  {
68  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem& item , mCache )
69  {
70  if ( item.value == mLineEdit->text() )
71  {
72  v = item.value;
73  break;
74  }
75  }
76  }
77 
78  return v;
79 }
80 
82 {
83  if ( config( QStringLiteral( "AllowMulti" ) ).toBool() )
84  {
85  return new QListWidget( parent );
86  }
87  else if ( config( QStringLiteral( "UseCompleter" ) ).toBool() )
88  {
89  return new QgsFilterLineEdit( parent );
90  }
91  {
92  return new QComboBox( parent );
93  }
94 }
95 
97 {
99 
100  mComboBox = qobject_cast<QComboBox*>( editor );
101  mListWidget = qobject_cast<QListWidget*>( editor );
102  mLineEdit = qobject_cast<QLineEdit*>( editor );
103 
104  if ( mComboBox )
105  {
106  if ( config( QStringLiteral( "AllowNull" ) ).toBool() )
107  {
108  mComboBox->addItem( tr( "(no selection)" ), QVariant( field().type() ) );
109  }
110 
111  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem& element, mCache )
112  {
113  mComboBox->addItem( element.value, element.key );
114  }
115 
116  connect( mComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( valueChanged() ) );
117  }
118  else if ( mListWidget )
119  {
120  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem& element, mCache )
121  {
122  QListWidgetItem *item;
123  item = new QListWidgetItem( element.value );
124  item->setData( Qt::UserRole, element.key );
125 
126  mListWidget->addItem( item );
127  }
128  connect( mListWidget, SIGNAL( itemChanged( QListWidgetItem* ) ), this, SLOT( valueChanged() ) );
129  }
130  else if ( mLineEdit )
131  {
132  QStringList values;
133  values.reserve( mCache.size() );
134  Q_FOREACH ( const QgsValueRelationFieldFormatter::ValueRelationItem& i, mCache )
135  {
136  values << i.value;
137  }
138 
139  QStringListModel* m = new QStringListModel( values, mLineEdit );
140  QCompleter* completer = new QCompleter( m, mLineEdit );
141  completer->setCaseSensitivity( Qt::CaseInsensitive );
142  mLineEdit->setCompleter( completer );
143  }
144 }
145 
147 {
148  return mListWidget || mLineEdit || mComboBox;
149 }
150 
152 {
153  if ( mListWidget )
154  {
155  QStringList checkList = value.toString().remove( QChar( '{' ) ).remove( QChar( '}' ) ).split( ',' );
156 
157  for ( int i = 0; i < mListWidget->count(); ++i )
158  {
159  QListWidgetItem* item = mListWidget->item( i );
160  item->setCheckState( checkList.contains( item->data( Qt::UserRole ).toString() ) ? Qt::Checked : Qt::Unchecked );
161  }
162  }
163  else if ( mComboBox )
164  {
165  mComboBox->setCurrentIndex( mComboBox->findData( value ) );
166  }
167  else if ( mLineEdit )
168  {
170  {
171  if ( i.key == value )
172  {
173  mLineEdit->setText( i.value );
174  break;
175  }
176  }
177  }
178 }
179 
181 {
182  if ( mListWidget )
183  {
184  mListWidget->blockSignals( true );
185  for ( int i = 0; i < mListWidget->count(); ++i )
186  {
187  mListWidget->item( i )->setCheckState( Qt::PartiallyChecked );
188  }
189  mListWidget->blockSignals( false );
190  }
191  else if ( mComboBox )
192  {
193  whileBlocking( mComboBox )->setCurrentIndex( -1 );
194  }
195  else if ( mLineEdit )
196  {
197  whileBlocking( mLineEdit )->clear();
198  }
199 }
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
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.
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:173
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)