QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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 {
104  return mWidget->showUnlinkButton();
105 }
106 
108 {
109  if ( mWidget )
111 }
112 
113 
114 void QgsRelationWidgetWrapper::setShowSaveChildEditsButton( bool showSaveChildEditsButton )
115 {
116  if ( mWidget )
118 }
119 
121 {
122  if ( mWidget )
123  return mWidget->showLabel();
124  else
125  return false;
126 }
127 
129 {
130  if ( mWidget )
131  mWidget->setShowLabel( showLabel );
132 }
133 
135 {
136  QgsRelationEditorWidget *w = qobject_cast<QgsRelationEditorWidget *>( editor );
137 
138  // if the editor cannot be cast to relation editor, insert a new one
139  if ( !w )
140  {
141  w = new QgsRelationEditorWidget( editor );
142  w->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
143  if ( ! editor->layout() )
144  {
145  editor->setLayout( new QGridLayout() );
146  }
147  editor->layout()->addWidget( w );
148  }
149 
151 
152  if ( config( QStringLiteral( "force-suppress-popup" ), false ).toBool() )
153  {
154  const_cast<QgsVectorLayerTools *>( myContext.vectorLayerTools() )->setForceSuppressFormPopup( true );
155  }
156 
157  if ( config( QStringLiteral( "hide-save-child-edits" ), false ).toBool() )
158  {
159  w->setShowSaveChildEditsButton( false );
160  }
161 
162  w->setEditorContext( myContext );
163 
164  mNmRelation = QgsProject::instance()->relationManager()->relation( config( QStringLiteral( "nm-rel" ) ).toString() );
165 
166  // If this widget is already embedded by the same relation, reduce functionality
167  const QgsAttributeEditorContext *ctx = &context();
168  do
169  {
170  if ( ( ctx->relation().name() == mRelation.name() && ctx->formMode() == QgsAttributeEditorContext::Embed )
171  || ( mNmRelation.isValid() && ctx->relation().name() == mNmRelation.name() ) )
172  {
173  w->setVisible( false );
174  break;
175  }
176  ctx = ctx->parentContext();
177  }
178  while ( ctx );
179 
180  w->setRelations( mRelation, mNmRelation );
181 
182  mWidget = w;
183 }
184 
186 {
187  return mWidget;
188 }
189 
191 {
192  return mWidget->showLinkButton();
193 }
194 
196 {
197  if ( mWidget )
198  mWidget->setShowLinkButton( showLinkButton );
199 }
200 
202 {
203  return mWidget && mWidget->showSaveChildEditsButton();
204 }
QgsProject::relationManager
QgsRelationManager relationManager
Definition: qgsproject.h:103
QgsAttributeEditorContext::setParentFormFeature
void setParentFormFeature(const QgsFeature &feature)
Sets the feature of the currently edited parent form.
Definition: qgsattributeeditorcontext.h:257
QgsRelationWidgetWrapper::showSaveChildEditsButton
bool showSaveChildEditsButton() const
Determines if the "save child layer edits" button should be shown.
Definition: qgsrelationwidgetwrapper.cpp:201
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:394
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:960
QgsWidgetWrapper
Definition: qgswidgetwrapper.h:52
QgsRelationEditorWidget::feature
QgsFeature feature() const
Returns the widget's current feature.
Definition: qgsrelationeditorwidget.cpp:1021
QgsRelationWidgetWrapper::setShowLinkButton
void setShowLinkButton(bool showLinkButton)
Determines if the "link feature" button should be shown.
Definition: qgsrelationwidgetwrapper.cpp:195
QgsRelation::name
QString name
Definition: qgsrelation.h:48
QgsRelationEditorWidget::showLinkButton
bool showLinkButton() const
Determines if the "link feature" button should be shown.
Definition: qgsrelationeditorwidget.cpp:930
QgsRelationEditorWidget
Definition: qgsrelationeditorwidget.h:83
QgsVectorLayerTools
Definition: qgsvectorlayertools.h:39
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:458
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:71
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
bool showLinkButton() const
Determines if the "link feature" button should be shown.
Definition: qgsrelationwidgetwrapper.cpp:190
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:189
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
QgsRelationWidgetWrapper::initWidget
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
Definition: qgsrelationwidgetwrapper.cpp:134
QgsRelationEditorWidget::showLabel
bool showLabel
Definition: qgsrelationeditorwidget.h:99
QgsRelation::referencedLayer
QgsVectorLayer referencedLayer
Definition: qgsrelation.h:47
QgsRelationEditorWidget::setShowUnlinkButton
void setShowUnlinkButton(bool showUnlinkButton)
Determines if the "unlink feature" button should be shown.
Definition: qgsrelationeditorwidget.cpp:955
QgsRelationEditorWidget::setShowLinkButton
void setShowLinkButton(bool showLinkButton)
Determines if the "link feature" button should be shown.
Definition: qgsrelationeditorwidget.cpp:935
QgsRelationEditorWidget::setShowSaveChildEditsButton
void setShowSaveChildEditsButton(bool showChildEdits)
Determines if the "Save child layer edits" button should be shown.
Definition: qgsrelationeditorwidget.cpp:945
qgsattributeeditorcontext.h
QgsRelationWidgetWrapper::setShowUnlinkButton
void setShowUnlinkButton(bool showUnlinkButton)
Determines if the "unlink feature" button should be shown.
Definition: qgsrelationwidgetwrapper.cpp:107
QgsAttributeEditorContext::formMode
FormMode formMode() const
Returns the form mode.
Definition: qgsattributeeditorcontext.h:203
qgsrelationmanager.h
QgsRelationWidgetWrapper::setFeature
void setFeature(const QgsFeature &feature) override
Definition: qgsrelationwidgetwrapper.cpp:40
QgsRelationEditorWidget::showSaveChildEditsButton
bool showSaveChildEditsButton() const
Determines if the "Save child layer edits" button should be shown.
Definition: qgsrelationeditorwidget.cpp:950
QgsFeature::setAttribute
bool setAttribute(int field, const QVariant &attr)
Set an attribute's value by field index.
Definition: qgsfeature.cpp:211
QgsRelationEditorWidget::editorContext
QgsAttributeEditorContext editorContext() const
Returns the attribute editor context.
Definition: qgsrelationeditorwidget.cpp:378
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:301
QgsRelationEditorWidget::setShowLabel
void setShowLabel(bool showLabel)
Defines if a title label should be shown for this widget.
Definition: qgsrelationeditorwidget.cpp:970
QgsWidgetWrapper::config
QVariantMap config() const
Returns the whole config.
Definition: qgswidgetwrapper.cpp:81
QgsVectorLayer
Definition: qgsvectorlayer.h:385
QgsRelation::isValid
bool isValid
Definition: qgsrelation.h:49
QgsRelationWidgetWrapper::setShowSaveChildEditsButton
void setShowSaveChildEditsButton(bool showSaveChildEditsButton)
Determines if the "save child layer edits" button should be shown.
Definition: qgsrelationwidgetwrapper.cpp:114
QgsRelationWidgetWrapper::setShowLabel
void setShowLabel(bool showLabel)
Defines if a title label should be shown for this widget.
Definition: qgsrelationwidgetwrapper.cpp:128
QgsRelation
Definition: qgsrelation.h:41
QgsRelationWidgetWrapper::showLabel
bool showLabel() const
Defines if a title label should be shown for this widget.
Definition: qgsrelationwidgetwrapper.cpp:120
QgsVectorLayer::isModified
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
Definition: qgsvectorlayer.cpp:3613
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.
QgsFeature
Definition: qgsfeature.h:55
QgsAttributeForm
Definition: qgsattributeform.h:44
QgsRelationEditorWidget::showUnlinkButton
bool showUnlinkButton() const
Determines if the "unlink feature" button should be shown.
Definition: qgsrelationeditorwidget.cpp:940
QgsAttributeEditorContext::parentContext
const QgsAttributeEditorContext * parentContext() const
Definition: qgsattributeeditorcontext.h:229
QgsAttributeEditorContext
Definition: qgsattributeeditorcontext.h:40
qgsrelationwidgetwrapper.h
QgsAttributeEditorContext::Multiple
@ Multiple
When showing a list of features (e.g. houses as an embedded form in a district form)
Definition: qgsattributeeditorcontext.h:65
qgsproject.h
QgsAttributeEditorContext::vectorLayerTools
const QgsVectorLayerTools * vectorLayerTools() const
Returns the associated vector layer tools.
Definition: qgsattributeeditorcontext.h:171
QgsRelationWidgetWrapper::valid
bool valid() const override
Returns true if the widget has been properly initialized.
Definition: qgsrelationwidgetwrapper.cpp:185
QgsRelationWidgetWrapper::showUnlinkButton
bool showUnlinkButton() const
Determines if the "unlink feature" button should be shown.
Definition: qgsrelationwidgetwrapper.cpp:102