QGIS API Documentation 3.99.0-Master (e9821da5c6b)
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 "qgsproviderregistry.h"
21
22#include <QDialogButtonBox>
23#include <QPushButton>
24#include <QSortFilterProxyModel>
25#include <QString>
26
27#include "moc_qgsdbrelationshipwidget.cpp"
28
29using namespace Qt::StringLiterals;
30
31//
32// QgsDbRelationWidget
33//
34
36 : QWidget( parent )
37 , mConnection( connection )
38{
39 setupUi( this );
40
41 // takes ownership of connection
42 mTableModel = new QgsDatabaseTableModel( connection, QString(), this );
43
44 const QList<Qgis::RelationshipCardinality> cardinalities = mConnection->supportedRelationshipCardinalities();
45 for ( Qgis::RelationshipCardinality cardinality :
46 {
51 } )
52 {
53 if ( cardinalities.contains( cardinality ) )
54 mCardinalityCombo->addItem( QgsRelation::cardinalityToDisplayString( cardinality ), QVariant::fromValue( cardinality ) );
55 }
56
57 const QList<Qgis::RelationshipStrength> strengths = mConnection->supportedRelationshipStrengths();
58 for ( Qgis::RelationshipStrength strength :
59 {
62 } )
63 {
64 if ( strengths.contains( strength ) )
65 mStrengthCombo->addItem( QgsRelation::strengthToDisplayString( strength ), QVariant::fromValue( strength ) );
66 }
67
68 const Qgis::RelationshipCapabilities capabilities = mConnection->supportedRelationshipCapabilities();
69 if ( !( capabilities & Qgis::RelationshipCapability::ForwardPathLabel ) )
70 {
71 mForwardLabelLineEdit->hide();
72 mForwardLabel->hide();
73 }
74
76 {
77 mBackwardLabelLineEdit->hide();
78 mReverseLabel->hide();
79 }
80
81 const QStringList relatedTableTypes = mConnection->relatedTableTypes();
82 mRelatedTableTypeCombo->addItems( relatedTableTypes );
83
84 mProxyModel = new QSortFilterProxyModel( mTableModel );
85 mProxyModel->setSourceModel( mTableModel );
86 mProxyModel->setDynamicSortFilter( true );
87 mProxyModel->setSortCaseSensitivity( Qt::CaseInsensitive );
88 mProxyModel->setSortRole( Qt::DisplayRole );
89 mProxyModel->sort( 0 );
90
91 mLeftTableCombo->setModel( mProxyModel );
92 mRightTableCombo->setModel( mProxyModel );
93
94 connect( mNameEdit, &QLineEdit::textChanged, this, [this] {
95 emit validityChanged( isValid() );
96 } );
97 connect( mLeftTableCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
98 mLeftFieldsCombo->setFields( mConnection->fields( QString(), mLeftTableCombo->currentText() ) );
99 emit validityChanged( isValid() );
100 } );
101 connect( mRightTableCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
102 mRightFieldsCombo->setFields( mConnection->fields( QString(), mRightTableCombo->currentText() ) );
103 emit validityChanged( isValid() );
104 } );
105
106 for ( QComboBox *combo :
107 {
108 mCardinalityCombo,
109 qobject_cast<QComboBox *>( mLeftFieldsCombo ),
110 qobject_cast<QComboBox *>( mRightFieldsCombo ),
111 mStrengthCombo,
112 mRelatedTableTypeCombo
113 } )
114 {
115 connect( combo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
116 emit validityChanged( isValid() );
117 } );
118 }
119
120 mLeftFieldsCombo->setFields( mConnection->fields( QString(), mLeftTableCombo->currentText() ) );
121 mRightFieldsCombo->setFields( mConnection->fields( QString(), mRightTableCombo->currentText() ) );
122}
123
125{
126 mRelation = relationship;
127 mNameEdit->setText( mRelation.name() );
128 mNameEdit->setEnabled( false );
129 mStrengthCombo->setCurrentIndex( mStrengthCombo->findData( QVariant::fromValue( mRelation.strength() ) ) );
130
131 QVariantMap parts = QgsProviderRegistry::instance()->decodeUri( mConnection->providerKey(), mRelation.referencedLayerSource() );
132 mLeftTableCombo->setCurrentText( parts.value( u"layerName"_s ).toString() );
133 parts = QgsProviderRegistry::instance()->decodeUri( mConnection->providerKey(), mRelation.referencingLayerSource() );
134 mRightTableCombo->setCurrentText( parts.value( u"layerName"_s ).toString() );
135
136 mCardinalityCombo->setCurrentIndex( mCardinalityCombo->findData( QVariant::fromValue( mRelation.cardinality() ) ) );
137 mLeftFieldsCombo->setCurrentText( mRelation.referencedLayerFields().value( 0 ) );
138 mRightFieldsCombo->setCurrentText( mRelation.referencingLayerFields().value( 0 ) );
139 mForwardLabelLineEdit->setText( mRelation.forwardPathLabel() );
140 mBackwardLabelLineEdit->setText( mRelation.backwardPathLabel() );
141 mRelatedTableTypeCombo->setCurrentText( mRelation.relatedTableType() );
142}
143
145{
146 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() );
147 result.setCardinality( mCardinalityCombo->currentData().value<Qgis::RelationshipCardinality>() );
148 result.setReferencedLayerFields( { mLeftFieldsCombo->currentText() } );
149 result.setReferencingLayerFields( { mRightFieldsCombo->currentText() } );
150 result.setForwardPathLabel( mForwardLabelLineEdit->text() );
151 result.setBackwardPathLabel( mBackwardLabelLineEdit->text() );
152
153 result.setMappingTable( mRelation.mappingTable() );
154 result.setMappingReferencedLayerFields( mRelation.mappingReferencedLayerFields() );
155 result.setMappingReferencingLayerFields( mRelation.mappingReferencingLayerFields() );
156
157 if ( mRelatedTableTypeCombo->currentIndex() >= 0 )
158 result.setRelatedTableType( mRelatedTableTypeCombo->currentText() );
159 return result;
160}
161
163{
164 if ( mNameEdit->text().trimmed().isEmpty() )
165 return false;
166
167 if ( mLeftTableCombo->currentText().isEmpty() )
168 return false;
169
170 if ( mRightTableCombo->currentText().isEmpty() )
171 return false;
172
173 if ( mLeftTableCombo->currentText() == mRightTableCombo->currentText() )
174 return false;
175
176 if ( mLeftFieldsCombo->currentText().isEmpty() )
177 return false;
178
179 if ( mRightFieldsCombo->currentText().isEmpty() )
180 return false;
181
182
183 return true;
184}
185
186//
187// QgsDbRelationDialog
188//
189
190QgsDbRelationDialog::QgsDbRelationDialog( QgsAbstractDatabaseProviderConnection *connection, QWidget *parent, Qt::WindowFlags flags )
191 : QDialog( parent, flags )
192{
193 setObjectName( u"QgsDbRelationDialog"_s );
194
195 QVBoxLayout *vLayout = new QVBoxLayout();
196 mWidget = new QgsDbRelationWidget( connection );
197 vLayout->addWidget( mWidget, 1 );
198
199 mButtonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel );
200 connect( mButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept );
201 connect( mButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject );
202 vLayout->addWidget( mButtonBox );
203
204 setLayout( vLayout );
205 connect( mWidget, &QgsDbRelationWidget::validityChanged, this, &QgsDbRelationDialog::validityChanged );
206 validityChanged( mWidget->isValid() );
207
209}
210
212{
213 mWidget->setRelationship( relationship );
214}
215
217{
218 return mWidget->relationship();
219}
220
222{
223 if ( !mWidget->isValid() )
224 return;
225
226 QDialog::accept();
227}
228
229void QgsDbRelationDialog::validityChanged( bool isValid )
230{
231 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( isValid );
232}
RelationshipStrength
Relationship strength.
Definition qgis.h:4488
@ Composition
Fix relation, related elements are part of the parent and a parent copy will copy any children or del...
Definition qgis.h:4490
@ Association
Loose relation, related elements are not part of the parent and a parent copy will not copy any child...
Definition qgis.h:4489
@ BackwardPathLabel
Supports backward path labels.
Definition qgis.h:4517
@ ForwardPathLabel
Supports forward path labels.
Definition qgis.h:4516
RelationshipCardinality
Relationship cardinality.
Definition qgis.h:4500
@ ManyToMany
Many to many relationship.
Definition qgis.h:4504
@ ManyToOne
Many to one relationship.
Definition qgis.h:4503
@ OneToOne
One to one relationship.
Definition qgis.h:4501
@ OneToMany
One to many relationship.
Definition qgis.h:4502
QFlags< RelationshipCapability > RelationshipCapabilities
Relationship capabilities.
Definition qgis.h:4526
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
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.