QGIS API Documentation  2.14.11-Essen
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
qgsrelationeditorwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrelationeditor.cpp
3  --------------------------------------
4  Date : 17.5.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 "qgsapplication.h"
19 #include "qgsdistancearea.h"
20 #include "qgsvectordataprovider.h"
21 #include "qgsexpression.h"
22 #include "qgsfeature.h"
23 #include "qgsfeatureselectiondlg.h"
25 #include "qgsrelation.h"
26 #include "qgsvectorlayertools.h"
27 
28 #include <QHBoxLayout>
29 #include <QLabel>
30 
32  : QgsCollapsibleGroupBox( parent )
33  , mViewMode( QgsDualView::AttributeEditor )
34  , mVisible( false )
35 {
36  QVBoxLayout* topLayout = new QVBoxLayout( this );
37  topLayout->setContentsMargins( 0, 9, 0, 0 );
38  setLayout( topLayout );
39 
40  // buttons
41  QHBoxLayout* buttonLayout = new QHBoxLayout();
42  buttonLayout->setContentsMargins( 0, 0, 0, 0 );
43  // toogle editing
44  mToggleEditingButton = new QToolButton( this );
45  mToggleEditingButton->setObjectName( "mToggleEditingButton" );
46  mToggleEditingButton->setIcon( QgsApplication::getThemeIcon( "/mActionToggleEditing.svg" ) );
47  mToggleEditingButton->setText( tr( "Toggle editing" ) );
48  mToggleEditingButton->setEnabled( false );
49  mToggleEditingButton->setCheckable( true );
50  mToggleEditingButton->setToolTip( tr( "Toggle editing mode for child layer" ) );
51  buttonLayout->addWidget( mToggleEditingButton );
52  // save Edits
53  mSaveEditsButton = new QToolButton( this );
54  mSaveEditsButton->setIcon( QgsApplication::getThemeIcon( "/mActionSaveEdits.svg" ) );
55  mSaveEditsButton->setText( tr( "Save layer edits" ) );
56  mSaveEditsButton->setToolTip( tr( "Save child layer edits" ) );
57  mSaveEditsButton->setEnabled( true );
58  buttonLayout->addWidget( mSaveEditsButton );
59  // add feature
60  mAddFeatureButton = new QToolButton( this );
61  mAddFeatureButton->setIcon( QgsApplication::getThemeIcon( "/mActionAdd.svg" ) );
62  mAddFeatureButton->setText( tr( "Add feature" ) );
63  mAddFeatureButton->setToolTip( tr( "Add child feature" ) );
64  mAddFeatureButton->setObjectName( "mAddFeatureButton" );
65  buttonLayout->addWidget( mAddFeatureButton );
66  // delete feature
67  mDeleteFeatureButton = new QToolButton( this );
68  mDeleteFeatureButton->setIcon( QgsApplication::getThemeIcon( "/mActionRemove.svg" ) );
69  mDeleteFeatureButton->setText( tr( "Delete feature" ) );
70  mDeleteFeatureButton->setToolTip( tr( "Delete child feature" ) );
71  mDeleteFeatureButton->setObjectName( "mDeleteFeatureButton" );
72  buttonLayout->addWidget( mDeleteFeatureButton );
73  // link feature
74  mLinkFeatureButton = new QToolButton( this );
75  mLinkFeatureButton->setIcon( QgsApplication::getThemeIcon( "/mActionLink.svg" ) );
76  mLinkFeatureButton->setText( tr( "Link feature" ) );
77  mLinkFeatureButton->setToolTip( tr( "Link existing child features" ) );
78  mLinkFeatureButton->setObjectName( "mLinkFeatureButton" );
79  buttonLayout->addWidget( mLinkFeatureButton );
80  // unlink feature
81  mUnlinkFeatureButton = new QToolButton( this );
82  mUnlinkFeatureButton->setIcon( QgsApplication::getThemeIcon( "/mActionUnlink.svg" ) );
83  mUnlinkFeatureButton->setText( tr( "Unlink feature" ) );
84  mUnlinkFeatureButton->setToolTip( tr( "Unlink child feature" ) );
85  mUnlinkFeatureButton->setObjectName( "mUnlinkFeatureButton" );
86  buttonLayout->addWidget( mUnlinkFeatureButton );
87  // spacer
88  buttonLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding ) );
89  // form view
90  mFormViewButton = new QToolButton( this );
91  mFormViewButton->setText( tr( "Form view" ) );
92  mFormViewButton->setToolTip( tr( "Switch to form view" ) );
93  mFormViewButton->setIcon( QgsApplication::getThemeIcon( "/mActionPropertyItem.png" ) );
94  mFormViewButton->setCheckable( true );
95  mFormViewButton->setChecked( mViewMode == QgsDualView::AttributeEditor );
96  buttonLayout->addWidget( mFormViewButton );
97  // table view
98  mTableViewButton = new QToolButton( this );
99  mTableViewButton->setText( tr( "Table view" ) );
100  mTableViewButton->setToolTip( tr( "Switch to table view" ) );
101  mTableViewButton->setIcon( QgsApplication::getThemeIcon( "/mActionOpenTable.svg" ) );
102  mTableViewButton->setCheckable( true );
103  mTableViewButton->setChecked( mViewMode == QgsDualView::AttributeTable );
104  buttonLayout->addWidget( mTableViewButton );
105  // button group
106  mViewModeButtonGroup = new QButtonGroup( this );
107  mViewModeButtonGroup->addButton( mFormViewButton, QgsDualView::AttributeEditor );
108  mViewModeButtonGroup->addButton( mTableViewButton, QgsDualView::AttributeTable );
109 
110  // add buttons layout
111  topLayout->addLayout( buttonLayout );
112 
113  mRelationLayout = new QGridLayout();
114  mRelationLayout->setContentsMargins( 0, 0, 0, 0 );
115  topLayout->addLayout( mRelationLayout );
116 
117  mDualView = new QgsDualView( this );
118  mDualView->setView( mViewMode );
119  mFeatureSelectionMgr = new QgsGenericFeatureSelectionManager( mDualView );
120  mDualView->setFeatureSelectionManager( mFeatureSelectionMgr );
121 
122  mRelationLayout->addWidget( mDualView );
123 
124  connect( this, SIGNAL( collapsedStateChanged( bool ) ), this, SLOT( onCollapsedStateChanged( bool ) ) );
125  connect( mViewModeButtonGroup, SIGNAL( buttonClicked( int ) ), this, SLOT( setViewMode( int ) ) );
126  connect( mToggleEditingButton, SIGNAL( clicked( bool ) ), this, SLOT( toggleEditing( bool ) ) );
127  connect( mSaveEditsButton, SIGNAL( clicked() ), this, SLOT( saveEdits() ) );
128  connect( mAddFeatureButton, SIGNAL( clicked() ), this, SLOT( addFeature() ) );
129  connect( mDeleteFeatureButton, SIGNAL( clicked() ), this, SLOT( deleteFeature() ) );
130  connect( mLinkFeatureButton, SIGNAL( clicked() ), this, SLOT( linkFeature() ) );
131  connect( mUnlinkFeatureButton, SIGNAL( clicked() ), this, SLOT( unlinkFeature() ) );
132  connect( mFeatureSelectionMgr, SIGNAL( selectionChanged( QgsFeatureIds, QgsFeatureIds, bool ) ), this, SLOT( updateButtons() ) );
133 
134  // Set initial state for add/remove etc. buttons
135  updateButtons();
136 }
137 
139 {
140  if ( mRelation.isValid() )
141  {
142  disconnect( mRelation.referencingLayer(), SIGNAL( editingStarted() ), this, SLOT( updateButtons() ) );
143  disconnect( mRelation.referencingLayer(), SIGNAL( editingStopped() ), this, SLOT( updateButtons() ) );
144  }
145 
146  mRelation = relation;
147  mFeature = feature;
148 
149  connect( mRelation.referencingLayer(), SIGNAL( editingStarted() ), this, SLOT( updateButtons() ) );
150  connect( mRelation.referencingLayer(), SIGNAL( editingStopped() ), this, SLOT( updateButtons() ) );
151 
152  setTitle( relation.name() );
153 
154  QgsVectorLayer* lyr = relation.referencingLayer();
155 
156  bool canChangeAttributes = lyr->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues;
157  if ( canChangeAttributes && !lyr->isReadOnly() )
158  {
159  mToggleEditingButton->setEnabled( true );
160  updateButtons();
161  }
162  else
163  {
164  mToggleEditingButton->setEnabled( false );
165  }
166 
167  setObjectName( mRelation.name() );
168  loadState();
169 
170  // If not yet initialized, it is not (yet) visible, so we don't load it to be faster (lazy loading)
171  // If it is already initialized, it has been set visible before and the currently shown feature is changing
172  // and the widget needs updating
173 
174  if ( mVisible )
175  {
176  QgsFeatureRequest myRequest = mRelation.getRelatedFeaturesRequest( mFeature );
177 
178  mDualView->init( mRelation.referencingLayer(), nullptr, myRequest, mEditorContext );
179  }
180 }
181 
182 void QgsRelationEditorWidget::setRelations( const QgsRelation& relation, const QgsRelation& nmrelation )
183 {
184  if ( mRelation.isValid() )
185  {
186  disconnect( mRelation.referencingLayer(), SIGNAL( editingStarted() ), this, SLOT( updateButtons() ) );
187  disconnect( mRelation.referencingLayer(), SIGNAL( editingStopped() ), this, SLOT( updateButtons() ) );
188  }
189 
190  if ( mNmRelation.isValid() )
191  {
192  disconnect( mNmRelation.referencedLayer(), SIGNAL( editingStarted() ), this, SLOT( updateButtons() ) );
193  disconnect( mNmRelation.referencedLayer(), SIGNAL( editingStopped() ), this, SLOT( updateButtons() ) );
194  }
195 
196  mRelation = relation;
197  mNmRelation = nmrelation;
198 
199  if ( !mRelation.isValid() )
200  return;
201 
202  connect( mRelation.referencingLayer(), SIGNAL( editingStarted() ), this, SLOT( updateButtons() ) );
203  connect( mRelation.referencingLayer(), SIGNAL( editingStopped() ), this, SLOT( updateButtons() ) );
204 
205  if ( mNmRelation.isValid() )
206  {
207  connect( mNmRelation.referencingLayer(), SIGNAL( editingStarted() ), this, SLOT( updateButtons() ) );
208  connect( mNmRelation.referencingLayer(), SIGNAL( editingStopped() ), this, SLOT( updateButtons() ) );
209  }
210 
211  setTitle( relation.name() );
212 
213  QgsVectorLayer* lyr = relation.referencingLayer();
214 
215  bool canChangeAttributes = lyr->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues;
216  if ( canChangeAttributes && !lyr->isReadOnly() )
217  {
218  mToggleEditingButton->setEnabled( true );
219  updateButtons();
220  }
221  else
222  {
223  mToggleEditingButton->setEnabled( false );
224  }
225 
226  setObjectName( mRelation.name() );
227  loadState();
228 
229  updateUi();
230 }
231 
233 {
234  mEditorContext = context;
235 }
236 
238 {
239  return mFeatureSelectionMgr;
240 }
241 
243 {
244  mDualView->setView( mode );
245  mViewMode = mode;
246 }
247 
248 
250 {
251  mFeature = feature;
252 
253  updateUi();
254 }
255 
256 void QgsRelationEditorWidget::updateButtons()
257 {
258  bool editable = false;
259  bool linkable = false;
260  bool selectionNotEmpty = mFeatureSelectionMgr->selectedFeatureCount();
261 
262  if ( mRelation.isValid() )
263  {
264  editable = mRelation.referencingLayer()->isEditable();
265  linkable = mRelation.referencingLayer()->isEditable();
266  }
267 
268  if ( mNmRelation.isValid() )
269  {
270  editable = mNmRelation.referencedLayer()->isEditable();
271  }
272 
273  mAddFeatureButton->setEnabled( editable );
274  mLinkFeatureButton->setEnabled( linkable );
275  mDeleteFeatureButton->setEnabled( editable && selectionNotEmpty );
276  mUnlinkFeatureButton->setEnabled( linkable && selectionNotEmpty );
277  mToggleEditingButton->setChecked( editable );
278  mSaveEditsButton->setEnabled( editable );
279 }
280 
281 void QgsRelationEditorWidget::addFeature()
282 {
283  QgsAttributeMap keyAttrs;
284 
285  const QgsVectorLayerTools* vlTools = mEditorContext.vectorLayerTools();
286 
287  if ( mNmRelation.isValid() )
288  {
289  // n:m Relation: first let the user create a new feature on the other table
290  // and autocreate a new linking feature.
291  QgsFeature f;
292  if ( vlTools->addFeature( mNmRelation.referencedLayer(), QgsAttributeMap(), QgsGeometry(), &f ) )
293  {
294  QgsFeature flink( mRelation.referencingLayer()->fields() ); // Linking feature
295 
296  flink.setAttribute( mRelation.fieldPairs().at( 0 ).first, mFeature.attribute( mRelation.fieldPairs().at( 0 ).second ) );
297  flink.setAttribute( mNmRelation.referencingFields().at( 0 ), f.attribute( mNmRelation.referencedFields().at( 0 ) ) );
298 
299  mRelation.referencingLayer()->addFeature( flink );
300 
301  updateUi();
302  }
303  }
304  else
305  {
306  QgsFields fields = mRelation.referencingLayer()->fields();
307 
308  Q_FOREACH ( const QgsRelation::FieldPair& fieldPair, mRelation.fieldPairs() )
309  {
310  keyAttrs.insert( fields.indexFromName( fieldPair.referencingField() ), mFeature.attribute( fieldPair.referencedField() ) );
311  }
312 
313  vlTools->addFeature( mDualView->masterModel()->layer(), keyAttrs );
314  }
315 }
316 
317 void QgsRelationEditorWidget::linkFeature()
318 {
319  QgsVectorLayer* layer;
320 
321  if ( mNmRelation.isValid() )
322  layer = mNmRelation.referencedLayer();
323  else
324  layer = mRelation.referencingLayer();
325 
326  QgsFeatureSelectionDlg selectionDlg( layer, mEditorContext , this );
327 
328  if ( selectionDlg.exec() )
329  {
330  if ( mNmRelation.isValid() )
331  {
332  QgsFeatureIterator it = mNmRelation.referencedLayer()->getFeatures(
334  .setFilterFids( selectionDlg.selectedFeatures() )
335  .setSubsetOfAttributes( mNmRelation.referencedFields() ) );
336 
337  QgsFeature relatedFeature;
338 
339  QgsFeatureList newFeatures;
340  QgsFeature linkFeature( mRelation.referencingLayer()->fields() );
341 
342  Q_FOREACH ( const QgsRelation::FieldPair& fieldPair, mRelation.fieldPairs() )
343  {
344  linkFeature.setAttribute( fieldPair.first, mFeature.attribute( fieldPair.second ) );
345  }
346 
347  while ( it.nextFeature( relatedFeature ) )
348  {
349  Q_FOREACH ( const QgsRelation::FieldPair& fieldPair, mNmRelation.fieldPairs() )
350  {
351  linkFeature.setAttribute( fieldPair.first, relatedFeature.attribute( fieldPair.second ) );
352  }
353 
354  newFeatures << linkFeature;
355  }
356 
357  mRelation.referencingLayer()->addFeatures( newFeatures );
358 
359  updateUi();
360  }
361  else
362  {
363  QMap<int, QVariant> keys;
364  Q_FOREACH ( const QgsRelation::FieldPair& fieldPair, mRelation.fieldPairs() )
365  {
366  int idx = mRelation.referencingLayer()->fieldNameIndex( fieldPair.referencingField() );
367  QVariant val = mFeature.attribute( fieldPair.referencedField() );
368  keys.insert( idx, val );
369  }
370 
371  Q_FOREACH ( QgsFeatureId fid, selectionDlg.selectedFeatures() )
372  {
373  QMapIterator<int, QVariant> it( keys );
374  while ( it.hasNext() )
375  {
376  it.next();
377  mRelation.referencingLayer()->changeAttributeValue( fid, it.key(), it.value() );
378  }
379  }
380  }
381  }
382 }
383 
384 void QgsRelationEditorWidget::deleteFeature()
385 {
386  QgsVectorLayer* layer;
387 
388  if ( mNmRelation.isValid() )
389  // So far we expect the database to take care of cleaning up the linking table or restricting
390  // TODO: add more options for the behavior here
391  layer = mNmRelation.referencedLayer();
392  else
393  layer = mRelation.referencingLayer();
394  QgsDebugMsg( QString( "Delete %1" ).arg( mFeatureSelectionMgr->selectedFeaturesIds().size() ) );
395  layer->deleteFeatures( mFeatureSelectionMgr->selectedFeaturesIds() );
396 }
397 
398 void QgsRelationEditorWidget::unlinkFeature()
399 {
400  if ( mNmRelation.isValid() )
401  {
402  QgsFeatureIterator selectedIterator = mNmRelation.referencedLayer()->getFeatures(
404  .setFilterFids( mFeatureSelectionMgr->selectedFeaturesIds() )
405  .setSubsetOfAttributes( mNmRelation.referencedFields() ) );
406 
407  QgsFeature f;
408 
409  QStringList filters;
410 
411  while ( selectedIterator.nextFeature( f ) )
412  {
413  filters << '(' + mNmRelation.getRelatedFeaturesRequest( f ).filterExpression()->expression() + ')';
414  }
415 
416  QString filter = QString( "(%1) AND (%2)" ).arg(
417  mRelation.getRelatedFeaturesRequest( mFeature ).filterExpression()->expression(),
418  filters.join( " OR " ) );
419 
420  QgsFeatureIterator linkedIterator = mRelation.referencingLayer()->getFeatures( QgsFeatureRequest()
421  .setSubsetOfAttributes( QgsAttributeList() )
422  .setFilterExpression( filter ) );
423 
424  QgsFeatureIds fids;
425 
426  while ( linkedIterator.nextFeature( f ) )
427  fids << f.id();
428 
429  mRelation.referencingLayer()->deleteFeatures( fids );
430 
431  updateUi();
432  }
433  else
434  {
435  QMap<int, QgsField> keyFields;
436  Q_FOREACH ( const QgsRelation::FieldPair& fieldPair, mRelation.fieldPairs() )
437  {
438  int idx = mRelation.referencingLayer()->fieldNameIndex( fieldPair.referencingField() );
439  if ( idx < 0 )
440  {
441  QgsDebugMsg( QString( "referencing field %1 not found" ).arg( fieldPair.referencingField() ) );
442  return;
443  }
444  QgsField fld = mRelation.referencingLayer()->fields().at( idx );
445  keyFields.insert( idx, fld );
446  }
447 
448  Q_FOREACH ( QgsFeatureId fid, mFeatureSelectionMgr->selectedFeaturesIds() )
449  {
450  QMapIterator<int, QgsField> it( keyFields );
451  while ( it.hasNext() )
452  {
453  it.next();
454  mRelation.referencingLayer()->changeAttributeValue( fid, it.key(), QVariant( it.value().type() ) );
455  }
456  }
457  }
458 }
459 
460 void QgsRelationEditorWidget::toggleEditing( bool state )
461 {
462  if ( state )
463  {
464  mEditorContext.vectorLayerTools()->startEditing( mRelation.referencingLayer() );
465  if ( mNmRelation.isValid() )
466  mEditorContext.vectorLayerTools()->startEditing( mNmRelation.referencedLayer() );
467  }
468  else
469  {
470  mEditorContext.vectorLayerTools()->stopEditing( mRelation.referencingLayer() );
471  if ( mNmRelation.isValid() )
472  mEditorContext.vectorLayerTools()->stopEditing( mNmRelation.referencedLayer() );
473  }
474 }
475 
476 void QgsRelationEditorWidget::saveEdits()
477 {
478  mEditorContext.vectorLayerTools()->saveEdits( mRelation.referencingLayer() );
479  if ( mNmRelation.isValid() )
480  mEditorContext.vectorLayerTools()->saveEdits( mNmRelation.referencedLayer() );
481 }
482 
483 void QgsRelationEditorWidget::onCollapsedStateChanged( bool collapsed )
484 {
485 
486  if ( !collapsed )
487  {
488  mVisible = true;
489  updateUi();
490  }
491 }
492 
493 void QgsRelationEditorWidget::updateUi()
494 {
495  // If not yet initialized, it is not (yet) visible, so we don't load it to be faster (lazy loading)
496  // If it is already initialized, it has been set visible before and the currently shown feature is changing
497  // and the widget needs updating
498 
499  if ( mVisible )
500  {
501  QgsFeatureRequest myRequest = mRelation.getRelatedFeaturesRequest( mFeature );
502 
503  if ( mNmRelation.isValid() )
504  {
505  QgsFeatureIterator it = mRelation.referencingLayer()->getFeatures( myRequest );
506 
507  QgsFeature fet;
508 
509  QStringList filters;
510 
511  while ( it.nextFeature( fet ) )
512  {
513  QString filter = mNmRelation.getReferencedFeatureRequest( fet ).filterExpression()->expression();
514  filters << filter.prepend( '(' ).append( ')' );
515  }
516 
517  QgsFeatureRequest nmRequest;
518 
519  nmRequest.setFilterExpression( filters.join( " OR " ) );
520 
521  mDualView->init( mNmRelation.referencedLayer(), nullptr, nmRequest, mEditorContext );
522  }
523  else
524  {
525  mDualView->init( mRelation.referencingLayer(), nullptr, myRequest, mEditorContext );
526  }
527  }
528 }
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:65
Methods in this class are used to handle basic operations on vector layers.
Wrapper for iterator of features from vector data provider or vector layer.
bool isValid() const
Returns the validity of this relation.
Allows modification of attribute values.
virtual bool saveEdits(QgsVectorLayer *layer) const =0
Should be called, when the features should be commited but the editing session is not ended...
QString & append(QChar ch)
void setContentsMargins(int left, int top, int right, int bottom)
QString referencedField() const
Get the name of the referenced field.
Definition: qgsrelation.h:52
virtual bool startEditing(QgsVectorLayer *layer) const =0
This will be called, whenever a vector layer should be switched to edit mode.
QMap< int, QVariant > QgsAttributeMap
Definition: qgsfeature.h:104
void setFeatureSelectionManager(QgsIFeatureSelectionManager *featureSelectionManager)
void addWidget(QWidget *widget, int row, int column, QFlags< Qt::AlignmentFlag > alignment)
A groupbox that collapses/expands when toggled and can save its collapsed and checked states...
void addButton(QAbstractButton *button)
virtual int selectedFeatureCount() override
The number of features that are selected in this layer.
void clicked(bool checked)
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
QgsFields fields() const
Returns the list of fields of this layer.
This class contains context information for attribute editor widgets.
int size() const
QString & prepend(QChar ch)
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
const T & at(int i) const
ViewMode
The view modes, in which this widget can present information.
Definition: qgsdualview.h:53
void collapsedStateChanged(bool collapsed)
Signal emitted when groupbox collapsed/expanded state is changed, and when first shown.
bool deleteFeatures(const QgsFeatureIds &fids)
Deletes a set of features from the layer (but does not commit it)
QgsVectorLayer * referencedLayer() const
Access the referenced (parent) layer.
Container of fields for a vector layer.
Definition: qgsfield.h:187
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:76
bool setAttribute(int field, const QVariant &attr)
Set an attribute's value by field index.
Definition: qgsfeature.cpp:222
virtual bool stopEditing(QgsVectorLayer *layer, bool allowCancel=true) const =0
Will be called, when an editing session is ended and the features should be commited.
bool addFeature(QgsFeature &f, bool alsoUpdateExtent=true)
Adds a feature.
QString join(const QString &separator) const
virtual const QgsFeatureIds & selectedFeaturesIds() const override
Return reference to identifiers of selected features.
QString name() const
Returns a human readable name for this relation.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
QgsAttributeList referencedFields() const
Returns a list of attributes used to form the referenced fields (most likely primary key) on the refe...
void setViewMode(QgsDualView::ViewMode mode)
Define the view mode for the dual view.
QgsFeatureRequest getReferencedFeatureRequest(const QgsAttributes &attributes) const
Creates a request to return the feature on the referenced (parent) layer which is referenced by the p...
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
virtual bool isEditable() const override
Returns true if the provider is in editing mode.
void setIcon(const QIcon &icon)
QString tr(const char *sourceText, const char *disambiguation, int n)
void setView(ViewMode view)
Change the current view mode.
Show a list of the features, where one can be chosen and the according attribute dialog will be prese...
Definition: qgsdualview.h:64
void setEnabled(bool)
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
Defines a relation between matching fields of the two involved tables of a relation.
Definition: qgsrelation.h:38
void setLayout(QLayout *layout)
Shows the features and attributes in a table layout.
Definition: qgsdualview.h:58
QString referencingField() const
Get the name of the referencing field.
Definition: qgsrelation.h:50
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
QgsVectorLayer * referencingLayer() const
Access the referencing (child) layer This is the layer which has the field(s) which point to another ...
virtual void addItem(QLayoutItem *item)
void setObjectName(const QString &name)
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QList< int > QgsAttributeList
void init(QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const QgsFeatureRequest &request=QgsFeatureRequest(), const QgsAttributeEditorContext &context=QgsAttributeEditorContext())
Has to be called to initialize the dual view.
Definition: qgsdualview.cpp:64
QgsRelationEditorWidget(QWidget *parent=nullptr)
void setCheckable(bool)
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:44
QgsFeatureRequest getRelatedFeaturesRequest(const QgsFeature &feature) const
Creates a request to return all the features on the referencing (child) layer which have a foreign ke...
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:385
bool addFeatures(QgsFeatureList features, bool makeSelected=true)
Insert a copy of the given features into the layer (but does not commit it)
Q_DECL_DEPRECATED bool changeAttributeValue(QgsFeatureId fid, int field, const QVariant &value, bool emitSignal)
Changes an attribute value (but does not commit it)
int indexFromName(const QString &name) const
Look up field's index from name. Returns -1 on error.
Definition: qgsfield.cpp:424
QgsAttributeList referencingFields() const
Returns a list of attributes used to form the referencing fields (foreign key) on the referencing lay...
This selection manager synchronizes a local set of selected features with an attribute table...
QgsAttributeTableModel * masterModel() const
Returns the model which has the information about all features (not only filtered) ...
Definition: qgsdualview.h:138
void setRelations(const QgsRelation &relation, const QgsRelation &nmrelation)
Set the relation(s) for this widget If only one relation is set, it will act as a simple 1:N relation...
void setChecked(bool)
void setRelationFeature(const QgsRelation &relation, const QgsFeature &feature)
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:271
QgsIFeatureSelectionManager * featureSelectionManager()
The feature selection manager is responsible for the selected features which are currently being edit...
void setTitle(const QString &title)
QgsVectorLayer * layer() const
Returns the layer this model uses as backend.
void setEditorContext(const QgsAttributeEditorContext &context)
const QgsVectorLayerTools * vectorLayerTools() const
virtual bool addFeature(QgsVectorLayer *layer, const QgsAttributeMap &defaultValues=QgsAttributeMap(), const QgsGeometry &defaultGeometry=QgsGeometry(), QgsFeature *feature=nullptr) const =0
This method should/will be called, whenever a new feature will be added to the layer.
void loadState()
Will load the collapsed and checked state.
QList< FieldPair > fieldPairs() const
Returns the field pairs which form this relation The first element of each pair are the field names f...
qint64 QgsFeatureId
Definition: qgsfeature.h:31
void setText(const QString &text)
QString expression() const
Return the original, unmodified expression string.
iterator insert(const Key &key, const T &value)
QFuture< void > filter(Sequence &sequence, FilterFunction filterFunction)
void setToolTip(const QString &)
QgsVectorDataProvider * dataProvider()
Returns the data provider.
bool nextFeature(QgsFeature &f)
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Is an interface class to abstract feature selection handling.
Represents a vector layer which manages a vector based data sets.
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
void setFeature(const QgsFeature &feature)
This widget is used to show the attributes of a set of features of a QgsVectorLayer.
Definition: qgsdualview.h:41
void addLayout(QLayout *layout, int stretch)
QgsExpression * filterExpression() const
Returns the filter expression if set.