30 #include <QHeaderView> 33 #include <QTableWidget> 34 #include <QStringListModel> 37 #include <nlohmann/json.hpp> 53 int cbxIdx = mComboBox->currentIndex();
56 v = mComboBox->currentData();
60 const int nofColumns = columnCount();
64 QStringList selection;
65 for (
int j = 0; j < mTableWidget->rowCount(); j++ )
67 for (
int i = 0; i < nofColumns; ++i )
69 QTableWidgetItem *item = mTableWidget->item( j, i );
72 if ( item->checkState() == Qt::Checked )
73 selection << item->data( Qt::UserRole ).toString();
80 for (
const QString &s : qgis::as_const( selection ) )
83 const QVariant::Type type { fkType() };
86 case QVariant::Type::Int:
87 vl.push_back( s.toInt() );
89 case QVariant::Type::LongLong:
90 vl.push_back( s.toLongLong() );
104 if ( item.value == mLineEdit->text() )
121 mExpression =
config().value( QStringLiteral(
"FilterExpression" ) ).toString();
123 if (
config( QStringLiteral(
"AllowMulti" ) ).toBool() )
125 return new QTableWidget( parent );
127 else if (
config( QStringLiteral(
"UseCompleter" ) ).toBool() )
132 return new QComboBox( parent );
139 mComboBox = qobject_cast<QComboBox *>( editor );
140 mTableWidget = qobject_cast<QTableWidget *>( editor );
141 mLineEdit = qobject_cast<QLineEdit *>( editor );
148 connect( mComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
151 else if ( mTableWidget )
153 mTableWidget->horizontalHeader()->setResizeMode( QHeaderView::Stretch );
154 mTableWidget->horizontalHeader()->setVisible(
false );
155 mTableWidget->verticalHeader()->setResizeMode( QHeaderView::Stretch );
156 mTableWidget->verticalHeader()->setVisible(
false );
157 mTableWidget->setShowGrid(
false );
158 mTableWidget->setEditTriggers( QAbstractItemView::NoEditTriggers );
159 mTableWidget->setSelectionMode( QAbstractItemView::NoSelection );
162 else if ( mLineEdit )
164 connect( mLineEdit, &QLineEdit::textChanged,
this, [ = ](
const QString &
value ) { emit
valueChanged( value ); }, Qt::UniqueConnection );
170 return mTableWidget || mLineEdit || mComboBox;
177 QStringList checkList;
179 if (
layer()->fields().at(
fieldIdx() ).type() == QVariant::Map )
182 checkList = value.toStringList();
189 QTableWidgetItem *lastChangedItem =
nullptr;
191 const int nofColumns = columnCount();
195 for (
int j = 0; j < mTableWidget->rowCount(); j++ )
197 auto signalBlockedTableWidget =
whileBlocking( mTableWidget );
198 Q_UNUSED( signalBlockedTableWidget )
200 for (
int i = 0; i < nofColumns; ++i )
202 QTableWidgetItem *item = mTableWidget->item( j, i );
205 item->setCheckState( checkList.contains( item->data( Qt::UserRole ).toString() ) ? Qt::Checked : Qt::Unchecked );
207 item->setFlags( mEnabled ? item->flags() | Qt::ItemIsEnabled : item->flags() & ~Qt::ItemIsEnabled );
208 lastChangedItem = item;
213 if ( lastChangedItem )
214 lastChangedItem->setCheckState( checkList.contains( lastChangedItem->data( Qt::UserRole ).toString() ) ? Qt::Checked : Qt::Unchecked );
217 else if ( mComboBox )
222 for (
int i = 0; i < mComboBox->count(); i++ )
224 QVariant v( mComboBox->itemData( i ) );
231 mComboBox->setCurrentIndex( idx );
233 else if ( mLineEdit )
237 if ( i.key == value )
239 mLineEdit->setText( i.value );
250 if ( attributeChanged )
252 QVariant oldValue(
value( ) );
286 && !
config( QStringLiteral(
"AllowNull" ) ).toBool( ) )
290 QTimer::singleShot( 0,
this, [
this ]
297 int QgsValueRelationWidgetWrapper::columnCount()
const 299 return std::max( 1,
config( QStringLiteral(
"NofColumns" ) ).toInt() );
303 QVariant::Type QgsValueRelationWidgetWrapper::fkType()
const 312 return fields.
at( idx ).
type();
315 return QVariant::Type::Invalid;
318 void QgsValueRelationWidgetWrapper::populate( )
325 else if ( mCache.empty() )
333 if (
config( QStringLiteral(
"AllowNull" ) ).toBool( ) )
335 whileBlocking( mComboBox )->addItem( tr(
"(no selection)" ), QVariant(
field().type( ) ) );
340 whileBlocking( mComboBox )->addItem( element.value, element.key );
343 else if ( mTableWidget )
345 const int nofColumns = columnCount();
347 if ( ! mCache.empty() )
349 mTableWidget->setRowCount( ( mCache.size() + nofColumns - 1 ) / nofColumns );
352 mTableWidget->setRowCount( 1 );
353 mTableWidget->setColumnCount( nofColumns );
360 if ( column == nofColumns )
365 QTableWidgetItem *item =
nullptr;
366 item =
new QTableWidgetItem( element.value );
367 item->setData( Qt::UserRole, element.key );
372 else if ( mLineEdit )
375 values.reserve( mCache.size() );
380 QStringListModel *m =
new QStringListModel( values, mLineEdit );
381 QCompleter *completer =
new QCompleter( m, mLineEdit );
382 completer->setCaseSensitivity( Qt::CaseInsensitive );
383 mLineEdit->setCompleter( completer );
389 const int nofColumns = columnCount();
393 for (
int j = 0; j < mTableWidget->rowCount(); j++ )
395 for (
int i = 0; i < nofColumns; ++i )
397 whileBlocking( mTableWidget )->item( j, i )->setCheckState( Qt::PartiallyChecked );
401 else if ( mComboBox )
405 else if ( mLineEdit )
413 if ( mEnabled == enabled )
420 auto signalBlockedTableWidget =
whileBlocking( mTableWidget );
421 Q_UNUSED( signalBlockedTableWidget )
423 for (
int j = 0; j < mTableWidget->rowCount(); j++ )
425 for (
int i = 0; i < mTableWidget->columnCount(); ++i )
427 QTableWidgetItem *item = mTableWidget->item( j, i );
430 item->setFlags( enabled ? item->flags() | Qt::ItemIsEnabled : item->flags() & ~Qt::ItemIsEnabled );
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
bool isValid() const
Returns the validity of this feature.
Container of fields for a vector layer.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QLineEdit subclass with built in support for clearing the widget's value and handling custom null val...
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
static QgsProject * instance()
Returns the QgsProject singleton instance.
bool qgsVariantEqual(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether they are equal, NULL values are treated as equal...
Represents a vector layer which manages a vector based data sets.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.