QGIS API Documentation 3.99.0-Master (a5475b57e34)
Loading...
Searching...
No Matches
qgsdbrelationshipwidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsdbrelationshipwidget.cpp
3 ------------------
4 Date : November 2022
5 Copyright : (C) 2022 by Nyall Dawson
6 Email : nyall dot dawson at gmail dot com
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
19#include "qgsgui.h"
20#include "qgshelp.h"
21#include "qgsproviderregistry.h"
22
23#include <QDialogButtonBox>
24#include <QPushButton>
25#include <QSortFilterProxyModel>
26#include <QString>
27
28#include "moc_qgsdbrelationshipwidget.cpp"
29
30using namespace Qt::StringLiterals;
31
32//
33// QgsDbRelationWidget
34//
35
37 : QWidget( parent )
38 , mConnection( connection )
39{
40 setupUi( this );
41
42 // takes ownership of connection
43 mTableModel = new QgsDatabaseTableModel( connection, QString(), this );
44
45 const QList<Qgis::RelationshipCardinality> cardinalities = mConnection->supportedRelationshipCardinalities();
46 for ( Qgis::RelationshipCardinality cardinality :
47 {
52 } )
53 {
54 if ( cardinalities.contains( cardinality ) )
55 mCardinalityCombo->addItem( QgsRelation::cardinalityToDisplayString( cardinality ), QVariant::fromValue( cardinality ) );
56 }
57
58 const QList<Qgis::RelationshipStrength> strengths = mConnection->supportedRelationshipStrengths();
59 for ( Qgis::RelationshipStrength strength :
60 {
63 } )
64 {
65 if ( strengths.contains( strength ) )
66 mStrengthCombo->addItem( QgsRelation::strengthToDisplayString( strength ), QVariant::fromValue( strength ) );
67 }
68
69 const Qgis::RelationshipCapabilities capabilities = mConnection->supportedRelationshipCapabilities();
70 if ( !( capabilities & Qgis::RelationshipCapability::ForwardPathLabel ) )
71 {
72 mForwardLabelLineEdit->hide();
73 mForwardLabel->hide();
74 }
75
77 {
78 mBackwardLabelLineEdit->hide();
79 mReverseLabel->hide();
80 }
81
82 const QStringList relatedTableTypes = mConnection->relatedTableTypes();
83 mRelatedTableTypeCombo->addItems( relatedTableTypes );
84
85 mProxyModel = new QSortFilterProxyModel( mTableModel );
86 mProxyModel->setSourceModel( mTableModel );
87 mProxyModel->setDynamicSortFilter( true );
88 mProxyModel->setSortCaseSensitivity( Qt::CaseInsensitive );
89 mProxyModel->setSortRole( Qt::DisplayRole );
90 mProxyModel->sort( 0 );
91
92 mLeftTableCombo->setModel( mProxyModel );
93 mRightTableCombo->setModel( mProxyModel );
94
95 connect( mNameEdit, &QLineEdit::textChanged, this, [this] {
96 emit validityChanged( isValid() );
97 } );
98 connect( mLeftTableCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
99 mLeftFieldsCombo->setFields( mConnection->fields( QString(), mLeftTableCombo->currentText() ) );
100 emit validityChanged( isValid() );
101 } );
102 connect( mRightTableCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
103 mRightFieldsCombo->setFields( mConnection->fields( QString(), mRightTableCombo->currentText() ) );
104 emit validityChanged( isValid() );
105 } );
106
107 for ( QComboBox *combo :
108 {
109 mCardinalityCombo,
110 qobject_cast<QComboBox *>( mLeftFieldsCombo ),
111 qobject_cast<QComboBox *>( mRightFieldsCombo ),
112 mStrengthCombo,
113 mRelatedTableTypeCombo
114 } )
115 {
116 connect( combo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
117 emit validityChanged( isValid() );
118 } );
119 }
120
121 mLeftFieldsCombo->setFields( mConnection->fields( QString(), mLeftTableCombo->currentText() ) );
122 mRightFieldsCombo->setFields( mConnection->fields( QString(), mRightTableCombo->currentText() ) );
123}
124
126{
127 mRelation = relationship;
128 mNameEdit->setText( mRelation.name() );
129 mNameEdit->setEnabled( false );
130 mStrengthCombo->setCurrentIndex( mStrengthCombo->findData( QVariant::fromValue( mRelation.strength() ) ) );
131
132 QVariantMap parts = QgsProviderRegistry::instance()->decodeUri( mConnection->providerKey(), mRelation.referencedLayerSource() );
133 mLeftTableCombo->setCurrentText( parts.value( u"layerName"_s ).toString() );
134 parts = QgsProviderRegistry::instance()->decodeUri( mConnection->providerKey(), mRelation.referencingLayerSource() );
135 mRightTableCombo->setCurrentText( parts.value( u"layerName"_s ).toString() );
136
137 mCardinalityCombo->setCurrentIndex( mCardinalityCombo->findData( QVariant::fromValue( mRelation.cardinality() ) ) );
138 mLeftFieldsCombo->setCurrentText( mRelation.referencedLayerFields().value( 0 ) );
139 mRightFieldsCombo->setCurrentText( mRelation.referencingLayerFields().value( 0 ) );
140 mForwardLabelLineEdit->setText( mRelation.forwardPathLabel() );
141 mBackwardLabelLineEdit->setText( mRelation.backwardPathLabel() );
142 mRelatedTableTypeCombo->setCurrentText( mRelation.relatedTableType() );
143}
144
146{
147 QgsWeakRelation result( mRelation.id().isEmpty() ? mNameEdit->text() : mRelation.id(), mRelation.name().isEmpty() ? mNameEdit->text() : mRelation.name(), mStrengthCombo->currentData().value<Qgis::RelationshipStrength>(), QString(), QString(), mConnection->tableUri( QString(), mRightTableCombo->currentText() ), mConnection->providerKey(), QString(), QString(), mConnection->tableUri( QString(), mLeftTableCombo->currentText() ), mConnection->providerKey() );
148 result.setCardinality( mCardinalityCombo->currentData().value<Qgis::RelationshipCardinality>() );
149 result.setReferencedLayerFields( { mLeftFieldsCombo->currentText() } );
150 result.setReferencingLayerFields( { mRightFieldsCombo->currentText() } );
151 result.setForwardPathLabel( mForwardLabelLineEdit->text() );
152 result.setBackwardPathLabel( mBackwardLabelLineEdit->text() );
153
154 result.setMappingTable( mRelation.mappingTable() );
155 result.setMappingReferencedLayerFields( mRelation.mappingReferencedLayerFields() );
156 result.setMappingReferencingLayerFields( mRelation.mappingReferencingLayerFields() );
157
158 if ( mRelatedTableTypeCombo->currentIndex() >= 0 )
159 result.setRelatedTableType( mRelatedTableTypeCombo->currentText() );
160 return result;
161}
162
164{
165 if ( mNameEdit->text().trimmed().isEmpty() )
166 return false;
167
168 if ( mLeftTableCombo->currentText().isEmpty() )
169 return false;
170
171 if ( mRightTableCombo->currentText().isEmpty() )
172 return false;
173
174 if ( mLeftTableCombo->currentText() == mRightTableCombo->currentText() )
175 return false;
176
177 if ( mLeftFieldsCombo->currentText().isEmpty() )
178 return false;
179
180 if ( mRightFieldsCombo->currentText().isEmpty() )
181 return false;
182
183
184 return true;
185}
186
187//
188// QgsDbRelationDialog
189//
190
191QgsDbRelationDialog::QgsDbRelationDialog( QgsAbstractDatabaseProviderConnection *connection, QWidget *parent, Qt::WindowFlags flags )
192 : QDialog( parent, flags )
193{
194 setObjectName( u"QgsDbRelationDialog"_s );
195
196 QVBoxLayout *vLayout = new QVBoxLayout();
197 mWidget = new QgsDbRelationWidget( connection );
198 vLayout->addWidget( mWidget, 1 );
199
200 mButtonBox = new QDialogButtonBox( QDialogButtonBox::StandardButton::Cancel | QDialogButtonBox::StandardButton::Help | QDialogButtonBox::StandardButton::Ok );
201 connect( mButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept );
202 connect( mButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject );
203 connect( mButtonBox, &QDialogButtonBox::helpRequested, this, [] {
204 QgsHelp::openHelp( u"working_with_vector/joins_relations.html#dataset-stored-relationships"_s );
205 } );
206 vLayout->addWidget( mButtonBox );
207
208 setLayout( vLayout );
209 connect( mWidget, &QgsDbRelationWidget::validityChanged, this, &QgsDbRelationDialog::validityChanged );
210 validityChanged( mWidget->isValid() );
211
213}
214
216{
217 mWidget->setRelationship( relationship );
218}
219
221{
222 return mWidget->relationship();
223}
224
226{
227 if ( !mWidget->isValid() )
228 return;
229
230 QDialog::accept();
231}
232
233void QgsDbRelationDialog::validityChanged( bool isValid )
234{
235 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( isValid );
236}
RelationshipStrength
Relationship strength.
Definition qgis.h:4514
@ Composition
Fix relation, related elements are part of the parent and a parent copy will copy any children or del...
Definition qgis.h:4516
@ Association
Loose relation, related elements are not part of the parent and a parent copy will not copy any child...
Definition qgis.h:4515
@ BackwardPathLabel
Supports backward path labels.
Definition qgis.h:4543
@ ForwardPathLabel
Supports forward path labels.
Definition qgis.h:4542
RelationshipCardinality
Relationship cardinality.
Definition qgis.h:4526
@ ManyToMany
Many to many relationship.
Definition qgis.h:4530
@ ManyToOne
Many to one relationship.
Definition qgis.h:4529
@ OneToOne
One to one relationship.
Definition qgis.h:4527
@ OneToMany
One to many relationship.
Definition qgis.h:4528
QFlags< RelationshipCapability > RelationshipCapabilities
Relationship capabilities.
Definition qgis.h:4552
Provides common functionality for database based connections.
A model containing tables from a database connection.
QgsDbRelationDialog(QgsAbstractDatabaseProviderConnection *connection, QWidget *parent=nullptr, Qt::WindowFlags flags=Qt::WindowFlags())
Constructor for QgsDbRelationDialog, with the specified parent widget and window flags,...
QgsWeakRelation relationship() const
Returns the relationship as defined in the dialog.
void setRelationship(const QgsWeakRelation &relationship)
Sets the current relationship to show properties for in the dialog.
A widget for configuration of the properties of a relationship in a database.
void setRelationship(const QgsWeakRelation &relationship)
Sets the current relationship to show properties for in the widget.
QgsDbRelationWidget(QgsAbstractDatabaseProviderConnection *connection, QWidget *parent=nullptr)
Constructor for QgsDbRelationWidget with the specified parent widget, for the specified connection.
void validityChanged(bool isValid)
Emitted whenever the validity of the relationship configuration in the widget changes.
bool isValid() const
Returns true if the widget currently represents a valid relationship configuration.
QgsWeakRelation relationship() const
Returns the relationship as defined in the widget.
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition qgsgui.cpp:224
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition qgshelp.cpp:41
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
static QString cardinalityToDisplayString(Qgis::RelationshipCardinality cardinality)
Returns a user-friendly translated string representing a relationship cardinality.
static QString strengthToDisplayString(Qgis::RelationshipStrength strength)
Returns a user-friendly translated string representing a relationship strength.
Represent a QgsRelation with possibly unresolved layers or unmatched fields.
void setMappingTable(const QgsVectorLayerRef &table)
Sets a weak reference to the mapping table, which forms the middle table in many-to-many relationship...
void setForwardPathLabel(const QString &label)
Sets the label of the forward path for the relationship.
void setMappingReferencingLayerFields(const QStringList &fields)
Sets the list of fields from the mappingTable() involved in the relationship.
void setBackwardPathLabel(const QString &label)
Sets the label of the backward path for the relationship.
void setReferencingLayerFields(const QStringList &fields)
Sets the list of fields from the referencingLayer() involved in the relationship.
void setMappingReferencedLayerFields(const QStringList &fields)
Sets the list of fields from the mappingTable() involved in the relationship.
void setCardinality(Qgis::RelationshipCardinality cardinality)
Sets the relationship's cardinality.
void setRelatedTableType(const QString &type)
Sets the type string of the related table.
void setReferencedLayerFields(const QStringList &fields)
Sets the list of fields from the referencedLayer() involved in the relationship.