QGIS API Documentation 3.34.0-Prizren (ffbdd678812)
Loading...
Searching...
No Matches
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 "qgsfields.h"
19#include "qgsproject.h"
20#include "qgsrelationmanager.h"
21#include "qgsvectorlayer.h"
24
26 : QgsEditorConfigWidget( vl, fieldIdx, parent )
27
28{
29 setupUi( this );
30
31 mFetchLimit->setMaximum( std::numeric_limits<int>::max() );
32
33 connect( mAddFilterButton, &QToolButton::clicked, this, &QgsRelationReferenceConfigDlg::mAddFilterButton_clicked );
34 connect( mRemoveFilterButton, &QToolButton::clicked, this, &QgsRelationReferenceConfigDlg::mRemoveFilterButton_clicked );
35
36 mExpressionWidget->registerExpressionContextGenerator( vl );
37
38 connect( mComboRelation, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsRelationReferenceConfigDlg::relationChanged );
39
40 const auto constReferencingRelations = vl->referencingRelations( fieldIdx );
41 for ( const QgsRelation &relation : constReferencingRelations )
42 {
43 if ( relation.name().isEmpty() )
44 mComboRelation->addItem( QStringLiteral( "%1 (%2)" ).arg( relation.id(), relation.referencedLayerId() ), relation.id() );
45 else
46 mComboRelation->addItem( QStringLiteral( "%1 (%2)" ).arg( relation.name(), relation.referencedLayerId() ), relation.id() );
47
48 QStandardItemModel *model = qobject_cast<QStandardItemModel *>( mComboRelation->model() );
49 QStandardItem *item = model->item( model->rowCount() - 1 );
50 item->setFlags( relation.type() == Qgis::RelationshipType::Generated
51 ? item->flags() & ~Qt::ItemIsEnabled
52 : item->flags() | Qt::ItemIsEnabled );
53
54 if ( auto *lReferencedLayer = relation.referencedLayer() )
55 {
56 mExpressionWidget->setField( lReferencedLayer->displayExpression() );
57 }
58 }
59
60 connect( mCbxAllowNull, &QAbstractButton::toggled, this, &QgsEditorConfigWidget::changed );
61 connect( mCbxShowForm, &QAbstractButton::toggled, this, &QgsEditorConfigWidget::changed );
62 connect( mCbxShowOpenFormButton, &QAbstractButton::toggled, this, &QgsEditorConfigWidget::changed );
63 connect( mCbxMapIdentification, &QAbstractButton::toggled, this, &QgsEditorConfigWidget::changed );
64 connect( mCbxReadOnly, &QAbstractButton::toggled, this, &QgsEditorConfigWidget::changed );
65 connect( mComboRelation, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsEditorConfigWidget::changed );
66 connect( mCbxAllowAddFeatures, &QAbstractButton::toggled, this, &QgsEditorConfigWidget::changed );
67 connect( mFilterGroupBox, &QGroupBox::toggled, this, &QgsEditorConfigWidget::changed );
68 connect( mFilterFieldsList, &QListWidget::itemChanged, this, &QgsEditorConfigWidget::changed );
69 connect( mCbxChainFilters, &QAbstractButton::toggled, this, &QgsEditorConfigWidget::changed );
70 connect( mExpressionWidget, static_cast<void ( QgsFieldExpressionWidget::* )( const QString & )>( &QgsFieldExpressionWidget::fieldChanged ), this, &QgsEditorConfigWidget::changed );
71 connect( mEditExpression, &QAbstractButton::clicked, this, &QgsRelationReferenceConfigDlg::mEditExpression_clicked );
72 connect( mFilterExpression, &QTextEdit::textChanged, this, &QgsEditorConfigWidget::changed );
73}
74
75void QgsRelationReferenceConfigDlg::mEditExpression_clicked()
76{
77 QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer() );
78 if ( !vl )
79 return;
80
84
85 context.setHighlightedFunctions( QStringList() << QStringLiteral( "current_value" ) << QStringLiteral( "current_parent_value" ) );
86 context.setHighlightedVariables( QStringList() << QStringLiteral( "current_geometry" )
87 << QStringLiteral( "current_feature" )
88 << QStringLiteral( "form_mode" )
89 << QStringLiteral( "current_parent_geometry" )
90 << QStringLiteral( "current_parent_feature" ) );
91
92 QgsExpressionBuilderDialog dlg( vl, mFilterExpression->toPlainText(), this, QStringLiteral( "generic" ), context );
93 dlg.setWindowTitle( tr( "Edit Filter Expression" ) );
94
95 if ( dlg.exec() == QDialog::Accepted )
96 {
97 mFilterExpression->setPlainText( dlg.expressionBuilder()->expressionText() );
98 }
99}
100
101void QgsRelationReferenceConfigDlg::setConfig( const QVariantMap &config )
102{
103 mCbxAllowNull->setChecked( config.value( QStringLiteral( "AllowNULL" ), false ).toBool() );
104 mCbxShowForm->setChecked( config.value( QStringLiteral( "ShowForm" ), false ).toBool() );
105 mCbxShowOpenFormButton->setChecked( config.value( QStringLiteral( "ShowOpenFormButton" ), true ).toBool() );
106
107 if ( config.contains( QStringLiteral( "Relation" ) ) )
108 {
109 mComboRelation->setCurrentIndex( mComboRelation->findData( config.value( QStringLiteral( "Relation" ) ).toString() ) );
110 relationChanged( mComboRelation->currentIndex() );
111 }
112
113 mCbxMapIdentification->setChecked( config.value( QStringLiteral( "MapIdentification" ), false ).toBool() );
114 mCbxAllowAddFeatures->setChecked( config.value( QStringLiteral( "AllowAddFeatures" ), false ).toBool() );
115 mCbxReadOnly->setChecked( config.value( QStringLiteral( "ReadOnly" ), false ).toBool() );
116 mFetchLimitGroupBox->setChecked( config.value( QStringLiteral( "FetchLimitActive" ), QgsSettings().value( QStringLiteral( "maxEntriesRelationWidget" ), 100, QgsSettings::Gui ).toInt() > 0 ).toBool() );
117 mFetchLimit->setValue( config.value( QStringLiteral( "FetchLimitNumber" ), QgsSettings().value( QStringLiteral( "maxEntriesRelationWidget" ), 100, QgsSettings::Gui ) ).toInt() );
118 mFilterExpression->setPlainText( config.value( QStringLiteral( "FilterExpression" ) ).toString() );
119
120 if ( config.contains( QStringLiteral( "FilterFields" ) ) )
121 {
122 mFilterGroupBox->setChecked( true );
123 const auto constToStringList = config.value( "FilterFields" ).toStringList();
124 for ( const QString &fld : constToStringList )
125 {
126 addFilterField( fld );
127 }
128
129 mCbxChainFilters->setChecked( config.value( QStringLiteral( "ChainFilters" ) ).toBool() );
130 }
131}
132
133void QgsRelationReferenceConfigDlg::relationChanged( int idx )
134{
135 const QString relName = mComboRelation->itemData( idx ).toString();
136 const QgsRelation rel = QgsProject::instance()->relationManager()->relation( relName );
137
138 mReferencedLayer = rel.referencedLayer();
139 mExpressionWidget->setLayer( mReferencedLayer ); // set even if 0
140 if ( mReferencedLayer )
141 {
142 mExpressionWidget->setField( mReferencedLayer->displayExpression() );
143 mCbxMapIdentification->setEnabled( mReferencedLayer->isSpatial() );
144 }
145
146 loadFields();
147}
148
149void QgsRelationReferenceConfigDlg::mAddFilterButton_clicked()
150{
151 const auto constSelectedItems = mAvailableFieldsList->selectedItems();
152 for ( QListWidgetItem *item : constSelectedItems )
153 {
154 addFilterField( item );
155 }
156}
157
158void QgsRelationReferenceConfigDlg::mRemoveFilterButton_clicked()
159{
160 const auto constSelectedItems = mFilterFieldsList->selectedItems();
161 for ( QListWidgetItem *item : constSelectedItems )
162 {
163 mFilterFieldsList->takeItem( indexFromListWidgetItem( item ) );
164 mAvailableFieldsList->addItem( item );
165 }
166}
167
169{
170 QVariantMap myConfig;
171 myConfig.insert( QStringLiteral( "AllowNULL" ), mCbxAllowNull->isChecked() );
172 myConfig.insert( QStringLiteral( "ShowForm" ), mCbxShowForm->isChecked() );
173 myConfig.insert( QStringLiteral( "ShowOpenFormButton" ), mCbxShowOpenFormButton->isChecked() );
174 myConfig.insert( QStringLiteral( "MapIdentification" ), mCbxMapIdentification->isEnabled() && mCbxMapIdentification->isChecked() );
175 myConfig.insert( QStringLiteral( "ReadOnly" ), mCbxReadOnly->isChecked() );
176 myConfig.insert( QStringLiteral( "Relation" ), mComboRelation->currentData() );
177 myConfig.insert( QStringLiteral( "AllowAddFeatures" ), mCbxAllowAddFeatures->isChecked() );
178 myConfig.insert( QStringLiteral( "FetchLimitActive" ), mFetchLimitGroupBox->isChecked() );
179 myConfig.insert( QStringLiteral( "FetchLimitNumber" ), mFetchLimit->value() );
180
181 if ( mFilterGroupBox->isChecked() )
182 {
183 QStringList filterFields;
184 filterFields.reserve( mFilterFieldsList->count() );
185 for ( int i = 0; i < mFilterFieldsList->count(); i++ )
186 {
187 filterFields << mFilterFieldsList->item( i )->data( Qt::UserRole ).toString();
188 }
189 myConfig.insert( QStringLiteral( "FilterFields" ), filterFields );
190
191 myConfig.insert( QStringLiteral( "ChainFilters" ), mCbxChainFilters->isChecked() );
192 myConfig.insert( QStringLiteral( "FilterExpression" ), mFilterExpression->toPlainText() );
193 }
194
195 if ( mReferencedLayer )
196 {
197 // Store referenced layer data source and provider
198 myConfig.insert( QStringLiteral( "ReferencedLayerDataSource" ), mReferencedLayer->publicSource() );
199 myConfig.insert( QStringLiteral( "ReferencedLayerProviderKey" ), mReferencedLayer->providerType() );
200 myConfig.insert( QStringLiteral( "ReferencedLayerId" ), mReferencedLayer->id() );
201 myConfig.insert( QStringLiteral( "ReferencedLayerName" ), mReferencedLayer->name() );
202 mReferencedLayer->setDisplayExpression( mExpressionWidget->currentField() );
203 }
204
205 return myConfig;
206}
207
208void QgsRelationReferenceConfigDlg::loadFields()
209{
210 mAvailableFieldsList->clear();
211 mFilterFieldsList->clear();
212
213 if ( mReferencedLayer )
214 {
215 QgsVectorLayer *l = mReferencedLayer;
216 const QgsFields &flds = l->fields();
217 for ( int i = 0; i < flds.count(); i++ )
218 {
219 mAvailableFieldsList->addItem( flds.at( i ).displayName() );
220 mAvailableFieldsList->item( mAvailableFieldsList->count() - 1 )->setData( Qt::UserRole, flds.at( i ).name() );
221 }
222 }
223}
224
225void QgsRelationReferenceConfigDlg::addFilterField( const QString &field )
226{
227 for ( int i = 0; i < mAvailableFieldsList->count(); i++ )
228 {
229 if ( mAvailableFieldsList->item( i )->data( Qt::UserRole ).toString() == field )
230 {
231 addFilterField( mAvailableFieldsList->item( i ) );
232 break;
233 }
234 }
235}
236
237void QgsRelationReferenceConfigDlg::addFilterField( QListWidgetItem *item )
238{
239 mAvailableFieldsList->takeItem( indexFromListWidgetItem( item ) );
240 mFilterFieldsList->addItem( item );
241}
242
243int QgsRelationReferenceConfigDlg::indexFromListWidgetItem( QListWidgetItem *item )
244{
245 QListWidget *lw = item->listWidget();
246
247 for ( int i = 0; i < lw->count(); i++ )
248 {
249 if ( lw->item( i ) == item )
250 return i;
251 }
252
253 return -1;
254}
@ Generated
A generated relation is a child of a polymorphic relation.
This class should be subclassed for every configurable editor widget type.
int field()
Returns the field for which this configuration widget applies.
QgsVectorLayer * layer()
Returns the layer for which this configuration widget applies.
void changed()
Emitted when the configuration of the widget is changed.
A generic dialog for building expression strings.
static QgsExpressionContextScope * parentFormScope(const QgsFeature &formFeature=QgsFeature(), const QString &formMode=QString())
Creates a new scope which contains functions and variables from the current parent attribute form/tab...
static QgsExpressionContextScope * formScope(const QgsFeature &formFeature=QgsFeature(), const QString &formMode=QString())
Creates a new scope which contains functions and variables from the current attribute form/table form...
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
The QgsFieldExpressionWidget class reates a widget to choose fields and edit expressions It contains ...
void fieldChanged(const QString &fieldName)
Emitted when the currently selected field changes.
QString name
Definition qgsfield.h:62
QString displayName() const
Returns the name to use when displaying this field.
Definition qgsfield.cpp:88
Container of fields for a vector layer.
Definition qgsfields.h:45
int count() const
Returns number of items.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
QString name
Definition qgsmaplayer.h:77
QString providerType() const
Returns the provider type (provider key) for this layer.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
QString publicSource(bool hidePassword=false) const
Gets a version of the internal layer definition that has sensitive bits removed (for example,...
QgsRelationManager * relationManager
Definition qgsproject.h:117
static QgsProject * instance()
Returns the QgsProject singleton instance.
Q_INVOKABLE QgsRelation relation(const QString &id) const
Gets access to a relation by its id.
QgsRelationReferenceConfigDlg(QgsVectorLayer *vl, int fieldIdx, QWidget *parent)
void setConfig(const QVariantMap &config) override
Update the configuration widget to represent the given configuration.
QVariantMap config() override
Create a configuration from the current GUI state.
QgsVectorLayer * referencedLayer
Definition qgsrelation.h:47
This class is a composition of two QSettings instances:
Definition qgssettings.h:63
Represents a vector layer which manages a vector based data sets.
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
QgsFields fields() const FINAL
Returns the list of fields of this layer.
QList< QgsRelation > referencingRelations(int idx) const
Returns the layer's relations, where the foreign key is on this layer.
void setDisplayExpression(const QString &displayExpression)
Set the preview expression, used to create a human readable preview string.
QString displayExpression