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