QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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
18#include "qgsapplication.h"
20#include <QHBoxLayout>
21#include <QToolButton>
22
23QgsDatabaseTableComboBox::QgsDatabaseTableComboBox( const QString &provider, const QString &connection, const QString &schema, QWidget *parent )
24 : QWidget( parent )
25 , mProvider( provider )
26 , mConnection( connection )
27 , mSchema( schema )
28{
29 if ( !provider.isEmpty() && !connection.isEmpty() )
30 mModel = new QgsDatabaseTableModel( provider, connection, schema, this );
31 init();
32}
33
35 : QWidget( parent )
36 , mSchema( schema )
37{
38 mModel = new QgsDatabaseTableModel( connection, schema, this );
39 init();
40}
41
43{
44 mAllowEmpty = allowEmpty;
45 if ( mModel )
46 mModel->setAllowEmptyTable( allowEmpty );
47}
48
50{
51 return mAllowEmpty;
52}
53
54void QgsDatabaseTableComboBox::init()
55{
56 mComboBox = new QComboBox();
57
58 mSortModel = new QgsDatabaseTableComboBoxSortModel( this );
59 if ( mModel )
60 mSortModel->setSourceModel( mModel );
61 mSortModel->setSortRole( Qt::DisplayRole );
62 mSortModel->setSortLocaleAware( true );
63 mSortModel->setSortCaseSensitivity( Qt::CaseInsensitive );
64 mSortModel->setDynamicSortFilter( true );
65 mSortModel->sort( 0 );
66
67 mComboBox->setModel( mSortModel );
68
69 QHBoxLayout *l = new QHBoxLayout();
70 l->setContentsMargins( 0, 0, 0, 0 );
71 l->addWidget( mComboBox );
72
73 QToolButton *refreshButton = new QToolButton();
74 refreshButton->setAutoRaise( true );
75 refreshButton->setToolTip( tr( "Refresh tables" ) );
76 refreshButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionRefresh.svg" ) ) );
77 l->addWidget( refreshButton );
78 setLayout( l );
79
80 connect( refreshButton, &QToolButton::clicked, this, &QgsDatabaseTableComboBox::refreshTables );
81
82 connect( mComboBox, static_cast < void ( QComboBox::* )( int ) > ( &QComboBox::activated ), this, &QgsDatabaseTableComboBox::indexChanged );
83 connect( mSortModel, &QAbstractItemModel::rowsInserted, this, &QgsDatabaseTableComboBox::rowsChanged );
84 connect( mSortModel, &QAbstractItemModel::rowsRemoved, this, &QgsDatabaseTableComboBox::rowsChanged );
85}
86
87void QgsDatabaseTableComboBox::setTable( const QString &table, const QString &schema )
88{
89 if ( schema == currentSchema() && table == currentTable() )
90 return;
91
92 if ( table.isEmpty() )
93 {
94 if ( mAllowEmpty )
95 mComboBox->setCurrentIndex( 0 );
96 else
97 mComboBox->setCurrentIndex( -1 );
98
99 emit tableChanged( QString() );
100 return;
101 }
102
103 const QModelIndexList idxs = mSortModel->match( mSortModel->index( 0, 0 ), static_cast< int >( QgsDatabaseTableModel::CustomRole::TableName ), table, -1, Qt::MatchFixedString | Qt::MatchCaseSensitive );
104 for ( const QModelIndex &proxyIdx : idxs )
105 {
106 if ( proxyIdx.isValid() && proxyIdx.data( static_cast< int >( QgsDatabaseTableModel::CustomRole::TableName ) ).toString() == table
107 && ( schema.isEmpty() || proxyIdx.data( static_cast< int >( QgsDatabaseTableModel::CustomRole::Schema ) ).toString() == schema ) )
108 {
109 mComboBox->setCurrentIndex( proxyIdx.row() );
111 return;
112 }
113 }
114 mComboBox->setCurrentIndex( -1 );
115 emit tableChanged( QString() );
116}
117
118void QgsDatabaseTableComboBox::setConnectionName( const QString &connection, const QString &provider )
119{
120 if ( provider.isEmpty() && mConnection == connection )
121 return;
122
123 if ( !provider.isEmpty() )
124 mProvider = provider;
125
126 mConnection = connection;
127
128 const QString oldTable = currentTable();
129 const QString oldSchema = currentSchema();
130 QgsDatabaseTableModel *oldModel = mModel;
131 if ( !mConnection.isEmpty() )
132 {
133 mModel = new QgsDatabaseTableModel( mProvider, mConnection, mSchema, this );
134 mModel->setAllowEmptyTable( mAllowEmpty );
135 }
136 else
137 mModel = nullptr;
138
139 mSortModel->setSourceModel( mModel );
140 if ( oldModel )
141 oldModel->deleteLater();
142 if ( currentTable() != oldTable || currentSchema() != oldSchema )
143 setTable( oldTable, oldSchema );
144}
145
146void QgsDatabaseTableComboBox::setSchema( const QString &schema )
147{
148 if ( schema == mSchema )
149 return;
150 mSchema = schema;
151
152 if ( !mProvider.isEmpty() && !mConnection.isEmpty() )
153 {
154 const QString oldTable = currentTable();
155 QgsDatabaseTableModel *oldModel = mModel;
156 mModel = new QgsDatabaseTableModel( mProvider, mConnection, mSchema, this );
157 mModel->setAllowEmptyTable( mAllowEmpty );
158 mSortModel->setSourceModel( mModel );
159 oldModel->deleteLater();
160 setTable( oldTable );
161 }
162}
163
165{
166 const QString oldSchema = currentSchema();
167 const QString oldTable = currentTable();
168 if ( mModel )
169 mModel->refresh();
170 setTable( oldTable, oldSchema );
171}
172
174{
175 const QModelIndex proxyIndex = mSortModel->index( mComboBox->currentIndex(), 0 );
176 if ( !proxyIndex.isValid() )
177 {
178 return QString();
179 }
180
181 return mSortModel->data( proxyIndex, static_cast< int >( QgsDatabaseTableModel::CustomRole::Schema ) ).toString();
182}
183
185{
186 const QModelIndex proxyIndex = mSortModel->index( mComboBox->currentIndex(), 0 );
187 if ( !proxyIndex.isValid() )
188 {
189 return QString();
190 }
191
192 return mSortModel->data( proxyIndex, static_cast< int >( QgsDatabaseTableModel::CustomRole::TableName ) ).toString();
193}
194
195void QgsDatabaseTableComboBox::indexChanged( int i )
196{
197 Q_UNUSED( i )
198 emit tableChanged( currentTable() );
199}
200
201void QgsDatabaseTableComboBox::rowsChanged()
202{
203 if ( mComboBox->count() == 1 || ( mAllowEmpty && mComboBox->count() == 2 && mComboBox->currentIndex() == 1 ) )
204 {
205 //currently selected connection item has changed
207 }
208 else if ( mComboBox->count() == 0 )
209 {
210 emit tableChanged( QString() );
211 }
212}
213
215QgsDatabaseTableComboBoxSortModel::QgsDatabaseTableComboBoxSortModel( QObject *parent )
216 : QSortFilterProxyModel( parent )
217{
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.