QGIS API Documentation  2.14.0-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  buttonLayout->addWidget( mToggleEditingButton );
51  // save Edits
52  mSaveEditsButton = new QToolButton( this );
53  mSaveEditsButton->setIcon( QgsApplication::getThemeIcon( "/mActionSaveEdits.svg" ) );
54  mSaveEditsButton->setText( tr( "Save layer edits" ) );
55  mSaveEditsButton->setEnabled( true );
56  buttonLayout->addWidget( mSaveEditsButton );
57  // add feature
58  mAddFeatureButton = new QToolButton( this );
59  mAddFeatureButton->setIcon( QgsApplication::getThemeIcon( "/mActionAdd.svg" ) );
60  mAddFeatureButton->setText( tr( "Add feature" ) );
61  mAddFeatureButton->setObjectName( "mAddFeatureButton" );
62  buttonLayout->addWidget( mAddFeatureButton );
63  // delete feature
64  mDeleteFeatureButton = new QToolButton( this );
65  mDeleteFeatureButton->setIcon( QgsApplication::getThemeIcon( "/mActionRemove.svg" ) );
66  mDeleteFeatureButton->setText( tr( "Delete feature" ) );
67  mDeleteFeatureButton->setObjectName( "mDeleteFeatureButton" );
68  buttonLayout->addWidget( mDeleteFeatureButton );
69  // link feature
70  mLinkFeatureButton = new QToolButton( this );
71  mLinkFeatureButton->setIcon( QgsApplication::getThemeIcon( "/mActionLink.svg" ) );
72  mLinkFeatureButton->setText( tr( "Link feature" ) );
73  mLinkFeatureButton->setObjectName( "mLinkFeatureButton" );
74  buttonLayout->addWidget( mLinkFeatureButton );
75  // unlink feature
76  mUnlinkFeatureButton = new QToolButton( this );
77  mUnlinkFeatureButton->setIcon( QgsApplication::getThemeIcon( "/mActionUnlink.svg" ) );
78  mUnlinkFeatureButton->setText( tr( "Unlink feature" ) );
79  mUnlinkFeatureButton->setObjectName( "mUnlinkFeatureButton" );
80  buttonLayout->addWidget( mUnlinkFeatureButton );
81  // spacer
82  buttonLayout->addItem( new QSpacerItem( 0, 0, QSizePolicy::Expanding ) );
83  // form view
84  mFormViewButton = new QToolButton( this );
85  mFormViewButton->setText( tr( "Form view" ) );
86  mFormViewButton->setIcon( QgsApplication::getThemeIcon( "/mActionPropertyItem.png" ) );
87  mFormViewButton->setCheckable( true );
88  mFormViewButton->setChecked( mViewMode == QgsDualView::AttributeEditor );
89  buttonLayout->addWidget( mFormViewButton );
90  // table view
91  mTableViewButton = new QToolButton( this );
92  mTableViewButton->setText( tr( "Table view" ) );
93  mTableViewButton->setIcon( QgsApplication::getThemeIcon( "/mActionOpenTable.svg" ) );
94  mTableViewButton->setCheckable( true );
95  mTableViewButton->setChecked( mViewMode == QgsDualView::AttributeTable );
96  buttonLayout->addWidget( mTableViewButton );
97  // button group
98  mViewModeButtonGroup = new QButtonGroup( this );
99  mViewModeButtonGroup->addButton( mFormViewButton, QgsDualView::AttributeEditor );
100  mViewModeButtonGroup->addButton( mTableViewButton, QgsDualView::AttributeTable );
101 
102  // add buttons layout
103  topLayout->addLayout( buttonLayout );
104 
105  mRelationLayout = new QGridLayout();
106  mRelationLayout->setContentsMargins( 0, 0, 0, 0 );
107  topLayout->addLayout( mRelationLayout );
108 
109  mDualView = new QgsDualView( this );
110  mDualView->setView( mViewMode );
111  mFeatureSelectionMgr = new QgsGenericFeatureSelectionManager( mDualView );
112  mDualView->setFeatureSelectionManager( mFeatureSelectionMgr );
113 
114  mRelationLayout->addWidget( mDualView );
115 
116  connect( this, SIGNAL( collapsedStateChanged( bool ) ), this, SLOT( onCollapsedStateChanged( bool ) ) );
117  connect( mViewModeButtonGroup, SIGNAL( buttonClicked( int ) ), this, SLOT( setViewMode( int ) ) );
118  connect( mToggleEditingButton, SIGNAL( clicked( bool ) ), this, SLOT( toggleEditing( bool ) ) );
119  connect( mSaveEditsButton, SIGNAL( clicked() ), this, SLOT( saveEdits() ) );
120  connect( mAddFeatureButton, SIGNAL( clicked() ), this, SLOT( addFeature() ) );
121  connect( mDeleteFeatureButton, SIGNAL( clicked() ), this, SLOT( deleteFeature() ) );
122  connect( mLinkFeatureButton, SIGNAL( clicked() ), this, SLOT( linkFeature() ) );
123  connect( mUnlinkFeatureButton, SIGNAL( clicked() ), this, SLOT( unlinkFeature() ) );
124  connect( mFeatureSelectionMgr, SIGNAL( selectionChanged( QgsFeatureIds, QgsFeatureIds, bool ) ), this, SLOT( updateButtons() ) );
125 
126  // Set initial state for add/remove etc. buttons
127  updateButtons();
128 }
129 
131 {
132  if ( mRelation.isValid() )
133  {
134  disconnect( mRelation.referencingLayer(), SIGNAL( editingStarted() ), this, SLOT( updateButtons() ) );
135  disconnect( mRelation.referencingLayer(), SIGNAL( editingStopped() ), this, SLOT( updateButtons() ) );
136  }
137 
138  mRelation = relation;
139  mFeature = feature;
140 
141  connect( mRelation.referencingLayer(), SIGNAL( editingStarted() ), this, SLOT( updateButtons() ) );
142  connect( mRelation.referencingLayer(), SIGNAL( editingStopped() ), this, SLOT( updateButtons() ) );
143 
144  setTitle( relation.name() );
145 
146  QgsVectorLayer* lyr = relation.referencingLayer();
147 
148  bool canChangeAttributes = lyr->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues;
149  if ( canChangeAttributes && !lyr->isReadOnly() )
150  {
151  mToggleEditingButton->setEnabled( true );
152  updateButtons();
153  }
154  else
155  {
156  mToggleEditingButton->setEnabled( false );
157  }
158 
159  setObjectName( mRelation.name() );
160  loadState();
161 
162  // If not yet initialized, it is not (yet) visible, so we don't load it to be faster (lazy loading)
163  // If it is already initialized, it has been set visible before and the currently shown feature is changing
164  // and the widget needs updating
165 
166  if ( mVisible )
167  {
168  QgsFeatureRequest myRequest = mRelation.getRelatedFeaturesRequest( mFeature );
169 
170  mDualView->init( mRelation.referencingLayer(), nullptr, myRequest, mEditorContext );
171  }
172 }
173 
174 void QgsRelationEditorWidget::setRelations( const QgsRelation& relation, const QgsRelation& nmrelation )
175 {
176  if ( mRelation.isValid() )
177  {
178  disconnect( mRelation.referencingLayer(), SIGNAL( editingStarted() ), this, SLOT( updateButtons() ) );
179  disconnect( mRelation.referencingLayer(), SIGNAL( editingStopped() ), this, SLOT( updateButtons() ) );
180  }
181 
182  if ( mNmRelation.isValid() )
183  {
184  disconnect( mNmRelation.referencedLayer(), SIGNAL( editingStarted() ), this, SLOT( updateButtons() ) );
185  disconnect( mNmRelation.referencedLayer(), SIGNAL( editingStopped() ), this, SLOT( updateButtons() ) );
186  }
187 
188  mRelation = relation;
189  mNmRelation = nmrelation;
190 
191  if ( !mRelation.isValid() )
192  return;
193 
194  connect( mRelation.referencingLayer(), SIGNAL( editingStarted() ), this, SLOT( updateButtons() ) );
195  connect( mRelation.referencingLayer(), SIGNAL( editingStopped() ), this, SLOT( updateButtons() ) );
196 
197  if ( mNmRelation.isValid() )
198  {
199  connect( mNmRelation.referencingLayer(), SIGNAL( editingStarted() ), this, SLOT( updateButtons() ) );
200  connect( mNmRelation.referencingLayer(), SIGNAL( editingStopped() ), this, SLOT( updateButtons() ) );
201  }
202 
203  setTitle( relation.name() );
204 
205  QgsVectorLayer* lyr = relation.referencingLayer();
206 
207  bool canChangeAttributes = lyr->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues;
208  if ( canChangeAttributes && !lyr->isReadOnly() )
209  {
210  mToggleEditingButton->setEnabled( true );
211  updateButtons();
212  }
213  else
214  {
215  mToggleEditingButton->setEnabled( false );
216  }
217 
218  setObjectName( mRelation.name() );
219  loadState();
220 
221  updateUi();
222 }
223 
225 {
226  mEditorContext = context;
227 }
228 
230 {
231  return mFeatureSelectionMgr;
232 }
233 
235 {
236  mDualView->setView( mode );
237  mViewMode = mode;
238 }
239 
240 
242 {
243  mFeature = feature;
244 
245  updateUi();
246 }
247 
248 void QgsRelationEditorWidget::updateButtons()
249 {
250  bool editable = false;
251  bool linkable = false;
252  bool selectionNotEmpty = mFeatureSelectionMgr->selectedFeatureCount();
253 
254  if ( mRelation.isValid() )
255  {
256  editable = mRelation.referencingLayer()->isEditable();
257  linkable = mRelation.referencingLayer()->isEditable();
258  }
259 
260  if ( mNmRelation.isValid() )
261  {
262  editable = mNmRelation.referencedLayer()->isEditable();
263  }
264 
265  mAddFeatureButton->setEnabled( editable );
266  mLinkFeatureButton->setEnabled( linkable );
267  mDeleteFeatureButton->setEnabled( editable && selectionNotEmpty );
268  mUnlinkFeatureButton->setEnabled( linkable && selectionNotEmpty );
269  mToggleEditingButton->setChecked( editable );
270  mSaveEditsButton->setEnabled( editable );
271 }
272 
273 void QgsRelationEditorWidget::addFeature()
274 {
275  QgsAttributeMap keyAttrs;
276 
277  const QgsVectorLayerTools* vlTools = mEditorContext.vectorLayerTools();
278 
279  if ( mNmRelation.isValid() )
280  {
281  // n:m Relation: first let the user create a new feature on the other table
282  // and autocreate a new linking feature.
283  QgsFeature f;
284  if ( vlTools->addFeature( mNmRelation.referencedLayer(), QgsAttributeMap(), QgsGeometry(), &f ) )
285  {
286  QgsFeature flink( mRelation.referencingLayer()->fields() ); // Linking feature
287 
288  flink.setAttribute( mRelation.fieldPairs().at( 0 ).first, mFeature.attribute( mRelation.fieldPairs().at( 0 ).second ) );
289  flink.setAttribute( mNmRelation.referencingFields().at( 0 ), f.attribute( mNmRelation.referencedFields().at( 0 ) ) );
290 
291  mRelation.referencingLayer()->addFeature( flink );
292 
293  updateUi();
294  }
295  }
296  else
297  {
298  QgsFields fields = mRelation.referencingLayer()->fields();
299 
300  Q_FOREACH ( const QgsRelation::FieldPair& fieldPair, mRelation.fieldPairs() )
301  {
302  keyAttrs.insert( fields.indexFromName( fieldPair.referencingField() ), mFeature.attribute( fieldPair.referencedField() ) );
303  }
304 
305  vlTools->addFeature( mDualView->masterModel()->layer(), keyAttrs );
306  }
307 }
308 
309 void QgsRelationEditorWidget::linkFeature()
310 {
311  QgsVectorLayer* layer;
312 
313  if ( mNmRelation.isValid() )
314  layer = mNmRelation.referencedLayer();
315  else
316  layer = mRelation.referencingLayer();
317 
318  QgsFeatureSelectionDlg selectionDlg( layer, mEditorContext , this );
319 
320  if ( selectionDlg.exec() )
321  {
322  if ( mNmRelation.isValid() )
323  {
324  QgsFeatureIterator it = mNmRelation.referencedLayer()->getFeatures(
326  .setFilterFids( selectionDlg.selectedFeatures() )
327  .setSubsetOfAttributes( mNmRelation.referencedFields() ) );
328 
329  QgsFeature relatedFeature;
330 
331  QgsFeatureList newFeatures;
332  QgsFeature linkFeature( mRelation.referencingLayer()->fields() );
333 
334  Q_FOREACH ( const QgsRelation::FieldPair& fieldPair, mRelation.fieldPairs() )
335  {
336  linkFeature.setAttribute( fieldPair.first, mFeature.attribute( fieldPair.second ) );
337  }
338 
339  while ( it.nextFeature( relatedFeature ) )
340  {
341  Q_FOREACH ( const QgsRelation::FieldPair& fieldPair, mNmRelation.fieldPairs() )
342  {
343  linkFeature.setAttribute( fieldPair.first, relatedFeature.attribute( fieldPair.second ) );
344  }
345 
346  newFeatures << linkFeature;
347  }
348 
349  mRelation.referencingLayer()->addFeatures( newFeatures );
350 
351  updateUi();
352  }
353  else
354  {
355  QMap<int, QVariant> keys;
356  Q_FOREACH ( const QgsRelation::FieldPair& fieldPair, mRelation.fieldPairs() )
357  {
358  int idx = mRelation.referencingLayer()->fieldNameIndex( fieldPair.referencingField() );
359  QVariant val = mFeature.attribute( fieldPair.referencedField() );
360  keys.insert( idx, val );
361  }
362 
363  Q_FOREACH ( QgsFeatureId fid, selectionDlg.selectedFeatures() )
364  {
365  QMapIterator<int, QVariant> it( keys );
366  while ( it.hasNext() )
367  {
368  it.next();
369  mRelation.referencingLayer()->changeAttributeValue( fid, it.key(), it.value() );
370  }
371  }
372  }
373  }
374 }
375 
376 void QgsRelationEditorWidget::deleteFeature()
377 {
378  QgsVectorLayer* layer;
379 
380  if ( mNmRelation.isValid() )
381  // So far we expect the database to take care of cleaning up the linking table or restricting
382  // TODO: add more options for the behavior here
383  layer = mNmRelation.referencedLayer();
384  else
385  layer = mRelation.referencingLayer();
386  QgsDebugMsg( QString( "Delete %1" ).arg( mFeatureSelectionMgr->selectedFeaturesIds().size() ) );
387  layer->deleteFeatures( mFeatureSelectionMgr->selectedFeaturesIds() );
388 }
389 
390 void QgsRelationEditorWidget::unlinkFeature()
391 {
392  if ( mNmRelation.isValid() )
393  {
394  QgsFeatureIterator selectedIterator = mNmRelation.referencedLayer()->getFeatures(
396  .setFilterFids( mFeatureSelectionMgr->selectedFeaturesIds() )
397  .setSubsetOfAttributes( mNmRelation.referencedFields() ) );
398 
399  QgsFeature f;
400 
401  QStringList filters;
402 
403  while ( selectedIterator.nextFeature( f ) )
404  {
405  filters << '(' + mNmRelation.getRelatedFeaturesRequest( f ).filterExpression()->expression() + ')';
406  }
407 
408  QString filter = QString( "(%1) AND (%2)" ).arg(
409  mRelation.getRelatedFeaturesRequest( mFeature ).filterExpression()->expression(),
410  filters.join( " OR " ) );
411 
412  QgsFeatureIterator linkedIterator = mRelation.referencingLayer()->getFeatures( QgsFeatureRequest()
413  .setSubsetOfAttributes( QgsAttributeList() )
414  .setFilterExpression( filter ) );
415 
416  QgsFeatureIds fids;
417 
418  while ( linkedIterator.nextFeature( f ) )
419  fids << f.id();
420 
421  mRelation.referencingLayer()->deleteFeatures( fids );
422 
423  updateUi();
424  }
425  else
426  {
427  QMap<int, QgsField> keyFields;
428  Q_FOREACH ( const QgsRelation::FieldPair& fieldPair, mRelation.fieldPairs() )
429  {
430  int idx = mRelation.referencingLayer()->fieldNameIndex( fieldPair.referencingField() );
431  if ( idx < 0 )
432  {
433  QgsDebugMsg( QString( "referencing field %1 not found" ).arg( fieldPair.referencingField() ) );
434  return;
435  }
436  QgsField fld = mRelation.referencingLayer()->fields().at( idx );
437  keyFields.insert( idx, fld );
438  }
439 
440  Q_FOREACH ( QgsFeatureId fid, mFeatureSelectionMgr->selectedFeaturesIds() )
441  {
442  QMapIterator<int, QgsField> it( keyFields );
443  while ( it.hasNext() )
444  {
445  it.next();
446  mRelation.referencingLayer()->changeAttributeValue( fid, it.key(), QVariant( it.value().type() ) );
447  }
448  }
449  }
450 }
451 
452 void QgsRelationEditorWidget::toggleEditing( bool state )
453 {
454  if ( state )
455  {
456  mEditorContext.vectorLayerTools()->startEditing( mRelation.referencingLayer() );
457  if ( mNmRelation.isValid() )
458  mEditorContext.vectorLayerTools()->startEditing( mNmRelation.referencedLayer() );
459  }
460  else
461  {
462  mEditorContext.vectorLayerTools()->stopEditing( mRelation.referencingLayer() );
463  if ( mNmRelation.isValid() )
464  mEditorContext.vectorLayerTools()->stopEditing( mNmRelation.referencedLayer() );
465  }
466 }
467 
468 void QgsRelationEditorWidget::saveEdits()
469 {
470  mEditorContext.vectorLayerTools()->saveEdits( mRelation.referencingLayer() );
471  if ( mNmRelation.isValid() )
472  mEditorContext.vectorLayerTools()->saveEdits( mNmRelation.referencedLayer() );
473 }
474 
475 void QgsRelationEditorWidget::onCollapsedStateChanged( bool collapsed )
476 {
477 
478  if ( !collapsed )
479  {
480  mVisible = true;
481  updateUi();
482  }
483 }
484 
485 void QgsRelationEditorWidget::updateUi()
486 {
487  // If not yet initialized, it is not (yet) visible, so we don't load it to be faster (lazy loading)
488  // If it is already initialized, it has been set visible before and the currently shown feature is changing
489  // and the widget needs updating
490 
491  if ( mVisible )
492  {
493  QgsFeatureRequest myRequest = mRelation.getRelatedFeaturesRequest( mFeature );
494 
495  if ( mNmRelation.isValid() )
496  {
497  QgsFeatureIterator it = mRelation.referencingLayer()->getFeatures( myRequest );
498 
499  QgsFeature fet;
500 
501  QStringList filters;
502 
503  while ( it.nextFeature( fet ) )
504  {
505  QString filter = mNmRelation.getReferencedFeatureRequest( fet ).filterExpression()->expression();
506  filters << filter.prepend( '(' ).append( ')' );
507  }
508 
509  QgsFeatureRequest nmRequest;
510 
511  nmRequest.setFilterExpression( filters.join( " OR " ) );
512 
513  mDualView->init( mNmRelation.referencedLayer(), nullptr, nmRequest, mEditorContext );
514  }
515  else
516  {
517  mDualView->init( mRelation.referencingLayer(), nullptr, myRequest, mEditorContext );
518  }
519  }
520 }
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.
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.
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.
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.
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.
const QgsFeatureIds & selectedFeatures()
Get the selected features.
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
const Key & key() const
const T & value() const
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&#39;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)
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
Allows modification of attribute values.
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
bool hasNext() const
void addLayout(QLayout *layout, int stretch)
QgsExpression * filterExpression() const
Returns the filter expression if set.