QGIS API Documentation  2.14.11-Essen
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 }
Methods in this class are used to handle basic operations on vector layers.
const QgsVectorLayerTools * vectorLayerTools() const
Wrapper for iterator of features from vector data provider or vector layer.
QgsVectorLayer * layer() const
Returns the layer this model uses as backend.
bool isValid() const
Returns the validity of this relation.
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)
bool collapsed
The collapsed state of this group box.
QgsAttributeList referencingFields() const
Returns a list of attributes used to form the referencing fields (foreign key) on the referencing lay...
virtual bool startEditing(QgsVectorLayer *layer) const =0
This will be called, whenever a vector layer should be switched to edit mode.
QgsAttributeTableModel * masterModel() const
Returns the model which has the information about all features (not only filtered) ...
Definition: qgsdualview.h:138
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
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)
int exec()
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&#39;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.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
void setViewMode(QgsDualView::ViewMode mode)
Define the view mode for the dual view.
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.
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:385
const QgsFeatureIds & selectedFeatures()
Get the selected features.
QgsFields fields() const
Returns the list of fields of this layer.
QgsExpression * filterExpression() const
Returns the filter expression if set.
Show a list of the features, where one can be chosen and the according attribute dialog will be prese...
Definition: qgsdualview.h:64
QgsAttributeList referencedFields() const
Returns a list of attributes used to form the referenced fields (most likely primary key) on the refe...
void setEnabled(bool)
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
QgsFeatureRequest getReferencedFeatureRequest(const QgsAttributes &attributes) const
Creates a request to return the feature on the referenced (parent) layer which is referenced by the p...
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
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 Key & key() const
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
const T & value() const
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)
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:65
QList< FieldPair > fieldPairs() const
Returns the field pairs which form this relation The first element of each pair are the field names f...
QgsVectorLayer * referencedLayer() const
Access the referenced (parent) layer.
QString expression() const
Return the original, unmodified expression string.
This selection manager synchronizes a local set of selected features with an attribute table...
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)
QgsVectorLayer * referencingLayer() const
Access the referencing (child) layer This is the layer which has the field(s) which point to another ...
int indexFromName(const QString &name) const
Look up field&#39;s index from name. Returns -1 on error.
Definition: qgsfield.cpp:424
QgsIFeatureSelectionManager * featureSelectionManager()
The feature selection manager is responsible for the selected features which are currently being edit...
void setTitle(const QString &title)
void setEditorContext(const QgsAttributeEditorContext &context)
QString referencedField() const
Get the name of the referenced field.
Definition: qgsrelation.h:52
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.
qint64 QgsFeatureId
Definition: qgsfeature.h:31
void setText(const QString &text)
iterator insert(const Key &key, const T &value)
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.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:271
QString referencingField() const
Get the name of the referencing field.
Definition: qgsrelation.h:50
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
Allows modification of attribute values.
void setFeature(const QgsFeature &feature)
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
QString name() const
Returns a human readable name for this relation.
This widget is used to show the attributes of a set of features of a QgsVectorLayer.
Definition: qgsdualview.h:41
bool hasNext() const
void addLayout(QLayout *layout, int stretch)