QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgsrelationreferencewidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrelationreferencewidget.cpp
3  --------------------------------------
4  Date : 20.4.2013
5  Copyright : (C) 2013 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 <QPushButton>
19 #include <QDialog>
20 #include <QHBoxLayout>
21 #include <QTimer>
22 #include <QCompleter>
23 
24 #include "qgsattributeform.h"
26 #include "qgsattributedialog.h"
27 #include "qgsapplication.h"
28 #include "qgscollapsiblegroupbox.h"
29 #include "qgseditorwidgetfactory.h"
30 #include "qgsexpression.h"
31 #include "qgsfeaturelistmodel.h"
32 #include "qgsfields.h"
33 #include "qgsgeometry.h"
34 #include "qgshighlight.h"
35 #include "qgsmapcanvas.h"
36 #include "qgsmessagebar.h"
38 #include "qgsvectorlayer.h"
39 #include "qgsattributetablemodel.h"
42 #include "qgsfeatureiterator.h"
43 #include "qgsfeaturelistcombobox.h"
45 #include "qgsfeaturefiltermodel.h"
46 #include "qgsidentifymenu.h"
47 #include "qgsvectorlayerutils.h"
48 
49 
50 bool qVariantListIsNull( const QVariantList &list )
51 {
52  if ( list.isEmpty() )
53  return true;
54 
55  for ( int i = 0; i < list.size(); ++i )
56  {
57  if ( !list.at( i ).isNull() )
58  return false;
59  }
60  return true;
61 }
62 
63 
65  : QWidget( parent )
66 {
67  mTopLayout = new QVBoxLayout( this );
68  mTopLayout->setContentsMargins( 0, 0, 0, 0 );
69 
70  setSizePolicy( sizePolicy().horizontalPolicy(), QSizePolicy::Fixed );
71 
72  setLayout( mTopLayout );
73 
74  QHBoxLayout *editLayout = new QHBoxLayout();
75  editLayout->setContentsMargins( 0, 0, 0, 0 );
76  editLayout->setSpacing( 2 );
77 
78  // Prepare the container and layout for the filter comboboxes
79  mChooserContainer = new QWidget;
80  editLayout->addWidget( mChooserContainer );
81  QHBoxLayout *chooserLayout = new QHBoxLayout;
82  chooserLayout->setContentsMargins( 0, 0, 0, 0 );
83  mFilterLayout = new QHBoxLayout;
84  mFilterLayout->setContentsMargins( 0, 0, 0, 0 );
85  mFilterContainer = new QWidget;
86  mFilterContainer->setLayout( mFilterLayout );
87  mChooserContainer->setLayout( chooserLayout );
88  chooserLayout->addWidget( mFilterContainer );
89 
90  mComboBox = new QgsFeatureListComboBox();
91  mChooserContainer->layout()->addWidget( mComboBox );
92 
93  // open form button
94  mOpenFormButton = new QToolButton();
95  mOpenFormButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionPropertyItem.svg" ) ) );
96  mOpenFormButton->setText( tr( "Open Related Feature Form" ) );
97  editLayout->addWidget( mOpenFormButton );
98 
99  mAddEntryButton = new QToolButton();
100  mAddEntryButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionAdd.svg" ) ) );
101  mAddEntryButton->setText( tr( "Add New Entry" ) );
102  editLayout->addWidget( mAddEntryButton );
103 
104  // highlight button
105  mHighlightFeatureButton = new QToolButton( this );
106  mHighlightFeatureButton->setPopupMode( QToolButton::MenuButtonPopup );
107  mHighlightFeatureAction = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionHighlightFeature.svg" ) ), tr( "Highlight feature" ), this );
108  mScaleHighlightFeatureAction = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionScaleHighlightFeature.svg" ) ), tr( "Scale and highlight feature" ), this );
109  mPanHighlightFeatureAction = new QAction( QgsApplication::getThemeIcon( QStringLiteral( "/mActionPanHighlightFeature.svg" ) ), tr( "Pan and highlight feature" ), this );
110  mHighlightFeatureButton->addAction( mHighlightFeatureAction );
111  mHighlightFeatureButton->addAction( mScaleHighlightFeatureAction );
112  mHighlightFeatureButton->addAction( mPanHighlightFeatureAction );
113  mHighlightFeatureButton->setDefaultAction( mHighlightFeatureAction );
114  editLayout->addWidget( mHighlightFeatureButton );
115 
116  // map identification button
117  mMapIdentificationButton = new QToolButton( this );
118  mMapIdentificationButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionMapIdentification.svg" ) ) );
119  mMapIdentificationButton->setText( tr( "Select on Map" ) );
120  mMapIdentificationButton->setCheckable( true );
121  editLayout->addWidget( mMapIdentificationButton );
122 
123  // remove foreign key button
124  mRemoveFKButton = new QToolButton( this );
125  mRemoveFKButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionRemove.svg" ) ) );
126  mRemoveFKButton->setText( tr( "No Selection" ) );
127  editLayout->addWidget( mRemoveFKButton );
128 
129  // add line to top layout
130  mTopLayout->addLayout( editLayout );
131 
132  // embed form
133  mAttributeEditorFrame = new QgsCollapsibleGroupBox( this );
134  mAttributeEditorLayout = new QVBoxLayout( mAttributeEditorFrame );
135  mAttributeEditorFrame->setLayout( mAttributeEditorLayout );
136  mAttributeEditorFrame->setSizePolicy( mAttributeEditorFrame->sizePolicy().horizontalPolicy(), QSizePolicy::Expanding );
137  mTopLayout->addWidget( mAttributeEditorFrame );
138 
139  // invalid label
140  mInvalidLabel = new QLabel( tr( "The relation is not valid. Please make sure your relation definitions are OK." ) );
141  mInvalidLabel->setWordWrap( true );
142  QFont font = mInvalidLabel->font();
143  font.setItalic( true );
144  mInvalidLabel->setStyleSheet( QStringLiteral( "QLabel { color: red; } " ) );
145  mInvalidLabel->setFont( font );
146  mTopLayout->addWidget( mInvalidLabel );
147 
148  // default mode is combobox, no geometric relation and no embed form
149  mMapIdentificationButton->hide();
150  mHighlightFeatureButton->hide();
151  mAttributeEditorFrame->hide();
152  mInvalidLabel->hide();
153  mAddEntryButton->hide();
154 
155  // connect buttons
156  connect( mOpenFormButton, &QAbstractButton::clicked, this, &QgsRelationReferenceWidget::openForm );
157  connect( mHighlightFeatureButton, &QToolButton::triggered, this, &QgsRelationReferenceWidget::highlightActionTriggered );
158  connect( mMapIdentificationButton, &QAbstractButton::clicked, this, &QgsRelationReferenceWidget::mapIdentification );
159  connect( mRemoveFKButton, &QAbstractButton::clicked, this, &QgsRelationReferenceWidget::deleteForeignKeys );
160  connect( mAddEntryButton, &QAbstractButton::clicked, this, &QgsRelationReferenceWidget::addEntry );
161  connect( mComboBox, &QComboBox::editTextChanged, this, &QgsRelationReferenceWidget::updateAddEntryButton );
162 }
163 
165 {
166  deleteHighlight();
167  unsetMapTool();
168 }
169 
170 void QgsRelationReferenceWidget::setRelation( const QgsRelation &relation, bool allowNullValue )
171 {
172  mAllowNull = allowNullValue;
173  mRemoveFKButton->setVisible( allowNullValue && mReadOnlySelector );
174 
175  if ( relation.isValid() )
176  {
177  mReferencedLayerId = relation.referencedLayerId();
178  mReferencedLayerName = relation.referencedLayer()->name();
180  mReferencedLayerProviderKey = relation.referencedLayer()->providerType();
181  mInvalidLabel->hide();
182 
183  mRelation = relation;
184  mReferencingLayer = relation.referencingLayer();
185  mReferencedLayer = relation.referencedLayer();
186 
187  const QList<QgsRelation::FieldPair> fieldPairs = relation.fieldPairs();
188  for ( const QgsRelation::FieldPair &fieldPair : fieldPairs )
189  {
190  mReferencedFields << fieldPair.referencedField();
191  }
192  if ( mComboBox )
193  {
194  mComboBox->setAllowNull( mAllowNull );
195  mComboBox->setSourceLayer( mReferencedLayer );
196  mComboBox->setIdentifierFields( mReferencedFields );
197  mComboBox->setFilterExpression( mFilterExpression );
198  }
199  mAttributeEditorFrame->setObjectName( QStringLiteral( "referencing/" ) + relation.name() );
200 
201  if ( mEmbedForm )
202  {
204  mAttributeEditorFrame->setTitle( mReferencedLayer->name() );
205  mReferencedAttributeForm = new QgsAttributeForm( relation.referencedLayer(), QgsFeature(), context, this );
206  mAttributeEditorLayout->addWidget( mReferencedAttributeForm );
207  }
208 
209  connect( mReferencedLayer, &QgsVectorLayer::editingStarted, this, &QgsRelationReferenceWidget::updateAddEntryButton );
210  connect( mReferencedLayer, &QgsVectorLayer::editingStopped, this, &QgsRelationReferenceWidget::updateAddEntryButton );
211  updateAddEntryButton();
212  }
213  else
214  {
215  mInvalidLabel->show();
216  }
217 
218  if ( mShown && isVisible() )
219  {
220  init();
221  }
222 }
223 
225 {
226  if ( !editable )
227  {
228  unsetMapTool();
229  }
230 
231  mFilterContainer->setEnabled( editable );
232  mComboBox->setEnabled( editable && !mReadOnlySelector );
233  mComboBox->setEditable( true );
234  mMapIdentificationButton->setEnabled( editable );
235  mRemoveFKButton->setEnabled( editable );
236  mIsEditable = editable;
237 }
238 
239 void QgsRelationReferenceWidget::setForeignKey( const QVariant &value )
240 {
241  setForeignKeys( QVariantList() << value );
242 }
243 
244 void QgsRelationReferenceWidget::setForeignKeys( const QVariantList &values )
245 {
246  if ( values.isEmpty() )
247  {
248  return;
249  }
250  if ( qVariantListIsNull( values ) )
251  {
253  return;
254  }
255 
256  if ( !mReferencedLayer )
257  return;
258 
259  mComboBox->setIdentifierValues( values );
260 
261  if ( mEmbedForm || mChainFilters )
262  {
263  QgsFeatureRequest request = mComboBox->currentFeatureRequest();
264  mReferencedLayer->getFeatures( request ).nextFeature( mFeature );
265  }
266  if ( mChainFilters )
267  {
268  QVariant nullValue = QgsApplication::nullRepresentation();
269  const int count = std::min( mFilterComboBoxes.size(), mFilterFields.size() );
270  for ( int i = 0; i < count; i++ )
271  {
272  QVariant v = mFeature.attribute( mFilterFields[i] );
273  QString f = v.isNull() ? nullValue.toString() : v.toString();
274  mFilterComboBoxes.at( i )->setCurrentIndex( mFilterComboBoxes.at( i )->findText( f ) );
275  }
276  }
277 
278  mRemoveFKButton->setEnabled( mIsEditable );
279  highlightFeature( mFeature ); // TODO : make this async
280  updateAttributeEditorFrame( mFeature );
281 
282  emitForeignKeysChanged( foreignKeys() );
283 }
284 
286 {
287  // deactivate filter comboboxes
288  if ( mChainFilters && !mFilterComboBoxes.isEmpty() )
289  {
290  QComboBox *cb = mFilterComboBoxes.first();
291  cb->setCurrentIndex( 0 );
292  disableChainedComboBoxes( cb );
293  }
294 
295  mComboBox->setIdentifierValuesToNull();
296  mRemoveFKButton->setEnabled( false );
297  updateAttributeEditorFrame( QgsFeature() );
298 
299  emitForeignKeysChanged( foreignKeys() );
300 }
301 
303 {
304  QgsFeature f;
305  if ( mReferencedLayer )
306  {
307  mReferencedLayer->getFeatures( mComboBox->currentFeatureRequest() ).nextFeature( f );
308  }
309  return f;
310 }
311 
313 {
314  whileBlocking( mComboBox )->setIdentifierValuesToNull();
315  mRemoveFKButton->setEnabled( false );
316  updateAttributeEditorFrame( QgsFeature() );
317 }
318 
320 {
321  QVariantList fkeys;
322  if ( fkeys.isEmpty() )
323  return QVariant( QVariant::Int );
324  else
325  return fkeys.at( 0 );
326 }
327 
329 {
330  return mComboBox->identifierValues();
331 }
332 
334 {
335  mEditorContext = context;
336  mCanvas = canvas;
337  mMessageBar = messageBar;
338 
339  mMapToolIdentify.reset( new QgsMapToolIdentifyFeature( mCanvas ) );
340  mMapToolIdentify->setButton( mMapIdentificationButton );
341 
342  if ( mEditorContext.cadDockWidget() )
343  {
344  mMapToolDigitize.reset( new QgsMapToolDigitizeFeature( mCanvas, mEditorContext.cadDockWidget() ) );
345  mMapToolDigitize->setButton( mAddEntryButton );
346  updateAddEntryButton();
347  }
348 }
349 
351 {
352  if ( display )
353  {
354  setSizePolicy( sizePolicy().horizontalPolicy(), QSizePolicy::MinimumExpanding );
355  mTopLayout->setAlignment( Qt::AlignTop );
356  }
357 
358  mAttributeEditorFrame->setVisible( display );
359  mEmbedForm = display;
360 }
361 
363 {
364  mComboBox->setEnabled( !readOnly );
365  mRemoveFKButton->setVisible( mAllowNull && readOnly );
366  mReadOnlySelector = readOnly;
367 }
368 
369 void QgsRelationReferenceWidget::setAllowMapIdentification( bool allowMapIdentification )
370 {
371  mHighlightFeatureButton->setVisible( allowMapIdentification );
372  mMapIdentificationButton->setVisible( allowMapIdentification );
373  mAllowMapIdentification = allowMapIdentification;
374 }
375 
377 {
378  mOrderByValue = orderByValue;
379 }
380 
381 void QgsRelationReferenceWidget::setFilterFields( const QStringList &filterFields )
382 {
383  mFilterFields = filterFields;
384 }
385 
387 {
388  mOpenFormButton->setVisible( openFormButtonVisible );
389  mOpenFormButtonVisible = openFormButtonVisible;
390 }
391 
393 {
394  mChainFilters = chainFilters;
395 }
396 
397 void QgsRelationReferenceWidget::setFilterExpression( const QString &expression )
398 {
399  mFilterExpression = expression;
400 }
401 
403 {
404  Q_UNUSED( e )
405 
406  mShown = true;
407  if ( !mInitialized )
408  init();
409 }
410 
412 {
413  if ( mReferencedLayer )
414  {
415  QApplication::setOverrideCursor( Qt::WaitCursor );
416 
417  QSet<QString> requestedAttrs;
418 
419  if ( !mFilterFields.isEmpty() )
420  {
421  for ( const QString &fieldName : std::as_const( mFilterFields ) )
422  {
423  int idx = mReferencedLayer->fields().lookupField( fieldName );
424 
425  if ( idx == -1 )
426  continue;
427 
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 ) );
434  QVariant nullValue = QgsApplication::nullRepresentation();
435  cb->addItem( nullValue.toString(), QVariant( mReferencedLayer->fields().at( idx ).type() ) );
436 
437  std::sort( uniqueValues.begin(), uniqueValues.end(), qgsVariantLessThan );
438  const auto constUniqueValues = uniqueValues;
439  for ( const QVariant &v : constUniqueValues )
440  {
441  cb->addItem( v.toString(), v );
442  }
443 
444  connect( cb, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRelationReferenceWidget::filterChanged );
445 
446  // Request this attribute for caching
447  requestedAttrs << fieldName;
448 
449  mFilterLayout->addWidget( cb );
450  }
451 
452  if ( mChainFilters )
453  {
454  QVariant nullValue = QgsApplication::nullRepresentation();
455 
456  QgsFeature ft;
457  QgsFeatureIterator fit = mFilterExpression.isEmpty()
458  ? mReferencedLayer->getFeatures()
459  : mReferencedLayer->getFeatures( mFilterExpression );
460  while ( fit.nextFeature( ft ) )
461  {
462  const int count = std::min( mFilterComboBoxes.count(), mFilterFields.count() );
463  for ( int i = 0; i < count - 1; i++ )
464  {
465  QVariant cv = ft.attribute( mFilterFields.at( i ) );
466  QVariant nv = ft.attribute( mFilterFields.at( i + 1 ) );
467  QString cf = cv.isNull() ? nullValue.toString() : cv.toString();
468  QString nf = nv.isNull() ? nullValue.toString() : nv.toString();
469  mFilterCache[mFilterFields[i]][cf] << nf;
470  }
471  }
472 
473  if ( !mFilterComboBoxes.isEmpty() )
474  {
475  QComboBox *cb = mFilterComboBoxes.first();
476  cb->setCurrentIndex( 0 );
477  disableChainedComboBoxes( cb );
478  }
479  }
480  }
481  else
482  {
483  mFilterContainer->hide();
484  }
485 
486  mComboBox->setSourceLayer( mReferencedLayer );
487  mComboBox->setDisplayExpression( mReferencedLayer->displayExpression() );
488  mComboBox->setAllowNull( mAllowNull );
489  mComboBox->setIdentifierFields( mReferencedFields );
490 
491  if ( ! mFilterExpression.isEmpty() )
492  mComboBox->setFilterExpression( mFilterExpression );
493 
494  QVariant nullValue = QgsApplication::nullRepresentation();
495 
496  if ( mChainFilters && mFeature.isValid() )
497  {
498  for ( int i = 0; i < mFilterFields.size(); i++ )
499  {
500  QVariant v = mFeature.attribute( mFilterFields[i] );
501  QString f = v.isNull() ? nullValue.toString() : v.toString();
502  mFilterComboBoxes.at( i )->setCurrentIndex( mFilterComboBoxes.at( i )->findText( f ) );
503  }
504  }
505 
506  // Only connect after iterating, to have only one iterator on the referenced table at once
507  connect( mComboBox, &QgsFeatureListComboBox::currentFeatureChanged, this, &QgsRelationReferenceWidget::comboReferenceChanged );
508 
509  QApplication::restoreOverrideCursor();
510 
511  mInitialized = true;
512  }
513 }
514 
515 void QgsRelationReferenceWidget::highlightActionTriggered( QAction *action )
516 {
517  if ( action == mHighlightFeatureAction )
518  {
519  highlightFeature();
520  }
521  else if ( action == mScaleHighlightFeatureAction )
522  {
523  highlightFeature( QgsFeature(), Scale );
524  }
525  else if ( action == mPanHighlightFeatureAction )
526  {
527  highlightFeature( QgsFeature(), Pan );
528  }
529 }
530 
532 {
533  QgsFeature feat = referencedFeature();
534 
535  if ( !feat.isValid() )
536  return;
537 
539  QgsAttributeDialog *attributeDialog = new QgsAttributeDialog( mReferencedLayer, new QgsFeature( feat ), true, this, true, context );
540  attributeDialog->show();
541 }
542 
543 void QgsRelationReferenceWidget::highlightFeature( QgsFeature f, CanvasExtent canvasExtent )
544 {
545  if ( !mCanvas )
546  return;
547 
548  if ( !f.isValid() )
549  {
550  f = referencedFeature();
551  if ( !f.isValid() )
552  return;
553  }
554 
555  if ( !f.hasGeometry() )
556  {
557  return;
558  }
559 
560  QgsGeometry geom = f.geometry();
561 
562  // scale or pan
563  if ( canvasExtent == Scale )
564  {
565  QgsRectangle featBBox = geom.boundingBox();
566  featBBox = mCanvas->mapSettings().layerToMapCoordinates( mReferencedLayer, featBBox );
567  QgsRectangle extent = mCanvas->extent();
568  if ( !extent.contains( featBBox ) )
569  {
570  extent.combineExtentWith( featBBox );
571  extent.scale( 1.1 );
572  mCanvas->setExtent( extent, true );
573  mCanvas->refresh();
574  }
575  }
576  else if ( canvasExtent == Pan )
577  {
578  QgsGeometry centroid = geom.centroid();
579  QgsPointXY center = centroid.asPoint();
580  center = mCanvas->mapSettings().layerToMapCoordinates( mReferencedLayer, center );
581  mCanvas->zoomByFactor( 1.0, &center ); // refresh is done in this method
582  }
583 
584  // highlight
585  deleteHighlight();
586  mHighlight = new QgsHighlight( mCanvas, f, mReferencedLayer );
587  QgsIdentifyMenu::styleHighlight( mHighlight );
588  mHighlight->show();
589 
590  QTimer *timer = new QTimer( this );
591  timer->setSingleShot( true );
592  connect( timer, &QTimer::timeout, this, &QgsRelationReferenceWidget::deleteHighlight );
593  timer->start( 3000 );
594 }
595 
596 void QgsRelationReferenceWidget::deleteHighlight()
597 {
598  if ( mHighlight )
599  {
600  mHighlight->hide();
601  delete mHighlight;
602  }
603  mHighlight = nullptr;
604 }
605 
607 {
608  if ( !mAllowMapIdentification || !mReferencedLayer )
609  return;
610 
611  const QgsVectorLayerTools *tools = mEditorContext.vectorLayerTools();
612  if ( !tools )
613  return;
614  if ( !mCanvas )
615  return;
616 
617  mMapToolIdentify->setLayer( mReferencedLayer );
618  setMapTool( mMapToolIdentify );
619 
620  connect( mMapToolIdentify, qOverload<const QgsFeature &>( &QgsMapToolIdentifyFeature::featureIdentified ), this, &QgsRelationReferenceWidget::featureIdentified );
621 
622  if ( mMessageBar )
623  {
624  QString title = tr( "Relation %1 for %2." ).arg( mRelation.name(), mReferencingLayer->name() );
625  QString msg = tr( "Identify a feature of %1 to be associated. Press &lt;ESC&gt; to cancel." ).arg( mReferencedLayer->name() );
626  mMessageBarItem = QgsMessageBar::createMessage( title, msg, this );
627  mMessageBar->pushItem( mMessageBarItem );
628  }
629 }
630 
631 void QgsRelationReferenceWidget::comboReferenceChanged()
632 {
633  mReferencedLayer->getFeatures( mComboBox->currentFeatureRequest() ).nextFeature( mFeature );
634  highlightFeature( mFeature );
635  updateAttributeEditorFrame( mFeature );
636 
637  emitForeignKeysChanged( mComboBox->identifierValues() );
638 }
639 
640 void QgsRelationReferenceWidget::updateAttributeEditorFrame( const QgsFeature &feature )
641 {
642  mOpenFormButton->setEnabled( feature.isValid() );
643  // Check if we're running with an embedded frame we need to update
644  if ( mAttributeEditorFrame && mReferencedAttributeForm )
645  {
646  mReferencedAttributeForm->setFeature( feature );
647  }
648 }
649 
651 {
652  return mAllowAddFeatures;
653 }
654 
656 {
657  mAllowAddFeatures = allowAddFeatures;
658  updateAddEntryButton();
659 }
660 
662 {
663  return mRelation;
664 }
665 
666 void QgsRelationReferenceWidget::featureIdentified( const QgsFeature &feature )
667 {
668  mComboBox->setCurrentFeature( feature );
669  mFeature = feature;
670 
671  mRemoveFKButton->setEnabled( mIsEditable );
672  highlightFeature( feature );
673  updateAttributeEditorFrame( feature );
674  emitForeignKeysChanged( foreignKeys(), true );
675 
676  unsetMapTool();
677 }
678 
679 void QgsRelationReferenceWidget::setMapTool( QgsMapTool *mapTool )
680 {
681  mCurrentMapTool = mapTool;
682  mCanvas->setMapTool( mapTool );
683 
684  mWindowWidget = window();
685 
686  mCanvas->window()->raise();
687  mCanvas->activateWindow();
688  mCanvas->setFocus();
689  connect( mapTool, &QgsMapTool::deactivated, this, &QgsRelationReferenceWidget::mapToolDeactivated );
690 }
691 
692 void QgsRelationReferenceWidget::unsetMapTool()
693 {
694  // deactivate map tools if activated
695  if ( mCurrentMapTool )
696  {
697  /* this will call mapToolDeactivated */
698  mCanvas->unsetMapTool( mCurrentMapTool );
699 
700  if ( mCurrentMapTool == mMapToolDigitize )
701  {
702  disconnect( mCanvas, &QgsMapCanvas::keyPressed, this, &QgsRelationReferenceWidget::onKeyPressed );
703  disconnect( mMapToolDigitize, &QgsMapToolDigitizeFeature::digitizingCompleted, this, &QgsRelationReferenceWidget::entryAdded );
704  }
705  else
706  {
707  disconnect( mMapToolIdentify, qOverload<const QgsFeature &>( &QgsMapToolIdentifyFeature::featureIdentified ), this, &QgsRelationReferenceWidget::featureIdentified );
708  }
709  }
710 }
711 
712 void QgsRelationReferenceWidget::onKeyPressed( QKeyEvent *e )
713 {
714  if ( e->key() == Qt::Key_Escape )
715  {
716  unsetMapTool();
717  }
718 }
719 
720 void QgsRelationReferenceWidget::mapToolDeactivated()
721 {
722  if ( mWindowWidget )
723  {
724  mWindowWidget->raise();
725  mWindowWidget->activateWindow();
726  }
727 
728  if ( mMessageBar && mMessageBarItem )
729  {
730  mMessageBar->popWidget( mMessageBarItem );
731  }
732  mMessageBarItem = nullptr;
733 }
734 
735 void QgsRelationReferenceWidget::filterChanged()
736 {
737  QVariant nullValue = QgsApplication::nullRepresentation();
738 
739  QMap<QString, QString> filters;
740  QgsAttributeList attrs;
741 
742  QComboBox *scb = qobject_cast<QComboBox *>( sender() );
743 
744  Q_ASSERT( scb );
745 
746  QgsFeature f;
747  QgsFeatureIds featureIds;
748  QString filterExpression = mFilterExpression;
749 
750  // wrap the expression with parentheses as it might contain `OR`
751  if ( !filterExpression.isEmpty() )
752  filterExpression = QStringLiteral( " ( %1 ) " ).arg( filterExpression );
753 
754  // comboboxes have to be disabled before building filters
755  if ( mChainFilters )
756  disableChainedComboBoxes( scb );
757 
758  // build filters
759  const auto constMFilterComboBoxes = mFilterComboBoxes;
760  for ( QComboBox *cb : constMFilterComboBoxes )
761  {
762  if ( cb->currentIndex() != 0 )
763  {
764  const QString fieldName = cb->property( "Field" ).toString();
765 
766  if ( cb->currentText() == nullValue.toString() )
767  {
768  filters[fieldName] = QStringLiteral( "\"%1\" IS NULL" ).arg( fieldName );
769  }
770  else
771  {
772  filters[fieldName] = QgsExpression::createFieldEqualityExpression( fieldName, cb->currentText() );
773  }
774  attrs << mReferencedLayer->fields().lookupField( fieldName );
775  }
776  }
777 
778  if ( mChainFilters )
779  {
780  QComboBox *ccb = nullptr;
781  const auto constMFilterComboBoxes = mFilterComboBoxes;
782  for ( QComboBox *cb : constMFilterComboBoxes )
783  {
784  if ( !ccb )
785  {
786  if ( cb == scb )
787  ccb = cb;
788 
789  continue;
790  }
791 
792  if ( ccb->currentIndex() != 0 )
793  {
794  const QString fieldName = cb->property( "Field" ).toString();
795 
796  cb->blockSignals( true );
797  cb->clear();
798  cb->addItem( cb->property( "FieldAlias" ).toString() );
799 
800  // ccb = scb
801  // cb = scb + 1
802  QStringList texts;
803  const auto txts { mFilterCache[ccb->property( "Field" ).toString()][ccb->currentText()] };
804  for ( const QString &txt : txts )
805  {
806  QMap<QString, QString> filtersAttrs = filters;
807  filtersAttrs[fieldName] = QgsExpression::createFieldEqualityExpression( fieldName, txt );
808  QgsAttributeList subset = attrs;
809 
810  QString expression = filterExpression;
811  if ( ! filterExpression.isEmpty() && ! filtersAttrs.values().isEmpty() )
812  expression += QLatin1String( " AND " );
813 
814  expression += filtersAttrs.isEmpty() ? QString() : QStringLiteral( " ( " );
815  expression += filtersAttrs.values().join( QLatin1String( " AND " ) );
816  expression += filtersAttrs.isEmpty() ? QString() : QStringLiteral( " ) " );
817 
818  subset << mReferencedLayer->fields().lookupField( fieldName );
819 
820  QgsFeatureIterator it( mReferencedLayer->getFeatures( QgsFeatureRequest().setFilterExpression( expression ).setSubsetOfAttributes( subset ) ) );
821 
822  bool found = false;
823  while ( it.nextFeature( f ) )
824  {
825  if ( !featureIds.contains( f.id() ) )
826  featureIds << f.id();
827 
828  found = true;
829  }
830 
831  // item is only provided if at least 1 feature exists
832  if ( found )
833  texts << txt;
834  }
835 
836  texts.sort();
837  cb->addItems( texts );
838 
839  cb->setEnabled( true );
840  cb->blockSignals( false );
841 
842  ccb = cb;
843  }
844  }
845  }
846 
847  if ( ! filterExpression.isEmpty() && ! filters.values().isEmpty() )
848  filterExpression += QLatin1String( " AND " );
849 
850  filterExpression += filters.isEmpty() ? QString() : QStringLiteral( " ( " );
851  filterExpression += filters.values().join( QLatin1String( " AND " ) );
852  filterExpression += filters.isEmpty() ? QString() : QStringLiteral( " ) " );
853 
855 }
856 
857 void QgsRelationReferenceWidget::addEntry()
858 {
859  if ( !mReferencedLayer )
860  return;
861 
862  const QgsVectorLayerTools *tools = mEditorContext.vectorLayerTools();
863  if ( !tools )
864  return;
865  if ( !mCanvas )
866  return;
867 
868  // no geometry, skip the digitizing
869  if ( mReferencedLayer->geometryType() == QgsWkbTypes::UnknownGeometry || mReferencedLayer->geometryType() == QgsWkbTypes::NullGeometry )
870  {
871  QgsFeature f( mReferencedLayer->fields() );
872  entryAdded( f );
873  return;
874  }
875 
876  mMapToolDigitize->setLayer( mReferencedLayer );
877  setMapTool( mMapToolDigitize );
878 
879  connect( mMapToolDigitize, &QgsMapToolDigitizeFeature::digitizingCompleted, this, &QgsRelationReferenceWidget::entryAdded );
880  connect( mCanvas, &QgsMapCanvas::keyPressed, this, &QgsRelationReferenceWidget::onKeyPressed );
881 
882  if ( mMessageBar )
883  {
884  QString title = tr( "Relation %1 for %2." ).arg( mRelation.name(), mReferencingLayer->name() );
885 
886  QString displayString = QgsVectorLayerUtils::getFeatureDisplayString( mReferencingLayer, mFormFeature );
887  QString msg = tr( "Link feature to %1 \"%2\" : Digitize the geometry for the new feature on layer %3. Press &lt;ESC&gt; to cancel." )
888  .arg( mReferencingLayer->name(), displayString, mReferencedLayer->name() );
889  mMessageBarItem = QgsMessageBar::createMessage( title, msg, this );
890  mMessageBar->pushItem( mMessageBarItem );
891  }
892 
893 }
894 
895 void QgsRelationReferenceWidget::entryAdded( const QgsFeature &feat )
896 {
897  QgsFeature f( feat );
898  QgsAttributeMap attributes;
899 
900  // if custom text is in the combobox and the displayExpression is simply a field, use the current text for the new feature
901  if ( mComboBox->itemText( mComboBox->currentIndex() ) != mComboBox->currentText() )
902  {
903  int fieldIdx = mReferencedLayer->fields().lookupField( mReferencedLayer->displayExpression() );
904 
905  if ( fieldIdx != -1 )
906  {
907  attributes.insert( fieldIdx, mComboBox->currentText() );
908  }
909  }
910 
911  if ( mEditorContext.vectorLayerTools()->addFeature( mReferencedLayer, attributes, f.geometry(), &f, this, false, true ) )
912  {
913  QVariantList attrs;
914  for ( const QString &fieldName : std::as_const( mReferencedFields ) )
915  attrs << f.attribute( fieldName );
916 
917  setForeignKeys( attrs );
918 
919  mAddEntryButton->setEnabled( false );
920  }
921 
922  unsetMapTool();
923 }
924 
925 void QgsRelationReferenceWidget::updateAddEntryButton()
926 {
927  mAddEntryButton->setVisible( mAllowAddFeatures && mMapToolDigitize );
928  mAddEntryButton->setEnabled( mReferencedLayer && mReferencedLayer->isEditable() );
929 }
930 
931 void QgsRelationReferenceWidget::disableChainedComboBoxes( const QComboBox *scb )
932 {
933  QComboBox *ccb = nullptr;
934  const auto constMFilterComboBoxes = mFilterComboBoxes;
935  for ( QComboBox *cb : constMFilterComboBoxes )
936  {
937  if ( !ccb )
938  {
939  if ( cb == scb )
940  {
941  ccb = cb;
942  }
943 
944  continue;
945  }
946 
947  cb->setCurrentIndex( 0 );
948  if ( ccb->currentIndex() == 0 )
949  {
950  cb->setEnabled( false );
951  }
952 
953  ccb = cb;
954  }
955 }
956 
957 void QgsRelationReferenceWidget::emitForeignKeysChanged( const QVariantList &foreignKeys, bool force )
958 {
959  if ( foreignKeys == mForeignKeys && force == false && qVariantListIsNull( foreignKeys ) == qVariantListIsNull( mForeignKeys ) )
960  return;
961 
962  mForeignKeys = foreignKeys;
964  emit foreignKeyChanged( foreignKeys.at( 0 ) );
967 }
968 
970 {
971  return mReferencedLayerName;
972 }
973 
974 void QgsRelationReferenceWidget::setReferencedLayerName( const QString &relationLayerName )
975 {
976  mReferencedLayerName = relationLayerName;
977 }
978 
980 {
981  return mReferencedLayerId;
982 }
983 
984 void QgsRelationReferenceWidget::setReferencedLayerId( const QString &relationLayerId )
985 {
986  mReferencedLayerId = relationLayerId;
987 }
988 
990 {
991  return mReferencedLayerProviderKey;
992 }
993 
994 void QgsRelationReferenceWidget::setReferencedLayerProviderKey( const QString &relationProviderKey )
995 {
996  mReferencedLayerProviderKey = relationProviderKey;
997 }
998 
1000 {
1001  return mReferencedLayerDataSource;
1002 }
1003 
1004 void QgsRelationReferenceWidget::setReferencedLayerDataSource( const QString &relationDataSource )
1005 {
1006  const QgsPathResolver resolver { QgsProject::instance()->pathResolver() };
1007  mReferencedLayerDataSource = resolver.writePath( relationDataSource );
1008 }
1009 
1011 {
1012  mFormFeature = formFeature;
1013 }
QgsAttributeDialog
Definition: qgsattributedialog.h:37
QgsVectorLayer::getFeatures
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries the layer for features specified in request.
Definition: qgsvectorlayer.cpp:1052
qgsfeaturefiltermodel.h
qgsmaptoolidentifyfeature.h
qgsfields.h
qgsexpressioncontextutils.h
QgsRelationReferenceWidget::showEvent
void showEvent(QShowEvent *e) override
Definition: qgsrelationreferencewidget.cpp:402
QgsRelationReferenceWidget::Pan
@ Pan
Definition: qgsrelationreferencewidget.h:77
qgsattributeform.h
QgsMapCanvas::extent
QgsRectangle extent() const
Returns the current zoom extent of the map canvas.
Definition: qgsmapcanvas.cpp:1331
QObjectUniquePtr::reset
void reset(T *p=nullptr)
Will reset the managed pointer to p.
Definition: qobjectuniqueptr.h:179
qgscollapsiblegroupbox.h
QgsRelationReferenceWidget::referencedFeature
QgsFeature referencedFeature() const
Returns the related feature (from the referenced layer) if no feature is related, it returns an inval...
Definition: qgsrelationreferencewidget.cpp:302
QgsAttributeEditorContext::cadDockWidget
QgsAdvancedDigitizingDockWidget * cadDockWidget() const
Returns the associated CAD dock widget (e.g.
Definition: qgsattributeeditorcontext.h:156
QgsMapCanvas::refresh
void refresh()
Repaints the canvas map.
Definition: qgsmapcanvas.cpp:643
QgsMapLayer::editingStopped
void editingStopped()
Emitted when edited changes have been successfully written to the data provider.
QgsFeatureListComboBox::setCurrentFeature
void setCurrentFeature(const QgsFeature &feature)
Sets the current index by using the given feature.
Definition: qgsfeaturelistcombobox.cpp:79
QgsRectangle::combineExtentWith
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
Definition: qgsrectangle.h:391
QgsRelationReferenceWidget::allowMapIdentification
bool allowMapIdentification()
determines if the widget offers the possibility to select the related feature on the map (using a ded...
Definition: qgsrelationreferencewidget.h:131
QgsRelationReferenceWidget::init
void init()
Definition: qgsrelationreferencewidget.cpp:411
qgsmapcanvas.h
QgsWkbTypes::NullGeometry
@ NullGeometry
Definition: qgswkbtypes.h:146
QgsRelationReferenceWidget::setFilterFields
void setFilterFields(const QStringList &filterFields)
Sets the fields for which filter comboboxes will be created.
Definition: qgsrelationreferencewidget.cpp:381
QgsMapCanvas::zoomByFactor
void zoomByFactor(double scaleFactor, const QgsPointXY *center=nullptr, bool ignoreScaleLock=false)
Zoom with the factor supplied.
Definition: qgsmapcanvas.cpp:3054
qgsfeaturelistcombobox.h
QgsRelationReferenceWidget::openForm
void openForm()
open the form of the related feature in a new dialog
Definition: qgsrelationreferencewidget.cpp:531
QgsMapToolIdentifyFeature::setLayer
void setLayer(QgsVectorLayer *vl)
change the layer used by the map tool to identify
Definition: qgsmaptoolidentifyfeature.h:55
QgsMeshUtils::centroid
CORE_EXPORT QgsMeshVertex centroid(const QgsMeshFace &face, const QVector< QgsMeshVertex > &vertices)
Returns the centroid of the face.
Definition: qgstriangularmesh.cpp:955
qgsexpression.h
QgsFeatureListComboBox::setFilterExpression
void setFilterExpression(const QString &filterExpression)
An additional expression to further restrict the available features.
Definition: qgsfeaturelistcombobox.cpp:301
QgsMapCanvas::mapSettings
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
Definition: qgsmapcanvas.cpp:437
qgsVariantLessThan
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
Definition: qgis.cpp:119
QgsRelationReferenceWidget::foreignKeyChanged
Q_DECL_DEPRECATED void foreignKeyChanged(const QVariant &)
Emitted when the foreign key changed.
QgsRelationReferenceWidget::showIndeterminateState
void showIndeterminateState()
Sets the widget to display in an indeterminate "mixed value" state.
Definition: qgsrelationreferencewidget.cpp:312
QgsRelation::name
QString name
Definition: qgsrelation.h:49
QgsProject::pathResolver
QgsPathResolver pathResolver() const
Returns path resolver object with considering whether the project uses absolute or relative paths and...
Definition: qgsproject.cpp:3094
QgsRelationReferenceWidget::allowAddFeatures
bool allowAddFeatures() const
Determines if a button for adding new features should be shown.
Definition: qgsrelationreferencewidget.cpp:650
QgsAttributeForm::setFeature
void setFeature(const QgsFeature &feature)
Update all editors to correspond to a different feature.
Definition: qgsattributeform.cpp:292
qgsfeatureiterator.h
QgsMapCanvas
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:89
QgsGeometry::centroid
QgsGeometry centroid() const
Returns the center of mass of a geometry.
Definition: qgsgeometry.cpp:2284
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:71
QgsVectorLayerTools
Methods in this class are used to handle basic operations on vector layers. With an implementation of...
Definition: qgsvectorlayertools.h:39
QgsFeatureListComboBox::identifierValues
QVariantList identifierValues
Definition: qgsfeaturelistcombobox.h:47
QgsRelationReferenceWidget::setReferencedLayerProviderKey
void setReferencedLayerProviderKey(const QString &referencedLayerProviderKey)
Set the data provider key of the referenced layer to referencedLayerProviderKey.
Definition: qgsrelationreferencewidget.cpp:994
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:480
QgsRelationReferenceWidget::setRelationEditable
void setRelationEditable(bool editable)
Definition: qgsrelationreferencewidget.cpp:224
QgsAttributeEditorContext::Embed
@ Embed
A form was embedded as a widget on another form.
Definition: qgsattributeeditorcontext.h:72
qVariantListIsNull
bool qVariantListIsNull(const QVariantList &list)
Definition: qgsrelationreferencewidget.cpp:50
qgsfeaturelistmodel.h
QgsMapLayer::editingStarted
void editingStarted()
Emitted when editing on this layer has started.
QgsRelationReferenceWidget::Scale
@ Scale
Definition: qgsrelationreferencewidget.h:78
QgsMapToolIdentifyFeature
The QgsMapToolIdentifyFeature class is a map tool to identify a feature on a chosen layer....
Definition: qgsmaptoolidentifyfeature.h:28
QgsRelationReferenceWidget::~QgsRelationReferenceWidget
~QgsRelationReferenceWidget() override
Definition: qgsrelationreferencewidget.cpp:164
QgsAttributeList
QList< int > QgsAttributeList
Definition: qgsfield.h:26
qgsidentifymenu.h
QgsCollapsibleGroupBox
A groupbox that collapses/expands when toggled and can save its collapsed and checked states....
Definition: qgscollapsiblegroupbox.h:185
QgsMessageBar::popWidget
bool popWidget(QgsMessageBarItem *item)
Remove the specified item from the bar, and display the next most recent one in the stack.
Definition: qgsmessagebar.cpp:161
QgsRelationReferenceWidget::filterExpression
QString filterExpression() const
Returns the currently set filter expression.
Definition: qgsrelationreferencewidget.h:163
QgsRelationReferenceWidget::chainFilters
bool chainFilters() const
Determines if the filters are chained.
Definition: qgsrelationreferencewidget.h:150
QgsRelationReferenceWidget::setReferencedLayerName
void setReferencedLayerName(const QString &referencedLayerName)
Set the name of the referenced layer to referencedLayerName.
Definition: qgsrelationreferencewidget.cpp:974
QgsRelationReferenceWidget::setForeignKeys
void setForeignKeys(const QVariantList &values)
Sets the related feature using the foreign keys.
Definition: qgsrelationreferencewidget.cpp:244
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:41
QgsVectorLayer::isEditable
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
Definition: qgsvectorlayer.cpp:3728
QgsHighlight
A class for highlight features on the map.
Definition: qgshighlight.h:61
QgsMapLayer::providerType
QString providerType() const
Returns the provider type (provider key) for this layer.
Definition: qgsmaplayer.cpp:1864
QgsRelation::referencingLayer
QgsVectorLayer referencingLayer
Definition: qgsrelation.h:47
qgsapplication.h
QgsMapTool
Abstract base class for all map tools. Map tools are user interactive tools for manipulating the map ...
Definition: qgsmaptool.h:70
qgsmaptooldigitizefeature.h
QgsFeatureListComboBox::setDisplayExpression
void setDisplayExpression(const QString &displayExpression)
The display expression will be used to display features as well as the value to match the typed text ...
Definition: qgsfeaturelistcombobox.cpp:95
QgsVectorLayer::fields
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Definition: qgsvectorlayer.cpp:3436
Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:2820
QgsFeature::id
QgsFeatureId id
Definition: qgsfeature.h:68
QgsRectangle::scale
void scale(double scaleFactor, const QgsPointXY *c=nullptr)
Scale the rectangle around its center point.
Definition: qgsrectangle.h:256
QgsRelationReferenceWidget::setAllowMapIdentification
void setAllowMapIdentification(bool allowMapIdentification)
Definition: qgsrelationreferencewidget.cpp:369
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:83
QgsRelationReferenceWidget::setAllowAddFeatures
void setAllowAddFeatures(bool allowAddFeatures)
Determines if a button for adding new features should be shown.
Definition: qgsrelationreferencewidget.cpp:655
QgsRelationReferenceWidget::referencedLayerName
QString referencedLayerName() const
Returns the name of the referenced layer.
Definition: qgsrelationreferencewidget.cpp:969
QgsMapToolDigitizeFeature::digitizingCompleted
void digitizingCompleted(const QgsFeature &feature)
Emitted whenever the digitizing has been successfully completed.
QgsRelationReferenceWidget::mapIdentification
void mapIdentification()
activate the map tool to select a new related feature on the map
Definition: qgsrelationreferencewidget.cpp:606
QgsFeatureListComboBox::setIdentifierValues
void setIdentifierValues(const QVariantList &identifierValues)
The identifier values of the currently selected feature.
Definition: qgsfeaturelistcombobox.cpp:259
whileBlocking
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:2191
QgsFeature::isValid
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:216
QgsApplication::nullRepresentation
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS.
Definition: qgsapplication.cpp:2018
QgsRelationReferenceWidget::setEditorContext
void setEditorContext(const QgsAttributeEditorContext &context, QgsMapCanvas *canvas, QgsMessageBar *messageBar)
Sets the editor context.
Definition: qgsrelationreferencewidget.cpp:333
QgsAttributeEditorContext::StandaloneDialog
@ StandaloneDialog
A form was opened as a new dialog.
Definition: qgsattributeeditorcontext.h:73
QgsRelationReferenceWidget::foreignKeysChanged
void foreignKeysChanged(const QVariantList &)
Emitted when the foreign keys changed.
QgsMapToolDigitizeFeature::setLayer
void setLayer(QgsMapLayer *vl)
Change the layer edited by the map tool.
Definition: qgsmaptooldigitizefeature.cpp:204
QgsRelation::referencedLayer
QgsVectorLayer referencedLayer
Definition: qgsrelation.h:48
QgsRelationReferenceWidget::orderByValue
bool orderByValue()
If the widget will order the combobox entries by value.
Definition: qgsrelationreferencewidget.h:135
qgsattributetablefiltermodel.h
QgsMessageBar::pushItem
void pushItem(QgsMessageBarItem *item)
Display a message item on the bar, after hiding the currently visible one and putting it in a stack.
Definition: qgsmessagebar.cpp:295
QgsRelationReferenceWidget::setEmbedForm
void setEmbedForm(bool display)
Definition: qgsrelationreferencewidget.cpp:350
QgsRectangle::contains
bool contains(const QgsRectangle &rect) const SIP_HOLDGIL
Returns true when rectangle contains other rectangle.
Definition: qgsrectangle.h:363
QgsRelationReferenceWidget::setReferencedLayerDataSource
void setReferencedLayerDataSource(const QString &referencedLayerDataSource)
Set the public data source of the referenced layer to referencedLayerDataSource.
Definition: qgsrelationreferencewidget.cpp:1004
QgsVectorLayer::uniqueValues
QSet< QVariant > uniqueValues(int fieldIndex, int limit=-1) const FINAL
Calculates a list of unique values contained within an attribute in the layer.
Definition: qgsvectorlayer.cpp:4161
QgsMessageBar
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:60
QgsAttributeMap
QMap< int, QVariant > QgsAttributeMap
Definition: qgsattributes.h:38
qgsvectorlayerutils.h
qgsattributedialog.h
QgsMapToolDigitizeFeature
This tool digitizes geometry of new point/line/polygon features on already existing vector layers Onc...
Definition: qgsmaptooldigitizefeature.h:31
QgsAttributeDialog::show
void show()
Show the dialog non-blocking. Reparents this dialog to be a child of the dialog form.
Definition: qgsattributedialog.cpp:86
QgsFeature::attribute
QVariant attribute(const QString &name) const
Lookup attribute value by attribute name.
Definition: qgsfeature.cpp:327
QgsFeatureListComboBox
This offers a combobox with autocompleter that allows selecting features from a layer.
Definition: qgsfeaturelistcombobox.h:39
qgsmessagebar.h
qgsattributetablemodel.h
QgsFeatureListComboBox::currentFeatureRequest
QgsFeatureRequest currentFeatureRequest() const
Shorthand for getting a feature request to query the currently selected feature.
Definition: qgsfeaturelistcombobox.cpp:269
QgsRelationReferenceWidget::setForeignKey
Q_DECL_DEPRECATED void setForeignKey(const QVariant &value)
this sets the related feature using from the foreign key
Definition: qgsrelationreferencewidget.cpp:239
QgsMapTool::setButton
void setButton(QAbstractButton *button)
Use this to associate a button to this maptool.
Definition: qgsmaptool.cpp:150
QgsMapCanvas::setExtent
void setExtent(const QgsRectangle &r, bool magnified=false)
Sets the extent of the map canvas to the specified rectangle.
Definition: qgsmapcanvas.cpp:1359
QgsExpression::createFieldEqualityExpression
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value, QVariant::Type fieldType=QVariant::Type::Invalid)
Create an expression allowing to evaluate if a field is equal to a value.
Definition: qgsexpression.cpp:1126
QgsMapCanvas::setMapTool
void setMapTool(QgsMapTool *mapTool, bool clean=false)
Sets the map tool currently being used on the canvas.
Definition: qgsmapcanvas.cpp:2475
QgsFeatureIds
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
QgsRelation::FieldPair
Defines a relation between matching fields of the two involved tables of a relation.
Definition: qgsrelation.h:88
QgsFeatureListComboBox::setSourceLayer
void setSourceLayer(QgsVectorLayer *sourceLayer)
The layer from which features should be listed.
Definition: qgsfeaturelistcombobox.cpp:74
qgsvectorlayer.h
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:58
QgsAttributeEditorContext::Single
@ Single
When showing a single feature (e.g. district information when looking at the form of a house)
Definition: qgsattributeeditorcontext.h:67
QgsRelation::fieldPairs
QList< QgsRelation::FieldPair > fieldPairs() const
Returns the field pairs which form this relation The first element of each pair are the field names o...
Definition: qgsrelation.cpp:330
QgsRelationReferenceWidget::referencedLayerProviderKey
QString referencedLayerProviderKey() const
Returns the data provider key of the referenced layer.
Definition: qgsrelationreferencewidget.cpp:989
QgsMapLayer::publicSource
QString publicSource() const
Gets a version of the internal layer definition that has sensitive bits removed (for example,...
Definition: qgsmaplayer.cpp:292
QgsRelationReferenceWidget::relation
QgsRelation relation() const
Returns the current relation, which might be invalid.
Definition: qgsrelationreferencewidget.cpp:661
QgsRelationReferenceWidget::openFormButtonVisible
bool openFormButtonVisible
Definition: qgsrelationreferencewidget.h:70
qgsgeometry.h
qgshighlight.h
QgsRelationReferenceWidget::foreignKeys
QVariantList foreignKeys() const
returns the related feature foreign key
Definition: qgsrelationreferencewidget.cpp:328
QgsFeatureListComboBox::setIdentifierFields
void setIdentifierFields(const QStringList &identifierFields)
Field name that will be used to uniquely identify the current feature.
Definition: qgsfeaturelistcombobox.cpp:205
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:399
QgsVectorLayer::attributeDisplayName
QString attributeDisplayName(int index) const
Convenience function that returns the attribute alias if defined or the field name else.
Definition: qgsvectorlayer.cpp:3245
QgsRelationReferenceWidget::deleteForeignKeys
void deleteForeignKeys()
unset the currently related feature
Definition: qgsrelationreferencewidget.cpp:285
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsRelationReferenceWidget::setRelation
void setRelation(const QgsRelation &relation, bool allowNullValue)
Definition: qgsrelationreferencewidget.cpp:170
qgseditorwidgetfactory.h
QgsFeature::hasGeometry
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:230
QgsFeatureListComboBox::currentFeatureChanged
void currentFeatureChanged()
Emitted when the current feature changes.
QgsRelationReferenceWidget::setChainFilters
void setChainFilters(bool chainFilters)
Set if filters are chained.
Definition: qgsrelationreferencewidget.cpp:392
QgsRelation::isValid
bool isValid
Definition: qgsrelation.h:50
QgsRelationReferenceWidget::setOrderByValue
void setOrderByValue(bool orderByValue)
Sets if the widget will order the combobox entries by value.
Definition: qgsrelationreferencewidget.cpp:376
QgsMapLayer::name
QString name
Definition: qgsmaplayer.h:76
QgsWkbTypes::UnknownGeometry
@ UnknownGeometry
Definition: qgswkbtypes.h:145
QgsMapCanvas::keyPressed
void keyPressed(QKeyEvent *e)
Emit key press event.
QgsRelationReferenceWidget::referencedLayerId
QString referencedLayerId() const
Returns the id of the referenced layer.
Definition: qgsrelationreferencewidget.cpp:979
QgsMapCanvas::unsetMapTool
void unsetMapTool(QgsMapTool *mapTool)
Unset the current map tool or last non zoom tool.
Definition: qgsmapcanvas.cpp:2515
QgsRelationReferenceWidget::setReferencedLayerId
void setReferencedLayerId(const QString &referencedLayerId)
Set the id of the referenced layer to referencedLayerId.
Definition: qgsrelationreferencewidget.cpp:984
QgsRelation
Definition: qgsrelation.h:42
QgsFeatureListComboBox::setAllowNull
void setAllowNull(bool allowNull)
Determines if a NULL value should be available in the list.
Definition: qgsfeaturelistcombobox.cpp:236
QgsGeometry::boundingBox
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Definition: qgsgeometry.cpp:1080
QgsRelationReferenceWidget::referencedLayerDataSource
QString referencedLayerDataSource() const
Returns the public data source of the referenced layer.
Definition: qgsrelationreferencewidget.cpp:999
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
QgsApplication::getThemeIcon
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
Definition: qgsapplication.cpp:693
QgsAttributeForm
Definition: qgsattributeform.h:44
QgsRelationReferenceWidget::setOpenFormButtonVisible
void setOpenFormButtonVisible(bool openFormButtonVisible)
Definition: qgsrelationreferencewidget.cpp:386
QgsMessageBar::createMessage
static QgsMessageBarItem * createMessage(const QString &text, QWidget *parent=nullptr)
Creates message bar item widget containing a message text to be displayed on the bar.
Definition: qgsmessagebar.cpp:389
qgsrelationreferencewidget.h
QgsFields::lookupField
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
Definition: qgsfields.cpp:349
QgsFeatureListComboBox::setIdentifierValuesToNull
void setIdentifierValuesToNull()
Sets the identifier values of the currently selected feature to NULL value(s).
Definition: qgsfeaturelistcombobox.cpp:264
QgsMapToolIdentifyFeature::featureIdentified
void featureIdentified(const QgsFeature &)
QgsRelationReferenceWidget::setFilterExpression
void setFilterExpression(const QString &filterExpression)
If not empty, will be used as filter expression.
Definition: qgsrelationreferencewidget.cpp:397
QgsRelationReferenceWidget::QgsRelationReferenceWidget
QgsRelationReferenceWidget(QWidget *parent)
Definition: qgsrelationreferencewidget.cpp:64
QgsFields::at
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Definition: qgsfields.cpp:163
QgsAttributeEditorContext
This class contains context information for attribute editor widgets. It will be passed to embedded w...
Definition: qgsattributeeditorcontext.h:40
QgsVectorLayer::displayExpression
QString displayExpression
Definition: qgsvectorlayer.h:396
QgsRelationReferenceWidget::foreignKey
Q_DECL_DEPRECATED QVariant foreignKey() const
returns the related feature foreign key
Definition: qgsrelationreferencewidget.cpp:319
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:289
QgsMapSettings::layerToMapCoordinates
QgsPointXY layerToMapCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from layer's CRS to output CRS
Definition: qgsmapsettings.cpp:578
QgsVectorLayer::geometryType
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
Definition: qgsvectorlayer.cpp:720
Q_NOWARN_DEPRECATED_PUSH
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:2819
QgsIdentifyMenu::styleHighlight
static void styleHighlight(QgsHighlight *highlight)
Applies style from the settings to the highlight.
Definition: qgsidentifymenu.cpp:682
QgsRelationReferenceWidget::setReadOnlySelector
void setReadOnlySelector(bool readOnly)
Definition: qgsrelationreferencewidget.cpp:362
QgsRelationReferenceWidget::setFormFeature
void setFormFeature(const QgsFeature &formFeature)
Set the current form feature (from the referencing layer)
Definition: qgsrelationreferencewidget.cpp:1010
QgsVectorLayerTools::addFeature
virtual bool addFeature(QgsVectorLayer *layer, const QgsAttributeMap &defaultValues=QgsAttributeMap(), const QgsGeometry &defaultGeometry=QgsGeometry(), QgsFeature *feature=nullptr, QWidget *parentWidget=nullptr, bool showModal=true, bool hideParent=false) const =0
This method should/will be called, whenever a new feature will be added to the layer.
qgsrelationreferenceconfigdlg.h
QgsPathResolver
Resolves relative paths into absolute paths and vice versa. Used for writing.
Definition: qgspathresolver.h:31
QgsAttributeEditorContext::vectorLayerTools
const QgsVectorLayerTools * vectorLayerTools() const
Returns the associated vector layer tools.
Definition: qgsattributeeditorcontext.h:172
QgsField::type
QVariant::Type type
Definition: qgsfield.h:58
QgsRelation::referencedLayerId
QString referencedLayerId() const
Access the referenced (parent) layer's id.
Definition: qgsrelation.cpp:320
QgsMapTool::deactivated
void deactivated()
signal emitted once the map tool is deactivated
QgsVectorLayerUtils::getFeatureDisplayString
static QString getFeatureDisplayString(const QgsVectorLayer *layer, const QgsFeature &feature)
Definition: qgsvectorlayerutils.cpp:1053