QGIS API Documentation 3.41.0-Master (cea29feecf2)
Loading...
Searching...
No Matches
qgsdatabasetablecombobox.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsdatabasetablecombobox.cpp
3 --------------------------------
4 Date : March 2020
5 Copyright : (C) 2020 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#include "moc_qgsdatabasetablecombobox.cpp"
19#include "qgsapplication.h"
21#include <QHBoxLayout>
22#include <QToolButton>
23
24QgsDatabaseTableComboBox::QgsDatabaseTableComboBox( const QString &provider, const QString &connection, const QString &schema, QWidget *parent )
25 : QWidget( parent )
26 , mProvider( provider )
27 , mConnection( connection )
28 , mSchema( schema )
29{
30 if ( !provider.isEmpty() && !connection.isEmpty() )
31 mModel = new QgsDatabaseTableModel( provider, connection, schema, this );
32 init();
33}
34
36 : QWidget( parent )
37 , mSchema( schema )
38{
39 mModel = new QgsDatabaseTableModel( connection, schema, this );
40 init();
41}
42
44{
45 mAllowEmpty = allowEmpty;
46 if ( mModel )
47 mModel->setAllowEmptyTable( allowEmpty );
48}
49
51{
52 return mAllowEmpty;
53}
54
55void QgsDatabaseTableComboBox::init()
56{
57 mComboBox = new QComboBox();
58
59 mSortModel = new QgsDatabaseTableComboBoxSortModel( this );
60 if ( mModel )
61 mSortModel->setSourceModel( mModel );
62 mSortModel->setSortRole( Qt::DisplayRole );
63 mSortModel->setSortLocaleAware( true );
64 mSortModel->setSortCaseSensitivity( Qt::CaseInsensitive );
65 mSortModel->setDynamicSortFilter( true );
66 mSortModel->sort( 0 );
67
68 mComboBox->setModel( mSortModel );
69
70 QHBoxLayout *l = new QHBoxLayout();
71 l->setContentsMargins( 0, 0, 0, 0 );
72 l->addWidget( mComboBox );
73
74 QToolButton *refreshButton = new QToolButton();
75 refreshButton->setAutoRaise( true );
76 refreshButton->setToolTip( tr( "Refresh tables" ) );
77 refreshButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionRefresh.svg" ) ) );
78 l->addWidget( refreshButton );
79 setLayout( l );
80
81 connect( refreshButton, &QToolButton::clicked, this, &QgsDatabaseTableComboBox::refreshTables );
82
83 connect( mComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::activated ), this, &QgsDatabaseTableComboBox::indexChanged );
84 connect( mSortModel, &QAbstractItemModel::rowsInserted, this, &QgsDatabaseTableComboBox::rowsChanged );
85 connect( mSortModel, &QAbstractItemModel::rowsRemoved, this, &QgsDatabaseTableComboBox::rowsChanged );
86}
87
88void QgsDatabaseTableComboBox::setTable( const QString &table, const QString &schema )
89{
90 if ( schema == currentSchema() && table == currentTable() )
91 return;
92
93 if ( table.isEmpty() )
94 {
95 if ( mAllowEmpty )
96 mComboBox->setCurrentIndex( 0 );
97 else
98 mComboBox->setCurrentIndex( -1 );
99
100 emit tableChanged( QString() );
101 return;
102 }
103
104 const QModelIndexList idxs = mSortModel->match( mSortModel->index( 0, 0 ), static_cast<int>( QgsDatabaseTableModel::CustomRole::TableName ), table, -1, Qt::MatchFixedString | Qt::MatchCaseSensitive );
105 for ( const QModelIndex &proxyIdx : idxs )
106 {
107 if ( proxyIdx.isValid() && proxyIdx.data( static_cast<int>( QgsDatabaseTableModel::CustomRole::TableName ) ).toString() == table
108 && ( schema.isEmpty() || proxyIdx.data( static_cast<int>( QgsDatabaseTableModel::CustomRole::Schema ) ).toString() == schema ) )
109 {
110 mComboBox->setCurrentIndex( proxyIdx.row() );
112 return;
113 }
114 }
115 mComboBox->setCurrentIndex( -1 );
116 emit tableChanged( QString() );
117}
118
119void QgsDatabaseTableComboBox::setConnectionName( const QString &connection, const QString &provider )
120{
121 if ( provider.isEmpty() && mConnection == connection )
122 return;
123
124 if ( !provider.isEmpty() )
125 mProvider = provider;
126
127 mConnection = connection;
128
129 const QString oldTable = currentTable();
130 const QString oldSchema = currentSchema();
131 QgsDatabaseTableModel *oldModel = mModel;
132 if ( !mConnection.isEmpty() )
133 {
134 mModel = new QgsDatabaseTableModel( mProvider, mConnection, mSchema, this );
135 mModel->setAllowEmptyTable( mAllowEmpty );
136 }
137 else
138 mModel = nullptr;
139
140 mSortModel->setSourceModel( mModel );
141 if ( oldModel )
142 oldModel->deleteLater();
143 if ( currentTable() != oldTable || currentSchema() != oldSchema )
144 setTable( oldTable, oldSchema );
145}
146
147void QgsDatabaseTableComboBox::setSchema( const QString &schema )
148{
149 if ( schema == mSchema )
150 return;
151 mSchema = schema;
152
153 if ( !mProvider.isEmpty() && !mConnection.isEmpty() )
154 {
155 const QString oldTable = currentTable();
156 QgsDatabaseTableModel *oldModel = mModel;
157 mModel = new QgsDatabaseTableModel( mProvider, mConnection, mSchema, this );
158 mModel->setAllowEmptyTable( mAllowEmpty );
159 mSortModel->setSourceModel( mModel );
160 oldModel->deleteLater();
161 setTable( oldTable );
162 }
163}
164
166{
167 const QString oldSchema = currentSchema();
168 const QString oldTable = currentTable();
169 if ( mModel )
170 mModel->refresh();
171 setTable( oldTable, oldSchema );
172}
173
175{
176 const QModelIndex proxyIndex = mSortModel->index( mComboBox->currentIndex(), 0 );
177 if ( !proxyIndex.isValid() )
178 {
179 return QString();
180 }
181
182 return mSortModel->data( proxyIndex, static_cast<int>( QgsDatabaseTableModel::CustomRole::Schema ) ).toString();
183}
184
186{
187 const QModelIndex proxyIndex = mSortModel->index( mComboBox->currentIndex(), 0 );
188 if ( !proxyIndex.isValid() )
189 {
190 return QString();
191 }
192
193 return mSortModel->data( proxyIndex, static_cast<int>( QgsDatabaseTableModel::CustomRole::TableName ) ).toString();
194}
195
196void QgsDatabaseTableComboBox::indexChanged( int i )
197{
198 Q_UNUSED( i )
199 emit tableChanged( currentTable() );
200}
201
202void QgsDatabaseTableComboBox::rowsChanged()
203{
204 if ( mComboBox->count() == 1 || ( mAllowEmpty && mComboBox->count() == 2 && mComboBox->currentIndex() == 1 ) )
205 {
206 //currently selected connection item has changed
208 }
209 else if ( mComboBox->count() == 0 )
210 {
211 emit tableChanged( QString() );
212 }
213}
214
216QgsDatabaseTableComboBoxSortModel::QgsDatabaseTableComboBoxSortModel( QObject *parent )
217 : QSortFilterProxyModel( parent )
218{
219}
220
221bool QgsDatabaseTableComboBoxSortModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
222{
223 // empty row is always first
224 if ( sourceModel()->data( left, static_cast<int>( QgsDatabaseTableModel::CustomRole::Empty ) ).toBool() )
225 return true;
226 else if ( sourceModel()->data( right, static_cast<int>( QgsDatabaseTableModel::CustomRole::Empty ) ).toBool() )
227 return false;
228
229 // default mode is alphabetical order
230 const QString leftStr = sourceModel()->data( left ).toString();
231 const QString rightStr = sourceModel()->data( right ).toString();
232 return QString::localeAwareCompare( leftStr, rightStr ) < 0;
233}
234
The QgsAbstractDatabaseProviderConnection class provides common functionality for DB based connection...
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
void setSchema(const QString &schema)
Sets the schema from which to retrieve the available tables.
void tableChanged(const QString &table, const QString &schema=QString())
Emitted whenever the currently selected table changes.
void setTable(const QString &table, const QString &schema=QString())
Sets the current table selected in the combo box.
void setConnectionName(const QString &connection, const QString &provider=QString())
Sets the database connection name from which to retrieve the available tables.
void refreshTables()
Refreshes the list of available tables.
QString currentSchema() const
Returns the schema of the current table selected in the combo box.
bool allowEmptyTable() const
Returns true if the combobox allows the empty table ("not set") choice.
void setAllowEmptyTable(bool allowEmpty)
Sets whether an optional empty table ("not set") option is present in the combobox.
QgsDatabaseTableComboBox(const QString &provider, const QString &connection, const QString &schema=QString(), QWidget *parent=nullptr)
Constructor for QgsDatabaseTableComboBox, for the specified provider and connection.
QString currentTable() const
Returns the name of the current table selected in the combo box.
A model containing tables from a database connection.
void refresh()
Refreshes the table list by querying the underlying connection.
void setAllowEmptyTable(bool allowEmpty)
Sets whether an optional empty table ("not set") option is present in the model.
@ Empty
Entry is an empty entry.