QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
qgsjoindialog.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsjoindialog.cpp
3 --------------------
4 begin : July 10, 2010
5 copyright : (C) 2010 by Marco Hugentobler
6 email : marco dot hugentobler at sourcepole dot ch
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include "qgsjoindialog.h"
19
20#include "qgsfieldcombobox.h"
21#include "qgshelp.h"
22#include "qgsmaplayer.h"
23#include "qgsmaplayercombobox.h"
24#include "qgsproject.h"
26#include "qgsvectorlayer.h"
28
29#include <QPushButton>
30#include <QStandardItemModel>
31#include <QString>
32
33#include "moc_qgsjoindialog.cpp"
34
35using namespace Qt::StringLiterals;
36
37QgsJoinDialog::QgsJoinDialog( QgsVectorLayer *layer, QList<QgsMapLayer *> alreadyJoinedLayers, QWidget *parent, Qt::WindowFlags f )
38 : QDialog( parent, f )
39 , mLayer( layer )
40{
41 setupUi( this );
42 connect( buttonBox, &QDialogButtonBox::helpRequested, this, [] {
43 QgsHelp::openHelp( u"working_with_vector/vector_properties.html#joins-properties"_s );
44 } );
45
46 if ( !mLayer )
47 {
48 return;
49 }
50 // adds self layer to the joined layer (cannot join to itself)
51 alreadyJoinedLayers.append( layer );
52
53 mTargetFieldComboBox->setLayer( mLayer );
54
55 mDynamicFormCheckBox->setToolTip( tr( "This option allows values of the joined fields to be automatically reloaded when the \"Target Field\" is changed" ) );
56
57 mEditableJoinLayer->setToolTip( tr( "This option allows values of the joined layers to be editable if they're themselves editable" ) );
58 mUpsertOnEditCheckBox->setToolTip( tr( "Automatically adds a matching row to the joined table, but if one already exists then update that matching row instead" ) );
59 mDeleteCascadeCheckBox->setToolTip( tr( "Automatically delete the corresponding feature of the linked layer if one exists" ) );
60
61 mJoinLayerComboBox->setFilters( Qgis::LayerFilter::VectorLayer );
62 mJoinLayerComboBox->setExceptedLayerList( alreadyJoinedLayers );
63 connect( mJoinLayerComboBox, &QgsMapLayerComboBox::layerChanged, mJoinFieldComboBox, &QgsFieldComboBox::setLayer );
64 connect( mJoinLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsJoinDialog::joinedLayerChanged );
65
66 mCacheInMemoryCheckBox->setChecked( true );
67 mCacheEnabled = mCacheInMemoryCheckBox->isChecked();
68
69 QgsMapLayer *joinLayer = mJoinLayerComboBox->currentLayer();
70 if ( joinLayer && joinLayer->isValid() )
71 {
72 mJoinFieldComboBox->setLayer( joinLayer );
73 joinedLayerChanged( joinLayer );
74 }
75
76 connect( mJoinLayerComboBox, &QgsMapLayerComboBox::layerChanged, this, &QgsJoinDialog::checkDefinitionValid );
77 connect( mJoinFieldComboBox, &QgsFieldComboBox::fieldChanged, this, &QgsJoinDialog::checkDefinitionValid );
78 connect( mTargetFieldComboBox, &QgsFieldComboBox::fieldChanged, this, &QgsJoinDialog::checkDefinitionValid );
79 connect( mEditableJoinLayer, &QGroupBox::toggled, this, &QgsJoinDialog::editableJoinLayerChanged );
80
81 checkDefinitionValid();
82}
83
85{
86 mJoinLayerComboBox->setLayer( joinInfo.joinLayer() );
87 mJoinFieldComboBox->setField( joinInfo.joinFieldName() );
88 mTargetFieldComboBox->setField( joinInfo.targetFieldName() );
89
90 mCacheEnabled = joinInfo.isUsingMemoryCache();
91 mCacheInMemoryCheckBox->setChecked( joinInfo.isUsingMemoryCache() );
92
93 mDynamicFormCheckBox->setChecked( joinInfo.isDynamicFormEnabled() );
94 mEditableJoinLayer->setChecked( joinInfo.isEditable() );
95 mUpsertOnEditCheckBox->setChecked( joinInfo.hasUpsertOnEdit() );
96 mDeleteCascadeCheckBox->setChecked( joinInfo.hasCascadedDelete() );
97
98 if ( joinInfo.prefix().isNull() )
99 {
100 mUseCustomPrefix->setChecked( false );
101 }
102 else
103 {
104 mUseCustomPrefix->setChecked( true );
105 mCustomPrefix->setText( joinInfo.prefix() );
106 }
107
108 QStringList *lst = joinInfo.joinFieldNamesSubset();
109 mUseJoinFieldsSubset->setChecked( lst && !lst->isEmpty() );
110 QAbstractItemModel *model = mJoinFieldsSubsetView->model();
111 if ( model )
112 {
113 for ( int i = 0; i < model->rowCount(); ++i )
114 {
115 const QModelIndex index = model->index( i, 0 );
116 if ( lst && lst->contains( model->data( index, Qt::DisplayRole ).toString() ) )
117 {
118 model->setData( index, Qt::Checked, Qt::CheckStateRole );
119 }
120 else
121 {
122 model->setData( index, Qt::Unchecked, Qt::CheckStateRole );
123 }
124 }
125 }
126
127 editableJoinLayerChanged();
128}
129
131{
133 info.setJoinLayer( qobject_cast<QgsVectorLayer *>( mJoinLayerComboBox->currentLayer() ) );
134 info.setJoinFieldName( mJoinFieldComboBox->currentField() );
135 info.setTargetFieldName( mTargetFieldComboBox->currentField() );
136 info.setUsingMemoryCache( mCacheInMemoryCheckBox->isChecked() );
137 info.setDynamicFormEnabled( mDynamicFormCheckBox->isChecked() );
138
139 info.setEditable( mEditableJoinLayer->isChecked() );
140 if ( info.isEditable() )
141 {
142 info.setUpsertOnEdit( mUpsertOnEditCheckBox->isChecked() );
143 info.setCascadedDelete( mDeleteCascadeCheckBox->isChecked() );
144 }
145
146 if ( mUseCustomPrefix->isChecked() )
147 info.setPrefix( mCustomPrefix->text() );
148 else
149 info.setPrefix( QString() );
150
151 if ( mUseJoinFieldsSubset->isChecked() )
152 {
153 QStringList lst;
154 QAbstractItemModel *model = mJoinFieldsSubsetView->model();
155 if ( model )
156 {
157 for ( int i = 0; i < model->rowCount(); ++i )
158 {
159 const QModelIndex index = model->index( i, 0 );
160 if ( model->data( index, Qt::CheckStateRole ).toInt() == Qt::Checked )
161 lst << model->data( index ).toString();
162 }
163 }
164 info.setJoinFieldNamesSubset( new QStringList( lst ) );
165 }
166
167 return info;
168}
169
171{
172 return mCreateIndexCheckBox->isChecked();
173}
174
175void QgsJoinDialog::joinedLayerChanged( QgsMapLayer *layer )
176{
177 mJoinFieldComboBox->clear();
178
179 QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>( layer );
180 if ( !vLayer )
181 {
182 return;
183 }
184
185 mUseJoinFieldsSubset->setChecked( false );
186 QStandardItemModel *subsetModel = new QStandardItemModel( this );
187 const QgsFields layerFields = vLayer->fields();
188 for ( const QgsField &field : layerFields )
189 {
190 QStandardItem *subsetItem = new QStandardItem( field.name() );
191 subsetItem->setCheckable( true );
192 //subsetItem->setFlags( subsetItem->flags() | Qt::ItemIsUserCheckable );
193 subsetModel->appendRow( subsetItem );
194 }
195 mJoinFieldsSubsetView->setModel( subsetModel );
196
197 QgsVectorDataProvider *dp = vLayer->dataProvider();
198 const bool canCreateAttrIndex = dp && ( dp->capabilities() & Qgis::VectorProviderCapability::CreateAttributeIndex );
199 if ( canCreateAttrIndex )
200 {
201 mCreateIndexCheckBox->setEnabled( true );
202 }
203 else
204 {
205 mCreateIndexCheckBox->setEnabled( false );
206 mCreateIndexCheckBox->setChecked( false );
207 }
208
209 if ( !mUseCustomPrefix->isChecked() )
210 {
211 mCustomPrefix->setText( layer->name() + '_' );
212 }
213}
214
215void QgsJoinDialog::checkDefinitionValid()
216{
217 buttonBox->button( QDialogButtonBox::Ok )->setEnabled( mJoinLayerComboBox->currentIndex() != -1 && mJoinFieldComboBox->currentIndex() != -1 && mTargetFieldComboBox->currentIndex() != -1 );
218}
219
220void QgsJoinDialog::editableJoinLayerChanged()
221{
222 if ( mEditableJoinLayer->isChecked() )
223 {
224 mCacheInMemoryCheckBox->setEnabled( false );
225 mCacheInMemoryCheckBox->setToolTip( tr( "Caching can not be enabled if editable join layer is enabled" ) );
226 mCacheEnabled = mCacheInMemoryCheckBox->isChecked();
227 mCacheInMemoryCheckBox->setChecked( false );
228 }
229 else
230 {
231 mCacheInMemoryCheckBox->setEnabled( true );
232 mCacheInMemoryCheckBox->setToolTip( QString() );
233 mCacheInMemoryCheckBox->setChecked( mCacheEnabled );
234 }
235}
@ CreateAttributeIndex
Can create indexes on provider's fields.
Definition qgis.h:529
void fieldChanged(const QString &fieldName)
Emitted when the currently selected field changes.
void setLayer(QgsMapLayer *layer)
Sets the layer for which fields are listed in the combobox.
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition qgshelp.cpp:41
QgsJoinDialog(QgsVectorLayer *layer, QList< QgsMapLayer * > alreadyJoinedLayers, QWidget *parent=nullptr, Qt::WindowFlags f=Qt::WindowFlags())
QgsVectorLayerJoinInfo joinInfo() const
Returns the join info.
bool createAttributeIndex() const
Returns true if user wants to create an attribute index on the join field.
void setJoinInfo(const QgsVectorLayerJoinInfo &joinInfo)
Configure the dialog for an existing join.
void layerChanged(QgsMapLayer *layer)
Emitted whenever the currently selected layer changes.
Base class for all map layer types.
Definition qgsmaplayer.h:83
QString name
Definition qgsmaplayer.h:87
virtual Q_INVOKABLE Qgis::VectorProviderCapabilities capabilities() const
Returns flags containing the supported capabilities.
Defines left outer join from our vector layer to some other vector layer.
void setDynamicFormEnabled(bool enabled)
Sets whether the form has to be dynamically updated with joined fields when a feature is being create...
void setUsingMemoryCache(bool enabled)
Sets whether values from the joined layer should be cached in memory to speed up lookups.
void setEditable(bool enabled)
Sets whether the form of the target layer allows editing joined fields.
bool isEditable() const
Returns whether joined fields may be edited through the form of the target layer.
void setCascadedDelete(bool enabled)
Sets whether a feature deleted on the target layer has to impact the joined layer by deleting the cor...
void setJoinFieldName(const QString &fieldName)
Sets name of the field of joined layer that will be used for join.
void setTargetFieldName(const QString &fieldName)
Sets name of the field of our layer that will be used for join.
void setUpsertOnEdit(bool enabled)
Sets whether a feature created on the target layer has to impact the joined layer by creating a new f...
void setPrefix(const QString &prefix)
Sets prefix of fields from the joined layer. If nullptr, joined layer's name will be used.
void setJoinLayer(QgsVectorLayer *layer)
Sets weak reference to the joined layer.
void setJoinFieldNamesSubset(QStringList *fieldNamesSubset)
Sets the subset of fields to be used from joined layer.
Represents a vector layer which manages a vector based dataset.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.