QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
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 :
48 {
49 if ( cardinalities.contains( cardinality ) )
50 mCardinalityCombo->addItem( QgsRelation::cardinalityToDisplayString( cardinality ), QVariant::fromValue( cardinality ) );
51 }
52
53 const QList<Qgis::RelationshipStrength> strengths = mConnection->supportedRelationshipStrengths();
55 {
56 if ( strengths.contains( strength ) )
57 mStrengthCombo->addItem( QgsRelation::strengthToDisplayString( strength ), QVariant::fromValue( strength ) );
58 }
59
60 const Qgis::RelationshipCapabilities capabilities = mConnection->supportedRelationshipCapabilities();
61 if ( !( capabilities & Qgis::RelationshipCapability::ForwardPathLabel ) )
62 {
63 mForwardLabelLineEdit->hide();
64 mForwardLabel->hide();
65 }
66
68 {
69 mBackwardLabelLineEdit->hide();
70 mReverseLabel->hide();
71 }
72
73 const QStringList relatedTableTypes = mConnection->relatedTableTypes();
74 mRelatedTableTypeCombo->addItems( relatedTableTypes );
75
76 mProxyModel = new QSortFilterProxyModel( mTableModel );
77 mProxyModel->setSourceModel( mTableModel );
78 mProxyModel->setDynamicSortFilter( true );
79 mProxyModel->setSortCaseSensitivity( Qt::CaseInsensitive );
80 mProxyModel->setSortRole( Qt::DisplayRole );
81 mProxyModel->sort( 0 );
82
83 mLeftTableCombo->setModel( mProxyModel );
84 mRightTableCombo->setModel( mProxyModel );
85
86 connect( mNameEdit, &QLineEdit::textChanged, this, [this] { emit validityChanged( isValid() ); } );
87 connect( mLeftTableCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
88 mLeftFieldsCombo->setFields( mConnection->fields( QString(), mLeftTableCombo->currentText() ) );
89 emit validityChanged( isValid() );
90 } );
91 connect( mRightTableCombo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) {
92 mRightFieldsCombo->setFields( mConnection->fields( QString(), mRightTableCombo->currentText() ) );
93 emit validityChanged( isValid() );
94 } );
95
96 for ( QComboBox *combo : { mCardinalityCombo, qobject_cast<QComboBox *>( mLeftFieldsCombo ), qobject_cast<QComboBox *>( mRightFieldsCombo ), mStrengthCombo, mRelatedTableTypeCombo } )
97 {
98 connect( combo, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int ) { emit validityChanged( isValid() ); } );
99 }
100
101 mLeftFieldsCombo->setFields( mConnection->fields( QString(), mLeftTableCombo->currentText() ) );
102 mRightFieldsCombo->setFields( mConnection->fields( QString(), mRightTableCombo->currentText() ) );
103}
104
106{
107 mRelation = relationship;
108 mNameEdit->setText( mRelation.name() );
109 mNameEdit->setEnabled( false );
110 mStrengthCombo->setCurrentIndex( mStrengthCombo->findData( QVariant::fromValue( mRelation.strength() ) ) );
111
112 QVariantMap parts = QgsProviderRegistry::instance()->decodeUri( mConnection->providerKey(), mRelation.referencedLayerSource() );
113 mLeftTableCombo->setCurrentText( parts.value( u"layerName"_s ).toString() );
114 parts = QgsProviderRegistry::instance()->decodeUri( mConnection->providerKey(), mRelation.referencingLayerSource() );
115 mRightTableCombo->setCurrentText( parts.value( u"layerName"_s ).toString() );
116
117 mCardinalityCombo->setCurrentIndex( mCardinalityCombo->findData( QVariant::fromValue( mRelation.cardinality() ) ) );
118 mLeftFieldsCombo->setCurrentText( mRelation.referencedLayerFields().value( 0 ) );
119 mRightFieldsCombo->setCurrentText( mRelation.referencingLayerFields().value( 0 ) );
120 mForwardLabelLineEdit->setText( mRelation.forwardPathLabel() );
121 mBackwardLabelLineEdit->setText( mRelation.backwardPathLabel() );
122 mRelatedTableTypeCombo->setCurrentText( mRelation.relatedTableType() );
123}
124
126{
127 QgsWeakRelation result(
128 mRelation.id().isEmpty() ? mNameEdit->text() : mRelation.id(),
129 mRelation.name().isEmpty() ? mNameEdit->text() : mRelation.name(),
130 mStrengthCombo->currentData().value<Qgis::RelationshipStrength>(),
131 QString(),
132 QString(),
133 mConnection->tableUri( QString(), mRightTableCombo->currentText() ),
134 mConnection->providerKey(),
135 QString(),
136 QString(),
137 mConnection->tableUri( QString(), mLeftTableCombo->currentText() ),
138 mConnection->providerKey()
139 );
140 result.setCardinality( mCardinalityCombo->currentData().value<Qgis::RelationshipCardinality>() );
141 result.setReferencedLayerFields( { mLeftFieldsCombo->currentText() } );
142 result.setReferencingLayerFields( { mRightFieldsCombo->currentText() } );
143 result.setForwardPathLabel( mForwardLabelLineEdit->text() );
144 result.setBackwardPathLabel( mBackwardLabelLineEdit->text() );
145
146 result.setMappingTable( mRelation.mappingTable() );
147 result.setMappingReferencedLayerFields( mRelation.mappingReferencedLayerFields() );
148 result.setMappingReferencingLayerFields( mRelation.mappingReferencingLayerFields() );
149
150 if ( mRelatedTableTypeCombo->currentIndex() >= 0 )
151 result.setRelatedTableType( mRelatedTableTypeCombo->currentText() );
152 return result;
153}
154
156{
157 if ( mNameEdit->text().trimmed().isEmpty() )
158 return false;
159
160 if ( mLeftTableCombo->currentText().isEmpty() )
161 return false;
162
163 if ( mRightTableCombo->currentText().isEmpty() )
164 return false;
165
166 if ( mLeftTableCombo->currentText() == mRightTableCombo->currentText() )
167 return false;
168
169 if ( mLeftFieldsCombo->currentText().isEmpty() )
170 return false;
171
172 if ( mRightFieldsCombo->currentText().isEmpty() )
173 return false;
174
175
176 return true;
177}
178
179//
180// QgsDbRelationDialog
181//
182
183QgsDbRelationDialog::QgsDbRelationDialog( QgsAbstractDatabaseProviderConnection *connection, QWidget *parent, Qt::WindowFlags flags )
184 : QDialog( parent, flags )
185{
186 setObjectName( u"QgsDbRelationDialog"_s );
187
188 QVBoxLayout *vLayout = new QVBoxLayout();
189 mWidget = new QgsDbRelationWidget( connection );
190 vLayout->addWidget( mWidget, 1 );
191
192 mButtonBox = new QDialogButtonBox( QDialogButtonBox::StandardButton::Cancel | QDialogButtonBox::StandardButton::Help | QDialogButtonBox::StandardButton::Ok );
193 connect( mButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept );
194 connect( mButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject );
195 connect( mButtonBox, &QDialogButtonBox::helpRequested, this, [] { QgsHelp::openHelp( u"working_with_vector/joins_relations.html#dataset-stored-relationships"_s ); } );
196 vLayout->addWidget( mButtonBox );
197
198 setLayout( vLayout );
199 connect( mWidget, &QgsDbRelationWidget::validityChanged, this, &QgsDbRelationDialog::validityChanged );
200 validityChanged( mWidget->isValid() );
201
203}
204
206{
207 mWidget->setRelationship( relationship );
208}
209
211{
212 return mWidget->relationship();
213}
214
216{
217 if ( !mWidget->isValid() )
218 return;
219
220 QDialog::accept();
221}
222
223void QgsDbRelationDialog::validityChanged( bool isValid )
224{
225 mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( isValid );
226}
RelationshipStrength
Relationship strength.
Definition qgis.h:4549
@ Composition
Fix relation, related elements are part of the parent and a parent copy will copy any children or del...
Definition qgis.h:4551
@ Association
Loose relation, related elements are not part of the parent and a parent copy will not copy any child...
Definition qgis.h:4550
@ BackwardPathLabel
Supports backward path labels.
Definition qgis.h:4578
@ ForwardPathLabel
Supports forward path labels.
Definition qgis.h:4577
RelationshipCardinality
Relationship cardinality.
Definition qgis.h:4561
@ ManyToMany
Many to many relationship.
Definition qgis.h:4565
@ ManyToOne
Many to one relationship.
Definition qgis.h:4564
@ OneToOne
One to one relationship.
Definition qgis.h:4562
@ OneToMany
One to many relationship.
Definition qgis.h:4563
QFlags< RelationshipCapability > RelationshipCapabilities
Relationship capabilities.
Definition qgis.h:4587
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.