QGIS API Documentation  2.14.0-Essen
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  mComboRelation->addItem( QString( "%1 (%2)" ).arg( relation.id(), relation.referencedLayerId() ), relation.id() );
51  if ( relation.referencedLayer() )
52  {
53  mExpressionWidget->setField( relation.referencedLayer()->displayExpression() );
54  }
55  }
56 }
57 
59 {
60  if ( config.contains( "AllowNULL" ) )
61  {
62  mCbxAllowNull->setChecked( config[ "AllowNULL" ].toBool() );
63  }
64 
65  if ( config.contains( "OrderByValue" ) )
66  {
67  mCbxOrderByValue->setChecked( config[ "OrderByValue" ].toBool() );
68  }
69 
70  if ( config.contains( "ShowForm" ) )
71  {
72  mCbxShowForm->setChecked( config[ "ShowForm" ].toBool() );
73  }
74 
75  if ( config.contains( "Relation" ) )
76  {
77  mComboRelation->setCurrentIndex( mComboRelation->findData( config[ "Relation" ].toString() ) );
78  relationChanged( mComboRelation->currentIndex() );
79  }
80 
81  if ( config.contains( "MapIdentification" ) )
82  {
83  mCbxMapIdentification->setChecked( config[ "MapIdentification"].toBool() );
84  }
85 
86  if ( config.contains( "ReadOnly" ) )
87  {
88  mCbxReadOnly->setChecked( config[ "ReadOnly"].toBool() );
89  }
90 
91  if ( config.contains( "FilterFields" ) )
92  {
93  mFilterGroupBox->setChecked( true );
94  Q_FOREACH ( const QString& fld, config["FilterFields"].toStringList() )
95  {
96  addFilterField( fld );
97  }
98 
99  mCbxChainFilters->setChecked( config["ChainFilters"].toBool() );
100  }
101 }
102 
103 void QgsRelationReferenceConfigDlg::relationChanged( int idx )
104 {
105  QString relName = mComboRelation->itemData( idx ).toString();
107 
108  mReferencedLayer = rel.referencedLayer();
109  mExpressionWidget->setLayer( mReferencedLayer ); // set even if 0
110  if ( mReferencedLayer )
111  {
112  mExpressionWidget->setField( mReferencedLayer->displayExpression() );
113  mCbxMapIdentification->setEnabled( mReferencedLayer->hasGeometryType() );
114  }
115 
116  loadFields();
117 }
118 
119 void QgsRelationReferenceConfigDlg::on_mAddFilterButton_clicked()
120 {
121  Q_FOREACH ( QListWidgetItem* item, mAvailableFieldsList->selectedItems() )
122  {
123  addFilterField( item );
124  }
125 }
126 
127 void QgsRelationReferenceConfigDlg::on_mRemoveFilterButton_clicked()
128 {
129  Q_FOREACH ( QListWidgetItem* item , mFilterFieldsList->selectedItems() )
130  {
131  mFilterFieldsList->takeItem( indexFromListWidgetItem( item ) );
132  mAvailableFieldsList->addItem( item );
133  }
134 }
135 
137 {
138  QgsEditorWidgetConfig myConfig;
139  myConfig.insert( "AllowNULL", mCbxAllowNull->isChecked() );
140  myConfig.insert( "OrderByValue", mCbxOrderByValue->isChecked() );
141  myConfig.insert( "ShowForm", mCbxShowForm->isChecked() );
142  myConfig.insert( "MapIdentification", mCbxMapIdentification->isEnabled() && mCbxMapIdentification->isChecked() );
143  myConfig.insert( "ReadOnly", mCbxReadOnly->isChecked() );
144  myConfig.insert( "Relation", mComboRelation->itemData( mComboRelation->currentIndex() ) );
145 
146  if ( mFilterGroupBox->isChecked() )
147  {
148  QStringList filterFields;
149  filterFields.reserve( mFilterFieldsList->count() );
150  for ( int i = 0; i < mFilterFieldsList->count(); i++ )
151  {
152  filterFields << mFilterFieldsList->item( i )->data( Qt::UserRole ).toString();
153  }
154  myConfig.insert( "FilterFields", filterFields );
155 
156  myConfig.insert( "ChainFilters", mCbxChainFilters->isChecked() );
157  }
158 
159  if ( mReferencedLayer )
160  {
161  mReferencedLayer->setDisplayExpression( mExpressionWidget->currentField() );
162  }
163 
164  return myConfig;
165 }
166 
167 void QgsRelationReferenceConfigDlg::loadFields()
168 {
169  mAvailableFieldsList->clear();
170  mFilterFieldsList->clear();
171 
172  if ( mReferencedLayer )
173  {
174  QgsVectorLayer* l = mReferencedLayer;
175  const QgsFields& flds = l->fields();
176  for ( int i = 0; i < flds.count(); i++ )
177  {
178  mAvailableFieldsList->addItem( l->attributeAlias( i ).isEmpty() ? flds.at( i ).name() : l->attributeAlias( i ) );
179  mAvailableFieldsList->item( mAvailableFieldsList->count() - 1 )->setData( Qt::UserRole, flds.at( i ).name() );
180  }
181  }
182 }
183 
184 void QgsRelationReferenceConfigDlg::addFilterField( const QString& field )
185 {
186  for ( int i = 0; i < mAvailableFieldsList->count(); i++ )
187  {
188  if ( mAvailableFieldsList->item( i )->data( Qt::UserRole ).toString() == field )
189  {
190  addFilterField( mAvailableFieldsList->item( i ) );
191  break;
192  }
193  }
194 }
195 
196 void QgsRelationReferenceConfigDlg::addFilterField( QListWidgetItem* item )
197 {
198  mAvailableFieldsList->takeItem( indexFromListWidgetItem( item ) );
199  mFilterFieldsList->addItem( item );
200 }
201 
202 int QgsRelationReferenceConfigDlg::indexFromListWidgetItem( QListWidgetItem* item )
203 {
204  QListWidget* lw = item->listWidget();
205 
206  for ( int i = 0; i < lw->count(); i++ )
207  {
208  if ( lw->item( i ) == item )
209  return i;
210  }
211 
212  return -1;
213 }
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)
bool contains(const Key &key) const
This class should be subclassed for every configurable editor widget type.
QListWidget * listWidget() const
QgsFields fields() const
Returns the list of fields of this layer.
void reserve(int alloc)
QgsVectorLayer * referencedLayer() const
Access the referenced (parent) layer.
Container of fields for a vector layer.
Definition: qgsfield.h:187
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.
const QString displayExpression()
Get the preview expression, used to create a human readable preview string.
QString id() const
A (project-wide) unique id for this relation.
virtual void setConfig(const QgsEditorWidgetConfig &config) override
Update the configuration widget to represent the given configuration.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
QgsRelation relation(const QString &id) const
Get access to a relation by its id.
QString name() const
Gets the name of the field.
Definition: qgsfield.cpp:84
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
bool isEmpty() const
int count() const
Return number of items.
Definition: qgsfield.cpp:365
QListWidgetItem * item(int row) const
QString attributeAlias(int attributeIndex) const
Returns the alias of an attribute name or an empty string if there is no alias.
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:385
QString referencedLayerId() const
Access the referenced (parent) layer&#39;s id.
bool hasGeometryType() const
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:381
static QgsExpressionContext _getExpressionContext(const void *context)
iterator insert(const Key &key, const T &value)
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.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Represents a vector layer which manages a vector based data sets.
QgsRelationManager * relationManager() const
QgsRelationReferenceConfigDlg(QgsVectorLayer *vl, int fieldIdx, QWidget *parent)