29 #include <QHeaderView> 32 #include <QTableWidget> 33 #include <QStringListModel> 48 int cbxIdx = mComboBox->currentIndex();
51 v = mComboBox->currentData();
55 const int nofColumns = columnCount();
59 QStringList selection;
60 for (
int j = 0; j < mTableWidget->rowCount(); j++ )
62 for (
int i = 0; i < nofColumns; ++i )
64 QTableWidgetItem *item = mTableWidget->item( j, i );
67 if ( item->checkState() == Qt::Checked )
68 selection << item->data( Qt::UserRole ).toString();
73 if (
layer()->fields().at(
fieldIdx() ).type() == QVariant::Map )
77 for (
const QString &s : qgis::as_const( selection ) )
86 v = selection.join(
',' ).prepend(
'{' ).append(
'}' );
94 if ( item.value == mLineEdit->text() )
111 mExpression =
config().value( QStringLiteral(
"FilterExpression" ) ).toString();
113 if (
config( QStringLiteral(
"AllowMulti" ) ).toBool() )
115 return new QTableWidget( parent );
117 else if (
config( QStringLiteral(
"UseCompleter" ) ).toBool() )
122 return new QComboBox( parent );
129 mComboBox = qobject_cast<QComboBox *>( editor );
130 mTableWidget = qobject_cast<QTableWidget *>( editor );
131 mLineEdit = qobject_cast<QLineEdit *>( editor );
138 connect( mComboBox,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
141 else if ( mTableWidget )
143 mTableWidget->horizontalHeader()->setResizeMode( QHeaderView::Stretch );
144 mTableWidget->horizontalHeader()->setVisible(
false );
145 mTableWidget->verticalHeader()->setResizeMode( QHeaderView::Stretch );
146 mTableWidget->verticalHeader()->setVisible(
false );
147 mTableWidget->setShowGrid(
false );
148 mTableWidget->setEditTriggers( QAbstractItemView::NoEditTriggers );
149 mTableWidget->setSelectionMode( QAbstractItemView::NoSelection );
152 else if ( mLineEdit )
154 connect( mLineEdit, &QLineEdit::textChanged,
this, [ = ](
const QString &
value ) { emit
valueChanged( value ); }, Qt::UniqueConnection );
160 return mTableWidget || mLineEdit || mComboBox;
167 QStringList checkList;
169 if (
layer()->fields().at(
fieldIdx() ).type() == QVariant::Map )
172 checkList = value.toStringList();
179 QTableWidgetItem *lastChangedItem =
nullptr;
181 const int nofColumns = columnCount();
185 for (
int j = 0; j < mTableWidget->rowCount(); j++ )
187 auto signalBlockedTableWidget =
whileBlocking( mTableWidget );
188 Q_UNUSED( signalBlockedTableWidget )
190 for (
int i = 0; i < nofColumns; ++i )
192 QTableWidgetItem *item = mTableWidget->item( j, i );
195 item->setCheckState( checkList.contains( item->data( Qt::UserRole ).toString() ) ? Qt::Checked : Qt::Unchecked );
197 item->setFlags( mEnabled ? item->flags() | Qt::ItemIsEnabled : item->flags() & ~Qt::ItemIsEnabled );
198 lastChangedItem = item;
203 if ( lastChangedItem )
204 lastChangedItem->setCheckState( checkList.contains( lastChangedItem->data( Qt::UserRole ).toString() ) ? Qt::Checked : Qt::Unchecked );
207 else if ( mComboBox )
212 for (
int i = 0; i < mComboBox->count(); i++ )
214 QVariant v( mComboBox->itemData( i ) );
221 mComboBox->setCurrentIndex( idx );
223 else if ( mLineEdit )
227 if ( i.key == value )
229 mLineEdit->setText( i.value );
240 if ( attributeChanged )
242 QVariant oldValue(
value( ) );
276 && !
config( QStringLiteral(
"AllowNull" ) ).toBool( ) )
280 QTimer::singleShot( 0,
this, [
this ]
287 int QgsValueRelationWidgetWrapper::columnCount()
const 289 return std::max( 1,
config( QStringLiteral(
"NofColumns" ) ).toInt() );
292 void QgsValueRelationWidgetWrapper::populate( )
299 else if ( mCache.empty() )
307 if (
config( QStringLiteral(
"AllowNull" ) ).toBool( ) )
309 whileBlocking( mComboBox )->addItem( tr(
"(no selection)" ), QVariant(
field().type( ) ) );
314 whileBlocking( mComboBox )->addItem( element.value, element.key );
317 else if ( mTableWidget )
319 const int nofColumns = columnCount();
321 if ( ! mCache.empty() )
323 mTableWidget->setRowCount( ( mCache.size() + nofColumns - 1 ) / nofColumns );
326 mTableWidget->setRowCount( 1 );
327 mTableWidget->setColumnCount( nofColumns );
334 if ( column == nofColumns )
339 QTableWidgetItem *item =
nullptr;
340 item =
new QTableWidgetItem( element.value );
341 item->setData( Qt::UserRole, element.key );
346 else if ( mLineEdit )
349 values.reserve( mCache.size() );
354 QStringListModel *m =
new QStringListModel( values, mLineEdit );
355 QCompleter *completer =
new QCompleter( m, mLineEdit );
356 completer->setCaseSensitivity( Qt::CaseInsensitive );
357 mLineEdit->setCompleter( completer );
363 const int nofColumns = columnCount();
367 for (
int j = 0; j < mTableWidget->rowCount(); j++ )
369 for (
int i = 0; i < nofColumns; ++i )
371 whileBlocking( mTableWidget )->item( j, i )->setCheckState( Qt::PartiallyChecked );
375 else if ( mComboBox )
379 else if ( mLineEdit )
387 if ( mEnabled == enabled )
394 auto signalBlockedTableWidget =
whileBlocking( mTableWidget );
395 Q_UNUSED( signalBlockedTableWidget )
397 for (
int j = 0; j < mTableWidget->rowCount(); j++ )
399 for (
int i = 0; i < mTableWidget->columnCount(); ++i )
401 QTableWidgetItem *item = mTableWidget->item( j, i );
404 item->setFlags( enabled ? item->flags() | Qt::ItemIsEnabled : item->flags() & ~Qt::ItemIsEnabled );
bool isValid() const
Returns the validity of this feature.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
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.
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.