QGIS API Documentation  3.2.0-Bonn (bc43194)
qgsrelationreferencewidgetwrapper.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrelationreferencewidgetwrapper.cpp
3  --------------------------------------
4  Date : 20.4.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 
16 
18 #include "qgsproject.h"
19 #include "qgsrelationmanager.h"
21 
22 QgsRelationReferenceWidgetWrapper::QgsRelationReferenceWidgetWrapper( QgsVectorLayer *vl, int fieldIdx, QWidget *editor, QgsMapCanvas *canvas, QgsMessageBar *messageBar, QWidget *parent )
23  : QgsEditorWidgetWrapper( vl, fieldIdx, editor, parent )
24  , mCanvas( canvas )
25  , mMessageBar( messageBar )
26  , mIndeterminateState( false )
27 {
28 }
29 
31 {
33  return w;
34 }
35 
37 {
38  QgsRelationReferenceWidget *w = qobject_cast<QgsRelationReferenceWidget *>( editor );
39  if ( !w )
40  {
41  w = new QgsRelationReferenceWidget( editor );
42  }
43 
44  mWidget = w;
45 
46  const QgsAttributeEditorContext *ctx = &context();
47 
48  mWidget->setEditorContext( *ctx, mCanvas, mMessageBar );
49 
50  bool showForm = config( QStringLiteral( "ShowForm" ), false ).toBool();
51  bool mapIdent = config( QStringLiteral( "MapIdentification" ), false ).toBool();
52  bool readOnlyWidget = config( QStringLiteral( "ReadOnly" ), false ).toBool();
53  bool orderByValue = config( QStringLiteral( "OrderByValue" ), false ).toBool();
54  bool showOpenFormButton = config( QStringLiteral( "ShowOpenFormButton" ), true ).toBool();
55 
56  mWidget->setEmbedForm( showForm );
57  mWidget->setReadOnlySelector( readOnlyWidget );
58  mWidget->setAllowMapIdentification( mapIdent );
59  mWidget->setOrderByValue( orderByValue );
60  mWidget->setOpenFormButtonVisible( showOpenFormButton );
61  if ( config( QStringLiteral( "FilterFields" ), QVariant() ).isValid() )
62  {
63  mWidget->setFilterFields( config( QStringLiteral( "FilterFields" ) ).toStringList() );
64  mWidget->setChainFilters( config( QStringLiteral( "ChainFilters" ) ).toBool() );
65  }
66  mWidget->setAllowAddFeatures( config( QStringLiteral( "AllowAddFeatures" ), false ).toBool() );
67 
68  const QVariant relationName = config( QStringLiteral( "Relation" ) );
69 
70  QgsRelation relation; // invalid relation by default
71  if ( relationName.isValid() )
72  relation = QgsProject::instance()->relationManager()->relation( relationName.toString() );
73  else if ( ! layer()->referencingRelations( fieldIdx() ).isEmpty() )
74  relation = layer()->referencingRelations( fieldIdx() )[0];
75 
76  // If this widget is already embedded by the same relation, reduce functionality
77  do
78  {
79  if ( ctx->relation().id() == relation.id() )
80  {
81  mWidget->setEmbedForm( false );
82  mWidget->setReadOnlySelector( true );
83  mWidget->setAllowMapIdentification( false );
84  mWidget->setOpenFormButtonVisible( false );
85  break;
86  }
87  ctx = ctx->parentContext();
88  }
89  while ( ctx );
90 
91  mWidget->setRelation( relation, config( QStringLiteral( "AllowNULL" ) ).toBool() );
92 
93  connect( mWidget, &QgsRelationReferenceWidget::foreignKeyChanged, this, &QgsRelationReferenceWidgetWrapper::foreignKeyChanged );
94 }
95 
97 {
98  if ( !mWidget )
99  return QVariant( field().type() );
100 
101  QVariant v = mWidget->foreignKey();
102 
103  if ( v.isNull() )
104  {
105  return QVariant( field().type() );
106  }
107  else
108  {
109  return v;
110  }
111 }
112 
114 {
115  return mWidget;
116 }
117 
119 {
120  if ( mWidget )
121  {
122  mWidget->showIndeterminateState();
123  }
124  mIndeterminateState = true;
125 }
126 
128 {
129  if ( !mWidget || ( !mIndeterminateState && val == value() && val.isNull() == value().isNull() ) )
130  return;
131 
132  mIndeterminateState = false;
133  mWidget->setForeignKey( val );
134 }
135 
137 {
138  if ( !mWidget )
139  return;
140 
141  mWidget->setRelationEditable( enabled );
142 }
143 
144 void QgsRelationReferenceWidgetWrapper::foreignKeyChanged( QVariant value )
145 {
146  if ( !value.isValid() || value.isNull() )
147  {
148  value = QVariant( field().type() );
149  }
150  emit valueChanged( value );
151 }
152 
154 {
155  if ( mWidget )
156  {
157  if ( !constraintResultVisible() )
158  {
159  widget()->setStyleSheet( QString() );
160  }
161  else
162  {
163  switch ( constraintResult() )
164  {
166  mWidget->setStyleSheet( QString() );
167  break;
168 
170  mWidget->setStyleSheet( QStringLiteral( ".QComboBox { background-color: #dd7777; }" ) );
171  break;
172 
174  mWidget->setStyleSheet( QStringLiteral( ".QComboBox { background-color: #ffd85d; }" ) );
175  break;
176  }
177  }
178  }
179 }
void setEditorContext(const QgsAttributeEditorContext &context, QgsMapCanvas *canvas, QgsMessageBar *messageBar)
QVariant foreignKey() const
returns the related feature foreign key
Widget failed at least one soft (non-enforced) constraint.
QgsField field() const
Access the field.
void setFilterFields(const QStringList &filterFields)
Sets the fields for which filter comboboxes will be created.
void foreignKeyChanged(const QVariant &)
This class contains context information for attribute editor widgets.
Manages an editor widget Widget and wrapper share the same parent.
void setOpenFormButtonVisible(bool openFormButtonVisible)
QString id
Definition: qgsrelation.h:42
A bar for displaying non-blocking messages to the user.
Definition: qgsmessagebar.h:45
Widget failed at least one hard (enforced) constraint.
QVariantMap config() const
Returns the whole config.
bool constraintResultVisible() const
Returns whether the constraint result is visible.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:74
void setAllowMapIdentification(bool allowMapIdentification)
void showIndeterminateState() override
Sets the widget to display in an indeterminate "mixed value" state.
void setForeignKey(const QVariant &value)
this sets the related feature using from the foreign key
void setOrderByValue(bool orderByValue)
Sets if the widget will order the combobox entries by value.
QVariant value() const override
Will be used to access the widget&#39;s value.
QList< QgsRelation > referencingRelations(int idx) const
Returns the layer&#39;s relations, where the foreign key is on this layer.
const QgsRelation & relation() const
Returns the attribute relation.
QgsRelationManager relationManager
Definition: qgsproject.h:95
void setRelation(const QgsRelation &relation, bool allowNullValue)
QWidget * createWidget(QWidget *parent) override
This method should create a new widget with the provided parent.
const QgsAttributeEditorContext & context() const
Returns information about the context in which this widget is shown.
const QgsAttributeEditorContext * parentContext() const
Widget passed constraints successfully.
void valueChanged(const QVariant &value)
Emit this signal, whenever the value changed.
void setAllowAddFeatures(bool allowAddFeatures)
Determines if a button for adding new features should be shown.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:391
void showIndeterminateState()
Sets the widget to display in an indeterminate "mixed value" state.
ConstraintResult constraintResult() const
Returns the constraint result, which is the current result of the constraint on the widget influencin...
QWidget * widget()
Access the widget managed by this wrapper.
int fieldIdx() const
Access the field index.
bool valid() const override
Returns true if the widget has been properly initialized.
QgsVectorLayer * layer() const
Returns the vector layer associated with the widget.
Q_INVOKABLE QgsRelation relation(const QString &id) const
Gets access to a relation by its id.
Represents a vector layer which manages a vector based data sets.
QgsRelationReferenceWidgetWrapper(QgsVectorLayer *vl, int fieldIdx, QWidget *editor, QgsMapCanvas *canvas, QgsMessageBar *messageBar, QWidget *parent=nullptr)
Constructor for QgsRelationReferenceWidgetWrapper.
void setValue(const QVariant &value) override
void setChainFilters(bool chainFilters)
Set if filters are chained.
void initWidget(QWidget *editor) override
This method should initialize the editor widget with runtime data.
void updateConstraintWidgetStatus() override
This should update the widget with a visual cue if a constraint status changed.