QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
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 "qgsdatabasetablemodel.h"
18 #include "qgsapplication.h"
20 #include <QHBoxLayout>
21 #include <QToolButton>
22 
23 QgsDatabaseTableComboBox::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 
54 void 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 
87 void 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 ), QgsDatabaseTableModel::RoleTableName, table, -1, Qt::MatchFixedString | Qt::MatchCaseSensitive );
104  for ( const QModelIndex &proxyIdx : idxs )
105  {
106  if ( proxyIdx.isValid() && proxyIdx.data( QgsDatabaseTableModel::RoleTableName ).toString() == table
107  && ( schema.isEmpty() || proxyIdx.data( QgsDatabaseTableModel::RoleSchema ).toString() == schema ) )
108  {
109  mComboBox->setCurrentIndex( proxyIdx.row() );
111  return;
112  }
113  }
114  mComboBox->setCurrentIndex( -1 );
115  emit tableChanged( QString() );
116 }
117 
118 void 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 
146 void 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  mSortModel->setSourceModel( mModel );
158  oldModel->deleteLater();
159  setTable( oldTable );
160  }
161 }
162 
164 {
165  const QString oldSchema = currentSchema();
166  const QString oldTable = currentTable();
167  if ( mModel )
168  mModel->refresh();
169  setTable( oldTable, oldSchema );
170 }
171 
173 {
174  const QModelIndex proxyIndex = mSortModel->index( mComboBox->currentIndex(), 0 );
175  if ( !proxyIndex.isValid() )
176  {
177  return QString();
178  }
179 
180  return mSortModel->data( proxyIndex, QgsDatabaseTableModel::RoleSchema ).toString();
181 }
182 
184 {
185  const QModelIndex proxyIndex = mSortModel->index( mComboBox->currentIndex(), 0 );
186  if ( !proxyIndex.isValid() )
187  {
188  return QString();
189  }
190 
191  return mSortModel->data( proxyIndex, QgsDatabaseTableModel::RoleTableName ).toString();
192 }
193 
194 void QgsDatabaseTableComboBox::indexChanged( int i )
195 {
196  Q_UNUSED( i )
197  emit tableChanged( currentTable() );
198 }
199 
200 void QgsDatabaseTableComboBox::rowsChanged()
201 {
202  if ( mComboBox->count() == 1 || ( mAllowEmpty && mComboBox->count() == 2 && mComboBox->currentIndex() == 1 ) )
203  {
204  //currently selected connection item has changed
206  }
207  else if ( mComboBox->count() == 0 )
208  {
209  emit tableChanged( QString() );
210  }
211 }
212 
214 QgsDatabaseTableComboBoxSortModel::QgsDatabaseTableComboBoxSortModel( QObject *parent )
215  : QSortFilterProxyModel( parent )
216 {
217 
218 }
219 
220 bool QgsDatabaseTableComboBoxSortModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const
221 {
222  // empty row is always first
223  if ( sourceModel()->data( left, QgsDatabaseTableModel::RoleEmpty ).toBool() )
224  return true;
225  else if ( sourceModel()->data( right, QgsDatabaseTableModel::RoleEmpty ).toBool() )
226  return false;
227 
228  // default mode is alphabetical order
229  QString leftStr = sourceModel()->data( left ).toString();
230  QString rightStr = sourceModel()->data( right ).toString();
231  return QString::localeAwareCompare( leftStr, rightStr ) < 0;
232 }
233 
QgsDatabaseTableComboBox::setSchema
void setSchema(const QString &schema)
Sets the schema from which to retrieve the available tables.
Definition: qgsdatabasetablecombobox.cpp:146
QgsApplication::getThemeIcon
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
Definition: qgsapplication.cpp:626
QgsDatabaseTableModel::RoleEmpty
@ RoleEmpty
Entry is an empty entry.
Definition: qgsdatabasetablemodel.h:55
qgsdatabasetablemodel.h
QgsDatabaseTableModel::RoleSchema
@ RoleSchema
Table schema.
Definition: qgsdatabasetablemodel.h:49
QgsDatabaseTableComboBox::setTable
void setTable(const QString &table, const QString &schema=QString())
Sets the current table selected in the combo box.
Definition: qgsdatabasetablecombobox.cpp:87
QgsDatabaseTableComboBox::currentTable
QString currentTable() const
Returns the name of the current table selected in the combo box.
Definition: qgsdatabasetablecombobox.cpp:183
qgsdatabasetablecombobox.h
qgsapplication.h
QgsDatabaseTableComboBox::setAllowEmptyTable
void setAllowEmptyTable(bool allowEmpty)
Sets whether an optional empty table ("not set") option is present in the combobox.
Definition: qgsdatabasetablecombobox.cpp:42
QgsDatabaseTableComboBox::refreshTables
void refreshTables()
Refreshes the list of available tables.
Definition: qgsdatabasetablecombobox.cpp:163
QgsDatabaseTableModel
A model containing tables from a database connection.
Definition: qgsdatabasetablemodel.h:40
QgsDatabaseTableComboBox::allowEmptyTable
bool allowEmptyTable() const
Returns true if the combobox allows the empty table ("not set") choice.
Definition: qgsdatabasetablecombobox.cpp:49
QgsDatabaseTableComboBox::tableChanged
void tableChanged(const QString &table, const QString &schema=QString())
Emitted whenever the currently selected table changes.
QgsDatabaseTableComboBox::setConnectionName
void setConnectionName(const QString &connection, const QString &provider=QString())
Sets the database connection name from which to retrieve the available tables.
Definition: qgsdatabasetablecombobox.cpp:118
QgsDatabaseTableModel::refresh
void refresh()
Refreshes the table list by querying the underlying connection.
Definition: qgsdatabasetablemodel.cpp:193
QgsDatabaseTableModel::setAllowEmptyTable
void setAllowEmptyTable(bool allowEmpty)
Sets whether an optional empty table ("not set") option is present in the model.
Definition: qgsdatabasetablemodel.cpp:174
QgsDatabaseTableComboBox::QgsDatabaseTableComboBox
QgsDatabaseTableComboBox(const QString &provider, const QString &connection, const QString &schema=QString(), QWidget *parent=nullptr)
Constructor for QgsDatabaseTableComboBox, for the specified provider and connection.
Definition: qgsdatabasetablecombobox.cpp:23
QgsDatabaseTableComboBox::currentSchema
QString currentSchema() const
Returns the schema of the current table selected in the combo box.
Definition: qgsdatabasetablecombobox.cpp:172
QgsDatabaseTableModel::RoleTableName
@ RoleTableName
Table name.
Definition: qgsdatabasetablemodel.h:48
qgsabstractdatabaseproviderconnection.h
QgsAbstractDatabaseProviderConnection
The QgsAbstractDatabaseProviderConnection class provides common functionality for DB based connection...
Definition: qgsabstractdatabaseproviderconnection.h:44