QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsrelationwidgetwrapper.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrelationwidgetwrapper.cpp
3  --------------------------------------
4  Date : 14.5.2014
5  Copyright : (C) 2014 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 
20 #include "qgsproject.h"
21 #include "qgsrelationmanager.h"
22 #include <QWidget>
23 
24 QgsRelationWidgetWrapper::QgsRelationWidgetWrapper( QgsVectorLayer *vl, const QgsRelation &relation, QWidget *editor, QWidget *parent )
25  : QgsWidgetWrapper( vl, editor, parent )
26  , mRelation( relation )
27 
28 {
29 }
30 
31 QWidget *QgsRelationWidgetWrapper::createWidget( QWidget *parent )
32 {
33  QgsAttributeForm *form = qobject_cast<QgsAttributeForm *>( parent );
34  if ( form )
36 
37  return new QgsRelationEditorWidget( parent );
38 }
39 
41 {
42  if ( mWidget && mRelation.isValid() )
43  mWidget->setFeature( feature );
44 }
45 
47 {
48  if ( mWidget )
49  mWidget->setVisible( visible );
50 }
51 
52 void QgsRelationWidgetWrapper::aboutToSave()
53 {
54  if ( !mRelation.isValid() || !widget() || !widget()->isVisible() || mRelation.referencingLayer() == mRelation.referencedLayer() )
55  return;
56 
57  // If the layer is already saved before, return
58  const QgsAttributeEditorContext *ctx = &context();
59  do
60  {
61  if ( ctx->relation().isValid() && ( ctx->relation().referencedLayer() == mRelation.referencingLayer()
62  || ( mNmRelation.isValid() && ctx->relation().referencedLayer() == mNmRelation.referencedLayer() ) )
63  )
64  {
65  return;
66  }
67  ctx = ctx->parentContext();
68  }
69  while ( ctx );
70 
71  // Calling isModified() will emit a beforeModifiedCheck()
72  // signal that will make the embedded form to send any
73  // outstanding widget changes to the edit buffer
74  mRelation.referencingLayer()->isModified();
75 
76  if ( mNmRelation.isValid() )
77  mNmRelation.referencedLayer()->isModified();
78 }
79 
81 {
82  return mRelation;
83 }
84 
85 void QgsRelationWidgetWrapper::widgetValueChanged( const QString &attribute, const QVariant &newValue, bool attributeChanged )
86 {
87  if ( mWidget && attributeChanged )
88  {
89  QgsFeature feature { mWidget->feature() };
90  if ( feature.attribute( attribute ) != newValue )
91  {
92  feature.setAttribute( attribute, newValue );
93  QgsAttributeEditorContext newContext { mWidget->editorContext() };
94  newContext.setParentFormFeature( feature );
95  mWidget->setEditorContext( newContext );
96  mWidget->setFeature( feature, false );
97  mWidget->parentFormValueChanged( attribute, newValue );
98  }
99  }
100 }
101 
103 {
105  return mWidget->showUnlinkButton();
107 }
108 
110 {
112  if ( mWidget )
115 }
116 
117 void QgsRelationWidgetWrapper::setShowSaveChildEditsButton( bool showSaveChildEditsButton )
118 {
120  if ( mWidget )
123 }
124 
126 {
127  if ( mWidget )
128  {
129  return mWidget->showLabel();
130  }
131  return false;
132 }
133 
135 {
136  if ( mWidget )
137  mWidget->setShowLabel( showLabel );
138 }
139 
141 {
142  QgsRelationEditorWidget *w = qobject_cast<QgsRelationEditorWidget *>( editor );
143 
144  // if the editor cannot be cast to relation editor, insert a new one
145  if ( !w )
146  {
147  w = new QgsRelationEditorWidget( editor );
148  w->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
149  if ( ! editor->layout() )
150  {
151  editor->setLayout( new QGridLayout() );
152  }
153  editor->layout()->addWidget( w );
154  }
155 
157 
158  // read the legacy config of force-suppress-popup to support settings made on autoconfigurated forms
159  // it will be overwritten on specific widget configuration
160  if ( config( QStringLiteral( "force-suppress-popup" ), false ).toBool() )
161  {
162  const_cast<QgsVectorLayerTools *>( myContext.vectorLayerTools() )->setForceSuppressFormPopup( true );
163  }
164 
165  /* TODO: this seems to have no effect
166  if ( config( QStringLiteral( "hide-save-child-edits" ), false ).toBool() )
167  {
168  w->setShowSaveChildEditsButton( false );
169  }
170  */
171 
172  // read the legacy config of nm-rel to support settings made on autoconfigurated forms
173  // it will be overwritten on specific widget configuration
174  mNmRelation = QgsProject::instance()->relationManager()->relation( config( QStringLiteral( "nm-rel" ) ).toString() );
175 
176  // If this widget is already embedded by the same relation, reduce functionality
177  const QgsAttributeEditorContext *ctx = &context();
178  do
179  {
180  if ( ( ctx->relation().name() == mRelation.name() && ctx->formMode() == QgsAttributeEditorContext::Embed )
181  || ( mNmRelation.isValid() && ctx->relation().name() == mNmRelation.name() ) )
182  {
183  w->setVisible( false );
184  break;
185  }
186  ctx = ctx->parentContext();
187  }
188  while ( ctx );
189 
190  w->setRelations( mRelation, mNmRelation );
191 
192  w->setEditorContext( myContext );
193 
194  mWidget = w;
195 }
196 
198 {
199  return mWidget;
200 }
201 
203 {
204  return visibleButtons().testFlag( QgsAttributeEditorRelation::Button::Link );
205 }
206 
208 {
210  if ( mWidget )
211  mWidget->setShowLinkButton( showLinkButton );
213 }
214 
216 {
217  return visibleButtons().testFlag( QgsAttributeEditorRelation::Button::SaveChildEdits );
218 }
219 
220 void QgsRelationWidgetWrapper::setVisibleButtons( const QgsAttributeEditorRelation::Buttons &buttons )
221 {
222  if ( mWidget )
223  mWidget->setVisibleButtons( buttons );
224 }
225 
226 QgsAttributeEditorRelation::Buttons QgsRelationWidgetWrapper::visibleButtons() const
227 {
228  return mWidget->visibleButtons();
229 }
230 
231 void QgsRelationWidgetWrapper::setForceSuppressFormPopup( bool forceSuppressFormPopup )
232 {
233  if ( mWidget )
234  {
236  //it's set to true if one widget is configured like this but the setting is done generally (influencing all widgets).
238  {
239  const_cast<QgsVectorLayerTools *>( mWidget->editorContext().vectorLayerTools() )->setForceSuppressFormPopup( true );
240  }
241  }
242 }
243 
245 {
246  if ( mWidget )
247  return mWidget->forceSuppressFormPopup();
248  return false;
249 }
250 
251 void QgsRelationWidgetWrapper::setNmRelationId( const QVariant &nmRelationId )
252 {
253  if ( mWidget )
254  {
255  mWidget->setNmRelationId( nmRelationId );
256 
257  mNmRelation = QgsProject::instance()->relationManager()->relation( nmRelationId.toString() );
258 
259  // If this widget is already embedded by the same relation, reduce functionality
260  const QgsAttributeEditorContext *ctx = &context();
261  do
262  {
263  if ( ( ctx->relation().name() == mRelation.name() && ctx->formMode() == QgsAttributeEditorContext::Embed )
264  || ( mNmRelation.isValid() && ctx->relation().name() == mNmRelation.name() ) )
265  {
266  mWidget->setVisible( false );
267  break;
268  }
269  ctx = ctx->parentContext();
270  }
271  while ( ctx );
272 
273  mWidget->setRelations( mRelation, mNmRelation );
274  }
275 }
276 
278 {
279  if ( mWidget )
280  return mWidget->nmRelationId();
281  return QVariant();
282 }
283 
284 
285 void QgsRelationWidgetWrapper::setLabel( const QString &label )
286 {
287  if ( mWidget )
288  mWidget->setLabel( label );
289 }
290 
292 {
293  if ( mWidget )
294  return mWidget->label();
295  return QString();
296 }
QgsProject::relationManager
QgsRelationManager * relationManager
Definition: qgsproject.h:105
QgsAttributeEditorContext::setParentFormFeature
void setParentFormFeature(const QgsFeature &feature)
Sets the feature of the currently edited parent form.
Definition: qgsattributeeditorcontext.h:258
QgsRelationEditorWidget::setForceSuppressFormPopup
void setForceSuppressFormPopup(bool forceSuppressFormPopup)
Sets force suppress form popup status with forceSuppressFormPopup configured for this widget.
Definition: qgsrelationeditorwidget.cpp:980
QgsRelationWidgetWrapper::showSaveChildEditsButton
Q_DECL_DEPRECATED bool showSaveChildEditsButton() const
Determines if the "Save child layer edits" button should be shown.
Definition: qgsrelationwidgetwrapper.cpp:215
QgsRelationEditorWidget::setFeature
void setFeature(const QgsFeature &feature, bool update=true)
Sets the feature being edited and updates the UI unless update is set to false.
Definition: qgsrelationeditorwidget.cpp:396
QgsRelationEditorWidget::parentFormValueChanged
void parentFormValueChanged(const QString &attribute, const QVariant &newValue)
Called when an attribute value in the parent widget has changed to newValue.
Definition: qgsrelationeditorwidget.cpp:1017
QgsWidgetWrapper
Manages an editor widget Widget and wrapper share the same parent.
Definition: qgswidgetwrapper.h:53
QgsRelationEditorWidget::feature
QgsFeature feature() const
Returns the widget's current feature.
Definition: qgsrelationeditorwidget.cpp:1086
QgsRelationWidgetWrapper::visibleButtons
QgsAttributeEditorRelation::Buttons visibleButtons() const
Returns the buttons which are shown.
Definition: qgsrelationwidgetwrapper.cpp:226
QgsRelationWidgetWrapper::setShowLinkButton
Q_DECL_DEPRECATED void setShowLinkButton(bool showLinkButton)
Determines if the "link feature" button should be shown.
Definition: qgsrelationwidgetwrapper.cpp:207
QgsRelation::name
QString name
Definition: qgsrelation.h:48
QgsRelationEditorWidget
Definition: qgsrelationeditorwidget.h:84
QgsVectorLayerTools
Methods in this class are used to handle basic operations on vector layers.
Definition: qgsvectorlayertools.h:40
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:468
QgsRelationManager::relation
Q_INVOKABLE QgsRelation relation(const QString &id) const
Gets access to a relation by its id.
Definition: qgsrelationmanager.cpp:96
QgsAttributeEditorContext::Embed
@ Embed
A form was embedded as a widget on another form.
Definition: qgsattributeeditorcontext.h:72
QgsRelationWidgetWrapper::setLabel
void setLabel(const QString &label=QString())
Sets label for this element If it's empty it takes the relation id as label.
Definition: qgsrelationwidgetwrapper.cpp:285
QgsWidgetWrapper::context
const QgsAttributeEditorContext & context() const
Returns information about the context in which this widget is shown.
Definition: qgswidgetwrapper.cpp:86
qgsrelationeditorwidget.h
QgsWidgetWrapper::widget
QWidget * widget()
Access the widget managed by this wrapper.
Definition: qgswidgetwrapper.cpp:46
QgsRelationWidgetWrapper::showLinkButton
Q_DECL_DEPRECATED bool showLinkButton() const
Determines if the "link feature" button should be shown.
Definition: qgsrelationwidgetwrapper.cpp:202
QgsRelationWidgetWrapper::setNmRelationId
void setNmRelationId(const QVariant &nmRelationId=QVariant())
Sets nmRelationId for the relation id of the second relation involved in an N:M relation.
Definition: qgsrelationwidgetwrapper.cpp:251
QgsRelationWidgetWrapper::forceSuppressFormPopup
bool forceSuppressFormPopup() const
Determines the force suppress form popup status that is configured for this widget.
Definition: qgsrelationwidgetwrapper.cpp:244
QgsRelationWidgetWrapper::createWidget
QWidget * createWidget(QWidget *parent) override
This method should create a new widget with the provided parent.
Definition: qgsrelationwidgetwrapper.cpp:31
QgsAttributeEditorContext::relation
const QgsRelation & relation() const
Returns the attribute relation.
Definition: qgsattributeeditorcontext.h:190
QgsRelation::referencingLayer
QgsVectorLayer * referencingLayer
Definition: qgsrelation.h:46
QgsRelationWidgetWrapper::widgetValueChanged
void widgetValueChanged(const QString &attribute, const QVariant &newValue, bool attributeChanged)
Will be called when a value in the current edited form or table row changes.
Definition: qgsrelationwidgetwrapper.cpp:85
QgsRelationWidgetWrapper::relation
QgsRelation relation() const
The relation for which this wrapper is created.
Definition: qgsrelationwidgetwrapper.cpp:80
QgsRelationWidgetWrapper::QgsRelationWidgetWrapper
QgsRelationWidgetWrapper(QgsVectorLayer *vl, const QgsRelation &relation, QWidget *editor=nullptr, QWidget *parent=nullptr)
Constructor for QgsRelationWidgetWrapper.
Definition: qgsrelationwidgetwrapper.cpp:24
Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:797
QgsRelationWidgetWrapper::initWidget
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
Definition: qgsrelationwidgetwrapper.cpp:140
QgsRelationEditorWidget::label
QString label() const
Determines the label of this element.
Definition: qgsrelationeditorwidget.cpp:1000
QgsRelationEditorWidget::visibleButtons
QgsAttributeEditorRelation::Buttons visibleButtons
Definition: qgsrelationeditorwidget.h:100
QgsRelationEditorWidget::showLabel
bool showLabel
Definition: qgsrelationeditorwidget.h:99
QgsRelation::referencedLayer
QgsVectorLayer * referencedLayer
Definition: qgsrelation.h:47
QgsRelationEditorWidget::setShowUnlinkButton
Q_DECL_DEPRECATED void setShowUnlinkButton(bool showUnlinkButton)
Determines if the "unlink feature" button should be shown.
Definition: qgsrelationeditorwidget.cpp:1012
QgsRelationEditorWidget::nmRelationId
QVariant nmRelationId() const
Determines the relation id of the second relation involved in an N:M relation.
Definition: qgsrelationeditorwidget.cpp:995
QgsRelationEditorWidget::setShowLinkButton
Q_DECL_DEPRECATED void setShowLinkButton(bool showLinkButton)
Determines if the "link feature" button should be shown.
Definition: qgsrelationeditorwidget.cpp:934
QgsRelationEditorWidget::setShowSaveChildEditsButton
Q_DECL_DEPRECATED void setShowSaveChildEditsButton(bool showChildEdits)
Determines if the "Save child layer edits" button should be shown.
Definition: qgsrelationeditorwidget.cpp:944
qgsattributeeditorcontext.h
QgsRelationWidgetWrapper::setShowUnlinkButton
Q_DECL_DEPRECATED void setShowUnlinkButton(bool showUnlinkButton)
Determines if the "unlink feature" button should be shown.
Definition: qgsrelationwidgetwrapper.cpp:109
QgsAttributeEditorContext::formMode
FormMode formMode() const
Returns the form mode.
Definition: qgsattributeeditorcontext.h:204
QgsRelationEditorWidget::setLabel
void setLabel(const QString &label=QString())
Sets label for this element If it's empty it takes the relation id as label.
Definition: qgsrelationeditorwidget.cpp:1005
qgsrelationmanager.h
QgsRelationWidgetWrapper::setFeature
void setFeature(const QgsFeature &feature) override
Definition: qgsrelationwidgetwrapper.cpp:40
QgsRelationWidgetWrapper::label
QString label() const
Determines the label of this element.
Definition: qgsrelationwidgetwrapper.cpp:291
QgsFeature::setAttribute
bool setAttribute(int field, const QVariant &attr)
Set an attribute's value by field index.
Definition: qgsfeature.cpp:213
QgsRelationEditorWidget::editorContext
QgsAttributeEditorContext editorContext() const
Returns the attribute editor context.
Definition: qgsrelationeditorwidget.cpp:380
QgsRelationWidgetWrapper::setVisibleButtons
void setVisibleButtons(const QgsAttributeEditorRelation::Buttons &buttons)
Defines the buttons which are shown.
Definition: qgsrelationwidgetwrapper.cpp:220
QgsRelationWidgetWrapper::setVisible
void setVisible(bool visible)
Sets the visibility of the wrapper's widget.
Definition: qgsrelationwidgetwrapper.cpp:46
QgsRelationEditorWidget::setRelations
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...
Definition: qgsrelationeditorwidget.cpp:297
QgsRelationEditorWidget::setShowLabel
void setShowLabel(bool showLabel)
Defines if a title label should be shown for this widget.
Definition: qgsrelationeditorwidget.cpp:1027
QgsWidgetWrapper::config
QVariantMap config() const
Returns the whole config.
Definition: qgswidgetwrapper.cpp:81
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
QgsRelation::isValid
bool isValid
Definition: qgsrelation.h:49
QgsRelationWidgetWrapper::setShowLabel
void setShowLabel(bool showLabel)
Defines if a title label should be shown for this widget.
Definition: qgsrelationwidgetwrapper.cpp:134
QgsRelationWidgetWrapper::nmRelationId
QVariant nmRelationId() const
Determines the relation id of the second relation involved in an N:M relation.
Definition: qgsrelationwidgetwrapper.cpp:277
QgsRelationWidgetWrapper::setShowSaveChildEditsButton
Q_DECL_DEPRECATED void setShowSaveChildEditsButton(bool showChildEdits)
Determines if the "Save child layer edits" button should be shown.
Definition: qgsrelationwidgetwrapper.cpp:117
QgsRelation
Definition: qgsrelation.h:42
QgsRelationWidgetWrapper::showLabel
bool showLabel() const
Defines if a title label should be shown for this widget.
Definition: qgsrelationwidgetwrapper.cpp:125
QgsRelationEditorWidget::setVisibleButtons
void setVisibleButtons(const QgsAttributeEditorRelation::Buttons &buttons)
Defines the buttons which are shown.
Definition: qgsrelationeditorwidget.cpp:954
QgsVectorLayer::isModified
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
Definition: qgsvectorlayer.cpp:3621
QgsRelationEditorWidget::setEditorContext
void setEditorContext(const QgsAttributeEditorContext &context)
Sets the editor context.
Definition: qgsrelationeditorwidget.cpp:367
QgsAttributeForm::widgetValueChanged
void widgetValueChanged(const QString &attribute, const QVariant &value, bool attributeChanged)
Notifies about changes of attributes.
QgsRelationEditorWidget::forceSuppressFormPopup
bool forceSuppressFormPopup() const
Determines the force suppress form popup status that is configured for this widget.
Definition: qgsrelationeditorwidget.cpp:985
QgsRelationEditorWidget::setNmRelationId
void setNmRelationId(const QVariant &nmRelationId=QVariant())
Sets nmRelationId for the relation id of the second relation involved in an N:M relation.
Definition: qgsrelationeditorwidget.cpp:990
QgsFeature
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:56
QgsAttributeForm
Definition: qgsattributeform.h:45
QgsRelationWidgetWrapper::setForceSuppressFormPopup
void setForceSuppressFormPopup(bool forceSuppressFormPopup)
Sets force suppress form popup status to forceSuppressFormPopup for this widget and for the vectorLay...
Definition: qgsrelationwidgetwrapper.cpp:231
QgsRelationEditorWidget::showUnlinkButton
Q_DECL_DEPRECATED bool showUnlinkButton() const
Determines if the "unlink feature" button should be shown.
Definition: qgsrelationeditorwidget.cpp:939
QgsAttributeEditorContext::parentContext
const QgsAttributeEditorContext * parentContext() const
Definition: qgsattributeeditorcontext.h:230
QgsAttributeEditorContext
This class contains context information for attribute editor widgets.
Definition: qgsattributeeditorcontext.h:41
qgsrelationwidgetwrapper.h
Q_NOWARN_DEPRECATED_PUSH
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:796
QgsAttributeEditorContext::Multiple
@ Multiple
When showing a list of features (e.g. houses as an embedded form in a district form)
Definition: qgsattributeeditorcontext.h:66
qgsproject.h
QgsAttributeEditorContext::vectorLayerTools
const QgsVectorLayerTools * vectorLayerTools() const
Returns the associated vector layer tools.
Definition: qgsattributeeditorcontext.h:172
QgsRelationWidgetWrapper::valid
bool valid() const override
Returns true if the widget has been properly initialized.
Definition: qgsrelationwidgetwrapper.cpp:197
QgsRelationWidgetWrapper::showUnlinkButton
Q_DECL_DEPRECATED bool showUnlinkButton() const
Determines if the "unlink feature" button should be shown.
Definition: qgsrelationwidgetwrapper.cpp:102