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