QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
qgsrelationreferenceconfigdlg.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrelationreferenceconfigdlg.cpp
3  --------------------------------------
4  Date : 21.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 
17 
18 #include "qgseditorwidgetfactory.h"
19 #include "qgsfield.h"
20 #include "qgsproject.h"
21 #include "qgsrelationmanager.h"
22 #include "qgsvectorlayer.h"
24 
25 static QgsExpressionContext _getExpressionContext( const void* context )
26 {
27  QgsExpressionContext expContext;
30 
31  const QgsVectorLayer* layer = ( const QgsVectorLayer* ) context;
32  if ( layer )
33  expContext << QgsExpressionContextUtils::layerScope( layer );
34 
35  return expContext;
36 }
37 
39  : QgsEditorConfigWidget( vl, fieldIdx, parent )
40  , mReferencedLayer( nullptr )
41 {
42  setupUi( this );
43 
44  mExpressionWidget->registerGetExpressionContextCallback( &_getExpressionContext, vl );
45 
46  connect( mComboRelation, SIGNAL( currentIndexChanged( int ) ), this, SLOT( relationChanged( int ) ) );
47 
48  Q_FOREACH ( const QgsRelation& relation, vl->referencingRelations( fieldIdx ) )
49  {
50  if ( relation.name().isEmpty() )
51  mComboRelation->addItem( QString( "%1 (%2)" ).arg( relation.id(), relation.referencedLayerId() ), relation.id() );
52  else
53  mComboRelation->addItem( QString( "%1 (%2)" ).arg( relation.name(), relation.referencedLayerId() ), relation.id() );
54 
55  if ( relation.referencedLayer() )
56  {
57  mExpressionWidget->setField( relation.referencedLayer()->displayExpression() );
58  }
59  }
60 
61  connect( mCbxAllowNull, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
62  connect( mCbxOrderByValue, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
63  connect( mCbxShowForm, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
64  connect( mCbxMapIdentification, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
65  connect( mCbxReadOnly, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
66  connect( mComboRelation, SIGNAL( currentIndexChanged( int ) ), this, SIGNAL( changed() ) );
67  connect( mCbxAllowAddFeatures, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
68  connect( mFilterGroupBox, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
69  connect( mFilterFieldsList, SIGNAL( itemChanged( QListWidgetItem* ) ), this, SIGNAL( changed() ) );
70  connect( mCbxChainFilters, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
71  connect( mExpressionWidget, SIGNAL( fieldChanged( QString ) ), this, SIGNAL( changed() ) );
72 }
73 
75 {
76  if ( config.contains( "AllowNULL" ) )
77  {
78  mCbxAllowNull->setChecked( config.value( "AllowNULL" ).toBool() );
79  }
80 
81  if ( config.contains( "OrderByValue" ) )
82  {
83  mCbxOrderByValue->setChecked( config.value( "OrderByValue" ).toBool() );
84  }
85 
86  if ( config.contains( "ShowForm" ) )
87  {
88  mCbxShowForm->setChecked( config.value( "ShowForm" ).toBool() );
89  }
90 
91  if ( config.contains( "Relation" ) )
92  {
93  mComboRelation->setCurrentIndex( mComboRelation->findData( config.value( "Relation" ).toString() ) );
94  relationChanged( mComboRelation->currentIndex() );
95  }
96 
97  if ( config.contains( "MapIdentification" ) )
98  {
99  mCbxMapIdentification->setChecked( config.value( "MapIdentification" ).toBool() );
100  }
101 
102  if ( config.contains( "AllowAddFeatures" ) )
103  mCbxAllowAddFeatures->setChecked( config.value( "AllowAddFeatures" ).toBool() );
104 
105  if ( config.contains( "ReadOnly" ) )
106  {
107  mCbxReadOnly->setChecked( config.value( "ReadOnly" ).toBool() );
108  }
109 
110  if ( config.contains( "FilterFields" ) )
111  {
112  mFilterGroupBox->setChecked( true );
113  Q_FOREACH ( const QString& fld, config.value( "FilterFields" ).toStringList() )
114  {
115  addFilterField( fld );
116  }
117 
118  mCbxChainFilters->setChecked( config.value( "ChainFilters" ).toBool() );
119  }
120 }
121 
122 void QgsRelationReferenceConfigDlg::relationChanged( int idx )
123 {
124  QString relName = mComboRelation->itemData( idx ).toString();
126 
127  mReferencedLayer = rel.referencedLayer();
128  mExpressionWidget->setLayer( mReferencedLayer ); // set even if 0
129  if ( mReferencedLayer )
130  {
131  mExpressionWidget->setField( mReferencedLayer->displayExpression() );
132  mCbxMapIdentification->setEnabled( mReferencedLayer->hasGeometryType() );
133  }
134 
135  loadFields();
136 }
137 
138 void QgsRelationReferenceConfigDlg::on_mAddFilterButton_clicked()
139 {
140  Q_FOREACH ( QListWidgetItem* item, mAvailableFieldsList->selectedItems() )
141  {
142  addFilterField( item );
143  }
144 }
145 
146 void QgsRelationReferenceConfigDlg::on_mRemoveFilterButton_clicked()
147 {
148  Q_FOREACH ( QListWidgetItem* item , mFilterFieldsList->selectedItems() )
149  {
150  mFilterFieldsList->takeItem( indexFromListWidgetItem( item ) );
151  mAvailableFieldsList->addItem( item );
152  }
153 }
154 
156 {
157  QgsEditorWidgetConfig myConfig;
158  myConfig.insert( "AllowNULL", mCbxAllowNull->isChecked() );
159  myConfig.insert( "OrderByValue", mCbxOrderByValue->isChecked() );
160  myConfig.insert( "ShowForm", mCbxShowForm->isChecked() );
161  myConfig.insert( "MapIdentification", mCbxMapIdentification->isEnabled() && mCbxMapIdentification->isChecked() );
162  myConfig.insert( "ReadOnly", mCbxReadOnly->isChecked() );
163  myConfig.insert( "Relation", mComboRelation->itemData( mComboRelation->currentIndex() ) );
164  myConfig.insert( "AllowAddFeatures", mCbxAllowAddFeatures->isChecked() );
165 
166  if ( mFilterGroupBox->isChecked() )
167  {
168  QStringList filterFields;
169  filterFields.reserve( mFilterFieldsList->count() );
170  for ( int i = 0; i < mFilterFieldsList->count(); i++ )
171  {
172  filterFields << mFilterFieldsList->item( i )->data( Qt::UserRole ).toString();
173  }
174  myConfig.insert( "FilterFields", filterFields );
175 
176  myConfig.insert( "ChainFilters", mCbxChainFilters->isChecked() );
177  }
178 
179  if ( mReferencedLayer )
180  {
181  mReferencedLayer->setDisplayExpression( mExpressionWidget->currentField() );
182  }
183 
184  return myConfig;
185 }
186 
187 void QgsRelationReferenceConfigDlg::loadFields()
188 {
189  mAvailableFieldsList->clear();
190  mFilterFieldsList->clear();
191 
192  if ( mReferencedLayer )
193  {
194  QgsVectorLayer* l = mReferencedLayer;
195  const QgsFields& flds = l->fields();
196  for ( int i = 0; i < flds.count(); i++ )
197  {
198  mAvailableFieldsList->addItem( flds.at( i ).displayName() );
199  mAvailableFieldsList->item( mAvailableFieldsList->count() - 1 )->setData( Qt::UserRole, flds.at( i ).name() );
200  }
201  }
202 }
203 
204 void QgsRelationReferenceConfigDlg::addFilterField( const QString& field )
205 {
206  for ( int i = 0; i < mAvailableFieldsList->count(); i++ )
207  {
208  if ( mAvailableFieldsList->item( i )->data( Qt::UserRole ).toString() == field )
209  {
210  addFilterField( mAvailableFieldsList->item( i ) );
211  break;
212  }
213  }
214 }
215 
216 void QgsRelationReferenceConfigDlg::addFilterField( QListWidgetItem* item )
217 {
218  mAvailableFieldsList->takeItem( indexFromListWidgetItem( item ) );
219  mFilterFieldsList->addItem( item );
220 }
221 
222 int QgsRelationReferenceConfigDlg::indexFromListWidgetItem( QListWidgetItem* item )
223 {
224  QListWidget* lw = item->listWidget();
225 
226  for ( int i = 0; i < lw->count(); i++ )
227  {
228  if ( lw->item( i ) == item )
229  return i;
230  }
231 
232  return -1;
233 }
virtual QgsEditorWidgetConfig config() override
Create a configuration from the current GUI state.
int field()
Returns the field for which this configuration widget applies.
void setupUi(QWidget *widget)
This class should be subclassed for every configurable editor widget type.
QString name
Definition: qgsfield.h:52
QListWidget * listWidget() const
void reserve(int alloc)
Container of fields for a vector layer.
Definition: qgsfield.h:252
void setDisplayExpression(const QString &displayExpression)
Set the preview expression, used to create a human readable preview string.
QList< QgsRelation > referencingRelations(int idx)
Get relations, where the foreign key is on this layer.
QgsRelationManager * relationManager() const
int count() const
Return number of items.
Definition: qgsfield.cpp:402
QString id() const
A (project-wide) unique id for this relation.
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:422
QgsFields fields() const
Returns the list of fields of this layer.
bool hasGeometryType() const
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
virtual void setConfig(const QgsEditorWidgetConfig &config) override
Update the configuration widget to represent the given configuration.
QVariantMap QgsEditorWidgetConfig
Holds a set of configuration parameters for a editor widget wrapper.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
QString displayName() const
Returns the name to use when displaying this field.
Definition: qgsfield.cpp:89
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
bool isEmpty() const
QListWidgetItem * item(int row) const
QgsVectorLayer * referencedLayer() const
Access the referenced (parent) layer.
void changed()
Emitted when the configuration of the widget is changed.
void insert(int i, const T &value)
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:382
static QgsExpressionContext _getExpressionContext(const void *context)
static QgsExpressionContextScope * projectScope()
Creates a new scope which contains variables and functions relating to the current QGIS project...
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
QgsRelation relation(const QString &id) const
Get access to a relation by its id.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString displayExpression() const
Get the preview expression, used to create a human readable preview string.
Represents a vector layer which manages a vector based data sets.
QString referencedLayerId() const
Access the referenced (parent) layer&#39;s id.
QgsRelationReferenceConfigDlg(QgsVectorLayer *vl, int fieldIdx, QWidget *parent)
QString name() const
Returns a human readable name for this relation.