41#include "moc_qgsrelationreferencewidget.cpp"
48 for (
int i = 0; i < list.size(); ++i )
60 mTopLayout =
new QVBoxLayout(
this );
61 mTopLayout->setContentsMargins( 0, 0, 0, 0 );
63 setSizePolicy( sizePolicy().horizontalPolicy(), QSizePolicy::Fixed );
65 setLayout( mTopLayout );
67 QHBoxLayout *editLayout =
new QHBoxLayout();
68 editLayout->setContentsMargins( 0, 0, 0, 0 );
69 editLayout->setSpacing( 2 );
72 mChooserContainer =
new QWidget;
73 editLayout->addWidget( mChooserContainer );
74 QHBoxLayout *chooserLayout =
new QHBoxLayout;
75 chooserLayout->setContentsMargins( 0, 0, 0, 0 );
76 mFilterLayout =
new QHBoxLayout;
77 mFilterLayout->setContentsMargins( 0, 0, 0, 0 );
78 mFilterContainer =
new QWidget;
79 mFilterContainer->setLayout( mFilterLayout );
80 mChooserContainer->setLayout( chooserLayout );
81 chooserLayout->addWidget( mFilterContainer );
84 mChooserContainer->layout()->addWidget( mComboBox );
87 mOpenFormButton =
new QToolButton();
89 mOpenFormButton->setText( tr(
"Open Related Feature Form" ) );
90 editLayout->addWidget( mOpenFormButton );
92 mAddEntryButton =
new QToolButton();
94 mAddEntryButton->setText( tr(
"Add New Entry" ) );
95 editLayout->addWidget( mAddEntryButton );
98 mHighlightFeatureButton =
new QToolButton(
this );
99 mHighlightFeatureButton->setPopupMode( QToolButton::MenuButtonPopup );
100 mHighlightFeatureAction =
new QAction(
QgsApplication::getThemeIcon( QStringLiteral(
"/mActionHighlightFeature.svg" ) ), tr(
"Highlight feature" ),
this );
101 mScaleHighlightFeatureAction =
new QAction(
QgsApplication::getThemeIcon( QStringLiteral(
"/mActionScaleHighlightFeature.svg" ) ), tr(
"Scale and highlight feature" ),
this );
102 mPanHighlightFeatureAction =
new QAction(
QgsApplication::getThemeIcon( QStringLiteral(
"/mActionPanHighlightFeature.svg" ) ), tr(
"Pan and highlight feature" ),
this );
103 mHighlightFeatureButton->addAction( mHighlightFeatureAction );
104 mHighlightFeatureButton->addAction( mScaleHighlightFeatureAction );
105 mHighlightFeatureButton->addAction( mPanHighlightFeatureAction );
106 mHighlightFeatureButton->setDefaultAction( mHighlightFeatureAction );
107 editLayout->addWidget( mHighlightFeatureButton );
110 mMapIdentificationButton =
new QToolButton(
this );
112 mMapIdentificationButton->setText( tr(
"Select on Map" ) );
113 mMapIdentificationButton->setCheckable(
true );
114 editLayout->addWidget( mMapIdentificationButton );
117 mRemoveFKButton =
new QToolButton(
this );
119 mRemoveFKButton->setText( tr(
"No Selection" ) );
120 editLayout->addWidget( mRemoveFKButton );
123 mTopLayout->addLayout( editLayout );
127 mAttributeEditorLayout =
new QVBoxLayout( mAttributeEditorFrame );
128 mAttributeEditorFrame->setLayout( mAttributeEditorLayout );
129 mAttributeEditorFrame->setSizePolicy( mAttributeEditorFrame->sizePolicy().horizontalPolicy(), QSizePolicy::Expanding );
130 mTopLayout->addWidget( mAttributeEditorFrame );
133 mInvalidLabel =
new QLabel( tr(
"The relation is not valid. Please make sure your relation definitions are OK." ) );
134 mInvalidLabel->setWordWrap(
true );
135 QFont font = mInvalidLabel->font();
136 font.setItalic(
true );
137 mInvalidLabel->setStyleSheet( QStringLiteral(
"QLabel { color: red; } " ) );
138 mInvalidLabel->setFont( font );
139 mTopLayout->addWidget( mInvalidLabel );
142 mMapIdentificationButton->hide();
143 mHighlightFeatureButton->hide();
144 mAttributeEditorFrame->hide();
145 mInvalidLabel->hide();
146 mAddEntryButton->hide();
150 connect( mHighlightFeatureButton, &QToolButton::triggered,
this, &QgsRelationReferenceWidget::highlightActionTriggered );
153 connect( mAddEntryButton, &QAbstractButton::clicked,
this, &QgsRelationReferenceWidget::addEntry );
154 connect( mComboBox, &QComboBox::editTextChanged,
this, &QgsRelationReferenceWidget::updateAddEntryButton );
165 mAllowNull = allowNullValue;
166 mRemoveFKButton->setVisible( allowNullValue && mReadOnlySelector );
170 mReferencedLayerId =
relation.referencedLayerId();
171 mReferencedLayerName =
relation.referencedLayer()->name();
173 mReferencedLayerProviderKey =
relation.referencedLayer()->providerType();
174 mInvalidLabel->hide();
177 mReferencingLayer =
relation.referencingLayer();
178 mReferencedLayer =
relation.referencedLayer();
180 const QList<QgsRelation::FieldPair> fieldPairs =
relation.fieldPairs();
183 mReferencedFields << fieldPair.referencedField();
187 mComboBox->setAllowNull( mAllowNull );
188 mComboBox->setSourceLayer( mReferencedLayer );
189 mComboBox->setIdentifierFields( mReferencedFields );
190 mComboBox->setFilterExpression( mFilterExpression );
191 mComboBox->setFetchLimit( mFetchLimit );
192 mComboBox->setOrderExpression( mOrderExpression );
193 mComboBox->setSortOrder( mSortOrder );
195 mAttributeEditorFrame->setObjectName( QStringLiteral(
"referencing/" ) +
relation.name() );
200 mAttributeEditorFrame->setTitle( mReferencedLayer->name() );
202 mAttributeEditorLayout->addWidget( mReferencedAttributeForm );
207 updateAddEntryButton();
211 mInvalidLabel->show();
214 if ( mShown && isVisible() )
227 mFilterContainer->setEnabled( editable );
228 mComboBox->setEnabled( editable && !mReadOnlySelector );
229 mComboBox->setEditable(
true );
230 mMapIdentificationButton->setEnabled( editable );
231 mRemoveFKButton->setEnabled( editable );
232 mIsEditable = editable;
242 if ( values.isEmpty() )
252 if ( !mReferencedLayer )
255 mComboBox->setIdentifierValues( values );
257 if ( mEmbedForm || mChainFilters )
260 mReferencedLayer->getFeatures( request ).nextFeature( mFeature );
265 const int count = std::min( mFilterComboBoxes.size(), mFilterFields.size() );
266 for (
int i = 0; i < count; i++ )
268 QVariant v = mFeature.attribute( mFilterFields[i] );
270 mFilterComboBoxes.at( i )->setCurrentIndex( mFilterComboBoxes.at( i )->findText( f ) );
274 mRemoveFKButton->setEnabled( mIsEditable );
275 highlightFeature( mFeature );
276 updateAttributeEditorFrame( mFeature );
284 if ( mChainFilters && !mFilterComboBoxes.isEmpty() )
286 QComboBox *cb = mFilterComboBoxes.first();
287 cb->setCurrentIndex( 0 );
288 disableChainedComboBoxes( cb );
291 mComboBox->setIdentifierValuesToNull();
292 mRemoveFKButton->setEnabled(
false );
304 return mReferencedAttributeForm->save();
310 if ( mReferencedLayer )
312 mReferencedLayer->getFeatures( mComboBox->currentFeatureRequest() ).nextFeature( f );
320 mRemoveFKButton->setEnabled(
false );
327 if ( fkeys.isEmpty() )
330 return fkeys.at( 0 );
335 return mComboBox->identifierValues();
340 mEditorContext = context;
342 mMessageBar = messageBar;
345 mMapToolIdentify->setButton( mMapIdentificationButton );
347 if ( mEditorContext.cadDockWidget() )
350 mMapToolDigitize->setButton( mAddEntryButton );
351 updateAddEntryButton();
359 setSizePolicy( sizePolicy().horizontalPolicy(), QSizePolicy::MinimumExpanding );
360 mTopLayout->setAlignment( Qt::AlignTop );
363 mAttributeEditorFrame->setVisible( display );
364 mEmbedForm = display;
369 mComboBox->setEnabled( !readOnly );
370 mRemoveFKButton->setVisible( mAllowNull && readOnly );
371 mReadOnlySelector = readOnly;
383 mFilterFields = filterFields;
399 mFilterExpression = expression;
413 if ( mReferencedLayer )
415 QApplication::setOverrideCursor( Qt::WaitCursor );
417 QSet<QString> requestedAttrs;
419 if ( !mFilterFields.isEmpty() )
421 for (
const QString &fieldName : std::as_const( mFilterFields ) )
423 int idx = mReferencedLayer->fields().lookupField( fieldName );
428 QComboBox *cb =
new QComboBox();
429 cb->setProperty(
"Field", fieldName );
430 cb->setProperty(
"FieldAlias", mReferencedLayer->attributeDisplayName( idx ) );
431 mFilterComboBoxes << cb;
432 QVariantList uniqueValues = qgis::setToList( mReferencedLayer->uniqueValues( idx ) );
433 cb->addItem( mReferencedLayer->attributeDisplayName( idx ) );
438 const auto constUniqueValues = uniqueValues;
439 for (
const QVariant &v : constUniqueValues )
441 cb->addItem( v.toString(), v );
444 connect( cb,
static_cast<void ( QComboBox::* )(
int )
>( &QComboBox::currentIndexChanged ),
this, &QgsRelationReferenceWidget::filterChanged );
447 requestedAttrs << fieldName;
449 mFilterLayout->addWidget( cb );
458 ? mReferencedLayer->getFeatures()
459 : mReferencedLayer->getFeatures( mFilterExpression );
462 const int count = std::min( mFilterComboBoxes.count(), mFilterFields.count() );
463 for (
int i = 0; i < count - 1; i++ )
465 QVariant cv = ft.
attribute( mFilterFields.at( i ) );
466 QVariant nv = ft.
attribute( mFilterFields.at( i + 1 ) );
469 mFilterCache[mFilterFields[i]][cf] << nf;
473 if ( !mFilterComboBoxes.isEmpty() )
475 QComboBox *cb = mFilterComboBoxes.first();
476 cb->setCurrentIndex( 0 );
477 disableChainedComboBoxes( cb );
483 mFilterContainer->hide();
486 mComboBox->setSourceLayer( mReferencedLayer );
487 mComboBox->setDisplayExpression( mReferencedLayer->displayExpression() );
488 mComboBox->setAllowNull( mAllowNull );
489 mComboBox->setIdentifierFields( mReferencedFields );
490 mComboBox->setFetchLimit( mFetchLimit );
491 mComboBox->setOrderExpression( mOrderExpression );
492 mComboBox->setSortOrder( mSortOrder );
494 if ( !mFilterExpression.isEmpty() )
495 mComboBox->setFilterExpression( mFilterExpression );
499 if ( mChainFilters && mFeature.isValid() )
501 for (
int i = 0; i < mFilterFields.size(); i++ )
503 QVariant v = mFeature.attribute( mFilterFields[i] );
505 mFilterComboBoxes.at( i )->setCurrentIndex( mFilterComboBoxes.at( i )->findText( f ) );
514 QApplication::restoreOverrideCursor();
520void QgsRelationReferenceWidget::highlightActionTriggered( QAction *action )
522 if ( action == mHighlightFeatureAction )
526 else if ( action == mScaleHighlightFeatureAction )
528 highlightFeature( QgsFeature(),
Scale );
530 else if ( action == mPanHighlightFeatureAction )
532 highlightFeature( QgsFeature(),
Pan );
545 attributeDialog->
show();
548void QgsRelationReferenceWidget::highlightFeature(
QgsFeature f, CanvasExtent canvasExtent )
568 if ( canvasExtent ==
Scale )
571 featBBox = mCanvas->mapSettings().layerToMapCoordinates( mReferencedLayer, featBBox );
572 QgsRectangle extent = mCanvas->extent();
577 mCanvas->setExtent( extent,
true );
581 else if ( canvasExtent ==
Pan )
583 QgsGeometry centroid = geom.
centroid();
584 QgsPointXY center = centroid.
asPoint();
585 center = mCanvas->mapSettings().layerToMapCoordinates( mReferencedLayer, center );
586 mCanvas->zoomByFactor( 1.0, ¢er );
591 mHighlight =
new QgsHighlight( mCanvas, f, mReferencedLayer );
592 mHighlight->applyDefaultStyle();
595 QTimer *timer =
new QTimer(
this );
596 timer->setSingleShot(
true );
597 connect( timer, &QTimer::timeout,
this, &QgsRelationReferenceWidget::deleteHighlight );
598 timer->start( 3000 );
601void QgsRelationReferenceWidget::deleteHighlight()
608 mHighlight =
nullptr;
613 if ( !mAllowMapIdentification || !mReferencedLayer )
622 mMapToolIdentify->setLayer( mReferencedLayer );
623 setMapTool( mMapToolIdentify );
629 QString title = tr(
"Relation %1 for %2." ).arg( mRelation.name(), mReferencingLayer->name() );
630 QString msg = tr(
"Identify a feature of %1 to be associated. Press <ESC> to cancel." ).arg( mReferencedLayer->name() );
632 mMessageBar->pushItem( mMessageBarItem );
636void QgsRelationReferenceWidget::comboReferenceChanged()
639 highlightFeature( mFeature );
640 updateAttributeEditorFrame( mFeature );
645void QgsRelationReferenceWidget::comboReferenceFoundChanged(
bool )
647 mReferencedLayer->getFeatures( mComboBox->currentFeatureRequest() ).nextFeature( mFeature );
648 highlightFeature( mFeature );
649 updateAttributeEditorFrame( mFeature );
652void QgsRelationReferenceWidget::updateAttributeEditorFrame(
const QgsFeature &feature )
654 mOpenFormButton->setEnabled( feature.
isValid() );
656 if ( mAttributeEditorFrame && mReferencedAttributeForm )
658 mReferencedAttributeForm->setFeature( feature );
664 return mAllowAddFeatures;
670 updateAddEntryButton();
678void QgsRelationReferenceWidget::featureIdentified(
const QgsFeature &feature )
683 mRemoveFKButton->setEnabled( mIsEditable );
684 highlightFeature( feature );
685 updateAttributeEditorFrame( feature );
691void QgsRelationReferenceWidget::setMapTool(
QgsMapTool *mapTool )
693 mCurrentMapTool = mapTool;
694 mCanvas->setMapTool( mapTool );
696 mWindowWidget = window();
698 mCanvas->window()->raise();
699 mCanvas->activateWindow();
704void QgsRelationReferenceWidget::unsetMapTool()
707 if ( mCurrentMapTool )
710 mCanvas->unsetMapTool( mCurrentMapTool );
712 if ( mCurrentMapTool == mMapToolDigitize )
724void QgsRelationReferenceWidget::onKeyPressed( QKeyEvent *e )
726 if ( e->key() == Qt::Key_Escape )
732void QgsRelationReferenceWidget::mapToolDeactivated()
736 mWindowWidget->raise();
737 mWindowWidget->activateWindow();
740 if ( mMessageBar && mMessageBarItem )
742 mMessageBar->popWidget( mMessageBarItem );
744 mMessageBarItem =
nullptr;
747void QgsRelationReferenceWidget::filterChanged()
751 QMap<QString, QString> filters;
754 QComboBox *scb = qobject_cast<QComboBox *>( sender() );
768 disableChainedComboBoxes( scb );
771 const auto constMFilterComboBoxes = mFilterComboBoxes;
772 for ( QComboBox *cb : constMFilterComboBoxes )
774 if ( cb->currentIndex() != 0 )
776 const QString fieldName = cb->property(
"Field" ).toString();
778 if ( cb->currentText() == nullValue.toString() )
780 filters[fieldName] = QStringLiteral(
"\"%1\" IS NULL" ).arg( fieldName );
786 attrs << mReferencedLayer->fields().lookupField( fieldName );
792 QComboBox *ccb =
nullptr;
793 const auto constMFilterComboBoxes = mFilterComboBoxes;
794 for ( QComboBox *cb : constMFilterComboBoxes )
804 if ( ccb->currentIndex() != 0 )
806 const QString fieldName = cb->property(
"Field" ).toString();
808 cb->blockSignals(
true );
810 cb->addItem( cb->property(
"FieldAlias" ).toString() );
815 const auto txts { mFilterCache[ccb->property(
"Field" ).toString()][ccb->currentText()] };
816 for (
const QString &txt : txts )
818 QMap<QString, QString> filtersAttrs = filters;
823 if ( !expression.isEmpty() && !filtersAttrs.isEmpty() )
824 expression += QLatin1String(
" AND " );
826 expression += filtersAttrs.isEmpty() ? QString() : QStringLiteral(
" ( " );
828 expression += filtersAttrs.isEmpty() ? QString() : QStringLiteral(
" ) " );
830 subset << mReferencedLayer->fields().lookupField( fieldName );
832 QgsFeatureIterator it( mReferencedLayer->getFeatures( QgsFeatureRequest().
setFilterExpression( expression ).setSubsetOfAttributes( subset ) ) );
835 while ( it.nextFeature( f ) )
837 if ( !featureIds.contains( f.
id() ) )
838 featureIds << f.
id();
849 cb->addItems( texts );
851 cb->setEnabled(
true );
852 cb->blockSignals(
false );
862 filterExpression += filters.isEmpty() ? QString() : QStringLiteral(
" ( " );
864 filterExpression += filters.isEmpty() ? QString() : QStringLiteral(
" ) " );
869void QgsRelationReferenceWidget::addEntry()
871 if ( !mReferencedLayer )
874 const QgsVectorLayerTools *tools = mEditorContext.vectorLayerTools();
883 QgsFeature f( mReferencedLayer->fields() );
888 mMapToolDigitize->setLayer( mReferencedLayer );
889 setMapTool( mMapToolDigitize );
896 QString title = tr(
"Relation %1 for %2." ).arg( mRelation.name(), mReferencingLayer->name() );
899 QString msg = tr(
"Link feature to %1 \"%2\" : Digitize the geometry for the new feature on layer %3. Press <ESC> to cancel." )
900 .arg( mReferencingLayer->name(), displayString, mReferencedLayer->name() );
902 mMessageBar->pushItem( mMessageBarItem );
906void QgsRelationReferenceWidget::entryAdded(
const QgsFeature &feat )
908 QgsFeature f( feat );
912 if ( mComboBox->itemText( mComboBox->currentIndex() ) != mComboBox->currentText() )
914 int fieldIdx = mReferencedLayer->fields().lookupField( mReferencedLayer->displayExpression() );
916 if ( fieldIdx != -1 )
918 attributes.insert( fieldIdx, mComboBox->currentText() );
922 if ( mEditorContext.vectorLayerTools()->addFeature( mReferencedLayer, attributes, f.
geometry(), &f,
this,
false,
true ) )
925 for (
const QString &fieldName : std::as_const( mReferencedFields ) )
930 mAddEntryButton->setEnabled(
false );
936void QgsRelationReferenceWidget::updateAddEntryButton()
938 mAddEntryButton->setVisible( mAllowAddFeatures && mMapToolDigitize );
939 mAddEntryButton->setEnabled( mReferencedLayer && mReferencedLayer->isEditable() );
942void QgsRelationReferenceWidget::disableChainedComboBoxes(
const QComboBox *scb )
944 QComboBox *ccb =
nullptr;
945 const auto constMFilterComboBoxes = mFilterComboBoxes;
946 for ( QComboBox *cb : constMFilterComboBoxes )
958 cb->setCurrentIndex( 0 );
959 if ( ccb->currentIndex() == 0 )
961 cb->setEnabled(
false );
968void QgsRelationReferenceWidget::emitForeignKeysChanged(
const QVariantList &foreignKeys,
bool force )
982 return mReferencedLayerName;
987 mReferencedLayerName = relationLayerName;
992 return mReferencedLayerId;
997 mReferencedLayerId = relationLayerId;
1002 return mReferencedLayerProviderKey;
1007 mReferencedLayerProviderKey = relationProviderKey;
1012 return mReferencedLayerDataSource;
1018 mReferencedLayerDataSource = resolver.
writePath( relationDataSource );
1023 mComboBox->setFormFeature( formFeature );
1028 mComboBox->setParentFormFeature( parentFormFeature );
static QString nullRepresentation()
Returns the string used to represent the value NULL throughout QGIS.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
An attribute table dialog for a vector layer.
void show()
Show the dialog non-blocking. Reparents this dialog to be a child of the dialog form.
Contains context information for attribute editor widgets.
@ Single
When showing a single feature (e.g. district information when looking at the form of a house).
@ Embed
A form was embedded as a widget on another form.
@ StandaloneDialog
A form was opened as a new dialog.
A groupbox that collapses/expands when toggled and can save its collapsed and checked states.
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value, QMetaType::Type fieldType=QMetaType::Type::UnknownType)
Create an expression allowing to evaluate if a field is equal to a value.
Wrapper for iterator of features from vector data provider or vector layer.
bool nextFeature(QgsFeature &f)
Fetch next feature and stores in f, returns true on success.
This offers a combobox with autocompleter that allows selecting features from a layer.
QgsFeatureRequest currentFeatureRequest() const
Shorthand for getting a feature request to query the currently selected feature.
QVariantList identifierValues
void setCurrentFeature(const QgsFeature &feature)
Sets the current index by using the given feature.
void currentFeatureFoundChanged(bool found)
Emitted when the feature picker model changes its feature found state.
void currentFeatureChanged()
Emitted when the current feature changes.
Wraps a request for features to a vector layer (or directly its vector data provider).
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool hasGeometry() const
Returns true if the feature has an associated geometry.
bool isValid() const
Returns the validity of this feature.
Q_INVOKABLE QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
QgsGeometry centroid() const
Returns the center of mass of a geometry.
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Map canvas is a class for displaying all GIS data types on a canvas.
void keyPressed(QKeyEvent *e)
Emit key press event.
void editingStopped()
Emitted when edited changes have been successfully written to the data provider.
void editingStarted()
Emitted when editing on this layer has started.
A bar for displaying non-blocking messages to the user.
static QgsMessageBarItem * createMessage(const QString &text, QWidget *parent=nullptr)
Creates message bar item widget containing a message text to be displayed on the bar.
Resolves relative paths into absolute paths and vice versa.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsPathResolver pathResolver() const
Returns path resolver object with considering whether the project uses absolute or relative paths and...
void scale(double scaleFactor, const QgsPointXY *c=nullptr)
Scale the rectangle around its center point.
bool contains(const QgsRectangle &rect) const
Returns true when rectangle contains other rectangle.
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
Defines a relation between matching fields of the two involved tables of a relation.
Represents a relationship between two vector layers.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
static QVariant createNullVariant(QMetaType::Type metaType)
Helper method to properly create a null QVariant from a metaType Returns the created QVariant.
static QString getFeatureDisplayString(const QgsVectorLayer *layer, const QgsFeature &feature)
Returns a descriptive string for a feature, suitable for displaying to the user.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const final
Queries the layer for features specified in request.
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
#define Q_NOWARN_DEPRECATED_POP
QString qgsMapJoinValues(const QMap< Key, Value > &map, const QString &separator)
Joins all the map values into a single string with each element separated by the given separator.
#define Q_NOWARN_DEPRECATED_PUSH
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
QMap< int, QVariant > QgsAttributeMap
QSet< QgsFeatureId > QgsFeatureIds
QList< int > QgsAttributeList